From c09eb08dadae341e7f68d34e9ec3f15afd86e469 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Tue, 12 Jul 2022 03:41:30 +0100 Subject: uboot-mediatek: add support for MT798x platforms Import pending patches to support the upcoming Filogic platforms. Signed-off-by: Daniel Golle --- package/boot/uboot-mediatek/Makefile | 11 +- ...iatek-add-support-for-MediaTek-MT7986-SoC.patch | 552 ++++++++++ ...iatek-add-support-for-MediaTek-MT7981-SoC.patch | 462 ++++++++ ...oard-mediatek-add-MT7986-reference-boards.patch | 1148 ++++++++++++++++++++ ...oard-mediatek-add-MT7981-reference-boards.patch | 779 +++++++++++++ ...k-add-support-for-MediaTek-MT7891-MT7986-.patch | 132 +++ ...k-use-a-struct-to-cover-variations-of-all.patch | 163 +++ ...k-stop-using-bitfileds-for-DMA-descriptor.patch | 317 ++++++ ...0008-net-mediatek-add-support-for-PDMA-v2.patch | 298 +++++ ...ek-add-support-for-MediaTek-MT7981-MT7986.patch | 100 ++ ...add-support-for-using-dynamic-baud-clock-.patch | 202 ++++ ...dts-mt7622-force-high-speed-mode-for-uart.patch | 26 + ...m-mtk-add-support-for-MediaTek-MT7986-SoC.patch | 32 + ...m-mtk-add-support-for-MediaTek-MT7981-SoC.patch | 99 ++ ...dd-support-for-MediaTek-MT7981-MT7986-SoC.patch | 119 ++ ...diatek-add-support-for-MediaTek-MT7986-So.patch | 23 + ...d-support-for-MediaTek-spi-mem-controller.patch | 748 +++++++++++++ ...2c-add-support-for-MediaTek-I2C-interface.patch | 870 +++++++++++++++ .../002-0018-arm-dts-mt7622-add-i2c-support.patch | 76 ++ ...-pinctrl-mediatek-add-a-header-for-common.patch | 60 + ...ediatek-add-pinctrl-driver-for-MT7981-SoC.patch | 1091 +++++++++++++++++++ ...ediatek-add-pinctrl-driver-for-MT7986-SoC.patch | 817 ++++++++++++++ ...k-add-CLK_BYPASS_XTAL-flag-to-allow-bypas.patch | 69 ++ ...k-add-support-to-configure-clock-driver-p.patch | 198 ++++ ...k-mediatek-add-infrasys-clock-mux-support.patch | 136 +++ ...tek-add-CLK_XTAL-support-for-clock-driver.patch | 46 + ...k-add-clock-driver-support-for-MediaTek-M.patch | 955 ++++++++++++++++ ...k-add-clock-driver-support-for-MediaTek-M.patch | 984 +++++++++++++++++ ...mage-split-gfh-header-verification-into-a.patch | 89 ++ ...mage-split-the-code-of-generating-NAND-he.patch | 821 ++++++++++++++ ...mage-add-support-for-nand-headers-used-by.patch | 702 ++++++++++++ ...-update-maintainer-for-MediaTek-ARM-platf.patch | 42 + .../patches/200-cmd-add-imsz-and-imszb.patch | 4 +- ...01-mt7622-generic-reset-button-ignore-env.patch | 4 +- .../patches/410-add-linksys-e8450.patch | 2 +- .../patches/412-add-ubnt-unifi-6-lr.patch | 2 +- 36 files changed, 12173 insertions(+), 6 deletions(-) create mode 100644 package/boot/uboot-mediatek/patches/002-0001-arm-mediatek-add-support-for-MediaTek-MT7986-SoC.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0002-arm-mediatek-add-support-for-MediaTek-MT7981-SoC.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0003-board-mediatek-add-MT7986-reference-boards.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0004-board-mediatek-add-MT7981-reference-boards.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0005-mmc-mediatek-add-support-for-MediaTek-MT7891-MT7986-.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0006-net-mediatek-use-a-struct-to-cover-variations-of-all.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0007-net-mediatek-stop-using-bitfileds-for-DMA-descriptor.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0008-net-mediatek-add-support-for-PDMA-v2.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0009-net-mediatek-add-support-for-MediaTek-MT7981-MT7986.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0010-serial-mtk-add-support-for-using-dynamic-baud-clock-.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0011-arm-dts-mt7622-force-high-speed-mode-for-uart.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0012-pwm-mtk-add-support-for-MediaTek-MT7986-SoC.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0013-pwm-mtk-add-support-for-MediaTek-MT7981-SoC.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0014-timer-mtk-add-support-for-MediaTek-MT7981-MT7986-SoC.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0015-watchdog-mediatek-add-support-for-MediaTek-MT7986-So.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0016-spi-add-support-for-MediaTek-spi-mem-controller.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0017-i2c-add-support-for-MediaTek-I2C-interface.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0018-arm-dts-mt7622-add-i2c-support.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0019-dt-bindings-pinctrl-mediatek-add-a-header-for-common.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0020-pinctrl-mediatek-add-pinctrl-driver-for-MT7981-SoC.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0021-pinctrl-mediatek-add-pinctrl-driver-for-MT7986-SoC.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0022-clk-mediatek-add-CLK_BYPASS_XTAL-flag-to-allow-bypas.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0023-clk-mediatek-add-support-to-configure-clock-driver-p.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0024-clk-mediatek-add-infrasys-clock-mux-support.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0025-clk-mediatek-add-CLK_XTAL-support-for-clock-driver.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0026-clk-mediatek-add-clock-driver-support-for-MediaTek-M.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0027-clk-mediatek-add-clock-driver-support-for-MediaTek-M.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0028-tools-mtk_image-split-gfh-header-verification-into-a.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0029-tools-mtk_image-split-the-code-of-generating-NAND-he.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0030-tools-mtk_image-add-support-for-nand-headers-used-by.patch create mode 100644 package/boot/uboot-mediatek/patches/002-0031-MAINTAINERS-update-maintainer-for-MediaTek-ARM-platf.patch (limited to 'package') diff --git a/package/boot/uboot-mediatek/Makefile b/package/boot/uboot-mediatek/Makefile index a8add7ef94..c89fb197ae 100644 --- a/package/boot/uboot-mediatek/Makefile +++ b/package/boot/uboot-mediatek/Makefile @@ -175,6 +175,14 @@ define U-Boot/mt7629_rfb UBOOT_CONFIG:=mt7629_rfb endef +define U-Boot/mt7986_rfb + NAME:=MT7986 Reference Board + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=mediatek_mt7986-rfb + UBOOT_CONFIG:=mt7986_rfb + UBOOT_IMAGE:=u-boot.bin +endef + UBOOT_TARGETS := \ mt7620_mt7530_rfb \ mt7620_rfb \ @@ -190,7 +198,8 @@ UBOOT_TARGETS := \ mt7623a_unielec_u7623 \ mt7628_rfb \ ravpower_rp-wd009 \ - mt7629_rfb + mt7629_rfb \ + mt7986_rfb ifdef CONFIG_TARGET_mediatek UBOOT_MAKE_FLAGS += $(UBOOT_IMAGE:.fip=.bin) diff --git a/package/boot/uboot-mediatek/patches/002-0001-arm-mediatek-add-support-for-MediaTek-MT7986-SoC.patch b/package/boot/uboot-mediatek/patches/002-0001-arm-mediatek-add-support-for-MediaTek-MT7986-SoC.patch new file mode 100644 index 0000000000..663f06c22c --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0001-arm-mediatek-add-support-for-MediaTek-MT7986-SoC.patch @@ -0,0 +1,552 @@ +From a299de45833df13d4ec28092201ea5fec0ba24fe Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 15:17:58 +0800 +Subject: [PATCH 01/31] arm: mediatek: add support for MediaTek MT7986 SoC + +This patch adds basic support for MediaTek MT7986 SoC. +This include the file that will initialize the SoC after boot and its +device tree. + +Signed-off-by: Weijie Gao +--- + arch/arm/dts/mt7986-u-boot.dtsi | 33 ++ + arch/arm/dts/mt7986.dtsi | 341 ++++++++++++++++++ + arch/arm/mach-mediatek/Kconfig | 11 + + arch/arm/mach-mediatek/Makefile | 1 + + arch/arm/mach-mediatek/mt7986/Makefile | 4 + + arch/arm/mach-mediatek/mt7986/init.c | 51 +++ + arch/arm/mach-mediatek/mt7986/lowlevel_init.S | 32 ++ + 7 files changed, 473 insertions(+) + create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi + create mode 100644 arch/arm/dts/mt7986.dtsi + create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile + create mode 100644 arch/arm/mach-mediatek/mt7986/init.c + create mode 100644 arch/arm/mach-mediatek/mt7986/lowlevel_init.S + +--- /dev/null ++++ b/arch/arm/dts/mt7986-u-boot.dtsi +@@ -0,0 +1,33 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++&topckgen { ++ u-boot,dm-pre-reloc; ++}; ++ ++&pericfg { ++ u-boot,dm-pre-reloc; ++}; ++ ++&apmixedsys { ++ u-boot,dm-pre-reloc; ++}; ++ ++&timer0 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&uart0 { ++ u-boot,dm-pre-reloc; ++}; ++ ++&snand { ++ u-boot,dm-pre-reloc; ++}; ++ ++&pinctrl { ++ u-boot,dm-pre-reloc; ++}; +--- /dev/null ++++ b/arch/arm/dts/mt7986.dtsi +@@ -0,0 +1,341 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/ { ++ compatible = "mediatek,mt7986"; ++ interrupt-parent = <&gic>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ config { ++ u-boot,mmc-env-partition = "u-boot-env"; ++ }; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a53"; ++ reg = <0x0>; ++ }; ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a53"; ++ reg = <0x1>; ++ }; ++ cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a53"; ++ reg = <0x1>; ++ }; ++ cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a53"; ++ reg = <0x1>; ++ }; ++ }; ++ ++ dummy_clk: dummy12m { ++ compatible = "fixed-clock"; ++ clock-frequency = <12000000>; ++ #clock-cells = <0>; ++ /* must need this line, or uart uanable to get dummy_clk */ ++ u-boot,dm-pre-reloc; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupt-parent = <&gic>; ++ clock-frequency = <13000000>; ++ interrupts = , ++ , ++ , ++ ; ++ arm,cpu-registers-not-fw-configured; ++ }; ++ ++ timer0: timer@10008000 { ++ compatible = "mediatek,mt7986-timer"; ++ reg = <0x10008000 0x1000>; ++ interrupts = ; ++ clocks = <&infracfg CK_INFRA_CK_F26M>; ++ clock-names = "gpt-clk"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ watchdog: watchdog@1001c000 { ++ compatible = "mediatek,mt7986-wdt"; ++ reg = <0x1001c000 0x1000>; ++ interrupts = ; ++ #reset-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ gic: interrupt-controller@c000000 { ++ compatible = "arm,gic-v3"; ++ #interrupt-cells = <3>; ++ interrupt-parent = <&gic>; ++ interrupt-controller; ++ reg = <0x0c000000 0x40000>, /* GICD */ ++ <0x0c080000 0x200000>; /* GICR */ ++ ++ interrupts = ; ++ }; ++ ++ fixed_plls: apmixedsys@1001E000 { ++ compatible = "mediatek,mt7986-fixed-plls"; ++ reg = <0x1001E000 0x1000>; ++ #clock-cells = <1>; ++ }; ++ ++ topckgen: topckgen@1001B000 { ++ compatible = "mediatek,mt7986-topckgen"; ++ reg = <0x1001B000 0x1000>; ++ clock-parent = <&fixed_plls>; ++ #clock-cells = <1>; ++ }; ++ ++ infracfg_ao: infracfg_ao@10001000 { ++ compatible = "mediatek,mt7986-infracfg_ao"; ++ reg = <0x10001000 0x68>; ++ clock-parent = <&infracfg>; ++ #clock-cells = <1>; ++ }; ++ ++ infracfg: infracfg@10001040 { ++ compatible = "mediatek,mt7986-infracfg"; ++ reg = <0x10001000 0x1000>; ++ clock-parent = <&topckgen>; ++ #clock-cells = <1>; ++ }; ++ ++ pinctrl: pinctrl@1001f000 { ++ compatible = "mediatek,mt7986-pinctrl"; ++ reg = <0x1001f000 0x1000>, ++ <0x11c30000 0x1000>, ++ <0x11c40000 0x1000>, ++ <0x11e20000 0x1000>, ++ <0x11e30000 0x1000>, ++ <0x11f00000 0x1000>, ++ <0x11f10000 0x1000>, ++ <0x1000b000 0x1000>; ++ reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rb_base", ++ "iocfg_lt_base", "iocfg_lb_base", "iocfg_tr_base", ++ "iocfg_tl_base", "eint"; ++ gpio: gpio-controller { ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++ }; ++ ++ pwm: pwm@10048000 { ++ compatible = "mediatek,mt7986-pwm"; ++ reg = <0x10048000 0x1000>; ++ #clock-cells = <1>; ++ #pwm-cells = <2>; ++ interrupts = ; ++ clocks = <&infracfg CK_INFRA_PWM>, ++ <&infracfg_ao CK_INFRA_PWM_BSEL>, ++ <&infracfg_ao CK_INFRA_PWM1_CK>, ++ <&infracfg_ao CK_INFRA_PWM2_CK>; ++ assigned-clocks = <&topckgen CK_TOP_PWM_SEL>, ++ <&infracfg CK_INFRA_PWM_BSEL>, ++ <&infracfg CK_INFRA_PWM1_SEL>, ++ <&infracfg CK_INFRA_PWM2_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D4>, ++ <&infracfg CK_INFRA_PWM>, ++ <&infracfg CK_INFRA_PWM>, ++ <&infracfg CK_INFRA_PWM>; ++ clock-names = "top", "main", "pwm1", "pwm2"; ++ status = "disabled"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ uart0: serial@11002000 { ++ compatible = "mediatek,hsuart"; ++ reg = <0x11002000 0x400>; ++ interrupts = ; ++ clocks = <&infracfg_ao CK_INFRA_UART0_CK>; ++ assigned-clocks = <&topckgen CK_TOP_UART_SEL>, ++ <&infracfg_ao CK_INFRA_UART0_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, ++ <&infracfg CK_INFRA_UART>; ++ mediatek,force-highspeed; ++ status = "disabled"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ uart1: serial@11003000 { ++ compatible = "mediatek,hsuart"; ++ reg = <0x11003000 0x400>; ++ interrupts = ; ++ clocks = <&infracfg_ao CK_INFRA_UART1_CK>; ++ assigned-clocks = <&infracfg CK_INFRA_UART1_SEL>; ++ assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>; ++ mediatek,force-highspeed; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@11004000 { ++ compatible = "mediatek,hsuart"; ++ reg = <0x11004000 0x400>; ++ interrupts = ; ++ clocks = <&infracfg_ao CK_INFRA_UART2_CK>; ++ assigned-clocks = <&infracfg CK_INFRA_UART2_SEL>; ++ assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>; ++ mediatek,force-highspeed; ++ status = "disabled"; ++ }; ++ ++ snand: snand@11005000 { ++ compatible = "mediatek,mt7986-snand"; ++ reg = <0x11005000 0x1000>, ++ <0x11006000 0x1000>; ++ reg-names = "nfi", "ecc"; ++ clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>, ++ <&infracfg_ao CK_INFRA_NFI1_CK>, ++ <&infracfg_ao CK_INFRA_NFI_HCK_CK>; ++ clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; ++ assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>, ++ <&topckgen CK_TOP_NFI1X_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>, ++ <&topckgen CK_TOP_CB_M_D8>; ++ status = "disabled"; ++ }; ++ ++ ethsys: syscon@15000000 { ++ compatible = "mediatek,mt7986-ethsys", "syscon"; ++ reg = <0x15000000 0x1000>; ++ clock-parent = <&topckgen>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ eth: ethernet@15100000 { ++ compatible = "mediatek,mt7986-eth", "syscon"; ++ reg = <0x15100000 0x20000>; ++ resets = <ðsys ETHSYS_FE_RST>; ++ reset-names = "fe"; ++ mediatek,ethsys = <ðsys>; ++ mediatek,sgmiisys = <&sgmiisys0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ sgmiisys0: syscon@10060000 { ++ compatible = "mediatek,mt7986-sgmiisys", "syscon"; ++ reg = <0x10060000 0x1000>; ++ #clock-cells = <1>; ++ }; ++ ++ sgmiisys1: syscon@10070000 { ++ compatible = "mediatek,mt7986-sgmiisys", "syscon"; ++ reg = <0x10070000 0x1000>; ++ #clock-cells = <1>; ++ }; ++ ++ spi0: spi@1100a000 { ++ compatible = "mediatek,ipm-spi"; ++ reg = <0x1100a000 0x100>; ++ clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, ++ <&topckgen CK_TOP_SPI_SEL>; ++ assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, ++ <&infracfg CK_INFRA_SPI0_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, ++ <&topckgen CK_INFRA_ISPI0>; ++ clock-names = "sel-clk", "spi-clk"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ spi1: spi@1100b000 { ++ compatible = "mediatek,ipm-spi"; ++ reg = <0x1100b000 0x100>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ mmc0: mmc@11230000 { ++ compatible = "mediatek,mt7986-mmc"; ++ reg = <0x11230000 0x1000>, ++ <0x11C20000 0x1000>; ++ interrupts = ; ++ clocks = <&topckgen CK_TOP_EMMC_416M>, ++ <&topckgen CK_TOP_EMMC_250M>, ++ <&infracfg_ao CK_INFRA_MSDC_CK>; ++ assigned-clocks = <&topckgen CK_TOP_EMMC_416M_SEL>, ++ <&topckgen CK_TOP_EMMC_250M_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_M_416M>, ++ <&topckgen CK_TOP_NET1_D5_D2>; ++ clock-names = "source", "hclk", "source_cg"; ++ status = "disabled"; ++ }; ++ ++ xhci: xhci@11200000 { ++ compatible = "mediatek,mt7986-xhci", ++ "mediatek,mtk-xhci"; ++ reg = <0x11200000 0x2e00>, ++ <0x11203e00 0x0100>; ++ reg-names = "mac", "ippc"; ++ interrupts = ; ++ phys = <&u2port0 PHY_TYPE_USB2>, ++ <&u3port0 PHY_TYPE_USB3>, ++ <&u2port1 PHY_TYPE_USB2>; ++ clocks = <&dummy_clk>, ++ <&dummy_clk>, ++ <&dummy_clk>, ++ <&dummy_clk>, ++ <&dummy_clk>; ++ clock-names = "sys_ck", ++ "xhci_ck", ++ "ref_ck", ++ "mcu_ck", ++ "dma_ck"; ++ tpl-support; ++ status = "okay"; ++ }; ++ ++ usbtphy: usb-phy@11e10000 { ++ compatible = "mediatek,mt7986", ++ "mediatek,generic-tphy-v2"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ status = "okay"; ++ ++ u2port0: usb-phy@11e10000 { ++ reg = <0x11e10000 0x700>; ++ clocks = <&dummy_clk>; ++ clock-names = "ref"; ++ #phy-cells = <1>; ++ status = "okay"; ++ }; ++ ++ u3port0: usb-phy@11e10700 { ++ reg = <0x11e10700 0x900>; ++ clocks = <&dummy_clk>; ++ clock-names = "ref"; ++ #phy-cells = <1>; ++ status = "okay"; ++ }; ++ ++ u2port1: usb-phy@11e11000 { ++ reg = <0x11e11000 0x700>; ++ clocks = <&dummy_clk>; ++ clock-names = "ref"; ++ #phy-cells = <1>; ++ status = "okay"; ++ }; ++ }; ++}; +--- a/arch/arm/mach-mediatek/Kconfig ++++ b/arch/arm/mach-mediatek/Kconfig +@@ -40,6 +40,14 @@ config TARGET_MT7629 + including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet, + switch, USB3.0, PCIe, UART, SPI, I2C and PWM. + ++config TARGET_MT7986 ++ bool "MediaTek MT7986 SoC" ++ select ARM64 ++ help ++ The MediaTek MT7986 is a ARM64-based SoC with a quad-core Cortex-A53. ++ including UART, SPI, SPI flash, USB3.0, MMC, NAND, SNFI, PWM, PCIe, ++ Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe. ++ + config TARGET_MT8183 + bool "MediaTek MT8183 SoC" + select ARM64 +@@ -84,6 +92,7 @@ config SYS_BOARD + default "mt7622" if TARGET_MT7622 + default "mt7623" if TARGET_MT7623 + default "mt7629" if TARGET_MT7629 ++ default "mt7986" if TARGET_MT7986 + default "mt8183" if TARGET_MT8183 + default "mt8512" if TARGET_MT8512 + default "mt8516" if TARGET_MT8516 +@@ -99,6 +108,7 @@ config SYS_CONFIG_NAME + default "mt7622" if TARGET_MT7622 + default "mt7623" if TARGET_MT7623 + default "mt7629" if TARGET_MT7629 ++ default "mt7986" if TARGET_MT7986 + default "mt8183" if TARGET_MT8183 + default "mt8512" if TARGET_MT8512 + default "mt8516" if TARGET_MT8516 +@@ -113,6 +123,7 @@ config MTK_BROM_HEADER_INFO + string + default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 || TARGET_MT7622 + default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183 ++ default "media=snand;nandinfo=2k+64" if TARGET_MT7986 + default "lk=1" if TARGET_MT7623 + + endif +--- a/arch/arm/mach-mediatek/Makefile ++++ b/arch/arm/mach-mediatek/Makefile +@@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/ + obj-$(CONFIG_TARGET_MT7622) += mt7622/ + obj-$(CONFIG_TARGET_MT7623) += mt7623/ + obj-$(CONFIG_TARGET_MT7629) += mt7629/ ++obj-$(CONFIG_TARGET_MT7986) += mt7986/ + obj-$(CONFIG_TARGET_MT8183) += mt8183/ + obj-$(CONFIG_TARGET_MT8516) += mt8516/ + obj-$(CONFIG_TARGET_MT8518) += mt8518/ +--- /dev/null ++++ b/arch/arm/mach-mediatek/mt7986/Makefile +@@ -0,0 +1,4 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y += init.o ++obj-y += lowlevel_init.o +--- /dev/null ++++ b/arch/arm/mach-mediatek/mt7986/init.c +@@ -0,0 +1,51 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++int print_cpuinfo(void) ++{ ++ printf("CPU: MediaTek MT7986\n"); ++ return 0; ++} ++ ++int dram_init(void) ++{ ++ gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G); ++ ++ return 0; ++} ++ ++void reset_cpu(ulong addr) ++{ ++ psci_system_reset(); ++} ++ ++static struct mm_region mt7986_mem_map[] = { ++ { ++ /* DDR */ ++ .virt = 0x40000000UL, ++ .phys = 0x40000000UL, ++ .size = 0x80000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE, ++ }, { ++ .virt = 0x00000000UL, ++ .phys = 0x00000000UL, ++ .size = 0x40000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE | ++ PTE_BLOCK_PXN | PTE_BLOCK_UXN ++ }, { ++ 0, ++ } ++}; ++ ++struct mm_region *mem_map = mt7986_mem_map; +--- /dev/null ++++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/* ++ * Switch from AArch64 EL2 to AArch32 EL2 ++ * @param inputs: ++ * x0: argument, zero ++ * x1: machine nr ++ * x2: fdt address ++ * x3: input argument ++ * x4: kernel entry point ++ * @param outputs for secure firmware: ++ * x0: function id ++ * x1: kernel entry point ++ * x2: machine nr ++ * x3: fdt address ++ * ++ * [1] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/mediatek/common/mtk_sip_svc.c ++*/ ++ ++.global armv8_el2_to_aarch32 ++armv8_el2_to_aarch32: ++ mov x3, x2 ++ mov x2, x1 ++ mov x1, x4 ++ mov x4, #0 ++ ldr x0, =0x82000200 /* MTK_SIP_KERNEL_BOOT_AARCH32 */ ++ SMC #0 ++ ret diff --git a/package/boot/uboot-mediatek/patches/002-0002-arm-mediatek-add-support-for-MediaTek-MT7981-SoC.patch b/package/boot/uboot-mediatek/patches/002-0002-arm-mediatek-add-support-for-MediaTek-MT7981-SoC.patch new file mode 100644 index 0000000000..93596af53d --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0002-arm-mediatek-add-support-for-MediaTek-MT7981-SoC.patch @@ -0,0 +1,462 @@ +From 38faebb811868f9e6734dea7894d0fa5a61f3a22 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 15:58:11 +0800 +Subject: [PATCH 02/31] arm: mediatek: add support for MediaTek MT7981 SoC + +This patch adds basic support for MediaTek MT7981 SoC. +This include the file that will initialize the SoC after boot and its +device tree. + +Signed-off-by: Weijie Gao +--- + arch/arm/dts/mt7981.dtsi | 288 ++++++++++++++++++ + arch/arm/mach-mediatek/Kconfig | 12 +- + arch/arm/mach-mediatek/Makefile | 1 + + arch/arm/mach-mediatek/mt7981/Makefile | 4 + + arch/arm/mach-mediatek/mt7981/init.c | 51 ++++ + arch/arm/mach-mediatek/mt7981/lowlevel_init.S | 32 ++ + 6 files changed, 387 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/dts/mt7981.dtsi + create mode 100644 arch/arm/mach-mediatek/mt7981/Makefile + create mode 100644 arch/arm/mach-mediatek/mt7981/init.c + create mode 100644 arch/arm/mach-mediatek/mt7981/lowlevel_init.S + +--- /dev/null ++++ b/arch/arm/dts/mt7981.dtsi +@@ -0,0 +1,288 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/ { ++ compatible = "mediatek,mt7981"; ++ interrupt-parent = <&gic>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a53"; ++ reg = <0x0>; ++ }; ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a53"; ++ reg = <0x1>; ++ }; ++ }; ++ ++ gpt_clk: gpt_dummy20m { ++ compatible = "fixed-clock"; ++ clock-frequency = <13000000>; ++ #clock-cells = <0>; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupt-parent = <&gic>; ++ clock-frequency = <13000000>; ++ interrupts = , ++ , ++ , ++ ; ++ arm,cpu-registers-not-fw-configured; ++ }; ++ ++ timer0: timer@10008000 { ++ compatible = "mediatek,mt7986-timer"; ++ reg = <0x10008000 0x1000>; ++ interrupts = ; ++ clocks = <&gpt_clk>; ++ clock-names = "gpt-clk"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ watchdog: watchdog@1001c000 { ++ compatible = "mediatek,mt7986-wdt"; ++ reg = <0x1001c000 0x1000>; ++ interrupts = ; ++ #reset-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ gic: interrupt-controller@c000000 { ++ compatible = "arm,gic-v3"; ++ #interrupt-cells = <3>; ++ interrupt-parent = <&gic>; ++ interrupt-controller; ++ reg = <0x0c000000 0x40000>, /* GICD */ ++ <0x0c080000 0x200000>; /* GICR */ ++ ++ interrupts = ; ++ }; ++ ++ fixed_plls: apmixedsys@1001e000 { ++ compatible = "mediatek,mt7981-fixed-plls"; ++ reg = <0x1001e000 0x1000>; ++ #clock-cells = <1>; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ topckgen: topckgen@1001b000 { ++ compatible = "mediatek,mt7981-topckgen"; ++ reg = <0x1001b000 0x1000>; ++ clock-parent = <&fixed_plls>; ++ #clock-cells = <1>; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ infracfg_ao: infracfg_ao@10001000 { ++ compatible = "mediatek,mt7981-infracfg_ao"; ++ reg = <0x10001000 0x80>; ++ clock-parent = <&infracfg>; ++ #clock-cells = <1>; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ infracfg: infracfg@10001000 { ++ compatible = "mediatek,mt7981-infracfg"; ++ reg = <0x10001000 0x30>; ++ clock-parent = <&topckgen>; ++ #clock-cells = <1>; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ pinctrl: pinctrl@11d00000 { ++ compatible = "mediatek,mt7981-pinctrl"; ++ reg = <0x11d00000 0x1000>, ++ <0x11c00000 0x1000>, ++ <0x11c10000 0x1000>, ++ <0x11d20000 0x1000>, ++ <0x11e00000 0x1000>, ++ <0x11e20000 0x1000>, ++ <0x11f00000 0x1000>, ++ <0x11f10000 0x1000>, ++ <0x1000b000 0x1000>; ++ reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rm_base", ++ "iocfg_rb_base", "iocfg_lb_base", "iocfg_bl_base", ++ "iocfg_tm_base", "iocfg_tl_base", "eint"; ++ gpio: gpio-controller { ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++ }; ++ ++ pwm: pwm@10048000 { ++ compatible = "mediatek,mt7981-pwm"; ++ reg = <0x10048000 0x1000>; ++ #clock-cells = <1>; ++ #pwm-cells = <2>; ++ interrupts = ; ++ clocks = <&infracfg CK_INFRA_PWM>, ++ <&infracfg_ao CK_INFRA_PWM_BSEL>, ++ <&infracfg_ao CK_INFRA_PWM1_CK>, ++ <&infracfg_ao CK_INFRA_PWM2_CK>, ++ /* FIXME */ ++ <&infracfg_ao CK_INFRA_PWM2_CK>; ++ assigned-clocks = <&topckgen CK_TOP_PWM_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>; ++ clock-names = "top", "main", "pwm1", "pwm2", "pwm3"; ++ status = "disabled"; ++ }; ++ ++ uart0: serial@11002000 { ++ compatible = "mediatek,hsuart"; ++ reg = <0x11002000 0x400>; ++ interrupts = ; ++ clocks = <&infracfg_ao CK_INFRA_UART0_CK>; ++ assigned-clocks = <&topckgen CK_TOP_UART_SEL>, ++ <&infracfg_ao CK_INFRA_UART0_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, ++ <&infracfg CK_INFRA_UART>; ++ mediatek,force-highspeed; ++ status = "disabled"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ uart1: serial@11003000 { ++ compatible = "mediatek,hsuart"; ++ reg = <0x11003000 0x400>; ++ interrupts = ; ++ clocks = <&infracfg_ao CK_INFRA_UART1_CK>; ++ assigned-clocks = <&topckgen CK_TOP_UART_SEL>, ++ <&infracfg_ao CK_INFRA_UART1_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, ++ <&infracfg CK_INFRA_UART>; ++ mediatek,force-highspeed; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@11004000 { ++ compatible = "mediatek,hsuart"; ++ reg = <0x11004000 0x400>; ++ interrupts = ; ++ clocks = <&infracfg_ao CK_INFRA_UART2_CK>; ++ assigned-clocks = <&topckgen CK_TOP_UART_SEL>, ++ <&infracfg_ao CK_INFRA_UART2_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, ++ <&infracfg CK_INFRA_UART>; ++ mediatek,force-highspeed; ++ status = "disabled"; ++ }; ++ ++ snand: snand@11005000 { ++ compatible = "mediatek,mt7986-snand"; ++ reg = <0x11005000 0x1000>, ++ <0x11006000 0x1000>; ++ reg-names = "nfi", "ecc"; ++ clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>, ++ <&infracfg_ao CK_INFRA_NFI1_CK>, ++ <&infracfg_ao CK_INFRA_NFI_HCK_CK>; ++ clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; ++ assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>, ++ <&topckgen CK_TOP_NFI1X_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>, ++ <&topckgen CK_TOP_CB_M_D8>; ++ status = "disabled"; ++ }; ++ ++ ethsys: syscon@15000000 { ++ compatible = "mediatek,mt7981-ethsys", "syscon"; ++ reg = <0x15000000 0x1000>; ++ clock-parent = <&topckgen>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ eth: ethernet@15100000 { ++ compatible = "mediatek,mt7981-eth", "syscon"; ++ reg = <0x15100000 0x20000>; ++ resets = <ðsys ETHSYS_FE_RST>; ++ reset-names = "fe"; ++ mediatek,ethsys = <ðsys>; ++ mediatek,sgmiisys = <&sgmiisys0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ sgmiisys0: syscon@10060000 { ++ compatible = "mediatek,mt7986-sgmiisys", "syscon"; ++ reg = <0x10060000 0x1000>; ++ pn_swap; ++ #clock-cells = <1>; ++ }; ++ ++ sgmiisys1: syscon@10070000 { ++ compatible = "mediatek,mt7986-sgmiisys", "syscon"; ++ reg = <0x10070000 0x1000>; ++ #clock-cells = <1>; ++ }; ++ ++ spi0: spi@1100a000 { ++ compatible = "mediatek,ipm-spi"; ++ reg = <0x1100a000 0x100>; ++ clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, ++ <&topckgen CK_TOP_SPI_SEL>; ++ assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, ++ <&infracfg CK_INFRA_SPI0_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, ++ <&topckgen CK_INFRA_ISPI0>; ++ clock-names = "sel-clk", "spi-clk"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ spi1: spi@1100b000 { ++ compatible = "mediatek,ipm-spi"; ++ reg = <0x1100b000 0x100>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ spi2: spi@11009000 { ++ compatible = "mediatek,ipm-spi"; ++ reg = <0x11009000 0x100>; ++ clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, ++ <&topckgen CK_TOP_SPI_SEL>; ++ assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, ++ <&infracfg CK_INFRA_SPI0_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, ++ <&topckgen CK_INFRA_ISPI0>; ++ clock-names = "sel-clk", "spi-clk"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ mmc0: mmc@11230000 { ++ compatible = "mediatek,mt7981-mmc"; ++ reg = <0x11230000 0x1000>, ++ <0x11C20000 0x1000>; ++ interrupts = ; ++ clocks = <&topckgen CK_TOP_EMMC_400M>, ++ <&topckgen CK_TOP_EMMC_208M>, ++ <&infracfg_ao CK_INFRA_MSDC_CK>; ++ assigned-clocks = <&topckgen CK_TOP_EMMC_400M_SEL>, ++ <&topckgen CK_TOP_EMMC_208M_SEL>; ++ assigned-clock-parents = <&topckgen CK_TOP_CB_NET2_D2>, ++ <&topckgen CK_TOP_CB_M_D2>; ++ clock-names = "source", "hclk", "source_cg"; ++ status = "disabled"; ++ }; ++ ++}; +--- a/arch/arm/mach-mediatek/Kconfig ++++ b/arch/arm/mach-mediatek/Kconfig +@@ -40,6 +40,14 @@ config TARGET_MT7629 + including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet, + switch, USB3.0, PCIe, UART, SPI, I2C and PWM. + ++config TARGET_MT7981 ++ bool "MediaTek MT7981 SoC" ++ select ARM64 ++ help ++ The MediaTek MT7981 is a ARM64-based SoC with a dual-core Cortex-A53. ++ including UART, SPI, USB, NAND, SNFI, PWM, Gigabit Ethernet, I2C, ++ built-in Wi-Fi, and PCIe. ++ + config TARGET_MT7986 + bool "MediaTek MT7986 SoC" + select ARM64 +@@ -92,6 +100,7 @@ config SYS_BOARD + default "mt7622" if TARGET_MT7622 + default "mt7623" if TARGET_MT7623 + default "mt7629" if TARGET_MT7629 ++ default "mt7981" if TARGET_MT7981 + default "mt7986" if TARGET_MT7986 + default "mt8183" if TARGET_MT8183 + default "mt8512" if TARGET_MT8512 +@@ -108,6 +117,7 @@ config SYS_CONFIG_NAME + default "mt7622" if TARGET_MT7622 + default "mt7623" if TARGET_MT7623 + default "mt7629" if TARGET_MT7629 ++ default "mt7981" if TARGET_MT7981 + default "mt7986" if TARGET_MT7986 + default "mt8183" if TARGET_MT8183 + default "mt8512" if TARGET_MT8512 +@@ -123,7 +133,7 @@ config MTK_BROM_HEADER_INFO + string + default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 || TARGET_MT7622 + default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183 +- default "media=snand;nandinfo=2k+64" if TARGET_MT7986 ++ default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986 + default "lk=1" if TARGET_MT7623 + + endif +--- a/arch/arm/mach-mediatek/Makefile ++++ b/arch/arm/mach-mediatek/Makefile +@@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/ + obj-$(CONFIG_TARGET_MT7622) += mt7622/ + obj-$(CONFIG_TARGET_MT7623) += mt7623/ + obj-$(CONFIG_TARGET_MT7629) += mt7629/ ++obj-$(CONFIG_TARGET_MT7981) += mt7981/ + obj-$(CONFIG_TARGET_MT7986) += mt7986/ + obj-$(CONFIG_TARGET_MT8183) += mt8183/ + obj-$(CONFIG_TARGET_MT8516) += mt8516/ +--- /dev/null ++++ b/arch/arm/mach-mediatek/mt7981/Makefile +@@ -0,0 +1,4 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y += init.o ++obj-y += lowlevel_init.o +--- /dev/null ++++ b/arch/arm/mach-mediatek/mt7981/init.c +@@ -0,0 +1,51 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++int print_cpuinfo(void) ++{ ++ printf("CPU: MediaTek MT7981\n"); ++ return 0; ++} ++ ++int dram_init(void) ++{ ++ gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G); ++ ++ return 0; ++} ++ ++void reset_cpu(ulong addr) ++{ ++ psci_system_reset(); ++} ++ ++static struct mm_region mt7981_mem_map[] = { ++ { ++ /* DDR */ ++ .virt = 0x40000000UL, ++ .phys = 0x40000000UL, ++ .size = 0x80000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE, ++ }, { ++ .virt = 0x00000000UL, ++ .phys = 0x00000000UL, ++ .size = 0x40000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE | ++ PTE_BLOCK_PXN | PTE_BLOCK_UXN ++ }, { ++ 0, ++ } ++}; ++ ++struct mm_region *mem_map = mt7981_mem_map; +--- /dev/null ++++ b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/* ++ * Switch from AArch64 EL2 to AArch32 EL2 ++ * @param inputs: ++ * x0: argument, zero ++ * x1: machine nr ++ * x2: fdt address ++ * x3: input argument ++ * x4: kernel entry point ++ * @param outputs for secure firmware: ++ * x0: function id ++ * x1: kernel entry point ++ * x2: machine nr ++ * x3: fdt address ++ * ++ * [1] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/mediatek/common/mtk_sip_svc.c ++*/ ++ ++.global armv8_el2_to_aarch32 ++armv8_el2_to_aarch32: ++ mov x3, x2 ++ mov x2, x1 ++ mov x1, x4 ++ mov x4, #0 ++ ldr x0, =0x82000200 /* MTK_SIP_KERNEL_BOOT_AARCH32 */ ++ SMC #0 ++ ret diff --git a/package/boot/uboot-mediatek/patches/002-0003-board-mediatek-add-MT7986-reference-boards.patch b/package/boot/uboot-mediatek/patches/002-0003-board-mediatek-add-MT7986-reference-boards.patch new file mode 100644 index 0000000000..8cbd57459d --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0003-board-mediatek-add-MT7986-reference-boards.patch @@ -0,0 +1,1148 @@ +From ab3f81920b4e47bd2894388540363700d5b1e59c Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 15:26:31 +0800 +Subject: [PATCH 03/31] board: mediatek: add MT7986 reference boards + +Add general board files based on MT7986 SoCs. + +MT7986 uses one mmc controller for booting from both SD and eMMC. +Both MT7986A and MT7986B use the same pins for spi controller. + +Configs for various boot types: +1. mt7986_rfb_defconfig - SPI-NOR and SPI-NAND for MT7986A/B +2. mt7986a_bpir3_emmc_defconfig - eMMC for MT7986A only +3. mt7986a_bpir3_sd_defconfig - SD for MT7986A only + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + arch/arm/dts/Makefile | 6 + + arch/arm/dts/mt7986a-emmc-rfb.dts | 16 ++ + arch/arm/dts/mt7986a-rfb.dts | 218 +++++++++++++++++++++++++++ + arch/arm/dts/mt7986a-sd-rfb.dts | 177 ++++++++++++++++++++++ + arch/arm/dts/mt7986b-emmc-rfb.dts | 16 ++ + arch/arm/dts/mt7986b-rfb.dts | 204 +++++++++++++++++++++++++ + arch/arm/dts/mt7986b-sd-rfb.dts | 173 +++++++++++++++++++++ + board/mediatek/mt7986/MAINTAINERS | 10 ++ + board/mediatek/mt7986/Makefile | 3 + + board/mediatek/mt7986/mt7986_rfb.c | 10 ++ + configs/mt7986_rfb_defconfig | 66 ++++++++ + configs/mt7986a_bpir3_emmc_defconfig | 64 ++++++++ + configs/mt7986a_bpir3_sd_defconfig | 64 ++++++++ + include/configs/mt7986.h | 26 ++++ + 14 files changed, 1053 insertions(+) + create mode 100644 arch/arm/dts/mt7986a-emmc-rfb.dts + create mode 100644 arch/arm/dts/mt7986a-rfb.dts + create mode 100644 arch/arm/dts/mt7986a-sd-rfb.dts + create mode 100644 arch/arm/dts/mt7986b-emmc-rfb.dts + create mode 100644 arch/arm/dts/mt7986b-rfb.dts + create mode 100644 arch/arm/dts/mt7986b-sd-rfb.dts + create mode 100644 board/mediatek/mt7986/MAINTAINERS + create mode 100644 board/mediatek/mt7986/Makefile + create mode 100644 board/mediatek/mt7986/mt7986_rfb.c + create mode 100644 configs/mt7986_rfb_defconfig + create mode 100644 configs/mt7986a_bpir3_emmc_defconfig + create mode 100644 configs/mt7986a_bpir3_sd_defconfig + create mode 100644 include/configs/mt7986.h + +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -1205,6 +1205,12 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + mt7622-bananapi-bpi-r64.dtb \ + mt7623n-bananapi-bpi-r2.dtb \ + mt7629-rfb.dtb \ ++ mt7986a-rfb.dtb \ ++ mt7986b-rfb.dtb \ ++ mt7986a-sd-rfb.dtb \ ++ mt7986b-sd-rfb.dtb \ ++ mt7986a-emmc-rfb.dtb \ ++ mt7986b-emmc-rfb.dtb \ + mt8183-pumpkin.dtb \ + mt8512-bm1-emmc.dtb \ + mt8516-pumpkin.dtb \ +--- /dev/null ++++ b/arch/arm/dts/mt7986a-emmc-rfb.dts +@@ -0,0 +1,16 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7986a-rfb.dts" ++ ++/ { ++ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", ++ "mediatek,mt7986-emmc-rfb"; ++ bl2_verify { ++ bl2_compatible = "emmc"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/dts/mt7986a-rfb.dts +@@ -0,0 +1,218 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7986.dtsi" ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "mt7986-rfb"; ++ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb"; ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "sgmii"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ snfi_pins: snfi-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ ++ clk { ++ pins = "SPI0_CLK"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ conf-pu { ++ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI0_MOSI", "SPI0_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_2"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++ ++ pwm_pins: pwm0-pins-func-1 { ++ mux { ++ function = "pwm"; ++ groups = "pwm0"; ++ }; ++ }; ++ ++ mmc0_pins_default: mmc0default { ++ mux { ++ function = "flash"; ++ groups = "emmc_51"; ++ }; ++ ++ conf-cmd-dat { ++ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", ++ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", ++ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; ++ input-enable; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-clk { ++ pins = "EMMC_CK"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ conf-dsl { ++ pins = "EMMC_DSL"; ++ bias-pull-down = ; ++ }; ++ ++ conf-rst { ++ pins = "EMMC_RSTB"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ }; ++}; ++ ++&snand { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&snfi_pins>; ++ status = "okay"; ++ quad-spi; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nor@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ }; ++ ++ spi_nand@1 { ++ compatible = "spi-nand"; ++ reg = <1>; ++ spi-max-frequency = <52000000>; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ bus-width = <8>; ++ max-frequency = <52000000>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_1p8v>; ++ non-removable; ++ status = "okay"; ++}; +--- /dev/null ++++ b/arch/arm/dts/mt7986a-sd-rfb.dts +@@ -0,0 +1,177 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7986.dtsi" ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "mt7986-rfb"; ++ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", ++ "mediatek,mt7986-sd-rfb"; ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "sgmii"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_2"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++ ++ pwm_pins: pwm0-pins-func-1 { ++ mux { ++ function = "pwm"; ++ groups = "pwm0"; ++ }; ++ }; ++ ++ mmc0_pins_default: mmc0default { ++ mux { ++ function = "flash"; ++ groups = "emmc_51"; ++ }; ++ ++ conf-cmd-dat { ++ pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", ++ "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", ++ "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; ++ input-enable; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-clk { ++ pins = "EMMC_CK"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ conf-dsl { ++ pins = "EMMC_DSL"; ++ bias-pull-down = ; ++ }; ++ ++ conf-rst { ++ pins = "EMMC_RSTB"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nor@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ }; ++ ++ spi_nand@1 { ++ compatible = "spi-nand"; ++ reg = <1>; ++ spi-max-frequency = <52000000>; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ bus-width = <4>; ++ max-frequency = <52000000>; ++ cap-sd-highspeed; ++ r_smpl = <1>; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_3p3v>; ++ status = "okay"; ++}; +--- /dev/null ++++ b/arch/arm/dts/mt7986b-emmc-rfb.dts +@@ -0,0 +1,16 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7986a-rfb.dts" ++ ++/ { ++ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", ++ "mediatek,mt7986-emmc-rfb"; ++ bl2_verify { ++ bl2_compatible = "emmc"; ++ }; ++}; +--- /dev/null ++++ b/arch/arm/dts/mt7986b-rfb.dts +@@ -0,0 +1,204 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7986.dtsi" ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "mt7986-rfb"; ++ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb"; ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "sgmii"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ snfi_pins: snfi-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ ++ clk { ++ pins = "SPI0_CLK"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ conf-pu { ++ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI0_MOSI", "SPI0_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_2"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++ ++ pwm_pins: pwm0-pins-func-1 { ++ mux { ++ function = "pwm"; ++ groups = "pwm0"; ++ }; ++ }; ++ ++ mmc0_pins_default: mmc0default { ++ mux { ++ function = "flash"; ++ groups = "emmc_45"; ++ input-schmitt-enable; ++ }; ++ ++ conf-cmd-dat { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", ++ "SPI0_CS", "SPI0_HOLD", "SPI0_WP", ++ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; ++ input-enable; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-clk { ++ pins = "SPI1_CS"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ conf-rst { ++ pins = "PWM1"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ }; ++}; ++ ++&snand { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&snfi_pins>; ++ status = "okay"; ++ quad-spi; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nor@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ }; ++ ++ spi_nand@1 { ++ compatible = "spi-nand"; ++ reg = <1>; ++ spi-max-frequency = <52000000>; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ bus-width = <8>; ++ max-frequency = <52000000>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ vmmc-supply = <®_3p3v>; ++ non-removable; ++ status = "okay"; ++}; +--- /dev/null ++++ b/arch/arm/dts/mt7986b-sd-rfb.dts +@@ -0,0 +1,173 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7986.dtsi" ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "mt7986-rfb"; ++ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", ++ "mediatek,mt7986-sd-rfb"; ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "sgmii"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_2"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++ ++ pwm_pins: pwm0-pins-func-1 { ++ mux { ++ function = "pwm"; ++ groups = "pwm0"; ++ }; ++ }; ++ ++ mmc0_pins_default: mmc0default { ++ mux { ++ function = "flash"; ++ groups = "emmc_45"; ++ input-schmitt-enable; ++ }; ++ ++ conf-cmd-dat { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", ++ "SPI0_CS", "SPI0_HOLD", "SPI0_WP", ++ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; ++ input-enable; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-clk { ++ pins = "SPI1_CS"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ conf-rst { ++ pins = "PWM1"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nor@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ }; ++ ++ spi_nand@1 { ++ compatible = "spi-nand"; ++ reg = <1>; ++ spi-max-frequency = <52000000>; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ bus-width = <4>; ++ max-frequency = <52000000>; ++ cap-sd-highspeed; ++ r_smpl = <1>; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_3p3v>; ++ status = "okay"; ++}; +--- /dev/null ++++ b/board/mediatek/mt7986/MAINTAINERS +@@ -0,0 +1,10 @@ ++MT7986 ++M: Sam Shih ++S: Maintained ++F: board/mediatek/mt7986 ++F: include/configs/mt7986.h ++F: configs/mt7986_rfb_defconfig ++F: configs/mt7986a_emmc_rfb_defconfig ++F: configs/mt7986a_sd_rfb_defconfig ++F: configs/mt7986b_emmc_rfb_defconfig ++F: configs/mt7986b_sd_rfb_defconfig +--- /dev/null ++++ b/board/mediatek/mt7986/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y += mt7986_rfb.o +--- /dev/null ++++ b/board/mediatek/mt7986/mt7986_rfb.c +@@ -0,0 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++int board_init(void) ++{ ++ return 0; ++} +--- /dev/null ++++ b/configs/mt7986_rfb_defconfig +@@ -0,0 +1,66 @@ ++CONFIG_ARM=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_SYS_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7986a-rfb" ++CONFIG_TARGET_MT7986=y ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++# CONFIG_AUTOBOOT is not set ++CONFIG_DEFAULT_FDT_FILE="mt7986a-rfb" ++CONFIG_LOGLEVEL=7 ++CONFIG_LOG=y ++CONFIG_SYS_PROMPT="MT7986> " ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++# 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_CMD_ELF is not set ++# CONFIG_CMD_UNLZ4 is not set ++# CONFIG_CMD_UNZIP is not set ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_SF_TEST=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_SMC=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_CLK=y ++# CONFIG_MMC is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_DM_SPI_FLASH=y ++CONFIG_SPI_FLASH_SFDP_SUPPORT=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_SPI_FLASH_MTD=y ++CONFIG_PHY_FIXED=y ++CONFIG_DM_ETH=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7986=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_HEXDUMP=y +--- /dev/null ++++ b/configs/mt7986a_bpir3_emmc_defconfig +@@ -0,0 +1,64 @@ ++CONFIG_ARM=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_SYS_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_ENV_SIZE=0x80000 ++CONFIG_ENV_OFFSET=0x300000 ++CONFIG_DEFAULT_DEVICE_TREE="mt7986a-emmc-rfb" ++CONFIG_TARGET_MT7986=y ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++# CONFIG_AUTOBOOT is not set ++CONFIG_DEFAULT_FDT_FILE="mt7986a-emmc-rfb" ++CONFIG_LOGLEVEL=7 ++CONFIG_LOG=y ++CONFIG_SYS_PROMPT="MT7986> " ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++# 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_CMD_ELF is not set ++# CONFIG_CMD_UNLZ4 is not set ++# CONFIG_CMD_UNZIP is not set ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_GPT_RENAME=y ++CONFIG_CMD_LSBLK=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_READ=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_FAT=y ++CONFIG_CMD_FS_GENERIC=y ++CONFIG_PARTITION_TYPE_GUID=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_CLK=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_MMC_MTK=y ++CONFIG_PHY_FIXED=y ++CONFIG_DM_ETH=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7986=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_FAT_WRITE=y ++CONFIG_HEXDUMP=y ++# CONFIG_EFI_LOADER is not set +--- /dev/null ++++ b/configs/mt7986a_bpir3_sd_defconfig +@@ -0,0 +1,64 @@ ++CONFIG_ARM=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_SYS_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_ENV_SIZE=0x80000 ++CONFIG_ENV_OFFSET=0x300000 ++CONFIG_DEFAULT_DEVICE_TREE="mt7986a-sd-rfb" ++CONFIG_TARGET_MT7986=y ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++# CONFIG_AUTOBOOT is not set ++CONFIG_DEFAULT_FDT_FILE="mt7986a-sd-rfb" ++CONFIG_LOGLEVEL=7 ++CONFIG_LOG=y ++CONFIG_SYS_PROMPT="MT7986> " ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++# 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_CMD_ELF is not set ++# CONFIG_CMD_UNLZ4 is not set ++# CONFIG_CMD_UNZIP is not set ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_GPT_RENAME=y ++CONFIG_CMD_LSBLK=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_READ=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_FAT=y ++CONFIG_CMD_FS_GENERIC=y ++CONFIG_PARTITION_TYPE_GUID=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_CLK=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_MMC_MTK=y ++CONFIG_PHY_FIXED=y ++CONFIG_DM_ETH=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7986=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_FAT_WRITE=y ++CONFIG_HEXDUMP=y ++# CONFIG_EFI_LOADER is not set +--- /dev/null ++++ b/include/configs/mt7986.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Configuration for MediaTek MT7986 SoC ++ * ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#ifndef __MT7986_H ++#define __MT7986_H ++ ++#include ++ ++#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M ++#define CONFIG_SYS_MMC_ENV_DEV 0 ++ ++/* Uboot definition */ ++#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE ++ ++/* SPL -> Uboot */ ++#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE ++ ++/* DRAM */ ++#define CONFIG_SYS_SDRAM_BASE 0x40000000 ++ ++#endif diff --git a/package/boot/uboot-mediatek/patches/002-0004-board-mediatek-add-MT7981-reference-boards.patch b/package/boot/uboot-mediatek/patches/002-0004-board-mediatek-add-MT7981-reference-boards.patch new file mode 100644 index 0000000000..6e08843bdc --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0004-board-mediatek-add-MT7981-reference-boards.patch @@ -0,0 +1,779 @@ +From 89a31bfa05c384a2b4e56ddb9814633325b7feab Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 16:02:37 +0800 +Subject: [PATCH 04/31] board: mediatek: add MT7981 reference boards + +This patch adds general board files based on MT7981 SoCs. + +MT7981 uses one mmc controller for booting from both SD and eMMC, and the +pins of mmc controller are also shared with spi controller. +So three configs are need for these boot types: + +1. mt7981_rfb_defconfig - SPI-NOR and SPI-NAND +2. mt7981_emmc_rfb_defconfig - eMMC only +3. mt7981_sd_rfb_defconfig - SD only + +Signed-off-by: Weijie Gao +--- + arch/arm/dts/Makefile | 3 + + arch/arm/dts/mt7981-emmc-rfb.dts | 139 +++++++++++++++++++++++ + arch/arm/dts/mt7981-rfb.dts | 173 +++++++++++++++++++++++++++++ + arch/arm/dts/mt7981-sd-rfb.dts | 139 +++++++++++++++++++++++ + board/mediatek/mt7981/MAINTAINERS | 10 ++ + board/mediatek/mt7981/Makefile | 3 + + board/mediatek/mt7981/mt7981_rfb.c | 10 ++ + configs/mt7981_emmc_rfb_defconfig | 64 +++++++++++ + configs/mt7981_rfb_defconfig | 69 ++++++++++++ + configs/mt7981_sd_rfb_defconfig | 64 +++++++++++ + include/configs/mt7981.h | 26 +++++ + 11 files changed, 700 insertions(+) + create mode 100644 arch/arm/dts/mt7981-emmc-rfb.dts + create mode 100644 arch/arm/dts/mt7981-rfb.dts + create mode 100644 arch/arm/dts/mt7981-sd-rfb.dts + create mode 100644 board/mediatek/mt7981/MAINTAINERS + create mode 100644 board/mediatek/mt7981/Makefile + create mode 100644 board/mediatek/mt7981/mt7981_rfb.c + create mode 100644 configs/mt7981_emmc_rfb_defconfig + create mode 100644 configs/mt7981_rfb_defconfig + create mode 100644 configs/mt7981_sd_rfb_defconfig + create mode 100644 include/configs/mt7981.h + +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -1205,6 +1205,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + mt7622-bananapi-bpi-r64.dtb \ + mt7623n-bananapi-bpi-r2.dtb \ + mt7629-rfb.dtb \ ++ mt7981-rfb.dtb \ ++ mt7981-emmc-rfb.dtb \ ++ mt7981-sd-rfb.dtb \ + mt7986a-rfb.dtb \ + mt7986b-rfb.dtb \ + mt7986a-sd-rfb.dtb \ +--- /dev/null ++++ b/arch/arm/dts/mt7981-emmc-rfb.dts +@@ -0,0 +1,139 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "mt7981-rfb"; ++ compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "sgmii"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_1"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++ ++ /* pin15 as pwm0 */ ++ one_pwm_pins: one-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1"; ++ }; ++ }; ++ ++ /* pin15 as pwm0 and pin14 as pwm1 */ ++ two_pwm_pins: two-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1", "pwm1_0"; ++ }; ++ }; ++ ++ /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ ++ three_pwm_pins: three-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1", "pwm1_0", "pwm2"; ++ }; ++ }; ++ ++ mmc0_pins_default: mmc0default { ++ mux { ++ function = "flash"; ++ groups = "emmc_45"; ++ }; ++ conf-cmd-dat { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", ++ "SPI0_CS", "SPI0_HOLD", "SPI0_WP", ++ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; ++ input-enable; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ conf-clk { ++ pins = "SPI1_CS"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ conf-rst { ++ pins = "PWM0"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&two_pwm_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ bus-width = <8>; ++ max-frequency = <52000000>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ vmmc-supply = <®_3p3v>; ++ non-removable; ++ status = "okay"; ++}; +--- /dev/null ++++ b/arch/arm/dts/mt7981-rfb.dts +@@ -0,0 +1,173 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "mt7981-rfb"; ++ compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "sgmii"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ spi2_flash_pins: spi2-spi2-pins { ++ mux { ++ function = "spi"; ++ groups = "spi2", "spi2_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_1"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++ ++ /* pin15 as pwm0 */ ++ one_pwm_pins: one-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1"; ++ }; ++ }; ++ ++ /* pin15 as pwm0 and pin14 as pwm1 */ ++ two_pwm_pins: two-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1", "pwm1_0"; ++ }; ++ }; ++ ++ /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ ++ three_pwm_pins: three-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1", "pwm1_0", "pwm2"; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nand@0 { ++ compatible = "spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ }; ++}; ++ ++&spi2 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ support_quad; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nor@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <52000000>; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&two_pwm_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; +--- /dev/null ++++ b/arch/arm/dts/mt7981-sd-rfb.dts +@@ -0,0 +1,139 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++/dts-v1/; ++#include "mt7981.dtsi" ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "mt7981-rfb"; ++ compatible = "mediatek,mt7981", "mediatek,mt7981-sd-rfb"; ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "sgmii"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_1"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++ ++ /* pin15 as pwm0 */ ++ one_pwm_pins: one-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1"; ++ }; ++ }; ++ ++ /* pin15 as pwm0 and pin14 as pwm1 */ ++ two_pwm_pins: two-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1", "pwm1_0"; ++ }; ++ }; ++ ++ /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ ++ three_pwm_pins: three-pwm-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm0_1", "pwm1_0", "pwm2"; ++ }; ++ }; ++ ++ mmc0_pins_default: mmc0default { ++ mux { ++ function = "flash"; ++ groups = "emmc_45"; ++ }; ++ conf-cmd-dat { ++ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", ++ "SPI0_CS", "SPI0_HOLD", "SPI0_WP", ++ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; ++ input-enable; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ conf-clk { ++ pins = "SPI1_CS"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ conf-rst { ++ pins = "PWM0"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&two_pwm_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ bus-width = <4>; ++ max-frequency = <52000000>; ++ cap-sd-highspeed; ++ r_smpl = <0>; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_3p3v>; ++ status = "okay"; ++}; +--- /dev/null ++++ b/board/mediatek/mt7981/MAINTAINERS +@@ -0,0 +1,10 @@ ++MT7981 ++M: Sam Shih ++S: Maintained ++F: board/mediatek/mt7981 ++F: include/configs/mt7981.h ++F: configs/mt7981_emmc_rfb_defconfig ++F: configs/mt7981_rfb_defconfig ++F: configs/mt7981_sd_rfb_defconfig ++F: configs/mt7981_spim_nand_rfb_defconfig ++F: configs/mt7981_spim_nor_rfb_defconfig +--- /dev/null ++++ b/board/mediatek/mt7981/Makefile +@@ -0,0 +1,3 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-y += mt7981_rfb.o +--- /dev/null ++++ b/board/mediatek/mt7981/mt7981_rfb.c +@@ -0,0 +1,10 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++int board_init(void) ++{ ++ return 0; ++} +--- /dev/null ++++ b/configs/mt7981_emmc_rfb_defconfig +@@ -0,0 +1,64 @@ ++CONFIG_ARM=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_SYS_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_ENV_SIZE=0x80000 ++CONFIG_ENV_OFFSET=0x300000 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-emmc-rfb" ++CONFIG_TARGET_MT7981=y ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++# CONFIG_AUTOBOOT is not set ++CONFIG_DEFAULT_FDT_FILE="mt7981-emmc-rfb" ++CONFIG_LOGLEVEL=7 ++CONFIG_LOG=y ++CONFIG_SYS_PROMPT="MT7981> " ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++# 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_CMD_ELF is not set ++# CONFIG_CMD_UNLZ4 is not set ++# CONFIG_CMD_UNZIP is not set ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_GPT_RENAME=y ++CONFIG_CMD_LSBLK=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_READ=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_FAT=y ++CONFIG_CMD_FS_GENERIC=y ++CONFIG_PARTITION_TYPE_GUID=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_CLK=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_MMC_MTK=y ++CONFIG_PHY_FIXED=y ++CONFIG_DM_ETH=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_FAT_WRITE=y ++CONFIG_HEXDUMP=y ++# CONFIG_EFI_LOADER is not set +--- /dev/null ++++ b/configs/mt7981_rfb_defconfig +@@ -0,0 +1,69 @@ ++CONFIG_ARM=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_SYS_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-rfb" ++CONFIG_TARGET_MT7981=y ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++# CONFIG_AUTOBOOT is not set ++CONFIG_DEFAULT_FDT_FILE="mt7981-rfb" ++CONFIG_LOGLEVEL=7 ++CONFIG_LOG=y ++CONFIG_SYS_PROMPT="MT7981> " ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++# 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_CMD_ELF is not set ++# CONFIG_CMD_UNLZ4 is not set ++# CONFIG_CMD_UNZIP is not set ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_SF_TEST=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_SMC=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BLK=y ++CONFIG_HAVE_BLOCK_DEVICE=y ++CONFIG_CLK=y ++# CONFIG_MMC is not set ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_DM_SPI_FLASH=y ++CONFIG_SPI_FLASH_SFDP_SUPPORT=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_SPI_FLASH_MTD=y ++CONFIG_PHY_FIXED=y ++CONFIG_DM_ETH=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_HEXDUMP=y ++# CONFIG_EFI_LOADER is not set +--- /dev/null ++++ b/configs/mt7981_sd_rfb_defconfig +@@ -0,0 +1,64 @@ ++CONFIG_ARM=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_SYS_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_ENV_SIZE=0x80000 ++CONFIG_ENV_OFFSET=0x300000 ++CONFIG_DEFAULT_DEVICE_TREE="mt7981-sd-rfb" ++CONFIG_TARGET_MT7981=y ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++# CONFIG_AUTOBOOT is not set ++CONFIG_DEFAULT_FDT_FILE="mt7981-sd-rfb" ++CONFIG_LOGLEVEL=7 ++CONFIG_LOG=y ++CONFIG_SYS_PROMPT="MT7981> " ++CONFIG_SYS_CBSIZE=512 ++CONFIG_SYS_PBSIZE=1049 ++# 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_CMD_ELF is not set ++# CONFIG_CMD_UNLZ4 is not set ++# CONFIG_CMD_UNZIP is not set ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_GPT_RENAME=y ++CONFIG_CMD_LSBLK=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_PART=y ++CONFIG_CMD_READ=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_FAT=y ++CONFIG_CMD_FS_GENERIC=y ++CONFIG_PARTITION_TYPE_GUID=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_MMC=y ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_CLK=y ++CONFIG_MMC_HS200_SUPPORT=y ++CONFIG_MMC_MTK=y ++CONFIG_PHY_FIXED=y ++CONFIG_DM_ETH=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7981=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_FAT_WRITE=y ++CONFIG_HEXDUMP=y ++# CONFIG_EFI_LOADER is not set +--- /dev/null ++++ b/include/configs/mt7981.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Configuration for MediaTek MT7981 SoC ++ * ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#ifndef __MT7981_H ++#define __MT7981_H ++ ++#include ++ ++#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M ++#define CONFIG_SYS_MMC_ENV_DEV 0 ++ ++/* Uboot definition */ ++#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE ++ ++/* SPL -> Uboot */ ++#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE ++ ++/* DRAM */ ++#define CONFIG_SYS_SDRAM_BASE 0x40000000 ++ ++#endif diff --git a/package/boot/uboot-mediatek/patches/002-0005-mmc-mediatek-add-support-for-MediaTek-MT7891-MT7986-.patch b/package/boot/uboot-mediatek/patches/002-0005-mmc-mediatek-add-support-for-MediaTek-MT7891-MT7986-.patch new file mode 100644 index 0000000000..281c289c6a --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0005-mmc-mediatek-add-support-for-MediaTek-MT7891-MT7986-.patch @@ -0,0 +1,132 @@ +From 3831266fedf14ef415791a93dd03a9e637eb8b5e Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Tue, 26 Jul 2022 09:24:13 +0800 +Subject: [PATCH 05/31] mmc: mediatek: add support for MediaTek MT7891/MT7986 + SoCs + +Add eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs +Both chips support SDXC and eMMC 4.5. MT7986A supports eMMC 5.1. + +Reviewed-by: Jaehoon Chung +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/mmc/mtk-sd.c | 68 ++++++++++++++++++++++++++++++++++---------- + 1 file changed, 53 insertions(+), 15 deletions(-) + +--- a/drivers/mmc/mtk-sd.c ++++ b/drivers/mmc/mtk-sd.c +@@ -1496,7 +1496,12 @@ static void msdc_init_hw(struct msdc_hos + /* Enable data & cmd interrupts */ + writel(DATA_INTS_MASK | CMD_INTS_MASK, &host->base->msdc_inten); + +- writel(0, tune_reg); ++ if (host->top_base) { ++ writel(0, &host->top_base->emmc_top_control); ++ writel(0, &host->top_base->emmc_top_cmd); ++ } else { ++ writel(0, tune_reg); ++ } + writel(0, &host->base->msdc_iocon); + + if (host->r_smpl) +@@ -1507,9 +1512,14 @@ static void msdc_init_hw(struct msdc_hos + writel(0x403c0046, &host->base->patch_bit0); + writel(0xffff4089, &host->base->patch_bit1); + +- if (host->dev_comp->stop_clk_fix) ++ if (host->dev_comp->stop_clk_fix) { + clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M, + 3 << MSDC_PB1_STOP_DLY_S); ++ clrbits_le32(&host->base->sdc_fifo_cfg, ++ SDC_FIFO_CFG_WRVALIDSEL); ++ clrbits_le32(&host->base->sdc_fifo_cfg, ++ SDC_FIFO_CFG_RDVALIDSEL); ++ } + + if (host->dev_comp->busy_check) + clrbits_le32(&host->base->patch_bit1, (1 << 7)); +@@ -1544,15 +1554,28 @@ static void msdc_init_hw(struct msdc_hos + } + + if (host->dev_comp->data_tune) { +- setbits_le32(tune_reg, +- MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); +- clrsetbits_le32(&host->base->patch_bit0, +- MSDC_INT_DAT_LATCH_CK_SEL_M, +- host->latch_ck << +- MSDC_INT_DAT_LATCH_CK_SEL_S); ++ if (host->top_base) { ++ setbits_le32(&host->top_base->emmc_top_control, ++ PAD_DAT_RD_RXDLY_SEL); ++ clrbits_le32(&host->top_base->emmc_top_control, ++ DATA_K_VALUE_SEL); ++ setbits_le32(&host->top_base->emmc_top_cmd, ++ PAD_CMD_RD_RXDLY_SEL); ++ } else { ++ setbits_le32(tune_reg, ++ MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); ++ clrsetbits_le32(&host->base->patch_bit0, ++ MSDC_INT_DAT_LATCH_CK_SEL_M, ++ host->latch_ck << ++ MSDC_INT_DAT_LATCH_CK_SEL_S); ++ } + } else { + /* choose clock tune */ +- setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL); ++ if (host->top_base) ++ setbits_le32(&host->top_base->emmc_top_control, ++ PAD_RXDLY_SEL); ++ else ++ setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL); + } + + if (host->dev_comp->builtin_pad_ctrl) { +@@ -1604,12 +1627,6 @@ static void msdc_init_hw(struct msdc_hos + clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M, + 3 << SDC_CFG_DTOC_S); + +- if (host->dev_comp->stop_clk_fix) { +- clrbits_le32(&host->base->sdc_fifo_cfg, +- SDC_FIFO_CFG_WRVALIDSEL); +- clrbits_le32(&host->base->sdc_fifo_cfg, +- SDC_FIFO_CFG_RDVALIDSEL); +- } + + host->def_tune_para.iocon = readl(&host->base->msdc_iocon); + host->def_tune_para.pad_tune = readl(&host->base->pad_tune); +@@ -1792,6 +1809,25 @@ static const struct msdc_compatible mt76 + .enhance_rx = false + }; + ++static const struct msdc_compatible mt7986_compat = { ++ .clk_div_bits = 12, ++ .pad_tune0 = true, ++ .async_fifo = true, ++ .data_tune = true, ++ .busy_check = true, ++ .stop_clk_fix = true, ++ .enhance_rx = true, ++}; ++ ++static const struct msdc_compatible mt7981_compat = { ++ .clk_div_bits = 12, ++ .pad_tune0 = true, ++ .async_fifo = true, ++ .data_tune = true, ++ .busy_check = true, ++ .stop_clk_fix = true, ++}; ++ + static const struct msdc_compatible mt8512_compat = { + .clk_div_bits = 12, + .pad_tune0 = true, +@@ -1824,6 +1860,8 @@ static const struct udevice_id msdc_ids[ + { .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,mt7986-mmc", .data = (ulong)&mt7986_compat }, ++ { .compatible = "mediatek,mt7981-mmc", .data = (ulong)&mt7981_compat }, + { .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat }, + { .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat }, + { .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat }, diff --git a/package/boot/uboot-mediatek/patches/002-0006-net-mediatek-use-a-struct-to-cover-variations-of-all.patch b/package/boot/uboot-mediatek/patches/002-0006-net-mediatek-use-a-struct-to-cover-variations-of-all.patch new file mode 100644 index 0000000000..2a1f5892d8 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0006-net-mediatek-use-a-struct-to-cover-variations-of-all.patch @@ -0,0 +1,163 @@ +From 5c5af768c4cceaa9d7497c3e5bfbc9d1ea8b279c Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Tue, 26 Jul 2022 10:44:57 +0800 +Subject: [PATCH 06/31] net: mediatek: use a struct to cover variations of all + SoCs + +Using a single soc id to control different initialization and TX/RX flow +for all SoCs is not extensible if more hardware variations are added in +the future. + +This patch introduces a struct to replace the original mtk_soc to allow +the driver be able handle newer hardwares. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/net/mtk_eth.c | 56 ++++++++++++++++++++++++++++++------------- + drivers/net/mtk_eth.h | 25 ++++++++++++++++++- + 2 files changed, 64 insertions(+), 17 deletions(-) + +--- a/drivers/net/mtk_eth.c ++++ b/drivers/net/mtk_eth.c +@@ -142,11 +142,15 @@ enum mtk_switch { + SW_MT7531 + }; + +-enum mtk_soc { +- SOC_MT7623, +- SOC_MT7629, +- SOC_MT7622, +- SOC_MT7621 ++/* struct mtk_soc_data - This is the structure holding all differences ++ * among various plaforms ++ * @caps Flags shown the extra capability for the SoC ++ * @ana_rgc3: The offset for register ANA_RGC3 related to ++ * sgmiisys syscon ++ */ ++struct mtk_soc_data { ++ u32 caps; ++ u32 ana_rgc3; + }; + + struct mtk_eth_priv { +@@ -171,7 +175,7 @@ struct mtk_eth_priv { + int (*mmd_write)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg, + u16 val); + +- enum mtk_soc soc; ++ const struct mtk_soc_data *soc; + int gmac_id; + int force_mode; + int speed; +@@ -679,7 +683,7 @@ static int mt7530_setup(struct mtk_eth_p + u32 val, txdrv; + int i; + +- if (priv->soc != SOC_MT7621) { ++ if (!MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) { + /* Select 250MHz clk for RGMII mode */ + mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG, + ETHSYS_TRGMII_CLK_SEL362_5, 0); +@@ -1108,9 +1112,8 @@ static int mtk_phy_probe(struct udevice + static void mtk_sgmii_init(struct mtk_eth_priv *priv) + { + /* Set SGMII GEN2 speed(2.5G) */ +- clrsetbits_le32(priv->sgmii_base + ((priv->soc == SOC_MT7622) ? +- SGMSYS_GEN2_SPEED : SGMSYS_GEN2_SPEED_V2), +- SGMSYS_SPEED_2500, SGMSYS_SPEED_2500); ++ setbits_le32(priv->sgmii_base + priv->soc->ana_rgc3, ++ SGMSYS_SPEED_2500); + + /* Disable SGMII AN */ + clrsetbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1, +@@ -1182,7 +1185,8 @@ static void mtk_mac_init(struct mtk_eth_ + mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr); + } + +- if (priv->soc == SOC_MT7623) { ++ if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC1_TRGMII) && ++ !MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) { + /* Lower Tx Driving for TRGMII path */ + for (i = 0 ; i < NUM_TRGMII_CTRL; i++) + mtk_gmac_write(priv, GMAC_TRGMII_TD_ODT(i), +@@ -1431,7 +1435,11 @@ static int mtk_eth_of_to_plat(struct ude + ofnode subnode; + int ret; + +- priv->soc = dev_get_driver_data(dev); ++ priv->soc = (const struct mtk_soc_data *)dev_get_driver_data(dev); ++ if (!priv->soc) { ++ dev_err(dev, "missing soc compatible data\n"); ++ return -EINVAL; ++ } + + pdata->iobase = (phys_addr_t)dev_remap_addr(dev); + +@@ -1544,11 +1552,27 @@ static int mtk_eth_of_to_plat(struct ude + return 0; + } + ++static const struct mtk_soc_data mt7629_data = { ++ .ana_rgc3 = 0x128, ++}; ++ ++static const struct mtk_soc_data mt7623_data = { ++ .caps = MT7623_CAPS, ++}; ++ ++static const struct mtk_soc_data mt7622_data = { ++ .ana_rgc3 = 0x2028, ++}; ++ ++static const struct mtk_soc_data mt7621_data = { ++ .caps = MT7621_CAPS, ++}; ++ + 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 }, ++ { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data }, ++ { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data }, ++ { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data }, ++ { .compatible = "mediatek,mt7621-eth", .data = (ulong)&mt7621_data }, + {} + }; + +--- a/drivers/net/mtk_eth.h ++++ b/drivers/net/mtk_eth.h +@@ -9,8 +9,31 @@ + #ifndef _MTK_ETH_H_ + #define _MTK_ETH_H_ + +-/* Frame Engine Register Bases */ + #include ++ ++enum mkt_eth_capabilities { ++ MTK_TRGMII_BIT, ++ MTK_TRGMII_MT7621_CLK_BIT, ++ ++ /* PATH BITS */ ++ MTK_ETH_PATH_GMAC1_TRGMII_BIT, ++}; ++ ++#define MTK_TRGMII BIT(MTK_TRGMII_BIT) ++#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) ++ ++/* Supported path present on SoCs */ ++#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT) ++ ++#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) ++ ++#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) ++ ++#define MT7621_CAPS (MTK_GMAC1_TRGMII | MTK_TRGMII_MT7621_CLK) ++ ++#define MT7623_CAPS (MTK_GMAC1_TRGMII) ++ ++/* Frame Engine Register Bases */ + #define PDMA_BASE 0x0800 + #define GDMA1_BASE 0x0500 + #define GDMA2_BASE 0x1500 diff --git a/package/boot/uboot-mediatek/patches/002-0007-net-mediatek-stop-using-bitfileds-for-DMA-descriptor.patch b/package/boot/uboot-mediatek/patches/002-0007-net-mediatek-stop-using-bitfileds-for-DMA-descriptor.patch new file mode 100644 index 0000000000..3cf45b7f3e --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0007-net-mediatek-stop-using-bitfileds-for-DMA-descriptor.patch @@ -0,0 +1,317 @@ +From b978c067075fddbac341bf551ebef29e78767b75 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 09:32:29 +0800 +Subject: [PATCH 07/31] net: mediatek: stop using bitfileds for DMA descriptors + +This patch is a preparation for adding a new version of PDMA of which the +DMA descriptor fields has changed. Using bitfields will result in a complex +modification. Convert bitfields to u32 units can solve this problem easily. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/net/mtk_eth.c | 144 ++++++++++++++---------------------------- + drivers/net/mtk_eth.h | 32 ++++++++++ + 2 files changed, 80 insertions(+), 96 deletions(-) + +--- a/drivers/net/mtk_eth.c ++++ b/drivers/net/mtk_eth.c +@@ -65,77 +65,6 @@ + (DP_DISCARD << MC_DP_S) | \ + (DP_DISCARD << UN_DP_S)) + +-struct pdma_rxd_info1 { +- u32 PDP0; +-}; +- +-struct pdma_rxd_info2 { +- u32 PLEN1 : 14; +- u32 LS1 : 1; +- u32 UN_USED : 1; +- u32 PLEN0 : 14; +- u32 LS0 : 1; +- u32 DDONE : 1; +-}; +- +-struct pdma_rxd_info3 { +- u32 PDP1; +-}; +- +-struct pdma_rxd_info4 { +- u32 FOE_ENTRY : 14; +- u32 CRSN : 5; +- u32 SP : 3; +- u32 L4F : 1; +- u32 L4VLD : 1; +- u32 TACK : 1; +- u32 IP4F : 1; +- u32 IP4 : 1; +- u32 IP6 : 1; +- u32 UN_USED : 4; +-}; +- +-struct pdma_rxdesc { +- struct pdma_rxd_info1 rxd_info1; +- struct pdma_rxd_info2 rxd_info2; +- struct pdma_rxd_info3 rxd_info3; +- struct pdma_rxd_info4 rxd_info4; +-}; +- +-struct pdma_txd_info1 { +- u32 SDP0; +-}; +- +-struct pdma_txd_info2 { +- u32 SDL1 : 14; +- u32 LS1 : 1; +- u32 BURST : 1; +- u32 SDL0 : 14; +- u32 LS0 : 1; +- u32 DDONE : 1; +-}; +- +-struct pdma_txd_info3 { +- u32 SDP1; +-}; +- +-struct pdma_txd_info4 { +- u32 VLAN_TAG : 16; +- u32 INS : 1; +- u32 RESV : 2; +- u32 UDF : 6; +- u32 FPORT : 3; +- u32 TSO : 1; +- u32 TUI_CO : 3; +-}; +- +-struct pdma_txdesc { +- struct pdma_txd_info1 txd_info1; +- struct pdma_txd_info2 txd_info2; +- struct pdma_txd_info3 txd_info3; +- struct pdma_txd_info4 txd_info4; +-}; +- + enum mtk_switch { + SW_NONE, + SW_MT7530, +@@ -151,13 +80,15 @@ enum mtk_switch { + struct mtk_soc_data { + u32 caps; + u32 ana_rgc3; ++ u32 txd_size; ++ u32 rxd_size; + }; + + struct mtk_eth_priv { + char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN); + +- struct pdma_txdesc *tx_ring_noc; +- struct pdma_rxdesc *rx_ring_noc; ++ void *tx_ring_noc; ++ void *rx_ring_noc; + + int rx_dma_owner_idx0; + int tx_cpu_owner_idx0; +@@ -1202,14 +1133,16 @@ static void mtk_mac_init(struct mtk_eth_ + static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) + { + char *pkt_base = priv->pkt_pool; ++ struct mtk_tx_dma *txd; ++ struct mtk_rx_dma *rxd; + int i; + + mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0); + udelay(500); + +- memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct pdma_txdesc)); +- memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc)); +- memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE); ++ memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc->txd_size); ++ memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc->rxd_size); ++ memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE); + + flush_dcache_range((ulong)pkt_base, + (ulong)(pkt_base + TOTAL_PKT_BUF_SIZE)); +@@ -1218,17 +1151,21 @@ static void mtk_eth_fifo_init(struct mtk + priv->tx_cpu_owner_idx0 = 0; + + for (i = 0; i < NUM_TX_DESC; i++) { +- priv->tx_ring_noc[i].txd_info2.LS0 = 1; +- priv->tx_ring_noc[i].txd_info2.DDONE = 1; +- priv->tx_ring_noc[i].txd_info4.FPORT = priv->gmac_id + 1; ++ txd = priv->tx_ring_noc + i * priv->soc->txd_size; ++ ++ txd->txd1 = virt_to_phys(pkt_base); ++ txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0; ++ txd->txd4 = PDMA_TXD4_FPORT_SET(priv->gmac_id + 1); + +- priv->tx_ring_noc[i].txd_info1.SDP0 = virt_to_phys(pkt_base); + pkt_base += PKTSIZE_ALIGN; + } + + for (i = 0; i < NUM_RX_DESC; i++) { +- priv->rx_ring_noc[i].rxd_info2.PLEN0 = PKTSIZE_ALIGN; +- priv->rx_ring_noc[i].rxd_info1.PDP0 = virt_to_phys(pkt_base); ++ rxd = priv->rx_ring_noc + i * priv->soc->rxd_size; ++ ++ rxd->rxd1 = virt_to_phys(pkt_base); ++ rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN); ++ + pkt_base += PKTSIZE_ALIGN; + } + +@@ -1315,20 +1252,22 @@ static int mtk_eth_send(struct udevice * + { + struct mtk_eth_priv *priv = dev_get_priv(dev); + u32 idx = priv->tx_cpu_owner_idx0; ++ struct mtk_tx_dma *txd; + void *pkt_base; + +- if (!priv->tx_ring_noc[idx].txd_info2.DDONE) { ++ txd = priv->tx_ring_noc + idx * priv->soc->txd_size; ++ ++ if (!(txd->txd2 & PDMA_TXD2_DDONE)) { + debug("mtk-eth: TX DMA descriptor ring is full\n"); + return -EPERM; + } + +- pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0); ++ pkt_base = (void *)phys_to_virt(txd->txd1); + memcpy(pkt_base, packet, length); + flush_dcache_range((ulong)pkt_base, (ulong)pkt_base + + roundup(length, ARCH_DMA_MINALIGN)); + +- priv->tx_ring_noc[idx].txd_info2.SDL0 = length; +- priv->tx_ring_noc[idx].txd_info2.DDONE = 0; ++ txd->txd2 = PDMA_TXD2_LS0 | PDMA_TXD2_SDL0_SET(length); + + priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC; + mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0); +@@ -1340,16 +1279,20 @@ static int mtk_eth_recv(struct udevice * + { + struct mtk_eth_priv *priv = dev_get_priv(dev); + u32 idx = priv->rx_dma_owner_idx0; ++ struct mtk_rx_dma *rxd; + uchar *pkt_base; + u32 length; + +- if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) { ++ rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size; ++ ++ if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) { + debug("mtk-eth: RX DMA descriptor ring is empty\n"); + return -EAGAIN; + } + +- length = priv->rx_ring_noc[idx].rxd_info2.PLEN0; +- pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0); ++ length = PDMA_RXD2_PLEN0_GET(rxd->rxd2); ++ ++ pkt_base = (void *)phys_to_virt(rxd->rxd1); + invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base + + roundup(length, ARCH_DMA_MINALIGN)); + +@@ -1363,10 +1306,11 @@ static int mtk_eth_free_pkt(struct udevi + { + struct mtk_eth_priv *priv = dev_get_priv(dev); + u32 idx = priv->rx_dma_owner_idx0; ++ struct mtk_rx_dma *rxd; ++ ++ rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size; + +- priv->rx_ring_noc[idx].rxd_info2.DDONE = 0; +- priv->rx_ring_noc[idx].rxd_info2.LS0 = 0; +- priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN; ++ rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + + mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx); + priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC; +@@ -1393,11 +1337,11 @@ static int mtk_eth_probe(struct udevice + return ret; + + /* Prepare for tx/rx rings */ +- priv->tx_ring_noc = (struct pdma_txdesc *) +- noncached_alloc(sizeof(struct pdma_txdesc) * NUM_TX_DESC, ++ priv->tx_ring_noc = (void *) ++ noncached_alloc(priv->soc->txd_size * NUM_TX_DESC, + ARCH_DMA_MINALIGN); +- priv->rx_ring_noc = (struct pdma_rxdesc *) +- noncached_alloc(sizeof(struct pdma_rxdesc) * NUM_RX_DESC, ++ priv->rx_ring_noc = (void *) ++ noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC, + ARCH_DMA_MINALIGN); + + /* Set MAC mode */ +@@ -1554,18 +1498,26 @@ static int mtk_eth_of_to_plat(struct ude + + static const struct mtk_soc_data mt7629_data = { + .ana_rgc3 = 0x128, ++ .txd_size = sizeof(struct mtk_tx_dma), ++ .rxd_size = sizeof(struct mtk_rx_dma), + }; + + static const struct mtk_soc_data mt7623_data = { + .caps = MT7623_CAPS, ++ .txd_size = sizeof(struct mtk_tx_dma), ++ .rxd_size = sizeof(struct mtk_rx_dma), + }; + + static const struct mtk_soc_data mt7622_data = { + .ana_rgc3 = 0x2028, ++ .txd_size = sizeof(struct mtk_tx_dma), ++ .rxd_size = sizeof(struct mtk_rx_dma), + }; + + static const struct mtk_soc_data mt7621_data = { + .caps = MT7621_CAPS, ++ .txd_size = sizeof(struct mtk_tx_dma), ++ .rxd_size = sizeof(struct mtk_rx_dma), + }; + + static const struct udevice_id mtk_eth_ids[] = { +--- a/drivers/net/mtk_eth.h ++++ b/drivers/net/mtk_eth.h +@@ -10,6 +10,7 @@ + #define _MTK_ETH_H_ + + #include ++#include + + enum mkt_eth_capabilities { + MTK_TRGMII_BIT, +@@ -435,4 +436,35 @@ enum mkt_eth_capabilities { + #define PHY_POWER_SAVING_M 0x300 + #define PHY_POWER_SAVING_TX 0x0 + ++/* PDMA descriptors */ ++struct mtk_rx_dma { ++ unsigned int rxd1; ++ unsigned int rxd2; ++ unsigned int rxd3; ++ unsigned int rxd4; ++} __packed __aligned(4); ++ ++struct mtk_tx_dma { ++ unsigned int txd1; ++ unsigned int txd2; ++ unsigned int txd3; ++ unsigned int txd4; ++} __packed __aligned(4); ++ ++/* PDMA TXD fields */ ++#define PDMA_TXD2_DDONE BIT(31) ++#define PDMA_TXD2_LS0 BIT(30) ++#define PDMA_TXD2_SDL0_M GENMASK(29, 16) ++#define PDMA_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_TXD2_SDL0_M, (_v)) ++ ++#define PDMA_TXD4_FPORT_M GENMASK(27, 25) ++#define PDMA_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_TXD4_FPORT_M, (_v)) ++ ++/* PDMA RXD fields */ ++#define PDMA_RXD2_DDONE BIT(31) ++#define PDMA_RXD2_LS0 BIT(30) ++#define PDMA_RXD2_PLEN0_M GENMASK(29, 16) ++#define PDMA_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_RXD2_PLEN0_M, (_v)) ++#define PDMA_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_RXD2_PLEN0_M, (_v)) ++ + #endif /* _MTK_ETH_H_ */ diff --git a/package/boot/uboot-mediatek/patches/002-0008-net-mediatek-add-support-for-PDMA-v2.patch b/package/boot/uboot-mediatek/patches/002-0008-net-mediatek-add-support-for-PDMA-v2.patch new file mode 100644 index 0000000000..0fc0f4cafb --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0008-net-mediatek-add-support-for-PDMA-v2.patch @@ -0,0 +1,298 @@ +From 2f53795aac940d960bc5f3b08a730c4d480fc5f6 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 09:56:30 +0800 +Subject: [PATCH 08/31] net: mediatek: add support for PDMA v2 + +This patch adds support for PDMA v2 hardware. The PDMA v2 has extended the +DMA descriptor to 8-words, and some of its fields have changed comparing +to the v1 hardware. + +Reviewed-by: Ramon Fried +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/net/mtk_eth.c | 54 ++++++++++++++++++++++++++++++++----------- + drivers/net/mtk_eth.h | 53 +++++++++++++++++++++++++++++++++++------- + 2 files changed, 86 insertions(+), 21 deletions(-) + +--- a/drivers/net/mtk_eth.c ++++ b/drivers/net/mtk_eth.c +@@ -76,10 +76,14 @@ enum mtk_switch { + * @caps Flags shown the extra capability for the SoC + * @ana_rgc3: The offset for register ANA_RGC3 related to + * sgmiisys syscon ++ * @pdma_base: Register base of PDMA block ++ * @txd_size: Tx DMA descriptor size. ++ * @rxd_size: Rx DMA descriptor size. + */ + struct mtk_soc_data { + u32 caps; + u32 ana_rgc3; ++ u32 pdma_base; + u32 txd_size; + u32 rxd_size; + }; +@@ -130,13 +134,13 @@ struct mtk_eth_priv { + + static void mtk_pdma_write(struct mtk_eth_priv *priv, u32 reg, u32 val) + { +- writel(val, priv->fe_base + PDMA_BASE + reg); ++ writel(val, priv->fe_base + priv->soc->pdma_base + reg); + } + + static void mtk_pdma_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, + u32 set) + { +- clrsetbits_le32(priv->fe_base + PDMA_BASE + reg, clr, set); ++ clrsetbits_le32(priv->fe_base + priv->soc->pdma_base + reg, clr, set); + } + + static void mtk_gdma_write(struct mtk_eth_priv *priv, int no, u32 reg, +@@ -1133,8 +1137,8 @@ static void mtk_mac_init(struct mtk_eth_ + static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) + { + char *pkt_base = priv->pkt_pool; +- struct mtk_tx_dma *txd; +- struct mtk_rx_dma *rxd; ++ struct mtk_tx_dma_v2 *txd; ++ struct mtk_rx_dma_v2 *rxd; + int i; + + mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0); +@@ -1155,7 +1159,11 @@ static void mtk_eth_fifo_init(struct mtk + + txd->txd1 = virt_to_phys(pkt_base); + txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0; +- txd->txd4 = PDMA_TXD4_FPORT_SET(priv->gmac_id + 1); ++ ++ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) ++ txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id + 1); ++ else ++ txd->txd4 = PDMA_V1_TXD4_FPORT_SET(priv->gmac_id + 1); + + pkt_base += PKTSIZE_ALIGN; + } +@@ -1164,7 +1172,11 @@ static void mtk_eth_fifo_init(struct mtk + rxd = priv->rx_ring_noc + i * priv->soc->rxd_size; + + rxd->rxd1 = virt_to_phys(pkt_base); +- rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN); ++ ++ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) ++ rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN); ++ else ++ rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + + pkt_base += PKTSIZE_ALIGN; + } +@@ -1193,6 +1205,9 @@ static int mtk_eth_start(struct udevice + reset_deassert(&priv->rst_fe); + mdelay(10); + ++ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) ++ setbits_le32(priv->fe_base + FE_GLO_MISC_REG, PDMA_VER_V2); ++ + /* Packets forward to PDMA */ + mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU); + +@@ -1227,7 +1242,7 @@ static void mtk_eth_stop(struct udevice + TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0); + udelay(500); + +- wait_for_bit_le32(priv->fe_base + PDMA_BASE + PDMA_GLO_CFG_REG, ++ wait_for_bit_le32(priv->fe_base + priv->soc->pdma_base + PDMA_GLO_CFG_REG, + RX_DMA_BUSY | TX_DMA_BUSY, 0, 5000, 0); + } + +@@ -1252,7 +1267,7 @@ static int mtk_eth_send(struct udevice * + { + struct mtk_eth_priv *priv = dev_get_priv(dev); + u32 idx = priv->tx_cpu_owner_idx0; +- struct mtk_tx_dma *txd; ++ struct mtk_tx_dma_v2 *txd; + void *pkt_base; + + txd = priv->tx_ring_noc + idx * priv->soc->txd_size; +@@ -1267,7 +1282,10 @@ static int mtk_eth_send(struct udevice * + flush_dcache_range((ulong)pkt_base, (ulong)pkt_base + + roundup(length, ARCH_DMA_MINALIGN)); + +- txd->txd2 = PDMA_TXD2_LS0 | PDMA_TXD2_SDL0_SET(length); ++ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) ++ txd->txd2 = PDMA_TXD2_LS0 | PDMA_V2_TXD2_SDL0_SET(length); ++ else ++ txd->txd2 = PDMA_TXD2_LS0 | PDMA_V1_TXD2_SDL0_SET(length); + + priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC; + mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0); +@@ -1279,7 +1297,7 @@ static int mtk_eth_recv(struct udevice * + { + struct mtk_eth_priv *priv = dev_get_priv(dev); + u32 idx = priv->rx_dma_owner_idx0; +- struct mtk_rx_dma *rxd; ++ struct mtk_rx_dma_v2 *rxd; + uchar *pkt_base; + u32 length; + +@@ -1290,7 +1308,10 @@ static int mtk_eth_recv(struct udevice * + return -EAGAIN; + } + +- length = PDMA_RXD2_PLEN0_GET(rxd->rxd2); ++ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) ++ length = PDMA_V2_RXD2_PLEN0_GET(rxd->rxd2); ++ else ++ length = PDMA_V1_RXD2_PLEN0_GET(rxd->rxd2); + + pkt_base = (void *)phys_to_virt(rxd->rxd1); + invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base + +@@ -1306,11 +1327,14 @@ static int mtk_eth_free_pkt(struct udevi + { + struct mtk_eth_priv *priv = dev_get_priv(dev); + u32 idx = priv->rx_dma_owner_idx0; +- struct mtk_rx_dma *rxd; ++ struct mtk_rx_dma_v2 *rxd; + + rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size; + +- rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN); ++ if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) ++ rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN); ++ else ++ rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + + mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx); + priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC; +@@ -1498,24 +1522,28 @@ static int mtk_eth_of_to_plat(struct ude + + static const struct mtk_soc_data mt7629_data = { + .ana_rgc3 = 0x128, ++ .pdma_base = PDMA_V1_BASE, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), + }; + + static const struct mtk_soc_data mt7623_data = { + .caps = MT7623_CAPS, ++ .pdma_base = PDMA_V1_BASE, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), + }; + + static const struct mtk_soc_data mt7622_data = { + .ana_rgc3 = 0x2028, ++ .pdma_base = PDMA_V1_BASE, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), + }; + + static const struct mtk_soc_data mt7621_data = { + .caps = MT7621_CAPS, ++ .pdma_base = PDMA_V1_BASE, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), + }; +--- a/drivers/net/mtk_eth.h ++++ b/drivers/net/mtk_eth.h +@@ -15,6 +15,7 @@ + enum mkt_eth_capabilities { + MTK_TRGMII_BIT, + MTK_TRGMII_MT7621_CLK_BIT, ++ MTK_NETSYS_V2_BIT, + + /* PATH BITS */ + MTK_ETH_PATH_GMAC1_TRGMII_BIT, +@@ -22,6 +23,7 @@ enum mkt_eth_capabilities { + + #define MTK_TRGMII BIT(MTK_TRGMII_BIT) + #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) ++#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) + + /* Supported path present on SoCs */ + #define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT) +@@ -35,7 +37,8 @@ enum mkt_eth_capabilities { + #define MT7623_CAPS (MTK_GMAC1_TRGMII) + + /* Frame Engine Register Bases */ +-#define PDMA_BASE 0x0800 ++#define PDMA_V1_BASE 0x0800 ++#define PDMA_V2_BASE 0x6000 + #define GDMA1_BASE 0x0500 + #define GDMA2_BASE 0x1500 + #define GMAC_BASE 0x10000 +@@ -74,6 +77,8 @@ enum mkt_eth_capabilities { + #define SGMSYS_SPEED_2500 BIT(2) + + /* Frame Engine Registers */ ++#define FE_GLO_MISC_REG 0x124 ++#define PDMA_VER_V2 BIT(4) + + /* PDMA */ + #define TX_BASE_PTR_REG(n) (0x000 + (n) * 0x10) +@@ -444,6 +449,17 @@ struct mtk_rx_dma { + unsigned int rxd4; + } __packed __aligned(4); + ++struct mtk_rx_dma_v2 { ++ unsigned int rxd1; ++ unsigned int rxd2; ++ unsigned int rxd3; ++ unsigned int rxd4; ++ unsigned int rxd5; ++ unsigned int rxd6; ++ unsigned int rxd7; ++ unsigned int rxd8; ++} __packed __aligned(4); ++ + struct mtk_tx_dma { + unsigned int txd1; + unsigned int txd2; +@@ -451,20 +467,41 @@ struct mtk_tx_dma { + unsigned int txd4; + } __packed __aligned(4); + ++struct mtk_tx_dma_v2 { ++ unsigned int txd1; ++ unsigned int txd2; ++ unsigned int txd3; ++ unsigned int txd4; ++ unsigned int txd5; ++ unsigned int txd6; ++ unsigned int txd7; ++ unsigned int txd8; ++} __packed __aligned(4); ++ + /* PDMA TXD fields */ + #define PDMA_TXD2_DDONE BIT(31) + #define PDMA_TXD2_LS0 BIT(30) +-#define PDMA_TXD2_SDL0_M GENMASK(29, 16) +-#define PDMA_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_TXD2_SDL0_M, (_v)) ++#define PDMA_V1_TXD2_SDL0_M GENMASK(29, 16) ++#define PDMA_V1_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V1_TXD2_SDL0_M, (_v)) ++#define PDMA_V2_TXD2_SDL0_M GENMASK(23, 8) ++#define PDMA_V2_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V2_TXD2_SDL0_M, (_v)) ++ ++#define PDMA_V1_TXD4_FPORT_M GENMASK(27, 25) ++#define PDMA_V1_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V1_TXD4_FPORT_M, (_v)) ++#define PDMA_V2_TXD4_FPORT_M GENMASK(27, 24) ++#define PDMA_V2_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD4_FPORT_M, (_v)) + +-#define PDMA_TXD4_FPORT_M GENMASK(27, 25) +-#define PDMA_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_TXD4_FPORT_M, (_v)) ++#define PDMA_V2_TXD5_FPORT_M GENMASK(19, 16) ++#define PDMA_V2_TXD5_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD5_FPORT_M, (_v)) + + /* PDMA RXD fields */ + #define PDMA_RXD2_DDONE BIT(31) + #define PDMA_RXD2_LS0 BIT(30) +-#define PDMA_RXD2_PLEN0_M GENMASK(29, 16) +-#define PDMA_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_RXD2_PLEN0_M, (_v)) +-#define PDMA_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_RXD2_PLEN0_M, (_v)) ++#define PDMA_V1_RXD2_PLEN0_M GENMASK(29, 16) ++#define PDMA_V1_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V1_RXD2_PLEN0_M, (_v)) ++#define PDMA_V1_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V1_RXD2_PLEN0_M, (_v)) ++#define PDMA_V2_RXD2_PLEN0_M GENMASK(23, 8) ++#define PDMA_V2_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V2_RXD2_PLEN0_M, (_v)) ++#define PDMA_V2_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V2_RXD2_PLEN0_M, (_v)) + + #endif /* _MTK_ETH_H_ */ diff --git a/package/boot/uboot-mediatek/patches/002-0009-net-mediatek-add-support-for-MediaTek-MT7981-MT7986.patch b/package/boot/uboot-mediatek/patches/002-0009-net-mediatek-add-support-for-MediaTek-MT7981-MT7986.patch new file mode 100644 index 0000000000..7afd49d457 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0009-net-mediatek-add-support-for-MediaTek-MT7981-MT7986.patch @@ -0,0 +1,100 @@ +From 5e06e9a78bbc81f64fdb4c8502a8e7175d8b6216 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 10:03:17 +0800 +Subject: [PATCH 09/31] net: mediatek: add support for MediaTek MT7981/MT7986 + +This patch adds support for MediaTek MT7981 and MT7986. Both chips uses +PDMA v2. + +Reviewed-by: Ramon Fried +Signed-off-by: Weijie Gao +--- + drivers/net/mtk_eth.c | 27 +++++++++++++++++++++++++++ + drivers/net/mtk_eth.h | 5 +++++ + 2 files changed, 32 insertions(+) + +--- a/drivers/net/mtk_eth.c ++++ b/drivers/net/mtk_eth.c +@@ -115,6 +115,7 @@ struct mtk_eth_priv { + int force_mode; + int speed; + int duplex; ++ bool pn_swap; + + struct phy_device *phydev; + int phy_interface; +@@ -1057,6 +1058,12 @@ static void mtk_sgmii_init(struct mtk_et + /* SGMII force mode setting */ + writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE); + ++ /* SGMII PN SWAP setting */ ++ if (priv->pn_swap) { ++ setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL, ++ SGMII_PN_SWAP_TX_RX); ++ } ++ + /* Release PHYA power down state */ + clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL, + SGMII_PHYA_PWD, 0); +@@ -1470,6 +1477,8 @@ static int mtk_eth_of_to_plat(struct ude + dev_err(dev, "Unable to find sgmii\n"); + return -ENODEV; + } ++ ++ priv->pn_swap = ofnode_read_bool(args.node, "pn_swap"); + } + + /* check for switch first, otherwise phy will be used */ +@@ -1520,6 +1529,22 @@ static int mtk_eth_of_to_plat(struct ude + return 0; + } + ++static const struct mtk_soc_data mt7986_data = { ++ .caps = MT7986_CAPS, ++ .ana_rgc3 = 0x128, ++ .pdma_base = PDMA_V2_BASE, ++ .txd_size = sizeof(struct mtk_tx_dma_v2), ++ .rxd_size = sizeof(struct mtk_rx_dma_v2), ++}; ++ ++static const struct mtk_soc_data mt7981_data = { ++ .caps = MT7986_CAPS, ++ .ana_rgc3 = 0x128, ++ .pdma_base = PDMA_V2_BASE, ++ .txd_size = sizeof(struct mtk_tx_dma_v2), ++ .rxd_size = sizeof(struct mtk_rx_dma_v2), ++}; ++ + static const struct mtk_soc_data mt7629_data = { + .ana_rgc3 = 0x128, + .pdma_base = PDMA_V1_BASE, +@@ -1549,6 +1574,8 @@ static const struct mtk_soc_data mt7621_ + }; + + static const struct udevice_id mtk_eth_ids[] = { ++ { .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data }, ++ { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data }, + { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data }, + { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data }, + { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data }, +--- a/drivers/net/mtk_eth.h ++++ b/drivers/net/mtk_eth.h +@@ -36,6 +36,8 @@ enum mkt_eth_capabilities { + + #define MT7623_CAPS (MTK_GMAC1_TRGMII) + ++#define MT7986_CAPS (MTK_NETSYS_V2) ++ + /* Frame Engine Register Bases */ + #define PDMA_V1_BASE 0x0800 + #define PDMA_V2_BASE 0x6000 +@@ -72,6 +74,9 @@ enum mkt_eth_capabilities { + #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 + #define SGMII_PHYA_PWD BIT(4) + ++#define SGMSYS_QPHY_WRAP_CTRL 0xec ++#define SGMII_PN_SWAP_TX_RX 0x03 ++ + #define SGMSYS_GEN2_SPEED 0x2028 + #define SGMSYS_GEN2_SPEED_V2 0x128 + #define SGMSYS_SPEED_2500 BIT(2) diff --git a/package/boot/uboot-mediatek/patches/002-0010-serial-mtk-add-support-for-using-dynamic-baud-clock-.patch b/package/boot/uboot-mediatek/patches/002-0010-serial-mtk-add-support-for-using-dynamic-baud-clock-.patch new file mode 100644 index 0000000000..ff7f66f067 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0010-serial-mtk-add-support-for-using-dynamic-baud-clock-.patch @@ -0,0 +1,202 @@ +From 55ed87efb110d13fce6d1a7ee6cb04fac1a2c08a Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 10:28:05 +0800 +Subject: [PATCH 10/31] serial: mtk: add support for using dynamic baud clock + souce + +The baud clock on some platform may change due to assigned-clock-parent +set in DT. In current flow the baud clock is only retrieved during probe +stage. If the parent of the source clock changes after probe stage, the +setbrg will set wrong baudrate. + +To get the right clock rate, this patch records the baud clk struct to the +driver's priv, and changes the driver's flow to get the clock rate before +calling _mtk_serial_setbrg(). + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/serial/serial_mtk.c | 80 ++++++++++++++++++++++--------------- + 1 file changed, 47 insertions(+), 33 deletions(-) + +--- a/drivers/serial/serial_mtk.c ++++ b/drivers/serial/serial_mtk.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -70,27 +71,37 @@ struct mtk_serial_regs { + #define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100) + #define BAUD_ALLOW_MIX(baud) ((baud) - (baud) * 3 / 100) + ++/* struct mtk_serial_priv - Structure holding all information used by the ++ * driver ++ * @regs: Register base of the serial port ++ * @clk: The baud clock device ++ * @fixed_clk_rate: Fallback fixed baud clock rate if baud clock ++ * device is not specified ++ * @force_highspeed: Force using high-speed mode ++ */ + struct mtk_serial_priv { + struct mtk_serial_regs __iomem *regs; +- u32 clock; ++ struct clk clk; ++ u32 fixed_clk_rate; + bool force_highspeed; + }; + +-static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud) ++static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud, ++ uint clk_rate) + { + u32 quot, realbaud, samplecount = 1; + + /* Special case for low baud clock */ +- if (baud <= 115200 && priv->clock <= 12000000) { ++ if (baud <= 115200 && clk_rate == 12000000) { + writel(3, &priv->regs->highspeed); + +- quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud); ++ quot = DIV_ROUND_CLOSEST(clk_rate, 256 * baud); + if (quot == 0) + quot = 1; + +- samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud); ++ samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud); + +- realbaud = priv->clock / samplecount / quot; ++ realbaud = clk_rate / samplecount / quot; + if (realbaud > BAUD_ALLOW_MAX(baud) || + realbaud < BAUD_ALLOW_MIX(baud)) { + pr_info("baud %d can't be handled\n", baud); +@@ -104,7 +115,7 @@ static void _mtk_serial_setbrg(struct mt + + if (baud <= 115200) { + writel(0, &priv->regs->highspeed); +- quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud); ++ quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud); + } else if (baud <= 576000) { + writel(2, &priv->regs->highspeed); + +@@ -112,13 +123,13 @@ static void _mtk_serial_setbrg(struct mt + if ((baud == 500000) || (baud == 576000)) + baud = 460800; + +- quot = DIV_ROUND_UP(priv->clock, 4 * baud); ++ quot = DIV_ROUND_UP(clk_rate, 4 * baud); + } else { + use_hs3: + writel(3, &priv->regs->highspeed); + +- quot = DIV_ROUND_UP(priv->clock, 256 * baud); +- samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud); ++ quot = DIV_ROUND_UP(clk_rate, 256 * baud); ++ samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud); + } + + set_baud: +@@ -167,8 +178,13 @@ static int _mtk_serial_pending(struct mt + static int mtk_serial_setbrg(struct udevice *dev, int baudrate) + { + struct mtk_serial_priv *priv = dev_get_priv(dev); ++ u32 clk_rate; ++ ++ clk_rate = clk_get_rate(&priv->clk); ++ if (IS_ERR_VALUE(clk_rate) || clk_rate == 0) ++ clk_rate = priv->fixed_clk_rate; + +- _mtk_serial_setbrg(priv, baudrate); ++ _mtk_serial_setbrg(priv, baudrate, clk_rate); + + return 0; + } +@@ -211,7 +227,6 @@ static int mtk_serial_of_to_plat(struct + { + struct mtk_serial_priv *priv = dev_get_priv(dev); + fdt_addr_t addr; +- struct clk clk; + int err; + + addr = dev_read_addr(dev); +@@ -220,22 +235,19 @@ static int mtk_serial_of_to_plat(struct + + priv->regs = map_physmem(addr, 0, MAP_NOCACHE); + +- err = clk_get_by_index(dev, 0, &clk); +- if (!err) { +- err = clk_get_rate(&clk); +- if (!IS_ERR_VALUE(err)) +- priv->clock = err; +- } else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) { +- debug("mtk_serial: failed to get clock\n"); +- return err; +- } +- +- if (!priv->clock) +- priv->clock = dev_read_u32_default(dev, "clock-frequency", 0); +- +- if (!priv->clock) { +- debug("mtk_serial: clock not defined\n"); +- return -EINVAL; ++ err = clk_get_by_index(dev, 0, &priv->clk); ++ if (err) { ++ err = dev_read_u32(dev, "clock-frequency", &priv->fixed_clk_rate); ++ if (err) { ++ dev_err(dev, "baud clock not defined\n"); ++ return -EINVAL; ++ } ++ } else { ++ err = clk_get_rate(&priv->clk); ++ if (IS_ERR_VALUE(err)) { ++ dev_err(dev, "invalid baud clock\n"); ++ return -EINVAL; ++ } + } + + priv->force_highspeed = dev_read_bool(dev, "mediatek,force-highspeed"); +@@ -273,7 +285,7 @@ DECLARE_GLOBAL_DATA_PTR; + #define DECLARE_HSUART_PRIV(port) \ + static struct mtk_serial_priv mtk_hsuart##port = { \ + .regs = (struct mtk_serial_regs *)CONFIG_SYS_NS16550_COM##port, \ +- .clock = CONFIG_SYS_NS16550_CLK \ ++ .fixed_clk_rate = CONFIG_SYS_NS16550_CLK \ + }; + + #define DECLARE_HSUART_FUNCTIONS(port) \ +@@ -282,12 +294,14 @@ DECLARE_GLOBAL_DATA_PTR; + writel(0, &mtk_hsuart##port.regs->ier); \ + writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \ + writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \ +- _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ ++ _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \ ++ mtk_hsuart##port.fixed_clk_rate); \ + return 0 ; \ + } \ + static void mtk_serial##port##_setbrg(void) \ + { \ +- _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ ++ _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \ ++ mtk_hsuart##port.fixed_clk_rate); \ + } \ + static int mtk_serial##port##_getc(void) \ + { \ +@@ -427,13 +441,13 @@ static inline void _debug_uart_init(void + struct mtk_serial_priv priv; + + priv.regs = (void *) CONFIG_DEBUG_UART_BASE; +- priv.clock = CONFIG_DEBUG_UART_CLOCK; ++ priv.fixed_clk_rate = CONFIG_DEBUG_UART_CLOCK; + + writel(0, &priv.regs->ier); + writel(UART_MCRVAL, &priv.regs->mcr); + writel(UART_FCRVAL, &priv.regs->fcr); + +- _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE); ++ _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE, priv.fixed_clk_rate); + } + + static inline void _debug_uart_putc(int ch) diff --git a/package/boot/uboot-mediatek/patches/002-0011-arm-dts-mt7622-force-high-speed-mode-for-uart.patch b/package/boot/uboot-mediatek/patches/002-0011-arm-dts-mt7622-force-high-speed-mode-for-uart.patch new file mode 100644 index 0000000000..085d66776f --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0011-arm-dts-mt7622-force-high-speed-mode-for-uart.patch @@ -0,0 +1,26 @@ +From 893368e64049fd770e55fffcc8758d2619dc337d Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Mon, 25 Jul 2022 16:33:13 +0800 +Subject: [PATCH 11/31] arm: dts: mt7622: force high-speed mode for uart + +The input clock for uart is too slow (25MHz) which introduces frequent data +error on both receiving and transmitting even if the baudrate is 115200. + +Using high-speed can significantly solve this issue. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + arch/arm/dts/mt7622.dtsi | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/dts/mt7622.dtsi ++++ b/arch/arm/dts/mt7622.dtsi +@@ -191,6 +191,7 @@ + status = "disabled"; + assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>; ++ mediatek,force-highspeed; + }; + + mmc0: mmc@11230000 { diff --git a/package/boot/uboot-mediatek/patches/002-0012-pwm-mtk-add-support-for-MediaTek-MT7986-SoC.patch b/package/boot/uboot-mediatek/patches/002-0012-pwm-mtk-add-support-for-MediaTek-MT7986-SoC.patch new file mode 100644 index 0000000000..a19b69a53c --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0012-pwm-mtk-add-support-for-MediaTek-MT7986-SoC.patch @@ -0,0 +1,32 @@ +From 63acbf4ffe328809ca479e5c7d344882810d412c Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 11:00:15 +0800 +Subject: [PATCH 12/31] pwm: mtk: add support for MediaTek MT7986 SoC + +This patch adds PWM support for MediaTek MT7986 SoC. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/pwm/pwm-mtk.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/pwm/pwm-mtk.c ++++ b/drivers/pwm/pwm-mtk.c +@@ -171,10 +171,16 @@ static const struct mtk_pwm_soc mt7629_d + .pwm45_fixup = false, + }; + ++static const struct mtk_pwm_soc mt7986_data = { ++ .num_pwms = 2, ++ .pwm45_fixup = false, ++}; ++ + static const struct udevice_id mtk_pwm_ids[] = { + { .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data }, + { .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data }, + { .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data }, ++ { .compatible = "mediatek,mt7986-pwm", .data = (ulong)&mt7986_data }, + { } + }; + diff --git a/package/boot/uboot-mediatek/patches/002-0013-pwm-mtk-add-support-for-MediaTek-MT7981-SoC.patch b/package/boot/uboot-mediatek/patches/002-0013-pwm-mtk-add-support-for-MediaTek-MT7981-SoC.patch new file mode 100644 index 0000000000..2da5b960a3 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0013-pwm-mtk-add-support-for-MediaTek-MT7981-SoC.patch @@ -0,0 +1,99 @@ +From 4569ef02981f20b236a8cdc3a57b4d27fbdbc22e Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 11:01:34 +0800 +Subject: [PATCH 13/31] pwm: mtk: add support for MediaTek MT7981 SoC + +This patch adds PWM support for MediaTek MT7981 SoC. +MT7981 uses a different register offset so we have to add a version field +to indicate the IP core version. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/pwm/pwm-mtk.c | 34 ++++++++++++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) + +--- a/drivers/pwm/pwm-mtk.c ++++ b/drivers/pwm/pwm-mtk.c +@@ -29,13 +29,23 @@ + + #define NSEC_PER_SEC 1000000000L + +-static const unsigned int mtk_pwm_reg_offset[] = { ++enum mtk_pwm_reg_ver { ++ PWM_REG_V1, ++ PWM_REG_V2, ++}; ++ ++static const unsigned int mtk_pwm_reg_offset_v1[] = { + 0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220 + }; + ++static const unsigned int mtk_pwm_reg_offset_v2[] = { ++ 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240 ++}; ++ + struct mtk_pwm_soc { + unsigned int num_pwms; + bool pwm45_fixup; ++ enum mtk_pwm_reg_ver reg_ver; + }; + + struct mtk_pwm_priv { +@@ -49,7 +59,16 @@ struct mtk_pwm_priv { + static void mtk_pwm_w32(struct udevice *dev, uint channel, uint reg, uint val) + { + struct mtk_pwm_priv *priv = dev_get_priv(dev); +- u32 offset = mtk_pwm_reg_offset[channel]; ++ u32 offset; ++ ++ switch (priv->soc->reg_ver) { ++ case PWM_REG_V2: ++ offset = mtk_pwm_reg_offset_v2[channel]; ++ break; ++ ++ default: ++ offset = mtk_pwm_reg_offset_v1[channel]; ++ } + + writel(val, priv->base + offset + reg); + } +@@ -159,27 +178,38 @@ static const struct pwm_ops mtk_pwm_ops + static const struct mtk_pwm_soc mt7622_data = { + .num_pwms = 6, + .pwm45_fixup = false, ++ .reg_ver = PWM_REG_V1, + }; + + static const struct mtk_pwm_soc mt7623_data = { + .num_pwms = 5, + .pwm45_fixup = true, ++ .reg_ver = PWM_REG_V1, + }; + + static const struct mtk_pwm_soc mt7629_data = { + .num_pwms = 1, + .pwm45_fixup = false, ++ .reg_ver = PWM_REG_V1, ++}; ++ ++static const struct mtk_pwm_soc mt7981_data = { ++ .num_pwms = 2, ++ .pwm45_fixup = false, ++ .reg_ver = PWM_REG_V2, + }; + + static const struct mtk_pwm_soc mt7986_data = { + .num_pwms = 2, + .pwm45_fixup = false, ++ .reg_ver = PWM_REG_V1, + }; + + static const struct udevice_id mtk_pwm_ids[] = { + { .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data }, + { .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data }, + { .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data }, ++ { .compatible = "mediatek,mt7981-pwm", .data = (ulong)&mt7981_data }, + { .compatible = "mediatek,mt7986-pwm", .data = (ulong)&mt7986_data }, + { } + }; diff --git a/package/boot/uboot-mediatek/patches/002-0014-timer-mtk-add-support-for-MediaTek-MT7981-MT7986-SoC.patch b/package/boot/uboot-mediatek/patches/002-0014-timer-mtk-add-support-for-MediaTek-MT7981-MT7986-SoC.patch new file mode 100644 index 0000000000..7889401931 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0014-timer-mtk-add-support-for-MediaTek-MT7981-MT7986-SoC.patch @@ -0,0 +1,119 @@ +From 7860bc58c43dfa939d2664be518c28aea591aeef Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 11:38:33 +0800 +Subject: [PATCH 14/31] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs + +This patch add general-purpose timer support for MediaTek MT7981/MT7986. +These two SoCs uses a newer version of timer with its register definition +slightly changed. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/timer/mtk_timer.c | 59 ++++++++++++++++++++++++--------------- + 1 file changed, 37 insertions(+), 22 deletions(-) + +--- a/drivers/timer/mtk_timer.c ++++ b/drivers/timer/mtk_timer.c +@@ -13,24 +13,32 @@ + #include + #include + +-#define MTK_GPT4_CTRL 0x40 +-#define MTK_GPT4_CLK 0x44 +-#define MTK_GPT4_CNT 0x48 +- +-#define GPT4_ENABLE BIT(0) +-#define GPT4_CLEAR BIT(1) +-#define GPT4_FREERUN GENMASK(5, 4) +-#define GPT4_CLK_SYS 0x0 +-#define GPT4_CLK_DIV1 0x0 ++#define MTK_GPT4_OFFSET_V1 0x40 ++#define MTK_GPT4_OFFSET_V2 0x80 ++ ++#define MTK_GPT_CON 0x0 ++#define MTK_GPT_V1_CLK 0x4 ++#define MTK_GPT_CNT 0x8 ++ ++#define GPT_ENABLE BIT(0) ++#define GPT_CLEAR BIT(1) ++#define GPT_V1_FREERUN GENMASK(5, 4) ++#define GPT_V2_FREERUN GENMASK(6, 5) ++ ++enum mtk_gpt_ver { ++ MTK_GPT_V1, ++ MTK_GPT_V2 ++}; + + struct mtk_timer_priv { + void __iomem *base; ++ unsigned int gpt4_offset; + }; + + static u64 mtk_timer_get_count(struct udevice *dev) + { + struct mtk_timer_priv *priv = dev_get_priv(dev); +- u32 val = readl(priv->base + MTK_GPT4_CNT); ++ u32 val = readl(priv->base + priv->gpt4_offset + MTK_GPT_CNT); + + return timer_conv_64(val); + } +@@ -40,12 +48,27 @@ static int mtk_timer_probe(struct udevic + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct mtk_timer_priv *priv = dev_get_priv(dev); + struct clk clk, parent; +- int ret; ++ int ret, gpt_ver; + + priv->base = dev_read_addr_ptr(dev); ++ gpt_ver = dev_get_driver_data(dev); ++ + if (!priv->base) + return -ENOENT; + ++ if (gpt_ver == MTK_GPT_V2) { ++ priv->gpt4_offset = MTK_GPT4_OFFSET_V2; ++ ++ writel(GPT_V2_FREERUN | GPT_CLEAR | GPT_ENABLE, ++ priv->base + priv->gpt4_offset + MTK_GPT_CON); ++ } else { ++ priv->gpt4_offset = MTK_GPT4_OFFSET_V1; ++ ++ writel(GPT_V1_FREERUN | GPT_CLEAR | GPT_ENABLE, ++ priv->base + priv->gpt4_offset + MTK_GPT_CON); ++ writel(0, priv->base + priv->gpt4_offset + MTK_GPT_V1_CLK); ++ } ++ + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; +@@ -61,16 +84,6 @@ static int mtk_timer_probe(struct udevic + if (!uc_priv->clock_rate) + return -EINVAL; + +- /* +- * Initialize the timer: +- * 1. set clock source to system clock with clock divider setting to 1 +- * 2. set timer mode to free running +- * 3. reset timer counter to 0 then enable the timer +- */ +- writel(GPT4_CLK_SYS | GPT4_CLK_DIV1, priv->base + MTK_GPT4_CLK); +- writel(GPT4_FREERUN | GPT4_CLEAR | GPT4_ENABLE, +- priv->base + MTK_GPT4_CTRL); +- + return 0; + } + +@@ -79,8 +92,10 @@ static const struct timer_ops mtk_timer_ + }; + + static const struct udevice_id mtk_timer_ids[] = { +- { .compatible = "mediatek,timer" }, +- { .compatible = "mediatek,mt6577-timer" }, ++ { .compatible = "mediatek,timer", .data = MTK_GPT_V1 }, ++ { .compatible = "mediatek,mt6577-timer", .data = MTK_GPT_V1 }, ++ { .compatible = "mediatek,mt7981-timer", .data = MTK_GPT_V2 }, ++ { .compatible = "mediatek,mt7986-timer", .data = MTK_GPT_V2 }, + { } + }; + diff --git a/package/boot/uboot-mediatek/patches/002-0015-watchdog-mediatek-add-support-for-MediaTek-MT7986-So.patch b/package/boot/uboot-mediatek/patches/002-0015-watchdog-mediatek-add-support-for-MediaTek-MT7986-So.patch new file mode 100644 index 0000000000..09ffc5c7d9 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0015-watchdog-mediatek-add-support-for-MediaTek-MT7986-So.patch @@ -0,0 +1,23 @@ +From ec7e5d3e4d6e9239f3d7ac861f07ca4a52bec9fa Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 11:47:50 +0800 +Subject: [PATCH 15/31] watchdog: mediatek: add support for MediaTek MT7986 SoC + +Add watchdog support for MediaTek MT7986 SoC + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/watchdog/mtk_wdt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/watchdog/mtk_wdt.c ++++ b/drivers/watchdog/mtk_wdt.c +@@ -145,6 +145,7 @@ static const struct wdt_ops mtk_wdt_ops + static const struct udevice_id mtk_wdt_ids[] = { + { .compatible = "mediatek,wdt"}, + { .compatible = "mediatek,mt6589-wdt"}, ++ { .compatible = "mediatek,mt7986-wdt" }, + {} + }; + diff --git a/package/boot/uboot-mediatek/patches/002-0016-spi-add-support-for-MediaTek-spi-mem-controller.patch b/package/boot/uboot-mediatek/patches/002-0016-spi-add-support-for-MediaTek-spi-mem-controller.patch new file mode 100644 index 0000000000..04c2df3b48 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0016-spi-add-support-for-MediaTek-spi-mem-controller.patch @@ -0,0 +1,748 @@ +From f85493e3c2d1e4fd411061540b4f4943c09114df Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 16:58:38 +0800 +Subject: [PATCH 16/31] spi: add support for MediaTek spi-mem controller + +This patch adds support for spi-mem controller found on newer MediaTek SoCs +This controller supports Single/Dual/Quad SPI mode. + +Reviewed-by: Simon Glass +Signed-off-by: SkyLake.Huang +--- + drivers/spi/Kconfig | 8 + + drivers/spi/Makefile | 1 + + drivers/spi/mtk_spim.c | 701 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 710 insertions(+) + create mode 100644 drivers/spi/mtk_spim.c + +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -262,6 +262,14 @@ config MTK_SNFI_SPI + used to access SPI memory devices like SPI-NOR or SPI-NAND on + platforms embedding this IP core, like MT7622/M7629. + ++config MTK_SPIM ++ bool "Mediatek SPI-MEM master controller driver" ++ depends on SPI_MEM ++ help ++ Enable MediaTek SPI-MEM master controller driver. This driver mainly ++ supports SPI flashes. You can use single, dual or quad mode ++ transmission on this controller. ++ + config MVEBU_A3700_SPI + bool "Marvell Armada 3700 SPI driver" + select CLK_ARMADA_3720 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -41,6 +41,7 @@ obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o + obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o + obj-$(CONFIG_MTK_SNFI_SPI) += mtk_snfi_spi.o + obj-$(CONFIG_MTK_SNOR) += mtk_snor.o ++obj-$(CONFIG_MTK_SPIM) += mtk_spim.o + obj-$(CONFIG_MT7620_SPI) += mt7620_spi.o + obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o + obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o +--- /dev/null ++++ b/drivers/spi/mtk_spim.c +@@ -0,0 +1,701 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2022 MediaTek Inc. All Rights Reserved. ++ * ++ * Author: SkyLake.Huang ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SPI_CFG0_REG 0x0000 ++#define SPI_CFG1_REG 0x0004 ++#define SPI_TX_SRC_REG 0x0008 ++#define SPI_RX_DST_REG 0x000c ++#define SPI_TX_DATA_REG 0x0010 ++#define SPI_RX_DATA_REG 0x0014 ++#define SPI_CMD_REG 0x0018 ++#define SPI_IRQ_REG 0x001c ++#define SPI_STATUS_REG 0x0020 ++#define SPI_PAD_SEL_REG 0x0024 ++#define SPI_CFG2_REG 0x0028 ++#define SPI_TX_SRC_REG_64 0x002c ++#define SPI_RX_DST_REG_64 0x0030 ++#define SPI_CFG3_IPM_REG 0x0040 ++ ++#define SPI_CFG0_SCK_HIGH_OFFSET 0 ++#define SPI_CFG0_SCK_LOW_OFFSET 8 ++#define SPI_CFG0_CS_HOLD_OFFSET 16 ++#define SPI_CFG0_CS_SETUP_OFFSET 24 ++#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0 ++#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET 16 ++ ++#define SPI_CFG1_CS_IDLE_OFFSET 0 ++#define SPI_CFG1_PACKET_LOOP_OFFSET 8 ++#define SPI_CFG1_PACKET_LENGTH_OFFSET 16 ++#define SPI_CFG1_GET_TICKDLY_OFFSET 29 ++ ++#define SPI_CFG1_GET_TICKDLY_MASK GENMASK(31, 29) ++#define SPI_CFG1_CS_IDLE_MASK 0xff ++#define SPI_CFG1_PACKET_LOOP_MASK 0xff00 ++#define SPI_CFG1_PACKET_LENGTH_MASK 0x3ff0000 ++#define SPI_CFG1_IPM_PACKET_LENGTH_MASK GENMASK(31, 16) ++#define SPI_CFG2_SCK_HIGH_OFFSET 0 ++#define SPI_CFG2_SCK_LOW_OFFSET 16 ++#define SPI_CFG2_SCK_HIGH_MASK GENMASK(15, 0) ++#define SPI_CFG2_SCK_LOW_MASK GENMASK(31, 16) ++ ++#define SPI_CMD_ACT BIT(0) ++#define SPI_CMD_RESUME BIT(1) ++#define SPI_CMD_RST BIT(2) ++#define SPI_CMD_PAUSE_EN BIT(4) ++#define SPI_CMD_DEASSERT BIT(5) ++#define SPI_CMD_SAMPLE_SEL BIT(6) ++#define SPI_CMD_CS_POL BIT(7) ++#define SPI_CMD_CPHA BIT(8) ++#define SPI_CMD_CPOL BIT(9) ++#define SPI_CMD_RX_DMA BIT(10) ++#define SPI_CMD_TX_DMA BIT(11) ++#define SPI_CMD_TXMSBF BIT(12) ++#define SPI_CMD_RXMSBF BIT(13) ++#define SPI_CMD_RX_ENDIAN BIT(14) ++#define SPI_CMD_TX_ENDIAN BIT(15) ++#define SPI_CMD_FINISH_IE BIT(16) ++#define SPI_CMD_PAUSE_IE BIT(17) ++#define SPI_CMD_IPM_NONIDLE_MODE BIT(19) ++#define SPI_CMD_IPM_SPIM_LOOP BIT(21) ++#define SPI_CMD_IPM_GET_TICKDLY_OFFSET 22 ++ ++#define SPI_CMD_IPM_GET_TICKDLY_MASK GENMASK(24, 22) ++ ++#define PIN_MODE_CFG(x) ((x) / 2) ++ ++#define SPI_CFG3_IPM_PIN_MODE_OFFSET 0 ++#define SPI_CFG3_IPM_HALF_DUPLEX_DIR BIT(2) ++#define SPI_CFG3_IPM_HALF_DUPLEX_EN BIT(3) ++#define SPI_CFG3_IPM_XMODE_EN BIT(4) ++#define SPI_CFG3_IPM_NODATA_FLAG BIT(5) ++#define SPI_CFG3_IPM_CMD_BYTELEN_OFFSET 8 ++#define SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET 12 ++#define SPI_CFG3_IPM_DUMMY_BYTELEN_OFFSET 16 ++ ++#define SPI_CFG3_IPM_CMD_PIN_MODE_MASK GENMASK(1, 0) ++#define SPI_CFG3_IPM_CMD_BYTELEN_MASK GENMASK(11, 8) ++#define SPI_CFG3_IPM_ADDR_BYTELEN_MASK GENMASK(15, 12) ++#define SPI_CFG3_IPM_DUMMY_BYTELEN_MASK GENMASK(19, 16) ++ ++#define MT8173_SPI_MAX_PAD_SEL 3 ++ ++#define MTK_SPI_PAUSE_INT_STATUS 0x2 ++ ++#define MTK_SPI_IDLE 0 ++#define MTK_SPI_PAUSED 1 ++ ++#define MTK_SPI_MAX_FIFO_SIZE 32U ++#define MTK_SPI_PACKET_SIZE 1024 ++#define MTK_SPI_IPM_PACKET_SIZE SZ_64K ++#define MTK_SPI_IPM_PACKET_LOOP SZ_256 ++ ++#define MTK_SPI_32BITS_MASK 0xffffffff ++ ++#define DMA_ADDR_EXT_BITS 36 ++#define DMA_ADDR_DEF_BITS 32 ++ ++#define CLK_TO_US(freq, clkcnt) DIV_ROUND_UP((clkcnt), (freq) / 1000000) ++ ++/* struct mtk_spim_capability ++ * @enhance_timing: Some IC design adjust cfg register to enhance time accuracy ++ * @dma_ext: Some IC support DMA addr extension ++ * @ipm_design: The IPM IP design improves some features, and supports dual/quad mode ++ * @support_quad: Whether quad mode is supported ++ */ ++struct mtk_spim_capability { ++ bool enhance_timing; ++ bool dma_ext; ++ bool ipm_design; ++ bool support_quad; ++}; ++ ++/* struct mtk_spim_priv ++ * @base: Base address of the spi controller ++ * @state: Controller state ++ * @sel_clk: Pad clock ++ * @spi_clk: Core clock ++ * @xfer_len: Current length of data for transfer ++ * @hw_cap: Controller capabilities ++ * @tick_dly: Used to postpone SPI sampling time ++ * @sample_sel: Sample edge of MISO ++ * @dev: udevice of this spi controller ++ * @tx_dma: Tx DMA address ++ * @rx_dma: Rx DMA address ++ */ ++struct mtk_spim_priv { ++ void __iomem *base; ++ u32 state; ++ struct clk sel_clk, spi_clk; ++ u32 xfer_len; ++ struct mtk_spim_capability hw_cap; ++ u32 tick_dly; ++ u32 sample_sel; ++ ++ struct device *dev; ++ dma_addr_t tx_dma; ++ dma_addr_t rx_dma; ++}; ++ ++static void mtk_spim_reset(struct mtk_spim_priv *priv) ++{ ++ /* set the software reset bit in SPI_CMD_REG. */ ++ setbits_le32(priv->base + SPI_CMD_REG, SPI_CMD_RST); ++ clrbits_le32(priv->base + SPI_CMD_REG, SPI_CMD_RST); ++} ++ ++static int mtk_spim_hw_init(struct spi_slave *slave) ++{ ++ struct udevice *bus = dev_get_parent(slave->dev); ++ struct mtk_spim_priv *priv = dev_get_priv(bus); ++ u16 cpha, cpol; ++ u32 reg_val; ++ ++ cpha = slave->mode & SPI_CPHA ? 1 : 0; ++ cpol = slave->mode & SPI_CPOL ? 1 : 0; ++ ++ if (priv->hw_cap.enhance_timing) { ++ if (priv->hw_cap.ipm_design) { ++ /* CFG3 reg only used for spi-mem, ++ * here write to default value ++ */ ++ writel(0x0, priv->base + SPI_CFG3_IPM_REG); ++ clrsetbits_le32(priv->base + SPI_CMD_REG, ++ SPI_CMD_IPM_GET_TICKDLY_MASK, ++ priv->tick_dly << ++ SPI_CMD_IPM_GET_TICKDLY_OFFSET); ++ } else { ++ clrsetbits_le32(priv->base + SPI_CFG1_REG, ++ SPI_CFG1_GET_TICKDLY_MASK, ++ priv->tick_dly << ++ SPI_CFG1_GET_TICKDLY_OFFSET); ++ } ++ } ++ ++ reg_val = readl(priv->base + SPI_CMD_REG); ++ if (priv->hw_cap.ipm_design) { ++ /* SPI transfer without idle time until packet length done */ ++ reg_val |= SPI_CMD_IPM_NONIDLE_MODE; ++ if (slave->mode & SPI_LOOP) ++ reg_val |= SPI_CMD_IPM_SPIM_LOOP; ++ else ++ reg_val &= ~SPI_CMD_IPM_SPIM_LOOP; ++ } ++ ++ if (cpha) ++ reg_val |= SPI_CMD_CPHA; ++ else ++ reg_val &= ~SPI_CMD_CPHA; ++ if (cpol) ++ reg_val |= SPI_CMD_CPOL; ++ else ++ reg_val &= ~SPI_CMD_CPOL; ++ ++ /* set the mlsbx and mlsbtx */ ++ if (slave->mode & SPI_LSB_FIRST) { ++ reg_val &= ~SPI_CMD_TXMSBF; ++ reg_val &= ~SPI_CMD_RXMSBF; ++ } else { ++ reg_val |= SPI_CMD_TXMSBF; ++ reg_val |= SPI_CMD_RXMSBF; ++ } ++ ++ /* do not reverse tx/rx endian */ ++ reg_val &= ~SPI_CMD_TX_ENDIAN; ++ reg_val &= ~SPI_CMD_RX_ENDIAN; ++ ++ if (priv->hw_cap.enhance_timing) { ++ /* set CS polarity */ ++ if (slave->mode & SPI_CS_HIGH) ++ reg_val |= SPI_CMD_CS_POL; ++ else ++ reg_val &= ~SPI_CMD_CS_POL; ++ ++ if (priv->sample_sel) ++ reg_val |= SPI_CMD_SAMPLE_SEL; ++ else ++ reg_val &= ~SPI_CMD_SAMPLE_SEL; ++ } ++ ++ /* disable dma mode */ ++ reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA); ++ ++ /* disable deassert mode */ ++ reg_val &= ~SPI_CMD_DEASSERT; ++ ++ writel(reg_val, priv->base + SPI_CMD_REG); ++ ++ return 0; ++} ++ ++static void mtk_spim_prepare_transfer(struct mtk_spim_priv *priv, ++ u32 speed_hz) ++{ ++ u32 spi_clk_hz, div, sck_time, cs_time, reg_val; ++ ++ spi_clk_hz = clk_get_rate(&priv->spi_clk); ++ if (speed_hz <= spi_clk_hz / 4) ++ div = DIV_ROUND_UP(spi_clk_hz, speed_hz); ++ else ++ div = 4; ++ ++ sck_time = (div + 1) / 2; ++ cs_time = sck_time * 2; ++ ++ if (priv->hw_cap.enhance_timing) { ++ reg_val = ((sck_time - 1) & 0xffff) ++ << SPI_CFG2_SCK_HIGH_OFFSET; ++ reg_val |= ((sck_time - 1) & 0xffff) ++ << SPI_CFG2_SCK_LOW_OFFSET; ++ writel(reg_val, priv->base + SPI_CFG2_REG); ++ ++ reg_val = ((cs_time - 1) & 0xffff) ++ << SPI_ADJUST_CFG0_CS_HOLD_OFFSET; ++ reg_val |= ((cs_time - 1) & 0xffff) ++ << SPI_ADJUST_CFG0_CS_SETUP_OFFSET; ++ writel(reg_val, priv->base + SPI_CFG0_REG); ++ } else { ++ reg_val = ((sck_time - 1) & 0xff) ++ << SPI_CFG0_SCK_HIGH_OFFSET; ++ reg_val |= ((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET; ++ reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET; ++ reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET; ++ writel(reg_val, priv->base + SPI_CFG0_REG); ++ } ++ ++ reg_val = readl(priv->base + SPI_CFG1_REG); ++ reg_val &= ~SPI_CFG1_CS_IDLE_MASK; ++ reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET; ++ writel(reg_val, priv->base + SPI_CFG1_REG); ++} ++ ++/** ++ * mtk_spim_setup_packet() - setup packet format. ++ * @priv: controller priv ++ * ++ * This controller sents/receives data in packets. The packet size is ++ * configurable. ++ * ++ * This function calculates the maximum packet size available for current ++ * data, and calculates the number of packets required to sent/receive data ++ * as much as possible. ++ */ ++static void mtk_spim_setup_packet(struct mtk_spim_priv *priv) ++{ ++ u32 packet_size, packet_loop, reg_val; ++ ++ /* Calculate maximum packet size */ ++ if (priv->hw_cap.ipm_design) ++ packet_size = min_t(u32, ++ priv->xfer_len, ++ MTK_SPI_IPM_PACKET_SIZE); ++ else ++ packet_size = min_t(u32, ++ priv->xfer_len, ++ MTK_SPI_PACKET_SIZE); ++ ++ /* Calculates number of packets to sent/receive */ ++ packet_loop = priv->xfer_len / packet_size; ++ ++ reg_val = readl(priv->base + SPI_CFG1_REG); ++ if (priv->hw_cap.ipm_design) ++ reg_val &= ~SPI_CFG1_IPM_PACKET_LENGTH_MASK; ++ else ++ reg_val &= ~SPI_CFG1_PACKET_LENGTH_MASK; ++ ++ reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET; ++ ++ reg_val &= ~SPI_CFG1_PACKET_LOOP_MASK; ++ ++ reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET; ++ ++ writel(reg_val, priv->base + SPI_CFG1_REG); ++} ++ ++static void mtk_spim_enable_transfer(struct mtk_spim_priv *priv) ++{ ++ u32 cmd; ++ ++ cmd = readl(priv->base + SPI_CMD_REG); ++ if (priv->state == MTK_SPI_IDLE) ++ cmd |= SPI_CMD_ACT; ++ else ++ cmd |= SPI_CMD_RESUME; ++ writel(cmd, priv->base + SPI_CMD_REG); ++} ++ ++static bool mtk_spim_supports_op(struct spi_slave *slave, ++ const struct spi_mem_op *op) ++{ ++ struct udevice *bus = dev_get_parent(slave->dev); ++ struct mtk_spim_priv *priv = dev_get_priv(bus); ++ ++ if (op->cmd.buswidth == 0 || op->cmd.buswidth > 4 || ++ op->addr.buswidth > 4 || op->dummy.buswidth > 4 || ++ op->data.buswidth > 4) ++ return false; ++ ++ if (!priv->hw_cap.support_quad && (op->cmd.buswidth > 2 || ++ op->addr.buswidth > 2 || op->dummy.buswidth > 2 || ++ op->data.buswidth > 2)) ++ return false; ++ ++ if (op->addr.nbytes && op->dummy.nbytes && ++ op->addr.buswidth != op->dummy.buswidth) ++ return false; ++ ++ if (op->addr.nbytes + op->dummy.nbytes > 16) ++ return false; ++ ++ if (op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) { ++ if (op->data.nbytes / MTK_SPI_IPM_PACKET_SIZE > ++ MTK_SPI_IPM_PACKET_LOOP || ++ op->data.nbytes % MTK_SPI_IPM_PACKET_SIZE != 0) ++ return false; ++ } ++ ++ return true; ++} ++ ++static void mtk_spim_setup_dma_xfer(struct mtk_spim_priv *priv, ++ const struct spi_mem_op *op) ++{ ++ writel((u32)(priv->tx_dma & MTK_SPI_32BITS_MASK), ++ priv->base + SPI_TX_SRC_REG); ++ ++ if (priv->hw_cap.dma_ext) ++ writel((u32)(priv->tx_dma >> 32), ++ priv->base + SPI_TX_SRC_REG_64); ++ ++ if (op->data.dir == SPI_MEM_DATA_IN) { ++ writel((u32)(priv->rx_dma & MTK_SPI_32BITS_MASK), ++ priv->base + SPI_RX_DST_REG); ++ ++ if (priv->hw_cap.dma_ext) ++ writel((u32)(priv->rx_dma >> 32), ++ priv->base + SPI_RX_DST_REG_64); ++ } ++} ++ ++static int mtk_spim_transfer_wait(struct spi_slave *slave, ++ const struct spi_mem_op *op) ++{ ++ struct udevice *bus = dev_get_parent(slave->dev); ++ struct mtk_spim_priv *priv = dev_get_priv(bus); ++ u32 sck_l, sck_h, spi_bus_clk, clk_count, reg; ++ ulong us = 1; ++ int ret = 0; ++ ++ if (op->data.dir == SPI_MEM_NO_DATA) ++ clk_count = 32; ++ else ++ clk_count = op->data.nbytes; ++ ++ spi_bus_clk = clk_get_rate(&priv->spi_clk); ++ sck_l = readl(priv->base + SPI_CFG2_REG) >> SPI_CFG2_SCK_LOW_OFFSET; ++ sck_h = readl(priv->base + SPI_CFG2_REG) & SPI_CFG2_SCK_HIGH_MASK; ++ do_div(spi_bus_clk, sck_l + sck_h + 2); ++ ++ us = CLK_TO_US(spi_bus_clk, clk_count * 8); ++ us += 1000 * 1000; /* 1s tolerance */ ++ ++ if (us > UINT_MAX) ++ us = UINT_MAX; ++ ++ ret = readl_poll_timeout(priv->base + SPI_STATUS_REG, reg, ++ reg & 0x1, us); ++ if (ret < 0) { ++ dev_err(priv->dev, "transfer timeout, val: 0x%lx\n", us); ++ return -ETIMEDOUT; ++ } ++ ++ return 0; ++} ++ ++static int mtk_spim_exec_op(struct spi_slave *slave, ++ const struct spi_mem_op *op) ++{ ++ struct udevice *bus = dev_get_parent(slave->dev); ++ struct mtk_spim_priv *priv = dev_get_priv(bus); ++ u32 reg_val, nio = 1, tx_size; ++ char *tx_tmp_buf; ++ char *rx_tmp_buf; ++ int i, ret = 0; ++ ++ mtk_spim_reset(priv); ++ mtk_spim_hw_init(slave); ++ mtk_spim_prepare_transfer(priv, slave->max_hz); ++ ++ reg_val = readl(priv->base + SPI_CFG3_IPM_REG); ++ /* opcode byte len */ ++ reg_val &= ~SPI_CFG3_IPM_CMD_BYTELEN_MASK; ++ reg_val |= 1 << SPI_CFG3_IPM_CMD_BYTELEN_OFFSET; ++ ++ /* addr & dummy byte len */ ++ if (op->addr.nbytes || op->dummy.nbytes) ++ reg_val |= (op->addr.nbytes + op->dummy.nbytes) << ++ SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET; ++ ++ /* data byte len */ ++ if (!op->data.nbytes) { ++ reg_val |= SPI_CFG3_IPM_NODATA_FLAG; ++ writel(0, priv->base + SPI_CFG1_REG); ++ } else { ++ reg_val &= ~SPI_CFG3_IPM_NODATA_FLAG; ++ priv->xfer_len = op->data.nbytes; ++ mtk_spim_setup_packet(priv); ++ } ++ ++ if (op->addr.nbytes || op->dummy.nbytes) { ++ if (op->addr.buswidth == 1 || op->dummy.buswidth == 1) ++ reg_val |= SPI_CFG3_IPM_XMODE_EN; ++ else ++ reg_val &= ~SPI_CFG3_IPM_XMODE_EN; ++ } ++ ++ if (op->addr.buswidth == 2 || ++ op->dummy.buswidth == 2 || ++ op->data.buswidth == 2) ++ nio = 2; ++ else if (op->addr.buswidth == 4 || ++ op->dummy.buswidth == 4 || ++ op->data.buswidth == 4) ++ nio = 4; ++ ++ reg_val &= ~SPI_CFG3_IPM_CMD_PIN_MODE_MASK; ++ reg_val |= PIN_MODE_CFG(nio) << SPI_CFG3_IPM_PIN_MODE_OFFSET; ++ ++ reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN; ++ if (op->data.dir == SPI_MEM_DATA_IN) ++ reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_DIR; ++ else ++ reg_val &= ~SPI_CFG3_IPM_HALF_DUPLEX_DIR; ++ writel(reg_val, priv->base + SPI_CFG3_IPM_REG); ++ ++ tx_size = 1 + op->addr.nbytes + op->dummy.nbytes; ++ if (op->data.dir == SPI_MEM_DATA_OUT) ++ tx_size += op->data.nbytes; ++ ++ tx_size = max(tx_size, (u32)32); ++ ++ /* Fill up tx data */ ++ tx_tmp_buf = kzalloc(tx_size, GFP_KERNEL); ++ if (!tx_tmp_buf) { ++ ret = -ENOMEM; ++ goto exit; ++ } ++ ++ tx_tmp_buf[0] = op->cmd.opcode; ++ ++ if (op->addr.nbytes) { ++ for (i = 0; i < op->addr.nbytes; i++) ++ tx_tmp_buf[i + 1] = op->addr.val >> ++ (8 * (op->addr.nbytes - i - 1)); ++ } ++ ++ if (op->dummy.nbytes) ++ memset(tx_tmp_buf + op->addr.nbytes + 1, 0xff, ++ op->dummy.nbytes); ++ ++ if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) ++ memcpy(tx_tmp_buf + op->dummy.nbytes + op->addr.nbytes + 1, ++ op->data.buf.out, op->data.nbytes); ++ /* Finish filling up tx data */ ++ ++ priv->tx_dma = dma_map_single(tx_tmp_buf, tx_size, DMA_TO_DEVICE); ++ if (dma_mapping_error(priv->dev, priv->tx_dma)) { ++ ret = -ENOMEM; ++ goto tx_free; ++ } ++ ++ if (op->data.dir == SPI_MEM_DATA_IN) { ++ if (!IS_ALIGNED((size_t)op->data.buf.in, 4)) { ++ rx_tmp_buf = kzalloc(op->data.nbytes, GFP_KERNEL); ++ if (!rx_tmp_buf) { ++ ret = -ENOMEM; ++ goto tx_unmap; ++ } ++ } else { ++ rx_tmp_buf = op->data.buf.in; ++ } ++ ++ priv->rx_dma = dma_map_single(rx_tmp_buf, op->data.nbytes, ++ DMA_FROM_DEVICE); ++ if (dma_mapping_error(priv->dev, priv->rx_dma)) { ++ ret = -ENOMEM; ++ goto rx_free; ++ } ++ } ++ ++ reg_val = readl(priv->base + SPI_CMD_REG); ++ reg_val |= SPI_CMD_TX_DMA; ++ if (op->data.dir == SPI_MEM_DATA_IN) ++ reg_val |= SPI_CMD_RX_DMA; ++ ++ writel(reg_val, priv->base + SPI_CMD_REG); ++ ++ mtk_spim_setup_dma_xfer(priv, op); ++ ++ mtk_spim_enable_transfer(priv); ++ ++ /* Wait for the interrupt. */ ++ ret = mtk_spim_transfer_wait(slave, op); ++ if (ret) ++ goto rx_unmap; ++ ++ if (op->data.dir == SPI_MEM_DATA_IN && ++ !IS_ALIGNED((size_t)op->data.buf.in, 4)) ++ memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes); ++ ++rx_unmap: ++ /* spi disable dma */ ++ reg_val = readl(priv->base + SPI_CMD_REG); ++ reg_val &= ~SPI_CMD_TX_DMA; ++ if (op->data.dir == SPI_MEM_DATA_IN) ++ reg_val &= ~SPI_CMD_RX_DMA; ++ writel(reg_val, priv->base + SPI_CMD_REG); ++ ++ writel(0, priv->base + SPI_TX_SRC_REG); ++ writel(0, priv->base + SPI_RX_DST_REG); ++ ++ if (op->data.dir == SPI_MEM_DATA_IN) ++ dma_unmap_single(priv->rx_dma, ++ op->data.nbytes, DMA_FROM_DEVICE); ++rx_free: ++ if (op->data.dir == SPI_MEM_DATA_IN && ++ !IS_ALIGNED((size_t)op->data.buf.in, 4)) ++ kfree(rx_tmp_buf); ++tx_unmap: ++ dma_unmap_single(priv->tx_dma, ++ tx_size, DMA_TO_DEVICE); ++tx_free: ++ kfree(tx_tmp_buf); ++exit: ++ return ret; ++} ++ ++static int mtk_spim_adjust_op_size(struct spi_slave *slave, ++ struct spi_mem_op *op) ++{ ++ int opcode_len; ++ ++ if (!op->data.nbytes) ++ return 0; ++ ++ if (op->data.dir != SPI_MEM_NO_DATA) { ++ opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes; ++ if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) { ++ op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE - opcode_len; ++ /* force data buffer dma-aligned. */ ++ op->data.nbytes -= op->data.nbytes % 4; ++ } ++ } ++ ++ return 0; ++} ++ ++static int mtk_spim_get_attr(struct mtk_spim_priv *priv, struct udevice *dev) ++{ ++ int ret; ++ ++ priv->hw_cap.enhance_timing = dev_read_bool(dev, "enhance_timing"); ++ priv->hw_cap.dma_ext = dev_read_bool(dev, "dma_ext"); ++ priv->hw_cap.ipm_design = dev_read_bool(dev, "ipm_design"); ++ priv->hw_cap.support_quad = dev_read_bool(dev, "support_quad"); ++ ++ ret = dev_read_u32(dev, "tick_dly", &priv->tick_dly); ++ if (ret < 0) ++ dev_err(priv->dev, "tick dly not set.\n"); ++ ++ ret = dev_read_u32(dev, "sample_sel", &priv->sample_sel); ++ if (ret < 0) ++ dev_err(priv->dev, "sample sel not set.\n"); ++ ++ return ret; ++} ++ ++static int mtk_spim_probe(struct udevice *dev) ++{ ++ struct mtk_spim_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ priv->base = (void __iomem *)devfdt_get_addr(dev); ++ if (!priv->base) ++ return -EINVAL; ++ ++ mtk_spim_get_attr(priv, dev); ++ ++ ret = clk_get_by_name(dev, "sel-clk", &priv->sel_clk); ++ if (ret < 0) { ++ dev_err(dev, "failed to get sel-clk\n"); ++ return ret; ++ } ++ ++ ret = clk_get_by_name(dev, "spi-clk", &priv->spi_clk); ++ if (ret < 0) { ++ dev_err(dev, "failed to get spi-clk\n"); ++ return ret; ++ } ++ ++ clk_enable(&priv->sel_clk); ++ clk_enable(&priv->spi_clk); ++ ++ return 0; ++} ++ ++static int mtk_spim_set_speed(struct udevice *dev, uint speed) ++{ ++ return 0; ++} ++ ++static int mtk_spim_set_mode(struct udevice *dev, uint mode) ++{ ++ return 0; ++} ++ ++static const struct spi_controller_mem_ops mtk_spim_mem_ops = { ++ .adjust_op_size = mtk_spim_adjust_op_size, ++ .supports_op = mtk_spim_supports_op, ++ .exec_op = mtk_spim_exec_op ++}; ++ ++static const struct dm_spi_ops mtk_spim_ops = { ++ .mem_ops = &mtk_spim_mem_ops, ++ .set_speed = mtk_spim_set_speed, ++ .set_mode = mtk_spim_set_mode, ++}; ++ ++static const struct udevice_id mtk_spim_ids[] = { ++ { .compatible = "mediatek,ipm-spi" }, ++ {} ++}; ++ ++U_BOOT_DRIVER(mtk_spim) = { ++ .name = "mtk_spim", ++ .id = UCLASS_SPI, ++ .of_match = mtk_spim_ids, ++ .ops = &mtk_spim_ops, ++ .priv_auto = sizeof(struct mtk_spim_priv), ++ .probe = mtk_spim_probe, ++}; diff --git a/package/boot/uboot-mediatek/patches/002-0017-i2c-add-support-for-MediaTek-I2C-interface.patch b/package/boot/uboot-mediatek/patches/002-0017-i2c-add-support-for-MediaTek-I2C-interface.patch new file mode 100644 index 0000000000..c2bc33cdaa --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0017-i2c-add-support-for-MediaTek-I2C-interface.patch @@ -0,0 +1,870 @@ +From de6f2293ab087f405dbcf7b8df45d1f9b03fc091 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 27 Jul 2022 17:16:38 +0800 +Subject: [PATCH 17/31] i2c: add support for MediaTek I2C interface + +This patch adds support for MediaTek I2C interface + +Reviewed-by: Heiko Schocher +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/i2c/Kconfig | 9 + + drivers/i2c/Makefile | 1 + + drivers/i2c/mtk_i2c.c | 822 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 832 insertions(+) + create mode 100644 drivers/i2c/mtk_i2c.c + +--- a/drivers/i2c/Kconfig ++++ b/drivers/i2c/Kconfig +@@ -261,6 +261,15 @@ config SYS_I2C_MESON + internal buffer holding up to 8 bytes for transfers and supports + both 7-bit and 10-bit addresses. + ++config SYS_I2C_MTK ++ bool "MediaTek I2C driver" ++ help ++ This selects the MediaTek Integrated Inter Circuit bus driver. ++ The I2C bus adapter is the base for some other I2C client, ++ eg: touch, sensors. ++ If you want to use MediaTek I2C interface, say Y here. ++ If unsure, say N. ++ + config SYS_I2C_MICROCHIP + bool "Microchip I2C driver" + help +--- a/drivers/i2c/Makefile ++++ b/drivers/i2c/Makefile +@@ -32,6 +32,7 @@ obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-m + obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o + obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o + obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o ++obj-$(CONFIG_SYS_I2C_MTK) += mtk_i2c.o + obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o + obj-$(CONFIG_SYS_I2C_OCORES) += ocores_i2c.o + obj-$(CONFIG_SYS_I2C_OCTEON) += octeon_i2c.o +--- /dev/null ++++ b/drivers/i2c/mtk_i2c.c +@@ -0,0 +1,822 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2022 MediaTek Inc. All Rights Reserved. ++ * ++ * Author: Mingming Lee ++ * ++ * MediaTek I2C Interface driver ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define I2C_RS_TRANSFER BIT(4) ++#define I2C_HS_NACKERR BIT(2) ++#define I2C_ACKERR BIT(1) ++#define I2C_TRANSAC_COMP BIT(0) ++#define I2C_TRANSAC_START BIT(0) ++#define I2C_RS_MUL_CNFG BIT(15) ++#define I2C_RS_MUL_TRIG BIT(14) ++#define I2C_DCM_DISABLE 0x0000 ++#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 ++#define I2C_IO_CONFIG_PUSH_PULL 0x0000 ++#define I2C_SOFT_RST 0x0001 ++#define I2C_FIFO_ADDR_CLR 0x0001 ++#define I2C_DELAY_LEN 0x0002 ++#define I2C_ST_START_CON 0x8001 ++#define I2C_FS_START_CON 0x1800 ++#define I2C_TIME_CLR_VALUE 0x0000 ++#define I2C_TIME_DEFAULT_VALUE 0x0003 ++#define I2C_WRRD_TRANAC_VALUE 0x0002 ++#define I2C_RD_TRANAC_VALUE 0x0001 ++ ++#define I2C_DMA_CON_TX 0x0000 ++#define I2C_DMA_CON_RX 0x0001 ++#define I2C_DMA_START_EN 0x0001 ++#define I2C_DMA_INT_FLAG_NONE 0x0000 ++#define I2C_DMA_CLR_FLAG 0x0000 ++#define I2C_DMA_TX_RX 0x0000 ++#define I2C_DMA_HARD_RST 0x0002 ++ ++#define MAX_ST_MODE_SPEED 100000 ++#define MAX_FS_MODE_SPEED 400000 ++#define MAX_HS_MODE_SPEED 3400000 ++#define MAX_SAMPLE_CNT_DIV 8 ++#define MAX_STEP_CNT_DIV 64 ++#define MAX_HS_STEP_CNT_DIV 8 ++#define I2C_DEFAULT_CLK_DIV 4 ++ ++#define MAX_I2C_ADDR 0x7f ++#define MAX_I2C_LEN 0xff ++#define TRANS_ADDR_ONLY BIT(8) ++#define TRANSFER_TIMEOUT 50000 /* us */ ++#define I2C_FIFO_STAT1_MASK 0x001f ++#define TIMING_SAMPLE_OFFSET 8 ++#define HS_SAMPLE_OFFSET 12 ++#define HS_STEP_OFFSET 8 ++ ++#define I2C_CONTROL_WRAPPER BIT(0) ++#define I2C_CONTROL_RS BIT(1) ++#define I2C_CONTROL_DMA_EN BIT(2) ++#define I2C_CONTROL_CLK_EXT_EN BIT(3) ++#define I2C_CONTROL_DIR_CHANGE BIT(4) ++#define I2C_CONTROL_ACKERR_DET_EN BIT(5) ++#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6) ++#define I2C_CONTROL_DMAACK BIT(8) ++#define I2C_CONTROL_ASYNC BIT(9) ++ ++#define I2C_MASTER_WR BIT(0) ++#define I2C_MASTER_RD BIT(1) ++#define I2C_MASTER_WRRD (I2C_MASTER_WR | I2C_MASTER_RD) ++ ++enum I2C_REGS_OFFSET { ++ REG_PORT, ++ REG_SLAVE_ADDR, ++ REG_INTR_MASK, ++ REG_INTR_STAT, ++ REG_CONTROL, ++ REG_TRANSFER_LEN, ++ REG_TRANSAC_LEN, ++ REG_DELAY_LEN, ++ REG_TIMING, ++ REG_START, ++ REG_EXT_CONF, ++ REG_FIFO_STAT1, ++ REG_LTIMING, ++ REG_FIFO_STAT, ++ REG_FIFO_THRESH, ++ REG_FIFO_ADDR_CLR, ++ REG_IO_CONFIG, ++ REG_RSV_DEBUG, ++ REG_HS, ++ REG_SOFTRESET, ++ REG_DCM_EN, ++ REG_PATH_DIR, ++ REG_DEBUGSTAT, ++ REG_DEBUGCTRL, ++ REG_TRANSFER_LEN_AUX, ++ REG_CLOCK_DIV, ++ REG_SCL_HL_RATIO, ++ REG_SCL_HS_HL_RATIO, ++ REG_SCL_MIS_COMP_POINT, ++ REG_STA_STOP_AC_TIME, ++ REG_HS_STA_STOP_AC_TIME, ++ REG_DATA_TIME, ++}; ++ ++enum DMA_REGS_OFFSET { ++ REG_INT_FLAG = 0x0, ++ REG_INT_EN = 0x04, ++ REG_EN = 0x08, ++ REG_RST = 0x0c, ++ REG_CON = 0x18, ++ REG_TX_MEM_ADDR = 0x1c, ++ REG_RX_MEM_ADDR = 0x20, ++ REG_TX_LEN = 0x24, ++ REG_RX_LEN = 0x28, ++}; ++ ++static const uint mt_i2c_regs_v1[] = { ++ [REG_PORT] = 0x0, ++ [REG_SLAVE_ADDR] = 0x4, ++ [REG_INTR_MASK] = 0x8, ++ [REG_INTR_STAT] = 0xc, ++ [REG_CONTROL] = 0x10, ++ [REG_TRANSFER_LEN] = 0x14, ++ [REG_TRANSAC_LEN] = 0x18, ++ [REG_DELAY_LEN] = 0x1c, ++ [REG_TIMING] = 0x20, ++ [REG_START] = 0x24, ++ [REG_EXT_CONF] = 0x28, ++ [REG_FIFO_STAT1] = 0x2c, ++ [REG_FIFO_STAT] = 0x30, ++ [REG_FIFO_THRESH] = 0x34, ++ [REG_FIFO_ADDR_CLR] = 0x38, ++ [REG_IO_CONFIG] = 0x40, ++ [REG_RSV_DEBUG] = 0x44, ++ [REG_HS] = 0x48, ++ [REG_SOFTRESET] = 0x50, ++ [REG_SOFTRESET] = 0x50, ++ [REG_DCM_EN] = 0x54, ++ [REG_DEBUGSTAT] = 0x64, ++ [REG_DEBUGCTRL] = 0x68, ++ [REG_TRANSFER_LEN_AUX] = 0x6c, ++ [REG_CLOCK_DIV] = 0x70, ++ [REG_SCL_HL_RATIO] = 0x74, ++ [REG_SCL_HS_HL_RATIO] = 0x78, ++ [REG_SCL_MIS_COMP_POINT] = 0x7c, ++ [REG_STA_STOP_AC_TIME] = 0x80, ++ [REG_HS_STA_STOP_AC_TIME] = 0x84, ++ [REG_DATA_TIME] = 0x88, ++}; ++ ++static const uint mt_i2c_regs_v2[] = { ++ [REG_PORT] = 0x0, ++ [REG_SLAVE_ADDR] = 0x4, ++ [REG_INTR_MASK] = 0x8, ++ [REG_INTR_STAT] = 0xc, ++ [REG_CONTROL] = 0x10, ++ [REG_TRANSFER_LEN] = 0x14, ++ [REG_TRANSAC_LEN] = 0x18, ++ [REG_DELAY_LEN] = 0x1c, ++ [REG_TIMING] = 0x20, ++ [REG_START] = 0x24, ++ [REG_EXT_CONF] = 0x28, ++ [REG_LTIMING] = 0x2c, ++ [REG_HS] = 0x30, ++ [REG_IO_CONFIG] = 0x34, ++ [REG_FIFO_ADDR_CLR] = 0x38, ++ [REG_TRANSFER_LEN_AUX] = 0x44, ++ [REG_CLOCK_DIV] = 0x48, ++ [REG_SOFTRESET] = 0x50, ++ [REG_DEBUGSTAT] = 0xe0, ++ [REG_DEBUGCTRL] = 0xe8, ++ [REG_FIFO_STAT] = 0xf4, ++ [REG_FIFO_THRESH] = 0xf8, ++ [REG_DCM_EN] = 0xf88, ++}; ++ ++struct mtk_i2c_soc_data { ++ const uint *regs; ++ uint dma_sync: 1; ++}; ++ ++struct mtk_i2c_priv { ++ /* set in i2c probe */ ++ void __iomem *base; /* i2c base addr */ ++ void __iomem *pdmabase; /* dma base address*/ ++ struct clk clk_main; /* main clock for i2c bus */ ++ struct clk clk_dma; /* DMA clock for i2c via DMA */ ++ const struct mtk_i2c_soc_data *soc_data; /* Compatible data for different IC */ ++ int op; /* operation mode */ ++ bool zero_len; /* Only transfer slave address, no data */ ++ bool pushpull; /* push pull mode or open drain mode */ ++ bool filter_msg; /* filter msg error log */ ++ bool auto_restart; /* restart mode */ ++ bool ignore_restart_irq; /* ignore restart IRQ */ ++ uint speed; /* i2c speed, unit: hz */ ++}; ++ ++static inline void i2c_writel(struct mtk_i2c_priv *priv, uint reg, uint value) ++{ ++ u32 offset = priv->soc_data->regs[reg]; ++ ++ writel(value, priv->base + offset); ++} ++ ++static inline uint i2c_readl(struct mtk_i2c_priv *priv, uint offset) ++{ ++ return readl(priv->base + priv->soc_data->regs[offset]); ++} ++ ++static int mtk_i2c_clk_enable(struct mtk_i2c_priv *priv) ++{ ++ int ret; ++ ++ ret = clk_enable(&priv->clk_main); ++ if (ret) ++ return log_msg_ret("enable clk_main", ret); ++ ++ ret = clk_enable(&priv->clk_dma); ++ if (ret) ++ return log_msg_ret("enable clk_dma", ret); ++ ++ return 0; ++} ++ ++static int mtk_i2c_clk_disable(struct mtk_i2c_priv *priv) ++{ ++ int ret; ++ ++ ret = clk_disable(&priv->clk_dma); ++ if (ret) ++ return log_msg_ret("disable clk_dma", ret); ++ ++ ret = clk_disable(&priv->clk_main); ++ if (ret) ++ return log_msg_ret("disable clk_main", ret); ++ ++ return 0; ++} ++ ++static void mtk_i2c_init_hw(struct mtk_i2c_priv *priv) ++{ ++ uint control_reg; ++ ++ writel(I2C_DMA_HARD_RST, priv->pdmabase + REG_RST); ++ writel(I2C_DMA_CLR_FLAG, priv->pdmabase + REG_RST); ++ i2c_writel(priv, REG_SOFTRESET, I2C_SOFT_RST); ++ /* set ioconfig */ ++ if (priv->pushpull) ++ i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_PUSH_PULL); ++ else ++ i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_OPEN_DRAIN); ++ ++ i2c_writel(priv, REG_DCM_EN, I2C_DCM_DISABLE); ++ control_reg = I2C_CONTROL_ACKERR_DET_EN | I2C_CONTROL_CLK_EXT_EN; ++ if (priv->soc_data->dma_sync) ++ control_reg |= I2C_CONTROL_DMAACK | I2C_CONTROL_ASYNC; ++ i2c_writel(priv, REG_CONTROL, control_reg); ++ i2c_writel(priv, REG_DELAY_LEN, I2C_DELAY_LEN); ++} ++ ++/* ++ * Calculate i2c port speed ++ * ++ * Hardware design: ++ * i2c_bus_freq = parent_clk / (clock_div * 2 * sample_cnt * step_cnt) ++ * clock_div: fixed in hardware, but may be various in different SoCs ++ * ++ * The calculation want to pick the highest bus frequency that is still ++ * less than or equal to target_speed. The calculation try to get ++ * sample_cnt and step_cn ++ * @param[in] ++ * clk_src: i2c clock source ++ * @param[out] ++ * timing_step_cnt: step cnt calculate result ++ * @param[out] ++ * timing_sample_cnt: sample cnt calculate result ++ * @return ++ * 0, set speed successfully. ++ * -EINVAL, Unsupported speed. ++ */ ++static int mtk_i2c_calculate_speed(uint clk_src, ++ uint target_speed, ++ uint *timing_step_cnt, ++ uint *timing_sample_cnt) ++{ ++ uint base_sample_cnt = MAX_SAMPLE_CNT_DIV; ++ uint base_step_cnt; ++ uint max_step_cnt; ++ uint sample_cnt; ++ uint step_cnt; ++ uint opt_div; ++ uint best_mul; ++ uint cnt_mul; ++ ++ if (target_speed > MAX_HS_MODE_SPEED) ++ target_speed = MAX_HS_MODE_SPEED; ++ ++ if (target_speed > MAX_FS_MODE_SPEED) ++ max_step_cnt = MAX_HS_STEP_CNT_DIV; ++ else ++ max_step_cnt = MAX_STEP_CNT_DIV; ++ ++ base_step_cnt = max_step_cnt; ++ /* Find the best combination */ ++ opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed); ++ best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt; ++ ++ /* ++ * Search for the best pair (sample_cnt, step_cnt) with ++ * 0 < sample_cnt < MAX_SAMPLE_CNT_DIV ++ * 0 < step_cnt < max_step_cnt ++ * sample_cnt * step_cnt >= opt_div ++ * optimizing for sample_cnt * step_cnt being minimal ++ */ ++ for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) { ++ step_cnt = DIV_ROUND_UP(opt_div, sample_cnt); ++ cnt_mul = step_cnt * sample_cnt; ++ if (step_cnt > max_step_cnt) ++ continue; ++ ++ if (cnt_mul < best_mul) { ++ best_mul = cnt_mul; ++ base_sample_cnt = sample_cnt; ++ base_step_cnt = step_cnt; ++ if (best_mul == opt_div) ++ break; ++ } ++ } ++ ++ sample_cnt = base_sample_cnt; ++ step_cnt = base_step_cnt; ++ ++ if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) { ++ /* ++ * In this case, hardware can't support such ++ * low i2c_bus_freq ++ */ ++ debug("Unsupported speed(%uhz)\n", target_speed); ++ return log_msg_ret("calculate speed", -EINVAL); ++ } ++ ++ *timing_step_cnt = step_cnt - 1; ++ *timing_sample_cnt = sample_cnt - 1; ++ ++ return 0; ++} ++ ++/* ++ * mtk_i2c_set_speed ++ * ++ * @par Description ++ * Calculate i2c speed and write sample_cnt, step_cnt to TIMING register. ++ * @param[in] ++ * dev: udevice pointer, struct udevice contains i2c source clock, ++ * clock divide and speed. ++ * @return ++ * 0, set speed successfully.\n ++ * error code from mtk_i2c_calculate_speed(). ++ */ ++static int mtk_i2c_set_speed(struct udevice *dev, uint speed) ++{ ++ struct mtk_i2c_priv *priv = dev_get_priv(dev); ++ uint high_speed_reg; ++ uint sample_cnt; ++ uint timing_reg; ++ uint step_cnt; ++ uint clk_src; ++ int ret = 0; ++ ++ priv->speed = speed; ++ if (mtk_i2c_clk_enable(priv)) ++ return log_msg_ret("set_speed enable clk", -1); ++ ++ clk_src = clk_get_rate(&priv->clk_main) / I2C_DEFAULT_CLK_DIV; ++ i2c_writel(priv, REG_CLOCK_DIV, (I2C_DEFAULT_CLK_DIV - 1)); ++ if (priv->speed > MAX_FS_MODE_SPEED) { ++ /* Set master code speed register */ ++ ret = mtk_i2c_calculate_speed(clk_src, MAX_FS_MODE_SPEED, ++ &step_cnt, &sample_cnt); ++ if (ret < 0) ++ goto exit; ++ ++ timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt; ++ i2c_writel(priv, REG_TIMING, timing_reg); ++ /* Set the high speed mode register */ ++ ret = mtk_i2c_calculate_speed(clk_src, priv->speed, ++ &step_cnt, &sample_cnt); ++ if (ret < 0) ++ goto exit; ++ ++ high_speed_reg = I2C_TIME_DEFAULT_VALUE | ++ (sample_cnt << HS_SAMPLE_OFFSET) | ++ (step_cnt << HS_STEP_OFFSET); ++ i2c_writel(priv, REG_HS, high_speed_reg); ++ } else { ++ ret = mtk_i2c_calculate_speed(clk_src, priv->speed, ++ &step_cnt, &sample_cnt); ++ if (ret < 0) ++ goto exit; ++ ++ timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt; ++ /* Disable the high speed transaction */ ++ high_speed_reg = I2C_TIME_CLR_VALUE; ++ i2c_writel(priv, REG_TIMING, timing_reg); ++ i2c_writel(priv, REG_HS, high_speed_reg); ++ } ++exit: ++ if (mtk_i2c_clk_disable(priv)) ++ return log_msg_ret("set_speed disable clk", -1); ++ ++ return ret; ++} ++ ++/* ++ * mtk_i2c_do_transfer ++ * ++ * @par Description ++ * Configure i2c register and trigger transfer. ++ * @param[in] ++ * priv: mtk_i2cmtk_i2c_priv pointer, struct mtk_i2c_priv contains register base\n ++ * address, operation mode, interrupt status and i2c driver data. ++ * @param[in] ++ * msgs: i2c_msg pointer, struct i2c_msg contains slave\n ++ * address, operation mode, msg length and data buffer. ++ * @param[in] ++ * num: i2c_msg number. ++ * @param[in] ++ * left_num: left i2c_msg number. ++ * @return ++ * 0, i2c transfer successfully.\n ++ * -ETIMEDOUT, i2c transfer timeout.\n ++ * -EREMOTEIO, i2c transfer ack error. ++ */ ++static int mtk_i2c_do_transfer(struct mtk_i2c_priv *priv, ++ struct i2c_msg *msgs, ++ int num, int left_num) ++{ ++ struct i2c_msg *msg_rx = NULL; ++ uint restart_flag = 0; ++ uint trans_error = 0; ++ uint irq_stat = 0; ++ uint tmo_poll = 0; ++ uint control_reg; ++ bool tmo = false; ++ uint start_reg; ++ uint addr_reg; ++ int ret = 0; ++ ++ if (priv->auto_restart) ++ restart_flag = I2C_RS_TRANSFER; ++ ++ control_reg = i2c_readl(priv, REG_CONTROL) & ++ ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS); ++ ++ if (priv->speed > MAX_FS_MODE_SPEED || num > 1) ++ control_reg |= I2C_CONTROL_RS; ++ ++ if (priv->op == I2C_MASTER_WRRD) ++ control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS; ++ ++ control_reg |= I2C_CONTROL_DMA_EN; ++ i2c_writel(priv, REG_CONTROL, control_reg); ++ ++ /* set start condition */ ++ if (priv->speed <= MAX_ST_MODE_SPEED) ++ i2c_writel(priv, REG_EXT_CONF, I2C_ST_START_CON); ++ else ++ i2c_writel(priv, REG_EXT_CONF, I2C_FS_START_CON); ++ ++ addr_reg = msgs->addr << 1; ++ if (priv->op == I2C_MASTER_RD) ++ addr_reg |= I2C_M_RD; ++ if (priv->zero_len) ++ i2c_writel(priv, REG_SLAVE_ADDR, addr_reg | TRANS_ADDR_ONLY); ++ else ++ i2c_writel(priv, REG_SLAVE_ADDR, addr_reg); ++ ++ /* clear interrupt status */ ++ i2c_writel(priv, REG_INTR_STAT, restart_flag | I2C_HS_NACKERR | ++ I2C_ACKERR | I2C_TRANSAC_COMP); ++ i2c_writel(priv, REG_FIFO_ADDR_CLR, I2C_FIFO_ADDR_CLR); ++ ++ /* enable interrupt */ ++ i2c_writel(priv, REG_INTR_MASK, restart_flag | I2C_HS_NACKERR | ++ I2C_ACKERR | I2C_TRANSAC_COMP); ++ ++ /* set transfer and transaction len */ ++ if (priv->op == I2C_MASTER_WRRD) { ++ i2c_writel(priv, REG_TRANSFER_LEN, msgs->len); ++ i2c_writel(priv, REG_TRANSFER_LEN_AUX, (msgs + 1)->len); ++ i2c_writel(priv, REG_TRANSAC_LEN, I2C_WRRD_TRANAC_VALUE); ++ } else { ++ i2c_writel(priv, REG_TRANSFER_LEN, msgs->len); ++ i2c_writel(priv, REG_TRANSAC_LEN, num); ++ } ++ ++ /* Clear DMA interrupt flag */ ++ writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG); ++ ++ /* Flush cache for first msg */ ++ flush_cache((ulong)msgs->buf, msgs->len); ++ ++ /* ++ * prepare buffer data to start transfer ++ * three cases here: read, write, write then read ++ */ ++ if (priv->op & I2C_MASTER_WR) { ++ /* Set DMA direction TX (w/ or w/o RX) */ ++ writel(I2C_DMA_CON_TX, priv->pdmabase + REG_CON); ++ ++ /* Write the tx buffer address to dma register */ ++ writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR); ++ /* Write the tx length to dma register */ ++ writel(msgs->len, priv->pdmabase + REG_TX_LEN); ++ ++ if (priv->op & I2C_MASTER_RD) { ++ /* write then read */ ++ msg_rx = msgs + 1; ++ ++ /* Flush cache for second msg */ ++ flush_cache((ulong)msg_rx->buf, msg_rx->len); ++ } ++ } ++ ++ if (priv->op & I2C_MASTER_RD) { ++ if (!msg_rx) { ++ /* Set DMA direction RX */ ++ writel(I2C_DMA_CON_RX, priv->pdmabase + REG_CON); ++ ++ msg_rx = msgs; ++ } ++ ++ /* Write the rx buffer address to dma register */ ++ writel((ulong)msg_rx->buf, priv->pdmabase + REG_RX_MEM_ADDR); ++ /* Write the rx length to dma register */ ++ writel(msg_rx->len, priv->pdmabase + REG_RX_LEN); ++ } ++ ++ writel(I2C_DMA_START_EN, priv->pdmabase + REG_EN); ++ ++ if (!priv->auto_restart) { ++ start_reg = I2C_TRANSAC_START; ++ } else { ++ start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG; ++ if (left_num >= 1) ++ start_reg |= I2C_RS_MUL_CNFG; ++ } ++ i2c_writel(priv, REG_START, start_reg); ++ ++ for (;;) { ++ irq_stat = i2c_readl(priv, REG_INTR_STAT); ++ ++ /* ignore the first restart irq after the master code */ ++ if (priv->ignore_restart_irq && (irq_stat & restart_flag)) { ++ priv->ignore_restart_irq = false; ++ irq_stat = 0; ++ i2c_writel(priv, REG_START, I2C_RS_MUL_CNFG | ++ I2C_RS_MUL_TRIG | I2C_TRANSAC_START); ++ } ++ ++ if (irq_stat & (I2C_TRANSAC_COMP | restart_flag)) { ++ tmo = false; ++ if (irq_stat & (I2C_HS_NACKERR | I2C_ACKERR)) ++ trans_error = 1; ++ ++ break; ++ } ++ udelay(1); ++ if (tmo_poll++ >= TRANSFER_TIMEOUT) { ++ tmo = true; ++ break; ++ } ++ } ++ ++ /* clear interrupt mask */ ++ i2c_writel(priv, REG_INTR_MASK, ~(restart_flag | I2C_HS_NACKERR | ++ I2C_ACKERR | I2C_TRANSAC_COMP)); ++ ++ if (!tmo && trans_error != 0) { ++ if (tmo) { ++ ret = -ETIMEDOUT; ++ if (!priv->filter_msg) ++ debug("I2C timeout! addr: 0x%x,\n", msgs->addr); ++ } else { ++ ret = -EREMOTEIO; ++ if (!priv->filter_msg) ++ debug("I2C ACKERR! addr: 0x%x,IRQ:0x%x\n", ++ msgs->addr, irq_stat); ++ } ++ mtk_i2c_init_hw(priv); ++ } ++ ++ return ret; ++} ++ ++/* ++ * mtk_i2c_transfer ++ * ++ * @par Description ++ * Common i2c transfer API. Set i2c transfer mode according to i2c_msg\n ++ * information, then call mtk_i2c_do_transfer() to configure i2c register\n ++ * and trigger transfer. ++ * @param[in] ++ * dev: udevice pointer, struct udevice contains struct mtk_i2c_priv, \n ++ * struct mtk_i2c_priv contains register base\n ++ * address, operation mode, interrupt status and i2c driver data. ++ * @param[in] ++ * msgs: i2c_msg pointer, struct i2c_msg contains slave\n ++ * address, operation mode, msg length and data buffer. ++ * @param[in] ++ * num: i2c_msg number. ++ * @return ++ * i2c_msg number, i2c transfer successfully.\n ++ * -EINVAL, msg length is more than 16\n ++ * use DMA MODE or slave address more than 0x7f.\n ++ * error code from mtk_i2c_init_base().\n ++ * error code from mtk_i2c_set_speed().\n ++ * error code from mtk_i2c_do_transfer(). ++ */ ++static int mtk_i2c_transfer(struct udevice *dev, struct i2c_msg *msg, ++ int nmsgs) ++{ ++ struct mtk_i2c_priv *priv = dev_get_priv(dev); ++ int left_num; ++ uint num_cnt; ++ int ret; ++ ++ priv->auto_restart = true; ++ left_num = nmsgs; ++ if (mtk_i2c_clk_enable(priv)) ++ return log_msg_ret("transfer enable clk", -1); ++ ++ for (num_cnt = 0; num_cnt < nmsgs; num_cnt++) { ++ if (((msg + num_cnt)->addr) > MAX_I2C_ADDR) { ++ ret = -EINVAL; ++ goto err_exit; ++ } ++ if ((msg + num_cnt)->len > MAX_I2C_LEN) { ++ ret = -EINVAL; ++ goto err_exit; ++ } ++ } ++ ++ /* check if we can skip restart and optimize using WRRD mode */ ++ if (priv->auto_restart && nmsgs == 2) { ++ if (!(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD) && ++ msg[0].addr == msg[1].addr) { ++ priv->auto_restart = false; ++ } ++ } ++ ++ if (priv->auto_restart && nmsgs >= 2 && priv->speed > MAX_FS_MODE_SPEED) ++ /* ignore the first restart irq after the master code, ++ * otherwise the first transfer will be discarded. ++ */ ++ priv->ignore_restart_irq = true; ++ else ++ priv->ignore_restart_irq = false; ++ ++ while (left_num--) { ++ /* transfer slave address only to support devices detect */ ++ if (!msg->buf) ++ priv->zero_len = true; ++ else ++ priv->zero_len = false; ++ ++ if (msg->flags & I2C_M_RD) ++ priv->op = I2C_MASTER_RD; ++ else ++ priv->op = I2C_MASTER_WR; ++ ++ if (!priv->auto_restart) { ++ if (nmsgs > 1) { ++ /* combined two messages into one transaction */ ++ priv->op = I2C_MASTER_WRRD; ++ left_num--; ++ } ++ } ++ ret = mtk_i2c_do_transfer(priv, msg, nmsgs, left_num); ++ if (ret < 0) ++ goto err_exit; ++ msg++; ++ } ++ ret = 0; ++ ++err_exit: ++ if (mtk_i2c_clk_disable(priv)) ++ return log_msg_ret("transfer disable clk", -1); ++ ++ return ret; ++} ++ ++static int mtk_i2c_of_to_plat(struct udevice *dev) ++{ ++ struct mtk_i2c_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ priv->base = dev_remap_addr_index(dev, 0); ++ priv->pdmabase = dev_remap_addr_index(dev, 1); ++ ret = clk_get_by_index(dev, 0, &priv->clk_main); ++ if (ret) ++ return log_msg_ret("clk_get_by_index 0", ret); ++ ++ ret = clk_get_by_index(dev, 1, &priv->clk_dma); ++ ++ return ret; ++} ++ ++static int mtk_i2c_probe(struct udevice *dev) ++{ ++ struct mtk_i2c_priv *priv = dev_get_priv(dev); ++ ++ priv->soc_data = (struct mtk_i2c_soc_data *)dev_get_driver_data(dev); ++ ++ if (mtk_i2c_clk_enable(priv)) ++ return log_msg_ret("probe enable clk", -1); ++ ++ mtk_i2c_init_hw(priv); ++ ++ if (mtk_i2c_clk_disable(priv)) ++ return log_msg_ret("probe disable clk", -1); ++ ++ return 0; ++} ++ ++static int mtk_i2c_deblock(struct udevice *dev) ++{ ++ struct mtk_i2c_priv *priv = dev_get_priv(dev); ++ ++ if (mtk_i2c_clk_enable(priv)) ++ return log_msg_ret("deblock enable clk", -1); ++ ++ mtk_i2c_init_hw(priv); ++ ++ if (mtk_i2c_clk_disable(priv)) ++ return log_msg_ret("deblock disable clk", -1); ++ ++ return 0; ++} ++ ++static const struct mtk_i2c_soc_data mt76xx_soc_data = { ++ .regs = mt_i2c_regs_v1, ++ .dma_sync = 0, ++}; ++ ++static const struct mtk_i2c_soc_data mt7981_soc_data = { ++ .regs = mt_i2c_regs_v1, ++ .dma_sync = 1, ++}; ++ ++static const struct mtk_i2c_soc_data mt7986_soc_data = { ++ .regs = mt_i2c_regs_v1, ++ .dma_sync = 1, ++}; ++ ++static const struct mtk_i2c_soc_data mt8183_soc_data = { ++ .regs = mt_i2c_regs_v2, ++ .dma_sync = 1, ++}; ++ ++static const struct mtk_i2c_soc_data mt8518_soc_data = { ++ .regs = mt_i2c_regs_v1, ++ .dma_sync = 0, ++}; ++ ++static const struct mtk_i2c_soc_data mt8512_soc_data = { ++ .regs = mt_i2c_regs_v1, ++ .dma_sync = 1, ++}; ++ ++static const struct dm_i2c_ops mtk_i2c_ops = { ++ .xfer = mtk_i2c_transfer, ++ .set_bus_speed = mtk_i2c_set_speed, ++ .deblock = mtk_i2c_deblock, ++}; ++ ++static const struct udevice_id mtk_i2c_ids[] = { ++ { ++ .compatible = "mediatek,mt7622-i2c", ++ .data = (ulong)&mt76xx_soc_data, ++ }, { ++ .compatible = "mediatek,mt7623-i2c", ++ .data = (ulong)&mt76xx_soc_data, ++ }, { ++ .compatible = "mediatek,mt7629-i2c", ++ .data = (ulong)&mt76xx_soc_data, ++ }, { ++ .compatible = "mediatek,mt7981-i2c", ++ .data = (ulong)&mt7981_soc_data, ++ }, { ++ .compatible = "mediatek,mt7986-i2c", ++ .data = (ulong)&mt7986_soc_data, ++ }, { ++ .compatible = "mediatek,mt8183-i2c", ++ .data = (ulong)&mt8183_soc_data, ++ }, { ++ .compatible = "mediatek,mt8512-i2c", ++ .data = (ulong)&mt8512_soc_data, ++ }, { ++ .compatible = "mediatek,mt8518-i2c", ++ .data = (ulong)&mt8518_soc_data, ++ } ++}; ++ ++U_BOOT_DRIVER(mtk_i2c) = { ++ .name = "mtk_i2c", ++ .id = UCLASS_I2C, ++ .of_match = mtk_i2c_ids, ++ .of_to_plat = mtk_i2c_of_to_plat, ++ .probe = mtk_i2c_probe, ++ .priv_auto = sizeof(struct mtk_i2c_priv), ++ .ops = &mtk_i2c_ops, ++}; diff --git a/package/boot/uboot-mediatek/patches/002-0018-arm-dts-mt7622-add-i2c-support.patch b/package/boot/uboot-mediatek/patches/002-0018-arm-dts-mt7622-add-i2c-support.patch new file mode 100644 index 0000000000..415b37ba55 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0018-arm-dts-mt7622-add-i2c-support.patch @@ -0,0 +1,76 @@ +From 9ae337317d5634569bda83dfc5e0658fce34b1e2 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Mon, 25 Jul 2022 16:30:30 +0800 +Subject: [PATCH 18/31] arm: dts: mt7622: add i2c support + +Add both hardware and software i2c support for mt7622. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + arch/arm/dts/mt7622-rfb.dts | 18 ++++++++++++++++++ + arch/arm/dts/mt7622.dtsi | 24 ++++++++++++++++++++++++ + 2 files changed, 42 insertions(+) + +--- a/arch/arm/dts/mt7622-rfb.dts ++++ b/arch/arm/dts/mt7622-rfb.dts +@@ -159,6 +159,14 @@ + }; + + }; ++ ++ i2c1_pins_default: i2c1-default { ++ mux { ++ function = "i2c"; ++ groups = "i2c1_0"; ++ }; ++ }; ++ + }; + + &snfi { +@@ -249,3 +257,13 @@ + &u3phy { + status = "okay"; + }; ++ ++&soft_i2c { ++ status = "disabled"; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins_default>; ++ status = "okay"; ++}; +--- a/arch/arm/dts/mt7622.dtsi ++++ b/arch/arm/dts/mt7622.dtsi +@@ -440,4 +440,28 @@ + status = "disabled"; + }; + ++ soft_i2c: soft_i2c@0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "i2c-gpio"; ++ gpios = <&gpio 56 GPIO_ACTIVE_HIGH>, /* SDA */ ++ <&gpio 55 GPIO_ACTIVE_HIGH>; /* CLK */ ++ i2c-gpio,delay-us = <5>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@11008000 { ++ compatible = "mediatek,mt7622-i2c"; ++ reg = <0x11008000 0x90>, ++ <0x11000180 0x80>; ++ interrupts = ; ++ clock-div = <16>; ++ clocks = <&pericfg CLK_PERI_I2C1_PD>, ++ <&pericfg CLK_PERI_AP_DMA_PD>; ++ clock-names = "main", "dma"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ + }; diff --git a/package/boot/uboot-mediatek/patches/002-0019-dt-bindings-pinctrl-mediatek-add-a-header-for-common.patch b/package/boot/uboot-mediatek/patches/002-0019-dt-bindings-pinctrl-mediatek-add-a-header-for-common.patch new file mode 100644 index 0000000000..385ec1395b --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0019-dt-bindings-pinctrl-mediatek-add-a-header-for-common.patch @@ -0,0 +1,60 @@ +From 920ba7b9ba1787fd03dad7a5bdc894073936c197 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Thu, 28 Jul 2022 09:37:26 +0800 +Subject: [PATCH 19/31] dt-bindings: pinctrl: mediatek: add a header for common + pinconf parameters + +This patch adds a pinctrl header for common pinconf parameters such as +pull-up/pull-down resistors and drive strengths. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + include/dt-bindings/pinctrl/mt65xx.h | 41 ++++++++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + create mode 100644 include/dt-bindings/pinctrl/mt65xx.h + +--- /dev/null ++++ b/include/dt-bindings/pinctrl/mt65xx.h +@@ -0,0 +1,41 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2022 MediaTek Inc. ++ * Author: Hongzhou.Yang ++ */ ++ ++#ifndef _DT_BINDINGS_PINCTRL_MT65XX_H ++#define _DT_BINDINGS_PINCTRL_MT65XX_H ++ ++#define MTK_PIN_NO(x) ((x) << 8) ++#define MTK_GET_PIN_NO(x) ((x) >> 8) ++#define MTK_GET_PIN_FUNC(x) ((x) & 0xf) ++ ++#define MTK_PUPD_SET_R1R0_00 100 ++#define MTK_PUPD_SET_R1R0_01 101 ++#define MTK_PUPD_SET_R1R0_10 102 ++#define MTK_PUPD_SET_R1R0_11 103 ++ ++#define MTK_PULL_SET_RSEL_000 200 ++#define MTK_PULL_SET_RSEL_001 201 ++#define MTK_PULL_SET_RSEL_010 202 ++#define MTK_PULL_SET_RSEL_011 203 ++#define MTK_PULL_SET_RSEL_100 204 ++#define MTK_PULL_SET_RSEL_101 205 ++#define MTK_PULL_SET_RSEL_110 206 ++#define MTK_PULL_SET_RSEL_111 207 ++ ++#define MTK_DRIVE_2mA 2 ++#define MTK_DRIVE_4mA 4 ++#define MTK_DRIVE_6mA 6 ++#define MTK_DRIVE_8mA 8 ++#define MTK_DRIVE_10mA 10 ++#define MTK_DRIVE_12mA 12 ++#define MTK_DRIVE_14mA 14 ++#define MTK_DRIVE_16mA 16 ++#define MTK_DRIVE_20mA 20 ++#define MTK_DRIVE_24mA 24 ++#define MTK_DRIVE_28mA 28 ++#define MTK_DRIVE_32mA 32 ++ ++#endif /* _DT_BINDINGS_PINCTRL_MT65XX_H */ diff --git a/package/boot/uboot-mediatek/patches/002-0020-pinctrl-mediatek-add-pinctrl-driver-for-MT7981-SoC.patch b/package/boot/uboot-mediatek/patches/002-0020-pinctrl-mediatek-add-pinctrl-driver-for-MT7981-SoC.patch new file mode 100644 index 0000000000..809b3cbc9b --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0020-pinctrl-mediatek-add-pinctrl-driver-for-MT7981-SoC.patch @@ -0,0 +1,1091 @@ +From 49e7b1e01cf80437c7e22f8b6579d4a81e7f8a3a Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Thu, 28 Jul 2022 09:57:58 +0800 +Subject: [PATCH 20/31] pinctrl: mediatek: add pinctrl driver for MT7981 SoC + +This patch adds pinctrl and gpio support for MT7981 SoC + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/pinctrl/mediatek/Kconfig | 4 + + drivers/pinctrl/mediatek/Makefile | 1 + + drivers/pinctrl/mediatek/pinctrl-mt7981.c | 1049 +++++++++++++++++++++ + 3 files changed, 1054 insertions(+) + create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7981.c + +--- a/drivers/pinctrl/mediatek/Kconfig ++++ b/drivers/pinctrl/mediatek/Kconfig +@@ -16,6 +16,10 @@ config PINCTRL_MT7629 + bool "MT7629 SoC pinctrl driver" + select PINCTRL_MTK + ++config PINCTRL_MT7981 ++ bool "MT7981 SoC pinctrl driver" ++ select PINCTRL_MTK ++ + config PINCTRL_MT8512 + bool "MT8512 SoC pinctrl driver" + select PINCTRL_MTK +--- a/drivers/pinctrl/mediatek/Makefile ++++ b/drivers/pinctrl/mediatek/Makefile +@@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk + obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o + obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o + obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o ++obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o + obj-$(CONFIG_PINCTRL_MT8512) += pinctrl-mt8512.o + obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o + obj-$(CONFIG_PINCTRL_MT8518) += pinctrl-mt8518.o +--- /dev/null ++++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c +@@ -0,0 +1,1049 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * The MT7981 driver based on Linux generic pinctrl binding. ++ * ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#include ++#include "pinctrl-mtk-common.h" ++ ++#define MT7981_TYPE0_PIN(_number, _name) \ ++ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0) ++ ++#define MT7981_TYPE1_PIN(_number, _name) \ ++ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1) ++ ++#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ ++ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \ ++ _s_bit, _x_bits, 32, 0) ++ ++#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ ++ _x_bits) \ ++ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ ++ _x_bits, 32, 0) ++ ++/** ++ * enum - Locking variants of the iocfg bases ++ * ++ * MT7981 have multiple bases to program pin configuration listed as the below: ++ * iocfg_rt:0x11c00000, iocfg_rm:0x11c10000, iocfg_rb:0x11d20000, ++ * iocfg_lb:0x11e00000, iocfg_bl:0x11e20000, iocfg_tm:0x11f00000, ++ * iocfg_tl:0x11f10000, ++ * _i_based could be used to indicate what base the pin should be mapped into. ++ * ++ * Each iocfg register base control different group of pads on the SoC ++ * ++ * ++ * chip carrier ++ * ++ * A B C D E F G H ++ * +------------------------+ ++ * 8 | o o o o o o o o | ++ * 7 | o o o o o o o o | ++ * 6 | o o o o o o o o | ++ * 5 | o o o o o o o o | ++ * 4 | o o o o o o o o | ++ * 3 | o o o o o o o o | ++ * 2 | o o o o o o o o | ++ * 1 | o o o o o o o o | ++ * +------------------------+ ++ * ++ * inside Chip carrier ++ * ++ * A B C D E F G H ++ * +------------------------+ ++ * 8 | | ++ * 7 | TL TM | ++ * 6 | +---------+ | ++ * 5 | | | RT | ++ * 4 | | | RM | ++ * 3 | LB | | RB | ++ * 2 | +---------+ | ++ * 1 | BL | ++ * +------------------------+ ++ * ++ */ ++ ++enum { ++ GPIO_BASE, ++ IOCFG_RT_BASE, ++ IOCFG_RM_BASE, ++ IOCFG_RB_BASE, ++ IOCFG_LB_BASE, ++ IOCFG_BL_BASE, ++ IOCFG_TM_BASE, ++ IOCFG_TL_BASE, ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_mode_range[] = { ++ PIN_FIELD_GPIO(0, 56, 0x300, 0x10, 0, 4), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_dir_range[] = { ++ PIN_FIELD_GPIO(0, 56, 0x0, 0x10, 0, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_di_range[] = { ++ PIN_FIELD_GPIO(0, 56, 0x200, 0x10, 0, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_do_range[] = { ++ PIN_FIELD_GPIO(0, 56, 0x100, 0x10, 0, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_ies_range[] = { ++ PIN_FIELD_BASE(0, 0, 1, 0x10, 0x10, 1, 1), ++ PIN_FIELD_BASE(1, 1, 1, 0x10, 0x10, 0, 1), ++ PIN_FIELD_BASE(2, 2, 5, 0x20, 0x10, 6, 1), ++ PIN_FIELD_BASE(3, 3, 4, 0x20, 0x10, 6, 1), ++ PIN_FIELD_BASE(4, 4, 4, 0x20, 0x10, 2, 1), ++ PIN_FIELD_BASE(5, 5, 4, 0x20, 0x10, 1, 1), ++ PIN_FIELD_BASE(6, 6, 4, 0x20, 0x10, 3, 1), ++ PIN_FIELD_BASE(7, 7, 4, 0x20, 0x10, 0, 1), ++ PIN_FIELD_BASE(8, 8, 4, 0x20, 0x10, 4, 1), ++ PIN_FIELD_BASE(9, 9, 4, 0x20, 0x10, 9, 1), ++ ++ PIN_FIELD_BASE(10, 10, 5, 0x20, 0x10, 8, 1), ++ PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1), ++ PIN_FIELD_BASE(12, 12, 5, 0x20, 0x10, 7, 1), ++ PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1), ++ ++ PIN_FIELD_BASE(14, 14, 4, 0x20, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(15, 15, 2, 0x20, 0x10, 0, 1), ++ PIN_FIELD_BASE(16, 16, 2, 0x20, 0x10, 1, 1), ++ PIN_FIELD_BASE(17, 17, 2, 0x20, 0x10, 5, 1), ++ PIN_FIELD_BASE(18, 18, 2, 0x20, 0x10, 4, 1), ++ PIN_FIELD_BASE(19, 19, 2, 0x20, 0x10, 2, 1), ++ PIN_FIELD_BASE(20, 20, 2, 0x20, 0x10, 3, 1), ++ PIN_FIELD_BASE(21, 21, 2, 0x20, 0x10, 6, 1), ++ PIN_FIELD_BASE(22, 22, 2, 0x20, 0x10, 7, 1), ++ PIN_FIELD_BASE(23, 23, 2, 0x20, 0x10, 10, 1), ++ PIN_FIELD_BASE(24, 24, 2, 0x20, 0x10, 9, 1), ++ PIN_FIELD_BASE(25, 25, 2, 0x20, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(26, 26, 5, 0x20, 0x10, 0, 1), ++ PIN_FIELD_BASE(27, 27, 5, 0x20, 0x10, 4, 1), ++ PIN_FIELD_BASE(28, 28, 5, 0x20, 0x10, 3, 1), ++ PIN_FIELD_BASE(29, 29, 5, 0x20, 0x10, 1, 1), ++ PIN_FIELD_BASE(30, 30, 5, 0x20, 0x10, 2, 1), ++ PIN_FIELD_BASE(31, 31, 5, 0x20, 0x10, 5, 1), ++ ++ PIN_FIELD_BASE(32, 32, 1, 0x10, 0x10, 2, 1), ++ PIN_FIELD_BASE(33, 33, 1, 0x10, 0x10, 3, 1), ++ ++ PIN_FIELD_BASE(34, 34, 4, 0x20, 0x10, 5, 1), ++ PIN_FIELD_BASE(35, 35, 4, 0x20, 0x10, 7, 1), ++ ++ PIN_FIELD_BASE(36, 36, 3, 0x10, 0x10, 2, 1), ++ PIN_FIELD_BASE(37, 37, 3, 0x10, 0x10, 3, 1), ++ PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 0, 1), ++ PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 1, 1), ++ ++ PIN_FIELD_BASE(40, 40, 7, 0x30, 0x10, 1, 1), ++ PIN_FIELD_BASE(41, 41, 7, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(42, 42, 7, 0x30, 0x10, 9, 1), ++ PIN_FIELD_BASE(43, 43, 7, 0x30, 0x10, 7, 1), ++ PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1), ++ PIN_FIELD_BASE(45, 45, 7, 0x30, 0x10, 3, 1), ++ PIN_FIELD_BASE(46, 46, 7, 0x30, 0x10, 4, 1), ++ PIN_FIELD_BASE(47, 47, 7, 0x30, 0x10, 5, 1), ++ PIN_FIELD_BASE(48, 48, 7, 0x30, 0x10, 6, 1), ++ PIN_FIELD_BASE(49, 49, 7, 0x30, 0x10, 2, 1), ++ ++ PIN_FIELD_BASE(50, 50, 6, 0x10, 0x10, 0, 1), ++ PIN_FIELD_BASE(51, 51, 6, 0x10, 0x10, 2, 1), ++ PIN_FIELD_BASE(52, 52, 6, 0x10, 0x10, 3, 1), ++ PIN_FIELD_BASE(53, 53, 6, 0x10, 0x10, 4, 1), ++ PIN_FIELD_BASE(54, 54, 6, 0x10, 0x10, 5, 1), ++ PIN_FIELD_BASE(55, 55, 6, 0x10, 0x10, 6, 1), ++ PIN_FIELD_BASE(56, 56, 6, 0x10, 0x10, 1, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_smt_range[] = { ++ PIN_FIELD_BASE(0, 0, 1, 0x60, 0x10, 1, 1), ++ PIN_FIELD_BASE(1, 1, 1, 0x60, 0x10, 0, 1), ++ PIN_FIELD_BASE(2, 2, 5, 0x90, 0x10, 6, 1), ++ PIN_FIELD_BASE(3, 3, 4, 0x80, 0x10, 6, 1), ++ PIN_FIELD_BASE(4, 4, 4, 0x80, 0x10, 2, 1), ++ PIN_FIELD_BASE(5, 5, 4, 0x80, 0x10, 1, 1), ++ PIN_FIELD_BASE(6, 6, 4, 0x80, 0x10, 3, 1), ++ PIN_FIELD_BASE(7, 7, 4, 0x80, 0x10, 0, 1), ++ PIN_FIELD_BASE(8, 8, 4, 0x80, 0x10, 4, 1), ++ PIN_FIELD_BASE(9, 9, 4, 0x80, 0x10, 9, 1), ++ ++ PIN_FIELD_BASE(10, 10, 5, 0x90, 0x10, 8, 1), ++ PIN_FIELD_BASE(11, 11, 5, 0x90, 0x10, 10, 1), ++ PIN_FIELD_BASE(12, 12, 5, 0x90, 0x10, 7, 1), ++ PIN_FIELD_BASE(13, 13, 5, 0x90, 0x10, 11, 1), ++ ++ PIN_FIELD_BASE(14, 14, 4, 0x80, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(15, 15, 2, 0x90, 0x10, 0, 1), ++ PIN_FIELD_BASE(16, 16, 2, 0x90, 0x10, 1, 1), ++ PIN_FIELD_BASE(17, 17, 2, 0x90, 0x10, 5, 1), ++ PIN_FIELD_BASE(18, 18, 2, 0x90, 0x10, 4, 1), ++ PIN_FIELD_BASE(19, 19, 2, 0x90, 0x10, 2, 1), ++ PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1), ++ PIN_FIELD_BASE(21, 21, 2, 0x90, 0x10, 6, 1), ++ PIN_FIELD_BASE(22, 22, 2, 0x90, 0x10, 7, 1), ++ PIN_FIELD_BASE(23, 23, 2, 0x90, 0x10, 10, 1), ++ PIN_FIELD_BASE(24, 24, 2, 0x90, 0x10, 9, 1), ++ PIN_FIELD_BASE(25, 25, 2, 0x90, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(26, 26, 5, 0x90, 0x10, 0, 1), ++ PIN_FIELD_BASE(27, 27, 5, 0x90, 0x10, 4, 1), ++ PIN_FIELD_BASE(28, 28, 5, 0x90, 0x10, 3, 1), ++ PIN_FIELD_BASE(29, 29, 5, 0x90, 0x10, 1, 1), ++ PIN_FIELD_BASE(30, 30, 5, 0x90, 0x10, 2, 1), ++ PIN_FIELD_BASE(31, 31, 5, 0x90, 0x10, 5, 1), ++ ++ PIN_FIELD_BASE(32, 32, 1, 0x60, 0x10, 2, 1), ++ PIN_FIELD_BASE(33, 33, 1, 0x60, 0x10, 3, 1), ++ ++ PIN_FIELD_BASE(34, 34, 4, 0x80, 0x10, 5, 1), ++ PIN_FIELD_BASE(35, 35, 4, 0x80, 0x10, 7, 1), ++ ++ PIN_FIELD_BASE(36, 36, 3, 0x60, 0x10, 2, 1), ++ PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 3, 1), ++ PIN_FIELD_BASE(38, 38, 3, 0x60, 0x10, 0, 1), ++ PIN_FIELD_BASE(39, 39, 3, 0x60, 0x10, 1, 1), ++ ++ PIN_FIELD_BASE(40, 40, 7, 0x70, 0x10, 1, 1), ++ PIN_FIELD_BASE(41, 41, 7, 0x70, 0x10, 0, 1), ++ PIN_FIELD_BASE(42, 42, 7, 0x70, 0x10, 9, 1), ++ PIN_FIELD_BASE(43, 43, 7, 0x70, 0x10, 7, 1), ++ PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1), ++ PIN_FIELD_BASE(45, 45, 7, 0x70, 0x10, 3, 1), ++ PIN_FIELD_BASE(46, 46, 7, 0x70, 0x10, 4, 1), ++ PIN_FIELD_BASE(47, 47, 7, 0x70, 0x10, 5, 1), ++ PIN_FIELD_BASE(48, 48, 7, 0x70, 0x10, 6, 1), ++ PIN_FIELD_BASE(49, 49, 7, 0x70, 0x10, 2, 1), ++ ++ PIN_FIELD_BASE(50, 50, 6, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(51, 51, 6, 0x50, 0x10, 2, 1), ++ PIN_FIELD_BASE(52, 52, 6, 0x50, 0x10, 3, 1), ++ PIN_FIELD_BASE(53, 53, 6, 0x50, 0x10, 4, 1), ++ PIN_FIELD_BASE(54, 54, 6, 0x50, 0x10, 5, 1), ++ PIN_FIELD_BASE(55, 55, 6, 0x50, 0x10, 6, 1), ++ PIN_FIELD_BASE(56, 56, 6, 0x50, 0x10, 1, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_pu_range[] = { ++ PIN_FIELD_BASE(40, 40, 7, 0x50, 0x10, 1, 1), ++ PIN_FIELD_BASE(41, 41, 7, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(42, 42, 7, 0x50, 0x10, 9, 1), ++ PIN_FIELD_BASE(43, 43, 7, 0x50, 0x10, 7, 1), ++ PIN_FIELD_BASE(44, 44, 7, 0x50, 0x10, 8, 1), ++ PIN_FIELD_BASE(45, 45, 7, 0x50, 0x10, 3, 1), ++ PIN_FIELD_BASE(46, 46, 7, 0x50, 0x10, 4, 1), ++ PIN_FIELD_BASE(47, 47, 7, 0x50, 0x10, 5, 1), ++ PIN_FIELD_BASE(48, 48, 7, 0x50, 0x10, 6, 1), ++ PIN_FIELD_BASE(49, 49, 7, 0x50, 0x10, 2, 1), ++ ++ PIN_FIELD_BASE(50, 50, 6, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(51, 51, 6, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(52, 52, 6, 0x30, 0x10, 3, 1), ++ PIN_FIELD_BASE(53, 53, 6, 0x30, 0x10, 4, 1), ++ PIN_FIELD_BASE(54, 54, 6, 0x30, 0x10, 5, 1), ++ PIN_FIELD_BASE(55, 55, 6, 0x30, 0x10, 6, 1), ++ PIN_FIELD_BASE(56, 56, 6, 0x30, 0x10, 1, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_pd_range[] = { ++ PIN_FIELD_BASE(40, 40, 7, 0x40, 0x10, 1, 1), ++ PIN_FIELD_BASE(41, 41, 7, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(42, 42, 7, 0x40, 0x10, 9, 1), ++ PIN_FIELD_BASE(43, 43, 7, 0x40, 0x10, 7, 1), ++ PIN_FIELD_BASE(44, 44, 7, 0x40, 0x10, 8, 1), ++ PIN_FIELD_BASE(45, 45, 7, 0x40, 0x10, 3, 1), ++ PIN_FIELD_BASE(46, 46, 7, 0x40, 0x10, 4, 1), ++ PIN_FIELD_BASE(47, 47, 7, 0x40, 0x10, 5, 1), ++ PIN_FIELD_BASE(48, 48, 7, 0x40, 0x10, 6, 1), ++ PIN_FIELD_BASE(49, 49, 7, 0x40, 0x10, 2, 1), ++ ++ PIN_FIELD_BASE(50, 50, 6, 0x20, 0x10, 0, 1), ++ PIN_FIELD_BASE(51, 51, 6, 0x20, 0x10, 2, 1), ++ PIN_FIELD_BASE(52, 52, 6, 0x20, 0x10, 3, 1), ++ PIN_FIELD_BASE(53, 53, 6, 0x20, 0x10, 4, 1), ++ PIN_FIELD_BASE(54, 54, 6, 0x20, 0x10, 5, 1), ++ PIN_FIELD_BASE(55, 55, 6, 0x20, 0x10, 6, 1), ++ PIN_FIELD_BASE(56, 56, 6, 0x20, 0x10, 1, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_drv_range[] = { ++ PIN_FIELD_BASE(0, 0, 1, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(1, 1, 1, 0x00, 0x10, 0, 3), ++ ++ PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 18, 3), ++ ++ PIN_FIELD_BASE(3, 3, 4, 0x00, 0x10, 18, 1), ++ PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 1), ++ PIN_FIELD_BASE(5, 5, 4, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(6, 6, 4, 0x00, 0x10, 9, 3), ++ PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 12, 3), ++ PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 27, 3), ++ ++ PIN_FIELD_BASE(10, 10, 5, 0x00, 0x10, 24, 3), ++ PIN_FIELD_BASE(11, 11, 5, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(12, 12, 5, 0x00, 0x10, 21, 3), ++ PIN_FIELD_BASE(13, 13, 5, 0x00, 0x10, 3, 3), ++ ++ PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3), ++ ++ PIN_FIELD_BASE(15, 15, 2, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(16, 16, 2, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(17, 17, 2, 0x00, 0x10, 15, 3), ++ PIN_FIELD_BASE(18, 18, 2, 0x00, 0x10, 12, 3), ++ PIN_FIELD_BASE(19, 19, 2, 0x00, 0x10, 6, 3), ++ PIN_FIELD_BASE(20, 20, 2, 0x00, 0x10, 9, 3), ++ PIN_FIELD_BASE(21, 21, 2, 0x00, 0x10, 18, 3), ++ PIN_FIELD_BASE(22, 22, 2, 0x00, 0x10, 21, 3), ++ PIN_FIELD_BASE(23, 23, 2, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3), ++ PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3), ++ ++ PIN_FIELD_BASE(26, 26, 5, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(27, 27, 5, 0x00, 0x10, 12, 3), ++ PIN_FIELD_BASE(28, 28, 5, 0x00, 0x10, 9, 3), ++ PIN_FIELD_BASE(29, 29, 5, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(30, 30, 5, 0x00, 0x10, 6, 3), ++ PIN_FIELD_BASE(31, 31, 5, 0x00, 0x10, 15, 3), ++ ++ PIN_FIELD_BASE(32, 32, 1, 0x00, 0x10, 9, 3), ++ PIN_FIELD_BASE(33, 33, 1, 0x00, 0x10, 12, 3), ++ ++ PIN_FIELD_BASE(34, 34, 4, 0x00, 0x10, 15, 3), ++ PIN_FIELD_BASE(35, 35, 4, 0x00, 0x10, 21, 3), ++ ++ PIN_FIELD_BASE(36, 36, 3, 0x00, 0x10, 6, 3), ++ PIN_FIELD_BASE(37, 37, 3, 0x00, 0x10, 9, 3), ++ PIN_FIELD_BASE(38, 38, 3, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(39, 39, 3, 0x00, 0x10, 3, 3), ++ ++ PIN_FIELD_BASE(40, 40, 7, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(41, 41, 7, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(42, 42, 7, 0x00, 0x10, 27, 3), ++ PIN_FIELD_BASE(43, 43, 7, 0x00, 0x10, 21, 3), ++ PIN_FIELD_BASE(44, 44, 7, 0x00, 0x10, 24, 3), ++ PIN_FIELD_BASE(45, 45, 7, 0x00, 0x10, 9, 3), ++ PIN_FIELD_BASE(46, 46, 7, 0x00, 0x10, 12, 3), ++ PIN_FIELD_BASE(47, 47, 7, 0x00, 0x10, 15, 3), ++ PIN_FIELD_BASE(48, 48, 7, 0x00, 0x10, 18, 3), ++ PIN_FIELD_BASE(49, 49, 7, 0x00, 0x10, 6, 3), ++ ++ PIN_FIELD_BASE(50, 50, 6, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(51, 51, 6, 0x00, 0x10, 6, 3), ++ PIN_FIELD_BASE(52, 52, 6, 0x00, 0x10, 9, 3), ++ PIN_FIELD_BASE(53, 53, 6, 0x00, 0x10, 12, 3), ++ PIN_FIELD_BASE(54, 54, 6, 0x00, 0x10, 15, 3), ++ PIN_FIELD_BASE(55, 55, 6, 0x00, 0x10, 18, 3), ++ PIN_FIELD_BASE(56, 56, 6, 0x00, 0x10, 3, 3), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_pupd_range[] = { ++ PIN_FIELD_BASE(0, 0, 1, 0x20, 0x10, 1, 1), ++ PIN_FIELD_BASE(1, 1, 1, 0x20, 0x10, 0, 1), ++ PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 6, 1), ++ PIN_FIELD_BASE(3, 3, 4, 0x30, 0x10, 6, 1), ++ PIN_FIELD_BASE(4, 4, 4, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(5, 5, 4, 0x30, 0x10, 1, 1), ++ PIN_FIELD_BASE(6, 6, 4, 0x30, 0x10, 3, 1), ++ PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 4, 1), ++ PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 9, 1), ++ ++ PIN_FIELD_BASE(10, 10, 5, 0x30, 0x10, 8, 1), ++ PIN_FIELD_BASE(11, 11, 5, 0x30, 0x10, 10, 1), ++ PIN_FIELD_BASE(12, 12, 5, 0x30, 0x10, 7, 1), ++ PIN_FIELD_BASE(13, 13, 5, 0x30, 0x10, 11, 1), ++ ++ PIN_FIELD_BASE(14, 14, 4, 0x30, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(15, 15, 2, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(16, 16, 2, 0x30, 0x10, 1, 1), ++ PIN_FIELD_BASE(17, 17, 2, 0x30, 0x10, 5, 1), ++ PIN_FIELD_BASE(18, 18, 2, 0x30, 0x10, 4, 1), ++ PIN_FIELD_BASE(19, 19, 2, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1), ++ PIN_FIELD_BASE(21, 21, 2, 0x30, 0x10, 6, 1), ++ PIN_FIELD_BASE(22, 22, 2, 0x30, 0x10, 7, 1), ++ PIN_FIELD_BASE(23, 23, 2, 0x30, 0x10, 10, 1), ++ PIN_FIELD_BASE(24, 24, 2, 0x30, 0x10, 9, 1), ++ PIN_FIELD_BASE(25, 25, 2, 0x30, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(26, 26, 5, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(27, 27, 5, 0x30, 0x10, 4, 1), ++ PIN_FIELD_BASE(28, 28, 5, 0x30, 0x10, 3, 1), ++ PIN_FIELD_BASE(29, 29, 5, 0x30, 0x10, 1, 1), ++ PIN_FIELD_BASE(30, 30, 5, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(31, 31, 5, 0x30, 0x10, 5, 1), ++ ++ PIN_FIELD_BASE(32, 32, 1, 0x20, 0x10, 2, 1), ++ PIN_FIELD_BASE(33, 33, 1, 0x20, 0x10, 3, 1), ++ ++ PIN_FIELD_BASE(34, 34, 4, 0x30, 0x10, 5, 1), ++ PIN_FIELD_BASE(35, 35, 4, 0x30, 0x10, 7, 1), ++ ++ PIN_FIELD_BASE(36, 36, 3, 0x20, 0x10, 2, 1), ++ PIN_FIELD_BASE(37, 37, 3, 0x20, 0x10, 3, 1), ++ PIN_FIELD_BASE(38, 38, 3, 0x20, 0x10, 0, 1), ++ PIN_FIELD_BASE(39, 39, 3, 0x20, 0x10, 1, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_r0_range[] = { ++ PIN_FIELD_BASE(0, 0, 1, 0x30, 0x10, 1, 1), ++ PIN_FIELD_BASE(1, 1, 1, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(2, 2, 5, 0x40, 0x10, 6, 1), ++ PIN_FIELD_BASE(3, 3, 4, 0x40, 0x10, 6, 1), ++ PIN_FIELD_BASE(4, 4, 4, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(5, 5, 4, 0x40, 0x10, 1, 1), ++ PIN_FIELD_BASE(6, 6, 4, 0x40, 0x10, 3, 1), ++ PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1), ++ PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 9, 1), ++ ++ PIN_FIELD_BASE(10, 10, 5, 0x40, 0x10, 8, 1), ++ PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1), ++ PIN_FIELD_BASE(12, 12, 5, 0x40, 0x10, 7, 1), ++ PIN_FIELD_BASE(13, 13, 5, 0x40, 0x10, 11, 1), ++ ++ PIN_FIELD_BASE(14, 14, 4, 0x40, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(15, 15, 2, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(16, 16, 2, 0x40, 0x10, 1, 1), ++ PIN_FIELD_BASE(17, 17, 2, 0x40, 0x10, 5, 1), ++ PIN_FIELD_BASE(18, 18, 2, 0x40, 0x10, 4, 1), ++ PIN_FIELD_BASE(19, 19, 2, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(20, 20, 2, 0x40, 0x10, 3, 1), ++ PIN_FIELD_BASE(21, 21, 2, 0x40, 0x10, 6, 1), ++ PIN_FIELD_BASE(22, 22, 2, 0x40, 0x10, 7, 1), ++ PIN_FIELD_BASE(23, 23, 2, 0x40, 0x10, 10, 1), ++ PIN_FIELD_BASE(24, 24, 2, 0x40, 0x10, 9, 1), ++ PIN_FIELD_BASE(25, 25, 2, 0x40, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(26, 26, 5, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(27, 27, 5, 0x40, 0x10, 4, 1), ++ PIN_FIELD_BASE(28, 28, 5, 0x40, 0x10, 3, 1), ++ PIN_FIELD_BASE(29, 29, 5, 0x40, 0x10, 1, 1), ++ PIN_FIELD_BASE(30, 30, 5, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(31, 31, 5, 0x40, 0x10, 5, 1), ++ ++ PIN_FIELD_BASE(32, 32, 1, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(33, 33, 1, 0x30, 0x10, 3, 1), ++ ++ PIN_FIELD_BASE(34, 34, 4, 0x40, 0x10, 5, 1), ++ PIN_FIELD_BASE(35, 35, 4, 0x40, 0x10, 7, 1), ++ ++ PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 3, 1), ++ PIN_FIELD_BASE(38, 38, 3, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(39, 39, 3, 0x30, 0x10, 1, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7981_pin_r1_range[] = { ++ PIN_FIELD_BASE(0, 0, 1, 0x40, 0x10, 1, 1), ++ PIN_FIELD_BASE(1, 1, 1, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 6, 1), ++ PIN_FIELD_BASE(3, 3, 4, 0x50, 0x10, 6, 1), ++ PIN_FIELD_BASE(4, 4, 4, 0x50, 0x10, 2, 1), ++ PIN_FIELD_BASE(5, 5, 4, 0x50, 0x10, 1, 1), ++ PIN_FIELD_BASE(6, 6, 4, 0x50, 0x10, 3, 1), ++ PIN_FIELD_BASE(7, 7, 4, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(8, 8, 4, 0x50, 0x10, 4, 1), ++ PIN_FIELD_BASE(9, 9, 4, 0x50, 0x10, 9, 1), ++ ++ PIN_FIELD_BASE(10, 10, 5, 0x50, 0x10, 8, 1), ++ PIN_FIELD_BASE(11, 11, 5, 0x50, 0x10, 10, 1), ++ PIN_FIELD_BASE(12, 12, 5, 0x50, 0x10, 7, 1), ++ PIN_FIELD_BASE(13, 13, 5, 0x50, 0x10, 11, 1), ++ ++ PIN_FIELD_BASE(14, 14, 4, 0x50, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(15, 15, 2, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(16, 16, 2, 0x50, 0x10, 1, 1), ++ PIN_FIELD_BASE(17, 17, 2, 0x50, 0x10, 5, 1), ++ PIN_FIELD_BASE(18, 18, 2, 0x50, 0x10, 4, 1), ++ PIN_FIELD_BASE(19, 19, 2, 0x50, 0x10, 2, 1), ++ PIN_FIELD_BASE(20, 20, 2, 0x50, 0x10, 3, 1), ++ PIN_FIELD_BASE(21, 21, 2, 0x50, 0x10, 6, 1), ++ PIN_FIELD_BASE(22, 22, 2, 0x50, 0x10, 7, 1), ++ PIN_FIELD_BASE(23, 23, 2, 0x50, 0x10, 10, 1), ++ PIN_FIELD_BASE(24, 24, 2, 0x50, 0x10, 9, 1), ++ PIN_FIELD_BASE(25, 25, 2, 0x50, 0x10, 8, 1), ++ ++ PIN_FIELD_BASE(26, 26, 5, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(27, 27, 5, 0x50, 0x10, 4, 1), ++ PIN_FIELD_BASE(28, 28, 5, 0x50, 0x10, 3, 1), ++ PIN_FIELD_BASE(29, 29, 5, 0x50, 0x10, 1, 1), ++ PIN_FIELD_BASE(30, 30, 5, 0x50, 0x10, 2, 1), ++ PIN_FIELD_BASE(31, 31, 5, 0x50, 0x10, 5, 1), ++ ++ PIN_FIELD_BASE(32, 32, 1, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(33, 33, 1, 0x40, 0x10, 3, 1), ++ ++ PIN_FIELD_BASE(34, 34, 4, 0x50, 0x10, 5, 1), ++ PIN_FIELD_BASE(35, 35, 4, 0x50, 0x10, 7, 1), ++ ++ PIN_FIELD_BASE(36, 36, 3, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(37, 37, 3, 0x40, 0x10, 3, 1), ++ PIN_FIELD_BASE(38, 38, 3, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1), ++}; ++ ++static const struct mtk_pin_reg_calc mt7981_reg_cals[] = { ++ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range), ++ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range), ++ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7981_pin_di_range), ++ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7981_pin_do_range), ++ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7981_pin_smt_range), ++ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7981_pin_ies_range), ++ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7981_pin_pu_range), ++ [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7981_pin_pd_range), ++ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7981_pin_drv_range), ++ [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7981_pin_pupd_range), ++ [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7981_pin_r0_range), ++ [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7981_pin_r1_range), ++}; ++ ++static const struct mtk_pin_desc mt7981_pins[] = { ++ MT7981_TYPE0_PIN(0, "GPIO_WPS"), ++ MT7981_TYPE0_PIN(1, "GPIO_RESET"), ++ MT7981_TYPE0_PIN(2, "SYS_WATCHDOG"), ++ MT7981_TYPE0_PIN(3, "PCIE_PERESET_N"), ++ MT7981_TYPE0_PIN(4, "JTAG_JTDO"), ++ MT7981_TYPE0_PIN(5, "JTAG_JTDI"), ++ MT7981_TYPE0_PIN(6, "JTAG_JTMS"), ++ MT7981_TYPE0_PIN(7, "JTAG_JTCLK"), ++ MT7981_TYPE0_PIN(8, "JTAG_JTRST_N"), ++ MT7981_TYPE0_PIN(9, "WO_JTAG_JTDO"), ++ MT7981_TYPE0_PIN(10, "WO_JTAG_JTDI"), ++ MT7981_TYPE0_PIN(11, "WO_JTAG_JTMS"), ++ MT7981_TYPE0_PIN(12, "WO_JTAG_JTCLK"), ++ MT7981_TYPE0_PIN(13, "WO_JTAG_JTRST_N"), ++ MT7981_TYPE0_PIN(14, "USB_VBUS"), ++ MT7981_TYPE0_PIN(15, "PWM0"), ++ MT7981_TYPE0_PIN(16, "SPI0_CLK"), ++ MT7981_TYPE0_PIN(17, "SPI0_MOSI"), ++ MT7981_TYPE0_PIN(18, "SPI0_MISO"), ++ MT7981_TYPE0_PIN(19, "SPI0_CS"), ++ MT7981_TYPE0_PIN(20, "SPI0_HOLD"), ++ MT7981_TYPE0_PIN(21, "SPI0_WP"), ++ MT7981_TYPE0_PIN(22, "SPI1_CLK"), ++ MT7981_TYPE0_PIN(23, "SPI1_MOSI"), ++ MT7981_TYPE0_PIN(24, "SPI1_MISO"), ++ MT7981_TYPE0_PIN(25, "SPI1_CS"), ++ MT7981_TYPE0_PIN(26, "SPI2_CLK"), ++ MT7981_TYPE0_PIN(27, "SPI2_MOSI"), ++ MT7981_TYPE0_PIN(28, "SPI2_MISO"), ++ MT7981_TYPE0_PIN(29, "SPI2_CS"), ++ MT7981_TYPE0_PIN(30, "SPI2_HOLD"), ++ MT7981_TYPE0_PIN(31, "SPI2_WP"), ++ MT7981_TYPE0_PIN(32, "UART0_RXD"), ++ MT7981_TYPE0_PIN(33, "UART0_TXD"), ++ MT7981_TYPE0_PIN(34, "PCIE_CLK_REQ"), ++ MT7981_TYPE0_PIN(35, "PCIE_WAKE_N"), ++ MT7981_TYPE0_PIN(36, "SMI_MDC"), ++ MT7981_TYPE0_PIN(37, "SMI_MDIO"), ++ MT7981_TYPE0_PIN(38, "GBE_INT"), ++ MT7981_TYPE0_PIN(39, "GBE_RESET"), ++ MT7981_TYPE1_PIN(40, "WF_DIG_RESETB"), ++ MT7981_TYPE1_PIN(41, "WF_CBA_RESETB"), ++ MT7981_TYPE1_PIN(42, "WF_XO_REQ"), ++ MT7981_TYPE1_PIN(43, "WF_TOP_CLK"), ++ MT7981_TYPE1_PIN(44, "WF_TOP_DATA"), ++ MT7981_TYPE1_PIN(45, "WF_HB1"), ++ MT7981_TYPE1_PIN(46, "WF_HB2"), ++ MT7981_TYPE1_PIN(47, "WF_HB3"), ++ MT7981_TYPE1_PIN(48, "WF_HB4"), ++ MT7981_TYPE1_PIN(49, "WF_HB0"), ++ MT7981_TYPE1_PIN(50, "WF_HB0_B"), ++ MT7981_TYPE1_PIN(51, "WF_HB5"), ++ MT7981_TYPE1_PIN(52, "WF_HB6"), ++ MT7981_TYPE1_PIN(53, "WF_HB7"), ++ MT7981_TYPE1_PIN(54, "WF_HB8"), ++ MT7981_TYPE1_PIN(55, "WF_HB9"), ++ MT7981_TYPE1_PIN(56, "WF_HB10"), ++}; ++ ++/* WA_AICE */ ++static int mt7981_wa_aice1_pins[] = { 0, 1, }; ++static int mt7981_wa_aice1_funcs[] = { 2, 2, }; ++ ++static int mt7981_wa_aice2_pins[] = { 0, 1, }; ++static int mt7981_wa_aice2_funcs[] = { 3, 3, }; ++ ++static int mt7981_wa_aice3_pins[] = { 28, 29, }; ++static int mt7981_wa_aice3_funcs[] = { 3, 3, }; ++ ++static int mt7981_wm_aice1_pins[] = { 9, 10, }; ++static int mt7981_wm_aice1_funcs[] = { 2, 2, }; ++ ++static int mt7981_wm_aice2_pins[] = { 30, 31, }; ++static int mt7981_wm_aice2_funcs[] = { 5, 5, }; ++ ++/* WM_UART */ ++static int mt7981_wm_uart_0_pins[] = { 0, 1, }; ++static int mt7981_wm_uart_0_funcs[] = { 5, 5, }; ++ ++static int mt7981_wm_uart_1_pins[] = { 20, 21, }; ++static int mt7981_wm_uart_1_funcs[] = { 4, 4, }; ++ ++static int mt7981_wm_uart_2_pins[] = { 30, 31, }; ++static int mt7981_wm_uart_2_funcs[] = { 3, 3, }; ++ ++/* DFD */ ++static int mt7981_dfd_pins[] = { 0, 1, 4, 5, }; ++static int mt7981_dfd_funcs[] = { 5, 5, 6, 6, }; ++ ++/* SYS_WATCHDOG */ ++static int mt7981_watchdog_pins[] = { 2, }; ++static int mt7981_watchdog_funcs[] = { 1, }; ++ ++static int mt7981_watchdog1_pins[] = { 13, }; ++static int mt7981_watchdog1_funcs[] = { 5, }; ++ ++/* PCIE_PERESET_N */ ++static int mt7981_pcie_pereset_pins[] = { 3, }; ++static int mt7981_pcie_pereset_funcs[] = { 1, }; ++ ++/* JTAG */ ++static int mt7981_jtag_pins[] = { 4, 5, 6, 7, 8, }; ++static int mt7981_jtag_funcs[] = { 1, 1, 1, 1, 1, }; ++ ++/* WM_JTAG */ ++static int mt7981_wm_jtag_0_pins[] = { 4, 5, 6, 7, 8, }; ++static int mt7981_wm_jtag_0_funcs[] = { 2, 2, 2, 2, 2, }; ++ ++static int mt7981_wm_jtag_1_pins[] = { 20, 21, 22, 23, 24, }; ++static int mt7981_wm_jtag_1_funcs[] = { 5, 5, 5, 5, 5, }; ++ ++/* WO0_JTAG */ ++static int mt7981_wo0_jtag_0_pins[] = { 9, 10, 11, 12, 13, }; ++static int mt7981_wo0_jtag_0_funcs[] = { 1, 1, 1, 1, 1, }; ++ ++static int mt7981_wo0_jtag_1_pins[] = { 25, 26, 27, 28, 29, }; ++static int mt7981_wo0_jtag_1_funcs[] = { 5, 5, 5, 5, 5, }; ++ ++/* UART2 */ ++static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, }; ++static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, }; ++ ++/* GBE_LED0 */ ++static int mt7981_gbe_led0_pins[] = { 8, }; ++static int mt7981_gbe_led0_funcs[] = { 3, }; ++ ++/* PTA_EXT */ ++static int mt7981_pta_ext_0_pins[] = { 4, 5, 6, }; ++static int mt7981_pta_ext_0_funcs[] = { 4, 4, 4, }; ++ ++static int mt7981_pta_ext_1_pins[] = { 22, 23, 24, }; ++static int mt7981_pta_ext_1_funcs[] = { 4, 4, 4, }; ++ ++/* PWM2 */ ++static int mt7981_pwm2_pins[] = { 7, }; ++static int mt7981_pwm2_funcs[] = { 4, }; ++ ++/* NET_WO0_UART_TXD */ ++static int mt7981_net_wo0_uart_txd_0_pins[] = { 8, }; ++static int mt7981_net_wo0_uart_txd_0_funcs[] = { 4, }; ++ ++static int mt7981_net_wo0_uart_txd_1_pins[] = { 14, }; ++static int mt7981_net_wo0_uart_txd_1_funcs[] = { 3, }; ++ ++static int mt7981_net_wo0_uart_txd_2_pins[] = { 15, }; ++static int mt7981_net_wo0_uart_txd_2_funcs[] = { 4, }; ++ ++/* SPI1 */ ++static int mt7981_spi1_0_pins[] = { 4, 5, 6, 7, }; ++static int mt7981_spi1_0_funcs[] = { 5, 5, 5, 5, }; ++ ++/* I2C */ ++static int mt7981_i2c0_0_pins[] = { 6, 7, }; ++static int mt7981_i2c0_0_funcs[] = { 6, 6, }; ++ ++static int mt7981_i2c0_1_pins[] = { 30, 31, }; ++static int mt7981_i2c0_1_funcs[] = { 4, 4, }; ++ ++static int mt7981_i2c0_2_pins[] = { 36, 37, }; ++static int mt7981_i2c0_2_funcs[] = { 2, 2, }; ++ ++static int mt7981_u2_phy_i2c_pins[] = { 30, 31, }; ++static int mt7981_u2_phy_i2c_funcs[] = { 6, 6, }; ++ ++static int mt7981_u3_phy_i2c_pins[] = { 32, 33, }; ++static int mt7981_u3_phy_i2c_funcs[] = { 3, 3, }; ++ ++static int mt7981_sgmii1_phy_i2c_pins[] = { 32, 33, }; ++static int mt7981_sgmii1_phy_i2c_funcs[] = { 2, 2, }; ++ ++static int mt7981_sgmii0_phy_i2c_pins[] = { 32, 33, }; ++static int mt7981_sgmii0_phy_i2c_funcs[] = { 5, 5, }; ++ ++/* DFD_NTRST */ ++static int mt7981_dfd_ntrst_pins[] = { 8, }; ++static int mt7981_dfd_ntrst_funcs[] = { 6, }; ++ ++/* PWM0 */ ++static int mt7981_pwm0_0_pins[] = { 13, }; ++static int mt7981_pwm0_0_funcs[] = { 2, }; ++ ++static int mt7981_pwm0_1_pins[] = { 15, }; ++static int mt7981_pwm0_1_funcs[] = { 1, }; ++ ++/* PWM1 */ ++static int mt7981_pwm1_0_pins[] = { 14, }; ++static int mt7981_pwm1_0_funcs[] = { 2, }; ++ ++static int mt7981_pwm1_1_pins[] = { 15, }; ++static int mt7981_pwm1_1_funcs[] = { 3, }; ++ ++/* GBE_LED1 */ ++static int mt7981_gbe_led1_pins[] = { 13, }; ++static int mt7981_gbe_led1_funcs[] = { 3, }; ++ ++/* PCM */ ++static int mt7981_pcm_pins[] = { 9, 10, 11, 12, 13, 25 }; ++static int mt7981_pcm_funcs[] = { 4, 4, 4, 4, 4, 4, }; ++ ++/* UDI */ ++static int mt7981_udi_pins[] = { 9, 10, 11, 12, 13, }; ++static int mt7981_udi_funcs[] = { 6, 6, 6, 6, 6, }; ++ ++/* DRV_VBUS */ ++static int mt7981_drv_vbus_pins[] = { 14, }; ++static int mt7981_drv_vbus_funcs[] = { 1, }; ++ ++/* EMMC */ ++static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, }; ++static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; ++ ++/* SNFI */ ++static int mt7981_snfi_pins[] = { 16, 17, 18, 19, 20, 21, }; ++static int mt7981_snfi_funcs[] = { 3, 3, 3, 3, 3, 3, }; ++ ++/* SPI0 */ ++static int mt7981_spi0_pins[] = { 16, 17, 18, 19, }; ++static int mt7981_spi0_funcs[] = { 1, 1, 1, 1, }; ++ ++/* SPI0 */ ++static int mt7981_spi0_wp_hold_pins[] = { 20, 21, }; ++static int mt7981_spi0_wp_hold_funcs[] = { 1, 1, }; ++ ++/* SPI1 */ ++static int mt7981_spi1_1_pins[] = { 22, 23, 24, 25, }; ++static int mt7981_spi1_1_funcs[] = { 1, 1, 1, 1, }; ++ ++/* SPI2 */ ++static int mt7981_spi2_pins[] = { 26, 27, 28, 29, }; ++static int mt7981_spi2_funcs[] = { 1, 1, 1, 1, }; ++ ++/* SPI2 */ ++static int mt7981_spi2_wp_hold_pins[] = { 30, 31, }; ++static int mt7981_spi2_wp_hold_funcs[] = { 1, 1, }; ++ ++/* UART1 */ ++static int mt7981_uart1_0_pins[] = { 16, 17, 18, 19, }; ++static int mt7981_uart1_0_funcs[] = { 4, 4, 4, 4, }; ++ ++static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, }; ++static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, }; ++ ++/* UART2 */ ++static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, }; ++static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, }; ++ ++/* UART0 */ ++static int mt7981_uart0_pins[] = { 32, 33, }; ++static int mt7981_uart0_funcs[] = { 1, 1, }; ++ ++/* PCIE_CLK_REQ */ ++static int mt7981_pcie_clk_pins[] = { 34, }; ++static int mt7981_pcie_clk_funcs[] = { 2, }; ++ ++/* PCIE_WAKE_N */ ++static int mt7981_pcie_wake_pins[] = { 35, }; ++static int mt7981_pcie_wake_funcs[] = { 2, }; ++ ++/* MDC_MDIO */ ++static int mt7981_smi_mdc_mdio_pins[] = { 36, 37, }; ++static int mt7981_smi_mdc_mdio_funcs[] = { 1, 1, }; ++ ++static int mt7981_gbe_ext_mdc_mdio_pins[] = { 36, 37, }; ++static int mt7981_gbe_ext_mdc_mdio_funcs[] = { 3, 3, }; ++ ++/* WF0_MODE1 */ ++static int mt7981_wf0_mode1_pins[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ++ 50, 51, 52, 53, 54, 55, 56 }; ++static int mt7981_wf0_mode1_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 1, 1, 1, 1 }; ++ ++/* WF0_MODE3 */ ++static int mt7981_wf0_mode3_pins[] = { 45, 46, 47, 48, 49, 51 }; ++static int mt7981_wf0_mode3_funcs[] = { 2, 2, 2, 2, 2, 2 }; ++ ++/* WF2G_LED */ ++static int mt7981_wf2g_led0_pins[] = { 30, }; ++static int mt7981_wf2g_led0_funcs[] = { 2, }; ++ ++static int mt7981_wf2g_led1_pins[] = { 34, }; ++static int mt7981_wf2g_led1_funcs[] = { 1, }; ++ ++/* WF5G_LED */ ++static int mt7981_wf5g_led0_pins[] = { 31, }; ++static int mt7981_wf5g_led0_funcs[] = { 2, }; ++ ++static int mt7981_wf5g_led1_pins[] = { 35, }; ++static int mt7981_wf5g_led1_funcs[] = { 1, }; ++ ++/* MT7531_INT */ ++static int mt7981_mt7531_int_pins[] = { 38, }; ++static int mt7981_mt7531_int_funcs[] = { 1, }; ++ ++/* ANT_SEL */ ++static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 34, 35 }; ++static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }; ++ ++static const struct mtk_group_desc mt7981_groups[] = { ++ /* @GPIO(0,1): WA_AICE(2) */ ++ PINCTRL_PIN_GROUP("wa_aice1", mt7981_wa_aice1), ++ /* @GPIO(0,1): WA_AICE(3) */ ++ PINCTRL_PIN_GROUP("wa_aice2", mt7981_wa_aice2), ++ /* @GPIO(0,1): WM_UART(5) */ ++ PINCTRL_PIN_GROUP("wm_uart_0", mt7981_wm_uart_0), ++ /* @GPIO(0,1,4,5): DFD(6) */ ++ PINCTRL_PIN_GROUP("dfd", mt7981_dfd), ++ /* @GPIO(2): SYS_WATCHDOG(1) */ ++ PINCTRL_PIN_GROUP("watchdog", mt7981_watchdog), ++ /* @GPIO(3): PCIE_PERESET_N(1) */ ++ PINCTRL_PIN_GROUP("pcie_pereset", mt7981_pcie_pereset), ++ /* @GPIO(4,8) JTAG(1) */ ++ PINCTRL_PIN_GROUP("jtag", mt7981_jtag), ++ /* @GPIO(4,8) WM_JTAG(2) */ ++ PINCTRL_PIN_GROUP("wm_jtag_0", mt7981_wm_jtag_0), ++ /* @GPIO(9,13) WO0_JTAG(1) */ ++ PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0), ++ /* @GPIO(4,7) WM_JTAG(3) */ ++ PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0), ++ /* @GPIO(8) GBE_LED0(3) */ ++ PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0), ++ /* @GPIO(4,6) PTA_EXT(4) */ ++ PINCTRL_PIN_GROUP("pta_ext_0", mt7981_pta_ext_0), ++ /* @GPIO(7) PWM2(4) */ ++ PINCTRL_PIN_GROUP("pwm2", mt7981_pwm2), ++ /* @GPIO(8) NET_WO0_UART_TXD(4) */ ++ PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7981_net_wo0_uart_txd_0), ++ /* @GPIO(4,7) SPI1(5) */ ++ PINCTRL_PIN_GROUP("spi1_0", mt7981_spi1_0), ++ /* @GPIO(6,7) I2C(5) */ ++ PINCTRL_PIN_GROUP("i2c0_0", mt7981_i2c0_0), ++ /* @GPIO(8): DFD_NTRST(6) */ ++ PINCTRL_PIN_GROUP("dfd_ntrst", mt7981_dfd_ntrst), ++ /* @GPIO(9,10): WM_AICE(2) */ ++ PINCTRL_PIN_GROUP("wm_aice1", mt7981_wm_aice1), ++ /* @GPIO(13): PWM0(2) */ ++ PINCTRL_PIN_GROUP("pwm0_0", mt7981_pwm0_0), ++ /* @GPIO(15): PWM0(1) */ ++ PINCTRL_PIN_GROUP("pwm0_1", mt7981_pwm0_1), ++ /* @GPIO(14): PWM1(2) */ ++ PINCTRL_PIN_GROUP("pwm1_0", mt7981_pwm1_0), ++ /* @GPIO(15): PWM1(3) */ ++ PINCTRL_PIN_GROUP("pwm1_1", mt7981_pwm1_1), ++ /* @GPIO(14) NET_WO0_UART_TXD(3) */ ++ PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7981_net_wo0_uart_txd_1), ++ /* @GPIO(15) NET_WO0_UART_TXD(4) */ ++ PINCTRL_PIN_GROUP("net_wo0_uart_txd_2", mt7981_net_wo0_uart_txd_2), ++ /* @GPIO(13) GBE_LED0(3) */ ++ PINCTRL_PIN_GROUP("gbe_led1", mt7981_gbe_led1), ++ /* @GPIO(9,13) PCM(4) */ ++ PINCTRL_PIN_GROUP("pcm", mt7981_pcm), ++ /* @GPIO(13): SYS_WATCHDOG1(5) */ ++ PINCTRL_PIN_GROUP("watchdog1", mt7981_watchdog1), ++ /* @GPIO(9,13) UDI(4) */ ++ PINCTRL_PIN_GROUP("udi", mt7981_udi), ++ /* @GPIO(14) DRV_VBUS(1) */ ++ PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus), ++ /* @GPIO(15,25): EMMC(2) */ ++ PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45), ++ /* @GPIO(16,21): SNFI(3) */ ++ PINCTRL_PIN_GROUP("snfi", mt7981_snfi), ++ /* @GPIO(16,19): SPI0(1) */ ++ PINCTRL_PIN_GROUP("spi0", mt7981_spi0), ++ /* @GPIO(20,21): SPI0(1) */ ++ PINCTRL_PIN_GROUP("spi0_wp_hold", mt7981_spi0_wp_hold), ++ /* @GPIO(22,25) SPI1(1) */ ++ PINCTRL_PIN_GROUP("spi1_1", mt7981_spi1_1), ++ /* @GPIO(26,29): SPI2(1) */ ++ PINCTRL_PIN_GROUP("spi2", mt7981_spi2), ++ /* @GPIO(30,31): SPI2(1) */ ++ PINCTRL_PIN_GROUP("spi2_wp_hold", mt7981_spi2_wp_hold), ++ /* @GPIO(16,19): UART1(4) */ ++ PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0), ++ /* @GPIO(26,29): UART1(2) */ ++ PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1), ++ /* @GPIO(22,25): UART2(3) */ ++ PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_1), ++ /* @GPIO(22,24) PTA_EXT(4) */ ++ PINCTRL_PIN_GROUP("pta_ext_1", mt7981_pta_ext_1), ++ /* @GPIO(20,21): WM_UART(4) */ ++ PINCTRL_PIN_GROUP("wm_aurt_1", mt7981_wm_uart_1), ++ /* @GPIO(30,31): WM_UART(3) */ ++ PINCTRL_PIN_GROUP("wm_aurt_2", mt7981_wm_uart_2), ++ /* @GPIO(20,24) WM_JTAG(5) */ ++ PINCTRL_PIN_GROUP("wm_jtag_1", mt7981_wm_jtag_1), ++ /* @GPIO(25,29) WO0_JTAG(5) */ ++ PINCTRL_PIN_GROUP("wo0_jtag_1", mt7981_wo0_jtag_1), ++ /* @GPIO(28,29): WA_AICE(3) */ ++ PINCTRL_PIN_GROUP("wa_aice3", mt7981_wa_aice3), ++ /* @GPIO(30,31): WM_AICE(5) */ ++ PINCTRL_PIN_GROUP("wm_aice2", mt7981_wm_aice2), ++ /* @GPIO(30,31): I2C(4) */ ++ PINCTRL_PIN_GROUP("i2c0_1", mt7981_i2c0_1), ++ /* @GPIO(30,31): I2C(6) */ ++ PINCTRL_PIN_GROUP("u2_phy_i2c", mt7981_u2_phy_i2c), ++ /* @GPIO(32,33): I2C(1) */ ++ PINCTRL_PIN_GROUP("uart0", mt7981_uart0), ++ /* @GPIO(32,33): I2C(2) */ ++ PINCTRL_PIN_GROUP("sgmii1_phy_i2c", mt7981_sgmii1_phy_i2c), ++ /* @GPIO(32,33): I2C(3) */ ++ PINCTRL_PIN_GROUP("u3_phy_i2c", mt7981_u3_phy_i2c), ++ /* @GPIO(32,33): I2C(5) */ ++ PINCTRL_PIN_GROUP("sgmii0_phy_i2c", mt7981_sgmii0_phy_i2c), ++ /* @GPIO(34): PCIE_CLK_REQ(2) */ ++ PINCTRL_PIN_GROUP("pcie_clk", mt7981_pcie_clk), ++ /* @GPIO(35): PCIE_WAKE_N(2) */ ++ PINCTRL_PIN_GROUP("pcie_wake", mt7981_pcie_wake), ++ /* @GPIO(36,37): I2C(2) */ ++ PINCTRL_PIN_GROUP("i2c0_2", mt7981_i2c0_2), ++ /* @GPIO(36,37): MDC_MDIO(1) */ ++ PINCTRL_PIN_GROUP("smi_mdc_mdio", mt7981_smi_mdc_mdio), ++ /* @GPIO(36,37): MDC_MDIO(3) */ ++ PINCTRL_PIN_GROUP("gbe_ext_mdc_mdio", mt7981_gbe_ext_mdc_mdio), ++ /* @GPIO(40,56): WF0_MODE1(1) */ ++ PINCTRL_PIN_GROUP("wf0_mode1", mt7981_wf0_mode1), ++ /* @GPIO(45,46,47,48,49,51): WF0_MODE3(3) */ ++ PINCTRL_PIN_GROUP("wf0_mode3", mt7981_wf0_mode3), ++ /* @GPIO(30): WF2G_LED(2) */ ++ PINCTRL_PIN_GROUP("wf2g_led0", mt7981_wf2g_led0), ++ /* @GPIO(34): WF2G_LED(1) */ ++ PINCTRL_PIN_GROUP("wf2g_led1", mt7981_wf2g_led1), ++ /* @GPIO(31): WF5G_LED(2) */ ++ PINCTRL_PIN_GROUP("wf5g_led0", mt7981_wf5g_led0), ++ /* @GPIO(35): WF5G_LED(1) */ ++ PINCTRL_PIN_GROUP("wf5g_led1", mt7981_wf5g_led1), ++ /* @GPIO(38): MT7531_INT(1) */ ++ PINCTRL_PIN_GROUP("mt7531_int", mt7981_mt7531_int), ++ /* @GPIO(14,15,26,17,18,19,20,21,22,23,24,25,34,35): ANT_SEL(1) */ ++ PINCTRL_PIN_GROUP("ant_sel", mt7981_ant_sel), ++}; ++ ++static const struct mtk_io_type_desc mt7981_io_type_desc[] = { ++ [IO_TYPE_GRP0] = { ++ .name = "18OD33", ++ .bias_set = mtk_pinconf_bias_set_pupd_r1_r0, ++ .drive_set = mtk_pinconf_drive_set_v1, ++ .input_enable = mtk_pinconf_input_enable_v1, ++ }, ++ [IO_TYPE_GRP1] = { ++ .name = "18A01", ++ .bias_set = mtk_pinconf_bias_set_pu_pd, ++ .drive_set = mtk_pinconf_drive_set_v1, ++ .input_enable = mtk_pinconf_input_enable_v1, ++ }, ++}; ++ ++/* Joint those groups owning the same capability in user point of view which ++ * allows that people tend to use through the device tree. ++ */ ++static const char *const mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", ++ "wm_aice1_1", "wa_aice3", "wm_aice1_2", }; ++static const char *const mt7981_uart_groups[] = { "wm_uart_0", "uart2_0", ++ "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2", ++ "uart1_0", "uart1_1", "uart2_0", "wm_aurt_1", "wm_aurt_2", "uart0", }; ++static const char *const mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", }; ++static const char *const mt7981_wdt_groups[] = { "watchdog", "watchdog1", }; ++static const char *const mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk", ++ "pcie_wake", }; ++static const char *const mt7981_jtag_groups[] = { "jtag", "wm_jtag_0", ++ "wo0_jtag_0", "wo0_jtag_1", "wm_jtag_1", }; ++static const char *const mt7981_led_groups[] = { "gbe_led0", "gbe_led1", ++ "wf2g_led0", "wf2g_led1", "wf5g_led0", "wf5g_led1", }; ++static const char *const mt7981_pta_groups[] = { "pta_ext_0", "pta_ext_1", }; ++static const char *const mt7981_pwm_groups[] = { "pwm2", "pwm0_0", "pwm0_1", ++ "pwm1_0", "pwm1_1", }; ++static const char *const mt7981_spi_groups[] = { "spi1_0", "spi0", ++ "spi0_wp_hold", "spi1_1", "spi2", "spi2_wp_hold", }; ++static const char *const mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1", ++ "u2_phy_i2c", "sgmii1_phy_i2c", "u3_phy_i2c", "sgmii0_phy_i2c", ++ "i2c0_2", }; ++static const char *const mt7981_pcm_groups[] = { "pcm", }; ++static const char *const mt7981_udi_groups[] = { "udi", }; ++static const char *const mt7981_usb_groups[] = { "drv_vbus", }; ++static const char *const mt7981_flash_groups[] = { "emmc_45", "snfi", }; ++static const char *const mt7981_ethernet_groups[] = { "smi_mdc_mdio", ++ "gbe_ext_mdc_mdio", "wf0_mode1", "wf0_mode3", "mt7531_int", }; ++static const char *const mt7981_ant_groups[] = { "ant_sel", }; ++ ++static const struct mtk_function_desc mt7981_functions[] = { ++ {"wa_aice", mt7981_wa_aice_groups, ARRAY_SIZE(mt7981_wa_aice_groups)}, ++ {"dfd", mt7981_dfd_groups, ARRAY_SIZE(mt7981_dfd_groups)}, ++ {"jtag", mt7981_jtag_groups, ARRAY_SIZE(mt7981_jtag_groups)}, ++ {"pta", mt7981_pta_groups, ARRAY_SIZE(mt7981_pta_groups)}, ++ {"pcm", mt7981_pcm_groups, ARRAY_SIZE(mt7981_pcm_groups)}, ++ {"udi", mt7981_udi_groups, ARRAY_SIZE(mt7981_udi_groups)}, ++ {"usb", mt7981_usb_groups, ARRAY_SIZE(mt7981_usb_groups)}, ++ {"ant", mt7981_ant_groups, ARRAY_SIZE(mt7981_ant_groups)}, ++ {"eth", mt7981_ethernet_groups, ARRAY_SIZE(mt7981_ethernet_groups)}, ++ {"i2c", mt7981_i2c_groups, ARRAY_SIZE(mt7981_i2c_groups)}, ++ {"led", mt7981_led_groups, ARRAY_SIZE(mt7981_led_groups)}, ++ {"pwm", mt7981_pwm_groups, ARRAY_SIZE(mt7981_pwm_groups)}, ++ {"spi", mt7981_spi_groups, ARRAY_SIZE(mt7981_spi_groups)}, ++ {"uart", mt7981_uart_groups, ARRAY_SIZE(mt7981_uart_groups)}, ++ {"watchdog", mt7981_wdt_groups, ARRAY_SIZE(mt7981_wdt_groups)}, ++ {"flash", mt7981_flash_groups, ARRAY_SIZE(mt7981_flash_groups)}, ++ {"pcie", mt7981_pcie_groups, ARRAY_SIZE(mt7981_pcie_groups)}, ++}; ++ ++static const char *const mt7981_pinctrl_register_base_names[] = { ++ "gpio_base", "iocfg_rt_base", "iocfg_rm_base", "iocfg_rb_base", ++ "iocfg_lb_base", "iocfg_bl_base", "iocfg_tm_base", "iocfg_tl_base", ++}; ++ ++static struct mtk_pinctrl_soc mt7981_data = { ++ .name = "mt7981_pinctrl", ++ .reg_cal = mt7981_reg_cals, ++ .pins = mt7981_pins, ++ .npins = ARRAY_SIZE(mt7981_pins), ++ .grps = mt7981_groups, ++ .ngrps = ARRAY_SIZE(mt7981_groups), ++ .funcs = mt7981_functions, ++ .nfuncs = ARRAY_SIZE(mt7981_functions), ++ .io_type = mt7981_io_type_desc, ++ .ntype = ARRAY_SIZE(mt7981_io_type_desc), ++ .gpio_mode = 0, ++ .base_names = mt7981_pinctrl_register_base_names, ++ .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names), ++ .base_calc = 1, ++}; ++ ++static int mtk_pinctrl_mt7981_probe(struct udevice *dev) ++{ ++ return mtk_pinctrl_common_probe(dev, &mt7981_data); ++} ++ ++static const struct udevice_id mt7981_pctrl_match[] = { ++ {.compatible = "mediatek,mt7981-pinctrl"}, ++ { /* sentinel */ } ++}; ++ ++U_BOOT_DRIVER(mt7981_pinctrl) = { ++ .name = "mt7981_pinctrl", ++ .id = UCLASS_PINCTRL, ++ .of_match = mt7981_pctrl_match, ++ .ops = &mtk_pinctrl_ops, ++ .probe = mtk_pinctrl_mt7981_probe, ++ .priv_auto = sizeof(struct mtk_pinctrl_priv), ++}; diff --git a/package/boot/uboot-mediatek/patches/002-0021-pinctrl-mediatek-add-pinctrl-driver-for-MT7986-SoC.patch b/package/boot/uboot-mediatek/patches/002-0021-pinctrl-mediatek-add-pinctrl-driver-for-MT7986-SoC.patch new file mode 100644 index 0000000000..d0675ed4f8 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0021-pinctrl-mediatek-add-pinctrl-driver-for-MT7986-SoC.patch @@ -0,0 +1,817 @@ +From a018800db986d63cf95b0779ebb33b5e246072a7 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Thu, 28 Jul 2022 10:01:00 +0800 +Subject: [PATCH 21/31] pinctrl: mediatek: add pinctrl driver for MT7986 SoC + +This patch adds pinctrl and gpio support for MT7986 SoC + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/pinctrl/mediatek/Kconfig | 4 + + drivers/pinctrl/mediatek/Makefile | 1 + + drivers/pinctrl/mediatek/pinctrl-mt7986.c | 775 ++++++++++++++++++++++ + 3 files changed, 780 insertions(+) + create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c + +--- a/drivers/pinctrl/mediatek/Kconfig ++++ b/drivers/pinctrl/mediatek/Kconfig +@@ -20,6 +20,10 @@ config PINCTRL_MT7981 + bool "MT7981 SoC pinctrl driver" + select PINCTRL_MTK + ++config PINCTRL_MT7986 ++ bool "MT7986 SoC pinctrl driver" ++ select PINCTRL_MTK ++ + config PINCTRL_MT8512 + bool "MT8512 SoC pinctrl driver" + select PINCTRL_MTK +--- a/drivers/pinctrl/mediatek/Makefile ++++ b/drivers/pinctrl/mediatek/Makefile +@@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_MT7622) += pinctrl- + obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o + obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o + obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o ++obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o + obj-$(CONFIG_PINCTRL_MT8512) += pinctrl-mt8512.o + obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o + obj-$(CONFIG_PINCTRL_MT8518) += pinctrl-mt8518.o +--- /dev/null ++++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c +@@ -0,0 +1,775 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * The MT7986 driver based on Linux generic pinctrl binding. ++ * ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#include ++#include "pinctrl-mtk-common.h" ++ ++#define MT7986_TYPE0_PIN(_number, _name) \ ++ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0) ++ ++#define MT7986_TYPE1_PIN(_number, _name) \ ++ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1) ++ ++#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ ++ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \ ++ _s_bit, _x_bits, 32, 0) ++ ++#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ ++ _x_bits) \ ++ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ ++ _x_bits, 32, 0) ++ ++/** ++ * enum - Locking variants of the iocfg bases ++ * ++ * MT7986 have multiple bases to program pin configuration listed as the below: ++ * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000, ++ * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000, ++ * _i_based could be used to indicate what base the pin should be mapped into. ++ * ++ * Each iocfg register base control different group of pads on the SoC ++ * ++ * ++ * chip carrier ++ * ++ * A B C D E F G H ++ * +------------------------+ ++ * 8 | o o o o o o o o | ++ * 7 | o o o o o o o o | ++ * 6 | o o o o o o o o | ++ * 5 | o o o o o o o o | ++ * 4 | o o o o o o o o | ++ * 3 | o o o o o o o o | ++ * 2 | o o o o o o o o | ++ * 1 | o o o o o o o o | ++ * +------------------------+ ++ * ++ * inside Chip carrier ++ * ++ * A B C D E F G H ++ * +------------------------+ ++ * 8 | | ++ * 7 | TL TR | ++ * 6 | +---------+ | ++ * 5 | LT | | RT | ++ * 4 | | | | ++ * 3 | LB | | RB | ++ * 2 | +---------+ | ++ * 1 | | ++ * +------------------------+ ++ * ++ */ ++ ++enum { ++ GPIO_BASE, ++ IOCFG_RT_BASE, ++ IOCFG_RB_BASE, ++ IOCFG_LT_BASE, ++ IOCFG_LB_BASE, ++ IOCFG_TR_BASE, ++ IOCFG_TL_BASE, ++}; ++ ++static const char *const mt7986_pinctrl_register_base_names[] = { ++ "gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt", "iocfg_lb", "iocfg_tr", ++ "iocfg_tl", ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = { ++ PIN_FIELD_GPIO(0, 100, 0x300, 0x10, 0, 4), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = { ++ PIN_FIELD_GPIO(0, 100, 0x0, 0x10, 0, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_di_range[] = { ++ PIN_FIELD_GPIO(0, 100, 0x200, 0x10, 0, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_do_range[] = { ++ PIN_FIELD_GPIO(0, 100, 0x100, 0x10, 0, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = { ++ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1), ++ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x20, 0x10, 10, 1), ++ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x20, 0x10, 0, 1), ++ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x20, 0x10, 0, 1), ++ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x40, 0x10, 8, 1), ++ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x30, 0x10, 12, 1), ++ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1), ++ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1), ++ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x30, 0x10, 15, 1), ++ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x30, 0x10, 19, 1), ++ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x30, 0x10, 23, 1), ++ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x30, 0x10, 22, 1), ++ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x30, 0x10, 21, 1), ++ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x20, 0x10, 4, 1), ++ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x20, 0x10, 8, 1), ++ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x20, 0x10, 7, 1), ++ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x20, 0x10, 5, 1), ++ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x20, 0x10, 9, 1), ++ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x40, 0x10, 18, 1), ++ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x40, 0x10, 12, 1), ++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x40, 0x10, 22, 1), ++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x40, 0x10, 20, 1), ++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x40, 0x10, 26, 1), ++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x40, 0x10, 24, 1), ++ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x30, 0x10, 1, 1), ++ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x30, 0x10, 10, 1), ++ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x40, 0x10, 15, 1), ++ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x40, 0x10, 14, 1), ++ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x40, 0x10, 13, 1), ++ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x40, 0x10, 16, 1), ++ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x20, 0x10, 2, 1), ++ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x30, 0x10, 1, 1), ++ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x30, 0x10, 16, 1), ++ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x30, 0x10, 14, 1), ++ PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x30, 0x10, 4, 1), ++ PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x30, 0x10, 6, 1), ++ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x30, 0x10, 9, 1), ++ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x30, 0x10, 5, 1), ++ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x30, 0x10, 1, 1), ++ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x30, 0x10, 14, 1), ++ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x30, 0x10, 12, 1), ++ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x30, 0x10, 4, 1), ++ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x30, 0x10, 2, 1), ++ PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x30, 0x10, 8, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_smt_range[] = { ++ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0xf0, 0x10, 17, 1), ++ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x90, 0x10, 10, 1), ++ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x90, 0x10, 0, 1), ++ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0xf0, 0x10, 0, 1), ++ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x90, 0x10, 0, 1), ++ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0xf0, 0x10, 8, 1), ++ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0xf0, 0x10, 2, 1), ++ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0xc0, 0x10, 12, 1), ++ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0xc0, 0x10, 18, 1), ++ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0xc0, 0x10, 17, 1), ++ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0xc0, 0x10, 15, 1), ++ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0xc0, 0x10, 19, 1), ++ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0xc0, 0x10, 23, 1), ++ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0xc0, 0x10, 22, 1), ++ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0xc0, 0x10, 21, 1), ++ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x90, 0x10, 4, 1), ++ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x90, 0x10, 8, 1), ++ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x90, 0x10, 7, 1), ++ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x90, 0x10, 5, 1), ++ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x90, 0x10, 9, 1), ++ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0xf0, 0x10, 18, 1), ++ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0xf0, 0x10, 12, 1), ++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0xf0, 0x10, 22, 1), ++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0xf0, 0x10, 20, 1), ++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0xf0, 0x10, 26, 1), ++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0xf0, 0x10, 24, 1), ++ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0xc0, 0x10, 2, 1), ++ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0xc0, 0x10, 1, 1), ++ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0xc0, 0x10, 0, 1), ++ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0xc0, 0x10, 10, 1), ++ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0xf0, 0x10, 15, 1), ++ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0xf0, 0x10, 14, 1), ++ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0xf0, 0x10, 13, 1), ++ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0xf0, 0x10, 16, 1), ++ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x90, 0x10, 2, 1), ++ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x80, 0x10, 1, 1), ++ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x80, 0x10, 0, 1), ++ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x80, 0x10, 16, 1), ++ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x80, 0x10, 14, 1), ++ PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x80, 0x10, 4, 1), ++ PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x80, 0x10, 6, 1), ++ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x80, 0x10, 2, 1), ++ PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x80, 0x10, 9, 1), ++ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x80, 0x10, 5, 1), ++ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x70, 0x10, 1, 1), ++ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x70, 0x10, 0, 1), ++ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x70, 0x10, 14, 1), ++ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x70, 0x10, 12, 1), ++ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x70, 0x10, 4, 1), ++ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x70, 0x10, 2, 1), ++ PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x70, 0x10, 8, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_pu_range[] = { ++ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x50, 0x10, 1, 1), ++ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x50, 0x10, 16, 1), ++ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x50, 0x10, 14, 1), ++ PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x50, 0x10, 4, 1), ++ PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x50, 0x10, 6, 1), ++ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x50, 0x10, 2, 1), ++ PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x50, 0x10, 9, 1), ++ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x50, 0x10, 5, 1), ++ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x50, 0x10, 1, 1), ++ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x50, 0x10, 14, 1), ++ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x50, 0x10, 12, 1), ++ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x50, 0x10, 4, 1), ++ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x50, 0x10, 2, 1), ++ PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x50, 0x10, 8, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_pd_range[] = { ++ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x40, 0x10, 1, 1), ++ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x40, 0x10, 16, 1), ++ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x40, 0x10, 14, 1), ++ PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x40, 0x10, 4, 1), ++ PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x40, 0x10, 6, 1), ++ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x40, 0x10, 9, 1), ++ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x40, 0x10, 5, 1), ++ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x40, 0x10, 1, 1), ++ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x40, 0x10, 14, 1), ++ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x40, 0x10, 12, 1), ++ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x40, 0x10, 4, 1), ++ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x40, 0x10, 8, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_drv_range[] = { ++ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x10, 0x10, 21, 3), ++ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x10, 0x10, 0, 3), ++ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x00, 0x10, 0, 1), ++ PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x00, 0x10, 21, 3), ++ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(11, 12, IOCFG_RB_BASE, 0x00, 0x10, 24, 3), ++ PIN_FIELD_BASE(13, 14, IOCFG_RB_BASE, 0x10, 0x10, 0, 3), ++ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x10, 0x10, 6, 3), ++ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x10, 0x10, 24, 3), ++ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x10, 0x10, 21, 3), ++ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x10, 0x10, 15, 3), ++ PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x10, 0x10, 27, 3), ++ PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x20, 0x10, 0, 3), ++ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x20, 0x10, 9, 3), ++ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x20, 0x10, 6, 3), ++ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x20, 0x10, 3, 3), ++ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x00, 0x10, 12, 3), ++ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x00, 0x10, 24, 3), ++ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x00, 0x10, 21, 3), ++ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x00, 0x10, 15, 3), ++ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x00, 0x10, 27, 3), ++ PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x10, 0x10, 27, 3), ++ PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x20, 0x10, 0, 3), ++ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x10, 0x10, 6, 3), ++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x20, 0x10, 9, 3), ++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x20, 0x10, 3, 3), ++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x20, 0x10, 21, 3), ++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x20, 0x10, 15, 3), ++ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x00, 0x10, 6, 3), ++ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x10, 0x10, 0, 3), ++ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x10, 0x10, 15, 3), ++ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x10, 0x10, 12, 3), ++ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x10, 0x10, 9, 3), ++ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x10, 0x10, 18, 3), ++ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x00, 0x10, 2, 3), ++ PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x10, 0x10, 18, 3), ++ PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x10, 0x10, 12, 3), ++ PIN_FIELD_BASE(74, 77, IOCFG_TR_BASE, 0x00, 0x10, 15, 3), ++ PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x00, 0x10, 6, 3), ++ PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x00, 0x10, 27, 3), ++ PIN_FIELD_BASE(81, 84, IOCFG_TR_BASE, 0x10, 0x10, 0, 3), ++ PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x00, 0x10, 12, 3), ++ PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x00, 0x10, 3, 3), ++ PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x00, 0x10, 0, 3), ++ PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x10, 0x10, 12, 3), ++ PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x10, 0x10, 6, 3), ++ PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x00, 0x10, 12, 3), ++ PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x00, 0x10, 6, 3), ++ PIN_FIELD_BASE(97, 98, IOCFG_TL_BASE, 0x00, 0x10, 24, 3), ++ PIN_FIELD_BASE(99, 100, IOCFG_TL_BASE, 0x10, 0x10, 2, 3), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = { ++ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x60, 0x10, 17, 1), ++ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x30, 0x10, 10, 1), ++ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x60, 0x10, 0, 1), ++ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x30, 0x10, 0, 1), ++ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x60, 0x10, 8, 1), ++ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x60, 0x10, 2, 1), ++ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x40, 0x10, 12, 1), ++ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x40, 0x10, 18, 1), ++ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x40, 0x10, 17, 1), ++ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x40, 0x10, 15, 1), ++ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x40, 0x10, 19, 1), ++ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x40, 0x10, 23, 1), ++ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x40, 0x10, 22, 1), ++ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x40, 0x10, 21, 1), ++ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x30, 0x10, 4, 1), ++ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x30, 0x10, 8, 1), ++ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x30, 0x10, 7, 1), ++ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x30, 0x10, 5, 1), ++ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1), ++ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1), ++ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1), ++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 23, 1), ++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 21, 1), ++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 27, 1), ++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 25, 1), ++ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1), ++ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1), ++ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x40, 0x10, 10, 1), ++ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x60, 0x10, 15, 1), ++ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x60, 0x10, 14, 1), ++ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x60, 0x10, 13, 1), ++ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x60, 0x10, 16, 1), ++ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x40, 0x10, 2, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = { ++ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x70, 0x10, 17, 1), ++ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x40, 0x10, 10, 1), ++ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x70, 0x10, 0, 1), ++ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x40, 0x10, 0, 1), ++ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x70, 0x10, 8, 1), ++ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x70, 0x10, 2, 1), ++ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x50, 0x10, 12, 1), ++ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x50, 0x10, 18, 1), ++ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x50, 0x10, 17, 1), ++ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x50, 0x10, 15, 1), ++ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x50, 0x10, 19, 1), ++ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x50, 0x10, 23, 1), ++ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x50, 0x10, 22, 1), ++ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x50, 0x10, 21, 1), ++ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x40, 0x10, 4, 1), ++ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x40, 0x10, 8, 1), ++ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x40, 0x10, 7, 1), ++ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x40, 0x10, 5, 1), ++ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1), ++ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1), ++ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1), ++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 23, 1), ++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 21, 1), ++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 27, 1), ++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 25, 1), ++ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1), ++ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1), ++ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x50, 0x10, 10, 1), ++ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x70, 0x10, 15, 1), ++ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x70, 0x10, 14, 1), ++ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x70, 0x10, 13, 1), ++ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x70, 0x10, 16, 1), ++ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x50, 0x10, 2, 1), ++}; ++ ++static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = { ++ PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x80, 0x10, 17, 1), ++ PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x50, 0x10, 10, 1), ++ PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x60, 0x10, 0, 1), ++ PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x80, 0x10, 0, 1), ++ PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x50, 0x10, 0, 1), ++ PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x80, 0x10, 8, 1), ++ PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x80, 0x10, 2, 1), ++ PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x60, 0x10, 12, 1), ++ PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x60, 0x10, 18, 1), ++ PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x60, 0x10, 17, 1), ++ PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x60, 0x10, 15, 1), ++ PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x60, 0x10, 19, 1), ++ PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x60, 0x10, 23, 1), ++ PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x60, 0x10, 22, 1), ++ PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x60, 0x10, 21, 1), ++ PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x50, 0x10, 4, 1), ++ PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x50, 0x10, 8, 1), ++ PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x50, 0x10, 7, 1), ++ PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x50, 0x10, 5, 1), ++ PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1), ++ PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1), ++ PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1), ++ PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 23, 1), ++ PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 21, 1), ++ PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 27, 1), ++ PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 25, 1), ++ PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1), ++ PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1), ++ PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1), ++ PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x60, 0x10, 10, 1), ++ PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x80, 0x10, 15, 1), ++ PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x80, 0x10, 14, 1), ++ PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x80, 0x10, 13, 1), ++ PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x80, 0x10, 16, 1), ++ PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1), ++}; ++ ++static const struct mtk_pin_reg_calc mt7986_reg_cals[] = { ++ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range), ++ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range), ++ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7986_pin_di_range), ++ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7986_pin_do_range), ++ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7986_pin_smt_range), ++ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7986_pin_ies_range), ++ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7986_pin_drv_range), ++ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7986_pin_pu_range), ++ [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7986_pin_pd_range), ++ [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7986_pin_pupd_range), ++ [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7986_pin_r0_range), ++ [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7986_pin_r1_range), ++}; ++ ++static const struct mtk_pin_desc mt7986_pins[] = { ++ MT7986_TYPE0_PIN(0, "SYS_WATCHDOG"), ++ MT7986_TYPE0_PIN(1, "WF2G_LED"), ++ MT7986_TYPE0_PIN(2, "WF5G_LED"), ++ MT7986_TYPE0_PIN(3, "I2C_SCL"), ++ MT7986_TYPE0_PIN(4, "I2C_SDA"), ++ MT7986_TYPE0_PIN(5, "GPIO_0"), ++ MT7986_TYPE0_PIN(6, "GPIO_1"), ++ MT7986_TYPE0_PIN(7, "GPIO_2"), ++ MT7986_TYPE0_PIN(8, "GPIO_3"), ++ MT7986_TYPE0_PIN(9, "GPIO_4"), ++ MT7986_TYPE0_PIN(10, "GPIO_5"), ++ MT7986_TYPE0_PIN(11, "GPIO_6"), ++ MT7986_TYPE0_PIN(12, "GPIO_7"), ++ MT7986_TYPE0_PIN(13, "GPIO_8"), ++ MT7986_TYPE0_PIN(14, "GPIO_9"), ++ MT7986_TYPE0_PIN(15, "GPIO_10"), ++ MT7986_TYPE0_PIN(16, "GPIO_11"), ++ MT7986_TYPE0_PIN(17, "GPIO_12"), ++ MT7986_TYPE0_PIN(18, "GPIO_13"), ++ MT7986_TYPE0_PIN(19, "GPIO_14"), ++ MT7986_TYPE0_PIN(20, "GPIO_15"), ++ MT7986_TYPE0_PIN(21, "PWM0"), ++ MT7986_TYPE0_PIN(22, "PWM1"), ++ MT7986_TYPE0_PIN(23, "SPI0_CLK"), ++ MT7986_TYPE0_PIN(24, "SPI0_MOSI"), ++ MT7986_TYPE0_PIN(25, "SPI0_MISO"), ++ MT7986_TYPE0_PIN(26, "SPI0_CS"), ++ MT7986_TYPE0_PIN(27, "SPI0_HOLD"), ++ MT7986_TYPE0_PIN(28, "SPI0_WP"), ++ MT7986_TYPE0_PIN(29, "SPI1_CLK"), ++ MT7986_TYPE0_PIN(30, "SPI1_MOSI"), ++ MT7986_TYPE0_PIN(31, "SPI1_MISO"), ++ MT7986_TYPE0_PIN(32, "SPI1_CS"), ++ MT7986_TYPE0_PIN(33, "SPI2_CLK"), ++ MT7986_TYPE0_PIN(34, "SPI2_MOSI"), ++ MT7986_TYPE0_PIN(35, "SPI2_MISO"), ++ MT7986_TYPE0_PIN(36, "SPI2_CS"), ++ MT7986_TYPE0_PIN(37, "SPI2_HOLD"), ++ MT7986_TYPE0_PIN(38, "SPI2_WP"), ++ MT7986_TYPE0_PIN(39, "UART0_RXD"), ++ MT7986_TYPE0_PIN(40, "UART0_TXD"), ++ MT7986_TYPE0_PIN(41, "PCIE_PERESET_N"), ++ MT7986_TYPE0_PIN(42, "UART1_RXD"), ++ MT7986_TYPE0_PIN(43, "UART1_TXD"), ++ MT7986_TYPE0_PIN(44, "UART1_CTS"), ++ MT7986_TYPE0_PIN(45, "UART1_RTS"), ++ MT7986_TYPE0_PIN(46, "UART2_RXD"), ++ MT7986_TYPE0_PIN(47, "UART2_TXD"), ++ MT7986_TYPE0_PIN(48, "UART2_CTS"), ++ MT7986_TYPE0_PIN(49, "UART2_RTS"), ++ MT7986_TYPE0_PIN(50, "EMMC_DATA_0"), ++ MT7986_TYPE0_PIN(51, "EMMC_DATA_1"), ++ MT7986_TYPE0_PIN(52, "EMMC_DATA_2"), ++ MT7986_TYPE0_PIN(53, "EMMC_DATA_3"), ++ MT7986_TYPE0_PIN(54, "EMMC_DATA_4"), ++ MT7986_TYPE0_PIN(55, "EMMC_DATA_5"), ++ MT7986_TYPE0_PIN(56, "EMMC_DATA_6"), ++ MT7986_TYPE0_PIN(57, "EMMC_DATA_7"), ++ MT7986_TYPE0_PIN(58, "EMMC_CMD"), ++ MT7986_TYPE0_PIN(59, "EMMC_CK"), ++ MT7986_TYPE0_PIN(60, "EMMC_DSL"), ++ MT7986_TYPE0_PIN(61, "EMMC_RSTB"), ++ MT7986_TYPE0_PIN(62, "PCM_DTX"), ++ MT7986_TYPE0_PIN(63, "PCM_DRX"), ++ MT7986_TYPE0_PIN(64, "PCM_CLK"), ++ MT7986_TYPE0_PIN(65, "PCM_FS"), ++ MT7986_TYPE0_PIN(66, "MT7531_INT"), ++ MT7986_TYPE0_PIN(67, "SMI_MDC"), ++ MT7986_TYPE0_PIN(68, "SMI_MDIO"), ++ MT7986_TYPE1_PIN(69, "WF0_DIG_RESETB"), ++ MT7986_TYPE1_PIN(70, "WF0_CBA_RESETB"), ++ MT7986_TYPE1_PIN(71, "WF0_XO_REQ"), ++ MT7986_TYPE1_PIN(72, "WF0_TOP_CLK"), ++ MT7986_TYPE1_PIN(73, "WF0_TOP_DATA"), ++ MT7986_TYPE1_PIN(74, "WF0_HB1"), ++ MT7986_TYPE1_PIN(75, "WF0_HB2"), ++ MT7986_TYPE1_PIN(76, "WF0_HB3"), ++ MT7986_TYPE1_PIN(77, "WF0_HB4"), ++ MT7986_TYPE1_PIN(78, "WF0_HB0"), ++ MT7986_TYPE1_PIN(79, "WF0_HB0_B"), ++ MT7986_TYPE1_PIN(80, "WF0_HB5"), ++ MT7986_TYPE1_PIN(81, "WF0_HB6"), ++ MT7986_TYPE1_PIN(82, "WF0_HB7"), ++ MT7986_TYPE1_PIN(83, "WF0_HB8"), ++ MT7986_TYPE1_PIN(84, "WF0_HB9"), ++ MT7986_TYPE1_PIN(85, "WF0_HB10"), ++ MT7986_TYPE1_PIN(86, "WF1_DIG_RESETB"), ++ MT7986_TYPE1_PIN(87, "WF1_CBA_RESETB"), ++ MT7986_TYPE1_PIN(88, "WF1_XO_REQ"), ++ MT7986_TYPE1_PIN(89, "WF1_TOP_CLK"), ++ MT7986_TYPE1_PIN(90, "WF1_TOP_DATA"), ++ MT7986_TYPE1_PIN(91, "WF1_HB1"), ++ MT7986_TYPE1_PIN(92, "WF1_HB2"), ++ MT7986_TYPE1_PIN(93, "WF1_HB3"), ++ MT7986_TYPE1_PIN(94, "WF1_HB4"), ++ MT7986_TYPE1_PIN(95, "WF1_HB0"), ++ MT7986_TYPE1_PIN(96, "WF1_HB0_B"), ++ MT7986_TYPE1_PIN(97, "WF1_HB5"), ++ MT7986_TYPE1_PIN(98, "WF1_HB6"), ++ MT7986_TYPE1_PIN(99, "WF1_HB7"), ++ MT7986_TYPE1_PIN(100, "WF1_HB8"), ++}; ++ ++static const struct mtk_io_type_desc mt7986_io_type_desc[] = { ++ [IO_TYPE_GRP0] = { ++ .name = "18OD33", ++ .bias_set = mtk_pinconf_bias_set_pupd_r1_r0, ++ .drive_set = mtk_pinconf_drive_set_v1, ++ .input_enable = mtk_pinconf_input_enable_v1, ++ }, ++ [IO_TYPE_GRP1] = { ++ .name = "18A01", ++ .bias_set = mtk_pinconf_bias_set_pu_pd, ++ .drive_set = mtk_pinconf_drive_set_v1, ++ .input_enable = mtk_pinconf_input_enable_v1, ++ }, ++}; ++ ++/* List all groups consisting of these pins dedicated to the enablement of ++ * certain hardware block and the corresponding mode for all of the pins. ++ * The hardware probably has multiple combinations of these pinouts. ++ */ ++ ++static int mt7986_watchdog_pins[] = { 0, }; ++static int mt7986_watchdog_funcs[] = { 1, }; ++ ++static int mt7986_wifi_led_pins[] = { 1, 2, }; ++static int mt7986_wifi_led_funcs[] = { 1, 1, }; ++ ++static int mt7986_i2c_pins[] = { 3, 4, }; ++static int mt7986_i2c_funcs[] = { 1, 1, }; ++ ++static int mt7986_uart1_0_pins[] = { 7, 8, 9, 10, }; ++static int mt7986_uart1_0_funcs[] = { 3, 3, 3, 3, }; ++ ++static int mt7986_spi1_0_pins[] = { 11, 12, 13, 14, }; ++static int mt7986_spi1_0_funcs[] = { 3, 3, 3, 3, }; ++ ++static int mt7986_pwm1_1_pins[] = { 20, }; ++static int mt7986_pwm1_1_funcs[] = { 2, }; ++ ++static int mt7986_pwm0_pins[] = { 21, }; ++static int mt7986_pwm0_funcs[] = { 1, }; ++ ++static int mt7986_pwm1_0_pins[] = { 22, }; ++static int mt7986_pwm1_0_funcs[] = { 1, }; ++ ++static int mt7986_emmc_45_pins[] = { ++ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, }; ++static int mt7986_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; ++ ++static int mt7986_snfi_pins[] = { 23, 24, 25, 26, 27, 28, }; ++static int mt7986_snfi_funcs[] = { 1, 1, 1, 1, 1, 1, }; ++ ++static int mt7986_spi1_1_pins[] = { 23, 24, 25, 26, }; ++static int mt7986_spi1_1_funcs[] = { 3, 3, 3, 3, }; ++ ++static int mt7986_uart1_1_pins[] = { 23, 24, 25, 26, }; ++static int mt7986_uart1_1_funcs[] = { 4, 4, 4, 4, }; ++ ++static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, }; ++static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, }; ++ ++static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, }; ++static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, }; ++ ++static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, }; ++static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, }; ++ ++static int mt7986_spi0_pins[] = { 33, 34, 35, 36, }; ++static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, }; ++ ++static int mt7986_spi0_wp_hold_pins[] = { 37, 38, }; ++static int mt7986_spi0_wp_hold_funcs[] = { 1, 1, }; ++ ++static int mt7986_uart2_1_pins[] = { 33, 34, 35, 36, }; ++static int mt7986_uart2_1_funcs[] = { 3, 3, 3, 3, }; ++ ++static int mt7986_uart1_3_rx_tx_pins[] = { 35, 36, }; ++static int mt7986_uart1_3_rx_tx_funcs[] = { 2, 2, }; ++ ++static int mt7986_uart1_3_cts_rts_pins[] = { 37, 38, }; ++static int mt7986_uart1_3_cts_rts_funcs[] = { 2, 2, }; ++ ++static int mt7986_spi1_3_pins[] = { 33, 34, 35, 36, }; ++static int mt7986_spi1_3_funcs[] = { 4, 4, 4, 4, }; ++ ++static int mt7986_uart0_pins[] = { 39, 40, }; ++static int mt7986_uart0_funcs[] = { 1, 1, }; ++ ++static int mt7986_pcie_reset_pins[] = { 41, }; ++static int mt7986_pcie_reset_funcs[] = { 1, }; ++ ++static int mt7986_uart1_pins[] = { 42, 43, 44, 45, }; ++static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, }; ++ ++static int mt7986_uart2_pins[] = { 46, 47, 48, 49, }; ++static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, }; ++ ++static int mt7986_emmc_51_pins[] = { ++ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, }; ++static int mt7986_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; ++ ++static int mt7986_pcm_pins[] = { 62, 63, 64, 65, }; ++static int mt7986_pcm_funcs[] = { 1, 1, 1, 1, }; ++ ++static int mt7986_i2s_pins[] = { 62, 63, 64, 65, }; ++static int mt7986_i2s_funcs[] = { 1, 1, 1, 1, }; ++ ++static int mt7986_switch_int_pins[] = { 66, }; ++static int mt7986_switch_int_funcs[] = { 1, }; ++ ++static int mt7986_mdc_mdio_pins[] = { 67, 68, }; ++static int mt7986_mdc_mdio_funcs[] = { 1, 1, }; ++ ++static int mt7986_wf_2g_pins[] = {74, 75, 76, 77, 78, 79, 80, 81, 82, 83, }; ++static int mt7986_wf_2g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; ++ ++static int mt7986_wf_5g_pins[] = {91, 92, 93, 94, 95, 96, 97, 98, 99, 100, }; ++static int mt7986_wf_5g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; ++ ++static int mt7986_wf_dbdc_pins[] = { ++ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, }; ++static int mt7986_wf_dbdc_funcs[] = { ++ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; ++ ++static int mt7986_pcie_clk_pins[] = { 9, }; ++static int mt7986_pcie_clk_funcs[] = { 1, }; ++ ++static int mt7986_pcie_wake_pins[] = { 10, }; ++static int mt7986_pcie_wake_funcs[] = { 1, }; ++ ++static const struct mtk_group_desc mt7986_groups[] = { ++ PINCTRL_PIN_GROUP("watchdog", mt7986_watchdog), ++ PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led), ++ PINCTRL_PIN_GROUP("i2c", mt7986_i2c), ++ PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0), ++ PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk), ++ PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake), ++ PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0), ++ PINCTRL_PIN_GROUP("pwm1_1", mt7986_pwm1_1), ++ PINCTRL_PIN_GROUP("pwm0", mt7986_pwm0), ++ PINCTRL_PIN_GROUP("pwm1_0", mt7986_pwm1_0), ++ PINCTRL_PIN_GROUP("emmc_45", mt7986_emmc_45), ++ PINCTRL_PIN_GROUP("snfi", mt7986_snfi), ++ PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1), ++ PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1), ++ PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2), ++ PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2), ++ PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0), ++ PINCTRL_PIN_GROUP("spi0", mt7986_spi0), ++ PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold), ++ PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1), ++ PINCTRL_PIN_GROUP("uart1_3_rx_tx", mt7986_uart1_3_rx_tx), ++ PINCTRL_PIN_GROUP("uart1_3_cts_rts", mt7986_uart1_3_cts_rts), ++ PINCTRL_PIN_GROUP("spi1_3", mt7986_spi1_3), ++ PINCTRL_PIN_GROUP("uart0", mt7986_uart0), ++ PINCTRL_PIN_GROUP("switch_int", mt7986_switch_int), ++ PINCTRL_PIN_GROUP("mdc_mdio", mt7986_mdc_mdio), ++ PINCTRL_PIN_GROUP("pcie_pereset", mt7986_pcie_reset), ++ PINCTRL_PIN_GROUP("uart1", mt7986_uart1), ++ PINCTRL_PIN_GROUP("uart2", mt7986_uart2), ++ PINCTRL_PIN_GROUP("emmc_51", mt7986_emmc_51), ++ PINCTRL_PIN_GROUP("pcm", mt7986_pcm), ++ PINCTRL_PIN_GROUP("i2s", mt7986_i2s), ++ PINCTRL_PIN_GROUP("wf_2g", mt7986_wf_2g), ++ PINCTRL_PIN_GROUP("wf_5g", mt7986_wf_5g), ++ PINCTRL_PIN_GROUP("wf_dbdc", mt7986_wf_dbdc), ++}; ++ ++/* Joint those groups owning the same capability in user point of view which ++ * allows that people tend to use through the device tree. ++ */ ++ ++static const char *const mt7986_audio_groups[] = { "pcm", "i2s" }; ++static const char *const mt7986_emmc_groups[] = { "emmc_45", "emmc_51", }; ++static const char *const mt7986_ethernet_groups[] = { "switch_int", ++ "mdc_mdio", }; ++static const char *const mt7986_i2c_groups[] = { "i2c", }; ++static const char *const mt7986_led_groups[] = { "wifi_led", }; ++static const char *const mt7986_flash_groups[] = { "snfi", }; ++static const char *const mt7986_pcie_groups[] = { "pcie_clk", "pcie_wake", ++ "pcie_pereset" }; ++static const char *const mt7986_pwm_groups[] = { "pwm0", "pwm1_0", "pwm1_1", }; ++static const char *const mt7986_spi_groups[] = { "spi0", "spi0_wp_hold", ++ "spi1_0", "spi1_1", "spi1_2", "spi1_3", }; ++static const char *const mt7986_uart_groups[] = { "uart1_0", "uart1_1", ++ "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts", "uart2_0", "uart2_1", ++ "uart0", "uart1", "uart2", }; ++static const char *const mt7986_wdt_groups[] = { "watchdog", }; ++static const char *const mt7986_wf_groups[] = { "wf_2g", "wf_5g", "wf_dbdc", }; ++ ++static const struct mtk_function_desc mt7986_functions[] = { ++ {"audio", mt7986_audio_groups, ARRAY_SIZE(mt7986_audio_groups)}, ++ {"emmc", mt7986_emmc_groups, ARRAY_SIZE(mt7986_emmc_groups)}, ++ {"eth", mt7986_ethernet_groups, ARRAY_SIZE(mt7986_ethernet_groups)}, ++ {"i2c", mt7986_i2c_groups, ARRAY_SIZE(mt7986_i2c_groups)}, ++ {"led", mt7986_led_groups, ARRAY_SIZE(mt7986_led_groups)}, ++ {"flash", mt7986_flash_groups, ARRAY_SIZE(mt7986_flash_groups)}, ++ {"pcie", mt7986_pcie_groups, ARRAY_SIZE(mt7986_pcie_groups)}, ++ {"pwm", mt7986_pwm_groups, ARRAY_SIZE(mt7986_pwm_groups)}, ++ {"spi", mt7986_spi_groups, ARRAY_SIZE(mt7986_spi_groups)}, ++ {"uart", mt7986_uart_groups, ARRAY_SIZE(mt7986_uart_groups)}, ++ {"watchdog", mt7986_wdt_groups, ARRAY_SIZE(mt7986_wdt_groups)}, ++ {"wifi", mt7986_wf_groups, ARRAY_SIZE(mt7986_wf_groups)}, ++}; ++ ++static struct mtk_pinctrl_soc mt7986_data = { ++ .name = "mt7986_pinctrl", ++ .reg_cal = mt7986_reg_cals, ++ .pins = mt7986_pins, ++ .npins = ARRAY_SIZE(mt7986_pins), ++ .grps = mt7986_groups, ++ .ngrps = ARRAY_SIZE(mt7986_groups), ++ .funcs = mt7986_functions, ++ .nfuncs = ARRAY_SIZE(mt7986_functions), ++ .io_type = mt7986_io_type_desc, ++ .ntype = ARRAY_SIZE(mt7986_io_type_desc), ++ .gpio_mode = 0, ++ .base_names = mt7986_pinctrl_register_base_names, ++ .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names), ++ .base_calc = 1, ++}; ++ ++static int mtk_pinctrl_mt7986_probe(struct udevice *dev) ++{ ++ return mtk_pinctrl_common_probe(dev, &mt7986_data); ++} ++ ++static const struct udevice_id mt7986_pctrl_match[] = { ++ {.compatible = "mediatek,mt7986-pinctrl"}, ++ { /* sentinel */ } ++}; ++ ++U_BOOT_DRIVER(mt7986_pinctrl) = { ++ .name = "mt7986_pinctrl", ++ .id = UCLASS_PINCTRL, ++ .of_match = mt7986_pctrl_match, ++ .ops = &mtk_pinctrl_ops, ++ .probe = mtk_pinctrl_mt7986_probe, ++ .priv_auto = sizeof(struct mtk_pinctrl_priv), ++}; diff --git a/package/boot/uboot-mediatek/patches/002-0022-clk-mediatek-add-CLK_BYPASS_XTAL-flag-to-allow-bypas.patch b/package/boot/uboot-mediatek/patches/002-0022-clk-mediatek-add-CLK_BYPASS_XTAL-flag-to-allow-bypas.patch new file mode 100644 index 0000000000..c26fc8090e --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0022-clk-mediatek-add-CLK_BYPASS_XTAL-flag-to-allow-bypas.patch @@ -0,0 +1,69 @@ +From 7f6c8bdfe020c45c398c01b417460e3319476606 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 10:43:39 +0800 +Subject: [PATCH 22/31] clk: mediatek: add CLK_BYPASS_XTAL flag to allow + bypassing searching clock parent of xtal clock + +The mtk clock framework in u-boot uses array index for searching clock +parent (kernel uses strings for search), so we need to specify a special +clock with ID=0 for CLK_XTAL in u-boot. + +In the mt7622/mt7629 clock tree, the clocks with ID=0 never call +mtk_topckgen_get_mux_rate, adn return xtal clock directly. This what we +expected. + +However for newer chips, they may have some clocks with ID=0 not +representing the xtal clock and still needs mtk_topckgen_get_mux_rate be +called. Current logic will make entire clock driver not working. + +This patch adds a flag to indicate that whether a clock driver needs clocks +with ID=0 to call mtk_topckgen_get_mux_rate. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/clk/mediatek/clk-mtk.c | 5 ++++- + drivers/clk/mediatek/clk-mtk.h | 6 ++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/clk/mediatek/clk-mtk.c ++++ b/drivers/clk/mediatek/clk-mtk.c +@@ -314,12 +314,15 @@ static ulong mtk_topckgen_get_mux_rate(s + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + const struct mtk_composite *mux = &priv->tree->muxes[off]; + u32 index; ++ u32 flag = 0; + + index = readl(priv->base + mux->mux_reg); + index &= mux->mux_mask << mux->mux_shift; + index = index >> mux->mux_shift; + +- if (mux->parent[index]) ++ if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL) ++ flag = 1; ++ if (mux->parent[index] > 0 || flag == 1) + return mtk_clk_find_parent_rate(clk, mux->parent[index], + NULL); + +--- a/drivers/clk/mediatek/clk-mtk.h ++++ b/drivers/clk/mediatek/clk-mtk.h +@@ -11,6 +11,11 @@ + #define CLK_XTAL 0 + #define MHZ (1000 * 1000) + ++/* flags in struct mtk_clk_tree */ ++ ++/* clk id == 0 doesn't mean it's xtal clk */ ++#define CLK_BYPASS_XTAL BIT(0) ++ + #define HAVE_RST_BAR BIT(0) + #define CLK_DOMAIN_SCPSYS BIT(0) + #define CLK_MUX_SETCLR_UPD BIT(1) +@@ -197,6 +202,7 @@ struct mtk_clk_tree { + const struct mtk_fixed_clk *fclks; + const struct mtk_fixed_factor *fdivs; + const struct mtk_composite *muxes; ++ u32 flags; + }; + + struct mtk_clk_priv { diff --git a/package/boot/uboot-mediatek/patches/002-0023-clk-mediatek-add-support-to-configure-clock-driver-p.patch b/package/boot/uboot-mediatek/patches/002-0023-clk-mediatek-add-support-to-configure-clock-driver-p.patch new file mode 100644 index 0000000000..41600a96b5 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0023-clk-mediatek-add-support-to-configure-clock-driver-p.patch @@ -0,0 +1,198 @@ +From cd4d6be5ed0488de2e0df9c388d89ad93d781caa Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 10:57:05 +0800 +Subject: [PATCH 23/31] clk: mediatek: add support to configure clock driver + parent + +This patch adds support for a clock node to configure its parent clock +where possible. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/clk/mediatek/clk-mtk.c | 79 ++++++++++++++++++++-------------- + drivers/clk/mediatek/clk-mtk.h | 2 + + 2 files changed, 48 insertions(+), 33 deletions(-) + +--- a/drivers/clk/mediatek/clk-mtk.c ++++ b/drivers/clk/mediatek/clk-mtk.c +@@ -42,20 +42,14 @@ + * the accurate frequency. + */ + static ulong mtk_clk_find_parent_rate(struct clk *clk, int id, +- const struct driver *drv) ++ struct udevice *pdev) + { + struct clk parent = { .id = id, }; + +- if (drv) { +- struct udevice *dev; +- +- if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev)) +- return -ENODEV; +- +- parent.dev = dev; +- } else { ++ if (pdev) ++ parent.dev = pdev; ++ else + parent.dev = clk->dev; +- } + + return clk_get_rate(&parent); + } +@@ -296,7 +290,7 @@ static ulong mtk_topckgen_get_factor_rat + switch (fdiv->flags & CLK_PARENT_MASK) { + case CLK_PARENT_APMIXED: + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, +- DM_DRIVER_GET(mtk_clk_apmixedsys)); ++ priv->parent); + break; + case CLK_PARENT_TOPCKGEN: + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); +@@ -322,9 +316,18 @@ static ulong mtk_topckgen_get_mux_rate(s + + if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL) + flag = 1; +- if (mux->parent[index] > 0 || flag == 1) +- return mtk_clk_find_parent_rate(clk, mux->parent[index], +- NULL); ++ if (mux->parent[index] > 0 || flag == 1) { ++ switch (mux->flags & CLK_PARENT_MASK) { ++ case CLK_PARENT_APMIXED: ++ return mtk_clk_find_parent_rate(clk, mux->parent[index], ++ priv->parent); ++ break; ++ default: ++ return mtk_clk_find_parent_rate(clk, mux->parent[index], ++ NULL); ++ break; ++ } ++ } + + return priv->tree->xtal_rate; + } +@@ -343,7 +346,7 @@ static ulong mtk_topckgen_get_rate(struc + priv->tree->muxes_offs); + } + +-static int mtk_topckgen_enable(struct clk *clk) ++static int mtk_clk_mux_enable(struct clk *clk) + { + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + const struct mtk_composite *mux; +@@ -376,7 +379,7 @@ static int mtk_topckgen_enable(struct cl + return 0; + } + +-static int mtk_topckgen_disable(struct clk *clk) ++static int mtk_clk_mux_disable(struct clk *clk) + { + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + const struct mtk_composite *mux; +@@ -402,7 +405,7 @@ static int mtk_topckgen_disable(struct c + return 0; + } + +-static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent) ++static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent) + { + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + +@@ -474,19 +477,7 @@ static ulong mtk_clk_gate_get_rate(struc + struct mtk_cg_priv *priv = dev_get_priv(clk->dev); + const struct mtk_gate *gate = &priv->gates[clk->id]; + +- switch (gate->flags & CLK_PARENT_MASK) { +- case CLK_PARENT_APMIXED: +- return mtk_clk_find_parent_rate(clk, gate->parent, +- DM_DRIVER_GET(mtk_clk_apmixedsys)); +- break; +- case CLK_PARENT_TOPCKGEN: +- return mtk_clk_find_parent_rate(clk, gate->parent, +- DM_DRIVER_GET(mtk_clk_topckgen)); +- break; +- +- default: +- return priv->tree->xtal_rate; +- } ++ return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent); + } + + const struct clk_ops mtk_clk_apmixedsys_ops = { +@@ -497,10 +488,10 @@ const struct clk_ops mtk_clk_apmixedsys_ + }; + + const struct clk_ops mtk_clk_topckgen_ops = { +- .enable = mtk_topckgen_enable, +- .disable = mtk_topckgen_disable, ++ .enable = mtk_clk_mux_enable, ++ .disable = mtk_clk_mux_disable, + .get_rate = mtk_topckgen_get_rate, +- .set_parent = mtk_topckgen_set_parent, ++ .set_parent = mtk_common_clk_set_parent, + }; + + const struct clk_ops mtk_clk_gate_ops = { +@@ -513,11 +504,22 @@ int mtk_common_clk_init(struct udevice * + const struct mtk_clk_tree *tree) + { + struct mtk_clk_priv *priv = dev_get_priv(dev); ++ struct udevice *parent; ++ int ret; + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -ENOENT; + ++ ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); ++ if (ret || !parent) { ++ ret = uclass_get_device_by_driver(UCLASS_CLK, ++ DM_DRIVER_GET(mtk_clk_apmixedsys), &parent); ++ if (ret || !parent) ++ return -ENOENT; ++ } ++ ++ priv->parent = parent; + priv->tree = tree; + + return 0; +@@ -528,11 +530,22 @@ int mtk_common_clk_gate_init(struct udev + const struct mtk_gate *gates) + { + struct mtk_cg_priv *priv = dev_get_priv(dev); ++ struct udevice *parent; ++ int ret; + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -ENOENT; + ++ ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); ++ if (ret || !parent) { ++ ret = uclass_get_device_by_driver(UCLASS_CLK, ++ DM_DRIVER_GET(mtk_clk_topckgen), &parent); ++ if (ret || !parent) ++ return -ENOENT; ++ } ++ ++ priv->parent = parent; + priv->tree = tree; + priv->gates = gates; + +--- a/drivers/clk/mediatek/clk-mtk.h ++++ b/drivers/clk/mediatek/clk-mtk.h +@@ -206,11 +206,13 @@ struct mtk_clk_tree { + }; + + struct mtk_clk_priv { ++ struct udevice *parent; + void __iomem *base; + const struct mtk_clk_tree *tree; + }; + + struct mtk_cg_priv { ++ struct udevice *parent; + void __iomem *base; + const struct mtk_clk_tree *tree; + const struct mtk_gate *gates; diff --git a/package/boot/uboot-mediatek/patches/002-0024-clk-mediatek-add-infrasys-clock-mux-support.patch b/package/boot/uboot-mediatek/patches/002-0024-clk-mediatek-add-infrasys-clock-mux-support.patch new file mode 100644 index 0000000000..f84fdec2b4 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0024-clk-mediatek-add-infrasys-clock-mux-support.patch @@ -0,0 +1,136 @@ +From e9c0c2ebd346aa578007c2aa88fc0974af6afb40 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 11:14:33 +0800 +Subject: [PATCH 24/31] clk: mediatek: add infrasys clock mux support + +This patch adds infrasys clock mux support for mediatek clock drivers. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/clk/mediatek/clk-mtk.c | 72 ++++++++++++++++++++++++++++++++++ + drivers/clk/mediatek/clk-mtk.h | 4 +- + 2 files changed, 75 insertions(+), 1 deletion(-) + +--- a/drivers/clk/mediatek/clk-mtk.c ++++ b/drivers/clk/mediatek/clk-mtk.c +@@ -303,6 +303,24 @@ static ulong mtk_topckgen_get_factor_rat + return mtk_factor_recalc_rate(fdiv, rate); + } + ++static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32 off) ++{ ++ struct mtk_clk_priv *priv = dev_get_priv(clk->dev); ++ const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off]; ++ ulong rate; ++ ++ switch (fdiv->flags & CLK_PARENT_MASK) { ++ case CLK_PARENT_TOPCKGEN: ++ rate = mtk_clk_find_parent_rate(clk, fdiv->parent, ++ priv->parent); ++ break; ++ default: ++ rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); ++ } ++ ++ return mtk_factor_recalc_rate(fdiv, rate); ++} ++ + static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) + { + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); +@@ -332,6 +350,34 @@ static ulong mtk_topckgen_get_mux_rate(s + return priv->tree->xtal_rate; + } + ++static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off) ++{ ++ struct mtk_clk_priv *priv = dev_get_priv(clk->dev); ++ const struct mtk_composite *mux = &priv->tree->muxes[off]; ++ u32 index; ++ u32 flag; ++ ++ index = readl(priv->base + mux->mux_reg); ++ index &= mux->mux_mask << mux->mux_shift; ++ index = index >> mux->mux_shift; ++ ++ if (mux->parent[index] == CLK_XTAL && priv->tree->flags & CLK_BYPASS_XTAL) ++ flag = 1; ++ if (mux->parent[index] > 0 || flag == 1) { ++ switch (mux->flags & CLK_PARENT_MASK) { ++ case CLK_PARENT_TOPCKGEN: ++ return mtk_clk_find_parent_rate(clk, mux->parent[index], ++ priv->parent); ++ break; ++ default: ++ return mtk_clk_find_parent_rate(clk, mux->parent[index], ++ NULL); ++ break; ++ } ++ } ++ return 0; ++} ++ + static ulong mtk_topckgen_get_rate(struct clk *clk) + { + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); +@@ -346,6 +392,25 @@ static ulong mtk_topckgen_get_rate(struc + priv->tree->muxes_offs); + } + ++static ulong mtk_infrasys_get_rate(struct clk *clk) ++{ ++ struct mtk_clk_priv *priv = dev_get_priv(clk->dev); ++ ++ ulong rate; ++ ++ if (clk->id < priv->tree->fdivs_offs) { ++ rate = priv->tree->fclks[clk->id].rate; ++ } else if (clk->id < priv->tree->muxes_offs) { ++ rate = mtk_infrasys_get_factor_rate(clk, clk->id - ++ priv->tree->fdivs_offs); ++ } else { ++ rate = mtk_infrasys_get_mux_rate(clk, clk->id - ++ priv->tree->muxes_offs); ++ } ++ ++ return rate; ++} ++ + static int mtk_clk_mux_enable(struct clk *clk) + { + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); +@@ -494,6 +559,13 @@ const struct clk_ops mtk_clk_topckgen_op + .set_parent = mtk_common_clk_set_parent, + }; + ++const struct clk_ops mtk_clk_infrasys_ops = { ++ .enable = mtk_clk_mux_enable, ++ .disable = mtk_clk_mux_disable, ++ .get_rate = mtk_infrasys_get_rate, ++ .set_parent = mtk_common_clk_set_parent, ++}; ++ + const struct clk_ops mtk_clk_gate_ops = { + .enable = mtk_clk_gate_enable, + .disable = mtk_clk_gate_disable, +--- a/drivers/clk/mediatek/clk-mtk.h ++++ b/drivers/clk/mediatek/clk-mtk.h +@@ -28,7 +28,8 @@ + + #define CLK_PARENT_APMIXED BIT(4) + #define CLK_PARENT_TOPCKGEN BIT(5) +-#define CLK_PARENT_MASK GENMASK(5, 4) ++#define CLK_PARENT_INFRASYS BIT(6) ++#define CLK_PARENT_MASK GENMASK(6, 4) + + #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34 + +@@ -220,6 +221,7 @@ struct mtk_cg_priv { + + extern const struct clk_ops mtk_clk_apmixedsys_ops; + extern const struct clk_ops mtk_clk_topckgen_ops; ++extern const struct clk_ops mtk_clk_infrasys_ops; + extern const struct clk_ops mtk_clk_gate_ops; + + int mtk_common_clk_init(struct udevice *dev, diff --git a/package/boot/uboot-mediatek/patches/002-0025-clk-mediatek-add-CLK_XTAL-support-for-clock-driver.patch b/package/boot/uboot-mediatek/patches/002-0025-clk-mediatek-add-CLK_XTAL-support-for-clock-driver.patch new file mode 100644 index 0000000000..37619d22f0 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0025-clk-mediatek-add-CLK_XTAL-support-for-clock-driver.patch @@ -0,0 +1,46 @@ +From cf70b726c9844bb5d1ba4bc3c202c5ab3ba4d421 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 11:15:35 +0800 +Subject: [PATCH 25/31] clk: mediatek: add CLK_XTAL support for clock driver + +This add CLK_XTAL macro and flag to mediatek clock driver common part, +to make thi SoC that has clock directlly connect to XTAL working. + +Signed-off-by: Weijie Gao +--- + drivers/clk/mediatek/clk-mtk.c | 4 ++++ + drivers/clk/mediatek/clk-mtk.h | 3 ++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/clk/mediatek/clk-mtk.c ++++ b/drivers/clk/mediatek/clk-mtk.c +@@ -296,6 +296,7 @@ static ulong mtk_topckgen_get_factor_rat + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); + break; + ++ case CLK_PARENT_XTAL: + default: + rate = priv->tree->xtal_rate; + } +@@ -314,6 +315,9 @@ static ulong mtk_infrasys_get_factor_rat + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, + priv->parent); + break; ++ case CLK_PARENT_XTAL: ++ rate = priv->tree->xtal_rate; ++ break; + default: + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); + } +--- a/drivers/clk/mediatek/clk-mtk.h ++++ b/drivers/clk/mediatek/clk-mtk.h +@@ -29,7 +29,8 @@ + #define CLK_PARENT_APMIXED BIT(4) + #define CLK_PARENT_TOPCKGEN BIT(5) + #define CLK_PARENT_INFRASYS BIT(6) +-#define CLK_PARENT_MASK GENMASK(6, 4) ++#define CLK_PARENT_XTAL BIT(7) ++#define CLK_PARENT_MASK GENMASK(7, 4) + + #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34 + diff --git a/package/boot/uboot-mediatek/patches/002-0026-clk-mediatek-add-clock-driver-support-for-MediaTek-M.patch b/package/boot/uboot-mediatek/patches/002-0026-clk-mediatek-add-clock-driver-support-for-MediaTek-M.patch new file mode 100644 index 0000000000..f42e497141 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0026-clk-mediatek-add-clock-driver-support-for-MediaTek-M.patch @@ -0,0 +1,955 @@ +From ba4acf55044a8a11fc7e11a558a8a93e3c126391 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 11:21:59 +0800 +Subject: [PATCH 26/31] clk: mediatek: add clock driver support for MediaTek + MT7986 SoC + +This patch adds clock driver support for MediaTek MT7986 SoC + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/clk/mediatek/Makefile | 1 + + drivers/clk/mediatek/clk-mt7986.c | 672 +++++++++++++++++++++++++ + include/dt-bindings/clock/mt7986-clk.h | 249 +++++++++ + 3 files changed, 922 insertions(+) + create mode 100644 drivers/clk/mediatek/clk-mt7986.c + create mode 100644 include/dt-bindings/clock/mt7986-clk.h + +--- a/drivers/clk/mediatek/Makefile ++++ b/drivers/clk/mediatek/Makefile +@@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += clk-mt8512.o + obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o + obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o + obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o ++obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o + obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o + obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o + obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o +--- /dev/null ++++ b/drivers/clk/mediatek/clk-mt7986.c +@@ -0,0 +1,672 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * MediaTek clock driver for MT7986 SoC ++ * ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk-mtk.h" ++ ++#define MT7986_CLK_PDN 0x250 ++#define MT7986_CLK_PDN_EN_WRITE BIT(31) ++ ++#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \ ++ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED) ++ ++#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \ ++ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN) ++ ++#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \ ++ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS) ++ ++/* FIXED PLLS */ ++static const struct mtk_fixed_clk fixed_pll_clks[] = { ++ FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 2000000000), ++ FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000), ++ FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 1440000000), ++ FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000), ++ FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 760000000), ++ FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000), ++ FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000), ++ FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000), ++}; ++ ++/* TOPCKGEN FIXED CLK */ ++static const struct mtk_fixed_clk top_fixed_clks[] = { ++ FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000), ++}; ++ ++/* TOPCKGEN FIXED DIV */ ++static const struct mtk_fixed_factor top_fixed_divs[] = { ++ PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1), ++ PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2), ++ PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4), ++ PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8), ++ PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16), ++ PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2), ++ PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2), ++ PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4), ++ PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8), ++ PLL_FACTOR(CK_TOP_MM_D8_D2, "mm_d8_d2", CK_APMIXED_MMPLL, 1, 16), ++ PLL_FACTOR(CK_TOP_MM_D3_D8, "mm_d3_d8", CK_APMIXED_MMPLL, 1, 8), ++ PLL_FACTOR(CK_TOP_CB_U2_PHYD_CK, "cb_u2_phyd", CK_APMIXED_MMPLL, 1, 30), ++ PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1, ++ 1), ++ PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4), ++ PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4), ++ PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5), ++ PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10), ++ PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20), ++ PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16), ++ PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32), ++ PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1, ++ 1), ++ PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4), ++ PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8), ++ PLL_FACTOR(CK_TOP_NET2_D3_D2, "net2_d3_d2", CK_APMIXED_NET2PLL, 1, 2), ++ PLL_FACTOR(CK_TOP_CB_WEDMCU_760M, "cb_wedmcu_760m", ++ CK_APMIXED_WEDMCUPLL, 1, 1), ++ PLL_FACTOR(CK_TOP_WEDMCU_D5_D2, "wedmcu_d5_d2", CK_APMIXED_WEDMCUPLL, 1, ++ 10), ++ PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1), ++ TOP_FACTOR(CK_TOP_CB_CKSQ_40M_D2, "cb_cksq_40m_d2", CK_TOP_CB_CKSQ_40M, ++ 1, 2), ++ TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1, ++ 1250), ++ TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1, ++ 1220), ++ TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1, ++ 1), ++ TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1), ++ TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1), ++ TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1), ++ TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_EMMC_250M, "emmc_250m", CK_TOP_EMMC_250M_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_EMMC_416M, "emmc_416m", CK_TOP_EMMC_416M_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_F_26M_ADC_CK, "f_26m_adc", CK_TOP_F_26M_ADC_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", ++ CK_TOP_NETSYS_MCU_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_EIP_B, "eip_b", CK_TOP_EIP_B_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 2, 1), ++ TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1, ++ 1), ++}; ++ ++/* TOPCKGEN MUX PARENTS */ ++static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D8, ++ CK_TOP_NET1_D8_D2, CK_TOP_NET2_D3_D2, ++ CK_TOP_CB_M_D4, CK_TOP_MM_D8_D2, ++ CK_TOP_WEDMCU_D5_D2, CK_TOP_CB_M_D8 }; ++ ++static const int spinfi_parents[] = { ++ CK_TOP_CB_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, ++ CK_TOP_CB_M_D4, CK_TOP_MM_D8_D2, CK_TOP_WEDMCU_D5_D2, ++ CK_TOP_MM_D3_D8, CK_TOP_CB_M_D8 ++}; ++ ++static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, ++ CK_TOP_CB_MM_D8, CK_TOP_NET1_D8_D2, ++ CK_TOP_NET2_D3_D2, CK_TOP_NET1_D5_D4, ++ CK_TOP_CB_M_D4, CK_TOP_WEDMCU_D5_D2 }; ++ ++static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8, ++ CK_TOP_M_D8_D2 }; ++ ++static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, ++ CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4 }; ++ ++static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, ++ CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; ++ ++static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_NET1_D5_D4, CK_TOP_NET2_D4_D2, ++ CK_TOP_CB_RTC_32K }; ++ ++static const int emmc_250m_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_NET1_D5_D2 }; ++ ++static const int emmc_416m_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_416M }; ++ ++static const int f_26m_adc_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 }; ++ ++static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2 }; ++ ++static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, ++ CK_TOP_CB_NET2_D4 }; ++ ++static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2, ++ CK_TOP_NET2_D4_D2 }; ++ ++static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_NET2_D3_D2 }; ++ ++static const int arm_db_jtsel_parents[] = { -1, CK_TOP_CB_CKSQ_40M }; ++ ++static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4 }; ++ ++static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_NET1_D5 }; ++ ++static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_WEDMCU_760M, ++ CK_TOP_CB_MM_D2, CK_TOP_CB_NET1_D4, ++ CK_TOP_CB_NET1_D5 }; ++ ++static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_NET2_800M, ++ CK_TOP_CB_WEDMCU_760M, ++ CK_TOP_CB_MM_D2 }; ++ ++static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_SGM_325M }; ++ ++static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D4 }; ++ ++static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 }; ++ ++static const int conn_mcusys_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_MM_D2 }; ++ ++static const int eip_b_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_800M }; ++ ++static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M, ++ CK_TOP_M_D8_D2 }; ++ ++static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4, ++ CK_TOP_M_D8_D2 }; ++ ++static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4 }; ++ ++static const int da_u2_refsel_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_U2_PHYD_CK }; ++ ++#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ ++ _shift, _width, _gate, _upd_ofs, _upd) \ ++ { \ ++ .id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs, \ ++ .mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs, \ ++ .upd_shift = _upd, .mux_shift = _shift, \ ++ .mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs, \ ++ .gate_shift = _gate, .parent = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .flags = CLK_MUX_SETCLR_UPD, \ ++ } ++ ++/* TOPCKGEN MUX_GATE */ ++static const struct mtk_composite top_muxes[] = { ++ /* CLK_CFG_0 */ ++ TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x000, 0x004, ++ 0x008, 0, 3, 7, 0x1C0, 0), ++ TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x000, 0x004, ++ 0x008, 8, 3, 15, 0x1C0, 1), ++ TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000, 0x004, 0x008, 16, ++ 3, 23, 0x1C0, 2), ++ TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x000, 0x004, ++ 0x008, 24, 3, 31, 0x1C0, 3), ++ /* CLK_CFG_1 */ ++ TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010, 0x014, 0x018, ++ 0, 2, 7, 0x1C0, 4), ++ TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010, 0x014, 0x018, 8, ++ 2, 15, 0x1C0, 5), ++ TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010, 0x014, 0x018, 16, ++ 2, 23, 0x1C0, 6), ++ TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents, ++ 0x010, 0x014, 0x018, 24, 2, 31, 0x1C0, 7), ++ /* CLK_CFG_2 */ ++ TOP_MUX(CK_TOP_EMMC_250M_SEL, "emmc_250m_sel", emmc_250m_parents, 0x020, ++ 0x024, 0x028, 0, 1, 7, 0x1C0, 8), ++ TOP_MUX(CK_TOP_EMMC_416M_SEL, "emmc_416m_sel", emmc_416m_parents, 0x020, ++ 0x024, 0x028, 8, 1, 15, 0x1C0, 9), ++ TOP_MUX(CK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel", f_26m_adc_parents, 0x020, ++ 0x024, 0x028, 16, 1, 23, 0x1C0, 10), ++ TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents, 0x020, 0x024, ++ 0x028, 24, 1, 31, 0x1C0, 11), ++ /* CLK_CFG_3 */ ++ TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents, ++ 0x030, 0x034, 0x038, 0, 1, 7, 0x1C0, 12), ++ TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x030, 0x034, ++ 0x038, 8, 2, 15, 0x1C0, 13), ++ TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x030, 0x034, ++ 0x038, 16, 2, 23, 0x1C0, 14), ++ TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents, ++ 0x030, 0x034, 0x038, 24, 1, 31, 0x1C0, 15), ++ /* CLK_CFG_4 */ ++ TOP_MUX(CK_TOP_ARM_DB_JTSEL, "arm_db_jtsel", arm_db_jtsel_parents, ++ 0x040, 0x044, 0x048, 0, 1, 7, 0x1C0, 16), ++ TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x040, 0x044, ++ 0x048, 8, 1, 15, 0x1C0, 17), ++ TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents, ++ 0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18), ++ TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents, ++ 0x040, 0x044, 0x048, 24, 3, 31, 0x1C0, 19), ++ /* CLK_CFG_5 */ ++ TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x050, ++ 0x054, 0x058, 0, 2, 7, 0x1C0, 20), ++ TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x050, ++ 0x054, 0x058, 8, 1, 15, 0x1C0, 21), ++ TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x050, ++ 0x054, 0x058, 16, 1, 23, 0x1C0, 22), ++ TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x050, 0x054, ++ 0x058, 24, 1, 31, 0x1C0, 23), ++ /* CLK_CFG_6 */ ++ TOP_MUX(CK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel", conn_mcusys_parents, ++ 0x060, 0x064, 0x068, 0, 1, 7, 0x1C0, 24), ++ TOP_MUX(CK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents, 0x060, 0x064, ++ 0x068, 8, 1, 15, 0x1C0, 25), ++ TOP_MUX(CK_TOP_PCIE_PHY_SEL, "pcie_phy_sel", f_26m_adc_parents, 0x060, ++ 0x064, 0x068, 16, 1, 23, 0x1C0, 26), ++ TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", f_26m_adc_parents, 0x060, ++ 0x064, 0x068, 24, 1, 31, 0x1C0, 27), ++ /* CLK_CFG_7 */ ++ TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", f_26m_adc_parents, 0x070, ++ 0x074, 0x078, 0, 1, 7, 0x1C0, 28), ++ TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x070, 0x074, ++ 0x078, 8, 2, 15, 0x1C0, 29), ++ TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x070, ++ 0x074, 0x078, 16, 2, 23, 0x1C0, 30), ++ TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents, 0x070, 0x074, ++ 0x078, 24, 1, 31, 0x1C4, 0), ++ /* CLK_CFG_8 */ ++ TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x080, ++ 0x084, 0x088, 0, 1, 7, 0x1C4, 1), ++ TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x080, ++ 0x084, 0x088, 8, 1, 15, 0x1C4, 2), ++ TOP_MUX(CK_TOP_DA_U2_REFSEL, "da_u2_refsel", da_u2_refsel_parents, ++ 0x080, 0x084, 0x088, 16, 1, 23, 0x1C4, 3), ++ TOP_MUX(CK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel", da_u2_refsel_parents, ++ 0x080, 0x084, 0x088, 24, 1, 31, 0x1C4, 4), ++ /* CLK_CFG_9 */ ++ TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", sgm_reg_parents, ++ 0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5), ++}; ++ ++/* INFRA FIXED DIV */ ++static const struct mtk_fixed_factor infra_fixed_divs[] = { ++ TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPINFI_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2), ++ TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1), ++ INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1, ++ 1), ++ INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1, ++ 1), ++ INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1), ++ TOP_FACTOR(CK_INFRA_EIP_CK, "infra_eip", CK_TOP_EIP_B, 1, 1), ++ INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1), ++ TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1), ++ TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1), ++ INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL, ++ 1, 1), ++ INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL, ++ 1, 1), ++ INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL, ++ 1, 1), ++ TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1), ++ TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1), ++ INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1, ++ 1), ++ INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1), ++ TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_416M, 1, 1), ++ TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_250M, ++ 1, 1), ++ TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1), ++ TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1), ++ TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1), ++ TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1), ++ TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux", ++ CK_TOP_PEXTP_TL, 1, 1), ++ TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1), ++ TOP_FACTOR(CK_INFRA_HD_133M, "infra_hd_133m", CK_TOP_SYSAXI, 1, 1), ++}; ++ ++/* INFRASYS MUX PARENTS */ ++static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART }; ++ ++static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 }; ++ ++static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 }; ++ ++static const int infra_pwm_bsel_parents[] = { CK_INFRA_CK_F32K, ++ CK_INFRA_CK_F26M, ++ CK_INFRA_66M_MCK, CK_INFRA_PWM }; ++ ++static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K, CK_INFRA_CK_F26M, ++ -1, CK_INFRA_PCIE_CK }; ++ ++#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \ ++ { \ ++ .id = _id, .mux_reg = (_reg) + 0x8, \ ++ .mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4, \ ++ .mux_shift = _shift, .mux_mask = BIT(_width) - 1, \ ++ .parent = _parents, .num_parents = ARRAY_SIZE(_parents), \ ++ .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS, \ ++ } ++ ++/* INFRA MUX */ ++ ++static const struct mtk_composite infra_muxes[] = { ++ /* MODULE_CLK_SEL_0 */ ++ INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents, ++ 0x10, 0, 1), ++ INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents, ++ 0x10, 1, 1), ++ INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents, ++ 0x10, 2, 1), ++ INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10, ++ 4, 1), ++ INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10, ++ 5, 1), ++ INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm_bsel_parents, ++ 0x10, 9, 2), ++ INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm_bsel_parents, ++ 0x10, 11, 2), ++ INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents, ++ 0x10, 13, 2), ++ /* MODULE_CLK_SEL_1 */ ++ INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20, ++ 0, 2), ++}; ++ ++static const struct mtk_gate_regs infra_0_cg_regs = { ++ .set_ofs = 0x40, ++ .clr_ofs = 0x44, ++ .sta_ofs = 0x48, ++}; ++ ++static const struct mtk_gate_regs infra_1_cg_regs = { ++ .set_ofs = 0x50, ++ .clr_ofs = 0x54, ++ .sta_ofs = 0x58, ++}; ++ ++static const struct mtk_gate_regs infra_2_cg_regs = { ++ .set_ofs = 0x60, ++ .clr_ofs = 0x64, ++ .sta_ofs = 0x68, ++}; ++ ++#define GATE_INFRA0(_id, _name, _parent, _shift) \ ++ { \ ++ .id = _id, .parent = _parent, .regs = &infra_0_cg_regs, \ ++ .shift = _shift, \ ++ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ ++ } ++ ++#define GATE_INFRA1(_id, _name, _parent, _shift) \ ++ { \ ++ .id = _id, .parent = _parent, .regs = &infra_1_cg_regs, \ ++ .shift = _shift, \ ++ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ ++ } ++ ++#define GATE_INFRA2(_id, _name, _parent, _shift) \ ++ { \ ++ .id = _id, .parent = _parent, .regs = &infra_2_cg_regs, \ ++ .shift = _shift, \ ++ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ ++ } ++ ++/* INFRA GATE */ ++ ++static const struct mtk_gate infracfg_ao_gates[] = { ++ /* INFRA0 */ ++ GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0), ++ GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1), ++ GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2), ++ GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3), ++ GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4), ++ GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6), ++ GATE_INFRA0(CK_INFRA_EIP97_CK, "infra_eip97", CK_INFRA_EIP_CK, 7), ++ GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8), ++ GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9), ++ GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10), ++ GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK, ++ 11), ++ GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK, ++ 13), ++ GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M, ++ 14), ++ GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15), ++ GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16), ++ GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24), ++ GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25), ++ GATE_INFRA0(CK_INFRA_TRNG_CK, "infra_trng", CK_INFRA_HD_133M, 26), ++ /* INFRA1 */ ++ GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0), ++ GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1), ++ GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2), ++ GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3), ++ GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4), ++ GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8), ++ GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK, ++ 9), ++ GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10), ++ GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11), ++ GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12), ++ GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK, ++ 13), ++ GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK, ++ 14), ++ GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15), ++ GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16), ++ GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", ++ CK_INFRA_FMSDC_HCK_CK, 17), ++ GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m", ++ CK_INFRA_PERI_133M, 18), ++ GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK, ++ 19), ++ GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_INFRA_CK_F26M, 20), ++ GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_INFRA_CK_F26M, 21), ++ GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK, ++ 23), ++ /* INFRA2 */ ++ GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK, ++ 0), ++ GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK, ++ 1), ++ GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK, ++ 2), ++ GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3), ++ GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie", CK_INFRA_PCIE_CK, 13), ++ GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 15), ++ GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15), ++}; ++ ++static const struct mtk_clk_tree mt7986_fixed_pll_clk_tree = { ++ .fdivs_offs = CLK_APMIXED_NR_CLK, ++ .xtal_rate = 40 * MHZ, ++ .fclks = fixed_pll_clks, ++}; ++ ++static const struct mtk_clk_tree mt7986_topckgen_clk_tree = { ++ .fdivs_offs = CK_TOP_CB_M_416M, ++ .muxes_offs = CK_TOP_NFI1X_SEL, ++ .fclks = top_fixed_clks, ++ .fdivs = top_fixed_divs, ++ .muxes = top_muxes, ++ .flags = CLK_BYPASS_XTAL, ++}; ++ ++static const struct mtk_clk_tree mt7986_infracfg_clk_tree = { ++ .fdivs_offs = CK_INFRA_CK_F26M, ++ .muxes_offs = CK_INFRA_UART0_SEL, ++ .fdivs = infra_fixed_divs, ++ .muxes = infra_muxes, ++}; ++ ++static const struct udevice_id mt7986_fixed_pll_compat[] = { ++ { .compatible = "mediatek,mt7986-fixed-plls" }, ++ {} ++}; ++ ++static const struct udevice_id mt7986_topckgen_compat[] = { ++ { .compatible = "mediatek,mt7986-topckgen" }, ++ {} ++}; ++ ++static int mt7986_fixed_pll_probe(struct udevice *dev) ++{ ++ return mtk_common_clk_init(dev, &mt7986_fixed_pll_clk_tree); ++} ++ ++static int mt7986_topckgen_probe(struct udevice *dev) ++{ ++ struct mtk_clk_priv *priv = dev_get_priv(dev); ++ ++ priv->base = dev_read_addr_ptr(dev); ++ writel(MT7986_CLK_PDN_EN_WRITE, priv->base + MT7986_CLK_PDN); ++ ++ return mtk_common_clk_init(dev, &mt7986_topckgen_clk_tree); ++} ++ ++U_BOOT_DRIVER(mtk_clk_apmixedsys) = { ++ .name = "mt7986-clock-fixed-pll", ++ .id = UCLASS_CLK, ++ .of_match = mt7986_fixed_pll_compat, ++ .probe = mt7986_fixed_pll_probe, ++ .priv_auto = sizeof(struct mtk_clk_priv), ++ .ops = &mtk_clk_topckgen_ops, ++ .flags = DM_FLAG_PRE_RELOC, ++}; ++ ++U_BOOT_DRIVER(mtk_clk_topckgen) = { ++ .name = "mt7986-clock-topckgen", ++ .id = UCLASS_CLK, ++ .of_match = mt7986_topckgen_compat, ++ .probe = mt7986_topckgen_probe, ++ .priv_auto = sizeof(struct mtk_clk_priv), ++ .ops = &mtk_clk_topckgen_ops, ++ .flags = DM_FLAG_PRE_RELOC, ++}; ++ ++static const struct udevice_id mt7986_infracfg_compat[] = { ++ { .compatible = "mediatek,mt7986-infracfg" }, ++ {} ++}; ++ ++static const struct udevice_id mt7986_infracfg_ao_compat[] = { ++ { .compatible = "mediatek,mt7986-infracfg_ao" }, ++ {} ++}; ++ ++static int mt7986_infracfg_probe(struct udevice *dev) ++{ ++ return mtk_common_clk_init(dev, &mt7986_infracfg_clk_tree); ++} ++ ++static int mt7986_infracfg_ao_probe(struct udevice *dev) ++{ ++ return mtk_common_clk_gate_init(dev, &mt7986_infracfg_clk_tree, ++ infracfg_ao_gates); ++} ++ ++U_BOOT_DRIVER(mtk_clk_infracfg) = { ++ .name = "mt7986-clock-infracfg", ++ .id = UCLASS_CLK, ++ .of_match = mt7986_infracfg_compat, ++ .probe = mt7986_infracfg_probe, ++ .priv_auto = sizeof(struct mtk_clk_priv), ++ .ops = &mtk_clk_infrasys_ops, ++ .flags = DM_FLAG_PRE_RELOC, ++}; ++ ++U_BOOT_DRIVER(mtk_clk_infracfg_ao) = { ++ .name = "mt7986-clock-infracfg-ao", ++ .id = UCLASS_CLK, ++ .of_match = mt7986_infracfg_ao_compat, ++ .probe = mt7986_infracfg_ao_probe, ++ .priv_auto = sizeof(struct mtk_cg_priv), ++ .ops = &mtk_clk_gate_ops, ++ .flags = DM_FLAG_PRE_RELOC, ++}; ++ ++/* ethsys */ ++static const struct mtk_gate_regs eth_cg_regs = { ++ .sta_ofs = 0x30, ++}; ++ ++#define GATE_ETH(_id, _name, _parent, _shift) \ ++ { \ ++ .id = _id, .parent = _parent, .regs = ð_cg_regs, \ ++ .shift = _shift, \ ++ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \ ++ } ++ ++static const struct mtk_gate eth_cgs[] = { ++ GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 7), ++ GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 8), ++ GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8), ++ GATE_ETH(CK_ETH_WOCPU1_EN, "eth_wocpu1_en", CK_TOP_NETSYS_WED_MCU, 14), ++ GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15), ++}; ++ ++static int mt7986_ethsys_probe(struct udevice *dev) ++{ ++ return mtk_common_clk_gate_init(dev, &mt7986_topckgen_clk_tree, ++ eth_cgs); ++} ++ ++static int mt7986_ethsys_bind(struct udevice *dev) ++{ ++ int ret = 0; ++ ++ if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) { ++ ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1); ++ if (ret) ++ debug("Warning: failed to bind reset controller\n"); ++ } ++ ++ return ret; ++} ++ ++static const struct udevice_id mt7986_ethsys_compat[] = { ++ { .compatible = "mediatek,mt7986-ethsys" }, ++ { } ++}; ++ ++U_BOOT_DRIVER(mtk_clk_ethsys) = { ++ .name = "mt7986-clock-ethsys", ++ .id = UCLASS_CLK, ++ .of_match = mt7986_ethsys_compat, ++ .probe = mt7986_ethsys_probe, ++ .bind = mt7986_ethsys_bind, ++ .priv_auto = sizeof(struct mtk_cg_priv), ++ .ops = &mtk_clk_gate_ops, ++}; +--- /dev/null ++++ b/include/dt-bindings/clock/mt7986-clk.h +@@ -0,0 +1,249 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2022 MediaTek Inc. All rights reserved. ++ * ++ * Author: Sam Shih ++ */ ++ ++#ifndef _DT_BINDINGS_CLK_MT7986_H ++#define _DT_BINDINGS_CLK_MT7986_H ++ ++/* INFRACFG */ ++ ++#define CK_INFRA_CK_F26M 0 ++#define CK_INFRA_UART 1 ++#define CK_INFRA_ISPI0 2 ++#define CK_INFRA_I2C 3 ++#define CK_INFRA_ISPI1 4 ++#define CK_INFRA_PWM 5 ++#define CK_INFRA_66M_MCK 6 ++#define CK_INFRA_CK_F32K 7 ++#define CK_INFRA_PCIE_CK 8 ++#define CK_INFRA_PWM_BCK 9 ++#define CK_INFRA_PWM_CK1 10 ++#define CK_INFRA_PWM_CK2 11 ++#define CK_INFRA_133M_HCK 12 ++#define CK_INFRA_EIP_CK 13 ++#define CK_INFRA_66M_PHCK 14 ++#define CK_INFRA_FAUD_L_CK 15 ++#define CK_INFRA_FAUD_AUD_CK 17 ++#define CK_INFRA_FAUD_EG2_CK 17 ++#define CK_INFRA_I2CS_CK 18 ++#define CK_INFRA_MUX_UART0 19 ++#define CK_INFRA_MUX_UART1 20 ++#define CK_INFRA_MUX_UART2 21 ++#define CK_INFRA_NFI_CK 22 ++#define CK_INFRA_SPINFI_CK 23 ++#define CK_INFRA_MUX_SPI0 24 ++#define CK_INFRA_MUX_SPI1 25 ++#define CK_INFRA_RTC_32K 26 ++#define CK_INFRA_FMSDC_CK 27 ++#define CK_INFRA_FMSDC_HCK_CK 28 ++#define CK_INFRA_PERI_133M 29 ++#define CK_INFRA_133M_PHCK 30 ++#define CK_INFRA_USB_SYS_CK 31 ++#define CK_INFRA_USB_CK 32 ++#define CK_INFRA_USB_XHCI_CK 33 ++#define CK_INFRA_PCIE_GFMUX_TL_O_PRE 34 ++#define CK_INFRA_F26M_CK0 35 ++#define CK_INFRA_HD_133M 36 ++#define CLK_INFRA_NR_CLK 37 ++ ++/* TOPCKGEN */ ++ ++#define CK_TOP_CB_CKSQ_40M 0 ++#define CK_TOP_CB_M_416M 1 ++#define CK_TOP_CB_M_D2 2 ++#define CK_TOP_CB_M_D4 3 ++#define CK_TOP_CB_M_D8 4 ++#define CK_TOP_M_D8_D2 5 ++#define CK_TOP_M_D3_D2 6 ++#define CK_TOP_CB_MM_D2 7 ++#define CK_TOP_CB_MM_D4 8 ++#define CK_TOP_CB_MM_D8 9 ++#define CK_TOP_MM_D8_D2 10 ++#define CK_TOP_MM_D3_D8 11 ++#define CK_TOP_CB_U2_PHYD_CK 12 ++#define CK_TOP_CB_APLL2_196M 13 ++#define CK_TOP_APLL2_D4 14 ++#define CK_TOP_CB_NET1_D4 15 ++#define CK_TOP_CB_NET1_D5 16 ++#define CK_TOP_NET1_D5_D2 17 ++#define CK_TOP_NET1_D5_D4 18 ++#define CK_TOP_NET1_D8_D2 19 ++#define CK_TOP_NET1_D8_D4 20 ++#define CK_TOP_CB_NET2_800M 21 ++#define CK_TOP_CB_NET2_D4 22 ++#define CK_TOP_NET2_D4_D2 23 ++#define CK_TOP_NET2_D3_D2 24 ++#define CK_TOP_CB_WEDMCU_760M 25 ++#define CK_TOP_WEDMCU_D5_D2 26 ++#define CK_TOP_CB_SGM_325M 27 ++#define CK_TOP_CB_CKSQ_40M_D2 28 ++#define CK_TOP_CB_RTC_32K 29 ++#define CK_TOP_CB_RTC_32P7K 30 ++#define CK_TOP_NFI1X 31 ++#define CK_TOP_USB_EQ_RX250M 32 ++#define CK_TOP_USB_TX250M 33 ++#define CK_TOP_USB_LN0_CK 34 ++#define CK_TOP_USB_CDR_CK 35 ++#define CK_TOP_SPINFI_BCK 36 ++#define CK_TOP_I2C_BCK 37 ++#define CK_TOP_PEXTP_TL 38 ++#define CK_TOP_EMMC_250M 39 ++#define CK_TOP_EMMC_416M 40 ++#define CK_TOP_F_26M_ADC_CK 41 ++#define CK_TOP_SYSAXI 42 ++#define CK_TOP_NETSYS_WED_MCU 43 ++#define CK_TOP_NETSYS_2X 44 ++#define CK_TOP_SGM_325M 45 ++#define CK_TOP_A1SYS 46 ++#define CK_TOP_EIP_B 47 ++#define CK_TOP_F26M 48 ++#define CK_TOP_AUD_L 49 ++#define CK_TOP_A_TUNER 50 ++#define CK_TOP_U2U3_REF 51 ++#define CK_TOP_U2U3_SYS 52 ++#define CK_TOP_U2U3_XHCI 53 ++#define CK_TOP_AP2CNN_HOST 54 ++#define CK_TOP_NFI1X_SEL 55 ++#define CK_TOP_SPINFI_SEL 56 ++#define CK_TOP_SPI_SEL 57 ++#define CK_TOP_SPIM_MST_SEL 58 ++#define CK_TOP_UART_SEL 59 ++#define CK_TOP_PWM_SEL 60 ++#define CK_TOP_I2C_SEL 61 ++#define CK_TOP_PEXTP_TL_SEL 62 ++#define CK_TOP_EMMC_250M_SEL 63 ++#define CK_TOP_EMMC_416M_SEL 64 ++#define CK_TOP_F_26M_ADC_SEL 65 ++#define CK_TOP_DRAMC_SEL 66 ++#define CK_TOP_DRAMC_MD32_SEL 67 ++#define CK_TOP_SYSAXI_SEL 68 ++#define CK_TOP_SYSAPB_SEL 69 ++#define CK_TOP_ARM_DB_MAIN_SEL 70 ++#define CK_TOP_ARM_DB_JTSEL 71 ++#define CK_TOP_NETSYS_SEL 72 ++#define CK_TOP_NETSYS_500M_SEL 73 ++#define CK_TOP_NETSYS_MCU_SEL 74 ++#define CK_TOP_NETSYS_2X_SEL 75 ++#define CK_TOP_SGM_325M_SEL 76 ++#define CK_TOP_SGM_REG_SEL 77 ++#define CK_TOP_A1SYS_SEL 78 ++#define CK_TOP_CONN_MCUSYS_SEL 79 ++#define CK_TOP_EIP_B_SEL 80 ++#define CK_TOP_PCIE_PHY_SEL 81 ++#define CK_TOP_USB3_PHY_SEL 82 ++#define CK_TOP_F26M_SEL 83 ++#define CK_TOP_AUD_L_SEL 84 ++#define CK_TOP_A_TUNER_SEL 85 ++#define CK_TOP_U2U3_SEL 86 ++#define CK_TOP_U2U3_SYS_SEL 87 ++#define CK_TOP_U2U3_XHCI_SEL 88 ++#define CK_TOP_DA_U2_REFSEL 89 ++#define CK_TOP_DA_U2_CK_1P_SEL 90 ++#define CK_TOP_AP2CNN_HOST_SEL 91 ++#define CLK_TOP_NR_CLK 92 ++ ++/* ++ * INFRACFG_AO ++ * clock muxes need to be append to infracfg domain, and clock gates ++ * need to be keep in infracgh_ao domain ++ */ ++ ++#define CK_INFRA_UART0_SEL (0 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_UART1_SEL (1 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_UART2_SEL (2 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_SPI0_SEL (3 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_SPI1_SEL (4 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_PWM1_SEL (5 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_PWM2_SEL (6 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_PWM_BSEL (7 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_PCIE_SEL (8 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_GPT_STA 0 ++#define CK_INFRA_PWM_HCK 1 ++#define CK_INFRA_PWM_STA 2 ++#define CK_INFRA_PWM1_CK 3 ++#define CK_INFRA_PWM2_CK 4 ++#define CK_INFRA_CQ_DMA_CK 5 ++#define CK_INFRA_EIP97_CK 6 ++#define CK_INFRA_AUD_BUS_CK 7 ++#define CK_INFRA_AUD_26M_CK 8 ++#define CK_INFRA_AUD_L_CK 9 ++#define CK_INFRA_AUD_AUD_CK 10 ++#define CK_INFRA_AUD_EG2_CK 11 ++#define CK_INFRA_DRAMC_26M_CK 12 ++#define CK_INFRA_DBG_CK 13 ++#define CK_INFRA_AP_DMA_CK 14 ++#define CK_INFRA_SEJ_CK 15 ++#define CK_INFRA_SEJ_13M_CK 16 ++#define CK_INFRA_THERM_CK 17 ++#define CK_INFRA_I2CO_CK 18 ++#define CK_INFRA_TRNG_CK 19 ++#define CK_INFRA_UART0_CK 20 ++#define CK_INFRA_UART1_CK 21 ++#define CK_INFRA_UART2_CK 22 ++#define CK_INFRA_NFI1_CK 23 ++#define CK_INFRA_SPINFI1_CK 24 ++#define CK_INFRA_NFI_HCK_CK 25 ++#define CK_INFRA_SPI0_CK 26 ++#define CK_INFRA_SPI1_CK 27 ++#define CK_INFRA_SPI0_HCK_CK 28 ++#define CK_INFRA_SPI1_HCK_CK 29 ++#define CK_INFRA_FRTC_CK 30 ++#define CK_INFRA_MSDC_CK 31 ++#define CK_INFRA_MSDC_HCK_CK 32 ++#define CK_INFRA_MSDC_133M_CK 33 ++#define CK_INFRA_MSDC_66M_CK 34 ++#define CK_INFRA_ADC_26M_CK 35 ++#define CK_INFRA_ADC_FRC_CK 36 ++#define CK_INFRA_FBIST2FPC_CK 37 ++#define CK_INFRA_IUSB_133_CK 38 ++#define CK_INFRA_IUSB_66M_CK 39 ++#define CK_INFRA_IUSB_SYS_CK 40 ++#define CK_INFRA_IUSB_CK 41 ++#define CK_INFRA_IPCIE_CK 42 ++#define CK_INFRA_IPCIER_CK 43 ++#define CK_INFRA_IPCIEB_CK 44 ++#define CLK_INFRA_AO_NR_CLK 45 ++ ++/* APMIXEDSYS */ ++ ++#define CK_APMIXED_ARMPLL 0 ++#define CK_APMIXED_NET2PLL 1 ++#define CK_APMIXED_MMPLL 2 ++#define CK_APMIXED_SGMPLL 3 ++#define CK_APMIXED_WEDMCUPLL 4 ++#define CK_APMIXED_NET1PLL 5 ++#define CK_APMIXED_MPLL 6 ++#define CK_APMIXED_APLL2 7 ++#define CLK_APMIXED_NR_CLK 8 ++ ++/* SGMIISYS_0 */ ++ ++#define CK_SGM0_TX_EN 0 ++#define CK_SGM0_RX_EN 1 ++#define CK_SGM0_CK0_EN 2 ++#define CK_SGM0_CDR_CK0_EN 3 ++#define CLK_SGMII0_NR_CLK 4 ++ ++/* SGMIISYS_1 */ ++ ++#define CK_SGM1_TX_EN 0 ++#define CK_SGM1_RX_EN 1 ++#define CK_SGM1_CK1_EN 2 ++#define CK_SGM1_CDR_CK1_EN 3 ++#define CLK_SGMII1_NR_CLK 4 ++ ++/* ETHSYS */ ++ ++#define CK_ETH_FE_EN 0 ++#define CK_ETH_GP2_EN 1 ++#define CK_ETH_GP1_EN 2 ++#define CK_ETH_WOCPU1_EN 3 ++#define CK_ETH_WOCPU0_EN 4 ++#define CLK_ETH_NR_CLK 5 ++ ++#endif ++ ++/* _DT_BINDINGS_CLK_MT7986_H */ diff --git a/package/boot/uboot-mediatek/patches/002-0027-clk-mediatek-add-clock-driver-support-for-MediaTek-M.patch b/package/boot/uboot-mediatek/patches/002-0027-clk-mediatek-add-clock-driver-support-for-MediaTek-M.patch new file mode 100644 index 0000000000..26084a6535 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0027-clk-mediatek-add-clock-driver-support-for-MediaTek-M.patch @@ -0,0 +1,984 @@ +From 79bca945dbfafcd08d71437b11e8ee57d64b4305 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Fri, 29 Jul 2022 11:22:51 +0800 +Subject: [PATCH 27/31] clk: mediatek: add clock driver support for MediaTek + MT7981 SoC + +This patch adds clock driver support for MediaTek MT7981 SoC + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + drivers/clk/mediatek/Makefile | 1 + + drivers/clk/mediatek/clk-mt7981.c | 683 +++++++++++++++++++++++++ + include/dt-bindings/clock/mt7981-clk.h | 267 ++++++++++ + 3 files changed, 951 insertions(+) + create mode 100644 drivers/clk/mediatek/clk-mt7981.c + create mode 100644 include/dt-bindings/clock/mt7981-clk.h + +--- a/drivers/clk/mediatek/Makefile ++++ b/drivers/clk/mediatek/Makefile +@@ -8,6 +8,7 @@ obj-$(CONFIG_TARGET_MT7623) += clk-mt762 + obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o + obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o + obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o ++obj-$(CONFIG_TARGET_MT7981) += clk-mt7981.o + obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o + obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o + obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o +--- /dev/null ++++ b/drivers/clk/mediatek/clk-mt7981.c +@@ -0,0 +1,683 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * MediaTek clock driver for MT7981 SoC ++ * ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Sam Shih ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk-mtk.h" ++ ++#define MT7981_CLK_PDN 0x250 ++#define MT7981_CLK_PDN_EN_WRITE BIT(31) ++ ++#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \ ++ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED) ++ ++#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \ ++ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN) ++ ++#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \ ++ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS) ++ ++/* FIXED PLLS */ ++static const struct mtk_fixed_clk fixed_pll_clks[] = { ++ FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 1300000000), ++ FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000), ++ FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 720000000), ++ FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000), ++ FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 208000000), ++ FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000), ++ FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000), ++ FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000), ++}; ++ ++/* TOPCKGEN FIXED CLK */ ++static const struct mtk_fixed_clk top_fixed_clks[] = { ++ FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000), ++}; ++ ++/* TOPCKGEN FIXED DIV */ ++static const struct mtk_fixed_factor top_fixed_divs[] = { ++ PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1), ++ PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2), ++ PLL_FACTOR(CK_TOP_CB_M_D3, "cb_m_d3", CK_APMIXED_MPLL, 1, 3), ++ PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2), ++ PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4), ++ PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8), ++ PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16), ++ PLL_FACTOR(CK_TOP_CB_MM_720M, "cb_mm_720m", CK_APMIXED_MMPLL, 1, 1), ++ PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2), ++ PLL_FACTOR(CK_TOP_CB_MM_D3, "cb_mm_d3", CK_APMIXED_MMPLL, 1, 3), ++ PLL_FACTOR(CK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", CK_APMIXED_MMPLL, 1, 15), ++ PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4), ++ PLL_FACTOR(CK_TOP_CB_MM_D6, "cb_mm_d6", CK_APMIXED_MMPLL, 1, 6), ++ PLL_FACTOR(CK_TOP_MM_D6_D2, "mm_d6_d2", CK_APMIXED_MMPLL, 1, 12), ++ PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8), ++ PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1, ++ 1), ++ PLL_FACTOR(CK_TOP_APLL2_D2, "apll2_d2", CK_APMIXED_APLL2, 1, 2), ++ PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4), ++ PLL_FACTOR(CK_TOP_NET1_2500M, "net1_2500m", CK_APMIXED_NET1PLL, 1, 1), ++ PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4), ++ PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5), ++ PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10), ++ PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20), ++ PLL_FACTOR(CK_TOP_CB_NET1_D8, "cb_net1_d8", CK_APMIXED_NET1PLL, 1, 8), ++ PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16), ++ PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32), ++ PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1, ++ 1), ++ PLL_FACTOR(CK_TOP_CB_NET2_D2, "cb_net2_d2", CK_APMIXED_NET2PLL, 1, 2), ++ PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4), ++ PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8), ++ PLL_FACTOR(CK_TOP_NET2_D4_D4, "net2_d4_d4", CK_APMIXED_NET2PLL, 1, 16), ++ PLL_FACTOR(CK_TOP_CB_NET2_D6, "cb_net2_d6", CK_APMIXED_NET2PLL, 1, 6), ++ PLL_FACTOR(CK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m", ++ CK_APMIXED_WEDMCUPLL, 1, 1), ++ PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1), ++ TOP_FACTOR(CK_TOP_CKSQ_40M_D2, "cksq_40m_d2", CK_TOP_CB_CKSQ_40M, 1, 2), ++ TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1, ++ 1250), ++ TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1, ++ 1220), ++ TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1), ++ TOP_FACTOR(CK_TOP_FAUD, "faud", CK_TOP_CB_CKSQ_40M, 1, 1), ++ TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1, ++ 1), ++ TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1), ++ TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1), ++ TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_SPI, "spi", CK_TOP_SPI_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_SPIM_MST, "spim_mst", CK_TOP_SPIM_MST_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_UART_BCK, "uart_bck", CK_TOP_UART_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_PWM_BCK, "pwm_bck", CK_TOP_PWM_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_EMMC_208M, "emmc_208m", CK_TOP_EMMC_208M_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_EMMC_400M, "emmc_400m", CK_TOP_EMMC_400M_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_DRAMC_REF, "dramc_ref", CK_TOP_DRAMC_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_DRAMC_MD32, "dramc_md32", CK_TOP_DRAMC_MD32_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_SYSAPB, "sysapb", CK_TOP_SYSAPB_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_ARM_DB_MAIN, "arm_db_main", CK_TOP_ARM_DB_MAIN_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_TOP_NETSYS, "netsys", CK_TOP_NETSYS_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_NETSYS_500M, "netsys_500m", CK_TOP_NETSYS_500M_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", ++ CK_TOP_NETSYS_MCU_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_SGM_REG, "sgm_reg", CK_TOP_SGM_REG_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_EIP97B, "eip97b", CK_TOP_EIP97B_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_USB3_PHY, "usb3_phy", CK_TOP_USB3_PHY_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_AUD, "aud", CK_TOP_FAUD, 1, 1), ++ TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1), ++ TOP_FACTOR(CK_TOP_USB_FRMCNT, "usb_frmcnt", CK_TOP_USB_FRMCNT_SEL, 1, ++ 1), ++}; ++ ++/* TOPCKGEN MUX PARENTS */ ++static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4, ++ CK_TOP_NET1_D8_D2, CK_TOP_CB_NET2_D6, ++ CK_TOP_CB_M_D4, CK_TOP_CB_MM_D8, ++ CK_TOP_NET1_D8_D4, CK_TOP_CB_M_D8 }; ++ ++static const int spinfi_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M, ++ CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, ++ CK_TOP_CB_MM_D8, CK_TOP_NET1_D8_D4, ++ CK_TOP_MM_D6_D2, CK_TOP_CB_M_D8 }; ++ ++static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, ++ CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2, ++ CK_TOP_CB_NET2_D6, CK_TOP_NET1_D5_D4, ++ CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; ++ ++static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8, ++ CK_TOP_M_D8_D2 }; ++ ++static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, ++ CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, ++ CK_TOP_M_D8_D2, CK_TOP_CB_RTC_32K }; ++ ++static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, ++ CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; ++ ++static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, ++ CK_TOP_CB_RTC_32K }; ++ ++static const int emmc_208m_parents[] = { ++ CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, CK_TOP_CB_NET2_D4, ++ CK_TOP_CB_APLL2_196M, CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2, ++ CK_TOP_CB_MM_D6 ++}; ++ ++static const int emmc_400m_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_D2, ++ CK_TOP_CB_MM_D2, CK_TOP_CB_NET2_D2 }; ++ ++static const int csw_f26m_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_M_D8_D2 }; ++ ++static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, ++ CK_TOP_CB_WEDMCU_208M }; ++ ++static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2 }; ++ ++static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2 }; ++ ++static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_NET2_D6 }; ++ ++static const int ap2cnn_host_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_NET1_D8_D4 }; ++ ++static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D2 }; ++ ++static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_NET1_D5 }; ++ ++static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_720M, ++ CK_TOP_CB_NET1_D4, CK_TOP_CB_NET1_D5, ++ CK_TOP_CB_M_416M }; ++ ++static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_NET2_800M, ++ CK_TOP_CB_MM_720M }; ++ ++static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_SGM_325M }; ++ ++static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_D4 }; ++ ++static const int eip97b_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET1_D5, ++ CK_TOP_CB_M_416M, CK_TOP_CB_MM_D2, ++ CK_TOP_NET1_D5_D2 }; ++ ++static const int aud_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M }; ++ ++static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 }; ++ ++static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M, ++ CK_TOP_M_D8_D2 }; ++ ++static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4, ++ CK_TOP_M_D8_D2 }; ++ ++static const int u2u3_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 }; ++ ++static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4 }; ++ ++static const int usb_frmcnt_parents[] = { CK_TOP_CB_CKSQ_40M, ++ CK_TOP_CB_MM_D3_D5 }; ++ ++#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ ++ _shift, _width, _gate, _upd_ofs, _upd) \ ++ { \ ++ .id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs, \ ++ .mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs, \ ++ .upd_shift = _upd, .mux_shift = _shift, \ ++ .mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs, \ ++ .gate_shift = _gate, .parent = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .flags = CLK_MUX_SETCLR_UPD, \ ++ } ++ ++/* TOPCKGEN MUX_GATE */ ++static const struct mtk_composite top_muxes[] = { ++ TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x0, 0x4, 0x8, 0, ++ 3, 7, 0x1c0, 0), ++ TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x0, 0x4, 0x8, ++ 8, 3, 15, 0x1c0, 1), ++ TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0, 0x4, 0x8, 16, 3, ++ 23, 0x1c0, 2), ++ TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x0, 0x4, 0x8, ++ 24, 3, 31, 0x1c0, 3), ++ TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x10, 0x14, 0x18, 0, ++ 2, 7, 0x1c0, 4), ++ TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x10, 0x14, 0x18, 8, 3, ++ 15, 0x1c0, 5), ++ TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x10, 0x14, 0x18, 16, 2, ++ 23, 0x1c0, 6), ++ TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents, ++ 0x10, 0x14, 0x18, 24, 2, 31, 0x1c0, 7), ++ TOP_MUX(CK_TOP_EMMC_208M_SEL, "emmc_208m_sel", emmc_208m_parents, 0x20, ++ 0x24, 0x28, 0, 3, 7, 0x1c0, 8), ++ TOP_MUX(CK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents, 0x20, ++ 0x24, 0x28, 8, 2, 15, 0x1c0, 9), ++ TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", csw_f26m_parents, 0x20, 0x24, ++ 0x28, 16, 1, 23, 0x1c0, 10), ++ TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", csw_f26m_parents, 0x20, 0x24, ++ 0x28, 24, 1, 31, 0x1c0, 11), ++ TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents, ++ 0x30, 0x34, 0x38, 0, 2, 7, 0x1c0, 12), ++ TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x30, 0x34, ++ 0x38, 8, 1, 15, 0x1c0, 13), ++ TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x30, 0x34, ++ 0x38, 16, 1, 23, 0x1c0, 14), ++ TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents, ++ 0x30, 0x34, 0x38, 24, 1, 31, 0x1c0, 15), ++ TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", ap2cnn_host_parents, ++ 0x40, 0x44, 0x48, 0, 1, 7, 0x1c0, 16), ++ TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x40, 0x44, ++ 0x48, 8, 1, 15, 0x1c0, 17), ++ TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents, ++ 0x40, 0x44, 0x48, 16, 1, 23, 0x1c0, 18), ++ TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents, ++ 0x40, 0x44, 0x48, 24, 3, 31, 0x1c0, 19), ++ TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x50, ++ 0x54, 0x58, 0, 2, 7, 0x1c0, 20), ++ TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x50, ++ 0x54, 0x58, 8, 1, 15, 0x1c0, 21), ++ TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x50, 0x54, ++ 0x58, 16, 1, 23, 0x1c0, 22), ++ TOP_MUX(CK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents, 0x50, 0x54, ++ 0x58, 24, 3, 31, 0x1c0, 23), ++ TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", csw_f26m_parents, 0x60, ++ 0x64, 0x68, 0, 1, 7, 0x1c0, 24), ++ TOP_MUX(CK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x60, 0x64, 0x68, 8, 1, ++ 15, 0x1c0, 25), ++ TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x60, 0x64, 0x68, ++ 16, 1, 23, 0x1c0, 26), ++ TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x60, 0x64, 0x68, ++ 24, 2, 31, 0x1c0, 27), ++ TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x70, 0x74, ++ 0x78, 0, 2, 7, 0x1c0, 28), ++ TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x70, 0x74, 0x78, 8, ++ 1, 15, 0x1c0, 29), ++ TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x70, ++ 0x74, 0x78, 16, 1, 23, 0x1c0, 30), ++ TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x70, ++ 0x74, 0x78, 24, 1, 31, 0x1c4, 0), ++ TOP_MUX(CK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel", usb_frmcnt_parents, ++ 0x80, 0x84, 0x88, 0, 1, 7, 0x1c4, 1), ++}; ++ ++/* INFRA FIXED DIV */ ++static const struct mtk_fixed_factor infra_fixed_divs[] = { ++ TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPIM_MST_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1), ++ TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2), ++ TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1), ++ INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1, ++ 1), ++ INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1, ++ 1), ++ INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1), ++ INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1), ++ TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1), ++ TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1), ++ INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL, ++ 1, 1), ++ INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL, ++ 1, 1), ++ INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL, ++ 1, 1), ++ TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1), ++ TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1), ++ INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1, ++ 1), ++ INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1, ++ 1), ++ INFRA_FACTOR(CK_INFRA_MUX_SPI2, "infra_mux_spi2", CK_INFRA_SPI2_SEL, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1), ++ TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_400M, 1, 1), ++ TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_208M, ++ 1, 1), ++ TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1), ++ TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1), ++ TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1), ++ TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1), ++ TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1, ++ 1), ++ TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux", ++ CK_TOP_PEXTP_TL, 1, 1), ++ TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1), ++ TOP_FACTOR(CK_INFRA_133M_MCK, "infra_133m_mck", CK_TOP_SYSAXI, 1, 1), ++}; ++ ++/* INFRASYS MUX PARENTS */ ++static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART }; ++ ++static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 }; ++ ++static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 }; ++ ++static const int infra_pwm1_parents[] = { -1, -1, -1, CK_INFRA_PWM }; ++ ++static const int infra_pwm_bsel_parents[] = { -1, -1, -1, CK_INFRA_PWM }; ++ ++static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K, CK_INFRA_CK_F26M, ++ CK_TOP_CB_CKSQ_40M, CK_INFRA_PCIE_CK}; ++ ++#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \ ++ { \ ++ .id = _id, .mux_reg = (_reg) + 0x8, \ ++ .mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4, \ ++ .mux_shift = _shift, .mux_mask = BIT(_width) - 1, \ ++ .parent = _parents, .num_parents = ARRAY_SIZE(_parents), \ ++ .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS, \ ++ } ++ ++/* INFRA MUX */ ++static const struct mtk_composite infra_muxes[] = { ++ INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents, ++ 0x10, 0, 1), ++ INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents, ++ 0x10, 1, 1), ++ INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents, ++ 0x10, 2, 1), ++ INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10, ++ 4, 1), ++ INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10, ++ 5, 1), ++ INFRA_MUX(CK_INFRA_SPI2_SEL, "infra_spi2_sel", infra_spi0_parents, 0x10, ++ 6, 1), ++ INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm1_parents, 0x10, ++ 9, 2), ++ INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm1_parents, 0x10, ++ 11, 2), ++ INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents, ++ 0x10, 13, 2), ++ INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20, ++ 0, 2), ++}; ++ ++static const struct mtk_gate_regs infra_0_cg_regs = { ++ .set_ofs = 0x40, ++ .clr_ofs = 0x44, ++ .sta_ofs = 0x48, ++}; ++ ++static const struct mtk_gate_regs infra_1_cg_regs = { ++ .set_ofs = 0x50, ++ .clr_ofs = 0x54, ++ .sta_ofs = 0x58, ++}; ++ ++static const struct mtk_gate_regs infra_2_cg_regs = { ++ .set_ofs = 0x60, ++ .clr_ofs = 0x64, ++ .sta_ofs = 0x68, ++}; ++ ++#define GATE_INFRA0(_id, _name, _parent, _shift) \ ++ { \ ++ .id = _id, .parent = _parent, .regs = &infra_0_cg_regs, \ ++ .shift = _shift, \ ++ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ ++ } ++ ++#define GATE_INFRA1(_id, _name, _parent, _shift) \ ++ { \ ++ .id = _id, .parent = _parent, .regs = &infra_1_cg_regs, \ ++ .shift = _shift, \ ++ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ ++ } ++ ++#define GATE_INFRA2(_id, _name, _parent, _shift) \ ++ { \ ++ .id = _id, .parent = _parent, .regs = &infra_2_cg_regs, \ ++ .shift = _shift, \ ++ .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ ++ } ++ ++/* INFRA GATE */ ++static const struct mtk_gate infracfg_ao_gates[] = { ++ GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0), ++ GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1), ++ GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2), ++ GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3), ++ GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4), ++ GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6), ++ GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8), ++ GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9), ++ GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10), ++ GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK, ++ 11), ++ GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK, ++ 13), ++ GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M, ++ 14), ++ GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15), ++ GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16), ++ GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24), ++ GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25), ++ GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0), ++ GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1), ++ GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2), ++ GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3), ++ GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4), ++ GATE_INFRA1(CK_INFRA_SPI2_CK, "infra_spi2", CK_INFRA_MUX_SPI2, 6), ++ GATE_INFRA1(CK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", CK_INFRA_66M_MCK, ++ 7), ++ GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8), ++ GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK, ++ 9), ++ GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10), ++ GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11), ++ GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12), ++ GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK, ++ 13), ++ GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK, ++ 14), ++ GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15), ++ GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16), ++ GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", ++ CK_INFRA_FMSDC_HCK_CK, 17), ++ GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m", ++ CK_INFRA_PERI_133M, 18), ++ GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK, ++ 19), ++ GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_TOP_F26M, 20), ++ GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_TOP_F26M, 21), ++ GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK, ++ 23), ++ GATE_INFRA1(CK_INFRA_I2C_MCK_CK, "infra_i2c_mck", CK_INFRA_133M_MCK, ++ 25), ++ GATE_INFRA1(CK_INFRA_I2C_PCK_CK, "infra_i2c_pck", CK_INFRA_66M_MCK, 26), ++ GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK, ++ 0), ++ GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK, ++ 1), ++ GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK, ++ 2), ++ GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3), ++ GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie", ++ CK_INFRA_PCIE_GFMUX_TL_O_PRE, 12), ++ GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 14), ++ GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15), ++}; ++ ++static const struct mtk_clk_tree mt7981_fixed_pll_clk_tree = { ++ .fdivs_offs = CLK_APMIXED_NR_CLK, ++ .xtal_rate = 40 * MHZ, ++ .fclks = fixed_pll_clks, ++}; ++ ++static const struct mtk_clk_tree mt7981_topckgen_clk_tree = { ++ .fdivs_offs = CK_TOP_CB_M_416M, ++ .muxes_offs = CK_TOP_NFI1X_SEL, ++ .fclks = top_fixed_clks, ++ .fdivs = top_fixed_divs, ++ .muxes = top_muxes, ++ .flags = CLK_BYPASS_XTAL, ++}; ++ ++static const struct mtk_clk_tree mt7981_infracfg_clk_tree = { ++ .fdivs_offs = CK_INFRA_CK_F26M, ++ .muxes_offs = CK_INFRA_UART0_SEL, ++ .fdivs = infra_fixed_divs, ++ .muxes = infra_muxes, ++}; ++ ++static const struct udevice_id mt7981_fixed_pll_compat[] = { ++ { .compatible = "mediatek,mt7981-fixed-plls" }, ++ {} ++}; ++ ++static const struct udevice_id mt7981_topckgen_compat[] = { ++ { .compatible = "mediatek,mt7981-topckgen" }, ++ {} ++}; ++ ++static int mt7981_fixed_pll_probe(struct udevice *dev) ++{ ++ return mtk_common_clk_init(dev, &mt7981_fixed_pll_clk_tree); ++} ++ ++static int mt7981_topckgen_probe(struct udevice *dev) ++{ ++ struct mtk_clk_priv *priv = dev_get_priv(dev); ++ ++ priv->base = dev_read_addr_ptr(dev); ++ writel(MT7981_CLK_PDN_EN_WRITE, priv->base + MT7981_CLK_PDN); ++ ++ return mtk_common_clk_init(dev, &mt7981_topckgen_clk_tree); ++} ++ ++U_BOOT_DRIVER(mtk_clk_apmixedsys) = { ++ .name = "mt7981-clock-fixed-pll", ++ .id = UCLASS_CLK, ++ .of_match = mt7981_fixed_pll_compat, ++ .probe = mt7981_fixed_pll_probe, ++ .priv_auto = sizeof(struct mtk_clk_priv), ++ .ops = &mtk_clk_topckgen_ops, ++ .flags = DM_FLAG_PRE_RELOC, ++}; ++ ++U_BOOT_DRIVER(mtk_clk_topckgen) = { ++ .name = "mt7981-clock-topckgen", ++ .id = UCLASS_CLK, ++ .of_match = mt7981_topckgen_compat, ++ .probe = mt7981_topckgen_probe, ++ .priv_auto = sizeof(struct mtk_clk_priv), ++ .ops = &mtk_clk_topckgen_ops, ++ .flags = DM_FLAG_PRE_RELOC, ++}; ++ ++static const struct udevice_id mt7981_infracfg_compat[] = { ++ { .compatible = "mediatek,mt7981-infracfg" }, ++ {} ++}; ++ ++static const struct udevice_id mt7981_infracfg_ao_compat[] = { ++ { .compatible = "mediatek,mt7981-infracfg_ao" }, ++ {} ++}; ++ ++static int mt7981_infracfg_probe(struct udevice *dev) ++{ ++ return mtk_common_clk_init(dev, &mt7981_infracfg_clk_tree); ++} ++ ++static int mt7981_infracfg_ao_probe(struct udevice *dev) ++{ ++ return mtk_common_clk_gate_init(dev, &mt7981_infracfg_clk_tree, ++ infracfg_ao_gates); ++} ++ ++U_BOOT_DRIVER(mtk_clk_infracfg) = { ++ .name = "mt7981-clock-infracfg", ++ .id = UCLASS_CLK, ++ .of_match = mt7981_infracfg_compat, ++ .probe = mt7981_infracfg_probe, ++ .priv_auto = sizeof(struct mtk_clk_priv), ++ .ops = &mtk_clk_infrasys_ops, ++ .flags = DM_FLAG_PRE_RELOC, ++}; ++ ++U_BOOT_DRIVER(mtk_clk_infracfg_ao) = { ++ .name = "mt7981-clock-infracfg-ao", ++ .id = UCLASS_CLK, ++ .of_match = mt7981_infracfg_ao_compat, ++ .probe = mt7981_infracfg_ao_probe, ++ .priv_auto = sizeof(struct mtk_cg_priv), ++ .ops = &mtk_clk_gate_ops, ++ .flags = DM_FLAG_PRE_RELOC, ++}; ++ ++/* ethsys */ ++static const struct mtk_gate_regs eth_cg_regs = { ++ .set_ofs = 0x30, ++ .clr_ofs = 0x30, ++ .sta_ofs = 0x30, ++}; ++ ++#define GATE_ETH(_id, _name, _parent, _shift) \ ++ { \ ++ .id = _id, .parent = _parent, .regs = ð_cg_regs, \ ++ .shift = _shift, \ ++ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \ ++ } ++ ++static const struct mtk_gate eth_cgs[] = { ++ GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 6), ++ GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 7), ++ GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8), ++ GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15), ++}; ++ ++static int mt7981_ethsys_probe(struct udevice *dev) ++{ ++ return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree, ++ eth_cgs); ++} ++ ++static int mt7981_ethsys_bind(struct udevice *dev) ++{ ++ int ret = 0; ++ ++ if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) { ++ ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1); ++ if (ret) ++ debug("Warning: failed to bind reset controller\n"); ++ } ++ ++ return ret; ++} ++ ++static const struct udevice_id mt7981_ethsys_compat[] = { ++ { .compatible = "mediatek,mt7981-ethsys", }, ++ {} ++}; ++ ++U_BOOT_DRIVER(mtk_clk_ethsys) = { ++ .name = "mt7981-clock-ethsys", ++ .id = UCLASS_CLK, ++ .of_match = mt7981_ethsys_compat, ++ .probe = mt7981_ethsys_probe, ++ .bind = mt7981_ethsys_bind, ++ .priv_auto = sizeof(struct mtk_cg_priv), ++ .ops = &mtk_clk_gate_ops, ++}; +--- /dev/null ++++ b/include/dt-bindings/clock/mt7981-clk.h +@@ -0,0 +1,267 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2022 MediaTek Inc. All rights reserved. ++ * ++ * Author: Sam Shih ++ */ ++ ++#ifndef _DT_BINDINGS_CLK_MT7981_H ++#define _DT_BINDINGS_CLK_MT7981_H ++ ++/* INFRACFG */ ++ ++#define CK_INFRA_CK_F26M 0 ++#define CK_INFRA_UART 1 ++#define CK_INFRA_ISPI0 2 ++#define CK_INFRA_I2C 3 ++#define CK_INFRA_ISPI1 4 ++#define CK_INFRA_PWM 5 ++#define CK_INFRA_66M_MCK 6 ++#define CK_INFRA_CK_F32K 7 ++#define CK_INFRA_PCIE_CK 8 ++#define CK_INFRA_PWM_BCK 9 ++#define CK_INFRA_PWM_CK1 10 ++#define CK_INFRA_PWM_CK2 11 ++#define CK_INFRA_133M_HCK 12 ++#define CK_INFRA_66M_PHCK 13 ++#define CK_INFRA_FAUD_L_CK 14 ++#define CK_INFRA_FAUD_AUD_CK 15 ++#define CK_INFRA_FAUD_EG2_CK 16 ++#define CK_INFRA_I2CS_CK 17 ++#define CK_INFRA_MUX_UART0 18 ++#define CK_INFRA_MUX_UART1 19 ++#define CK_INFRA_MUX_UART2 20 ++#define CK_INFRA_NFI_CK 21 ++#define CK_INFRA_SPINFI_CK 22 ++#define CK_INFRA_MUX_SPI0 23 ++#define CK_INFRA_MUX_SPI1 24 ++#define CK_INFRA_MUX_SPI2 25 ++#define CK_INFRA_RTC_32K 26 ++#define CK_INFRA_FMSDC_CK 27 ++#define CK_INFRA_FMSDC_HCK_CK 28 ++#define CK_INFRA_PERI_133M 29 ++#define CK_INFRA_133M_PHCK 30 ++#define CK_INFRA_USB_SYS_CK 31 ++#define CK_INFRA_USB_CK 32 ++#define CK_INFRA_USB_XHCI_CK 33 ++#define CK_INFRA_PCIE_GFMUX_TL_O_PRE 34 ++#define CK_INFRA_F26M_CK0 35 ++#define CK_INFRA_133M_MCK 36 ++#define CLK_INFRA_NR_CLK 37 ++ ++/* TOPCKGEN */ ++ ++#define CK_TOP_CB_CKSQ_40M 0 ++#define CK_TOP_CB_M_416M 1 ++#define CK_TOP_CB_M_D2 2 ++#define CK_TOP_CB_M_D3 3 ++#define CK_TOP_M_D3_D2 4 ++#define CK_TOP_CB_M_D4 5 ++#define CK_TOP_CB_M_D8 6 ++#define CK_TOP_M_D8_D2 7 ++#define CK_TOP_CB_MM_720M 8 ++#define CK_TOP_CB_MM_D2 9 ++#define CK_TOP_CB_MM_D3 10 ++#define CK_TOP_CB_MM_D3_D5 11 ++#define CK_TOP_CB_MM_D4 12 ++#define CK_TOP_CB_MM_D6 13 ++#define CK_TOP_MM_D6_D2 14 ++#define CK_TOP_CB_MM_D8 15 ++#define CK_TOP_CB_APLL2_196M 16 ++#define CK_TOP_APLL2_D2 17 ++#define CK_TOP_APLL2_D4 18 ++#define CK_TOP_NET1_2500M 19 ++#define CK_TOP_CB_NET1_D4 20 ++#define CK_TOP_CB_NET1_D5 21 ++#define CK_TOP_NET1_D5_D2 22 ++#define CK_TOP_NET1_D5_D4 23 ++#define CK_TOP_CB_NET1_D8 24 ++#define CK_TOP_NET1_D8_D2 25 ++#define CK_TOP_NET1_D8_D4 26 ++#define CK_TOP_CB_NET2_800M 27 ++#define CK_TOP_CB_NET2_D2 28 ++#define CK_TOP_CB_NET2_D4 29 ++#define CK_TOP_NET2_D4_D2 30 ++#define CK_TOP_NET2_D4_D4 31 ++#define CK_TOP_CB_NET2_D6 32 ++#define CK_TOP_CB_WEDMCU_208M 33 ++#define CK_TOP_CB_SGM_325M 34 ++#define CK_TOP_CKSQ_40M_D2 35 ++#define CK_TOP_CB_RTC_32K 36 ++#define CK_TOP_CB_RTC_32P7K 37 ++#define CK_TOP_USB_TX250M 38 ++#define CK_TOP_FAUD 39 ++#define CK_TOP_NFI1X 40 ++#define CK_TOP_USB_EQ_RX250M 41 ++#define CK_TOP_USB_CDR_CK 42 ++#define CK_TOP_USB_LN0_CK 43 ++#define CK_TOP_SPINFI_BCK 44 ++#define CK_TOP_SPI 45 ++#define CK_TOP_SPIM_MST 46 ++#define CK_TOP_UART_BCK 47 ++#define CK_TOP_PWM_BCK 48 ++#define CK_TOP_I2C_BCK 49 ++#define CK_TOP_PEXTP_TL 50 ++#define CK_TOP_EMMC_208M 51 ++#define CK_TOP_EMMC_400M 52 ++#define CK_TOP_DRAMC_REF 53 ++#define CK_TOP_DRAMC_MD32 54 ++#define CK_TOP_SYSAXI 55 ++#define CK_TOP_SYSAPB 56 ++#define CK_TOP_ARM_DB_MAIN 57 ++#define CK_TOP_AP2CNN_HOST 58 ++#define CK_TOP_NETSYS 59 ++#define CK_TOP_NETSYS_500M 60 ++#define CK_TOP_NETSYS_WED_MCU 61 ++#define CK_TOP_NETSYS_2X 62 ++#define CK_TOP_SGM_325M 63 ++#define CK_TOP_SGM_REG 64 ++#define CK_TOP_F26M 65 ++#define CK_TOP_EIP97B 66 ++#define CK_TOP_USB3_PHY 67 ++#define CK_TOP_AUD 68 ++#define CK_TOP_A1SYS 69 ++#define CK_TOP_AUD_L 70 ++#define CK_TOP_A_TUNER 71 ++#define CK_TOP_U2U3_REF 72 ++#define CK_TOP_U2U3_SYS 73 ++#define CK_TOP_U2U3_XHCI 74 ++#define CK_TOP_USB_FRMCNT 75 ++#define CK_TOP_NFI1X_SEL 76 ++#define CK_TOP_SPINFI_SEL 77 ++#define CK_TOP_SPI_SEL 78 ++#define CK_TOP_SPIM_MST_SEL 79 ++#define CK_TOP_UART_SEL 80 ++#define CK_TOP_PWM_SEL 81 ++#define CK_TOP_I2C_SEL 82 ++#define CK_TOP_PEXTP_TL_SEL 83 ++#define CK_TOP_EMMC_208M_SEL 84 ++#define CK_TOP_EMMC_400M_SEL 85 ++#define CK_TOP_F26M_SEL 86 ++#define CK_TOP_DRAMC_SEL 87 ++#define CK_TOP_DRAMC_MD32_SEL 88 ++#define CK_TOP_SYSAXI_SEL 89 ++#define CK_TOP_SYSAPB_SEL 90 ++#define CK_TOP_ARM_DB_MAIN_SEL 91 ++#define CK_TOP_AP2CNN_HOST_SEL 92 ++#define CK_TOP_NETSYS_SEL 93 ++#define CK_TOP_NETSYS_500M_SEL 94 ++#define CK_TOP_NETSYS_MCU_SEL 95 ++#define CK_TOP_NETSYS_2X_SEL 96 ++#define CK_TOP_SGM_325M_SEL 97 ++#define CK_TOP_SGM_REG_SEL 98 ++#define CK_TOP_EIP97B_SEL 99 ++#define CK_TOP_USB3_PHY_SEL 100 ++#define CK_TOP_AUD_SEL 101 ++#define CK_TOP_A1SYS_SEL 102 ++#define CK_TOP_AUD_L_SEL 103 ++#define CK_TOP_A_TUNER_SEL 104 ++#define CK_TOP_U2U3_SEL 105 ++#define CK_TOP_U2U3_SYS_SEL 106 ++#define CK_TOP_U2U3_XHCI_SEL 107 ++#define CK_TOP_USB_FRMCNT_SEL 108 ++#define CLK_TOP_NR_CLK 109 ++ ++/* ++ * INFRACFG_AO ++ * clock muxes need to be append to infracfg domain, and clock gates ++ * need to be keep in infracgh_ao domain ++ */ ++#define INFRACFG_AO_OFFSET 10 ++ ++#define CK_INFRA_UART0_SEL (0 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_UART1_SEL (1 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_UART2_SEL (2 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_SPI0_SEL (3 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_SPI1_SEL (4 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_SPI2_SEL (5 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_PWM1_SEL (6 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_PWM2_SEL (7 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_PWM_BSEL (8 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_PCIE_SEL (9 + CLK_INFRA_NR_CLK) ++#define CK_INFRA_GPT_STA (10 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_PWM_HCK (11 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_PWM_STA (12 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_PWM1_CK (13 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_PWM2_CK (14 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_CQ_DMA_CK (15 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_AUD_BUS_CK (16 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_AUD_26M_CK (17 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_AUD_L_CK (18 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_AUD_AUD_CK (19 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_AUD_EG2_CK (20 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_DRAMC_26M_CK (21 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_DBG_CK (22 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_AP_DMA_CK (23 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SEJ_CK (24 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SEJ_13M_CK (25 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_THERM_CK (26 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_I2CO_CK (27 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_UART0_CK (28 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_UART1_CK (29 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_UART2_CK (30 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SPI2_CK (31 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SPI2_HCK_CK (32 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_NFI1_CK (33 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SPINFI1_CK (34 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_NFI_HCK_CK (35 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SPI0_CK (36 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SPI1_CK (37 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SPI0_HCK_CK (38 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_SPI1_HCK_CK (39 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_FRTC_CK (40 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_MSDC_CK (41 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_MSDC_HCK_CK (42 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_MSDC_133M_CK (43 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_MSDC_66M_CK (44 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_ADC_26M_CK (45 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_ADC_FRC_CK (46 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_FBIST2FPC_CK (47 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_I2C_MCK_CK (48 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_I2C_PCK_CK (49 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_IUSB_133_CK (50 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_IUSB_66M_CK (51 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_IUSB_SYS_CK (52 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_IUSB_CK (53 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_IPCIE_CK (54 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_IPCIER_CK (55 - INFRACFG_AO_OFFSET) ++#define CK_INFRA_IPCIEB_CK (56 - INFRACFG_AO_OFFSET) ++#define CLK_INFRA_AO_NR_CLK (57 - INFRACFG_AO_OFFSET) ++ ++/* APMIXEDSYS */ ++ ++#define CK_APMIXED_ARMPLL 0 ++#define CK_APMIXED_NET2PLL 1 ++#define CK_APMIXED_MMPLL 2 ++#define CK_APMIXED_SGMPLL 3 ++#define CK_APMIXED_WEDMCUPLL 4 ++#define CK_APMIXED_NET1PLL 5 ++#define CK_APMIXED_MPLL 6 ++#define CK_APMIXED_APLL2 7 ++#define CLK_APMIXED_NR_CLK 8 ++ ++/* SGMIISYS_0 */ ++ ++#define CK_SGM0_TX_EN 0 ++#define CK_SGM0_RX_EN 1 ++#define CK_SGM0_CK0_EN 2 ++#define CK_SGM0_CDR_CK0_EN 3 ++#define CLK_SGMII0_NR_CLK 4 ++ ++/* SGMIISYS_1 */ ++ ++#define CK_SGM1_TX_EN 0 ++#define CK_SGM1_RX_EN 1 ++#define CK_SGM1_CK1_EN 2 ++#define CK_SGM1_CDR_CK1_EN 3 ++#define CLK_SGMII1_NR_CLK 4 ++ ++/* ETHSYS */ ++ ++#define CK_ETH_FE_EN 0 ++#define CK_ETH_GP2_EN 1 ++#define CK_ETH_GP1_EN 2 ++#define CK_ETH_WOCPU0_EN 3 ++#define CLK_ETH_NR_CLK 4 ++ ++#endif /* _DT_BINDINGS_CLK_MT7981_H */ diff --git a/package/boot/uboot-mediatek/patches/002-0028-tools-mtk_image-split-gfh-header-verification-into-a.patch b/package/boot/uboot-mediatek/patches/002-0028-tools-mtk_image-split-gfh-header-verification-into-a.patch new file mode 100644 index 0000000000..c8747ae154 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0028-tools-mtk_image-split-gfh-header-verification-into-a.patch @@ -0,0 +1,89 @@ +From b6bb61fd3818f4a3025fedbe4d15dbeeaef6ee82 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Tue, 2 Aug 2022 17:21:34 +0800 +Subject: [PATCH 28/31] tools: mtk_image: split gfh header verification into a + new function + +The verification code of gfh header for NAND and non-NAND are identical. +It's better to define a individual function to reduce redundancy. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + tools/mtk_image.c | 51 +++++++++++++++++++---------------------------- + 1 file changed, 21 insertions(+), 30 deletions(-) + +--- a/tools/mtk_image.c ++++ b/tools/mtk_image.c +@@ -480,6 +480,25 @@ static int mtk_image_vrec_header(struct + return SHA256_SUM_LEN; + } + ++static int mtk_image_verify_gfh(struct gfh_header *gfh, uint32_t type, int print) ++{ ++ if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) ++ return -1; ++ ++ if (le32_to_cpu(gfh->file_info.flash_type) != type) ++ return -1; ++ ++ if (print) ++ printf("Load Address: %08x\n", ++ le32_to_cpu(gfh->file_info.load_addr) + ++ le32_to_cpu(gfh->file_info.jump_offset)); ++ ++ if (print) ++ printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); ++ ++ return 0; ++} ++ + static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) + { + union gen_boot_header *gbh = (union gen_boot_header *)ptr; +@@ -542,21 +561,7 @@ static int mtk_image_verify_gen_header(c + + gfh = (struct gfh_header *)(ptr + gfh_offset); + +- if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) +- return -1; +- +- if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN) +- return -1; +- +- if (print) +- printf("Load Address: %08x\n", +- le32_to_cpu(gfh->file_info.load_addr) + +- le32_to_cpu(gfh->file_info.jump_offset)); +- +- if (print) +- printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); +- +- return 0; ++ return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_GEN, print); + } + + static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) +@@ -610,21 +615,7 @@ static int mtk_image_verify_nand_header( + + gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize)); + +- if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) +- return -1; +- +- if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND) +- return -1; +- +- if (print) +- printf("Load Address: %08x\n", +- le32_to_cpu(gfh->file_info.load_addr) + +- le32_to_cpu(gfh->file_info.jump_offset)); +- +- if (print) +- printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); +- +- return 0; ++ return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print); + } + + static uint32_t crc32be_cal(const void *data, size_t length) diff --git a/package/boot/uboot-mediatek/patches/002-0029-tools-mtk_image-split-the-code-of-generating-NAND-he.patch b/package/boot/uboot-mediatek/patches/002-0029-tools-mtk_image-split-the-code-of-generating-NAND-he.patch new file mode 100644 index 0000000000..8ecfda2d46 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0029-tools-mtk_image-split-the-code-of-generating-NAND-he.patch @@ -0,0 +1,821 @@ +From 20ebf03eab571b25e9f62b2764ab84932111dcd6 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Tue, 2 Aug 2022 17:23:57 +0800 +Subject: [PATCH 29/31] tools: mtk_image: split the code of generating NAND + header into a new file + +The predefined NAND headers take too much spaces in the mtk_image.c. +Moving them into a new file can significantly improve the readability of +both mtk_image.c and the new mtk_nand_headers.c. + +This is a preparation for adding more NAND headers. + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + tools/Makefile | 1 + + tools/mtk_image.c | 305 ++++++--------------------------------- + tools/mtk_image.h | 25 ---- + tools/mtk_nand_headers.c | 286 ++++++++++++++++++++++++++++++++++++ + tools/mtk_nand_headers.h | 61 ++++++++ + 5 files changed, 389 insertions(+), 289 deletions(-) + create mode 100644 tools/mtk_nand_headers.c + create mode 100644 tools/mtk_nand_headers.h + +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -148,6 +148,7 @@ dumpimage-mkimage-objs := aisimage.o \ + gpimage.o \ + gpimage-common.o \ + mtk_image.o \ ++ mtk_nand_headers.o \ + $(ECDSA_OBJS-y) \ + $(RSA_OBJS-y) \ + $(AES_OBJS-y) +--- a/tools/mtk_image.c ++++ b/tools/mtk_image.c +@@ -12,216 +12,7 @@ + #include + #include "imagetool.h" + #include "mtk_image.h" +- +-/* NAND header for SPI-NAND with 2KB page + 64B spare */ +-static const union nand_boot_header snand_hdr_2k_64_data = { +- .data = { +- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, +- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, +- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, +- 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00, +- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D, +- 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7, +- 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8, +- 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00 +- } +-}; +- +-/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */ +-static const union nand_boot_header snand_hdr_2k_128_data = { +- .data = { +- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, +- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, +- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, +- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, +- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13, +- 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3, +- 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7, +- 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00 +- } +-}; +- +-/* NAND header for SPI-NAND with 4KB page + 256B spare */ +-static const union nand_boot_header snand_hdr_4k_256_data = { +- .data = { +- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, +- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, +- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, +- 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00, +- 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3, +- 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57, +- 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F, +- 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00 +- } +-}; +- +-/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */ +-static const union nand_boot_header nand_hdr_1gb_2k_64_data = { +- .data = { +- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, +- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, +- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, +- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, +- 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12, +- 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C, +- 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82, +- 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00 +- } +-}; +- +-/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */ +-static const union nand_boot_header nand_hdr_2gb_2k_64_data = { +- .data = { +- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, +- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, +- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, +- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, +- 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D, +- 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1, +- 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95, +- 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00 +- } +-}; +- +-/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */ +-static const union nand_boot_header nand_hdr_4gb_2k_64_data = { +- .data = { +- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, +- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, +- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, +- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, +- 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32, +- 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B, +- 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87, +- 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00 +- } +-}; +- +-/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */ +-static const union nand_boot_header nand_hdr_2gb_2k_128_data = { +- .data = { +- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, +- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, +- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, +- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, +- 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A, +- 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC, +- 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0, +- 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00 +- } +-}; +- +-/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */ +-static const union nand_boot_header nand_hdr_4gb_2k_128_data = { +- .data = { +- 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, +- 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, +- 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, +- 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, +- 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45, +- 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46, +- 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2, +- 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00 +- } +-}; +- +-static const struct nand_header_type { +- const char *name; +- const union nand_boot_header *data; +-} nand_headers[] = { +- { +- .name = "2k+64", +- .data = &snand_hdr_2k_64_data +- }, { +- .name = "2k+120", +- .data = &snand_hdr_2k_128_data +- }, { +- .name = "2k+128", +- .data = &snand_hdr_2k_128_data +- }, { +- .name = "4k+256", +- .data = &snand_hdr_4k_256_data +- }, { +- .name = "1g:2k+64", +- .data = &nand_hdr_1gb_2k_64_data +- }, { +- .name = "2g:2k+64", +- .data = &nand_hdr_2gb_2k_64_data +- }, { +- .name = "4g:2k+64", +- .data = &nand_hdr_4gb_2k_64_data +- }, { +- .name = "2g:2k+128", +- .data = &nand_hdr_2gb_2k_128_data +- }, { +- .name = "4g:2k+128", +- .data = &nand_hdr_4gb_2k_128_data +- } +-}; ++#include "mtk_nand_headers.h" + + static const struct brom_img_type { + const char *name; +@@ -264,6 +55,7 @@ static uint32_t crc32tbl[256]; + + /* NAND header selected by user */ + static const union nand_boot_header *hdr_nand; ++static uint32_t hdr_nand_size; + + /* GFH header + 2 * 4KB pages of NAND */ + static char hdr_tmp[sizeof(struct gfh_header) + 0x2000]; +@@ -402,12 +194,7 @@ static int mtk_brom_parse_imagename(cons + } + + /* parse nand header type */ +- for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { +- if (!strcmp(nand_headers[i].name, nandinfo)) { +- hdr_nand = nand_headers[i].data; +- break; +- } +- } ++ hdr_nand = mtk_nand_header_find(nandinfo); + + /* parse device header offset */ + if (hdr_offs && hdr_offs[0]) +@@ -432,6 +219,9 @@ static int mtk_brom_parse_imagename(cons + return -EINVAL; + } + ++ if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) ++ hdr_nand_size = mtk_nand_header_size(hdr_nand); ++ + return 0; + } + +@@ -468,7 +258,7 @@ static int mtk_image_vrec_header(struct + } + + if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) +- tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize); ++ tparams->header_size = hdr_nand_size; + else + tparams->header_size = sizeof(struct gen_device_header); + +@@ -566,16 +356,17 @@ static int mtk_image_verify_gen_header(c + + static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) + { +- union nand_boot_header *nh = (union nand_boot_header *)ptr; + struct brom_layout_header *bh; ++ struct nand_header_info info; + struct gfh_header *gfh; + const char *bootmedia; ++ int ret; + +- if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) || +- strcmp(nh->id, NAND_BOOT_ID)) +- return -1; ++ ret = mtk_nand_header_info(ptr, &info); ++ if (ret < 0) ++ return ret; + +- bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize)); ++ bh = (struct brom_layout_header *)(ptr + info.page_size); + + if (strcmp(bh->name, BRLYT_NAME)) + return -1; +@@ -586,34 +377,23 @@ static int mtk_image_verify_nand_header( + if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) + bootmedia = "Parallel NAND"; + else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND) +- bootmedia = "Serial NAND"; ++ bootmedia = "Serial NAND (SNFI/AP)"; + else + return -1; + } + + if (print) { +- printf("Boot Media: %s\n", bootmedia); +- +- if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) { +- uint64_t capacity = +- (uint64_t)le16_to_cpu(nh->numblocks) * +- (uint64_t)le16_to_cpu(nh->pages_of_block) * +- (uint64_t)le16_to_cpu(nh->pagesize) * 8; +- printf("Capacity: %dGb\n", +- (uint32_t)(capacity >> 30)); +- } ++ printf("Boot Media: %s\n", bootmedia); + +- if (le16_to_cpu(nh->pagesize) >= 1024) +- printf("Page Size: %dKB\n", +- le16_to_cpu(nh->pagesize) >> 10); ++ if (info.page_size >= 1024) ++ printf("Page Size: %dKB\n", info.page_size >> 10); + else +- printf("Page Size: %dB\n", +- le16_to_cpu(nh->pagesize)); ++ printf("Page Size: %dB\n", info.page_size); + +- printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize)); ++ printf("Spare Size: %dB\n", info.spare_size); + } + +- gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize)); ++ gfh = (struct gfh_header *)(ptr + info.gfh_offset); + + return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print); + } +@@ -713,7 +493,7 @@ static int mtk_image_verify_header(unsig + if (image_get_magic(hdr) == IH_MAGIC) + return mtk_image_verify_mt7621_header(ptr, 0); + +- if (!strcmp((char *)ptr, NAND_BOOT_NAME)) ++ if (is_mtk_nand_header(ptr)) + return mtk_image_verify_nand_header(ptr, 0); + else + return mtk_image_verify_gen_header(ptr, 0); +@@ -739,7 +519,7 @@ static void mtk_image_print_header(const + return; + } + +- if (!strcmp((char *)ptr, NAND_BOOT_NAME)) ++ if (is_mtk_nand_header(ptr)) + mtk_image_verify_nand_header(ptr, 1); + else + mtk_image_verify_gen_header(ptr, 1); +@@ -870,36 +650,33 @@ static void mtk_image_set_gen_header(voi + static void mtk_image_set_nand_header(void *ptr, off_t filesize, + uint32_t loadaddr) + { +- union nand_boot_header *nh = (union nand_boot_header *)ptr; + struct brom_layout_header *brlyt; + struct gfh_header *gfh; +- uint32_t payload_pages; +- int i; ++ uint32_t payload_pages, nand_page_size; + +- /* NAND device header, repeat 4 times */ +- for (i = 0; i < 4; i++) +- memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); ++ /* NAND header */ ++ nand_page_size = mtk_nand_header_put(hdr_nand, ptr); + +- /* BRLYT header */ +- payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) / +- le16_to_cpu(hdr_nand->pagesize); +- brlyt = (struct brom_layout_header *) +- (ptr + le16_to_cpu(hdr_nand->pagesize)); +- put_brom_layout_header(brlyt, hdr_media); +- brlyt->header_size = cpu_to_le32(2); +- brlyt->total_size = cpu_to_le32(payload_pages); +- brlyt->header_size_2 = brlyt->header_size; +- brlyt->total_size_2 = brlyt->total_size; +- brlyt->unused = cpu_to_le32(1); ++ if (nand_page_size) { ++ /* BRLYT header */ ++ payload_pages = (filesize + nand_page_size - 1) / ++ nand_page_size; ++ brlyt = (struct brom_layout_header *)(ptr + nand_page_size); ++ put_brom_layout_header(brlyt, hdr_media); ++ brlyt->header_size = cpu_to_le32(2); ++ brlyt->total_size = cpu_to_le32(payload_pages); ++ brlyt->header_size_2 = brlyt->header_size; ++ brlyt->total_size_2 = brlyt->total_size; ++ brlyt->unused = cpu_to_le32(1); ++ } + + /* GFH header */ +- gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize)); +- put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize), +- loadaddr, GFH_FLASH_TYPE_NAND); ++ gfh = (struct gfh_header *)(ptr + hdr_nand_size); ++ put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr, ++ GFH_FLASH_TYPE_NAND); + + /* Generate SHA256 hash */ +- put_hash((uint8_t *)gfh, +- filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN); ++ put_hash((uint8_t *)gfh, filesize - hdr_nand_size - SHA256_SUM_LEN); + } + + static void mtk_image_set_mt7621_header(void *ptr, off_t filesize, +--- a/tools/mtk_image.h ++++ b/tools/mtk_image.h +@@ -26,31 +26,6 @@ union gen_boot_header { + #define SF_BOOT_NAME "SF_BOOT" + #define SDMMC_BOOT_NAME "SDMMC_BOOT" + +-/* Header for NAND */ +-union nand_boot_header { +- struct { +- char name[12]; +- char version[4]; +- char id[8]; +- uint16_t ioif; +- uint16_t pagesize; +- uint16_t addrcycles; +- uint16_t oobsize; +- uint16_t pages_of_block; +- uint16_t numblocks; +- uint16_t writesize_shift; +- uint16_t erasesize_shift; +- uint8_t dummy[60]; +- uint8_t ecc_parity[28]; +- }; +- +- uint8_t data[0x80]; +-}; +- +-#define NAND_BOOT_NAME "BOOTLOADER!" +-#define NAND_BOOT_VERSION "V006" +-#define NAND_BOOT_ID "NFIINFO" +- + /* BootROM layout header */ + struct brom_layout_header { + char name[8]; +--- /dev/null ++++ b/tools/mtk_nand_headers.c +@@ -0,0 +1,286 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * MediaTek BootROM NAND header definitions ++ * ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#include ++#include ++#include "imagetool.h" ++#include "mtk_image.h" ++#include "mtk_nand_headers.h" ++ ++/* NAND header for SPI-NAND with 2KB page + 64B spare */ ++static const union nand_boot_header snand_hdr_2k_64_data = { ++ .data = { ++ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, ++ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, ++ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, ++ 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00, ++ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D, ++ 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7, ++ 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8, ++ 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00 ++ } ++}; ++ ++/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */ ++static const union nand_boot_header snand_hdr_2k_128_data = { ++ .data = { ++ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, ++ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, ++ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, ++ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, ++ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13, ++ 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3, ++ 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7, ++ 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00 ++ } ++}; ++ ++/* NAND header for SPI-NAND with 4KB page + 256B spare */ ++static const union nand_boot_header snand_hdr_4k_256_data = { ++ .data = { ++ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, ++ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, ++ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, ++ 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00, ++ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3, ++ 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57, ++ 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F, ++ 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00 ++ } ++}; ++ ++/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */ ++static const union nand_boot_header nand_hdr_1gb_2k_64_data = { ++ .data = { ++ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, ++ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, ++ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, ++ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, ++ 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12, ++ 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C, ++ 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82, ++ 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00 ++ } ++}; ++ ++/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */ ++static const union nand_boot_header nand_hdr_2gb_2k_64_data = { ++ .data = { ++ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, ++ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, ++ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, ++ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, ++ 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D, ++ 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1, ++ 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95, ++ 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00 ++ } ++}; ++ ++/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */ ++static const union nand_boot_header nand_hdr_4gb_2k_64_data = { ++ .data = { ++ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, ++ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, ++ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, ++ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, ++ 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32, ++ 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B, ++ 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87, ++ 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00 ++ } ++}; ++ ++/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */ ++static const union nand_boot_header nand_hdr_2gb_2k_128_data = { ++ .data = { ++ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, ++ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, ++ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, ++ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, ++ 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A, ++ 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC, ++ 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0, ++ 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00 ++ } ++}; ++ ++/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */ ++static const union nand_boot_header nand_hdr_4gb_2k_128_data = { ++ .data = { ++ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, ++ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, ++ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, ++ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, ++ 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45, ++ 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46, ++ 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2, ++ 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00 ++ } ++}; ++ ++static const struct nand_header_type { ++ const char *name; ++ const union nand_boot_header *data; ++} nand_headers[] = { ++ { ++ .name = "2k+64", ++ .data = &snand_hdr_2k_64_data ++ }, { ++ .name = "2k+120", ++ .data = &snand_hdr_2k_128_data ++ }, { ++ .name = "2k+128", ++ .data = &snand_hdr_2k_128_data ++ }, { ++ .name = "4k+256", ++ .data = &snand_hdr_4k_256_data ++ }, { ++ .name = "1g:2k+64", ++ .data = &nand_hdr_1gb_2k_64_data ++ }, { ++ .name = "2g:2k+64", ++ .data = &nand_hdr_2gb_2k_64_data ++ }, { ++ .name = "4g:2k+64", ++ .data = &nand_hdr_4gb_2k_64_data ++ }, { ++ .name = "2g:2k+128", ++ .data = &nand_hdr_2gb_2k_128_data ++ }, { ++ .name = "4g:2k+128", ++ .data = &nand_hdr_4gb_2k_128_data ++ } ++}; ++ ++const union nand_boot_header *mtk_nand_header_find(const char *name) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { ++ if (!strcmp(nand_headers[i].name, name)) ++ return nand_headers[i].data; ++ } ++ ++ return NULL; ++} ++ ++uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand) ++{ ++ return 2 * le16_to_cpu(hdr_nand->pagesize); ++} ++ ++static int mtk_nand_header_ap_info(const void *ptr, ++ struct nand_header_info *info) ++{ ++ union nand_boot_header *nh = (union nand_boot_header *)ptr; ++ ++ if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) || ++ strcmp(nh->id, NAND_BOOT_ID)) ++ return -1; ++ ++ info->page_size = le16_to_cpu(nh->pagesize); ++ info->spare_size = le16_to_cpu(nh->oobsize); ++ info->gfh_offset = 2 * info->page_size; ++ ++ return 0; ++} ++ ++int mtk_nand_header_info(const void *ptr, struct nand_header_info *info) ++{ ++ if (!strcmp((char *)ptr, NAND_BOOT_NAME)) ++ return mtk_nand_header_ap_info(ptr, info); ++ ++ return -1; ++} ++ ++bool is_mtk_nand_header(const void *ptr) ++{ ++ struct nand_header_info info; ++ ++ if (mtk_nand_header_info(ptr, &info) >= 0) ++ return true; ++ ++ return false; ++} ++ ++uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr) ++{ ++ union nand_boot_header *nh = (union nand_boot_header *)ptr; ++ int i; ++ ++ /* NAND device header, repeat 4 times */ ++ for (i = 0; i < 4; i++) ++ memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); ++ ++ return le16_to_cpu(hdr_nand->pagesize); ++} +--- /dev/null ++++ b/tools/mtk_nand_headers.h +@@ -0,0 +1,61 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * MediaTek BootROM NAND header definitions ++ * ++ * Copyright (C) 2022 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#ifndef _MTK_NAND_HEADERS_H ++#define _MTK_NAND_HEADERS_H ++ ++#include ++#include ++ ++struct nand_header_info { ++ uint32_t page_size; ++ uint32_t spare_size; ++ uint32_t gfh_offset; ++}; ++ ++/* AP BROM Header for NAND */ ++union nand_boot_header { ++ struct { ++ char name[12]; ++ char version[4]; ++ char id[8]; ++ uint16_t ioif; /* I/O interface */ ++ uint16_t pagesize; /* NAND page size */ ++ uint16_t addrcycles; /* Address cycles */ ++ uint16_t oobsize; /* NAND page spare size */ ++ uint16_t pages_of_block; /* Pages of one block */ ++ uint16_t numblocks; /* Total blocks of NAND chip */ ++ uint16_t writesize_shift; ++ uint16_t erasesize_shift; ++ uint8_t dummy[60]; ++ uint8_t ecc_parity[28]; /* ECC parity of this header */ ++ }; ++ ++ uint8_t data[0x80]; ++}; ++ ++#define NAND_BOOT_NAME "BOOTLOADER!" ++#define NAND_BOOT_VERSION "V006" ++#define NAND_BOOT_ID "NFIINFO" ++ ++/* Find nand header data by name */ ++const union nand_boot_header *mtk_nand_header_find(const char *name); ++ ++/* Device header size using this nand header */ ++uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand); ++ ++/* Get nand info from nand header (page size, spare size, ...) */ ++int mtk_nand_header_info(const void *ptr, struct nand_header_info *info); ++ ++/* Whether given header data is valid */ ++bool is_mtk_nand_header(const void *ptr); ++ ++/* Generate Device header using give nand header */ ++uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr); ++ ++#endif /* _MTK_NAND_HEADERS_H */ diff --git a/package/boot/uboot-mediatek/patches/002-0030-tools-mtk_image-add-support-for-nand-headers-used-by.patch b/package/boot/uboot-mediatek/patches/002-0030-tools-mtk_image-add-support-for-nand-headers-used-by.patch new file mode 100644 index 0000000000..0ce095998f --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0030-tools-mtk_image-add-support-for-nand-headers-used-by.patch @@ -0,0 +1,702 @@ +From fbf296f9ed5daab70020686e9ba072efe663bbab Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 3 Aug 2022 11:14:36 +0800 +Subject: [PATCH 30/31] tools: mtk_image: add support for nand headers used by + newer chips + +This patch adds more nand headers in two new types: +1. HSM header, used for spi-nand thru SNFI interface +2. SPIM header, used for spi-nand thru spi-mem interface + +The original nand header is renamed to AP header. + +Signed-off-by: Weijie Gao +--- + tools/mtk_image.c | 23 ++- + tools/mtk_nand_headers.c | 422 +++++++++++++++++++++++++++++++++++++-- + tools/mtk_nand_headers.h | 110 +++++++++- + 3 files changed, 525 insertions(+), 30 deletions(-) + +--- a/tools/mtk_image.c ++++ b/tools/mtk_image.c +@@ -33,6 +33,9 @@ static const struct brom_img_type { + }, { + .name = "snand", + .type = BRLYT_TYPE_SNAND ++ }, { ++ .name = "spim-nand", ++ .type = BRLYT_TYPE_SNAND + } + }; + +@@ -54,7 +57,7 @@ static char lk_name[32] = "U-Boot"; + static uint32_t crc32tbl[256]; + + /* NAND header selected by user */ +-static const union nand_boot_header *hdr_nand; ++static const struct nand_header_type *hdr_nand; + static uint32_t hdr_nand_size; + + /* GFH header + 2 * 4KB pages of NAND */ +@@ -366,20 +369,26 @@ static int mtk_image_verify_nand_header( + if (ret < 0) + return ret; + +- bh = (struct brom_layout_header *)(ptr + info.page_size); ++ if (!ret) { ++ bh = (struct brom_layout_header *)(ptr + info.page_size); + +- if (strcmp(bh->name, BRLYT_NAME)) +- return -1; ++ if (strcmp(bh->name, BRLYT_NAME)) ++ return -1; ++ ++ if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) ++ return -1; + +- if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) { +- return -1; +- } else { + if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) + bootmedia = "Parallel NAND"; + else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND) + bootmedia = "Serial NAND (SNFI/AP)"; + else + return -1; ++ } else { ++ if (info.snfi) ++ bootmedia = "Serial NAND (SNFI/HSM)"; ++ else ++ bootmedia = "Serial NAND (SPIM)"; + } + + if (print) { +--- a/tools/mtk_nand_headers.c ++++ b/tools/mtk_nand_headers.c +@@ -188,55 +188,346 @@ static const union nand_boot_header nand + } + }; + +-static const struct nand_header_type { ++/* HSM BROM NAND header for SPI NAND with 2KB page + 64B spare */ ++static const union hsm_nand_boot_header hsm_nand_hdr_2k_64_data = { ++ .data = { ++ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, ++ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, ++ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0xFF, 0x00, 0x00, 0x00, 0x21, 0xD2, 0xEE, 0xF6, ++ 0xAE, 0xDD, 0x5E, 0xC2, 0x82, 0x8E, 0x9A, 0x62, ++ 0x09, 0x8E, 0x80, 0xE2, 0x37, 0x0D, 0xC9, 0xFA, ++ 0xA9, 0xDD, 0xFC, 0x92, 0x34, 0x2A, 0xED, 0x51, ++ 0xA4, 0x1B, 0xF7, 0x63, 0xCC, 0x5A, 0xC7, 0xFB, ++ 0xED, 0x21, 0x02, 0x23, 0x51, 0x31 ++ } ++}; ++ ++/* HSM BROM NAND header for SPI NAND with 2KB page + 128B spare */ ++static const union hsm_nand_boot_header hsm_nand_hdr_2k_128_data = { ++ .data = { ++ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, ++ 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, ++ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0xFF, 0x00, 0x00, 0x00, 0x71, 0x7f, 0x71, 0xAC, ++ 0x42, 0xD0, 0x5B, 0xD2, 0x12, 0x81, 0x15, 0x0A, ++ 0x0C, 0xD4, 0xF6, 0x32, 0x1E, 0x63, 0xE7, 0x81, ++ 0x8A, 0x7F, 0xDE, 0xF9, 0x4B, 0x91, 0xEC, 0xC2, ++ 0x70, 0x00, 0x7F, 0x57, 0xAF, 0xDC, 0xE4, 0x24, ++ 0x57, 0x09, 0xBC, 0xC5, 0x35, 0xDC ++ } ++}; ++ ++/* HSM BROM NAND header for SPI NAND with 4KB page + 256B spare */ ++static const union hsm_nand_boot_header hsm_nand_hdr_4k_256_data = { ++ .data = { ++ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, ++ 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, ++ 0xFF, 0x00, 0x00, 0x00, 0x62, 0x04, 0xD6, 0x1F, ++ 0x2B, 0x57, 0x7A, 0x2D, 0xFE, 0xBB, 0x4A, 0x50, ++ 0xEC, 0xF8, 0x70, 0x1A, 0x44, 0x15, 0xF6, 0xA2, ++ 0x8E, 0xB0, 0xFD, 0xFA, 0xDC, 0xAA, 0x5A, 0x4E, ++ 0xCB, 0x8E, 0xC9, 0x72, 0x08, 0xDC, 0x20, 0xB9, ++ 0x98, 0xC8, 0x82, 0xD8, 0xBE, 0x44 ++ } ++}; ++ ++/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 64B spare */ ++static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_64_data = { ++ .data = { ++ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, ++ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, ++ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, ++ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x5F, 0x4B, 0xB2, 0x5B, 0x8B, 0x1C, 0x35, 0xDA, ++ 0x83, 0xE6, 0x6C, 0xC3, 0xFB, 0x8C, 0x78, 0x23, ++ 0xD0, 0x89, 0x24, 0xD9, 0x6C, 0x35, 0x2C, 0x5D, ++ 0x8F, 0xBB, 0xFC, 0x10, 0xD0, 0xE2, 0x22, 0x7D, ++ 0xC8, 0x97, 0x9A, 0xEF, 0xC6, 0xB5, 0xA7, 0x4E, ++ 0x4E, 0x0E ++ } ++}; ++ ++/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 128B spare */ ++static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_128_data = { ++ .data = { ++ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, ++ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, ++ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, ++ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0xF8, 0x7E, 0xC1, 0x5D, 0x61, 0x54, 0xEA, 0x9F, ++ 0x5E, 0x66, 0x39, 0x66, 0x21, 0xFF, 0x8C, 0x3B, ++ 0xBE, 0xA7, 0x5A, 0x9E, 0xD7, 0xBD, 0x9E, 0x89, ++ 0xEE, 0x7E, 0x10, 0x31, 0x9A, 0x1D, 0x82, 0x49, ++ 0xA3, 0x4E, 0xD8, 0x47, 0xD7, 0x19, 0xF4, 0x2D, ++ 0x8E, 0x53 ++ } ++}; ++ ++/* HSM2.0 BROM NAND header for SPI NAND with 4KB page + 256B spare */ ++static const union hsm20_nand_boot_header hsm20_nand_hdr_4k_256_data = { ++ .data = { ++ 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, ++ 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, ++ 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x79, 0x01, 0x1F, 0x86, 0x62, 0x6A, 0x43, 0xAE, ++ 0xE6, 0xF8, 0xDD, 0x5B, 0x29, 0xB7, 0xA2, 0x7F, ++ 0x29, 0x72, 0x54, 0x37, 0xBE, 0x50, 0xD4, 0x24, ++ 0xAB, 0x60, 0xF4, 0x44, 0x97, 0x3B, 0x65, 0x21, ++ 0x73, 0x24, 0x1F, 0x93, 0x0E, 0x9E, 0x96, 0x88, ++ 0x78, 0x6C ++ } ++}; ++ ++/* SPIM-NAND header for SPI NAND with 2KB page + 64B spare */ ++static const union spim_nand_boot_header spim_nand_hdr_2k_64_data = { ++ .data = { ++ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, ++ 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, ++ 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30, ++ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ } ++}; ++ ++/* SPIM-NAND header for SPI NAND with 2KB page + 128B spare */ ++static const union spim_nand_boot_header spim_nand_hdr_2k_128_data = { ++ .data = { ++ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, ++ 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, ++ 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30, ++ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ } ++}; ++ ++/* SPIM-NAND header for SPI NAND with 4KB page + 256B spare */ ++static const union spim_nand_boot_header spim_nand_hdr_4k_256_data = { ++ .data = { ++ 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, ++ 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, ++ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, ++ 0x40, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x30, ++ 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++ } ++}; ++ ++struct nand_header_type { + const char *name; +- const union nand_boot_header *data; ++ enum nand_boot_header_type type; ++ union { ++ const union nand_boot_header *ap; ++ const union hsm_nand_boot_header *hsm; ++ const union hsm20_nand_boot_header *hsm20; ++ const union spim_nand_boot_header *spim; ++ }; + } nand_headers[] = { + { + .name = "2k+64", +- .data = &snand_hdr_2k_64_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &snand_hdr_2k_64_data, + }, { + .name = "2k+120", +- .data = &snand_hdr_2k_128_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &snand_hdr_2k_128_data, + }, { + .name = "2k+128", +- .data = &snand_hdr_2k_128_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &snand_hdr_2k_128_data, + }, { + .name = "4k+256", +- .data = &snand_hdr_4k_256_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &snand_hdr_4k_256_data, + }, { + .name = "1g:2k+64", +- .data = &nand_hdr_1gb_2k_64_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &nand_hdr_1gb_2k_64_data, + }, { + .name = "2g:2k+64", +- .data = &nand_hdr_2gb_2k_64_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &nand_hdr_2gb_2k_64_data, + }, { + .name = "4g:2k+64", +- .data = &nand_hdr_4gb_2k_64_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &nand_hdr_4gb_2k_64_data, + }, { + .name = "2g:2k+128", +- .data = &nand_hdr_2gb_2k_128_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &nand_hdr_2gb_2k_128_data, + }, { + .name = "4g:2k+128", +- .data = &nand_hdr_4gb_2k_128_data ++ .type = NAND_BOOT_AP_HEADER, ++ .ap = &nand_hdr_4gb_2k_128_data, ++ }, { ++ .name = "hsm:2k+64", ++ .type = NAND_BOOT_HSM_HEADER, ++ .hsm = &hsm_nand_hdr_2k_64_data, ++ }, { ++ .name = "hsm:2k+128", ++ .type = NAND_BOOT_HSM_HEADER, ++ .hsm = &hsm_nand_hdr_2k_128_data, ++ }, { ++ .name = "hsm:4k+256", ++ .type = NAND_BOOT_HSM_HEADER, ++ .hsm = &hsm_nand_hdr_4k_256_data, ++ }, { ++ .name = "hsm20:2k+64", ++ .type = NAND_BOOT_HSM20_HEADER, ++ .hsm20 = &hsm20_nand_hdr_2k_64_data, ++ }, { ++ .name = "hsm20:2k+128", ++ .type = NAND_BOOT_HSM20_HEADER, ++ .hsm20 = &hsm20_nand_hdr_2k_128_data, ++ }, { ++ .name = "hsm20:4k+256", ++ .type = NAND_BOOT_HSM20_HEADER, ++ .hsm20 = &hsm20_nand_hdr_4k_256_data, ++ }, { ++ .name = "spim:2k+64", ++ .type = NAND_BOOT_SPIM_HEADER, ++ .spim = &spim_nand_hdr_2k_64_data, ++ }, { ++ .name = "spim:2k+128", ++ .type = NAND_BOOT_SPIM_HEADER, ++ .spim = &spim_nand_hdr_2k_128_data, ++ }, { ++ .name = "spim:4k+256", ++ .type = NAND_BOOT_SPIM_HEADER, ++ .spim = &spim_nand_hdr_4k_256_data, + } + }; + +-const union nand_boot_header *mtk_nand_header_find(const char *name) ++const struct nand_header_type *mtk_nand_header_find(const char *name) + { + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { + if (!strcmp(nand_headers[i].name, name)) +- return nand_headers[i].data; ++ return &nand_headers[i]; + } + + return NULL; + } + +-uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand) ++uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand) + { +- return 2 * le16_to_cpu(hdr_nand->pagesize); ++ switch (hdr_nand->type) { ++ case NAND_BOOT_HSM_HEADER: ++ return le32_to_cpu(hdr_nand->hsm->page_size); ++ ++ case NAND_BOOT_HSM20_HEADER: ++ return le32_to_cpu(hdr_nand->hsm20->page_size); ++ ++ case NAND_BOOT_SPIM_HEADER: ++ return le32_to_cpu(hdr_nand->spim->page_size); ++ ++ default: ++ return 2 * le16_to_cpu(hdr_nand->ap->pagesize); ++ } + } + + static int mtk_nand_header_ap_info(const void *ptr, +@@ -251,14 +542,45 @@ static int mtk_nand_header_ap_info(const + info->page_size = le16_to_cpu(nh->pagesize); + info->spare_size = le16_to_cpu(nh->oobsize); + info->gfh_offset = 2 * info->page_size; ++ info->snfi = true; + + return 0; + } + ++static int mtk_nand_header_hsm_info(const void *ptr, ++ struct nand_header_info *info) ++{ ++ union hsm_nand_boot_header *nh = (union hsm_nand_boot_header *)ptr; ++ ++ info->page_size = le16_to_cpu(nh->page_size); ++ info->spare_size = le16_to_cpu(nh->spare_size); ++ info->gfh_offset = info->page_size; ++ info->snfi = true; ++ ++ return 1; ++} ++ ++static int mtk_nand_header_spim_info(const void *ptr, ++ struct nand_header_info *info) ++{ ++ union spim_nand_boot_header *nh = (union spim_nand_boot_header *)ptr; ++ ++ info->page_size = le16_to_cpu(nh->page_size); ++ info->spare_size = le16_to_cpu(nh->spare_size); ++ info->gfh_offset = info->page_size; ++ info->snfi = false; ++ ++ return 1; ++} ++ + int mtk_nand_header_info(const void *ptr, struct nand_header_info *info) + { + if (!strcmp((char *)ptr, NAND_BOOT_NAME)) + return mtk_nand_header_ap_info(ptr, info); ++ else if (!strncmp((char *)ptr, HSM_NAND_BOOT_NAME, 8)) ++ return mtk_nand_header_hsm_info(ptr, info); ++ else if (!strncmp((char *)ptr, SPIM_NAND_BOOT_NAME, 8)) ++ return mtk_nand_header_spim_info(ptr, info); + + return -1; + } +@@ -273,14 +595,74 @@ bool is_mtk_nand_header(const void *ptr) + return false; + } + +-uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr) ++static uint16_t crc16(const uint8_t *p, uint32_t len) ++{ ++ uint16_t crc = 0x4f4e; ++ uint32_t i; ++ ++ while (len--) { ++ crc ^= *p++ << 8; ++ for (i = 0; i < 8; i++) ++ crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); ++ } ++ ++ return crc; ++} ++ ++static uint32_t mtk_nand_header_put_ap(const struct nand_header_type *hdr_nand, ++ void *ptr) + { +- union nand_boot_header *nh = (union nand_boot_header *)ptr; + int i; + + /* NAND device header, repeat 4 times */ +- for (i = 0; i < 4; i++) +- memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); ++ for (i = 0; i < 4; i++) { ++ memcpy(ptr, hdr_nand->ap, sizeof(*hdr_nand->ap)); ++ ptr += sizeof(*hdr_nand->ap); ++ } ++ ++ return le16_to_cpu(hdr_nand->ap->pagesize); ++} + +- return le16_to_cpu(hdr_nand->pagesize); ++static uint32_t mtk_nand_header_put_hsm(const struct nand_header_type *hdr_nand, ++ void *ptr) ++{ ++ memcpy(ptr, hdr_nand->hsm, sizeof(*hdr_nand->hsm)); ++ return 0; ++} ++ ++static uint32_t mtk_nand_header_put_hsm20(const struct nand_header_type *hdr_nand, ++ void *ptr) ++{ ++ memcpy(ptr, hdr_nand->hsm20, sizeof(*hdr_nand->hsm20)); ++ return 0; ++} ++ ++static uint32_t mtk_nand_header_put_spim(const struct nand_header_type *hdr_nand, ++ void *ptr) ++{ ++ uint16_t crc; ++ ++ memcpy(ptr, hdr_nand->spim, sizeof(*hdr_nand->spim)); ++ ++ crc = crc16(ptr, 0x4e); ++ memcpy(ptr + 0x4e, &crc, sizeof(uint16_t)); ++ ++ return 0; ++} ++ ++uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, void *ptr) ++{ ++ switch (hdr_nand->type) { ++ case NAND_BOOT_HSM_HEADER: ++ return mtk_nand_header_put_hsm(hdr_nand, ptr); ++ ++ case NAND_BOOT_HSM20_HEADER: ++ return mtk_nand_header_put_hsm20(hdr_nand, ptr); ++ ++ case NAND_BOOT_SPIM_HEADER: ++ return mtk_nand_header_put_spim(hdr_nand, ptr); ++ ++ default: ++ return mtk_nand_header_put_ap(hdr_nand, ptr); ++ } + } +--- a/tools/mtk_nand_headers.h ++++ b/tools/mtk_nand_headers.h +@@ -16,6 +16,7 @@ struct nand_header_info { + uint32_t page_size; + uint32_t spare_size; + uint32_t gfh_offset; ++ bool snfi; + }; + + /* AP BROM Header for NAND */ +@@ -39,15 +40,117 @@ union nand_boot_header { + uint8_t data[0x80]; + }; + ++/* HSM BROM Header for NAND */ ++union hsm_nand_boot_header { ++ struct { ++ char id[8]; ++ uint32_t version; /* Header version */ ++ uint32_t config; /* Header config */ ++ uint32_t sector_size; /* ECC step size */ ++ uint32_t fdm_size; /* User OOB size of a step */ ++ uint32_t fdm_ecc_size; /* ECC parity size of a step */ ++ uint32_t lbs; ++ uint32_t page_size; /* NAND page size */ ++ uint32_t spare_size; /* NAND page spare size */ ++ uint32_t page_per_block; /* Pages of one block */ ++ uint32_t blocks; /* Total blocks of NAND chip */ ++ uint32_t plane_sel_position; /* Plane bit position */ ++ uint32_t pll; /* Value of pll reg */ ++ uint32_t acccon; /* Value of access timing reg */ ++ uint32_t strobe_sel; /* Value of DQS selection reg*/ ++ uint32_t acccon1; /* Value of access timing reg */ ++ uint32_t dqs_mux; /* Value of DQS mux reg */ ++ uint32_t dqs_ctrl; /* Value of DQS control reg */ ++ uint32_t delay_ctrl; /* Value of delay ctrl reg */ ++ uint32_t latch_lat; /* Value of latch latency reg */ ++ uint32_t sample_delay; /* Value of sample delay reg */ ++ uint32_t driving; /* Value of driving reg */ ++ uint32_t bl_start; /* Bootloader start addr */ ++ uint32_t bl_end; /* Bootloader end addr */ ++ uint8_t ecc_parity[42]; /* ECC parity of this header */ ++ }; ++ ++ uint8_t data[0x8E]; ++}; ++ ++/* HSM2.0 BROM Header for NAND */ ++union hsm20_nand_boot_header { ++ struct { ++ char id[8]; ++ uint32_t version; /* Header version */ ++ uint32_t config; /* Header config */ ++ uint32_t sector_size; /* ECC step size */ ++ uint32_t fdm_size; /* User OOB size of a step */ ++ uint32_t fdm_ecc_size; /* ECC parity size of a step */ ++ uint32_t lbs; ++ uint32_t page_size; /* NAND page size */ ++ uint32_t spare_size; /* NAND page spare size */ ++ uint32_t page_per_block; /* Pages of one block */ ++ uint32_t blocks; /* Total blocks of NAND chip */ ++ uint32_t plane_sel_position; /* Plane bit position */ ++ uint32_t pll; /* Value of pll reg */ ++ uint32_t acccon; /* Value of access timing reg */ ++ uint32_t strobe_sel; /* Value of DQS selection reg*/ ++ uint32_t acccon1; /* Value of access timing reg */ ++ uint32_t dqs_mux; /* Value of DQS mux reg */ ++ uint32_t dqs_ctrl; /* Value of DQS control reg */ ++ uint32_t delay_ctrl; /* Value of delay ctrl reg */ ++ uint32_t latch_lat; /* Value of latch latency reg */ ++ uint32_t sample_delay; /* Value of sample delay reg */ ++ uint32_t driving; /* Value of driving reg */ ++ uint32_t reserved; ++ uint32_t bl0_start; /* Bootloader start addr */ ++ uint32_t bl0_end; /* Bootloader end addr */ ++ uint32_t bl0_type; /* Bootloader type */ ++ uint8_t bl_reserve[84]; ++ uint8_t ecc_parity[42]; /* ECC parity of this header */ ++ }; ++ ++ uint8_t data[0xEA]; ++}; ++ ++/* SPIM BROM Header for SPI-NAND */ ++union spim_nand_boot_header { ++ struct { ++ char id[8]; ++ uint32_t version; /* Header version */ ++ uint32_t config; /* Header config */ ++ uint32_t page_size; /* NAND page size */ ++ uint32_t spare_size; /* NAND page spare size */ ++ uint16_t page_per_block; /* Pages of one block */ ++ uint16_t plane_sel_position; /* Plane bit position */ ++ uint16_t reserve_reg; ++ uint16_t reserve_val; ++ uint16_t ecc_error; /* ECC error reg addr */ ++ uint16_t ecc_mask; /* ECC error bit mask */ ++ uint32_t bl_start; /* Bootloader start addr */ ++ uint32_t bl_end; /* Bootloader end addr */ ++ uint8_t ecc_parity[32]; /* ECC parity of this header */ ++ uint32_t integrity_crc; /* CRC of this header */ ++ }; ++ ++ uint8_t data[0x50]; ++}; ++ ++enum nand_boot_header_type { ++ NAND_BOOT_AP_HEADER, ++ NAND_BOOT_HSM_HEADER, ++ NAND_BOOT_HSM20_HEADER, ++ NAND_BOOT_SPIM_HEADER ++}; ++ + #define NAND_BOOT_NAME "BOOTLOADER!" + #define NAND_BOOT_VERSION "V006" + #define NAND_BOOT_ID "NFIINFO" + ++#define HSM_NAND_BOOT_NAME "NANDCFG!" ++#define SPIM_NAND_BOOT_NAME "SPINAND!" ++ + /* Find nand header data by name */ +-const union nand_boot_header *mtk_nand_header_find(const char *name); ++const struct nand_header_type *mtk_nand_header_find(const char *name); + + /* Device header size using this nand header */ +-uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand); ++uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand); + + /* Get nand info from nand header (page size, spare size, ...) */ + int mtk_nand_header_info(const void *ptr, struct nand_header_info *info); +@@ -56,6 +159,7 @@ int mtk_nand_header_info(const void *ptr + bool is_mtk_nand_header(const void *ptr); + + /* Generate Device header using give nand header */ +-uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr); ++uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, ++ void *ptr); + + #endif /* _MTK_NAND_HEADERS_H */ diff --git a/package/boot/uboot-mediatek/patches/002-0031-MAINTAINERS-update-maintainer-for-MediaTek-ARM-platf.patch b/package/boot/uboot-mediatek/patches/002-0031-MAINTAINERS-update-maintainer-for-MediaTek-ARM-platf.patch new file mode 100644 index 0000000000..227fa07527 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/002-0031-MAINTAINERS-update-maintainer-for-MediaTek-ARM-platf.patch @@ -0,0 +1,42 @@ +From ca90c165157c19af9bf46a69dcf719b8aab636b1 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Thu, 4 Aug 2022 09:50:40 +0800 +Subject: [PATCH 31/31] MAINTAINERS: update maintainer for MediaTek ARM + platform + +Add new files for MediaTek ARM platform + +Reviewed-by: Simon Glass +Signed-off-by: Weijie Gao +--- + MAINTAINERS | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -340,20 +340,25 @@ F: doc/device-tree-bindings/phy/phy-mtk- + F: doc/device-tree-bindings/usb/mediatek,* + F: doc/README.mediatek + F: drivers/clk/mediatek/ ++F: drivers/i2c/mtk_i2c.c + F: drivers/mmc/mtk-sd.c + F: drivers/phy/phy-mtk-* + F: drivers/pinctrl/mediatek/ + F: drivers/power/domain/mtk-power-domain.c + F: drivers/ram/mediatek/ + F: drivers/spi/mtk_snfi_spi.c ++F: drivers/spi/mtk_spim.c + F: drivers/timer/mtk_timer.c + F: drivers/usb/host/xhci-mtk.c + F: drivers/usb/mtu3/ + F: drivers/watchdog/mtk_wdt.c + F: drivers/net/mtk_eth.c ++F: drivers/net/mtk_eth.h + F: drivers/reset/reset-mediatek.c + F: tools/mtk_image.c + F: tools/mtk_image.h ++F: tools/mtk_nand_headers.c ++F: tools/mtk_nand_headers.h + N: mediatek + + ARM MICROCHIP/ATMEL AT91 diff --git a/package/boot/uboot-mediatek/patches/200-cmd-add-imsz-and-imszb.patch b/package/boot/uboot-mediatek/patches/200-cmd-add-imsz-and-imszb.patch index 1759b04899..9031e37f55 100644 --- a/package/boot/uboot-mediatek/patches/200-cmd-add-imsz-and-imszb.patch +++ b/package/boot/uboot-mediatek/patches/200-cmd-add-imsz-and-imszb.patch @@ -1,9 +1,10 @@ --- a/cmd/bootm.c +++ b/cmd/bootm.c -@@ -257,6 +257,65 @@ U_BOOT_CMD( +@@ -257,6 +257,67 @@ U_BOOT_CMD( /* iminfo - print header info for a requested image */ /*******************************************************************/ #if defined(CONFIG_CMD_IMI) ++#if defined(CONFIG_FIT) +#define SECTOR_SHIFT 9 +static int image_totalsize(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[], short int in_blocks) @@ -63,6 +64,7 @@ + "addr [maxhdrlen] [varname]\n" +); + ++#endif static int do_iminfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { diff --git a/package/boot/uboot-mediatek/patches/301-mt7622-generic-reset-button-ignore-env.patch b/package/boot/uboot-mediatek/patches/301-mt7622-generic-reset-button-ignore-env.patch index 43270a7a72..8630fc16ce 100644 --- a/package/boot/uboot-mediatek/patches/301-mt7622-generic-reset-button-ignore-env.patch +++ b/package/boot/uboot-mediatek/patches/301-mt7622-generic-reset-button-ignore-env.patch @@ -40,8 +40,8 @@ } --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig -@@ -115,4 +115,8 @@ config MTK_BROM_HEADER_INFO - default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183 +@@ -136,4 +136,8 @@ config MTK_BROM_HEADER_INFO + default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986 default "lk=1" if TARGET_MT7623 +config RESET_BUTTON_LABEL diff --git a/package/boot/uboot-mediatek/patches/410-add-linksys-e8450.patch b/package/boot/uboot-mediatek/patches/410-add-linksys-e8450.patch index 23a667a434..cbcd098c3b 100644 --- a/package/boot/uboot-mediatek/patches/410-add-linksys-e8450.patch +++ b/package/boot/uboot-mediatek/patches/410-add-linksys-e8450.patch @@ -342,7 +342,7 @@ + mt7622-linksys-e8450-ubi.dtb \ mt7623n-bananapi-bpi-r2.dtb \ mt7629-rfb.dtb \ - mt8183-pumpkin.dtb \ + mt7981-rfb.dtb \ --- /dev/null +++ b/linksys_e8450_env @@ -0,0 +1,57 @@ diff --git a/package/boot/uboot-mediatek/patches/412-add-ubnt-unifi-6-lr.patch b/package/boot/uboot-mediatek/patches/412-add-ubnt-unifi-6-lr.patch index 916ae93929..a30baf0074 100644 --- a/package/boot/uboot-mediatek/patches/412-add-ubnt-unifi-6-lr.patch +++ b/package/boot/uboot-mediatek/patches/412-add-ubnt-unifi-6-lr.patch @@ -342,7 +342,7 @@ + mt7622-ubnt-unifi-6-lr.dtb \ mt7623n-bananapi-bpi-r2.dtb \ mt7629-rfb.dtb \ - mt8183-pumpkin.dtb \ + mt7981-rfb.dtb \ --- /dev/null +++ b/ubnt_unifi-6-lr_env @@ -0,0 +1,50 @@ -- cgit v1.2.3