summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arc/Kconfig4
-rw-r--r--arch/arc/dts/Makefile2
-rw-r--r--arch/arc/dts/hsdk-4xd.dts12
-rw-r--r--arch/arc/dts/hsdk-common.dtsi152
-rw-r--r--arch/arc/dts/hsdk.dts145
-rw-r--r--arch/arc/include/asm/arcregs.h4
-rw-r--r--arch/arc/lib/start.S15
-rw-r--r--arch/arm/dts/meson-axg-s400.dts6
-rw-r--r--arch/arm/dts/meson-g12-common.dtsi136
-rw-r--r--arch/arm/dts/meson-g12.dtsi1
-rw-r--r--arch/arm/dts/meson-g12a-sei510.dts4
-rw-r--r--arch/arm/dts/meson-g12a-u200.dts2
-rw-r--r--arch/arm/dts/meson-g12b-a311d-khadas-vim3-u-boot.dtsi7
-rw-r--r--arch/arm/dts/meson-g12b-khadas-vim3.dtsi4
-rw-r--r--arch/arm/dts/meson-g12b-odroid-n2.dts25
-rw-r--r--arch/arm/dts/meson-gx.dtsi52
-rw-r--r--arch/arm/dts/meson-gxbb-odroidc2.dts1
-rw-r--r--arch/arm/dts/meson-gxl-s905x-p212.dtsi9
-rw-r--r--arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi15
-rw-r--r--arch/arm/dts/meson-gxm-khadas-vim2.dts89
-rw-r--r--arch/arm/dts/meson-gxm.dtsi28
-rw-r--r--arch/arm/dts/meson-khadas-vim3-u-boot.dtsi21
-rw-r--r--arch/arm/dts/meson-khadas-vim3.dtsi24
-rw-r--r--arch/arm/dts/meson-sm1-khadas-vim3l-u-boot.dtsi7
-rw-r--r--arch/arm/dts/meson-sm1-khadas-vim3l.dts8
-rw-r--r--arch/arm/dts/meson-sm1-sei610.dts3
-rw-r--r--arch/arm/dts/meson-sm1.dtsi1
-rw-r--r--arch/arm/include/asm/arch-bcmcygnus/configs.h1
-rw-r--r--arch/arm/mach-socfpga/include/mach/clock_manager_s10.h2
-rw-r--r--arch/mips/Kconfig64
-rw-r--r--arch/mips/cpu/start.S16
-rw-r--r--arch/mips/cpu/u-boot-spl.lds4
-rw-r--r--arch/mips/dts/Makefile2
-rw-r--r--arch/mips/dts/mediatek,mt7628-rfb.dts67
-rw-r--r--arch/mips/dts/mt7628-u-boot.dtsi38
-rw-r--r--arch/mips/dts/mt7628a.dtsi17
-rw-r--r--arch/mips/dts/vocore_vocore2.dts85
-rw-r--r--arch/mips/include/asm/global_data.h3
-rw-r--r--arch/mips/include/asm/u-boot-mips.h2
-rw-r--r--arch/mips/lib/Makefile1
-rw-r--r--arch/mips/lib/bootm.c3
-rw-r--r--arch/mips/lib/spl.c21
-rw-r--r--arch/mips/lib/traps.c19
-rw-r--r--arch/mips/mach-mtmips/Kconfig142
-rw-r--r--arch/mips/mach-mtmips/Makefile8
-rw-r--r--arch/mips/mach-mtmips/cpu.c58
-rw-r--r--arch/mips/mach-mtmips/ddr_cal.c205
-rw-r--r--arch/mips/mach-mtmips/ddr_calibrate.c309
-rw-r--r--arch/mips/mach-mtmips/ddr_init.c194
-rw-r--r--arch/mips/mach-mtmips/include/mach/ddr.h52
-rw-r--r--arch/mips/mach-mtmips/include/mach/mc.h180
-rw-r--r--arch/mips/mach-mtmips/include/mach/serial.h13
-rw-r--r--arch/mips/mach-mtmips/lowlevel_init.S328
-rw-r--r--arch/mips/mach-mtmips/mt7628/Makefile6
-rw-r--r--arch/mips/mach-mtmips/mt7628/ddr.c173
-rw-r--r--arch/mips/mach-mtmips/mt7628/init.c109
-rw-r--r--arch/mips/mach-mtmips/mt7628/lowlevel_init.S161
-rw-r--r--arch/mips/mach-mtmips/mt7628/mt7628.h104
-rw-r--r--arch/mips/mach-mtmips/mt7628/serial.c34
-rw-r--r--arch/mips/mach-mtmips/mt76xx.h32
-rw-r--r--arch/mips/mach-mtmips/spl.c44
61 files changed, 2204 insertions, 1070 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 545fc3e243..6ff201fa81 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -164,18 +164,16 @@ config TARGET_NSIM
config TARGET_AXS101
bool "Support Synopsys Designware SDP board AXS101"
- select BOUNCE_BUFFER if CMD_NAND
config TARGET_AXS103
bool "Support Synopsys Designware SDP board AXS103"
- select BOUNCE_BUFFER if CMD_NAND
config TARGET_EMSDP
bool "Synopsys EM Software Development Platform"
select CPU_ARCEM6
config TARGET_HSDK
- bool "Support Synpsys HS DevelopmentKit board"
+ bool "Support Synopsys HSDK or HSDK-4xD board"
config TARGET_IOT_DEVKIT
bool "Synopsys Brite IoT Development kit"
diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile
index 4f1e4637ce..515fe1fe53 100644
--- a/arch/arc/dts/Makefile
+++ b/arch/arc/dts/Makefile
@@ -5,7 +5,7 @@ dtb-$(CONFIG_TARGET_AXS103) += axs103.dtb
dtb-$(CONFIG_TARGET_NSIM) += nsim.dtb
dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb
dtb-$(CONFIG_TARGET_EMSDP) += emsdp.dtb
-dtb-$(CONFIG_TARGET_HSDK) += hsdk.dtb
+dtb-$(CONFIG_TARGET_HSDK) += hsdk.dtb hsdk-4xd.dtb
dtb-$(CONFIG_TARGET_IOT_DEVKIT) += iot_devkit.dtb
targets += $(dtb-y)
diff --git a/arch/arc/dts/hsdk-4xd.dts b/arch/arc/dts/hsdk-4xd.dts
new file mode 100644
index 0000000000..b245eea769
--- /dev/null
+++ b/arch/arc/dts/hsdk-4xd.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Synopsys, Inc. All rights reserved.
+ * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+ */
+/dts-v1/;
+
+#include "hsdk-common.dtsi"
+
+/ {
+ model = "snps,hsdk-4xd";
+};
diff --git a/arch/arc/dts/hsdk-common.dtsi b/arch/arc/dts/hsdk-common.dtsi
new file mode 100644
index 0000000000..fd4245e164
--- /dev/null
+++ b/arch/arc/dts/hsdk-common.dtsi
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017-2020 Synopsys, Inc. All rights reserved.
+ * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+ */
+/dts-v1/;
+
+#include "skeleton.dtsi"
+#include "dt-bindings/clock/snps,hsdk-cgu.h"
+#include "dt-bindings/reset/snps,hsdk-reset.h"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ console = &uart0;
+ spi0 = &spi0;
+ };
+
+ cpu_card {
+ core_clk: core_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <500000000>;
+ u-boot,dm-pre-reloc;
+ };
+ };
+
+ clk-fmeas {
+ clocks = <&cgu_clk CLK_ARC_PLL>, <&cgu_clk CLK_SYS_PLL>,
+ <&cgu_clk CLK_TUN_PLL>, <&cgu_clk CLK_DDR_PLL>,
+ <&cgu_clk CLK_ARC>, <&cgu_clk CLK_HDMI_PLL>,
+ <&cgu_clk CLK_TUN_TUN>, <&cgu_clk CLK_HDMI>,
+ <&cgu_clk CLK_SYS_APB>, <&cgu_clk CLK_SYS_AXI>,
+ <&cgu_clk CLK_SYS_ETH>, <&cgu_clk CLK_SYS_USB>,
+ <&cgu_clk CLK_SYS_SDIO>, <&cgu_clk CLK_SYS_HDMI>,
+ <&cgu_clk CLK_SYS_GFX_CORE>, <&cgu_clk CLK_SYS_GFX_DMA>,
+ <&cgu_clk CLK_SYS_GFX_CFG>, <&cgu_clk CLK_SYS_DMAC_CORE>,
+ <&cgu_clk CLK_SYS_DMAC_CFG>, <&cgu_clk CLK_SYS_SDIO_REF>,
+ <&cgu_clk CLK_SYS_SPI_REF>, <&cgu_clk CLK_SYS_I2C_REF>,
+ <&cgu_clk CLK_SYS_UART_REF>, <&cgu_clk CLK_SYS_EBI_REF>,
+ <&cgu_clk CLK_TUN_ROM>, <&cgu_clk CLK_TUN_PWM>,
+ <&cgu_clk CLK_TUN_TIMER>;
+ clock-names = "cpu-pll", "sys-pll",
+ "tun-pll", "ddr-clk",
+ "cpu-clk", "hdmi-pll",
+ "tun-clk", "hdmi-clk",
+ "apb-clk", "axi-clk",
+ "eth-clk", "usb-clk",
+ "sdio-clk", "hdmi-sys-clk",
+ "gfx-core-clk", "gfx-dma-clk",
+ "gfx-cfg-clk", "dmac-core-clk",
+ "dmac-cfg-clk", "sdio-ref-clk",
+ "spi-clk", "i2c-clk",
+ "uart-clk", "ebi-clk",
+ "rom-clk", "pwm-clk",
+ "timer-clk";
+ };
+
+ cgu_clk: cgu-clk@f0000000 {
+ compatible = "snps,hsdk-cgu-clock";
+ reg = <0xf0000000 0x10>, <0xf00014B8 0x4>;
+ #clock-cells = <1>;
+ };
+
+ cgu_rst: reset-controller@f00008a0 {
+ compatible = "snps,hsdk-reset";
+ #reset-cells = <1>;
+ reg = <0xf00008a0 0x4>, <0xf0000ff0 0x4>;
+ };
+
+ uart0: serial0@f0005000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0xf0005000 0x1000>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+ ethernet@f0008000 {
+ #interrupt-cells = <1>;
+ compatible = "snps,arc-dwmac-3.70a";
+ reg = <0xf0008000 0x2000>;
+ phy-mode = "gmii";
+ };
+
+ ehci@0xf0040000 {
+ compatible = "generic-ehci";
+ reg = <0xf0040000 0x100>;
+ };
+
+ ohci@0xf0060000 {
+ compatible = "generic-ohci";
+ reg = <0xf0060000 0x100>;
+ };
+
+ mmcclk_ciu: mmcclk-ciu {
+ compatible = "fixed-clock";
+ /*
+ * DW sdio controller has external ciu clock divider
+ * controlled via register in SDIO IP. Due to its
+ * unexpected default value (it should divide by 1
+ * but it divides by 8) SDIO IP uses wrong clock and
+ * works unstable (see STAR 9001204800)
+ * We switched to the minimum possible value of the
+ * divisor (div-by-2) in HSDK platform code.
+ * So default mmcclk ciu clock is 50000000 Hz.
+ */
+ clock-frequency = <50000000>;
+ #clock-cells = <0>;
+ };
+
+ mmc: mmc0@f000a000 {
+ compatible = "snps,dw-mshc";
+ reg = <0xf000a000 0x400>;
+ bus-width = <4>;
+ fifo-depth = <256>;
+ clocks = <&cgu_clk CLK_SYS_SDIO>, <&mmcclk_ciu>;
+ clock-names = "biu", "ciu";
+ max-frequency = <25000000>;
+ };
+
+ spi0: spi@f0020000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0xf0020000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ spi-max-frequency = <4000000>;
+ clocks = <&cgu_clk CLK_SYS_SPI_REF>;
+ clock-names = "spi_clk";
+ cs-gpio = <&cs_gpio 0>;
+ spi_flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <4000000>;
+ };
+ };
+
+ cs_gpio: gpio@f00014b0 {
+ compatible = "snps,creg-gpio";
+ reg = <0xf00014b0 0x4>;
+ gpio-controller;
+ #gpio-cells = <1>;
+ gpio-bank-name = "hsdk-spi-cs";
+ gpio-count = <1>;
+ gpio-first-shift = <0>;
+ gpio-bit-per-line = <2>;
+ gpio-activate-val = <2>;
+ gpio-deactivate-val = <3>;
+ gpio-default-val = <1>;
+ };
+};
diff --git a/arch/arc/dts/hsdk.dts b/arch/arc/dts/hsdk.dts
index cf2ce8a1f6..1a2e3d4322 100644
--- a/arch/arc/dts/hsdk.dts
+++ b/arch/arc/dts/hsdk.dts
@@ -1,151 +1,12 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright (C) 2017 Synopsys, Inc. All rights reserved.
+ * Copyright (C) 2017-2020 Synopsys, Inc. All rights reserved.
+ * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
*/
/dts-v1/;
-#include "skeleton.dtsi"
-#include "dt-bindings/clock/snps,hsdk-cgu.h"
-#include "dt-bindings/reset/snps,hsdk-reset.h"
+#include "hsdk-common.dtsi"
/ {
model = "snps,hsdk";
-
- #address-cells = <1>;
- #size-cells = <1>;
-
- aliases {
- console = &uart0;
- spi0 = &spi0;
- };
-
- cpu_card {
- core_clk: core_clk {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <500000000>;
- u-boot,dm-pre-reloc;
- };
- };
-
- clk-fmeas {
- clocks = <&cgu_clk CLK_ARC_PLL>, <&cgu_clk CLK_SYS_PLL>,
- <&cgu_clk CLK_TUN_PLL>, <&cgu_clk CLK_DDR_PLL>,
- <&cgu_clk CLK_ARC>, <&cgu_clk CLK_HDMI_PLL>,
- <&cgu_clk CLK_TUN_TUN>, <&cgu_clk CLK_HDMI>,
- <&cgu_clk CLK_SYS_APB>, <&cgu_clk CLK_SYS_AXI>,
- <&cgu_clk CLK_SYS_ETH>, <&cgu_clk CLK_SYS_USB>,
- <&cgu_clk CLK_SYS_SDIO>, <&cgu_clk CLK_SYS_HDMI>,
- <&cgu_clk CLK_SYS_GFX_CORE>, <&cgu_clk CLK_SYS_GFX_DMA>,
- <&cgu_clk CLK_SYS_GFX_CFG>, <&cgu_clk CLK_SYS_DMAC_CORE>,
- <&cgu_clk CLK_SYS_DMAC_CFG>, <&cgu_clk CLK_SYS_SDIO_REF>,
- <&cgu_clk CLK_SYS_SPI_REF>, <&cgu_clk CLK_SYS_I2C_REF>,
- <&cgu_clk CLK_SYS_UART_REF>, <&cgu_clk CLK_SYS_EBI_REF>,
- <&cgu_clk CLK_TUN_ROM>, <&cgu_clk CLK_TUN_PWM>;
- clock-names = "cpu-pll", "sys-pll",
- "tun-pll", "ddr-clk",
- "cpu-clk", "hdmi-pll",
- "tun-clk", "hdmi-clk",
- "apb-clk", "axi-clk",
- "eth-clk", "usb-clk",
- "sdio-clk", "hdmi-sys-clk",
- "gfx-core-clk", "gfx-dma-clk",
- "gfx-cfg-clk", "dmac-core-clk",
- "dmac-cfg-clk", "sdio-ref-clk",
- "spi-clk", "i2c-clk",
- "uart-clk", "ebi-clk",
- "rom-clk", "pwm-clk";
- };
-
- cgu_clk: cgu-clk@f0000000 {
- compatible = "snps,hsdk-cgu-clock";
- reg = <0xf0000000 0x10>, <0xf00014B8 0x4>;
- #clock-cells = <1>;
- };
-
- cgu_rst: reset-controller@f00008a0 {
- compatible = "snps,hsdk-reset";
- #reset-cells = <1>;
- reg = <0xf00008a0 0x4>, <0xf0000ff0 0x4>;
- };
-
- uart0: serial0@f0005000 {
- compatible = "snps,dw-apb-uart";
- reg = <0xf0005000 0x1000>;
- reg-shift = <2>;
- reg-io-width = <4>;
- };
-
- ethernet@f0008000 {
- #interrupt-cells = <1>;
- compatible = "snps,arc-dwmac-3.70a";
- reg = <0xf0008000 0x2000>;
- phy-mode = "gmii";
- };
-
- ehci@0xf0040000 {
- compatible = "generic-ehci";
- reg = <0xf0040000 0x100>;
- };
-
- ohci@0xf0060000 {
- compatible = "generic-ohci";
- reg = <0xf0060000 0x100>;
- };
-
- mmcclk_ciu: mmcclk-ciu {
- compatible = "fixed-clock";
- /*
- * DW sdio controller has external ciu clock divider
- * controlled via register in SDIO IP. Due to its
- * unexpected default value (it should divide by 1
- * but it divides by 8) SDIO IP uses wrong clock and
- * works unstable (see STAR 9001204800)
- * We switched to the minimum possible value of the
- * divisor (div-by-2) in HSDK platform code.
- * So default mmcclk ciu clock is 50000000 Hz.
- */
- clock-frequency = <50000000>;
- #clock-cells = <0>;
- };
-
- mmc: mmc0@f000a000 {
- compatible = "snps,dw-mshc";
- reg = <0xf000a000 0x400>;
- bus-width = <4>;
- fifo-depth = <256>;
- clocks = <&cgu_clk CLK_SYS_SDIO>, <&mmcclk_ciu>;
- clock-names = "biu", "ciu";
- max-frequency = <25000000>;
- };
-
- spi0: spi@f0020000 {
- compatible = "snps,dw-apb-ssi";
- reg = <0xf0020000 0x1000>;
- #address-cells = <1>;
- #size-cells = <0>;
- spi-max-frequency = <4000000>;
- clocks = <&cgu_clk CLK_SYS_SPI_REF>;
- clock-names = "spi_clk";
- cs-gpio = <&cs_gpio 0>;
- spi_flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <4000000>;
- };
- };
-
- cs_gpio: gpio@f00014b0 {
- compatible = "snps,creg-gpio";
- reg = <0xf00014b0 0x4>;
- gpio-controller;
- #gpio-cells = <1>;
- gpio-bank-name = "hsdk-spi-cs";
- gpio-count = <1>;
- gpio-first-shift = <0>;
- gpio-bit-per-line = <2>;
- gpio-activate-val = <2>;
- gpio-deactivate-val = <3>;
- gpio-default-val = <1>;
- };
};
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index fff6591c68..516c14e105 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -51,6 +51,9 @@
#define ARC_AUX_DCCM_BASE 0x18 /* DCCM Base Addr ARCv2 */
#define ARC_AUX_ICCM_BASE 0x208 /* ICCM Base Addr ARCv2 */
+/* CSM auxiliary registers */
+#define ARC_AUX_CSM_ENABLE 0x9A0
+
/* Timer related auxiliary registers */
#define ARC_AUX_TIMER0_CNT 0x21 /* Timer 0 count */
#define ARC_AUX_TIMER0_CTRL 0x22 /* Timer 0 control */
@@ -100,6 +103,7 @@
/* DSP-extensions related auxiliary registers */
#define ARC_AUX_DSP_BUILD 0x7A
+#define ARC_AUX_DSP_CTRL 0x59F
/* ARC Subsystems related auxiliary registers */
#define ARC_AUX_SUBSYS_BUILD 0xF0
diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S
index 8c744f5be7..016ae85be2 100644
--- a/arch/arc/lib/start.S
+++ b/arch/arc/lib/start.S
@@ -61,6 +61,21 @@ ENTRY(_start)
1:
#endif
+#ifdef CONFIG_ISA_ARCV2
+ ; In case of DSP extension presence in HW some instructions
+ ; (related to integer multiply, multiply-accumulate, and divide
+ ; operation) executes on this DSP execution unit. So their
+ ; execution will depend on dsp configuration register (DSP_CTRL)
+ ; As we want these instructions to execute the same way regardless
+ ; of DSP presence we need to set DSP_CTRL properly.
+ lr r5, [ARC_AUX_DSP_BUILD]
+ bmsk r5, r5, 7
+ breq r5, 0, 1f
+ mov r5, 0
+ sr r5, [ARC_AUX_DSP_CTRL]
+1:
+#endif
+
#ifdef __ARC_UNALIGNED__
/*
* Enable handling of unaligned access in the CPU as by default
diff --git a/arch/arm/dts/meson-axg-s400.dts b/arch/arm/dts/meson-axg-s400.dts
index 4cd2d59518..cb1360ae12 100644
--- a/arch/arm/dts/meson-axg-s400.dts
+++ b/arch/arm/dts/meson-axg-s400.dts
@@ -313,15 +313,15 @@
dai-tdm-slot-rx-mask-1 = <1 1>;
mclk-fs = <256>;
- codec@0 {
+ codec-0 {
sound-dai = <&lineout>;
};
- codec@1 {
+ codec-1 {
sound-dai = <&speaker_amp1>;
};
- codec@2 {
+ codec-2 {
sound-dai = <&linein>;
};
diff --git a/arch/arm/dts/meson-g12-common.dtsi b/arch/arm/dts/meson-g12-common.dtsi
index abe04f4ad7..0882ea215b 100644
--- a/arch/arm/dts/meson-g12-common.dtsi
+++ b/arch/arm/dts/meson-g12-common.dtsi
@@ -295,17 +295,9 @@
};
};
- emmc_pins: emmc {
+ emmc_ctrl_pins: emmc-ctrl {
mux-0 {
- groups = "emmc_nand_d0",
- "emmc_nand_d1",
- "emmc_nand_d2",
- "emmc_nand_d3",
- "emmc_nand_d4",
- "emmc_nand_d5",
- "emmc_nand_d6",
- "emmc_nand_d7",
- "emmc_cmd";
+ groups = "emmc_cmd";
function = "emmc";
bias-pull-up;
drive-strength-microamp = <4000>;
@@ -319,6 +311,34 @@
};
};
+ emmc_data_4b_pins: emmc-data-4b {
+ mux-0 {
+ groups = "emmc_nand_d0",
+ "emmc_nand_d1",
+ "emmc_nand_d2",
+ "emmc_nand_d3";
+ function = "emmc";
+ bias-pull-up;
+ drive-strength-microamp = <4000>;
+ };
+ };
+
+ emmc_data_8b_pins: emmc-data-8b {
+ mux-0 {
+ groups = "emmc_nand_d0",
+ "emmc_nand_d1",
+ "emmc_nand_d2",
+ "emmc_nand_d3",
+ "emmc_nand_d4",
+ "emmc_nand_d5",
+ "emmc_nand_d6",
+ "emmc_nand_d7";
+ function = "emmc";
+ bias-pull-up;
+ drive-strength-microamp = <4000>;
+ };
+ };
+
emmc_ds_pins: emmc-ds {
mux {
groups = "emmc_nand_ds";
@@ -573,6 +593,17 @@
};
};
+ nor_pins: nor {
+ mux {
+ groups = "nor_d",
+ "nor_q",
+ "nor_c",
+ "nor_cs";
+ function = "nor";
+ bias-disable;
+ };
+ };
+
pdm_din0_a_pins: pdm-din0-a {
mux {
groups = "pdm_din0_a";
@@ -957,6 +988,57 @@
};
};
+ spicc0_x_pins: spicc0-x {
+ mux {
+ groups = "spi0_mosi_x",
+ "spi0_miso_x",
+ "spi0_clk_x";
+ function = "spi0";
+ drive-strength-microamp = <4000>;
+ bias-disable;
+ };
+ };
+
+ spicc0_ss0_x_pins: spicc0-ss0-x {
+ mux {
+ groups = "spi0_ss0_x";
+ function = "spi0";
+ drive-strength-microamp = <4000>;
+ bias-disable;
+ };
+ };
+
+ spicc0_c_pins: spicc0-c {
+ mux {
+ groups = "spi0_mosi_c",
+ "spi0_miso_c",
+ "spi0_ss0_c",
+ "spi0_clk_c";
+ function = "spi0";
+ drive-strength-microamp = <4000>;
+ bias-disable;
+ };
+ };
+
+ spicc1_pins: spicc1 {
+ mux {
+ groups = "spi1_mosi",
+ "spi1_miso",
+ "spi1_clk";
+ function = "spi1";
+ drive-strength-microamp = <4000>;
+ };
+ };
+
+ spicc1_ss0_pins: spicc1-ss0 {
+ mux {
+ groups = "spi1_ss0";
+ function = "spi1";
+ drive-strength-microamp = <4000>;
+ bias-disable;
+ };
+ };
+
tdm_a_din0_pins: tdm-a-din0 {
mux {
groups = "tdm_a_din0";
@@ -2051,6 +2133,39 @@
amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>;
};
+ spicc0: spi@13000 {
+ compatible = "amlogic,meson-g12a-spicc";
+ reg = <0x0 0x13000 0x0 0x44>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_SPICC0>,
+ <&clkc CLKID_SPICC0_SCLK>;
+ clock-names = "core", "pclk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spicc1: spi@15000 {
+ compatible = "amlogic,meson-g12a-spicc";
+ reg = <0x0 0x15000 0x0 0x44>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_SPICC1>,
+ <&clkc CLKID_SPICC1_SCLK>;
+ clock-names = "core", "pclk";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spifc: spi@14000 {
+ compatible = "amlogic,meson-gxbb-spifc";
+ status = "disabled";
+ reg = <0x0 0x14000 0x0 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&clkc CLKID_CLK81>;
+ };
+
pwm_ef: pwm@19000 {
compatible = "amlogic,meson-g12a-ee-pwm";
reg = <0x0 0x19000 0x0 0x20>;
@@ -2220,6 +2335,7 @@
dr_mode = "host";
snps,dis_u2_susphy_quirk;
snps,quirk-frame-length-adjustment;
+ snps,parkmode-disable-ss-quirk;
};
};
diff --git a/arch/arm/dts/meson-g12.dtsi b/arch/arm/dts/meson-g12.dtsi
index 03054c4788..55d39020ec 100644
--- a/arch/arm/dts/meson-g12.dtsi
+++ b/arch/arm/dts/meson-g12.dtsi
@@ -56,6 +56,7 @@
<&clkc_audio AUD_CLKID_PDM_DCLK>,
<&clkc_audio AUD_CLKID_PDM_SYSCLK>;
clock-names = "pclk", "dclk", "sysclk";
+ resets = <&clkc_audio AUD_RESET_PDM>;
status = "disabled";
};
diff --git a/arch/arm/dts/meson-g12a-sei510.dts b/arch/arm/dts/meson-g12a-sei510.dts
index 2ac9e3a43b..b00d0468c7 100644
--- a/arch/arm/dts/meson-g12a-sei510.dts
+++ b/arch/arm/dts/meson-g12a-sei510.dts
@@ -269,7 +269,7 @@
dai-tdm-slot-tx-mask-3 = <1 1>;
mclk-fs = <256>;
- codec@0 {
+ codec {
sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
};
};
@@ -472,7 +472,7 @@
/* eMMC */
&sd_emmc_c {
status = "okay";
- pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
pinctrl-1 = <&emmc_clk_gate_pins>;
pinctrl-names = "default", "clk-gate";
diff --git a/arch/arm/dts/meson-g12a-u200.dts b/arch/arm/dts/meson-g12a-u200.dts
index 2a324f0136..a26bfe7255 100644
--- a/arch/arm/dts/meson-g12a-u200.dts
+++ b/arch/arm/dts/meson-g12a-u200.dts
@@ -271,7 +271,7 @@
/* eMMC */
&sd_emmc_c {
status = "okay";
- pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
pinctrl-1 = <&emmc_clk_gate_pins>;
pinctrl-names = "default", "clk-gate";
diff --git a/arch/arm/dts/meson-g12b-a311d-khadas-vim3-u-boot.dtsi b/arch/arm/dts/meson-g12b-a311d-khadas-vim3-u-boot.dtsi
new file mode 100644
index 0000000000..f66eca14b1
--- /dev/null
+++ b/arch/arm/dts/meson-g12b-a311d-khadas-vim3-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include "meson-khadas-vim3-u-boot.dtsi"
diff --git a/arch/arm/dts/meson-g12b-khadas-vim3.dtsi b/arch/arm/dts/meson-g12b-khadas-vim3.dtsi
index 554863429a..c33e85fbda 100644
--- a/arch/arm/dts/meson-g12b-khadas-vim3.dtsi
+++ b/arch/arm/dts/meson-g12b-khadas-vim3.dtsi
@@ -8,6 +8,8 @@
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
/ {
+ model = "Khadas VIM3";
+
vddcpu_a: regulator-vddcpu-a {
/*
* MP8756GD Regulator.
@@ -48,7 +50,7 @@
sound {
compatible = "amlogic,axg-sound-card";
- model = "G12A-KHADAS-VIM3";
+ model = "G12B-KHADAS-VIM3";
audio-aux-devs = <&tdmout_b>;
audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
"TDMOUT_B IN 1", "FRDDR_B OUT 1",
diff --git a/arch/arm/dts/meson-g12b-odroid-n2.dts b/arch/arm/dts/meson-g12b-odroid-n2.dts
index 0e54c1dc28..169ea283d4 100644
--- a/arch/arm/dts/meson-g12b-odroid-n2.dts
+++ b/arch/arm/dts/meson-g12b-odroid-n2.dts
@@ -208,7 +208,7 @@
sound {
compatible = "amlogic,axg-sound-card";
- model = "G12A-ODROIDN2";
+ model = "G12B-ODROID-N2";
audio-aux-devs = <&tdmout_b>;
audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
"TDMOUT_B IN 1", "FRDDR_B OUT 1",
@@ -435,7 +435,7 @@
/* eMMC */
&sd_emmc_c {
status = "okay";
- pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
pinctrl-1 = <&emmc_clk_gate_pins>;
pinctrl-names = "default", "clk-gate";
@@ -451,6 +451,27 @@
vqmmc-supply = <&flash_1v8>;
};
+/*
+ * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR pins
+ * and eMMC Data 4 to 7 pins.
+ * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0,
+ * and change bus-width to 4 then spifc can be enabled.
+ * The SW1 slide should also be set to the correct position.
+ */
+&spifc {
+ status = "disabled";
+ pinctrl-0 = <&nor_pins>;
+ pinctrl-names = "default";
+
+ mx25u64: spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mxicy,mx25u6435f", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ };
+};
+
&tdmif_b {
status = "okay";
};
diff --git a/arch/arm/dts/meson-gx.dtsi b/arch/arm/dts/meson-gx.dtsi
index 40db06e28b..03f79fe045 100644
--- a/arch/arm/dts/meson-gx.dtsi
+++ b/arch/arm/dts/meson-gx.dtsi
@@ -12,6 +12,7 @@
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
interrupt-parent = <&gic>;
@@ -83,6 +84,7 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 0>;
+ #cooling-cells = <2>;
};
cpu1: cpu@1 {
@@ -92,6 +94,7 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 0>;
+ #cooling-cells = <2>;
};
cpu2: cpu@2 {
@@ -101,6 +104,7 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 0>;
+ #cooling-cells = <2>;
};
cpu3: cpu@3 {
@@ -110,6 +114,7 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 0>;
+ #cooling-cells = <2>;
};
l2: l2-cache0 {
@@ -117,6 +122,53 @@
};
};
+ thermal-zones {
+ cpu-thermal {
+ polling-delay-passive = <250>; /* milliseconds */
+ polling-delay = <1000>; /* milliseconds */
+
+ thermal-sensors = <&scpi_sensors 0>;
+
+ trips {
+ cpu_passive: cpu-passive {
+ temperature = <80000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "passive";
+ };
+
+ cpu_hot: cpu-hot {
+ temperature = <90000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "hot";
+ };
+
+ cpu_critical: cpu-critical {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cpu_cooling_maps: cooling-maps {
+ map0 {
+ trip = <&cpu_passive>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ trip = <&cpu_hot>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
arm-pmu {
compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm/dts/meson-gxbb-odroidc2.dts b/arch/arm/dts/meson-gxbb-odroidc2.dts
index 6ded279c40..b46ef985bb 100644
--- a/arch/arm/dts/meson-gxbb-odroidc2.dts
+++ b/arch/arm/dts/meson-gxbb-odroidc2.dts
@@ -248,6 +248,7 @@
status = "okay";
pinctrl-0 = <&remote_input_ao_pins>;
pinctrl-names = "default";
+ linux,rc-map-name = "rc-odroid";
};
&gpio_ao {
diff --git a/arch/arm/dts/meson-gxl-s905x-p212.dtsi b/arch/arm/dts/meson-gxl-s905x-p212.dtsi
index 43eb7d149e..6ac678f88b 100644
--- a/arch/arm/dts/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm/dts/meson-gxl-s905x-p212.dtsi
@@ -15,7 +15,6 @@
/ {
aliases {
serial0 = &uart_AO;
- serial1 = &uart_A;
ethernet0 = &ethmac;
};
@@ -180,6 +179,14 @@
pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
pinctrl-names = "default";
uart-has-rtscts;
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ max-speed = <2000000>;
+ clocks = <&wifi32k>;
+ clock-names = "lpo";
+ };
};
&uart_AO {
diff --git a/arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi b/arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi
index c35158d7e9..bec9e05b09 100644
--- a/arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi
+++ b/arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi
@@ -5,3 +5,18 @@
*/
#include "meson-gx-u-boot.dtsi"
+
+/ {
+ aliases {
+ spi0 = &spifc;
+ };
+};
+
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+};
+
+&spifc {
+ status = "okay";
+};
diff --git a/arch/arm/dts/meson-gxm-khadas-vim2.dts b/arch/arm/dts/meson-gxm-khadas-vim2.dts
index f82f25c1a5..27eeab71ec 100644
--- a/arch/arm/dts/meson-gxm-khadas-vim2.dts
+++ b/arch/arm/dts/meson-gxm-khadas-vim2.dts
@@ -8,7 +8,6 @@
/dts-v1/;
#include <dt-bindings/input/input.h>
-#include <dt-bindings/thermal/thermal.h>
#include "meson-gxm.dtsi"
@@ -100,49 +99,6 @@
clock-names = "ext_clock";
};
- thermal-zones {
- cpu-thermal {
- polling-delay-passive = <250>; /* milliseconds */
- polling-delay = <1000>; /* milliseconds */
-
- thermal-sensors = <&scpi_sensors 0>;
-
- trips {
- cpu_alert0: cpu-alert0 {
- temperature = <70000>; /* millicelsius */
- hysteresis = <2000>; /* millicelsius */
- type = "active";
- };
-
- cpu_alert1: cpu-alert1 {
- temperature = <80000>; /* millicelsius */
- hysteresis = <2000>; /* millicelsius */
- type = "passive";
- };
- };
-
- cooling-maps {
- map0 {
- trip = <&cpu_alert0>;
- cooling-device = <&gpio_fan THERMAL_NO_LIMIT 1>;
- };
-
- map1 {
- trip = <&cpu_alert1>;
- cooling-device = <&gpio_fan 2 THERMAL_NO_LIMIT>,
- <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
- };
- };
- };
- };
-
hdmi_5v: regulator-hdmi-5v {
compatible = "regulator-fixed";
@@ -198,36 +154,23 @@
hdmi-phandle = <&hdmi_tx>;
};
-&cpu0 {
- #cooling-cells = <2>;
-};
-
-&cpu1 {
- #cooling-cells = <2>;
-};
-
-&cpu2 {
- #cooling-cells = <2>;
-};
-&cpu3 {
- #cooling-cells = <2>;
-};
-
-&cpu4 {
- #cooling-cells = <2>;
-};
-
-&cpu5 {
- #cooling-cells = <2>;
-};
-
-&cpu6 {
- #cooling-cells = <2>;
-};
+&cpu_cooling_maps {
+ map0 {
+ cooling-device = <&gpio_fan THERMAL_NO_LIMIT 1>;
+ };
-&cpu7 {
- #cooling-cells = <2>;
+ map1 {
+ cooling-device = <&gpio_fan 2 THERMAL_NO_LIMIT>,
+ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
};
&ethmac {
@@ -327,7 +270,7 @@
#size-cells = <0>;
bus-width = <4>;
- max-frequency = <50000000>;
+ max-frequency = <60000000>;
non-removable;
disable-wp;
diff --git a/arch/arm/dts/meson-gxm.dtsi b/arch/arm/dts/meson-gxm.dtsi
index 5ff64a0d2d..b6f89f108e 100644
--- a/arch/arm/dts/meson-gxm.dtsi
+++ b/arch/arm/dts/meson-gxm.dtsi
@@ -49,6 +49,7 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 1>;
+ #cooling-cells = <2>;
};
cpu5: cpu@101 {
@@ -58,6 +59,7 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 1>;
+ #cooling-cells = <2>;
};
cpu6: cpu@102 {
@@ -67,6 +69,7 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 1>;
+ #cooling-cells = <2>;
};
cpu7: cpu@103 {
@@ -76,6 +79,7 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 1>;
+ #cooling-cells = <2>;
};
};
};
@@ -124,6 +128,30 @@
compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc";
};
+&cpu_cooling_maps {
+ map0 {
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+
+ map1 {
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+};
+
&saradc {
compatible = "amlogic,meson-gxm-saradc", "amlogic,meson-saradc";
};
diff --git a/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi b/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi
new file mode 100644
index 0000000000..81fd5be378
--- /dev/null
+++ b/arch/arm/dts/meson-khadas-vim3-u-boot.dtsi
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+/ {
+ aliases {
+ spi0 = &spifc;
+ };
+};
+
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_4b_pins>, <&emmc_ds_pins>;
+ bus-width = <4>;
+};
+
+&spifc {
+ status = "okay";
+};
diff --git a/arch/arm/dts/meson-khadas-vim3.dtsi b/arch/arm/dts/meson-khadas-vim3.dtsi
index 90815fa25e..094ecf2222 100644
--- a/arch/arm/dts/meson-khadas-vim3.dtsi
+++ b/arch/arm/dts/meson-khadas-vim3.dtsi
@@ -9,8 +9,6 @@
#include <dt-bindings/gpio/meson-g12a-gpio.h>
/ {
- model = "Khadas VIM3";
-
aliases {
serial0 = &uart_AO;
ethernet0 = &ethmac;
@@ -312,7 +310,7 @@
/* eMMC */
&sd_emmc_c {
status = "okay";
- pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
pinctrl-1 = <&emmc_clk_gate_pins>;
pinctrl-names = "default", "clk-gate";
@@ -328,6 +326,26 @@
vqmmc-supply = <&emmc_1v8>;
};
+/*
+ * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR CS
+ * and eMMC Data 4 to 7 pins.
+ * Replace emmc_data_8b_pins to emmc_data_4b_pins from sd_emmc_c pinctrl-0,
+ * and change bus-width to 4 then spifc can be enabled.
+ */
+&spifc {
+ status = "disabled";
+ pinctrl-0 = <&nor_pins>;
+ pinctrl-names = "default";
+
+ w25q32: spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "winbond,w25q128fw", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <104000000>;
+ };
+};
+
&uart_A {
status = "okay";
pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
diff --git a/arch/arm/dts/meson-sm1-khadas-vim3l-u-boot.dtsi b/arch/arm/dts/meson-sm1-khadas-vim3l-u-boot.dtsi
new file mode 100644
index 0000000000..f66eca14b1
--- /dev/null
+++ b/arch/arm/dts/meson-sm1-khadas-vim3l-u-boot.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include "meson-khadas-vim3-u-boot.dtsi"
diff --git a/arch/arm/dts/meson-sm1-khadas-vim3l.dts b/arch/arm/dts/meson-sm1-khadas-vim3l.dts
index 1001b376ca..dbbf29a0db 100644
--- a/arch/arm/dts/meson-sm1-khadas-vim3l.dts
+++ b/arch/arm/dts/meson-sm1-khadas-vim3l.dts
@@ -72,9 +72,10 @@
/*
* The VIM3 on-board MCU can mux the PCIe/USB3.0 shared differential
* lines using a FUSB340TMX USB 3.1 SuperSpeed Data Switch between
- * an USB3.0 Type A connector and a M.2 Key M slot. The PHY driving
- * these differential lines is shared between the USB3.0 controller
- * and the PCIe Controller, thus only a single controller can use it.
+ * an USB3.0 Type A connector and a M.2 Key M slot.
+ * The PHY driving these differential lines is shared between
+ * the USB3.0 controller and the PCIe Controller, thus only
+ * a single controller can use it.
* If the MCU is configured to mux the PCIe/USB3.0 differential lines
* to the M.2 Key M slot, uncomment the following block to disable
* USB3.0 from the USB Complex and enable the PCIe controller.
@@ -82,7 +83,6 @@
* testing purposes, but instead rely on the firmware/bootloader to
* update these nodes accordingly if PCIe mode is selected by the MCU.
*/
-
/*
&pcie {
status = "okay";
diff --git a/arch/arm/dts/meson-sm1-sei610.dts b/arch/arm/dts/meson-sm1-sei610.dts
index a8bb3fa9fe..dfb2438851 100644
--- a/arch/arm/dts/meson-sm1-sei610.dts
+++ b/arch/arm/dts/meson-sm1-sei610.dts
@@ -518,7 +518,7 @@
/* eMMC */
&sd_emmc_c {
status = "okay";
- pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
pinctrl-1 = <&emmc_clk_gate_pins>;
pinctrl-names = "default", "clk-gate";
@@ -593,6 +593,7 @@
compatible = "brcm,bcm43438-bt";
interrupt-parent = <&gpio_intc>;
interrupts = <95 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wakeup";
shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
max-speed = <2000000>;
clocks = <&wifi32k>;
diff --git a/arch/arm/dts/meson-sm1.dtsi b/arch/arm/dts/meson-sm1.dtsi
index d847a3fcbc..d4ec735fb1 100644
--- a/arch/arm/dts/meson-sm1.dtsi
+++ b/arch/arm/dts/meson-sm1.dtsi
@@ -448,6 +448,7 @@
<&clkc_audio AUD_CLKID_PDM_DCLK>,
<&clkc_audio AUD_CLKID_PDM_SYSCLK>;
clock-names = "pclk", "dclk", "sysclk";
+ resets = <&clkc_audio AUD_RESET_PDM>;
status = "disabled";
};
};
diff --git a/arch/arm/include/asm/arch-bcmcygnus/configs.h b/arch/arm/include/asm/arch-bcmcygnus/configs.h
index 9eafe43fba..bf05cb3a72 100644
--- a/arch/arm/include/asm/arch-bcmcygnus/configs.h
+++ b/arch/arm/include/asm/arch-bcmcygnus/configs.h
@@ -21,7 +21,6 @@
#define CONFIG_SYS_NS16550_COM3 0x18023000
/* Ethernet */
-#define CONFIG_PHY_BROADCOM
#define CONFIG_PHY_RESET_DELAY 10000 /* PHY reset delay in us*/
#endif /* __ARCH_CONFIGS_H */
diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h b/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
index e710aa2f94..9d2b3babab 100644
--- a/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
+++ b/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
@@ -85,7 +85,7 @@ void cm_basic_init(const struct cm_config * const cfg);
#define CLKMGR_S10_MAINPLL_VCOCALIB 0x8c
/* Periphpll group */
#define CLKMGR_S10_PERPLL_EN 0xa4
-#define CLKMGR_S10_PERPLL_BYPASS 0xac
+#define CLKMGR_S10_PERPLL_BYPASS 0xb0
#define CLKMGR_S10_PERPLL_CNTR2CLK 0xbc
#define CLKMGR_S10_PERPLL_CNTR3CLK 0xc0
#define CLKMGR_S10_PERPLL_CNTR4CLK 0xc4
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a3ae603044..48e754cc46 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -98,6 +98,7 @@ config ARCH_MTMIPS
select SUPPORTS_CPU_MIPS32_R2
select SUPPORTS_LITTLE_ENDIAN
select SYSRESET
+ select SUPPORT_SPL
config ARCH_JZ47XX
bool "Support Ingenic JZ47xx"
@@ -287,6 +288,60 @@ config MIPS_RELOCATION_TABLE_SIZE
If unsure, leave at the default value.
+config RESTORE_EXCEPTION_VECTOR_BASE
+ bool "Restore exception vector base before booting linux kernel"
+ default n
+ help
+ In U-Boot the exception vector base will be moved to top of memory,
+ to be used to display register dump when exception occurs.
+ But some old linux kernel does not honor the base set in CP0_EBASE.
+ A modified exception vector base will cause kernel crash.
+
+ This option will restore the exception vector base to its previous
+ value.
+
+ If unsure, say N.
+
+config OVERRIDE_EXCEPTION_VECTOR_BASE
+ bool "Override the exception vector base to be restored"
+ depends on RESTORE_EXCEPTION_VECTOR_BASE
+ default n
+ help
+ Enable this option if you want to use a different exception vector
+ base rather than the previously saved one.
+
+config NEW_EXCEPTION_VECTOR_BASE
+ hex "New exception vector base"
+ depends on OVERRIDE_EXCEPTION_VECTOR_BASE
+ range 0x80000000 0xbffff000
+ default 0x80000000
+ help
+ The exception vector base to be restored before booting linux kernel
+
+config INIT_STACK_WITHOUT_MALLOC_F
+ bool "Do not reserve malloc space on initial stack"
+ default n
+ help
+ Enable this option if you don't want to reserve malloc space on
+ initial stack. This is useful if the initial stack can't hold large
+ malloc space. Platform should set the malloc_base later when DRAM is
+ ready to use.
+
+config SPL_INIT_STACK_WITHOUT_MALLOC_F
+ bool "Do not reserve malloc space on initial stack in SPL"
+ default n
+ help
+ Enable this option if you don't want to reserve malloc space on
+ initial stack. This is useful if the initial stack can't hold large
+ malloc space. Platform should set the malloc_base later when DRAM is
+ ready to use.
+
+config SPL_LOADER_SUPPORT
+ bool
+ default n
+ help
+ Enable this option if you want to use SPL loaders without DM enabled.
+
endmenu
menu "OS boot interface"
@@ -389,6 +444,15 @@ config MIPS_INIT_STACK_IN_SRAM
lowlevel_init. Thus lowlevel_init does not need to be implemented
in assembler.
+config MIPS_SRAM_INIT
+ bool
+ default n
+ depends on MIPS_INIT_STACK_IN_SRAM
+ help
+ Select this if the SRAM for initial stack needs to be initialized
+ before it can be used. If enabled, a function mips_sram_init() will
+ be called just before setup_stack_gd.
+
config SYS_DCACHE_SIZE
int
default 0
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S
index 1d21b2324a..6de9a2f362 100644
--- a/arch/mips/cpu/start.S
+++ b/arch/mips/cpu/start.S
@@ -59,7 +59,8 @@
sp, sp, GD_SIZE # reserve space for gd
and sp, sp, t0 # force 16 byte alignment
move k0, sp # save gd pointer
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
+ !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
PTR_SUBU \
sp, sp, t2 # reserve space for early malloc
@@ -71,10 +72,12 @@
move t0, k0
1:
PTR_S zero, 0(t0)
+ PTR_ADDIU t0, PTRSIZE
blt t0, t1, 1b
- PTR_ADDIU t0, PTRSIZE
+ nop
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
+ !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
#endif
.endm
@@ -216,6 +219,13 @@ wr_done:
#endif
#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
+#ifdef CONFIG_MIPS_SRAM_INIT
+ /* Initialize the SRAM first */
+ PTR_LA t9, mips_sram_init
+ jalr t9
+ nop
+#endif
+
/* Set up initial stack and global data */
setup_stack_gd
diff --git a/arch/mips/cpu/u-boot-spl.lds b/arch/mips/cpu/u-boot-spl.lds
index d08d6222c4..28ea4f2a48 100644
--- a/arch/mips/cpu/u-boot-spl.lds
+++ b/arch/mips/cpu/u-boot-spl.lds
@@ -27,7 +27,7 @@ SECTIONS
*(SORT_BY_ALIGNMENT(.sdata*))
} > .spl_mem
-#ifdef CONFIG_SPL_DM
+#if defined(CONFIG_SPL_DM) || defined(CONFIG_SPL_LOADER_SUPPORT)
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
@@ -37,6 +37,8 @@ SECTIONS
. = ALIGN(4);
__image_copy_end = .;
+ _image_binary_end = .;
+
.bss (NOLOAD) : {
__bss_start = .;
*(.bss*)
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index c9d75596f2..f711e9fb59 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -17,11 +17,13 @@ dtb-$(CONFIG_BOARD_COMTREND_CT5361) += comtrend,ct-5361.dtb
dtb-$(CONFIG_BOARD_COMTREND_VR3032U) += comtrend,vr-3032u.dtb
dtb-$(CONFIG_BOARD_COMTREND_WAP5813N) += comtrend,wap-5813n.dtb
dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
+dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb
dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb
dtb-$(CONFIG_BOARD_SFR_NB4_SER) += sfr,nb4-ser.dtb
dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
+dtb-$(CONFIG_BOARD_VOCORE2) += vocore_vocore2.dtb
dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb
dtb-$(CONFIG_SOC_LUTON) += luton_pcb090.dtb luton_pcb091.dtb
dtb-$(CONFIG_SOC_OCELOT) += ocelot_pcb120.dtb ocelot_pcb123.dtb
diff --git a/arch/mips/dts/mediatek,mt7628-rfb.dts b/arch/mips/dts/mediatek,mt7628-rfb.dts
new file mode 100644
index 0000000000..6ff36daa6e
--- /dev/null
+++ b/arch/mips/dts/mediatek,mt7628-rfb.dts
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+/dts-v1/;
+
+#include "mt7628a.dtsi"
+
+/ {
+ compatible = "mediatek,mt7628-rfb", "ralink,mt7628a-soc";
+ model = "MediaTek MT7628 RFB";
+
+ aliases {
+ serial0 = &uart0;
+ spi0 = &spi0;
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ };
+};
+
+&pinctrl {
+ state_default: pin_state {
+ pleds {
+ groups = "p0led", "p1led", "p2led", "p3led", "p4led";
+ function = "led";
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+ num-cs = <2>;
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+};
+
+&eth {
+ mediatek,wan-port = <0>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ephy_router_mode>;
+};
+
+&mmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_router_mode>;
+
+ status = "okay";
+};
diff --git a/arch/mips/dts/mt7628-u-boot.dtsi b/arch/mips/dts/mt7628-u-boot.dtsi
new file mode 100644
index 0000000000..eea5dc64bf
--- /dev/null
+++ b/arch/mips/dts/mt7628-u-boot.dtsi
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+&palmbus {
+ u-boot,dm-pre-reloc;
+};
+
+&reboot {
+ u-boot,dm-pre-reloc;
+};
+
+&clkctrl {
+ u-boot,dm-pre-reloc;
+};
+
+&rstctrl {
+ u-boot,dm-pre-reloc;
+};
+
+&pinctrl {
+ u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
+
+&uart1 {
+ u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi
index 76a80c8952..6baa63add3 100644
--- a/arch/mips/dts/mt7628a.dtsi
+++ b/arch/mips/dts/mt7628a.dtsi
@@ -33,7 +33,7 @@
#clock-cells = <0>;
};
- palmbus@10000000 {
+ palmbus: palmbus@10000000 {
compatible = "palmbus", "simple-bus";
reg = <0x10000000 0x200000>;
ranges = <0x0 0x10000000 0x1FFFFF>;
@@ -46,11 +46,11 @@
reg = <0x0 0x100>;
};
- syscon-reboot {
- compatible = "syscon-reboot";
- regmap = <&sysc>;
- offset = <0x34>;
- mask = <0x1>;
+ reboot: resetctl-reboot {
+ compatible = "resetctl-reboot";
+
+ resets = <&rstctrl MT7628_SYS_RST>;
+ reset-names = "sysreset";
};
clkctrl: clkctrl@0x2c {
@@ -110,6 +110,11 @@
function = "uart2";
};
+ uart2_pwm_pins: uart2_pwm_pins {
+ groups = "spis";
+ function = "pwm_uart2";
+ };
+
i2c_pins: i2c_pins {
groups = "i2c";
function = "i2c";
diff --git a/arch/mips/dts/vocore_vocore2.dts b/arch/mips/dts/vocore_vocore2.dts
new file mode 100644
index 0000000000..3502e4b8b7
--- /dev/null
+++ b/arch/mips/dts/vocore_vocore2.dts
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Mauro Condarelli <mc5686@mclink.it>
+ */
+
+/dts-v1/;
+
+#include "mt7628a.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ compatible = "vocore,vocore2", "ralink,mt7628a-soc";
+ model = "VoCore2";
+
+ aliases {
+ serial0 = &uart2;
+ spi0 = &spi0;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x08000000>;
+ };
+ leds {
+ compatible = "gpio-leds";
+
+ power {
+ label = "vocore:power";
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS2,115200";
+ stdout-path = &uart2;
+ };
+};
+
+&pinctrl {
+ state_default: pin_state {
+ p0led {
+ groups = "p0led_a";
+ function = "led";
+ };
+ };
+};
+
+&uart2 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pwm_pins>;
+};
+
+&spi0 {
+ status = "okay";
+ nor0: spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+};
+
+&eth {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ephy_iot_mode>;
+ mediatek,poll-link-phy = <0>;
+};
+
+&mmc {
+ status = "okay";
+
+ bus-width = <4>;
+ max-frequency = <48000000>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_iot_mode>;
+};
diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
index 7b4ad083ba..4c30fab871 100644
--- a/arch/mips/include/asm/global_data.h
+++ b/arch/mips/include/asm/global_data.h
@@ -27,6 +27,9 @@ struct arch_global_data {
#ifdef CONFIG_MIPS_L2_CACHE
unsigned short l2_line_size;
#endif
+#ifdef CONFIG_ARCH_MTMIPS
+ unsigned long timer_freq;
+#endif
};
#include <asm-generic/global_data.h>
diff --git a/arch/mips/include/asm/u-boot-mips.h b/arch/mips/include/asm/u-boot-mips.h
index 88438b9576..8b37cc4029 100644
--- a/arch/mips/include/asm/u-boot-mips.h
+++ b/arch/mips/include/asm/u-boot-mips.h
@@ -9,4 +9,6 @@ void except_vec_ejtag_debug(void);
int arch_misc_init(void);
+void trap_restore(void);
+
#endif /* _U_BOOT_MIPS_H_ */
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 24a72d9c97..9ee1fcb5c7 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -12,5 +12,6 @@ obj-y += traps.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_GO) += boot.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += ashldi3.o ashrdi3.o lshrdi3.o
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
index 8c0d7672f2..f1db6d23b8 100644
--- a/arch/mips/lib/bootm.c
+++ b/arch/mips/lib/bootm.c
@@ -294,6 +294,9 @@ static void boot_jump_linux(bootm_headers_t *images)
bootstage_report();
#endif
+ if (CONFIG_IS_ENABLED(RESTORE_EXCEPTION_VECTOR_BASE))
+ trap_restore();
+
if (images->ft_len)
kernel(-2, (ulong)images->ft_addr, 0, 0);
else
diff --git a/arch/mips/lib/spl.c b/arch/mips/lib/spl.c
new file mode 100644
index 0000000000..7ba3e53f6d
--- /dev/null
+++ b/arch/mips/lib/spl.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <spl.h>
+
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+ typedef void __noreturn (*image_entry_noargs_t)(void);
+ image_entry_noargs_t image_entry =
+ (image_entry_noargs_t)spl_image->entry_point;
+
+ /* Flush cache before jumping to application */
+ flush_cache((unsigned long)spl_image->load_addr, spl_image->size);
+
+ debug("image entry point: 0x%lx\n", spl_image->entry_point);
+ image_entry();
+}
diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c
index b8568c00fe..8fff7541e3 100644
--- a/arch/mips/lib/traps.c
+++ b/arch/mips/lib/traps.c
@@ -20,6 +20,8 @@
DECLARE_GLOBAL_DATA_PTR;
+static unsigned long saved_ebase;
+
static void show_regs(const struct pt_regs *regs)
{
const int field = 2 * sizeof(unsigned long);
@@ -102,7 +104,24 @@ void trap_init(ulong reloc_addr)
set_handler(0x180, &except_vec3_generic, 0x80);
set_handler(0x280, &except_vec_ejtag_debug, 0x80);
+ saved_ebase = read_c0_ebase() & 0xfffff000;
+
write_c0_ebase(ebase);
clear_c0_status(ST0_BEV);
execution_hazard_barrier();
}
+
+void trap_restore(void)
+{
+ set_c0_status(ST0_BEV);
+ execution_hazard_barrier();
+
+#ifdef CONFIG_OVERRIDE_EXCEPTION_VECTOR_BASE
+ write_c0_ebase(CONFIG_NEW_EXCEPTION_VECTOR_BASE & 0xfffff000);
+#else
+ write_c0_ebase(saved_ebase);
+#endif
+
+ clear_c0_status(ST0_BEV);
+ execution_hazard_barrier();
+}
diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig
index c8dcf19c0d..737de2cb8e 100644
--- a/arch/mips/mach-mtmips/Kconfig
+++ b/arch/mips/mach-mtmips/Kconfig
@@ -7,14 +7,52 @@ config SYS_MALLOC_F_LEN
config SYS_SOC
default "mt7628" if SOC_MT7628
+config SYS_DCACHE_SIZE
+ default 32768
+
+config SYS_DCACHE_LINE_SIZE
+ default 32
+
+config SYS_ICACHE_SIZE
+ default 65536
+
+config SYS_ICACHE_LINE_SIZE
+ default 32
+
+config SYS_TEXT_BASE
+ default 0x9c000000 if !SPL
+ default 0x80200000 if SPL
+
+config SPL_TEXT_BASE
+ default 0x9c000000
+
+config SPL_PAYLOAD
+ default "u-boot-lzma.img" if SPL_LZMA
+
+config BUILD_TARGET
+ default "u-boot-with-spl.bin" if SPL
+
choice
prompt "MediaTek MIPS SoC select"
config SOC_MT7628
bool "MT7628"
select MIPS_L1_CACHE_SHIFT_5
+ select MIPS_INIT_STACK_IN_SRAM
+ select MIPS_SRAM_INIT
+ select SYS_MIPS_CACHE_INIT_RAM_LOAD
select PINCTRL_MT7628
select MTK_SERIAL
+ select SYSRESET_RESETCTL
+ select SPL_SEPARATE_BSS if SPL
+ select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
+ select SPL_LOADER_SUPPORT if SPL
+ select SPL_OF_CONTROL if SPL_DM
+ select SPL_SIMPLE_BUS if SPL_DM
+ select SPL_DM_SERIAL if SPL_DM
+ select SPL_CLK if SPL_DM && SPL_SERIAL_SUPPORT
+ select SPL_SYSRESET if SPL_DM
+ select SPL_OF_LIBFDT if SPL_OF_CONTROL
help
This supports MediaTek MT7628/MT7688.
@@ -27,7 +65,6 @@ 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.
@@ -35,7 +72,6 @@ config BOARD_GARDENA_SMART_GATEWAY_MT7688
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).
@@ -43,96 +79,36 @@ config BOARD_LINKIT_SMART_7688
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
+config BOARD_MT7628_RFB
+ bool "MediaTek MT7628 RFB"
+ depends on SOC_MT7628
help
- Use DDR chips with 8bit width
+ The reference design of MT7628. The board has 128 MiB DDR2, 8 MiB
+ SPI-NOR flash, 1 built-in switch with 5 ports, 1 UART, 1 USB host,
+ 1 SDXC, 1 PCIe socket and JTAG pins.
-config ONBOARD_DDR2_CHIP_WIDTH_16BIT
- bool "16bit DDR chip width"
- depends on BOOT_ROM
+config BOARD_VOCORE2
+ bool "VoCore2"
+ depends on SOC_MT7628
+ select SPL_SERIAL_SUPPORT
+ select SPL_UART2_SPIS_PINMUX
help
- Use DDR chips with 16bit width
+ VoCore VoCore2 board has a MT7628 SoC with 128 MiB of RAM
+ and 16 MiB of flash (SPI).
endchoice
-choice
- prompt "DDR2 bus width"
-
-config ONBOARD_DDR2_BUS_WIDTH_16BIT
- bool "16bit DDR bus width"
- depends on BOOT_ROM
+config SPL_UART2_SPIS_PINMUX
+ bool "Use alternative pinmux for UART2 in SPL stage"
+ depends on SPL_SERIAL_SUPPORT
+ default n
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
+ Select this if the UART2 of your board is connected to GPIO 16/17
+ (shared with SPIS) rather than the usual GPIO 20/21.
source "board/gardena/smart-gateway-mt7688/Kconfig"
+source "board/mediatek/mt7628/Kconfig"
source "board/seeed/linkit-smart-7688/Kconfig"
+source "board/vocore/vocore2/Kconfig"
endmenu
diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile
index 1f3e65e8a5..a7e6a66304 100644
--- a/arch/mips/mach-mtmips/Makefile
+++ b/arch/mips/mach-mtmips/Makefile
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y += cpu.o
+obj-y += ddr_init.o
+obj-y += ddr_cal.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
-ifndef CONFIG_SKIP_LOWLEVEL_INIT
-obj-y += ddr_calibrate.o
-obj-y += lowlevel_init.o
-endif
+obj-$(CONFIG_SOC_MT7628) += mt7628/
diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c
index 8976ef57c7..459a9673eb 100644
--- a/arch/mips/mach-mtmips/cpu.c
+++ b/arch/mips/mach-mtmips/cpu.c
@@ -4,69 +4,17 @@
*/
#include <common.h>
-#include <dm.h>
-#include <init.h>
#include <malloc.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
+DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
+#ifdef CONFIG_SKIP_LOWLEVEL_INIT
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]);
+#endif
return 0;
}
diff --git a/arch/mips/mach-mtmips/ddr_cal.c b/arch/mips/mach-mtmips/ddr_cal.c
new file mode 100644
index 0000000000..71a53c3c9c
--- /dev/null
+++ b/arch/mips/mach-mtmips/ddr_cal.c
@@ -0,0 +1,205 @@
+// 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 <asm/cacheops.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <mach/mc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define COARSE_MIN_START 6
+#define FINE_MIN_START 15
+#define COARSE_MAX_START 7
+#define FINE_MAX_START 0
+
+#define NUM_OF_CACHELINE 128
+#define TEST_PAT_SIZE (NUM_OF_CACHELINE * CONFIG_SYS_CACHELINE_SIZE)
+
+#define INIT_DQS_VAL ((7 << DQS1_DELAY_COARSE_TUNING_S) | \
+ (4 << DQS1_DELAY_FINE_TUNING_S) | \
+ (7 << DQS0_DELAY_COARSE_TUNING_S) | \
+ (4 << DQS0_DELAY_FINE_TUNING_S))
+
+static inline void pref_op(int op, const volatile void *addr)
+{
+ __asm__ __volatile__("pref %0, 0(%1)" : : "i" (op), "r" (addr));
+}
+
+static inline bool dqs_test_error(void __iomem *memc, u32 memsize, u32 dqsval,
+ u32 bias)
+{
+ u32 *nca, *ca;
+ u32 off;
+ int i;
+
+ for (off = 0; off < memsize - TEST_PAT_SIZE; off += (memsize >> 6)) {
+ nca = (u32 *)KSEG1ADDR(off);
+ ca = (u32 *)KSEG0ADDR(off);
+
+ writel(INIT_DQS_VAL, memc + MEMCTL_DDR_DQS_DLY_REG);
+ wmb();
+
+ for (i = 0; i < TEST_PAT_SIZE / sizeof(u32); i++)
+ ca[i] = 0x1f1f1f1f;
+
+ for (i = 0; i < TEST_PAT_SIZE / sizeof(u32); i++)
+ nca[i] = (u32)nca + i + bias;
+
+ writel(dqsval, memc + MEMCTL_DDR_DQS_DLY_REG);
+ wmb();
+
+ for (i = 0; i < TEST_PAT_SIZE; i += CONFIG_SYS_CACHELINE_SIZE)
+ mips_cache(HIT_INVALIDATE_D, (u8 *)ca + i);
+ wmb();
+
+ for (i = 0; i < TEST_PAT_SIZE; i += CONFIG_SYS_CACHELINE_SIZE)
+ pref_op(0, (u8 *)ca + i);
+
+ for (i = 0; i < TEST_PAT_SIZE / sizeof(u32); i++) {
+ if (ca[i] != (u32)nca + i + bias)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static inline int dqs_find_max(void __iomem *memc, u32 memsize, int initval,
+ int maxval, int shift, u32 regval)
+{
+ int fieldval;
+ u32 dqsval;
+
+ for (fieldval = initval; fieldval <= maxval; fieldval++) {
+ dqsval = regval | (fieldval << shift);
+ if (dqs_test_error(memc, memsize, dqsval, 3))
+ return max(fieldval - 1, initval);
+ }
+
+ return maxval;
+}
+
+static inline int dqs_find_min(void __iomem *memc, u32 memsize, int initval,
+ int minval, int shift, u32 regval)
+{
+ int fieldval;
+ u32 dqsval;
+
+ for (fieldval = initval; fieldval >= minval; fieldval--) {
+ dqsval = regval | (fieldval << shift);
+ if (dqs_test_error(memc, memsize, dqsval, 1))
+ return min(fieldval + 1, initval);
+ }
+
+ return minval;
+}
+
+void ddr_calibrate(void __iomem *memc, u32 memsize, u32 bw)
+{
+ u32 dqs_coarse_min, dqs_coarse_max, dqs_coarse_val;
+ u32 dqs_fine_min, dqs_fine_max, dqs_fine_val;
+ u32 dqs_coarse_min_limit, dqs_fine_min_limit;
+ u32 dlls, dqs_dll, ddr_cfg2_reg;
+ u32 dqs_dly_tmp, dqs_dly, test_dqs, shift;
+ u32 rem, mask;
+ int i;
+
+ /* Disable Self-refresh */
+ clrbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
+
+ /* Save DDR_CFG2 and modify its DQS gating window */
+ ddr_cfg2_reg = readl(memc + MEMCTL_DDR_CFG2_REG);
+ mask = DQS0_GATING_WINDOW_M;
+ if (bw == IND_SDRAM_WIDTH_16BIT)
+ mask |= DQS1_GATING_WINDOW_M;
+ clrbits_32(memc + MEMCTL_DDR_CFG2_REG, mask);
+
+ /* Get minimum available DQS value */
+ dlls = readl(memc + MEMCTL_DLL_DBG_REG);
+ dlls = (dlls & MST_DLY_SEL_M) >> MST_DLY_SEL_S;
+
+ dqs_dll = dlls >> 4;
+ if (dqs_dll <= 8)
+ dqs_coarse_min_limit = 8 - dqs_dll;
+ else
+ dqs_coarse_min_limit = 0;
+
+ dqs_dll = dlls & 0xf;
+ if (dqs_dll <= 8)
+ dqs_fine_min_limit = 8 - dqs_dll;
+ else
+ dqs_fine_min_limit = 0;
+
+ /* Initial DQS register value */
+ dqs_dly = INIT_DQS_VAL;
+
+ /* Calibrate DQS0 and/or DQS1 */
+ for (i = 0; i < bw; i++) {
+ shift = i * 8;
+ dqs_dly &= ~(0xff << shift);
+
+ /* Find maximum DQS coarse-grain */
+ dqs_dly_tmp = dqs_dly | (0xf << shift);
+ dqs_coarse_max = dqs_find_max(memc, memsize, COARSE_MAX_START,
+ 0xf, 4 + shift, dqs_dly_tmp);
+
+ /* Find maximum DQS fine-grain */
+ dqs_dly_tmp = dqs_dly | (dqs_coarse_max << (4 + shift));
+ test_dqs = dqs_find_max(memc, memsize, FINE_MAX_START, 0xf,
+ shift, dqs_dly_tmp);
+
+ if (test_dqs == FINE_MAX_START) {
+ dqs_coarse_max--;
+ dqs_fine_max = 0xf;
+ } else {
+ dqs_fine_max = test_dqs - 1;
+ }
+
+ /* Find minimum DQS coarse-grain */
+ dqs_dly_tmp = dqs_dly;
+ dqs_coarse_min = dqs_find_min(memc, memsize, COARSE_MIN_START,
+ dqs_coarse_min_limit, 4 + shift,
+ dqs_dly_tmp);
+
+ /* Find minimum DQS fine-grain */
+ dqs_dly_tmp = dqs_dly | (dqs_coarse_min << (4 + shift));
+ test_dqs = dqs_find_min(memc, memsize, FINE_MIN_START,
+ dqs_fine_min_limit, shift, dqs_dly_tmp);
+
+ if (test_dqs == FINE_MIN_START + 1) {
+ dqs_coarse_min++;
+ dqs_fine_min = 0;
+ } else {
+ dqs_fine_min = test_dqs;
+ }
+
+ /* Calculate central DQS coarse/fine value */
+ dqs_coarse_val = (dqs_coarse_max + dqs_coarse_min) >> 1;
+ rem = (dqs_coarse_max + dqs_coarse_min) % 2;
+
+ dqs_fine_val = (rem * 4) + ((dqs_fine_max + dqs_fine_min) >> 1);
+ if (dqs_fine_val >= 0x10) {
+ dqs_coarse_val++;
+ dqs_fine_val -= 8;
+ }
+
+ /* Save current DQS value */
+ dqs_dly |= ((dqs_coarse_val << 4) | dqs_fine_val) << shift;
+ }
+
+ /* Set final DQS value */
+ writel(dqs_dly, memc + MEMCTL_DDR_DQS_DLY_REG);
+
+ /* Restore DDR_CFG2 */
+ writel(ddr_cfg2_reg, memc + MEMCTL_DDR_CFG2_REG);
+
+ /* Enable Self-refresh */
+ setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
+}
diff --git a/arch/mips/mach-mtmips/ddr_calibrate.c b/arch/mips/mach-mtmips/ddr_calibrate.c
deleted file mode 100644
index 3cd440804d..0000000000
--- a/arch/mips/mach-mtmips/ddr_calibrate.c
+++ /dev/null
@@ -1,309 +0,0 @@
-// 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 <cpu_func.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);
-}
diff --git a/arch/mips/mach-mtmips/ddr_init.c b/arch/mips/mach-mtmips/ddr_init.c
new file mode 100644
index 0000000000..cd355cc840
--- /dev/null
+++ b/arch/mips/mach-mtmips/ddr_init.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include <mach/ddr.h>
+#include <mach/mc.h>
+
+#define DDR_BW_TEST_PAT 0xaa5555aa
+
+static const u32 dram_size[] = {
+ [DRAM_8MB] = SZ_8M,
+ [DRAM_16MB] = SZ_16M,
+ [DRAM_32MB] = SZ_32M,
+ [DRAM_64MB] = SZ_64M,
+ [DRAM_128MB] = SZ_128M,
+ [DRAM_256MB] = SZ_256M,
+};
+
+static void dram_test_write(u32 addr, u32 val)
+{
+ volatile ulong *target = (volatile ulong *)(KSEG1 + addr);
+
+ sync();
+ *target = val;
+ sync();
+}
+
+static u32 dram_test_read(u32 addr)
+{
+ volatile ulong *target = (volatile ulong *)(KSEG1 + addr);
+ u32 val;
+
+ sync();
+ val = *target;
+ sync();
+
+ return val;
+}
+
+static int dram_addr_test_bit(u32 bit)
+{
+ u32 val;
+
+ dram_test_write(0, 0);
+ dram_test_write(BIT(bit), DDR_BW_TEST_PAT);
+ val = dram_test_read(0);
+
+ if (val == DDR_BW_TEST_PAT)
+ return 1;
+
+ return 0;
+}
+
+static void mc_ddr_init(void __iomem *memc, const struct mc_ddr_cfg *cfg,
+ u32 dq_dly, u32 dqs_dly, mc_reset_t mc_reset, u32 bw)
+{
+ u32 val;
+
+ mc_reset(1);
+ __udelay(200);
+ mc_reset(0);
+
+ clrbits_32(memc + MEMCTL_SDRAM_CFG1_REG, RBC_MAPPING);
+
+ writel(cfg->cfg2, memc + MEMCTL_DDR_CFG2_REG);
+ writel(cfg->cfg3, memc + MEMCTL_DDR_CFG3_REG);
+ writel(cfg->cfg4, memc + MEMCTL_DDR_CFG4_REG);
+ writel(dq_dly, memc + MEMCTL_DDR_DQ_DLY_REG);
+ writel(dqs_dly, memc + MEMCTL_DDR_DQS_DLY_REG);
+
+ writel(cfg->cfg0, memc + MEMCTL_DDR_CFG0_REG);
+
+ val = cfg->cfg1;
+ if (bw) {
+ val &= ~IND_SDRAM_WIDTH_M;
+ val |= (bw << IND_SDRAM_WIDTH_S) & IND_SDRAM_WIDTH_M;
+ }
+
+ writel(val, memc + MEMCTL_DDR_CFG1_REG);
+
+ clrsetbits_32(memc + MEMCTL_PWR_SAVE_CNT_REG, SR_TAR_CNT_M,
+ 1 << SR_TAR_CNT_S);
+
+ setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
+}
+
+void ddr1_init(struct mc_ddr_init_param *param)
+{
+ enum mc_dram_size sz;
+ u32 bw = 0;
+
+ /* First initialization, determine bus width */
+ mc_ddr_init(param->memc, &param->cfgs[DRAM_8MB], param->dq_dly,
+ param->dqs_dly, param->mc_reset, IND_SDRAM_WIDTH_16BIT);
+
+ /* Test bus width */
+ dram_test_write(0, DDR_BW_TEST_PAT);
+ if (dram_test_read(0) == DDR_BW_TEST_PAT)
+ bw = IND_SDRAM_WIDTH_16BIT;
+ else
+ bw = IND_SDRAM_WIDTH_8BIT;
+
+ /* Second initialization, determine DDR capacity */
+ mc_ddr_init(param->memc, &param->cfgs[DRAM_128MB], param->dq_dly,
+ param->dqs_dly, param->mc_reset, bw);
+
+ if (dram_addr_test_bit(9)) {
+ sz = DRAM_8MB;
+ } else {
+ if (dram_addr_test_bit(10)) {
+ if (dram_addr_test_bit(23))
+ sz = DRAM_16MB;
+ else
+ sz = DRAM_32MB;
+ } else {
+ if (dram_addr_test_bit(24))
+ sz = DRAM_64MB;
+ else
+ sz = DRAM_128MB;
+ }
+ }
+
+ /* Final initialization, with DDR calibration */
+ mc_ddr_init(param->memc, &param->cfgs[sz], param->dq_dly,
+ param->dqs_dly, param->mc_reset, bw);
+
+ /* Return actual DDR configuration */
+ param->memsize = dram_size[sz];
+ param->bus_width = bw;
+}
+
+void ddr2_init(struct mc_ddr_init_param *param)
+{
+ enum mc_dram_size sz;
+ u32 bw = 0;
+
+ /* First initialization, determine bus width */
+ mc_ddr_init(param->memc, &param->cfgs[DRAM_32MB], param->dq_dly,
+ param->dqs_dly, param->mc_reset, IND_SDRAM_WIDTH_16BIT);
+
+ /* Test bus width */
+ dram_test_write(0, DDR_BW_TEST_PAT);
+ if (dram_test_read(0) == DDR_BW_TEST_PAT)
+ bw = IND_SDRAM_WIDTH_16BIT;
+ else
+ bw = IND_SDRAM_WIDTH_8BIT;
+
+ /* Second initialization, determine DDR capacity */
+ mc_ddr_init(param->memc, &param->cfgs[DRAM_256MB], param->dq_dly,
+ param->dqs_dly, param->mc_reset, bw);
+
+ if (bw == IND_SDRAM_WIDTH_16BIT) {
+ if (dram_addr_test_bit(10)) {
+ sz = DRAM_32MB;
+ } else {
+ if (dram_addr_test_bit(24)) {
+ if (dram_addr_test_bit(27))
+ sz = DRAM_64MB;
+ else
+ sz = DRAM_128MB;
+ } else {
+ sz = DRAM_256MB;
+ }
+ }
+ } else {
+ if (dram_addr_test_bit(23)) {
+ sz = DRAM_32MB;
+ } else {
+ if (dram_addr_test_bit(24)) {
+ if (dram_addr_test_bit(27))
+ sz = DRAM_64MB;
+ else
+ sz = DRAM_128MB;
+ } else {
+ sz = DRAM_256MB;
+ }
+ }
+ }
+
+ /* Final initialization, with DDR calibration */
+ mc_ddr_init(param->memc, &param->cfgs[sz], param->dq_dly,
+ param->dqs_dly, param->mc_reset, bw);
+
+ /* Return actual DDR configuration */
+ param->memsize = dram_size[sz];
+ param->bus_width = bw;
+}
diff --git a/arch/mips/mach-mtmips/include/mach/ddr.h b/arch/mips/mach-mtmips/include/mach/ddr.h
new file mode 100644
index 0000000000..f92198137b
--- /dev/null
+++ b/arch/mips/mach-mtmips/include/mach/ddr.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTMIPS_DDR_H_
+#define _MTMIPS_DDR_H_
+
+#include <linux/io.h>
+#include <linux/types.h>
+
+enum mc_dram_size {
+ DRAM_8MB,
+ DRAM_16MB,
+ DRAM_32MB,
+ DRAM_64MB,
+ DRAM_128MB,
+ DRAM_256MB,
+
+ __DRAM_SZ_MAX
+};
+
+struct mc_ddr_cfg {
+ u32 cfg0;
+ u32 cfg1;
+ u32 cfg2;
+ u32 cfg3;
+ u32 cfg4;
+};
+
+typedef void (*mc_reset_t)(int assert);
+
+struct mc_ddr_init_param {
+ void __iomem *memc;
+
+ u32 dq_dly;
+ u32 dqs_dly;
+
+ const struct mc_ddr_cfg *cfgs;
+ mc_reset_t mc_reset;
+
+ u32 memsize;
+ u32 bus_width;
+};
+
+void ddr1_init(struct mc_ddr_init_param *param);
+void ddr2_init(struct mc_ddr_init_param *param);
+void ddr_calibrate(void __iomem *memc, u32 memsize, u32 bw);
+
+#endif /* _MTMIPS_DDR_H_ */
diff --git a/arch/mips/mach-mtmips/include/mach/mc.h b/arch/mips/mach-mtmips/include/mach/mc.h
new file mode 100644
index 0000000000..d7d623a63b
--- /dev/null
+++ b/arch/mips/mach-mtmips/include/mach/mc.h
@@ -0,0 +1,180 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTMIPS_MC_H_
+#define _MTMIPS_MC_H_
+
+#define MEMCTL_SDRAM_CFG0_REG 0x00
+#define DIS_CLK_GT 0x80000000
+#define CLK_SLEW_S 29
+#define CLK_SLEW_M 0x60000000
+#define TWR 0x10000000
+#define TMRD_S 24
+#define TMRD_M 0xf000000
+#define TRFC_S 20
+#define TRFC_M 0xf00000
+#define TCAS_S 16
+#define TCAS_M 0x30000
+#define TRAS_S 12
+#define TRAS_M 0xf000
+#define TRCD_S 8
+#define TRCD_M 0x300
+#define TRC_S 4
+#define TRC_M 0xf0
+#define TRP_S 0
+#define TRP_M 0x03
+
+#define MEMCTL_SDRAM_CFG1_REG 0x04
+#define SDRAM_INIT_START 0x80000000
+#define SDRAM_INIT_DONE 0x40000000
+#define RBC_MAPPING 0x20000000
+#define PWR_DOWN_EN 0x10000000
+#define PWR_DOWN_MODE 0x8000000
+#define SDRAM_WIDTH 0x1000000
+#define NUMCOLS_S 20
+#define NUMCOLS_M 0x300000
+#define NUMROWS_S 16
+#define NUMROWS_M 0x30000
+#define TREFR_S 0
+#define TREFR_M 0xffff
+
+#define MEMCTL_DDR_SELF_REFRESH_REG 0x10
+#define ODT_SRC_SEL_S 24
+#define ODT_SRC_SEL_M 0xf000000
+#define ODT_OFF_DLY_S 20
+#define ODT_OFF_DLY_M 0xf00000
+#define ODT_ON_DLY_S 16
+#define ODT_ON_DLY_M 0xf0000
+#define SR_AUTO_EN 0x10
+#define SRACK_B 0x02
+#define SRREQ_B 0x01
+
+#define MEMCTL_PWR_SAVE_CNT_REG 0x14
+#define PD_CNT_S 24
+#define PD_CNT_M 0xff000000
+#define SR_TAR_CNT_S 0
+#define SR_TAR_CNT_M 0xffffff
+
+#define MEMCTL_DLL_DBG_REG 0x20
+#define TDC_STABLE_S 12
+#define TDC_STABLE_M 0x3f000
+#define MST_DLY_SEL_S 4
+#define MST_DLY_SEL_M 0xff0
+#define CURR_STATE_S 1
+#define CURR_STATE_M 0x06
+#define ADLL_LOCK_DONE 0x01
+
+#define MEMCTL_DDR_CFG0_REG 0x40
+#define T_RRD_S 28
+#define T_RRD_M 0xf0000000
+#define T_RAS_S 23
+#define T_RAS_M 0xf800000
+#define T_RP_S 19
+#define T_RP_M 0x780000
+#define T_RFC_S 13
+#define T_RFC_M 0x7e000
+#define T_REFI_S 0
+#define T_REFI_M 0x1fff
+
+#define MEMCTL_DDR_CFG1_REG 0x44
+#define T_WTR_S 28
+#define T_WTR_M 0xf0000000
+#define T_RTP_S 24
+#define T_RTP_M 0xf000000
+#define USER_DATA_WIDTH 0x200000
+#define IND_SDRAM_SIZE_S 18
+#define IND_SDRAM_SIZE_M 0x1c0000
+#define IND_SDRAM_SIZE_8MB 1
+#define IND_SDRAM_SIZE_16MB 2
+#define IND_SDRAM_SIZE_32MB 3
+#define IND_SDRAM_SIZE_64MB 4
+#define IND_SDRAM_SIZE_128MB 5
+#define IND_SDRAM_SIZE_256MB 6
+#define IND_SDRAM_WIDTH_S 16
+#define IND_SDRAM_WIDTH_M 0x30000
+#define IND_SDRAM_WIDTH_8BIT 1
+#define IND_SDRAM_WIDTH_16BIT 2
+#define EXT_BANK_S 14
+#define EXT_BANK_M 0xc000
+#define TOTAL_SDRAM_WIDTH_S 12
+#define TOTAL_SDRAM_WIDTH_M 0x3000
+#define T_WR_S 8
+#define T_WR_M 0xf00
+#define T_MRD_S 4
+#define T_MRD_M 0xf0
+#define T_RCD_S 0
+#define T_RCD_M 0x0f
+
+#define MEMCTL_DDR_CFG2_REG 0x48
+#define REGE 0x80000000
+#define DDR2_MODE 0x40000000
+#define DQS0_GATING_WINDOW_S 28
+#define DQS0_GATING_WINDOW_M 0x30000000
+#define DQS1_GATING_WINDOW_S 26
+#define DQS1_GATING_WINDOW_M 0xc000000
+#define PD 0x1000
+#define WR_S 9
+#define WR_M 0xe00
+#define DLLRESET 0x100
+#define TESTMODE 0x80
+#define CAS_LATENCY_S 4
+#define CAS_LATENCY_M 0x70
+#define BURST_TYPE 0x08
+#define BURST_LENGTH_S 0
+#define BURST_LENGTH_M 0x07
+
+#define MEMCTL_DDR_CFG3_REG 0x4c
+#define Q_OFF 0x1000
+#define RDOS 0x800
+#define DIS_DIFF_DQS 0x400
+#define OCD_S 7
+#define OCD_M 0x380
+#define RTT1 0x40
+#define ADDITIVE_LATENCY_S 3
+#define ADDITIVE_LATENCY_M 0x38
+#define RTT0 0x04
+#define DS 0x02
+#define DLL 0x01
+
+#define MEMCTL_DDR_CFG4_REG 0x50
+#define FAW_S 0
+#define FAW_M 0x0f
+
+#define MEMCTL_DDR_DQ_DLY_REG 0x60
+#define DQ1_DELAY_SEL_S 24
+#define DQ1_DELAY_SEL_M 0xff000000
+#define DQ0_DELAY_SEL_S 16
+#define DQ0_DELAY_SEL_M 0xff0000
+#define DQ1_DELAY_COARSE_TUNING_S 12
+#define DQ1_DELAY_COARSE_TUNING_M 0xf000
+#define DQ1_DELAY_FINE_TUNING_S 8
+#define DQ1_DELAY_FINE_TUNING_M 0xf00
+#define DQ0_DELAY_COARSE_TUNING_S 4
+#define DQ0_DELAY_COARSE_TUNING_M 0xf0
+#define DQ0_DELAY_FINE_TUNING_S 0
+#define DQ0_DELAY_FINE_TUNING_M 0x0f
+
+#define MEMCTL_DDR_DQS_DLY_REG 0x64
+#define DQS1_DELAY_SEL_S 24
+#define DQS1_DELAY_SEL_M 0xff000000
+#define DQS0_DELAY_SEL_S 16
+#define DQS0_DELAY_SEL_M 0xff0000
+#define DQS1_DELAY_COARSE_TUNING_S 12
+#define DQS1_DELAY_COARSE_TUNING_M 0xf000
+#define DQS1_DELAY_FINE_TUNING_S 8
+#define DQS1_DELAY_FINE_TUNING_M 0xf00
+#define DQS0_DELAY_COARSE_TUNING_S 4
+#define DQS0_DELAY_COARSE_TUNING_M 0xf0
+#define DQS0_DELAY_FINE_TUNING_S 0
+#define DQS0_DELAY_FINE_TUNING_M 0x0f
+
+#define MEMCTL_DDR_DLL_SLV_REG 0x68
+#define DLL_SLV_UPDATE_MODE 0x100
+#define DQS_DLY_SEL_EN 0x80
+#define DQ_DLY_SEL_EN 0x01
+
+#endif /* _MTMIPS_MC_H_ */
diff --git a/arch/mips/mach-mtmips/include/mach/serial.h b/arch/mips/mach-mtmips/include/mach/serial.h
new file mode 100644
index 0000000000..bfa246b428
--- /dev/null
+++ b/arch/mips/mach-mtmips/include/mach/serial.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTMIPS_SERIAL_H_
+#define _MTMIPS_SERIAL_H_
+
+void mtmips_spl_serial_init(void);
+
+#endif /* _MTMIPS_SERIAL_H_ */
diff --git a/arch/mips/mach-mtmips/lowlevel_init.S b/arch/mips/mach-mtmips/lowlevel_init.S
deleted file mode 100644
index aa707e0de6..0000000000
--- a/arch/mips/mach-mtmips/lowlevel_init.S
+++ /dev/null
@@ -1,328 +0,0 @@
-/* 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)
diff --git a/arch/mips/mach-mtmips/mt7628/Makefile b/arch/mips/mach-mtmips/mt7628/Makefile
new file mode 100644
index 0000000000..7e139d5adf
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += lowlevel_init.o
+obj-y += init.o
+obj-y += ddr.o
+obj-$(CONFIG_SPL_BUILD) += serial.o
diff --git a/arch/mips/mach-mtmips/mt7628/ddr.c b/arch/mips/mach-mtmips/mt7628/ddr.c
new file mode 100644
index 0000000000..06c0ca6854
--- /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 0000000000..77d1f2ea0d
--- /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 0000000000..e4a6c03580
--- /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 0000000000..391880b014
--- /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_ */
diff --git a/arch/mips/mach-mtmips/mt7628/serial.c b/arch/mips/mach-mtmips/mt7628/serial.c
new file mode 100644
index 0000000000..a7d324792d
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/serial.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include "mt7628.h"
+
+void mtmips_spl_serial_init(void)
+{
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+ void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+#if CONFIG_CONS_INDEX == 1
+ clrbits_32(base + SYSCTL_GPIO_MODE1_REG, UART0_MODE_M);
+#elif CONFIG_CONS_INDEX == 2
+ clrbits_32(base + SYSCTL_GPIO_MODE1_REG, UART1_MODE_M);
+#elif CONFIG_CONS_INDEX == 3
+ setbits_32(base + SYSCTL_AGPIO_CFG_REG, EPHY_GPIO_AIO_EN_M);
+#ifdef CONFIG_SPL_UART2_SPIS_PINMUX
+ setbits_32(base + SYSCTL_GPIO_MODE1_REG, SPIS_MODE_M);
+ clrsetbits_32(base + SYSCTL_GPIO_MODE1_REG, UART2_MODE_M,
+ 1 << UART2_MODE_S);
+#else
+ clrbits_32(base + SYSCTL_GPIO_MODE1_REG, UART2_MODE_M);
+ clrsetbits_32(base + SYSCTL_GPIO_MODE1_REG, SPIS_MODE_M,
+ 1 << SPIS_MODE_S);
+#endif /* CONFIG_SPL_UART2_SPIS_PINMUX */
+#endif /* CONFIG_CONS_INDEX */
+#endif /* CONFIG_SPL_SERIAL_SUPPORT */
+}
diff --git a/arch/mips/mach-mtmips/mt76xx.h b/arch/mips/mach-mtmips/mt76xx.h
deleted file mode 100644
index 17473ea8f1..0000000000
--- a/arch/mips/mach-mtmips/mt76xx.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* 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
diff --git a/arch/mips/mach-mtmips/spl.c b/arch/mips/mach-mtmips/spl.c
new file mode 100644
index 0000000000..2a24af70c3
--- /dev/null
+++ b/arch/mips/mach-mtmips/spl.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <fdt.h>
+#include <spl.h>
+#include <asm/sections.h>
+#include <linux/sizes.h>
+#include <mach/serial.h>
+
+void __noreturn board_init_f(ulong dummy)
+{
+ spl_init();
+
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+ /*
+ * mtmips_spl_serial_init() is useful if debug uart is enabled,
+ * or DM based serial is not enabled.
+ */
+ mtmips_spl_serial_init();
+ preloader_console_init();
+#endif
+
+ board_init_r(NULL, 0);
+}
+
+void board_boot_order(u32 *spl_boot_list)
+{
+ spl_boot_list[0] = BOOT_DEVICE_NOR;
+}
+
+unsigned long spl_nor_get_uboot_base(void)
+{
+ void *uboot_base = __image_copy_end;
+
+ if (fdt_magic(uboot_base) == FDT_MAGIC)
+ return (unsigned long)uboot_base + fdt_totalsize(uboot_base);
+
+ return (unsigned long)uboot_base;
+}