All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support
@ 2018-08-06 15:11 Stefan Roese
  2018-08-06 15:11 ` [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h Stefan Roese
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Stefan Roese @ 2018-08-06 15:11 UTC (permalink / raw)
  To: u-boot

This patch adds basic support for the MediaTek MT7620/88 SoCs. Parts of
the code is copied from the MediaTek GitHub repository:

https://github.com/MediaTek-Labs/linkit-smart-uboot.git

Support for the LinkIt Smart 7688 module and the Gardena Smart Gateway
both based on the MT7688 will be added in further patches.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
 arch/mips/Kconfig                     |  15 ++
 arch/mips/Makefile                    |   1 +
 arch/mips/mach-mt7620/Kconfig         | 130 ++++++++++
 arch/mips/mach-mt7620/Makefile        |   8 +
 arch/mips/mach-mt7620/cpu.c           |  66 +++++
 arch/mips/mach-mt7620/ddr_calibrate.c | 331 +++++++++++++++++++++++++
 arch/mips/mach-mt7620/lowlevel_init.S | 337 ++++++++++++++++++++++++++
 arch/mips/mach-mt7620/mt76xx.h        |  39 +++
 8 files changed, 927 insertions(+)
 create mode 100644 arch/mips/mach-mt7620/Kconfig
 create mode 100644 arch/mips/mach-mt7620/Makefile
 create mode 100644 arch/mips/mach-mt7620/cpu.c
 create mode 100644 arch/mips/mach-mt7620/ddr_calibrate.c
 create mode 100644 arch/mips/mach-mt7620/lowlevel_init.S
 create mode 100644 arch/mips/mach-mt7620/mt76xx.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 31b622ff51..af791c320d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -87,6 +87,20 @@ config ARCH_BMIPS
 	select SYSRESET
 	imply CMD_DM
 
+config ARCH_MT7620
+	bool "Support MT7620/7688 SoCs"
+	select SUPPORTS_LITTLE_ENDIAN
+	select SUPPORTS_CPU_MIPS32_R1
+	select SUPPORTS_CPU_MIPS32_R2
+	select ROM_EXCEPTION_VECTORS
+	select MIPS_TUNE_4KC
+	select OF_CONTROL
+	select DM
+	select DM_SERIAL
+	select DM_SPI
+	select DM_SPI_FLASH
+	select DISPLAY_CPUINFO
+
 config MACH_PIC32
 	bool "Support Microchip PIC32"
 	select DM
@@ -141,6 +155,7 @@ source "board/qemu-mips/Kconfig"
 source "arch/mips/mach-ath79/Kconfig"
 source "arch/mips/mach-bmips/Kconfig"
 source "arch/mips/mach-pic32/Kconfig"
+source "arch/mips/mach-mt7620/Kconfig"
 
 if MIPS
 
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 5deec9a202..cc8ea5d7d4 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -15,6 +15,7 @@ machine-$(CONFIG_SOC_AU1X00) += au1x00
 machine-$(CONFIG_ARCH_ATH79) += ath79
 machine-$(CONFIG_ARCH_BMIPS) += bmips
 machine-$(CONFIG_MACH_PIC32) += pic32
+machine-$(CONFIG_ARCH_MT7620) += mt7620
 
 machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
 libs-y += $(machdirs)
diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig
new file mode 100644
index 0000000000..40e15b8a31
--- /dev/null
+++ b/arch/mips/mach-mt7620/Kconfig
@@ -0,0 +1,130 @@
+menu "MediaTek MIPS platforms"
+	depends on ARCH_MT7620
+
+config SYS_MALLOC_F_LEN
+	default 0x1000
+
+config SYS_SOC
+	default "mt7620" if SOC_MT7620
+
+choice
+	prompt "MediaTek MIPS SoC select"
+
+config SOC_MT7620
+	bool "MT7620/8"
+	select MIPS_L1_CACHE_SHIFT_5
+	help
+	  This supports MediaTek MIPS MT7620 family.
+
+endchoice
+
+choice
+	prompt "Board select"
+
+config BOARD_LINKIT_SMART_7688
+	bool "LinkIt Smart 7688"
+	depends on SOC_MT7620
+	select SUPPORTS_BOOT_RAM
+	help
+	  Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
+	  and 32 MiB of flash (SPI).
+	  Between its different peripherals there's an integrated switch with 4
+	  ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
+	  a MT7688 (PCIe).
+
+endchoice
+
+choice
+	prompt "Boot mode"
+
+config BOOT_RAM
+	bool "RAM boot"
+	depends on SUPPORTS_BOOT_RAM
+	select SKIP_LOWLEVEL_INIT
+	help
+	  This builds an image that is linked to a RAM address. It can be used
+	  for booting from CFE via TFTP using an ELF image, but it can also be
+	  booted from RAM by other bootloaders using a BIN image.
+
+config BOOT_ROM
+	bool "ROM boot"
+	depends on SUPPORTS_BOOT_RAM
+	help
+	  This builds an image that is linked to a ROM address. It can be
+	  used as main bootloader image which is programmed onto the onboard
+	  flash storage (SPI NOR).
+
+endchoice
+
+choice
+	prompt "DDR2 size"
+
+config ONBOARD_DDR2_SIZE_256MBIT
+	bool "256MBit (32MByte) total size"
+	depends on BOOT_ROM
+	help
+	  Use 256MBit (32MByte) of DDR total size
+
+config ONBOARD_DDR2_SIZE_512MBIT
+	bool "512MBit (64MByte) total size"
+	depends on BOOT_ROM
+	help
+	  Use 512MBit (64MByte) of DDR total size
+
+config ONBOARD_DDR2_SIZE_1024MBIT
+	bool "1024MBit (128MByte) total size"
+	depends on BOOT_ROM
+	help
+	  Use 1024MBit (128MByte) of DDR total size
+
+config ONBOARD_DDR2_SIZE_2048MBIT
+	bool "2048MBit (256MByte) total size"
+	depends on BOOT_ROM
+	help
+	  Use 2048MBit (256MByte) of DDR total size
+
+endchoice
+
+choice
+	prompt "DDR2 chip width"
+
+config ONBOARD_DDR2_CHIP_WIDTH_8BIT
+	bool "8bit DDR chip width"
+	depends on BOOT_ROM
+	help
+	  Use DDR chips with 8bit width
+
+config ONBOARD_DDR2_CHIP_WIDTH_16BIT
+	bool "16bit DDR chip width"
+	depends on BOOT_ROM
+	help
+	  Use DDR chips with 16bit width
+
+endchoice
+
+choice
+	prompt "DDR2 bus width"
+
+config ONBOARD_DDR2_BUS_WIDTH_16BIT
+	bool "16bit DDR bus width"
+	depends on BOOT_ROM
+	help
+	  Use 16bit DDR bus width
+
+config ONBOARD_DDR2_BUS_WIDTH_32BIT
+	bool "32bit DDR bus width"
+	depends on BOOT_ROM
+	help
+	  Use 32bit DDR bus width
+
+endchoice
+
+config SUPPORTS_BOOT_RAM
+	bool
+
+config SKIP_LOWLEVEL_INIT
+	bool
+
+source "board/seeed/linkit-smart-7688/Kconfig"
+
+endmenu
diff --git a/arch/mips/mach-mt7620/Makefile b/arch/mips/mach-mt7620/Makefile
new file mode 100644
index 0000000000..1f3e65e8a5
--- /dev/null
+++ b/arch/mips/mach-mt7620/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += cpu.o
+
+ifndef CONFIG_SKIP_LOWLEVEL_INIT
+obj-y += ddr_calibrate.o
+obj-y += lowlevel_init.o
+endif
diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c
new file mode 100644
index 0000000000..0b22956499
--- /dev/null
+++ b/arch/mips/mach-mt7620/cpu.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include "mt76xx.h"
+
+#define STR_LEN			6
+
+#ifdef CONFIG_BOOT_ROM
+int mach_cpu_init(void)
+{
+	void (*ptr)(void);
+
+	/*
+	 * DDR calibration routine needs to be called very early. This
+	 * function also configures the clock to run at full speed.
+	 */
+	ptr = (void *)CKSEG0ADDR(ddr_calibrate);
+	(*ptr)();
+
+	return 0;
+}
+#endif
+
+int print_cpuinfo(void)
+{
+	static const char * const boot_str[] = { "PLL (3-Byte SPI Addr)",
+						 "PLL (4-Byte SPI Addr)",
+						 "XTAL (3-Byte SPI Addr)",
+						 "XTAL (4-Byte SPI Addr)" };
+	char *chr = (char *)MT76XX_CHIPID;
+	char buf[STR_LEN + 1];
+	u32 val;
+
+	snprintf(buf, STR_LEN + 1, "%s", chr);
+	val = readl((void *)MT76XX_CHIP_REV_ID);
+	printf("CPU:   %-*s Rev %ld.%ld - ", STR_LEN, buf,
+	       (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0));
+
+	val = (readl((void *)MT76XX_SYSCFG0) & GENMASK(3, 1)) >> 1;
+	printf("Boot from %s\n", boot_str[val]);
+
+	return 0;
+}
+
+void _machine_restart(void)
+{
+	writel(0x01, (void *)MT76XX_RSTCTL);
+
+	while (1)
+		;	/* NOP */
+}
+
+int dram_init(void)
+{
+	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
+
+	return 0;
+}
diff --git a/arch/mips/mach-mt7620/ddr_calibrate.c b/arch/mips/mach-mt7620/ddr_calibrate.c
new file mode 100644
index 0000000000..6fd136674e
--- /dev/null
+++ b/arch/mips/mach-mt7620/ddr_calibrate.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ *
+ * This code is mostly based on the code extracted from this MediaTek
+ * github repository:
+ *
+ * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
+ *
+ * I was not able to find a specific license or other developers
+ * copyrights here, so I can't add them here.
+ *
+ * Most functions in this file are copied from the MediaTek U-Boot
+ * repository. Without any documentation, it was impossible to really
+ * implement this differently. So its mostly a cleaned-up version of
+ * the original code, with only support for the MT7628 / MT7688 SoC.
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <asm/cacheops.h>
+#include <asm/io.h>
+#include "mt76xx.h"
+
+#define NUM_OF_CACHELINE	64
+#define MIN_START		6
+#define MIN_FINE_START		0xf
+#define MAX_START		7
+#define MAX_FINE_START		0x0
+
+#define CPU_FRAC_DIV		1
+
+#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
+#define DRAM_BUTTOM 0x02000000
+#endif
+#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
+#define DRAM_BUTTOM 0x04000000
+#endif
+#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
+#define DRAM_BUTTOM 0x08000000
+#endif
+#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
+#define DRAM_BUTTOM 0x10000000
+#endif
+
+static inline void cal_memcpy(void *src, void *dst, u32 size)
+{
+	u8 *psrc = (u8 *)src;
+	u8 *pdst = (u8 *)dst;
+	int i;
+
+	for (i = 0; i < size; i++, psrc++, pdst++)
+		*pdst = *psrc;
+}
+
+static inline void cal_memset(void *src, u8 pat, u32 size)
+{
+	u8 *psrc = (u8 *)src;
+	int i;
+
+	for (i = 0; i < size; i++, psrc++)
+		*psrc = pat;
+}
+
+#define pref_op(hint, addr)						\
+	__asm__ __volatile__(						\
+		".set	push\n"						\
+		".set	noreorder\n"					\
+		"pref	%0, %1\n"					\
+		".set	pop\n"						\
+		:							\
+		: "i" (hint), "R" (*(u8 *)(addr)))
+
+#define cache_op(op, addr)						\
+	__asm__ __volatile__(						\
+		".set	push\n"						\
+		".set	noreorder\n"					\
+		".set	mips3\n"					\
+		"cache	%0, %1\n"					\
+		".set	pop\n"						\
+		:							\
+		: "i" (op), "R" (*(u8 *)(addr)))
+
+static inline void cal_invalidate_dcache_range(u32 start_addr, u32 stop)
+{
+	u32 lsize = CONFIG_SYS_CACHELINE_SIZE;
+	u32 addr = start_addr & ~(lsize - 1);
+	u32 aend = (stop - 1) & ~(lsize - 1);
+
+	while (1) {
+		cache_op(HIT_INVALIDATE_D, addr);
+		if (addr == aend)
+			break;
+		addr += lsize;
+	}
+}
+
+static inline void cal_patgen(u32 start_addr, u32 size, u32 bias)
+{
+	u32 *addr = (u32 *)start_addr;
+	int i;
+
+	for (i = 0; i < size; i++)
+		addr[i] = start_addr + i + bias;
+}
+
+static inline int test_loop(int k, int dqs, u32 test_dqs, u32 *coarse_dqs,
+			    u32 offs, u32 pat, u32 val)
+{
+	u32 nc_addr;
+	u32 *c_addr;
+	int i;
+
+	for (nc_addr = 0xa0000000;
+	     nc_addr < (0xa0000000 + DRAM_BUTTOM - NUM_OF_CACHELINE * 32);
+	     nc_addr += (DRAM_BUTTOM >> 6) + offs) {
+		writel(0x00007474, MT76XX_MEMCTRL_BASE + 0x64);
+		wmb();		/* Make sure store if finished */
+
+		c_addr = (u32 *)(nc_addr & 0xdfffffff);
+		cal_memset(((u8 *)c_addr), 0x1F, NUM_OF_CACHELINE * 32);
+		cal_patgen(nc_addr, NUM_OF_CACHELINE * 8, pat);
+
+		if (dqs > 0)
+			writel(0x00000074 |
+			       (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 12) |
+			       (((k == 0) ? val : test_dqs) << 8),
+			       MT76XX_MEMCTRL_BASE + 0x64);
+		else
+			writel(0x00007400 |
+			       (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 4) |
+			       (((k == 0) ? val : test_dqs) << 0),
+			       MT76XX_MEMCTRL_BASE + 0x64);
+		wmb();		/* Make sure store if finished */
+
+		cal_invalidate_dcache_range((u32)c_addr,
+					    (u32)c_addr +
+					    NUM_OF_CACHELINE * 32);
+		wmb();		/* Make sure store if finished */
+
+		for (i = 0; i < NUM_OF_CACHELINE * 8; i++) {
+			if (i % 8 == 0)
+				pref_op(0, &c_addr[i]);
+		}
+
+		for (i = 0; i < NUM_OF_CACHELINE * 8; i++) {
+			if (c_addr[i] != nc_addr + i + pat)
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+void ddr_calibrate(void)
+{
+	u32 min_coarse_dqs[2];
+	u32 max_coarse_dqs[2];
+	u32 min_fine_dqs[2];
+	u32 max_fine_dqs[2];
+	u32 coarse_dqs[2];
+	u32 fine_dqs[2];
+	int reg = 0, ddr_cfg2_reg;
+	int flag;
+	int i, k;
+	int dqs = 0;
+	u32 min_coarse_dqs_bnd, min_fine_dqs_bnd, coarse_dqs_dll, fine_dqs_dll;
+	u32 val;
+	u32 fdiv = 0, frac = 0;
+
+	/* Setup clock to run@full speed */
+	val = readl(MT76XX_DYN_CFG0_REG);
+	fdiv = (u32)((val >> 8) & 0x0F);
+	if (CPU_FRAC_DIV < 1 || CPU_FRAC_DIV > 10)
+		frac = val & 0x0f;
+	else
+		frac = CPU_FRAC_DIV;
+
+	while (frac < fdiv) {
+		val = readl(MT76XX_DYN_CFG0_REG);
+		fdiv = (val >> 8) & 0x0f;
+		fdiv--;
+		val &= ~(0x0f << 8);
+		val |= (fdiv << 8);
+		writel(val, MT76XX_DYN_CFG0_REG);
+		udelay(500);
+		val = readl(MT76XX_DYN_CFG0_REG);
+		fdiv = (val >> 8) & 0x0f;
+	}
+
+	clrbits_le32(MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
+	ddr_cfg2_reg = readl(MT76XX_MEMCTRL_BASE + 0x48);
+	clrbits_le32(MT76XX_MEMCTRL_BASE + 0x48, (0x3 << 28) | (0x3 << 26));
+
+	min_coarse_dqs[0] = MIN_START;
+	min_coarse_dqs[1] = MIN_START;
+	min_fine_dqs[0] = MIN_FINE_START;
+	min_fine_dqs[1] = MIN_FINE_START;
+	max_coarse_dqs[0] = MAX_START;
+	max_coarse_dqs[1] = MAX_START;
+	max_fine_dqs[0] = MAX_FINE_START;
+	max_fine_dqs[1] = MAX_FINE_START;
+	dqs = 0;
+
+	/* Add by KP, DQS MIN boundary */
+	reg = readl(MT76XX_MEMCTRL_BASE + 0x20);
+	coarse_dqs_dll = (reg & 0xf00) >> 8;
+	fine_dqs_dll = (reg & 0xf0) >> 4;
+	if (coarse_dqs_dll <= 8)
+		min_coarse_dqs_bnd = 8 - coarse_dqs_dll;
+	else
+		min_coarse_dqs_bnd = 0;
+
+	if (fine_dqs_dll <= 8)
+		min_fine_dqs_bnd = 8 - fine_dqs_dll;
+	else
+		min_fine_dqs_bnd = 0;
+	/* DQS MIN boundary */
+
+DQS_CAL:
+
+	for (k = 0; k < 2; k++) {
+		u32 test_dqs;
+
+		if (k == 0)
+			test_dqs = MAX_START;
+		else
+			test_dqs = MAX_FINE_START;
+
+		do {
+			flag = test_loop(k, dqs, test_dqs, max_coarse_dqs,
+					 0x400, 0x3, 0xf);
+			if (flag == -1)
+				break;
+
+			test_dqs++;
+		} while (test_dqs <= 0xf);
+
+		if (k == 0) {
+			max_coarse_dqs[dqs] = test_dqs;
+		} else {
+			test_dqs--;
+
+			if (test_dqs == MAX_FINE_START - 1) {
+				max_coarse_dqs[dqs]--;
+				max_fine_dqs[dqs] = 0xf;
+			} else {
+				max_fine_dqs[dqs] = test_dqs;
+			}
+		}
+	}
+
+	for (k = 0; k < 2; k++) {
+		u32 test_dqs;
+
+		if (k == 0)
+			test_dqs = MIN_START;
+		else
+			test_dqs = MIN_FINE_START;
+
+		do {
+			flag = test_loop(k, dqs, test_dqs, min_coarse_dqs,
+					 0x480, 0x1, 0x0);
+			if (k == 0) {
+				if (flag == -1 ||
+				    test_dqs == min_coarse_dqs_bnd)
+					break;
+
+				test_dqs--;
+
+				if (test_dqs < min_coarse_dqs_bnd)
+					break;
+			} else {
+				if (flag == -1) {
+					test_dqs++;
+					break;
+				} else if (test_dqs == min_fine_dqs_bnd) {
+					break;
+				}
+
+				test_dqs--;
+
+				if (test_dqs < min_fine_dqs_bnd)
+					break;
+			}
+		} while (test_dqs >= 0);
+
+		if (k == 0) {
+			min_coarse_dqs[dqs] = test_dqs;
+		} else {
+			if (test_dqs == MIN_FINE_START + 1) {
+				min_coarse_dqs[dqs]++;
+				min_fine_dqs[dqs] = 0x0;
+			} else {
+				min_fine_dqs[dqs] = test_dqs;
+			}
+		}
+	}
+
+	if (dqs == 0) {
+		dqs = 1;
+		goto DQS_CAL;
+	}
+
+	for (i = 0; i < 2; i++) {
+		u32 temp;
+
+		coarse_dqs[i] = (max_coarse_dqs[i] + min_coarse_dqs[i]) >> 1;
+		temp =
+		    (((max_coarse_dqs[i] + min_coarse_dqs[i]) % 2) * 4) +
+		    ((max_fine_dqs[i] + min_fine_dqs[i]) >> 1);
+		if (temp >= 0x10) {
+			coarse_dqs[i]++;
+			fine_dqs[i] = (temp - 0x10) + 0x8;
+		} else {
+			fine_dqs[i] = temp;
+		}
+	}
+	reg = (coarse_dqs[1] << 12) | (fine_dqs[1] << 8) |
+		(coarse_dqs[0] << 4) | fine_dqs[0];
+
+	clrbits_le32(MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
+	writel(reg, MT76XX_MEMCTRL_BASE + 0x64);
+	writel(ddr_cfg2_reg, MT76XX_MEMCTRL_BASE + 0x48);
+	setbits_le32(MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
+
+	for (i = 0; i < 2; i++)
+		debug("[%02X%02X%02X%02X]", min_coarse_dqs[i],
+		      min_fine_dqs[i], max_coarse_dqs[i], max_fine_dqs[i]);
+	debug("\nDDR Calibration DQS reg = %08X\n", reg);
+}
diff --git a/arch/mips/mach-mt7620/lowlevel_init.S b/arch/mips/mach-mt7620/lowlevel_init.S
new file mode 100644
index 0000000000..92b2fcd2bb
--- /dev/null
+++ b/arch/mips/mach-mt7620/lowlevel_init.S
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (c) 2018 Stefan Roese <sr@denx.de>
+ *
+ * This code is mostly based on the code extracted from this MediaTek
+ * github repository:
+ *
+ * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
+ *
+ * I was not able to find a specific license or other developers
+ * copyrights here, so I can't add them here.
+ */
+
+#include <config.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm.h>
+#include "mt76xx.h"
+
+#ifndef BIT
+#define BIT(nr)			(1 << (nr))
+#endif
+
+#define DELAY_USEC(us)		((us) / 100)
+
+#define DDR_CFG1_CHIP_WIDTH_MASK (0x3 << 16)
+#define DDR_CFG1_BUS_WIDTH_MASK	(0x3 << 12)
+
+#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
+#define DDR_CFG1_SIZE_VAL	0x222e2323
+#define DDR_CFG4_SIZE_VAL	7
+#endif
+#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
+#define DDR_CFG1_SIZE_VAL	0x22322323
+#define DDR_CFG4_SIZE_VAL	9
+#endif
+#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
+#define DDR_CFG1_SIZE_VAL	0x22362323
+#define DDR_CFG4_SIZE_VAL	9
+#endif
+#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
+#define DDR_CFG1_SIZE_VAL	0x223a2323
+#define DDR_CFG4_SIZE_VAL	9
+#endif
+
+#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_8BIT)
+#define DDR_CFG1_CHIP_WIDTH_VAL	(0x1 << 16)
+#endif
+#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT)
+#define DDR_CFG1_CHIP_WIDTH_VAL	(0x2 << 16)
+#endif
+
+#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_16BIT)
+#define DDR_CFG1_BUS_WIDTH_VAL	(0x2 << 12)
+#endif
+#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_32BIT)
+#define DDR_CFG1_BUS_WIDTH_VAL	(0x3 << 12)
+#endif
+
+LEAF(lowlevel_init)
+	/* polling CPLL is ready */
+	li	t1, DELAY_USEC(1000000)
+	la	t5, MT76XX_ROM_STATUS_REG
+1:
+	lw	t2, 0(t5)
+	andi	t2, t2, 0x1
+	bnez	t2, CPLL_READY
+	subu	t1, t1, 1
+	bgtz	t1, 1b
+	nop
+	la      t0, MT76XX_CLKCFG0_REG
+	lw      t3, 0(t0)
+	ori	t3, t3, 0x1
+	sw	t3, 0(t0)
+	j	CPLL_DONE
+	nop
+CPLL_READY:
+	la	t0, MT76XX_CLKCFG0_REG
+	lw	t1, 0(t0)
+	li	t2, ~0x0c
+	and	t1, t1, t2
+	ori	t1, t1, 0xc
+	sw	t1, 0(t0)
+	la	t0, MT76XX_DYN_CFG0_REG
+	lw	t3, 0(t0)
+	li	t5, ~((0x0f << 8) | (0x0f << 0))
+	and	t3, t3, t5
+	li	t5, (10 << 8) | (1 << 0)
+	or	t3, t3, t5
+	sw	t3, 0(t0)
+	la	t0, MT76XX_CLKCFG0_REG
+	lw	t3, 0(t0)
+	li	t4, ~0x0F
+	and     t3, t3, t4
+	ori	t3, t3, 0xc
+	sw	t3, 0(t0)
+	lw	t3, 0(t0)
+	ori	t3, t3, 0x08
+	sw	t3, 0(t0)
+
+CPLL_DONE:
+	/*
+	 * SDR and DDR initialization: delay 200us
+	 */
+	li	t0, DELAY_USEC(200 + 40)
+	li	t1, 0x1
+1:
+	sub	t0, t0, t1
+	bnez	t0, 1b
+	nop
+
+	/* set DRAM IO PAD for MT7628IC */
+	/* DDR LDO Enable  */
+	li	t1, MT76XX_RGCTRL_BASE+0x100
+	lw	t4, 0(t1)
+	li	t2, BIT(31)
+	or	t4, t4, t2
+	sw	t4, 0(t1)
+	li	t1, MT76XX_RGCTRL_BASE+0x10c
+	lw	t4, 0(t1)
+	j	LDO_1P8V
+	nop
+LDO_1P8V:
+	li	t2, ~BIT(6)
+	and	t4, t4, t2
+	li	t1, MT76XX_RGCTRL_BASE+0x10c
+	sw	t4, 0(t1)
+	j	DDRLDO_SOFT_START
+LDO_2P5V:
+	/* suppose external DDR1 LDO 2.5V */
+	li	t2, BIT(6)
+	or	t4, t4, t2
+	li	t1, MT76XX_RGCTRL_BASE+0x10c
+	sw	t4, 0(t1)
+
+DDRLDO_SOFT_START:
+	li	t1, MT76XX_RGCTRL_BASE+0x10c
+	lw	t2, 0(t1)
+	li	t3, BIT(16)
+	or	t2, t2, t3
+	sw	t2, 0(t1)
+	li	t3, DELAY_USEC(250*50)
+LDO_DELAY:
+	subu	t3, t3, 1
+	bnez	t3, LDO_DELAY
+	nop
+
+	li	t1, MT76XX_RGCTRL_BASE+0x10c
+	lw	t2, 0(t1)
+	li	t3, BIT(18)
+	or	t2, t2, t3
+	sw	t2, 0(t1)
+
+SET_RG_BUCK_FPWM:
+	li	t1, MT76XX_RGCTRL_BASE+0x104
+	lw	t2, 0(t1)
+	ori	t2, t2, BIT(10)
+	sw	t2, 0(t1)
+
+DDR_PAD_CFG:
+	/* clean CLK PAD */
+	li	t1, MT76XX_RGCTRL_BASE+0x704
+	lw	t2, 0(t1)
+	li	t8, 0xfffff0f0
+	and	t2, t2, t8
+	/* clean CMD PAD */
+	li	t1, MT76XX_RGCTRL_BASE+0x70c
+	lw	t3, 0(t1)
+	li	t8, 0xfffff0f0
+	and	t3, t3, t8
+	/* clean DQ IPAD */
+	li	t1, MT76XX_RGCTRL_BASE+0x710
+	lw	t4, 0(t1)
+	li	t8, 0xfffff8ff
+	and	t4, t4, t8
+	/* clean DQ OPAD */
+	li	t1, MT76XX_RGCTRL_BASE+0x714
+	lw	t5, 0(t1)
+	li	t8, 0xfffff0f0
+	and	t5, t5, t8
+	/* clean DQS IPAD */
+	li	t1, MT76XX_RGCTRL_BASE+0x718
+	lw	t6, 0(t1)
+	li	t8, 0xfffff8ff
+	and	t6, t6, t8
+	/* clean DQS OPAD */
+	li	t1, MT76XX_RGCTRL_BASE+0x71c
+	lw	t7, 0(t1)
+	li	t8, 0xfffff0f0
+	and	t7, t7, t8
+
+	li	t1, MT76XX_SYSCTL_BASE+0xC
+	lw	t9, 0(t1)
+	srl	t9, t9, 16
+	andi	t9, t9, 0x1
+	bnez	t9, MT7628_AN_DDR1_PAD
+MT7628_KN_PAD:
+	li	t8, 0x00000303
+	or	t2, t2, t8
+	or	t3, t3, t8
+	or	t5, t5, t8
+	or	t7, t7, t8
+	li	t8, 0x00000000
+	or	t4, t4, t8
+	or	t6, t6, t8
+	j	SET_PAD_CFG
+MT7628_AN_DDR1_PAD:
+	li	t1, MT76XX_SYSCTL_BASE+0x10
+	lw	t1, 0(t1)
+	andi	t1, t1, 0x1
+	beqz	t1, MT7628_AN_DDR2_PAD
+	li	t8, 0x00000c0c
+	or	t2, t2, t8
+	li	t8, 0x00000202
+	or	t3, t3, t8
+	li	t8, 0x00000707
+	or	t5, t5, t8
+	li	t8, 0x00000c0c
+	or	t7, t7, t8
+	li	t8, 0x00000000
+	or	t4, t4, t8
+	or	t6, t6, t8
+	j	SET_PAD_CFG
+MT7628_AN_DDR2_PAD:
+	li	t8, 0x00000c0c
+	or	t2, t2, t8
+	li	t8, 0x00000202
+	or	t3, t3, t8
+	li	t8, 0x00000404
+	or	t5, t5, t8
+	li	t8, 0x00000c0c
+	or	t7, t7, t8
+	li	t8, 0x00000000		/* ODT off */
+	or	t4, t4, t8
+	or	t6, t6, t8
+
+SET_PAD_CFG:
+	li	t1, MT76XX_RGCTRL_BASE+0x704
+	sw	t2, 0(t1)
+	li	t1, MT76XX_RGCTRL_BASE+0x70c
+	sw	t3, 0(t1)
+	li	t1, MT76XX_RGCTRL_BASE+0x710
+	sw	t4, 0(t1)
+	li	t1, MT76XX_RGCTRL_BASE+0x714
+	sw	t5, 0(t1)
+	li	t1, MT76XX_RGCTRL_BASE+0x718
+	sw	t6, 0(t1)
+	li	t1, MT76XX_RGCTRL_BASE+0x71c
+	sw	t7, 0(t1)
+
+	/*
+	 * DDR initialization: reset pin to 0
+	 */
+	li	t1, MT76XX_SYSCTL_BASE + 0x34
+	lw	t2, 0(t1)
+	and	t2, ~BIT(10)
+	sw	t2, 0(t1)
+	nop
+
+	/*
+	 * DDR initialization: wait til reg DDR_CFG1 bit 21 equal to 1 (ready)
+	 */
+DDR_READY:
+	li	t1, DDR_CFG1_REG
+	lw	t0, 0(t1)
+	nop
+	and	t2, t0, BIT(21)
+	beqz	t2, DDR_READY
+	nop
+
+	/*
+	 * DDR initialization
+	 *
+	 * Only DDR2 supported right now. DDR2 support can be added, once
+	 * boards using it will get added to mainline U-Boot.
+	 */
+	li	t1, DDR_CFG2_REG
+	lw	t0, 0(t1)
+	nop
+	and	t0, ~BIT(30)
+	and	t0, ~(7 << 4)
+	or	t0, (4 << 4)
+	or	t0, BIT(30)
+	or	t0, BIT(11)
+	sw	t0, 0(t1)
+	nop
+
+	li	t1, DDR_CFG3_REG
+	lw	t2, 0(t1)
+	/* Disable ODT; reference board ok, ev board fail */
+	and	t2, ~BIT(6)
+	or	t2, BIT(2)
+	li	t0, DDR_CFG4_REG
+	lw	t1, 0(t0)
+	li	t2, ~(0x01f | 0x0f0)
+	and	t1, t1, t2
+	ori	t1, t1, DDR_CFG4_SIZE_VAL
+	sw	t1, 0(t0)
+	nop
+
+	/*
+	 * DDR initialization: config size and width on reg DDR_CFG1
+	 */
+	li	t6, DDR_CFG1_SIZE_VAL
+
+	and	t6, ~DDR_CFG1_CHIP_WIDTH_MASK
+	or	t6, DDR_CFG1_CHIP_WIDTH_VAL
+
+	/* CONFIG DDR_CFG1[13:12] about TOTAL WIDTH */
+	and	t6, ~DDR_CFG1_BUS_WIDTH_MASK
+	or	t6, DDR_CFG1_BUS_WIDTH_VAL
+
+	li	t5, DDR_CFG1_REG
+	sw	t6, 0(t5)
+	nop
+
+	/*
+	 * DDR: enable self auto refresh for power saving
+	 * enable it by default for both RAM and ROM version (for CoC)
+	 */
+	li	t0, MT76XX_MEMCTRL_BASE + 0x14
+	lw	t1, 0(t0)
+	nop
+	and	t1, 0xff000000
+	or	t1, 0x01
+	sw	t1, 0(t0)
+	nop
+	li	t0, MT76XX_MEMCTRL_BASE + 0x10
+	lw	t1, 0(t0)
+	nop
+	or	t1, 0x10
+	sw	t1, 0(t0)
+	nop
+
+	jr	ra
+	nop
+	END(lowlevel_init)
diff --git a/arch/mips/mach-mt7620/mt76xx.h b/arch/mips/mach-mt7620/mt76xx.h
new file mode 100644
index 0000000000..712d8aade0
--- /dev/null
+++ b/arch/mips/mach-mt7620/mt76xx.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#ifndef __MT76XX_H
+#define __MT76XX_H
+
+#ifdef __ASSEMBLY__
+#define VOID_PTR
+#else
+#define VOID_PTR		(void *)
+#endif
+
+#define MT76XX_SYSCTL_BASE	0xb0000000
+
+#define MT76XX_CHIPID		(VOID_PTR(MT76XX_SYSCTL_BASE + 0x00))
+#define MT76XX_CHIP_REV_ID	(VOID_PTR(MT76XX_SYSCTL_BASE + 0x0c))
+#define MT76XX_SYSCFG0		(VOID_PTR(MT76XX_SYSCTL_BASE + 0x10))
+#define MT76XX_RSTCTL		(VOID_PTR(MT76XX_SYSCTL_BASE + 0x34))
+
+#define MT76XX_MEMCTRL_BASE	(VOID_PTR(MT76XX_SYSCTL_BASE + 0x0300))
+#define MT76XX_RGCTRL_BASE	(VOID_PTR(MT76XX_SYSCTL_BASE + 0x1000))
+
+#define MT76XX_ROM_STATUS_REG	(VOID_PTR(MT76XX_SYSCTL_BASE + 0x0028))
+#define MT76XX_CLKCFG0_REG	(VOID_PTR(MT76XX_SYSCTL_BASE + 0x002c))
+#define MT76XX_DYN_CFG0_REG	(VOID_PTR(MT76XX_SYSCTL_BASE + 0x0440))
+
+#define DDR_CFG1_REG		(MT76XX_MEMCTRL_BASE + 0x44)
+#define DDR_CFG2_REG		(MT76XX_MEMCTRL_BASE + 0x48)
+#define DDR_CFG3_REG		(MT76XX_MEMCTRL_BASE + 0x4c)
+#define DDR_CFG4_REG		(MT76XX_MEMCTRL_BASE + 0x50)
+
+#ifndef __ASSEMBLY__
+/* Prototypes */
+void ddr_calibrate(void);
+#endif
+
+#endif
-- 
2.18.0

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

* [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h
  2018-08-06 15:11 [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Stefan Roese
@ 2018-08-06 15:11 ` Stefan Roese
  2018-08-07 14:51   ` Daniel Schwierzeck
  2018-08-06 15:11 ` [U-Boot] [PATCH 3/4] mips: Add LinkIt Smart 7688 support Stefan Roese
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Stefan Roese @ 2018-08-06 15:11 UTC (permalink / raw)
  To: u-boot

