Merge tag 'mips-pull-2022-07-13' of https://source.denx.de/u-boot/custodians/u-boot-mips
- MIPS: add drivers and board support for Mediatek MT7621 SoC
This commit is contained in:
@@ -1032,15 +1032,23 @@ R: GSS_MTK_Uboot_upstream <GSS_MTK_Uboot_upstream@mediatek.com>
|
||||
S: Maintained
|
||||
F: arch/mips/mach-mtmips/
|
||||
F: arch/mips/dts/mt7620.dtsi
|
||||
F: arch/mips/dts/mt7621.dtsi
|
||||
F: arch/mips/dts/mt7620-u-boot.dtsi
|
||||
F: arch/mips/dts/mt7621-u-boot.dtsi
|
||||
F: include/configs/mt7620.h
|
||||
F: include/configs/mt7621.h
|
||||
F: include/dt-bindings/clock/mt7620-clk.h
|
||||
F: include/dt-bindings/clock/mt7621-clk.h
|
||||
F: include/dt-bindings/clock/mt7628-clk.h
|
||||
F: include/dt-bindings/reset/mt7620-reset.h
|
||||
F: include/dt-bindings/reset/mt7621-reset.h
|
||||
F: include/dt-bindings/reset/mt7628-reset.h
|
||||
F: drivers/clk/mtmips/
|
||||
F: drivers/pinctrl/mtmips/
|
||||
F: drivers/gpio/mt7620_gpio.c
|
||||
F: drivers/mtd/nand/raw/mt7621_nand.c
|
||||
F: drivers/mtd/nand/raw/mt7621_nand.h
|
||||
F: drivers/mtd/nand/raw/mt7621_nand_spl.c
|
||||
F: drivers/net/mt7620-eth.c
|
||||
F: drivers/phy/mt7620-usb-phy.c
|
||||
F: drivers/reset/reset-mtmips.c
|
||||
|
||||
@@ -4,6 +4,11 @@ head-y := arch/mips/cpu/start.o
|
||||
|
||||
ifeq ($(CONFIG_SPL_BUILD),y)
|
||||
head-$(CONFIG_ARCH_JZ47XX) := arch/mips/mach-jz47xx/start.o
|
||||
head-$(CONFIG_SOC_MT7621) := arch/mips/mach-mtmips/mt7621/spl/start.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TPL_BUILD),y)
|
||||
head-$(CONFIG_SOC_MT7621) := arch/mips/mach-mtmips/mt7621/tpl/start.o
|
||||
endif
|
||||
|
||||
libs-y += arch/mips/cpu/
|
||||
|
||||
@@ -13,7 +13,9 @@ SECTIONS
|
||||
|
||||
. = ALIGN(4);
|
||||
.text : {
|
||||
__text_start = .;
|
||||
*(.text*)
|
||||
__text_end = .;
|
||||
} > .spl_mem
|
||||
|
||||
. = ALIGN(4);
|
||||
@@ -36,6 +38,7 @@ SECTIONS
|
||||
|
||||
. = ALIGN(4);
|
||||
__image_copy_end = .;
|
||||
__image_copy_len = __image_copy_end - __text_start;
|
||||
|
||||
_image_binary_end = .;
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ dtb-$(CONFIG_BOARD_COMTREND_WAP5813N) += comtrend,wap-5813n.dtb
|
||||
dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
|
||||
dtb-$(CONFIG_BOARD_MT7620_RFB) += mediatek,mt7620-rfb.dtb
|
||||
dtb-$(CONFIG_BOARD_MT7620_MT7530_RFB) += mediatek,mt7620-mt7530-rfb.dtb
|
||||
dtb-$(CONFIG_BOARD_MT7621_RFB) += mediatek,mt7621-rfb.dtb
|
||||
dtb-$(CONFIG_BOARD_MT7621_NAND_RFB) += mediatek,mt7621-nand-rfb.dtb
|
||||
dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
|
||||
dtb-$(CONFIG_BOARD_GARDENA_SMART_GATEWAY_MT7688) += gardena-smart-gateway-mt7688.dtb
|
||||
dtb-$(CONFIG_BOARD_LINKIT_SMART_7688) += linkit-smart-7688.dtb
|
||||
|
||||
67
arch/mips/dts/mediatek,mt7621-nand-rfb.dts
Normal file
67
arch/mips/dts/mediatek,mt7621-nand-rfb.dts
Normal file
@@ -0,0 +1,67 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7621.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "mediatek,mt7621-nand-rfb", "mediatek,mt7621-soc";
|
||||
model = "MediaTek MT7621 RFB (NAND)";
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pin_state {
|
||||
nand {
|
||||
groups = "spi", "sdxc";
|
||||
function = "nand";
|
||||
};
|
||||
|
||||
gpios {
|
||||
groups = "i2c", "uart3", "pcie reset";
|
||||
function = "gpio";
|
||||
};
|
||||
|
||||
wdt {
|
||||
groups = "wdt";
|
||||
function = "wdt rst";
|
||||
};
|
||||
|
||||
jtag {
|
||||
groups = "jtag";
|
||||
function = "jtag";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ð {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ssusb {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&u3phy {
|
||||
status = "okay";
|
||||
};
|
||||
82
arch/mips/dts/mediatek,mt7621-rfb.dts
Normal file
82
arch/mips/dts/mediatek,mt7621-rfb.dts
Normal file
@@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7621.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "mediatek,mt7621-rfb", "mediatek,mt7621-soc";
|
||||
model = "MediaTek MT7621 RFB (SPI-NOR)";
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
spi0 = &spi;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart0;
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pin_state {
|
||||
gpios {
|
||||
groups = "i2c", "uart3", "pcie reset";
|
||||
function = "gpio";
|
||||
};
|
||||
|
||||
wdt {
|
||||
groups = "wdt";
|
||||
function = "wdt rst";
|
||||
};
|
||||
|
||||
jtag {
|
||||
groups = "jtag";
|
||||
function = "jtag";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi {
|
||||
status = "okay";
|
||||
num-cs = <2>;
|
||||
|
||||
spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
spi-max-frequency = <25000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
ð {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mmc {
|
||||
cap-sd-highspeed;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ssusb {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&u3phy {
|
||||
status = "okay";
|
||||
};
|
||||
111
arch/mips/dts/mt7621-u-boot.dtsi
Normal file
111
arch/mips/dts/mt7621-u-boot.dtsi
Normal file
@@ -0,0 +1,111 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <linux/stringify.h>
|
||||
|
||||
/ {
|
||||
binman: binman {
|
||||
multiple-images;
|
||||
};
|
||||
};
|
||||
|
||||
&sysc {
|
||||
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;
|
||||
};
|
||||
|
||||
&binman {
|
||||
u-boot-spl-ddr {
|
||||
align = <4>;
|
||||
align-size = <4>;
|
||||
filename = "u-boot-spl-ddr.bin";
|
||||
pad-byte = <0xff>;
|
||||
|
||||
u-boot-spl {
|
||||
align-end = <4>;
|
||||
filename = "u-boot-spl.bin";
|
||||
};
|
||||
|
||||
stage_bin {
|
||||
filename = "mt7621_stage_sram.bin";
|
||||
type = "blob-ext";
|
||||
};
|
||||
};
|
||||
|
||||
spl-img {
|
||||
filename = "u-boot-spl-ddr.img";
|
||||
|
||||
mkimage {
|
||||
#ifdef CONFIG_MT7621_BOOT_FROM_NAND
|
||||
args = "-T", "mtk_image", "-n", "mt7621=1",
|
||||
"-a", __stringify(CONFIG_SPL_TEXT_BASE),
|
||||
"-e", __stringify(CONFIG_SPL_TEXT_BASE);
|
||||
#else
|
||||
args = "-A", "mips", "-T", "standalone", "-O", "u-boot",
|
||||
"-C", "none", "-n", "MT7621 U-Boot SPL",
|
||||
"-a", __stringify(CONFIG_SPL_TEXT_BASE),
|
||||
"-e", __stringify(CONFIG_SPL_TEXT_BASE);
|
||||
#endif
|
||||
|
||||
blob {
|
||||
filename = "u-boot-spl-ddr.bin";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mt7621-uboot {
|
||||
filename = "u-boot-mt7621.bin";
|
||||
pad-byte = <0xff>;
|
||||
|
||||
#ifndef CONFIG_MT7621_BOOT_FROM_NAND
|
||||
u-boot-tpl {
|
||||
align-end = <4>;
|
||||
filename = "u-boot-tpl.bin";
|
||||
};
|
||||
#endif
|
||||
|
||||
spl {
|
||||
#ifdef CONFIG_MT7621_BOOT_FROM_NAND
|
||||
align-end = <0x1000>;
|
||||
#endif
|
||||
filename = "u-boot-spl-ddr.img";
|
||||
type = "blob";
|
||||
};
|
||||
|
||||
u-boot {
|
||||
filename = "u-boot-lzma.img";
|
||||
type = "blob";
|
||||
};
|
||||
};
|
||||
};
|
||||
349
arch/mips/dts/mt7621.dtsi
Normal file
349
arch/mips/dts/mt7621.dtsi
Normal file
@@ -0,0 +1,349 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/mt7621-clk.h>
|
||||
#include <dt-bindings/reset/mt7621-reset.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "mediatek,mt7621-soc";
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "mips,mips1004Kc";
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "mips,mips1004Kc";
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
clk48m: clk48m {
|
||||
compatible = "fixed-clock";
|
||||
|
||||
clock-frequency = <48000000>;
|
||||
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
clk50m: clk50m {
|
||||
compatible = "fixed-clock";
|
||||
|
||||
clock-frequency = <50000000>;
|
||||
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
sysc: sysctrl@1e000000 {
|
||||
compatible = "mediatek,mt7621-sysc", "syscon";
|
||||
reg = <0x1e000000 0x100>;
|
||||
|
||||
clkctrl: clock-controller@1e000030 {
|
||||
compatible = "mediatek,mt7621-clk";
|
||||
mediatek,memc = <&memc>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
rstctrl: reset-controller@1e000034 {
|
||||
compatible = "mediatek,mtmips-reset";
|
||||
reg = <0x1e000034 0x4>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
reboot: resetctl-reboot {
|
||||
compatible = "resetctl-reboot";
|
||||
|
||||
resets = <&rstctrl RST_SYS>;
|
||||
reset-names = "sysreset";
|
||||
};
|
||||
|
||||
memc: memctrl@1e005000 {
|
||||
compatible = "mediatek,mt7621-memc", "syscon";
|
||||
reg = <0x1e005000 0x1000>;
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@1e000060 {
|
||||
compatible = "mediatek,mt7621-pinctrl";
|
||||
reg = <0x1e000048 0x30>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&state_default>;
|
||||
|
||||
state_default: pin_state {
|
||||
};
|
||||
|
||||
uart1_pins: uart1_pins {
|
||||
groups = "uart1";
|
||||
function = "uart";
|
||||
};
|
||||
|
||||
uart2_pins: uart2_pins {
|
||||
groups = "uart2";
|
||||
function = "uart";
|
||||
};
|
||||
|
||||
uart3_pins: uart3_pins {
|
||||
groups = "uart3";
|
||||
function = "uart";
|
||||
};
|
||||
|
||||
sdxc_pins: sdxc_pins {
|
||||
groups = "sdxc";
|
||||
function = "sdxc";
|
||||
};
|
||||
|
||||
spi_pins: spi_pins {
|
||||
groups = "spi";
|
||||
function = "spi";
|
||||
};
|
||||
|
||||
eth_pins: eth_pins {
|
||||
mdio_pins {
|
||||
groups = "mdio";
|
||||
function = "mdio";
|
||||
};
|
||||
|
||||
rgmii1_pins {
|
||||
groups = "rgmii1";
|
||||
function = "rgmii";
|
||||
};
|
||||
|
||||
esw_pins {
|
||||
groups = "esw int";
|
||||
function = "esw int";
|
||||
};
|
||||
|
||||
mdio_pconf {
|
||||
groups = "mdio";
|
||||
drive-strength = <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
watchdog: watchdog@1e000100 {
|
||||
compatible = "mediatek,mt7621-wdt";
|
||||
reg = <0x1e000100 0x40>;
|
||||
|
||||
resets = <&rstctrl RST_TIMER>;
|
||||
reset-names = "wdt";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gpio: gpio@1e000600 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
compatible = "mtk,mt7621-gpio";
|
||||
reg = <0x1e000600 0x100>;
|
||||
|
||||
resets = <&rstctrl RST_PIO>;
|
||||
reset-names = "pio";
|
||||
|
||||
gpio0: bank@0 {
|
||||
reg = <0>;
|
||||
compatible = "mtk,mt7621-gpio-bank";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpio1: bank@1 {
|
||||
reg = <1>;
|
||||
compatible = "mtk,mt7621-gpio-bank";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpio2: bank@2 {
|
||||
reg = <2>;
|
||||
compatible = "mtk,mt7621-gpio-bank";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
spi: spi@1e000b00 {
|
||||
compatible = "ralink,mt7621-spi";
|
||||
reg = <0x1e000b00 0x40>;
|
||||
|
||||
status = "disabled";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi_pins>;
|
||||
|
||||
resets = <&rstctrl RST_SPI>;
|
||||
reset-names = "spi";
|
||||
|
||||
clocks = <&clkctrl MT7621_CLK_SPI>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
uart0: uart1@1e000c00 {
|
||||
compatible = "mediatek,hsuart", "ns16550a";
|
||||
reg = <0x1e000c00 0x100>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart1_pins>;
|
||||
|
||||
clocks = <&clkctrl MT7621_CLK_UART1>;
|
||||
|
||||
resets = <&rstctrl RST_UART1>;
|
||||
|
||||
reg-shift = <2>;
|
||||
};
|
||||
|
||||
uart1: uart2@1e000d00 {
|
||||
compatible = "mediatek,hsuart", "ns16550a";
|
||||
reg = <0x1e000d00 0x100>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart2_pins>;
|
||||
|
||||
clocks = <&clkctrl MT7621_CLK_UART2>;
|
||||
|
||||
resets = <&rstctrl RST_UART2>;
|
||||
|
||||
reg-shift = <2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart2: uart3@1e000e00 {
|
||||
compatible = "mediatek,hsuart", "ns16550a";
|
||||
reg = <0x1e000e00 0x100>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart3_pins>;
|
||||
|
||||
clocks = <&clkctrl MT7621_CLK_UART3>;
|
||||
|
||||
resets = <&rstctrl RST_UART3>;
|
||||
|
||||
reg-shift = <2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
eth: eth@1e100000 {
|
||||
compatible = "mediatek,mt7621-eth";
|
||||
reg = <0x1e100000 0x20000>;
|
||||
mediatek,ethsys = <&sysc>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <ð_pins>;
|
||||
|
||||
resets = <&rstctrl RST_FE>, <&rstctrl RST_GMAC>, <&rstctrl RST_MCM>;
|
||||
reset-names = "fe", "gmac", "mcm";
|
||||
|
||||
clocks = <&clkctrl MT7621_CLK_GDMA>,
|
||||
<&clkctrl MT7621_CLK_ETH>;
|
||||
clock-names = "gmac", "fe";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mediatek,gmac-id = <0>;
|
||||
phy-mode = "rgmii";
|
||||
mediatek,switch = "mt7530";
|
||||
mediatek,mcm;
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
mmc: mmc@1e130000 {
|
||||
compatible = "mediatek,mt7621-mmc";
|
||||
reg = <0x1e130000 0x4000>;
|
||||
|
||||
status = "disabled";
|
||||
|
||||
bus-width = <4>;
|
||||
builtin-cd = <1>;
|
||||
r_smpl = <1>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sdxc_pins>;
|
||||
|
||||
clocks = <&clk50m>, <&clkctrl MT7621_CLK_SHXC>;
|
||||
clock-names = "source", "hclk";
|
||||
|
||||
resets = <&rstctrl RST_SDXC>;
|
||||
};
|
||||
|
||||
ssusb: usb@1e1c0000 {
|
||||
compatible = "mediatek,mt7621-xhci", "mediatek,mtk-xhci";
|
||||
reg = <0x1e1c0000 0x1000>, <0x1e1d0700 0x100>;
|
||||
reg-names = "mac", "ippc";
|
||||
|
||||
clocks = <&clk48m>, <&clk48m>;
|
||||
clock-names = "sys_ck", "ref_ck";
|
||||
|
||||
phys = <&u2port0 PHY_TYPE_USB2>,
|
||||
<&u3port0 PHY_TYPE_USB3>,
|
||||
<&u2port1 PHY_TYPE_USB2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
u3phy: usb-phy@1e1d0000 {
|
||||
compatible = "mediatek,mt7621-u3phy",
|
||||
"mediatek,generic-tphy-v1";
|
||||
reg = <0x1e1d0000 0x700>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
status = "disabled";
|
||||
|
||||
u2port0: usb-phy@1e1d0800 {
|
||||
reg = <0x1e1d0800 0x0100>;
|
||||
#phy-cells = <1>;
|
||||
clocks = <&clk48m>;
|
||||
clock-names = "ref";
|
||||
};
|
||||
|
||||
u3port0: usb-phy@1e1d0900 {
|
||||
reg = <0x1e1d0900 0x0100>;
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
|
||||
u2port1: usb-phy@1e1d1000 {
|
||||
reg = <0x1e1d1000 0x0100>;
|
||||
#phy-cells = <1>;
|
||||
clocks = <&clk48m>;
|
||||
clock-names = "ref";
|
||||
};
|
||||
};
|
||||
|
||||
i2c: i2c@1e000900 {
|
||||
compatible = "i2c-gpio";
|
||||
|
||||
status = "disabled";
|
||||
|
||||
i2c-gpio,delay-us = <3>;
|
||||
|
||||
gpios = <&gpio0 3 1>, /* PIN3 as SDA */
|
||||
<&gpio0 4 1>; /* PIN4 as CLK */
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
@@ -8,9 +8,23 @@
|
||||
#define __MIPS_ASM_CM_H__
|
||||
|
||||
/* Global Control Register (GCR) offsets */
|
||||
#define GCR_CONFIG 0x0000
|
||||
#define GCR_BASE 0x0008
|
||||
#define GCR_BASE_UPPER 0x000c
|
||||
#define GCR_CONTROL 0x0010
|
||||
#define GCR_ACCESS 0x0020
|
||||
#define GCR_REV 0x0030
|
||||
#define GCR_GIC_BASE 0x0080
|
||||
#define GCR_CPC_BASE 0x0088
|
||||
#define GCR_REG0_BASE 0x0090
|
||||
#define GCR_REG0_MASK 0x0098
|
||||
#define GCR_REG1_BASE 0x00a0
|
||||
#define GCR_REG1_MASK 0x00a8
|
||||
#define GCR_REG2_BASE 0x00b0
|
||||
#define GCR_REG2_MASK 0x00b8
|
||||
#define GCR_REG3_BASE 0x00c0
|
||||
#define GCR_REG3_MASK 0x00c8
|
||||
#define GCR_CPC_STATUS 0x00f0
|
||||
#define GCR_L2_CONFIG 0x0130
|
||||
#define GCR_L2_TAG_ADDR 0x0600
|
||||
#define GCR_L2_TAG_ADDR_UPPER 0x0604
|
||||
@@ -19,10 +33,59 @@
|
||||
#define GCR_L2_DATA 0x0610
|
||||
#define GCR_L2_DATA_UPPER 0x0614
|
||||
#define GCR_Cx_COHERENCE 0x2008
|
||||
#define GCR_Cx_OTHER 0x2018
|
||||
#define GCR_Cx_ID 0x2028
|
||||
#define GCR_CO_COHERENCE 0x4008
|
||||
|
||||
/* GCR_CONFIG fields */
|
||||
#define GCR_CONFIG_NUM_CLUSTERS_SHIFT 23
|
||||
#define GCR_CONFIG_NUM_CLUSTERS (0x7f << 23)
|
||||
#define GCR_CONFIG_NUMIOCU_SHIFT 8
|
||||
#define GCR_CONFIG_NUMIOCU (0xff << 8)
|
||||
#define GCR_CONFIG_PCORES_SHIFT 0
|
||||
#define GCR_CONFIG_PCORES (0xff << 0)
|
||||
|
||||
/* GCR_BASE fields */
|
||||
#define GCR_BASE_SHIFT 15
|
||||
#define CCA_DEFAULT_OVR_SHIFT 5
|
||||
#define CCA_DEFAULT_OVR_MASK (0x7 << 5)
|
||||
#define CCA_DEFAULT_OVREN (0x1 << 4)
|
||||
#define CM_DEFAULT_TARGET_SHIFT 0
|
||||
#define CM_DEFAULT_TARGET_MASK (0x3 << 0)
|
||||
|
||||
/* GCR_CONTROL fields */
|
||||
#define GCR_CONTROL_SYNCCTL (0x1 << 16)
|
||||
|
||||
/* GCR_REV CM versions */
|
||||
#define GCR_REV_CM3 0x0800
|
||||
|
||||
/* GCR_GIC_BASE fields */
|
||||
#define GCR_GIC_BASE_ADDRMASK_SHIFT 7
|
||||
#define GCR_GIC_BASE_ADDRMASK (0x1ffffff << 7)
|
||||
#define GCR_GIC_EN (0x1 << 0)
|
||||
|
||||
/* GCR_CPC_BASE fields */
|
||||
#define GCR_CPC_BASE_ADDRMASK_SHIFT 15
|
||||
#define GCR_CPC_BASE_ADDRMASK (0x1ffff << 15)
|
||||
#define GCR_CPC_EN (0x1 << 0)
|
||||
|
||||
/* GCR_REGn_MASK fields */
|
||||
#define GCR_REGn_MASK_ADDRMASK_SHIFT 16
|
||||
#define GCR_REGn_MASK_ADDRMASK (0xffff << 16)
|
||||
#define GCR_REGn_MASK_CCAOVR_SHIFT 5
|
||||
#define GCR_REGn_MASK_CCAOVR (0x7 << 5)
|
||||
#define GCR_REGn_MASK_CCAOVREN (1 << 4)
|
||||
#define GCR_REGn_MASK_DROPL2 (1 << 2)
|
||||
#define GCR_REGn_MASK_CMTGT_SHIFT 0
|
||||
#define GCR_REGn_MASK_CMTGT (0x3 << 0)
|
||||
#define GCR_REGn_MASK_CMTGT_DISABLED 0x0
|
||||
#define GCR_REGn_MASK_CMTGT_MEM 0x1
|
||||
#define GCR_REGn_MASK_CMTGT_IOCU0 0x2
|
||||
#define GCR_REGn_MASK_CMTGT_IOCU1 0x3
|
||||
|
||||
/* GCR_CPC_STATUS fields */
|
||||
#define GCR_CPC_EX (0x1 << 0)
|
||||
|
||||
/* GCR_L2_CONFIG fields */
|
||||
#define GCR_L2_CONFIG_ASSOC_SHIFT 0
|
||||
#define GCR_L2_CONFIG_ASSOC_BITS 8
|
||||
@@ -36,6 +99,10 @@
|
||||
#define GCR_Cx_COHERENCE_DOM_EN (0xff << 0)
|
||||
#define GCR_Cx_COHERENCE_EN (0x1 << 0)
|
||||
|
||||
/* GCR_Cx_OTHER fields */
|
||||
#define GCR_Cx_OTHER_CORENUM_SHIFT 16
|
||||
#define GCR_Cx_OTHER_CORENUM (0xffff << 16)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
142
arch/mips/include/asm/mipsmtregs.h
Normal file
142
arch/mips/include/asm/mipsmtregs.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* MT regs definitions, follows on from mipsregs.h
|
||||
* Copyright (C) 2004 - 2005 MIPS Technologies, Inc. All rights reserved.
|
||||
* Elizabeth Clarke et. al.
|
||||
*
|
||||
*/
|
||||
#ifndef _ASM_MIPSMTREGS_H
|
||||
#define _ASM_MIPSMTREGS_H
|
||||
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
/*
|
||||
* Macros for use in assembly language code
|
||||
*/
|
||||
|
||||
#define CP0_MVPCONTROL $0, 1
|
||||
#define CP0_MVPCONF0 $0, 2
|
||||
#define CP0_MVPCONF1 $0, 3
|
||||
#define CP0_VPECONTROL $1, 1
|
||||
#define CP0_VPECONF0 $1, 2
|
||||
#define CP0_VPECONF1 $1, 3
|
||||
#define CP0_YQMASK $1, 4
|
||||
#define CP0_VPESCHEDULE $1, 5
|
||||
#define CP0_VPESCHEFBK $1, 6
|
||||
#define CP0_TCSTATUS $2, 1
|
||||
#define CP0_TCBIND $2, 2
|
||||
#define CP0_TCRESTART $2, 3
|
||||
#define CP0_TCHALT $2, 4
|
||||
#define CP0_TCCONTEXT $2, 5
|
||||
#define CP0_TCSCHEDULE $2, 6
|
||||
#define CP0_TCSCHEFBK $2, 7
|
||||
#define CP0_SRSCONF0 $6, 1
|
||||
#define CP0_SRSCONF1 $6, 2
|
||||
#define CP0_SRSCONF2 $6, 3
|
||||
#define CP0_SRSCONF3 $6, 4
|
||||
#define CP0_SRSCONF4 $6, 5
|
||||
|
||||
/* MVPControl fields */
|
||||
#define MVPCONTROL_EVP (_ULCAST_(1))
|
||||
|
||||
#define MVPCONTROL_VPC_SHIFT 1
|
||||
#define MVPCONTROL_VPC (_ULCAST_(1) << MVPCONTROL_VPC_SHIFT)
|
||||
|
||||
#define MVPCONTROL_STLB_SHIFT 2
|
||||
#define MVPCONTROL_STLB (_ULCAST_(1) << MVPCONTROL_STLB_SHIFT)
|
||||
|
||||
/* MVPConf0 fields */
|
||||
#define MVPCONF0_PTC_SHIFT 0
|
||||
#define MVPCONF0_PTC (_ULCAST_(0xff))
|
||||
#define MVPCONF0_PVPE_SHIFT 10
|
||||
#define MVPCONF0_PVPE (_ULCAST_(0xf) << MVPCONF0_PVPE_SHIFT)
|
||||
#define MVPCONF0_TCA_SHIFT 15
|
||||
#define MVPCONF0_TCA (_ULCAST_(1) << MVPCONF0_TCA_SHIFT)
|
||||
#define MVPCONF0_PTLBE_SHIFT 16
|
||||
#define MVPCONF0_PTLBE (_ULCAST_(0x3ff) << MVPCONF0_PTLBE_SHIFT)
|
||||
#define MVPCONF0_TLBS_SHIFT 29
|
||||
#define MVPCONF0_TLBS (_ULCAST_(1) << MVPCONF0_TLBS_SHIFT)
|
||||
#define MVPCONF0_M_SHIFT 31
|
||||
#define MVPCONF0_M (_ULCAST_(0x1) << MVPCONF0_M_SHIFT)
|
||||
|
||||
/* config3 fields */
|
||||
#define CONFIG3_MT_SHIFT 2
|
||||
#define CONFIG3_MT (_ULCAST_(1) << CONFIG3_MT_SHIFT)
|
||||
|
||||
/* VPEControl fields (per VPE) */
|
||||
#define VPECONTROL_TARGTC (_ULCAST_(0xff))
|
||||
|
||||
#define VPECONTROL_TE_SHIFT 15
|
||||
#define VPECONTROL_TE (_ULCAST_(1) << VPECONTROL_TE_SHIFT)
|
||||
#define VPECONTROL_EXCPT_SHIFT 16
|
||||
#define VPECONTROL_EXCPT (_ULCAST_(0x7) << VPECONTROL_EXCPT_SHIFT)
|
||||
|
||||
/* Thread Exception Codes for EXCPT field */
|
||||
#define THREX_TU 0
|
||||
#define THREX_TO 1
|
||||
#define THREX_IYQ 2
|
||||
#define THREX_GSX 3
|
||||
#define THREX_YSCH 4
|
||||
#define THREX_GSSCH 5
|
||||
|
||||
#define VPECONTROL_GSI_SHIFT 20
|
||||
#define VPECONTROL_GSI (_ULCAST_(1) << VPECONTROL_GSI_SHIFT)
|
||||
#define VPECONTROL_YSI_SHIFT 21
|
||||
#define VPECONTROL_YSI (_ULCAST_(1) << VPECONTROL_YSI_SHIFT)
|
||||
|
||||
/* VPEConf0 fields (per VPE) */
|
||||
#define VPECONF0_VPA_SHIFT 0
|
||||
#define VPECONF0_VPA (_ULCAST_(1) << VPECONF0_VPA_SHIFT)
|
||||
#define VPECONF0_MVP_SHIFT 1
|
||||
#define VPECONF0_MVP (_ULCAST_(1) << VPECONF0_MVP_SHIFT)
|
||||
#define VPECONF0_XTC_SHIFT 21
|
||||
#define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT)
|
||||
|
||||
/* VPEConf1 fields (per VPE) */
|
||||
#define VPECONF1_NCP1_SHIFT 0
|
||||
#define VPECONF1_NCP1 (_ULCAST_(0xff) << VPECONF1_NCP1_SHIFT)
|
||||
#define VPECONF1_NCP2_SHIFT 10
|
||||
#define VPECONF1_NCP2 (_ULCAST_(0xff) << VPECONF1_NCP2_SHIFT)
|
||||
#define VPECONF1_NCX_SHIFT 20
|
||||
#define VPECONF1_NCX (_ULCAST_(0xff) << VPECONF1_NCX_SHIFT)
|
||||
|
||||
/* TCStatus fields (per TC) */
|
||||
#define TCSTATUS_TASID (_ULCAST_(0xff))
|
||||
#define TCSTATUS_IXMT_SHIFT 10
|
||||
#define TCSTATUS_IXMT (_ULCAST_(1) << TCSTATUS_IXMT_SHIFT)
|
||||
#define TCSTATUS_TKSU_SHIFT 11
|
||||
#define TCSTATUS_TKSU (_ULCAST_(3) << TCSTATUS_TKSU_SHIFT)
|
||||
#define TCSTATUS_A_SHIFT 13
|
||||
#define TCSTATUS_A (_ULCAST_(1) << TCSTATUS_A_SHIFT)
|
||||
#define TCSTATUS_DA_SHIFT 15
|
||||
#define TCSTATUS_DA (_ULCAST_(1) << TCSTATUS_DA_SHIFT)
|
||||
#define TCSTATUS_DT_SHIFT 20
|
||||
#define TCSTATUS_DT (_ULCAST_(1) << TCSTATUS_DT_SHIFT)
|
||||
#define TCSTATUS_TDS_SHIFT 21
|
||||
#define TCSTATUS_TDS (_ULCAST_(1) << TCSTATUS_TDS_SHIFT)
|
||||
#define TCSTATUS_TSST_SHIFT 22
|
||||
#define TCSTATUS_TSST (_ULCAST_(1) << TCSTATUS_TSST_SHIFT)
|
||||
#define TCSTATUS_RNST_SHIFT 23
|
||||
#define TCSTATUS_RNST (_ULCAST_(3) << TCSTATUS_RNST_SHIFT)
|
||||
/* Codes for RNST */
|
||||
#define TC_RUNNING 0
|
||||
#define TC_WAITING 1
|
||||
#define TC_YIELDING 2
|
||||
#define TC_GATED 3
|
||||
|
||||
#define TCSTATUS_TMX_SHIFT 27
|
||||
#define TCSTATUS_TMX (_ULCAST_(1) << TCSTATUS_TMX_SHIFT)
|
||||
/* TCStatus TCU bits can use same definitions/offsets as CU bits in Status */
|
||||
|
||||
/* TCBind */
|
||||
#define TCBIND_CURVPE_SHIFT 0
|
||||
#define TCBIND_CURVPE (_ULCAST_(0xf))
|
||||
|
||||
#define TCBIND_CURTC_SHIFT 21
|
||||
|
||||
#define TCBIND_CURTC (_ULCAST_(0xff) << TCBIND_CURTC_SHIFT)
|
||||
|
||||
/* TCHalt */
|
||||
#define TCHALT_H (_ULCAST_(1))
|
||||
|
||||
#endif
|
||||
@@ -282,4 +282,24 @@ static inline void instruction_hazard_barrier(void)
|
||||
: "=&r"(tmp));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_NONCACHED_MEMORY
|
||||
/* 1MB granularity */
|
||||
#define MMU_SECTION_SHIFT 20
|
||||
#define MMU_SECTION_SIZE (1 << MMU_SECTION_SHIFT)
|
||||
|
||||
/**
|
||||
* noncached_init() - Initialize non-cached memory region
|
||||
*
|
||||
* Initialize non-cached memory area. This memory region will be typically
|
||||
* located right below the malloc() area and be accessed from KSEG1.
|
||||
*
|
||||
* It is called during the generic post-relocation init sequence.
|
||||
*
|
||||
* Return: 0 if OK
|
||||
*/
|
||||
int noncached_init(void);
|
||||
|
||||
phys_addr_t noncached_alloc(size_t size, size_t align);
|
||||
#endif /* CONFIG_SYS_NONCACHED_MEMORY */
|
||||
|
||||
#endif /* _ASM_SYSTEM_H */
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/cacheops.h>
|
||||
#include <asm/cm.h>
|
||||
@@ -197,3 +198,45 @@ void dcache_disable(void)
|
||||
/* ensure the pipeline doesn't contain now-invalid instructions */
|
||||
instruction_hazard_barrier();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_NONCACHED_MEMORY
|
||||
static unsigned long noncached_start;
|
||||
static unsigned long noncached_end;
|
||||
static unsigned long noncached_next;
|
||||
|
||||
void noncached_set_region(void)
|
||||
{
|
||||
}
|
||||
|
||||
int noncached_init(void)
|
||||
{
|
||||
phys_addr_t start, end;
|
||||
size_t size;
|
||||
|
||||
/* If this calculation changes, update board_f.c:reserve_noncached() */
|
||||
end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE;
|
||||
size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE);
|
||||
start = end - size;
|
||||
|
||||
debug("mapping memory %pa-%pa non-cached\n", &start, &end);
|
||||
|
||||
noncached_start = start;
|
||||
noncached_end = end;
|
||||
noncached_next = start;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
phys_addr_t noncached_alloc(size_t size, size_t align)
|
||||
{
|
||||
phys_addr_t next = ALIGN(noncached_next, align);
|
||||
|
||||
if (next >= noncached_end || (noncached_end - next) < size)
|
||||
return 0;
|
||||
|
||||
debug("allocated %zu bytes of uncached memory @%pa\n", size, &next);
|
||||
noncached_next = next + size;
|
||||
|
||||
return CKSEG1ADDR(next);
|
||||
}
|
||||
#endif /* CONFIG_SYS_NONCACHED_MEMORY */
|
||||
|
||||
@@ -9,6 +9,7 @@ config SYS_MALLOC_F_LEN
|
||||
|
||||
config SYS_SOC
|
||||
default "mt7620" if SOC_MT7620
|
||||
default "mt7621" if SOC_MT7621
|
||||
default "mt7628" if SOC_MT7628
|
||||
|
||||
config SYS_DCACHE_SIZE
|
||||
@@ -18,25 +19,45 @@ config SYS_DCACHE_LINE_SIZE
|
||||
default 32
|
||||
|
||||
config SYS_ICACHE_SIZE
|
||||
default 65536
|
||||
default 65536 if SOC_MT7620 || SOC_MT7628
|
||||
default 32768 if SOC_MT7621
|
||||
|
||||
config SYS_ICACHE_LINE_SIZE
|
||||
default 32
|
||||
|
||||
config SYS_SCACHE_LINE_SIZE
|
||||
default 32 if SOC_MT7621
|
||||
|
||||
config SYS_TEXT_BASE
|
||||
default 0x9c000000 if !SPL
|
||||
default 0x80200000 if SPL
|
||||
default 0x9c000000 if !SPL && !SOC_MT7621
|
||||
default 0x80200000 if SPL || SOC_MT7621
|
||||
|
||||
config SPL_TEXT_BASE
|
||||
default 0x9c000000
|
||||
default 0x9c000000 if !SOC_MT7621
|
||||
default 0x80100000 if SOC_MT7621
|
||||
|
||||
config SPL_SIZE_LIMIT
|
||||
default 0x30000 if SOC_MT7621
|
||||
|
||||
config TPL_TEXT_BASE
|
||||
default 0xbfc00000 if SOC_MT7621
|
||||
|
||||
config TPL_MAX_SIZE
|
||||
default 4096 if SOC_MT7621
|
||||
|
||||
config SPL_PAYLOAD
|
||||
default "u-boot-lzma.img" if SPL_LZMA
|
||||
|
||||
config BUILD_TARGET
|
||||
default "u-boot-with-spl.bin" if SPL
|
||||
default "u-boot-with-spl.bin" if SPL && !SOC_MT7621
|
||||
default "u-boot-lzma.img" if SOC_MT7621
|
||||
default "u-boot.bin"
|
||||
|
||||
config MAX_MEM_SIZE
|
||||
int
|
||||
default 256 if SOC_MT7620 || SOC_MT7628
|
||||
default 512 if SOC_MT7621
|
||||
|
||||
choice
|
||||
prompt "MediaTek MIPS SoC select"
|
||||
|
||||
@@ -55,6 +76,23 @@ config SOC_MT7620
|
||||
help
|
||||
This supports MediaTek MT7620.
|
||||
|
||||
config SOC_MT7621
|
||||
bool "MT7621"
|
||||
select MIPS_CM
|
||||
select MIPS_L2_CACHE
|
||||
select SYS_CACHE_SHIFT_5
|
||||
select SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
select PINCTRL_MT7621
|
||||
select MTK_SERIAL
|
||||
select REGMAP
|
||||
select SYSCON
|
||||
select BINMAN
|
||||
select SUPPORT_TPL
|
||||
select SPL_LOADER_SUPPORT if SPL
|
||||
select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
|
||||
help
|
||||
This supports MediaTek MT7621.
|
||||
|
||||
config SOC_MT7628
|
||||
bool "MT7628"
|
||||
select SYS_CACHE_SHIFT_5
|
||||
@@ -80,6 +118,7 @@ config SOC_MT7628
|
||||
endchoice
|
||||
|
||||
source "arch/mips/mach-mtmips/mt7620/Kconfig"
|
||||
source "arch/mips/mach-mtmips/mt7621/Kconfig"
|
||||
source "arch/mips/mach-mtmips/mt7628/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
obj-y += cpu.o
|
||||
|
||||
ifneq ($(CONFIG_SOC_MT7621),y)
|
||||
obj-y += ddr_init.o
|
||||
obj-y += ddr_cal.o
|
||||
obj-$(CONFIG_SPL_BUILD) += spl.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SOC_MT7620) += mt7620/
|
||||
obj-$(CONFIG_SOC_MT7621) += mt7621/
|
||||
obj-$(CONFIG_SOC_MT7628) += mt7628/
|
||||
|
||||
@@ -16,7 +16,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = get_ram_size((void *)KSEG1, SZ_256M);
|
||||
gd->ram_size = get_ram_size((void *)KSEG1, CONFIG_MAX_MEM_SIZE << 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
115
arch/mips/mach-mtmips/mt7621/Kconfig
Normal file
115
arch/mips/mach-mtmips/mt7621/Kconfig
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
if SOC_MT7621
|
||||
|
||||
menu "CPU & DDR configuration"
|
||||
|
||||
config MT7621_CPU_FREQ
|
||||
int "CPU Frequency (MHz)"
|
||||
range 400 1200
|
||||
default 880
|
||||
|
||||
choice
|
||||
prompt "DRAM Frequency"
|
||||
default MT7621_DRAM_FREQ_1200
|
||||
|
||||
config MT7621_DRAM_FREQ_400
|
||||
bool "400MHz"
|
||||
|
||||
config MT7621_DRAM_FREQ_800
|
||||
bool "800MHz"
|
||||
|
||||
config MT7621_DRAM_FREQ_1066
|
||||
bool "1066MHz"
|
||||
|
||||
config MT7621_DRAM_FREQ_1200
|
||||
bool "1200MHz"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "DDR2 timing parameters"
|
||||
default MT7621_DRAM_DDR2_1024M
|
||||
|
||||
config MT7621_DRAM_DDR2_512M
|
||||
bool "64MB"
|
||||
|
||||
config MT7621_DRAM_DDR2_1024M
|
||||
bool "128MB"
|
||||
|
||||
config MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ
|
||||
bool "W9751G6KB_A02 @ 1066MHz (64MB)"
|
||||
|
||||
config MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ
|
||||
bool "W971GG6KB25 @ 800MHz (128MB)"
|
||||
|
||||
config MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ
|
||||
bool "W971GG6KB18 @ 1066MHz (128MB)"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "DDR3 timing parameters"
|
||||
default MT7621_DRAM_DDR3_2048M
|
||||
|
||||
config MT7621_DRAM_DDR3_1024M
|
||||
bool "128MB"
|
||||
|
||||
config MT7621_DRAM_DDR3_1024M_KGD
|
||||
bool "128MB KGD (MT7621DA)"
|
||||
|
||||
config MT7621_DRAM_DDR3_2048M
|
||||
bool "256MB"
|
||||
|
||||
config MT7621_DRAM_DDR3_4096M
|
||||
bool "512MB"
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
config DEBUG_UART_BOARD_INIT
|
||||
default y
|
||||
|
||||
config MT7621_BOOT_FROM_NAND
|
||||
bool "Boot from NAND"
|
||||
help
|
||||
Select this if u-boot will boot from NAND flash. When booting from
|
||||
NAND, SPL will be loaded by bootrom directly and no TPL is needed.
|
||||
|
||||
choice
|
||||
prompt "Board select"
|
||||
|
||||
config BOARD_MT7621_RFB
|
||||
bool "MediaTek MT7621 RFB (SPI-NOR)"
|
||||
help
|
||||
The reference design of MT7621A (WS3010) booting from SPI-NOR flash.
|
||||
The board can be configured with DDR2 (64MiB~256MiB) or DDR3
|
||||
(128MiB~512MiB). The board has 16 MiB SPI-NOR flash, built-in MT7530
|
||||
GbE switch, 1 UART, 1 USB 2.0 host, 1 USB 3.0 host, 1 SDXC, 3 PCIe
|
||||
sockets, 1 RGMII to external GbE PHY, 2 audio jacks (in/out),
|
||||
JTAG pins and expansion GPIO pins.
|
||||
|
||||
config BOARD_MT7621_NAND_RFB
|
||||
bool "MediaTek MT7621 RFB (NAND)"
|
||||
help
|
||||
The reference design of MT7621A (WS3010) booting from NAND flash.
|
||||
The board can be configured with DDR2 (64MiB~256MiB) or DDR3
|
||||
(128MiB~512MiB). The board has 128 MiB parallel NAND flash, built-in
|
||||
MT7530 GbE switch, 1 UART, 1 USB 2.0 host, 1 USB 3.0 host, 3 PCIe
|
||||
sockets, 1 RGMII to external GbE PHY, 2 audio jacks (in/out),
|
||||
JTAG pins and expansion GPIO pins.
|
||||
|
||||
endchoice
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
string "Board configuration name"
|
||||
default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
|
||||
|
||||
config SYS_BOARD
|
||||
string "Board name"
|
||||
default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
|
||||
|
||||
config SYS_VENDOR
|
||||
default "mediatek" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
|
||||
|
||||
endif
|
||||
14
arch/mips/mach-mtmips/mt7621/Makefile
Normal file
14
arch/mips/mach-mtmips/mt7621/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += init.o
|
||||
obj-y += serial.o
|
||||
|
||||
ifeq ($(CONFIG_SPL_BUILD),y)
|
||||
ifeq ($(CONFIG_TPL_BUILD),y)
|
||||
obj-y += tpl/
|
||||
else
|
||||
obj-y += spl/
|
||||
endif
|
||||
|
||||
obj-y += sram_init.o
|
||||
endif
|
||||
246
arch/mips/mach-mtmips/mt7621/init.c
Normal file
246
arch/mips/mach-mtmips/mt7621/init.c
Normal file
@@ -0,0 +1,246 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <dt-bindings/clock/mt7621-clk.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include "mt7621.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const char *const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + 1] = {
|
||||
[1] = "NAND 2K+64",
|
||||
[2] = "SPI-NOR 3-Byte Addr",
|
||||
[3] = "SPI-NOR 4-Byte Addr",
|
||||
[10] = "NAND 2K+128",
|
||||
[11] = "NAND 4K+128",
|
||||
[12] = "NAND 4K+256",
|
||||
};
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
|
||||
u32 val, ver, eco, pkg, core, dram, chipmode;
|
||||
u32 cpu_clk, ddr_clk, bus_clk, xtal_clk;
|
||||
struct udevice *clkdev;
|
||||
const char *bootdev;
|
||||
struct clk clk;
|
||||
int ret;
|
||||
|
||||
val = readl(sysc + SYSCTL_CHIP_REV_ID_REG);
|
||||
ver = FIELD_GET(VER_ID_M, val);
|
||||
eco = FIELD_GET(ECO_ID_M, val);
|
||||
pkg = FIELD_GET(PKG_ID, val);
|
||||
core = FIELD_GET(CPU_ID, val);
|
||||
|
||||
val = readl(sysc + SYSCTL_SYSCFG0_REG);
|
||||
dram = FIELD_GET(DRAM_TYPE, val);
|
||||
chipmode = FIELD_GET(CHIP_MODE_M, val);
|
||||
|
||||
bootdev = boot_mode[chipmode];
|
||||
if (!bootdev)
|
||||
bootdev = "Unsupported boot mode";
|
||||
|
||||
printf("CPU: MediaTek MT7621%c ver %u, eco %u\n",
|
||||
core ? (pkg ? 'A' : 'N') : 'S', ver, eco);
|
||||
|
||||
printf("Boot: DDR%u, %s\n", dram ? 2 : 3, bootdev);
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(mt7621_clk),
|
||||
&clkdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk.dev = clkdev;
|
||||
|
||||
clk.id = MT7621_CLK_CPU;
|
||||
cpu_clk = clk_get_rate(&clk);
|
||||
|
||||
clk.id = MT7621_CLK_BUS;
|
||||
bus_clk = clk_get_rate(&clk);
|
||||
|
||||
clk.id = MT7621_CLK_DDR;
|
||||
ddr_clk = clk_get_rate(&clk);
|
||||
|
||||
clk.id = MT7621_CLK_XTAL;
|
||||
xtal_clk = clk_get_rate(&clk);
|
||||
|
||||
/* Set final timer frequency */
|
||||
if (cpu_clk)
|
||||
gd->arch.timer_freq = cpu_clk / 2;
|
||||
|
||||
printf("Clock: CPU: %uMHz, DDR: %uMT/s, Bus: %uMHz, XTAL: %uMHz\n",
|
||||
cpu_clk / 1000000, ddr_clk / 500000, bus_clk / 1000000,
|
||||
xtal_clk / 1000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long get_xtal_mhz(void)
|
||||
{
|
||||
void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
|
||||
u32 bs, xtal_sel;
|
||||
|
||||
bs = readl(sysc + SYSCTL_SYSCFG0_REG);
|
||||
xtal_sel = FIELD_GET(XTAL_MODE_SEL_M, bs);
|
||||
|
||||
if (xtal_sel <= 2)
|
||||
return 20;
|
||||
else if (xtal_sel <= 5)
|
||||
return 40;
|
||||
else
|
||||
return 25;
|
||||
}
|
||||
|
||||
static void xhci_config_40mhz(void __iomem *usbh)
|
||||
{
|
||||
writel(FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M, 0x20) |
|
||||
FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M, 0x20) |
|
||||
FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MODE_M, 2) |
|
||||
FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MODE_M, 2) | 0x10,
|
||||
usbh + SSUSB_MAC_CK_CTRL_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_PREDIV_PE1D_M, 2) |
|
||||
FIELD_PREP(SSUSB_PLL_PREDIV_U3_M, 1) |
|
||||
FIELD_PREP(SSUSB_PLL_FBKDI_M, 4),
|
||||
usbh + DA_SSUSB_U3PHYA_10_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_FBKDIV_PE2H_M, 0x18) |
|
||||
FIELD_PREP(SSUSB_PLL_FBKDIV_PE1D_M, 0x18) |
|
||||
FIELD_PREP(SSUSB_PLL_FBKDIV_PE1H_M, 0x18) |
|
||||
FIELD_PREP(SSUSB_PLL_FBKDIV_U3_M, 0x1e),
|
||||
usbh + DA_SSUSB_PLL_FBKDIV_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_PCW_NCPO_U3_M, 0x1e400000),
|
||||
usbh + DA_SSUSB_PLL_PCW_NCPO_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE1H_M, 0x25) |
|
||||
FIELD_PREP(SSUSB_PLL_SSC_DELTA1_U3_M, 0x73),
|
||||
usbh + DA_SSUSB_PLL_SSC_DELTA1_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA_U3_M, 0x71) |
|
||||
FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE2D_M, 0x4a),
|
||||
usbh + DA_SSUSB_U3PHYA_21_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_SSC_PRD_M, 0x140),
|
||||
usbh + SSUSB_U3PHYA_9_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_SYSPLL_PCW_NCPO_M, 0x11c00000),
|
||||
usbh + SSUSB_U3PHYA_3_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PCIE_CLKDRV_AMP_M, 4) |
|
||||
FIELD_PREP(SSUSB_SYSPLL_FBSEL_M, 1) |
|
||||
FIELD_PREP(SSUSB_SYSPLL_PREDIV_M, 1),
|
||||
usbh + SSUSB_U3PHYA_1_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_SYSPLL_FBDIV_M, 0x12) |
|
||||
SSUSB_SYSPLL_VCO_DIV_SEL | SSUSB_SYSPLL_FPEN |
|
||||
SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN,
|
||||
usbh + SSUSB_U3PHYA_2_REG);
|
||||
|
||||
writel(SSUSB_EQ_CURSEL | FIELD_PREP(SSUSB_RX_DAC_MUX_M, 8) |
|
||||
FIELD_PREP(SSUSB_PCIE_SIGDET_VTH_M, 1) |
|
||||
FIELD_PREP(SSUSB_PCIE_SIGDET_LPF_M, 1),
|
||||
usbh + SSUSB_U3PHYA_11_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_RING_OSC_CNTEND_M, 0x1ff) |
|
||||
FIELD_PREP(SSUSB_XTAL_OSC_CNTEND_M, 0x7f) |
|
||||
SSUSB_RING_BYPASS_DET,
|
||||
usbh + SSUSB_B2_ROSC_0_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_RING_OSC_FRC_RECAL_M, 3) |
|
||||
SSUSB_RING_OSC_FRC_SEL,
|
||||
usbh + SSUSB_B2_ROSC_1_REG);
|
||||
}
|
||||
|
||||
static void xhci_config_25mhz(void __iomem *usbh)
|
||||
{
|
||||
writel(FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M, 0x20) |
|
||||
FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M, 0x20) |
|
||||
FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MODE_M, 2) |
|
||||
FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MODE_M, 2) | 0x10,
|
||||
usbh + SSUSB_MAC_CK_CTRL_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_PREDIV_PE1D_M, 2) |
|
||||
FIELD_PREP(SSUSB_PLL_FBKDI_M, 4),
|
||||
usbh + DA_SSUSB_U3PHYA_10_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_FBKDIV_PE2H_M, 0x18) |
|
||||
FIELD_PREP(SSUSB_PLL_FBKDIV_PE1D_M, 0x18) |
|
||||
FIELD_PREP(SSUSB_PLL_FBKDIV_PE1H_M, 0x18) |
|
||||
FIELD_PREP(SSUSB_PLL_FBKDIV_U3_M, 0x19),
|
||||
usbh + DA_SSUSB_PLL_FBKDIV_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_PCW_NCPO_U3_M, 0x18000000),
|
||||
usbh + DA_SSUSB_PLL_PCW_NCPO_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE1H_M, 0x25) |
|
||||
FIELD_PREP(SSUSB_PLL_SSC_DELTA1_U3_M, 0x4a),
|
||||
usbh + DA_SSUSB_PLL_SSC_DELTA1_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA_U3_M, 0x48) |
|
||||
FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE2D_M, 0x4a),
|
||||
usbh + DA_SSUSB_U3PHYA_21_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PLL_SSC_PRD_M, 0x190),
|
||||
usbh + SSUSB_U3PHYA_9_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_SYSPLL_PCW_NCPO_M, 0xe000000),
|
||||
usbh + SSUSB_U3PHYA_3_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_PCIE_CLKDRV_AMP_M, 4) |
|
||||
FIELD_PREP(SSUSB_SYSPLL_FBSEL_M, 1),
|
||||
usbh + SSUSB_U3PHYA_1_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_SYSPLL_FBDIV_M, 0xf) |
|
||||
SSUSB_SYSPLL_VCO_DIV_SEL | SSUSB_SYSPLL_FPEN |
|
||||
SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN,
|
||||
usbh + SSUSB_U3PHYA_2_REG);
|
||||
|
||||
writel(SSUSB_EQ_CURSEL | FIELD_PREP(SSUSB_RX_DAC_MUX_M, 8) |
|
||||
FIELD_PREP(SSUSB_PCIE_SIGDET_VTH_M, 1) |
|
||||
FIELD_PREP(SSUSB_PCIE_SIGDET_LPF_M, 1),
|
||||
usbh + SSUSB_U3PHYA_11_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_RING_OSC_CNTEND_M, 0x1ff) |
|
||||
FIELD_PREP(SSUSB_XTAL_OSC_CNTEND_M, 0x7f) |
|
||||
SSUSB_RING_BYPASS_DET,
|
||||
usbh + SSUSB_B2_ROSC_0_REG);
|
||||
|
||||
writel(FIELD_PREP(SSUSB_RING_OSC_FRC_RECAL_M, 3) |
|
||||
SSUSB_RING_OSC_FRC_SEL,
|
||||
usbh + SSUSB_B2_ROSC_1_REG);
|
||||
}
|
||||
|
||||
void lowlevel_init(void)
|
||||
{
|
||||
void __iomem *usbh = ioremap_nocache(SSUSB_BASE, SSUSB_SIZE);
|
||||
u32 xtal = get_xtal_mhz();
|
||||
|
||||
/* Setup USB xHCI */
|
||||
if (xtal == 40)
|
||||
xhci_config_40mhz(usbh);
|
||||
else if (xtal == 25)
|
||||
xhci_config_25mhz(usbh);
|
||||
}
|
||||
|
||||
ulong notrace get_tbclk(void)
|
||||
{
|
||||
return gd->arch.timer_freq;
|
||||
}
|
||||
|
||||
void _machine_restart(void)
|
||||
{
|
||||
void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
|
||||
|
||||
while (1)
|
||||
writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG);
|
||||
}
|
||||
229
arch/mips/mach-mtmips/mt7621/mt7621.h
Normal file
229
arch/mips/mach-mtmips/mt7621/mt7621.h
Normal file
@@ -0,0 +1,229 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT7621_H_
|
||||
#define _MT7621_H_
|
||||
|
||||
#define SYSCTL_BASE 0x1e000000
|
||||
#define SYSCTL_SIZE 0x100
|
||||
#define TIMER_BASE 0x1e000100
|
||||
#define TIMER_SIZE 0x100
|
||||
#define RBUS_BASE 0x1e000400
|
||||
#define RBUS_SIZE 0x100
|
||||
#define GPIO_BASE 0x1e000600
|
||||
#define GPIO_SIZE 0x100
|
||||
#define DMA_CFG_ARB_BASE 0x1e000800
|
||||
#define DMA_CFG_ARB_SIZE 0x100
|
||||
#define SPI_BASE 0x1e000b00
|
||||
#define SPI_SIZE 0x100
|
||||
#define UART1_BASE 0x1e000c00
|
||||
#define UART1_SIZE 0x100
|
||||
#define UART2_BASE 0x1e000d00
|
||||
#define UART2_SIZE 0x100
|
||||
#define UART3_BASE 0x1e000e00
|
||||
#define UART3_SIZE 0x100
|
||||
#define NFI_BASE 0x1e003000
|
||||
#define NFI_SIZE 0x800
|
||||
#define NFI_ECC_BASE 0x1e003800
|
||||
#define NFI_ECC_SIZE 0x800
|
||||
#define DRAMC_BASE 0x1e005000
|
||||
#define DRAMC_SIZE 0x1000
|
||||
#define FE_BASE 0x1e100000
|
||||
#define FE_SIZE 0xe000
|
||||
#define GMAC_BASE 0x1e110000
|
||||
#define GMAC_SIZE 0x8000
|
||||
#define SSUSB_BASE 0x1e1c0000
|
||||
#define SSUSB_SIZE 0x40000
|
||||
|
||||
/* GIC Base Address */
|
||||
#define MIPS_GIC_BASE 0x1fbc0000
|
||||
|
||||
/* CPC Base Address */
|
||||
#define MIPS_CPC_BASE 0x1fbf0000
|
||||
|
||||
/* Flash Memory-mapped Base Address */
|
||||
#define FLASH_MMAP_BASE 0x1fc00000
|
||||
#define TPL_INFO_OFFSET 0x40
|
||||
#define TPL_INFO_MAGIC 0x31323637 /* Magic "7621" */
|
||||
|
||||
/* SRAM */
|
||||
#define FE_SRAM_BASE1 0x8000
|
||||
#define FE_SRAM_BASE2 0xa000
|
||||
|
||||
/* SYSCTL_BASE */
|
||||
#define SYSCTL_CHIP_REV_ID_REG 0x0c
|
||||
#define CPU_ID 0x20000
|
||||
#define PKG_ID 0x10000
|
||||
#define VER_ID_S 8
|
||||
#define VER_ID_M 0xf00
|
||||
#define ECO_ID_S 0
|
||||
#define ECO_ID_M 0x0f
|
||||
|
||||
#define SYSCTL_SYSCFG0_REG 0x10
|
||||
#define XTAL_MODE_SEL_S 6
|
||||
#define XTAL_MODE_SEL_M 0x1c0
|
||||
#define DRAM_TYPE 0x10
|
||||
#define CHIP_MODE_S 0
|
||||
#define CHIP_MODE_M 0x0f
|
||||
|
||||
#define BOOT_SRAM_BASE_REG 0x20
|
||||
|
||||
#define SYSCTL_CLKCFG0_REG 0x2c
|
||||
#define CPU_CLK_SEL_S 30
|
||||
#define CPU_CLK_SEL_M 0xc0000000
|
||||
#define MPLL_CFG_SEL_S 23
|
||||
#define MPLL_CFG_SEL_M 0x800000
|
||||
|
||||
#define SYSCTL_RSTCTL_REG 0x34
|
||||
#define MCM_RST 0x04
|
||||
#define SYS_RST 0x01
|
||||
|
||||
#define SYSCTL_CUR_CLK_STS_REG 0x44
|
||||
#define CUR_CPU_FDIV_S 8
|
||||
#define CUR_CPU_FDIV_M 0x1f00
|
||||
#define CUR_CPU_FFRAC_S 0
|
||||
#define CUR_CPU_FFRAC_M 0x1f
|
||||
|
||||
#define SYSCTL_GPIOMODE_REG 0x60
|
||||
#define UART2_MODE_S 5
|
||||
#define UART2_MODE_M 0x60
|
||||
#define UART3_MODE_S 3
|
||||
#define UART3_MODE_M 0x18
|
||||
#define UART1_MODE 0x02
|
||||
|
||||
/* RBUS_BASE */
|
||||
#define RBUS_DYN_CFG0_REG 0x0010
|
||||
#define CPU_FDIV_S 8
|
||||
#define CPU_FDIV_M 0x1f00
|
||||
#define CPU_FFRAC_S 0
|
||||
#define CPU_FFRAC_M 0x1f
|
||||
|
||||
/* DMA_CFG_ARB_BASE */
|
||||
#define DMA_ROUTE_REG 0x000c
|
||||
|
||||
/* SPI_BASE */
|
||||
#define SPI_SPACE_REG 0x003c
|
||||
#define FS_SLAVE_SEL_S 12
|
||||
#define FS_SLAVE_SEL_M 0x70000
|
||||
#define FS_CLK_SEL_S 0
|
||||
#define FS_CLK_SEL_M 0xfff
|
||||
|
||||
/* FE_BASE */
|
||||
#define FE_RST_GLO_REG 0x0004
|
||||
#define FE_PSE_RAM 0x04
|
||||
#define FE_PSE_MEM_EN 0x02
|
||||
#define FE_PSE_RESET 0x01
|
||||
|
||||
/* SSUSB_BASE */
|
||||
#define SSUSB_MAC_CK_CTRL_REG 0x10784
|
||||
#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S 16
|
||||
#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M 0xff0000
|
||||
#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S 8
|
||||
#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M 0xff00
|
||||
#define SSUSB_MAC3_SYS_CK_GATE_MODE_S 2
|
||||
#define SSUSB_MAC3_SYS_CK_GATE_MODE_M 0x0c
|
||||
#define SSUSB_MAC2_SYS_CK_GATE_MODE_S 0
|
||||
#define SSUSB_MAC2_SYS_CK_GATE_MODE_M 0x03
|
||||
|
||||
#define SSUSB_B2_ROSC_0_REG 0x10a40
|
||||
#define SSUSB_RING_OSC_CNTEND_S 23
|
||||
#define SSUSB_RING_OSC_CNTEND_M 0xff800000
|
||||
#define SSUSB_XTAL_OSC_CNTEND_S 16
|
||||
#define SSUSB_XTAL_OSC_CNTEND_M 0x7f0000
|
||||
#define SSUSB_RING_BYPASS_DET 0x01
|
||||
|
||||
#define SSUSB_B2_ROSC_1_REG 0x10a44
|
||||
#define SSUSB_RING_OSC_FRC_RECAL_S 17
|
||||
#define SSUSB_RING_OSC_FRC_RECAL_M 0x60000
|
||||
#define SSUSB_RING_OSC_FRC_SEL 0x01
|
||||
|
||||
#define SSUSB_U3PHYA_1_REG 0x10b04
|
||||
#define SSUSB_PCIE_CLKDRV_AMP_S 27
|
||||
#define SSUSB_PCIE_CLKDRV_AMP_M 0x38000000
|
||||
#define SSUSB_SYSPLL_FBSEL_S 2
|
||||
#define SSUSB_SYSPLL_FBSEL_M 0x0c
|
||||
#define SSUSB_SYSPLL_PREDIV_S 0
|
||||
#define SSUSB_SYSPLL_PREDIV_M 0x03
|
||||
|
||||
#define SSUSB_U3PHYA_2_REG 0x10b08
|
||||
#define SSUSB_SYSPLL_FBDIV_S 24
|
||||
#define SSUSB_SYSPLL_FBDIV_M 0x7f000000
|
||||
#define SSUSB_SYSPLL_VCO_DIV_SEL 0x200000
|
||||
#define SSUSB_SYSPLL_FPEN 0x2000
|
||||
#define SSUSB_SYSPLL_MONCK_EN 0x1000
|
||||
#define SSUSB_SYSPLL_VOD_EN 0x200
|
||||
|
||||
#define SSUSB_U3PHYA_3_REG 0x10b10
|
||||
#define SSUSB_SYSPLL_PCW_NCPO_S 1
|
||||
#define SSUSB_SYSPLL_PCW_NCPO_M 0xfffffffe
|
||||
|
||||
#define SSUSB_U3PHYA_9_REG 0x10b24
|
||||
#define SSUSB_PLL_SSC_PRD_S 0
|
||||
#define SSUSB_PLL_SSC_PRD_M 0xffff
|
||||
|
||||
#define SSUSB_U3PHYA_11_REG 0x10b2c
|
||||
#define SSUSB_EQ_CURSEL 0x1000000
|
||||
#define SSUSB_RX_DAC_MUX_S 19
|
||||
#define SSUSB_RX_DAC_MUX_M 0xf80000
|
||||
#define SSUSB_PCIE_SIGDET_VTH_S 5
|
||||
#define SSUSB_PCIE_SIGDET_VTH_M 0x60
|
||||
#define SSUSB_PCIE_SIGDET_LPF_S 3
|
||||
#define SSUSB_PCIE_SIGDET_LPF_M 0x18
|
||||
|
||||
#define DA_SSUSB_PLL_FBKDIV_REG 0x10c1c
|
||||
#define SSUSB_PLL_FBKDIV_PE2H_S 24
|
||||
#define SSUSB_PLL_FBKDIV_PE2H_M 0x7f000000
|
||||
#define SSUSB_PLL_FBKDIV_PE1D_S 16
|
||||
#define SSUSB_PLL_FBKDIV_PE1D_M 0x7f0000
|
||||
#define SSUSB_PLL_FBKDIV_PE1H_S 8
|
||||
#define SSUSB_PLL_FBKDIV_PE1H_M 0x7f00
|
||||
#define SSUSB_PLL_FBKDIV_U3_S 0
|
||||
#define SSUSB_PLL_FBKDIV_U3_M 0x7f
|
||||
|
||||
#define DA_SSUSB_U3PHYA_10_REG 0x10c20
|
||||
#define SSUSB_PLL_PREDIV_PE1D_S 18
|
||||
#define SSUSB_PLL_PREDIV_PE1D_M 0xc0000
|
||||
#define SSUSB_PLL_PREDIV_U3_S 8
|
||||
#define SSUSB_PLL_PREDIV_U3_M 0x300
|
||||
#define SSUSB_PLL_FBKDI_S 0
|
||||
#define SSUSB_PLL_FBKDI_M 0x07
|
||||
|
||||
#define DA_SSUSB_PLL_PCW_NCPO_REG 0x10c24
|
||||
#define SSUSB_PLL_PCW_NCPO_U3_S 0
|
||||
#define SSUSB_PLL_PCW_NCPO_U3_M 0x7fffffff
|
||||
|
||||
#define DA_SSUSB_PLL_SSC_DELTA1_REG 0x10c38
|
||||
#define SSUSB_PLL_SSC_DELTA1_PE1H_S 16
|
||||
#define SSUSB_PLL_SSC_DELTA1_PE1H_M 0xffff0000
|
||||
#define SSUSB_PLL_SSC_DELTA1_U3_S 0
|
||||
#define SSUSB_PLL_SSC_DELTA1_U3_M 0xffff
|
||||
|
||||
#define DA_SSUSB_U3PHYA_21_REG 0x10c40
|
||||
#define SSUSB_PLL_SSC_DELTA_U3_S 16
|
||||
#define SSUSB_PLL_SSC_DELTA_U3_M 0xffff0000
|
||||
#define SSUSB_PLL_SSC_DELTA1_PE2D_S 0
|
||||
#define SSUSB_PLL_SSC_DELTA1_PE2D_M 0xffff
|
||||
|
||||
/* MT7621 specific CM values */
|
||||
|
||||
/* GCR_REGx_BASE */
|
||||
#define GCR_REG0_BASE_VALUE 0x1c000000
|
||||
#define GCR_REG1_BASE_VALUE 0x60000000
|
||||
#define GCR_REG2_BASE_VALUE 0x1c000000
|
||||
#define GCR_REG3_BASE_VALUE 0x1c000000
|
||||
|
||||
/* GCR_REGx_MASK */
|
||||
#define GCR_REG0_MASK_VALUE 0x0000fc00 /* 64M Bus */
|
||||
#define GCR_REG1_MASK_VALUE 0x0000f000 /* 256M PCI Mem */
|
||||
#define GCR_REG2_MASK_VALUE 0x0000fc00 /* unused */
|
||||
#define GCR_REG3_MASK_VALUE 0x0000fc00 /* unused */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
unsigned long get_xtal_mhz(void);
|
||||
#endif
|
||||
|
||||
#endif /* _MT7621_H_ */
|
||||
23
arch/mips/mach-mtmips/mt7621/serial.c
Normal file
23
arch/mips/mach-mtmips/mt7621/serial.c
Normal file
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include "mt7621.h"
|
||||
|
||||
void board_debug_uart_init(void)
|
||||
{
|
||||
void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
|
||||
|
||||
#if CONFIG_DEBUG_UART_BASE == 0xbe000c00 /* KSEG1ADDR(UART1_BASE) */
|
||||
clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE);
|
||||
#elif CONFIG_DEBUG_UART_BASE == 0xbe000d00 /* KSEG1ADDR(UART2_BASE) */
|
||||
clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M);
|
||||
#elif CONFIG_DEBUG_UART_BASE == 0xbe000e00 /* KSEG1ADDR(UART3_BASE) */
|
||||
clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M);
|
||||
#endif
|
||||
}
|
||||
9
arch/mips/mach-mtmips/mt7621/spl/Makefile
Normal file
9
arch/mips/mach-mtmips/mt7621/spl/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
extra-y += start.o
|
||||
|
||||
obj-y += spl.o
|
||||
obj-y += cps.o
|
||||
obj-y += dram.o
|
||||
obj-y += serial.o
|
||||
obj-y += launch.o
|
||||
obj-y += launch_ll.o
|
||||
153
arch/mips/mach-mtmips/mt7621/spl/cps.c
Normal file
153
arch/mips/mach-mtmips/mt7621/spl/cps.c
Normal file
@@ -0,0 +1,153 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/cm.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include "../mt7621.h"
|
||||
|
||||
/* GIC Shared Register Bases */
|
||||
#define GIC_SH_POL_BASE 0x100
|
||||
#define GIC_SH_TRIG_BASE 0x180
|
||||
#define GIC_SH_RMASK_BASE 0x300
|
||||
#define GIC_SH_SMASK_BASE 0x380
|
||||
#define GIC_SH_MASK_BASE 0x400
|
||||
#define GIC_SH_PEND_BASE 0x480
|
||||
#define GIC_SH_MAP_PIN_BASE 0x500
|
||||
#define GIC_SH_MAP_VPE_BASE 0x2000
|
||||
|
||||
/* GIC Registers */
|
||||
#define GIC_SH_POL31_0 (GIC_SH_POL_BASE + 0x00)
|
||||
#define GIC_SH_POL63_32 (GIC_SH_POL_BASE + 0x04)
|
||||
|
||||
#define GIC_SH_TRIG31_0 (GIC_SH_TRIG_BASE + 0x00)
|
||||
#define GIC_SH_TRIG63_32 (GIC_SH_TRIG_BASE + 0x04)
|
||||
|
||||
#define GIC_SH_RMASK31_0 (GIC_SH_RMASK_BASE + 0x00)
|
||||
#define GIC_SH_RMASK63_32 (GIC_SH_RMASK_BASE + 0x04)
|
||||
|
||||
#define GIC_SH_SMASK31_0 (GIC_SH_SMASK_BASE + 0x00)
|
||||
#define GIC_SH_SMASK63_32 (GIC_SH_SMASK_BASE + 0x04)
|
||||
|
||||
#define GIC_SH_MAP_PIN(n) (GIC_SH_MAP_PIN_BASE + (n) * 4)
|
||||
|
||||
#define GIC_SH_MAP_VPE(n, v) (GIC_SH_MAP_VPE_BASE + (n) * 0x20 + ((v) / 32) * 4)
|
||||
#define GIC_SH_MAP_VPE31_0(n) GIC_SH_MAP_VPE(n, 0)
|
||||
|
||||
/* GIC_SH_MAP_PIN fields */
|
||||
#define GIC_MAP_TO_PIN BIT(31)
|
||||
#define GIC_MAP_TO_NMI BIT(30)
|
||||
#define GIC_MAP GENMASK(5, 0)
|
||||
#define GIC_MAP_SHIFT 0
|
||||
|
||||
static void cm_init(void __iomem *cm_base)
|
||||
{
|
||||
u32 gcrcfg, num_cores;
|
||||
|
||||
gcrcfg = readl(cm_base + GCR_CONFIG);
|
||||
num_cores = FIELD_GET(GCR_CONFIG_PCORES, gcrcfg) + 1;
|
||||
|
||||
writel((1 << num_cores) - 1, cm_base + GCR_ACCESS);
|
||||
|
||||
writel(GCR_REG0_BASE_VALUE, cm_base + GCR_REG0_BASE);
|
||||
writel(GCR_REG1_BASE_VALUE, cm_base + GCR_REG1_BASE);
|
||||
writel(GCR_REG2_BASE_VALUE, cm_base + GCR_REG2_BASE);
|
||||
writel(GCR_REG3_BASE_VALUE, cm_base + GCR_REG3_BASE);
|
||||
|
||||
clrsetbits_32(cm_base + GCR_REG0_MASK,
|
||||
GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
|
||||
FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG0_MASK_VALUE) |
|
||||
GCR_REGn_MASK_CMTGT_IOCU0);
|
||||
|
||||
clrsetbits_32(cm_base + GCR_REG1_MASK,
|
||||
GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
|
||||
FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG1_MASK_VALUE) |
|
||||
GCR_REGn_MASK_CMTGT_IOCU0);
|
||||
|
||||
clrsetbits_32(cm_base + GCR_REG2_MASK,
|
||||
GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
|
||||
FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG2_MASK_VALUE) |
|
||||
GCR_REGn_MASK_CMTGT_IOCU0);
|
||||
|
||||
clrsetbits_32(cm_base + GCR_REG3_MASK,
|
||||
GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
|
||||
FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG3_MASK_VALUE) |
|
||||
GCR_REGn_MASK_CMTGT_IOCU0);
|
||||
|
||||
clrbits_32(cm_base + GCR_BASE, CM_DEFAULT_TARGET_MASK);
|
||||
setbits_32(cm_base + GCR_CONTROL, GCR_CONTROL_SYNCCTL);
|
||||
}
|
||||
|
||||
static void gic_init(void)
|
||||
{
|
||||
void __iomem *gic_base = (void *)KSEG1ADDR(MIPS_GIC_BASE);
|
||||
int i;
|
||||
|
||||
/* Interrupt 0..5: Level Trigger, Active High */
|
||||
writel(0, gic_base + GIC_SH_TRIG31_0);
|
||||
writel(0x3f, gic_base + GIC_SH_RMASK31_0);
|
||||
writel(0x3f, gic_base + GIC_SH_POL31_0);
|
||||
writel(0x3f, gic_base + GIC_SH_SMASK31_0);
|
||||
|
||||
/* Interrupt 56..63: Edge Trigger, Rising Edge */
|
||||
/* Hardcoded to set up the last 8 external interrupts for IPI. */
|
||||
writel(0xff000000, gic_base + GIC_SH_TRIG63_32);
|
||||
writel(0xff000000, gic_base + GIC_SH_RMASK63_32);
|
||||
writel(0xff000000, gic_base + GIC_SH_POL63_32);
|
||||
writel(0xff000000, gic_base + GIC_SH_SMASK63_32);
|
||||
|
||||
/* Map interrupt source to particular hardware interrupt pin */
|
||||
/* source {0,1,2,3,4,5} -> pin {0,0,4,3,0,5} */
|
||||
writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(0));
|
||||
writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(1));
|
||||
writel(GIC_MAP_TO_PIN | 4, gic_base + GIC_SH_MAP_PIN(2));
|
||||
writel(GIC_MAP_TO_PIN | 3, gic_base + GIC_SH_MAP_PIN(3));
|
||||
writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(4));
|
||||
writel(GIC_MAP_TO_PIN | 5, gic_base + GIC_SH_MAP_PIN(5));
|
||||
|
||||
/* source 56~59 -> pin 1, 60~63 -> pin 2 */
|
||||
writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(56));
|
||||
writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(57));
|
||||
writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(58));
|
||||
writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(59));
|
||||
writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(60));
|
||||
writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(61));
|
||||
writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(62));
|
||||
writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(63));
|
||||
|
||||
/* Interrupt map to VPE (bit mask) */
|
||||
for (i = 0; i < 32; i++)
|
||||
writel(BIT(0), gic_base + GIC_SH_MAP_VPE31_0(i));
|
||||
|
||||
/*
|
||||
* Direct GIC_int 56..63 to vpe 0..3
|
||||
* MIPS Linux convention that last 16 interrupts implemented be set
|
||||
* aside for IPI signaling.
|
||||
* The actual interrupts are tied low and software sends interrupts
|
||||
* via GIC_SH_WEDGE writes.
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 56));
|
||||
writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 60));
|
||||
}
|
||||
}
|
||||
|
||||
void mt7621_cps_init(void)
|
||||
{
|
||||
void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE);
|
||||
|
||||
/* Enable GIC */
|
||||
writel(MIPS_GIC_BASE | GCR_GIC_EN, cm_base + GCR_GIC_BASE);
|
||||
|
||||
/* Enable CPC */
|
||||
writel(MIPS_CPC_BASE | GCR_CPC_EN, cm_base + GCR_CPC_BASE);
|
||||
|
||||
gic_init();
|
||||
cm_init(cm_base);
|
||||
}
|
||||
153
arch/mips/mach-mtmips/mt7621/spl/dram.c
Normal file
153
arch/mips/mach-mtmips/mt7621/spl/dram.c
Normal file
@@ -0,0 +1,153 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <vsprintf.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <linux/string.h>
|
||||
#include "../mt7621.h"
|
||||
#include "dram.h"
|
||||
|
||||
static const u32 ddr2_act[DDR_PARAM_SIZE] = {
|
||||
#if defined(CONFIG_MT7621_DRAM_DDR2_512M)
|
||||
0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441,
|
||||
0x00000000, 0xF0748661, 0x40001273, 0x9F0A0481,
|
||||
0x0304692F, 0x15602842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x07100000,
|
||||
0x00001B63, 0x00002000, 0x00004000, 0x00006000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
#elif defined(CONFIG_MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ)
|
||||
0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584,
|
||||
0x00000000, 0xF07486A1, 0x50001273, 0x9F010481,
|
||||
0x0304693F, 0x15602842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000010, 0x07100000,
|
||||
0x00001F73, 0x00002000, 0x00004000, 0x00006000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ)
|
||||
0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174430,
|
||||
0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481,
|
||||
0x0304692F, 0x15602842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x07100000,
|
||||
0x00001B63, 0x00002000, 0x00004000, 0x00006000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ)
|
||||
0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584,
|
||||
0x01000000, 0xF07486A1, 0x50001273, 0x9F070481,
|
||||
0x0304693F, 0x15602842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000010, 0x07100000,
|
||||
0x00001F73, 0x00002000, 0x00004000, 0x00006000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
#else /* CONFIG_MT7621_DRAM_DDR2_1024M */
|
||||
0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441,
|
||||
0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481,
|
||||
0x0304692F, 0x15602842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x07100000,
|
||||
0x00001B63, 0x00002000, 0x00004000, 0x00006000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const u32 ddr3_act[DDR_PARAM_SIZE] = {
|
||||
#if defined(CONFIG_MT7621_DRAM_DDR3_1024M)
|
||||
0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683,
|
||||
0x01000000, 0xF07486A1, 0xC287221D, 0x9F060481,
|
||||
0x03046948, 0x15602842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000210, 0x07100000,
|
||||
0x00001B61, 0x00002040, 0x00004010, 0x00006000,
|
||||
0x0C000000, 0x07070000, 0x00000000, 0x00000000,
|
||||
#elif defined(CONFIG_MT7621_DRAM_DDR3_4096M)
|
||||
0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683,
|
||||
0x01000000, 0xF07486A1, 0xC287221D, 0x9F0F0481,
|
||||
0x03046948, 0x15602842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000240, 0x07100000,
|
||||
0x00001B61, 0x00002040, 0x00004010, 0x00006000,
|
||||
0x0C000000, 0x07070000, 0x00000000, 0x00000000,
|
||||
#elif defined(CONFIG_MT7621_DRAM_DDR3_1024M_KGD)
|
||||
0xFF00FF00, 0xFF00FF00, 0x00000007, 0x44694683,
|
||||
0x01000000, 0xF07406A1, 0xC287221D, 0x9F060481,
|
||||
0x03046923, 0x152f2842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000210, 0x07100000,
|
||||
0x00001B61, 0x00002040, 0x00004010, 0x00006000,
|
||||
0x0C000000, 0x07070000, 0x000C0000, 0x00000000,
|
||||
#else /* CONFIG_MT7621_DRAM_DDR3_2048M */
|
||||
0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694673,
|
||||
0x01000000, 0xF07486A1, 0xC287221D, 0x9F050481,
|
||||
0x03046948, 0x15602842, 0x00008888, 0x88888888,
|
||||
0x00000000, 0x00000000, 0x00000220, 0x07100000,
|
||||
0x00001B61, 0x00002040, 0x00004010, 0x00006000,
|
||||
0x0C000000, 0x07070000, 0x00000000, 0x00000000,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(CONFIG_MT7621_DRAM_FREQ_400)
|
||||
#define DDR_FREQ_PARAM 0x41000000
|
||||
#elif defined(CONFIG_MT7621_DRAM_FREQ_1066)
|
||||
#define DDR_FREQ_PARAM 0x21000000
|
||||
#elif defined(CONFIG_MT7621_DRAM_FREQ_1200)
|
||||
#define DDR_FREQ_PARAM 0x11000000
|
||||
#else /* CONFIG_MT7621_DRAM_FREQ_800 */
|
||||
#define DDR_FREQ_PARAM 0x31000000
|
||||
#endif
|
||||
|
||||
#define RG_MEPL_FBDIV_S 4
|
||||
#define RG_MEPL_FBDIV_M 0x7f
|
||||
|
||||
static inline void word_copy(u32 *dest, const u32 *src, u32 count)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
dest[i] = src[i];
|
||||
}
|
||||
|
||||
static u32 calc_cpu_pll_val(void)
|
||||
{
|
||||
u32 div, baseval, fb;
|
||||
|
||||
div = get_xtal_mhz();
|
||||
|
||||
if (div == 40) {
|
||||
div /= 2;
|
||||
baseval = 0xc0005802;
|
||||
} else {
|
||||
baseval = 0xc0004802;
|
||||
}
|
||||
|
||||
fb = CONFIG_MT7621_CPU_FREQ / div - 1;
|
||||
if (fb > RG_MEPL_FBDIV_M)
|
||||
fb = RG_MEPL_FBDIV_M;
|
||||
|
||||
return baseval | (fb << RG_MEPL_FBDIV_S);
|
||||
}
|
||||
|
||||
void prepare_stage_bin(void)
|
||||
{
|
||||
u32 stage_size;
|
||||
|
||||
const struct stage_header *stock_stage_bin =
|
||||
(const struct stage_header *)__image_copy_end;
|
||||
|
||||
struct stage_header *new_stage_bin =
|
||||
(struct stage_header *)STAGE_LOAD_ADDR;
|
||||
|
||||
if (be32_to_cpu(stock_stage_bin->ep) != STAGE_LOAD_ADDR)
|
||||
panic("Invalid DDR stage binary blob\n");
|
||||
|
||||
stage_size = be32_to_cpu(stock_stage_bin->stage_size);
|
||||
|
||||
word_copy((u32 *)new_stage_bin, (const u32 *)stock_stage_bin,
|
||||
(stage_size + sizeof(u32) - 1) / sizeof(u32));
|
||||
|
||||
word_copy(new_stage_bin->ddr2_act, ddr2_act, DDR_PARAM_SIZE);
|
||||
word_copy(new_stage_bin->ddr3_act, ddr3_act, DDR_PARAM_SIZE);
|
||||
|
||||
new_stage_bin->cpu_pll_cfg = calc_cpu_pll_val();
|
||||
new_stage_bin->ddr_pll_cfg = DDR_FREQ_PARAM;
|
||||
new_stage_bin->baudrate = CONFIG_BAUDRATE;
|
||||
}
|
||||
39
arch/mips/mach-mtmips/mt7621/spl/dram.h
Normal file
39
arch/mips/mach-mtmips/mt7621/spl/dram.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT7621_DRAM_H_
|
||||
#define _MT7621_DRAM_H_
|
||||
|
||||
#define STAGE_LOAD_ADDR 0xBE108800
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <linux/types.h>
|
||||
|
||||
#define DDR_PARAM_SIZE 24
|
||||
|
||||
struct stage_header {
|
||||
u32 jump_insn[2];
|
||||
u32 ep;
|
||||
u32 stage_size;
|
||||
u32 has_stage2;
|
||||
u32 next_ep;
|
||||
u32 next_size;
|
||||
u32 next_offset;
|
||||
u32 cpu_pll_cfg;
|
||||
u32 ddr_pll_cfg;
|
||||
u32 reserved2[6];
|
||||
char build_tag[32];
|
||||
u32 ddr3_act[DDR_PARAM_SIZE];
|
||||
u32 padding1[2];
|
||||
u32 ddr2_act[DDR_PARAM_SIZE];
|
||||
u32 padding2[2];
|
||||
u32 baudrate;
|
||||
u32 padding3;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* _MT7621_DRAM_H_ */
|
||||
100
arch/mips/mach-mtmips/mt7621/spl/launch.c
Normal file
100
arch/mips/mach-mtmips/mt7621/spl/launch.c
Normal file
@@ -0,0 +1,100 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/cm.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/mipsmtregs.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <time.h>
|
||||
#include <cpu_func.h>
|
||||
#include "launch.h"
|
||||
#include "../mt7621.h"
|
||||
|
||||
/* Cluster Power Controller (CPC) offsets */
|
||||
#define CPC_CL_OTHER 0x2010
|
||||
#define CPC_CO_CMD 0x4000
|
||||
|
||||
/* CPC_CL_OTHER fields */
|
||||
#define CPC_CL_OTHER_CORENUM_SHIFT 16
|
||||
#define CPC_CL_OTHER_CORENUM GENMASK(23, 16)
|
||||
|
||||
/* CPC_CO_CMD */
|
||||
#define PWR_UP 3
|
||||
|
||||
#define NUM_CORES 2
|
||||
#define NUM_CPUS 4
|
||||
#define WAIT_CPUS_TIMEOUT 4000
|
||||
|
||||
static void copy_launch_wait_code(void)
|
||||
{
|
||||
memset((void *)KSEG1, 0, SZ_4K);
|
||||
|
||||
memcpy((void *)KSEG1ADDR(LAUNCH_WAITCODE),
|
||||
&launch_wait_code_start,
|
||||
&launch_wait_code_end - &launch_wait_code_start);
|
||||
|
||||
invalidate_dcache_range(KSEG0, SZ_4K);
|
||||
}
|
||||
|
||||
static void bootup_secondary_core(void)
|
||||
{
|
||||
void __iomem *cpcbase = (void __iomem *)KSEG1ADDR(MIPS_CPC_BASE);
|
||||
int i;
|
||||
|
||||
for (i = 1; i < NUM_CORES; i++) {
|
||||
writel(i << CPC_CL_OTHER_CORENUM_SHIFT, cpcbase + CPC_CL_OTHER);
|
||||
writel(PWR_UP, cpcbase + CPC_CO_CMD);
|
||||
}
|
||||
}
|
||||
|
||||
void secondary_cpu_init(void)
|
||||
{
|
||||
void __iomem *sysc = (void __iomem *)KSEG1ADDR(SYSCTL_BASE);
|
||||
u32 i, dual_core = 0, cpuready = 1, cpumask = 0x03;
|
||||
ulong wait_tick;
|
||||
struct cpulaunch_t *c;
|
||||
|
||||
/* Copy LAUNCH wait code used by other VPEs */
|
||||
copy_launch_wait_code();
|
||||
|
||||
dual_core = readl(sysc + SYSCTL_CHIP_REV_ID_REG) & CPU_ID;
|
||||
|
||||
if (dual_core) {
|
||||
/* Bootup secondary core for MT7621A */
|
||||
cpumask = 0x0f;
|
||||
|
||||
/* Make BootROM/TPL redirect Core1's bootup flow to our entry point */
|
||||
writel((uintptr_t)&_start, sysc + BOOT_SRAM_BASE_REG);
|
||||
|
||||
bootup_secondary_core();
|
||||
}
|
||||
|
||||
/* Join the coherent domain */
|
||||
join_coherent_domain(dual_core ? 2 : 1);
|
||||
|
||||
/* Bootup Core0/VPE1 */
|
||||
boot_vpe1();
|
||||
|
||||
/* Wait for all CPU ready */
|
||||
wait_tick = get_timer(0) + WAIT_CPUS_TIMEOUT;
|
||||
|
||||
while (time_before(get_timer(0), wait_tick)) {
|
||||
/* CPU0 is obviously ready */
|
||||
for (i = 1; i < NUM_CPUS; i++) {
|
||||
c = (struct cpulaunch_t *)(KSEG0ADDR(CPULAUNCH) +
|
||||
(i << LOG2CPULAUNCH));
|
||||
|
||||
if (c->flags & LAUNCH_FREADY)
|
||||
cpuready |= BIT(i);
|
||||
}
|
||||
|
||||
if ((cpuready & cpumask) == cpumask)
|
||||
break;
|
||||
}
|
||||
}
|
||||
52
arch/mips/mach-mtmips/mt7621/spl/launch.h
Normal file
52
arch/mips/mach-mtmips/mt7621/spl/launch.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _LAUNCH_H_
|
||||
#define _LAUNCH_H_
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct cpulaunch_t {
|
||||
unsigned long pc;
|
||||
unsigned long gp;
|
||||
unsigned long sp;
|
||||
unsigned long a0;
|
||||
unsigned long _pad[3]; /* pad to cache line size to avoid thrashing */
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
extern char launch_wait_code_start;
|
||||
extern char launch_wait_code_end;
|
||||
|
||||
void join_coherent_domain(int ncores);
|
||||
void boot_vpe1(void);
|
||||
|
||||
#else
|
||||
|
||||
#define LAUNCH_PC 0
|
||||
#define LAUNCH_GP 4
|
||||
#define LAUNCH_SP 8
|
||||
#define LAUNCH_A0 12
|
||||
#define LAUNCH_FLAGS 28
|
||||
|
||||
#endif
|
||||
|
||||
#define LOG2CPULAUNCH 5
|
||||
|
||||
#define LAUNCH_FREADY 1
|
||||
#define LAUNCH_FGO 2
|
||||
#define LAUNCH_FGONE 4
|
||||
|
||||
#define LAUNCH_WAITCODE 0x00000d00
|
||||
#define SCRLAUNCH 0x00000e00
|
||||
#define CPULAUNCH 0x00000f00
|
||||
#define NCPULAUNCH 8
|
||||
|
||||
/* Polling period in count cycles for secondary CPU's */
|
||||
#define LAUNCHPERIOD 10000
|
||||
|
||||
#endif /* _LAUNCH_H_ */
|
||||
339
arch/mips/mach-mtmips/mt7621/spl/launch_ll.S
Normal file
339
arch/mips/mach-mtmips/mt7621/spl/launch_ll.S
Normal file
@@ -0,0 +1,339 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <asm/cm.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/cacheops.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/mipsmtregs.h>
|
||||
#include "launch.h"
|
||||
|
||||
.macro cache_loop curr, end, line_sz, op
|
||||
10: cache \op, 0(\curr)
|
||||
PTR_ADDU \curr, \curr, \line_sz
|
||||
bne \curr, \end, 10b
|
||||
.endm
|
||||
|
||||
.set mt
|
||||
|
||||
/*
|
||||
* Join the coherent domain
|
||||
* a0 = number of cores
|
||||
*/
|
||||
LEAF(join_coherent_domain)
|
||||
/*
|
||||
* Enable coherence and allow interventions from all other cores.
|
||||
* (Write access enabled via GCR_ACCESS by core 0.)
|
||||
*/
|
||||
li t1, 1
|
||||
sll t1, a0
|
||||
addiu t1, -1
|
||||
|
||||
li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
|
||||
sw t1, GCR_Cx_COHERENCE(t0)
|
||||
ehb
|
||||
|
||||
move t2, zero
|
||||
|
||||
_next_coherent_core:
|
||||
sll t1, t2, GCR_Cx_OTHER_CORENUM_SHIFT
|
||||
sw t1, GCR_Cx_OTHER(t0)
|
||||
|
||||
_busy_wait_coherent_core:
|
||||
lw t1, GCR_CO_COHERENCE(t0)
|
||||
beqz t1, _busy_wait_coherent_core
|
||||
|
||||
addiu t2, 1
|
||||
bne t2, a0, _next_coherent_core
|
||||
|
||||
jr ra
|
||||
END(join_coherent_domain)
|
||||
|
||||
/*
|
||||
* All VPEs other than VPE0 will go here.
|
||||
*/
|
||||
LEAF(launch_vpe_entry)
|
||||
mfc0 t0, CP0_EBASE
|
||||
and t0, t0, MIPS_EBASE_CPUNUM
|
||||
|
||||
/* per-VPE cpulaunch_t */
|
||||
li a0, KSEG0ADDR(CPULAUNCH)
|
||||
sll t1, t0, LOG2CPULAUNCH
|
||||
addu a0, t1
|
||||
|
||||
/* Set CPU online flag */
|
||||
li t0, LAUNCH_FREADY
|
||||
sw t0, LAUNCH_FLAGS(a0)
|
||||
|
||||
/* Enable count interrupt in mask, but do not enable interrupts */
|
||||
mfc0 t0, CP0_STATUS
|
||||
ori t0, STATUSF_IP7
|
||||
mtc0 t0, CP0_STATUS
|
||||
|
||||
/* VPEs executing in wait code do not need a stack */
|
||||
li t9, KSEG0ADDR(LAUNCH_WAITCODE)
|
||||
jr t9
|
||||
END(launch_vpe_entry)
|
||||
|
||||
/*
|
||||
* This function will not be executed in place.
|
||||
* It will be copied into memory, and VPEs other than VPE0 will be
|
||||
* started to run into this in-memory function.
|
||||
*/
|
||||
LEAF(launch_wait_code)
|
||||
.globl launch_wait_code_start
|
||||
launch_wait_code_start:
|
||||
|
||||
move t0, a0
|
||||
|
||||
start_poll:
|
||||
/* Poll CPU go flag */
|
||||
mtc0 zero, CP0_COUNT
|
||||
li t1, LAUNCHPERIOD
|
||||
mtc0 t1, CP0_COMPARE
|
||||
|
||||
time_wait:
|
||||
/* Software wait */
|
||||
mfc0 t2, CP0_COUNT
|
||||
subu t2, t1
|
||||
bltz t2, time_wait
|
||||
|
||||
/* Check the launch flag */
|
||||
lw t3, LAUNCH_FLAGS(t0)
|
||||
and t3, LAUNCH_FGO
|
||||
beqz t3, start_poll
|
||||
|
||||
/* Reset the counter and interrupts to give naive clients a chance */
|
||||
mfc0 t1, CP0_STATUS
|
||||
ins t1, zero, STATUSB_IP7, 1
|
||||
mtc0 t1, CP0_STATUS
|
||||
|
||||
mfc0 t1, CP0_COUNT
|
||||
subu t1, 1
|
||||
mtc0 t1, CP0_COMPARE
|
||||
|
||||
/* Jump to kernel */
|
||||
lw t9, LAUNCH_PC(t0)
|
||||
lw gp, LAUNCH_GP(t0)
|
||||
lw sp, LAUNCH_SP(t0)
|
||||
lw a0, LAUNCH_A0(t0)
|
||||
move a1, zero
|
||||
move a2, zero
|
||||
move a3, zero
|
||||
ori t3, LAUNCH_FGONE
|
||||
sw t3, LAUNCH_FLAGS(t0)
|
||||
|
||||
jr t9
|
||||
|
||||
.globl launch_wait_code_end
|
||||
launch_wait_code_end:
|
||||
END(launch_wait_code)
|
||||
|
||||
/*
|
||||
* Core1 will go here.
|
||||
*/
|
||||
LEAF(launch_core_entry)
|
||||
/* Disable caches */
|
||||
bal mips_cache_disable
|
||||
|
||||
/* Initialize L1 cache only */
|
||||
li a0, CONFIG_SYS_ICACHE_SIZE
|
||||
li a1, CONFIG_SYS_ICACHE_LINE_SIZE
|
||||
li a2, CONFIG_SYS_DCACHE_SIZE
|
||||
li a3, CONFIG_SYS_DCACHE_LINE_SIZE
|
||||
|
||||
mtc0 zero, CP0_TAGLO
|
||||
mtc0 zero, CP0_TAGLO, 2
|
||||
ehb
|
||||
|
||||
/*
|
||||
* Initialize the I-cache first,
|
||||
*/
|
||||
li t0, KSEG0
|
||||
addu t1, t0, a0
|
||||
/* clear tag to invalidate */
|
||||
cache_loop t0, t1, a1, INDEX_STORE_TAG_I
|
||||
#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
/* fill once, so data field parity is correct */
|
||||
PTR_LI t0, KSEG0
|
||||
cache_loop t0, t1, a1, FILL
|
||||
/* invalidate again - prudent but not strictly necessary */
|
||||
PTR_LI t0, KSEG0
|
||||
cache_loop t0, t1, a1, INDEX_STORE_TAG_I
|
||||
#endif
|
||||
|
||||
/*
|
||||
* then initialize D-cache.
|
||||
*/
|
||||
PTR_LI t0, KSEG0
|
||||
PTR_ADDU t1, t0, a2
|
||||
/* clear all tags */
|
||||
cache_loop t0, t1, a3, INDEX_STORE_TAG_D
|
||||
#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
/* load from each line (in cached space) */
|
||||
PTR_LI t0, KSEG0
|
||||
2: LONG_L zero, 0(t0)
|
||||
PTR_ADDU t0, a3
|
||||
bne t0, t1, 2b
|
||||
/* clear all tags */
|
||||
PTR_LI t0, KSEG0
|
||||
cache_loop t0, t1, a3, INDEX_STORE_TAG_D
|
||||
#endif
|
||||
|
||||
/* Set Cache Mode */
|
||||
mfc0 t0, CP0_CONFIG
|
||||
li t1, CONF_CM_CACHABLE_COW
|
||||
ins t0, t1, 0, 3
|
||||
mtc0 t0, CP0_CONFIG
|
||||
|
||||
/* Join the coherent domain */
|
||||
li a0, 2
|
||||
bal join_coherent_domain
|
||||
|
||||
/* Bootup Core0/VPE1 */
|
||||
bal boot_vpe1
|
||||
|
||||
b launch_vpe_entry
|
||||
END(launch_core_entry)
|
||||
|
||||
/*
|
||||
* Bootup VPE1.
|
||||
* This subroutine must be executed from VPE0 with VPECONF0[MVP] already set.
|
||||
*/
|
||||
LEAF(boot_vpe1)
|
||||
mfc0 t0, CP0_MVPCONF0
|
||||
|
||||
/* a0 = number of TCs - 1 */
|
||||
ext a0, t0, MVPCONF0_PTC_SHIFT, 8
|
||||
beqz a0, _vpe1_init_done
|
||||
|
||||
/* a1 = number of VPEs - 1 */
|
||||
ext a1, t0, MVPCONF0_PVPE_SHIFT, 4
|
||||
beqz a1, _vpe1_init_done
|
||||
|
||||
/* a2 = current TC No. */
|
||||
move a2, zero
|
||||
|
||||
/* Enter VPE Configuration State */
|
||||
mfc0 t0, CP0_MVPCONTROL
|
||||
or t0, MVPCONTROL_VPC
|
||||
mtc0 t0, CP0_MVPCONTROL
|
||||
ehb
|
||||
|
||||
_next_tc:
|
||||
/* Set the TC number to be used on MTTR and MFTR instructions */
|
||||
mfc0 t0, CP0_VPECONTROL
|
||||
ins t0, a2, 0, 8
|
||||
mtc0 t0, CP0_VPECONTROL
|
||||
ehb
|
||||
|
||||
/* TC0 is already bound */
|
||||
beqz a2, _next_vpe
|
||||
|
||||
/* Halt current TC */
|
||||
li t0, TCHALT_H
|
||||
mttc0 t0, CP0_TCHALT
|
||||
ehb
|
||||
|
||||
/* If there is spare TC, bind it to the last VPE (VPE[a1]) */
|
||||
slt t1, a1, a2
|
||||
bnez t1, _vpe_bind_tc
|
||||
move t1, a1
|
||||
|
||||
/* Set Exclusive TC for active TC */
|
||||
mftc0 t0, CP0_VPECONF0
|
||||
ins t0, a2, VPECONF0_XTC_SHIFT, 8
|
||||
mttc0 t0, CP0_VPECONF0
|
||||
|
||||
move t1, a2
|
||||
_vpe_bind_tc:
|
||||
/* Bind TC to a VPE */
|
||||
mftc0 t0, CP0_TCBIND
|
||||
ins t0, t1, TCBIND_CURVPE_SHIFT, 4
|
||||
mttc0 t0, CP0_TCBIND
|
||||
|
||||
/*
|
||||
* Set up CP0_TCSTATUS register:
|
||||
* Disable Coprocessor Usable bits
|
||||
* Disable MDMX/DSP ASE
|
||||
* Clear Dirty TC
|
||||
* not dynamically allocatable
|
||||
* not allocated
|
||||
* Kernel mode
|
||||
* interrupt exempt
|
||||
* ASID 0
|
||||
*/
|
||||
li t0, TCSTATUS_IXMT
|
||||
mttc0 t0, CP0_TCSTATUS
|
||||
|
||||
_next_vpe:
|
||||
slt t1, a1, a2
|
||||
bnez t1, _done_vpe # No more VPEs
|
||||
|
||||
/* Disable TC multi-threading */
|
||||
mftc0 t0, CP0_VPECONTROL
|
||||
ins t0, zero, VPECONTROL_TE_SHIFT, 1
|
||||
mttc0 t0, CP0_VPECONTROL
|
||||
|
||||
/* Skip following configuration for TC0 */
|
||||
beqz a2, _done_vpe
|
||||
|
||||
/* Deactivate VPE, set Master VPE */
|
||||
mftc0 t0, CP0_VPECONF0
|
||||
ins t0, zero, VPECONF0_VPA_SHIFT, 1
|
||||
or t0, VPECONF0_MVP
|
||||
mttc0 t0, CP0_VPECONF0
|
||||
|
||||
mfc0 t0, CP0_STATUS
|
||||
mttc0 t0, CP0_STATUS
|
||||
|
||||
mttc0 zero, CP0_EPC
|
||||
mttc0 zero, CP0_CAUSE
|
||||
|
||||
mfc0 t0, CP0_CONFIG
|
||||
mttc0 t0, CP0_CONFIG
|
||||
|
||||
/*
|
||||
* VPE1 of each core can execute cached as its L1 I$ has already
|
||||
* been initialized.
|
||||
* and the L2$ has been initialized or "disabled" via CCA override.
|
||||
*/
|
||||
PTR_LA t0, _start
|
||||
mttc0 t0, CP0_TCRESTART
|
||||
|
||||
/* Unset Interrupt Exempt, set Activate Thread */
|
||||
mftc0 t0, CP0_TCSTATUS
|
||||
ins t0, zero, TCSTATUS_IXMT_SHIFT, 1
|
||||
ori t0, TCSTATUS_A
|
||||
mttc0 t0, CP0_TCSTATUS
|
||||
|
||||
/* Resume TC */
|
||||
mttc0 zero, CP0_TCHALT
|
||||
|
||||
/* Activate VPE */
|
||||
mftc0 t0, CP0_VPECONF0
|
||||
ori t0, VPECONF0_VPA
|
||||
mttc0 t0, CP0_VPECONF0
|
||||
|
||||
_done_vpe:
|
||||
addu a2, 1
|
||||
sltu t0, a0, a2
|
||||
beqz t0, _next_tc
|
||||
|
||||
mfc0 t0, CP0_MVPCONTROL
|
||||
/* Enable all activated VPE to execute */
|
||||
ori t0, MVPCONTROL_EVP
|
||||
/* Exit VPE Configuration State */
|
||||
ins t0, zero, MVPCONTROL_VPC_SHIFT, 1
|
||||
mtc0 t0, CP0_MVPCONTROL
|
||||
ehb
|
||||
|
||||
_vpe1_init_done:
|
||||
jr ra
|
||||
END(boot_vpe1)
|
||||
24
arch/mips/mach-mtmips/mt7621/spl/serial.c
Normal file
24
arch/mips/mach-mtmips/mt7621/spl/serial.c
Normal file
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include "../mt7621.h"
|
||||
|
||||
void mtmips_spl_serial_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SPL_SERIAL
|
||||
void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
|
||||
|
||||
#if CONFIG_CONS_INDEX == 1
|
||||
clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE);
|
||||
#elif CONFIG_CONS_INDEX == 2
|
||||
clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M);
|
||||
#elif CONFIG_CONS_INDEX == 3
|
||||
clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M);
|
||||
#endif /* CONFIG_CONS_INDEX */
|
||||
#endif /* CONFIG_SPL_SERIAL */
|
||||
}
|
||||
96
arch/mips/mach-mtmips/mt7621/spl/spl.c
Normal file
96
arch/mips/mach-mtmips/mt7621/spl/spl.c
Normal file
@@ -0,0 +1,96 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <init.h>
|
||||
#include <image.h>
|
||||
#include <vsprintf.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/types.h>
|
||||
#include <mach/serial.h>
|
||||
#include "../mt7621.h"
|
||||
#include "dram.h"
|
||||
#include <spl.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct tpl_info {
|
||||
u32 magic;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
void set_timer_freq_simple(void)
|
||||
{
|
||||
u32 div = get_xtal_mhz();
|
||||
|
||||
/* Round down cpu freq */
|
||||
gd->arch.timer_freq = rounddown(CONFIG_MT7621_CPU_FREQ, div) * 500000;
|
||||
}
|
||||
|
||||
void __noreturn board_init_f(ulong dummy)
|
||||
{
|
||||
spl_init();
|
||||
|
||||
#ifdef CONFIG_SPL_SERIAL
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
#ifdef CONFIG_MT7621_BOOT_FROM_NAND
|
||||
spl_boot_list[0] = BOOT_DEVICE_NAND;
|
||||
#else
|
||||
spl_boot_list[0] = BOOT_DEVICE_NOR;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long spl_nor_get_uboot_base(void)
|
||||
{
|
||||
const struct tpl_info *tpli;
|
||||
const image_header_t *hdr;
|
||||
u32 addr;
|
||||
|
||||
addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET;
|
||||
tpli = (const struct tpl_info *)KSEG1ADDR(addr);
|
||||
|
||||
if (tpli->magic == TPL_INFO_MAGIC) {
|
||||
addr = FLASH_MMAP_BASE + tpli->size;
|
||||
hdr = (const image_header_t *)KSEG1ADDR(addr);
|
||||
|
||||
if (image_get_magic(hdr) == IH_MAGIC) {
|
||||
addr += sizeof(*hdr) + image_get_size(hdr);
|
||||
return KSEG1ADDR(addr);
|
||||
}
|
||||
}
|
||||
|
||||
panic("Unable to locate SPL payload\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t spl_nand_get_uboot_raw_page(void)
|
||||
{
|
||||
const struct stage_header *sh = (const struct stage_header *)&_start;
|
||||
u32 addr;
|
||||
|
||||
addr = image_get_header_size() + be32_to_cpu(sh->stage_size);
|
||||
addr = ALIGN(addr, SZ_4K);
|
||||
|
||||
return addr;
|
||||
}
|
||||
226
arch/mips/mach-mtmips/mt7621/spl/start.S
Normal file
226
arch/mips/mach-mtmips/mt7621/spl/start.S
Normal file
@@ -0,0 +1,226 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/cacheops.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/mipsmtregs.h>
|
||||
#include <asm/cm.h>
|
||||
#include "../mt7621.h"
|
||||
#include "dram.h"
|
||||
|
||||
#ifndef CONFIG_SYS_INIT_SP_ADDR
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
|
||||
CONFIG_SYS_INIT_SP_OFFSET)
|
||||
#endif
|
||||
|
||||
#define SP_ADDR_TEMP 0xbe10dff0
|
||||
|
||||
.macro init_wr sel
|
||||
MTC0 zero, CP0_WATCHLO,\sel
|
||||
mtc0 t1, CP0_WATCHHI,\sel
|
||||
.endm
|
||||
|
||||
.macro setup_stack_gd
|
||||
li t0, -16
|
||||
PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
|
||||
and sp, t1, t0 # force 16 byte alignment
|
||||
PTR_SUBU \
|
||||
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) && \
|
||||
!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
|
||||
and sp, sp, t0 # force 16 byte alignment
|
||||
#endif
|
||||
move fp, sp
|
||||
|
||||
/* Clear gd */
|
||||
move t0, k0
|
||||
1:
|
||||
PTR_S zero, 0(t0)
|
||||
PTR_ADDIU t0, PTRSIZE
|
||||
blt t0, t1, 1b
|
||||
nop
|
||||
|
||||
#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
|
||||
|
||||
.set noreorder
|
||||
|
||||
ENTRY(_start)
|
||||
b 1f
|
||||
mtc0 zero, CP0_COUNT
|
||||
|
||||
/* Stage header required by BootROM */
|
||||
.org 0x8
|
||||
.word 0 # ep, filled by mkimage
|
||||
.word 0 # stage_size, filled by mkimage
|
||||
.word 0 # has_stage2
|
||||
.word 0 # next_ep
|
||||
.word 0 # next_size
|
||||
.word 0 # next_offset
|
||||
|
||||
1:
|
||||
/* Init CP0 Status */
|
||||
mfc0 t0, CP0_STATUS
|
||||
and t0, ST0_IMPL
|
||||
or t0, ST0_BEV | ST0_ERL
|
||||
mtc0 t0, CP0_STATUS
|
||||
ehb
|
||||
|
||||
/* Clear Watch Status bits and disable watch exceptions */
|
||||
li t1, 0x7 # Clear I, R and W conditions
|
||||
init_wr 0
|
||||
init_wr 1
|
||||
init_wr 2
|
||||
init_wr 3
|
||||
|
||||
/* Clear WP, IV and SW interrupts */
|
||||
mtc0 zero, CP0_CAUSE
|
||||
|
||||
/* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
|
||||
mtc0 zero, CP0_COMPARE
|
||||
|
||||
/* VPE1 goes to wait code directly */
|
||||
mfc0 t0, CP0_TCBIND
|
||||
andi t0, TCBIND_CURVPE
|
||||
bnez t0, launch_vpe_entry
|
||||
nop
|
||||
|
||||
/* Core1 goes to specific launch entry */
|
||||
PTR_LI t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
|
||||
lw t1, GCR_Cx_ID(t0)
|
||||
bnez t1, launch_core_entry
|
||||
nop
|
||||
|
||||
/* MT7530 reset */
|
||||
li t0, KSEG1ADDR(SYSCTL_BASE)
|
||||
lw t1, SYSCTL_RSTCTL_REG(t0)
|
||||
ori t1, MCM_RST
|
||||
sw t1, SYSCTL_RSTCTL_REG(t0)
|
||||
|
||||
/* Disable DMA route for PSE SRAM set by BootROM */
|
||||
PTR_LI t0, KSEG1ADDR(DMA_CFG_ARB_BASE)
|
||||
sw zero, DMA_ROUTE_REG(t0)
|
||||
|
||||
/* Set CPU clock to 500MHz (Required if boot from NAND) */
|
||||
li t0, KSEG1ADDR(SYSCTL_BASE)
|
||||
lw t1, SYSCTL_CLKCFG0_REG(t0)
|
||||
ins t1, zero, 30, 2 # CPU_CLK_SEL
|
||||
sw t1, SYSCTL_CLKCFG0_REG(t0)
|
||||
|
||||
/* Set CPU clock divider to 1/1 */
|
||||
li t0, KSEG1ADDR(RBUS_BASE)
|
||||
li t1, 0x101
|
||||
sw t1, RBUS_DYN_CFG0_REG(t0)
|
||||
|
||||
/* (Re-)initialize the SRAM */
|
||||
bal mips_sram_init
|
||||
nop
|
||||
|
||||
/* Set up temporary stack */
|
||||
li sp, SP_ADDR_TEMP
|
||||
|
||||
/* Setup full CPS */
|
||||
bal mips_cm_map
|
||||
nop
|
||||
|
||||
bal mt7621_cps_init
|
||||
nop
|
||||
|
||||
/* Prepare for CPU/DDR initialization binary blob */
|
||||
bal prepare_stage_bin
|
||||
nop
|
||||
|
||||
/* Call CPU/DDR initialization binary blob */
|
||||
li t9, STAGE_LOAD_ADDR
|
||||
jalr t9
|
||||
nop
|
||||
|
||||
/* Switch CPU PLL source */
|
||||
li t0, KSEG1ADDR(SYSCTL_BASE)
|
||||
lw t1, SYSCTL_CLKCFG0_REG(t0)
|
||||
li t2, 1
|
||||
ins t1, t2, CPU_CLK_SEL_S, 2
|
||||
sw t1, SYSCTL_CLKCFG0_REG(t0)
|
||||
|
||||
/*
|
||||
* Currently SPL is running on locked L2 cache (on KSEG0).
|
||||
* To reset the entire cache, we have to writeback SPL to DRAM first.
|
||||
* Cache flush won't work here. Use memcpy instead.
|
||||
*/
|
||||
|
||||
la a0, __text_start
|
||||
move a1, a0
|
||||
la a2, __image_copy_end
|
||||
sub a2, a2, a1
|
||||
li a3, 5
|
||||
ins a0, a3, 29, 3 # convert to KSEG1
|
||||
|
||||
bal memcpy
|
||||
nop
|
||||
|
||||
/* Disable caches */
|
||||
bal mips_cache_disable
|
||||
nop
|
||||
|
||||
/* Reset caches */
|
||||
bal mips_cache_reset
|
||||
nop
|
||||
|
||||
/* Disable SRAM */
|
||||
li t0, KSEG1ADDR(FE_BASE)
|
||||
li t1, FE_PSE_RESET
|
||||
sw t1, FE_RST_GLO_REG(t0)
|
||||
|
||||
/* Clear the .bss section */
|
||||
la a0, __bss_start
|
||||
la a1, __bss_end
|
||||
1: sw zero, 0(a0)
|
||||
addiu a0, 4
|
||||
ble a0, a1, 1b
|
||||
nop
|
||||
|
||||
/* Set up initial stack and global data */
|
||||
setup_stack_gd
|
||||
|
||||
#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
|
||||
|
||||
#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_SPL_SERIAL)
|
||||
/* Earliest point to set up debug uart */
|
||||
bal debug_uart_init
|
||||
nop
|
||||
#endif
|
||||
|
||||
/* Setup timer */
|
||||
bal set_timer_freq_simple
|
||||
nop
|
||||
|
||||
/* Bootup secondary CPUs */
|
||||
bal secondary_cpu_init
|
||||
nop
|
||||
|
||||
move a0, zero # a0 <-- boot_flags = 0
|
||||
bal board_init_f
|
||||
move ra, zero
|
||||
|
||||
END(_start)
|
||||
22
arch/mips/mach-mtmips/mt7621/sram_init.S
Normal file
22
arch/mips/mach-mtmips/mt7621/sram_init.S
Normal file
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include "mt7621.h"
|
||||
|
||||
LEAF(mips_sram_init)
|
||||
li t0, KSEG1ADDR(FE_BASE)
|
||||
li t1, FE_PSE_RESET
|
||||
sw t1, FE_RST_GLO_REG(t0)
|
||||
|
||||
li t1, (FE_PSE_RAM | FE_PSE_MEM_EN)
|
||||
sw t1, FE_RST_GLO_REG(t0)
|
||||
|
||||
jr ra
|
||||
END(mips_sram_init)
|
||||
4
arch/mips/mach-mtmips/mt7621/tpl/Makefile
Normal file
4
arch/mips/mach-mtmips/mt7621/tpl/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
extra-y += start.o
|
||||
|
||||
obj-y += tpl.o
|
||||
161
arch/mips/mach-mtmips/mt7621/tpl/start.S
Normal file
161
arch/mips/mach-mtmips/mt7621/tpl/start.S
Normal file
@@ -0,0 +1,161 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/cm.h>
|
||||
#include "../mt7621.h"
|
||||
|
||||
#define SP_ADDR_TEMP 0xbe10dff0
|
||||
|
||||
.set noreorder
|
||||
|
||||
.macro init_wr sel
|
||||
MTC0 zero, CP0_WATCHLO,\sel
|
||||
mtc0 t1, CP0_WATCHHI,\sel
|
||||
.endm
|
||||
|
||||
.macro uhi_mips_exception
|
||||
move k0, t9 # preserve t9 in k0
|
||||
move k1, a0 # preserve a0 in k1
|
||||
li t9, 15 # UHI exception operation
|
||||
li a0, 0 # Use hard register context
|
||||
sdbbp 1 # Invoke UHI operation
|
||||
.endm
|
||||
|
||||
ENTRY(_start)
|
||||
b reset
|
||||
mtc0 zero, CP0_COUNT
|
||||
|
||||
/*
|
||||
* Store TPL size here.
|
||||
* This will be used by SPL to locate u-boot payload.
|
||||
*/
|
||||
.org TPL_INFO_OFFSET
|
||||
.word TPL_INFO_MAGIC
|
||||
.word __image_copy_len
|
||||
|
||||
/* Exception vector */
|
||||
.org 0x200
|
||||
/* TLB refill, 32 bit task */
|
||||
uhi_mips_exception
|
||||
|
||||
.org 0x280
|
||||
/* XTLB refill, 64 bit task */
|
||||
uhi_mips_exception
|
||||
|
||||
.org 0x300
|
||||
/* Cache error exception */
|
||||
uhi_mips_exception
|
||||
|
||||
.org 0x380
|
||||
/* General exception */
|
||||
uhi_mips_exception
|
||||
|
||||
.org 0x400
|
||||
/* Catch interrupt exceptions */
|
||||
uhi_mips_exception
|
||||
|
||||
.org 0x480
|
||||
/* EJTAG debug exception */
|
||||
1: b 1b
|
||||
nop
|
||||
|
||||
.org 0x500
|
||||
|
||||
reset:
|
||||
/* Set KSEG0 to Uncached */
|
||||
mfc0 t0, CP0_CONFIG
|
||||
ins t0, zero, 0, 3
|
||||
ori t0, t0, CONF_CM_UNCACHED
|
||||
mtc0 t0, CP0_CONFIG
|
||||
ehb
|
||||
|
||||
/* Check for CPU number */
|
||||
mfc0 t0, CP0_EBASE
|
||||
and t0, t0, MIPS_EBASE_CPUNUM
|
||||
beqz t0, 1f
|
||||
nop
|
||||
|
||||
/* Secondary core goes to specified SPL entry address */
|
||||
li t0, KSEG1ADDR(SYSCTL_BASE)
|
||||
lw t0, BOOT_SRAM_BASE_REG(t0)
|
||||
jr t0
|
||||
nop
|
||||
|
||||
/* Init CP0 Status */
|
||||
1: mfc0 t0, CP0_STATUS
|
||||
and t0, ST0_IMPL
|
||||
or t0, ST0_BEV | ST0_ERL
|
||||
mtc0 t0, CP0_STATUS
|
||||
nop
|
||||
|
||||
/* Clear Watch Status bits and disable watch exceptions */
|
||||
li t1, 0x7 # Clear I, R and W conditions
|
||||
init_wr 0
|
||||
init_wr 1
|
||||
init_wr 2
|
||||
init_wr 3
|
||||
|
||||
/* Clear WP, IV and SW interrupts */
|
||||
mtc0 zero, CP0_CAUSE
|
||||
|
||||
/* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
|
||||
mtc0 zero, CP0_COMPARE
|
||||
|
||||
/* Setup basic CPS */
|
||||
bal mips_cm_map
|
||||
nop
|
||||
|
||||
li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
|
||||
li t1, GCR_REG0_BASE_VALUE
|
||||
sw t1, GCR_REG0_BASE(t0)
|
||||
|
||||
li t1, ((GCR_REG0_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | \
|
||||
GCR_REGn_MASK_CMTGT_IOCU0)
|
||||
sw t1, GCR_REG0_MASK(t0)
|
||||
|
||||
lw t1, GCR_BASE(t0)
|
||||
ins t1, zero, 0, 2 # CM_DEFAULT_TARGET
|
||||
sw t1, GCR_BASE(t0)
|
||||
|
||||
lw t1, GCR_CONTROL(t0)
|
||||
li t2, GCR_CONTROL_SYNCCTL
|
||||
or t1, t1, t2
|
||||
sw t1, GCR_CONTROL(t0)
|
||||
|
||||
/* Increase SPI frequency */
|
||||
li t0, KSEG1ADDR(SPI_BASE)
|
||||
li t1, 5
|
||||
sw t1, SPI_SPACE_REG(t0)
|
||||
|
||||
/* Set CPU clock to 500MHz */
|
||||
li t0, KSEG1ADDR(SYSCTL_BASE)
|
||||
lw t1, SYSCTL_CLKCFG0_REG(t0)
|
||||
ins t1, zero, 30, 2 # CPU_CLK_SEL
|
||||
sw t1, SYSCTL_CLKCFG0_REG(t0)
|
||||
|
||||
/* Set CPU clock divider to 1/1 */
|
||||
li t0, KSEG1ADDR(RBUS_BASE)
|
||||
li t1, 0x101
|
||||
sw t1, RBUS_DYN_CFG0_REG(t0)
|
||||
|
||||
/* Initialize the SRAM */
|
||||
bal mips_sram_init
|
||||
nop
|
||||
|
||||
/* Set up initial stack */
|
||||
li sp, SP_ADDR_TEMP
|
||||
|
||||
bal tpl_main
|
||||
nop
|
||||
|
||||
END(_start)
|
||||
144
arch/mips/mach-mtmips/mt7621/tpl/tpl.c
Normal file
144
arch/mips/mach-mtmips/mt7621/tpl/tpl.c
Normal file
@@ -0,0 +1,144 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <image.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/cacheops.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/cm.h>
|
||||
|
||||
#define INDEX_STORE_DATA_SD 0x0f
|
||||
|
||||
typedef void __noreturn (*image_entry_noargs_t)(void);
|
||||
|
||||
/*
|
||||
* Lock L2 cache and fill data
|
||||
* Assume that data is 4-byte aligned and start_addr/size is 32-byte aligned
|
||||
*/
|
||||
static void fill_lock_l2cache(uintptr_t dataptr, ulong start_addr, ulong size)
|
||||
{
|
||||
ulong slsize = CONFIG_SYS_DCACHE_LINE_SIZE;
|
||||
ulong end_addr = start_addr + size;
|
||||
const u32 *data = (u32 *)dataptr;
|
||||
ulong i, addr;
|
||||
u32 val;
|
||||
|
||||
/* Clear WSC & SPR bit in ErrCtl */
|
||||
val = read_c0_ecc();
|
||||
val &= 0xcfffffff;
|
||||
write_c0_ecc(val);
|
||||
execution_hazard_barrier();
|
||||
|
||||
for (addr = start_addr; addr < end_addr; addr += slsize) {
|
||||
/* Set STagLo to lock cache line */
|
||||
write_c0_staglo((addr & 0x1ffff800) | 0xa0);
|
||||
mips_cache(INDEX_STORE_TAG_SD, (void *)addr);
|
||||
|
||||
/* Fill data */
|
||||
for (i = 0; i < slsize; i += 8) {
|
||||
val = *data++;
|
||||
__write_32bit_c0_register($28, 5, val); /* sdtaglo */
|
||||
val = *data++;
|
||||
__write_32bit_c0_register($29, 5, val); /* sdtaghi */
|
||||
mips_cache(INDEX_STORE_DATA_SD, (void *)(addr + i));
|
||||
}
|
||||
}
|
||||
|
||||
sync();
|
||||
}
|
||||
|
||||
/* A simple function to initialize MT7621's cache */
|
||||
static void mt7621_cache_init(void)
|
||||
{
|
||||
void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE);
|
||||
ulong lsize = CONFIG_SYS_DCACHE_LINE_SIZE;
|
||||
ulong addr;
|
||||
u32 val;
|
||||
|
||||
/* Enable CCA override. Set to uncached */
|
||||
val = readl(cm_base + GCR_BASE);
|
||||
val &= ~CCA_DEFAULT_OVR_MASK;
|
||||
val |= CCA_DEFAULT_OVREN | (2 << CCA_DEFAULT_OVR_SHIFT);
|
||||
writel(val, cm_base + GCR_BASE);
|
||||
|
||||
/* Initialize L1 I-Cache */
|
||||
write_c0_taglo(0);
|
||||
write_c0_taghi(0);
|
||||
|
||||
for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize)
|
||||
mips_cache(INDEX_STORE_TAG_I, (void *)addr);
|
||||
|
||||
/* Initialize L1 D-Cache */
|
||||
write_c0_dtaglo(0);
|
||||
__write_32bit_c0_register($29, 2, 0); /* dtaghi */
|
||||
|
||||
for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize)
|
||||
mips_cache(INDEX_STORE_TAG_D, (void *)addr);
|
||||
|
||||
/* Initialize L2 Cache */
|
||||
write_c0_staglo(0);
|
||||
__write_32bit_c0_register($29, 4, 0); /* staghi */
|
||||
|
||||
for (addr = 0; addr < (256 << 10); addr += lsize)
|
||||
mips_cache(INDEX_STORE_TAG_SD, (void *)addr);
|
||||
|
||||
/* Dsiable CCA override */
|
||||
val = readl(cm_base + GCR_BASE);
|
||||
val &= ~(CCA_DEFAULT_OVR_MASK | CCA_DEFAULT_OVREN);
|
||||
writel(val, cm_base + GCR_BASE);
|
||||
|
||||
/* Set KSEG0 to non-coherent cached (important!) */
|
||||
val = read_c0_config();
|
||||
val &= ~CONF_CM_CMASK;
|
||||
val |= CONF_CM_CACHABLE_NONCOHERENT;
|
||||
write_c0_config(val);
|
||||
execution_hazard_barrier();
|
||||
|
||||
/* Again, invalidate L1 D-Cache */
|
||||
for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize)
|
||||
mips_cache(INDEX_WRITEBACK_INV_D, (void *)addr);
|
||||
|
||||
/* Invalidate L1 I-Cache */
|
||||
for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize)
|
||||
mips_cache(INDEX_INVALIDATE_I, (void *)addr);
|
||||
|
||||
/* Disable L2 cache bypass */
|
||||
val = read_c0_config2();
|
||||
val &= ~MIPS_CONF_IMPL;
|
||||
write_c0_config2(val);
|
||||
execution_hazard_barrier();
|
||||
}
|
||||
|
||||
void __noreturn tpl_main(void)
|
||||
{
|
||||
const image_header_t *hdr = (const image_header_t *)__image_copy_end;
|
||||
image_entry_noargs_t image_entry;
|
||||
u32 loadaddr, size;
|
||||
uintptr_t data;
|
||||
|
||||
/* Initialize the cache first */
|
||||
mt7621_cache_init();
|
||||
|
||||
if (image_get_magic(hdr) != IH_MAGIC)
|
||||
goto failed;
|
||||
|
||||
loadaddr = image_get_load(hdr);
|
||||
size = image_get_size(hdr);
|
||||
image_entry = (image_entry_noargs_t)image_get_ep(hdr);
|
||||
|
||||
/* Load TPL image to L2 cache */
|
||||
data = (uintptr_t)__image_copy_end + sizeof(struct image_header);
|
||||
fill_lock_l2cache(data, loadaddr, size);
|
||||
|
||||
/* Jump to SPL */
|
||||
image_entry();
|
||||
|
||||
failed:
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
8
board/mediatek/mt7621/MAINTAINERS
Normal file
8
board/mediatek/mt7621/MAINTAINERS
Normal file
@@ -0,0 +1,8 @@
|
||||
MT7621_RFB BOARD
|
||||
M: Weijie Gao <weijie.gao@mediatek.com>
|
||||
S: Maintained
|
||||
F: board/mediatek/mt7621
|
||||
F: configs/mt7621_rfb_defconfig
|
||||
F: configs/mt7621_nand_rfb_defconfig
|
||||
F: arch/mips/dts/mediatek,mt7621-rfb.dts
|
||||
F: arch/mips/dts/mediatek,mt7621-nand-rfb.dts
|
||||
3
board/mediatek/mt7621/Makefile
Normal file
3
board/mediatek/mt7621/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-y += board.o
|
||||
6
board/mediatek/mt7621/board.c
Normal file
6
board/mediatek/mt7621/board.c
Normal file
@@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
@@ -884,7 +884,7 @@ config SPL_NAND_SIMPLE
|
||||
expose the cmd_ctrl() interface.
|
||||
|
||||
config SPL_NAND_BASE
|
||||
depends on SPL_NAND_DRIVERS
|
||||
depends on SPL_NAND_SUPPORT
|
||||
bool "Use Base NAND Driver"
|
||||
help
|
||||
Include nand_base.c in the SPL.
|
||||
|
||||
@@ -88,15 +88,29 @@ int spl_load_legacy_img(struct spl_image_info *spl_image,
|
||||
/* Read header into local struct */
|
||||
load->read(load, header, sizeof(hdr), &hdr);
|
||||
|
||||
/*
|
||||
* If the payload is compressed, the decompressed data should be
|
||||
* directly write to its load address.
|
||||
*/
|
||||
if (spl_image_get_comp(&hdr) != IH_COMP_NONE)
|
||||
spl_image->flags |= SPL_COPY_PAYLOAD_ONLY;
|
||||
|
||||
ret = spl_parse_image_header(spl_image, bootdev, &hdr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dataptr = header + sizeof(hdr);
|
||||
|
||||
/* Read image */
|
||||
switch (spl_image_get_comp(&hdr)) {
|
||||
case IH_COMP_NONE:
|
||||
dataptr = header;
|
||||
|
||||
/*
|
||||
* Image header will be skipped only if SPL_COPY_PAYLOAD_ONLY
|
||||
* is set
|
||||
*/
|
||||
if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY)
|
||||
dataptr += sizeof(hdr);
|
||||
|
||||
load->read(load, dataptr, spl_image->size,
|
||||
(void *)(unsigned long)spl_image->load_addr);
|
||||
break;
|
||||
@@ -104,6 +118,9 @@ int spl_load_legacy_img(struct spl_image_info *spl_image,
|
||||
case IH_COMP_LZMA:
|
||||
lzma_len = LZMA_LEN;
|
||||
|
||||
/* dataptr points to compressed payload */
|
||||
dataptr = header + sizeof(hdr);
|
||||
|
||||
debug("LZMA: Decompressing %08lx to %08lx\n",
|
||||
dataptr, spl_image->load_addr);
|
||||
src = malloc(spl_image->size);
|
||||
|
||||
@@ -56,6 +56,21 @@ static ulong spl_nand_fit_read(struct spl_load_info *load, ulong offs,
|
||||
return size / load->bl_len;
|
||||
}
|
||||
|
||||
static ulong spl_nand_legacy_read(struct spl_load_info *load, ulong offs,
|
||||
ulong size, void *dst)
|
||||
{
|
||||
int err;
|
||||
|
||||
debug("%s: offs %lx, size %lx, dst %p\n",
|
||||
__func__, offs, size, dst);
|
||||
|
||||
err = nand_spl_load_image(offs, size, dst);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
struct mtd_info * __weak nand_get_mtd(void)
|
||||
{
|
||||
return NULL;
|
||||
@@ -93,6 +108,18 @@ static int spl_nand_load_element(struct spl_image_info *spl_image,
|
||||
load.bl_len = bl_len;
|
||||
load.read = spl_nand_fit_read;
|
||||
return spl_load_imx_container(spl_image, &load, offset / bl_len);
|
||||
} else if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_FORMAT) &&
|
||||
image_get_magic(header) == IH_MAGIC) {
|
||||
struct spl_load_info load;
|
||||
|
||||
debug("Found legacy image\n");
|
||||
load.dev = NULL;
|
||||
load.priv = NULL;
|
||||
load.filename = NULL;
|
||||
load.bl_len = 1;
|
||||
load.read = spl_nand_legacy_read;
|
||||
|
||||
return spl_load_legacy_img(spl_image, bootdev, &load, offset);
|
||||
} else {
|
||||
err = spl_parse_image_header(spl_image, bootdev, header);
|
||||
if (err)
|
||||
|
||||
89
configs/mt7621_nand_rfb_defconfig
Normal file
89
configs/mt7621_nand_rfb_defconfig
Normal file
@@ -0,0 +1,89 @@
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_SYS_MALLOC_LEN=0x100000
|
||||
CONFIG_SPL_LIBCOMMON_SUPPORT=y
|
||||
CONFIG_SPL_LIBGENERIC_SUPPORT=y
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_ENV_SIZE=0x1000
|
||||
CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7621-nand-rfb"
|
||||
CONFIG_SPL_SERIAL=y
|
||||
CONFIG_SPL_SYS_MALLOC_F_LEN=0x100000
|
||||
CONFIG_SPL=y
|
||||
CONFIG_DEBUG_UART_BASE=0xbe000c00
|
||||
CONFIG_DEBUG_UART_CLOCK=50000000
|
||||
CONFIG_SYS_LOAD_ADDR=0x83000000
|
||||
CONFIG_ARCH_MTMIPS=y
|
||||
CONFIG_SOC_MT7621=y
|
||||
CONFIG_MT7621_BOOT_FROM_NAND=y
|
||||
CONFIG_BOARD_MT7621_NAND_RFB=y
|
||||
# CONFIG_MIPS_CACHE_SETUP is not set
|
||||
# CONFIG_MIPS_CACHE_DISABLE is not set
|
||||
CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
|
||||
CONFIG_MIPS_BOOT_FDT=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_FIT=y
|
||||
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
CONFIG_SPL_MAX_SIZE=0x30000
|
||||
CONFIG_SPL_BSS_START_ADDR=0x80140000
|
||||
CONFIG_SPL_BSS_MAX_SIZE=0x80000
|
||||
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
||||
CONFIG_SPL_NAND_SUPPORT=y
|
||||
CONFIG_SPL_NAND_BASE=y
|
||||
CONFIG_SPL_NAND_IDENT=y
|
||||
# CONFIG_BOOTM_NETBSD is not set
|
||||
# CONFIG_BOOTM_PLAN9 is not set
|
||||
# CONFIG_BOOTM_RTEMS is not set
|
||||
# CONFIG_BOOTM_VXWORKS is not set
|
||||
CONFIG_SYS_BOOTM_LEN=0x2000000
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
# CONFIG_CMD_CRC32 is not set
|
||||
# CONFIG_CMD_DM is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_GPIO=y
|
||||
# CONFIG_CMD_LOADS is not set
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_PART=y
|
||||
# CONFIG_CMD_PINMUX is not set
|
||||
CONFIG_CMD_USB=y
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_CMD_FS_GENERIC=y
|
||||
# CONFIG_SPL_DOS_PARTITION is not set
|
||||
# CONFIG_ISO_PARTITION is not set
|
||||
CONFIG_EFI_PARTITION=y
|
||||
# CONFIG_SPL_EFI_PARTITION is not set
|
||||
CONFIG_PARTITION_TYPE_GUID=y
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_INPUT is not set
|
||||
CONFIG_MMC=y
|
||||
# CONFIG_MMC_QUIRKS is not set
|
||||
# CONFIG_MMC_HW_PARTITIONING is not set
|
||||
CONFIG_MMC_MTK=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_NAND_MT7621=y
|
||||
CONFIG_SYS_NAND_ONFI_DETECTION=y
|
||||
CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
|
||||
CONFIG_SYS_NAND_U_BOOT_OFFS=0x0
|
||||
CONFIG_MEDIATEK_ETH=y
|
||||
CONFIG_PHY=y
|
||||
CONFIG_PHY_MTK_TPHY=y
|
||||
CONFIG_DEBUG_UART_SHIFT=2
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_SYSRESET_RESETCTL=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_MTK=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_WDT_MT7621=y
|
||||
CONFIG_FAT_WRITE=y
|
||||
# CONFIG_BINMAN_FDT is not set
|
||||
CONFIG_LZMA=y
|
||||
# CONFIG_GZIP is not set
|
||||
CONFIG_SPL_LZMA=y
|
||||
86
configs/mt7621_rfb_defconfig
Normal file
86
configs/mt7621_rfb_defconfig
Normal file
@@ -0,0 +1,86 @@
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_SYS_MALLOC_LEN=0x100000
|
||||
CONFIG_SPL_LIBCOMMON_SUPPORT=y
|
||||
CONFIG_SPL_LIBGENERIC_SUPPORT=y
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_ENV_SIZE=0x1000
|
||||
CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7621-rfb"
|
||||
CONFIG_SPL_SERIAL=y
|
||||
CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
|
||||
CONFIG_SPL=y
|
||||
CONFIG_DEBUG_UART_BASE=0xbe000c00
|
||||
CONFIG_DEBUG_UART_CLOCK=50000000
|
||||
CONFIG_SYS_LOAD_ADDR=0x83000000
|
||||
CONFIG_ARCH_MTMIPS=y
|
||||
CONFIG_SOC_MT7621=y
|
||||
# CONFIG_MIPS_CACHE_SETUP is not set
|
||||
# CONFIG_MIPS_CACHE_DISABLE is not set
|
||||
CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
|
||||
CONFIG_MIPS_BOOT_FDT=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_TPL_SYS_MALLOC_F_LEN=0x1000
|
||||
CONFIG_FIT=y
|
||||
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
CONFIG_SPL_MAX_SIZE=0x30000
|
||||
CONFIG_SPL_BSS_START_ADDR=0x80140000
|
||||
CONFIG_SPL_BSS_MAX_SIZE=0x80000
|
||||
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
||||
CONFIG_SPL_NOR_SUPPORT=y
|
||||
CONFIG_TPL=y
|
||||
# CONFIG_TPL_FRAMEWORK is not set
|
||||
# CONFIG_BOOTM_NETBSD is not set
|
||||
# CONFIG_BOOTM_PLAN9 is not set
|
||||
# CONFIG_BOOTM_RTEMS is not set
|
||||
# CONFIG_BOOTM_VXWORKS is not set
|
||||
CONFIG_SYS_BOOTM_LEN=0x2000000
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
# CONFIG_CMD_CRC32 is not set
|
||||
# CONFIG_CMD_DM is not set
|
||||
CONFIG_CMD_GPIO=y
|
||||
# CONFIG_CMD_LOADS is not set
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_PART=y
|
||||
# CONFIG_CMD_PINMUX is not set
|
||||
CONFIG_CMD_SPI=y
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_DOS_PARTITION=y
|
||||
# CONFIG_SPL_DOS_PARTITION is not set
|
||||
# CONFIG_ISO_PARTITION is not set
|
||||
CONFIG_EFI_PARTITION=y
|
||||
# CONFIG_SPL_EFI_PARTITION is not set
|
||||
CONFIG_PARTITION_TYPE_GUID=y
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_INPUT is not set
|
||||
CONFIG_MMC=y
|
||||
# CONFIG_MMC_QUIRKS is not set
|
||||
# CONFIG_MMC_HW_PARTITIONING is not set
|
||||
CONFIG_MMC_MTK=y
|
||||
CONFIG_SF_DEFAULT_SPEED=20000000
|
||||
CONFIG_SPI_FLASH_BAR=y
|
||||
CONFIG_SPI_FLASH_EON=y
|
||||
CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
CONFIG_SPI_FLASH_ISSI=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_SPI_FLASH_XMC=y
|
||||
CONFIG_SPI_FLASH_XTX=y
|
||||
CONFIG_MEDIATEK_ETH=y
|
||||
CONFIG_PHY=y
|
||||
CONFIG_PHY_MTK_TPHY=y
|
||||
CONFIG_DEBUG_UART_SHIFT=2
|
||||
CONFIG_SPI=y
|
||||
CONFIG_MT7621_SPI=y
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_SYSRESET_RESETCTL=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_WDT_MT7621=y
|
||||
# CONFIG_BINMAN_FDT is not set
|
||||
CONFIG_LZMA=y
|
||||
# CONFIG_GZIP is not set
|
||||
CONFIG_SPL_LZMA=y
|
||||
@@ -23,6 +23,7 @@ Board-specific doc
|
||||
highbank/index
|
||||
intel/index
|
||||
kontron/index
|
||||
mediatek/index
|
||||
microchip/index
|
||||
nokia/index
|
||||
nxp/index
|
||||
|
||||
9
doc/board/mediatek/index.rst
Normal file
9
doc/board/mediatek/index.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Mediatek
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
mt7621
|
||||
48
doc/board/mediatek/mt7621.rst
Normal file
48
doc/board/mediatek/mt7621.rst
Normal file
@@ -0,0 +1,48 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
mt7621_rfb/mt7621_nand_rfb
|
||||
==========================
|
||||
|
||||
U-Boot for the MediaTek MT7621 boards
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
|
||||
- Get the DDR initialization binary blob
|
||||
- Configure CPU and DDR parameters
|
||||
- Build U-Boot
|
||||
|
||||
Get the DDR initialization binary blob
|
||||
--------------------------------------
|
||||
|
||||
Download one from:
|
||||
- https://raw.githubusercontent.com/mtk-openwrt/mt7621-lowlevel-preloader/master/mt7621_stage_sram.bin
|
||||
- https://raw.githubusercontent.com/mtk-openwrt/mt7621-lowlevel-preloader/master/mt7621_stage_sram_noprint.bin
|
||||
|
||||
mt7621_stage_sram_noprint.bin has removed all output logs. To use this one,
|
||||
download and rename it to mt7621_stage_sram.bin
|
||||
|
||||
Put the binary blob to the u-boot build directory.
|
||||
|
||||
Configure CPU and DDR parameters
|
||||
--------------------------------
|
||||
|
||||
menuconfig > MIPS architecture > MediaTek MIPS platforms > CPU & DDR configuration
|
||||
|
||||
Select the correct DDR timing parameters for your board. The size shown here
|
||||
must match the DDR size of you board.
|
||||
|
||||
The frequency of CPU and DDR can also be adjusted.
|
||||
|
||||
Build U-Boot
|
||||
------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ export CROSS_COMPILE=mipsel-linux-
|
||||
$ make O=build mt7621_rfb_defconfig # or mt7621_nand_rfb_defconfig
|
||||
$ cp mt7621_stage_sram.bin ./build/mt7621_stage_sram.bin
|
||||
$ # or cp mt7621_stage_sram_noprint.bin ./build/mt7621_stage_sram.bin
|
||||
$ make O=build
|
||||
|
||||
Burn the u-boot-mt7621.bin to the SPI-NOR or NAND flash.
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_SOC_MT7620) += clk-mt7620.o
|
||||
obj-$(CONFIG_SOC_MT7621) += clk-mt7621.o
|
||||
obj-$(CONFIG_SOC_MT7628) += clk-mt7628.o
|
||||
|
||||
288
drivers/clk/mtmips/clk-mt7621.c
Normal file
288
drivers/clk/mtmips/clk-mt7621.c
Normal file
@@ -0,0 +1,288 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk-uclass.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <regmap.h>
|
||||
#include <syscon.h>
|
||||
#include <dt-bindings/clock/mt7621-clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
#define SYSC_MAP_SIZE 0x100
|
||||
#define MEMC_MAP_SIZE 0x1000
|
||||
|
||||
/* SYSC */
|
||||
#define SYSCFG0_REG 0x10
|
||||
#define XTAL_MODE_SEL GENMASK(8, 6)
|
||||
|
||||
#define CLKCFG0_REG 0x2c
|
||||
#define CPU_CLK_SEL GENMASK(31, 30)
|
||||
#define PERI_CLK_SEL BIT(4)
|
||||
|
||||
#define CLKCFG1_REG 0x30
|
||||
|
||||
#define CUR_CLK_STS_REG 0x44
|
||||
#define CUR_CPU_FDIV GENMASK(12, 8)
|
||||
#define CUR_CPU_FFRAC GENMASK(4, 0)
|
||||
|
||||
/* MEMC */
|
||||
#define MEMPLL1_REG 0x0604
|
||||
#define RG_MEPL_DIV2_SEL GENMASK(2, 1)
|
||||
|
||||
#define MEMPLL6_REG 0x0618
|
||||
#define MEMPLL18_REG 0x0648
|
||||
#define RG_MEPL_PREDIV GENMASK(13, 12)
|
||||
#define RG_MEPL_FBDIV GENMASK(10, 4)
|
||||
|
||||
/* Fixed 500M clock */
|
||||
#define GMPLL_CLK 500000000
|
||||
|
||||
struct mt7621_clk_priv {
|
||||
void __iomem *sysc_base;
|
||||
int cpu_clk;
|
||||
int ddr_clk;
|
||||
int sys_clk;
|
||||
int xtal_clk;
|
||||
};
|
||||
|
||||
enum mt7621_clk_src {
|
||||
CLK_SRC_CPU,
|
||||
CLK_SRC_DDR,
|
||||
CLK_SRC_SYS,
|
||||
CLK_SRC_XTAL,
|
||||
CLK_SRC_PERI,
|
||||
CLK_SRC_125M,
|
||||
CLK_SRC_150M,
|
||||
CLK_SRC_250M,
|
||||
CLK_SRC_270M,
|
||||
|
||||
__CLK_SRC_MAX
|
||||
};
|
||||
|
||||
struct mt7621_clk_map {
|
||||
u32 cgbit;
|
||||
enum mt7621_clk_src clksrc;
|
||||
};
|
||||
|
||||
#define CLK_MAP(_id, _cg, _src) \
|
||||
[_id] = { .cgbit = (_cg), .clksrc = (_src) }
|
||||
|
||||
#define CLK_MAP_SRC(_id, _src) \
|
||||
[_id] = { .cgbit = UINT32_MAX, .clksrc = (_src) }
|
||||
|
||||
static const struct mt7621_clk_map mt7621_clk_mappings[] = {
|
||||
CLK_MAP_SRC(MT7621_CLK_XTAL, CLK_SRC_XTAL),
|
||||
CLK_MAP_SRC(MT7621_CLK_CPU, CLK_SRC_CPU),
|
||||
CLK_MAP_SRC(MT7621_CLK_BUS, CLK_SRC_SYS),
|
||||
CLK_MAP_SRC(MT7621_CLK_50M, CLK_SRC_PERI),
|
||||
CLK_MAP_SRC(MT7621_CLK_125M, CLK_SRC_125M),
|
||||
CLK_MAP_SRC(MT7621_CLK_150M, CLK_SRC_150M),
|
||||
CLK_MAP_SRC(MT7621_CLK_250M, CLK_SRC_250M),
|
||||
CLK_MAP_SRC(MT7621_CLK_270M, CLK_SRC_270M),
|
||||
|
||||
CLK_MAP(MT7621_CLK_HSDMA, 5, CLK_SRC_150M),
|
||||
CLK_MAP(MT7621_CLK_FE, 6, CLK_SRC_250M),
|
||||
CLK_MAP(MT7621_CLK_SP_DIVTX, 7, CLK_SRC_270M),
|
||||
CLK_MAP(MT7621_CLK_TIMER, 8, CLK_SRC_PERI),
|
||||
CLK_MAP(MT7621_CLK_PCM, 11, CLK_SRC_270M),
|
||||
CLK_MAP(MT7621_CLK_PIO, 13, CLK_SRC_PERI),
|
||||
CLK_MAP(MT7621_CLK_GDMA, 14, CLK_SRC_SYS),
|
||||
CLK_MAP(MT7621_CLK_NAND, 15, CLK_SRC_125M),
|
||||
CLK_MAP(MT7621_CLK_I2C, 16, CLK_SRC_PERI),
|
||||
CLK_MAP(MT7621_CLK_I2S, 17, CLK_SRC_270M),
|
||||
CLK_MAP(MT7621_CLK_SPI, 18, CLK_SRC_SYS),
|
||||
CLK_MAP(MT7621_CLK_UART1, 19, CLK_SRC_PERI),
|
||||
CLK_MAP(MT7621_CLK_UART2, 20, CLK_SRC_PERI),
|
||||
CLK_MAP(MT7621_CLK_UART3, 21, CLK_SRC_PERI),
|
||||
CLK_MAP(MT7621_CLK_ETH, 23, CLK_SRC_PERI),
|
||||
CLK_MAP(MT7621_CLK_PCIE0, 24, CLK_SRC_125M),
|
||||
CLK_MAP(MT7621_CLK_PCIE1, 25, CLK_SRC_125M),
|
||||
CLK_MAP(MT7621_CLK_PCIE2, 26, CLK_SRC_125M),
|
||||
CLK_MAP(MT7621_CLK_CRYPTO, 29, CLK_SRC_250M),
|
||||
CLK_MAP(MT7621_CLK_SHXC, 30, CLK_SRC_PERI),
|
||||
|
||||
CLK_MAP_SRC(MT7621_CLK_MAX, __CLK_SRC_MAX),
|
||||
|
||||
CLK_MAP_SRC(MT7621_CLK_DDR, CLK_SRC_DDR),
|
||||
};
|
||||
|
||||
static ulong mt7621_clk_get_rate(struct clk *clk)
|
||||
{
|
||||
struct mt7621_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
u32 val;
|
||||
|
||||
switch (mt7621_clk_mappings[clk->id].clksrc) {
|
||||
case CLK_SRC_CPU:
|
||||
return priv->cpu_clk;
|
||||
case CLK_SRC_DDR:
|
||||
return priv->ddr_clk;
|
||||
case CLK_SRC_SYS:
|
||||
return priv->sys_clk;
|
||||
case CLK_SRC_XTAL:
|
||||
return priv->xtal_clk;
|
||||
case CLK_SRC_PERI:
|
||||
val = readl(priv->sysc_base + CLKCFG0_REG);
|
||||
if (val & PERI_CLK_SEL)
|
||||
return priv->xtal_clk;
|
||||
else
|
||||
return GMPLL_CLK / 10;
|
||||
case CLK_SRC_125M:
|
||||
return 125000000;
|
||||
case CLK_SRC_150M:
|
||||
return 150000000;
|
||||
case CLK_SRC_250M:
|
||||
return 250000000;
|
||||
case CLK_SRC_270M:
|
||||
return 270000000;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int mt7621_clk_enable(struct clk *clk)
|
||||
{
|
||||
struct mt7621_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
u32 cgbit;
|
||||
|
||||
cgbit = mt7621_clk_mappings[clk->id].cgbit;
|
||||
if (cgbit == UINT32_MAX)
|
||||
return -ENOSYS;
|
||||
|
||||
setbits_32(priv->sysc_base + CLKCFG1_REG, BIT(cgbit));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_clk_disable(struct clk *clk)
|
||||
{
|
||||
struct mt7621_clk_priv *priv = dev_get_priv(clk->dev);
|
||||
u32 cgbit;
|
||||
|
||||
cgbit = mt7621_clk_mappings[clk->id].cgbit;
|
||||
if (cgbit == UINT32_MAX)
|
||||
return -ENOSYS;
|
||||
|
||||
clrbits_32(priv->sysc_base + CLKCFG1_REG, BIT(cgbit));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_clk_request(struct clk *clk)
|
||||
{
|
||||
if (clk->id >= ARRAY_SIZE(mt7621_clk_mappings))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops mt7621_clk_ops = {
|
||||
.request = mt7621_clk_request,
|
||||
.enable = mt7621_clk_enable,
|
||||
.disable = mt7621_clk_disable,
|
||||
.get_rate = mt7621_clk_get_rate,
|
||||
};
|
||||
|
||||
static void mt7621_get_clocks(struct mt7621_clk_priv *priv, struct regmap *memc)
|
||||
{
|
||||
u32 bs, xtal_sel, clkcfg0, cur_clk, mempll, dividx, fb;
|
||||
u32 xtal_clk, xtal_div, ffiv, ffrac, cpu_clk, ddr_clk;
|
||||
static const u32 xtal_div_tbl[] = {0, 1, 2, 2};
|
||||
|
||||
bs = readl(priv->sysc_base + SYSCFG0_REG);
|
||||
clkcfg0 = readl(priv->sysc_base + CLKCFG0_REG);
|
||||
cur_clk = readl(priv->sysc_base + CUR_CLK_STS_REG);
|
||||
|
||||
xtal_sel = FIELD_GET(XTAL_MODE_SEL, bs);
|
||||
|
||||
if (xtal_sel <= 2)
|
||||
xtal_clk = 20 * 1000 * 1000;
|
||||
else if (xtal_sel <= 5)
|
||||
xtal_clk = 40 * 1000 * 1000;
|
||||
else
|
||||
xtal_clk = 25 * 1000 * 1000;
|
||||
|
||||
switch (FIELD_GET(CPU_CLK_SEL, clkcfg0)) {
|
||||
case 0:
|
||||
cpu_clk = GMPLL_CLK;
|
||||
break;
|
||||
case 1:
|
||||
regmap_read(memc, MEMPLL18_REG, &mempll);
|
||||
dividx = FIELD_GET(RG_MEPL_PREDIV, mempll);
|
||||
fb = FIELD_GET(RG_MEPL_FBDIV, mempll);
|
||||
xtal_div = 1 << xtal_div_tbl[dividx];
|
||||
cpu_clk = (fb + 1) * xtal_clk / xtal_div;
|
||||
break;
|
||||
default:
|
||||
cpu_clk = xtal_clk;
|
||||
}
|
||||
|
||||
ffiv = FIELD_GET(CUR_CPU_FDIV, cur_clk);
|
||||
ffrac = FIELD_GET(CUR_CPU_FFRAC, cur_clk);
|
||||
cpu_clk = cpu_clk / ffiv * ffrac;
|
||||
|
||||
regmap_read(memc, MEMPLL6_REG, &mempll);
|
||||
dividx = FIELD_GET(RG_MEPL_PREDIV, mempll);
|
||||
fb = FIELD_GET(RG_MEPL_FBDIV, mempll);
|
||||
xtal_div = 1 << xtal_div_tbl[dividx];
|
||||
ddr_clk = fb * xtal_clk / xtal_div;
|
||||
|
||||
regmap_read(memc, MEMPLL1_REG, &bs);
|
||||
if (!FIELD_GET(RG_MEPL_DIV2_SEL, bs))
|
||||
ddr_clk *= 2;
|
||||
|
||||
priv->cpu_clk = cpu_clk;
|
||||
priv->sys_clk = cpu_clk / 4;
|
||||
priv->ddr_clk = ddr_clk;
|
||||
priv->xtal_clk = xtal_clk;
|
||||
}
|
||||
|
||||
static int mt7621_clk_probe(struct udevice *dev)
|
||||
{
|
||||
struct mt7621_clk_priv *priv = dev_get_priv(dev);
|
||||
struct ofnode_phandle_args args;
|
||||
struct udevice *pdev;
|
||||
struct regmap *memc;
|
||||
int ret;
|
||||
|
||||
pdev = dev_get_parent(dev);
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
||||
priv->sysc_base = dev_remap_addr(pdev);
|
||||
if (!priv->sysc_base)
|
||||
return -EINVAL;
|
||||
|
||||
/* get corresponding memc phandle */
|
||||
ret = dev_read_phandle_with_args(dev, "mediatek,memc", NULL, 0, 0,
|
||||
&args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memc = syscon_node_to_regmap(args.node);
|
||||
if (IS_ERR(memc))
|
||||
return PTR_ERR(memc);
|
||||
|
||||
mt7621_get_clocks(priv, memc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id mt7621_clk_ids[] = {
|
||||
{ .compatible = "mediatek,mt7621-clk" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mt7621_clk) = {
|
||||
.name = "mt7621-clk",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = mt7621_clk_ids,
|
||||
.probe = mt7621_clk_probe,
|
||||
.priv_auto = sizeof(struct mt7621_clk_priv),
|
||||
.ops = &mt7621_clk_ops,
|
||||
};
|
||||
@@ -553,7 +553,7 @@ config MT7620_GPIO
|
||||
|
||||
config MT7621_GPIO
|
||||
bool "MediaTek MT7621 GPIO driver"
|
||||
depends on DM_GPIO && SOC_MT7628
|
||||
depends on DM_GPIO && (SOC_MT7621 || SOC_MT7628)
|
||||
default y
|
||||
help
|
||||
Say yes here to support MediaTek MT7621 compatible GPIOs.
|
||||
|
||||
@@ -1761,6 +1761,18 @@ static const struct msdc_compatible mt7620_compat = {
|
||||
.default_pad_dly = true,
|
||||
};
|
||||
|
||||
static const struct msdc_compatible mt7621_compat = {
|
||||
.clk_div_bits = 8,
|
||||
.pad_tune0 = false,
|
||||
.async_fifo = true,
|
||||
.data_tune = true,
|
||||
.busy_check = false,
|
||||
.stop_clk_fix = false,
|
||||
.enhance_rx = false,
|
||||
.builtin_pad_ctrl = true,
|
||||
.default_pad_dly = true,
|
||||
};
|
||||
|
||||
static const struct msdc_compatible mt7622_compat = {
|
||||
.clk_div_bits = 12,
|
||||
.pad_tune0 = true,
|
||||
@@ -1809,6 +1821,7 @@ static const struct msdc_compatible mt8183_compat = {
|
||||
|
||||
static const struct udevice_id msdc_ids[] = {
|
||||
{ .compatible = "mediatek,mt7620-mmc", .data = (ulong)&mt7620_compat },
|
||||
{ .compatible = "mediatek,mt7621-mmc", .data = (ulong)&mt7621_compat },
|
||||
{ .compatible = "mediatek,mt7622-mmc", .data = (ulong)&mt7622_compat },
|
||||
{ .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat },
|
||||
{ .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat },
|
||||
|
||||
@@ -526,12 +526,25 @@ config TEGRA_NAND
|
||||
help
|
||||
Enables support for NAND Flash chips on Tegra SoCs platforms.
|
||||
|
||||
config NAND_MT7621
|
||||
bool "Support for MediaTek MT7621 NAND flash controller"
|
||||
depends on SOC_MT7621
|
||||
select SYS_NAND_SELF_INIT
|
||||
select SPL_SYS_NAND_SELF_INIT
|
||||
imply CMD_NAND
|
||||
help
|
||||
This enables NAND driver for the NAND flash controller on MediaTek
|
||||
MT7621 platform.
|
||||
The controller supports 4~12 bits correction per 512 bytes with a
|
||||
maximum 4KB page size.
|
||||
|
||||
comment "Generic NAND options"
|
||||
|
||||
config SYS_NAND_BLOCK_SIZE
|
||||
hex "NAND chip eraseblock size"
|
||||
depends on ARCH_SUNXI || SPL_NAND_SUPPORT || TPL_NAND_SUPPORT
|
||||
depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && !NAND_FSL_IFC
|
||||
depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && \
|
||||
!NAND_FSL_IFC && !NAND_MT7621
|
||||
help
|
||||
Number of data bytes in one eraseblock for the NAND chip on the
|
||||
board. This is the multiple of NAND_PAGE_SIZE and the number of
|
||||
@@ -556,7 +569,7 @@ config SYS_NAND_PAGE_SIZE
|
||||
depends on ARCH_SUNXI || NAND_OMAP_GPMC || NAND_LPC32XX_SLC || \
|
||||
SPL_NAND_SIMPLE || (NAND_MXC && SPL_NAND_SUPPORT) || \
|
||||
(NAND_ATMEL && SPL_NAND_SUPPORT) || SPL_GENERATE_ATMEL_PMECC_HEADER
|
||||
depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC
|
||||
depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && !NAND_MT7621
|
||||
help
|
||||
Number of data bytes in one page for the NAND chip on the
|
||||
board, not including the OOB area.
|
||||
|
||||
@@ -72,6 +72,7 @@ obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o
|
||||
obj-$(CONFIG_NAND_STM32_FMC2) += stm32_fmc2_nand.o
|
||||
obj-$(CONFIG_CORTINA_NAND) += cortina_nand.o
|
||||
obj-$(CONFIG_ROCKCHIP_NAND) += rockchip_nfc.o
|
||||
obj-$(CONFIG_NAND_MT7621) += mt7621_nand.o
|
||||
|
||||
else # minimal SPL drivers
|
||||
|
||||
@@ -80,5 +81,6 @@ obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
|
||||
obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
|
||||
obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
|
||||
obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o
|
||||
obj-$(CONFIG_NAND_MT7621) += mt7621_nand_spl.o mt7621_nand.o
|
||||
|
||||
endif # drivers
|
||||
|
||||
1205
drivers/mtd/nand/raw/mt7621_nand.c
Normal file
1205
drivers/mtd/nand/raw/mt7621_nand.c
Normal file
File diff suppressed because it is too large
Load Diff
29
drivers/mtd/nand/raw/mt7621_nand.h
Normal file
29
drivers/mtd/nand/raw/mt7621_nand.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT7621_NAND_H_
|
||||
#define _MT7621_NAND_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/mtd/rawnand.h>
|
||||
|
||||
struct mt7621_nfc {
|
||||
struct nand_chip nand;
|
||||
|
||||
void __iomem *nfi_regs;
|
||||
void __iomem *ecc_regs;
|
||||
|
||||
u32 spare_per_sector;
|
||||
};
|
||||
|
||||
/* for SPL */
|
||||
void mt7621_nfc_spl_init(struct mt7621_nfc *nfc);
|
||||
int mt7621_nfc_spl_post_init(struct mt7621_nfc *nfc);
|
||||
|
||||
#endif /* _MT7621_NAND_H_ */
|
||||
237
drivers/mtd/nand/raw/mt7621_nand_spl.c
Normal file
237
drivers/mtd/nand/raw/mt7621_nand_spl.c
Normal file
@@ -0,0 +1,237 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <image.h>
|
||||
#include <malloc.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mtd/rawnand.h>
|
||||
#include "mt7621_nand.h"
|
||||
|
||||
static struct mt7621_nfc nfc_dev;
|
||||
static u8 *buffer;
|
||||
static int nand_valid;
|
||||
|
||||
static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
|
||||
int column, int page_addr)
|
||||
{
|
||||
register struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
|
||||
/* Command latch cycle */
|
||||
chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
|
||||
|
||||
if (column != -1 || page_addr != -1) {
|
||||
int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
|
||||
|
||||
/* Serially input address */
|
||||
if (column != -1) {
|
||||
chip->cmd_ctrl(mtd, column, ctrl);
|
||||
ctrl &= ~NAND_CTRL_CHANGE;
|
||||
if (command != NAND_CMD_READID)
|
||||
chip->cmd_ctrl(mtd, column >> 8, ctrl);
|
||||
}
|
||||
if (page_addr != -1) {
|
||||
chip->cmd_ctrl(mtd, page_addr, ctrl);
|
||||
chip->cmd_ctrl(mtd, page_addr >> 8,
|
||||
NAND_NCE | NAND_ALE);
|
||||
if (chip->options & NAND_ROW_ADDR_3)
|
||||
chip->cmd_ctrl(mtd, page_addr >> 16,
|
||||
NAND_NCE | NAND_ALE);
|
||||
}
|
||||
}
|
||||
chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
|
||||
|
||||
/*
|
||||
* Program and erase have their own busy handlers status, sequential
|
||||
* in and status need no delay.
|
||||
*/
|
||||
switch (command) {
|
||||
case NAND_CMD_STATUS:
|
||||
case NAND_CMD_READID:
|
||||
case NAND_CMD_SET_FEATURES:
|
||||
return;
|
||||
|
||||
case NAND_CMD_READ0:
|
||||
chip->cmd_ctrl(mtd, NAND_CMD_READSTART,
|
||||
NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
|
||||
chip->cmd_ctrl(mtd, NAND_CMD_NONE,
|
||||
NAND_NCE | NAND_CTRL_CHANGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply this short delay always to ensure that we do wait tWB in
|
||||
* any case on any machine.
|
||||
*/
|
||||
ndelay(100);
|
||||
|
||||
nand_wait_ready(mtd);
|
||||
}
|
||||
|
||||
static int nfc_read_page_hwecc(struct mtd_info *mtd, void *buf,
|
||||
unsigned int page)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
int ret;
|
||||
|
||||
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page);
|
||||
|
||||
ret = chip->ecc.read_page(mtd, chip, buf, 1, page);
|
||||
if (ret < 0 || ret > chip->ecc.strength)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfc_read_oob_hwecc(struct mtd_info *mtd, void *buf, u32 len,
|
||||
unsigned int page)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
int ret;
|
||||
|
||||
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page);
|
||||
|
||||
ret = chip->ecc.read_page(mtd, chip, NULL, 1, page);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
if (len > mtd->oobsize)
|
||||
len = mtd->oobsize;
|
||||
|
||||
memcpy(buf, chip->oob_poi, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nfc_check_bad_block(struct mtd_info *mtd, unsigned int page)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
u32 pages_per_block, i = 0;
|
||||
int ret;
|
||||
u8 bad;
|
||||
|
||||
pages_per_block = 1 << (mtd->erasesize_shift - mtd->writesize_shift);
|
||||
|
||||
/* Read from first/last page(s) if necessary */
|
||||
if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) {
|
||||
page += pages_per_block - 1;
|
||||
if (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)
|
||||
page--;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = nfc_read_oob_hwecc(mtd, &bad, 1, page);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = bad != 0xFF;
|
||||
|
||||
i++;
|
||||
page++;
|
||||
} while (!ret && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
|
||||
{
|
||||
struct mt7621_nfc *nfc = &nfc_dev;
|
||||
struct nand_chip *chip = &nfc->nand;
|
||||
struct mtd_info *mtd = &chip->mtd;
|
||||
u32 addr, col, page, chksz;
|
||||
bool check_bad = true;
|
||||
|
||||
if (!nand_valid)
|
||||
return -ENODEV;
|
||||
|
||||
while (size) {
|
||||
if (check_bad || !(offs & mtd->erasesize_mask)) {
|
||||
addr = offs & (~mtd->erasesize_mask);
|
||||
page = addr >> mtd->writesize_shift;
|
||||
if (nfc_check_bad_block(mtd, page)) {
|
||||
/* Skip bad block */
|
||||
if (addr >= mtd->size - mtd->erasesize)
|
||||
return -1;
|
||||
|
||||
offs += mtd->erasesize;
|
||||
continue;
|
||||
}
|
||||
|
||||
check_bad = false;
|
||||
}
|
||||
|
||||
col = offs & mtd->writesize_mask;
|
||||
page = offs >> mtd->writesize_shift;
|
||||
chksz = min(mtd->writesize - col, (uint32_t)size);
|
||||
|
||||
if (unlikely(chksz < mtd->writesize)) {
|
||||
/* Not reading a full page */
|
||||
if (nfc_read_page_hwecc(mtd, buffer, page))
|
||||
return -1;
|
||||
|
||||
memcpy(dest, buffer + col, chksz);
|
||||
} else {
|
||||
if (nfc_read_page_hwecc(mtd, dest, page))
|
||||
return -1;
|
||||
}
|
||||
|
||||
dest += chksz;
|
||||
offs += chksz;
|
||||
size -= chksz;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nand_default_bbt(struct mtd_info *mtd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long nand_size(void)
|
||||
{
|
||||
if (!nand_valid)
|
||||
return 0;
|
||||
|
||||
/* Unlikely that NAND size > 2GBytes */
|
||||
if (nfc_dev.nand.chipsize <= SZ_2G)
|
||||
return nfc_dev.nand.chipsize;
|
||||
|
||||
return SZ_2G;
|
||||
}
|
||||
|
||||
void nand_deselect(void)
|
||||
{
|
||||
}
|
||||
|
||||
void nand_init(void)
|
||||
{
|
||||
struct mtd_info *mtd;
|
||||
struct nand_chip *chip;
|
||||
|
||||
if (nand_valid)
|
||||
return;
|
||||
|
||||
mt7621_nfc_spl_init(&nfc_dev);
|
||||
|
||||
chip = &nfc_dev.nand;
|
||||
mtd = &chip->mtd;
|
||||
chip->cmdfunc = nand_command_lp;
|
||||
|
||||
if (mt7621_nfc_spl_post_init(&nfc_dev))
|
||||
return;
|
||||
|
||||
mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
|
||||
mtd->writesize_shift = ffs(mtd->writesize) - 1;
|
||||
mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
|
||||
mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
|
||||
|
||||
buffer = malloc(mtd->writesize);
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
nand_valid = 1;
|
||||
}
|
||||
@@ -145,7 +145,8 @@ enum mtk_switch {
|
||||
enum mtk_soc {
|
||||
SOC_MT7623,
|
||||
SOC_MT7629,
|
||||
SOC_MT7622
|
||||
SOC_MT7622,
|
||||
SOC_MT7621
|
||||
};
|
||||
|
||||
struct mtk_eth_priv {
|
||||
@@ -159,9 +160,10 @@ struct mtk_eth_priv {
|
||||
|
||||
void __iomem *fe_base;
|
||||
void __iomem *gmac_base;
|
||||
void __iomem *ethsys_base;
|
||||
void __iomem *sgmii_base;
|
||||
|
||||
struct regmap *ethsys_regmap;
|
||||
|
||||
struct mii_dev *mdio_bus;
|
||||
int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg);
|
||||
int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val);
|
||||
@@ -233,7 +235,12 @@ static void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
|
||||
static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
|
||||
u32 set)
|
||||
{
|
||||
clrsetbits_le32(priv->ethsys_base + reg, clr, set);
|
||||
uint val;
|
||||
|
||||
regmap_read(priv->ethsys_regmap, reg, &val);
|
||||
val &= ~clr;
|
||||
val |= set;
|
||||
regmap_write(priv->ethsys_regmap, reg, val);
|
||||
}
|
||||
|
||||
/* Direct MDIO clause 22/45 access via SoC */
|
||||
@@ -669,12 +676,18 @@ static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode)
|
||||
static int mt7530_setup(struct mtk_eth_priv *priv)
|
||||
{
|
||||
u16 phy_addr, phy_val;
|
||||
u32 val;
|
||||
u32 val, txdrv;
|
||||
int i;
|
||||
|
||||
/* Select 250MHz clk for RGMII mode */
|
||||
mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
|
||||
ETHSYS_TRGMII_CLK_SEL362_5, 0);
|
||||
if (priv->soc != SOC_MT7621) {
|
||||
/* Select 250MHz clk for RGMII mode */
|
||||
mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
|
||||
ETHSYS_TRGMII_CLK_SEL362_5, 0);
|
||||
|
||||
txdrv = 8;
|
||||
} else {
|
||||
txdrv = 4;
|
||||
}
|
||||
|
||||
/* Modify HWTRAP first to allow direct access to internal PHYs */
|
||||
mt753x_reg_read(priv, HWTRAP_REG, &val);
|
||||
@@ -732,7 +745,8 @@ static int mt7530_setup(struct mtk_eth_priv *priv)
|
||||
/* Lower Tx Driving for TRGMII path */
|
||||
for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
|
||||
mt753x_reg_write(priv, MT7530_TRGMII_TD_ODT(i),
|
||||
(8 << TD_DM_DRVP_S) | (8 << TD_DM_DRVN_S));
|
||||
(txdrv << TD_DM_DRVP_S) |
|
||||
(txdrv << TD_DM_DRVN_S));
|
||||
|
||||
for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
|
||||
mt753x_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16);
|
||||
@@ -1419,7 +1433,7 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
|
||||
|
||||
priv->soc = dev_get_driver_data(dev);
|
||||
|
||||
pdata->iobase = dev_read_addr(dev);
|
||||
pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
|
||||
|
||||
/* get corresponding ethsys phandle */
|
||||
ret = dev_read_phandle_with_args(dev, "mediatek,ethsys", NULL, 0, 0,
|
||||
@@ -1427,15 +1441,9 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap = syscon_node_to_regmap(args.node);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
priv->ethsys_base = regmap_get_range(regmap, 0);
|
||||
if (!priv->ethsys_base) {
|
||||
dev_err(dev, "Unable to find ethsys\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
priv->ethsys_regmap = syscon_node_to_regmap(args.node);
|
||||
if (IS_ERR(priv->ethsys_regmap))
|
||||
return PTR_ERR(priv->ethsys_regmap);
|
||||
|
||||
/* Reset controllers */
|
||||
ret = reset_get_by_name(dev, "fe", &priv->rst_fe);
|
||||
@@ -1540,6 +1548,7 @@ static const struct udevice_id mtk_eth_ids[] = {
|
||||
{ .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 },
|
||||
{ .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 },
|
||||
{ .compatible = "mediatek,mt7622-eth", .data = SOC_MT7622 },
|
||||
{ .compatible = "mediatek,mt7621-eth", .data = SOC_MT7621 },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ config MT76X8_USB_PHY
|
||||
config PHY_MTK_TPHY
|
||||
bool "MediaTek T-PHY Driver"
|
||||
depends on PHY
|
||||
depends on ARCH_MEDIATEK
|
||||
depends on ARCH_MEDIATEK || SOC_MT7621
|
||||
help
|
||||
MediaTek T-PHY driver supports usb2.0, usb3.0 ports, PCIe and
|
||||
SATA, and meanwhile supports two version T-PHY which have
|
||||
|
||||
@@ -12,6 +12,15 @@ config PINCTRL_MT7620
|
||||
The driver is controlled by a device tree node which contains
|
||||
the pin mux functions for each available pin groups.
|
||||
|
||||
config PINCTRL_MT7621
|
||||
bool "MediaTek MT7621 pin control driver"
|
||||
select PINCTRL_MTMIPS
|
||||
depends on SOC_MT7621 && PINCTRL_GENERIC
|
||||
help
|
||||
Support pin multiplexing control on MediaTek MT7621.
|
||||
The driver is controlled by a device tree node which contains
|
||||
the pin mux functions for each available pin groups.
|
||||
|
||||
config PINCTRL_MT7628
|
||||
bool "MediaTek MT7628 pin control driver"
|
||||
select PINCTRL_MTMIPS
|
||||
|
||||
@@ -5,4 +5,5 @@ obj-$(CONFIG_PINCTRL_MTMIPS) += pinctrl-mtmips-common.o
|
||||
|
||||
# SoC Drivers
|
||||
obj-$(CONFIG_PINCTRL_MT7620) += pinctrl-mt7620.o
|
||||
obj-$(CONFIG_PINCTRL_MT7621) += pinctrl-mt7621.o
|
||||
obj-$(CONFIG_PINCTRL_MT7628) += pinctrl-mt7628.o
|
||||
|
||||
306
drivers/pinctrl/mtmips/pinctrl-mt7621.c
Normal file
306
drivers/pinctrl/mtmips/pinctrl-mt7621.c
Normal file
@@ -0,0 +1,306 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "pinctrl-mtmips-common.h"
|
||||
|
||||
#define SYSC_MAP_SIZE 0x100
|
||||
|
||||
#define PAD_UART1_GPIO0_OFS 0x00
|
||||
#define PAD_UART3_I2C_OFS 0x04
|
||||
#define PAD_UART2_JTAG_OFS 0x08
|
||||
#define PAD_PERST_WDT_OFS 0x0c
|
||||
#define PAD_RGMII2_MDIO_OFS 0x10
|
||||
#define PAD_SDXC_SPI_OFS 0x14
|
||||
#define GPIOMODE_OFS 0x18
|
||||
#define PAD_BOPT_ESWINT_OFS 0x28
|
||||
|
||||
#define ESWINT_SHIFT 20
|
||||
#define SDXC_SHIFT 18
|
||||
#define SPI_SHIFT 16
|
||||
#define RGMII2_SHIFT 15
|
||||
#define RGMII1_SHIFT 14
|
||||
#define MDIO_SHIFT 12
|
||||
#define PERST_SHIFT 10
|
||||
#define WDT_SHIFT 8
|
||||
#define JTAG_SHIFT 7
|
||||
#define UART2_SHIFT 5
|
||||
#define UART3_SHIFT 3
|
||||
#define I2C_SHIFT 2
|
||||
#define UART1_SHIFT 1
|
||||
#define GPIO0_SHIFT 0 /* Dummy */
|
||||
|
||||
#define GM4_MASK 3
|
||||
|
||||
#define E4_E2_M 0x03
|
||||
#define E4_E2_S 4
|
||||
#define PULL_UP BIT(3)
|
||||
#define PULL_DOWN BIT(2)
|
||||
#define SMT BIT(1)
|
||||
#define SR BIT(0)
|
||||
|
||||
struct mt7621_pinctrl_priv {
|
||||
struct mtmips_pinctrl_priv mp;
|
||||
};
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINMUX)
|
||||
static const struct mtmips_pmx_func esw_int_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("esw int", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func sdxc_grp[] = {
|
||||
FUNC("nand", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("sdxc", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func spi_grp[] = {
|
||||
FUNC("nand", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("spi", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func rgmii2_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("rgmii", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func rgmii1_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("rgmii", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func mdio_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("mdio", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func perst_grp[] = {
|
||||
FUNC("refclk", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("pcie reset", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func wdt_grp[] = {
|
||||
FUNC("refclk", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("wdt rst", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func jtag_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("jtag", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func uart2_grp[] = {
|
||||
FUNC("spdif", 3),
|
||||
FUNC("pcm", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("uart", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func uart3_grp[] = {
|
||||
FUNC("spdif", 3),
|
||||
FUNC("i2s", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("uart", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func i2c_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("i2c", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func uart1_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("uart", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func gpio0_grp[] = {
|
||||
FUNC("gpio", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_group mt7621_pmx_data[] = {
|
||||
GRP_PCONF("esw int", esw_int_grp, GPIOMODE_OFS, ESWINT_SHIFT, 1,
|
||||
PAD_BOPT_ESWINT_OFS, 0),
|
||||
GRP_PCONF("sdxc", sdxc_grp, GPIOMODE_OFS, SDXC_SHIFT, GM4_MASK,
|
||||
PAD_SDXC_SPI_OFS, 16),
|
||||
GRP_PCONF("spi", spi_grp, GPIOMODE_OFS, SPI_SHIFT, GM4_MASK,
|
||||
PAD_SDXC_SPI_OFS, 0),
|
||||
GRP_PCONF("rgmii2", rgmii2_grp, GPIOMODE_OFS, RGMII2_SHIFT, 1,
|
||||
PAD_RGMII2_MDIO_OFS, 16),
|
||||
GRP("rgmii1", rgmii1_grp, GPIOMODE_OFS, RGMII1_SHIFT, 1),
|
||||
GRP_PCONF("mdio", mdio_grp, GPIOMODE_OFS, MDIO_SHIFT, GM4_MASK,
|
||||
PAD_RGMII2_MDIO_OFS, 0),
|
||||
GRP_PCONF("pcie reset", perst_grp, GPIOMODE_OFS, PERST_SHIFT, GM4_MASK,
|
||||
PAD_PERST_WDT_OFS, 16),
|
||||
GRP_PCONF("wdt", wdt_grp, GPIOMODE_OFS, WDT_SHIFT, GM4_MASK,
|
||||
PAD_PERST_WDT_OFS, 0),
|
||||
GRP_PCONF("jtag", jtag_grp, GPIOMODE_OFS, JTAG_SHIFT, 1,
|
||||
PAD_UART2_JTAG_OFS, 16),
|
||||
GRP_PCONF("uart2", uart2_grp, GPIOMODE_OFS, UART2_SHIFT, GM4_MASK,
|
||||
PAD_UART2_JTAG_OFS, 0),
|
||||
GRP_PCONF("uart3", uart3_grp, GPIOMODE_OFS, UART3_SHIFT, GM4_MASK,
|
||||
PAD_UART3_I2C_OFS, 16),
|
||||
GRP_PCONF("i2c", i2c_grp, GPIOMODE_OFS, I2C_SHIFT, 1,
|
||||
PAD_UART3_I2C_OFS, 0),
|
||||
GRP_PCONF("uart1", uart1_grp, GPIOMODE_OFS, UART1_SHIFT, 1,
|
||||
PAD_UART1_GPIO0_OFS, 16),
|
||||
GRP_PCONF("gpio0", gpio0_grp, GPIOMODE_OFS, GPIO0_SHIFT, 1,
|
||||
PAD_UART1_GPIO0_OFS, 0),
|
||||
};
|
||||
|
||||
static int mt7621_get_groups_count(struct udevice *dev)
|
||||
{
|
||||
return ARRAY_SIZE(mt7621_pmx_data);
|
||||
}
|
||||
|
||||
static const char *mt7621_get_group_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
return mt7621_pmx_data[selector].name;
|
||||
}
|
||||
#endif /* CONFIG_IS_ENABLED(PINMUX) */
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
static const struct pinconf_param mt7621_conf_params[] = {
|
||||
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
|
||||
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
|
||||
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
|
||||
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
|
||||
{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
|
||||
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
|
||||
{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
|
||||
};
|
||||
|
||||
static const u32 mt7621_pconf_drv_strength_tbl[] = {2, 4, 6, 8};
|
||||
|
||||
static int mt7621_pinconf_group_set(struct udevice *dev,
|
||||
unsigned int group_selector,
|
||||
unsigned int param, unsigned int arg)
|
||||
{
|
||||
struct mt7621_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct mtmips_pmx_group *grp = &mt7621_pmx_data[group_selector];
|
||||
u32 clr = 0, set = 0;
|
||||
int i;
|
||||
|
||||
if (!grp->pconf_avail)
|
||||
return 0;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
clr = PULL_UP | PULL_DOWN;
|
||||
break;
|
||||
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
clr = PULL_DOWN;
|
||||
set = PULL_UP;
|
||||
break;
|
||||
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
clr = PULL_UP;
|
||||
set = PULL_DOWN;
|
||||
break;
|
||||
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
if (arg)
|
||||
set = SMT;
|
||||
else
|
||||
clr = SMT;
|
||||
break;
|
||||
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
for (i = 0; i < ARRAY_SIZE(mt7621_pconf_drv_strength_tbl); i++)
|
||||
if (mt7621_pconf_drv_strength_tbl[i] == arg)
|
||||
break;
|
||||
|
||||
if (i >= ARRAY_SIZE(mt7621_pconf_drv_strength_tbl))
|
||||
return -EINVAL;
|
||||
|
||||
clr = E4_E2_M << E4_E2_S;
|
||||
set = i << E4_E2_S;
|
||||
break;
|
||||
|
||||
case PIN_CONFIG_SLEW_RATE:
|
||||
if (arg)
|
||||
set = SR;
|
||||
else
|
||||
clr = SR;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mtmips_pinctrl_reg_set(&priv->mp, grp->pconf_reg, grp->pconf_shift,
|
||||
clr, set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mt7621_pinctrl_probe(struct udevice *dev)
|
||||
{
|
||||
struct mt7621_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
int ret = 0;
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINMUX)
|
||||
ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7621_pmx_data),
|
||||
mt7621_pmx_data);
|
||||
#endif /* CONFIG_IS_ENABLED(PINMUX) */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mt7621_pinctrl_of_to_plat(struct udevice *dev)
|
||||
{
|
||||
struct mt7621_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0);
|
||||
|
||||
if (!priv->mp.base)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinctrl_ops mt7621_pinctrl_ops = {
|
||||
#if CONFIG_IS_ENABLED(PINMUX)
|
||||
.get_groups_count = mt7621_get_groups_count,
|
||||
.get_group_name = mt7621_get_group_name,
|
||||
.get_functions_count = mtmips_get_functions_count,
|
||||
.get_function_name = mtmips_get_function_name,
|
||||
.pinmux_group_set = mtmips_pinmux_group_set,
|
||||
#endif /* CONFIG_IS_ENABLED(PINMUX) */
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
.pinconf_num_params = ARRAY_SIZE(mt7621_conf_params),
|
||||
.pinconf_params = mt7621_conf_params,
|
||||
.pinconf_group_set = mt7621_pinconf_group_set,
|
||||
#endif /* CONFIG_IS_ENABLED(PINCONF) */
|
||||
.set_state = pinctrl_generic_set_state,
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7621_pinctrl_ids[] = {
|
||||
{ .compatible = "mediatek,mt7621-pinctrl" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mt7621_pinctrl) = {
|
||||
.name = "mt7621-pinctrl",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = mt7621_pinctrl_ids,
|
||||
.of_to_plat = mt7621_pinctrl_of_to_plat,
|
||||
.ops = &mt7621_pinctrl_ops,
|
||||
.probe = mt7621_pinctrl_probe,
|
||||
.priv_auto = sizeof(struct mt7621_pinctrl_priv),
|
||||
};
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
#include "pinctrl-mtmips-common.h"
|
||||
|
||||
static void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv,
|
||||
u32 reg, u32 shift, u32 mask, u32 value)
|
||||
void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv,
|
||||
u32 reg, u32 shift, u32 mask, u32 value)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ struct mtmips_pmx_group {
|
||||
u32 shift;
|
||||
char mask;
|
||||
|
||||
int pconf_avail;
|
||||
u32 pconf_reg;
|
||||
u32 pconf_shift;
|
||||
|
||||
int nfuncs;
|
||||
const struct mtmips_pmx_func *funcs;
|
||||
};
|
||||
@@ -42,6 +46,14 @@ struct mtmips_pinctrl_priv {
|
||||
{ .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \
|
||||
.funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs) }
|
||||
|
||||
#define GRP_PCONF(_name, _funcs, _reg, _shift, _mask, _pconf_reg, _pconf_shift) \
|
||||
{ .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \
|
||||
.funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs), .pconf_avail = 1, \
|
||||
.pconf_reg = (_pconf_reg), .pconf_shift = (_pconf_shift) }
|
||||
|
||||
void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv,
|
||||
u32 reg, u32 shift, u32 mask, u32 value);
|
||||
|
||||
int mtmips_get_functions_count(struct udevice *dev);
|
||||
const char *mtmips_get_function_name(struct udevice *dev,
|
||||
unsigned int selector);
|
||||
|
||||
@@ -254,7 +254,7 @@ config MT7620_SPI
|
||||
|
||||
config MT7621_SPI
|
||||
bool "MediaTek MT7621 SPI driver"
|
||||
depends on SOC_MT7628
|
||||
depends on SOC_MT7621 || SOC_MT7628
|
||||
help
|
||||
Enable the MT7621 SPI driver. This driver can be used to access
|
||||
the SPI NOR flash on platforms embedding this Ralink / MediaTek
|
||||
|
||||
@@ -42,7 +42,7 @@ config USB_XHCI_EXYNOS
|
||||
|
||||
config USB_XHCI_MTK
|
||||
bool "Support for MediaTek on-chip xHCI USB controller"
|
||||
depends on ARCH_MEDIATEK
|
||||
depends on ARCH_MEDIATEK || SOC_MT7621
|
||||
help
|
||||
Enables support for the on-chip xHCI controller on MediaTek SoCs.
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ config WDT_MT7620
|
||||
|
||||
config WDT_MT7621
|
||||
bool "MediaTek MT7621 watchdog timer support"
|
||||
depends on WDT && SOC_MT7628
|
||||
depends on WDT && (SOC_MT7621 || SOC_MT7628)
|
||||
help
|
||||
Select this to enable Ralink / Mediatek watchdog timer,
|
||||
which can be found on some MediaTek chips.
|
||||
|
||||
43
include/configs/mt7621.h
Normal file
43
include/configs/mt7621.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_MT7621_H
|
||||
#define __CONFIG_MT7621_H
|
||||
|
||||
#define CONFIG_SYS_MIPS_TIMER_FREQ 440000000
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x80000000
|
||||
|
||||
#define CONFIG_VERY_BIG_RAM
|
||||
#define CONFIG_MAX_MEM_MAPPED 0x1c000000
|
||||
|
||||
#define CONFIG_SYS_INIT_SP_OFFSET 0x800000
|
||||
|
||||
#define CONFIG_SYS_NONCACHED_MEMORY 0x100000
|
||||
|
||||
/* MMC */
|
||||
#define MMC_SUPPORTS_TUNING
|
||||
|
||||
/* NAND */
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
|
||||
/* Serial SPL */
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL)
|
||||
#define CONFIG_SYS_NS16550_MEM32
|
||||
#define CONFIG_SYS_NS16550_CLK 50000000
|
||||
#define CONFIG_SYS_NS16550_REG_SIZE -4
|
||||
#define CONFIG_SYS_NS16550_COM1 0xbe000c00
|
||||
#endif
|
||||
|
||||
/* Serial common */
|
||||
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
|
||||
230400, 460800, 921600 }
|
||||
|
||||
/* Dummy value */
|
||||
#define CONFIG_SYS_UBOOT_BASE 0
|
||||
|
||||
#endif /* __CONFIG_MT7621_H */
|
||||
46
include/dt-bindings/clock/mt7621-clk.h
Normal file
46
include/dt-bindings/clock/mt7621-clk.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_MT7621_CLK_H_
|
||||
#define _DT_BINDINGS_MT7621_CLK_H_
|
||||
|
||||
#define MT7621_CLK_XTAL 0
|
||||
#define MT7621_CLK_CPU 1
|
||||
#define MT7621_CLK_BUS 2
|
||||
#define MT7621_CLK_50M 3
|
||||
#define MT7621_CLK_125M 4
|
||||
#define MT7621_CLK_150M 5
|
||||
#define MT7621_CLK_250M 6
|
||||
#define MT7621_CLK_270M 7
|
||||
|
||||
#define MT7621_CLK_HSDMA 8
|
||||
#define MT7621_CLK_FE 9
|
||||
#define MT7621_CLK_SP_DIVTX 10
|
||||
#define MT7621_CLK_TIMER 11
|
||||
#define MT7621_CLK_PCM 12
|
||||
#define MT7621_CLK_PIO 13
|
||||
#define MT7621_CLK_GDMA 14
|
||||
#define MT7621_CLK_NAND 15
|
||||
#define MT7621_CLK_I2C 16
|
||||
#define MT7621_CLK_I2S 17
|
||||
#define MT7621_CLK_SPI 18
|
||||
#define MT7621_CLK_UART1 19
|
||||
#define MT7621_CLK_UART2 20
|
||||
#define MT7621_CLK_UART3 21
|
||||
#define MT7621_CLK_ETH 22
|
||||
#define MT7621_CLK_PCIE0 23
|
||||
#define MT7621_CLK_PCIE1 24
|
||||
#define MT7621_CLK_PCIE2 25
|
||||
#define MT7621_CLK_CRYPTO 26
|
||||
#define MT7621_CLK_SHXC 27
|
||||
|
||||
#define MT7621_CLK_MAX 28
|
||||
|
||||
/* for u-boot only */
|
||||
#define MT7621_CLK_DDR 29
|
||||
|
||||
#endif /* _DT_BINDINGS_MT7621_CLK_H_ */
|
||||
38
include/dt-bindings/reset/mt7621-reset.h
Normal file
38
include/dt-bindings/reset/mt7621-reset.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_MT7621_RESET_H_
|
||||
#define _DT_BINDINGS_MT7621_RESET_H_
|
||||
|
||||
#define RST_PPE 31
|
||||
#define RST_SDXC 30
|
||||
#define RST_CRYPTO 29
|
||||
#define RST_AUX_STCK 28
|
||||
#define RST_PCIE2 26
|
||||
#define RST_PCIE1 25
|
||||
#define RST_PCIE0 24
|
||||
#define RST_GMAC 23
|
||||
#define RST_UART3 21
|
||||
#define RST_UART2 20
|
||||
#define RST_UART1 19
|
||||
#define RST_SPI 18
|
||||
#define RST_I2S 17
|
||||
#define RST_I2C 16
|
||||
#define RST_NFI 15
|
||||
#define RST_GDMA 14
|
||||
#define RST_PIO 13
|
||||
#define RST_PCM 11
|
||||
#define RST_MC 10
|
||||
#define RST_INTC 9
|
||||
#define RST_TIMER 8
|
||||
#define RST_SPDIFTX 7
|
||||
#define RST_FE 6
|
||||
#define RST_HSDMA 5
|
||||
#define RST_MCM 2
|
||||
#define RST_SYS 0
|
||||
|
||||
#endif /* _DT_BINDINGS_MT7621_RESET_H_ */
|
||||
@@ -6,7 +6,9 @@
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <image.h>
|
||||
#include <u-boot/crc.h>
|
||||
#include <u-boot/sha256.h>
|
||||
#include "imagetool.h"
|
||||
#include "mtk_image.h"
|
||||
@@ -251,17 +253,45 @@ static uint32_t img_size;
|
||||
static enum brlyt_img_type hdr_media;
|
||||
static uint32_t hdr_offset;
|
||||
static int use_lk_hdr;
|
||||
static int use_mt7621_hdr;
|
||||
static bool is_arm64_image;
|
||||
|
||||
/* LK image name */
|
||||
static char lk_name[32] = "U-Boot";
|
||||
|
||||
/* CRC32 normal table required by MT7621 image */
|
||||
static uint32_t crc32tbl[256];
|
||||
|
||||
/* NAND header selected by user */
|
||||
static const union nand_boot_header *hdr_nand;
|
||||
|
||||
/* GFH header + 2 * 4KB pages of NAND */
|
||||
static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
|
||||
|
||||
static uint32_t crc32_normal_cal(uint32_t crc, const void *data, size_t length,
|
||||
const uint32_t *crc32c_table)
|
||||
{
|
||||
const uint8_t *p = data;
|
||||
|
||||
while (length--)
|
||||
crc = crc32c_table[(uint8_t)((crc >> 24) ^ *p++)] ^ (crc << 8);
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
static void crc32_normal_init(uint32_t *crc32c_table, uint32_t poly)
|
||||
{
|
||||
uint32_t v, i, j;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
v = i << 24;
|
||||
for (j = 0; j < 8; j++)
|
||||
v = (v << 1) ^ ((v & (1 << 31)) ? poly : 0);
|
||||
|
||||
crc32c_table[i] = v;
|
||||
}
|
||||
}
|
||||
|
||||
static int mtk_image_check_image_types(uint8_t type)
|
||||
{
|
||||
if (type == IH_TYPE_MTKIMAGE)
|
||||
@@ -283,6 +313,7 @@ static int mtk_brom_parse_imagename(const char *imagename)
|
||||
static const char *hdr_offs = "";
|
||||
static const char *nandinfo = "";
|
||||
static const char *lk = "";
|
||||
static const char *mt7621 = "";
|
||||
static const char *arm64_param = "";
|
||||
|
||||
key = buf;
|
||||
@@ -332,6 +363,9 @@ static int mtk_brom_parse_imagename(const char *imagename)
|
||||
if (!strcmp(key, "lk"))
|
||||
lk = val;
|
||||
|
||||
if (!strcmp(key, "mt7621"))
|
||||
mt7621 = val;
|
||||
|
||||
if (!strcmp(key, "lkname"))
|
||||
snprintf(lk_name, sizeof(lk_name), "%s", val);
|
||||
|
||||
@@ -352,6 +386,13 @@ static int mtk_brom_parse_imagename(const char *imagename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if user specified MT7621 image header, skip following checks */
|
||||
if (mt7621 && mt7621[0] == '1') {
|
||||
use_mt7621_hdr = 1;
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse media type */
|
||||
for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
|
||||
if (!strcmp(brom_images[i].name, media)) {
|
||||
@@ -419,6 +460,13 @@ static int mtk_image_vrec_header(struct image_tool_params *params,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (use_mt7621_hdr) {
|
||||
tparams->header_size = image_get_header_size();
|
||||
tparams->hdr = &hdr_tmp;
|
||||
memset(&hdr_tmp, 0, tparams->header_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
|
||||
tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
|
||||
else
|
||||
@@ -579,9 +627,90 @@ static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t crc32be_cal(const void *data, size_t length)
|
||||
{
|
||||
uint32_t crc = 0;
|
||||
uint8_t c;
|
||||
|
||||
if (crc32tbl[1] != MT7621_IH_CRC_POLYNOMIAL)
|
||||
crc32_normal_init(crc32tbl, MT7621_IH_CRC_POLYNOMIAL);
|
||||
|
||||
crc = crc32_normal_cal(crc, data, length, crc32tbl);
|
||||
|
||||
for (; length; length >>= 8) {
|
||||
c = length & 0xff;
|
||||
crc = crc32_normal_cal(crc, &c, 1, crc32tbl);
|
||||
}
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print)
|
||||
{
|
||||
const image_header_t *hdr = (const image_header_t *)ptr;
|
||||
struct mt7621_nand_header *nhdr;
|
||||
uint32_t spl_size, crcval;
|
||||
image_header_t header;
|
||||
int ret;
|
||||
|
||||
spl_size = image_get_size(hdr);
|
||||
|
||||
if (spl_size > img_size) {
|
||||
if (print)
|
||||
printf("Incomplete SPL image\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = image_check_hcrc(hdr);
|
||||
if (!ret) {
|
||||
if (print)
|
||||
printf("Bad header CRC\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = image_check_dcrc(hdr);
|
||||
if (!ret) {
|
||||
if (print)
|
||||
printf("Bad data CRC\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy header so we can blank CRC field for re-calculation */
|
||||
memmove(&header, hdr, image_get_header_size());
|
||||
image_set_hcrc(&header, 0);
|
||||
|
||||
nhdr = (struct mt7621_nand_header *)header.ih_name;
|
||||
crcval = be32_to_cpu(nhdr->crc);
|
||||
nhdr->crc = 0;
|
||||
|
||||
if (crcval != crc32be_cal(&header, image_get_header_size())) {
|
||||
if (print)
|
||||
printf("Bad NAND header CRC\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (print) {
|
||||
printf("Load Address: %08x\n", image_get_load(hdr));
|
||||
|
||||
printf("Image Name: %.*s\n", MT7621_IH_NMLEN,
|
||||
image_get_name(hdr));
|
||||
|
||||
if (IMAGE_ENABLE_TIMESTAMP) {
|
||||
printf("Created: ");
|
||||
genimg_print_time((time_t)image_get_time(hdr));
|
||||
}
|
||||
|
||||
printf("Data Size: ");
|
||||
genimg_print_size(image_get_data_size(hdr));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_image_verify_header(unsigned char *ptr, int image_size,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
image_header_t *hdr = (image_header_t *)ptr;
|
||||
union lk_hdr *lk = (union lk_hdr *)ptr;
|
||||
|
||||
/* nothing to verify for LK image header */
|
||||
@@ -590,6 +719,9 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size,
|
||||
|
||||
img_size = image_size;
|
||||
|
||||
if (image_get_magic(hdr) == IH_MAGIC)
|
||||
return mtk_image_verify_mt7621_header(ptr, 0);
|
||||
|
||||
if (!strcmp((char *)ptr, NAND_BOOT_NAME))
|
||||
return mtk_image_verify_nand_header(ptr, 0);
|
||||
else
|
||||
@@ -600,6 +732,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size,
|
||||
|
||||
static void mtk_image_print_header(const void *ptr)
|
||||
{
|
||||
image_header_t *hdr = (image_header_t *)ptr;
|
||||
union lk_hdr *lk = (union lk_hdr *)ptr;
|
||||
|
||||
if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
|
||||
@@ -610,6 +743,11 @@ static void mtk_image_print_header(const void *ptr)
|
||||
|
||||
printf("Image Type: MediaTek BootROM Loadable Image\n");
|
||||
|
||||
if (image_get_magic(hdr) == IH_MAGIC) {
|
||||
mtk_image_verify_mt7621_header(ptr, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp((char *)ptr, NAND_BOOT_NAME))
|
||||
mtk_image_verify_nand_header(ptr, 1);
|
||||
else
|
||||
@@ -773,6 +911,45 @@ static void mtk_image_set_nand_header(void *ptr, off_t filesize,
|
||||
filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
|
||||
}
|
||||
|
||||
static void mtk_image_set_mt7621_header(void *ptr, off_t filesize,
|
||||
uint32_t loadaddr)
|
||||
{
|
||||
image_header_t *hdr = (image_header_t *)ptr;
|
||||
struct mt7621_stage1_header *shdr;
|
||||
struct mt7621_nand_header *nhdr;
|
||||
uint32_t datasize, crcval;
|
||||
|
||||
datasize = filesize - image_get_header_size();
|
||||
nhdr = (struct mt7621_nand_header *)hdr->ih_name;
|
||||
shdr = (struct mt7621_stage1_header *)(ptr + image_get_header_size());
|
||||
|
||||
shdr->ep = cpu_to_be32(loadaddr);
|
||||
shdr->stage_size = cpu_to_be32(datasize);
|
||||
|
||||
image_set_magic(hdr, IH_MAGIC);
|
||||
image_set_time(hdr, time(NULL));
|
||||
image_set_size(hdr, datasize);
|
||||
image_set_load(hdr, loadaddr);
|
||||
image_set_ep(hdr, loadaddr);
|
||||
image_set_os(hdr, IH_OS_U_BOOT);
|
||||
image_set_arch(hdr, IH_ARCH_MIPS);
|
||||
image_set_type(hdr, IH_TYPE_STANDALONE);
|
||||
image_set_comp(hdr, IH_COMP_NONE);
|
||||
|
||||
crcval = crc32(0, (uint8_t *)shdr, datasize);
|
||||
image_set_dcrc(hdr, crcval);
|
||||
|
||||
strncpy(nhdr->ih_name, "MT7621 NAND", MT7621_IH_NMLEN);
|
||||
|
||||
nhdr->ih_stage_offset = cpu_to_be32(image_get_header_size());
|
||||
|
||||
crcval = crc32be_cal(hdr, image_get_header_size());
|
||||
nhdr->crc = cpu_to_be32(crcval);
|
||||
|
||||
crcval = crc32(0, (uint8_t *)hdr, image_get_header_size());
|
||||
image_set_hcrc(hdr, crcval);
|
||||
}
|
||||
|
||||
static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
@@ -791,6 +968,11 @@ static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
|
||||
img_gen = true;
|
||||
img_size = sbuf->st_size;
|
||||
|
||||
if (use_mt7621_hdr) {
|
||||
mtk_image_set_mt7621_header(ptr, sbuf->st_size, params->addr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
|
||||
mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
|
||||
else
|
||||
|
||||
@@ -200,4 +200,28 @@ union lk_hdr {
|
||||
|
||||
#define LK_PART_MAGIC 0x58881688
|
||||
|
||||
/* MT7621 NAND SPL image header */
|
||||
|
||||
#define MT7621_IH_NMLEN 12
|
||||
#define MT7621_IH_CRC_POLYNOMIAL 0x04c11db7
|
||||
|
||||
struct mt7621_nand_header {
|
||||
char ih_name[MT7621_IH_NMLEN];
|
||||
uint32_t nand_ac_timing;
|
||||
uint32_t ih_stage_offset;
|
||||
uint32_t ih_bootloader_offset;
|
||||
uint32_t nand_info_1_data;
|
||||
uint32_t crc;
|
||||
};
|
||||
|
||||
struct mt7621_stage1_header {
|
||||
uint32_t jump_insn[2];
|
||||
uint32_t ep;
|
||||
uint32_t stage_size;
|
||||
uint32_t has_stage2;
|
||||
uint32_t next_ep;
|
||||
uint32_t next_size;
|
||||
uint32_t next_offset;
|
||||
};
|
||||
|
||||
#endif /* _MTK_IMAGE_H */
|
||||
|
||||
Reference in New Issue
Block a user