[PATCH v1 11/12] board: econet: add EN7528 board support

AK Sharma <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <[email protected]>
Add the EcoNet EN7528 board: board glue, the reference/RAM/tclinux and
JCOW414 R3-hook defconfigs, board header and default environment.

Signed-off-by: AK Sharma <[email protected]>
---
 board/econet/en7528/MAINTAINERS         |  13 +++
 board/econet/en7528/Makefile            |   2 +
 board/econet/en7528/board.c             | 110 +++++++++++++++++++++++
 board/econet/en7528/mk_tclinux_uboot.py | 112 ++++++++++++++++++++++++
 board/econet/en7528/tclinux_stub.S      |  65 ++++++++++++++
 configs/en7528_jcow414_r3hook_defconfig |  76 ++++++++++++++++
 configs/en7528_ram_defconfig            |  62 +++++++++++++
 configs/en7528_reference_defconfig      |  40 +++++++++
 defenvs/en7528_jcow414_r3hook_env       |   5 ++
 include/configs/en7528.h                |   9 ++
 10 files changed, 494 insertions(+)
 create mode 100644 board/econet/en7528/MAINTAINERS
 create mode 100644 board/econet/en7528/Makefile
 create mode 100644 board/econet/en7528/board.c
 create mode 100644 board/econet/en7528/mk_tclinux_uboot.py
 create mode 100644 board/econet/en7528/tclinux_stub.S
 create mode 100644 configs/en7528_jcow414_r3hook_defconfig
 create mode 100644 configs/en7528_ram_defconfig
 create mode 100644 configs/en7528_reference_defconfig
 create mode 100644 defenvs/en7528_jcow414_r3hook_env
 create mode 100644 include/configs/en7528.h