This is needed for the UBIFS support. The file is a copy of
arch/xtensa/include/asm/atomic.h

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
 arch/mips/include/asm/atomic.h | 54 ++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 arch/mips/include/asm/atomic.h

diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
new file mode 100644
index 0000000000..7551bf6e6c
--- /dev/null
+++ b/arch/mips/include/asm/atomic.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Cadence Design Systems Inc.
+ */
+
+#ifndef _MIPS_ATOMIC_H
+#define _MIPS_ATOMIC_H
+
+#include <asm/system.h>
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i)	{ (i) }
+
+#define atomic_read(v)		((v)->counter)
+#define atomic_set(v, i)	((v)->counter = (i))
+
+static inline void atomic_add(int i, atomic_t *v)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	v->counter += i;
+	local_irq_restore(flags);
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	v->counter -= i;
+	local_irq_restore(flags);
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	++v->counter;
+	local_irq_restore(flags);
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	--v->counter;
+	local_irq_restore(flags);
+}
+
+#endif
-- 
2.18.0

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

* [U-Boot] [PATCH 3/4] mips: Add LinkIt Smart 7688 support
  2018-08-06 15:11 [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Stefan Roese
  2018-08-06 15:11 ` [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h Stefan Roese
@ 2018-08-06 15:11 ` Stefan Roese
  2018-08-06 15:11 ` [U-Boot] [PATCH 4/4] mips: Add Gardena Smart-Gateway board support Stefan Roese
  2018-08-07 15:44 ` [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Daniel Schwierzeck
  3 siblings, 0 replies; 13+ messages in thread
From: Stefan Roese @ 2018-08-06 15:11 UTC (permalink / raw)
  To: u-boot

The LinkIt Smart 7688 modules have a MT7688 SoC with 128 MiB of RAM
and 32 MiB of flash (SPI NOR).

The mt7628a.dtsi file is imported from Linux v4.17.

This patch also includes 2 targets. One is the target that can be
programmed into the SPI NOR flash and a 2nd target "xxx-ram" is
added to support loading and booting via an already running U-Boot
version. This allows easy development and testing without the
need to flash the image each time.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
 arch/mips/dts/linkit-smart-7688.dts       |  46 ++++++++
 arch/mips/dts/mt7628a.dtsi                | 135 ++++++++++++++++++++++
 board/seeed/linkit-smart-7688/Kconfig     |  12 ++
 board/seeed/linkit-smart-7688/MAINTAINERS |   8 ++
 board/seeed/linkit-smart-7688/Makefile    |   3 +
 board/seeed/linkit-smart-7688/board.c     |  22 ++++
 configs/linkit-smart-7688-ram_defconfig   |  58 ++++++++++
 configs/linkit-smart-7688_defconfig       |  62 ++++++++++
 include/configs/linkit-smart-7688.h       |  48 ++++++++
 9 files changed, 394 insertions(+)
 create mode 100644 arch/mips/dts/linkit-smart-7688.dts
 create mode 100644 arch/mips/dts/mt7628a.dtsi
 create mode 100644 board/seeed/linkit-smart-7688/Kconfig
 create mode 100644 board/seeed/linkit-smart-7688/MAINTAINERS
 create mode 100644 board/seeed/linkit-smart-7688/Makefile
 create mode 100644 board/seeed/linkit-smart-7688/board.c
 create mode 100644 configs/linkit-smart-7688-ram_defconfig
 create mode 100644 configs/linkit-smart-7688_defconfig
 create mode 100644 include/configs/linkit-smart-7688.h

diff --git a/arch/mips/dts/linkit-smart-7688.dts b/arch/mips/dts/linkit-smart-7688.dts
new file mode 100644
index 0000000000..df4bf907c6
--- /dev/null
+++ b/arch/mips/dts/linkit-smart-7688.dts
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+/dts-v1/;
+
+#include "mt7628a.dtsi"
+
+/ {
+	compatible = "seeed,linkit-smart-7688", "ralink,mt7628a-soc";
+	model = "LinkIt-Smart-7688";
+
+	aliases {
+		serial0 = &uart2;
+		spi0 = &spi0;
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x08000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+		stdout-path = &uart2;
+	};
+};
+
+&uart2 {
+	status = "okay";
+	clock-frequency = <40000000>;
+};
+
+&spi0 {
+	status = "okay";
+	num-cs = <2>;
+
+	spi-flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spi-flash", "jedec,spi-nor";
+		spi-max-frequency = <25000000>;
+		reg = <0>;
+	};
+};
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi
new file mode 100644
index 0000000000..d00f528e1f
--- /dev/null
+++ b/arch/mips/dts/mt7628a.dtsi
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ralink,mt7628a-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "mti,mips24KEc";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	resetc: reset-controller {
+		compatible = "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	cpuintc: interrupt-controller {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	palmbus at 10000000 {
+		compatible = "palmbus", "simple-bus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: system-controller at 0 {
+			compatible = "ralink,mt7620a-sysc", "syscon";
+			reg = <0x0 0x100>;
+		};
+
+		intc: interrupt-controller at 200 {
+			compatible = "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			resets = <&resetc 9>;
+			reset-names = "intc";
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+
+			ralink,intc-registers = <0x9c 0xa0
+						 0x6c 0xa4
+						 0x80 0x78>;
+		};
+
+		memory-controller at 300 {
+			compatible = "ralink,mt7620a-memc";
+			reg = <0x300 0x100>;
+		};
+
+		spi0: spi at b00 {
+			compatible = "ralink,mt7621-spi";
+			reg = <0xb00 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		uart0: uartlite at c00 {
+			compatible = "ns16550a";
+			reg = <0xc00 0x100>;
+
+			resets = <&resetc 12>;
+			reset-names = "uart0";
+
+			interrupt-parent = <&intc>;
+			interrupts = <20>;
+
+			reg-shift = <2>;
+		};
+
+		uart1: uart1 at d00 {
+			compatible = "ns16550a";
+			reg = <0xd00 0x100>;
+
+			resets = <&resetc 19>;
+			reset-names = "uart1";
+
+			interrupt-parent = <&intc>;
+			interrupts = <21>;
+
+			reg-shift = <2>;
+		};
+
+		uart2: uart2 at e00 {
+			compatible = "ns16550a";
+			reg = <0xe00 0x100>;
+
+			resets = <&resetc 20>;
+			reset-names = "uart2";
+
+			interrupt-parent = <&intc>;
+			interrupts = <22>;
+
+			reg-shift = <2>;
+		};
+	};
+
+	usb_phy: usb-phy at 10120000 {
+		compatible = "mediatek,mt7628-usbphy";
+		reg = <0x10120000 0x1000>;
+
+		#phy-cells = <0>;
+
+		ralink,sysctl = <&sysc>;
+		resets = <&resetc 22 &resetc 25>;
+		reset-names = "host", "device";
+	};
+
+	ehci at 101c0000 {
+		compatible = "generic-ehci";
+		reg = <0x101c0000 0x1000>;
+
+		phys = <&usb_phy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+	};
+};
diff --git a/board/seeed/linkit-smart-7688/Kconfig b/board/seeed/linkit-smart-7688/Kconfig
new file mode 100644
index 0000000000..a9d63285c3
--- /dev/null
+++ b/board/seeed/linkit-smart-7688/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_LINKIT_SMART_7688
+
+config SYS_BOARD
+	default "linkit-smart-7688"
+
+config SYS_VENDOR
+	default "seeed"
+
+config SYS_CONFIG_NAME
+	default "linkit-smart-7688"
+
+endif
diff --git a/board/seeed/linkit-smart-7688/MAINTAINERS b/board/seeed/linkit-smart-7688/MAINTAINERS
new file mode 100644
index 0000000000..c3bbad4231
--- /dev/null
+++ b/board/seeed/linkit-smart-7688/MAINTAINERS
@@ -0,0 +1,8 @@
+LINKIT_SMART_7688 BOARD
+M:	Stefan Roese <sr@denx.de>
+S:	Maintained
+F:	board/seeed/linkit-smart-7688
+F:	include/configs/linkit-smart-7688.h
+F:	configs/linkit-smart-7688_defconfig
+F:	configs/linkit-smart-7688_ram_defconfig
+F:	arch/mips/dts/linkit-smart-7688.dts
diff --git a/board/seeed/linkit-smart-7688/Makefile b/board/seeed/linkit-smart-7688/Makefile
new file mode 100644
index 0000000000..70cd7a8e56
--- /dev/null
+++ b/board/seeed/linkit-smart-7688/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += board.o
diff --git a/board/seeed/linkit-smart-7688/board.c b/board/seeed/linkit-smart-7688/board.c
new file mode 100644
index 0000000000..fbe94cc292
--- /dev/null
+++ b/board/seeed/linkit-smart-7688/board.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#define MT76XX_GPIO1_MODE	0xb0000060
+
+void board_debug_uart_init(void)
+{
+	/* Select UART2 mode instead of GPIO mode (default) */
+	clrbits_le32((void __iomem *)MT76XX_GPIO1_MODE, GENMASK(27, 26));
+}
+
+int board_early_init_f(void)
+{
+	board_debug_uart_init();
+
+	return 0;
+}
diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig
new file mode 100644
index 0000000000..4b269f459b
--- /dev/null
+++ b/configs/linkit-smart-7688-ram_defconfig
@@ -0,0 +1,58 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x80010000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0x10000e00
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_ARCH_MT7620=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
+CONFIG_DEBUG_UART=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_NET is not set
+CONFIG_CMD_TIME=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_HAVE_BLOCK_DEVICE=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_GPIO=y
+CONFIG_LED=y
+CONFIG_LED_BLINK=y
+CONFIG_LED_GPIO=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_4BYTE_MODE_ONLY=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=57600
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_MT76XX_SPI=y
+CONFIG_SYSRESET_SYSCON=y
diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig
new file mode 100644
index 0000000000..cdb8c06517
--- /dev/null
+++ b/configs/linkit-smart-7688_defconfig
@@ -0,0 +1,62 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0xbc000000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0x10000e00
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_ARCH_MT7620=y
+CONFIG_BOOT_ROM=y
+CONFIG_ONBOARD_DDR2_SIZE_1024MBIT=y
+CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
+CONFIG_DEBUG_UART=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_NET is not set
+CONFIG_CMD_TIME=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_HAVE_BLOCK_DEVICE=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_GPIO=y
+CONFIG_LED=y
+CONFIG_LED_BLINK=y
+CONFIG_LED_GPIO=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_4BYTE_MODE_ONLY=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=57600
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_MT76XX_SPI=y
+CONFIG_SYSRESET_SYSCON=y
diff --git a/include/configs/linkit-smart-7688.h b/include/configs/linkit-smart-7688.h
new file mode 100644
index 0000000000..def71ad012
--- /dev/null
+++ b/include/configs/linkit-smart-7688.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#ifndef __CONFIG_LINKIT_SMART_7688_H
+#define __CONFIG_LINKIT_SMART_7688_H
+
+/* CPU */
+#define CONFIG_SYS_MIPS_TIMER_FREQ	200000000
+
+/* RAM */
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_SDRAM_BASE + 0x100000
+
+#define CONFIG_SYS_INIT_SP_OFFSET	0x400000
+
+/* UART */
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, \
+					  230400, 500000, 1500000 }
+
+/* RAM */
+#define CONFIG_SYS_MEMTEST_START	0x80100000
+#define CONFIG_SYS_MEMTEST_END		0x80400000
+
+/* Memory usage */
+#define CONFIG_SYS_MAXARGS		64
+#define CONFIG_SYS_MALLOC_LEN		(1024 * 1024)
+#define CONFIG_SYS_BOOTPARAMS_LEN	(128 * 1024)
+#define CONFIG_SYS_CBSIZE		512
+
+/* U-Boot */
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
+
+/* Environment settings */
+#define CONFIG_ENV_OFFSET		0x40000
+#define CONFIG_ENV_SIZE			(16 << 10)
+#define CONFIG_ENV_SECT_SIZE		(64 << 10)
+
+/*
+ * Environment is right behind U-Boot in flash. Make sure U-Boot
+ * doesn't grow into the environment area.
+ */
+#define CONFIG_BOARD_SIZE_LIMIT		CONFIG_ENV_OFFSET
+
+#endif /* __CONFIG_LINKIT_SMART_7688_H */
-- 
2.18.0

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

