mips: mtmips: rewrite lowlevel codes of mt7628

This patch rewrites the mtmips architecture with the following changes:

1. Move MT7628 soc parts into a subfolder.
2. Lock parts of D-Cache as temporary stack.
3. Reimplement DDR initialization in C language.
4. Reimplement DDR calibration in a clear logic.
5. Add full support for auto size detection for DDR1 and DDR2.
6. Use accurate CPU clock depending on the input xtal frequency for timer
   and delay functions.

Note:

print_cpuinfo() has incompatible parts with MT7620 so it's moved into
mt7628 subfolder.

Reviewed-by: Stefan Roese <sr@denx.de>
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
diff --git a/arch/mips/mach-mtmips/mt7628/Makefile b/arch/mips/mach-mtmips/mt7628/Makefile
new file mode 100644
index 0000000..db62e90
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += lowlevel_init.o
+obj-y += init.o
+obj-y += ddr.o
diff --git a/arch/mips/mach-mtmips/mt7628/ddr.c b/arch/mips/mach-mtmips/mt7628/ddr.c
new file mode 100644
index 0000000..06c0ca6
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/ddr.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <asm/addrspace.h>
+#include <linux/bitops.h>
+#include <linux/sizes.h>
+#include <linux/io.h>
+#include <mach/ddr.h>
+#include <mach/mc.h>
+#include "mt7628.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* DDR2 DQ_DLY */
+#define DDR2_DQ_DLY \
+				((0x8 << DQ1_DELAY_COARSE_TUNING_S) | \
+				(0x2 << DQ1_DELAY_FINE_TUNING_S) | \
+				(0x8 << DQ0_DELAY_COARSE_TUNING_S) | \
+				(0x2 << DQ0_DELAY_FINE_TUNING_S))
+
+/* DDR2 DQS_DLY */
+#define DDR2_DQS_DLY \
+				((0x8 << DQS1_DELAY_COARSE_TUNING_S) | \
+				(0x3 << DQS1_DELAY_FINE_TUNING_S) | \
+				(0x8 << DQS0_DELAY_COARSE_TUNING_S) | \
+				(0x3 << DQS0_DELAY_FINE_TUNING_S))
+
+const struct mc_ddr_cfg ddr1_cfgs_200mhz[] = {
+	[DRAM_8MB]   = { 0x34A1EB94, 0x20262324, 0x28000033, 0x00000002, 0x00000000 },
+	[DRAM_16MB]  = { 0x34A1EB94, 0x202A2324, 0x28000033, 0x00000002, 0x00000000 },
+	[DRAM_32MB]  = { 0x34A1E5CA, 0x202E2324, 0x28000033, 0x00000002, 0x00000000 },
+	[DRAM_64MB]  = { 0x3421E5CA, 0x20322324, 0x28000033, 0x00000002, 0x00000000 },
+	[DRAM_128MB] = { 0x241B05CA, 0x20362334, 0x28000033, 0x00000002, 0x00000000 },
+};
+
+const struct mc_ddr_cfg ddr1_cfgs_160mhz[] = {
+	[DRAM_8MB]   = { 0x239964A1, 0x20262323, 0x00000033, 0x00000002, 0x00000000 },
+	[DRAM_16MB]  = { 0x239964A1, 0x202A2323, 0x00000033, 0x00000002, 0x00000000 },
+	[DRAM_32MB]  = { 0x239964A1, 0x202E2323, 0x00000033, 0x00000002, 0x00000000 },
+	[DRAM_64MB]  = { 0x239984A1, 0x20322323, 0x00000033, 0x00000002, 0x00000000 },
+	[DRAM_128MB] = { 0x239AB4A1, 0x20362333, 0x00000033, 0x00000002, 0x00000000 },
+};
+
+const struct mc_ddr_cfg ddr2_cfgs_200mhz[] = {
+	[DRAM_32MB]  = { 0x2519E2E5, 0x222E2323, 0x68000C43, 0x00000452, 0x0000000A },
+	[DRAM_64MB]  = { 0x249AA2E5, 0x22322323, 0x68000C43, 0x00000452, 0x0000000A },
+	[DRAM_128MB] = { 0x249B42E5, 0x22362323, 0x68000C43, 0x00000452, 0x0000000A },
+	[DRAM_256MB] = { 0x249CE2E5, 0x223A2323, 0x68000C43, 0x00000452, 0x0000000A },
+};
+
+const struct mc_ddr_cfg ddr2_cfgs_160mhz[] = {
+	[DRAM_32MB]  = { 0x23918250, 0x222E2322, 0x40000A43, 0x00000452, 0x00000006 },
+	[DRAM_64MB]  = { 0x239A2250, 0x22322322, 0x40000A43, 0x00000452, 0x00000008 },
+	[DRAM_128MB] = { 0x2392A250, 0x22362322, 0x40000A43, 0x00000452, 0x00000008 },
+	[DRAM_256MB] = { 0x24140250, 0x223A2322, 0x40000A43, 0x00000452, 0x00000008 },
+};
+
+static void mt7628_memc_reset(int assert)
+{
+	void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+	if (assert)
+		setbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST);
+	else
+		clrbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST);
+}
+
+static void mt7628_ddr_pad_ldo_config(int ddr_type, int pkg_type)
+{
+	void __iomem *rgc = ioremap_nocache(RGCTL_BASE, RGCTL_SIZE);
+	u32 ck_pad1, cmd_pad1, dq_pad0, dq_pad1, dqs_pad0, dqs_pad1;
+
+	setbits_32(rgc + RGCTL_PMU_G0_REG, PMU_CFG_EN);
+
+	if (ddr_type == DRAM_DDR1)
+		setbits_32(rgc + RGCTL_PMU_G3_REG, RG_DDRLDO_VOSEL);
+	else
+		clrbits_32(rgc + RGCTL_PMU_G3_REG, RG_DDRLDO_VOSEL);
+
+	setbits_32(rgc + RGCTL_PMU_G3_REG, NI_DDRLDO_EN);
+
+	__udelay(250 * 50);
+
+	setbits_32(rgc + RGCTL_PMU_G3_REG, NI_DDRLDO_STB);
+	setbits_32(rgc + RGCTL_PMU_G1_REG, RG_BUCK_FPWM);
+
+	ck_pad1 = readl(rgc + RGCTL_DDR_PAD_CK_G1_REG);
+	cmd_pad1 = readl(rgc + RGCTL_DDR_PAD_CMD_G1_REG);
+	dq_pad0 = readl(rgc + RGCTL_DDR_PAD_DQ_G0_REG);
+	dq_pad1 = readl(rgc + RGCTL_DDR_PAD_DQ_G1_REG);
+	dqs_pad0 = readl(rgc + RGCTL_DDR_PAD_DQS_G0_REG);
+	dqs_pad1 = readl(rgc + RGCTL_DDR_PAD_DQS_G1_REG);
+
+	ck_pad1 &= ~(DRVP_M | DRVN_M);
+	cmd_pad1 &= ~(DRVP_M | DRVN_M);
+	dq_pad0 &= ~RTT_M;
+	dq_pad1 &= ~(DRVP_M | DRVN_M);
+	dqs_pad0 &= ~RTT_M;
+	dqs_pad1 &= ~(DRVP_M | DRVN_M);
+
+	if (pkg_type == PKG_ID_KN) {
+		ck_pad1 |= (3 << DRVP_S) | (3 << DRVN_S);
+		cmd_pad1 |= (3 << DRVP_S) | (3 << DRVN_S);
+		dq_pad1 |= (3 << DRVP_S) | (3 << DRVN_S);
+		dqs_pad1 |= (3 << DRVP_S) | (3 << DRVN_S);
+	} else {
+		ck_pad1 |= (12 << DRVP_S) | (12 << DRVN_S);
+		cmd_pad1 |= (2 << DRVP_S) | (2 << DRVN_S);
+		dqs_pad1 |= (12 << DRVP_S) | (12 << DRVN_S);
+		if (ddr_type == DRAM_DDR1)
+			dq_pad1 |= (7 << DRVP_S) | (7 << DRVN_S);
+		else
+			dq_pad1 |= (4 << DRVP_S) | (4 << DRVN_S);
+	}
+
+	writel(ck_pad1, rgc + RGCTL_DDR_PAD_CK_G1_REG);
+	writel(cmd_pad1, rgc + RGCTL_DDR_PAD_CMD_G1_REG);
+	writel(dq_pad0, rgc + RGCTL_DDR_PAD_DQ_G0_REG);
+	writel(dq_pad1, rgc + RGCTL_DDR_PAD_DQ_G1_REG);
+	writel(dqs_pad0, rgc + RGCTL_DDR_PAD_DQS_G0_REG);
+	writel(dqs_pad1, rgc + RGCTL_DDR_PAD_DQS_G1_REG);
+}
+
+void mt7628_ddr_init(void)
+{
+	void __iomem *sysc;
+	int ddr_type, pkg_type, lspd;
+	struct mc_ddr_init_param param;
+
+	sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+	ddr_type = readl(sysc + SYSCTL_SYSCFG0_REG) & DRAM_TYPE;
+	pkg_type = !!(readl(sysc + SYSCTL_CHIP_REV_ID_REG) & PKG_ID);
+	lspd = readl(sysc + SYSCTL_CLKCFG0_REG) &
+	       (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL);
+
+	mt7628_memc_reset(1);
+	__udelay(200);
+
+	mt7628_ddr_pad_ldo_config(ddr_type, pkg_type);
+
+	param.memc = ioremap_nocache(MEMCTL_BASE, MEMCTL_SIZE);
+	param.dq_dly = DDR2_DQ_DLY;
+	param.dqs_dly = DDR2_DQS_DLY;
+	param.mc_reset = mt7628_memc_reset;
+	param.memsize = 0;
+	param.bus_width = 0;
+
+	if (pkg_type == PKG_ID_KN)
+		ddr_type = DRAM_DDR1;
+
+	if (ddr_type == DRAM_DDR1) {
+		if (lspd)
+			param.cfgs = ddr1_cfgs_160mhz;
+		else
+			param.cfgs = ddr1_cfgs_200mhz;
+		ddr1_init(&param);
+	} else {
+		if (lspd)
+			param.cfgs = ddr2_cfgs_160mhz;
+		else
+			param.cfgs = ddr2_cfgs_200mhz;
+		ddr2_init(&param);
+	}
+
+	ddr_calibrate(param.memc, param.memsize, param.bus_width);
+
+	gd->ram_size = param.memsize;
+}
diff --git a/arch/mips/mach-mtmips/mt7628/init.c b/arch/mips/mach-mtmips/mt7628/init.c
new file mode 100644
index 0000000..77d1f2e
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/init.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/mt7628-clk.h>
+#include <linux/io.h>
+#include "mt7628.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void set_init_timer_freq(void)
+{
+	void __iomem *sysc;
+	u32 bs, val, timer_freq_post;
+
+	sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+	/* We can't use the clk driver as the DM has not been initialized yet */
+	bs = readl(sysc + SYSCTL_SYSCFG0_REG);
+	if ((bs & XTAL_FREQ_SEL) == XTAL_25MHZ) {
+		gd->arch.timer_freq = 25000000;
+		timer_freq_post = 575000000;
+	} else {
+		gd->arch.timer_freq = 40000000;
+		timer_freq_post = 580000000;
+	}
+
+	val = readl(sysc + SYSCTL_CLKCFG0_REG);
+	if (!(val & (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)))
+		gd->arch.timer_freq = timer_freq_post;
+}
+
+void mt7628_init(void)
+{
+	set_init_timer_freq();
+
+	mt7628_ddr_init();
+}
+
+int print_cpuinfo(void)
+{
+	void __iomem *sysc;
+	struct udevice *clkdev;
+	u32 val, ver, eco, pkg, ddr, chipmode, ee;
+	ulong cpu_clk, bus_clk, xtal_clk, timer_freq;
+	struct clk clk;
+	int ret;
+
+	sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+	val = readl(sysc + SYSCTL_CHIP_REV_ID_REG);
+	ver = (val & VER_M) >> VER_S;
+	eco = (val & ECO_M) >> ECO_S;
+	pkg = !!(val & PKG_ID);
+
+	val = readl(sysc + SYSCTL_SYSCFG0_REG);
+	ddr = val & DRAM_TYPE;
+	chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S;
+
+	val = readl(sysc + SYSCTL_EFUSE_CFG_REG);
+	ee = val & EFUSE_MT7688;
+
+	printf("CPU:   MediaTek MT%u%c ver:%u eco:%u\n",
+	       ee ? 7688 : 7628, pkg ? 'A' : 'K', ver, eco);
+
+	printf("Boot:  DDR%s, SPI-NOR %u-Byte Addr, CPU clock from %s\n",
+	       ddr ? "" : "2", chipmode & 0x01 ? 4 : 3,
+	       chipmode & 0x02 ? "XTAL" : "CPLL");
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK, DM_GET_DRIVER(mt7628_clk),
+					  &clkdev);
+	if (ret)
+		return ret;
+
+	clk.dev = clkdev;
+
+	clk.id = CLK_CPU;
+	cpu_clk = clk_get_rate(&clk);
+
+	clk.id = CLK_SYS;
+	bus_clk = clk_get_rate(&clk);
+
+	clk.id = CLK_XTAL;
+	xtal_clk = clk_get_rate(&clk);
+
+	clk.id = CLK_MIPS_CNT;
+	timer_freq = clk_get_rate(&clk);
+
+	/* Set final timer frequency */
+	if (timer_freq)
+		gd->arch.timer_freq = timer_freq;
+
+	printf("Clock: CPU: %luMHz, Bus: %luMHz, XTAL: %luMHz\n",
+	       cpu_clk / 1000000, bus_clk / 1000000, xtal_clk / 1000000);
+
+	return 0;
+}
+
+ulong notrace get_tbclk(void)
+{
+	return gd->arch.timer_freq;
+}
diff --git a/arch/mips/mach-mtmips/mt7628/lowlevel_init.S b/arch/mips/mach-mtmips/mt7628/lowlevel_init.S
new file mode 100644
index 0000000..e4a6c03
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/lowlevel_init.S
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <config.h>
+#include <asm-offsets.h>
+#include <asm/cacheops.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include "mt7628.h"
+
+/* Set temporary stack address range */
+#ifndef CONFIG_SYS_INIT_SP_ADDR
+#define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_SDRAM_BASE + \
+				CONFIG_SYS_INIT_SP_OFFSET)
+#endif
+
+#define CACHE_STACK_SIZE	0x4000
+#define CACHE_STACK_BASE	(CONFIG_SYS_INIT_SP_ADDR - CACHE_STACK_SIZE)
+
+#define DELAY_USEC(us)		((58 * (us)) / 3)
+
+	.set noreorder
+
+LEAF(mips_sram_init)
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+	/* Setup CPU PLL */
+	li	t0, DELAY_USEC(1000000)
+	li	t1, KSEG1ADDR(SYSCTL_BASE + SYSCTL_ROM_STATUS_REG)
+	li	t2, KSEG1ADDR(SYSCTL_BASE + SYSCTL_CLKCFG0_REG)
+
+_check_rom_status:
+	lw	t3, 0(t1)
+	andi	t3, t3, 1
+	bnez	t3, _rom_normal
+	subu	t0, t0, 1
+	bnez	t0, _check_rom_status
+	 nop
+
+	lw	t3, 0(t2)
+	ori	t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)
+	xori	t3, CPU_PLL_FROM_BBP
+	b	_cpu_pll_done
+	 nop
+
+_rom_normal:
+	lw	t3, 0(t2)
+	ori	t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL | \
+		    DIS_BBP_SLEEP | EN_BBP_CLK)
+	xori	t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)
+
+_cpu_pll_done:
+	sw	t3, 0(t2)
+
+	li	t2, KSEG1ADDR(RBUSCTL_BASE + RBUSCTL_DYN_CFG0_REG)
+	lw	t3, 0(t2)
+	ori	t3, t3, (CPU_FDIV_M | CPU_FFRAC_M)
+	xori	t3, t3, (CPU_FDIV_M | CPU_FFRAC_M)
+	ori	t3, t3, ((1 << CPU_FDIV_S) | (1 << CPU_FFRAC_S))
+	sw	t3, 0(t2)
+
+	/* Clear WST & SPR bits in ErrCtl */
+	mfc0	t0, CP0_ECC
+	ins	t0, zero, 30, 2
+	mtc0	t0, CP0_ECC
+	ehb
+
+	/* Simply initialize I-Cache */
+	li	a0, 0
+	li	a1, CONFIG_SYS_ICACHE_SIZE
+
+	mtc0	zero, CP0_TAGLO		/* Zero to DDataLo */
+
+1:	cache	INDEX_STORE_TAG_I, 0(a0)
+	addiu	a0, CONFIG_SYS_ICACHE_LINE_SIZE
+	bne	a0, a1, 1b
+	 nop
+
+	/* Simply initialize D-Cache */
+	li	a0, 0
+	li	a1, CONFIG_SYS_DCACHE_SIZE
+
+	mtc0	zero, CP0_TAGLO, 2
+
+2:	cache	INDEX_STORE_TAG_D, 0(a0)
+	addiu	a0, CONFIG_SYS_DCACHE_LINE_SIZE
+	bne	a0, a1, 2b
+	 nop
+
+	/* Set KSEG0 Cachable */
+	mfc0	t0, CP0_CONFIG
+	and	t0, t0, MIPS_CONF_IMPL
+	or	t0, t0, CONF_CM_CACHABLE_NONCOHERENT
+	mtc0	t0, CP0_CONFIG
+	ehb
+
+	/* Lock D-Cache */
+	PTR_LI	a0, CACHE_STACK_BASE		/* D-Cache lock base */
+	li	a1, CACHE_STACK_SIZE		/* D-Cache lock size */
+	li	a2, 0x1ffff800			/* Mask of DTagLo[PTagLo] */
+
+3:
+	/* Lock one cacheline */
+	and	t0, a0, a2
+	ori	t0, 0xe0			/* Valid & Dirty & Lock bits */
+	mtc0	t0, CP0_TAGLO, 2		/* Write to DTagLo */
+	ehb
+	cache	INDEX_STORE_TAG_D, 0(a0)
+
+	addiu	a0, CONFIG_SYS_DCACHE_LINE_SIZE
+	sub	a1, CONFIG_SYS_DCACHE_LINE_SIZE
+	bnez	a1, 3b
+	 nop
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+
+	jr	ra
+	 nop
+	END(mips_sram_init)
+
+NESTED(lowlevel_init, 0, ra)
+	/* Save ra and do real lowlevel initialization */
+	move	s0, ra
+
+	PTR_LA	t9, mt7628_init
+	jalr	t9
+	 nop
+
+	move	ra, s0
+
+#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
+	/* Set malloc base */
+	li	t0, (CONFIG_SYS_INIT_SP_ADDR + 15) & (~15)
+	PTR_S	t0, GD_MALLOC_BASE(k0)	# gd->malloc_base offset
+#endif
+
+	/* Write back data in locked cache to DRAM */
+	PTR_LI	a0, CACHE_STACK_BASE		/* D-Cache unlock base */
+	li	a1, CACHE_STACK_SIZE		/* D-Cache unlock size */
+
+1:
+	cache	HIT_WRITEBACK_INV_D, 0(a0)
+	addiu	a0, CONFIG_SYS_DCACHE_LINE_SIZE
+	sub	a1, CONFIG_SYS_DCACHE_LINE_SIZE
+	bnez	a1, 1b
+	 nop
+
+	/* Set KSEG0 Uncached */
+	mfc0	t0, CP0_CONFIG
+	and	t0, t0, MIPS_CONF_IMPL
+	or	t0, t0, CONF_CM_UNCACHED
+	mtc0	t0, CP0_CONFIG
+	ehb
+
+	jr	ra
+	 nop
+	END(lowlevel_init)
diff --git a/arch/mips/mach-mtmips/mt7628/mt7628.h b/arch/mips/mach-mtmips/mt7628/mt7628.h
new file mode 100644
index 0000000..391880b
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/mt7628.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MT7628_H_
+#define _MT7628_H_
+
+#define SYSCTL_BASE			0x10000000
+#define SYSCTL_SIZE			0x100
+#define MEMCTL_BASE			0x10000300
+#define MEMCTL_SIZE			0x100
+#define RBUSCTL_BASE			0x10000400
+#define RBUSCTL_SIZE			0x100
+#define RGCTL_BASE			0x10001000
+#define RGCTL_SIZE			0x800
+
+#define SYSCTL_EFUSE_CFG_REG		0x08
+#define EFUSE_MT7688			0x100000
+
+#define SYSCTL_CHIP_REV_ID_REG		0x0c
+#define PKG_ID				0x10000
+#define PKG_ID_AN			1
+#define PKG_ID_KN			0
+#define VER_S				8
+#define VER_M				0xf00
+#define ECO_S				0
+#define ECO_M				0x0f
+
+#define SYSCTL_SYSCFG0_REG		0x10
+#define XTAL_FREQ_SEL			0x40
+#define XTAL_40MHZ			1
+#define XTAL_25MHZ			0
+#define CHIP_MODE_S			1
+#define CHIP_MODE_M			0x0e
+#define DRAM_TYPE			0x01
+#define DRAM_DDR1			1
+#define DRAM_DDR2			0
+
+#define SYSCTL_ROM_STATUS_REG		0x28
+
+#define SYSCTL_CLKCFG0_REG		0x2c
+#define DIS_BBP_SLEEP			0x08
+#define EN_BBP_CLK			0x04
+#define CPU_PLL_FROM_BBP		0x02
+#define CPU_PLL_FROM_XTAL		0x01
+
+#define SYSCTL_RSTCTL_REG		0x34
+#define MC_RST				0x400
+
+#define SYSCTL_AGPIO_CFG_REG		0x3c
+#define EPHY_GPIO_AIO_EN_S		17
+#define EPHY_GPIO_AIO_EN_M		0x1e0000
+
+#define SYSCTL_GPIO_MODE1_REG		0x60
+#define UART2_MODE_S			26
+#define UART2_MODE_M			0xc000000
+#define UART1_MODE_S			24
+#define UART1_MODE_M			0x3000000
+#define UART0_MODE_S			8
+#define UART0_MODE_M			0x300
+#define SPIS_MODE_S			2
+#define SPIS_MODE_M			0x0c
+
+#define RBUSCTL_DYN_CFG0_REG		0x40
+#define CPU_FDIV_S			8
+#define CPU_FDIV_M			0xf00
+#define CPU_FFRAC_S			0
+#define CPU_FFRAC_M			0x0f
+
+#define RGCTL_PMU_G0_REG		0x100
+#define PMU_CFG_EN			0x80000000
+
+#define RGCTL_PMU_G1_REG		0x104
+#define RG_BUCK_FPWM			0x02
+
+#define RGCTL_PMU_G3_REG		0x10c
+#define NI_DDRLDO_STB			0x40000
+#define NI_DDRLDO_EN			0x10000
+#define RG_DDRLDO_VOSEL			0x40
+
+#define RGCTL_DDR_PAD_CK_G0_REG		0x700
+#define RGCTL_DDR_PAD_CMD_G0_REG	0x708
+#define RGCTL_DDR_PAD_DQ_G0_REG		0x710
+#define RGCTL_DDR_PAD_DQS_G0_REG	0x718
+#define RTT_S				8
+#define RTT_M				0x700
+
+#define RGCTL_DDR_PAD_CK_G1_REG		0x704
+#define RGCTL_DDR_PAD_CMD_G1_REG	0x70c
+#define RGCTL_DDR_PAD_DQ_G1_REG		0x714
+#define RGCTL_DDR_PAD_DQS_G1_REG	0x71c
+#define DRVP_S				0
+#define DRVP_M				0x0f
+#define DRVN_S				8
+#define DRVN_M				0xf00
+
+#ifndef __ASSEMBLY__
+void mt7628_ddr_init(void);
+#endif
+
+#endif /* _MT7628_H_ */