From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DCD1CC433F5 for ; Wed, 11 May 2022 16:36:59 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 36DB384346; Wed, 11 May 2022 18:36:57 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Nswkmht8"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C323384346; Wed, 11 May 2022 18:36:54 +0200 (CEST) Received: from mail-qk1-x735.google.com (mail-qk1-x735.google.com [IPv6:2607:f8b0:4864:20::735]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 2C7DE8432E for ; Wed, 11 May 2022 18:36:44 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=seanga2@gmail.com Received: by mail-qk1-x735.google.com with SMTP id j6so2665908qkp.9 for ; Wed, 11 May 2022 09:36:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=XKQeKrPseVvu+UM2i6nm9hWot0fV6ebq4EnFMFzOyE8=; b=Nswkmht8sswoJvBMqYrFXUqwaMEojcdIJMmQx+oVggpmgOonzJPQw5pRabYzOFNbuW XSsfISwf/lr602dYqVCTn9VM1rjV1McllQXv0d1qJshdF3XdvLwlAs4AGovryhiT5WlX XOFCMc1hwYUguNlxQAAWjUY1T0aoKxX+ArkqSJm4t0xweULSl9d3Dtvor6w4OOLEmrgS 8+fudYOIJL6ei7isbk3PvK818RKJEViPKo9MUM6bUeItYRNS9nc8MRCq1EwdFyo+6EIT i2uGEoZZUBUd4EHFhv94kP7UbsfbopItjcDqml5CmIdtJ1J2m6dQxwF31D6UZpJhg0a5 rE7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=XKQeKrPseVvu+UM2i6nm9hWot0fV6ebq4EnFMFzOyE8=; b=XGF0rN69QVo989+ZEIuEEIbtM68lzAO3tLAsuzKDTTlKDUnQngUYb+X6BxwJQ5KuER Mel+X+duvpHyp8iJIhH6jrq3iDkjoW6vExI6Nba6U+HaFcbk5NRubb2mkJ9NrTSnFWXM w0om+k/tHMbjsV+1I19o6HQiHaL0lGP0qRHRds32aOf9cxrbKHhQGDTqVdtN7dOxvDYZ GPUF1fKR4SEwj5wVuF4OwEY0RnMeDp5H7qT4arEOnQWfBfDU8UmGLpnz+3O8ja/JaHIQ EyiMhHi2GdAPf+wPaBCMOwwlnaA96gTbgoVD7RsjOJqbcykANWqgu5pjxtbFusvEH/Nt i/vw== X-Gm-Message-State: AOAM531Bb4TtQCagHBkBL9PjmMkJbL5CIwojOeUEaxjW17yCX8t3pV6C N48NNivVrMlB3FpBUjgBGZM= X-Google-Smtp-Source: ABdhPJw3Imi5C7E7VMj+ppAha1NBRJr7/QTkGF6c/D2wS+77d8aQw04hPL1KfTILmaTlEX2HRUPitA== X-Received: by 2002:a37:8641:0:b0:67e:85d1:f5e9 with SMTP id i62-20020a378641000000b0067e85d1f5e9mr20161221qkd.128.1652287002211; Wed, 11 May 2022 09:36:42 -0700 (PDT) Received: from [192.168.1.201] (pool-108-18-248-138.washdc.fios.verizon.net. [108.18.248.138]) by smtp.googlemail.com with ESMTPSA id r14-20020ac8520e000000b002f39b99f674sm1361441qtn.14.2022.05.11.09.36.41 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 11 May 2022 09:36:41 -0700 (PDT) Subject: Re: [PATCH v4 05/25] mips: mtmips: add support for MediaTek MT7621 SoC To: Weijie Gao , u-boot@lists.denx.de Cc: GSS_MTK_Uboot_upstream , Daniel Schwierzeck References: From: Sean Anderson Message-ID: <3da7ec5d-1dee-f732-1660-9ce583168211@gmail.com> Date: Wed, 11 May 2022 12:36:41 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Hi Weijie, I just commented on the device tree stuff. On 5/10/22 8:18 AM, Weijie Gao wrote: > This patch adds support for MediaTek MT7621 SoC. > All files are dedicated for u-boot. > > The default build target is u-boot-mt7621.bin. > > The specification of this chip: > https://www.mediatek.com/products/homenetworking/mt7621 > > Signed-off-by: Weijie Gao > --- > v4 changes: > Add full support for booting from flash (SPL/TPL support) > Boot all cores/VPEs > Use binman to generate final binary > Use binman to embed external binary blob > v3 changes: > Update clock name for mt7621.dtsi due to clk driver changed > v2 changes: > Add a kconfig for max supported ram size > Remove network configs from default config file > --- > arch/mips/dts/mt7621-u-boot.dtsi | 79 ++++ > arch/mips/dts/mt7621.dtsi | 370 +++++++++++++++++++ > arch/mips/mach-mtmips/Kconfig | 49 ++- > arch/mips/mach-mtmips/Makefile | 4 + > arch/mips/mach-mtmips/cpu.c | 2 +- > arch/mips/mach-mtmips/mt7621/Kconfig | 95 +++++ > arch/mips/mach-mtmips/mt7621/Makefile | 14 + > arch/mips/mach-mtmips/mt7621/init.c | 229 ++++++++++++ > arch/mips/mach-mtmips/mt7621/mt7621.h | 229 ++++++++++++ > arch/mips/mach-mtmips/mt7621/serial.c | 23 ++ > arch/mips/mach-mtmips/mt7621/spl/Makefile | 9 + > arch/mips/mach-mtmips/mt7621/spl/cps.c | 152 ++++++++ > arch/mips/mach-mtmips/mt7621/spl/dram.c | 143 +++++++ > arch/mips/mach-mtmips/mt7621/spl/dram.h | 37 ++ > arch/mips/mach-mtmips/mt7621/spl/launch.c | 100 +++++ > arch/mips/mach-mtmips/mt7621/spl/launch.h | 52 +++ > arch/mips/mach-mtmips/mt7621/spl/launch_ll.S | 357 ++++++++++++++++++ > arch/mips/mach-mtmips/mt7621/spl/serial.c | 24 ++ > arch/mips/mach-mtmips/mt7621/spl/spl.c | 95 +++++ > arch/mips/mach-mtmips/mt7621/spl/start.S | 226 +++++++++++ > arch/mips/mach-mtmips/mt7621/sram_init.S | 22 ++ > arch/mips/mach-mtmips/mt7621/tpl/Makefile | 4 + > arch/mips/mach-mtmips/mt7621/tpl/start.S | 161 ++++++++ > arch/mips/mach-mtmips/mt7621/tpl/tpl.c | 146 ++++++++ > include/configs/mt7621.h | 67 ++++ > 25 files changed, 2683 insertions(+), 6 deletions(-) > create mode 100644 arch/mips/dts/mt7621-u-boot.dtsi > create mode 100644 arch/mips/dts/mt7621.dtsi > create mode 100644 arch/mips/mach-mtmips/mt7621/Kconfig > create mode 100644 arch/mips/mach-mtmips/mt7621/Makefile > create mode 100644 arch/mips/mach-mtmips/mt7621/init.c > create mode 100644 arch/mips/mach-mtmips/mt7621/mt7621.h > create mode 100644 arch/mips/mach-mtmips/mt7621/serial.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/Makefile > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/cps.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.h > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.h > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/serial.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/spl.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/start.S > create mode 100644 arch/mips/mach-mtmips/mt7621/sram_init.S > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/Makefile > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/start.S > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/tpl.c > create mode 100644 include/configs/mt7621.h > > diff --git a/arch/mips/dts/mt7621-u-boot.dtsi b/arch/mips/dts/mt7621-u-boot.dtsi > new file mode 100644 > index 0000000000..b9b02003a5 > --- /dev/null > +++ b/arch/mips/dts/mt7621-u-boot.dtsi > @@ -0,0 +1,79 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > + > +/ { > + binman: binman { > + multiple-images; > + }; > +}; > + > +&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"; > + }; > + }; > +}; > diff --git a/arch/mips/dts/mt7621.dtsi b/arch/mips/dts/mt7621.dtsi > new file mode 100644 > index 0000000000..285179e896 > --- /dev/null > +++ b/arch/mips/dts/mt7621.dtsi > @@ -0,0 +1,370 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > + > +/ { > + #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 = <0>; reg = <1>; > + }; > + }; > + > + clk48m: clk48m@0 { > + compatible = "fixed-clock"; > + > + clock-frequency = <48000000>; > + > + #clock-cells = <0>; > + }; > + > + clk50m: clk50m@0 { > + compatible = "fixed-clock"; > + > + clock-frequency = <50000000>; > + > + #clock-cells = <0>; > + }; > + > + sysc: sysc@1e000000 { sysc: syscon@1e000000 > + compatible = "mediatek,mt7621-sysc", "syscon"; > + reg = <0x1e000000 0x100>; > + }; As commented under the clock patch, I think it would be better to include the clock controller and reset controller bindings as children of this one. > + clkctrl: clkctrl@1e000030 { clock-controller@1e000030 (or just clock-controller with the above suggestion) > + compatible = "mediatek,mt7621-clk"; > + mediatek,sysc = <&sysc>; > + mediatek,memc = <&memc>; > + > + #clock-cells = <1>; > + u-boot,dm-pre-reloc; > + }; > + > + rstctrl: rstctrl@1e000034 { 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: memc@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 { > + groups = "uart1"; > + function = "uart"; > + }; > + > + gpios { > + groups = "i2c", "uart3", "pcie reset"; > + function = "gpio"; > + }; > + > + jtag { > + groups = "jtag"; > + function = "jtag"; > + }; I think the JTAG is perhaps the only thing which should be in here. Everything else can be changed by boards. > + > + wdt { > + groups = "wdt"; > + function = "wdt rst"; > + }; > + }; > + > + 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; > + }; Should this be under the board? The only time this should be in the SoC dts s if there is an internal connection to another MAC on the SoC itself. > + }; > + > + 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>; This should be in the board dts. > + > + 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>; > + }; This should be on the board dts. > +}; > diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig > index 151b004603..d46be503a2 100644 > --- a/arch/mips/mach-mtmips/Kconfig > +++ b/arch/mips/mach-mtmips/Kconfig > @@ -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 > diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile > index 4909b47ef2..19f1e07033 100644 > --- a/arch/mips/mach-mtmips/Makefile > +++ b/arch/mips/mach-mtmips/Makefile > @@ -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/ > diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c > index a4b5cff61d..f1e9022738 100644 > --- a/arch/mips/mach-mtmips/cpu.c > +++ b/arch/mips/mach-mtmips/cpu.c > @@ -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; > } > diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach-mtmips/mt7621/Kconfig > new file mode 100644 > index 0000000000..37d512c68f > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/Kconfig > @@ -0,0 +1,95 @@ > + > +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" > + > +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 > diff --git a/arch/mips/mach-mtmips/mt7621/Makefile b/arch/mips/mach-mtmips/mt7621/Makefile > new file mode 100644 > index 0000000000..bf1b0bb688 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/Makefile > @@ -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 > diff --git a/arch/mips/mach-mtmips/mt7621/init.c b/arch/mips/mach-mtmips/mt7621/init.c > new file mode 100644 > index 0000000000..ec63712bc1 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/init.c > @@ -0,0 +1,229 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#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 = (val & VER_ID_M) >> VER_ID_S; > + eco = (val & ECO_ID_M) >> ECO_ID_S; > + pkg = !!(val & PKG_ID); > + core = !!(val & CPU_ID); > + > + val = readl(sysc + SYSCTL_SYSCFG0_REG); > + dram = val & DRAM_TYPE; > + chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S; > + > + 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 = (void *)KSEG1ADDR(SYSCTL_BASE); > + u32 bs, xtal_sel; > + > + bs = readl(sysc + SYSCTL_SYSCFG0_REG); > + xtal_sel = (bs & XTAL_MODE_SEL_M) >> XTAL_MODE_SEL_S; > + > + 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((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | > + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | > + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | > + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, > + usbh + SSUSB_MAC_CK_CTRL_REG); > + > + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (1 << SSUSB_PLL_PREDIV_U3_S) | > + (4 << SSUSB_PLL_FBKDI_S), usbh + DA_SSUSB_U3PHYA_10_REG); > + > + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | > + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | > + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | > + (0x1e << SSUSB_PLL_FBKDIV_U3_S), > + usbh + DA_SSUSB_PLL_FBKDIV_REG); > + > + writel((0x1e400000 << SSUSB_PLL_PCW_NCPO_U3_S), > + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); > + > + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | > + (0x73 << SSUSB_PLL_SSC_DELTA1_U3_S), > + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); > + > + writel((0x71 << SSUSB_PLL_SSC_DELTA_U3_S) | > + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), > + usbh + DA_SSUSB_U3PHYA_21_REG); > + > + writel((0x140 << SSUSB_PLL_SSC_PRD_S), usbh + SSUSB_U3PHYA_9_REG); > + > + writel((0x11c00000 << SSUSB_SYSPLL_PCW_NCPO_S), > + usbh + SSUSB_U3PHYA_3_REG); > + > + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << SSUSB_SYSPLL_FBSEL_S) | > + (1 << SSUSB_SYSPLL_PREDIV_S), usbh + SSUSB_U3PHYA_1_REG); > + > + writel((0x12 << SSUSB_SYSPLL_FBDIV_S) | 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 | (8 << SSUSB_RX_DAC_MUX_S) | > + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << SSUSB_PCIE_SIGDET_LPF_S), > + usbh + SSUSB_U3PHYA_11_REG); > + > + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | > + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | SSUSB_RING_BYPASS_DET, > + usbh + SSUSB_B2_ROSC_0_REG); > + > + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | SSUSB_RING_OSC_FRC_SEL, > + usbh + SSUSB_B2_ROSC_1_REG); > +} > + > +static void xhci_config_25mhz(void __iomem *usbh) > +{ > + writel((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | > + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | > + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | > + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, > + usbh + SSUSB_MAC_CK_CTRL_REG); > + > + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (4 << SSUSB_PLL_FBKDI_S), > + usbh + DA_SSUSB_U3PHYA_10_REG); > + > + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | > + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | > + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | > + (0x19 << SSUSB_PLL_FBKDIV_U3_S), > + usbh + DA_SSUSB_PLL_FBKDIV_REG); > + > + writel((0x18000000 << SSUSB_PLL_PCW_NCPO_U3_S), > + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); > + > + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | > + (0x4a << SSUSB_PLL_SSC_DELTA1_U3_S), > + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); > + > + writel((0x48 << SSUSB_PLL_SSC_DELTA_U3_S) | > + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), > + usbh + DA_SSUSB_U3PHYA_21_REG); > + > + writel((0x190 << SSUSB_PLL_SSC_PRD_S), usbh + SSUSB_U3PHYA_9_REG); > + > + writel((0xe000000 << SSUSB_SYSPLL_PCW_NCPO_S), > + usbh + SSUSB_U3PHYA_3_REG); > + > + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << SSUSB_SYSPLL_FBSEL_S), > + usbh + SSUSB_U3PHYA_1_REG); > + > + writel((0xf << SSUSB_SYSPLL_FBDIV_S) | 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 | (8 << SSUSB_RX_DAC_MUX_S) | > + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << SSUSB_PCIE_SIGDET_LPF_S), > + usbh + SSUSB_U3PHYA_11_REG); > + > + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | > + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | SSUSB_RING_BYPASS_DET, > + usbh + SSUSB_B2_ROSC_0_REG); > + > + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | 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); > +} > diff --git a/arch/mips/mach-mtmips/mt7621/mt7621.h b/arch/mips/mach-mtmips/mt7621/mt7621.h > new file mode 100644 > index 0000000000..916cc993b4 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/mt7621.h > @@ -0,0 +1,229 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#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_ */ > diff --git a/arch/mips/mach-mtmips/mt7621/serial.c b/arch/mips/mach-mtmips/mt7621/serial.c > new file mode 100644 > index 0000000000..0ccc71dc75 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/serial.c > @@ -0,0 +1,23 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#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 > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/Makefile b/arch/mips/mach-mtmips/mt7621/spl/Makefile > new file mode 100644 > index 0000000000..ebe54e79b9 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/Makefile > @@ -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 > diff --git a/arch/mips/mach-mtmips/mt7621/spl/cps.c b/arch/mips/mach-mtmips/mt7621/spl/cps.c > new file mode 100644 > index 0000000000..61f319f45f > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/cps.c > @@ -0,0 +1,152 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#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 num_cores; > + > + num_cores = ((readl(cm_base + GCR_CONFIG) & GCR_CONFIG_PCORES) >> > + GCR_CONFIG_PCORES_SHIFT) + 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, > + (GCR_REG0_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | > + GCR_REGn_MASK_CMTGT_IOCU0); > + > + clrsetbits_32(cm_base + GCR_REG1_MASK, > + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, > + (GCR_REG1_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | > + GCR_REGn_MASK_CMTGT_IOCU0); > + > + clrsetbits_32(cm_base + GCR_REG2_MASK, > + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, > + (GCR_REG2_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | > + GCR_REGn_MASK_CMTGT_IOCU0); > + > + clrsetbits_32(cm_base + GCR_REG3_MASK, > + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, > + (GCR_REG3_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | > + 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); > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.c b/arch/mips/mach-mtmips/mt7621/spl/dram.c > new file mode 100644 > index 0000000000..6c3b501ae5 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.c > @@ -0,0 +1,143 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include "../mt7621.h" > +#include "dram.h" > + > +static const u32 ddr2_act[24] = { > +#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[24] = { > +#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 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) > +{ > + 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) { > + /* Possible wrong binary blob. Hang here */ > + for (;;) > + ; > + } > + > + memcpy(new_stage_bin, stock_stage_bin, > + be32_to_cpu(stock_stage_bin->stage_size)); > + > + memcpy(new_stage_bin->ddr2_act, ddr2_act, sizeof(ddr2_act)); > + memcpy(new_stage_bin->ddr3_act, ddr3_act, sizeof(ddr3_act)); > + > + 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; > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.h b/arch/mips/mach-mtmips/mt7621/spl/dram.h > new file mode 100644 > index 0000000000..4ca66644ef > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.h > @@ -0,0 +1,37 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#ifndef _MT7621_DRAM_H_ > +#define _MT7621_DRAM_H_ > + > +#define STAGE_LOAD_ADDR 0xBE108800 > + > +#ifndef __ASSEMBLY__ > +#include > + > +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[24]; > + u32 padding1[2]; > + u32 ddr2_act[24]; > + u32 padding2[2]; > + u32 baudrate; > + u32 padding3; > +}; > +#endif > + > +#endif /* _MT7621_DRAM_H_ */ > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.c b/arch/mips/mach-mtmips/mt7621/spl/launch.c > new file mode 100644 > index 0000000000..37c20a5f56 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.c > @@ -0,0 +1,100 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#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; > + } > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.h b/arch/mips/mach-mtmips/mt7621/spl/launch.h > new file mode 100644 > index 0000000000..f34250d605 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.h > @@ -0,0 +1,52 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#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_ */ > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > new file mode 100644 > index 0000000000..55a8fff9af > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > @@ -0,0 +1,357 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#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 > + nop > + > + addiu t2, 1 > + bne t2, a0, _next_coherent_core > + nop > + > + jr ra > + nop > + 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 > + nop > + 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 > + nop > + > + /* Check the launch flag */ > + lw t3, LAUNCH_FLAGS(t0) > + and t3, LAUNCH_FGO > + beqz t3, start_poll > + nop > + > + /* 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 > + nop > + > + .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 > + nop > + > + /* 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 > + nop > + > + /* Bootup Core0/VPE1 */ > + bal boot_vpe1 > + nop > + > + b launch_vpe_entry > + nop > + 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 > + nop > + > + /* a1 = number of VPEs - 1 */ > + ext a1, t0, MVPCONF0_PVPE_SHIFT, 4 > + beqz a1, _vpe1_init_done > + nop > + > + /* 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 > + nop > + > + /* 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 > + nop > + > + /* 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 > + nop > + > + /* 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 > + nop > + > + 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 > + nop > + END(boot_vpe1) > diff --git a/arch/mips/mach-mtmips/mt7621/spl/serial.c b/arch/mips/mach-mtmips/mt7621/spl/serial.c > new file mode 100644 > index 0000000000..5cf093a078 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/serial.c > @@ -0,0 +1,24 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#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 */ > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/spl.c b/arch/mips/mach-mtmips/mt7621/spl/spl.c > new file mode 100644 > index 0000000000..71d01aa7f5 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c > @@ -0,0 +1,95 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "../mt7621.h" > +#include "dram.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; > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/start.S b/arch/mips/mach-mtmips/mt7621/spl/start.S > new file mode 100644 > index 0000000000..3cad3567e7 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/start.S > @@ -0,0 +1,226 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#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) > diff --git a/arch/mips/mach-mtmips/mt7621/sram_init.S b/arch/mips/mach-mtmips/mt7621/sram_init.S > new file mode 100644 > index 0000000000..74ddd6bcd7 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/sram_init.S > @@ -0,0 +1,22 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#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) > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/Makefile b/arch/mips/mach-mtmips/mt7621/tpl/Makefile > new file mode 100644 > index 0000000000..471ad74249 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/tpl/Makefile > @@ -0,0 +1,4 @@ > + > +extra-y += start.o > + > +obj-y += tpl.o > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/start.S b/arch/mips/mach-mtmips/mt7621/tpl/start.S > new file mode 100644 > index 0000000000..19b09f7251 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/tpl/start.S > @@ -0,0 +1,161 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#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) > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c > new file mode 100644 > index 0000000000..77bcf0ddf0 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c > @@ -0,0 +1,146 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#define INDEX_STORE_DATA_SD 0x0f > + > +typedef void __noreturn (*image_entry_noargs_t)(void); > + > +static inline void ehb(void) > +{ > + __asm__ __volatile__ ("ehb"); > +} > + > +/* > + * 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); > + ehb(); > + > + 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)); > + } > + } > +} > + > +/* 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); > + ehb(); > + > + /* 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); > + ehb(); > +} > + > +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 (;;) > + ; > +} > diff --git a/include/configs/mt7621.h b/include/configs/mt7621.h > new file mode 100644 > index 0000000000..580d5fde0c > --- /dev/null > +++ b/include/configs/mt7621.h > @@ -0,0 +1,67 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao > + */ > + > +#ifndef __CONFIG_MT7621_H > +#define __CONFIG_MT7621_H > + > +#define CONFIG_SYS_HZ 1000 > +#define CONFIG_SYS_MIPS_TIMER_FREQ 440000000 > + > +#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000 > + > +#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_BOOTM_LEN 0x2000000 > + > +#define CONFIG_SYS_MAXARGS 16 > +#define CONFIG_SYS_CBSIZE 1024 > + > +#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 } > + > +/* SPL */ > +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE > + > +#ifdef CONFIG_TPL_BUILD > +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-mtmips/mt7621/tpl" > +/* .bss will not be used by TPL */ > +#define CONFIG_SPL_BSS_START_ADDR 0x80000000 > +#define CONFIG_SPL_BSS_MAX_SIZE 0 > +#else > +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-mtmips/mt7621/spl" > +#define CONFIG_SPL_BSS_START_ADDR 0x80140000 > +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 > +#define CONFIG_SPL_MAX_SIZE 0x30000 > +#endif > + > +/* Dummy value */ > +#define CONFIG_SYS_UBOOT_BASE 0 > +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0 > + > +#endif /* __CONFIG_MT7621_H */ >