* [U-Boot] [PATCH 4/4] mips: Add Gardena Smart-Gateway board support
  2018-08-06 15:11 [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Stefan Roese
  2018-08-06 15:11 ` [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h Stefan Roese
  2018-08-06 15:11 ` [U-Boot] [PATCH 3/4] mips: Add LinkIt Smart 7688 support Stefan Roese
@ 2018-08-06 15:11 ` Stefan Roese
  2018-08-07 15:44 ` [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Daniel Schwierzeck
  3 siblings, 0 replies; 13+ messages in thread
From: Stefan Roese @ 2018-08-06 15:11 UTC (permalink / raw)
  To: u-boot

The Gardena Smart-Gateway boards have a MT7688 SoC with 128 MiB of RAM
and 8 MiB of flash (SPI NOR) and additional 128MiB SPI NAND storage.

This patch also includes 2 targets. One is the target that can be
programmed into the SPI NOR flash and a 2nd target "xxx-ram" is
added to support loading and booting via an already running U-Boot
version. This allows easy development and testing without the
need to flash the image each time.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
---
 .../mips/dts/gardena-smart-gateway-mt7688.dts | 54 +++++++++++++++
 arch/mips/mach-mt7620/Kconfig                 |  9 +++
 board/gardena/smart-gateway-mt7688/Kconfig    | 12 ++++
 .../gardena/smart-gateway-mt7688/MAINTAINERS  |  8 +++
 board/gardena/smart-gateway-mt7688/Makefile   |  3 +
 board/gardena/smart-gateway-mt7688/board.c    | 18 +++++
 ...gardena-smart-gateway-mt7688-ram_defconfig | 65 ++++++++++++++++++
 .../gardena-smart-gateway-mt7688_defconfig    | 68 +++++++++++++++++++
 .../configs/gardena-smart-gateway-mt7688.h    | 52 ++++++++++++++
 9 files changed, 289 insertions(+)
 create mode 100644 arch/mips/dts/gardena-smart-gateway-mt7688.dts
 create mode 100644 board/gardena/smart-gateway-mt7688/Kconfig
 create mode 100644 board/gardena/smart-gateway-mt7688/MAINTAINERS
 create mode 100644 board/gardena/smart-gateway-mt7688/Makefile
 create mode 100644 board/gardena/smart-gateway-mt7688/board.c
 create mode 100644 configs/gardena-smart-gateway-mt7688-ram_defconfig
 create mode 100644 configs/gardena-smart-gateway-mt7688_defconfig
 create mode 100644 include/configs/gardena-smart-gateway-mt7688.h

diff --git a/arch/mips/dts/gardena-smart-gateway-mt7688.dts b/arch/mips/dts/gardena-smart-gateway-mt7688.dts
new file mode 100644
index 0000000000..6b2600a446
--- /dev/null
+++ b/arch/mips/dts/gardena-smart-gateway-mt7688.dts
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+/dts-v1/;
+
+#include "mt7628a.dtsi"
+
+/ {
+	compatible = "gardena,smart-gateway-mt7688", "ralink,mt7628a-soc";
+	model = "Gardena smart-Gateway-MT7688";
+
+	aliases {
+		serial0 = &uart0;
+		spi0 = &spi0;
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x08000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+		stdout-path = &uart0;
+	};
+};
+
+&uart0 {
+	status = "okay";
+	clock-frequency = <40000000>;
+};
+
+&spi0 {
+	status = "okay";
+	num-cs = <2>;
+
+	spi-flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spi-flash", "jedec,spi-nor";
+		spi-max-frequency = <25000000>;
+		reg = <0>;
+	};
+
+	spi-nand at 1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spi-nand";
+		spi-max-frequency = <25000000>;
+		reg = <1>;
+	};
+};
diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig
index 40e15b8a31..75e18d4648 100644
--- a/arch/mips/mach-mt7620/Kconfig
+++ b/arch/mips/mach-mt7620/Kconfig
@@ -21,6 +21,14 @@ endchoice
 choice
 	prompt "Board select"
 
+config BOARD_GARDENA_SMART_GATEWAY_MT7688
+	bool "Gardena Smart Gateway"
+	depends on SOC_MT7620
+	select SUPPORTS_BOOT_RAM
+	help
+	  Gardena Smart Gateway boards have a MT7688 SoC with 128 MiB of RAM
+	  and 8 MiB of flash (SPI NOR) and additional SPI NAND storage.
+
 config BOARD_LINKIT_SMART_7688
 	bool "LinkIt Smart 7688"
 	depends on SOC_MT7620
@@ -125,6 +133,7 @@ config SUPPORTS_BOOT_RAM
 config SKIP_LOWLEVEL_INIT
 	bool
 
+source "board/gardena/smart-gateway-mt7688/Kconfig"
 source "board/seeed/linkit-smart-7688/Kconfig"
 
 endmenu
diff --git a/board/gardena/smart-gateway-mt7688/Kconfig b/board/gardena/smart-gateway-mt7688/Kconfig
new file mode 100644
index 0000000000..3653f8aadb
--- /dev/null
+++ b/board/gardena/smart-gateway-mt7688/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_GARDENA_SMART_GATEWAY_MT7688
+
+config SYS_BOARD
+	default "smart-gateway-mt7688"
+
+config SYS_VENDOR
+	default "gardena"
+
+config SYS_CONFIG_NAME
+	default "gardena-smart-gateway-mt7688"
+
+endif
diff --git a/board/gardena/smart-gateway-mt7688/MAINTAINERS b/board/gardena/smart-gateway-mt7688/MAINTAINERS
new file mode 100644
index 0000000000..bbb491c1ce
--- /dev/null
+++ b/board/gardena/smart-gateway-mt7688/MAINTAINERS
@@ -0,0 +1,8 @@
+GARDENA_SMART_GATEWAY_MT7688 BOARD
+M:	Stefan Roese <sr@denx.de>
+S:	Maintained
+F:	board/gardena/smart-gateway-mt7688
+F:	include/configs/gardena-smart-gateway-mt7688.h
+F:	configs/gardena-smart-gateway-mt7688_defconfig
+F:	configs/gardena-smart-gateway-mt7688-ram_defconfig
+F:	arch/mips/dts/gardena-smart-gateway-mt7688.dts
diff --git a/board/gardena/smart-gateway-mt7688/Makefile b/board/gardena/smart-gateway-mt7688/Makefile
new file mode 100644
index 0000000000..70cd7a8e56
--- /dev/null
+++ b/board/gardena/smart-gateway-mt7688/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += board.o
diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
new file mode 100644
index 0000000000..a62dc654f2
--- /dev/null
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+void board_debug_uart_init(void)
+{
+	/* Nothing to be done here for this board (no UART setup etc) */
+}
+
+int board_early_init_f(void)
+{
+	/* Nothing to be done here for this board (no UART setup etc) */
+	return 0;
+}
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig
new file mode 100644
index 0000000000..03c1618b55
--- /dev/null
+++ b/configs/gardena-smart-gateway-mt7688-ram_defconfig
@@ -0,0 +1,65 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0x80010000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0x10000c00
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_ARCH_MT7620=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
+CONFIG_DEBUG_UART=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_NET is not set
+CONFIG_CMD_TIME=y
+CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(ubi)"
+CONFIG_CMD_UBI=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_HAVE_BLOCK_DEVICE=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_GPIO=y
+CONFIG_LED=y
+CONFIG_LED_BLINK=y
+CONFIG_LED_GPIO=y
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=57600
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_SPI_MEM_HALF_DUPLEX=y
+CONFIG_MT76XX_SPI=y
+CONFIG_SYSRESET_SYSCON=y
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
new file mode 100644
index 0000000000..777c0723eb
--- /dev/null
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -0,0 +1,68 @@
+CONFIG_MIPS=y
+CONFIG_SYS_TEXT_BASE=0xbc000000
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART_BASE=0x10000c00
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_ARCH_MT7620=y
+CONFIG_BOOT_ROM=y
+CONFIG_ONBOARD_DDR2_SIZE_1024MBIT=y
+CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT=y
+# CONFIG_MIPS_BOOT_CMDLINE_LEGACY is not set
+# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
+CONFIG_DEBUG_UART=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_LICENSE=y
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_NET is not set
+CONFIG_CMD_TIME=y
+CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
+CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:-(ubi)"
+CONFIG_CMD_UBI=y
+CONFIG_OF_EMBED=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_HAVE_BLOCK_DEVICE=y
+CONFIG_CLK=y
+CONFIG_CPU=y
+CONFIG_DM_GPIO=y
+CONFIG_LED=y
+CONFIG_LED_BLINK=y
+CONFIG_LED_GPIO=y
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_BAUDRATE=57600
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_SPI_MEM_HALF_DUPLEX=y
+CONFIG_MT76XX_SPI=y
+CONFIG_SYSRESET_SYSCON=y
diff --git a/include/configs/gardena-smart-gateway-mt7688.h b/include/configs/gardena-smart-gateway-mt7688.h
new file mode 100644
index 0000000000..1f168076ce
--- /dev/null
+++ b/include/configs/gardena-smart-gateway-mt7688.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#ifndef __CONFIG_GARDENA_SMART_GATEWAY_H
+#define __CONFIG_GARDENA_SMART_GATEWAY_H
+
+/* CPU */
+#define CONFIG_SYS_MIPS_TIMER_FREQ	200000000
+
+/* RAM */
+#define CONFIG_NR_DRAM_BANKS		1
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+
+#define CONFIG_SYS_LOAD_ADDR		CONFIG_SYS_SDRAM_BASE + 0x100000
+
+#define CONFIG_SYS_INIT_SP_OFFSET	0x400000
+
+/* UART */
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, \
+					  230400, 500000, 1500000 }
+
+/* RAM */
+#define CONFIG_SYS_MEMTEST_START	0x80100000
+#define CONFIG_SYS_MEMTEST_END		0x80400000
+
+/* Memory usage */
+#define CONFIG_SYS_MAXARGS		64
+#define CONFIG_SYS_MALLOC_LEN		(1024 * 1024)
+#define CONFIG_SYS_BOOTPARAMS_LEN	(128 * 1024)
+#define CONFIG_SYS_CBSIZE		512
+
+/* U-Boot */
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
+
+/* Environment settings */
+#define CONFIG_ENV_OFFSET		0x80000
+#define CONFIG_ENV_SIZE			(64 << 10)
+#define CONFIG_ENV_SECT_SIZE		(64 << 10)
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + \
+						CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE
+
+/*
+ * Environment is right behind U-Boot in flash. Make sure U-Boot
+ * doesn't grow into the environment area.
+ */
+#define CONFIG_BOARD_SIZE_LIMIT		CONFIG_ENV_OFFSET
+
+#endif /* __CONFIG_GARDENA_SMART_GATEWAY_H */
-- 
2.18.0

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