diff --git a/board/econet/en7528/MAINTAINERS b/board/econet/en7528/MAINTAINERS
new file mode 100644
index 00000000..69cefe4a
--- /dev/null
+++ b/board/econet/en7528/MAINTAINERS
@@ -0,0 +1,13 @@
+ECONET/AIROHA EN75XX
+M:	AK Sharma <[email protected]>
+S:	Maintained
+F:	arch/mips/mach-en75xx/
+F:	arch/mips/dts/econet,en7528*
+F:	board/econet/en7528/
+F:	configs/en7528_*_defconfig
+F:	defenvs/en7528_jcow414_r3hook_env
+F:	doc/board/econet/en7528.rst
+F:	doc/board/econet/index.rst
+F:	drivers/mtd/nand/spi/en75_bmt.*
+F:	drivers/serial/serial_en75xx.c
+F:	include/configs/en7528.h
diff --git a/board/econet/en7528/Makefile b/board/econet/en7528/Makefile
new file mode 100644
index 00000000..bcca1a9f
--- /dev/null
+++ b/board/econet/en7528/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0+
+obj-y += board.o
diff --git a/board/econet/en7528/board.c b/board/econet/en7528/board.c
new file mode 100644
index 00000000..5708781e
--- /dev/null
+++ b/board/econet/en7528/board.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <dm.h>
+#include <init.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <stdio.h>
+
+#if CONFIG_IS_ENABLED(AIROHA_ETH)
+extern U_BOOT_DRIVER(airoha_eth);
+#endif
+
+#if defined(CONFIG_USB_XHCI_MTK)
+/*
+ * Release the USB host + T-PHY reset domains. The SCU reset controller is not
+ * modelled as a DM reset provider in this port (the ethernet driver pokes it
+ * directly too), so pulse the reset bits by hand. Banks/bits verified against
+ * the kernel clk-en7523 en751221 reset table: USB_HOST_P0 = RST_CTRL1(0x834)
+ * bit22; USB_PHY_P0/P1 = RST_USB(0x0ec) bits 6/7. set = assert/hold in reset,
+ * clear = release.
+ */
+#define EN7528_SCU_RST_CTRL1	0xbfb00834
+#define EN7528_SCU_RST_USB	0xbfb000ec
+#define EN7528_RST_USB_HOST_P0	BIT(22)		/* in RST_CTRL1 */
+#define EN7528_RST_USB_PHY_P0	BIT(6)		/* in RST_USB */
+#define EN7528_RST_USB_PHY_P1	BIT(7)		/* in RST_USB */
+
+/*
+ * USB2 T-PHY port enable. The nop-phy placeholder does nothing, so bring the
+ * two USB2 PHY ports up by hand the way the kernel en7528 USB PHY driver's
+ * .init does: write ACR3_ENABLE to each U2 port block. PHY MMIO base
+ * 0x1fa80000; U2 port bases 0x300 / 0x1300; ACR3 at +0x1c.
+ */
+#define EN7528_USB_PHY_BASE	0xbfa80000
+#define EN7528_USB_PHY_U2_P0	0x300
+#define EN7528_USB_PHY_U2_P1	0x1300
+#define EN7528_USB_PHY_ACR3	0x1c
+#define EN7528_USB_PHY_ACR3_ENABLE	0xc0240000
+
+#define SCU_R(off)	__raw_readl((void __iomem *)(0xbfb00000 + (off)))
+#define SCU_W(off, v)	__raw_writel((v), (void __iomem *)(0xbfb00000 + (off)))
+
+static void en7528_usb_init(void)
+{
+	u32 v;
+
+	/*
+	 * SoC-level USB clock/PLL + XSI mux + reset, reverse-engineered from the
+	 * stock JCOW407 vendor kernel (MU3H driver, routine at 0x56f170). This is
+	 * what the mainline OpenWrt kernel relies on the bootloader to have done,
+	 * and which the bootbase does NOT do in our ramboot path — so the xHCI MAC
+	 * (0x1fb90000) comes up unclocked without it.
+	 */
+	v = SCU_R(0x90);			/* USB clock/PLL enable: bits[30:29]=11 */
+	SCU_W(0x90, (v & 0x9fffffff) | 0x60000000);
+	mdelay(10);				/* PLL settle */
+	v = SCU_R(0xa8); SCU_W(0xa8, v | 0x600);
+	v = SCU_R(0xac); SCU_W(0xac, v & ~0x30000000);
+	v = SCU_R(0xa8); SCU_W(0xa8, v | 0x6000);
+	v = SCU_R(0xa8); SCU_W(0xa8, v & ~0x1800);
+	v = SCU_R(0xac); SCU_W(0xac, v & ~0x08000000);
+	v = SCU_R(0xec); SCU_W(0xec, v & ~0x80000000);	/* RST_USB assert */
+	mdelay(1);
+	v = SCU_R(0xec); SCU_W(0xec, v | 0x80000000);	/* RST_USB deassert */
+	mdelay(6);
+
+	/* legacy per-domain reset release (harmless, kept) */
+	v = SCU_R(0x834); SCU_W(0x834, v & ~EN7528_RST_USB_HOST_P0);
+	v = SCU_R(0xec);  SCU_W(0xec, v & ~(EN7528_RST_USB_PHY_P0 | EN7528_RST_USB_PHY_P1));
+	mdelay(1);
+
+	/* enable both USB2 T-PHY ports (kernel en7528 phy .init) */
+	__raw_writel(EN7528_USB_PHY_ACR3_ENABLE,
+		     (void __iomem *)(EN7528_USB_PHY_BASE +
+				      EN7528_USB_PHY_U2_P0 + EN7528_USB_PHY_ACR3));
+	__raw_writel(EN7528_USB_PHY_ACR3_ENABLE,
+		     (void __iomem *)(EN7528_USB_PHY_BASE +
+				      EN7528_USB_PHY_U2_P1 + EN7528_USB_PHY_ACR3));
+	mdelay(1);
+}
+#endif
+
+int board_init(void)
+{
+	return 0;
+}
+
+int board_late_init(void)
+{
+#if defined(CONFIG_USB_XHCI_MTK)
+	en7528_usb_init();
+#endif
+#if CONFIG_IS_ENABLED(AIROHA_ETH)
+	struct udevice *dev;
+	int ret;
+
+	/*
+	 * Probe the EN751221-family Ethernet parent after the console is up and
+	 * just before initr_net() enumerates UCLASS_ETH devices (mirrors the
+	 * EN7512 reference board).
+	 */
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_DRIVER_GET(airoha_eth), &dev);
+	if (ret && ret != -ENODEV)
+		printf("EN7528 Ethernet probe failed: %d\n", ret);
+#endif
+	return 0;
+}
diff --git a/board/econet/en7528/mk_tclinux_uboot.py b/board/econet/en7528/mk_tclinux_uboot.py
new file mode 100644
index 00000000..d63f46a3
--- /dev/null
+++ b/board/econet/en7528/mk_tclinux_uboot.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python3
+"""
+Package U-Boot as an EcoNet/TrendChip "tclinux" HDR2 image, so the stock
+bootbase will load and run it exactly the way it loads the stock kernel.
+
+The bootbase decompresses a slot's LZMA payload to a fixed 0x80002000 and jumps
+there. U-Boot cannot be linked at that address (MIPS relocation needs the
+relocation delta 64 KiB aligned, and reserve_uboot() force-aligns relocaddr to
+64 KiB, so a TEXT_BASE of 0x80002000 always panics "Mis-aligned relocation").
+So the payload is a small relocator stub followed by a U-Boot linked at
+0x81000000; the stub copies it up and jumps.
+
+  payload = [stub @0x80002000][pad to 0x100][u-boot.bin linked @0x81000000]
+  image   = [HDR2 header 0x100][LZMA(payload)]
+
+Header layout, confirmed against the stock image on a live board
+(0x100 + kernel_len + rootfs_len == total, exactly):
+
+  0x00  "HDR2"
+  0x08  u32 LE  total size, including the 0x100 header
+  0x0c  u32 LE  JAMCRC of everything after the header
+  0x10  version string
+  0x50  u32 LE  kernel length
+  0x54  u32 LE  rootfs length
+  0x100         LZMA kernel, then the rootfs
+
+Usage: mk_tclinux_uboot.py <stub.bin> <u-boot.bin> <out.trx> [version]
+"""
+import struct
+import subprocess
+import sys
+import tempfile
+import zlib
+
+PAYLOAD_OFF = 0x100
+HDR_SIZE = 0x100
+DEFAULT_VERSION = 'UBOOT_EN7528'
+
+
+def lzma_alone(data):
+    """LZMA 'alone' stream, the format the bootbase decompressor expects.
+
+    xz streams and therefore stamps the uncompressed-size field as unknown; the
+    vendor encoder records the real size and some decoders rely on it, so the
+    field is filled in afterwards. Both are valid LZMA-alone.
+    """
+    out = subprocess.run(
+        ['xz', '--format=lzma', '--stdout', '-9', '--lzma1=preset=9,lc=1,lp=2,pb=2'],
+        input=data, check=True, capture_output=True).stdout
+
+    # xz streams, so it stamps the size field "unknown" (all 0xff). The vendor
+    # encoder (lzma_alone) records the real size and some decoders rely on it,
+    # so fill it in. Header is props(1) + dictsize(4) + uncompressed size(8).
+    out = bytearray(out)
+    struct.pack_into('<Q', out, 5, len(data))
+    return bytes(out)
+
+
+def main():
+    if len(sys.argv) < 4:
+        sys.exit(__doc__)
+
+    stub = open(sys.argv[1], 'rb').read()
+    uboot = open(sys.argv[2], 'rb').read()
+    outpath = sys.argv[3]
+    version = sys.argv[4] if len(sys.argv) > 4 else DEFAULT_VERSION
+
+    if len(stub) > PAYLOAD_OFF:
+        sys.exit('stub is %d bytes, must fit in %#x' % (len(stub), PAYLOAD_OFF))
+
+    payload = stub + b'\x00' * (PAYLOAD_OFF - len(stub)) + uboot
+    comp = lzma_alone(payload)
+
+    kernel_len = len(comp)
+    rootfs_len = 0
+    total = HDR_SIZE + kernel_len + rootfs_len
+
+    hdr = bytearray(b'\xff' * HDR_SIZE)
+    hdr[0x00:0x04] = b'HDR2'
+    hdr[0x04:0x08] = bytes([0x00, 0x01, 0x00, 0x00])   # as seen in stock images
+    struct.pack_into('<I', hdr, 0x08, total)
+    # 0x0c filled in below
+    ver = version.encode()[:0x1f] + b'\n'
+    hdr[0x10:0x10 + len(ver)] = ver
+    hdr[0x10 + len(ver):0x30] = b'\x00' * (0x30 - 0x10 - len(ver))
+    hdr[0x30] = 0x0a                                    # as seen in stock images
+    hdr[0x31:0x50] = b'\x00' * (0x50 - 0x31)
+    struct.pack_into('<I', hdr, 0x50, kernel_len)
+    struct.pack_into('<I', hdr, 0x54, rootfs_len)
+    hdr[0x58:0x100] = b'\x00' * (0x100 - 0x58)
+
+    body = comp
+    jamcrc = (zlib.crc32(body) ^ 0xFFFFFFFF) & 0xFFFFFFFF
+    struct.pack_into('<I', hdr, 0x0c, jamcrc)
+
+    image = bytes(hdr) + body
+    open(outpath, 'wb').write(image)
+
+    print('stub        : %d B' % len(stub))
+    print('u-boot      : %d B (linked 0x81000000)' % len(uboot))
+    print('payload     : %d B (entry 0x80002000)' % len(payload))
+    print('lzma        : %d B' % kernel_len)
+    print('version     : %s' % version)
+    print('JAMCRC      : 0x%08x' % jamcrc)
+    print('total       : %d B (0x%x)  [header 0x100 + kernel + rootfs]' % (total, total))
+    print('image       : %s  %d B' % (outpath, len(image)))
+    assert len(image) == total, (len(image), total)
+    print('consistency : 0x100 + %d + %d == %d  OK' % (kernel_len, rootfs_len, total))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/board/econet/en7528/tclinux_stub.S b/board/econet/en7528/tclinux_stub.S
new file mode 100644
index 00000000..4bd032d4
--- /dev/null
+++ b/board/econet/en7528/tclinux_stub.S
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Relocator stub for booting U-Boot as an EcoNet "tclinux" image.
+ *
+ * The vendor bootbase decompresses a firmware image to a fixed 0x80002000 and
+ * jumps there. U-Boot cannot be linked at that address: MIPS relocation
+ * requires (relocaddr - TEXT_BASE) to be 64 KiB aligned, and reserve_uboot()
+ * force-aligns relocaddr to 64 KiB, so a TEXT_BASE of 0x80002000 always
+ * panics with "Mis-aligned relocation".
+ *
+ * So this stub takes the entry instead: it copies the U-Boot image that
+ * follows it up to a 64 KiB aligned address and jumps there.
+ *
+ * The source is read through the cached KSEG0 alias, because the loader wrote
+ * it that way and the bytes may still only exist in cache. The destination is
+ * written through the uncached KSEG1 alias so it is guaranteed to reach DRAM
+ * without depending on this SoC's unreliable cache maintenance (see
+ * airoha_eth / en75_bmt), and nothing has cached that region before.
+ *
+ * Layout of the payload this stub heads:
+ *   +0x0000  this stub
+ *   +0x0100  u-boot.bin, linked at 0x81000000
+ */
+
+#define STUB_ENTRY	0x80002000
+#define PAYLOAD_OFF	0x100
+#define DEST		0x81000000
+/* Fixed generous span; U-Boot is ~0.5 MiB and trailing junk is harmless. */
+#define COPY_LEN	0x00100000
+
+	.set	noreorder
+	.set	noat
+	.globl	_start
+	.text
+_start:
+	/*
+	 * t0 = CACHED source = KSEG0(STUB_ENTRY + PAYLOAD_OFF).
+	 * Whoever loaded us (the bootbase decompressor, or tftpboot when
+	 * testing) wrote this image through the cache, so it must be read back
+	 * the same way - reading the uncached alias returns stale DRAM.
+	 */
+	lui	$t0, 0x8000
+	ori	$t0, $t0, (PAYLOAD_OFF + 0x2000)
+
+	/* t1 = uncached destination = KSEG1(DEST) */
+	lui	$t1, 0xa100
+
+	/* t2 = byte count */
+	lui	$t2, (COPY_LEN >> 16)
+	ori	$t2, $t2, (COPY_LEN & 0xffff)
+
+1:
+	lw	$t3, 0($t0)
+	sw	$t3, 0($t1)
+	addiu	$t0, $t0, 4
+	addiu	$t1, $t1, 4
+	addiu	$t2, $t2, -4
+	bgtz	$t2, 1b
+	nop
+
+	/* Enter U-Boot at its link address (cached KSEG0). */
+	lui	$t9, (DEST >> 16)
+	ori	$t9, $t9, (DEST & 0xffff)
+	jr	$t9
+	nop
diff --git a/configs/en7528_jcow414_r3hook_defconfig b/configs/en7528_jcow414_r3hook_defconfig
new file mode 100644
index 00000000..f847dc42
--- /dev/null
+++ b/configs/en7528_jcow414_r3hook_defconfig
@@ -0,0 +1,76 @@
+CONFIG_MIPS=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_SYS_MALLOC_LEN=0x400000
+CONFIG_SYS_MALLOC_F_LEN=0x10000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0xc0000
+CONFIG_ENV_OFFSET_REDUND=0xe0000
+CONFIG_DEFAULT_DEVICE_TREE="econet,en7528-ram"
+CONFIG_SYS_LOAD_ADDR=0x82000000
+CONFIG_ARCH_EN75XX=y
+CONFIG_BUILD_TARGET="u-boot.bin"
+CONFIG_BOARD_EN7528_R3HOOK=y
+CONFIG_TEXT_BASE=0x81E00000
+CONFIG_SYS_MIPS_TIMER_FREQ=200000000
+# CONFIG_MIPS_CACHE_SETUP is not set
+# CONFIG_MIPS_CACHE_DISABLE is not set
+# CONFIG_RESTORE_EXCEPTION_VECTOR_BASE is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SYS_BOOTM_LEN=0x2000000
+CONFIG_BOOTDELAY=2
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="EN7528> "
+CONFIG_SYS_MAXARGS=16
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_MTD=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_ENV_IS_NOWHERE is not set
+CONFIG_ENV_IS_IN_MTD=y
+CONFIG_ENV_MTD_DEV="spi-nand0"
+CONFIG_ENV_REDUNDANT=y
+CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
+CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/en7528_jcow414_r3hook_env"
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_CMD_NET=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_MII=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM_MDIO=y
+CONFIG_PHY=y
+CONFIG_NOP_PHY=y
+CONFIG_CLK=y
+CONFIG_DMA=y
+CONFIG_AIROHA_ETH=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MTK=y
+CONFIG_USB_STORAGE=y
+CONFIG_CMD_USB=y
+CONFIG_BLK=y
+CONFIG_PARTITIONS=y
+CONFIG_DOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_FS_FAT=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_AIROHA_SNFI_SPI=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_CMD_DM=y
+CONFIG_MTD_EN75_BMT=y
+CONFIG_LZMA=y
diff --git a/configs/en7528_ram_defconfig b/configs/en7528_ram_defconfig
new file mode 100644
index 00000000..55ec279c
--- /dev/null
+++ b/configs/en7528_ram_defconfig
@@ -0,0 +1,62 @@
+CONFIG_MIPS=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_SYS_MALLOC_LEN=0x100000
+CONFIG_SYS_MALLOC_F_LEN=0x10000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+CONFIG_DEFAULT_DEVICE_TREE="econet,en7528-ram"
+CONFIG_SYS_LOAD_ADDR=0x81800000
+CONFIG_ARCH_EN75XX=y
+CONFIG_BUILD_TARGET="u-boot.bin"
+CONFIG_BOARD_EN7528_RAM=y
+CONFIG_SYS_MIPS_TIMER_FREQ=200000000
+# CONFIG_MIPS_CACHE_SETUP is not set
+# CONFIG_MIPS_CACHE_DISABLE is not set
+# CONFIG_RESTORE_EXCEPTION_VECTOR_BASE is not set
+CONFIG_BOOTDELAY=3
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="EN7528> "
+CONFIG_SYS_MAXARGS=16
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_ENV_IS_NOWHERE=y
+CONFIG_BOARD_LATE_INIT=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_CMD_NET=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_MII=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM_MDIO=y
+CONFIG_PHY=y
+CONFIG_NOP_PHY=y
+CONFIG_CLK=y
+CONFIG_DMA=y
+CONFIG_AIROHA_ETH=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MTK=y
+CONFIG_USB_STORAGE=y
+CONFIG_CMD_USB=y
+CONFIG_BLK=y
+CONFIG_PARTITIONS=y
+CONFIG_DOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_FS_FAT=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_AIROHA_SNFI_SPI=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_DM=y
+CONFIG_MTD_EN75_BMT=y
+CONFIG_LZMA=y
diff --git a/configs/en7528_reference_defconfig b/configs/en7528_reference_defconfig
new file mode 100644
index 00000000..6811c7e3
--- /dev/null
+++ b/configs/en7528_reference_defconfig
@@ -0,0 +1,40 @@
+CONFIG_MIPS=y
+CONFIG_SYS_LITTLE_ENDIAN=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_SYS_MALLOC_LEN=0x100000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+CONFIG_DEFAULT_DEVICE_TREE="econet,en7528-reference"
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x10000
+CONFIG_SPL_SERIAL=y
+CONFIG_TPL_SYS_MALLOC_F_LEN=0x1000
+CONFIG_SPL_BSS_START_ADDR=0x80080000
+CONFIG_SPL_BSS_MAX_SIZE=0x10000
+CONFIG_SYS_LOAD_ADDR=0x81800000
+CONFIG_SPL=y
+CONFIG_ARCH_EN75XX=y
+CONFIG_BUILD_TARGET="u-boot.bin"
+CONFIG_BOARD_EN7528_REFERENCE=y
+CONFIG_SYS_MIPS_TIMER_FREQ=150000000
+CONFIG_MIPS_CACHE_SETUP=y
+CONFIG_MIPS_CACHE_DISABLE=y
+CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_FIT=y
+CONFIG_BOOTDELAY=3
+CONFIG_DISPLAY_CPUINFO=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SPL_MAX_SIZE=0x30000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_TPL=y
+# CONFIG_TPL_FRAMEWORK is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="EN7528> "
+CONFIG_SYS_MAXARGS=8
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_ENV_IS_NOWHERE=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_SPL_DM=y
diff --git a/defenvs/en7528_jcow414_r3hook_env b/defenvs/en7528_jcow414_r3hook_env
new file mode 100644
index 00000000..4bc9e278
--- /dev/null
+++ b/defenvs/en7528_jcow414_r3hook_env
@@ -0,0 +1,5 @@
+ipaddr=192.168.1.111
+serverip=192.168.1.166
+loadaddr=0x82000000
+bootdelay=2
+bootcmd=mtd read spi-nand0 ${loadaddr} 0x100000 0x1000000; bootm ${loadaddr}
diff --git a/include/configs/en7528.h b/include/configs/en7528.h
new file mode 100644
index 00000000..b8dc2410
--- /dev/null
+++ b/include/configs/en7528.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef __CONFIG_EN7528_H
+#define __CONFIG_EN7528_H
+
+#define CFG_SYS_SDRAM_BASE	0x80000000
+/* Above FIT scratch (0x82000000) and kernel load (0x80020000, up to ~32 MiB). */
+#define CFG_SYS_INIT_SP_OFFSET	0x04000000
+
+#endif
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.