aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/board/Synology
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/board/Synology')
-rw-r--r--roms/u-boot/board/Synology/common/Makefile5
-rw-r--r--roms/u-boot/board/Synology/common/legacy.c76
-rw-r--r--roms/u-boot/board/Synology/common/legacy.h33
-rw-r--r--roms/u-boot/board/Synology/ds109/Kconfig12
-rw-r--r--roms/u-boot/board/Synology/ds109/MAINTAINERS6
-rw-r--r--roms/u-boot/board/Synology/ds109/Makefile7
-rw-r--r--roms/u-boot/board/Synology/ds109/ds109.c149
-rw-r--r--roms/u-boot/board/Synology/ds109/ds109.h26
-rw-r--r--roms/u-boot/board/Synology/ds109/kwbimage.cfg150
-rw-r--r--roms/u-boot/board/Synology/ds109/openocd.cfg115
-rw-r--r--roms/u-boot/board/Synology/ds414/Kconfig12
-rw-r--r--roms/u-boot/board/Synology/ds414/MAINTAINERS6
-rw-r--r--roms/u-boot/board/Synology/ds414/Makefile8
-rw-r--r--roms/u-boot/board/Synology/ds414/cmd_syno.c225
-rw-r--r--roms/u-boot/board/Synology/ds414/cmd_syno.h17
-rw-r--r--roms/u-boot/board/Synology/ds414/ds414.c198
16 files changed, 1045 insertions, 0 deletions
diff --git a/roms/u-boot/board/Synology/common/Makefile b/roms/u-boot/board/Synology/common/Makefile
new file mode 100644
index 000000000..62354cc2e
--- /dev/null
+++ b/roms/u-boot/board/Synology/common/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021 Phil Sutter <phil@nwl.cc>
+
+obj-y += legacy.o
diff --git a/roms/u-boot/board/Synology/common/legacy.c b/roms/u-boot/board/Synology/common/legacy.c
new file mode 100644
index 000000000..3c89e92ae
--- /dev/null
+++ b/roms/u-boot/board/Synology/common/legacy.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * Walter Schweizer <swwa@users.sourceforge.net>
+ * Phil Sutter <phil@nwl.cc>
+ */
+
+#include <config.h>
+#include <vsprintf.h>
+#include <env.h>
+#include <net.h>
+#include <asm/setup.h>
+
+#include "legacy.h"
+
+static unsigned int syno_board_id(void)
+{
+ switch (CONFIG_MACH_TYPE) {
+ case 527:
+ return SYNO_DS109_ID;
+ case 3036:
+ return SYNO_AXP_4BAY_2BAY;
+ default:
+ return 0;
+ }
+}
+
+static unsigned int usb_port_modes(void)
+{
+ unsigned int i, ret = 0;
+ char var[32], *val;
+
+ for (i = 0; i < USBPORT_MAX; i++) {
+ snprintf(var, 32, "usb%dMode", i);
+ val = env_get(var);
+
+ if (!val || strcasecmp(val, "host"))
+ continue;
+
+ ret |= 1 << i;
+ }
+ return ret;
+}
+
+/* Support old kernels */
+void setup_board_tags(struct tag **in_params)
+{
+ struct tag_mv_uboot *t;
+ struct tag *params;
+ int i;
+
+ debug("Synology board tags...\n");
+
+ params = *in_params;
+ t = (struct tag_mv_uboot *)&params->u;
+
+ t->uboot_version = VER_NUM | syno_board_id();
+ t->tclk = CONFIG_SYS_TCLK;
+ t->sysclk = CONFIG_SYS_TCLK * 2;
+ t->isusbhost = usb_port_modes();
+
+ for (i = 0; i < ETHADDR_MAX; i++) {
+ char addrvar[16], mtuvar[16];
+
+ sprintf(addrvar, i ? "eth%daddr" : "ethaddr", i);
+ sprintf(mtuvar, i ? "eth%dmtu" : "ethmtu", i);
+
+ eth_env_get_enetaddr(addrvar, t->macaddr[i]);
+ t->mtu[i] = env_get_ulong(mtuvar, 10, 0);
+ }
+
+ params->hdr.tag = ATAG_MV_UBOOT;
+ params->hdr.size = tag_size(tag_mv_uboot);
+ params = tag_next(params);
+ *in_params = params;
+}
diff --git a/roms/u-boot/board/Synology/common/legacy.h b/roms/u-boot/board/Synology/common/legacy.h
new file mode 100644
index 000000000..0a814324d
--- /dev/null
+++ b/roms/u-boot/board/Synology/common/legacy.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021
+ * Walter Schweizer <swwa@users.sourceforge.net>
+ * Phil Sutter <phil@nwl.cc>
+ */
+
+#ifndef __SYNO_LEGACY_H
+#define __SYNO_LEGACY_H
+
+/* Marvell uboot parameters */
+#define ATAG_MV_UBOOT 0x41000403
+#define VER_NUM 0x03040400 /* 3.4.4 */
+
+#define BOARD_ID_BASE 0x0
+#define SYNO_DS109_ID (BOARD_ID_BASE + 0x15)
+#define SYNO_AXP_4BAY_2BAY (0xf + 1)
+
+#define ETHADDR_MAX 4
+#define USBPORT_MAX 3
+
+struct tag_mv_uboot {
+ u32 uboot_version;
+ u32 tclk;
+ u32 sysclk;
+ u32 isusbhost;
+ u8 macaddr[ETHADDR_MAX][ETH_ALEN];
+ u16 mtu[ETHADDR_MAX];
+ u32 fw_image_base;
+ u32 fw_image_size;
+};
+
+#endif /* __SYNO_LEGACY_H */
diff --git a/roms/u-boot/board/Synology/ds109/Kconfig b/roms/u-boot/board/Synology/ds109/Kconfig
new file mode 100644
index 000000000..a7c75ae36
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds109/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_DS109
+
+config SYS_BOARD
+ default "ds109"
+
+config SYS_VENDOR
+ default "Synology"
+
+config SYS_CONFIG_NAME
+ default "ds109"
+
+endif
diff --git a/roms/u-boot/board/Synology/ds109/MAINTAINERS b/roms/u-boot/board/Synology/ds109/MAINTAINERS
new file mode 100644
index 000000000..8783fdb1f
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds109/MAINTAINERS
@@ -0,0 +1,6 @@
+DS109 BOARD
+M: Walter Schweizer <swwa@users.sourceforge.net>
+S: Maintained
+F: board/Synology/ds109
+F: configs/ds109_defconfig
+F: include/configs/ds109.h
diff --git a/roms/u-boot/board/Synology/ds109/Makefile b/roms/u-boot/board/Synology/ds109/Makefile
new file mode 100644
index 000000000..9d103a61b
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds109/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+
+obj-y := ds109.o
diff --git a/roms/u-boot/board/Synology/ds109/ds109.c b/roms/u-boot/board/Synology/ds109/ds109.c
new file mode 100644
index 000000000..3914faaf3
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds109/ds109.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2009-2012
+ * Wojciech Dubowik <wojciech.dubowik@neratec.com>
+ * Luka Perkov <luka@openwrt.org>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <miiphy.h>
+#include <net.h>
+#include <asm/global_data.h>
+#include <asm/setup.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+#include <asm/arch/mpp.h>
+#include <linux/delay.h>
+#include "ds109.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_early_init_f(void)
+{
+ /*
+ * default gpio configuration
+ * There are maximum 64 gpios controlled through 2 sets of registers
+ * the below configuration configures mainly initial LED status
+ */
+ mvebu_config_gpio(DS109_OE_VAL_LOW,
+ DS109_OE_VAL_HIGH,
+ DS109_OE_LOW, DS109_OE_HIGH);
+
+ /* Multi-Purpose Pins Functionality configuration */
+ static const u32 kwmpp_config[] = {
+ MPP0_SPI_SCn, /* SPI Flash */
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP4_GPIO,
+ MPP5_GPO,
+ MPP6_SYSRST_OUTn, /* Reset signal */
+ MPP7_GPO,
+ MPP8_TW_SDA, /* I2C */
+ MPP9_TW_SCK, /* I2C */
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP12_GPO,
+ MPP13_UART1_TXD,
+ MPP14_UART1_RXD,
+ MPP15_GPIO,
+ MPP16_GPIO,
+ MPP17_GPIO,
+ MPP18_GPO,
+ MPP19_GPO,
+ MPP20_SATA1_ACTn,
+ MPP21_SATA0_ACTn,
+ MPP22_GPIO, /* HDD2 FAIL LED */
+ MPP23_GPIO, /* HDD1 FAIL LED */
+ MPP24_GPIO,
+ MPP25_GPIO,
+ MPP26_GPIO,
+ MPP27_GPIO,
+ MPP28_GPIO,
+ MPP29_GPIO,
+ MPP30_GPIO,
+ MPP31_GPIO, /* HDD2 */
+ MPP32_GPIO, /* FAN A */
+ MPP33_GPIO, /* FAN B */
+ MPP34_GPIO, /* FAN C */
+ MPP35_GPIO, /* FAN SENSE */
+ MPP36_GPIO,
+ MPP37_GPIO,
+ MPP38_GPIO,
+ MPP39_GPIO,
+ MPP40_GPIO,
+ MPP41_GPIO,
+ MPP42_GPIO,
+ MPP43_GPIO,
+ MPP44_GPIO,
+ MPP45_GPIO,
+ MPP46_GPIO,
+ MPP47_GPIO,
+ MPP48_GPIO,
+ MPP49_GPIO,
+ 0
+ };
+ kirkwood_mpp_conf(kwmpp_config, NULL);
+ return 0;
+}
+
+int board_init(void)
+{
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
+
+ return 0;
+}
+
+/* Synology reset uses UART */
+#include <ns16550.h>
+#define SOFTWARE_SHUTDOWN 0x31
+#define SOFTWARE_REBOOT 0x43
+#define CONFIG_SYS_NS16550_COM2 KW_UART1_BASE
+void reset_misc(void)
+{
+ int b_d;
+ printf("Synology reset...");
+ udelay(50000);
+
+ b_d = ns16550_calc_divisor((struct ns16550 *)CONFIG_SYS_NS16550_COM2,
+ CONFIG_SYS_NS16550_CLK, 9600);
+ ns16550_init((struct ns16550 *)CONFIG_SYS_NS16550_COM2, b_d);
+ ns16550_putc((struct ns16550 *)CONFIG_SYS_NS16550_COM2,
+ SOFTWARE_REBOOT);
+}
+
+#ifdef CONFIG_RESET_PHY_R
+/* Configure and enable MV88E1116 PHY */
+void reset_phy(void)
+{
+ u16 reg;
+ u16 devadr;
+ char *name = "egiga0";
+
+ if (miiphy_set_current_dev(name))
+ return;
+
+ /* command to read PHY dev address */
+ if (miiphy_read(name, 0xEE, 0xEE, (u16 *)&devadr)) {
+ printf("Error: 88E1116 could not read PHY dev address\n");
+ return;
+ }
+
+ /*
+ * Enable RGMII delay on Tx and Rx for CPU port
+ * Ref: sec 4.7.2 of chip datasheet
+ */
+ miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
+ miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
+ reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
+ miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
+ miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+
+ /* reset the phy */
+ miiphy_reset(name, devadr);
+
+ printf("88E1116 Initialized on %s\n", name);
+}
+#endif /* CONFIG_RESET_PHY_R */
diff --git a/roms/u-boot/board/Synology/ds109/ds109.h b/roms/u-boot/board/Synology/ds109/ds109.h
new file mode 100644
index 000000000..0cf05257c
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds109/ds109.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2009-2012
+ * Wojciech Dubowik <wojciech.dubowik@neratec.com>
+ * Luka Perkov <luka@openwrt.org>
+ */
+
+#ifndef __DS109_H
+#define __DS109_H
+
+#define DS109_OE_LOW (0)
+#define DS109_OE_HIGH (0)
+#define DS109_OE_VAL_LOW ((1 << 22)|(1 << 23))
+#define DS109_OE_VAL_HIGH ((1 << 1)|1)
+
+/* PHY related */
+#define MV88E1116_LED_FCTRL_REG 10
+#define MV88E1116_CPRSP_CR3_REG 21
+#define MV88E1116_MAC_CTRL_REG 21
+#define MV88E1116_MAC_CTRL2_REG 21
+
+#define MV88E1116_PGADR_REG 22
+#define MV88E1116_RGMII_TXTM_CTRL (1 << 4)
+#define MV88E1116_RGMII_RXTM_CTRL (1 << 5)
+
+#endif /* __DS109_H */
diff --git a/roms/u-boot/board/Synology/ds109/kwbimage.cfg b/roms/u-boot/board/Synology/ds109/kwbimage.cfg
new file mode 100644
index 000000000..8f6e70513
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds109/kwbimage.cfg
@@ -0,0 +1,150 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2011
+# Jason Cooper <u-boot@lakedaemon.net>
+#
+# Based on work by:
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Siddarth Gore <gores@marvell.com>
+# Refer doc/README.kwbimage for more details about how-to configure
+# and create kirkwood boot image
+#
+
+# Boot Media configurations
+BOOT_FROM spi
+
+# SOC registers configuration using bootrom header extension
+# Maximum KWBIMAGE_MAX_CONFIG configurations allowed
+
+# Configure RGMII-0/1 interface pad voltage to 1.8V
+DATA 0xFFD100e0 0x1b1b1b9b
+
+DATA 0xFFD20134 0xbbbbbbbb
+DATA 0xFFD20138 0x00bbbbbb
+
+#Dram initalization for SINGLE x16 CL=5 @ 400MHz
+DATA 0xFFD01400 0x43000c30 # DDR Configuration register
+# bit13-0: 0xc30 (3120 DDR2 clks refresh rate)
+# bit23-14: zero
+# bit24: 1= enable exit self refresh mode on DDR access
+# bit25: 1 required
+# bit29-26: zero
+# bit31-30: 01
+
+DATA 0xFFD01404 0x39543000 # DDR Controller Control Low
+# bit 4: 0=addr/cmd in smame cycle
+# bit 5: 0=clk is driven during self refresh, we don't care for APX
+# bit 6: 0=use recommended falling edge of clk for addr/cmd
+# bit14: 0=input buffer always powered up
+# bit18: 1=cpu lock transaction enabled
+# bit23-20: 5=recommended value for CL=5 and STARTBURST_DEL disabled bit31=0
+# bit27-24: 7= CL+2, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
+# bit30-28: 3 required
+# bit31: 0=no additional STARTBURST delay
+
+DATA 0xFFD01408 0x22125451 # DDR Timing (Low) (active cycles value +1)
+# bit3-0: TRAS lsbs
+# bit7-4: TRCD
+# bit11- 8: TRP
+# bit15-12: TWR
+# bit19-16: TWTR
+# bit20: TRAS msb
+# bit23-21: 0x0
+# bit27-24: TRRD
+# bit31-28: TRTP
+
+DATA 0xFFD0140C 0x00000833 # DDR Timing (High)
+# bit6-0: TRFC
+# bit8-7: TR2R
+# bit10-9: TR2W
+# bit12-11: TW2W
+# bit31-13: zero required
+
+DATA 0xFFD01410 0x0000000d # DDR Address Control
+# bit1-0: 01, Cs0width=x8
+# bit3-2: 10, Cs0size=1Gb
+# bit5-4: 01, Cs1width=x8
+# bit7-6: 10, Cs1size=1Gb
+# bit9-8: 00, Cs2width=nonexistent
+# bit11-10: 00, Cs2size =nonexistent
+# bit13-12: 00, Cs3width=nonexistent
+# bit15-14: 00, Cs3size =nonexistent
+# bit16: 0, Cs0AddrSel
+# bit17: 0, Cs1AddrSel
+# bit18: 0, Cs2AddrSel
+# bit19: 0, Cs3AddrSel
+# bit31-20: 0 required
+
+DATA 0xFFD01414 0x00000000 # DDR Open Pages Control
+# bit0: 0, OpenPage enabled
+# bit31-1: 0 required
+
+DATA 0xFFD01418 0x00000000 # DDR Operation
+# bit3-0: 0x0, DDR cmd
+# bit31-4: 0 required
+
+DATA 0xFFD0141C 0x00000C52 # DDR Mode
+# bit2-0: 2, BurstLen=2 required
+# bit3: 0, BurstType=0 required
+# bit6-4: 4, CL=5
+# bit7: 0, TestMode=0 normal
+# bit8: 0, DLL reset=0 normal
+# bit11-9: 6, auto-precharge write recovery ????????????
+# bit12: 0, PD must be zero
+# bit31-13: 0 required
+
+DATA 0xFFD01420 0x00000042 # DDR Extended Mode
+# bit0: 0, DDR DLL enabled
+# bit1: 0, DDR drive strenght normal
+# bit2: 0, DDR ODT control lsd (disabled)
+# bit5-3: 000, required
+# bit6: 1, DDR ODT control msb, (disabled)
+# bit9-7: 000, required
+# bit10: 0, differential DQS enabled
+# bit11: 0, required
+# bit12: 0, DDR output buffer enabled
+# bit31-13: 0 required
+
+DATA 0xFFD01424 0x0000F1FF # DDR Controller Control High
+# bit2-0: 111, required
+# bit3 : 1 , MBUS Burst Chop disabled
+# bit6-4: 111, required
+# bit7 : 0
+# bit8 : 1 , add writepath sample stage, must be 1 for DDR freq >= 300MHz
+# bit9 : 0 , no half clock cycle addition to dataout
+# bit10 : 0 , 1/4 clock cycle skew enabled for addr/ctl signals
+# bit11 : 0 , 1/4 clock cycle skew disabled for write mesh
+# bit15-12: 1111 required
+# bit31-16: 0 required
+
+DATA 0xFFD01428 0x00085520 # DDR2 ODT Read Timing (default values)
+DATA 0xFFD0147C 0x00008552 # DDR2 ODT Write Timing (default values)
+
+DATA 0xFFD01500 0x00000000 # CS[0]n Base address to 0x0
+DATA 0xFFD01504 0x07FFFFF1 # CS[0]n Size
+# bit0: 1, Window enabled
+# bit1: 0, Write Protect disabled
+# bit3-2: 00, CS0 hit selected
+# bit23-4: ones, required
+# bit31-24: 0x07, Size (i.e. 128MB)
+
+DATA 0xFFD01508 0x10000000 # CS[1]n Base address to 256Mb
+DATA 0xFFD0150C 0x00000000 # CS[1]n Size, window disabled
+
+DATA 0xFFD01510 0x20000000 # CS[2]n Base address to 256Mb
+DATA 0xFFD01514 0x00000000 # CS[2]n Size, window disabled
+DATA 0xFFD01518 0x30000000 # CS[3]n Base address to 256Mb
+DATA 0xFFD0151C 0x00000000 # CS[3]n Size, window disabled
+
+DATA 0xFFD01494 0x003C0000 # DDR ODT Control (Low)
+DATA 0xFFD01498 0x00000000 # DDR ODT Control (High)
+# bit1-0: 00, ODT0 controlled by ODT Control (low) register above
+# bit3-2: 01, ODT1 active NEVER!
+# bit31-4: zero, required
+
+DATA 0xFFD0149C 0x0000F80F # CPU ODT Control
+DATA 0xFFD01480 0x00000001 # DDR Initialization Control
+#bit0=1, enable DDR init upon this register write
+
+# End of Header extension
+DATA 0x0 0x0
diff --git a/roms/u-boot/board/Synology/ds109/openocd.cfg b/roms/u-boot/board/Synology/ds109/openocd.cfg
new file mode 100644
index 000000000..baa512aef
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds109/openocd.cfg
@@ -0,0 +1,115 @@
+# Synology DS109
+
+interface ftdi
+ftdi_vid_pid 0x0403 0x6010
+
+ftdi_layout_init 0x0008 0x000b
+ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010
+ftdi_layout_signal nSRST -data 0x0040 -oe 0x0040
+
+adapter_khz 2000
+
+# length of reset signal: [ms]
+adapter_nsrst_assert_width 1000
+
+# don't talk to JTAG after reset for: [ms]
+adapter_nsrst_delay 200
+
+source [find target/feroceon.cfg]
+
+reset_config trst_and_srst srst_nogate
+
+proc ds109_init { } {
+
+ # We need to assert DBGRQ while holding nSRST down.
+ # However DBGACK will be set only when nSRST is released.
+ # Furthermore, the JTAG interface doesn't respond at all when
+ # the CPU is in the WFI (wait for interrupts) state, so it is
+ # possible that initial tap examination failed. So let's
+ # re-examine the target again here when nSRST is asserted which
+ # should then succeed.
+ jtag_reset 0 1
+ feroceon.cpu arp_examine
+ halt 0
+ jtag_reset 0 0
+ wait_halt
+ #reset run
+ #soft_reset_halt
+
+ arm mcr 15 0 0 1 0 0x00052078
+
+ mww 0xD00100e0 0x1b1b1b9b ;#
+ mww 0xD0020134 0xbbbbbbbb ;#
+ mww 0xD0020138 0x00bbbbbb ;#
+ mww 0xD0001400 0x43000C30 ;# DDR SDRAM Configuration Register
+ mww 0xD0001404 0x39743000 ;# Dunit Control Low Register
+ mww 0xD0001408 0x22125551 ;# DDR SDRAM Timing (Low) Register
+ mww 0xD000140C 0x00000833 ;# DDR SDRAM Timing (High) Register
+ mww 0xD0001410 0x0000000d ;# DDR SDRAM Address Control Register
+ mww 0xD0001414 0x00000000 ;# DDR SDRAM Open Pages Control Register
+ mww 0xD0001418 0x00000000 ;# DDR SDRAM Operation Register
+ mww 0xD000141C 0x00000C62 ;# DDR SDRAM Mode Register
+ mww 0xD0001420 0x00000042 ;# DDR SDRAM Extended Mode Register
+ mww 0xD0001424 0x0000F1FF ;# Dunit Control High Register
+ mww 0xD0001428 0x00085520 ;# Dunit Control High Register
+ mww 0xD000147c 0x00008552 ;# Dunit Control High Register
+ mww 0xD0001500 0x00000000 ;#
+ mww 0xD0001504 0x07FFFFF1 ;# CS0n Size Register
+ mww 0xD0001508 0x10000000 ;# CS1n Base Register
+ mww 0xD000150C 0x00000000 ;# CS1n Size Register
+ mww 0xD0001510 0x20000000 ;#
+ mww 0xD0001514 0x00000000 ;# CS2n Size Register
+ mww 0xD000151C 0x00000000 ;# CS3n Size Register
+ mww 0xD0001494 0x003C0000 ;# DDR2 SDRAM ODT Control (Low) Register
+ mww 0xD0001498 0x00000000 ;# DDR2 SDRAM ODT Control (High) REgister
+ mww 0xD000149C 0x0000F80F ;# DDR2 Dunit ODT Control Register
+ mww 0xD0001480 0x00000001 ;# DDR SDRAM Initialization Control Register
+ mww 0xD0020204 0x00000000 ;# Main IRQ Interrupt Mask Register
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+ mww 0xD0020204 0x00000000 ;# "
+
+ mww 0xD0010000 0x01111111 ;# MPP 0 to 7
+ mww 0xD0010004 0x11113322 ;# MPP 8 to 15
+ mww 0xD0010008 0x00001111 ;# MPP 16 to 23
+}
+
+proc ds109_load { } {
+ # load u-Boot into RAM and execute it
+ ds109_init
+ load_image u-boot.bin 0x00600000 bin
+ resume 0x00600000
+}
diff --git a/roms/u-boot/board/Synology/ds414/Kconfig b/roms/u-boot/board/Synology/ds414/Kconfig
new file mode 100644
index 000000000..4d3085255
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds414/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_DS414
+
+config SYS_BOARD
+ default "ds414"
+
+config SYS_VENDOR
+ default "Synology"
+
+config SYS_CONFIG_NAME
+ default "ds414"
+
+endif
diff --git a/roms/u-boot/board/Synology/ds414/MAINTAINERS b/roms/u-boot/board/Synology/ds414/MAINTAINERS
new file mode 100644
index 000000000..502cbd775
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds414/MAINTAINERS
@@ -0,0 +1,6 @@
+DS414 BOARD
+M: Phil Sutter <phil@nwl.cc>
+S: Maintained
+F: board/Synology/ds414/
+F: include/configs/ds414.h
+F: configs/ds414_defconfig
diff --git a/roms/u-boot/board/Synology/ds414/Makefile b/roms/u-boot/board/Synology/ds414/Makefile
new file mode 100644
index 000000000..b1d018eff
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds414/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2015 Phil Sutter <phil@nwl.cc>
+
+obj-y += ds414.o
+ifndef CONFIG_SPL_BUILD
+obj-y += cmd_syno.o
+endif
diff --git a/roms/u-boot/board/Synology/ds414/cmd_syno.c b/roms/u-boot/board/Synology/ds414/cmd_syno.c
new file mode 100644
index 000000000..a62658a2e
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds414/cmd_syno.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Commands to deal with Synology specifics.
+ *
+ * Copyright (C) 2015 Phil Sutter <phil@nwl.cc>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <div64.h>
+#include <env.h>
+#include <net.h>
+#include <spi.h>
+#include <spi_flash.h>
+#include <linux/mtd/mtd.h>
+
+#include <asm/io.h>
+#include "../drivers/ddr/marvell/axp/ddr3_init.h"
+
+#include "cmd_syno.h"
+
+int do_syno_populate(int argc, char *const argv[])
+{
+ unsigned int bus = CONFIG_SF_DEFAULT_BUS;
+ unsigned int cs = CONFIG_SF_DEFAULT_CS;
+ unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
+ unsigned int mode = CONFIG_SF_DEFAULT_MODE;
+ struct spi_flash *flash;
+ unsigned long addr = 0x80000; /* XXX: parameterize this? */
+ loff_t offset = 0x007d0000;
+ loff_t len = 0x00010000;
+ char *buf, *bufp;
+ char var[128];
+ char val[128];
+ int ret, n;
+
+ /* XXX: arg parsing to select flash here? */
+
+ flash = spi_flash_probe(bus, cs, speed, mode);
+ if (!flash) {
+ printf("Failed to initialize SPI flash at %u:%u\n", bus, cs);
+ return 1;
+ }
+
+ buf = map_physmem(addr, len, MAP_WRBACK);
+ if (!buf) {
+ puts("Failed to map physical memory\n");
+ return 1;
+ }
+
+ ret = spi_flash_read(flash, offset, len, buf);
+ if (ret) {
+ puts("Failed to read from SPI flash\n");
+ goto out_unmap;
+ }
+
+ for (n = 0; n < SYNO_ETHADDR_MAX; n++) {
+ char ethaddr[ETH_ALEN];
+ int i, sum = 0;
+ unsigned char csum = 0;
+
+ for (i = 0, bufp = buf + n * 7; i < ETH_ALEN; i++) {
+ sum += bufp[i];
+ csum += bufp[i];
+ ethaddr[i] = bufp[i];
+ }
+ if (!sum) /* MAC address empty */
+ continue;
+ if (csum != bufp[i]) { /* seventh byte is checksum value */
+ printf("Invalid MAC address for interface %d!\n", n);
+ continue;
+ }
+ if (n == 0)
+ sprintf(var, "ethaddr");
+ else
+ sprintf(var, "eth%daddr", n);
+ snprintf(val, sizeof(val) - 1,
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ ethaddr[0], ethaddr[1], ethaddr[2],
+ ethaddr[3], ethaddr[4], ethaddr[5]);
+ printf("parsed %s = %s\n", var, val);
+ env_set(var, val);
+ }
+ if (!strncmp(buf + 32, SYNO_SN_TAG, strlen(SYNO_SN_TAG))) {
+ char *snp, *csump;
+ int csum = 0;
+ unsigned long c;
+
+ snp = bufp = buf + 32 + strlen(SYNO_SN_TAG);
+ for (n = 0; bufp[n] && bufp[n] != ','; n++)
+ csum += bufp[n];
+ bufp[n] = '\0';
+
+ /* should come right after, but you never know */
+ bufp = strstr(bufp + n + 1, SYNO_CHKSUM_TAG);
+ if (!bufp) {
+ printf("Serial number checksum tag missing!\n");
+ goto out_unmap;
+ }
+
+ csump = bufp += strlen(SYNO_CHKSUM_TAG);
+ for (n = 0; bufp[n] && bufp[n] != ','; n++)
+ ;
+ bufp[n] = '\0';
+
+ if (strict_strtoul(csump, 10, &c) || c != csum) {
+ puts("Invalid serial number found!\n");
+ ret = 1;
+ goto out_unmap;
+ }
+ printf("parsed SN = %s\n", snp);
+ env_set("SN", snp);
+ } else { /* old style format */
+ unsigned char csum = 0;
+
+ for (n = 0, bufp = buf + 32; n < 10; n++)
+ csum += bufp[n];
+
+ if (csum != bufp[n]) {
+ puts("Invalid serial number found!\n");
+ ret = 1;
+ goto out_unmap;
+ }
+ bufp[n] = '\0';
+ printf("parsed SN = %s\n", buf + 32);
+ env_set("SN", buf + 32);
+ }
+out_unmap:
+ unmap_physmem(buf, len);
+ return ret;
+}
+
+/* map bit position to function in POWER_MNG_CTRL_REG */
+static const char * const pwr_mng_bit_func[] = {
+ "audio",
+ "ge3", "ge2", "ge1", "ge0",
+ "pcie00", "pcie01", "pcie02", "pcie03",
+ "pcie10", "pcie11", "pcie12", "pcie13",
+ "bp",
+ "sata0_link", "sata0_core",
+ "lcd",
+ "sdio",
+ "usb0", "usb1", "usb2",
+ "idma", "xor0", "crypto",
+ NULL,
+ "tdm",
+ "pcie20", "pcie30",
+ "xor1",
+ "sata1_link", "sata1_core",
+ NULL,
+};
+
+static int do_syno_clk_gate(int argc, char *const argv[])
+{
+ u32 pwr_mng_ctrl_reg = reg_read(POWER_MNG_CTRL_REG);
+ const char *func, *state;
+ int i, val;
+
+ if (argc < 2)
+ return -1;
+
+ if (!strcmp(argv[1], "get")) {
+ puts("Clock Gating:\n");
+ for (i = 0; i < 32; i++) {
+ func = pwr_mng_bit_func[i];
+ if (!func)
+ continue;
+ state = pwr_mng_ctrl_reg & (1 << i) ? "ON" : "OFF";
+ printf("%s:\t\t%s\n", func, state);
+ }
+ return 0;
+ }
+ if (argc < 4)
+ return -1;
+ if (!strcmp(argv[1], "set")) {
+ func = argv[2];
+ state = argv[3];
+ for (i = 0; i < 32; i++) {
+ if (!pwr_mng_bit_func[i])
+ continue;
+ if (!strcmp(func, pwr_mng_bit_func[i]))
+ break;
+ }
+ if (i == 32) {
+ printf("Error: name '%s' not known\n", func);
+ return -1;
+ }
+ val = state[0] != '0';
+ pwr_mng_ctrl_reg |= (val << i);
+ pwr_mng_ctrl_reg &= ~(!val << i);
+ reg_write(POWER_MNG_CTRL_REG, pwr_mng_ctrl_reg);
+ }
+ return 0;
+}
+
+static int do_syno(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ const char *cmd;
+ int ret = 0;
+
+ if (argc < 2)
+ goto usage;
+
+ cmd = argv[1];
+ --argc;
+ ++argv;
+
+ if (!strcmp(cmd, "populate_env"))
+ ret = do_syno_populate(argc, argv);
+ else if (!strcmp(cmd, "clk_gate"))
+ ret = do_syno_clk_gate(argc, argv);
+
+ if (ret != -1)
+ return ret;
+usage:
+ return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+ syno, 5, 1, do_syno,
+ "Synology specific commands",
+ "populate_env - Read vendor data from SPI flash into environment\n"
+ "clk_gate (get|set name 1|0) - Manage clock gating\n"
+);
diff --git a/roms/u-boot/board/Synology/ds414/cmd_syno.h b/roms/u-boot/board/Synology/ds414/cmd_syno.h
new file mode 100644
index 000000000..42e435c80
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds414/cmd_syno.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Commands to deal with Synology specifics.
+ *
+ * Copyright (C) 2021 Phil Sutter <phil@nwl.cc>
+ */
+
+#ifndef _CMD_SYNO_H
+#define _CMD_SYNO_H
+
+#define SYNO_ETHADDR_MAX 4
+#define SYNO_SN_TAG "SN="
+#define SYNO_CHKSUM_TAG "CHK="
+
+int do_syno_populate(int argc, char *const argv[]);
+
+#endif /* _CMD_SYNO_H */
diff --git a/roms/u-boot/board/Synology/ds414/ds414.c b/roms/u-boot/board/Synology/ds414/ds414.c
new file mode 100644
index 000000000..abe6f9eb5
--- /dev/null
+++ b/roms/u-boot/board/Synology/ds414/ds414.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * Copyright (C) 2015 Phil Sutter <phil@nwl.cc>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <miiphy.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+#include <linux/bitops.h>
+#include <linux/mbus.h>
+
+#include "../drivers/ddr/marvell/axp/ddr3_hw_training.h"
+#include "../arch/arm/mach-mvebu/serdes/axp/high_speed_env_spec.h"
+#include "../arch/arm/mach-mvebu/serdes/axp/board_env_spec.h"
+
+#include "cmd_syno.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* GPP and MPP settings as found in mvBoardEnvSpec.c of Synology's U-Boot */
+
+#define DS414_GPP_OUT_VAL_LOW (BIT(25) | BIT(30))
+#define DS414_GPP_OUT_VAL_MID (BIT(10) | BIT(15))
+#define DS414_GPP_OUT_VAL_HIGH (0)
+
+#define DS414_GPP_OUT_POL_LOW (0)
+#define DS414_GPP_OUT_POL_MID (0)
+#define DS414_GPP_OUT_POL_HIGH (0)
+
+#define DS414_GPP_OUT_ENA_LOW (~(BIT(25) | BIT(30)))
+#define DS414_GPP_OUT_ENA_MID (~(BIT(10) | BIT(12) | \
+ BIT(13) | BIT(14) | BIT(15)))
+#define DS414_GPP_OUT_ENA_HIGH (~0)
+
+static const u32 ds414_mpp_control[] = {
+ 0x11111111,
+ 0x22221111,
+ 0x22222222,
+ 0x00000000,
+ 0x11110000,
+ 0x00004000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000
+};
+
+/* DDR3 static MC configuration */
+
+/* 1G_v1 (4x2Gbits) adapted by DS414 */
+MV_DRAM_MC_INIT syno_ddr3_b0_667_1g_v1[MV_MAX_DDR3_STATIC_SIZE] = {
+ {0x00001400, 0x73014A28}, /*DDR SDRAM Configuration Register */
+ {0x00001404, 0x30000800}, /*Dunit Control Low Register */
+ {0x00001408, 0x44148887}, /*DDR SDRAM Timing (Low) Register */
+ {0x0000140C, 0x3AD83FEA}, /*DDR SDRAM Timing (High) Register */
+
+ {0x00001410, 0x14000000}, /*DDR SDRAM Address Control Register */
+
+ {0x00001414, 0x00000000}, /*DDR SDRAM Open Pages Control Register */
+ {0x00001418, 0x00000e00}, /*DDR SDRAM Operation Register */
+ {0x00001420, 0x00000004}, /*DDR SDRAM Extended Mode Register */
+ {0x00001424, 0x0000F3FF}, /*Dunit Control High Register */
+ {0x00001428, 0x000F8830}, /*Dunit Control High Register */
+ {0x0000142C, 0x054C36F4}, /*Dunit Control High Register */
+ {0x0000147C, 0x0000C671},
+
+ {0x000014a0, 0x00000001},
+ {0x000014a8, 0x00000100}, /*2:1 */
+ {0x00020220, 0x00000006},
+
+ {0x00001494, 0x00010000}, /*DDR SDRAM ODT Control (Low) Register */
+ {0x00001498, 0x00000000}, /*DDR SDRAM ODT Control (High) Register */
+ {0x0000149C, 0x00000001}, /*DDR Dunit ODT Control Register */
+
+ {0x000014C0, 0x192424C9}, /* DRAM address and Control Driving Strenght */
+ {0x000014C4, 0x0AAA24C9}, /* DRAM Data and DQS Driving Strenght */
+
+ {0x000200e8, 0x3FFF0E01}, /* DO NOT Modify - Open Mbus Window - 2G - Mbus is required for the training sequence*/
+ {0x00020184, 0x3FFFFFE0}, /* DO NOT Modify - Close fast path Window to - 2G */
+
+ {0x0001504, 0x3FFFFFE1}, /* CS0 Size */
+ {0x000150C, 0x00000000}, /* CS1 Size */
+ {0x0001514, 0x00000000}, /* CS2 Size */
+ {0x000151C, 0x00000000}, /* CS3 Size */
+
+ {0x00001538, 0x00000009}, /*Read Data Sample Delays Register */
+ {0x0000153C, 0x00000009}, /*Read Data Ready Delay Register */
+
+ {0x000015D0, 0x00000650}, /*MR0 */
+ {0x000015D4, 0x00000044}, /*MR1 */
+ {0x000015D8, 0x00000010}, /*MR2 */
+ {0x000015DC, 0x00000000}, /*MR3 */
+
+ {0x000015E4, 0x00203c18}, /*ZQC Configuration Register */
+ {0x000015EC, 0xF800A225}, /*DDR PHY */
+
+ {0x0, 0x0}
+};
+
+MV_DRAM_MODES ds414_ddr_modes[MV_DDR3_MODES_NUMBER] = {
+ {"ds414_1333-667", 0x3, 0x5, 0x0, A0, syno_ddr3_b0_667_1g_v1, NULL},
+};
+
+extern MV_SERDES_CHANGE_M_PHY serdes_change_m_phy[];
+
+MV_BIN_SERDES_CFG ds414_serdes_cfg[] = {
+ { MV_PEX_ROOT_COMPLEX, 0x02011111, 0x00000000,
+ { PEX_BUS_MODE_X4, PEX_BUS_MODE_X1, PEX_BUS_DISABLED,
+ PEX_BUS_DISABLED },
+ 0x0040, serdes_change_m_phy
+ }
+};
+
+MV_DRAM_MODES *ddr3_get_static_ddr_mode(void)
+{
+ return &ds414_ddr_modes[0];
+}
+
+MV_BIN_SERDES_CFG *board_serdes_cfg_get(void)
+{
+ return &ds414_serdes_cfg[0];
+}
+
+u8 board_sat_r_get(u8 dev_num, u8 reg)
+{
+ return 0xf; /* All PEX ports support PCIe Gen2 */
+}
+
+int board_early_init_f(void)
+{
+ int i;
+
+ /* Set GPP Out value */
+ reg_write(GPP_DATA_OUT_REG(0), DS414_GPP_OUT_VAL_LOW);
+ reg_write(GPP_DATA_OUT_REG(1), DS414_GPP_OUT_VAL_MID);
+ reg_write(GPP_DATA_OUT_REG(2), DS414_GPP_OUT_VAL_HIGH);
+
+ /* set GPP polarity */
+ reg_write(GPP_DATA_IN_POL_REG(0), DS414_GPP_OUT_POL_LOW);
+ reg_write(GPP_DATA_IN_POL_REG(1), DS414_GPP_OUT_POL_MID);
+ reg_write(GPP_DATA_IN_POL_REG(2), DS414_GPP_OUT_POL_HIGH);
+
+ /* Set GPP Out Enable */
+ reg_write(GPP_DATA_OUT_EN_REG(0), DS414_GPP_OUT_ENA_LOW);
+ reg_write(GPP_DATA_OUT_EN_REG(1), DS414_GPP_OUT_ENA_MID);
+ reg_write(GPP_DATA_OUT_EN_REG(2), DS414_GPP_OUT_ENA_HIGH);
+
+ for (i = 0; i < ARRAY_SIZE(ds414_mpp_control); i++)
+ reg_write(MPP_CONTROL_REG(i), ds414_mpp_control[i]);
+
+ return 0;
+}
+
+int board_init(void)
+{
+ u32 pwr_mng_ctrl_reg;
+
+ /* Adress of boot parameters */
+ gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
+
+ /* Gate unused clocks
+ *
+ * Note: Disabling unused PCIe lanes will hang PCI bus scan.
+ * Once this is resolved, bits 10-12, 26 and 27 can be
+ * unset here as well.
+ */
+ pwr_mng_ctrl_reg = reg_read(POWER_MNG_CTRL_REG);
+ pwr_mng_ctrl_reg &= ~(BIT(0)); /* Audio */
+ pwr_mng_ctrl_reg &= ~(BIT(1) | BIT(2)); /* GE3, GE2 */
+ pwr_mng_ctrl_reg &= ~(BIT(14) | BIT(15)); /* SATA0 link and core */
+ pwr_mng_ctrl_reg &= ~(BIT(16)); /* LCD */
+ pwr_mng_ctrl_reg &= ~(BIT(17)); /* SDIO */
+ pwr_mng_ctrl_reg &= ~(BIT(19) | BIT(20)); /* USB1 and USB2 */
+ pwr_mng_ctrl_reg &= ~(BIT(29) | BIT(30)); /* SATA1 link and core */
+ reg_write(POWER_MNG_CTRL_REG, pwr_mng_ctrl_reg);
+
+ return 0;
+}
+
+int misc_init_r(void)
+{
+ if (!env_get("ethaddr")) {
+ puts("Incomplete environment, populating from SPI flash\n");
+ do_syno_populate(0, NULL);
+ }
+ return 0;
+}
+
+int checkboard(void)
+{
+ puts("Board: DS414\n");
+
+ return 0;
+}