* [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h
  2018-08-06 15:11 ` [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h Stefan Roese
@ 2018-08-07 14:51   ` Daniel Schwierzeck
  2018-08-09  9:27     ` Stefan Roese
  0 siblings, 1 reply; 13+ messages in thread
From: Daniel Schwierzeck @ 2018-08-07 14:51 UTC (permalink / raw)
  To: u-boot

2018-08-06 17:11 GMT+02:00 Stefan Roese <sr@denx.de>:
> This is needed for the UBIFS support. The file is a copy of
> arch/xtensa/include/asm/atomic.h

could you try to import this file from Linux MIPS? Then we would have
optimized functions.

Other way would be to import include/asm-generic/atomic.h from Linux
so that all architectures
in U-Boot could at least use a generic version.

>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> ---
>  arch/mips/include/asm/atomic.h | 54 ++++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
>  create mode 100644 arch/mips/include/asm/atomic.h
>
> diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
> new file mode 100644
> index 0000000000..7551bf6e6c
> --- /dev/null
> +++ b/arch/mips/include/asm/atomic.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2016 Cadence Design Systems Inc.
> + */
> +
> +#ifndef _MIPS_ATOMIC_H
> +#define _MIPS_ATOMIC_H
> +
> +#include <asm/system.h>
> +
> +typedef struct { volatile int counter; } atomic_t;
> +
> +#define ATOMIC_INIT(i) { (i) }
> +
> +#define atomic_read(v)         ((v)->counter)
> +#define atomic_set(v, i)       ((v)->counter = (i))
> +
> +static inline void atomic_add(int i, atomic_t *v)
> +{
> +       unsigned long flags;
> +
> +       local_irq_save(flags);
> +       v->counter += i;
> +       local_irq_restore(flags);
> +}
> +
> +static inline void atomic_sub(int i, atomic_t *v)
> +{
> +       unsigned long flags;
> +
> +       local_irq_save(flags);
> +       v->counter -= i;
> +       local_irq_restore(flags);
> +}
> +
> +static inline void atomic_inc(atomic_t *v)
> +{
> +       unsigned long flags;
> +
> +       local_irq_save(flags);
> +       ++v->counter;
> +       local_irq_restore(flags);
> +}
> +
> +static inline void atomic_dec(atomic_t *v)
> +{
> +       unsigned long flags;
> +
> +       local_irq_save(flags);
> +       --v->counter;
> +       local_irq_restore(flags);
> +}
> +
> +#endif
> --
> 2.18.0
>



-- 
- Daniel

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

* [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support
  2018-08-06 15:11 [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Stefan Roese
                   ` (2 preceding siblings ...)
  2018-08-06 15:11 ` [U-Boot] [PATCH 4/4] mips: Add Gardena Smart-Gateway board support Stefan Roese
@ 2018-08-07 15:44 ` Daniel Schwierzeck
  2018-08-09 10:46   ` Stefan Roese
  3 siblings, 1 reply; 13+ messages in thread
From: Daniel Schwierzeck @ 2018-08-07 15:44 UTC (permalink / raw)
  To: u-boot

2018-08-06 17:11 GMT+02:00 Stefan Roese <sr@denx.de>:
> This patch adds basic support for the MediaTek MT7620/88 SoCs. Parts of
> the code is copied from the MediaTek GitHub repository:
>
> https://github.com/MediaTek-Labs/linkit-smart-uboot.git
>
> Support for the LinkIt Smart 7688 module and the Gardena Smart Gateway
> both based on the MT7688 will be added in further patches.
>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> ---
>  arch/mips/Kconfig                     |  15 ++
>  arch/mips/Makefile                    |   1 +
>  arch/mips/mach-mt7620/Kconfig         | 130 ++++++++++
>  arch/mips/mach-mt7620/Makefile        |   8 +
>  arch/mips/mach-mt7620/cpu.c           |  66 +++++
>  arch/mips/mach-mt7620/ddr_calibrate.c | 331 +++++++++++++++++++++++++
>  arch/mips/mach-mt7620/lowlevel_init.S | 337 ++++++++++++++++++++++++++
>  arch/mips/mach-mt7620/mt76xx.h        |  39 +++
>  8 files changed, 927 insertions(+)
>  create mode 100644 arch/mips/mach-mt7620/Kconfig
>  create mode 100644 arch/mips/mach-mt7620/Makefile
>  create mode 100644 arch/mips/mach-mt7620/cpu.c
>  create mode 100644 arch/mips/mach-mt7620/ddr_calibrate.c
>  create mode 100644 arch/mips/mach-mt7620/lowlevel_init.S
>  create mode 100644 arch/mips/mach-mt7620/mt76xx.h
>
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 31b622ff51..af791c320d 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -87,6 +87,20 @@ config ARCH_BMIPS
>         select SYSRESET
>         imply CMD_DM
>
> +config ARCH_MT7620
> +       bool "Support MT7620/7688 SoCs"
> +       select SUPPORTS_LITTLE_ENDIAN
> +       select SUPPORTS_CPU_MIPS32_R1
> +       select SUPPORTS_CPU_MIPS32_R2
> +       select ROM_EXCEPTION_VECTORS
> +       select MIPS_TUNE_4KC

MT7620 has a MIPS 24kc core, thus you could optimize for that

> +       select OF_CONTROL
> +       select DM
> +       select DM_SERIAL
> +       select DM_SPI
> +       select DM_SPI_FLASH
> +       select DISPLAY_CPUINFO
> +

could you sort this in alphabetic order? There were some patches recently
which did the sorting tree wide. Also drop the SPI options until you add a
SPI driver.

>  config MACH_PIC32
>         bool "Support Microchip PIC32"
>         select DM
> @@ -141,6 +155,7 @@ source "board/qemu-mips/Kconfig"
>  source "arch/mips/mach-ath79/Kconfig"
>  source "arch/mips/mach-bmips/Kconfig"
>  source "arch/mips/mach-pic32/Kconfig"
> +source "arch/mips/mach-mt7620/Kconfig"
>
>  if MIPS
>
> diff --git a/arch/mips/Makefile b/arch/mips/Makefile
> index 5deec9a202..cc8ea5d7d4 100644
> --- a/arch/mips/Makefile
> +++ b/arch/mips/Makefile
> @@ -15,6 +15,7 @@ machine-$(CONFIG_SOC_AU1X00) += au1x00
>  machine-$(CONFIG_ARCH_ATH79) += ath79
>  machine-$(CONFIG_ARCH_BMIPS) += bmips
>  machine-$(CONFIG_MACH_PIC32) += pic32
> +machine-$(CONFIG_ARCH_MT7620) += mt7620
>
>  machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
>  libs-y += $(machdirs)
> diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig
> new file mode 100644
> index 0000000000..40e15b8a31
> --- /dev/null
> +++ b/arch/mips/mach-mt7620/Kconfig
> @@ -0,0 +1,130 @@
> +menu "MediaTek MIPS platforms"
> +       depends on ARCH_MT7620
> +
> +config SYS_MALLOC_F_LEN
> +       default 0x1000
> +
> +config SYS_SOC
> +       default "mt7620" if SOC_MT7620
> +
> +choice
> +       prompt "MediaTek MIPS SoC select"
> +
> +config SOC_MT7620
> +       bool "MT7620/8"
> +       select MIPS_L1_CACHE_SHIFT_5
> +       help
> +         This supports MediaTek MIPS MT7620 family.
> +
> +endchoice
> +
> +choice
> +       prompt "Board select"
> +
> +config BOARD_LINKIT_SMART_7688
> +       bool "LinkIt Smart 7688"
> +       depends on SOC_MT7620
> +       select SUPPORTS_BOOT_RAM
> +       help
> +         Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
> +         and 32 MiB of flash (SPI).
> +         Between its different peripherals there's an integrated switch with 4
> +         ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
> +         a MT7688 (PCIe).

could you add this part with patch 3/4?

> +
> +endchoice
> +
> +choice
> +       prompt "Boot mode"
> +
> +config BOOT_RAM
> +       bool "RAM boot"
> +       depends on SUPPORTS_BOOT_RAM
> +       select SKIP_LOWLEVEL_INIT
> +       help
> +         This builds an image that is linked to a RAM address. It can be used
> +         for booting from CFE via TFTP using an ELF image, but it can also be
> +         booted from RAM by other bootloaders using a BIN image.
> +
> +config BOOT_ROM
> +       bool "ROM boot"
> +       depends on SUPPORTS_BOOT_RAM
> +       help
> +         This builds an image that is linked to a ROM address. It can be
> +         used as main bootloader image which is programmed onto the onboard
> +         flash storage (SPI NOR).
> +
> +endchoice
> +
> +choice
> +       prompt "DDR2 size"
> +
> +config ONBOARD_DDR2_SIZE_256MBIT
> +       bool "256MBit (32MByte) total size"
> +       depends on BOOT_ROM
> +       help
> +         Use 256MBit (32MByte) of DDR total size
> +
> +config ONBOARD_DDR2_SIZE_512MBIT
> +       bool "512MBit (64MByte) total size"
> +       depends on BOOT_ROM
> +       help
> +         Use 512MBit (64MByte) of DDR total size
> +
> +config ONBOARD_DDR2_SIZE_1024MBIT
> +       bool "1024MBit (128MByte) total size"
> +       depends on BOOT_ROM
> +       help
> +         Use 1024MBit (128MByte) of DDR total size
> +
> +config ONBOARD_DDR2_SIZE_2048MBIT
> +       bool "2048MBit (256MByte) total size"
> +       depends on BOOT_ROM
> +       help
> +         Use 2048MBit (256MByte) of DDR total size
> +
> +endchoice
> +
> +choice
> +       prompt "DDR2 chip width"
> +
> +config ONBOARD_DDR2_CHIP_WIDTH_8BIT
> +       bool "8bit DDR chip width"
> +       depends on BOOT_ROM
> +       help
> +         Use DDR chips with 8bit width
> +
> +config ONBOARD_DDR2_CHIP_WIDTH_16BIT
> +       bool "16bit DDR chip width"
> +       depends on BOOT_ROM
> +       help
> +         Use DDR chips with 16bit width
> +
> +endchoice
> +
> +choice
> +       prompt "DDR2 bus width"
> +
> +config ONBOARD_DDR2_BUS_WIDTH_16BIT
> +       bool "16bit DDR bus width"
> +       depends on BOOT_ROM
> +       help
> +         Use 16bit DDR bus width
> +
> +config ONBOARD_DDR2_BUS_WIDTH_32BIT
> +       bool "32bit DDR bus width"
> +       depends on BOOT_ROM
> +       help
> +         Use 32bit DDR bus width
> +
> +endchoice
> +
> +config SUPPORTS_BOOT_RAM
> +       bool
> +
> +config SKIP_LOWLEVEL_INIT
> +       bool

this is a legacy config option, thus you have to define it in your
board config header file.
MIPS shouldn't add a Kconfig symbol for that. This have to be migrated
to Kconfig tree-wide.

> +
> +source "board/seeed/linkit-smart-7688/Kconfig"

could you add this part with patch 3/4?

> +
> +endmenu
> diff --git a/arch/mips/mach-mt7620/Makefile b/arch/mips/mach-mt7620/Makefile
> new file mode 100644
> index 0000000000..1f3e65e8a5
> --- /dev/null
> +++ b/arch/mips/mach-mt7620/Makefile
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +obj-y += cpu.o
> +
> +ifndef CONFIG_SKIP_LOWLEVEL_INIT
> +obj-y += ddr_calibrate.o
> +obj-y += lowlevel_init.o
> +endif
> diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c
> new file mode 100644
> index 0000000000..0b22956499
> --- /dev/null
> +++ b/arch/mips/mach-mt7620/cpu.c
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <ram.h>
> +#include <asm/io.h>
> +#include <linux/io.h>
> +#include <linux/sizes.h>
> +#include "mt76xx.h"
> +
> +#define STR_LEN                        6
> +
> +#ifdef CONFIG_BOOT_ROM
> +int mach_cpu_init(void)
> +{
> +       void (*ptr)(void);
> +
> +       /*
> +        * DDR calibration routine needs to be called very early. This
> +        * function also configures the clock to run at full speed.
> +        */
> +       ptr = (void *)CKSEG0ADDR(ddr_calibrate);
> +       (*ptr)();

what is the purpose of forcing the function symbol to KSEG0?

> +
> +       return 0;
> +}
> +#endif
> +
> +int print_cpuinfo(void)
> +{
> +       static const char * const boot_str[] = { "PLL (3-Byte SPI Addr)",
> +                                                "PLL (4-Byte SPI Addr)",
> +                                                "XTAL (3-Byte SPI Addr)",
> +                                                "XTAL (4-Byte SPI Addr)" };
> +       char *chr = (char *)MT76XX_CHIPID;
> +       char buf[STR_LEN + 1];
> +       u32 val;
> +
> +       snprintf(buf, STR_LEN + 1, "%s", chr);
> +       val = readl((void *)MT76XX_CHIP_REV_ID);
> +       printf("CPU:   %-*s Rev %ld.%ld - ", STR_LEN, buf,
> +              (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0));
> +
> +       val = (readl((void *)MT76XX_SYSCFG0) & GENMASK(3, 1)) >> 1;
> +       printf("Boot from %s\n", boot_str[val]);

could you try to create a CPU driver like on BMIPS?

> +
> +       return 0;
> +}
> +
> +void _machine_restart(void)
> +{
> +       writel(0x01, (void *)MT76XX_RSTCTL);
> +
> +       while (1)
> +               ;       /* NOP */

could you try to create a reset controller driver? Then you could also
use the generic syscon-reboot driver.

> +}
> +
> +int dram_init(void)
> +{
> +       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);

shouldn't you return the real configured DRAM size here?

> +
> +       return 0;
> +}
> diff --git a/arch/mips/mach-mt7620/ddr_calibrate.c b/arch/mips/mach-mt7620/ddr_calibrate.c
> new file mode 100644
> index 0000000000..6fd136674e
> --- /dev/null
> +++ b/arch/mips/mach-mt7620/ddr_calibrate.c
> @@ -0,0 +1,331 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
> + *
> + * This code is mostly based on the code extracted from this MediaTek
> + * github repository:
> + *
> + * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
> + *
> + * I was not able to find a specific license or other developers
> + * copyrights here, so I can't add them here.
> + *
> + * Most functions in this file are copied from the MediaTek U-Boot
> + * repository. Without any documentation, it was impossible to really
> + * implement this differently. So its mostly a cleaned-up version of
> + * the original code, with only support for the MT7628 / MT7688 SoC.
> + */
> +
> +#include <common.h>
> +#include <linux/io.h>
> +#include <asm/cacheops.h>
> +#include <asm/io.h>
> +#include "mt76xx.h"
> +
> +#define NUM_OF_CACHELINE       64
> +#define MIN_START              6
> +#define MIN_FINE_START         0xf
> +#define MAX_START              7
> +#define MAX_FINE_START         0x0
> +
> +#define CPU_FRAC_DIV           1
> +
> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
> +#define DRAM_BUTTOM 0x02000000
> +#endif
> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
> +#define DRAM_BUTTOM 0x04000000
> +#endif
> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
> +#define DRAM_BUTTOM 0x08000000
> +#endif
> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
> +#define DRAM_BUTTOM 0x10000000
> +#endif
> +
> +static inline void cal_memcpy(void *src, void *dst, u32 size)
> +{
> +       u8 *psrc = (u8 *)src;
> +       u8 *pdst = (u8 *)dst;
> +       int i;
> +
> +       for (i = 0; i < size; i++, psrc++, pdst++)
> +               *pdst = *psrc;
> +}
> +
> +static inline void cal_memset(void *src, u8 pat, u32 size)
> +{
> +       u8 *psrc = (u8 *)src;
> +       int i;
> +
> +       for (i = 0; i < size; i++, psrc++)
> +               *psrc = pat;
> +}
> +
> +#define pref_op(hint, addr)                                            \
> +       __asm__ __volatile__(                                           \
> +               ".set   push\n"                                         \
> +               ".set   noreorder\n"                                    \
> +               "pref   %0, %1\n"                                       \
> +               ".set   pop\n"                                          \
> +               :                                                       \
> +               : "i" (hint), "R" (*(u8 *)(addr)))
> +
> +#define cache_op(op, addr)                                             \
> +       __asm__ __volatile__(                                           \
> +               ".set   push\n"                                         \
> +               ".set   noreorder\n"                                    \
> +               ".set   mips3\n"                                        \
> +               "cache  %0, %1\n"                                       \
> +               ".set   pop\n"                                          \
> +               :                                                       \
> +               : "i" (op), "R" (*(u8 *)(addr)))

cache_op() is already available in arch/mips/include/asm/cacheops.h.
Maybe you could add pref_op in the same way to that file.

> +
> +static inline void cal_invalidate_dcache_range(u32 start_addr, u32 stop)
> +{
> +       u32 lsize = CONFIG_SYS_CACHELINE_SIZE;
> +       u32 addr = start_addr & ~(lsize - 1);
> +       u32 aend = (stop - 1) & ~(lsize - 1);
> +
> +       while (1) {
> +               cache_op(HIT_INVALIDATE_D, addr);
> +               if (addr == aend)
> +                       break;
> +               addr += lsize;
> +       }
> +}

you should use the generic MIPS implementation instead

> +
> +static inline void cal_patgen(u32 start_addr, u32 size, u32 bias)
> +{
> +       u32 *addr = (u32 *)start_addr;
> +       int i;
> +
> +       for (i = 0; i < size; i++)
> +               addr[i] = start_addr + i + bias;
> +}
> +
> +static inline int test_loop(int k, int dqs, u32 test_dqs, u32 *coarse_dqs,
> +                           u32 offs, u32 pat, u32 val)
> +{
> +       u32 nc_addr;
> +       u32 *c_addr;
> +       int i;
> +
> +       for (nc_addr = 0xa0000000;
> +            nc_addr < (0xa0000000 + DRAM_BUTTOM - NUM_OF_CACHELINE * 32);
> +            nc_addr += (DRAM_BUTTOM >> 6) + offs) {
> +               writel(0x00007474, MT76XX_MEMCTRL_BASE + 0x64);
> +               wmb();          /* Make sure store if finished */
> +
> +               c_addr = (u32 *)(nc_addr & 0xdfffffff);
> +               cal_memset(((u8 *)c_addr), 0x1F, NUM_OF_CACHELINE * 32);
> +               cal_patgen(nc_addr, NUM_OF_CACHELINE * 8, pat);
> +
> +               if (dqs > 0)
> +                       writel(0x00000074 |
> +                              (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 12) |
> +                              (((k == 0) ? val : test_dqs) << 8),
> +                              MT76XX_MEMCTRL_BASE + 0x64);
> +               else
> +                       writel(0x00007400 |
> +                              (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 4) |
> +                              (((k == 0) ? val : test_dqs) << 0),
> +                              MT76XX_MEMCTRL_BASE + 0x64);
> +               wmb();          /* Make sure store if finished */
> +
> +               cal_invalidate_dcache_range((u32)c_addr,
> +                                           (u32)c_addr +
> +                                           NUM_OF_CACHELINE * 32);
> +               wmb();          /* Make sure store if finished */
> +
> +               for (i = 0; i < NUM_OF_CACHELINE * 8; i++) {
> +                       if (i % 8 == 0)
> +                               pref_op(0, &c_addr[i]);
> +               }
> +
> +               for (i = 0; i < NUM_OF_CACHELINE * 8; i++) {
> +                       if (c_addr[i] != nc_addr + i + pat)
> +                               return -1;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +void ddr_calibrate(void)
> +{
> +       u32 min_coarse_dqs[2];
> +       u32 max_coarse_dqs[2];
> +       u32 min_fine_dqs[2];
> +       u32 max_fine_dqs[2];
> +       u32 coarse_dqs[2];
> +       u32 fine_dqs[2];
> +       int reg = 0, ddr_cfg2_reg;
> +       int flag;
> +       int i, k;
> +       int dqs = 0;
> +       u32 min_coarse_dqs_bnd, min_fine_dqs_bnd, coarse_dqs_dll, fine_dqs_dll;
> +       u32 val;
> +       u32 fdiv = 0, frac = 0;
> +
> +       /* Setup clock to run at full speed */
> +       val = readl(MT76XX_DYN_CFG0_REG);
> +       fdiv = (u32)((val >> 8) & 0x0F);
> +       if (CPU_FRAC_DIV < 1 || CPU_FRAC_DIV > 10)
> +               frac = val & 0x0f;
> +       else
> +               frac = CPU_FRAC_DIV;
> +
> +       while (frac < fdiv) {
> +               val = readl(MT76XX_DYN_CFG0_REG);
> +               fdiv = (val >> 8) & 0x0f;
> +               fdiv--;
> +               val &= ~(0x0f << 8);
> +               val |= (fdiv << 8);
> +               writel(val, MT76XX_DYN_CFG0_REG);
> +               udelay(500);
> +               val = readl(MT76XX_DYN_CFG0_REG);
> +               fdiv = (val >> 8) & 0x0f;
> +       }
> +
> +       clrbits_le32(MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
> +       ddr_cfg2_reg = readl(MT76XX_MEMCTRL_BASE + 0x48);
> +       clrbits_le32(MT76XX_MEMCTRL_BASE + 0x48, (0x3 << 28) | (0x3 << 26));
> +
> +       min_coarse_dqs[0] = MIN_START;
> +       min_coarse_dqs[1] = MIN_START;
> +       min_fine_dqs[0] = MIN_FINE_START;
> +       min_fine_dqs[1] = MIN_FINE_START;
> +       max_coarse_dqs[0] = MAX_START;
> +       max_coarse_dqs[1] = MAX_START;
> +       max_fine_dqs[0] = MAX_FINE_START;
> +       max_fine_dqs[1] = MAX_FINE_START;
> +       dqs = 0;
> +
> +       /* Add by KP, DQS MIN boundary */
> +       reg = readl(MT76XX_MEMCTRL_BASE + 0x20);
> +       coarse_dqs_dll = (reg & 0xf00) >> 8;
> +       fine_dqs_dll = (reg & 0xf0) >> 4;
> +       if (coarse_dqs_dll <= 8)
> +               min_coarse_dqs_bnd = 8 - coarse_dqs_dll;
> +       else
> +               min_coarse_dqs_bnd = 0;
> +
> +       if (fine_dqs_dll <= 8)
> +               min_fine_dqs_bnd = 8 - fine_dqs_dll;
> +       else
> +               min_fine_dqs_bnd = 0;
> +       /* DQS MIN boundary */
> +
> +DQS_CAL:
> +
> +       for (k = 0; k < 2; k++) {
> +               u32 test_dqs;
> +
> +               if (k == 0)
> +                       test_dqs = MAX_START;
> +               else
> +                       test_dqs = MAX_FINE_START;
> +
> +               do {
> +                       flag = test_loop(k, dqs, test_dqs, max_coarse_dqs,
> +                                        0x400, 0x3, 0xf);
> +                       if (flag == -1)
> +                               break;
> +
> +                       test_dqs++;
> +               } while (test_dqs <= 0xf);
> +
> +               if (k == 0) {
> +                       max_coarse_dqs[dqs] = test_dqs;
> +               } else {
> +                       test_dqs--;
> +
> +                       if (test_dqs == MAX_FINE_START - 1) {
> +                               max_coarse_dqs[dqs]--;
> +                               max_fine_dqs[dqs] = 0xf;
> +                       } else {
> +                               max_fine_dqs[dqs] = test_dqs;
> +                       }
> +               }
> +       }
> +
> +       for (k = 0; k < 2; k++) {
> +               u32 test_dqs;
> +
> +               if (k == 0)
> +                       test_dqs = MIN_START;
> +               else
> +                       test_dqs = MIN_FINE_START;
> +
> +               do {
> +                       flag = test_loop(k, dqs, test_dqs, min_coarse_dqs,
> +                                        0x480, 0x1, 0x0);
> +                       if (k == 0) {
> +                               if (flag == -1 ||
> +                                   test_dqs == min_coarse_dqs_bnd)
> +                                       break;
> +
> +                               test_dqs--;
> +
> +                               if (test_dqs < min_coarse_dqs_bnd)
> +                                       break;
> +                       } else {
> +                               if (flag == -1) {
> +                                       test_dqs++;
> +                                       break;
> +                               } else if (test_dqs == min_fine_dqs_bnd) {
> +                                       break;
> +                               }
> +
> +                               test_dqs--;
> +
> +                               if (test_dqs < min_fine_dqs_bnd)
> +                                       break;
> +                       }
> +               } while (test_dqs >= 0);
> +
> +               if (k == 0) {
> +                       min_coarse_dqs[dqs] = test_dqs;
> +               } else {
> +                       if (test_dqs == MIN_FINE_START + 1) {
> +                               min_coarse_dqs[dqs]++;
> +                               min_fine_dqs[dqs] = 0x0;
> +                       } else {
> +                               min_fine_dqs[dqs] = test_dqs;
> +                       }
> +               }
> +       }
> +
> +       if (dqs == 0) {
> +               dqs = 1;
> +               goto DQS_CAL;
> +       }
> +
> +       for (i = 0; i < 2; i++) {
> +               u32 temp;
> +
> +               coarse_dqs[i] = (max_coarse_dqs[i] + min_coarse_dqs[i]) >> 1;
> +               temp =
> +                   (((max_coarse_dqs[i] + min_coarse_dqs[i]) % 2) * 4) +
> +                   ((max_fine_dqs[i] + min_fine_dqs[i]) >> 1);
> +               if (temp >= 0x10) {
> +                       coarse_dqs[i]++;
> +                       fine_dqs[i] = (temp - 0x10) + 0x8;
> +               } else {
> +                       fine_dqs[i] = temp;
> +               }
> +       }
> +       reg = (coarse_dqs[1] << 12) | (fine_dqs[1] << 8) |
> +               (coarse_dqs[0] << 4) | fine_dqs[0];
> +
> +       clrbits_le32(MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
> +       writel(reg, MT76XX_MEMCTRL_BASE + 0x64);
> +       writel(ddr_cfg2_reg, MT76XX_MEMCTRL_BASE + 0x48);
> +       setbits_le32(MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
> +
> +       for (i = 0; i < 2; i++)
> +               debug("[%02X%02X%02X%02X]", min_coarse_dqs[i],
> +                     min_fine_dqs[i], max_coarse_dqs[i], max_fine_dqs[i]);
> +       debug("\nDDR Calibration DQS reg = %08X\n", reg);
> +}
> diff --git a/arch/mips/mach-mt7620/lowlevel_init.S b/arch/mips/mach-mt7620/lowlevel_init.S
> new file mode 100644
> index 0000000000..92b2fcd2bb
> --- /dev/null
> +++ b/arch/mips/mach-mt7620/lowlevel_init.S
> @@ -0,0 +1,337 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (c) 2018 Stefan Roese <sr@denx.de>
> + *
> + * This code is mostly based on the code extracted from this MediaTek
> + * github repository:
> + *
> + * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
> + *
> + * I was not able to find a specific license or other developers
> + * copyrights here, so I can't add them here.
> + */
> +
> +#include <config.h>
> +#include <asm/regdef.h>
> +#include <asm/mipsregs.h>
> +#include <asm/asm.h>
> +#include "mt76xx.h"
> +
> +#ifndef BIT
> +#define BIT(nr)                        (1 << (nr))
> +#endif
> +
> +#define DELAY_USEC(us)         ((us) / 100)
> +
> +#define DDR_CFG1_CHIP_WIDTH_MASK (0x3 << 16)
> +#define DDR_CFG1_BUS_WIDTH_MASK        (0x3 << 12)
> +
> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
> +#define DDR_CFG1_SIZE_VAL      0x222e2323
> +#define DDR_CFG4_SIZE_VAL      7
> +#endif
> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
> +#define DDR_CFG1_SIZE_VAL      0x22322323
> +#define DDR_CFG4_SIZE_VAL      9
> +#endif
> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
> +#define DDR_CFG1_SIZE_VAL      0x22362323
> +#define DDR_CFG4_SIZE_VAL      9
> +#endif
> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
> +#define DDR_CFG1_SIZE_VAL      0x223a2323
> +#define DDR_CFG4_SIZE_VAL      9
> +#endif
> +
> +#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_8BIT)
> +#define DDR_CFG1_CHIP_WIDTH_VAL        (0x1 << 16)
> +#endif
> +#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT)
> +#define DDR_CFG1_CHIP_WIDTH_VAL        (0x2 << 16)
> +#endif
> +
> +#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_16BIT)
> +#define DDR_CFG1_BUS_WIDTH_VAL (0x2 << 12)
> +#endif
> +#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_32BIT)
> +#define DDR_CFG1_BUS_WIDTH_VAL (0x3 << 12)
> +#endif
> +
> +LEAF(lowlevel_init)
> +       /* polling CPLL is ready */
> +       li      t1, DELAY_USEC(1000000)
> +       la      t5, MT76XX_ROM_STATUS_REG
> +1:
> +       lw      t2, 0(t5)
> +       andi    t2, t2, 0x1
> +       bnez    t2, CPLL_READY
> +       subu    t1, t1, 1
> +       bgtz    t1, 1b
> +       nop
> +       la      t0, MT76XX_CLKCFG0_REG
> +       lw      t3, 0(t0)
> +       ori     t3, t3, 0x1
> +       sw      t3, 0(t0)
> +       j       CPLL_DONE
> +       nop
> +CPLL_READY:
> +       la      t0, MT76XX_CLKCFG0_REG
> +       lw      t1, 0(t0)
> +       li      t2, ~0x0c
> +       and     t1, t1, t2
> +       ori     t1, t1, 0xc
> +       sw      t1, 0(t0)
> +       la      t0, MT76XX_DYN_CFG0_REG
> +       lw      t3, 0(t0)
> +       li      t5, ~((0x0f << 8) | (0x0f << 0))
> +       and     t3, t3, t5
> +       li      t5, (10 << 8) | (1 << 0)
> +       or      t3, t3, t5
> +       sw      t3, 0(t0)
> +       la      t0, MT76XX_CLKCFG0_REG
> +       lw      t3, 0(t0)
> +       li      t4, ~0x0F
> +       and     t3, t3, t4
> +       ori     t3, t3, 0xc
> +       sw      t3, 0(t0)
> +       lw      t3, 0(t0)
> +       ori     t3, t3, 0x08
> +       sw      t3, 0(t0)
> +
> +CPLL_DONE:
> +       /*
> +        * SDR and DDR initialization: delay 200us
> +        */
> +       li      t0, DELAY_USEC(200 + 40)
> +       li      t1, 0x1
> +1:
> +       sub     t0, t0, t1
> +       bnez    t0, 1b
> +       nop
> +
> +       /* set DRAM IO PAD for MT7628IC */
> +       /* DDR LDO Enable  */
> +       li      t1, MT76XX_RGCTRL_BASE+0x100
> +       lw      t4, 0(t1)
> +       li      t2, BIT(31)
> +       or      t4, t4, t2
> +       sw      t4, 0(t1)
> +       li      t1, MT76XX_RGCTRL_BASE+0x10c
> +       lw      t4, 0(t1)
> +       j       LDO_1P8V
> +       nop
> +LDO_1P8V:
> +       li      t2, ~BIT(6)
> +       and     t4, t4, t2
> +       li      t1, MT76XX_RGCTRL_BASE+0x10c
> +       sw      t4, 0(t1)
> +       j       DDRLDO_SOFT_START
> +LDO_2P5V:
> +       /* suppose external DDR1 LDO 2.5V */
> +       li      t2, BIT(6)
> +       or      t4, t4, t2
> +       li      t1, MT76XX_RGCTRL_BASE+0x10c
> +       sw      t4, 0(t1)
> +
> +DDRLDO_SOFT_START:
> +       li      t1, MT76XX_RGCTRL_BASE+0x10c
> +       lw      t2, 0(t1)
> +       li      t3, BIT(16)
> +       or      t2, t2, t3
> +       sw      t2, 0(t1)
> +       li      t3, DELAY_USEC(250*50)
> +LDO_DELAY:
> +       subu    t3, t3, 1
> +       bnez    t3, LDO_DELAY
> +       nop
> +
> +       li      t1, MT76XX_RGCTRL_BASE+0x10c
> +       lw      t2, 0(t1)
> +       li      t3, BIT(18)
> +       or      t2, t2, t3
> +       sw      t2, 0(t1)
> +
> +SET_RG_BUCK_FPWM:
> +       li      t1, MT76XX_RGCTRL_BASE+0x104
> +       lw      t2, 0(t1)
> +       ori     t2, t2, BIT(10)
> +       sw      t2, 0(t1)
> +
> +DDR_PAD_CFG:
> +       /* clean CLK PAD */
> +       li      t1, MT76XX_RGCTRL_BASE+0x704
> +       lw      t2, 0(t1)
> +       li      t8, 0xfffff0f0
> +       and     t2, t2, t8
> +       /* clean CMD PAD */
> +       li      t1, MT76XX_RGCTRL_BASE+0x70c
> +       lw      t3, 0(t1)
> +       li      t8, 0xfffff0f0
> +       and     t3, t3, t8
> +       /* clean DQ IPAD */
> +       li      t1, MT76XX_RGCTRL_BASE+0x710
> +       lw      t4, 0(t1)
> +       li      t8, 0xfffff8ff
> +       and     t4, t4, t8
> +       /* clean DQ OPAD */
> +       li      t1, MT76XX_RGCTRL_BASE+0x714
> +       lw      t5, 0(t1)
> +       li      t8, 0xfffff0f0
> +       and     t5, t5, t8
> +       /* clean DQS IPAD */
> +       li      t1, MT76XX_RGCTRL_BASE+0x718
> +       lw      t6, 0(t1)
> +       li      t8, 0xfffff8ff
> +       and     t6, t6, t8
> +       /* clean DQS OPAD */
> +       li      t1, MT76XX_RGCTRL_BASE+0x71c
> +       lw      t7, 0(t1)
> +       li      t8, 0xfffff0f0
> +       and     t7, t7, t8
> +
> +       li      t1, MT76XX_SYSCTL_BASE+0xC
> +       lw      t9, 0(t1)
> +       srl     t9, t9, 16
> +       andi    t9, t9, 0x1
> +       bnez    t9, MT7628_AN_DDR1_PAD
> +MT7628_KN_PAD:
> +       li      t8, 0x00000303
> +       or      t2, t2, t8
> +       or      t3, t3, t8
> +       or      t5, t5, t8
> +       or      t7, t7, t8
> +       li      t8, 0x00000000
> +       or      t4, t4, t8
> +       or      t6, t6, t8
> +       j       SET_PAD_CFG
> +MT7628_AN_DDR1_PAD:
> +       li      t1, MT76XX_SYSCTL_BASE+0x10
> +       lw      t1, 0(t1)
> +       andi    t1, t1, 0x1
> +       beqz    t1, MT7628_AN_DDR2_PAD
> +       li      t8, 0x00000c0c
> +       or      t2, t2, t8
> +       li      t8, 0x00000202
> +       or      t3, t3, t8
> +       li      t8, 0x00000707
> +       or      t5, t5, t8
> +       li      t8, 0x00000c0c
> +       or      t7, t7, t8
> +       li      t8, 0x00000000
> +       or      t4, t4, t8
> +       or      t6, t6, t8
> +       j       SET_PAD_CFG
> +MT7628_AN_DDR2_PAD:
> +       li      t8, 0x00000c0c
> +       or      t2, t2, t8
> +       li      t8, 0x00000202
> +       or      t3, t3, t8
> +       li      t8, 0x00000404
> +       or      t5, t5, t8
> +       li      t8, 0x00000c0c
> +       or      t7, t7, t8
> +       li      t8, 0x00000000          /* ODT off */
> +       or      t4, t4, t8
> +       or      t6, t6, t8
> +
> +SET_PAD_CFG:
> +       li      t1, MT76XX_RGCTRL_BASE+0x704
> +       sw      t2, 0(t1)
> +       li      t1, MT76XX_RGCTRL_BASE+0x70c
> +       sw      t3, 0(t1)
> +       li      t1, MT76XX_RGCTRL_BASE+0x710
> +       sw      t4, 0(t1)
> +       li      t1, MT76XX_RGCTRL_BASE+0x714
> +       sw      t5, 0(t1)
> +       li      t1, MT76XX_RGCTRL_BASE+0x718
> +       sw      t6, 0(t1)
> +       li      t1, MT76XX_RGCTRL_BASE+0x71c
> +       sw      t7, 0(t1)
> +
> +       /*
> +        * DDR initialization: reset pin to 0
> +        */
> +       li      t1, MT76XX_SYSCTL_BASE + 0x34
> +       lw      t2, 0(t1)
> +       and     t2, ~BIT(10)
> +       sw      t2, 0(t1)
> +       nop
> +
> +       /*
> +        * DDR initialization: wait til reg DDR_CFG1 bit 21 equal to 1 (ready)
> +        */
> +DDR_READY:
> +       li      t1, DDR_CFG1_REG
> +       lw      t0, 0(t1)
> +       nop
> +       and     t2, t0, BIT(21)
> +       beqz    t2, DDR_READY
> +       nop
> +
> +       /*
> +        * DDR initialization
> +        *
> +        * Only DDR2 supported right now. DDR2 support can be added, once
> +        * boards using it will get added to mainline U-Boot.
> +        */
> +       li      t1, DDR_CFG2_REG
> +       lw      t0, 0(t1)
> +       nop
> +       and     t0, ~BIT(30)
> +       and     t0, ~(7 << 4)
> +       or      t0, (4 << 4)
> +       or      t0, BIT(30)
> +       or      t0, BIT(11)
> +       sw      t0, 0(t1)
> +       nop
> +
> +       li      t1, DDR_CFG3_REG
> +       lw      t2, 0(t1)
> +       /* Disable ODT; reference board ok, ev board fail */
> +       and     t2, ~BIT(6)
> +       or      t2, BIT(2)
> +       li      t0, DDR_CFG4_REG
> +       lw      t1, 0(t0)
> +       li      t2, ~(0x01f | 0x0f0)
> +       and     t1, t1, t2
> +       ori     t1, t1, DDR_CFG4_SIZE_VAL
> +       sw      t1, 0(t0)
> +       nop
> +
> +       /*
> +        * DDR initialization: config size and width on reg DDR_CFG1
> +        */
> +       li      t6, DDR_CFG1_SIZE_VAL
> +
> +       and     t6, ~DDR_CFG1_CHIP_WIDTH_MASK
> +       or      t6, DDR_CFG1_CHIP_WIDTH_VAL
> +
> +       /* CONFIG DDR_CFG1[13:12] about TOTAL WIDTH */
> +       and     t6, ~DDR_CFG1_BUS_WIDTH_MASK
> +       or      t6, DDR_CFG1_BUS_WIDTH_VAL
> +
> +       li      t5, DDR_CFG1_REG
> +       sw      t6, 0(t5)
> +       nop
> +
> +       /*
> +        * DDR: enable self auto refresh for power saving
> +        * enable it by default for both RAM and ROM version (for CoC)
> +        */
> +       li      t0, MT76XX_MEMCTRL_BASE + 0x14
> +       lw      t1, 0(t0)
> +       nop
> +       and     t1, 0xff000000
> +       or      t1, 0x01
> +       sw      t1, 0(t0)
> +       nop
> +       li      t0, MT76XX_MEMCTRL_BASE + 0x10
> +       lw      t1, 0(t0)
> +       nop
> +       or      t1, 0x10
> +       sw      t1, 0(t0)
> +       nop
> +
> +       jr      ra
> +       nop
> +       END(lowlevel_init)
> diff --git a/arch/mips/mach-mt7620/mt76xx.h b/arch/mips/mach-mt7620/mt76xx.h
> new file mode 100644
> index 0000000000..712d8aade0
> --- /dev/null
> +++ b/arch/mips/mach-mt7620/mt76xx.h
> @@ -0,0 +1,39 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
> + */
> +
> +#ifndef __MT76XX_H
> +#define __MT76XX_H
> +
> +#ifdef __ASSEMBLY__
> +#define VOID_PTR
> +#else
> +#define VOID_PTR               (void *)
> +#endif
> +
> +#define MT76XX_SYSCTL_BASE     0xb0000000
> +
> +#define MT76XX_CHIPID          (VOID_PTR(MT76XX_SYSCTL_BASE + 0x00))
> +#define MT76XX_CHIP_REV_ID     (VOID_PTR(MT76XX_SYSCTL_BASE + 0x0c))
> +#define MT76XX_SYSCFG0         (VOID_PTR(MT76XX_SYSCTL_BASE + 0x10))
> +#define MT76XX_RSTCTL          (VOID_PTR(MT76XX_SYSCTL_BASE + 0x34))
> +
> +#define MT76XX_MEMCTRL_BASE    (VOID_PTR(MT76XX_SYSCTL_BASE + 0x0300))
> +#define MT76XX_RGCTRL_BASE     (VOID_PTR(MT76XX_SYSCTL_BASE + 0x1000))
> +
> +#define MT76XX_ROM_STATUS_REG  (VOID_PTR(MT76XX_SYSCTL_BASE + 0x0028))
> +#define MT76XX_CLKCFG0_REG     (VOID_PTR(MT76XX_SYSCTL_BASE + 0x002c))
> +#define MT76XX_DYN_CFG0_REG    (VOID_PTR(MT76XX_SYSCTL_BASE + 0x0440))
> +
> +#define DDR_CFG1_REG           (MT76XX_MEMCTRL_BASE + 0x44)
> +#define DDR_CFG2_REG           (MT76XX_MEMCTRL_BASE + 0x48)
> +#define DDR_CFG3_REG           (MT76XX_MEMCTRL_BASE + 0x4c)
> +#define DDR_CFG4_REG           (MT76XX_MEMCTRL_BASE + 0x50)
> +
> +#ifndef __ASSEMBLY__
> +/* Prototypes */
> +void ddr_calibrate(void);
> +#endif
> +
> +#endif
> --
> 2.18.0
>



-- 
- Daniel

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

* [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h
  2018-08-07 14:51   ` Daniel Schwierzeck
@ 2018-08-09  9:27     ` Stefan Roese
  2018-08-09 10:20       ` Daniel Schwierzeck
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Roese @ 2018-08-09  9:27 UTC (permalink / raw)
  To: u-boot

Hi Daniel,

On 07.08.2018 16:51, Daniel Schwierzeck wrote:
> 2018-08-06 17:11 GMT+02:00 Stefan Roese <sr@denx.de>:
>> This is needed for the UBIFS support. The file is a copy of
>> arch/xtensa/include/asm/atomic.h
> 
> could you try to import this file from Linux MIPS? Then we would have
> optimized functions.

Hmmm, looking at this file and the necessary headers that are not
present in U-Boot right now, this seems a bit too much in my taste.
Especially since U-Boot is not an OS and does not seed to support
all kind of protection against other threads / CPUs.

> Other way would be to import include/asm-generic/atomic.h from Linux
> so that all architectures
> in U-Boot could at least use a generic version.

I also took a quick glance at this and moving away from the
asm/atomic.h inclusion in U-Boot seems quite intrusive right now. I
would prefer to stay with this "simple" implementation for MIPS and
perhaps move to using this one (or a similar one) at a later time,
not being in the scope of this MIPS SoC addition.

What do you think? Would this be acceptable?

Thanks,
Stefan

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

* [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h
  2018-08-09  9:27     ` Stefan Roese
@ 2018-08-09 10:20       ` Daniel Schwierzeck
  0 siblings, 0 replies; 13+ messages in thread
From: Daniel Schwierzeck @ 2018-08-09 10:20 UTC (permalink / raw)
  To: u-boot

Stefan Roese <sr@denx.de> schrieb am Do., 9. Aug. 2018, 11:27:

> Hi Daniel,
>
> On 07.08.2018 16:51, Daniel Schwierzeck wrote:
> > 2018-08-06 17:11 GMT+02:00 Stefan Roese <sr@denx.de>:
> >> This is needed for the UBIFS support. The file is a copy of
> >> arch/xtensa/include/asm/atomic.h
> >
> > could you try to import this file from Linux MIPS? Then we would have
> > optimized functions.
>
> Hmmm, looking at this file and the necessary headers that are not
> present in U-Boot right now, this seems a bit too much in my taste.
> Especially since U-Boot is not an OS and does not seed to support
> all kind of protection against other threads / CPUs.
>
> > Other way would be to import include/asm-generic/atomic.h from Linux
> > so that all architectures
> > in U-Boot could at least use a generic version.
>
> I also took a quick glance at this and moving away from the
> asm/atomic.h inclusion in U-Boot seems quite intrusive right now. I
> would prefer to stay with this "simple" implementation for MIPS and
> perhaps move to using this one (or a similar one) at a later time,
> not being in the scope of this MIPS SoC addition.
>
> What do you think? Would this be acceptable?
>
> Thanks,
> Stefan
>

Yes okay, I'll put this onto my todo list

>

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

* [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support
  2018-08-07 15:44 ` [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Daniel Schwierzeck
@ 2018-08-09 10:46   ` Stefan Roese
  2018-08-09 13:28     ` Daniel Schwierzeck
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Roese @ 2018-08-09 10:46 UTC (permalink / raw)
  To: u-boot

Hi Daniel,

On 07.08.2018 17:44, Daniel Schwierzeck wrote:
> 2018-08-06 17:11 GMT+02:00 Stefan Roese <sr@denx.de>:
>> This patch adds basic support for the MediaTek MT7620/88 SoCs. Parts of
>> the code is copied from the MediaTek GitHub repository:
>>
>> https://github.com/MediaTek-Labs/linkit-smart-uboot.git
>>
>> Support for the LinkIt Smart 7688 module and the Gardena Smart Gateway
>> both based on the MT7688 will be added in further patches.
>>
>> Signed-off-by: Stefan Roese <sr@denx.de>
>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>> ---
>>   arch/mips/Kconfig                     |  15 ++
>>   arch/mips/Makefile                    |   1 +
>>   arch/mips/mach-mt7620/Kconfig         | 130 ++++++++++
>>   arch/mips/mach-mt7620/Makefile        |   8 +
>>   arch/mips/mach-mt7620/cpu.c           |  66 +++++
>>   arch/mips/mach-mt7620/ddr_calibrate.c | 331 +++++++++++++++++++++++++
>>   arch/mips/mach-mt7620/lowlevel_init.S | 337 ++++++++++++++++++++++++++
>>   arch/mips/mach-mt7620/mt76xx.h        |  39 +++
>>   8 files changed, 927 insertions(+)
>>   create mode 100644 arch/mips/mach-mt7620/Kconfig
>>   create mode 100644 arch/mips/mach-mt7620/Makefile
>>   create mode 100644 arch/mips/mach-mt7620/cpu.c
>>   create mode 100644 arch/mips/mach-mt7620/ddr_calibrate.c
>>   create mode 100644 arch/mips/mach-mt7620/lowlevel_init.S
>>   create mode 100644 arch/mips/mach-mt7620/mt76xx.h
>>
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index 31b622ff51..af791c320d 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -87,6 +87,20 @@ config ARCH_BMIPS
>>          select SYSRESET
>>          imply CMD_DM
>>
>> +config ARCH_MT7620
>> +       bool "Support MT7620/7688 SoCs"
>> +       select SUPPORTS_LITTLE_ENDIAN
>> +       select SUPPORTS_CPU_MIPS32_R1
>> +       select SUPPORTS_CPU_MIPS32_R2
>> +       select ROM_EXCEPTION_VECTORS
>> +       select MIPS_TUNE_4KC
> 
> MT7620 has a MIPS 24kc core, thus you could optimize for that

Okay.
 
>> +       select OF_CONTROL
>> +       select DM
>> +       select DM_SERIAL
>> +       select DM_SPI
>> +       select DM_SPI_FLASH
>> +       select DISPLAY_CPUINFO
>> +
> 
> could you sort this in alphabetic order?

Okay, will do in v2.

> There were some patches recently
> which did the sorting tree wide. Also drop the SPI options until you add a
> SPI driver.

The SPI driver is also on the list:

http://patchwork.ozlabs.org/patch/954365/
 
>>   config MACH_PIC32
>>          bool "Support Microchip PIC32"
>>          select DM
>> @@ -141,6 +155,7 @@ source "board/qemu-mips/Kconfig"
>>   source "arch/mips/mach-ath79/Kconfig"
>>   source "arch/mips/mach-bmips/Kconfig"
>>   source "arch/mips/mach-pic32/Kconfig"
>> +source "arch/mips/mach-mt7620/Kconfig"
>>
>>   if MIPS
>>
>> diff --git a/arch/mips/Makefile b/arch/mips/Makefile
>> index 5deec9a202..cc8ea5d7d4 100644
>> --- a/arch/mips/Makefile
>> +++ b/arch/mips/Makefile
>> @@ -15,6 +15,7 @@ machine-$(CONFIG_SOC_AU1X00) += au1x00
>>   machine-$(CONFIG_ARCH_ATH79) += ath79
>>   machine-$(CONFIG_ARCH_BMIPS) += bmips
>>   machine-$(CONFIG_MACH_PIC32) += pic32
>> +machine-$(CONFIG_ARCH_MT7620) += mt7620
>>
>>   machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
>>   libs-y += $(machdirs)
>> diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig
>> new file mode 100644
>> index 0000000000..40e15b8a31
>> --- /dev/null
>> +++ b/arch/mips/mach-mt7620/Kconfig
>> @@ -0,0 +1,130 @@
>> +menu "MediaTek MIPS platforms"
>> +       depends on ARCH_MT7620
>> +
>> +config SYS_MALLOC_F_LEN
>> +       default 0x1000
>> +
>> +config SYS_SOC
>> +       default "mt7620" if SOC_MT7620
>> +
>> +choice
>> +       prompt "MediaTek MIPS SoC select"
>> +
>> +config SOC_MT7620
>> +       bool "MT7620/8"
>> +       select MIPS_L1_CACHE_SHIFT_5
>> +       help
>> +         This supports MediaTek MIPS MT7620 family.
>> +
>> +endchoice
>> +
>> +choice
>> +       prompt "Board select"
>> +
>> +config BOARD_LINKIT_SMART_7688
>> +       bool "LinkIt Smart 7688"
>> +       depends on SOC_MT7620
>> +       select SUPPORTS_BOOT_RAM
>> +       help
>> +         Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
>> +         and 32 MiB of flash (SPI).
>> +         Between its different peripherals there's an integrated switch with 4
>> +         ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
>> +         a MT7688 (PCIe).
> 
> could you add this part with patch 3/4?

Ah, yes. This slipped in too early.
 
>> +
>> +endchoice
>> +
>> +choice
>> +       prompt "Boot mode"
>> +
>> +config BOOT_RAM
>> +       bool "RAM boot"
>> +       depends on SUPPORTS_BOOT_RAM
>> +       select SKIP_LOWLEVEL_INIT
>> +       help
>> +         This builds an image that is linked to a RAM address. It can be used
>> +         for booting from CFE via TFTP using an ELF image, but it can also be
>> +         booted from RAM by other bootloaders using a BIN image.
>> +
>> +config BOOT_ROM
>> +       bool "ROM boot"
>> +       depends on SUPPORTS_BOOT_RAM
>> +       help
>> +         This builds an image that is linked to a ROM address. It can be
>> +         used as main bootloader image which is programmed onto the onboard
>> +         flash storage (SPI NOR).
>> +
>> +endchoice
>> +
>> +choice
>> +       prompt "DDR2 size"
>> +
>> +config ONBOARD_DDR2_SIZE_256MBIT
>> +       bool "256MBit (32MByte) total size"
>> +       depends on BOOT_ROM
>> +       help
>> +         Use 256MBit (32MByte) of DDR total size
>> +
>> +config ONBOARD_DDR2_SIZE_512MBIT
>> +       bool "512MBit (64MByte) total size"
>> +       depends on BOOT_ROM
>> +       help
>> +         Use 512MBit (64MByte) of DDR total size
>> +
>> +config ONBOARD_DDR2_SIZE_1024MBIT
>> +       bool "1024MBit (128MByte) total size"
>> +       depends on BOOT_ROM
>> +       help
>> +         Use 1024MBit (128MByte) of DDR total size
>> +
>> +config ONBOARD_DDR2_SIZE_2048MBIT
>> +       bool "2048MBit (256MByte) total size"
>> +       depends on BOOT_ROM
>> +       help
>> +         Use 2048MBit (256MByte) of DDR total size
>> +
>> +endchoice
>> +
>> +choice
>> +       prompt "DDR2 chip width"
>> +
>> +config ONBOARD_DDR2_CHIP_WIDTH_8BIT
>> +       bool "8bit DDR chip width"
>> +       depends on BOOT_ROM
>> +       help
>> +         Use DDR chips with 8bit width
>> +
>> +config ONBOARD_DDR2_CHIP_WIDTH_16BIT
>> +       bool "16bit DDR chip width"
>> +       depends on BOOT_ROM
>> +       help
>> +         Use DDR chips with 16bit width
>> +
>> +endchoice
>> +
>> +choice
>> +       prompt "DDR2 bus width"
>> +
>> +config ONBOARD_DDR2_BUS_WIDTH_16BIT
>> +       bool "16bit DDR bus width"
>> +       depends on BOOT_ROM
>> +       help
>> +         Use 16bit DDR bus width
>> +
>> +config ONBOARD_DDR2_BUS_WIDTH_32BIT
>> +       bool "32bit DDR bus width"
>> +       depends on BOOT_ROM
>> +       help
>> +         Use 32bit DDR bus width
>> +
>> +endchoice
>> +
>> +config SUPPORTS_BOOT_RAM
>> +       bool
>> +
>> +config SKIP_LOWLEVEL_INIT
>> +       bool
> 
> this is a legacy config option, thus you have to define it in your
> board config header file.
> MIPS shouldn't add a Kconfig symbol for that. This have to be migrated
> to Kconfig tree-wide.

Will move to config header for now.
 
>> +
>> +source "board/seeed/linkit-smart-7688/Kconfig"
> 
> could you add this part with patch 3/4?

Sure.
 
>> +
>> +endmenu
>> diff --git a/arch/mips/mach-mt7620/Makefile b/arch/mips/mach-mt7620/Makefile
>> new file mode 100644
>> index 0000000000..1f3e65e8a5
>> --- /dev/null
>> +++ b/arch/mips/mach-mt7620/Makefile
>> @@ -0,0 +1,8 @@
>> +# SPDX-License-Identifier: GPL-2.0+
>> +
>> +obj-y += cpu.o
>> +
>> +ifndef CONFIG_SKIP_LOWLEVEL_INIT
>> +obj-y += ddr_calibrate.o
>> +obj-y += lowlevel_init.o
>> +endif
>> diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c
>> new file mode 100644
>> index 0000000000..0b22956499
>> --- /dev/null
>> +++ b/arch/mips/mach-mt7620/cpu.c
>> @@ -0,0 +1,66 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <ram.h>
>> +#include <asm/io.h>
>> +#include <linux/io.h>
>> +#include <linux/sizes.h>
>> +#include "mt76xx.h"
>> +
>> +#define STR_LEN                        6
>> +
>> +#ifdef CONFIG_BOOT_ROM
>> +int mach_cpu_init(void)
>> +{
>> +       void (*ptr)(void);
>> +
>> +       /*
>> +        * DDR calibration routine needs to be called very early. This
>> +        * function also configures the clock to run at full speed.
>> +        */
>> +       ptr = (void *)CKSEG0ADDR(ddr_calibrate);
>> +       (*ptr)();
> 
> what is the purpose of forcing the function symbol to KSEG0?

Its copied from the original MediaTek code. I just tested it without
forcing the execution into KSEG0 and the DDR calibration is extremely
slow then, taking a few minutes to complete.

I have to admit that I am not 100% sure, if the caches are configured
100% correctly / optimally for this SoC. Perhaps you (or someone else)
has some improvements here.
 
>> +
>> +       return 0;
>> +}
>> +#endif
>> +
>> +int print_cpuinfo(void)
>> +{
>> +       static const char * const boot_str[] = { "PLL (3-Byte SPI Addr)",
>> +                                                "PLL (4-Byte SPI Addr)",
>> +                                                "XTAL (3-Byte SPI Addr)",
>> +                                                "XTAL (4-Byte SPI Addr)" };
>> +       char *chr = (char *)MT76XX_CHIPID;
>> +       char buf[STR_LEN + 1];
>> +       u32 val;
>> +
>> +       snprintf(buf, STR_LEN + 1, "%s", chr);
>> +       val = readl((void *)MT76XX_CHIP_REV_ID);
>> +       printf("CPU:   %-*s Rev %ld.%ld - ", STR_LEN, buf,
>> +              (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0));
>> +
>> +       val = (readl((void *)MT76XX_SYSCFG0) & GENMASK(3, 1)) >> 1;
>> +       printf("Boot from %s\n", boot_str[val]);
> 
> could you try to create a CPU driver like on BMIPS?

Do you really think this is necessary just for printing some SoC
information here?
 
>> +
>> +       return 0;
>> +}
>> +
>> +void _machine_restart(void)
>> +{
>> +       writel(0x01, (void *)MT76XX_RSTCTL);
>> +
>> +       while (1)
>> +               ;       /* NOP */
> 
> could you try to create a reset controller driver? Then you could also
> use the generic syscon-reboot driver.

Yes, I also thought about this. Will do in v2.
 
>> +}
>> +
>> +int dram_init(void)
>> +{
>> +       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
> 
> shouldn't you return the real configured DRAM size here?

I always like using get_ram_size() as it automatically detects the
RAM size. This might be different (smaller) than the one configured,
if HW problems with the DDR interface exist.

We might think about printing a warning, if the detected size does not
match the configured one.
 
>> +
>> +       return 0;
>> +}
>> diff --git a/arch/mips/mach-mt7620/ddr_calibrate.c b/arch/mips/mach-mt7620/ddr_calibrate.c
>> new file mode 100644
>> index 0000000000..6fd136674e
>> --- /dev/null
>> +++ b/arch/mips/mach-mt7620/ddr_calibrate.c
>> @@ -0,0 +1,331 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
>> + *
>> + * This code is mostly based on the code extracted from this MediaTek
>> + * github repository:
>> + *
>> + * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
>> + *
>> + * I was not able to find a specific license or other developers
>> + * copyrights here, so I can't add them here.
>> + *
>> + * Most functions in this file are copied from the MediaTek U-Boot
>> + * repository. Without any documentation, it was impossible to really
>> + * implement this differently. So its mostly a cleaned-up version of
>> + * the original code, with only support for the MT7628 / MT7688 SoC.
>> + */
>> +
>> +#include <common.h>
>> +#include <linux/io.h>
>> +#include <asm/cacheops.h>
>> +#include <asm/io.h>
>> +#include "mt76xx.h"
>> +
>> +#define NUM_OF_CACHELINE       64
>> +#define MIN_START              6
>> +#define MIN_FINE_START         0xf
>> +#define MAX_START              7
>> +#define MAX_FINE_START         0x0
>> +
>> +#define CPU_FRAC_DIV           1
>> +
>> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
>> +#define DRAM_BUTTOM 0x02000000
>> +#endif
>> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
>> +#define DRAM_BUTTOM 0x04000000
>> +#endif
>> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
>> +#define DRAM_BUTTOM 0x08000000
>> +#endif
>> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
>> +#define DRAM_BUTTOM 0x10000000
>> +#endif
>> +
>> +static inline void cal_memcpy(void *src, void *dst, u32 size)
>> +{
>> +       u8 *psrc = (u8 *)src;
>> +       u8 *pdst = (u8 *)dst;
>> +       int i;
>> +
>> +       for (i = 0; i < size; i++, psrc++, pdst++)
>> +               *pdst = *psrc;
>> +}
>> +
>> +static inline void cal_memset(void *src, u8 pat, u32 size)
>> +{
>> +       u8 *psrc = (u8 *)src;
>> +       int i;
>> +
>> +       for (i = 0; i < size; i++, psrc++)
>> +               *psrc = pat;
>> +}
>> +
>> +#define pref_op(hint, addr)                                            \
>> +       __asm__ __volatile__(                                           \
>> +               ".set   push\n"                                         \
>> +               ".set   noreorder\n"                                    \
>> +               "pref   %0, %1\n"                                       \
>> +               ".set   pop\n"                                          \
>> +               :                                                       \
>> +               : "i" (hint), "R" (*(u8 *)(addr)))
>> +
>> +#define cache_op(op, addr)                                             \
>> +       __asm__ __volatile__(                                           \
>> +               ".set   push\n"                                         \
>> +               ".set   noreorder\n"                                    \
>> +               ".set   mips3\n"                                        \
>> +               "cache  %0, %1\n"                                       \
>> +               ".set   pop\n"                                          \
>> +               :                                                       \
>> +               : "i" (op), "R" (*(u8 *)(addr)))
> 
> cache_op() is already available in arch/mips/include/asm/cacheops.h.

Hmm, Where exactly?

> Maybe you could add pref_op in the same way to that file.

Could make sense, but please see above. Again, I'm still pretty new to
MIPS and especially the caches.
 
>> +
>> +static inline void cal_invalidate_dcache_range(u32 start_addr, u32 stop)
>> +{
>> +       u32 lsize = CONFIG_SYS_CACHELINE_SIZE;
>> +       u32 addr = start_addr & ~(lsize - 1);
>> +       u32 aend = (stop - 1) & ~(lsize - 1);
>> +
>> +       while (1) {
>> +               cache_op(HIT_INVALIDATE_D, addr);
>> +               if (addr == aend)
>> +                       break;
>> +               addr += lsize;
>> +       }
>> +}
> 
> you should use the generic MIPS implementation instead

Yes, makes sense.

Thanks,
Stefan

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

* [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support
  2018-08-09 10:46   ` Stefan Roese
@ 2018-08-09 13:28     ` Daniel Schwierzeck
  2018-08-09 14:22       ` Stefan Roese
  0 siblings, 1 reply; 13+ messages in thread
From: Daniel Schwierzeck @ 2018-08-09 13:28 UTC (permalink / raw)
  To: u-boot

Am Do., 9. Aug. 2018 um 12:46 Uhr schrieb Stefan Roese <sr@denx.de>:
>
> Hi Daniel,
>
> On 07.08.2018 17:44, Daniel Schwierzeck wrote:
> > 2018-08-06 17:11 GMT+02:00 Stefan Roese <sr@denx.de>:
> >> This patch adds basic support for the MediaTek MT7620/88 SoCs. Parts of
> >> the code is copied from the MediaTek GitHub repository:
> >>
> >> https://github.com/MediaTek-Labs/linkit-smart-uboot.git
> >>
> >> Support for the LinkIt Smart 7688 module and the Gardena Smart Gateway
> >> both based on the MT7688 will be added in further patches.
> >>
> >> Signed-off-by: Stefan Roese <sr@denx.de>
> >> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
> >> ---
> >>   arch/mips/Kconfig                     |  15 ++
> >>   arch/mips/Makefile                    |   1 +
> >>   arch/mips/mach-mt7620/Kconfig         | 130 ++++++++++
> >>   arch/mips/mach-mt7620/Makefile        |   8 +
> >>   arch/mips/mach-mt7620/cpu.c           |  66 +++++
> >>   arch/mips/mach-mt7620/ddr_calibrate.c | 331 +++++++++++++++++++++++++
> >>   arch/mips/mach-mt7620/lowlevel_init.S | 337 ++++++++++++++++++++++++++
> >>   arch/mips/mach-mt7620/mt76xx.h        |  39 +++
> >>   8 files changed, 927 insertions(+)
> >>   create mode 100644 arch/mips/mach-mt7620/Kconfig
> >>   create mode 100644 arch/mips/mach-mt7620/Makefile
> >>   create mode 100644 arch/mips/mach-mt7620/cpu.c
> >>   create mode 100644 arch/mips/mach-mt7620/ddr_calibrate.c
> >>   create mode 100644 arch/mips/mach-mt7620/lowlevel_init.S
> >>   create mode 100644 arch/mips/mach-mt7620/mt76xx.h
> >>
> >> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> >> index 31b622ff51..af791c320d 100644
> >> --- a/arch/mips/Kconfig
> >> +++ b/arch/mips/Kconfig
> >> @@ -87,6 +87,20 @@ config ARCH_BMIPS
> >>          select SYSRESET
> >>          imply CMD_DM
> >>
> >> +config ARCH_MT7620
> >> +       bool "Support MT7620/7688 SoCs"
> >> +       select SUPPORTS_LITTLE_ENDIAN
> >> +       select SUPPORTS_CPU_MIPS32_R1
> >> +       select SUPPORTS_CPU_MIPS32_R2
> >> +       select ROM_EXCEPTION_VECTORS
> >> +       select MIPS_TUNE_4KC
> >
> > MT7620 has a MIPS 24kc core, thus you could optimize for that
>
> Okay.
>
> >> +       select OF_CONTROL
> >> +       select DM
> >> +       select DM_SERIAL
> >> +       select DM_SPI
> >> +       select DM_SPI_FLASH
> >> +       select DISPLAY_CPUINFO
> >> +
> >
> > could you sort this in alphabetic order?
>
> Okay, will do in v2.
>
> > There were some patches recently
> > which did the sorting tree wide. Also drop the SPI options until you add a
> > SPI driver.
>
> The SPI driver is also on the list:
>
> http://patchwork.ozlabs.org/patch/954365/

ok, I didn't received this one. But since SPI is not strictly
required, you should prefer "imply" instead of a hard "select".

>
> >>   config MACH_PIC32
> >>          bool "Support Microchip PIC32"
> >>          select DM
> >> @@ -141,6 +155,7 @@ source "board/qemu-mips/Kconfig"
> >>   source "arch/mips/mach-ath79/Kconfig"
> >>   source "arch/mips/mach-bmips/Kconfig"
> >>   source "arch/mips/mach-pic32/Kconfig"
> >> +source "arch/mips/mach-mt7620/Kconfig"
> >>
> >>   if MIPS
> >>
> >> diff --git a/arch/mips/Makefile b/arch/mips/Makefile
> >> index 5deec9a202..cc8ea5d7d4 100644
> >> --- a/arch/mips/Makefile
> >> +++ b/arch/mips/Makefile
> >> @@ -15,6 +15,7 @@ machine-$(CONFIG_SOC_AU1X00) += au1x00
> >>   machine-$(CONFIG_ARCH_ATH79) += ath79
> >>   machine-$(CONFIG_ARCH_BMIPS) += bmips
> >>   machine-$(CONFIG_MACH_PIC32) += pic32
> >> +machine-$(CONFIG_ARCH_MT7620) += mt7620
> >>
> >>   machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
> >>   libs-y += $(machdirs)
> >> diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig
> >> new file mode 100644
> >> index 0000000000..40e15b8a31
> >> --- /dev/null
> >> +++ b/arch/mips/mach-mt7620/Kconfig
> >> @@ -0,0 +1,130 @@
> >> +menu "MediaTek MIPS platforms"
> >> +       depends on ARCH_MT7620
> >> +
> >> +config SYS_MALLOC_F_LEN
> >> +       default 0x1000
> >> +
> >> +config SYS_SOC
> >> +       default "mt7620" if SOC_MT7620
> >> +
> >> +choice
> >> +       prompt "MediaTek MIPS SoC select"
> >> +
> >> +config SOC_MT7620
> >> +       bool "MT7620/8"
> >> +       select MIPS_L1_CACHE_SHIFT_5
> >> +       help
> >> +         This supports MediaTek MIPS MT7620 family.
> >> +
> >> +endchoice
> >> +
> >> +choice
> >> +       prompt "Board select"
> >> +
> >> +config BOARD_LINKIT_SMART_7688
> >> +       bool "LinkIt Smart 7688"
> >> +       depends on SOC_MT7620
> >> +       select SUPPORTS_BOOT_RAM
> >> +       help
> >> +         Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
> >> +         and 32 MiB of flash (SPI).
> >> +         Between its different peripherals there's an integrated switch with 4
> >> +         ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
> >> +         a MT7688 (PCIe).
> >
> > could you add this part with patch 3/4?
>
> Ah, yes. This slipped in too early.
>
> >> +
> >> +endchoice
> >> +
> >> +choice
> >> +       prompt "Boot mode"
> >> +
> >> +config BOOT_RAM
> >> +       bool "RAM boot"
> >> +       depends on SUPPORTS_BOOT_RAM
> >> +       select SKIP_LOWLEVEL_INIT
> >> +       help
> >> +         This builds an image that is linked to a RAM address. It can be used
> >> +         for booting from CFE via TFTP using an ELF image, but it can also be
> >> +         booted from RAM by other bootloaders using a BIN image.
> >> +
> >> +config BOOT_ROM
> >> +       bool "ROM boot"
> >> +       depends on SUPPORTS_BOOT_RAM
> >> +       help
> >> +         This builds an image that is linked to a ROM address. It can be
> >> +         used as main bootloader image which is programmed onto the onboard
> >> +         flash storage (SPI NOR).
> >> +
> >> +endchoice
> >> +
> >> +choice
> >> +       prompt "DDR2 size"
> >> +
> >> +config ONBOARD_DDR2_SIZE_256MBIT
> >> +       bool "256MBit (32MByte) total size"
> >> +       depends on BOOT_ROM
> >> +       help
> >> +         Use 256MBit (32MByte) of DDR total size
> >> +
> >> +config ONBOARD_DDR2_SIZE_512MBIT
> >> +       bool "512MBit (64MByte) total size"
> >> +       depends on BOOT_ROM
> >> +       help
> >> +         Use 512MBit (64MByte) of DDR total size
> >> +
> >> +config ONBOARD_DDR2_SIZE_1024MBIT
> >> +       bool "1024MBit (128MByte) total size"
> >> +       depends on BOOT_ROM
> >> +       help
> >> +         Use 1024MBit (128MByte) of DDR total size
> >> +
> >> +config ONBOARD_DDR2_SIZE_2048MBIT
> >> +       bool "2048MBit (256MByte) total size"
> >> +       depends on BOOT_ROM
> >> +       help
> >> +         Use 2048MBit (256MByte) of DDR total size
> >> +
> >> +endchoice
> >> +
> >> +choice
> >> +       prompt "DDR2 chip width"
> >> +
> >> +config ONBOARD_DDR2_CHIP_WIDTH_8BIT
> >> +       bool "8bit DDR chip width"
> >> +       depends on BOOT_ROM
> >> +       help
> >> +         Use DDR chips with 8bit width
> >> +
> >> +config ONBOARD_DDR2_CHIP_WIDTH_16BIT
> >> +       bool "16bit DDR chip width"
> >> +       depends on BOOT_ROM
> >> +       help
> >> +         Use DDR chips with 16bit width
> >> +
> >> +endchoice
> >> +
> >> +choice
> >> +       prompt "DDR2 bus width"
> >> +
> >> +config ONBOARD_DDR2_BUS_WIDTH_16BIT
> >> +       bool "16bit DDR bus width"
> >> +       depends on BOOT_ROM
> >> +       help
> >> +         Use 16bit DDR bus width
> >> +
> >> +config ONBOARD_DDR2_BUS_WIDTH_32BIT
> >> +       bool "32bit DDR bus width"
> >> +       depends on BOOT_ROM
> >> +       help
> >> +         Use 32bit DDR bus width
> >> +
> >> +endchoice
> >> +
> >> +config SUPPORTS_BOOT_RAM
> >> +       bool
> >> +
> >> +config SKIP_LOWLEVEL_INIT
> >> +       bool
> >
> > this is a legacy config option, thus you have to define it in your
> > board config header file.
> > MIPS shouldn't add a Kconfig symbol for that. This have to be migrated
> > to Kconfig tree-wide.
>
> Will move to config header for now.
>
> >> +
> >> +source "board/seeed/linkit-smart-7688/Kconfig"
> >
> > could you add this part with patch 3/4?
>
> Sure.
>
> >> +
> >> +endmenu
> >> diff --git a/arch/mips/mach-mt7620/Makefile b/arch/mips/mach-mt7620/Makefile
> >> new file mode 100644
> >> index 0000000000..1f3e65e8a5
> >> --- /dev/null
> >> +++ b/arch/mips/mach-mt7620/Makefile
> >> @@ -0,0 +1,8 @@
> >> +# SPDX-License-Identifier: GPL-2.0+
> >> +
> >> +obj-y += cpu.o
> >> +
> >> +ifndef CONFIG_SKIP_LOWLEVEL_INIT
> >> +obj-y += ddr_calibrate.o
> >> +obj-y += lowlevel_init.o
> >> +endif
> >> diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c
> >> new file mode 100644
> >> index 0000000000..0b22956499
> >> --- /dev/null
> >> +++ b/arch/mips/mach-mt7620/cpu.c
> >> @@ -0,0 +1,66 @@
> >> +// SPDX-License-Identifier: GPL-2.0+
> >> +/*
> >> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
> >> + */
> >> +
> >> +#include <common.h>
> >> +#include <dm.h>
> >> +#include <ram.h>
> >> +#include <asm/io.h>
> >> +#include <linux/io.h>
> >> +#include <linux/sizes.h>
> >> +#include "mt76xx.h"
> >> +
> >> +#define STR_LEN                        6
> >> +
> >> +#ifdef CONFIG_BOOT_ROM
> >> +int mach_cpu_init(void)
> >> +{
> >> +       void (*ptr)(void);
> >> +
> >> +       /*
> >> +        * DDR calibration routine needs to be called very early. This
> >> +        * function also configures the clock to run at full speed.
> >> +        */
> >> +       ptr = (void *)CKSEG0ADDR(ddr_calibrate);
> >> +       (*ptr)();
> >
> > what is the purpose of forcing the function symbol to KSEG0?
>
> Its copied from the original MediaTek code. I just tested it without
> forcing the execution into KSEG0 and the DDR calibration is extremely
> slow then, taking a few minutes to complete.
>
> I have to admit that I am not 100% sure, if the caches are configured
> 100% correctly / optimally for this SoC. Perhaps you (or someone else)
> has some improvements here.

I guess the BootROM does some XiP magic with the SPI flash controller
and runs in the uncached KSEG1 segment.
That would explain why the pre-relocation code runs so slowly. But
this shift from KSEG1 to KSEG0 could be done
generically in start.S after the cache initialization is complete. I
will have a look at it.

>
> >> +
> >> +       return 0;
> >> +}
> >> +#endif
> >> +
> >> +int print_cpuinfo(void)
> >> +{
> >> +       static const char * const boot_str[] = { "PLL (3-Byte SPI Addr)",
> >> +                                                "PLL (4-Byte SPI Addr)",
> >> +                                                "XTAL (3-Byte SPI Addr)",
> >> +                                                "XTAL (4-Byte SPI Addr)" };
> >> +       char *chr = (char *)MT76XX_CHIPID;
> >> +       char buf[STR_LEN + 1];
> >> +       u32 val;
> >> +
> >> +       snprintf(buf, STR_LEN + 1, "%s", chr);
> >> +       val = readl((void *)MT76XX_CHIP_REV_ID);
> >> +       printf("CPU:   %-*s Rev %ld.%ld - ", STR_LEN, buf,
> >> +              (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0));
> >> +
> >> +       val = (readl((void *)MT76XX_SYSCFG0) & GENMASK(3, 1)) >> 1;
> >> +       printf("Boot from %s\n", boot_str[val]);
> >
> > could you try to create a CPU driver like on BMIPS?
>
> Do you really think this is necessary just for printing some SoC
> information here?

according to the datasheet those registers are in the memory space of
the system controller block. Thus you should create at least a syscon
driver. Also the device tree you're going to add references this
syscon device.

>
> >> +
> >> +       return 0;
> >> +}
> >> +
> >> +void _machine_restart(void)
> >> +{
> >> +       writel(0x01, (void *)MT76XX_RSTCTL);
> >> +
> >> +       while (1)
> >> +               ;       /* NOP */
> >
> > could you try to create a reset controller driver? Then you could also
> > use the generic syscon-reboot driver.
>
> Yes, I also thought about this. Will do in v2.
>
> >> +}
> >> +
> >> +int dram_init(void)
> >> +{
> >> +       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
> >
> > shouldn't you return the real configured DRAM size here?
>
> I always like using get_ram_size() as it automatically detects the
> RAM size. This might be different (smaller) than the one configured,
> if HW problems with the DDR interface exist.
>
> We might think about printing a warning, if the detected size does not
> match the configured one.
>
> >> +
> >> +       return 0;
> >> +}
> >> diff --git a/arch/mips/mach-mt7620/ddr_calibrate.c b/arch/mips/mach-mt7620/ddr_calibrate.c
> >> new file mode 100644
> >> index 0000000000..6fd136674e
> >> --- /dev/null
> >> +++ b/arch/mips/mach-mt7620/ddr_calibrate.c
> >> @@ -0,0 +1,331 @@
> >> +// SPDX-License-Identifier: GPL-2.0+
> >> +/*
> >> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
> >> + *
> >> + * This code is mostly based on the code extracted from this MediaTek
> >> + * github repository:
> >> + *
> >> + * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
> >> + *
> >> + * I was not able to find a specific license or other developers
> >> + * copyrights here, so I can't add them here.
> >> + *
> >> + * Most functions in this file are copied from the MediaTek U-Boot
> >> + * repository. Without any documentation, it was impossible to really
> >> + * implement this differently. So its mostly a cleaned-up version of
> >> + * the original code, with only support for the MT7628 / MT7688 SoC.
> >> + */
> >> +
> >> +#include <common.h>
> >> +#include <linux/io.h>
> >> +#include <asm/cacheops.h>
> >> +#include <asm/io.h>
> >> +#include "mt76xx.h"
> >> +
> >> +#define NUM_OF_CACHELINE       64
> >> +#define MIN_START              6
> >> +#define MIN_FINE_START         0xf
> >> +#define MAX_START              7
> >> +#define MAX_FINE_START         0x0
> >> +
> >> +#define CPU_FRAC_DIV           1
> >> +
> >> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
> >> +#define DRAM_BUTTOM 0x02000000
> >> +#endif
> >> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
> >> +#define DRAM_BUTTOM 0x04000000
> >> +#endif
> >> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
> >> +#define DRAM_BUTTOM 0x08000000
> >> +#endif
> >> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
> >> +#define DRAM_BUTTOM 0x10000000
> >> +#endif
> >> +
> >> +static inline void cal_memcpy(void *src, void *dst, u32 size)
> >> +{
> >> +       u8 *psrc = (u8 *)src;
> >> +       u8 *pdst = (u8 *)dst;
> >> +       int i;
> >> +
> >> +       for (i = 0; i < size; i++, psrc++, pdst++)
> >> +               *pdst = *psrc;
> >> +}
> >> +
> >> +static inline void cal_memset(void *src, u8 pat, u32 size)
> >> +{
> >> +       u8 *psrc = (u8 *)src;
> >> +       int i;
> >> +
> >> +       for (i = 0; i < size; i++, psrc++)
> >> +               *psrc = pat;
> >> +}
> >> +
> >> +#define pref_op(hint, addr)                                            \
> >> +       __asm__ __volatile__(                                           \
> >> +               ".set   push\n"                                         \
> >> +               ".set   noreorder\n"                                    \
> >> +               "pref   %0, %1\n"                                       \
> >> +               ".set   pop\n"                                          \
> >> +               :                                                       \
> >> +               : "i" (hint), "R" (*(u8 *)(addr)))
> >> +
> >> +#define cache_op(op, addr)                                             \
> >> +       __asm__ __volatile__(                                           \
> >> +               ".set   push\n"                                         \
> >> +               ".set   noreorder\n"                                    \
> >> +               ".set   mips3\n"                                        \
> >> +               "cache  %0, %1\n"                                       \
> >> +               ".set   pop\n"                                          \
> >> +               :                                                       \
> >> +               : "i" (op), "R" (*(u8 *)(addr)))
> >
> > cache_op() is already available in arch/mips/include/asm/cacheops.h.
>
> Hmm, Where exactly?

sorry, I meant mips_cache()

>
> > Maybe you could add pref_op in the same way to that file.
>
> Could make sense, but please see above. Again, I'm still pretty new to
> MIPS and especially the caches.

I noticed prefetch() is already defined in
arch/mips/include/asm/processor.h. You could utilize it if you add a
boolean Kconfig option CONFIG_CPU_HAS_PREFETCH in arch/mips/Kconfig
and select it for MT7620.

>
> >> +
> >> +static inline void cal_invalidate_dcache_range(u32 start_addr, u32 stop)
> >> +{
> >> +       u32 lsize = CONFIG_SYS_CACHELINE_SIZE;
> >> +       u32 addr = start_addr & ~(lsize - 1);
> >> +       u32 aend = (stop - 1) & ~(lsize - 1);
> >> +
> >> +       while (1) {
> >> +               cache_op(HIT_INVALIDATE_D, addr);
> >> +               if (addr == aend)
> >> +                       break;
> >> +               addr += lsize;
> >> +       }
> >> +}
> >
> > you should use the generic MIPS implementation instead
>
> Yes, makes sense.
>
> Thanks,
> Stefan



--
- Daniel

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

* [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support
  2018-08-09 13:28     ` Daniel Schwierzeck
@ 2018-08-09 14:22       ` Stefan Roese
  2018-08-11 22:52         ` Daniel Schwierzeck
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Roese @ 2018-08-09 14:22 UTC (permalink / raw)
  To: u-boot

Hi Daniel,

On 09.08.2018 15:28, Daniel Schwierzeck wrote:
> Am Do., 9. Aug. 2018 um 12:46 Uhr schrieb Stefan Roese <sr@denx.de>:
>>
>> Hi Daniel,
>>
>> On 07.08.2018 17:44, Daniel Schwierzeck wrote:
>>> 2018-08-06 17:11 GMT+02:00 Stefan Roese <sr@denx.de>:
>>>> This patch adds basic support for the MediaTek MT7620/88 SoCs. Parts of
>>>> the code is copied from the MediaTek GitHub repository:
>>>>
>>>> https://github.com/MediaTek-Labs/linkit-smart-uboot.git
>>>>
>>>> Support for the LinkIt Smart 7688 module and the Gardena Smart Gateway
>>>> both based on the MT7688 will be added in further patches.
>>>>
>>>> Signed-off-by: Stefan Roese <sr@denx.de>
>>>> Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
>>>> ---
>>>>    arch/mips/Kconfig                     |  15 ++
>>>>    arch/mips/Makefile                    |   1 +
>>>>    arch/mips/mach-mt7620/Kconfig         | 130 ++++++++++
>>>>    arch/mips/mach-mt7620/Makefile        |   8 +
>>>>    arch/mips/mach-mt7620/cpu.c           |  66 +++++
>>>>    arch/mips/mach-mt7620/ddr_calibrate.c | 331 +++++++++++++++++++++++++
>>>>    arch/mips/mach-mt7620/lowlevel_init.S | 337 ++++++++++++++++++++++++++
>>>>    arch/mips/mach-mt7620/mt76xx.h        |  39 +++
>>>>    8 files changed, 927 insertions(+)
>>>>    create mode 100644 arch/mips/mach-mt7620/Kconfig
>>>>    create mode 100644 arch/mips/mach-mt7620/Makefile
>>>>    create mode 100644 arch/mips/mach-mt7620/cpu.c
>>>>    create mode 100644 arch/mips/mach-mt7620/ddr_calibrate.c
>>>>    create mode 100644 arch/mips/mach-mt7620/lowlevel_init.S
>>>>    create mode 100644 arch/mips/mach-mt7620/mt76xx.h
>>>>
>>>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>>>> index 31b622ff51..af791c320d 100644
>>>> --- a/arch/mips/Kconfig
>>>> +++ b/arch/mips/Kconfig
>>>> @@ -87,6 +87,20 @@ config ARCH_BMIPS
>>>>           select SYSRESET
>>>>           imply CMD_DM
>>>>
>>>> +config ARCH_MT7620
>>>> +       bool "Support MT7620/7688 SoCs"
>>>> +       select SUPPORTS_LITTLE_ENDIAN
>>>> +       select SUPPORTS_CPU_MIPS32_R1
>>>> +       select SUPPORTS_CPU_MIPS32_R2
>>>> +       select ROM_EXCEPTION_VECTORS
>>>> +       select MIPS_TUNE_4KC
>>>
>>> MT7620 has a MIPS 24kc core, thus you could optimize for that
>>
>> Okay.
>>
>>>> +       select OF_CONTROL
>>>> +       select DM
>>>> +       select DM_SERIAL
>>>> +       select DM_SPI
>>>> +       select DM_SPI_FLASH
>>>> +       select DISPLAY_CPUINFO
>>>> +
>>>
>>> could you sort this in alphabetic order?
>>
>> Okay, will do in v2.
>>
>>> There were some patches recently
>>> which did the sorting tree wide. Also drop the SPI options until you add a
>>> SPI driver.
>>
>> The SPI driver is also on the list:
>>
>> http://patchwork.ozlabs.org/patch/954365/
> 
> ok, I didn't received this one. But since SPI is not strictly
> required, you should prefer "imply" instead of a hard "select".

I've not seen an MT76xx board without SPI NOR flash, but this is
okay, I will turn this option into an "imply" instead in v2.

>>
>>>>    config MACH_PIC32
>>>>           bool "Support Microchip PIC32"
>>>>           select DM
>>>> @@ -141,6 +155,7 @@ source "board/qemu-mips/Kconfig"
>>>>    source "arch/mips/mach-ath79/Kconfig"
>>>>    source "arch/mips/mach-bmips/Kconfig"
>>>>    source "arch/mips/mach-pic32/Kconfig"
>>>> +source "arch/mips/mach-mt7620/Kconfig"
>>>>
>>>>    if MIPS
>>>>
>>>> diff --git a/arch/mips/Makefile b/arch/mips/Makefile
>>>> index 5deec9a202..cc8ea5d7d4 100644
>>>> --- a/arch/mips/Makefile
>>>> +++ b/arch/mips/Makefile
>>>> @@ -15,6 +15,7 @@ machine-$(CONFIG_SOC_AU1X00) += au1x00
>>>>    machine-$(CONFIG_ARCH_ATH79) += ath79
>>>>    machine-$(CONFIG_ARCH_BMIPS) += bmips
>>>>    machine-$(CONFIG_MACH_PIC32) += pic32
>>>> +machine-$(CONFIG_ARCH_MT7620) += mt7620
>>>>
>>>>    machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
>>>>    libs-y += $(machdirs)
>>>> diff --git a/arch/mips/mach-mt7620/Kconfig b/arch/mips/mach-mt7620/Kconfig
>>>> new file mode 100644
>>>> index 0000000000..40e15b8a31
>>>> --- /dev/null
>>>> +++ b/arch/mips/mach-mt7620/Kconfig
>>>> @@ -0,0 +1,130 @@
>>>> +menu "MediaTek MIPS platforms"
>>>> +       depends on ARCH_MT7620
>>>> +
>>>> +config SYS_MALLOC_F_LEN
>>>> +       default 0x1000
>>>> +
>>>> +config SYS_SOC
>>>> +       default "mt7620" if SOC_MT7620
>>>> +
>>>> +choice
>>>> +       prompt "MediaTek MIPS SoC select"
>>>> +
>>>> +config SOC_MT7620
>>>> +       bool "MT7620/8"
>>>> +       select MIPS_L1_CACHE_SHIFT_5
>>>> +       help
>>>> +         This supports MediaTek MIPS MT7620 family.
>>>> +
>>>> +endchoice
>>>> +
>>>> +choice
>>>> +       prompt "Board select"
>>>> +
>>>> +config BOARD_LINKIT_SMART_7688
>>>> +       bool "LinkIt Smart 7688"
>>>> +       depends on SOC_MT7620
>>>> +       select SUPPORTS_BOOT_RAM
>>>> +       help
>>>> +         Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
>>>> +         and 32 MiB of flash (SPI).
>>>> +         Between its different peripherals there's an integrated switch with 4
>>>> +         ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
>>>> +         a MT7688 (PCIe).
>>>
>>> could you add this part with patch 3/4?
>>
>> Ah, yes. This slipped in too early.
>>
>>>> +
>>>> +endchoice
>>>> +
>>>> +choice
>>>> +       prompt "Boot mode"
>>>> +
>>>> +config BOOT_RAM
>>>> +       bool "RAM boot"
>>>> +       depends on SUPPORTS_BOOT_RAM
>>>> +       select SKIP_LOWLEVEL_INIT
>>>> +       help
>>>> +         This builds an image that is linked to a RAM address. It can be used
>>>> +         for booting from CFE via TFTP using an ELF image, but it can also be
>>>> +         booted from RAM by other bootloaders using a BIN image.
>>>> +
>>>> +config BOOT_ROM
>>>> +       bool "ROM boot"
>>>> +       depends on SUPPORTS_BOOT_RAM
>>>> +       help
>>>> +         This builds an image that is linked to a ROM address. It can be
>>>> +         used as main bootloader image which is programmed onto the onboard
>>>> +         flash storage (SPI NOR).
>>>> +
>>>> +endchoice
>>>> +
>>>> +choice
>>>> +       prompt "DDR2 size"
>>>> +
>>>> +config ONBOARD_DDR2_SIZE_256MBIT
>>>> +       bool "256MBit (32MByte) total size"
>>>> +       depends on BOOT_ROM
>>>> +       help
>>>> +         Use 256MBit (32MByte) of DDR total size
>>>> +
>>>> +config ONBOARD_DDR2_SIZE_512MBIT
>>>> +       bool "512MBit (64MByte) total size"
>>>> +       depends on BOOT_ROM
>>>> +       help
>>>> +         Use 512MBit (64MByte) of DDR total size
>>>> +
>>>> +config ONBOARD_DDR2_SIZE_1024MBIT
>>>> +       bool "1024MBit (128MByte) total size"
>>>> +       depends on BOOT_ROM
>>>> +       help
>>>> +         Use 1024MBit (128MByte) of DDR total size
>>>> +
>>>> +config ONBOARD_DDR2_SIZE_2048MBIT
>>>> +       bool "2048MBit (256MByte) total size"
>>>> +       depends on BOOT_ROM
>>>> +       help
>>>> +         Use 2048MBit (256MByte) of DDR total size
>>>> +
>>>> +endchoice
>>>> +
>>>> +choice
>>>> +       prompt "DDR2 chip width"
>>>> +
>>>> +config ONBOARD_DDR2_CHIP_WIDTH_8BIT
>>>> +       bool "8bit DDR chip width"
>>>> +       depends on BOOT_ROM
>>>> +       help
>>>> +         Use DDR chips with 8bit width
>>>> +
>>>> +config ONBOARD_DDR2_CHIP_WIDTH_16BIT
>>>> +       bool "16bit DDR chip width"
>>>> +       depends on BOOT_ROM
>>>> +       help
>>>> +         Use DDR chips with 16bit width
>>>> +
>>>> +endchoice
>>>> +
>>>> +choice
>>>> +       prompt "DDR2 bus width"
>>>> +
>>>> +config ONBOARD_DDR2_BUS_WIDTH_16BIT
>>>> +       bool "16bit DDR bus width"
>>>> +       depends on BOOT_ROM
>>>> +       help
>>>> +         Use 16bit DDR bus width
>>>> +
>>>> +config ONBOARD_DDR2_BUS_WIDTH_32BIT
>>>> +       bool "32bit DDR bus width"
>>>> +       depends on BOOT_ROM
>>>> +       help
>>>> +         Use 32bit DDR bus width
>>>> +
>>>> +endchoice
>>>> +
>>>> +config SUPPORTS_BOOT_RAM
>>>> +       bool
>>>> +
>>>> +config SKIP_LOWLEVEL_INIT
>>>> +       bool
>>>
>>> this is a legacy config option, thus you have to define it in your
>>> board config header file.
>>> MIPS shouldn't add a Kconfig symbol for that. This have to be migrated
>>> to Kconfig tree-wide.
>>
>> Will move to config header for now.
>>
>>>> +
>>>> +source "board/seeed/linkit-smart-7688/Kconfig"
>>>
>>> could you add this part with patch 3/4?
>>
>> Sure.
>>
>>>> +
>>>> +endmenu
>>>> diff --git a/arch/mips/mach-mt7620/Makefile b/arch/mips/mach-mt7620/Makefile
>>>> new file mode 100644
>>>> index 0000000000..1f3e65e8a5
>>>> --- /dev/null
>>>> +++ b/arch/mips/mach-mt7620/Makefile
>>>> @@ -0,0 +1,8 @@
>>>> +# SPDX-License-Identifier: GPL-2.0+
>>>> +
>>>> +obj-y += cpu.o
>>>> +
>>>> +ifndef CONFIG_SKIP_LOWLEVEL_INIT
>>>> +obj-y += ddr_calibrate.o
>>>> +obj-y += lowlevel_init.o
>>>> +endif
>>>> diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c
>>>> new file mode 100644
>>>> index 0000000000..0b22956499
>>>> --- /dev/null
>>>> +++ b/arch/mips/mach-mt7620/cpu.c
>>>> @@ -0,0 +1,66 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +/*
>>>> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
>>>> + */
>>>> +
>>>> +#include <common.h>
>>>> +#include <dm.h>
>>>> +#include <ram.h>
>>>> +#include <asm/io.h>
>>>> +#include <linux/io.h>
>>>> +#include <linux/sizes.h>
>>>> +#include "mt76xx.h"
>>>> +
>>>> +#define STR_LEN                        6
>>>> +
>>>> +#ifdef CONFIG_BOOT_ROM
>>>> +int mach_cpu_init(void)
>>>> +{
>>>> +       void (*ptr)(void);
>>>> +
>>>> +       /*
>>>> +        * DDR calibration routine needs to be called very early. This
>>>> +        * function also configures the clock to run at full speed.
>>>> +        */
>>>> +       ptr = (void *)CKSEG0ADDR(ddr_calibrate);
>>>> +       (*ptr)();
>>>
>>> what is the purpose of forcing the function symbol to KSEG0?
>>
>> Its copied from the original MediaTek code. I just tested it without
>> forcing the execution into KSEG0 and the DDR calibration is extremely
>> slow then, taking a few minutes to complete.
>>
>> I have to admit that I am not 100% sure, if the caches are configured
>> 100% correctly / optimally for this SoC. Perhaps you (or someone else)
>> has some improvements here.
> 
> I guess the BootROM does some XiP magic with the SPI flash controller
> and runs in the uncached KSEG1 segment.
> That would explain why the pre-relocation code runs so slowly. But
> this shift from KSEG1 to KSEG0 could be done
> generically in start.S after the cache initialization is complete. I
> will have a look at it.

That would be great. Please let me know if you need some help with
testing etc.

>>
>>>> +
>>>> +       return 0;
>>>> +}
>>>> +#endif
>>>> +
>>>> +int print_cpuinfo(void)
>>>> +{
>>>> +       static const char * const boot_str[] = { "PLL (3-Byte SPI Addr)",
>>>> +                                                "PLL (4-Byte SPI Addr)",
>>>> +                                                "XTAL (3-Byte SPI Addr)",
>>>> +                                                "XTAL (4-Byte SPI Addr)" };
>>>> +       char *chr = (char *)MT76XX_CHIPID;
>>>> +       char buf[STR_LEN + 1];
>>>> +       u32 val;
>>>> +
>>>> +       snprintf(buf, STR_LEN + 1, "%s", chr);
>>>> +       val = readl((void *)MT76XX_CHIP_REV_ID);
>>>> +       printf("CPU:   %-*s Rev %ld.%ld - ", STR_LEN, buf,
>>>> +              (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0));
>>>> +
>>>> +       val = (readl((void *)MT76XX_SYSCFG0) & GENMASK(3, 1)) >> 1;
>>>> +       printf("Boot from %s\n", boot_str[val]);
>>>
>>> could you try to create a CPU driver like on BMIPS?
>>
>> Do you really think this is necessary just for printing some SoC
>> information here?
> 
> according to the datasheet those registers are in the memory space of
> the system controller block. Thus you should create at least a syscon
> driver. Also the device tree you're going to add references this
> syscon device.

Yes, this would be a plus, to get rid of the base address definition
in the header and use the DT here. I'll take a look...

>>
>>>> +
>>>> +       return 0;
>>>> +}
>>>> +
>>>> +void _machine_restart(void)
>>>> +{
>>>> +       writel(0x01, (void *)MT76XX_RSTCTL);
>>>> +
>>>> +       while (1)
>>>> +               ;       /* NOP */
>>>
>>> could you try to create a reset controller driver? Then you could also
>>> use the generic syscon-reboot driver.
>>
>> Yes, I also thought about this. Will do in v2.
>>
>>>> +}
>>>> +
>>>> +int dram_init(void)
>>>> +{
>>>> +       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
>>>
>>> shouldn't you return the real configured DRAM size here?
>>
>> I always like using get_ram_size() as it automatically detects the
>> RAM size. This might be different (smaller) than the one configured,
>> if HW problems with the DDR interface exist.
>>
>> We might think about printing a warning, if the detected size does not
>> match the configured one.
>>
>>>> +
>>>> +       return 0;
>>>> +}
>>>> diff --git a/arch/mips/mach-mt7620/ddr_calibrate.c b/arch/mips/mach-mt7620/ddr_calibrate.c
>>>> new file mode 100644
>>>> index 0000000000..6fd136674e
>>>> --- /dev/null
>>>> +++ b/arch/mips/mach-mt7620/ddr_calibrate.c
>>>> @@ -0,0 +1,331 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +/*
>>>> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
>>>> + *
>>>> + * This code is mostly based on the code extracted from this MediaTek
>>>> + * github repository:
>>>> + *
>>>> + * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
>>>> + *
>>>> + * I was not able to find a specific license or other developers
>>>> + * copyrights here, so I can't add them here.
>>>> + *
>>>> + * Most functions in this file are copied from the MediaTek U-Boot
>>>> + * repository. Without any documentation, it was impossible to really
>>>> + * implement this differently. So its mostly a cleaned-up version of
>>>> + * the original code, with only support for the MT7628 / MT7688 SoC.
>>>> + */
>>>> +
>>>> +#include <common.h>
>>>> +#include <linux/io.h>
>>>> +#include <asm/cacheops.h>
>>>> +#include <asm/io.h>
>>>> +#include "mt76xx.h"
>>>> +
>>>> +#define NUM_OF_CACHELINE       64
>>>> +#define MIN_START              6
>>>> +#define MIN_FINE_START         0xf
>>>> +#define MAX_START              7
>>>> +#define MAX_FINE_START         0x0
>>>> +
>>>> +#define CPU_FRAC_DIV           1
>>>> +
>>>> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
>>>> +#define DRAM_BUTTOM 0x02000000
>>>> +#endif
>>>> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
>>>> +#define DRAM_BUTTOM 0x04000000
>>>> +#endif
>>>> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
>>>> +#define DRAM_BUTTOM 0x08000000
>>>> +#endif
>>>> +#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
>>>> +#define DRAM_BUTTOM 0x10000000
>>>> +#endif
>>>> +
>>>> +static inline void cal_memcpy(void *src, void *dst, u32 size)
>>>> +{
>>>> +       u8 *psrc = (u8 *)src;
>>>> +       u8 *pdst = (u8 *)dst;
>>>> +       int i;
>>>> +
>>>> +       for (i = 0; i < size; i++, psrc++, pdst++)
>>>> +               *pdst = *psrc;
>>>> +}
>>>> +
>>>> +static inline void cal_memset(void *src, u8 pat, u32 size)
>>>> +{
>>>> +       u8 *psrc = (u8 *)src;
>>>> +       int i;
>>>> +
>>>> +       for (i = 0; i < size; i++, psrc++)
>>>> +               *psrc = pat;
>>>> +}
>>>> +
>>>> +#define pref_op(hint, addr)                                            \
>>>> +       __asm__ __volatile__(                                           \
>>>> +               ".set   push\n"                                         \
>>>> +               ".set   noreorder\n"                                    \
>>>> +               "pref   %0, %1\n"                                       \
>>>> +               ".set   pop\n"                                          \
>>>> +               :                                                       \
>>>> +               : "i" (hint), "R" (*(u8 *)(addr)))
>>>> +
>>>> +#define cache_op(op, addr)                                             \
>>>> +       __asm__ __volatile__(                                           \
>>>> +               ".set   push\n"                                         \
>>>> +               ".set   noreorder\n"                                    \
>>>> +               ".set   mips3\n"                                        \
>>>> +               "cache  %0, %1\n"                                       \
>>>> +               ".set   pop\n"                                          \
>>>> +               :                                                       \
>>>> +               : "i" (op), "R" (*(u8 *)(addr)))
>>>
>>> cache_op() is already available in arch/mips/include/asm/cacheops.h.
>>
>> Hmm, Where exactly?
> 
> sorry, I meant mips_cache()

Not needed anymore when moved to using the generic invalidate
dcache function.

>>
>>> Maybe you could add pref_op in the same way to that file.
>>
>> Could make sense, but please see above. Again, I'm still pretty new to
>> MIPS and especially the caches.
> 
> I noticed prefetch() is already defined in
> arch/mips/include/asm/processor.h. You could utilize it if you add a
> boolean Kconfig option CONFIG_CPU_HAS_PREFETCH in arch/mips/Kconfig
> and select it for MT7620.

Yes. But which implementation is the correct one for this SoC?

#define PREF(hint, addr)				\
		.set	push;				\
		.set	arch=r5000;			\
		pref	hint, addr;			\
		.set	pop

#define PREFE(hint, addr)				\
		.set	push;				\
		.set	mips0;				\
		.set	eva;				\
		prefe	hint, addr;			\
		.set	pop

#define PREFX(hint, addr)				\
		.set	push;				\
		.set	arch=r5000;			\
		prefx	hint, addr;			\
		.set	pop

Thanks,
Stefan

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

* [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support
  2018-08-09 14:22       ` Stefan Roese
@ 2018-08-11 22:52         ` Daniel Schwierzeck
  2018-08-15  6:22           ` Stefan Roese
  0 siblings, 1 reply; 13+ messages in thread
From: Daniel Schwierzeck @ 2018-08-11 22:52 UTC (permalink / raw)
  To: u-boot



On 09.08.2018 16:22, Stefan Roese wrote:

>>>>> diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c
>>>>> new file mode 100644
>>>>> index 0000000000..0b22956499
>>>>> --- /dev/null
>>>>> +++ b/arch/mips/mach-mt7620/cpu.c
>>>>> @@ -0,0 +1,66 @@
>>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>>> +/*
>>>>> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
>>>>> + */
>>>>> +
>>>>> +#include <common.h>
>>>>> +#include <dm.h>
>>>>> +#include <ram.h>
>>>>> +#include <asm/io.h>
>>>>> +#include <linux/io.h>
>>>>> +#include <linux/sizes.h>
>>>>> +#include "mt76xx.h"
>>>>> +
>>>>> +#define STR_LEN                        6
>>>>> +
>>>>> +#ifdef CONFIG_BOOT_ROM
>>>>> +int mach_cpu_init(void)
>>>>> +{
>>>>> +       void (*ptr)(void);
>>>>> +
>>>>> +       /*
>>>>> +        * DDR calibration routine needs to be called very early. This
>>>>> +        * function also configures the clock to run at full speed.
>>>>> +        */
>>>>> +       ptr = (void *)CKSEG0ADDR(ddr_calibrate);
>>>>> +       (*ptr)();
>>>>
>>>> what is the purpose of forcing the function symbol to KSEG0?
>>>
>>> Its copied from the original MediaTek code. I just tested it without
>>> forcing the execution into KSEG0 and the DDR calibration is extremely
>>> slow then, taking a few minutes to complete.
>>>
>>> I have to admit that I am not 100% sure, if the caches are configured
>>> 100% correctly / optimally for this SoC. Perhaps you (or someone else)
>>> has some improvements here.
>>
>> I guess the BootROM does some XiP magic with the SPI flash controller
>> and runs in the uncached KSEG1 segment.
>> That would explain why the pre-relocation code runs so slowly. But
>> this shift from KSEG1 to KSEG0 could be done
>> generically in start.S after the cache initialization is complete. I
>> will have a look at it.
> 
> That would be great. Please let me know if you need some help with
> testing etc.
> 

could you try branch mips_optimize_cache_init from
git://git.denx.de/u-boot-mips.git. You have to change your text base
from 0xbc000000 to 0x9c000000 to execute all code prior relocation from
the cached KSEG0 segment. The code should now run fast without that
function pointer magic.

For now the patch series is only tested in Qemu and needs some more
cleanup. I'll try to do some testing on real hardware in the next days.

-- 
- Daniel

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180812/bba228e3/attachment.sig>

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

* [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support
  2018-08-11 22:52         ` Daniel Schwierzeck
@ 2018-08-15  6:22           ` Stefan Roese
  0 siblings, 0 replies; 13+ messages in thread
From: Stefan Roese @ 2018-08-15  6:22 UTC (permalink / raw)
  To: u-boot

Hi Daniel,

On 12.08.2018 00:52, Daniel Schwierzeck wrote:
> 
> 
> On 09.08.2018 16:22, Stefan Roese wrote:
> 
>>>>>> diff --git a/arch/mips/mach-mt7620/cpu.c b/arch/mips/mach-mt7620/cpu.c
>>>>>> new file mode 100644
>>>>>> index 0000000000..0b22956499
>>>>>> --- /dev/null
>>>>>> +++ b/arch/mips/mach-mt7620/cpu.c
>>>>>> @@ -0,0 +1,66 @@
>>>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>>>> +/*
>>>>>> + * Copyright (C) 2018 Stefan Roese <sr@denx.de>
>>>>>> + */
>>>>>> +
>>>>>> +#include <common.h>
>>>>>> +#include <dm.h>
>>>>>> +#include <ram.h>
>>>>>> +#include <asm/io.h>
>>>>>> +#include <linux/io.h>
>>>>>> +#include <linux/sizes.h>
>>>>>> +#include "mt76xx.h"
>>>>>> +
>>>>>> +#define STR_LEN                        6
>>>>>> +
>>>>>> +#ifdef CONFIG_BOOT_ROM
>>>>>> +int mach_cpu_init(void)
>>>>>> +{
>>>>>> +       void (*ptr)(void);
>>>>>> +
>>>>>> +       /*
>>>>>> +        * DDR calibration routine needs to be called very early. This
>>>>>> +        * function also configures the clock to run at full speed.
>>>>>> +        */
>>>>>> +       ptr = (void *)CKSEG0ADDR(ddr_calibrate);
>>>>>> +       (*ptr)();
>>>>>
>>>>> what is the purpose of forcing the function symbol to KSEG0?
>>>>
>>>> Its copied from the original MediaTek code. I just tested it without
>>>> forcing the execution into KSEG0 and the DDR calibration is extremely
>>>> slow then, taking a few minutes to complete.
>>>>
>>>> I have to admit that I am not 100% sure, if the caches are configured
>>>> 100% correctly / optimally for this SoC. Perhaps you (or someone else)
>>>> has some improvements here.
>>>
>>> I guess the BootROM does some XiP magic with the SPI flash controller
>>> and runs in the uncached KSEG1 segment.
>>> That would explain why the pre-relocation code runs so slowly. But
>>> this shift from KSEG1 to KSEG0 could be done
>>> generically in start.S after the cache initialization is complete. I
>>> will have a look at it.
>>
>> That would be great. Please let me know if you need some help with
>> testing etc.
>>
> 
> could you try branch mips_optimize_cache_init from
> git://git.denx.de/u-boot-mips.git. You have to change your text base
> from 0xbc000000 to 0x9c000000 to execute all code prior relocation from
> the cached KSEG0 segment. The code should now run fast without that
> function pointer magic.
> 
> For now the patch series is only tested in Qemu and needs some more
> cleanup. I'll try to do some testing on real hardware in the next days.

I'm back from a short trip and tested these 2 patches in my current
internal branch. It works great, thanks! The speedup is impressive.

How would you like to proceed? Should I re-send my MT7688 SoC port
again with the functions pointer magic removed? Or will you pull this
version first and your cache improvement later? I can always change
this ddr_calibrate() pointer magic at a later time (and change the
TEXT_BASE).

Thanks,
Stefan

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

end of thread, other threads:[~2018-08-15  6:22 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-06 15:11 [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Stefan Roese
2018-08-06 15:11 ` [U-Boot] [PATCH 2/4] mips: Add arch/mips/include/asm/atomic.h Stefan Roese
2018-08-07 14:51   ` Daniel Schwierzeck
2018-08-09  9:27     ` Stefan Roese
2018-08-09 10:20       ` Daniel Schwierzeck
2018-08-06 15:11 ` [U-Boot] [PATCH 3/4] mips: Add LinkIt Smart 7688 support Stefan Roese
2018-08-06 15:11 ` [U-Boot] [PATCH 4/4] mips: Add Gardena Smart-Gateway board support Stefan Roese
2018-08-07 15:44 ` [U-Boot] [PATCH 1/4] mips: Add basic MediaTek MT7620/88 support Daniel Schwierzeck
2018-08-09 10:46   ` Stefan Roese
2018-08-09 13:28     ` Daniel Schwierzeck
2018-08-09 14:22       ` Stefan Roese
2018-08-11 22:52         ` Daniel Schwierzeck
2018-08-15  6:22           ` Stefan Roese

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.