select SYSRESET
imply CMD_DM
-config ARCH_MT7620
- bool "Support MT7620/7688 SoCs"
+config ARCH_MTMIPS
+ bool "Support MediaTek MIPS platforms"
imply CMD_DM
select DISPLAY_CPUINFO
select DM
source "arch/mips/mach-bmips/Kconfig"
source "arch/mips/mach-jz47xx/Kconfig"
source "arch/mips/mach-pic32/Kconfig"
-source "arch/mips/mach-mt7620/Kconfig"
+source "arch/mips/mach-mtmips/Kconfig"
if MIPS
machine-$(CONFIG_ARCH_BMIPS) += bmips
machine-$(CONFIG_ARCH_JZ47XX) += jz47xx
machine-$(CONFIG_MACH_PIC32) += pic32
-machine-$(CONFIG_ARCH_MT7620) += mt7620
+machine-$(CONFIG_ARCH_MTMIPS) += mtmips
machine-$(CONFIG_ARCH_MSCC) += mscc
machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
# SPDX-License-Identifier: GPL-2.0+
-dtb-$(CONFIG_ARCH_MT7620) += \
+dtb-$(CONFIG_ARCH_MTMIPS) += \
gardena-smart-gateway-mt7688.dtb \
linkit-smart-7688.dtb
dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
+++ /dev/null
-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_GARDENA_SMART_GATEWAY_MT7688
- bool "GARDENA smart Gateway"
- depends on SOC_MT7620
- select BOARD_LATE_INIT
- 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
- 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
- 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
-
-source "board/gardena/smart-gateway-mt7688/Kconfig"
-source "board/seeed/linkit-smart-7688/Kconfig"
-
-endmenu
+++ /dev/null
-# 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
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2018 Stefan Roese <sr@denx.de>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <ram.h>
-#include <wdt.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)
-{
- ddr_calibrate();
-
- return 0;
-}
-#endif
-
-int dram_init(void)
-{
- gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
-
- return 0;
-}
-
-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)" };
- const void *blob = gd->fdt_blob;
- void __iomem *sysc_base;
- char buf[STR_LEN + 1];
- fdt_addr_t base;
- fdt_size_t size;
- char *str;
- int node;
- u32 val;
-
- /* Get system controller base address */
- node = fdt_node_offset_by_compatible(blob, -1, "ralink,mt7620a-sysc");
- if (node < 0)
- return -FDT_ERR_NOTFOUND;
-
- base = fdtdec_get_addr_size_auto_noparent(blob, node, "reg",
- 0, &size, true);
- if (base == FDT_ADDR_T_NONE)
- return -EINVAL;
-
- sysc_base = ioremap_nocache(base, size);
-
- str = (char *)sysc_base + MT76XX_CHIPID_OFFS;
- snprintf(buf, STR_LEN + 1, "%s", str);
- val = readl(sysc_base + MT76XX_CHIP_REV_ID_OFFS);
- printf("CPU: %-*s Rev %ld.%ld - ", STR_LEN, buf,
- (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0));
-
- val = (readl(sysc_base + MT76XX_SYSCFG0_OFFS) & GENMASK(3, 1)) >> 1;
- printf("Boot from %s\n", boot_str[val]);
-
- return 0;
-}
-
-int arch_misc_init(void)
-{
- /*
- * It has been noticed, that sometimes the d-cache is not in a
- * "clean-state" when U-Boot is running on MT7688. This was
- * detected when using the ethernet driver (which uses d-cache)
- * and a TFTP command does not complete. Flushing the complete
- * d-cache (again?) here seems to fix this issue.
- */
- flush_dcache_range(gd->bd->bi_memstart,
- gd->bd->bi_memstart + gd->ram_size - 1);
-
- return 0;
-}
+++ /dev/null
-// 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 128
-#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)))
-
-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, (void *)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),
- (void *)MT76XX_MEMCTRL_BASE + 0x64);
- else
- writel(0x00007400 |
- (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 4) |
- (((k == 0) ? val : test_dqs) << 0),
- (void *)MT76XX_MEMCTRL_BASE + 0x64);
- wmb(); /* Make sure store if finished */
-
- 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((void *)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((void *)MT76XX_DYN_CFG0_REG);
- fdiv = (val >> 8) & 0x0f;
- fdiv--;
- val &= ~(0x0f << 8);
- val |= (fdiv << 8);
- writel(val, (void *)MT76XX_DYN_CFG0_REG);
- udelay(500);
- val = readl((void *)MT76XX_DYN_CFG0_REG);
- fdiv = (val >> 8) & 0x0f;
- }
-
- clrbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
- ddr_cfg2_reg = readl((void *)MT76XX_MEMCTRL_BASE + 0x48);
- clrbits_le32((void *)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((void *)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((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
- writel(reg, (void *)MT76XX_MEMCTRL_BASE + 0x64);
- writel(ddr_cfg2_reg, (void *)MT76XX_MEMCTRL_BASE + 0x48);
- setbits_le32((void *)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);
-}
+++ /dev/null
-/* 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/addrspace.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
-
- .set noreorder
-
-LEAF(lowlevel_init)
-
- /* Load base addresses as physical addresses for later usage */
- li s0, CKSEG1ADDR(MT76XX_SYSCTL_BASE)
- li s1, CKSEG1ADDR(MT76XX_MEMCTRL_BASE)
- li s2, CKSEG1ADDR(MT76XX_RGCTRL_BASE)
-
- /* 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)
- b 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:
- /* Reset MC */
- lw t2, 0x34(s0)
- ori t2, BIT(10)
- sw t2, 0x34(s0)
- nop
-
- /*
- * 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 */
- lw t4, 0x100(s2)
- li t2, BIT(31)
- or t4, t4, t2
- sw t4, 0x100(s2)
- lw t4, 0x10c(s2)
- j LDO_1P8V
- nop
-LDO_1P8V:
- li t2, ~BIT(6)
- and t4, t4, t2
- sw t4, 0x10c(s2)
- j DDRLDO_SOFT_START
-LDO_2P5V:
- /* suppose external DDR1 LDO 2.5V */
- li t2, BIT(6)
- or t4, t4, t2
- sw t4, 0x10c(s2)
-
-DDRLDO_SOFT_START:
- lw t2, 0x10c(s2)
- li t3, BIT(16)
- or t2, t2, t3
- sw t2, 0x10c(s2)
- li t3, DELAY_USEC(250*50)
-LDO_DELAY:
- subu t3, t3, 1
- bnez t3, LDO_DELAY
- nop
-
- lw t2, 0x10c(s2)
- li t3, BIT(18)
- or t2, t2, t3
- sw t2, 0x10c(s2)
-
-SET_RG_BUCK_FPWM:
- lw t2, 0x104(s2)
- ori t2, t2, BIT(10)
- sw t2, 0x104(s2)
-
-DDR_PAD_CFG:
- /* clean CLK PAD */
- lw t2, 0x704(s2)
- li t8, 0xfffff0f0
- and t2, t2, t8
- /* clean CMD PAD */
- lw t3, 0x70c(s2)
- li t8, 0xfffff0f0
- and t3, t3, t8
- /* clean DQ IPAD */
- lw t4, 0x710(s2)
- li t8, 0xfffff8ff
- and t4, t4, t8
- /* clean DQ OPAD */
- lw t5, 0x714(s2)
- li t8, 0xfffff0f0
- and t5, t5, t8
- /* clean DQS IPAD */
- lw t6, 0x718(s2)
- li t8, 0xfffff8ff
- and t6, t6, t8
- /* clean DQS OPAD */
- lw t7, 0x71c(s2)
- li t8, 0xfffff0f0
- and t7, t7, t8
-
- lw t9, 0xc(s0)
- 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:
- lw t1, 0x10(s0)
- 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:
- sw t2, 0x704(s2)
- sw t3, 0x70c(s2)
- sw t4, 0x710(s2)
- sw t5, 0x714(s2)
- sw t6, 0x718(s2)
- sw t7, 0x71c(s2)
-
- /*
- * DDR initialization: reset pin to 0
- */
- lw t2, 0x34(s0)
- and t2, ~BIT(10)
- sw t2, 0x34(s0)
- 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)
- */
- lw t1, 0x14(s1)
- nop
- and t1, 0xff000000
- or t1, 0x01
- sw t1, 0x14(s1)
- nop
- lw t1, 0x10(s1)
- nop
- or t1, 0x10
- sw t1, 0x10(s1)
- nop
-
- jr ra
- nop
- END(lowlevel_init)
+++ /dev/null
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2018 Stefan Roese <sr@denx.de>
- */
-
-#ifndef __MT76XX_H
-#define __MT76XX_H
-
-#define MT76XX_SYSCTL_BASE 0x10000000
-
-#define MT76XX_CHIPID_OFFS 0x00
-#define MT76XX_CHIP_REV_ID_OFFS 0x0c
-#define MT76XX_SYSCFG0_OFFS 0x10
-
-#define MT76XX_MEMCTRL_BASE (MT76XX_SYSCTL_BASE + 0x0300)
-#define MT76XX_RGCTRL_BASE (MT76XX_SYSCTL_BASE + 0x1000)
-
-#define MT76XX_ROM_STATUS_REG (MT76XX_SYSCTL_BASE + 0x0028)
-#define MT76XX_CLKCFG0_REG (MT76XX_SYSCTL_BASE + 0x002c)
-#define MT76XX_DYN_CFG0_REG (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
--- /dev/null
+menu "MediaTek MIPS platforms"
+ depends on ARCH_MTMIPS
+
+config SYS_MALLOC_F_LEN
+ default 0x1000
+
+config SYS_SOC
+ default "mt7628" if SOC_MT7628
+
+choice
+ prompt "MediaTek MIPS SoC select"
+
+config SOC_MT7628
+ bool "MT7628"
+ select MIPS_L1_CACHE_SHIFT_5
+ help
+ This supports MediaTek MT7628/MT7688.
+
+endchoice
+
+choice
+ prompt "Board select"
+
+config BOARD_GARDENA_SMART_GATEWAY_MT7688
+ bool "GARDENA smart Gateway"
+ depends on SOC_MT7628
+ select BOARD_LATE_INIT
+ 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_MT7628
+ 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
+ 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
+
+source "board/gardena/smart-gateway-mt7688/Kconfig"
+source "board/seeed/linkit-smart-7688/Kconfig"
+
+endmenu
--- /dev/null
+# 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
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <wdt.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)
+{
+ ddr_calibrate();
+
+ return 0;
+}
+#endif
+
+int dram_init(void)
+{
+ gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
+
+ return 0;
+}
+
+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)" };
+ const void *blob = gd->fdt_blob;
+ void __iomem *sysc_base;
+ char buf[STR_LEN + 1];
+ fdt_addr_t base;
+ fdt_size_t size;
+ char *str;
+ int node;
+ u32 val;
+
+ /* Get system controller base address */
+ node = fdt_node_offset_by_compatible(blob, -1, "ralink,mt7620a-sysc");
+ if (node < 0)
+ return -FDT_ERR_NOTFOUND;
+
+ base = fdtdec_get_addr_size_auto_noparent(blob, node, "reg",
+ 0, &size, true);
+ if (base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ sysc_base = ioremap_nocache(base, size);
+
+ str = (char *)sysc_base + MT76XX_CHIPID_OFFS;
+ snprintf(buf, STR_LEN + 1, "%s", str);
+ val = readl(sysc_base + MT76XX_CHIP_REV_ID_OFFS);
+ printf("CPU: %-*s Rev %ld.%ld - ", STR_LEN, buf,
+ (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0));
+
+ val = (readl(sysc_base + MT76XX_SYSCFG0_OFFS) & GENMASK(3, 1)) >> 1;
+ printf("Boot from %s\n", boot_str[val]);
+
+ return 0;
+}
+
+int arch_misc_init(void)
+{
+ /*
+ * It has been noticed, that sometimes the d-cache is not in a
+ * "clean-state" when U-Boot is running on MT7688. This was
+ * detected when using the ethernet driver (which uses d-cache)
+ * and a TFTP command does not complete. Flushing the complete
+ * d-cache (again?) here seems to fix this issue.
+ */
+ flush_dcache_range(gd->bd->bi_memstart,
+ gd->bd->bi_memstart + gd->ram_size - 1);
+
+ return 0;
+}
--- /dev/null
+// 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 128
+#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)))
+
+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, (void *)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),
+ (void *)MT76XX_MEMCTRL_BASE + 0x64);
+ else
+ writel(0x00007400 |
+ (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 4) |
+ (((k == 0) ? val : test_dqs) << 0),
+ (void *)MT76XX_MEMCTRL_BASE + 0x64);
+ wmb(); /* Make sure store if finished */
+
+ 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((void *)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((void *)MT76XX_DYN_CFG0_REG);
+ fdiv = (val >> 8) & 0x0f;
+ fdiv--;
+ val &= ~(0x0f << 8);
+ val |= (fdiv << 8);
+ writel(val, (void *)MT76XX_DYN_CFG0_REG);
+ udelay(500);
+ val = readl((void *)MT76XX_DYN_CFG0_REG);
+ fdiv = (val >> 8) & 0x0f;
+ }
+
+ clrbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
+ ddr_cfg2_reg = readl((void *)MT76XX_MEMCTRL_BASE + 0x48);
+ clrbits_le32((void *)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((void *)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((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
+ writel(reg, (void *)MT76XX_MEMCTRL_BASE + 0x64);
+ writel(ddr_cfg2_reg, (void *)MT76XX_MEMCTRL_BASE + 0x48);
+ setbits_le32((void *)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);
+}
--- /dev/null
+/* 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/addrspace.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
+
+ .set noreorder
+
+LEAF(lowlevel_init)
+
+ /* Load base addresses as physical addresses for later usage */
+ li s0, CKSEG1ADDR(MT76XX_SYSCTL_BASE)
+ li s1, CKSEG1ADDR(MT76XX_MEMCTRL_BASE)
+ li s2, CKSEG1ADDR(MT76XX_RGCTRL_BASE)
+
+ /* 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)
+ b 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:
+ /* Reset MC */
+ lw t2, 0x34(s0)
+ ori t2, BIT(10)
+ sw t2, 0x34(s0)
+ nop
+
+ /*
+ * 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 */
+ lw t4, 0x100(s2)
+ li t2, BIT(31)
+ or t4, t4, t2
+ sw t4, 0x100(s2)
+ lw t4, 0x10c(s2)
+ j LDO_1P8V
+ nop
+LDO_1P8V:
+ li t2, ~BIT(6)
+ and t4, t4, t2
+ sw t4, 0x10c(s2)
+ j DDRLDO_SOFT_START
+LDO_2P5V:
+ /* suppose external DDR1 LDO 2.5V */
+ li t2, BIT(6)
+ or t4, t4, t2
+ sw t4, 0x10c(s2)
+
+DDRLDO_SOFT_START:
+ lw t2, 0x10c(s2)
+ li t3, BIT(16)
+ or t2, t2, t3
+ sw t2, 0x10c(s2)
+ li t3, DELAY_USEC(250*50)
+LDO_DELAY:
+ subu t3, t3, 1
+ bnez t3, LDO_DELAY
+ nop
+
+ lw t2, 0x10c(s2)
+ li t3, BIT(18)
+ or t2, t2, t3
+ sw t2, 0x10c(s2)
+
+SET_RG_BUCK_FPWM:
+ lw t2, 0x104(s2)
+ ori t2, t2, BIT(10)
+ sw t2, 0x104(s2)
+
+DDR_PAD_CFG:
+ /* clean CLK PAD */
+ lw t2, 0x704(s2)
+ li t8, 0xfffff0f0
+ and t2, t2, t8
+ /* clean CMD PAD */
+ lw t3, 0x70c(s2)
+ li t8, 0xfffff0f0
+ and t3, t3, t8
+ /* clean DQ IPAD */
+ lw t4, 0x710(s2)
+ li t8, 0xfffff8ff
+ and t4, t4, t8
+ /* clean DQ OPAD */
+ lw t5, 0x714(s2)
+ li t8, 0xfffff0f0
+ and t5, t5, t8
+ /* clean DQS IPAD */
+ lw t6, 0x718(s2)
+ li t8, 0xfffff8ff
+ and t6, t6, t8
+ /* clean DQS OPAD */
+ lw t7, 0x71c(s2)
+ li t8, 0xfffff0f0
+ and t7, t7, t8
+
+ lw t9, 0xc(s0)
+ 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:
+ lw t1, 0x10(s0)
+ 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:
+ sw t2, 0x704(s2)
+ sw t3, 0x70c(s2)
+ sw t4, 0x710(s2)
+ sw t5, 0x714(s2)
+ sw t6, 0x718(s2)
+ sw t7, 0x71c(s2)
+
+ /*
+ * DDR initialization: reset pin to 0
+ */
+ lw t2, 0x34(s0)
+ and t2, ~BIT(10)
+ sw t2, 0x34(s0)
+ 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)
+ */
+ lw t1, 0x14(s1)
+ nop
+ and t1, 0xff000000
+ or t1, 0x01
+ sw t1, 0x14(s1)
+ nop
+ lw t1, 0x10(s1)
+ nop
+ or t1, 0x10
+ sw t1, 0x10(s1)
+ nop
+
+ jr ra
+ nop
+ END(lowlevel_init)
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Stefan Roese <sr@denx.de>
+ */
+
+#ifndef __MT76XX_H
+#define __MT76XX_H
+
+#define MT76XX_SYSCTL_BASE 0x10000000
+
+#define MT76XX_CHIPID_OFFS 0x00
+#define MT76XX_CHIP_REV_ID_OFFS 0x0c
+#define MT76XX_SYSCFG0_OFFS 0x10
+
+#define MT76XX_MEMCTRL_BASE (MT76XX_SYSCTL_BASE + 0x0300)
+#define MT76XX_RGCTRL_BASE (MT76XX_SYSCTL_BASE + 0x1000)
+
+#define MT76XX_ROM_STATUS_REG (MT76XX_SYSCTL_BASE + 0x0028)
+#define MT76XX_CLKCFG0_REG (MT76XX_SYSCTL_BASE + 0x002c)
+#define MT76XX_DYN_CFG0_REG (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
CONFIG_MIPS=y
CONFIG_SYS_TEXT_BASE=0x80010000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_ARCH_MT7620=y
+CONFIG_ARCH_MTMIPS=y
# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
CONFIG_MIPS_BOOT_FDT=y
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_MIPS=y
CONFIG_SYS_TEXT_BASE=0x9c000000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_ARCH_MT7620=y
+CONFIG_ARCH_MTMIPS=y
CONFIG_BOOT_ROM=y
CONFIG_ONBOARD_DDR2_SIZE_1024MBIT=y
CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT=y
CONFIG_MIPS=y
CONFIG_SYS_TEXT_BASE=0x80010000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_ARCH_MT7620=y
+CONFIG_ARCH_MTMIPS=y
CONFIG_BOARD_LINKIT_SMART_7688=y
# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
CONFIG_MIPS_BOOT_FDT=y
CONFIG_MIPS=y
CONFIG_SYS_TEXT_BASE=0x9c000000
CONFIG_NR_DRAM_BANKS=1
-CONFIG_ARCH_MT7620=y
+CONFIG_ARCH_MTMIPS=y
CONFIG_BOARD_LINKIT_SMART_7688=y
CONFIG_BOOT_ROM=y
CONFIG_ONBOARD_DDR2_SIZE_1024MBIT=y
config MT7621_GPIO
bool "MediaTek MT7621 GPIO driver"
- depends on DM_GPIO && ARCH_MT7620
+ depends on DM_GPIO && SOC_MT7628
default y
help
Say yes here to support MediaTek MT7621 compatible GPIOs.
config MT7628_ETH
bool "MediaTek MT7628 Ethernet Interface"
- depends on ARCH_MT7620
+ depends on SOC_MT7628
help
The MediaTek MT7628 ethernet interface is used on MT7628 and
MT7688 based boards.
config MT7621_SPI
bool "MediaTek MT7621 SPI driver"
- depends on ARCH_MT7620
+ depends on SOC_MT7628
help
Enable the MT7621 SPI driver. This driver can be used to access
the SPI NOR flash on platforms embedding this Ralink / MediaTek
config WDT_MT7621
bool "MediaTek MT7621 watchdog timer support"
- depends on WDT && ARCH_MT7620
+ depends on WDT && SOC_MT7628
help
Select this to enable Ralink / Mediatek watchdog timer,
which can be found on some MediaTek chips.