]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
kernel/mediatek: restore files for v6.12
authorDaniel Golle <daniel@makrotopia.org>
Fri, 10 Apr 2026 13:03:10 +0000 (14:03 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Fri, 17 Apr 2026 13:37:52 +0000 (14:37 +0100)
This is an automatically generated commit which aids following Kernel patch
history, as git will see the move and copy as a rename thus defeating the
purpose.

For the original discussion see:
https://lists.openwrt.org/pipermail/openwrt-devel/2023-October/041673.html

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
175 files changed:
target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-eth1.dtso [new file with mode: 0644]
target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-swp5.dtso [new file with mode: 0644]
target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso [new file with mode: 0644]
target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts [new file with mode: 0644]
target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts [new file with mode: 0644]
target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts [new file with mode: 0644]
target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dtsi [new file with mode: 0644]
target/linux/mediatek/files-6.12/drivers/mfd/airoha-an8855.c [new file with mode: 0644]
target/linux/mediatek/files-6.12/drivers/net/dsa/an8855.c [new file with mode: 0644]
target/linux/mediatek/files-6.12/drivers/net/dsa/an8855.h [new file with mode: 0644]
target/linux/mediatek/files-6.12/drivers/net/mdio/mdio-an8855.c [new file with mode: 0644]
target/linux/mediatek/files-6.12/drivers/net/phy/air_an8855.c [new file with mode: 0644]
target/linux/mediatek/files-6.12/drivers/nvmem/an8855-efuse.c [new file with mode: 0644]
target/linux/mediatek/files-6.12/include/linux/mfd/airoha-an8855-mfd.h [new file with mode: 0644]
target/linux/mediatek/filogic/config-6.12 [new file with mode: 0644]
target/linux/mediatek/mt7622/config-6.12 [new file with mode: 0644]
target/linux/mediatek/mt7623/config-6.12 [new file with mode: 0644]
target/linux/mediatek/mt7629/config-6.12 [new file with mode: 0644]
target/linux/mediatek/patches-6.12/010-v6.14-pinctrl-mediatek-add-support-for-MTK_PULL_PD_TYPE.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/011-v6.14-pinctrl-mediatek-add-MT7988-pinctrl-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/012-v6.14-pinctrl-mediatek-Drop-mtk_pinconf_bias_set_pd.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/020-v6.13-arm64-dts-mediatek-mt7988-add-UART-controllers.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/021-v6.13-arm64-dts-mediatek-mt7988-add-efuse-block.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/022-v6.14-arm64-dts-mediatek-mt7988-Add-pinctrl-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/023-v6.14-arm64-dts-mediatek-mt7988-Add-reserved-memory.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/024-v6.14-arm64-dts-mediatek-mt7988-Add-mmc-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/025-v6.14-arm64-dts-mediatek-mt7988-Add-lvts-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/026-v6.14-arm64-dts-mediatek-mt7988-Add-thermal-zone.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/027-v6.14-arm64-dts-mediatek-mt7988-Add-mcu-sys-node-for-cpu.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/028-v6.14-arm64-dts-mediatek-mt7988-Add-CPU-OPP-table-for-cloc.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/029-v6.14-arm64-dts-mediatek-mt7988-Disable-usb-controllers-by.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/030-v6.14-arm64-dts-mediatek-mt7988-Add-t-phy-for-ssusb1.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/031-v6.14-arm64-dts-mediatek-mt7988-Add-pcie-nodes.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/032-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-pinctrl-subnod.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/033-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-watchdog.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/034-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-fixed-regulato.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/035-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-thermal-config.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/036-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-serial0-deb.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/037-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-default-UART-s.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/038-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-I2C-control.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/039-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-PCA9545-I2C-Mu.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/040-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-t-phy-for-s.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/041-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-ssusb1-on-b.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/042-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-pwm.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/043-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-pcie.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/044-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-MediaTek-MT668.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/045-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-proc-supply-fo.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/050-v6.16-phy-mediatek-xsphy-support-type-switch-by-pericfg.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/051-v6.16-hwrng-mtk-Add-struct-device-pointer-to-device-contex.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/060-v6.13-mmc-mtk-sd-add-support-for-mt7988.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/061-v6.19-arm64-dts-mediatek-mt7986-bpi-r3-Change-fan-PWM-valu.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/062-v6.18-arm64-dts-mediatek-add-thermal-sensor-support-on-mt7.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/070-v7.0-pinctrl-mediatek-enable-ies_present-flag-for-MT798x.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/100-dts-update-mt7622-rfb1.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/101-dts-update-mt7629-rfb.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/103-mt7623-enable-arch-timer.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/104-mt7622-add-snor-irq.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/105-dts-mt7622-enable-pstore.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/106-dts-mt7622-disable_btif.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/110-dts-fix-bpi2-console.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/111-dts-fix-bpi64-console.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/112-dts-fix-bpi64-lan-names.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/113-dts-fix-bpi64-leds-and-buttons.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/114-dts-bpi64-disable-rtc.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/115-Revert-arm64-dts-mediatek-fix-t-phy-unit-name.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/116-arm64-dts-mediatek-mt7622-readd-syscon-to-pciesys-no.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/117-complete-mt7981b-dtsi.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/119-pinctrl-mediatek-MT7981-some-register-map-fixes.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/121-hack-spi-nand-1b-bbm.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/130-dts-mt7629-add-snand-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/131-dts-mt7622-add-snand-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/140-dts-fix-wmac-support-for-mt7622-rfb1.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/150-dts-mt7623-eip97-inside-secure-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/160-dts-mt7623-bpi-r2-earlycon.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/161-dts-mt7623-bpi-r2-mmc-device-order.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/162-dts-mt7623-bpi-r2-led-aliases.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/163-dts-mt7623-bpi-r2-ethernet-alias.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/164-dts-mt7623-bpi-r2-rootdisk-for-fitblk.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/170-arm64-dts-mediatek-mt7988a-bpi-r4-allow-hw-variants-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/171-v6.16-arm64-dts-mediatek-mt7988-Add-xsphy-for-ssusb0-pcie2.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/172-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-enable-xsphy.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/173-dts-mt7988a-Add-built-in-ethernet-phy-firmware-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/174-v6.16-arm64-dts-mediatek-mt7988-add-spi-controllers.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/175-v6.16-arm64-dts-mediatek-mt7988-move-uart0-and-spi1-pins-t.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/176-v6.17-arm64-dts-mediatek-mt7988-add-cci-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/177-v6.16-arm64-dts-mediatek-mt7988-add-phy-calibration-efuse-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/178-arm64-dts-mediatek-mt7988-add-basic-ethernet-nodes.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/179-arm64-dts-mediatek-mt7988-add-switch-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/180-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-Add-fan-and-coolin.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/181-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-configure-spi-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/182-v6.17-arm64-dts-mediatek-mt7988a-bpi-r4-add-proc-supply-fo.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/183-arm64-dts-mediatek-mt7988a-bpi-r4-add-sfp-cages-and-link-to-gmac.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/184-arm64-dts-mediatek-mt7988a-bpi-r4-configure-switch-phys-and-leds.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/185-arm64-dts-mt7988a-add-serial1-and-serial2-aliases.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/186-arm64-dts-mt7988a-complete-dtsi.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/187-arm64-dts-mediatek-fix-mt7981-spim-clock.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/188-arm64-dts-mediatek-add-MT7988A-reference-board-devic.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/189-arm64-dts-mediatek-mt7988a-complete-bpi-r4.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/190-arm64-dts-mediatek-mt7622-fix-GICv2-range.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/193-dts-mt7623-thermal_zone_fix.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/194-dts-mt7968a-add-ramoops.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/195-dts-mt7986a-bpi-r3-leds-port-names-and-wifi-eeprom.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/196-dts-mt7986a-bpi-r3-use-all-ubi-nand-layout.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/198-dts-mt7988a-enable-wed.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/199-arm64-dts-mediatek-mt7986-increase-ATF-reserved-memo.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/200-phy-phy-mtk-tphy-Add-hifsys-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/210-PM-devfreq-mtk-cci-use-devres-for-resource-managemen.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/211-PM-devfreq-mtk-cci-check-cpufreq-availability-early.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/255-clk-mediatek-mt7988-infracfg-SPI0-clocks-are-not-critical.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/320-hwrng-mtk-add-support-for-hw-access-via-SMCC.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/330-snand-mtk-bmt-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/331-mt7622-rfb1-enable-bmt.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/360-pinctrl-mediatek-add-mt7987-pinctrl-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/361-clk-mediatek-add-mt7987-clock-drivers-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/400-crypto-add-eip97-inside-secure-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/401-crypto-fix-eip97-cache-incoherent.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/410-bt-mtk-serial-fix.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/411-mtd-spinand-fix-support-for-FORESEE.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/431-drivers-spi-mt65xx-Move-chip_config-to-driver-s-priv.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/432-drivers-spi-Add-support-for-dynamic-calibration.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/433-drivers-spi-mem-Add-spi-calibration-hook.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/434-drivers-spi-mt65xx-Add-controller-s-calibration-para.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/450-nvmem-add-layout-for-Adtran-devices.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/500-gsw-rtl8367s-mt7622-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/610-pcie-mediatek-fix-clearing-interrupt-status.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/611-pcie-mediatek-gen3-PERST-for-100ms.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/700-net-phy-mediatek-Add-2.5Gphy-firmware-dt-bindings-an.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/701-net-phy-mediatek-add-driver-for-built-in-2.5G-ethern.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/721-dts-mt7622-mediatek-fix-300mhz.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/722-remove-300Hz-to-prevent-freeze.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/734-net-phy-add-Airoha-EN8801SC-PHY.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/736-net-pcs-mtk_usxgmii-add-polarity-control.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/737-net-dsa-add-Airoha-AN8855.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/740-net-pcs-mtk_lynxi-add-mt7987-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/741-net-pcs-mtk-lynxi-add-phya-tx-rx-clock-path.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/750-net-ethernet-mtk_eth_soc-add-mt7987-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/751-net-ethernet-mtk_eth_soc-revise-hardware-configuration-for-mt7987.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/752-net-phy-mediatek-i2p5g-add-support-for-mt7987.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/821-add-pwm-feature-for-mt7987.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/830-thermal-drivers-mediatek-lvts_thermal-Add-irq_enable-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/831-thermal-drivers-mediatek-lvts_thermal-Add-MT7987-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/840-cpufreq-add-support-to-adjust-cpu-volt-by-efuse-cali.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/841-cpufreq-add-cpu-volt-correction-support-for-mt7988.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/842-mediatek-enable-using-efuse-cali-data-for-mt7988-cpu-volt.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/843-cpufreq-add-support-to-fix-voltage-cpu.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/844-cpufreq-mediatek-Add-support-for-MT7987.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/862-arm64-dts-mt7986-add-afe.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/863-arm64-dts-mt7986-add-sound-wm8960.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/864-arm64-dts-mt7986-add-sound-overlay-for-bpi-r3.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/901-arm-add-cmdline-override.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/910-dts-mt7622-bpi-r64-wifi-eeprom.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/911-dts-mt7622-bpi-r64-add-rootdisk.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/911-dts-mt7988a-bpi-r4-be14-wifi-eeprom.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/920-block-partitions-msdos-add-OF-node-by-partition-numb.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/930-spi-mt65xx-enable-sel-clk.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/940-net-ethernet-mtk_wed-rename-mtk_wed_get_memory_regio.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/941-arm64-dts-mt7986-move-cpuboot-in-a-dedicated-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/942-net-ethernet-mtk_wed-move-cpuboot-in-a-dedicated-dts.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/943-net-ethernet-mtk_wed-move-ilm-a-dedicated-dts-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/945-arm64-dts-mt7986-move-ilm-in-a-dedicated-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/946-arm64-dts-mt7986-move-dlm-in-a-dedicated-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/950-smartrg-i2c-led-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/955-dts-mt7968a-bpi-r3-add-label-to-gmac-for-sfp1-port.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/960-asus-hack-u-boot-ignore-mtdparts.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.12/966-pcie-mediatek-gen3-Add-WIFI-HW-reset-flow.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.18/965-dts-mt7988a-add-trng-support.patch

diff --git a/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-eth1.dtso b/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-eth1.dtso
new file mode 100644 (file)
index 0000000..51d5dc6
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
+
+       fragment@0 {
+               target = <&gmac1>;
+               __overlay__ {
+                       phy-mode = "2500base-x";
+                       phy-handle = <&phy5>;
+               };
+       };
+
+       fragment@1 {
+               target = <&mdio_bus>;
+               __overlay__ {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reset-gpios = <&pio 14 GPIO_ACTIVE_LOW>;
+                       reset-delay-us = <600>;
+                       reset-post-delay-us = <20000>;
+
+                       phy5: ethernet-phy@5 {
+                               reg = <5>;
+                               compatible = "ethernet-phy-ieee802.3-c45";
+                               phy-mode = "2500base-x";
+                       };
+               };
+       };
+};
diff --git a/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-swp5.dtso b/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-mxl-2p5g-phy-swp5.dtso
new file mode 100644 (file)
index 0000000..4cc3cf1
--- /dev/null
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
+
+       fragment@0 {
+               target = <&sw_p5>;
+               __overlay__ {
+                       phy-mode = "2500base-x";
+                       phy-handle = <&phy5>;
+                       status = "okay";
+               };
+       };
+
+       fragment@1 {
+               target = <&mdio_bus>;
+               __overlay__ {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reset-gpios = <&pio 14 GPIO_ACTIVE_LOW>;
+                       reset-delay-us = <600>;
+                       reset-post-delay-us = <20000>;
+
+                       phy5: ethernet-phy@5 {
+                               reg = <5>;
+                               compatible = "ethernet-phy-ieee802.3-c45";
+                               phy-mode = "2500base-x";
+                       };
+               };
+       };
+};
diff --git a/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso b/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso
new file mode 100644 (file)
index 0000000..7e731cd
--- /dev/null
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/dts-v1/;
+/plugin/;
+
+/ {
+       compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
+
+       fragment@0 {
+               target = <&chosen>;
+               rootdisk-spim-nand = <&ubi_rootdisk>;
+       };
+
+       fragment@1 {
+               target = <&spi0>;
+               __overlay__ {
+                       status = "okay";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       spi_nand: spi_nand@1 {
+                               compatible = "spi-nand";
+                               reg = <1>;
+                               spi-max-frequency = <10000000>;
+                               spi-tx-bus-width = <4>;
+                               spi-rx-bus-width = <4>;
+
+                               partitions {
+                                       compatible = "fixed-partitions";
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+
+                                       partition@0 {
+                                               label = "BL2";
+                                               reg = <0x00000 0x0100000>;
+                                               read-only;
+                                       };
+
+                                       partition@100000 {
+                                               label = "u-boot-env";
+                                               reg = <0x0100000 0x0080000>;
+                                       };
+
+                                       factory: partition@180000 {
+                                               label = "Factory";
+                                               reg = <0x180000 0x0200000>;
+                                       };
+
+                                       partition@380000 {
+                                               label = "FIP";
+                                               reg = <0x380000 0x0200000>;
+                                       };
+
+                                       partition@580000 {
+                                               label = "ubi";
+                                               reg = <0x580000 0x4000000>;
+                                               compatible = "linux,ubi";
+
+                                               volumes {
+                                                       ubi_rootdisk: ubi-volume-fit {
+                                                               volname = "fit";
+                                                       };
+                                               };
+                                       };
+                               };
+                       };
+               };
+       };
+
+       fragment@2 {
+               target = <&wifi>;
+               __overlay__ {
+                       mediatek,mtd-eeprom = <&factory 0x0>;
+                       status = "okay";
+               };
+       };
+};
diff --git a/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts b/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts
new file mode 100644 (file)
index 0000000..1551577
--- /dev/null
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981b.dtsi"
+
+/ {
+       model = "MediaTek MT7981 RFB";
+       compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen: chosen {
+               stdout-path = "serial0:115200n8";
+               bootargs-append = " root=/dev/fit0 rootwait";
+       };
+
+       memory@40000000 {
+               reg = <0 0x40000000 0 0x20000000>;
+               device_type = "memory";
+       };
+
+       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;
+       };
+
+       reg_5v: regulator-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               reset {
+                       label = "reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+               };
+               wps {
+                       label = "wps";
+                       linux,code = <KEY_WPS_BUTTON>;
+                       gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
+               };
+       };
+};
+
+&eth {
+       status = "okay";
+
+       gmac0: mac@0 {
+               compatible = "mediatek,eth-mac";
+               reg = <0>;
+               phy-mode = "2500base-x";
+
+               fixed-link {
+                       speed = <2500>;
+                       full-duplex;
+                       pause;
+               };
+       };
+
+       gmac1: mac@1 {
+               compatible = "mediatek,eth-mac";
+               reg = <1>;
+               phy-mode = "gmii";
+               phy-handle = <&int_gbe_phy>;
+       };
+};
+
+&mdio_bus {
+       switch: switch@1f {
+               compatible = "mediatek,mt7531";
+               reg = <31>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               interrupt-parent = <&pio>;
+               interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+               reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&crypto {
+       status = "okay";
+};
+
+&pio {
+       spi0_flash_pins: spi0-pins {
+               mux {
+                       function = "spi";
+                       groups = "spi0", "spi0_wp_hold";
+               };
+               conf-pu {
+                       pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+                       drive-strength = <MTK_DRIVE_8mA>;
+                       bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+               };
+               conf-pd {
+                       pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
+                       drive-strength = <MTK_DRIVE_8mA>;
+                       bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+               };
+       };
+
+};
+
+&spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi0_flash_pins>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "disabled";
+};
+
+&switch {
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+                       label = "lan1";
+               };
+
+               port@1 {
+                       reg = <1>;
+                       label = "lan2";
+               };
+
+               port@2 {
+                       reg = <2>;
+                       label = "lan3";
+               };
+
+               port@3 {
+                       reg = <3>;
+                       label = "lan4";
+               };
+
+               sw_p5: port@5 {
+                       reg = <5>;
+                       label = "lan5";
+                       status = "disabled";
+               };
+
+               port@6 {
+                       reg = <6>;
+                       ethernet = <&gmac0>;
+                       phy-mode = "2500base-x";
+
+                       fixed-link {
+                               speed = <2500>;
+                               full-duplex;
+                               pause;
+                       };
+               };
+       };
+};
+
+&xhci {
+       vusb33-supply = <&reg_3p3v>;
+       vbus-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&usb_phy {
+       status = "okay";
+};
+
+&watchdog {
+       status = "okay";
+};
diff --git a/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts b/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts
new file mode 100644 (file)
index 0000000..79a6df7
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+
+#include "mt7986a-rfb.dtsi"
+
+/ {
+       compatible = "mediatek,mt7986a-rfb-snand";
+};
+
+&spi0 {
+       status = "okay";
+
+       spi_nand: spi_nand@1 {
+               compatible = "spi-nand";
+               reg = <1>;
+               spi-max-frequency = <10000000>;
+               spi-tx-bus-width = <4>;
+               spi-rx-bus-width = <4>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       partition@0 {
+                               label = "BL2";
+                               reg = <0x00000 0x0100000>;
+                               read-only;
+                       };
+                       partition@100000 {
+                               label = "u-boot-env";
+                               reg = <0x0100000 0x0080000>;
+                       };
+                       factory: partition@180000 {
+                               label = "Factory";
+                               reg = <0x180000 0x0200000>;
+                       };
+                       partition@380000 {
+                               label = "FIP";
+                               reg = <0x380000 0x0200000>;
+                       };
+                       partition@580000 {
+                               label = "ubi";
+                               reg = <0x580000 0x4000000>;
+                       };
+               };
+       };
+};
+
+&wifi {
+       mediatek,mtd-eeprom = <&factory 0>;
+};
diff --git a/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts b/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts
new file mode 100644 (file)
index 0000000..009d2e1
--- /dev/null
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+
+#include "mt7986a-rfb.dtsi"
+
+/ {
+       compatible = "mediatek,mt7986a-rfb-snor";
+};
+
+&spi0 {
+       status = "okay";
+
+       spi_nor: spi_nor@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <52000000>;
+               spi-tx-bus-width = <4>;
+               spi-rx-bus-width = <4>;
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@00000 {
+                               label = "BL2";
+                               reg = <0x00000 0x0040000>;
+                       };
+                       partition@40000 {
+                               label = "u-boot-env";
+                               reg = <0x40000 0x0010000>;
+                       };
+                       factory: partition@50000 {
+                               label = "Factory";
+                               reg = <0x50000 0x00B0000>;
+                       };
+                       partition@100000 {
+                               label = "FIP";
+                               reg = <0x100000 0x0080000>;
+                       };
+                       partition@180000 {
+                               label = "firmware";
+                               reg = <0x180000 0xE00000>;
+                       };
+               };
+       };
+};
+
+&wifi {
+       mediatek,mtd-eeprom = <&factory 0>;
+};
diff --git a/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dtsi b/target/linux/mediatek/files-6.12/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dtsi
new file mode 100644 (file)
index 0000000..1dfb64d
--- /dev/null
@@ -0,0 +1,391 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+#include "mt7986a.dtsi"
+
+/ {
+       model = "MediaTek MT7986a RFB";
+       compatible = "mediatek,mt7986a-rfb";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@40000000 {
+               reg = <0 0x40000000 0 0x40000000>;
+               device_type = "memory";
+       };
+
+       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;
+       };
+
+       reg_5v: regulator-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&eth {
+       status = "okay";
+
+       gmac0: mac@0 {
+               compatible = "mediatek,eth-mac";
+               reg = <0>;
+               phy-mode = "2500base-x";
+
+               fixed-link {
+                       speed = <2500>;
+                       full-duplex;
+                       pause;
+               };
+       };
+
+       gmac1: mac@1 {
+               compatible = "mediatek,eth-mac";
+               reg = <1>;
+               phy-mode = "2500base-x";
+       };
+
+       mdio: mdio-bus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
+
+&wifi {
+       status = "okay";
+       pinctrl-names = "default", "dbdc";
+       pinctrl-0 = <&wf_2g_5g_pins>;
+       pinctrl-1 = <&wf_dbdc_pins>;
+};
+
+&mdio {
+       phy5: phy@5 {
+               compatible = "ethernet-phy-id67c9.de0a";
+               reg = <5>;
+
+               reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>;
+               reset-deassert-us = <20000>;
+       };
+
+       phy6: phy@6 {
+               compatible = "ethernet-phy-id67c9.de0a";
+               reg = <6>;
+       };
+
+       switch: switch@1f {
+               compatible = "mediatek,mt7531";
+               reg = <31>;
+               reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&crypto {
+       status = "okay";
+};
+
+&mmc0 {
+       pinctrl-names = "default", "state_uhs";
+       pinctrl-0 = <&mmc0_pins_default>;
+       pinctrl-1 = <&mmc0_pins_uhs>;
+       bus-width = <8>;
+       max-frequency = <200000000>;
+       cap-mmc-highspeed;
+       mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
+       hs400-ds-delay = <0x14014>;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_1p8v>;
+       non-removable;
+       no-sd;
+       no-sdio;
+       status = "okay";
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_pins>;
+       status = "okay";
+};
+
+&pcie_phy {
+       status = "okay";
+};
+
+&pio {
+       mmc0_pins_default: mmc0-pins {
+               mux {
+                       function = "emmc";
+                       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 = <MTK_DRIVE_4mA>;
+                       bias-pull-up = <MTK_PUPD_SET_R1R0_01>;  /* pull-up 10K */
+               };
+               conf-clk {
+                       pins = "EMMC_CK";
+                       drive-strength = <MTK_DRIVE_6mA>;
+                       bias-pull-down = <MTK_PUPD_SET_R1R0_10>;        /* pull-down 50K */
+               };
+               conf-ds {
+                       pins = "EMMC_DSL";
+                       bias-pull-down = <MTK_PUPD_SET_R1R0_10>;        /* pull-down 50K */
+               };
+               conf-rst {
+                       pins = "EMMC_RSTB";
+                       drive-strength = <MTK_DRIVE_4mA>;
+                       bias-pull-up = <MTK_PUPD_SET_R1R0_01>;  /* pull-up 10K */
+               };
+       };
+
+       mmc0_pins_uhs: mmc0-uhs-pins {
+               mux {
+                       function = "emmc";
+                       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 = <MTK_DRIVE_4mA>;
+                       bias-pull-up = <MTK_PUPD_SET_R1R0_01>;  /* pull-up 10K */
+               };
+               conf-clk {
+                       pins = "EMMC_CK";
+                       drive-strength = <MTK_DRIVE_6mA>;
+                       bias-pull-down = <MTK_PUPD_SET_R1R0_10>;        /* pull-down 50K */
+               };
+               conf-ds {
+                       pins = "EMMC_DSL";
+                       bias-pull-down = <MTK_PUPD_SET_R1R0_10>;        /* pull-down 50K */
+               };
+               conf-rst {
+                       pins = "EMMC_RSTB";
+                       drive-strength = <MTK_DRIVE_4mA>;
+                       bias-pull-up = <MTK_PUPD_SET_R1R0_01>;  /* pull-up 10K */
+               };
+       };
+
+       pcie_pins: pcie-pins {
+               mux {
+                       function = "pcie";
+                       groups = "pcie_clk", "pcie_wake", "pcie_pereset";
+               };
+       };
+
+       spic_pins_g2: spic-pins-29-to-32 {
+               mux {
+                       function = "spi";
+                       groups = "spi1_2";
+               };
+       };
+
+       spi_flash_pins: spi-flash-pins-33-to-38 {
+               mux {
+                       function = "spi";
+                       groups = "spi0", "spi0_wp_hold";
+               };
+               conf-pu {
+                       pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+                       drive-strength = <MTK_DRIVE_8mA>;
+                       bias-disable;   /* bias-disable */
+               };
+               conf-pd {
+                       pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+                       drive-strength = <MTK_DRIVE_8mA>;
+                       bias-disable;   /* bias-disable */
+               };
+       };
+
+       uart1_pins: uart1-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart1";
+               };
+       };
+
+       uart2_pins: uart2-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart2";
+               };
+       };
+
+       wf_2g_5g_pins: wf_2g_5g-pins {
+               mux {
+                       function = "wifi";
+                       groups = "wf_2g", "wf_5g";
+               };
+               conf {
+                       pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+                              "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+                              "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+                              "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+                              "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+                              "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+                              "WF1_TOP_CLK", "WF1_TOP_DATA";
+                       drive-strength = <MTK_DRIVE_4mA>;
+               };
+       };
+
+       wf_dbdc_pins: wf_dbdc-pins {
+               mux {
+                       function = "wifi";
+                       groups = "wf_dbdc";
+               };
+               conf {
+                       pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+                              "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+                              "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+                              "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+                              "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+                              "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+                              "WF1_TOP_CLK", "WF1_TOP_DATA";
+                       drive-strength = <MTK_DRIVE_4mA>;
+               };
+       };
+};
+
+&spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_flash_pins>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "disabled";
+};
+
+&spi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spic_pins_g2>;
+       status = "okay";
+
+       proslic_spi: proslic_spi@0 {
+               compatible = "silabs,proslic_spi";
+               reg = <0>;
+               spi-max-frequency = <10000000>;
+               spi-cpha = <1>;
+               spi-cpol = <1>;
+               channel_count = <1>;
+               debug_level = <4>;       /* 1 = TRC, 2 = DBG, 4 = ERR */
+               reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
+               ig,enable-spi = <1>;     /* 1: Enable, 0: Disable */
+       };
+};
+
+&gmac1 {
+       phy-mode = "2500base-x";
+       phy-connection-type = "2500base-x";
+       phy-handle = <&phy6>;
+};
+
+&switch {
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+                       label = "lan1";
+               };
+
+               port@1 {
+                       reg = <1>;
+                       label = "lan2";
+               };
+
+               port@2 {
+                       reg = <2>;
+                       label = "lan3";
+               };
+
+               port@3 {
+                       reg = <3>;
+                       label = "lan4";
+               };
+
+               port@4 {
+                       reg = <4>;
+                       label = "wan";
+               };
+
+               port@5 {
+                       reg = <5>;
+                       label = "lan6";
+
+                       phy-mode = "2500base-x";
+                       phy-handle = <&phy5>;
+               };
+
+               port@6 {
+                       reg = <6>;
+                       ethernet = <&gmac0>;
+                       phy-mode = "2500base-x";
+
+                       fixed-link {
+                               speed = <2500>;
+                               full-duplex;
+                               pause;
+                       };
+               };
+       };
+};
+
+&ssusb {
+       vusb33-supply = <&reg_3p3v>;
+       vbus-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "okay";
+};
+
+&usb_phy {
+       status = "okay";
+};
diff --git a/target/linux/mediatek/files-6.12/drivers/mfd/airoha-an8855.c b/target/linux/mediatek/files-6.12/drivers/mfd/airoha-an8855.c
new file mode 100644 (file)
index 0000000..eeaea34
--- /dev/null
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MFD driver for Airoha AN8855 Switch
+ */
+
+#include <linux/mfd/airoha-an8855-mfd.h>
+#include <linux/mfd/core.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell an8855_mfd_devs[] = {
+       {
+               .name = "an8855-efuse",
+               .of_compatible = "airoha,an8855-efuse",
+       }, {
+               .name = "an8855-switch",
+               .of_compatible = "airoha,an8855-switch",
+       }, {
+               .name = "an8855-mdio",
+               .of_compatible = "airoha,an8855-mdio",
+       }
+};
+
+int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
+                       u8 page) __must_hold(&priv->bus->mdio_lock)
+{
+       struct mii_bus *bus = priv->bus;
+       int ret;
+
+       ret = __mdiobus_write(bus, phy_id, AN8855_PHY_SELECT_PAGE, page);
+       if (ret < 0)
+               dev_err_ratelimited(&bus->dev,
+                                   "failed to set an8855 mii page\n");
+
+       /* Cache current page if next mii read/write is for switch */
+       priv->current_page = page;
+       return ret < 0 ? ret : 0;
+}
+EXPORT_SYMBOL_GPL(an8855_mii_set_page);
+
+static int an8855_mii_read32(struct mii_bus *bus, u8 phy_id, u32 reg,
+                            u32 *val) __must_hold(&bus->mdio_lock)
+{
+       int lo, hi, ret;
+
+       ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE,
+                             AN8855_PBUS_MODE_ADDR_FIXED);
+       if (ret < 0)
+               goto err;
+
+       ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_HIGH,
+                             upper_16_bits(reg));
+       if (ret < 0)
+               goto err;
+       ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_RD_ADDR_LOW,
+                             lower_16_bits(reg));
+       if (ret < 0)
+               goto err;
+
+       hi = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_HIGH);
+       if (hi < 0) {
+               ret = hi;
+               goto err;
+       }
+       lo = __mdiobus_read(bus, phy_id, AN8855_PBUS_RD_DATA_LOW);
+       if (lo < 0) {
+               ret = lo;
+               goto err;
+       }
+
+       *val = ((u16)hi << 16) | ((u16)lo & 0xffff);
+
+       return 0;
+err:
+       dev_err_ratelimited(&bus->dev,
+                           "failed to read an8855 register\n");
+       return ret;
+}
+
+static int an8855_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
+{
+       struct an8855_mfd_priv *priv = ctx;
+       struct mii_bus *bus = priv->bus;
+       u16 addr = priv->switch_addr;
+       int ret;
+
+       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+       ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+       if (ret < 0)
+               goto exit;
+
+       ret = an8855_mii_read32(bus, addr, reg, val);
+
+exit:
+       mutex_unlock(&bus->mdio_lock);
+
+       return ret < 0 ? ret : 0;
+}
+
+static int an8855_mii_write32(struct mii_bus *bus, u8 phy_id, u32 reg,
+                             u32 val) __must_hold(&bus->mdio_lock)
+{
+       int ret;
+
+       ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_MODE,
+                             AN8855_PBUS_MODE_ADDR_FIXED);
+       if (ret < 0)
+               goto err;
+
+       ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_HIGH,
+                             upper_16_bits(reg));
+       if (ret < 0)
+               goto err;
+       ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_ADDR_LOW,
+                             lower_16_bits(reg));
+       if (ret < 0)
+               goto err;
+
+       ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_HIGH,
+                             upper_16_bits(val));
+       if (ret < 0)
+               goto err;
+       ret = __mdiobus_write(bus, phy_id, AN8855_PBUS_WR_DATA_LOW,
+                             lower_16_bits(val));
+       if (ret < 0)
+               goto err;
+
+       return 0;
+err:
+       dev_err_ratelimited(&bus->dev,
+                           "failed to write an8855 register\n");
+       return ret;
+}
+
+static int
+an8855_regmap_write(void *ctx, uint32_t reg, uint32_t val)
+{
+       struct an8855_mfd_priv *priv = ctx;
+       struct mii_bus *bus = priv->bus;
+       u16 addr = priv->switch_addr;
+       int ret;
+
+       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+       ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+       if (ret < 0)
+               goto exit;
+
+       ret = an8855_mii_write32(bus, addr, reg, val);
+
+exit:
+       mutex_unlock(&bus->mdio_lock);
+
+       return ret < 0 ? ret : 0;
+}
+
+static int an8855_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask,
+                                    uint32_t write_val)
+{
+       struct an8855_mfd_priv *priv = ctx;
+       struct mii_bus *bus = priv->bus;
+       u16 addr = priv->switch_addr;
+       u32 val;
+       int ret;
+
+       mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+       ret = an8855_mii_set_page(priv, addr, AN8855_PHY_PAGE_EXTENDED_4);
+       if (ret < 0)
+               goto exit;
+
+       ret = an8855_mii_read32(bus, addr, reg, &val);
+       if (ret < 0)
+               goto exit;
+
+       val &= ~mask;
+       val |= write_val;
+       ret = an8855_mii_write32(bus, addr, reg, val);
+
+exit:
+       mutex_unlock(&bus->mdio_lock);
+
+       return ret < 0 ? ret : 0;
+}
+
+static const struct regmap_range an8855_readable_ranges[] = {
+       regmap_reg_range(0x10000000, 0x10000fff), /* SCU */
+       regmap_reg_range(0x10001000, 0x10001fff), /* RBUS */
+       regmap_reg_range(0x10002000, 0x10002fff), /* MCU */
+       regmap_reg_range(0x10005000, 0x10005fff), /* SYS SCU */
+       regmap_reg_range(0x10007000, 0x10007fff), /* I2C Slave */
+       regmap_reg_range(0x10008000, 0x10008fff), /* I2C Master */
+       regmap_reg_range(0x10009000, 0x10009fff), /* PDMA */
+       regmap_reg_range(0x1000a100, 0x1000a2ff), /* General Purpose Timer */
+       regmap_reg_range(0x1000a200, 0x1000a2ff), /* GPU timer */
+       regmap_reg_range(0x1000a300, 0x1000a3ff), /* GPIO */
+       regmap_reg_range(0x1000a400, 0x1000a5ff), /* EFUSE */
+       regmap_reg_range(0x1000c000, 0x1000cfff), /* GDMP CSR */
+       regmap_reg_range(0x10010000, 0x1001ffff), /* GDMP SRAM */
+       regmap_reg_range(0x10200000, 0x10203fff), /* Switch - ARL Global */
+       regmap_reg_range(0x10204000, 0x10207fff), /* Switch - BMU */
+       regmap_reg_range(0x10208000, 0x1020bfff), /* Switch - ARL Port */
+       regmap_reg_range(0x1020c000, 0x1020cfff), /* Switch - SCH */
+       regmap_reg_range(0x10210000, 0x10213fff), /* Switch - MAC */
+       regmap_reg_range(0x10214000, 0x10217fff), /* Switch - MIB */
+       regmap_reg_range(0x10218000, 0x1021bfff), /* Switch - Port Control */
+       regmap_reg_range(0x1021c000, 0x1021ffff), /* Switch - TOP */
+       regmap_reg_range(0x10220000, 0x1022ffff), /* SerDes */
+       regmap_reg_range(0x10286000, 0x10286fff), /* RG Batcher */
+       regmap_reg_range(0x1028c000, 0x1028ffff), /* ETHER_SYS */
+       regmap_reg_range(0x30000000, 0x37ffffff), /* I2C EEPROM */
+       regmap_reg_range(0x38000000, 0x3fffffff), /* BOOT_ROM */
+       regmap_reg_range(0xa0000000, 0xbfffffff), /* GPHY */
+};
+
+static const struct regmap_access_table an8855_readable_table = {
+       .yes_ranges = an8855_readable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(an8855_readable_ranges),
+};
+
+static const struct regmap_config an8855_regmap_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+       .max_register = 0xbfffffff,
+       .reg_read = an8855_regmap_read,
+       .reg_write = an8855_regmap_write,
+       .reg_update_bits = an8855_regmap_update_bits,
+       .disable_locking = true,
+       .rd_table = &an8855_readable_table,
+};
+
+static int an8855_mfd_probe(struct mdio_device *mdiodev)
+{
+       struct an8855_mfd_priv *priv;
+       struct regmap *regmap;
+
+       priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->bus = mdiodev->bus;
+       priv->dev = &mdiodev->dev;
+       priv->switch_addr = mdiodev->addr;
+       /* no DMA for mdiobus, mute warning for DMA mask not set */
+       priv->dev->dma_mask = &priv->dev->coherent_dma_mask;
+
+       regmap = devm_regmap_init(priv->dev, NULL, priv,
+                                 &an8855_regmap_config);
+       if (IS_ERR(regmap))
+               dev_err_probe(priv->dev, PTR_ERR(priv->dev),
+                             "regmap initialization failed\n");
+
+       dev_set_drvdata(&mdiodev->dev, priv);
+
+       return devm_mfd_add_devices(priv->dev, PLATFORM_DEVID_AUTO, an8855_mfd_devs,
+                                   ARRAY_SIZE(an8855_mfd_devs), NULL, 0,
+                                   NULL);
+}
+
+static const struct of_device_id an8855_mfd_of_match[] = {
+       { .compatible = "airoha,an8855-mfd" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_mfd_of_match);
+
+static struct mdio_driver an8855_mfd_driver = {
+       .probe = an8855_mfd_probe,
+       .mdiodrv.driver = {
+               .name = "an8855",
+               .of_match_table = an8855_mfd_of_match,
+       },
+};
+mdio_module_driver(an8855_mfd_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_DESCRIPTION("Driver for Airoha AN8855 MFD");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/files-6.12/drivers/net/dsa/an8855.c b/target/linux/mediatek/files-6.12/drivers/net/dsa/an8855.c
new file mode 100644 (file)
index 0000000..47a7d9b
--- /dev/null
@@ -0,0 +1,2307 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Airoha AN8855 DSA Switch driver
+ * Copyright (C) 2023 Min Yao <min.yao@airoha.com>
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth@gmail.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio/consumer.h>
+#include <linux/if_bridge.h>
+#include <linux/iopoll.h>
+#include <linux/netdevice.h>
+#include <linux/of_net.h>
+#include <linux/phylink.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <net/dsa.h>
+
+#include "an8855.h"
+
+static const struct an8855_mib_desc an8855_mib[] = {
+       MIB_DESC(1, AN8855_PORT_MIB_TX_DROP, "TxDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_TX_CRC_ERR, "TxCrcErr"),
+       MIB_DESC(1, AN8855_PORT_MIB_TX_COLLISION, "TxCollision"),
+       MIB_DESC(1, AN8855_PORT_MIB_TX_OVERSIZE_DROP, "TxOversizeDrop"),
+       MIB_DESC(2, AN8855_PORT_MIB_TX_BAD_PKT_BYTES, "TxBadPktBytes"),
+       MIB_DESC(1, AN8855_PORT_MIB_RX_DROP, "RxDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_RX_FILTERING, "RxFiltering"),
+       MIB_DESC(1, AN8855_PORT_MIB_RX_CRC_ERR, "RxCrcErr"),
+       MIB_DESC(1, AN8855_PORT_MIB_RX_CTRL_DROP, "RxCtrlDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_RX_INGRESS_DROP, "RxIngressDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_RX_ARL_DROP, "RxArlDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_FLOW_CONTROL_DROP, "FlowControlDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_WRED_DROP, "WredDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_MIRROR_DROP, "MirrorDrop"),
+       MIB_DESC(2, AN8855_PORT_MIB_RX_BAD_PKT_BYTES, "RxBadPktBytes"),
+       MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP, "RxsFlowSamplingPktDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP, "RxsFlowTotalPktDrop"),
+       MIB_DESC(1, AN8855_PORT_MIB_PORT_CONTROL_DROP, "PortControlDrop"),
+};
+
+static int
+an8855_mib_init(struct an8855_priv *priv)
+{
+       int ret;
+
+       ret = regmap_write(priv->regmap, AN8855_MIB_CCR,
+                          AN8855_CCR_MIB_ENABLE);
+       if (ret)
+               return ret;
+
+       return regmap_write(priv->regmap, AN8855_MIB_CCR,
+                           AN8855_CCR_MIB_ACTIVATE);
+}
+
+static void an8855_fdb_write(struct an8855_priv *priv, u16 vid,
+                            u8 port_mask, const u8 *mac,
+                            bool add) __must_hold(&priv->reg_mutex)
+{
+       u32 mac_reg[2] = { };
+       u32 reg;
+
+       mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC0, mac[0]);
+       mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC1, mac[1]);
+       mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC2, mac[2]);
+       mac_reg[0] |= FIELD_PREP(AN8855_ATA1_MAC3, mac[3]);
+       mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC4, mac[4]);
+       mac_reg[1] |= FIELD_PREP(AN8855_ATA2_MAC5, mac[5]);
+
+       regmap_bulk_write(priv->regmap, AN8855_ATA1, mac_reg,
+                         ARRAY_SIZE(mac_reg));
+
+       reg = AN8855_ATWD_IVL;
+       if (add)
+               reg |= AN8855_ATWD_VLD;
+       reg |= FIELD_PREP(AN8855_ATWD_VID, vid);
+       reg |= FIELD_PREP(AN8855_ATWD_FID, AN8855_FID_BRIDGED);
+       regmap_write(priv->regmap, AN8855_ATWD, reg);
+       regmap_write(priv->regmap, AN8855_ATWD2,
+                    FIELD_PREP(AN8855_ATWD2_PORT, port_mask));
+}
+
+static void an8855_fdb_read(struct an8855_priv *priv, struct an8855_fdb *fdb)
+{
+       u32 reg[4];
+
+       regmap_bulk_read(priv->regmap, AN8855_ATRD0, reg,
+                        ARRAY_SIZE(reg));
+
+       fdb->live = FIELD_GET(AN8855_ATRD0_LIVE, reg[0]);
+       fdb->type = FIELD_GET(AN8855_ATRD0_TYPE, reg[0]);
+       fdb->ivl = FIELD_GET(AN8855_ATRD0_IVL, reg[0]);
+       fdb->vid = FIELD_GET(AN8855_ATRD0_VID, reg[0]);
+       fdb->fid = FIELD_GET(AN8855_ATRD0_FID, reg[0]);
+       fdb->aging = FIELD_GET(AN8855_ATRD1_AGING, reg[1]);
+       fdb->port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, reg[3]);
+       fdb->mac[0] = FIELD_GET(AN8855_ATRD2_MAC0, reg[2]);
+       fdb->mac[1] = FIELD_GET(AN8855_ATRD2_MAC1, reg[2]);
+       fdb->mac[2] = FIELD_GET(AN8855_ATRD2_MAC2, reg[2]);
+       fdb->mac[3] = FIELD_GET(AN8855_ATRD2_MAC3, reg[2]);
+       fdb->mac[4] = FIELD_GET(AN8855_ATRD1_MAC4, reg[1]);
+       fdb->mac[5] = FIELD_GET(AN8855_ATRD1_MAC5, reg[1]);
+       fdb->noarp = !!FIELD_GET(AN8855_ATRD0_ARP, reg[0]);
+}
+
+static int an8855_fdb_cmd(struct an8855_priv *priv, u32 cmd,
+                         u32 *rsp) __must_hold(&priv->reg_mutex)
+{
+       u32 val;
+       int ret;
+
+       /* Set the command operating upon the MAC address entries */
+       val = AN8855_ATC_BUSY | cmd;
+       ret = regmap_write(priv->regmap, AN8855_ATC, val);
+       if (ret)
+               return ret;
+
+       ret = regmap_read_poll_timeout(priv->regmap, AN8855_ATC, val,
+                                      !(val & AN8855_ATC_BUSY), 20, 200000);
+       if (ret)
+               return ret;
+
+       if (rsp)
+               *rsp = val;
+
+       return 0;
+}
+
+static void
+an8855_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+       struct dsa_port *dp = dsa_to_port(ds, port);
+       struct an8855_priv *priv = ds->priv;
+       bool learning = false;
+       u32 stp_state;
+
+       switch (state) {
+       case BR_STATE_DISABLED:
+               stp_state = AN8855_STP_DISABLED;
+               break;
+       case BR_STATE_BLOCKING:
+               stp_state = AN8855_STP_BLOCKING;
+               break;
+       case BR_STATE_LISTENING:
+               stp_state = AN8855_STP_LISTENING;
+               break;
+       case BR_STATE_LEARNING:
+               stp_state = AN8855_STP_LEARNING;
+               learning = dp->learning;
+               break;
+       case BR_STATE_FORWARDING:
+               learning = dp->learning;
+               fallthrough;
+       default:
+               stp_state = AN8855_STP_FORWARDING;
+               break;
+       }
+
+       regmap_update_bits(priv->regmap, AN8855_SSP_P(port),
+                          AN8855_FID_PST_MASK(AN8855_FID_BRIDGED),
+                          AN8855_FID_PST_VAL(AN8855_FID_BRIDGED, stp_state));
+
+       regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS,
+                          learning ? 0 : AN8855_SA_DIS);
+}
+
+static void an8855_port_fast_age(struct dsa_switch *ds, int port)
+{
+       struct an8855_priv *priv = ds->priv;
+       int ret;
+
+       /* Set to clean Dynamic entry */
+       ret = regmap_write(priv->regmap, AN8855_ATA2, AN8855_ATA2_TYPE);
+       if (ret)
+               return;
+
+       /* Set Port */
+       ret = regmap_write(priv->regmap, AN8855_ATWD2,
+                          FIELD_PREP(AN8855_ATWD2_PORT, BIT(port)));
+       if (ret)
+               return;
+
+       /* Flush Dynamic entry at port */
+       an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_TYPE_PORT) |
+                      AN8855_FDB_FLUSH, NULL);
+}
+
+static int an8855_update_port_member(struct dsa_switch *ds, int port,
+                                    const struct net_device *bridge_dev,
+                                    bool join)
+{
+       struct an8855_priv *priv = ds->priv;
+       bool isolated, other_isolated;
+       struct dsa_port *dp;
+       u32 port_mask = 0;
+       int ret;
+
+       isolated = !!(priv->port_isolated_map & BIT(port));
+
+       dsa_switch_for_each_user_port(dp, ds) {
+               if (dp->index == port)
+                       continue;
+
+               if (!dsa_port_offloads_bridge_dev(dp, bridge_dev))
+                       continue;
+
+               other_isolated = !!(priv->port_isolated_map & BIT(dp->index));
+               port_mask |= BIT(dp->index);
+               /* Add/remove this port to the portvlan mask of the other
+                * ports in the bridge
+                */
+               if (join && !(isolated && other_isolated))
+                       ret = regmap_set_bits(priv->regmap,
+                                             AN8855_PORTMATRIX_P(dp->index),
+                                             FIELD_PREP(AN8855_USER_PORTMATRIX,
+                                                        BIT(port)));
+               else
+                       ret = regmap_clear_bits(priv->regmap,
+                                               AN8855_PORTMATRIX_P(dp->index),
+                                               FIELD_PREP(AN8855_USER_PORTMATRIX,
+                                                          BIT(port)));
+               if (ret)
+                       return ret;
+       }
+
+       /* Add/remove all other ports to this port's portvlan mask */
+       return regmap_update_bits(priv->regmap, AN8855_PORTMATRIX_P(port),
+                                 AN8855_USER_PORTMATRIX,
+                                 join ? port_mask : ~port_mask);
+}
+
+static int an8855_port_pre_bridge_flags(struct dsa_switch *ds, int port,
+                                       struct switchdev_brport_flags flags,
+                                       struct netlink_ext_ack *extack)
+{
+       if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
+                          BR_BCAST_FLOOD | BR_ISOLATED))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int an8855_port_bridge_flags(struct dsa_switch *ds, int port,
+                                   struct switchdev_brport_flags flags,
+                                   struct netlink_ext_ack *extack)
+{
+       struct an8855_priv *priv = ds->priv;
+       int ret;
+
+       if (flags.mask & BR_LEARNING) {
+               ret = regmap_update_bits(priv->regmap, AN8855_PSC_P(port), AN8855_SA_DIS,
+                                        flags.val & BR_LEARNING ? 0 : AN8855_SA_DIS);
+               if (ret)
+                       return ret;
+       }
+
+       if (flags.mask & BR_FLOOD) {
+               ret = regmap_update_bits(priv->regmap, AN8855_UNUF, BIT(port),
+                                        flags.val & BR_FLOOD ? BIT(port) : 0);
+               if (ret)
+                       return ret;
+       }
+
+       if (flags.mask & BR_MCAST_FLOOD) {
+               ret = regmap_update_bits(priv->regmap, AN8855_UNMF, BIT(port),
+                                        flags.val & BR_MCAST_FLOOD ? BIT(port) : 0);
+               if (ret)
+                       return ret;
+
+               ret = regmap_update_bits(priv->regmap, AN8855_UNIPMF, BIT(port),
+                                        flags.val & BR_MCAST_FLOOD ? BIT(port) : 0);
+               if (ret)
+                       return ret;
+       }
+
+       if (flags.mask & BR_BCAST_FLOOD) {
+               ret = regmap_update_bits(priv->regmap, AN8855_BCF, BIT(port),
+                                        flags.val & BR_BCAST_FLOOD ? BIT(port) : 0);
+               if (ret)
+                       return ret;
+       }
+
+       if (flags.mask & BR_ISOLATED) {
+               struct dsa_port *dp = dsa_to_port(ds, port);
+               struct net_device *bridge_dev = dsa_port_bridge_dev_get(dp);
+
+               if (flags.val & BR_ISOLATED)
+                       priv->port_isolated_map |= BIT(port);
+               else
+                       priv->port_isolated_map &= ~BIT(port);
+
+               ret = an8855_update_port_member(ds, port, bridge_dev, true);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int an8855_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
+{
+       struct an8855_priv *priv = ds->priv;
+       u32 age_count, age_unit, val;
+
+       /* Convert msec in AN8855_L2_AGING_MS_CONSTANT counter */
+       val = msecs / AN8855_L2_AGING_MS_CONSTANT;
+       /* Derive the count unit */
+       age_unit = val / FIELD_MAX(AN8855_AGE_UNIT);
+       /* Get the count in unit, age_unit is always incremented by 1 internally */
+       age_count = val / (age_unit + 1);
+
+       return regmap_update_bits(priv->regmap, AN8855_AAC,
+                                 AN8855_AGE_CNT | AN8855_AGE_UNIT,
+                                 FIELD_PREP(AN8855_AGE_CNT, age_count) |
+                                 FIELD_PREP(AN8855_AGE_UNIT, age_unit));
+}
+
+static int an8855_port_bridge_join(struct dsa_switch *ds, int port,
+                                  struct dsa_bridge bridge,
+                                  bool *tx_fwd_offload,
+                                  struct netlink_ext_ack *extack)
+{
+       struct an8855_priv *priv = ds->priv;
+       int ret;
+
+       ret = an8855_update_port_member(ds, port, bridge.dev, true);
+       if (ret)
+               return ret;
+
+       /* Set to fallback mode for independent VLAN learning if in a bridge */
+       return regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+                                 AN8855_PORT_VLAN,
+                                 FIELD_PREP(AN8855_PORT_VLAN,
+                                            AN8855_PORT_FALLBACK_MODE));
+}
+
+static void an8855_port_bridge_leave(struct dsa_switch *ds, int port,
+                                    struct dsa_bridge bridge)
+{
+       struct an8855_priv *priv = ds->priv;
+
+       an8855_update_port_member(ds, port, bridge.dev, false);
+
+       /* When a port is removed from the bridge, the port would be set up
+        * back to the default as is at initial boot which is a VLAN-unaware
+        * port.
+        */
+       regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+                          AN8855_PORT_VLAN,
+                          FIELD_PREP(AN8855_PORT_VLAN,
+                                     AN8855_PORT_MATRIX_MODE));
+}
+
+static int an8855_port_fdb_add(struct dsa_switch *ds, int port,
+                              const unsigned char *addr, u16 vid,
+                              struct dsa_db db)
+{
+       struct an8855_priv *priv = ds->priv;
+       u8 port_mask = BIT(port);
+       int ret;
+
+       /* Set the vid to the port vlan id if no vid is set */
+       if (!vid)
+               vid = AN8855_PORT_VID_DEFAULT;
+
+       mutex_lock(&priv->reg_mutex);
+       an8855_fdb_write(priv, vid, port_mask, addr, true);
+       ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+       mutex_unlock(&priv->reg_mutex);
+
+       return ret;
+}
+
+static int an8855_port_fdb_del(struct dsa_switch *ds, int port,
+                              const unsigned char *addr, u16 vid,
+                              struct dsa_db db)
+{
+       struct an8855_priv *priv = ds->priv;
+       u8 port_mask = BIT(port);
+       int ret;
+
+       /* Set the vid to the port vlan id if no vid is set */
+       if (!vid)
+               vid = AN8855_PORT_VID_DEFAULT;
+
+       mutex_lock(&priv->reg_mutex);
+       an8855_fdb_write(priv, vid, port_mask, addr, false);
+       ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+       mutex_unlock(&priv->reg_mutex);
+
+       return ret;
+}
+
+static int an8855_port_fdb_dump(struct dsa_switch *ds, int port,
+                               dsa_fdb_dump_cb_t *cb, void *data)
+{
+       struct an8855_priv *priv = ds->priv;
+       int banks, count = 0;
+       u32 rsp;
+       int ret;
+       int i;
+
+       mutex_lock(&priv->reg_mutex);
+
+       /* Load search port */
+       ret = regmap_write(priv->regmap, AN8855_ATWD2,
+                          FIELD_PREP(AN8855_ATWD2_PORT, BIT(port)));
+       if (ret)
+               goto exit;
+       ret = an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_PORT) |
+                            AN8855_FDB_START, &rsp);
+       if (ret < 0)
+               goto exit;
+
+       do {
+               /* From response get the number of banks to read, exit if 0 */
+               banks = FIELD_GET(AN8855_ATC_HIT, rsp);
+               if (!banks)
+                       break;
+
+               /* Each banks have 4 entry */
+               for (i = 0; i < 4; i++) {
+                       struct an8855_fdb _fdb = {  };
+
+                       count++;
+
+                       /* Check if bank is present */
+                       if (!(banks & BIT(i)))
+                               continue;
+
+                       /* Select bank entry index */
+                       ret = regmap_write(priv->regmap, AN8855_ATRDS,
+                                          FIELD_PREP(AN8855_ATRD_SEL, i));
+                       if (ret)
+                               break;
+                       /* wait 1ms for the bank entry to be filled */
+                       usleep_range(1000, 1500);
+                       an8855_fdb_read(priv, &_fdb);
+
+                       if (!_fdb.live)
+                               continue;
+                       ret = cb(_fdb.mac, _fdb.vid, _fdb.noarp, data);
+                       if (ret < 0)
+                               break;
+               }
+
+               /* Stop if reached max FDB number */
+               if (count >= AN8855_NUM_FDB_RECORDS)
+                       break;
+
+               /* Read next bank */
+               ret = an8855_fdb_cmd(priv, AN8855_ATC_MAT(AND8855_FDB_MAT_MAC_PORT) |
+                                    AN8855_FDB_NEXT, &rsp);
+               if (ret < 0)
+                       break;
+       } while (true);
+
+exit:
+       mutex_unlock(&priv->reg_mutex);
+       return ret;
+}
+
+static int an8855_vlan_cmd(struct an8855_priv *priv, enum an8855_vlan_cmd cmd,
+                          u16 vid) __must_hold(&priv->reg_mutex)
+{
+       u32 val;
+       int ret;
+
+       val = AN8855_VTCR_BUSY | FIELD_PREP(AN8855_VTCR_FUNC, cmd) |
+             FIELD_PREP(AN8855_VTCR_VID, vid);
+       ret = regmap_write(priv->regmap, AN8855_VTCR, val);
+       if (ret)
+               return ret;
+
+       return regmap_read_poll_timeout(priv->regmap, AN8855_VTCR, val,
+                                       !(val & AN8855_VTCR_BUSY), 20, 200000);
+}
+
+static int an8855_vlan_add(struct an8855_priv *priv, u8 port, u16 vid,
+                          bool untagged) __must_hold(&priv->reg_mutex)
+{
+       u32 port_mask;
+       u32 val;
+       int ret;
+
+       /* Fetch entry */
+       ret = an8855_vlan_cmd(priv, AN8855_VTCR_RD_VID, vid);
+       if (ret)
+               return ret;
+
+       ret = regmap_read(priv->regmap, AN8855_VARD0, &val);
+       if (ret)
+               return ret;
+       port_mask = FIELD_GET(AN8855_VA0_PORT, val) | BIT(port);
+
+       /* Validate the entry with independent learning, create egress tag per
+        * VLAN and joining the port as one of the port members.
+        */
+       val = (val & AN8855_VA0_ETAG) | AN8855_VA0_IVL_MAC |
+             AN8855_VA0_VTAG_EN | AN8855_VA0_VLAN_VALID |
+             FIELD_PREP(AN8855_VA0_PORT, port_mask) |
+             FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED);
+       ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+       if (ret)
+               return ret;
+       ret = regmap_write(priv->regmap, AN8855_VAWD1, 0);
+       if (ret)
+               return ret;
+
+       /* CPU port is always taken as a tagged port for serving more than one
+        * VLANs across and also being applied with egress type stack mode for
+        * that VLAN tags would be appended after hardware special tag used as
+        * DSA tag.
+        */
+       if (port == AN8855_CPU_PORT)
+               val = AN8855_VLAN_EGRESS_STACK;
+       /* Decide whether adding tag or not for those outgoing packets from the
+        * port inside the VLAN.
+        */
+       else
+               val = untagged ? AN8855_VLAN_EGRESS_UNTAG : AN8855_VLAN_EGRESS_TAG;
+       ret = regmap_update_bits(priv->regmap, AN8855_VAWD0,
+                                AN8855_VA0_ETAG_PORT_MASK(port),
+                                AN8855_VA0_ETAG_PORT_VAL(port, val));
+       if (ret)
+               return ret;
+
+       /* Flush result to hardware */
+       return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, vid);
+}
+
+static int an8855_vlan_del(struct an8855_priv *priv, u8 port,
+                          u16 vid) __must_hold(&priv->reg_mutex)
+{
+       u32 port_mask;
+       u32 val;
+       int ret;
+
+       /* Fetch entry */
+       ret = an8855_vlan_cmd(priv, AN8855_VTCR_RD_VID, vid);
+       if (ret)
+               return ret;
+
+       ret = regmap_read(priv->regmap, AN8855_VARD0, &val);
+       if (ret)
+               return ret;
+       port_mask = FIELD_GET(AN8855_VA0_PORT, val) & ~BIT(port);
+
+       if (!(val & AN8855_VA0_VLAN_VALID)) {
+               dev_err(priv->dev, "Cannot be deleted due to invalid entry\n");
+               return -EINVAL;
+       }
+
+       if (port_mask) {
+               val = (val & AN8855_VA0_ETAG) | AN8855_VA0_IVL_MAC |
+                      AN8855_VA0_VTAG_EN | AN8855_VA0_VLAN_VALID |
+                      FIELD_PREP(AN8855_VA0_PORT, port_mask);
+               ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+               if (ret)
+                       return ret;
+       } else {
+               ret = regmap_write(priv->regmap, AN8855_VAWD0, 0);
+               if (ret)
+                       return ret;
+       }
+       ret = regmap_write(priv->regmap, AN8855_VAWD1, 0);
+       if (ret)
+               return ret;
+
+       /* Flush result to hardware */
+       return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID, vid);
+}
+
+static int an8855_port_set_vlan_mode(struct an8855_priv *priv, int port,
+                                    enum an8855_port_mode port_mode,
+                                    enum an8855_vlan_port_eg_tag eg_tag,
+                                    enum an8855_vlan_port_attr vlan_attr,
+                                    enum an8855_vlan_port_acc_frm acc_frm)
+{
+       int ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(port),
+                                AN8855_PORT_VLAN,
+                                FIELD_PREP(AN8855_PORT_VLAN, port_mode));
+       if (ret)
+               return ret;
+
+       return regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+                                 AN8855_PVC_EG_TAG | AN8855_VLAN_ATTR | AN8855_ACC_FRM,
+                                 FIELD_PREP(AN8855_PVC_EG_TAG, eg_tag) |
+                                 FIELD_PREP(AN8855_VLAN_ATTR, vlan_attr) |
+                                 FIELD_PREP(AN8855_ACC_FRM, acc_frm));
+}
+
+static int an8855_port_set_pid(struct an8855_priv *priv, int port,
+                              u16 pid)
+{
+       int ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_PPBV1_P(port),
+                                AN8855_PPBV_G0_PORT_VID,
+                                FIELD_PREP(AN8855_PPBV_G0_PORT_VID, pid));
+       if (ret)
+               return ret;
+
+       return regmap_update_bits(priv->regmap, AN8855_PVID_P(port),
+                                 AN8855_G0_PORT_VID,
+                                 FIELD_PREP(AN8855_G0_PORT_VID, pid));
+}
+
+static int an8855_port_vlan_filtering(struct dsa_switch *ds, int port,
+                                     bool vlan_filtering,
+                                     struct netlink_ext_ack *extack)
+{
+       struct an8855_priv *priv = ds->priv;
+       u32 val;
+       int ret;
+
+       /* The port is being kept as VLAN-unaware port when bridge is
+        * set up with vlan_filtering not being set, Otherwise, the
+        * port and the corresponding CPU port is required the setup
+        * for becoming a VLAN-aware port.
+        */
+       if (vlan_filtering) {
+               u32 acc_frm;
+               /* CPU port is set to fallback mode to let untagged
+                * frames pass through.
+                */
+               ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT,
+                                               AN8855_PORT_FALLBACK_MODE,
+                                               AN8855_VLAN_EG_CONSISTENT,
+                                               AN8855_VLAN_USER,
+                                               AN8855_VLAN_ACC_ALL);
+               if (ret)
+                       return ret;
+
+               ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+               if (ret)
+                       return ret;
+
+               /* Only accept tagged frames if PVID is not set */
+               if (FIELD_GET(AN8855_G0_PORT_VID, val) != AN8855_PORT_VID_DEFAULT)
+                       acc_frm = AN8855_VLAN_ACC_TAGGED;
+               else
+                       acc_frm = AN8855_VLAN_ACC_ALL;
+
+               /* Trapped into security mode allows packet forwarding through VLAN
+                * table lookup.
+                * Set the port as a user port which is to be able to recognize VID
+                * from incoming packets before fetching entry within the VLAN table.
+                */
+               ret = an8855_port_set_vlan_mode(priv, port,
+                                               AN8855_PORT_SECURITY_MODE,
+                                               AN8855_VLAN_EG_DISABLED,
+                                               AN8855_VLAN_USER,
+                                               acc_frm);
+               if (ret)
+                       return ret;
+       } else {
+               bool disable_cpu_vlan = true;
+               struct dsa_port *dp;
+               u32 port_mode;
+
+               /* This is called after .port_bridge_leave when leaving a VLAN-aware
+                * bridge. Don't set standalone ports to fallback mode.
+                */
+               if (dsa_port_bridge_dev_get(dsa_to_port(ds, port)))
+                       port_mode = AN8855_PORT_FALLBACK_MODE;
+               else
+                       port_mode = AN8855_PORT_MATRIX_MODE;
+
+               /* When a port is removed from the bridge, the port would be set up
+                * back to the default as is at initial boot which is a VLAN-unaware
+                * port.
+                */
+               ret = an8855_port_set_vlan_mode(priv, port, port_mode,
+                                               AN8855_VLAN_EG_CONSISTENT,
+                                               AN8855_VLAN_TRANSPARENT,
+                                               AN8855_VLAN_ACC_ALL);
+               if (ret)
+                       return ret;
+
+               /* Restore default PVID */
+               ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+               if (ret)
+                       return ret;
+
+               dsa_switch_for_each_user_port(dp, ds) {
+                       if (dsa_port_is_vlan_filtering(dp)) {
+                               disable_cpu_vlan = false;
+                               break;
+                       }
+               }
+
+               if (disable_cpu_vlan) {
+                       ret = an8855_port_set_vlan_mode(priv, AN8855_CPU_PORT,
+                                                       AN8855_PORT_MATRIX_MODE,
+                                                       AN8855_VLAN_EG_CONSISTENT,
+                                                       AN8855_VLAN_USER,
+                                                       AN8855_VLAN_ACC_ALL);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int an8855_port_vlan_add(struct dsa_switch *ds, int port,
+                               const struct switchdev_obj_port_vlan *vlan,
+                               struct netlink_ext_ack *extack)
+{
+       bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
+       bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
+       struct an8855_priv *priv = ds->priv;
+       u32 val;
+       int ret;
+
+       mutex_lock(&priv->reg_mutex);
+       ret = an8855_vlan_add(priv, port, vlan->vid, untagged);
+       mutex_unlock(&priv->reg_mutex);
+       if (ret)
+               return ret;
+
+       if (pvid) {
+               /* Accept all frames if PVID is set */
+               regmap_update_bits(priv->regmap, AN8855_PVC_P(port), AN8855_ACC_FRM,
+                                  FIELD_PREP(AN8855_ACC_FRM, AN8855_VLAN_ACC_ALL));
+
+               /* Only configure PVID if VLAN filtering is enabled */
+               if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+                       ret = an8855_port_set_pid(priv, port, vlan->vid);
+                       if (ret)
+                               return ret;
+               }
+       } else if (vlan->vid) {
+               ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+               if (ret)
+                       return ret;
+
+               if (FIELD_GET(AN8855_G0_PORT_VID, val) != vlan->vid)
+                       return 0;
+
+               /* This VLAN is overwritten without PVID, so unset it */
+               if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+                       ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+                                                AN8855_ACC_FRM,
+                                                FIELD_PREP(AN8855_ACC_FRM,
+                                                           AN8855_VLAN_ACC_TAGGED));
+                       if (ret)
+                               return ret;
+               }
+
+               ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int an8855_port_vlan_del(struct dsa_switch *ds, int port,
+                               const struct switchdev_obj_port_vlan *vlan)
+{
+       struct an8855_priv *priv = ds->priv;
+       u32 val;
+       int ret;
+
+       mutex_lock(&priv->reg_mutex);
+       ret = an8855_vlan_del(priv, port, vlan->vid);
+       mutex_unlock(&priv->reg_mutex);
+       if (ret)
+               return ret;
+
+       ret = regmap_read(priv->regmap, AN8855_PVID_P(port), &val);
+       if (ret)
+               return ret;
+
+       /* PVID is being restored to the default whenever the PVID port
+        * is being removed from the VLAN.
+        */
+       if (FIELD_GET(AN8855_G0_PORT_VID, val) == vlan->vid) {
+               /* Only accept tagged frames if the port is VLAN-aware */
+               if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port))) {
+                       ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(port),
+                                                AN8855_ACC_FRM,
+                                                FIELD_PREP(AN8855_ACC_FRM,
+                                                           AN8855_VLAN_ACC_TAGGED));
+                       if (ret)
+                               return ret;
+               }
+
+               ret = an8855_port_set_pid(priv, port, AN8855_PORT_VID_DEFAULT);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int
+an8855_port_mdb_add(struct dsa_switch *ds, int port,
+                   const struct switchdev_obj_port_mdb *mdb,
+                   struct dsa_db db)
+{
+       struct an8855_priv *priv = ds->priv;
+       const u8 *addr = mdb->addr;
+       u16 vid = mdb->vid;
+       u8 port_mask = 0;
+       u32 val;
+       int ret;
+
+       /* Set the vid to the port vlan id if no vid is set */
+       if (!vid)
+               vid = AN8855_PORT_VID_DEFAULT;
+
+       mutex_lock(&priv->reg_mutex);
+
+       an8855_fdb_write(priv, vid, 0, addr, false);
+       if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) {
+               ret = regmap_read(priv->regmap, AN8855_ATRD3, &val);
+               if (ret)
+                       goto exit;
+
+               port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val);
+       }
+
+       port_mask |= BIT(port);
+       an8855_fdb_write(priv, vid, port_mask, addr, true);
+       ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+
+exit:
+       mutex_unlock(&priv->reg_mutex);
+
+       return ret;
+}
+
+static int
+an8855_port_mdb_del(struct dsa_switch *ds, int port,
+                   const struct switchdev_obj_port_mdb *mdb,
+                   struct dsa_db db)
+{
+       struct an8855_priv *priv = ds->priv;
+       const u8 *addr = mdb->addr;
+       u16 vid = mdb->vid;
+       u8 port_mask = 0;
+       u32 val;
+       int ret;
+
+       /* Set the vid to the port vlan id if no vid is set */
+       if (!vid)
+               vid = AN8855_PORT_VID_DEFAULT;
+
+       mutex_lock(&priv->reg_mutex);
+
+       an8855_fdb_write(priv, vid, 0, addr, 0);
+       if (!an8855_fdb_cmd(priv, AN8855_FDB_READ, NULL)) {
+               ret = regmap_read(priv->regmap, AN8855_ATRD3, &val);
+               if (ret)
+                       goto exit;
+
+               port_mask = FIELD_GET(AN8855_ATRD3_PORTMASK, val);
+       }
+
+       port_mask &= ~BIT(port);
+       an8855_fdb_write(priv, vid, port_mask, addr, port_mask ? true : false);
+       ret = an8855_fdb_cmd(priv, AN8855_FDB_WRITE, NULL);
+
+exit:
+       mutex_unlock(&priv->reg_mutex);
+
+       return ret;
+}
+
+static int
+an8855_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+       struct an8855_priv *priv = ds->priv;
+       int length;
+       u32 val;
+
+       /* When a new MTU is set, DSA always set the CPU port's MTU to the
+        * largest MTU of the slave ports. Because the switch only has a global
+        * RX length register, only allowing CPU port here is enough.
+        */
+       if (!dsa_is_cpu_port(ds, port))
+               return 0;
+
+       /* RX length also includes Ethernet header, MTK tag, and FCS length */
+       length = new_mtu + ETH_HLEN + MTK_TAG_LEN + ETH_FCS_LEN;
+       if (length <= 1522)
+               val = AN8855_MAX_RX_PKT_1518_1522;
+       else if (length <= 1536)
+               val = AN8855_MAX_RX_PKT_1536;
+       else if (length <= 1552)
+               val = AN8855_MAX_RX_PKT_1552;
+       else if (length <= 3072)
+               val = AN8855_MAX_RX_JUMBO_3K;
+       else if (length <= 4096)
+               val = AN8855_MAX_RX_JUMBO_4K;
+       else if (length <= 5120)
+               val = AN8855_MAX_RX_JUMBO_5K;
+       else if (length <= 6144)
+               val = AN8855_MAX_RX_JUMBO_6K;
+       else if (length <= 7168)
+               val = AN8855_MAX_RX_JUMBO_7K;
+       else if (length <= 8192)
+               val = AN8855_MAX_RX_JUMBO_8K;
+       else if (length <= 9216)
+               val = AN8855_MAX_RX_JUMBO_9K;
+       else if (length <= 12288)
+               val = AN8855_MAX_RX_JUMBO_12K;
+       else if (length <= 15360)
+               val = AN8855_MAX_RX_JUMBO_15K;
+       else
+               val = AN8855_MAX_RX_JUMBO_16K;
+
+       /* Enable JUMBO packet */
+       if (length > 1552)
+               val |= AN8855_MAX_RX_PKT_JUMBO;
+
+       return regmap_update_bits(priv->regmap, AN8855_GMACCR,
+                                 AN8855_MAX_RX_JUMBO | AN8855_MAX_RX_PKT_LEN,
+                                 val);
+}
+
+static int
+an8855_port_max_mtu(struct dsa_switch *ds, int port)
+{
+       return AN8855_MAX_MTU;
+}
+
+static void
+an8855_get_strings(struct dsa_switch *ds, int port, u32 stringset,
+                  uint8_t *data)
+{
+       int i;
+
+       if (stringset != ETH_SS_STATS)
+               return;
+
+       for (i = 0; i < ARRAY_SIZE(an8855_mib); i++)
+               ethtool_puts(&data, an8855_mib[i].name);
+}
+
+static void
+an8855_read_port_stats(struct an8855_priv *priv, int port, u32 offset, u8 size,
+                      uint64_t *data)
+{
+       u32 val, reg = AN8855_PORT_MIB_COUNTER(port) + offset;
+
+       regmap_read(priv->regmap, reg, &val);
+       *data = val;
+
+       if (size == 2) {
+               regmap_read(priv->regmap, reg + 4, &val);
+               *data |= (u64)val << 32;
+       }
+}
+
+static void
+an8855_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data)
+{
+       struct an8855_priv *priv = ds->priv;
+       const struct an8855_mib_desc *mib;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(an8855_mib); i++) {
+               mib = &an8855_mib[i];
+
+               an8855_read_port_stats(priv, port, mib->offset, mib->size,
+                                      data + i);
+       }
+}
+
+static int
+an8855_get_sset_count(struct dsa_switch *ds, int port, int sset)
+{
+       if (sset != ETH_SS_STATS)
+               return 0;
+
+       return ARRAY_SIZE(an8855_mib);
+}
+
+static void
+an8855_get_eth_mac_stats(struct dsa_switch *ds, int port,
+                        struct ethtool_eth_mac_stats *mac_stats)
+{
+       struct an8855_priv *priv = ds->priv;
+
+       /* MIB counter doesn't provide a FramesTransmittedOK but instead
+        * provide stats for Unicast, Broadcast and Multicast frames separately.
+        * To simulate a global frame counter, read Unicast and addition Multicast
+        * and Broadcast later
+        */
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_UNICAST, 1,
+                              &mac_stats->FramesTransmittedOK);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_SINGLE_COLLISION, 1,
+                              &mac_stats->SingleCollisionFrames);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_MULTIPLE_COLLISION, 1,
+                              &mac_stats->MultipleCollisionFrames);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_UNICAST, 1,
+                              &mac_stats->FramesReceivedOK);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_BYTES, 2,
+                              &mac_stats->OctetsTransmittedOK);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_ALIGN_ERR, 1,
+                              &mac_stats->AlignmentErrors);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_DEFERRED, 1,
+                              &mac_stats->FramesWithDeferredXmissions);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_LATE_COLLISION, 1,
+                              &mac_stats->LateCollisions);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION, 1,
+                              &mac_stats->FramesAbortedDueToXSColls);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_BYTES, 2,
+                              &mac_stats->OctetsReceivedOK);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_MULTICAST, 1,
+                              &mac_stats->MulticastFramesXmittedOK);
+       mac_stats->FramesTransmittedOK += mac_stats->MulticastFramesXmittedOK;
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_BROADCAST, 1,
+                              &mac_stats->BroadcastFramesXmittedOK);
+       mac_stats->FramesTransmittedOK += mac_stats->BroadcastFramesXmittedOK;
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_MULTICAST, 1,
+                              &mac_stats->MulticastFramesReceivedOK);
+       mac_stats->FramesReceivedOK += mac_stats->MulticastFramesReceivedOK;
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_BROADCAST, 1,
+                              &mac_stats->BroadcastFramesReceivedOK);
+       mac_stats->FramesReceivedOK += mac_stats->BroadcastFramesReceivedOK;
+}
+
+static const struct ethtool_rmon_hist_range an8855_rmon_ranges[] = {
+       { 0, 64 },
+       { 65, 127 },
+       { 128, 255 },
+       { 256, 511 },
+       { 512, 1023 },
+       { 1024, 1518 },
+       { 1519, AN8855_MAX_MTU },
+       {}
+};
+
+static void an8855_get_rmon_stats(struct dsa_switch *ds, int port,
+                                 struct ethtool_rmon_stats *rmon_stats,
+                                 const struct ethtool_rmon_hist_range **ranges)
+{
+       struct an8855_priv *priv = ds->priv;
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_UNDER_SIZE_ERR, 1,
+                              &rmon_stats->undersize_pkts);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_OVER_SZ_ERR, 1,
+                              &rmon_stats->oversize_pkts);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_FRAG_ERR, 1,
+                              &rmon_stats->fragments);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_JABBER_ERR, 1,
+                              &rmon_stats->jabbers);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_64, 1,
+                              &rmon_stats->hist[0]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127, 1,
+                              &rmon_stats->hist[1]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255, 1,
+                              &rmon_stats->hist[2]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511, 1,
+                              &rmon_stats->hist[3]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023, 1,
+                              &rmon_stats->hist[4]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518, 1,
+                              &rmon_stats->hist[5]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX, 1,
+                              &rmon_stats->hist[6]);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_64, 1,
+                              &rmon_stats->hist_tx[0]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127, 1,
+                              &rmon_stats->hist_tx[1]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255, 1,
+                              &rmon_stats->hist_tx[2]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511, 1,
+                              &rmon_stats->hist_tx[3]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023, 1,
+                              &rmon_stats->hist_tx[4]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518, 1,
+                              &rmon_stats->hist_tx[5]);
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX, 1,
+                              &rmon_stats->hist_tx[6]);
+
+       *ranges = an8855_rmon_ranges;
+}
+
+static void an8855_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
+                                     struct ethtool_eth_ctrl_stats *ctrl_stats)
+{
+       struct an8855_priv *priv = ds->priv;
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_TX_PAUSE, 1,
+                              &ctrl_stats->MACControlFramesTransmitted);
+
+       an8855_read_port_stats(priv, port, AN8855_PORT_MIB_RX_PAUSE, 1,
+                              &ctrl_stats->MACControlFramesReceived);
+}
+
+static int an8855_port_mirror_add(struct dsa_switch *ds, int port,
+                                 struct dsa_mall_mirror_tc_entry *mirror,
+                                 bool ingress,
+                                 struct netlink_ext_ack *extack)
+{
+       struct an8855_priv *priv = ds->priv;
+       int monitor_port;
+       u32 val;
+       int ret;
+
+       /* Check for existent entry */
+       if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
+               return -EEXIST;
+
+       ret = regmap_read(priv->regmap, AN8855_MIR, &val);
+       if (ret)
+               return ret;
+
+       /* AN8855 supports 4 monitor port, but only use first group */
+       monitor_port = FIELD_GET(AN8855_MIRROR_PORT, val);
+       if (val & AN8855_MIRROR_EN && monitor_port != mirror->to_local_port)
+               return -EEXIST;
+
+       val = AN8855_MIRROR_EN;
+       val |= FIELD_PREP(AN8855_MIRROR_PORT, mirror->to_local_port);
+       ret = regmap_update_bits(priv->regmap, AN8855_MIR,
+                                AN8855_MIRROR_EN | AN8855_MIRROR_PORT,
+                                val);
+       if (ret)
+               return ret;
+
+       ret = regmap_set_bits(priv->regmap, AN8855_PCR_P(port),
+                             ingress ? AN8855_PORT_RX_MIR : AN8855_PORT_TX_MIR);
+       if (ret)
+               return ret;
+
+       if (ingress)
+               priv->mirror_rx |= BIT(port);
+       else
+               priv->mirror_tx |= BIT(port);
+
+       return 0;
+}
+
+static void an8855_port_mirror_del(struct dsa_switch *ds, int port,
+                                  struct dsa_mall_mirror_tc_entry *mirror)
+{
+       struct an8855_priv *priv = ds->priv;
+
+       if (mirror->ingress)
+               priv->mirror_rx &= ~BIT(port);
+       else
+               priv->mirror_tx &= ~BIT(port);
+
+       regmap_clear_bits(priv->regmap, AN8855_PCR_P(port),
+                         mirror->ingress ? AN8855_PORT_RX_MIR :
+                                           AN8855_PORT_TX_MIR);
+
+       if (!priv->mirror_rx && !priv->mirror_tx)
+               regmap_clear_bits(priv->regmap, AN8855_MIR, AN8855_MIRROR_EN);
+}
+
+static int an8855_port_set_status(struct an8855_priv *priv, int port,
+                                 bool enable)
+{
+       if (enable)
+               return regmap_set_bits(priv->regmap, AN8855_PMCR_P(port),
+                                      AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+       else
+               return regmap_clear_bits(priv->regmap, AN8855_PMCR_P(port),
+                                        AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+}
+
+static int an8855_port_enable(struct dsa_switch *ds, int port,
+                             struct phy_device *phy)
+{
+       return an8855_port_set_status(ds->priv, port, true);
+}
+
+static void an8855_port_disable(struct dsa_switch *ds, int port)
+{
+       an8855_port_set_status(ds->priv, port, false);
+}
+
+static u32 en8855_get_phy_flags(struct dsa_switch *ds, int port)
+{
+       struct an8855_priv *priv = ds->priv;
+
+       /* PHY doesn't need calibration */
+       if (!priv->phy_require_calib)
+               return 0;
+
+       /* Use AN8855_PHY_FLAGS_EN_CALIBRATION to signal
+        * calibration needed.
+        */
+       return AN8855_PHY_FLAGS_EN_CALIBRATION;
+}
+
+static enum dsa_tag_protocol
+an8855_get_tag_protocol(struct dsa_switch *ds, int port,
+                       enum dsa_tag_protocol mp)
+{
+       return DSA_TAG_PROTO_MTK;
+}
+
+/* Similar to MT7530 also trap link local frame and special frame to CPU */
+static int an8855_trap_special_frames(struct an8855_priv *priv)
+{
+       int ret;
+
+       /* Trap BPDUs to the CPU port(s) and egress them
+        * VLAN-untagged.
+        */
+       ret = regmap_update_bits(priv->regmap, AN8855_BPC,
+                                AN8855_BPDU_BPDU_FR | AN8855_BPDU_EG_TAG |
+                                AN8855_BPDU_PORT_FW,
+                                AN8855_BPDU_BPDU_FR |
+                                FIELD_PREP(AN8855_BPDU_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+                                FIELD_PREP(AN8855_BPDU_PORT_FW, AN8855_BPDU_CPU_ONLY));
+       if (ret)
+               return ret;
+
+       /* Trap 802.1X PAE frames to the CPU port(s) and egress them
+        * VLAN-untagged.
+        */
+       ret = regmap_update_bits(priv->regmap, AN8855_PAC,
+                                AN8855_PAE_BPDU_FR | AN8855_PAE_EG_TAG |
+                                AN8855_PAE_PORT_FW,
+                                AN8855_PAE_BPDU_FR |
+                                FIELD_PREP(AN8855_PAE_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+                                FIELD_PREP(AN8855_PAE_PORT_FW, AN8855_BPDU_CPU_ONLY));
+       if (ret)
+               return ret;
+
+       /* Trap frames with :01 MAC DAs to the CPU port(s) and egress
+        * them VLAN-untagged.
+        */
+       ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+                                AN8855_R01_BPDU_FR | AN8855_R01_EG_TAG |
+                                AN8855_R01_PORT_FW,
+                                AN8855_R01_BPDU_FR |
+                                FIELD_PREP(AN8855_R01_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+                                FIELD_PREP(AN8855_R01_PORT_FW, AN8855_BPDU_CPU_ONLY));
+       if (ret)
+               return ret;
+
+       /* Trap frames with :02 MAC DAs to the CPU port(s) and egress
+        * them VLAN-untagged.
+        */
+       ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+                                AN8855_R02_BPDU_FR | AN8855_R02_EG_TAG |
+                                AN8855_R02_PORT_FW,
+                                AN8855_R02_BPDU_FR |
+                                FIELD_PREP(AN8855_R02_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+                                FIELD_PREP(AN8855_R02_PORT_FW, AN8855_BPDU_CPU_ONLY));
+       if (ret)
+               return ret;
+
+       /* Trap frames with :03 MAC DAs to the CPU port(s) and egress
+        * them VLAN-untagged.
+        */
+       ret = regmap_update_bits(priv->regmap, AN8855_RGAC1,
+                                AN8855_R03_BPDU_FR | AN8855_R03_EG_TAG |
+                                AN8855_R03_PORT_FW,
+                                AN8855_R03_BPDU_FR |
+                                FIELD_PREP(AN8855_R03_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+                                FIELD_PREP(AN8855_R03_PORT_FW, AN8855_BPDU_CPU_ONLY));
+       if (ret)
+               return ret;
+
+       /* Trap frames with :0E MAC DAs to the CPU port(s) and egress
+        * them VLAN-untagged.
+        */
+       return regmap_update_bits(priv->regmap, AN8855_RGAC1,
+                                 AN8855_R0E_BPDU_FR | AN8855_R0E_EG_TAG |
+                                 AN8855_R0E_PORT_FW,
+                                 AN8855_R0E_BPDU_FR |
+                                 FIELD_PREP(AN8855_R0E_EG_TAG, AN8855_VLAN_EG_UNTAGGED) |
+                                 FIELD_PREP(AN8855_R0E_PORT_FW, AN8855_BPDU_CPU_ONLY));
+}
+
+static int
+an8855_setup_pvid_vlan(struct an8855_priv *priv)
+{
+       u32 val;
+       int ret;
+
+       /* Validate the entry with independent learning, keep the original
+        * ingress tag attribute.
+        */
+       val = AN8855_VA0_IVL_MAC | AN8855_VA0_EG_CON |
+             FIELD_PREP(AN8855_VA0_FID, AN8855_FID_BRIDGED) |
+             AN8855_VA0_PORT | AN8855_VA0_VLAN_VALID;
+       ret = regmap_write(priv->regmap, AN8855_VAWD0, val);
+       if (ret)
+               return ret;
+
+       return an8855_vlan_cmd(priv, AN8855_VTCR_WR_VID,
+                              AN8855_PORT_VID_DEFAULT);
+}
+
+static int an8855_setup(struct dsa_switch *ds)
+{
+       struct an8855_priv *priv = ds->priv;
+       struct dsa_port *dp;
+       int ret;
+
+       /* Enable and reset MIB counters */
+       ret = an8855_mib_init(priv);
+       if (ret)
+               return ret;
+
+       dsa_switch_for_each_user_port(dp, ds) {
+               /* Disable MAC by default on all user ports */
+               ret = an8855_port_set_status(priv, dp->index, false);
+               if (ret)
+                       return ret;
+
+               /* Individual user ports get connected to CPU port only */
+               ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(dp->index),
+                                  FIELD_PREP(AN8855_PORTMATRIX, BIT(AN8855_CPU_PORT)));
+               if (ret)
+                       return ret;
+
+               /* Disable Broadcast Forward on user ports */
+               ret = regmap_clear_bits(priv->regmap, AN8855_BCF, BIT(dp->index));
+               if (ret)
+                       return ret;
+
+               /* Disable Unknown Unicast Forward on user ports */
+               ret = regmap_clear_bits(priv->regmap, AN8855_UNUF, BIT(dp->index));
+               if (ret)
+                       return ret;
+
+               /* Disable Unknown Multicast Forward on user ports */
+               ret = regmap_clear_bits(priv->regmap, AN8855_UNMF, BIT(dp->index));
+               if (ret)
+                       return ret;
+
+               ret = regmap_clear_bits(priv->regmap, AN8855_UNIPMF, BIT(dp->index));
+               if (ret)
+                       return ret;
+
+               /* Set default PVID to on all user ports */
+               ret = an8855_port_set_pid(priv, dp->index, AN8855_PORT_VID_DEFAULT);
+               if (ret)
+                       return ret;
+       }
+
+       /* Enable Airoha header mode on the cpu port */
+       ret = regmap_write(priv->regmap, AN8855_PVC_P(AN8855_CPU_PORT),
+                          AN8855_PORT_SPEC_REPLACE_MODE | AN8855_PORT_SPEC_TAG);
+       if (ret)
+               return ret;
+
+       /* Unknown multicast frame forwarding to the cpu port */
+       ret = regmap_write(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT));
+       if (ret)
+               return ret;
+
+       /* Set CPU port number */
+       ret = regmap_update_bits(priv->regmap, AN8855_MFC,
+                                AN8855_CPU_EN | AN8855_CPU_PORT_IDX,
+                                AN8855_CPU_EN |
+                                FIELD_PREP(AN8855_CPU_PORT_IDX, AN8855_CPU_PORT));
+       if (ret)
+               return ret;
+
+       /* CPU port gets connected to all user ports of
+        * the switch.
+        */
+       ret = regmap_write(priv->regmap, AN8855_PORTMATRIX_P(AN8855_CPU_PORT),
+                          FIELD_PREP(AN8855_PORTMATRIX, dsa_user_ports(ds)));
+       if (ret)
+               return ret;
+
+       /* CPU port is set to fallback mode to let untagged
+        * frames pass through.
+        */
+       ret = regmap_update_bits(priv->regmap, AN8855_PCR_P(AN8855_CPU_PORT),
+                                AN8855_PORT_VLAN,
+                                FIELD_PREP(AN8855_PORT_VLAN, AN8855_PORT_FALLBACK_MODE));
+       if (ret)
+               return ret;
+
+       /* Enable Broadcast Forward on CPU port */
+       ret = regmap_set_bits(priv->regmap, AN8855_BCF, BIT(AN8855_CPU_PORT));
+       if (ret)
+               return ret;
+
+       /* Enable Unknown Unicast Forward on CPU port */
+       ret = regmap_set_bits(priv->regmap, AN8855_UNUF, BIT(AN8855_CPU_PORT));
+       if (ret)
+               return ret;
+
+       /* Enable Unknown Multicast Forward on CPU port */
+       ret = regmap_set_bits(priv->regmap, AN8855_UNMF, BIT(AN8855_CPU_PORT));
+       if (ret)
+               return ret;
+
+       ret = regmap_set_bits(priv->regmap, AN8855_UNIPMF, BIT(AN8855_CPU_PORT));
+       if (ret)
+               return ret;
+
+       /* Setup Trap special frame to CPU rules */
+       ret = an8855_trap_special_frames(priv);
+       if (ret)
+               return ret;
+
+       dsa_switch_for_each_port(dp, ds) {
+               /* Disable Learning on all ports.
+                * Learning on CPU is disabled for fdb isolation and handled by
+                * assisted_learning_on_cpu_port.
+                */
+               ret = regmap_set_bits(priv->regmap, AN8855_PSC_P(dp->index),
+                                     AN8855_SA_DIS);
+               if (ret)
+                       return ret;
+
+               /* Enable consistent egress tag (for VLAN unware VLAN-passtrough) */
+               ret = regmap_update_bits(priv->regmap, AN8855_PVC_P(dp->index),
+                                        AN8855_PVC_EG_TAG,
+                                        FIELD_PREP(AN8855_PVC_EG_TAG, AN8855_VLAN_EG_CONSISTENT));
+               if (ret)
+                       return ret;
+       }
+
+       /* Setup VLAN for Default PVID */
+       ret = an8855_setup_pvid_vlan(priv);
+       if (ret)
+               return ret;
+
+       ret = regmap_clear_bits(priv->regmap, AN8855_CKGCR,
+                               AN8855_CKG_LNKDN_GLB_STOP | AN8855_CKG_LNKDN_PORT_STOP);
+       if (ret)
+               return ret;
+
+       /* Release global PHY power down */
+       ret = regmap_write(priv->regmap, AN8855_RG_GPHY_AFE_PWD, 0x0);
+       if (ret)
+               return ret;
+
+       ds->configure_vlan_while_not_filtering = true;
+
+       /* Flush the FDB table */
+       ret = an8855_fdb_cmd(priv, AN8855_FDB_FLUSH, NULL);
+       if (ret < 0)
+               return ret;
+
+       /* Set min a max ageing value supported */
+       ds->ageing_time_min = AN8855_L2_AGING_MS_CONSTANT;
+       ds->ageing_time_max = FIELD_MAX(AN8855_AGE_CNT) *
+                             FIELD_MAX(AN8855_AGE_UNIT) *
+                             AN8855_L2_AGING_MS_CONSTANT;
+
+       /* Enable assisted learning for fdb isolation */
+       ds->assisted_learning_on_cpu_port = true;
+
+       return 0;
+}
+
+static struct phylink_pcs *an8855_phylink_mac_select_pcs(struct phylink_config *config,
+                                                        phy_interface_t interface)
+{
+       struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct an8855_priv *priv = dp->ds->priv;
+
+       switch (interface) {
+       case PHY_INTERFACE_MODE_SGMII:
+       case PHY_INTERFACE_MODE_2500BASEX:
+               return &priv->pcs;
+       default:
+               return NULL;
+       }
+}
+
+static void an8855_phylink_mac_config(struct phylink_config *config,
+                                     unsigned int mode,
+                                     const struct phylink_link_state *state)
+{
+       struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       struct an8855_priv *priv;
+       int port = dp->index;
+
+       priv = ds->priv;
+
+       /* Nothing to configure for internal ports */
+       if (port != 5)
+               return;
+
+       regmap_update_bits(priv->regmap, AN8855_PMCR_P(port),
+                          AN8855_PMCR_IFG_XMIT | AN8855_PMCR_MAC_MODE |
+                          AN8855_PMCR_BACKOFF_EN | AN8855_PMCR_BACKPR_EN,
+                          FIELD_PREP(AN8855_PMCR_IFG_XMIT, 0x1) |
+                          AN8855_PMCR_MAC_MODE | AN8855_PMCR_BACKOFF_EN |
+                          AN8855_PMCR_BACKPR_EN);
+}
+
+static void an8855_phylink_get_caps(struct dsa_switch *ds, int port,
+                                   struct phylink_config *config)
+{
+       switch (port) {
+       case 0:
+       case 1:
+       case 2:
+       case 3:
+       case 4:
+               __set_bit(PHY_INTERFACE_MODE_GMII,
+                         config->supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+                         config->supported_interfaces);
+               break;
+       case 5:
+               phy_interface_set_rgmii(config->supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_SGMII,
+                         config->supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_2500BASEX,
+                         config->supported_interfaces);
+               break;
+       }
+
+       config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+                                  MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
+}
+
+static void an8855_phylink_mac_link_down(struct phylink_config *config,
+                                        unsigned int mode,
+                                        phy_interface_t interface)
+{
+       struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct an8855_priv *priv = dp->ds->priv;
+
+       /* With autoneg just disable TX/RX else also force link down */
+       if (phylink_autoneg_inband(mode)) {
+               regmap_clear_bits(priv->regmap, AN8855_PMCR_P(dp->index),
+                                 AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN);
+       } else {
+               regmap_update_bits(priv->regmap, AN8855_PMCR_P(dp->index),
+                                  AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN |
+                                  AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK,
+                                  AN8855_PMCR_FORCE_MODE);
+       }
+}
+
+static void an8855_phylink_mac_link_up(struct phylink_config *config,
+                                      struct phy_device *phydev, unsigned int mode,
+                                      phy_interface_t interface, int speed,
+                                      int duplex, bool tx_pause, bool rx_pause)
+{
+       struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct an8855_priv *priv = dp->ds->priv;
+       int port = dp->index;
+       u32 reg;
+
+       reg = regmap_read(priv->regmap, AN8855_PMCR_P(port), &reg);
+       if (phylink_autoneg_inband(mode)) {
+               reg &= ~AN8855_PMCR_FORCE_MODE;
+       } else {
+               reg |= AN8855_PMCR_FORCE_MODE | AN8855_PMCR_FORCE_LNK;
+
+               reg &= ~AN8855_PMCR_FORCE_SPEED;
+               switch (speed) {
+               case SPEED_10:
+                       reg |= AN8855_PMCR_FORCE_SPEED_10;
+                       break;
+               case SPEED_100:
+                       reg |= AN8855_PMCR_FORCE_SPEED_100;
+                       break;
+               case SPEED_1000:
+                       reg |= AN8855_PMCR_FORCE_SPEED_1000;
+                       break;
+               case SPEED_2500:
+                       reg |= AN8855_PMCR_FORCE_SPEED_2500;
+                       break;
+               case SPEED_5000:
+                       dev_err(priv->dev, "Missing support for 5G speed. Aborting...\n");
+                       return;
+               }
+
+               reg &= ~AN8855_PMCR_FORCE_FDX;
+               if (duplex == DUPLEX_FULL)
+                       reg |= AN8855_PMCR_FORCE_FDX;
+
+               reg &= ~AN8855_PMCR_RX_FC_EN;
+               if (rx_pause || dsa_port_is_cpu(dp))
+                       reg |= AN8855_PMCR_RX_FC_EN;
+
+               reg &= ~AN8855_PMCR_TX_FC_EN;
+               if (rx_pause || dsa_port_is_cpu(dp))
+                       reg |= AN8855_PMCR_TX_FC_EN;
+
+               /* Disable any EEE options */
+               reg &= ~(AN8855_PMCR_FORCE_EEE5G | AN8855_PMCR_FORCE_EEE2P5G |
+                        AN8855_PMCR_FORCE_EEE1G | AN8855_PMCR_FORCE_EEE100);
+       }
+
+       reg |= AN8855_PMCR_TX_EN | AN8855_PMCR_RX_EN;
+
+       regmap_write(priv->regmap, AN8855_PMCR_P(port), reg);
+}
+
+static unsigned int an8855_pcs_inband_caps(struct phylink_pcs *pcs,
+                                          phy_interface_t interface)
+{
+       /* SGMII can be configured to use inband with AN result */
+       if (interface == PHY_INTERFACE_MODE_SGMII)
+               return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+
+       /* inband is not supported in 2500-baseX and must be disabled */
+       return  LINK_INBAND_DISABLE;
+}
+
+static void an8855_pcs_get_state(struct phylink_pcs *pcs,
+                                struct phylink_link_state *state)
+{
+       struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
+       u32 val;
+       int ret;
+
+       ret = regmap_read(priv->regmap, AN8855_PMSR_P(AN8855_CPU_PORT), &val);
+       if (ret < 0) {
+               state->link = false;
+               return;
+       }
+
+       state->link = !!(val & AN8855_PMSR_LNK);
+       state->an_complete = state->link;
+       state->duplex = (val & AN8855_PMSR_DPX) ? DUPLEX_FULL :
+                                                 DUPLEX_HALF;
+
+       switch (val & AN8855_PMSR_SPEED) {
+       case AN8855_PMSR_SPEED_10:
+               state->speed = SPEED_10;
+               break;
+       case AN8855_PMSR_SPEED_100:
+               state->speed = SPEED_100;
+               break;
+       case AN8855_PMSR_SPEED_1000:
+               state->speed = SPEED_1000;
+               break;
+       case AN8855_PMSR_SPEED_2500:
+               state->speed = SPEED_2500;
+               break;
+       case AN8855_PMSR_SPEED_5000:
+               dev_err(priv->dev, "Missing support for 5G speed. Setting Unknown.\n");
+               fallthrough;
+       default:
+               state->speed = SPEED_UNKNOWN;
+               break;
+       }
+
+       if (val & AN8855_PMSR_RX_FC)
+               state->pause |= MLO_PAUSE_RX;
+       if (val & AN8855_PMSR_TX_FC)
+               state->pause |= MLO_PAUSE_TX;
+}
+
+static int an8855_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+                            phy_interface_t interface,
+                            const unsigned long *advertising,
+                            bool permit_pause_to_mac)
+{
+       struct an8855_priv *priv = container_of(pcs, struct an8855_priv, pcs);
+       u32 val;
+       int ret;
+
+       /*                   !!! WELCOME TO HELL !!!                   */
+
+       /* TX FIR - improve TX EYE */
+       ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_10,
+                                AN8855_RG_DA_QP_TX_FIR_C2_SEL |
+                                AN8855_RG_DA_QP_TX_FIR_C2_FORCE |
+                                AN8855_RG_DA_QP_TX_FIR_C1_SEL |
+                                AN8855_RG_DA_QP_TX_FIR_C1_FORCE,
+                                AN8855_RG_DA_QP_TX_FIR_C2_SEL |
+                                FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C2_FORCE, 0x4) |
+                                AN8855_RG_DA_QP_TX_FIR_C1_SEL |
+                                FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C1_FORCE, 0x0));
+       if (ret)
+               return ret;
+
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0x0;
+       else
+               val = 0xd;
+       ret = regmap_update_bits(priv->regmap, AN8855_INTF_CTRL_11,
+                                AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
+                                AN8855_RG_DA_QP_TX_FIR_C0B_FORCE,
+                                AN8855_RG_DA_QP_TX_FIR_C0B_SEL |
+                                FIELD_PREP(AN8855_RG_DA_QP_TX_FIR_C0B_FORCE, val));
+       if (ret)
+               return ret;
+
+       /* RX CDR - improve RX Jitter Tolerance */
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0x5;
+       else
+               val = 0x6;
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_BOT_LIM,
+                                AN8855_RG_QP_CDR_LPF_KP_GAIN |
+                                AN8855_RG_QP_CDR_LPF_KI_GAIN,
+                                FIELD_PREP(AN8855_RG_QP_CDR_LPF_KP_GAIN, val) |
+                                FIELD_PREP(AN8855_RG_QP_CDR_LPF_KI_GAIN, val));
+       if (ret)
+               return ret;
+
+       /* PLL */
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0x1;
+       else
+               val = 0x0;
+       ret = regmap_update_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_1,
+                                AN8855_RG_TPHY_SPEED,
+                                FIELD_PREP(AN8855_RG_TPHY_SPEED, val));
+       if (ret)
+               return ret;
+
+       /* PLL - LPF */
+       ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+                                AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
+                                AN8855_RG_DA_QP_PLL_FBKSEL_INTF |
+                                AN8855_RG_DA_QP_PLL_BR_INTF |
+                                AN8855_RG_DA_QP_PLL_BPD_INTF |
+                                AN8855_RG_DA_QP_PLL_BPA_INTF |
+                                AN8855_RG_DA_QP_PLL_BC_INTF,
+                                AN8855_RG_DA_QP_PLL_RICO_SEL_INTF |
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_FBKSEL_INTF, 0x0) |
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_BR_INTF, 0x3) |
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_BPD_INTF, 0x0) |
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_BPA_INTF, 0x5) |
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_BC_INTF, 0x1));
+       if (ret)
+               return ret;
+
+       /* PLL - ICO */
+       ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_4,
+                             AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF);
+       if (ret)
+               return ret;
+       ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
+                               AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF);
+       if (ret)
+               return ret;
+
+       /* PLL - CHP */
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0x6;
+       else
+               val = 0x4;
+       ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+                                AN8855_RG_DA_QP_PLL_IR_INTF,
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_IR_INTF, val));
+       if (ret)
+               return ret;
+
+       /* PLL - PFD */
+       ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+                                AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF |
+                                AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF |
+                                AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF,
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF, 0x1) |
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF, 0x1));
+       if (ret)
+               return ret;
+
+       /* PLL - POSTDIV */
+       ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+                                AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF |
+                                AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF |
+                                AN8855_RG_DA_QP_PLL_PCK_SEL_INTF,
+                                AN8855_RG_DA_QP_PLL_PCK_SEL_INTF);
+       if (ret)
+               return ret;
+
+       /* PLL - SDM */
+       ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_2,
+                                AN8855_RG_DA_QP_PLL_SDM_HREN_INTF,
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_SDM_HREN_INTF, 0x0));
+       if (ret)
+               return ret;
+       ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CTRL_2,
+                               AN8855_RG_DA_QP_PLL_SDM_IFM_INTF);
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_SS_LCPLL_PWCTL_SETTING_2,
+                                AN8855_RG_NCPO_ANA_MSB,
+                                FIELD_PREP(AN8855_RG_NCPO_ANA_MSB, 0x1));
+       if (ret)
+               return ret;
+
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0x7a000000;
+       else
+               val = 0x48000000;
+       ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_2,
+                          FIELD_PREP(AN8855_RG_LCPLL_NCPO_VALUE, val));
+       if (ret)
+               return ret;
+       ret = regmap_write(priv->regmap, AN8855_SS_LCPLL_TDC_PCW_1,
+                          FIELD_PREP(AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON, val));
+       if (ret)
+               return ret;
+
+       ret = regmap_clear_bits(priv->regmap, AN8855_SS_LCPLL_TDC_FLT_5,
+                               AN8855_RG_LCPLL_NCPO_CHG);
+       if (ret)
+               return ret;
+       ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
+                               AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF);
+       if (ret)
+               return ret;
+
+       /* PLL - SS */
+       ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
+                                AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF,
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF, 0x0));
+       if (ret)
+               return ret;
+       ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_4,
+                                AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF,
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF, 0x0));
+       if (ret)
+               return ret;
+       ret = regmap_update_bits(priv->regmap, AN8855_PLL_CTRL_3,
+                                AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF,
+                                FIELD_PREP(AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF, 0x0));
+       if (ret)
+               return ret;
+
+       /* PLL - TDC */
+       ret = regmap_clear_bits(priv->regmap, AN8855_PLL_CK_CTRL_0,
+                               AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF);
+       if (ret)
+               return ret;
+
+       ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
+                             AN8855_RG_QP_PLL_SSC_TRI_EN);
+       if (ret)
+               return ret;
+       ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_PLL_SDM_ORD,
+                             AN8855_RG_QP_PLL_SSC_PHASE_INI);
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_RX_DAC_EN,
+                                AN8855_RG_QP_SIGDET_HF,
+                                FIELD_PREP(AN8855_RG_QP_SIGDET_HF, 0x2));
+       if (ret)
+               return ret;
+
+       /* TCL Disable (only for Co-SIM) */
+       ret = regmap_clear_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_0,
+                               AN8855_RG_QP_EQ_RX500M_CK_SEL);
+       if (ret)
+               return ret;
+
+       /* TX Init */
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0x4;
+       else
+               val = 0x0;
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_TX_MODE,
+                                AN8855_RG_QP_TX_RESERVE |
+                                AN8855_RG_QP_TX_MODE_16B_EN,
+                                FIELD_PREP(AN8855_RG_QP_TX_RESERVE, val));
+       if (ret)
+               return ret;
+
+       /* RX Control/Init */
+       ret = regmap_set_bits(priv->regmap, AN8855_RG_QP_RXAFE_RESERVE,
+                             AN8855_RG_QP_CDR_PD_10B_EN);
+       if (ret)
+               return ret;
+
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0x1;
+       else
+               val = 0x2;
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_MJV_LIM,
+                                AN8855_RG_QP_CDR_LPF_RATIO,
+                                FIELD_PREP(AN8855_RG_QP_CDR_LPF_RATIO, val));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_LPF_SETVALUE,
+                                AN8855_RG_QP_CDR_PR_BUF_IN_SR |
+                                AN8855_RG_QP_CDR_PR_BETA_SEL,
+                                FIELD_PREP(AN8855_RG_QP_CDR_PR_BUF_IN_SR, 0x6) |
+                                FIELD_PREP(AN8855_RG_QP_CDR_PR_BETA_SEL, 0x1));
+       if (ret)
+               return ret;
+
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0xf;
+       else
+               val = 0xc;
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
+                                AN8855_RG_QP_CDR_PR_DAC_BAND,
+                                FIELD_PREP(AN8855_RG_QP_CDR_PR_DAC_BAND, val));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
+                                AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE |
+                                AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK,
+                                FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK, 0x19));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF,
+                                AN8855_RG_QP_CDR_PHYCK_SEL |
+                                AN8855_RG_QP_CDR_PHYCK_RSTB |
+                                AN8855_RG_QP_CDR_PHYCK_DIV,
+                                FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_SEL, 0x2) |
+                                FIELD_PREP(AN8855_RG_QP_CDR_PHYCK_DIV, 0x21));
+       if (ret)
+               return ret;
+
+       ret = regmap_clear_bits(priv->regmap, AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE,
+                               AN8855_RG_QP_CDR_PR_XFICK_EN);
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RG_QP_CDR_PR_CKREF_DIV1,
+                                AN8855_RG_QP_CDR_PR_KBAND_DIV,
+                                FIELD_PREP(AN8855_RG_QP_CDR_PR_KBAND_DIV, 0x4));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_26,
+                                AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
+                                AN8855_RG_LINK_NE_EN |
+                                AN8855_RG_LINK_ERRO_EN,
+                                AN8855_RG_QP_EQ_RETRAIN_ONLY_EN |
+                                AN8855_RG_LINK_ERRO_EN);
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RX_DLY_0,
+                                AN8855_RG_QP_RX_SAOSC_EN_H_DLY |
+                                AN8855_RG_QP_RX_PI_CAL_EN_H_DLY,
+                                FIELD_PREP(AN8855_RG_QP_RX_SAOSC_EN_H_DLY, 0x3f) |
+                                FIELD_PREP(AN8855_RG_QP_RX_PI_CAL_EN_H_DLY, 0x6f));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_42,
+                                AN8855_RG_QP_EQ_EN_DLY,
+                                FIELD_PREP(AN8855_RG_QP_EQ_EN_DLY, 0x150));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_2,
+                                AN8855_RG_QP_RX_EQ_EN_H_DLY,
+                                FIELD_PREP(AN8855_RG_QP_RX_EQ_EN_H_DLY, 0x150));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_PON_RXFEDIG_CTRL_9,
+                                AN8855_RG_QP_EQ_LEQOSC_DLYCNT,
+                                FIELD_PREP(AN8855_RG_QP_EQ_LEQOSC_DLYCNT, 0x1));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_8,
+                                AN8855_RG_DA_QP_SAOSC_DONE_TIME |
+                                AN8855_RG_DA_QP_LEQOS_EN_TIME,
+                                FIELD_PREP(AN8855_RG_DA_QP_SAOSC_DONE_TIME, 0x200) |
+                                FIELD_PREP(AN8855_RG_DA_QP_LEQOS_EN_TIME, 0xfff));
+       if (ret)
+               return ret;
+
+       /* Frequency meter */
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val = 0x10;
+       else
+               val = 0x28;
+       ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_5,
+                                AN8855_RG_FREDET_CHK_CYCLE,
+                                FIELD_PREP(AN8855_RG_FREDET_CHK_CYCLE, val));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_6,
+                                AN8855_RG_FREDET_GOLDEN_CYCLE,
+                                FIELD_PREP(AN8855_RG_FREDET_GOLDEN_CYCLE, 0x64));
+       if (ret)
+               return ret;
+
+       ret = regmap_update_bits(priv->regmap, AN8855_RX_CTRL_7,
+                                AN8855_RG_FREDET_TOLERATE_CYCLE,
+                                FIELD_PREP(AN8855_RG_FREDET_TOLERATE_CYCLE, 0x2710));
+       if (ret)
+               return ret;
+
+       ret = regmap_set_bits(priv->regmap, AN8855_PLL_CTRL_0,
+                             AN8855_RG_PHYA_AUTO_INIT);
+       if (ret)
+               return ret;
+
+       /* PCS Init */
+       if (interface == PHY_INTERFACE_MODE_SGMII &&
+           neg_mode == PHYLINK_PCS_NEG_INBAND_DISABLED) {
+               ret = regmap_clear_bits(priv->regmap, AN8855_QP_DIG_MODE_CTRL_0,
+                                       AN8855_RG_SGMII_MODE | AN8855_RG_SGMII_AN_EN);
+               if (ret)
+                       return ret;
+       }
+
+       ret = regmap_clear_bits(priv->regmap, AN8855_RG_HSGMII_PCS_CTROL_1,
+                               AN8855_RG_TBI_10B_MODE);
+       if (ret)
+               return ret;
+
+       if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+               /* Set AN Ability - Interrupt */
+               ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN_FORCE_CL37,
+                                     AN8855_RG_FORCE_AN_DONE);
+               if (ret)
+                       return ret;
+
+               ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN_13,
+                                        AN8855_SGMII_REMOTE_FAULT_DIS |
+                                        AN8855_SGMII_IF_MODE,
+                                        AN8855_SGMII_REMOTE_FAULT_DIS |
+                                        FIELD_PREP(AN8855_SGMII_IF_MODE, 0xb));
+               if (ret)
+                       return ret;
+       }
+
+       /* Rate Adaption - GMII path config. */
+       if (interface == PHY_INTERFACE_MODE_2500BASEX) {
+               ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+                                       AN8855_RG_P0_DIS_MII_MODE);
+               if (ret)
+                       return ret;
+       } else {
+               if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+                       ret = regmap_set_bits(priv->regmap, AN8855_MII_RA_AN_ENABLE,
+                                             AN8855_RG_P0_RA_AN_EN);
+                       if (ret)
+                               return ret;
+               } else {
+                       ret = regmap_update_bits(priv->regmap, AN8855_RG_AN_SGMII_MODE_FORCE,
+                                                AN8855_RG_FORCE_CUR_SGMII_MODE |
+                                                AN8855_RG_FORCE_CUR_SGMII_SEL,
+                                                AN8855_RG_FORCE_CUR_SGMII_SEL);
+                       if (ret)
+                               return ret;
+
+                       ret = regmap_clear_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+                                               AN8855_RG_P0_MII_RA_RX_EN |
+                                               AN8855_RG_P0_MII_RA_TX_EN |
+                                               AN8855_RG_P0_MII_RA_RX_MODE |
+                                               AN8855_RG_P0_MII_RA_TX_MODE);
+                       if (ret)
+                               return ret;
+               }
+
+               ret = regmap_set_bits(priv->regmap, AN8855_RATE_ADP_P0_CTRL_0,
+                                     AN8855_RG_P0_MII_MODE);
+               if (ret)
+                       return ret;
+       }
+
+       ret = regmap_set_bits(priv->regmap, AN8855_RG_RATE_ADAPT_CTRL_0,
+                             AN8855_RG_RATE_ADAPT_RX_BYPASS |
+                             AN8855_RG_RATE_ADAPT_TX_BYPASS |
+                             AN8855_RG_RATE_ADAPT_RX_EN |
+                             AN8855_RG_RATE_ADAPT_TX_EN);
+       if (ret)
+               return ret;
+
+       /* Disable AN if not in autoneg */
+       ret = regmap_update_bits(priv->regmap, AN8855_SGMII_REG_AN0, BMCR_ANENABLE,
+                                neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE :
+                                                                             0);
+       if (ret)
+               return ret;
+
+       if (interface == PHY_INTERFACE_MODE_SGMII) {
+               /* Follow SDK init flow with restarting AN after AN enable */
+               if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+                       ret = regmap_set_bits(priv->regmap, AN8855_SGMII_REG_AN0,
+                                             BMCR_ANRESTART);
+                       if (ret)
+                               return ret;
+               } else {
+                       ret = regmap_set_bits(priv->regmap, AN8855_PHY_RX_FORCE_CTRL_0,
+                                             AN8855_RG_FORCE_TXC_SEL);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       /* Force Speed with fixed-link or 2500base-x as doesn't support aneg */
+       if (interface == PHY_INTERFACE_MODE_2500BASEX ||
+           neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) {
+               if (interface == PHY_INTERFACE_MODE_2500BASEX)
+                       val = AN8855_RG_LINK_MODE_P0_SPEED_2500;
+               else
+                       val = AN8855_RG_LINK_MODE_P0_SPEED_1000;
+               ret = regmap_update_bits(priv->regmap, AN8855_SGMII_STS_CTRL_0,
+                                        AN8855_RG_LINK_MODE_P0 |
+                                        AN8855_RG_FORCE_SPD_MODE_P0,
+                                        val | AN8855_RG_FORCE_SPD_MODE_P0);
+               if (ret)
+                       return ret;
+       }
+
+       /* bypass flow control to MAC */
+       ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_0,
+                          AN8855_RG_DPX_STS_P3 | AN8855_RG_DPX_STS_P2 |
+                          AN8855_RG_DPX_STS_P1 | AN8855_RG_TXFC_STS_P0 |
+                          AN8855_RG_RXFC_STS_P0 | AN8855_RG_DPX_STS_P0);
+       if (ret)
+               return ret;
+       ret = regmap_write(priv->regmap, AN8855_MSG_RX_LIK_STS_2,
+                          AN8855_RG_RXFC_AN_BYPASS_P3 |
+                          AN8855_RG_RXFC_AN_BYPASS_P2 |
+                          AN8855_RG_RXFC_AN_BYPASS_P1 |
+                          AN8855_RG_TXFC_AN_BYPASS_P3 |
+                          AN8855_RG_TXFC_AN_BYPASS_P2 |
+                          AN8855_RG_TXFC_AN_BYPASS_P1 |
+                          AN8855_RG_DPX_AN_BYPASS_P3 |
+                          AN8855_RG_DPX_AN_BYPASS_P2 |
+                          AN8855_RG_DPX_AN_BYPASS_P1 |
+                          AN8855_RG_DPX_AN_BYPASS_P0);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static void an8855_pcs_an_restart(struct phylink_pcs *pcs)
+{
+       return;
+}
+
+static const struct phylink_pcs_ops an8855_pcs_ops = {
+       .pcs_inband_caps = an8855_pcs_inband_caps,
+       .pcs_get_state = an8855_pcs_get_state,
+       .pcs_config = an8855_pcs_config,
+       .pcs_an_restart = an8855_pcs_an_restart,
+};
+
+static const struct phylink_mac_ops an8855_phylink_mac_ops = {
+       .mac_select_pcs = an8855_phylink_mac_select_pcs,
+       .mac_config     = an8855_phylink_mac_config,
+       .mac_link_down  = an8855_phylink_mac_link_down,
+       .mac_link_up    = an8855_phylink_mac_link_up,
+};
+
+static const struct dsa_switch_ops an8855_switch_ops = {
+       .get_tag_protocol = an8855_get_tag_protocol,
+       .setup = an8855_setup,
+       .get_phy_flags = en8855_get_phy_flags,
+       .phylink_get_caps = an8855_phylink_get_caps,
+       .get_strings = an8855_get_strings,
+       .get_ethtool_stats = an8855_get_ethtool_stats,
+       .get_sset_count = an8855_get_sset_count,
+       .get_eth_mac_stats = an8855_get_eth_mac_stats,
+       .get_eth_ctrl_stats = an8855_get_eth_ctrl_stats,
+       .get_rmon_stats = an8855_get_rmon_stats,
+       .port_enable = an8855_port_enable,
+       .port_disable = an8855_port_disable,
+       .set_ageing_time = an8855_set_ageing_time,
+       .port_bridge_join = an8855_port_bridge_join,
+       .port_bridge_leave = an8855_port_bridge_leave,
+       .port_fast_age = an8855_port_fast_age,
+       .port_stp_state_set = an8855_port_stp_state_set,
+       .port_pre_bridge_flags = an8855_port_pre_bridge_flags,
+       .port_bridge_flags = an8855_port_bridge_flags,
+       .port_vlan_filtering = an8855_port_vlan_filtering,
+       .port_vlan_add = an8855_port_vlan_add,
+       .port_vlan_del = an8855_port_vlan_del,
+       .port_fdb_add = an8855_port_fdb_add,
+       .port_fdb_del = an8855_port_fdb_del,
+       .port_fdb_dump = an8855_port_fdb_dump,
+       .port_mdb_add = an8855_port_mdb_add,
+       .port_mdb_del = an8855_port_mdb_del,
+       .port_change_mtu = an8855_port_change_mtu,
+       .port_max_mtu = an8855_port_max_mtu,
+       .port_mirror_add = an8855_port_mirror_add,
+       .port_mirror_del = an8855_port_mirror_del,
+};
+
+static int an8855_read_switch_id(struct an8855_priv *priv)
+{
+       u32 id;
+       int ret;
+
+       ret = regmap_read(priv->regmap, AN8855_CREV, &id);
+       if (ret)
+               return ret;
+
+       if (id != AN8855_ID) {
+               dev_err(priv->dev,
+                       "Switch id detected %x but expected %x\n",
+                       id, AN8855_ID);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int an8855_switch_probe(struct platform_device *pdev)
+{
+       struct an8855_priv *priv;
+       u32 val;
+       int ret;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->dev = &pdev->dev;
+       priv->phy_require_calib = of_property_read_bool(priv->dev->of_node,
+                                                       "airoha,ext-surge");
+
+       priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
+                                                  GPIOD_OUT_LOW);
+       if (IS_ERR(priv->reset_gpio))
+               return PTR_ERR(priv->reset_gpio);
+
+       /* Get regmap from MFD */
+       priv->regmap = dev_get_regmap(priv->dev->parent, NULL);
+
+       if (priv->reset_gpio) {
+               usleep_range(100000, 150000);
+               gpiod_set_value_cansleep(priv->reset_gpio, 0);
+               usleep_range(100000, 150000);
+               gpiod_set_value_cansleep(priv->reset_gpio, 1);
+
+               /* Poll HWTRAP reg to wait for Switch to fully Init */
+               ret = regmap_read_poll_timeout(priv->regmap, AN8855_HWTRAP, val,
+                                              val, 20, 200000);
+               if (ret)
+                       return ret;
+       }
+
+       ret = an8855_read_switch_id(priv);
+       if (ret)
+               return ret;
+
+       priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
+       if (!priv->ds)
+               return -ENOMEM;
+
+       priv->ds->dev = priv->dev;
+       priv->ds->num_ports = AN8855_NUM_PORTS;
+       priv->ds->priv = priv;
+       priv->ds->ops = &an8855_switch_ops;
+       devm_mutex_init(priv->dev, &priv->reg_mutex);
+       priv->ds->phylink_mac_ops = &an8855_phylink_mac_ops;
+
+       priv->pcs.ops = &an8855_pcs_ops;
+       priv->pcs.neg_mode = true;
+       priv->pcs.poll = true;
+
+       dev_set_drvdata(priv->dev, priv);
+
+       return dsa_register_switch(priv->ds);
+}
+
+static void an8855_switch_remove(struct platform_device *pdev)
+{
+       struct an8855_priv *priv = dev_get_drvdata(&pdev->dev);
+
+       if (priv)
+               dsa_unregister_switch(priv->ds);
+}
+
+static const struct of_device_id an8855_switch_of_match[] = {
+       { .compatible = "airoha,an8855-switch" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_switch_of_match);
+
+static struct platform_driver an8855_switch_driver = {
+       .probe = an8855_switch_probe,
+       .remove_new = an8855_switch_remove,
+       .driver = {
+               .name = "an8855-switch",
+               .of_match_table = an8855_switch_of_match,
+       },
+};
+module_platform_driver(an8855_switch_driver);
+
+MODULE_AUTHOR("Min Yao <min.yao@airoha.com>");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_DESCRIPTION("Driver for Airoha AN8855 Switch");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/files-6.12/drivers/net/dsa/an8855.h b/target/linux/mediatek/files-6.12/drivers/net/dsa/an8855.h
new file mode 100644 (file)
index 0000000..2462b9d
--- /dev/null
@@ -0,0 +1,783 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023 Min Yao <min.yao@airoha.com>
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth@gmail.com>
+ */
+
+#ifndef __AN8855_H
+#define __AN8855_H
+
+#include <linux/bitfield.h>
+
+#define AN8855_NUM_PORTS               6
+#define AN8855_CPU_PORT                        5
+#define AN8855_NUM_FDB_RECORDS         2048
+#define AN8855_GPHY_SMI_ADDR_DEFAULT   1
+#define AN8855_PORT_VID_DEFAULT                0
+
+#define MTK_TAG_LEN                    4
+#define AN8855_MAX_MTU                 (15360 - ETH_HLEN - ETH_FCS_LEN - MTK_TAG_LEN)
+
+#define AN8855_L2_AGING_MS_CONSTANT    1024
+
+#define AN8855_PHY_FLAGS_EN_CALIBRATION        BIT(0)
+
+/*     AN8855_SCU                      0x10000000 */
+#define AN8855_RG_GPIO_LED_MODE                0x10000054
+#define AN8855_RG_GPIO_LED_SEL(i)      (0x10000000 + (0x0058 + ((i) * 4)))
+#define AN8855_RG_INTB_MODE            0x10000080
+#define AN8855_RG_RGMII_TXCK_C         0x100001d0
+
+#define AN8855_PKG_SEL                 0x10000094
+#define   AN8855_PAG_SEL_AN8855H       0x2
+
+/* Register for hw trap status */
+#define AN8855_HWTRAP                  0x1000009c
+
+#define AN8855_RG_GPIO_L_INV           0x10000010
+#define AN8855_RG_GPIO_CTRL            0x1000a300
+#define AN8855_RG_GPIO_DATA            0x1000a304
+#define AN8855_RG_GPIO_OE              0x1000a314
+
+#define AN8855_CREV                    0x10005000
+#define   AN8855_ID                    0x8855
+
+/* Register for system reset */
+#define AN8855_RST_CTRL                        0x100050c0
+#define   AN8855_SYS_CTRL_SYS_RST      BIT(31)
+
+#define AN8855_INT_MASK                        0x100050f0
+#define   AN8855_INT_SYS               BIT(15)
+
+#define AN8855_RG_CLK_CPU_ICG          0x10005034
+#define   AN8855_MCU_ENABLE            BIT(3)
+
+#define AN8855_RG_TIMER_CTL            0x1000a100
+#define   AN8855_WDOG_ENABLE           BIT(25)
+
+#define AN8855_RG_GDMP_RAM             0x10010000
+
+/* Registers to mac forward control for unknown frames */
+#define AN8855_MFC                     0x10200010
+#define   AN8855_CPU_EN                        BIT(15)
+#define   AN8855_CPU_PORT_IDX          GENMASK(12, 8)
+
+#define AN8855_PAC                     0x10200024
+#define   AN8855_TAG_PAE_MANG_FR       BIT(30)
+#define   AN8855_TAG_PAE_BPDU_FR       BIT(28)
+#define   AN8855_TAG_PAE_EG_TAG                GENMASK(27, 25)
+#define   AN8855_TAG_PAE_LKY_VLAN      BIT(24)
+#define   AN8855_TAG_PAE_PRI_HIGH      BIT(23)
+#define   AN8855_TAG_PAE_MIR           GENMASK(20, 19)
+#define   AN8855_TAG_PAE_PORT_FW       GENMASK(18, 16)
+#define   AN8855_PAE_MANG_FR           BIT(14)
+#define   AN8855_PAE_BPDU_FR           BIT(12)
+#define   AN8855_PAE_EG_TAG            GENMASK(11, 9)
+#define   AN8855_PAE_LKY_VLAN          BIT(8)
+#define   AN8855_PAE_PRI_HIGH          BIT(7)
+#define   AN8855_PAE_MIR               GENMASK(4, 3)
+#define   AN8855_PAE_PORT_FW           GENMASK(2, 0)
+
+#define AN8855_RGAC1                   0x10200028
+#define   AN8855_R02_MANG_FR           BIT(30)
+#define   AN8855_R02_BPDU_FR           BIT(28)
+#define   AN8855_R02_EG_TAG            GENMASK(27, 25)
+#define   AN8855_R02_LKY_VLAN          BIT(24)
+#define   AN8855_R02_PRI_HIGH          BIT(23)
+#define   AN8855_R02_MIR               GENMASK(20, 19)
+#define   AN8855_R02_PORT_FW           GENMASK(18, 16)
+#define   AN8855_R01_MANG_FR           BIT(14)
+#define   AN8855_R01_BPDU_FR           BIT(12)
+#define   AN8855_R01_EG_TAG            GENMASK(11, 9)
+#define   AN8855_R01_LKY_VLAN          BIT(8)
+#define   AN8855_R01_PRI_HIGH          BIT(7)
+#define   AN8855_R01_MIR               GENMASK(4, 3)
+#define   AN8855_R01_PORT_FW           GENMASK(2, 0)
+
+#define AN8855_RGAC2                   0x1020002c
+#define   AN8855_R0E_MANG_FR           BIT(30)
+#define   AN8855_R0E_BPDU_FR           BIT(28)
+#define   AN8855_R0E_EG_TAG            GENMASK(27, 25)
+#define   AN8855_R0E_LKY_VLAN          BIT(24)
+#define   AN8855_R0E_PRI_HIGH          BIT(23)
+#define   AN8855_R0E_MIR               GENMASK(20, 19)
+#define   AN8855_R0E_PORT_FW           GENMASK(18, 16)
+#define   AN8855_R03_MANG_FR           BIT(14)
+#define   AN8855_R03_BPDU_FR           BIT(12)
+#define   AN8855_R03_EG_TAG            GENMASK(11, 9)
+#define   AN8855_R03_LKY_VLAN          BIT(8)
+#define   AN8855_R03_PRI_HIGH          BIT(7)
+#define   AN8855_R03_MIR               GENMASK(4, 3)
+#define   AN8855_R03_PORT_FW           GENMASK(2, 0)
+
+#define AN8855_AAC                     0x102000a0
+#define   AN8855_MAC_AUTO_FLUSH                BIT(28)
+/* Control Address Table Age time.
+ * (AN8855_AGE_CNT + 1) * ( AN8855_AGE_UNIT + 1 ) * AN8855_L2_AGING_MS_CONSTANT
+ */
+#define   AN8855_AGE_CNT               GENMASK(20, 12)
+/* Value in seconds. Value is always incremented of 1 */
+#define   AN8855_AGE_UNIT              GENMASK(10, 0)
+
+/* Registers for ARL Unknown Unicast Forward control */
+#define AN8855_UNUF                    0x102000b4
+
+/* Registers for ARL Unknown Multicast Forward control */
+#define AN8855_UNMF                    0x102000b8
+
+/* Registers for ARL Broadcast forward control */
+#define AN8855_BCF                     0x102000bc
+
+/* Registers for port address age disable */
+#define AN8855_AGDIS                   0x102000c0
+
+/* Registers for mirror port control */
+#define AN8855_MIR                     0x102000cc
+#define   AN8855_MIRROR_EN             BIT(7)
+#define   AN8855_MIRROR_PORT           GENMASK(4, 0)
+
+/* Registers for BPDU and PAE frame control*/
+#define AN8855_BPC                     0x102000d0
+#define   AN8855_BPDU_MANG_FR          BIT(14)
+#define   AN8855_BPDU_BPDU_FR          BIT(12)
+#define   AN8855_BPDU_EG_TAG           GENMASK(11, 9)
+#define   AN8855_BPDU_LKY_VLAN         BIT(8)
+#define   AN8855_BPDU_PRI_HIGH         BIT(7)
+#define   AN8855_BPDU_MIR              GENMASK(4, 3)
+#define   AN8855_BPDU_PORT_FW          GENMASK(2, 0)
+
+/* Registers for IP Unknown Multicast Forward control */
+#define AN8855_UNIPMF                  0x102000dc
+
+enum an8855_bpdu_port_fw {
+       AN8855_BPDU_FOLLOW_MFC = 0,
+       AN8855_BPDU_CPU_EXCLUDE = 4,
+       AN8855_BPDU_CPU_INCLUDE = 5,
+       AN8855_BPDU_CPU_ONLY = 6,
+       AN8855_BPDU_DROP = 7,
+};
+
+/* Register for address table control */
+#define AN8855_ATC                     0x10200300
+#define   AN8855_ATC_BUSY              BIT(31)
+#define   AN8855_ATC_HASH              GENMASK(24, 16)
+#define   AN8855_ATC_HIT               GENMASK(15, 12)
+#define   AN8855_ATC_MAT_MASK          GENMASK(11, 7)
+#define   AN8855_ATC_MAT(x)            FIELD_PREP(AN8855_ATC_MAT_MASK, x)
+#define   AN8855_ATC_SAT               GENMASK(5, 4)
+#define   AN8855_ATC_CMD               GENMASK(2, 0)
+
+enum an8855_fdb_mat_cmds {
+       AND8855_FDB_MAT_ALL = 0,
+       AND8855_FDB_MAT_MAC, /* All MAC address */
+       AND8855_FDB_MAT_DYNAMIC_MAC, /* All Dynamic MAC address */
+       AND8855_FDB_MAT_STATIC_MAC, /* All Static Mac Address */
+       AND8855_FDB_MAT_DIP, /* All DIP/GA address */
+       AND8855_FDB_MAT_DIP_IPV4, /* All DIP/GA IPv4 address */
+       AND8855_FDB_MAT_DIP_IPV6, /* All DIP/GA IPv6 address */
+       AND8855_FDB_MAT_DIP_SIP, /* All DIP_SIP address */
+       AND8855_FDB_MAT_DIP_SIP_IPV4, /* All DIP_SIP IPv4 address */
+       AND8855_FDB_MAT_DIP_SIP_IPV6, /* All DIP_SIP IPv6 address */
+       AND8855_FDB_MAT_MAC_CVID, /* All MAC address with CVID */
+       AND8855_FDB_MAT_MAC_FID, /* All MAC address with Filter ID */
+       AND8855_FDB_MAT_MAC_PORT, /* All MAC address with port */
+       AND8855_FDB_MAT_DIP_SIP_DIP_IPV4, /* All DIP_SIP address with DIP_IPV4 */
+       AND8855_FDB_MAT_DIP_SIP_SIP_IPV4, /* All DIP_SIP address with SIP_IPV4 */
+       AND8855_FDB_MAT_DIP_SIP_DIP_IPV6, /* All DIP_SIP address with DIP_IPV6 */
+       AND8855_FDB_MAT_DIP_SIP_SIP_IPV6, /* All DIP_SIP address with SIP_IPV6 */
+       /* All MAC address with MAC type (dynamic or static) with CVID */
+       AND8855_FDB_MAT_MAC_TYPE_CVID,
+       /* All MAC address with MAC type (dynamic or static) with Filter ID */
+       AND8855_FDB_MAT_MAC_TYPE_FID,
+       /* All MAC address with MAC type (dynamic or static) with port */
+       AND8855_FDB_MAT_MAC_TYPE_PORT,
+};
+
+enum an8855_fdb_cmds {
+       AN8855_FDB_READ = 0,
+       AN8855_FDB_WRITE = 1,
+       AN8855_FDB_FLUSH = 2,
+       AN8855_FDB_START = 4,
+       AN8855_FDB_NEXT = 5,
+};
+
+/* Registers for address table access */
+#define AN8855_ATA1                    0x10200304
+#define   AN8855_ATA1_MAC0             GENMASK(31, 24)
+#define   AN8855_ATA1_MAC1             GENMASK(23, 16)
+#define   AN8855_ATA1_MAC2             GENMASK(15, 8)
+#define   AN8855_ATA1_MAC3             GENMASK(7, 0)
+#define AN8855_ATA2                    0x10200308
+#define   AN8855_ATA2_MAC4             GENMASK(31, 24)
+#define   AN8855_ATA2_MAC5             GENMASK(23, 16)
+#define   AN8855_ATA2_UNAUTH           BIT(10)
+#define   AN8855_ATA2_TYPE             BIT(9) /* 1: dynamic, 0: static */
+#define   AN8855_ATA2_AGE              GENMASK(8, 0)
+
+/* Register for address table write data */
+#define AN8855_ATWD                    0x10200324
+#define   AN8855_ATWD_FID              GENMASK(31, 28)
+#define   AN8855_ATWD_VID              GENMASK(27, 16)
+#define   AN8855_ATWD_IVL              BIT(15)
+#define   AN8855_ATWD_EG_TAG           GENMASK(14, 12)
+#define   AN8855_ATWD_SA_MIR           GENMASK(9, 8)
+#define   AN8855_ATWD_SA_FWD           GENMASK(7, 5)
+#define   AN8855_ATWD_UPRI             GENMASK(4, 2)
+#define   AN8855_ATWD_LEAKY            BIT(1)
+#define   AN8855_ATWD_VLD              BIT(0) /* vid LOAD */
+#define AN8855_ATWD2                   0x10200328
+#define   AN8855_ATWD2_PORT            GENMASK(7, 0)
+
+/* Registers for table search read address */
+#define AN8855_ATRDS                   0x10200330
+#define   AN8855_ATRD_SEL              GENMASK(1, 0)
+#define AN8855_ATRD0                   0x10200334
+#define   AN8855_ATRD0_FID             GENMASK(28, 25)
+#define   AN8855_ATRD0_VID             GENMASK(21, 10)
+#define   AN8855_ATRD0_IVL             BIT(9)
+#define   AN8855_ATRD0_TYPE            GENMASK(4, 3)
+#define   AN8855_ATRD0_ARP             GENMASK(2, 1)
+#define   AN8855_ATRD0_LIVE            BIT(0)
+#define AN8855_ATRD1                   0x10200338
+#define   AN8855_ATRD1_MAC4            GENMASK(31, 24)
+#define   AN8855_ATRD1_MAC5            GENMASK(23, 16)
+#define   AN8855_ATRD1_AGING           GENMASK(11, 3)
+#define AN8855_ATRD2                   0x1020033c
+#define   AN8855_ATRD2_MAC0            GENMASK(31, 24)
+#define   AN8855_ATRD2_MAC1            GENMASK(23, 16)
+#define   AN8855_ATRD2_MAC2            GENMASK(15, 8)
+#define   AN8855_ATRD2_MAC3            GENMASK(7, 0)
+#define AN8855_ATRD3                   0x10200340
+#define   AN8855_ATRD3_PORTMASK                GENMASK(7, 0)
+
+enum an8855_fdb_type {
+       AN8855_MAC_TB_TY_MAC = 0,
+       AN8855_MAC_TB_TY_DIP = 1,
+       AN8855_MAC_TB_TY_DIP_SIP = 2,
+};
+
+/* Register for vlan table control */
+#define AN8855_VTCR                    0x10200600
+#define   AN8855_VTCR_BUSY             BIT(31)
+#define   AN8855_VTCR_FUNC             GENMASK(15, 12)
+#define   AN8855_VTCR_VID              GENMASK(11, 0)
+
+enum an8855_vlan_cmd {
+       /* Read/Write the specified VID entry from VAWD register based
+        * on VID.
+        */
+       AN8855_VTCR_RD_VID = 0,
+       AN8855_VTCR_WR_VID = 1,
+};
+
+/* Register for setup vlan write data */
+#define AN8855_VAWD0                   0x10200604
+/* VLAN Member Control */
+#define   AN8855_VA0_PORT              GENMASK(31, 26)
+/* Egress Tag Control */
+#define   AN8855_VA0_ETAG              GENMASK(23, 12)
+#define   AN8855_VA0_ETAG_PORT         GENMASK(13, 12)
+#define   AN8855_VA0_ETAG_PORT_SHIFT(port) ((port) * 2)
+#define   AN8855_VA0_ETAG_PORT_MASK(port) (AN8855_VA0_ETAG_PORT << \
+                                               AN8855_VA0_ETAG_PORT_SHIFT(port))
+#define   AN8855_VA0_ETAG_PORT_VAL(port, val) (FIELD_PREP(AN8855_VA0_ETAG_PORT, (val)) << \
+                                               AN8855_VA0_ETAG_PORT_SHIFT(port))
+#define   AN8855_VA0_EG_CON            BIT(11)
+#define   AN8855_VA0_VTAG_EN           BIT(10) /* Per VLAN Egress Tag Control */
+#define   AN8855_VA0_IVL_MAC           BIT(5) /* Independent VLAN Learning */
+#define          AN8855_VA0_FID                GENMASK(4, 1)
+#define   AN8855_VA0_VLAN_VALID                BIT(0) /* VLAN Entry Valid */
+#define AN8855_VAWD1                   0x10200608
+#define   AN8855_VA1_PORT_STAG         BIT(1)
+
+enum an8855_fid {
+       AN8855_FID_STANDALONE = 0,
+       AN8855_FID_BRIDGED = 1,
+};
+
+/* Same register field of VAWD0 */
+#define AN8855_VARD0                   0x10200618
+
+enum an8855_vlan_egress_attr {
+       AN8855_VLAN_EGRESS_UNTAG = 0,
+       AN8855_VLAN_EGRESS_TAG = 2,
+       AN8855_VLAN_EGRESS_STACK = 3,
+};
+
+/* Register for port STP state control */
+#define AN8855_SSP_P(x)                        (0x10208000 + ((x) * 0x200))
+/* Up to 16 FID supported, each with the same mask */
+#define          AN8855_FID_PST                GENMASK(1, 0)
+#define   AN8855_FID_PST_SHIFT(fid)    (2 * (fid))
+#define   AN8855_FID_PST_MASK(fid)     (AN8855_FID_PST << \
+                                               AN8855_FID_PST_SHIFT(fid))
+#define   AN8855_FID_PST_VAL(fid, val) (FIELD_PREP(AN8855_FID_PST, (val)) << \
+                                               AN8855_FID_PST_SHIFT(fid))
+
+enum an8855_stp_state {
+       AN8855_STP_DISABLED = 0,
+       AN8855_STP_BLOCKING = 1,
+       AN8855_STP_LISTENING = AN8855_STP_BLOCKING,
+       AN8855_STP_LEARNING = 2,
+       AN8855_STP_FORWARDING = 3
+};
+
+/* Register for port control */
+#define AN8855_PCR_P(x)                        (0x10208004 + ((x) * 0x200))
+#define   AN8855_EG_TAG                        GENMASK(29, 28)
+#define   AN8855_PORT_PRI              GENMASK(26, 24)
+#define   AN8855_PORT_TX_MIR           BIT(20)
+#define   AN8855_PORT_RX_MIR           BIT(16)
+#define   AN8855_PORT_VLAN             GENMASK(1, 0)
+
+enum an8855_port_mode {
+       /* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */
+       AN8855_PORT_MATRIX_MODE = 0,
+
+       /* Fallback Mode: Forward received frames with ingress ports that do
+        * not belong to the VLAN member. Frames whose VID is not listed on
+        * the VLAN table are forwarded by the PCR_MATRIX members.
+        */
+       AN8855_PORT_FALLBACK_MODE = 1,
+
+       /* Check Mode: Forward received frames whose ingress do not
+        * belong to the VLAN member. Discard frames if VID ismiddes on the
+        * VLAN table.
+        */
+       AN8855_PORT_CHECK_MODE = 2,
+
+       /* Security Mode: Discard any frame due to ingress membership
+        * violation or VID missed on the VLAN table.
+        */
+       AN8855_PORT_SECURITY_MODE = 3,
+};
+
+/* Register for port security control */
+#define AN8855_PSC_P(x)                        (0x1020800c + ((x) * 0x200))
+#define   AN8855_SA_DIS                        BIT(4)
+
+/* Register for port vlan control */
+#define AN8855_PVC_P(x)                        (0x10208010 + ((x) * 0x200))
+#define   AN8855_PORT_SPEC_REPLACE_MODE        BIT(11)
+#define   AN8855_PVC_EG_TAG            GENMASK(10, 8)
+#define   AN8855_VLAN_ATTR             GENMASK(7, 6)
+#define   AN8855_PORT_SPEC_TAG         BIT(5)
+#define   AN8855_ACC_FRM               GENMASK(1, 0)
+
+enum an8855_vlan_port_eg_tag {
+       AN8855_VLAN_EG_DISABLED = 0,
+       AN8855_VLAN_EG_CONSISTENT = 1,
+       AN8855_VLAN_EG_UNTAGGED = 4,
+       AN8855_VLAN_EG_SWAP = 5,
+       AN8855_VLAN_EG_TAGGED = 6,
+       AN8855_VLAN_EG_STACK = 7,
+};
+
+enum an8855_vlan_port_attr {
+       AN8855_VLAN_USER = 0,
+       AN8855_VLAN_STACK = 1,
+       AN8855_VLAN_TRANSPARENT = 3,
+};
+
+enum an8855_vlan_port_acc_frm {
+       AN8855_VLAN_ACC_ALL = 0,
+       AN8855_VLAN_ACC_TAGGED = 1,
+       AN8855_VLAN_ACC_UNTAGGED = 2,
+};
+
+#define AN8855_PPBV1_P(x)              (0x10208014 + ((x) * 0x200))
+#define   AN8855_PPBV_G0_PORT_VID      GENMASK(11, 0)
+
+#define AN8855_PORTMATRIX_P(x)         (0x10208044 + ((x) * 0x200))
+#define   AN8855_PORTMATRIX            GENMASK(5, 0)
+/* Port matrix without the CPU port that should never be removed */
+#define   AN8855_USER_PORTMATRIX       GENMASK(4, 0)
+
+/* Register for port PVID */
+#define AN8855_PVID_P(x)               (0x10208048 + ((x) * 0x200))
+#define   AN8855_G0_PORT_VID           GENMASK(11, 0)
+
+/* Register for port MAC control register */
+#define AN8855_PMCR_P(x)               (0x10210000 + ((x) * 0x200))
+#define   AN8855_PMCR_FORCE_MODE       BIT(31)
+#define   AN8855_PMCR_FORCE_SPEED      GENMASK(30, 28)
+#define   AN8855_PMCR_FORCE_SPEED_5000 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x4)
+#define   AN8855_PMCR_FORCE_SPEED_2500 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x3)
+#define   AN8855_PMCR_FORCE_SPEED_1000 FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x2)
+#define   AN8855_PMCR_FORCE_SPEED_100  FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1)
+#define   AN8855_PMCR_FORCE_SPEED_10   FIELD_PREP_CONST(AN8855_PMCR_FORCE_SPEED, 0x1)
+#define   AN8855_PMCR_FORCE_FDX                BIT(25)
+#define   AN8855_PMCR_FORCE_LNK                BIT(24)
+#define   AN8855_PMCR_IFG_XMIT         GENMASK(21, 20)
+#define   AN8855_PMCR_EXT_PHY          BIT(19)
+#define   AN8855_PMCR_MAC_MODE         BIT(18)
+#define   AN8855_PMCR_TX_EN            BIT(16)
+#define   AN8855_PMCR_RX_EN            BIT(15)
+#define   AN8855_PMCR_BACKOFF_EN       BIT(12)
+#define   AN8855_PMCR_BACKPR_EN                BIT(11)
+#define   AN8855_PMCR_FORCE_EEE5G      BIT(9)
+#define   AN8855_PMCR_FORCE_EEE2P5G    BIT(8)
+#define   AN8855_PMCR_FORCE_EEE1G      BIT(7)
+#define   AN8855_PMCR_FORCE_EEE100     BIT(6)
+#define   AN8855_PMCR_TX_FC_EN         BIT(5)
+#define   AN8855_PMCR_RX_FC_EN         BIT(4)
+
+#define AN8855_PMSR_P(x)               (0x10210010 + (x) * 0x200)
+#define   AN8855_PMSR_SPEED            GENMASK(30, 28)
+#define   AN8855_PMSR_SPEED_5000       FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x4)
+#define   AN8855_PMSR_SPEED_2500       FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x3)
+#define   AN8855_PMSR_SPEED_1000       FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x2)
+#define   AN8855_PMSR_SPEED_100                FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x1)
+#define   AN8855_PMSR_SPEED_10         FIELD_PREP_CONST(AN8855_PMSR_SPEED, 0x0)
+#define   AN8855_PMSR_DPX              BIT(25)
+#define   AN8855_PMSR_LNK              BIT(24)
+#define   AN8855_PMSR_EEE1G            BIT(7)
+#define   AN8855_PMSR_EEE100M          BIT(6)
+#define   AN8855_PMSR_RX_FC            BIT(5)
+#define   AN8855_PMSR_TX_FC            BIT(4)
+
+#define AN8855_PMEEECR_P(x)            (0x10210004 + (x) * 0x200)
+#define   AN8855_LPI_MODE_EN           BIT(31)
+#define   AN8855_WAKEUP_TIME_2500      GENMASK(23, 16)
+#define   AN8855_WAKEUP_TIME_1000      GENMASK(15, 8)
+#define   AN8855_WAKEUP_TIME_100       GENMASK(7, 0)
+#define AN8855_PMEEECR2_P(x)           (0x10210008 + (x) * 0x200)
+#define   AN8855_WAKEUP_TIME_5000      GENMASK(7, 0)
+
+#define AN8855_GMACCR                  0x10213e00
+#define   AN8855_MAX_RX_JUMBO          GENMASK(7, 4)
+/* 2K for 0x0, 0x1, 0x2 */
+#define   AN8855_MAX_RX_JUMBO_2K       FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x0)
+#define   AN8855_MAX_RX_JUMBO_3K       FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x3)
+#define   AN8855_MAX_RX_JUMBO_4K       FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x4)
+#define   AN8855_MAX_RX_JUMBO_5K       FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x5)
+#define   AN8855_MAX_RX_JUMBO_6K       FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x6)
+#define   AN8855_MAX_RX_JUMBO_7K       FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x7)
+#define   AN8855_MAX_RX_JUMBO_8K       FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x8)
+#define   AN8855_MAX_RX_JUMBO_9K       FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0x9)
+#define   AN8855_MAX_RX_JUMBO_12K      FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xa)
+#define   AN8855_MAX_RX_JUMBO_15K      FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xb)
+#define   AN8855_MAX_RX_JUMBO_16K      FIELD_PREP_CONST(AN8855_MAX_RX_JUMBO, 0xc)
+#define   AN8855_MAX_RX_PKT_LEN                GENMASK(1, 0)
+#define   AN8855_MAX_RX_PKT_1518_1522  FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x0)
+#define   AN8855_MAX_RX_PKT_1536       FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x1)
+#define   AN8855_MAX_RX_PKT_1552       FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x2)
+#define   AN8855_MAX_RX_PKT_JUMBO      FIELD_PREP_CONST(AN8855_MAX_RX_PKT_LEN, 0x3)
+
+#define AN8855_CKGCR                   0x10213e1c
+#define   AN8855_LPI_TXIDLE_THD_MASK   GENMASK(31, 14)
+#define   AN8855_CKG_LNKDN_PORT_STOP   BIT(1)
+#define   AN8855_CKG_LNKDN_GLB_STOP    BIT(0)
+
+/* Register for MIB */
+#define AN8855_PORT_MIB_COUNTER(x)     (0x10214000 + (x) * 0x200)
+/* Each define is an offset of AN8855_PORT_MIB_COUNTER */
+#define   AN8855_PORT_MIB_TX_DROP      0x00
+#define   AN8855_PORT_MIB_TX_CRC_ERR   0x04
+#define   AN8855_PORT_MIB_TX_UNICAST   0x08
+#define   AN8855_PORT_MIB_TX_MULTICAST 0x0c
+#define   AN8855_PORT_MIB_TX_BROADCAST 0x10
+#define   AN8855_PORT_MIB_TX_COLLISION 0x14
+#define   AN8855_PORT_MIB_TX_SINGLE_COLLISION 0x18
+#define   AN8855_PORT_MIB_TX_MULTIPLE_COLLISION 0x1c
+#define   AN8855_PORT_MIB_TX_DEFERRED  0x20
+#define   AN8855_PORT_MIB_TX_LATE_COLLISION 0x24
+#define   AN8855_PORT_MIB_TX_EXCESSIVE_COLLISION 0x28
+#define   AN8855_PORT_MIB_TX_PAUSE     0x2c
+#define   AN8855_PORT_MIB_TX_PKT_SZ_64 0x30
+#define   AN8855_PORT_MIB_TX_PKT_SZ_65_TO_127 0x34
+#define   AN8855_PORT_MIB_TX_PKT_SZ_128_TO_255 0x38
+#define   AN8855_PORT_MIB_TX_PKT_SZ_256_TO_511 0x3
+#define   AN8855_PORT_MIB_TX_PKT_SZ_512_TO_1023 0x40
+#define   AN8855_PORT_MIB_TX_PKT_SZ_1024_TO_1518 0x44
+#define   AN8855_PORT_MIB_TX_PKT_SZ_1519_TO_MAX 0x48
+#define   AN8855_PORT_MIB_TX_BYTES     0x4c /* 64 bytes */
+#define   AN8855_PORT_MIB_TX_OVERSIZE_DROP 0x54
+#define   AN8855_PORT_MIB_TX_BAD_PKT_BYTES 0x58 /* 64 bytes */
+#define   AN8855_PORT_MIB_RX_DROP      0x80
+#define   AN8855_PORT_MIB_RX_FILTERING 0x84
+#define   AN8855_PORT_MIB_RX_UNICAST   0x88
+#define   AN8855_PORT_MIB_RX_MULTICAST 0x8c
+#define   AN8855_PORT_MIB_RX_BROADCAST 0x90
+#define   AN8855_PORT_MIB_RX_ALIGN_ERR 0x94
+#define   AN8855_PORT_MIB_RX_CRC_ERR   0x98
+#define   AN8855_PORT_MIB_RX_UNDER_SIZE_ERR 0x9c
+#define   AN8855_PORT_MIB_RX_FRAG_ERR  0xa0
+#define   AN8855_PORT_MIB_RX_OVER_SZ_ERR 0xa4
+#define   AN8855_PORT_MIB_RX_JABBER_ERR        0xa8
+#define   AN8855_PORT_MIB_RX_PAUSE     0xac
+#define   AN8855_PORT_MIB_RX_PKT_SZ_64 0xb0
+#define   AN8855_PORT_MIB_RX_PKT_SZ_65_TO_127 0xb4
+#define   AN8855_PORT_MIB_RX_PKT_SZ_128_TO_255 0xb8
+#define   AN8855_PORT_MIB_RX_PKT_SZ_256_TO_511 0xbc
+#define   AN8855_PORT_MIB_RX_PKT_SZ_512_TO_1023 0xc0
+#define   AN8855_PORT_MIB_RX_PKT_SZ_1024_TO_1518 0xc4
+#define   AN8855_PORT_MIB_RX_PKT_SZ_1519_TO_MAX 0xc8
+#define   AN8855_PORT_MIB_RX_BYTES     0xcc /* 64 bytes */
+#define   AN8855_PORT_MIB_RX_CTRL_DROP 0xd4
+#define   AN8855_PORT_MIB_RX_INGRESS_DROP 0xd8
+#define   AN8855_PORT_MIB_RX_ARL_DROP  0xdc
+#define   AN8855_PORT_MIB_FLOW_CONTROL_DROP 0xe0
+#define   AN8855_PORT_MIB_WRED_DROP    0xe4
+#define   AN8855_PORT_MIB_MIRROR_DROP  0xe8
+#define   AN8855_PORT_MIB_RX_BAD_PKT_BYTES 0xec /* 64 bytes */
+#define   AN8855_PORT_MIB_RXS_FLOW_SAMPLING_PKT_DROP 0xf4
+#define   AN8855_PORT_MIB_RXS_FLOW_TOTAL_PKT_DROP 0xf8
+#define   AN8855_PORT_MIB_PORT_CONTROL_DROP 0xfc
+#define AN8855_MIB_CCR                 0x10213e30
+#define   AN8855_CCR_MIB_ENABLE                BIT(31)
+#define   AN8855_CCR_RX_OCT_CNT_GOOD   BIT(7)
+#define   AN8855_CCR_RX_OCT_CNT_BAD    BIT(6)
+#define   AN8855_CCR_TX_OCT_CNT_GOOD   BIT(5)
+#define   AN8855_CCR_TX_OCT_CNT_BAD    BIT(4)
+#define   AN8855_CCR_RX_OCT_CNT_GOOD_2 BIT(3)
+#define   AN8855_CCR_RX_OCT_CNT_BAD_2  BIT(2)
+#define   AN8855_CCR_TX_OCT_CNT_GOOD_2 BIT(1)
+#define   AN8855_CCR_TX_OCT_CNT_BAD_2  BIT(0)
+#define   AN8855_CCR_MIB_ACTIVATE      (AN8855_CCR_MIB_ENABLE | \
+                                        AN8855_CCR_RX_OCT_CNT_GOOD | \
+                                        AN8855_CCR_RX_OCT_CNT_BAD | \
+                                        AN8855_CCR_TX_OCT_CNT_GOOD | \
+                                        AN8855_CCR_TX_OCT_CNT_BAD | \
+                                        AN8855_CCR_RX_OCT_CNT_BAD_2 | \
+                                        AN8855_CCR_TX_OCT_CNT_BAD_2)
+#define AN8855_MIB_CLR                 0x10213e34
+#define   AN8855_MIB_PORT6_CLR         BIT(6)
+#define   AN8855_MIB_PORT5_CLR         BIT(5)
+#define   AN8855_MIB_PORT4_CLR         BIT(4)
+#define   AN8855_MIB_PORT3_CLR         BIT(3)
+#define   AN8855_MIB_PORT2_CLR         BIT(2)
+#define   AN8855_MIB_PORT1_CLR         BIT(1)
+#define   AN8855_MIB_PORT0_CLR         BIT(0)
+
+/* HSGMII/SGMII Configuration register */
+/*     AN8855_HSGMII_AN_CSR_BASE       0x10220000 */
+#define AN8855_SGMII_REG_AN0           0x10220000
+/*        AN8855_SGMII_AN_ENABLE       BMCR_ANENABLE */
+/*        AN8855_SGMII_AN_RESTART      BMCR_ANRESTART */
+#define AN8855_SGMII_REG_AN_13         0x10220034
+#define   AN8855_SGMII_REMOTE_FAULT_DIS        BIT(8)
+#define   AN8855_SGMII_IF_MODE         GENMASK(5, 0)
+#define AN8855_SGMII_REG_AN_FORCE_CL37 0x10220060
+#define   AN8855_RG_FORCE_AN_DONE      BIT(0)
+
+/*     AN8855_HSGMII_CSR_PCS_BASE      0x10220000 */
+#define AN8855_RG_HSGMII_PCS_CTROL_1   0x10220a00
+#define   AN8855_RG_TBI_10B_MODE       BIT(30)
+#define AN8855_RG_AN_SGMII_MODE_FORCE  0x10220a24
+#define   AN8855_RG_FORCE_CUR_SGMII_MODE GENMASK(5, 4)
+#define   AN8855_RG_FORCE_CUR_SGMII_SEL        BIT(0)
+
+/*     AN8855_MULTI_SGMII_CSR_BASE     0x10224000 */
+#define AN8855_SGMII_STS_CTRL_0                0x10224018
+#define   AN8855_RG_LINK_MODE_P0       GENMASK(5, 4)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_2500 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x3)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_1000 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x2)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_100 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x1)
+#define   AN8855_RG_LINK_MODE_P0_SPEED_10 FIELD_PREP_CONST(AN8855_RG_LINK_MODE_P0, 0x0)
+#define   AN8855_RG_FORCE_SPD_MODE_P0  BIT(2)
+#define AN8855_MSG_RX_CTRL_0           0x10224100
+#define AN8855_MSG_RX_LIK_STS_0                0x10224514
+#define   AN8855_RG_DPX_STS_P3         BIT(24)
+#define   AN8855_RG_DPX_STS_P2         BIT(16)
+#define   AN8855_RG_EEE1G_STS_P1       BIT(12)
+#define   AN8855_RG_DPX_STS_P1         BIT(8)
+#define   AN8855_RG_TXFC_STS_P0                BIT(2)
+#define   AN8855_RG_RXFC_STS_P0                BIT(1)
+#define   AN8855_RG_DPX_STS_P0         BIT(0)
+#define AN8855_MSG_RX_LIK_STS_2                0x1022451c
+#define   AN8855_RG_RXFC_AN_BYPASS_P3  BIT(11)
+#define   AN8855_RG_RXFC_AN_BYPASS_P2  BIT(10)
+#define   AN8855_RG_RXFC_AN_BYPASS_P1  BIT(9)
+#define   AN8855_RG_TXFC_AN_BYPASS_P3  BIT(7)
+#define   AN8855_RG_TXFC_AN_BYPASS_P2  BIT(6)
+#define   AN8855_RG_TXFC_AN_BYPASS_P1  BIT(5)
+#define   AN8855_RG_DPX_AN_BYPASS_P3   BIT(3)
+#define   AN8855_RG_DPX_AN_BYPASS_P2   BIT(2)
+#define   AN8855_RG_DPX_AN_BYPASS_P1   BIT(1)
+#define   AN8855_RG_DPX_AN_BYPASS_P0   BIT(0)
+#define AN8855_PHY_RX_FORCE_CTRL_0     0x10224520
+#define   AN8855_RG_FORCE_TXC_SEL      BIT(4)
+
+/*     AN8855_XFI_CSR_PCS_BASE         0x10225000 */
+#define AN8855_RG_USXGMII_AN_CONTROL_0 0x10225bf8
+
+/*     AN8855_MULTI_PHY_RA_CSR_BASE    0x10226000 */
+#define AN8855_RG_RATE_ADAPT_CTRL_0    0x10226000
+#define   AN8855_RG_RATE_ADAPT_RX_BYPASS BIT(27)
+#define   AN8855_RG_RATE_ADAPT_TX_BYPASS BIT(26)
+#define   AN8855_RG_RATE_ADAPT_RX_EN   BIT(4)
+#define   AN8855_RG_RATE_ADAPT_TX_EN   BIT(0)
+#define AN8855_RATE_ADP_P0_CTRL_0      0x10226100
+#define   AN8855_RG_P0_DIS_MII_MODE    BIT(31)
+#define   AN8855_RG_P0_MII_MODE                BIT(28)
+#define   AN8855_RG_P0_MII_RA_RX_EN    BIT(3)
+#define   AN8855_RG_P0_MII_RA_TX_EN    BIT(2)
+#define   AN8855_RG_P0_MII_RA_RX_MODE  BIT(1)
+#define   AN8855_RG_P0_MII_RA_TX_MODE  BIT(0)
+#define AN8855_MII_RA_AN_ENABLE                0x10226300
+#define   AN8855_RG_P0_RA_AN_EN                BIT(0)
+
+/*     AN8855_QP_DIG_CSR_BASE          0x1022a000 */
+#define AN8855_QP_CK_RST_CTRL_4                0x1022a310
+#define AN8855_QP_DIG_MODE_CTRL_0      0x1022a324
+#define   AN8855_RG_SGMII_MODE         GENMASK(5, 4)
+#define   AN8855_RG_SGMII_AN_EN                BIT(0)
+#define AN8855_QP_DIG_MODE_CTRL_1      0x1022a330
+#define   AN8855_RG_TPHY_SPEED         GENMASK(3, 2)
+
+/*     AN8855_SERDES_WRAPPER_BASE      0x1022c000 */
+#define AN8855_USGMII_CTRL_0           0x1022c000
+
+/*     AN8855_QP_PMA_TOP_BASE          0x1022e000 */
+#define AN8855_PON_RXFEDIG_CTRL_0      0x1022e100
+#define   AN8855_RG_QP_EQ_RX500M_CK_SEL        BIT(12)
+#define AN8855_PON_RXFEDIG_CTRL_9      0x1022e124
+#define   AN8855_RG_QP_EQ_LEQOSC_DLYCNT        GENMASK(2, 0)
+
+#define AN8855_SS_LCPLL_PWCTL_SETTING_2        0x1022e208
+#define   AN8855_RG_NCPO_ANA_MSB       GENMASK(17, 16)
+#define AN8855_SS_LCPLL_TDC_FLT_2      0x1022e230
+#define   AN8855_RG_LCPLL_NCPO_VALUE   GENMASK(30, 0)
+#define AN8855_SS_LCPLL_TDC_FLT_5      0x1022e23c
+#define   AN8855_RG_LCPLL_NCPO_CHG     BIT(24)
+#define AN8855_SS_LCPLL_TDC_PCW_1      0x1022e248
+#define  AN8855_RG_LCPLL_PON_HRDDS_PCW_NCPO_GPON GENMASK(30, 0)
+#define AN8855_INTF_CTRL_8             0x1022e320
+#define AN8855_INTF_CTRL_9             0x1022e324
+#define AN8855_INTF_CTRL_10            0x1022e328
+#define   AN8855_RG_DA_QP_TX_FIR_C2_SEL        BIT(29)
+#define   AN8855_RG_DA_QP_TX_FIR_C2_FORCE GENMASK(28, 24)
+#define   AN8855_RG_DA_QP_TX_FIR_C1_SEL        BIT(21)
+#define   AN8855_RG_DA_QP_TX_FIR_C1_FORCE GENMASK(20, 16)
+#define AN8855_INTF_CTRL_11            0x1022e32c
+#define   AN8855_RG_DA_QP_TX_FIR_C0B_SEL BIT(6)
+#define   AN8855_RG_DA_QP_TX_FIR_C0B_FORCE GENMASK(5, 0)
+#define AN8855_PLL_CTRL_0              0x1022e400
+#define   AN8855_RG_PHYA_AUTO_INIT     BIT(0)
+#define AN8855_PLL_CTRL_2              0x1022e408
+#define   AN8855_RG_DA_QP_PLL_SDM_IFM_INTF BIT(30)
+#define   AN8855_RG_DA_QP_PLL_RICO_SEL_INTF BIT(29)
+#define   AN8855_RG_DA_QP_PLL_POSTDIV_EN_INTF BIT(28)
+#define   AN8855_RG_DA_QP_PLL_PHY_CK_EN_INTF BIT(27)
+#define   AN8855_RG_DA_QP_PLL_PFD_OFFSET_EN_INTRF BIT(26)
+#define   AN8855_RG_DA_QP_PLL_PFD_OFFSET_INTF GENMASK(25, 24)
+#define   AN8855_RG_DA_QP_PLL_PCK_SEL_INTF BIT(22)
+#define   AN8855_RG_DA_QP_PLL_KBAND_PREDIV_INTF GENMASK(21, 20)
+#define   AN8855_RG_DA_QP_PLL_IR_INTF  GENMASK(19, 16)
+#define   AN8855_RG_DA_QP_PLL_ICOIQ_EN_INTF BIT(14)
+#define   AN8855_RG_DA_QP_PLL_FBKSEL_INTF GENMASK(13, 12)
+#define   AN8855_RG_DA_QP_PLL_BR_INTF  GENMASK(10, 8)
+#define   AN8855_RG_DA_QP_PLL_BPD_INTF GENMASK(7, 6)
+#define   AN8855_RG_DA_QP_PLL_BPA_INTF GENMASK(4, 2)
+#define   AN8855_RG_DA_QP_PLL_BC_INTF  GENMASK(1, 0)
+#define AN8855_PLL_CTRL_3              0x1022e40c
+#define   AN8855_RG_DA_QP_PLL_SSC_PERIOD_INTF GENMASK(31, 16)
+#define   AN8855_RG_DA_QP_PLL_SSC_DELTA_INTF GENMASK(15, 0)
+#define AN8855_PLL_CTRL_4              0x1022e410
+#define   AN8855_RG_DA_QP_PLL_SDM_HREN_INTF GENMASK(4, 3)
+#define   AN8855_RG_DA_QP_PLL_ICOLP_EN_INTF BIT(2)
+#define   AN8855_RG_DA_QP_PLL_SSC_DIR_DLY_INTF GENMASK(1, 0)
+#define AN8855_PLL_CK_CTRL_0           0x1022e414
+#define   AN8855_RG_DA_QP_PLL_TDC_TXCK_SEL_INTF BIT(9)
+#define   AN8855_RG_DA_QP_PLL_SDM_DI_EN_INTF BIT(8)
+#define AN8855_RX_DLY_0                        0x1022e614
+#define   AN8855_RG_QP_RX_SAOSC_EN_H_DLY GENMASK(13, 8)
+#define   AN8855_RG_QP_RX_PI_CAL_EN_H_DLY GENMASK(7, 0)
+#define AN8855_RX_CTRL_2               0x1022e630
+#define   AN8855_RG_QP_RX_EQ_EN_H_DLY  GENMASK(28, 16)
+#define AN8855_RX_CTRL_5               0x1022e63c
+#define   AN8855_RG_FREDET_CHK_CYCLE   GENMASK(29, 10)
+#define AN8855_RX_CTRL_6               0x1022e640
+#define   AN8855_RG_FREDET_GOLDEN_CYCLE        GENMASK(19, 0)
+#define AN8855_RX_CTRL_7               0x1022e644
+#define   AN8855_RG_FREDET_TOLERATE_CYCLE GENMASK(19, 0)
+#define AN8855_RX_CTRL_8               0x1022e648
+#define   AN8855_RG_DA_QP_SAOSC_DONE_TIME GENMASK(27, 16)
+#define   AN8855_RG_DA_QP_LEQOS_EN_TIME        GENMASK(14, 0)
+#define AN8855_RX_CTRL_26              0x1022e690
+#define   AN8855_RG_QP_EQ_RETRAIN_ONLY_EN BIT(26)
+#define   AN8855_RG_LINK_NE_EN         BIT(24)
+#define   AN8855_RG_LINK_ERRO_EN       BIT(23)
+#define AN8855_RX_CTRL_42              0x1022e6d0
+#define   AN8855_RG_QP_EQ_EN_DLY       GENMASK(12, 0)
+
+/*     AN8855_QP_ANA_CSR_BASE          0x1022f000 */
+#define AN8855_RG_QP_RX_DAC_EN         0x1022f000
+#define   AN8855_RG_QP_SIGDET_HF       GENMASK(17, 16)
+#define AN8855_RG_QP_RXAFE_RESERVE     0x1022f004
+#define   AN8855_RG_QP_CDR_PD_10B_EN   BIT(11)
+#define AN8855_RG_QP_CDR_LPF_BOT_LIM   0x1022f008
+#define   AN8855_RG_QP_CDR_LPF_KP_GAIN GENMASK(26, 24)
+#define   AN8855_RG_QP_CDR_LPF_KI_GAIN GENMASK(22, 20)
+#define AN8855_RG_QP_CDR_LPF_MJV_LIM   0x1022f00c
+#define   AN8855_RG_QP_CDR_LPF_RATIO   GENMASK(5, 4)
+#define AN8855_RG_QP_CDR_LPF_SETVALUE  0x1022f014
+#define   AN8855_RG_QP_CDR_PR_BUF_IN_SR        GENMASK(31, 29)
+#define   AN8855_RG_QP_CDR_PR_BETA_SEL GENMASK(28, 25)
+#define AN8855_RG_QP_CDR_PR_CKREF_DIV1 0x1022f018
+#define   AN8855_RG_QP_CDR_PR_KBAND_DIV        GENMASK(26, 24)
+#define   AN8855_RG_QP_CDR_PR_DAC_BAND GENMASK(12, 8)
+#define AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE 0x1022f01c
+#define   AN8855_RG_QP_CDR_PR_XFICK_EN BIT(30)
+#define   AN8855_RG_QP_CDR_PR_KBAND_PCIE_MODE BIT(6)
+#define   AN8855_RG_QP_CDR_PR_KBAND_DIV_PCIE_MASK GENMASK(5, 0)
+#define AN8855_RG_QP_CDR_FORCE_IBANDLPF_R_OFF 0x1022f020
+#define   AN8855_RG_QP_CDR_PHYCK_SEL   GENMASK(17, 16)
+#define   AN8855_RG_QP_CDR_PHYCK_RSTB  BIT(13)
+#define   AN8855_RG_QP_CDR_PHYCK_DIV   GENMASK(12, 6)
+#define AN8855_RG_QP_TX_MODE           0x1022f028
+#define   AN8855_RG_QP_TX_RESERVE      GENMASK(31, 16)
+#define   AN8855_RG_QP_TX_MODE_16B_EN  BIT(0)
+#define AN8855_RG_QP_PLL_IPLL_DIG_PWR_SEL 0x1022f03c
+#define AN8855_RG_QP_PLL_SDM_ORD       0x1022f040
+#define   AN8855_RG_QP_PLL_SSC_PHASE_INI BIT(4)
+#define   AN8855_RG_QP_PLL_SSC_TRI_EN  BIT(3)
+
+/*     AN8855_ETHER_SYS_BASE           0x1028c800 */
+#define AN8855_RG_GPHY_AFE_PWD         0x1028c840
+#define AN8855_RG_GPHY_SMI_ADDR                0x1028c848
+
+#define MIB_DESC(_s, _o, _n)   \
+       {                       \
+               .size = (_s),   \
+               .offset = (_o), \
+               .name = (_n),   \
+       }
+
+struct an8855_mib_desc {
+       unsigned int size;
+       unsigned int offset;
+       const char *name;
+};
+
+struct an8855_fdb {
+       u16 vid;
+       u8 port_mask;
+       u16 aging;
+       u8 mac[6];
+       bool noarp;
+       u8 live;
+       u8 type;
+       u8 fid;
+       u8 ivl;
+};
+
+struct an8855_priv {
+       struct device *dev;
+       struct dsa_switch *ds;
+       struct regmap *regmap;
+       struct gpio_desc *reset_gpio;
+       /* Protect ATU or VLAN table access */
+       struct mutex reg_mutex;
+
+       struct phylink_pcs pcs;
+
+       u8 mirror_rx;
+       u8 mirror_tx;
+       u8 port_isolated_map;
+
+       bool phy_require_calib;
+};
+
+#endif /* __AN8855_H */
diff --git a/target/linux/mediatek/files-6.12/drivers/net/mdio/mdio-an8855.c b/target/linux/mediatek/files-6.12/drivers/net/mdio/mdio-an8855.c
new file mode 100644 (file)
index 0000000..5feba72
--- /dev/null
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MDIO passthrough driver for Airoha AN8855 Switch
+ */
+
+#include <linux/mfd/airoha-an8855-mfd.h>
+#include <linux/module.h>
+#include <linux/of_mdio.h>
+#include <linux/platform_device.h>
+
+static int an855_phy_restore_page(struct an8855_mfd_priv *priv,
+                                 int phy) __must_hold(&priv->bus->mdio_lock)
+{
+       /* Check PHY page only for addr shared with switch */
+       if (phy != priv->switch_addr)
+               return 0;
+
+       /* Don't restore page if it's not set to switch page */
+       if (priv->current_page != FIELD_GET(AN8855_PHY_PAGE,
+                                           AN8855_PHY_PAGE_EXTENDED_4))
+               return 0;
+
+       /* Restore page to 0, PHY might change page right after but that
+        * will be ignored as it won't be a switch page.
+        */
+       return an8855_mii_set_page(priv, phy, AN8855_PHY_PAGE_STANDARD);
+}
+
+static int an8855_phy_read(struct mii_bus *bus, int phy, int regnum)
+{
+       struct an8855_mfd_priv *priv = bus->priv;
+       struct mii_bus *real_bus = priv->bus;
+       int ret;
+
+       mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED);
+
+       ret = an855_phy_restore_page(priv, phy);
+       if (ret)
+               goto exit;
+
+       ret = __mdiobus_read(real_bus, phy, regnum);
+exit:
+       mutex_unlock(&real_bus->mdio_lock);
+
+       return ret;
+}
+
+static int an8855_phy_write(struct mii_bus *bus, int phy, int regnum, u16 val)
+{
+       struct an8855_mfd_priv *priv = bus->priv;
+       struct mii_bus *real_bus = priv->bus;
+       int ret;
+
+       mutex_lock_nested(&real_bus->mdio_lock, MDIO_MUTEX_NESTED);
+
+       ret = an855_phy_restore_page(priv, phy);
+       if (ret)
+               goto exit;
+
+       ret = __mdiobus_write(real_bus, phy, regnum, val);
+exit:
+       mutex_unlock(&real_bus->mdio_lock);
+
+       return ret;
+}
+
+static int an8855_mdio_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct an8855_mfd_priv *priv;
+       struct mii_bus *bus;
+       int ret;
+
+       /* Get priv of MFD */
+       priv = dev_get_drvdata(dev->parent);
+
+       bus = devm_mdiobus_alloc(dev);
+       if (!bus)
+               return -ENOMEM;
+
+       bus->priv = priv;
+       bus->name = KBUILD_MODNAME "-mii";
+       snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d",
+                priv->switch_addr);
+       bus->parent = dev;
+       bus->read = an8855_phy_read;
+       bus->write = an8855_phy_write;
+
+       ret = devm_of_mdiobus_register(dev, bus, dev->of_node);
+       if (ret)
+               return dev_err_probe(dev, ret, "failed to register MDIO bus\n");
+
+       return ret;
+}
+
+static const struct of_device_id an8855_mdio_of_match[] = {
+       { .compatible = "airoha,an8855-mdio", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_mdio_of_match);
+
+static struct platform_driver an8855_mdio_driver = {
+       .probe  = an8855_mdio_probe,
+       .driver = {
+               .name = "an8855-mdio",
+               .of_match_table = an8855_mdio_of_match,
+       },
+};
+module_platform_driver(an8855_mdio_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_DESCRIPTION("Driver for AN8855 MDIO passthrough");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/files-6.12/drivers/net/phy/air_an8855.c b/target/linux/mediatek/files-6.12/drivers/net/phy/air_an8855.c
new file mode 100644 (file)
index 0000000..cf10b7a
--- /dev/null
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth@gmail.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/phy.h>
+
+#define AN8855_PHY_SELECT_PAGE                 0x1f
+#define   AN8855_PHY_PAGE                      GENMASK(2, 0)
+#define   AN8855_PHY_PAGE_STANDARD             FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
+#define   AN8855_PHY_PAGE_EXTENDED_1           FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
+
+/* MII Registers Page 1 */
+#define AN8855_PHY_EXT_REG_14                  0x14
+#define   AN8855_PHY_EN_DOWN_SHIFT             BIT(4)
+
+/* R50 Calibration regs in MDIO_MMD_VEND1 */
+#define AN8855_PHY_R500HM_RSEL_TX_AB           0x174
+#define AN8855_PHY_R50OHM_RSEL_TX_A_EN         BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_A            GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_B_EN         BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_B            GENMASK(6, 0)
+#define AN8855_PHY_R500HM_RSEL_TX_CD           0x175
+#define AN8855_PHY_R50OHM_RSEL_TX_C_EN         BIT(15)
+#define AN8855_PHY_R50OHM_RSEL_TX_C            GENMASK(14, 8)
+#define AN8855_PHY_R50OHM_RSEL_TX_D_EN         BIT(7)
+#define AN8855_PHY_R50OHM_RSEL_TX_D            GENMASK(6, 0)
+
+#define AN8855_SWITCH_EFUSE_R50O               GENMASK(30, 24)
+
+/* PHY TX PAIR DELAY SELECT Register */
+#define AN8855_PHY_TX_PAIR_DLY_SEL_GBE         0x013
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE GENMASK(14, 12)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_B_GBE GENMASK(10, 8)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE GENMASK(6, 4)
+#define   AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_D_GBE GENMASK(2, 0)
+/* PHY ADC Register */
+#define AN8855_PHY_RXADC_CTRL                  0x0d8
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A     BIT(12)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_B     BIT(8)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C     BIT(4)
+#define   AN8855_PHY_RG_AD_SAMNPLE_PHSEL_D     BIT(0)
+#define AN8855_PHY_RXADC_REV_0                 0x0d9
+#define   AN8855_PHY_RG_AD_RESERVE0_A          GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_B          GENMASK(7, 0)
+#define AN8855_PHY_RXADC_REV_1                 0x0da
+#define   AN8855_PHY_RG_AD_RESERVE0_C          GENMASK(15, 8)
+#define   AN8855_PHY_RG_AD_RESERVE0_D          GENMASK(7, 0)
+
+#define AN8855_PHY_ID                          0xc0ff0410
+
+#define AN8855_PHY_FLAGS_EN_CALIBRATION                BIT(0)
+
+struct air_an8855_priv {
+       u8 calibration_data[4];
+};
+
+static const u8 dsa_r50ohm_table[] = {
+       127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+       127, 127, 127, 127, 127, 127, 127, 126, 122, 117,
+       112, 109, 104, 101,  97,  94,  90,  88,  84,  80,
+       78,  74,  72,  68,  66,  64,  61,  58,  56,  53,
+       51,  48,  47,  44,  42,  40,  38,  36,  34,  32,
+       31,  28,  27,  24,  24,  22,  20,  18,  16,  16,
+       14,  12,  11,   9
+};
+
+static int en8855_get_r50ohm_val(struct device *dev, const char *calib_name,
+                                u8 *dest)
+{
+       u32 shift_sel, val;
+       int ret;
+       int i;
+
+       ret = nvmem_cell_read_u32(dev, calib_name, &val);
+       if (ret)
+               return ret;
+
+       shift_sel = FIELD_GET(AN8855_SWITCH_EFUSE_R50O, val);
+       for (i = 0; i < ARRAY_SIZE(dsa_r50ohm_table); i++)
+               if (dsa_r50ohm_table[i] == shift_sel)
+                       break;
+
+       if (i < 8 || i >= ARRAY_SIZE(dsa_r50ohm_table))
+               *dest = dsa_r50ohm_table[25];
+       else
+               *dest = dsa_r50ohm_table[i - 8];
+
+       return 0;
+}
+
+static int an8855_probe(struct phy_device *phydev)
+{
+       struct device *dev = &phydev->mdio.dev;
+       struct device_node *node = dev->of_node;
+       struct air_an8855_priv *priv;
+
+       /* If we don't have a node, skip calib */
+       if (!node)
+               return 0;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       phydev->priv = priv;
+
+       return 0;
+}
+
+static int an8855_get_downshift(struct phy_device *phydev, u8 *data)
+{
+       int val;
+
+       val = phy_read_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1, AN8855_PHY_EXT_REG_14);
+       if (val < 0)
+               return val;
+
+       *data = val & AN8855_PHY_EN_DOWN_SHIFT ? DOWNSHIFT_DEV_DEFAULT_COUNT :
+                                                DOWNSHIFT_DEV_DISABLE;
+
+       return 0;
+}
+
+static int an8855_set_downshift(struct phy_device *phydev, u8 cnt)
+{
+       u16 ds = cnt != DOWNSHIFT_DEV_DISABLE ? AN8855_PHY_EN_DOWN_SHIFT : 0;
+
+       return phy_modify_paged(phydev, AN8855_PHY_PAGE_EXTENDED_1,
+                               AN8855_PHY_EXT_REG_14, AN8855_PHY_EN_DOWN_SHIFT,
+                               ds);
+}
+
+static int an8855_config_init(struct phy_device *phydev)
+{
+       struct air_an8855_priv *priv = phydev->priv;
+       struct device *dev = &phydev->mdio.dev;
+       int ret;
+
+       /* Enable HW auto downshift */
+       ret = an8855_set_downshift(phydev, DOWNSHIFT_DEV_DEFAULT_COUNT);
+       if (ret)
+               return ret;
+
+       /* Apply calibration values, if needed.
+        * AN8855_PHY_FLAGS_EN_CALIBRATION signal this.
+        */
+       if (priv && phydev->dev_flags & AN8855_PHY_FLAGS_EN_CALIBRATION) {
+               u8 *calibration_data = priv->calibration_data;
+
+               ret = en8855_get_r50ohm_val(dev, "tx_a", &calibration_data[0]);
+               if (ret)
+                       return ret;
+
+               ret = en8855_get_r50ohm_val(dev, "tx_b", &calibration_data[1]);
+               if (ret)
+                       return ret;
+
+               ret = en8855_get_r50ohm_val(dev, "tx_c", &calibration_data[2]);
+               if (ret)
+                       return ret;
+
+               ret = en8855_get_r50ohm_val(dev, "tx_d", &calibration_data[3]);
+               if (ret)
+                       return ret;
+
+               ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_AB,
+                                    AN8855_PHY_R50OHM_RSEL_TX_A | AN8855_PHY_R50OHM_RSEL_TX_B,
+                                    FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_A, calibration_data[0]) |
+                                    FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_B, calibration_data[1]));
+               if (ret)
+                       return ret;
+               ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_R500HM_RSEL_TX_CD,
+                                    AN8855_PHY_R50OHM_RSEL_TX_C | AN8855_PHY_R50OHM_RSEL_TX_D,
+                                    FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_C, calibration_data[2]) |
+                                    FIELD_PREP(AN8855_PHY_R50OHM_RSEL_TX_D, calibration_data[3]));
+               if (ret)
+                       return ret;
+       }
+
+       /* Apply values to reduce signal noise */
+       ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_TX_PAIR_DLY_SEL_GBE,
+                           FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_A_GBE, 0x4) |
+                           FIELD_PREP(AN8855_PHY_CR_DA_TX_PAIR_DELKAY_SEL_C_GBE, 0x4));
+       if (ret)
+               return ret;
+       ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_CTRL,
+                           AN8855_PHY_RG_AD_SAMNPLE_PHSEL_A |
+                           AN8855_PHY_RG_AD_SAMNPLE_PHSEL_C);
+       if (ret)
+               return ret;
+       ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_0,
+                           FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_A, 0x1));
+       if (ret)
+               return ret;
+       ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AN8855_PHY_RXADC_REV_1,
+                           FIELD_PREP(AN8855_PHY_RG_AD_RESERVE0_C, 0x1));
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int an8855_get_tunable(struct phy_device *phydev,
+                             struct ethtool_tunable *tuna, void *data)
+{
+       switch (tuna->id) {
+       case ETHTOOL_PHY_DOWNSHIFT:
+               return an8855_get_downshift(phydev, data);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static int an8855_set_tunable(struct phy_device *phydev,
+                             struct ethtool_tunable *tuna, const void *data)
+{
+       switch (tuna->id) {
+       case ETHTOOL_PHY_DOWNSHIFT:
+               return an8855_set_downshift(phydev, *(const u8 *)data);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static int an8855_read_page(struct phy_device *phydev)
+{
+       return __phy_read(phydev, AN8855_PHY_SELECT_PAGE);
+}
+
+static int an8855_write_page(struct phy_device *phydev, int page)
+{
+       return __phy_write(phydev, AN8855_PHY_SELECT_PAGE, page);
+}
+
+static struct phy_driver an8855_driver[] = {
+{
+       PHY_ID_MATCH_EXACT(AN8855_PHY_ID),
+       .name                   = "Airoha AN8855 internal PHY",
+       /* PHY_GBIT_FEATURES */
+       .flags                  = PHY_IS_INTERNAL,
+       .probe                  = an8855_probe,
+       .config_init            = an8855_config_init,
+       .soft_reset             = genphy_soft_reset,
+       .get_tunable            = an8855_get_tunable,
+       .set_tunable            = an8855_set_tunable,
+       .suspend                = genphy_suspend,
+       .resume                 = genphy_resume,
+       .read_page              = an8855_read_page,
+       .write_page             = an8855_write_page,
+}, };
+
+module_phy_driver(an8855_driver);
+
+static const struct mdio_device_id __maybe_unused an8855_tbl[] = {
+       { PHY_ID_MATCH_EXACT(AN8855_PHY_ID) },
+       { }
+};
+
+MODULE_DEVICE_TABLE(mdio, an8855_tbl);
+
+MODULE_DESCRIPTION("Airoha AN8855 PHY driver");
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/files-6.12/drivers/nvmem/an8855-efuse.c b/target/linux/mediatek/files-6.12/drivers/nvmem/an8855-efuse.c
new file mode 100644 (file)
index 0000000..7940453
--- /dev/null
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Airoha AN8855 Switch EFUSE Driver
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define AN8855_EFUSE_CELL              50
+
+#define AN8855_EFUSE_DATA0             0x1000a500
+#define   AN8855_EFUSE_R50O            GENMASK(30, 24)
+
+static int an8855_efuse_read(void *context, unsigned int offset,
+                            void *val, size_t bytes)
+{
+       struct regmap *regmap = context;
+
+       return regmap_bulk_read(regmap, AN8855_EFUSE_DATA0 + offset,
+                               val, bytes / sizeof(u32));
+}
+
+static int an8855_efuse_probe(struct platform_device *pdev)
+{
+       struct nvmem_config an8855_nvmem_config = {
+               .name = "an8855-efuse",
+               .size = AN8855_EFUSE_CELL * sizeof(u32),
+               .stride = sizeof(u32),
+               .word_size = sizeof(u32),
+               .reg_read = an8855_efuse_read,
+       };
+       struct device *dev = &pdev->dev;
+       struct nvmem_device *nvmem;
+
+       /* Assign NVMEM priv to MFD regmap */
+       an8855_nvmem_config.priv = dev_get_regmap(dev->parent, NULL);
+       an8855_nvmem_config.dev = dev;
+       nvmem = devm_nvmem_register(dev, &an8855_nvmem_config);
+
+       return PTR_ERR_OR_ZERO(nvmem);
+}
+
+static const struct of_device_id an8855_efuse_of_match[] = {
+       { .compatible = "airoha,an8855-efuse", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, an8855_efuse_of_match);
+
+static struct platform_driver an8855_efuse_driver = {
+       .probe = an8855_efuse_probe,
+       .driver = {
+               .name = "an8855-efuse",
+               .of_match_table = an8855_efuse_of_match,
+       },
+};
+module_platform_driver(an8855_efuse_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_DESCRIPTION("Driver for AN8855 Switch EFUSE");
+MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/files-6.12/include/linux/mfd/airoha-an8855-mfd.h b/target/linux/mediatek/files-6.12/include/linux/mfd/airoha-an8855-mfd.h
new file mode 100644 (file)
index 0000000..5606156
--- /dev/null
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * MFD driver for Airoha AN8855 Switch
+ */
+#ifndef _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H
+#define _LINUX_INCLUDE_MFD_AIROHA_AN8855_MFD_H
+
+#include <linux/bitfield.h>
+
+/* MII Registers */
+#define AN8855_PHY_SELECT_PAGE         0x1f
+#define   AN8855_PHY_PAGE              GENMASK(2, 0)
+#define   AN8855_PHY_PAGE_STANDARD     FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x0)
+#define   AN8855_PHY_PAGE_EXTENDED_1   FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x1)
+#define   AN8855_PHY_PAGE_EXTENDED_4   FIELD_PREP_CONST(AN8855_PHY_PAGE, 0x4)
+
+/* MII Registers Page 4 */
+#define AN8855_PBUS_MODE               0x10
+#define   AN8855_PBUS_MODE_ADDR_FIXED  0x0
+#define AN8855_PBUS_MODE_ADDR_INCR     BIT(15)
+#define AN8855_PBUS_WR_ADDR_HIGH       0x11
+#define AN8855_PBUS_WR_ADDR_LOW                0x12
+#define AN8855_PBUS_WR_DATA_HIGH       0x13
+#define AN8855_PBUS_WR_DATA_LOW                0x14
+#define AN8855_PBUS_RD_ADDR_HIGH       0x15
+#define AN8855_PBUS_RD_ADDR_LOW                0x16
+#define AN8855_PBUS_RD_DATA_HIGH       0x17
+#define AN8855_PBUS_RD_DATA_LOW                0x18
+
+struct an8855_mfd_priv {
+       struct device *dev;
+       struct mii_bus *bus;
+
+       unsigned int switch_addr;
+       u16 current_page;
+};
+
+int an8855_mii_set_page(struct an8855_mfd_priv *priv, u8 phy_id,
+                       u8 page);
+
+#endif
diff --git a/target/linux/mediatek/filogic/config-6.12 b/target/linux/mediatek/filogic/config-6.12
new file mode 100644 (file)
index 0000000..d319785
--- /dev/null
@@ -0,0 +1,534 @@
+CONFIG_64BIT=y
+# CONFIG_AHCI_MTK is not set
+CONFIG_AIROHA_EN8801SC_PHY=y
+CONFIG_AIR_AN8855_PHY=y
+CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
+CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
+CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_FORCE_MAX_ORDER=10
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=24
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_PKEY_BITS=3
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANTS_EXECMEM_LATE=y
+CONFIG_ARCH_WANTS_NO_INSTR=y
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_ARM64=y
+CONFIG_ARM64_4K_PAGES=y
+CONFIG_ARM64_ERRATUM_843419=y
+CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
+CONFIG_ARM64_PA_BITS=48
+CONFIG_ARM64_PA_BITS_48=y
+CONFIG_ARM64_PLATFORM_DEVICES=y
+CONFIG_ARM64_TAGGED_ADDR_ABI=y
+CONFIG_ARM64_VA_BITS=39
+CONFIG_ARM64_VA_BITS_39=y
+# CONFIG_ARM64_VA_BITS_52 is not set
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GIC_V2M=y
+CONFIG_ARM_GIC_V3=y
+CONFIG_ARM_GIC_V3_ITS=y
+CONFIG_ARM_MEDIATEK_CCI_DEVFREQ=y
+CONFIG_ARM_MEDIATEK_CPUFREQ=y
+CONFIG_ARM_PMU=y
+CONFIG_ARM_PMUV3=y
+CONFIG_ARM_PSCI_FW=y
+CONFIG_ATA=y
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BLOCK_NOTIFIERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
+CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
+CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE_OVERRIDE=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_MEDIATEK=y
+# CONFIG_COMMON_CLK_MT2712 is not set
+# CONFIG_COMMON_CLK_MT6779 is not set
+# CONFIG_COMMON_CLK_MT6795 is not set
+# CONFIG_COMMON_CLK_MT6797 is not set
+# CONFIG_COMMON_CLK_MT7622 is not set
+CONFIG_COMMON_CLK_MT7981=y
+CONFIG_COMMON_CLK_MT7981_ETHSYS=y
+CONFIG_COMMON_CLK_MT7986=y
+CONFIG_COMMON_CLK_MT7986_ETHSYS=y
+CONFIG_COMMON_CLK_MT7987=y
+CONFIG_COMMON_CLK_MT7988=y
+# CONFIG_COMMON_CLK_MT8173 is not set
+# CONFIG_COMMON_CLK_MT8183 is not set
+# CONFIG_COMMON_CLK_MT8186 is not set
+# CONFIG_COMMON_CLK_MT8195 is not set
+# CONFIG_COMMON_CLK_MT8365 is not set
+# CONFIG_COMMON_CLK_MT8516 is not set
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CRC16=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRYPTO_AES_ARM64=y
+CONFIG_CRYPTO_AES_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ECC=y
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
+CONFIG_CRYPTO_JITTERENTROPY_OSR=1
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA256_ARM64=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SM4=y
+CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y
+CONFIG_CRYPTO_SM4_ARM64_CE_CCM=y
+CONFIG_CRYPTO_SM4_ARM64_CE_GCM=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_MISC=y
+CONFIG_DEVFREQ_GOV_PASSIVE=y
+# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
+# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
+# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
+# CONFIG_DEVFREQ_GOV_USERSPACE is not set
+# CONFIG_DEVFREQ_THERMAL is not set
+CONFIG_DMADEVICES=y
+CONFIG_DMATEST=y
+CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_ENGINE_RAID=y
+CONFIG_DMA_NEED_SYNC=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DTC=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EINT_MTK=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_F2FS_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=4
+CONFIG_FUNCTION_ALIGNMENT_4B=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_DEVICES=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_WATCHDOG=y
+CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MTK=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MT65XX=y
+CONFIG_ICPLUS_PHY=y
+# CONFIG_IDPF is not set
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MSI_LIB=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_JUMP_LABEL=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_SMARTRG_LED=y
+CONFIG_LEDS_TRIGGER_PATTERN=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LRU_GEN_WALKS_MMU=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAXLINEAR_GPHY=y
+CONFIG_MDIO_AN8855=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEDIATEK_2P5GE_PHY=y
+CONFIG_MEDIATEK_GE_PHY=y
+CONFIG_MEDIATEK_GE_SOC_PHY=y
+CONFIG_MEDIATEK_WATCHDOG=y
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
+CONFIG_MFD_AIROHA_AN8855=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CQHCI=y
+CONFIG_MMC_MTK=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_ECC_MEDIATEK=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_NAND_MTK=y
+CONFIG_MTD_NAND_MTK_BMT=y
+CONFIG_MTD_PARSER_TRX=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_MTD_SPLIT_MSTC_BOOT=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_MTD_UBI_NVMEM=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_VIRT_CONCAT=y
+# CONFIG_MTK_CMDQ is not set
+CONFIG_MTK_CPUX_TIMER=y
+# CONFIG_MTK_CQDMA is not set
+CONFIG_MTK_HSDMA=y
+CONFIG_MTK_INFRACFG=y
+CONFIG_MTK_LVTS_THERMAL=y
+CONFIG_MTK_LVTS_THERMAL_DEBUGFS=y
+CONFIG_MTK_NET_PHYLIB=y
+CONFIG_MTK_PMIC_WRAP=y
+CONFIG_MTK_REGULATOR_COUPLER=y
+CONFIG_MTK_SCPSYS=y
+CONFIG_MTK_SCPSYS_PM_DOMAINS=y
+# CONFIG_MTK_SOCINFO is not set
+CONFIG_MTK_SOC_THERMAL=y
+# CONFIG_MTK_SVS is not set
+CONFIG_MTK_THERMAL=y
+CONFIG_MTK_TIMER=y
+# CONFIG_MTK_UART_APDMA is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+# CONFIG_NET_AIROHA is not set
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_AN8855=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_MT7530_MDIO=y
+CONFIG_NET_DSA_MT7530_MMIO=y
+CONFIG_NET_DSA_TAG_MTK=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_MEDIATEK_SOC=y
+CONFIG_NET_MEDIATEK_SOC_WED=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_VENDOR_MEDIATEK=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_NVMEM_AN8855_EFUSE=y
+CONFIG_NVMEM_BLOCK=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_LAYOUT_ADTRAN=y
+CONFIG_NVMEM_LAYOUT_U_BOOT_ENV=y
+CONFIG_NVMEM_MTK_EFUSE=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_DYNAMIC=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_OVERLAY=y
+CONFIG_OF_RESOLVE=y
+CONFIG_PADATA=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PARTITION_PERCPU=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEASPM=y
+# CONFIG_PCIEASPM_DEFAULT is not set
+CONFIG_PCIEASPM_PERFORMANCE=y
+# CONFIG_PCIEASPM_POWERSAVE is not set
+# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
+CONFIG_PCIEPORTBUS=y
+# CONFIG_PCIE_MEDIATEK is not set
+CONFIG_PCIE_MEDIATEK_GEN3=y
+CONFIG_PCIE_PME=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCS_MTK_LYNXI=y
+CONFIG_PCS_MTK_USXGMII=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PER_VMA_LOCK=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PHY_MTK_DP is not set
+# CONFIG_PHY_MTK_MIPI_CSI_0_5 is not set
+# CONFIG_PHY_MTK_PCIE is not set
+CONFIG_PHY_MTK_TPHY=y
+# CONFIG_PHY_MTK_UFS is not set
+CONFIG_PHY_MTK_XFI_TPHY=y
+CONFIG_PHY_MTK_XSPHY=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_MT2712 is not set
+# CONFIG_PINCTRL_MT6765 is not set
+# CONFIG_PINCTRL_MT6795 is not set
+# CONFIG_PINCTRL_MT6797 is not set
+# CONFIG_PINCTRL_MT7622 is not set
+CONFIG_PINCTRL_MT7981=y
+CONFIG_PINCTRL_MT7986=y
+CONFIG_PINCTRL_MT7987=y
+CONFIG_PINCTRL_MT7988=y
+# CONFIG_PINCTRL_MT8173 is not set
+# CONFIG_PINCTRL_MT8183 is not set
+# CONFIG_PINCTRL_MT8186 is not set
+# CONFIG_PINCTRL_MT8188 is not set
+# CONFIG_PINCTRL_MT8516 is not set
+CONFIG_PINCTRL_MTK_MOORE=y
+CONFIG_PINCTRL_MTK_V2=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_DEVFREQ=y
+CONFIG_PM_DEVFREQ_EVENT=y
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PM_OPP=y
+CONFIG_POLYNOMIAL=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_COMPRESS=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_PMSG=y
+CONFIG_PSTORE_RAM=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_MEDIATEK=y
+# CONFIG_PWM_MTK_DISP is not set
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+# CONFIG_RAVE_SP_CORE is not set
+CONFIG_REALTEK_PHY=y
+CONFIG_REALTEK_PHY_HWMON=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC8=y
+CONFIG_REED_SOLOMON_ENC8=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_MT6380=y
+CONFIG_REGULATOR_RT5190A=y
+CONFIG_RELOCATABLE=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_TI_SYSCON=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MT7622=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTL8261N_PHY=y
+# CONFIG_RTL8367S_GSW is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCHED_MC=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_MT6577=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_BUS=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_DYNAMIC=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_MT65XX=y
+# CONFIG_SPI_MTK_NOR is not set
+CONFIG_SPI_MTK_SNFI=y
+CONFIG_SPLIT_PMD_PTLOCKS=y
+CONFIG_SPLIT_PTE_PTLOCKS=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+# CONFIG_TEST_FPU is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_BANG_BANG=y
+CONFIG_THERMAL_GOV_FAIR_SHARE=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UBIFS_FS=y
+# CONFIG_UCLAMP_TASK is not set
+CONFIG_UIMAGE_FIT_BLK=y
+# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_VDSO_GETRANDOM=y
+CONFIG_VMAP_STACK=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
+# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/mediatek/mt7622/config-6.12 b/target/linux/mediatek/mt7622/config-6.12
new file mode 100644 (file)
index 0000000..79b244e
--- /dev/null
@@ -0,0 +1,516 @@
+CONFIG_64BIT=y
+# CONFIG_AHCI_MTK is not set
+# CONFIG_AIROHA_EN8801SC_PHY is not set
+# CONFIG_AIR_AN8855_PHY is not set
+CONFIG_AQUANTIA_PHY=y
+CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
+CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
+CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_FORCE_MAX_ORDER=10
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=24
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_PKEY_BITS=3
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANTS_EXECMEM_LATE=y
+CONFIG_ARCH_WANTS_NO_INSTR=y
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_ARM64=y
+CONFIG_ARM64_4K_PAGES=y
+CONFIG_ARM64_ERRATUM_843419=y
+CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
+CONFIG_ARM64_PA_BITS=48
+CONFIG_ARM64_PA_BITS_48=y
+CONFIG_ARM64_PLATFORM_DEVICES=y
+CONFIG_ARM64_TAGGED_ADDR_ABI=y
+CONFIG_ARM64_VA_BITS=39
+CONFIG_ARM64_VA_BITS_39=y
+# CONFIG_ARM64_VA_BITS_52 is not set
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GIC_V2M=y
+CONFIG_ARM_GIC_V3=y
+CONFIG_ARM_GIC_V3_ITS=y
+CONFIG_ARM_MEDIATEK_CPUFREQ=y
+CONFIG_ARM_PMU=y
+CONFIG_ARM_PMUV3=y
+CONFIG_ARM_PSCI_FW=y
+CONFIG_ATA=y
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BLOCK_NOTIFIERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
+CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
+CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_MEDIATEK=y
+CONFIG_COMMON_CLK_MT2712=y
+# CONFIG_COMMON_CLK_MT2712_BDPSYS is not set
+# CONFIG_COMMON_CLK_MT2712_IMGSYS is not set
+# CONFIG_COMMON_CLK_MT2712_JPGDECSYS is not set
+# CONFIG_COMMON_CLK_MT2712_MFGCFG is not set
+# CONFIG_COMMON_CLK_MT2712_MMSYS is not set
+# CONFIG_COMMON_CLK_MT2712_VDECSYS is not set
+# CONFIG_COMMON_CLK_MT2712_VENCSYS is not set
+# CONFIG_COMMON_CLK_MT6779 is not set
+# CONFIG_COMMON_CLK_MT6795 is not set
+# CONFIG_COMMON_CLK_MT6797 is not set
+CONFIG_COMMON_CLK_MT7622=y
+CONFIG_COMMON_CLK_MT7622_AUDSYS=y
+CONFIG_COMMON_CLK_MT7622_ETHSYS=y
+CONFIG_COMMON_CLK_MT7622_HIFSYS=y
+# CONFIG_COMMON_CLK_MT7981 is not set
+# CONFIG_COMMON_CLK_MT7986 is not set
+# CONFIG_COMMON_CLK_MT7987 is not set
+# CONFIG_COMMON_CLK_MT7988 is not set
+# CONFIG_COMMON_CLK_MT8173 is not set
+# CONFIG_COMMON_CLK_MT8183 is not set
+# CONFIG_COMMON_CLK_MT8186 is not set
+# CONFIG_COMMON_CLK_MT8195 is not set
+# CONFIG_COMMON_CLK_MT8365 is not set
+# CONFIG_COMMON_CLK_MT8516 is not set
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CRC16=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_AES_ARM64=y
+CONFIG_CRYPTO_AES_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ECC=y
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
+CONFIG_CRYPTO_JITTERENTROPY_OSR=1
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA256_ARM64=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SM4=y
+CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y
+CONFIG_CRYPTO_SM4_ARM64_CE_CCM=y
+CONFIG_CRYPTO_SM4_ARM64_CE_GCM=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_MISC=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_NEED_SYNC=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DTC=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EINT_MTK=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_F2FS_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FRAME_POINTER=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=4
+CONFIG_FUNCTION_ALIGNMENT_4B=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_DEVICES=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MTK=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MT65XX=y
+CONFIG_ICPLUS_PHY=y
+# CONFIG_IDPF is not set
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INTEL_XWAY_PHY=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MSI_LIB=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_JUMP_LABEL=y
+CONFIG_LEDS_SMARTRG_LED=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LRU_GEN_WALKS_MMU=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAXLINEAR_GPHY=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+# CONFIG_MEDIATEK_2P5GE_PHY is not set
+CONFIG_MEDIATEK_GE_PHY=y
+# CONFIG_MEDIATEK_GE_SOC_PHY is not set
+CONFIG_MEDIATEK_WATCHDOG=y
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
+# CONFIG_MFD_AIROHA_AN8855 is not set
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CQHCI=y
+CONFIG_MMC_MTK=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_ECC_MEDIATEK=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_NAND_MTK=y
+CONFIG_MTD_NAND_MTK_BMT=y
+CONFIG_MTD_PARSER_TRX=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_MTD_UBI_NVMEM=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+# CONFIG_MTK_CMDQ is not set
+CONFIG_MTK_CPUX_TIMER=y
+# CONFIG_MTK_CQDMA is not set
+CONFIG_MTK_HSDMA=y
+CONFIG_MTK_INFRACFG=y
+# CONFIG_MTK_LVTS_THERMAL is not set
+CONFIG_MTK_NET_PHYLIB=y
+CONFIG_MTK_PMIC_WRAP=y
+CONFIG_MTK_REGULATOR_COUPLER=y
+CONFIG_MTK_SCPSYS=y
+CONFIG_MTK_SCPSYS_PM_DOMAINS=y
+# CONFIG_MTK_SOCINFO is not set
+CONFIG_MTK_SOC_THERMAL=y
+# CONFIG_MTK_SVS is not set
+CONFIG_MTK_THERMAL=y
+CONFIG_MTK_TIMER=y
+# CONFIG_MTK_UART_APDMA is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+# CONFIG_NET_AIROHA is not set
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_MT7530_MDIO=y
+# CONFIG_NET_DSA_MT7530_MMIO is not set
+CONFIG_NET_DSA_TAG_MTK=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_MEDIATEK_SOC=y
+CONFIG_NET_MEDIATEK_SOC_WED=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_VENDOR_MEDIATEK=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=2
+CONFIG_NVMEM=y
+CONFIG_NVMEM_BLOCK=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_LAYOUT_ADTRAN=y
+CONFIG_NVMEM_MTK_EFUSE=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_DYNAMIC=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_OVERLAY=y
+CONFIG_OF_RESOLVE=y
+CONFIG_PADATA=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PARTITION_PERCPU=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEASPM=y
+# CONFIG_PCIEASPM_DEFAULT is not set
+CONFIG_PCIEASPM_PERFORMANCE=y
+# CONFIG_PCIEASPM_POWERSAVE is not set
+# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIE_MEDIATEK=y
+CONFIG_PCIE_PME=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCS_MTK_LYNXI=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PER_VMA_LOCK=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PHY_MTK_DP is not set
+# CONFIG_PHY_MTK_MIPI_CSI_0_5 is not set
+# CONFIG_PHY_MTK_PCIE is not set
+CONFIG_PHY_MTK_TPHY=y
+# CONFIG_PHY_MTK_UFS is not set
+# CONFIG_PHY_MTK_XSPHY is not set
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_MT2712 is not set
+# CONFIG_PINCTRL_MT6765 is not set
+# CONFIG_PINCTRL_MT6795 is not set
+# CONFIG_PINCTRL_MT6797 is not set
+CONFIG_PINCTRL_MT7622=y
+# CONFIG_PINCTRL_MT7981 is not set
+# CONFIG_PINCTRL_MT7986 is not set
+# CONFIG_PINCTRL_MT7987 is not set
+# CONFIG_PINCTRL_MT7988 is not set
+# CONFIG_PINCTRL_MT8173 is not set
+# CONFIG_PINCTRL_MT8183 is not set
+# CONFIG_PINCTRL_MT8186 is not set
+# CONFIG_PINCTRL_MT8188 is not set
+# CONFIG_PINCTRL_MT8516 is not set
+CONFIG_PINCTRL_MTK_MOORE=y
+CONFIG_PINCTRL_MTK_V2=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PM_OPP=y
+CONFIG_POLYNOMIAL=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_COMPRESS=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_PMSG=y
+CONFIG_PSTORE_RAM=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_MEDIATEK=y
+# CONFIG_PWM_MTK_DISP is not set
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+# CONFIG_RAVE_SP_CORE is not set
+CONFIG_REALTEK_PHY=y
+CONFIG_REALTEK_PHY_HWMON=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC8=y
+CONFIG_REED_SOLOMON_ENC8=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_MT6380=y
+CONFIG_RELOCATABLE=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MT7622=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTL8367S_GSW=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCHED_MC=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_MT6577=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_BUS=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_DYNAMIC=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_MT65XX=y
+CONFIG_SPI_MTK_NOR=y
+CONFIG_SPI_MTK_SNFI=y
+CONFIG_SWCONFIG=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+# CONFIG_TEST_FPU is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_EMULATION=y
+CONFIG_THERMAL_GOV_BANG_BANG=y
+CONFIG_THERMAL_GOV_FAIR_SHARE=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UBIFS_FS=y
+# CONFIG_UCLAMP_TASK is not set
+CONFIG_UIMAGE_FIT_BLK=y
+# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_VDSO_GETRANDOM=y
+CONFIG_VMAP_STACK=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
+# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/mediatek/mt7623/config-6.12 b/target/linux/mediatek/mt7623/config-6.12
new file mode 100644 (file)
index 0000000..b803887
--- /dev/null
@@ -0,0 +1,525 @@
+# CONFIG_AIO is not set
+# CONFIG_AIROHA_EN8801SC_PHY is not set
+# CONFIG_AIR_AN8855_PHY is not set
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+# CONFIG_ARM_ATAG_DTB_COMPAT is not set
+CONFIG_ARM_CPU_SUSPEND=y
+# CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8
+CONFIG_ARM_DMA_USE_IOMMU=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+# CONFIG_ARM_MEDIATEK_CCI_DEVFREQ is not set
+CONFIG_ARM_MEDIATEK_CPUFREQ=y
+CONFIG_ARM_PAN=y
+CONFIG_ARM_PATCH_IDIV=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_SMMU is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GPIO=y
+CONFIG_BACKLIGHT_LED=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BOUNCE=y
+CONFIG_BUFFER_HEAD=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_COMMON_CLK_MEDIATEK=y
+CONFIG_COMMON_CLK_MT2701=y
+CONFIG_COMMON_CLK_MT2701_AUDSYS=y
+CONFIG_COMMON_CLK_MT2701_BDPSYS=y
+CONFIG_COMMON_CLK_MT2701_ETHSYS=y
+CONFIG_COMMON_CLK_MT2701_G3DSYS=y
+CONFIG_COMMON_CLK_MT2701_HIFSYS=y
+CONFIG_COMMON_CLK_MT2701_IMGSYS=y
+CONFIG_COMMON_CLK_MT2701_MMSYS=y
+CONFIG_COMMON_CLK_MT2701_VDECSYS=y
+# CONFIG_COMMON_CLK_MT6795 is not set
+# CONFIG_COMMON_CLK_MT7622 is not set
+# CONFIG_COMMON_CLK_MT7629 is not set
+# CONFIG_COMMON_CLK_MT7981 is not set
+# CONFIG_COMMON_CLK_MT7986 is not set
+# CONFIG_COMMON_CLK_MT7987 is not set
+# CONFIG_COMMON_CLK_MT7988 is not set
+# CONFIG_COMMON_CLK_MT8135 is not set
+# CONFIG_COMMON_CLK_MT8365 is not set
+# CONFIG_COMMON_CLK_MT8516 is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_COREDUMP=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_GENIV=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS=64
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE=32
+CONFIG_CRYPTO_JITTERENTROPY_OSR=1
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SEQIV=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_ALIGN_RODATA=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
+CONFIG_DEBUG_MISC=y
+CONFIG_DEBUG_MT6589_UART0=y
+# CONFIG_DEBUG_MT8127_UART0 is not set
+# CONFIG_DEBUG_MT8135_UART3 is not set
+CONFIG_DEBUG_UART_8250=y
+CONFIG_DEBUG_UART_8250_SHIFT=2
+CONFIG_DEBUG_UART_PHYS=0x11004000
+CONFIG_DEBUG_UART_VIRT=0xf1004000
+# CONFIG_DEVFREQ_GOV_PASSIVE is not set
+# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
+# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+# CONFIG_DEVFREQ_GOV_USERSPACE is not set
+# CONFIG_DEVFREQ_THERMAL is not set
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DRM=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_BRIDGE_CONNECTOR=y
+CONFIG_DRM_DISPLAY_CONNECTOR=y
+CONFIG_DRM_DISPLAY_HDMI_HELPER=y
+CONFIG_DRM_DISPLAY_HDMI_STATE_HELPER=y
+CONFIG_DRM_DISPLAY_HELPER=y
+CONFIG_DRM_FBDEV_EMULATION=y
+CONFIG_DRM_FBDEV_OVERALLOC=100
+CONFIG_DRM_GEM_DMA_HELPER=y
+CONFIG_DRM_GEM_SHMEM_HELPER=y
+CONFIG_DRM_KMS_HELPER=y
+CONFIG_DRM_LIMA=y
+CONFIG_DRM_LVDS_CODEC=y
+CONFIG_DRM_MEDIATEK=y
+# CONFIG_DRM_MEDIATEK_DP is not set
+CONFIG_DRM_MEDIATEK_HDMI=y
+CONFIG_DRM_MIPI_DSI=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_BRIDGE=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=y
+CONFIG_DRM_SCHED=y
+CONFIG_DRM_SIMPLE_BRIDGE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EINT_MTK=y
+CONFIG_ELF_CORE=y
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+CONFIG_F2FS_FS=y
+CONFIG_FB=y
+CONFIG_FB_CORE=y
+CONFIG_FB_DEFERRED_IO=y
+CONFIG_FB_DEVICE=y
+CONFIG_FB_DMAMEM_HELPERS=y
+CONFIG_FB_DMAMEM_HELPERS_DEFERRED=y
+CONFIG_FB_SYSMEM_FOPS=y
+CONFIG_FB_SYSMEM_HELPERS=y
+CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+CONFIG_FIXED_PHY=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FREEZER=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_CACHE=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_VDSO_32=y
+CONFIG_GRO_CELLS=y
+# CONFIG_HARDEN_BRANCH_HISTORY is not set
+# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
+CONFIG_HAVE_SMP=y
+CONFIG_HDMI=y
+CONFIG_HID=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HOTPLUG_CORE_SYNC=y
+CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MTK=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MT65XX=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_IIO=y
+CONFIG_INPUT=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_IOMMUFD is not set
+CONFIG_IOMMU_API=y
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
+CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
+# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
+CONFIG_IOMMU_IO_PGTABLE=y
+CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
+# CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST is not set
+# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_JBD2=y
+CONFIG_KALLSYMS=y
+CONFIG_KCMP=y
+CONFIG_KEYBOARD_MTK_PMIC=y
+CONFIG_KMAP_LOCAL=y
+CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_LEDS_MT6323=y
+# CONFIG_LEDS_QCOM_LPG is not set
+# CONFIG_LEDS_SMARTRG_LED is not set
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_MACH_MT2701 is not set
+# CONFIG_MACH_MT6589 is not set
+# CONFIG_MACH_MT6592 is not set
+CONFIG_MACH_MT7623=y
+# CONFIG_MACH_MT7629 is not set
+# CONFIG_MACH_MT8127 is not set
+# CONFIG_MACH_MT8135 is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAILBOX=y
+# CONFIG_MAILBOX_TEST is not set
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_GPIO=y
+CONFIG_MEDIATEK_GE_PHY=y
+# CONFIG_MEDIATEK_MT6359_AUXADC is not set
+CONFIG_MEDIATEK_MT6577_AUXADC=y
+CONFIG_MEDIATEK_WATCHDOG=y
+CONFIG_MEMORY=y
+# CONFIG_MFD_AIROHA_AN8855 is not set
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_HI6421_SPMI is not set
+CONFIG_MFD_MT6397=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CQHCI=y
+CONFIG_MMC_MTK=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_NAND_ECC_MEDIATEK is not set
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+# CONFIG_MTK_ADSP_MBOX is not set
+CONFIG_MTK_CMDQ=y
+CONFIG_MTK_CMDQ_MBOX=y
+CONFIG_MTK_CPUX_TIMER=y
+CONFIG_MTK_CQDMA=y
+# CONFIG_MTK_HSDMA is not set
+CONFIG_MTK_INFRACFG=y
+CONFIG_MTK_IOMMU=y
+CONFIG_MTK_IOMMU_V1=y
+# CONFIG_MTK_LVTS_THERMAL is not set
+CONFIG_MTK_MMSYS=y
+CONFIG_MTK_NET_PHYLIB=y
+CONFIG_MTK_PMIC_WRAP=y
+CONFIG_MTK_REGULATOR_COUPLER=y
+CONFIG_MTK_SCPSYS=y
+CONFIG_MTK_SCPSYS_PM_DOMAINS=y
+CONFIG_MTK_SMI=y
+# CONFIG_MTK_SOCINFO is not set
+CONFIG_MTK_SOC_THERMAL=y
+# CONFIG_MTK_SVS is not set
+CONFIG_MTK_THERMAL=y
+CONFIG_MTK_TIMER=y
+# CONFIG_MTK_UART_APDMA is not set
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NEON=y
+# CONFIG_NET_AIROHA is not set
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DEVMEM=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_MT7530_MDIO=y
+# CONFIG_NET_DSA_MT7530_MMIO is not set
+CONFIG_NET_DSA_TAG_MTK=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_MEDIATEK_SOC=y
+CONFIG_NET_MEDIATEK_SOC_WED=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_VENDOR_MEDIATEK=y
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_NLS=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+# CONFIG_NVMEM_LAYOUT_ADTRAN is not set
+CONFIG_NVMEM_MTK_EFUSE=y
+# CONFIG_NVMEM_SPMI_SDAM is not set
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF_DYNAMIC=y
+CONFIG_OF_IOMMU=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_OVERLAY=y
+CONFIG_OF_RESOLVE=y
+CONFIG_PADATA=y
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIE_MEDIATEK=y
+CONFIG_PCIE_PME=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCS_MTK_LYNXI=y
+CONFIG_PER_VMA_LOCK=y
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+# CONFIG_PHY_MTK_DP is not set
+CONFIG_PHY_MTK_HDMI=y
+# CONFIG_PHY_MTK_MIPI_CSI_0_5 is not set
+CONFIG_PHY_MTK_MIPI_DSI=y
+# CONFIG_PHY_MTK_PCIE is not set
+CONFIG_PHY_MTK_TPHY=y
+# CONFIG_PHY_MTK_UFS is not set
+# CONFIG_PHY_MTK_XSPHY is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_MT2701=y
+# CONFIG_PINCTRL_MT6397 is not set
+CONFIG_PINCTRL_MT7623=y
+CONFIG_PINCTRL_MTK=y
+CONFIG_PINCTRL_MTK_MOORE=y
+CONFIG_PINCTRL_MTK_V2=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_DEVFREQ=y
+# CONFIG_PM_DEVFREQ_EVENT is not set
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
+CONFIG_PM_OPP=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_MT6323 is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_SUPPLY_HWMON=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PWM=y
+CONFIG_PWM_MEDIATEK=y
+# CONFIG_PWM_MTK_DISP is not set
+CONFIG_RAS=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MT6323=y
+# CONFIG_REGULATOR_MT6331 is not set
+# CONFIG_REGULATOR_MT6332 is not set
+# CONFIG_REGULATOR_MT6357 is not set
+# CONFIG_REGULATOR_MT6358 is not set
+# CONFIG_REGULATOR_MT6380 is not set
+# CONFIG_REGULATOR_MT6397 is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_MT6397 is not set
+# CONFIG_RTC_DRV_MT7622 is not set
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+# CONFIG_RTL8367S_GSW is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+# CONFIG_SERIAL_8250_DMA is not set
+CONFIG_SERIAL_8250_MT6577=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SGL_ALLOC=y
+CONFIG_SMP=y
+# CONFIG_SMP_ON_UP is not set
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_DYNAMIC=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_MT65XX=y
+# CONFIG_SPI_MTK_NOR is not set
+CONFIG_SPLIT_PTE_PTLOCKS=y
+CONFIG_SPMI=y
+# CONFIG_SPMI_HISI3670 is not set
+# CONFIG_SPMI_MTK_PMIF is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWPHY=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYNC_FILE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_OF=y
+CONFIG_TOUCHSCREEN_EDT_FT5X06=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UBIFS_FS=y
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_UIMAGE_FIT_BLK=y
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_F_ACM=y
+CONFIG_USB_F_ECM=y
+CONFIG_USB_F_MASS_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_USB_G_MULTI=y
+CONFIG_USB_G_MULTI_CDC=y
+# CONFIG_USB_G_MULTI_RNDIS is not set
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_INVENTRA_DMA=y
+CONFIG_USB_LIBCOMPOSITE=y
+CONFIG_USB_MUSB_DUAL_ROLE=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_MEDIATEK=y
+CONFIG_USB_OTG=y
+CONFIG_USB_PHY=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_U_ETHER=y
+CONFIG_USB_U_SERIAL=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VIDEO=y
+CONFIG_VIDEOMODE_HELPERS=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/mediatek/mt7629/config-6.12 b/target/linux/mediatek/mt7629/config-6.12
new file mode 100644 (file)
index 0000000..1f49214
--- /dev/null
@@ -0,0 +1,367 @@
+# CONFIG_AIROHA_EN8801SC_PHY is not set
+# CONFIG_AIR_AN8855_PHY is not set
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM=y
+CONFIG_ARM_ARCH_TIMER=y
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+# CONFIG_ARM_DEBUG_WX is not set
+CONFIG_ARM_GIC=y
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_HEAVY_MB=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_PAN=y
+CONFIG_ARM_PATCH_IDIV=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_CMDLINE_OVERRIDE=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_MEDIATEK=y
+# CONFIG_COMMON_CLK_MT2701 is not set
+# CONFIG_COMMON_CLK_MT6795 is not set
+# CONFIG_COMMON_CLK_MT7622 is not set
+CONFIG_COMMON_CLK_MT7629=y
+CONFIG_COMMON_CLK_MT7629_ETHSYS=y
+CONFIG_COMMON_CLK_MT7629_HIFSYS=y
+# CONFIG_COMMON_CLK_MT7981 is not set
+# CONFIG_COMMON_CLK_MT7986 is not set
+# CONFIG_COMMON_CLK_MT7987 is not set
+# CONFIG_COMMON_CLK_MT7988 is not set
+# CONFIG_COMMON_CLK_MT8135 is not set
+# CONFIG_COMMON_CLK_MT8365 is not set
+# CONFIG_COMMON_CLK_MT8516 is not set
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DEBUG_MISC=y
+CONFIG_DEFAULT_HOSTNAME="(mt7629)"
+CONFIG_DMA_NEED_SYNC=y
+CONFIG_DMA_OPS_HELPERS=y
+CONFIG_DTC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EINT_MTK=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FS_IOMAP=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_DEVICES=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_VDSO_32=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GRO_CELLS=y
+# CONFIG_HARDEN_BRANCH_HISTORY is not set
+# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_SMP=y
+CONFIG_HOTPLUG_CORE_SYNC=y
+CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MTK=y
+CONFIG_HZ_FIXED=0
+# CONFIG_IDPF is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
+# CONFIG_LEDS_SMARTRG_LED is not set
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_MACH_MT2701 is not set
+# CONFIG_MACH_MT6589 is not set
+# CONFIG_MACH_MT6592 is not set
+# CONFIG_MACH_MT7623 is not set
+CONFIG_MACH_MT7629=y
+# CONFIG_MACH_MT8127 is not set
+# CONFIG_MACH_MT8135 is not set
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEDIATEK_GE_PHY=y
+CONFIG_MEDIATEK_WATCHDOG=y
+# CONFIG_MFD_AIROHA_AN8855 is not set
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGRATION=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_ECC_MEDIATEK=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_NAND_MTK_BMT=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+# CONFIG_MTK_CMDQ is not set
+CONFIG_MTK_CPUX_TIMER=y
+CONFIG_MTK_INFRACFG=y
+CONFIG_MTK_NET_PHYLIB=y
+# CONFIG_MTK_PMIC_WRAP is not set
+CONFIG_MTK_SCPSYS=y
+CONFIG_MTK_SCPSYS_PM_DOMAINS=y
+CONFIG_MTK_TIMER=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_BPF_LINK=y
+# CONFIG_NET_AIROHA is not set
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_MT7530_MDIO=y
+# CONFIG_NET_DSA_MT7530_MMIO is not set
+CONFIG_NET_DSA_TAG_MTK=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_MEDIATEK_SOC=y
+CONFIG_NET_MEDIATEK_SOC_WED=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_VENDOR_MEDIATEK=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=2
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+# CONFIG_NVMEM_LAYOUT_ADTRAN is not set
+CONFIG_NVMEM_LAYOUT_ASCII_ENV=y
+# CONFIG_NVMEM_MTK_EFUSE is not set
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIE_MEDIATEK=y
+CONFIG_PCIE_PME=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCS_MTK_LYNXI=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PER_VMA_LOCK=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+# CONFIG_PHY_MTK_DP is not set
+# CONFIG_PHY_MTK_MIPI_CSI_0_5 is not set
+# CONFIG_PHY_MTK_PCIE is not set
+CONFIG_PHY_MTK_TPHY=y
+# CONFIG_PHY_MTK_UFS is not set
+# CONFIG_PHY_MTK_XSPHY is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_MT7629=y
+CONFIG_PINCTRL_MTK_MOORE=y
+CONFIG_PINCTRL_MTK_V2=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_MEDIATEK=y
+# CONFIG_PWM_MTK_DISP is not set
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+# CONFIG_RTL8367S_GSW is not set
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_MT6577=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_MT65XX=y
+CONFIG_SPI_MTK_NOR=y
+CONFIG_SPI_MTK_SNFI=y
+CONFIG_STACKTRACE=y
+# CONFIG_SWAP is not set
+CONFIG_SWCONFIG=y
+CONFIG_SWPHY=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UBIFS_FS=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MTK=y
+# CONFIG_USB_XHCI_PLATFORM is not set
+CONFIG_USE_OF=y
+# CONFIG_VFP is not set
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZSTD_COMMON=y
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/mediatek/patches-6.12/010-v6.14-pinctrl-mediatek-add-support-for-MTK_PULL_PD_TYPE.patch b/target/linux/mediatek/patches-6.12/010-v6.14-pinctrl-mediatek-add-support-for-MTK_PULL_PD_TYPE.patch
new file mode 100644 (file)
index 0000000..2dcdbcf
--- /dev/null
@@ -0,0 +1,151 @@
+From 1673d720b7e2862a5ff1994922558b7427f8a56b Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 17 Dec 2024 09:54:26 +0100
+Subject: [PATCH 1/2] pinctrl: mediatek: add support for MTK_PULL_PD_TYPE
+
+The MediaTek MT7988 SoC got some pins which only got configurable
+pull-down but unlike previous designs there is no pull-up option.
+Add new type MTK_PULL_PD_TYPE to support configuring such pins.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/20241217085435.9586-2-linux@fw-web.de
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 73 ++++++++++++++++---
+ .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |  1 +
+ 2 files changed, 63 insertions(+), 11 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_r
+  */
+ static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+-                              u32 pullup, u32 arg)
++                              u32 pullup, u32 arg, bool pd_only)
+ {
+       int err, pu, pd;
+@@ -587,18 +587,34 @@ static int mtk_pinconf_bias_set_pu_pd(st
+               pu = 0;
+               pd = 1;
+       } else {
+-              err = -EINVAL;
+-              goto out;
++              return -EINVAL;
+       }
+-      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
+-      if (err)
+-              goto out;
++      if (!pd_only) {
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
++              if (err)
++                      return err;
++      }
+-      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
++      return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
++}
++
++static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err, pd;
++
++      if (arg != MTK_DISABLE && arg != MTK_ENABLE)
++              return -EINVAL;
++
++      if (arg == MTK_DISABLE || pullup)
++              pd = 0;
++      else if (!pullup)
++              pd = 1;
++
++      return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+-out:
+-      return err;
+ }
+ static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
+@@ -737,7 +753,7 @@ static int mtk_pinconf_bias_set_pu_pd_rs
+                       return err;
+       }
+-      return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable);
++      return mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, enable, false);
+ }
+ int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+@@ -758,8 +774,14 @@ int mtk_pinconf_bias_set_combo(struct mt
+                       return 0;
+       }
++      if (try_all_type & MTK_PULL_PD_TYPE) {
++              err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, true);
++              if (!err)
++                      return err;
++      }
++
+       if (try_all_type & MTK_PULL_PU_PD_TYPE) {
+-              err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
++              err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg, false);
+               if (!err)
+                       return 0;
+       }
+@@ -878,6 +900,29 @@ out:
+       return err;
+ }
++static int mtk_pinconf_bias_get_pd(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 *pullup, u32 *enable)
++{
++      int err, pd;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
++      if (err)
++              goto out;
++
++      if (pd == 0) {
++              *pullup = 0;
++              *enable = MTK_DISABLE;
++      } else if (pd == 1) {
++              *pullup = 0;
++              *enable = MTK_ENABLE;
++      } else
++              err = -EINVAL;
++
++out:
++      return err;
++}
++
+ static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 *pullup, u32 *enable)
+@@ -947,6 +992,12 @@ int mtk_pinconf_bias_get_combo(struct mt
+                       return 0;
+       }
++      if (try_all_type & MTK_PULL_PD_TYPE) {
++              err = mtk_pinconf_bias_get_pd(hw, desc, pullup, enable);
++              if (!err)
++                      return err;
++      }
++
+       if (try_all_type & MTK_PULL_PU_PD_TYPE) {
+               err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+               if (!err)
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+@@ -24,6 +24,7 @@
+  * turned on/off itself. But it can't be selected pull up/down
+  */
+ #define MTK_PULL_RSEL_TYPE            BIT(3)
++#define MTK_PULL_PD_TYPE        BIT(4)
+ /* MTK_PULL_PU_PD_RSEL_TYPE is a type which is controlled by
+  * MTK_PULL_PU_PD_TYPE and MTK_PULL_RSEL_TYPE.
+  */
diff --git a/target/linux/mediatek/patches-6.12/011-v6.14-pinctrl-mediatek-add-MT7988-pinctrl-driver.patch b/target/linux/mediatek/patches-6.12/011-v6.14-pinctrl-mediatek-add-MT7988-pinctrl-driver.patch
new file mode 100644 (file)
index 0000000..d94a0ba
--- /dev/null
@@ -0,0 +1,1610 @@
+From 08bec851118226cc8c4397692542b855de2e0d73 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 17 Dec 2024 09:54:27 +0100
+Subject: [PATCH 2/2] pinctrl: mediatek: add MT7988 pinctrl driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add pinctrl driver for the MediaTek MT7988 SoC.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+[correctly initialise for the function_desc structure]
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/20241217085435.9586-3-linux@fw-web.de
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/Kconfig          |    7 +
+ drivers/pinctrl/mediatek/Makefile         |    1 +
+ drivers/pinctrl/mediatek/pinctrl-mt7988.c | 1556 +++++++++++++++++++++
+ 3 files changed, 1564 insertions(+)
+ create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7988.c
+
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -187,6 +187,13 @@ config PINCTRL_MT7986
+       default ARM64 && ARCH_MEDIATEK
+       select PINCTRL_MTK_MOORE
++config PINCTRL_MT7988
++      bool "Mediatek MT7988 pin control"
++      depends on OF
++      depends on ARM64 || COMPILE_TEST
++      default ARM64 && ARCH_MEDIATEK
++      select PINCTRL_MTK_MOORE
++
+ config PINCTRL_MT8167
+       bool "MediaTek MT8167 pin control"
+       depends on OF
+--- a/drivers/pinctrl/mediatek/Makefile
++++ b/drivers/pinctrl/mediatek/Makefile
+@@ -27,6 +27,7 @@ obj-$(CONFIG_PINCTRL_MT7623)         += pinctrl
+ obj-$(CONFIG_PINCTRL_MT7629)          += pinctrl-mt7629.o
+ obj-$(CONFIG_PINCTRL_MT7981)          += pinctrl-mt7981.o
+ obj-$(CONFIG_PINCTRL_MT7986)          += pinctrl-mt7986.o
++obj-$(CONFIG_PINCTRL_MT7988)          += pinctrl-mt7988.o
+ obj-$(CONFIG_PINCTRL_MT8167)          += pinctrl-mt8167.o
+ obj-$(CONFIG_PINCTRL_MT8173)          += pinctrl-mt8173.o
+ obj-$(CONFIG_PINCTRL_MT8183)          += pinctrl-mt8183.o
+--- /dev/null
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
+@@ -0,0 +1,1556 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * The MT7988 driver based on Linux generic pinctrl binding.
++ *
++ * Copyright (C) 2020 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ */
++
++#include "pinctrl-moore.h"
++
++enum mt7988_pinctrl_reg_page {
++      GPIO_BASE,
++      IOCFG_TR_BASE,
++      IOCFG_BR_BASE,
++      IOCFG_RB_BASE,
++      IOCFG_LB_BASE,
++      IOCFG_TL_BASE,
++};
++
++#define MT7988_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
++
++#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
++                     _x_bits)                                                \
++      PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
++                     _x_bits, 32, 0)
++
++#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,    \
++                      _x_bits)                                               \
++      PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
++                     _x_bits, 32, 1)
++
++static const struct mtk_pin_field_calc mt7988_pin_mode_range[] = {
++      PIN_FIELD(0, 83, 0x300, 0x10, 0, 4),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_dir_range[] = {
++      PIN_FIELD(0, 83, 0x0, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_di_range[] = {
++      PIN_FIELD(0, 83, 0x200, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_do_range[] = {
++      PIN_FIELD(0, 83, 0x100, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_ies_range[] = {
++      PIN_FIELD_BASE(0, 0, 5, 0x30, 0x10, 13, 1),
++      PIN_FIELD_BASE(1, 1, 5, 0x30, 0x10, 14, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 11, 1),
++      PIN_FIELD_BASE(3, 3, 5, 0x30, 0x10, 12, 1),
++      PIN_FIELD_BASE(4, 4, 5, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(5, 5, 5, 0x30, 0x10, 9, 1),
++      PIN_FIELD_BASE(6, 6, 5, 0x30, 0x10, 10, 1),
++
++      PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 8, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 6, 1),
++      PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(10, 10, 4, 0x30, 0x10, 3, 1),
++
++      PIN_FIELD_BASE(11, 11, 1, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(12, 12, 1, 0x40, 0x10, 21, 1),
++      PIN_FIELD_BASE(13, 13, 1, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(14, 14, 1, 0x40, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(15, 15, 5, 0x30, 0x10, 7, 1),
++      PIN_FIELD_BASE(16, 16, 5, 0x30, 0x10, 8, 1),
++      PIN_FIELD_BASE(17, 17, 5, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(18, 18, 5, 0x30, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(19, 19, 4, 0x30, 0x10, 7, 1),
++      PIN_FIELD_BASE(20, 20, 4, 0x30, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(21, 21, 3, 0x50, 0x10, 17, 1),
++      PIN_FIELD_BASE(22, 22, 3, 0x50, 0x10, 23, 1),
++      PIN_FIELD_BASE(23, 23, 3, 0x50, 0x10, 20, 1),
++      PIN_FIELD_BASE(24, 24, 3, 0x50, 0x10, 19, 1),
++      PIN_FIELD_BASE(25, 25, 3, 0x50, 0x10, 21, 1),
++      PIN_FIELD_BASE(26, 26, 3, 0x50, 0x10, 22, 1),
++      PIN_FIELD_BASE(27, 27, 3, 0x50, 0x10, 18, 1),
++      PIN_FIELD_BASE(28, 28, 3, 0x50, 0x10, 25, 1),
++      PIN_FIELD_BASE(29, 29, 3, 0x50, 0x10, 26, 1),
++      PIN_FIELD_BASE(30, 30, 3, 0x50, 0x10, 27, 1),
++      PIN_FIELD_BASE(31, 31, 3, 0x50, 0x10, 24, 1),
++      PIN_FIELD_BASE(32, 32, 3, 0x50, 0x10, 28, 1),
++      PIN_FIELD_BASE(33, 33, 3, 0x60, 0x10, 0, 1),
++      PIN_FIELD_BASE(34, 34, 3, 0x50, 0x10, 31, 1),
++      PIN_FIELD_BASE(35, 35, 3, 0x50, 0x10, 29, 1),
++      PIN_FIELD_BASE(36, 36, 3, 0x50, 0x10, 30, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x50, 0x10, 11, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x50, 0x10, 10, 1),
++      PIN_FIELD_BASE(40, 40, 3, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(41, 41, 3, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(42, 42, 3, 0x50, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 3, 0x50, 0x10, 8, 1),
++      PIN_FIELD_BASE(44, 44, 3, 0x50, 0x10, 7, 1),
++      PIN_FIELD_BASE(45, 45, 3, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, 3, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(47, 47, 3, 0x50, 0x10, 4, 1),
++      PIN_FIELD_BASE(48, 48, 3, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(49, 49, 3, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(50, 50, 3, 0x50, 0x10, 15, 1),
++      PIN_FIELD_BASE(51, 51, 3, 0x50, 0x10, 12, 1),
++      PIN_FIELD_BASE(52, 52, 3, 0x50, 0x10, 13, 1),
++      PIN_FIELD_BASE(53, 53, 3, 0x50, 0x10, 14, 1),
++      PIN_FIELD_BASE(54, 54, 3, 0x50, 0x10, 16, 1),
++
++      PIN_FIELD_BASE(55, 55, 1, 0x40, 0x10, 14, 1),
++      PIN_FIELD_BASE(56, 56, 1, 0x40, 0x10, 15, 1),
++      PIN_FIELD_BASE(57, 57, 1, 0x40, 0x10, 13, 1),
++      PIN_FIELD_BASE(58, 58, 1, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(59, 59, 1, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(60, 60, 1, 0x40, 0x10, 6, 1),
++      PIN_FIELD_BASE(61, 61, 1, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(62, 62, 1, 0x40, 0x10, 7, 1),
++      PIN_FIELD_BASE(63, 63, 1, 0x40, 0x10, 20, 1),
++      PIN_FIELD_BASE(64, 64, 1, 0x40, 0x10, 8, 1),
++      PIN_FIELD_BASE(65, 65, 1, 0x40, 0x10, 9, 1),
++      PIN_FIELD_BASE(66, 66, 1, 0x40, 0x10, 10, 1),
++      PIN_FIELD_BASE(67, 67, 1, 0x40, 0x10, 11, 1),
++      PIN_FIELD_BASE(68, 68, 1, 0x40, 0x10, 12, 1),
++
++      PIN_FIELD_BASE(69, 69, 5, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(70, 70, 5, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(71, 71, 5, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(72, 72, 5, 0x30, 0x10, 6, 1),
++
++      PIN_FIELD_BASE(73, 73, 4, 0x30, 0x10, 10, 1),
++      PIN_FIELD_BASE(74, 74, 4, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(75, 75, 4, 0x30, 0x10, 11, 1),
++      PIN_FIELD_BASE(76, 76, 4, 0x30, 0x10, 9, 1),
++      PIN_FIELD_BASE(77, 77, 4, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(78, 78, 4, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(79, 79, 4, 0x30, 0x10, 12, 1),
++
++      PIN_FIELD_BASE(80, 80, 1, 0x40, 0x10, 18, 1),
++      PIN_FIELD_BASE(81, 81, 1, 0x40, 0x10, 19, 1),
++      PIN_FIELD_BASE(82, 82, 1, 0x40, 0x10, 16, 1),
++      PIN_FIELD_BASE(83, 83, 1, 0x40, 0x10, 17, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_smt_range[] = {
++      PIN_FIELD_BASE(0, 0, 5, 0xc0, 0x10, 13, 1),
++      PIN_FIELD_BASE(1, 1, 5, 0xc0, 0x10, 14, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0xc0, 0x10, 11, 1),
++      PIN_FIELD_BASE(3, 3, 5, 0xc0, 0x10, 12, 1),
++      PIN_FIELD_BASE(4, 4, 5, 0xc0, 0x10, 0, 1),
++      PIN_FIELD_BASE(5, 5, 5, 0xc0, 0x10, 9, 1),
++      PIN_FIELD_BASE(6, 6, 5, 0xc0, 0x10, 10, 1),
++
++      PIN_FIELD_BASE(7, 7, 4, 0xb0, 0x10, 8, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0xb0, 0x10, 6, 1),
++      PIN_FIELD_BASE(9, 9, 4, 0xb0, 0x10, 5, 1),
++      PIN_FIELD_BASE(10, 10, 4, 0xb0, 0x10, 3, 1),
++
++      PIN_FIELD_BASE(11, 11, 1, 0xe0, 0x10, 0, 1),
++      PIN_FIELD_BASE(12, 12, 1, 0xe0, 0x10, 21, 1),
++      PIN_FIELD_BASE(13, 13, 1, 0xe0, 0x10, 1, 1),
++      PIN_FIELD_BASE(14, 14, 1, 0xe0, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(15, 15, 5, 0xc0, 0x10, 7, 1),
++      PIN_FIELD_BASE(16, 16, 5, 0xc0, 0x10, 8, 1),
++      PIN_FIELD_BASE(17, 17, 5, 0xc0, 0x10, 3, 1),
++      PIN_FIELD_BASE(18, 18, 5, 0xc0, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(19, 19, 4, 0xb0, 0x10, 7, 1),
++      PIN_FIELD_BASE(20, 20, 4, 0xb0, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(21, 21, 3, 0x140, 0x10, 17, 1),
++      PIN_FIELD_BASE(22, 22, 3, 0x140, 0x10, 23, 1),
++      PIN_FIELD_BASE(23, 23, 3, 0x140, 0x10, 20, 1),
++      PIN_FIELD_BASE(24, 24, 3, 0x140, 0x10, 19, 1),
++      PIN_FIELD_BASE(25, 25, 3, 0x140, 0x10, 21, 1),
++      PIN_FIELD_BASE(26, 26, 3, 0x140, 0x10, 22, 1),
++      PIN_FIELD_BASE(27, 27, 3, 0x140, 0x10, 18, 1),
++      PIN_FIELD_BASE(28, 28, 3, 0x140, 0x10, 25, 1),
++      PIN_FIELD_BASE(29, 29, 3, 0x140, 0x10, 26, 1),
++      PIN_FIELD_BASE(30, 30, 3, 0x140, 0x10, 27, 1),
++      PIN_FIELD_BASE(31, 31, 3, 0x140, 0x10, 24, 1),
++      PIN_FIELD_BASE(32, 32, 3, 0x140, 0x10, 28, 1),
++      PIN_FIELD_BASE(33, 33, 3, 0x150, 0x10, 0, 1),
++      PIN_FIELD_BASE(34, 34, 3, 0x140, 0x10, 31, 1),
++      PIN_FIELD_BASE(35, 35, 3, 0x140, 0x10, 29, 1),
++      PIN_FIELD_BASE(36, 36, 3, 0x140, 0x10, 30, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0x150, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x140, 0x10, 11, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x140, 0x10, 10, 1),
++      PIN_FIELD_BASE(40, 40, 3, 0x140, 0x10, 0, 1),
++      PIN_FIELD_BASE(41, 41, 3, 0x140, 0x10, 1, 1),
++      PIN_FIELD_BASE(42, 42, 3, 0x140, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 3, 0x140, 0x10, 8, 1),
++      PIN_FIELD_BASE(44, 44, 3, 0x140, 0x10, 7, 1),
++      PIN_FIELD_BASE(45, 45, 3, 0x140, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, 3, 0x140, 0x10, 5, 1),
++      PIN_FIELD_BASE(47, 47, 3, 0x140, 0x10, 4, 1),
++      PIN_FIELD_BASE(48, 48, 3, 0x140, 0x10, 3, 1),
++      PIN_FIELD_BASE(49, 49, 3, 0x140, 0x10, 2, 1),
++      PIN_FIELD_BASE(50, 50, 3, 0x140, 0x10, 15, 1),
++      PIN_FIELD_BASE(51, 51, 3, 0x140, 0x10, 12, 1),
++      PIN_FIELD_BASE(52, 52, 3, 0x140, 0x10, 13, 1),
++      PIN_FIELD_BASE(53, 53, 3, 0x140, 0x10, 14, 1),
++      PIN_FIELD_BASE(54, 54, 3, 0x140, 0x10, 16, 1),
++
++      PIN_FIELD_BASE(55, 55, 1, 0xe0, 0x10, 14, 1),
++      PIN_FIELD_BASE(56, 56, 1, 0xe0, 0x10, 15, 1),
++      PIN_FIELD_BASE(57, 57, 1, 0xe0, 0x10, 13, 1),
++      PIN_FIELD_BASE(58, 58, 1, 0xe0, 0x10, 4, 1),
++      PIN_FIELD_BASE(59, 59, 1, 0xe0, 0x10, 5, 1),
++      PIN_FIELD_BASE(60, 60, 1, 0xe0, 0x10, 6, 1),
++      PIN_FIELD_BASE(61, 61, 1, 0xe0, 0x10, 3, 1),
++      PIN_FIELD_BASE(62, 62, 1, 0xe0, 0x10, 7, 1),
++      PIN_FIELD_BASE(63, 63, 1, 0xe0, 0x10, 20, 1),
++      PIN_FIELD_BASE(64, 64, 1, 0xe0, 0x10, 8, 1),
++      PIN_FIELD_BASE(65, 65, 1, 0xe0, 0x10, 9, 1),
++      PIN_FIELD_BASE(66, 66, 1, 0xe0, 0x10, 10, 1),
++      PIN_FIELD_BASE(67, 67, 1, 0xe0, 0x10, 11, 1),
++      PIN_FIELD_BASE(68, 68, 1, 0xe0, 0x10, 12, 1),
++
++      PIN_FIELD_BASE(69, 69, 5, 0xc0, 0x10, 1, 1),
++      PIN_FIELD_BASE(70, 70, 5, 0xc0, 0x10, 2, 1),
++      PIN_FIELD_BASE(71, 71, 5, 0xc0, 0x10, 5, 1),
++      PIN_FIELD_BASE(72, 72, 5, 0xc0, 0x10, 6, 1),
++
++      PIN_FIELD_BASE(73, 73, 4, 0xb0, 0x10, 10, 1),
++      PIN_FIELD_BASE(74, 74, 4, 0xb0, 0x10, 1, 1),
++      PIN_FIELD_BASE(75, 75, 4, 0xb0, 0x10, 11, 1),
++      PIN_FIELD_BASE(76, 76, 4, 0xb0, 0x10, 9, 1),
++      PIN_FIELD_BASE(77, 77, 4, 0xb0, 0x10, 2, 1),
++      PIN_FIELD_BASE(78, 78, 4, 0xb0, 0x10, 0, 1),
++      PIN_FIELD_BASE(79, 79, 4, 0xb0, 0x10, 12, 1),
++
++      PIN_FIELD_BASE(80, 80, 1, 0xe0, 0x10, 18, 1),
++      PIN_FIELD_BASE(81, 81, 1, 0xe0, 0x10, 19, 1),
++      PIN_FIELD_BASE(82, 82, 1, 0xe0, 0x10, 16, 1),
++      PIN_FIELD_BASE(83, 83, 1, 0xe0, 0x10, 17, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_pu_range[] = {
++      PIN_FIELD_BASE(7, 7, 4, 0x60, 0x10, 5, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0x60, 0x10, 4, 1),
++      PIN_FIELD_BASE(9, 9, 4, 0x60, 0x10, 3, 1),
++      PIN_FIELD_BASE(10, 10, 4, 0x60, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(13, 13, 1, 0x70, 0x10, 0, 1),
++      PIN_FIELD_BASE(14, 14, 1, 0x70, 0x10, 1, 1),
++      PIN_FIELD_BASE(63, 63, 1, 0x70, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(75, 75, 4, 0x60, 0x10, 7, 1),
++      PIN_FIELD_BASE(76, 76, 4, 0x60, 0x10, 6, 1),
++      PIN_FIELD_BASE(77, 77, 4, 0x60, 0x10, 1, 1),
++      PIN_FIELD_BASE(78, 78, 4, 0x60, 0x10, 0, 1),
++      PIN_FIELD_BASE(79, 79, 4, 0x60, 0x10, 8, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_pd_range[] = {
++      PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(10, 10, 4, 0x40, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(13, 13, 1, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(14, 14, 1, 0x50, 0x10, 1, 1),
++
++      PIN_FIELD_BASE(15, 15, 5, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(16, 16, 5, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(17, 17, 5, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(18, 18, 5, 0x40, 0x10, 1, 1),
++
++      PIN_FIELD_BASE(63, 63, 1, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(71, 71, 5, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(72, 72, 5, 0x40, 0x10, 3, 1),
++
++      PIN_FIELD_BASE(75, 75, 4, 0x40, 0x10, 7, 1),
++      PIN_FIELD_BASE(76, 76, 4, 0x40, 0x10, 6, 1),
++      PIN_FIELD_BASE(77, 77, 4, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(78, 78, 4, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(79, 79, 4, 0x40, 0x10, 8, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_drv_range[] = {
++      PIN_FIELD_BASE(0, 0, 5, 0x00, 0x10, 21, 3),
++      PIN_FIELD_BASE(1, 1, 5, 0x00, 0x10, 24, 3),
++      PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 15, 3),
++      PIN_FIELD_BASE(3, 3, 5, 0x00, 0x10, 18, 3),
++      PIN_FIELD_BASE(4, 4, 5, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(5, 5, 5, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(6, 6, 5, 0x00, 0x10, 12, 3),
++
++      PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 24, 3),
++      PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 28, 3),
++      PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 15, 3),
++      PIN_FIELD_BASE(10, 10, 4, 0x00, 0x10, 9, 3),
++
++      PIN_FIELD_BASE(11, 11, 1, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(12, 12, 1, 0x20, 0x10, 3, 3),
++      PIN_FIELD_BASE(13, 13, 1, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(14, 14, 1, 0x00, 0x10, 6, 3),
++
++      PIN_FIELD_BASE(19, 19, 4, 0x00, 0x10, 21, 3),
++      PIN_FIELD_BASE(20, 20, 4, 0x00, 0x10, 12, 3),
++
++      PIN_FIELD_BASE(21, 21, 3, 0x10, 0x10, 21, 3),
++      PIN_FIELD_BASE(22, 22, 3, 0x20, 0x10, 9, 3),
++      PIN_FIELD_BASE(23, 23, 3, 0x20, 0x10, 0, 3),
++      PIN_FIELD_BASE(24, 24, 3, 0x10, 0x10, 27, 3),
++      PIN_FIELD_BASE(25, 25, 3, 0x20, 0x10, 3, 3),
++      PIN_FIELD_BASE(26, 26, 3, 0x20, 0x10, 6, 3),
++      PIN_FIELD_BASE(27, 27, 3, 0x10, 0x10, 24, 3),
++      PIN_FIELD_BASE(28, 28, 3, 0x20, 0x10, 15, 3),
++      PIN_FIELD_BASE(29, 29, 3, 0x20, 0x10, 18, 3),
++      PIN_FIELD_BASE(30, 30, 3, 0x20, 0x10, 21, 3),
++      PIN_FIELD_BASE(31, 31, 3, 0x20, 0x10, 12, 3),
++      PIN_FIELD_BASE(32, 32, 3, 0x20, 0x10, 24, 3),
++      PIN_FIELD_BASE(33, 33, 3, 0x30, 0x10, 6, 3),
++      PIN_FIELD_BASE(34, 34, 3, 0x30, 0x10, 3, 3),
++      PIN_FIELD_BASE(35, 35, 3, 0x20, 0x10, 27, 3),
++      PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 0, 3),
++      PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 9, 3),
++      PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 3, 3),
++      PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 0, 3),
++      PIN_FIELD_BASE(40, 40, 3, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(41, 41, 3, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(42, 42, 3, 0x00, 0x10, 27, 3),
++      PIN_FIELD_BASE(43, 43, 3, 0x00, 0x10, 24, 3),
++      PIN_FIELD_BASE(44, 44, 3, 0x00, 0x10, 21, 3),
++      PIN_FIELD_BASE(45, 45, 3, 0x00, 0x10, 18, 3),
++      PIN_FIELD_BASE(46, 46, 3, 0x00, 0x10, 15, 3),
++      PIN_FIELD_BASE(47, 47, 3, 0x00, 0x10, 12, 3),
++      PIN_FIELD_BASE(48, 48, 3, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(49, 49, 3, 0x00, 0x10, 6, 3),
++      PIN_FIELD_BASE(50, 50, 3, 0x10, 0x10, 15, 3),
++      PIN_FIELD_BASE(51, 51, 3, 0x10, 0x10, 6, 3),
++      PIN_FIELD_BASE(52, 52, 3, 0x10, 0x10, 9, 3),
++      PIN_FIELD_BASE(53, 53, 3, 0x10, 0x10, 12, 3),
++      PIN_FIELD_BASE(54, 54, 3, 0x10, 0x10, 18, 3),
++
++      PIN_FIELD_BASE(55, 55, 1, 0x10, 0x10, 12, 3),
++      PIN_FIELD_BASE(56, 56, 1, 0x10, 0x10, 15, 3),
++      PIN_FIELD_BASE(57, 57, 1, 0x10, 0x10, 9, 3),
++      PIN_FIELD_BASE(58, 58, 1, 0x00, 0x10, 12, 3),
++      PIN_FIELD_BASE(59, 59, 1, 0x00, 0x10, 15, 3),
++      PIN_FIELD_BASE(60, 60, 1, 0x00, 0x10, 18, 3),
++      PIN_FIELD_BASE(61, 61, 1, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(62, 62, 1, 0x00, 0x10, 21, 3),
++      PIN_FIELD_BASE(63, 63, 1, 0x20, 0x10, 0, 3),
++      PIN_FIELD_BASE(64, 64, 1, 0x00, 0x10, 24, 3),
++      PIN_FIELD_BASE(65, 65, 1, 0x00, 0x10, 27, 3),
++      PIN_FIELD_BASE(66, 66, 1, 0x10, 0x10, 0, 3),
++      PIN_FIELD_BASE(67, 67, 1, 0x10, 0x10, 3, 3),
++      PIN_FIELD_BASE(68, 68, 1, 0x10, 0x10, 6, 3),
++
++      PIN_FIELD_BASE(69, 69, 5, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(70, 70, 5, 0x00, 0x10, 6, 3),
++
++      PIN_FIELD_BASE(73, 73, 4, 0x10, 0x10, 0, 3),
++      PIN_FIELD_BASE(74, 74, 4, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(75, 75, 4, 0x10, 0x10, 3, 3),
++      PIN_FIELD_BASE(76, 76, 4, 0x00, 0x10, 27, 3),
++      PIN_FIELD_BASE(77, 77, 4, 0x00, 0x10, 6, 3),
++      PIN_FIELD_BASE(78, 78, 4, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(79, 79, 4, 0x10, 0x10, 6, 3),
++
++      PIN_FIELD_BASE(80, 80, 1, 0x10, 0x10, 24, 3),
++      PIN_FIELD_BASE(81, 81, 1, 0x10, 0x10, 27, 3),
++      PIN_FIELD_BASE(82, 82, 1, 0x10, 0x10, 18, 3),
++      PIN_FIELD_BASE(83, 83, 1, 0x10, 0x10, 21, 3),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_pupd_range[] = {
++      PIN_FIELD_BASE(0, 0, 5, 0x50, 0x10, 7, 1),
++      PIN_FIELD_BASE(1, 1, 5, 0x50, 0x10, 8, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(3, 3, 5, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(4, 4, 5, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(5, 5, 5, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(6, 6, 5, 0x50, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(11, 11, 1, 0x60, 0x10, 0, 1),
++      PIN_FIELD_BASE(12, 12, 1, 0x60, 0x10, 18, 1),
++
++      PIN_FIELD_BASE(19, 19, 4, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(20, 20, 4, 0x50, 0x10, 1, 1),
++
++      PIN_FIELD_BASE(21, 21, 3, 0x70, 0x10, 17, 1),
++      PIN_FIELD_BASE(22, 22, 3, 0x70, 0x10, 23, 1),
++      PIN_FIELD_BASE(23, 23, 3, 0x70, 0x10, 20, 1),
++      PIN_FIELD_BASE(24, 24, 3, 0x70, 0x10, 19, 1),
++      PIN_FIELD_BASE(25, 25, 3, 0x70, 0x10, 21, 1),
++      PIN_FIELD_BASE(26, 26, 3, 0x70, 0x10, 22, 1),
++      PIN_FIELD_BASE(27, 27, 3, 0x70, 0x10, 18, 1),
++      PIN_FIELD_BASE(28, 28, 3, 0x70, 0x10, 25, 1),
++      PIN_FIELD_BASE(29, 29, 3, 0x70, 0x10, 26, 1),
++      PIN_FIELD_BASE(30, 30, 3, 0x70, 0x10, 27, 1),
++      PIN_FIELD_BASE(31, 31, 3, 0x70, 0x10, 24, 1),
++      PIN_FIELD_BASE(32, 32, 3, 0x70, 0x10, 28, 1),
++      PIN_FIELD_BASE(33, 33, 3, 0x80, 0x10, 0, 1),
++      PIN_FIELD_BASE(34, 34, 3, 0x70, 0x10, 31, 1),
++      PIN_FIELD_BASE(35, 35, 3, 0x70, 0x10, 29, 1),
++      PIN_FIELD_BASE(36, 36, 3, 0x70, 0x10, 30, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0x80, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x70, 0x10, 11, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x70, 0x10, 10, 1),
++      PIN_FIELD_BASE(40, 40, 3, 0x70, 0x10, 0, 1),
++      PIN_FIELD_BASE(41, 41, 3, 0x70, 0x10, 1, 1),
++      PIN_FIELD_BASE(42, 42, 3, 0x70, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 3, 0x70, 0x10, 8, 1),
++      PIN_FIELD_BASE(44, 44, 3, 0x70, 0x10, 7, 1),
++      PIN_FIELD_BASE(45, 45, 3, 0x70, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, 3, 0x70, 0x10, 5, 1),
++      PIN_FIELD_BASE(47, 47, 3, 0x70, 0x10, 4, 1),
++      PIN_FIELD_BASE(48, 48, 3, 0x70, 0x10, 3, 1),
++      PIN_FIELD_BASE(49, 49, 3, 0x70, 0x10, 2, 1),
++      PIN_FIELD_BASE(50, 50, 3, 0x70, 0x10, 15, 1),
++      PIN_FIELD_BASE(51, 51, 3, 0x70, 0x10, 12, 1),
++      PIN_FIELD_BASE(52, 52, 3, 0x70, 0x10, 13, 1),
++      PIN_FIELD_BASE(53, 53, 3, 0x70, 0x10, 14, 1),
++      PIN_FIELD_BASE(54, 54, 3, 0x70, 0x10, 16, 1),
++
++      PIN_FIELD_BASE(55, 55, 1, 0x60, 0x10, 12, 1),
++      PIN_FIELD_BASE(56, 56, 1, 0x60, 0x10, 13, 1),
++      PIN_FIELD_BASE(57, 57, 1, 0x60, 0x10, 11, 1),
++      PIN_FIELD_BASE(58, 58, 1, 0x60, 0x10, 2, 1),
++      PIN_FIELD_BASE(59, 59, 1, 0x60, 0x10, 3, 1),
++      PIN_FIELD_BASE(60, 60, 1, 0x60, 0x10, 4, 1),
++      PIN_FIELD_BASE(61, 61, 1, 0x60, 0x10, 1, 1),
++      PIN_FIELD_BASE(62, 62, 1, 0x60, 0x10, 5, 1),
++      PIN_FIELD_BASE(64, 64, 1, 0x60, 0x10, 6, 1),
++      PIN_FIELD_BASE(65, 65, 1, 0x60, 0x10, 7, 1),
++      PIN_FIELD_BASE(66, 66, 1, 0x60, 0x10, 8, 1),
++      PIN_FIELD_BASE(67, 67, 1, 0x60, 0x10, 9, 1),
++      PIN_FIELD_BASE(68, 68, 1, 0x60, 0x10, 10, 1),
++
++      PIN_FIELD_BASE(69, 69, 5, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(70, 70, 5, 0x50, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(73, 73, 4, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(74, 74, 4, 0x50, 0x10, 0, 1),
++
++      PIN_FIELD_BASE(80, 80, 1, 0x60, 0x10, 16, 1),
++      PIN_FIELD_BASE(81, 81, 1, 0x60, 0x10, 17, 1),
++      PIN_FIELD_BASE(82, 82, 1, 0x60, 0x10, 14, 1),
++      PIN_FIELD_BASE(83, 83, 1, 0x60, 0x10, 15, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_r0_range[] = {
++      PIN_FIELD_BASE(0, 0, 5, 0x60, 0x10, 7, 1),
++      PIN_FIELD_BASE(1, 1, 5, 0x60, 0x10, 8, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x60, 0x10, 5, 1),
++      PIN_FIELD_BASE(3, 3, 5, 0x60, 0x10, 6, 1),
++      PIN_FIELD_BASE(4, 4, 5, 0x60, 0x10, 0, 1),
++      PIN_FIELD_BASE(5, 5, 5, 0x60, 0x10, 3, 1),
++      PIN_FIELD_BASE(6, 6, 5, 0x60, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(11, 11, 1, 0x80, 0x10, 0, 1),
++      PIN_FIELD_BASE(12, 12, 1, 0x80, 0x10, 18, 1),
++
++      PIN_FIELD_BASE(19, 19, 4, 0x70, 0x10, 2, 1),
++      PIN_FIELD_BASE(20, 20, 4, 0x70, 0x10, 1, 1),
++
++      PIN_FIELD_BASE(21, 21, 3, 0x90, 0x10, 17, 1),
++      PIN_FIELD_BASE(22, 22, 3, 0x90, 0x10, 23, 1),
++      PIN_FIELD_BASE(23, 23, 3, 0x90, 0x10, 20, 1),
++      PIN_FIELD_BASE(24, 24, 3, 0x90, 0x10, 19, 1),
++      PIN_FIELD_BASE(25, 25, 3, 0x90, 0x10, 21, 1),
++      PIN_FIELD_BASE(26, 26, 3, 0x90, 0x10, 22, 1),
++      PIN_FIELD_BASE(27, 27, 3, 0x90, 0x10, 18, 1),
++      PIN_FIELD_BASE(28, 28, 3, 0x90, 0x10, 25, 1),
++      PIN_FIELD_BASE(29, 29, 3, 0x90, 0x10, 26, 1),
++      PIN_FIELD_BASE(30, 30, 3, 0x90, 0x10, 27, 1),
++      PIN_FIELD_BASE(31, 31, 3, 0x90, 0x10, 24, 1),
++      PIN_FIELD_BASE(32, 32, 3, 0x90, 0x10, 28, 1),
++      PIN_FIELD_BASE(33, 33, 3, 0xa0, 0x10, 0, 1),
++      PIN_FIELD_BASE(34, 34, 3, 0x90, 0x10, 31, 1),
++      PIN_FIELD_BASE(35, 35, 3, 0x90, 0x10, 29, 1),
++      PIN_FIELD_BASE(36, 36, 3, 0x90, 0x10, 30, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0xa0, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x90, 0x10, 11, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x90, 0x10, 10, 1),
++      PIN_FIELD_BASE(40, 40, 3, 0x90, 0x10, 0, 1),
++      PIN_FIELD_BASE(41, 41, 3, 0x90, 0x10, 1, 1),
++      PIN_FIELD_BASE(42, 42, 3, 0x90, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 3, 0x90, 0x10, 8, 1),
++      PIN_FIELD_BASE(44, 44, 3, 0x90, 0x10, 7, 1),
++      PIN_FIELD_BASE(45, 45, 3, 0x90, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, 3, 0x90, 0x10, 5, 1),
++      PIN_FIELD_BASE(47, 47, 3, 0x90, 0x10, 4, 1),
++      PIN_FIELD_BASE(48, 48, 3, 0x90, 0x10, 3, 1),
++      PIN_FIELD_BASE(49, 49, 3, 0x90, 0x10, 2, 1),
++      PIN_FIELD_BASE(50, 50, 3, 0x90, 0x10, 15, 1),
++      PIN_FIELD_BASE(51, 51, 3, 0x90, 0x10, 12, 1),
++      PIN_FIELD_BASE(52, 52, 3, 0x90, 0x10, 13, 1),
++      PIN_FIELD_BASE(53, 53, 3, 0x90, 0x10, 14, 1),
++      PIN_FIELD_BASE(54, 54, 3, 0x90, 0x10, 16, 1),
++
++      PIN_FIELD_BASE(55, 55, 1, 0x80, 0x10, 12, 1),
++      PIN_FIELD_BASE(56, 56, 1, 0x80, 0x10, 13, 1),
++      PIN_FIELD_BASE(57, 57, 1, 0x80, 0x10, 11, 1),
++      PIN_FIELD_BASE(58, 58, 1, 0x80, 0x10, 2, 1),
++      PIN_FIELD_BASE(59, 59, 1, 0x80, 0x10, 3, 1),
++      PIN_FIELD_BASE(60, 60, 1, 0x80, 0x10, 4, 1),
++      PIN_FIELD_BASE(61, 61, 1, 0x80, 0x10, 1, 1),
++      PIN_FIELD_BASE(62, 62, 1, 0x80, 0x10, 5, 1),
++      PIN_FIELD_BASE(64, 64, 1, 0x80, 0x10, 6, 1),
++      PIN_FIELD_BASE(65, 65, 1, 0x80, 0x10, 7, 1),
++      PIN_FIELD_BASE(66, 66, 1, 0x80, 0x10, 8, 1),
++      PIN_FIELD_BASE(67, 67, 1, 0x80, 0x10, 9, 1),
++      PIN_FIELD_BASE(68, 68, 1, 0x80, 0x10, 10, 1),
++
++      PIN_FIELD_BASE(69, 69, 5, 0x60, 0x10, 1, 1),
++      PIN_FIELD_BASE(70, 70, 5, 0x60, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(73, 73, 4, 0x70, 0x10, 3, 1),
++      PIN_FIELD_BASE(74, 74, 4, 0x70, 0x10, 0, 1),
++
++      PIN_FIELD_BASE(80, 80, 1, 0x80, 0x10, 16, 1),
++      PIN_FIELD_BASE(81, 81, 1, 0x80, 0x10, 17, 1),
++      PIN_FIELD_BASE(82, 82, 1, 0x80, 0x10, 14, 1),
++      PIN_FIELD_BASE(83, 83, 1, 0x80, 0x10, 15, 1),
++};
++
++static const struct mtk_pin_field_calc mt7988_pin_r1_range[] = {
++      PIN_FIELD_BASE(0, 0, 5, 0x70, 0x10, 7, 1),
++      PIN_FIELD_BASE(1, 1, 5, 0x70, 0x10, 8, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x70, 0x10, 5, 1),
++      PIN_FIELD_BASE(3, 3, 5, 0x70, 0x10, 6, 1),
++      PIN_FIELD_BASE(4, 4, 5, 0x70, 0x10, 0, 1),
++      PIN_FIELD_BASE(5, 5, 5, 0x70, 0x10, 3, 1),
++      PIN_FIELD_BASE(6, 6, 5, 0x70, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(11, 11, 1, 0x90, 0x10, 0, 1),
++      PIN_FIELD_BASE(12, 12, 1, 0x90, 0x10, 18, 1),
++
++      PIN_FIELD_BASE(19, 19, 4, 0x80, 0x10, 2, 1),
++      PIN_FIELD_BASE(20, 20, 4, 0x80, 0x10, 1, 1),
++
++      PIN_FIELD_BASE(21, 21, 3, 0xb0, 0x10, 17, 1),
++      PIN_FIELD_BASE(22, 22, 3, 0xb0, 0x10, 23, 1),
++      PIN_FIELD_BASE(23, 23, 3, 0xb0, 0x10, 20, 1),
++      PIN_FIELD_BASE(24, 24, 3, 0xb0, 0x10, 19, 1),
++      PIN_FIELD_BASE(25, 25, 3, 0xb0, 0x10, 21, 1),
++      PIN_FIELD_BASE(26, 26, 3, 0xb0, 0x10, 22, 1),
++      PIN_FIELD_BASE(27, 27, 3, 0xb0, 0x10, 18, 1),
++      PIN_FIELD_BASE(28, 28, 3, 0xb0, 0x10, 25, 1),
++      PIN_FIELD_BASE(29, 29, 3, 0xb0, 0x10, 26, 1),
++      PIN_FIELD_BASE(30, 30, 3, 0xb0, 0x10, 27, 1),
++      PIN_FIELD_BASE(31, 31, 3, 0xb0, 0x10, 24, 1),
++      PIN_FIELD_BASE(32, 32, 3, 0xb0, 0x10, 28, 1),
++      PIN_FIELD_BASE(33, 33, 3, 0xc0, 0x10, 0, 1),
++      PIN_FIELD_BASE(34, 34, 3, 0xb0, 0x10, 31, 1),
++      PIN_FIELD_BASE(35, 35, 3, 0xb0, 0x10, 29, 1),
++      PIN_FIELD_BASE(36, 36, 3, 0xb0, 0x10, 30, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0xc0, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0xb0, 0x10, 11, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0xb0, 0x10, 10, 1),
++      PIN_FIELD_BASE(40, 40, 3, 0xb0, 0x10, 0, 1),
++      PIN_FIELD_BASE(41, 41, 3, 0xb0, 0x10, 1, 1),
++      PIN_FIELD_BASE(42, 42, 3, 0xb0, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 3, 0xb0, 0x10, 8, 1),
++      PIN_FIELD_BASE(44, 44, 3, 0xb0, 0x10, 7, 1),
++      PIN_FIELD_BASE(45, 45, 3, 0xb0, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, 3, 0xb0, 0x10, 5, 1),
++      PIN_FIELD_BASE(47, 47, 3, 0xb0, 0x10, 4, 1),
++      PIN_FIELD_BASE(48, 48, 3, 0xb0, 0x10, 3, 1),
++      PIN_FIELD_BASE(49, 49, 3, 0xb0, 0x10, 2, 1),
++      PIN_FIELD_BASE(50, 50, 3, 0xb0, 0x10, 15, 1),
++      PIN_FIELD_BASE(51, 51, 3, 0xb0, 0x10, 12, 1),
++      PIN_FIELD_BASE(52, 52, 3, 0xb0, 0x10, 13, 1),
++      PIN_FIELD_BASE(53, 53, 3, 0xb0, 0x10, 14, 1),
++      PIN_FIELD_BASE(54, 54, 3, 0xb0, 0x10, 16, 1),
++
++      PIN_FIELD_BASE(55, 55, 1, 0x90, 0x10, 12, 1),
++      PIN_FIELD_BASE(56, 56, 1, 0x90, 0x10, 13, 1),
++      PIN_FIELD_BASE(57, 57, 1, 0x90, 0x10, 11, 1),
++      PIN_FIELD_BASE(58, 58, 1, 0x90, 0x10, 2, 1),
++      PIN_FIELD_BASE(59, 59, 1, 0x90, 0x10, 3, 1),
++      PIN_FIELD_BASE(60, 60, 1, 0x90, 0x10, 4, 1),
++      PIN_FIELD_BASE(61, 61, 1, 0x90, 0x10, 1, 1),
++      PIN_FIELD_BASE(62, 62, 1, 0x90, 0x10, 5, 1),
++      PIN_FIELD_BASE(64, 64, 1, 0x90, 0x10, 6, 1),
++      PIN_FIELD_BASE(65, 65, 1, 0x90, 0x10, 7, 1),
++      PIN_FIELD_BASE(66, 66, 1, 0x90, 0x10, 8, 1),
++      PIN_FIELD_BASE(67, 67, 1, 0x90, 0x10, 9, 1),
++      PIN_FIELD_BASE(68, 68, 1, 0x90, 0x10, 10, 1),
++
++      PIN_FIELD_BASE(69, 69, 5, 0x70, 0x10, 1, 1),
++      PIN_FIELD_BASE(70, 70, 5, 0x70, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(73, 73, 4, 0x80, 0x10, 3, 1),
++      PIN_FIELD_BASE(74, 74, 4, 0x80, 0x10, 0, 1),
++
++      PIN_FIELD_BASE(80, 80, 1, 0x90, 0x10, 16, 1),
++      PIN_FIELD_BASE(81, 81, 1, 0x90, 0x10, 17, 1),
++      PIN_FIELD_BASE(82, 82, 1, 0x90, 0x10, 14, 1),
++      PIN_FIELD_BASE(83, 83, 1, 0x90, 0x10, 15, 1),
++};
++
++static const unsigned int mt7988_pull_type[] = {
++      MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PU_PD_TYPE,    /*7*/
++      MTK_PULL_PU_PD_TYPE,    /*8*/ MTK_PULL_PU_PD_TYPE,    /*9*/
++      MTK_PULL_PU_PD_TYPE,    /*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PU_PD_TYPE,    /*13*/
++      MTK_PULL_PU_PD_TYPE,    /*14*/ MTK_PULL_PD_TYPE,       /*15*/
++      MTK_PULL_PD_TYPE,       /*16*/ MTK_PULL_PD_TYPE,       /*17*/
++      MTK_PULL_PD_TYPE,       /*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PUPD_R1R0_TYPE,/*33*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*34*/ MTK_PULL_PUPD_R1R0_TYPE,/*35*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*36*/ MTK_PULL_PUPD_R1R0_TYPE,/*37*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*50*/ MTK_PULL_PUPD_R1R0_TYPE,/*51*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*52*/ MTK_PULL_PUPD_R1R0_TYPE,/*53*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*54*/ MTK_PULL_PUPD_R1R0_TYPE,/*55*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*56*/ MTK_PULL_PUPD_R1R0_TYPE,/*57*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*58*/ MTK_PULL_PUPD_R1R0_TYPE,/*59*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*60*/ MTK_PULL_PUPD_R1R0_TYPE,/*61*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*62*/ MTK_PULL_PU_PD_TYPE,    /*63*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*64*/ MTK_PULL_PUPD_R1R0_TYPE,/*65*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*66*/ MTK_PULL_PUPD_R1R0_TYPE,/*67*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PUPD_R1R0_TYPE,/*69*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*70*/ MTK_PULL_PD_TYPE,       /*71*/
++      MTK_PULL_PD_TYPE,       /*72*/ MTK_PULL_PUPD_R1R0_TYPE,/*73*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*74*/ MTK_PULL_PU_PD_TYPE,    /*75*/
++      MTK_PULL_PU_PD_TYPE,    /*76*/ MTK_PULL_PU_PD_TYPE,    /*77*/
++      MTK_PULL_PU_PD_TYPE,    /*78*/ MTK_PULL_PU_PD_TYPE,    /*79*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*80*/ MTK_PULL_PUPD_R1R0_TYPE,/*81*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*82*/ MTK_PULL_PUPD_R1R0_TYPE,/*83*/
++};
++
++static const struct mtk_pin_reg_calc mt7988_reg_cals[] = {
++      [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7988_pin_mode_range),
++      [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7988_pin_dir_range),
++      [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7988_pin_di_range),
++      [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7988_pin_do_range),
++      [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7988_pin_smt_range),
++      [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7988_pin_ies_range),
++      [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7988_pin_pu_range),
++      [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7988_pin_pd_range),
++      [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7988_pin_drv_range),
++      [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7988_pin_pupd_range),
++      [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7988_pin_r0_range),
++      [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7988_pin_r1_range),
++};
++
++static const struct mtk_pin_desc mt7988_pins[] = {
++      MT7988_PIN(0, "UART2_RXD"),
++      MT7988_PIN(1, "UART2_TXD"),
++      MT7988_PIN(2, "UART2_CTS"),
++      MT7988_PIN(3, "UART2_RTS"),
++      MT7988_PIN(4, "GPIO_A"),
++      MT7988_PIN(5, "SMI_0_MDC"),
++      MT7988_PIN(6, "SMI_0_MDIO"),
++      MT7988_PIN(7, "PCIE30_2L_0_WAKE_N"),
++      MT7988_PIN(8, "PCIE30_2L_0_CLKREQ_N"),
++      MT7988_PIN(9, "PCIE30_1L_1_WAKE_N"),
++      MT7988_PIN(10, "PCIE30_1L_1_CLKREQ_N"),
++      MT7988_PIN(11, "GPIO_P"),
++      MT7988_PIN(12, "WATCHDOG"),
++      MT7988_PIN(13, "GPIO_RESET"),
++      MT7988_PIN(14, "GPIO_WPS"),
++      MT7988_PIN(15, "PMIC_I2C_SCL"),
++      MT7988_PIN(16, "PMIC_I2C_SDA"),
++      MT7988_PIN(17, "I2C_1_SCL"),
++      MT7988_PIN(18, "I2C_1_SDA"),
++      MT7988_PIN(19, "PCIE30_2L_0_PRESET_N"),
++      MT7988_PIN(20, "PCIE30_1L_1_PRESET_N"),
++      MT7988_PIN(21, "PWMD1"),
++      MT7988_PIN(22, "SPI0_WP"),
++      MT7988_PIN(23, "SPI0_HOLD"),
++      MT7988_PIN(24, "SPI0_CSB"),
++      MT7988_PIN(25, "SPI0_MISO"),
++      MT7988_PIN(26, "SPI0_MOSI"),
++      MT7988_PIN(27, "SPI0_CLK"),
++      MT7988_PIN(28, "SPI1_CSB"),
++      MT7988_PIN(29, "SPI1_MISO"),
++      MT7988_PIN(30, "SPI1_MOSI"),
++      MT7988_PIN(31, "SPI1_CLK"),
++      MT7988_PIN(32, "SPI2_CLK"),
++      MT7988_PIN(33, "SPI2_MOSI"),
++      MT7988_PIN(34, "SPI2_MISO"),
++      MT7988_PIN(35, "SPI2_CSB"),
++      MT7988_PIN(36, "SPI2_HOLD"),
++      MT7988_PIN(37, "SPI2_WP"),
++      MT7988_PIN(38, "EMMC_RSTB"),
++      MT7988_PIN(39, "EMMC_DSL"),
++      MT7988_PIN(40, "EMMC_CK"),
++      MT7988_PIN(41, "EMMC_CMD"),
++      MT7988_PIN(42, "EMMC_DATA_7"),
++      MT7988_PIN(43, "EMMC_DATA_6"),
++      MT7988_PIN(44, "EMMC_DATA_5"),
++      MT7988_PIN(45, "EMMC_DATA_4"),
++      MT7988_PIN(46, "EMMC_DATA_3"),
++      MT7988_PIN(47, "EMMC_DATA_2"),
++      MT7988_PIN(48, "EMMC_DATA_1"),
++      MT7988_PIN(49, "EMMC_DATA_0"),
++      MT7988_PIN(50, "PCM_FS_I2S_LRCK"),
++      MT7988_PIN(51, "PCM_CLK_I2S_BCLK"),
++      MT7988_PIN(52, "PCM_DRX_I2S_DIN"),
++      MT7988_PIN(53, "PCM_DTX_I2S_DOUT"),
++      MT7988_PIN(54, "PCM_MCK_I2S_MCLK"),
++      MT7988_PIN(55, "UART0_RXD"),
++      MT7988_PIN(56, "UART0_TXD"),
++      MT7988_PIN(57, "PWMD0"),
++      MT7988_PIN(58, "JTAG_JTDI"),
++      MT7988_PIN(59, "JTAG_JTDO"),
++      MT7988_PIN(60, "JTAG_JTMS"),
++      MT7988_PIN(61, "JTAG_JTCLK"),
++      MT7988_PIN(62, "JTAG_JTRST_N"),
++      MT7988_PIN(63, "USB_DRV_VBUS_P1"),
++      MT7988_PIN(64, "LED_A"),
++      MT7988_PIN(65, "LED_B"),
++      MT7988_PIN(66, "LED_C"),
++      MT7988_PIN(67, "LED_D"),
++      MT7988_PIN(68, "LED_E"),
++      MT7988_PIN(69, "GPIO_B"),
++      MT7988_PIN(70, "GPIO_C"),
++      MT7988_PIN(71, "I2C_2_SCL"),
++      MT7988_PIN(72, "I2C_2_SDA"),
++      MT7988_PIN(73, "PCIE30_2L_1_PRESET_N"),
++      MT7988_PIN(74, "PCIE30_1L_0_PRESET_N"),
++      MT7988_PIN(75, "PCIE30_2L_1_WAKE_N"),
++      MT7988_PIN(76, "PCIE30_2L_1_CLKREQ_N"),
++      MT7988_PIN(77, "PCIE30_1L_0_WAKE_N"),
++      MT7988_PIN(78, "PCIE30_1L_0_CLKREQ_N"),
++      MT7988_PIN(79, "USB_DRV_VBUS_P0"),
++      MT7988_PIN(80, "UART1_RXD"),
++      MT7988_PIN(81, "UART1_TXD"),
++      MT7988_PIN(82, "UART1_CTS"),
++      MT7988_PIN(83, "UART1_RTS"),
++};
++
++/* jtag */
++static const int mt7988_tops_jtag0_0_pins[] = { 0, 1, 2, 3, 4 };
++static int mt7988_tops_jtag0_0_funcs[] = { 2, 2, 2, 2, 2 };
++
++static const int mt7988_wo0_jtag_pins[] = { 50, 51, 52, 53, 54 };
++static int mt7988_wo0_jtag_funcs[] = { 3, 3, 3, 3, 3 };
++
++static const int mt7988_wo1_jtag_pins[] = { 50, 51, 52, 53, 54 };
++static int mt7988_wo1_jtag_funcs[] = { 4, 4, 4, 4, 4 };
++
++static const int mt7988_wo2_jtag_pins[] = { 50, 51, 52, 53, 54 };
++static int mt7988_wo2_jtag_funcs[] = { 5, 5, 5, 5, 5 };
++
++static const int mt7988_jtag_pins[] = { 58, 59, 60, 61, 62 };
++static int mt7988_jtag_funcs[] = { 1, 1, 1, 1, 1 };
++
++static const int mt7988_tops_jtag0_1_pins[] = { 58, 59, 60, 61, 62 };
++static int mt7988_tops_jtag0_1_funcs[] = { 4, 4, 4, 4, 4 };
++
++/* int_usxgmii */
++static const int mt7988_int_usxgmii_pins[] = { 2, 3 };
++static int mt7988_int_usxgmii_funcs[] = { 3, 3 };
++
++/* pwm */
++static const int mt7988_pwm0_pins[] = { 57 };
++static int mt7988_pwm0_funcs[] = { 1 };
++
++static const int mt7988_pwm1_pins[] = { 21 };
++static int mt7988_pwm1_funcs[] = { 1 };
++
++static const int mt7988_pwm2_pins[] = { 80 };
++static int mt7988_pwm2_funcs[] = { 2 };
++
++static const int mt7988_pwm2_0_pins[] = { 58 };
++static int mt7988_pwm2_0_funcs[] = { 5 };
++
++static const int mt7988_pwm3_pins[] = { 81 };
++static int mt7988_pwm3_funcs[] = { 2 };
++
++static const int mt7988_pwm3_0_pins[] = { 59 };
++static int mt7988_pwm3_0_funcs[] = { 5 };
++
++static const int mt7988_pwm4_pins[] = { 82 };
++static int mt7988_pwm4_funcs[] = { 2 };
++
++static const int mt7988_pwm4_0_pins[] = { 60 };
++static int mt7988_pwm4_0_funcs[] = { 5 };
++
++static const int mt7988_pwm5_pins[] = { 83 };
++static int mt7988_pwm5_funcs[] = { 2 };
++
++static const int mt7988_pwm5_0_pins[] = { 61 };
++static int mt7988_pwm5_0_funcs[] = { 5 };
++
++static const int mt7988_pwm6_pins[] = { 69 };
++static int mt7988_pwm6_funcs[] = { 3 };
++
++static const int mt7988_pwm6_0_pins[] = { 62 };
++static int mt7988_pwm6_0_funcs[] = { 5 };
++
++static const int mt7988_pwm7_pins[] = { 70 };
++static int mt7988_pwm7_funcs[] = { 3 };
++
++static const int mt7988_pwm7_0_pins[] = { 4 };
++static int mt7988_pwm7_0_funcs[] = { 3 };
++
++/* dfd */
++static const int mt7988_dfd_pins[] = { 0, 1, 2, 3, 4 };
++static int mt7988_dfd_funcs[] = { 4, 4, 4, 4, 4 };
++
++/* i2c */
++static const int mt7988_xfi_phy0_i2c0_pins[] = { 0, 1 };
++static int mt7988_xfi_phy0_i2c0_funcs[] = { 5, 5 };
++
++static const int mt7988_xfi_phy1_i2c0_pins[] = { 0, 1 };
++static int mt7988_xfi_phy1_i2c0_funcs[] = { 6, 6 };
++
++static const int mt7988_xfi_phy_pll_i2c0_pins[] = { 3, 4 };
++static int mt7988_xfi_phy_pll_i2c0_funcs[] = { 5, 5 };
++
++static const int mt7988_xfi_phy_pll_i2c1_pins[] = { 3, 4 };
++static int mt7988_xfi_phy_pll_i2c1_funcs[] = { 6, 6 };
++
++static const int mt7988_i2c0_0_pins[] = { 5, 6 };
++static int mt7988_i2c0_0_funcs[] = { 2, 2 };
++
++static const int mt7988_i2c1_sfp_pins[] = { 5, 6 };
++static int mt7988_i2c1_sfp_funcs[] = { 4, 4 };
++
++static const int mt7988_xfi_pextp_phy0_i2c_pins[] = { 5, 6 };
++static int mt7988_xfi_pextp_phy0_i2c_funcs[] = { 5, 5 };
++
++static const int mt7988_xfi_pextp_phy1_i2c_pins[] = { 5, 6 };
++static int mt7988_xfi_pextp_phy1_i2c_funcs[] = { 6, 6 };
++
++static const int mt7988_i2c0_1_pins[] = { 15, 16 };
++static int mt7988_i2c0_1_funcs[] = { 1, 1 };
++
++static const int mt7988_u30_phy_i2c0_pins[] = { 15, 16 };
++static int mt7988_u30_phy_i2c0_funcs[] = { 2, 2 };
++
++static const int mt7988_u32_phy_i2c0_pins[] = { 15, 16 };
++static int mt7988_u32_phy_i2c0_funcs[] = { 3, 3 };
++
++static const int mt7988_xfi_phy0_i2c1_pins[] = { 15, 16 };
++static int mt7988_xfi_phy0_i2c1_funcs[] = { 5, 5 };
++
++static const int mt7988_xfi_phy1_i2c1_pins[] = { 15, 16 };
++static int mt7988_xfi_phy1_i2c1_funcs[] = { 6, 6 };
++
++static const int mt7988_xfi_phy_pll_i2c2_pins[] = { 15, 16 };
++static int mt7988_xfi_phy_pll_i2c2_funcs[] = { 7, 7 };
++
++static const int mt7988_i2c1_0_pins[] = { 17, 18 };
++static int mt7988_i2c1_0_funcs[] = { 1, 1 };
++
++static const int mt7988_u30_phy_i2c1_pins[] = { 17, 18 };
++static int mt7988_u30_phy_i2c1_funcs[] = { 2, 2 };
++
++static const int mt7988_u32_phy_i2c1_pins[] = { 17, 18 };
++static int mt7988_u32_phy_i2c1_funcs[] = { 3, 3 };
++
++static const int mt7988_xfi_phy_pll_i2c3_pins[] = { 17, 18 };
++static int mt7988_xfi_phy_pll_i2c3_funcs[] = { 4, 4 };
++
++static const int mt7988_sgmii0_i2c_pins[] = { 17, 18 };
++static int mt7988_sgmii0_i2c_funcs[] = { 5, 5 };
++
++static const int mt7988_sgmii1_i2c_pins[] = { 17, 18 };
++static int mt7988_sgmii1_i2c_funcs[] = { 6, 6 };
++
++static const int mt7988_i2c1_2_pins[] = { 69, 70 };
++static int mt7988_i2c1_2_funcs[] = { 2, 2 };
++
++static const int mt7988_i2c2_0_pins[] = { 69, 70 };
++static int mt7988_i2c2_0_funcs[] = { 4, 4 };
++
++static const int mt7988_i2c2_1_pins[] = { 71, 72 };
++static int mt7988_i2c2_1_funcs[] = { 1, 1 };
++
++/* eth */
++static const int mt7988_mdc_mdio0_pins[] = { 5, 6 };
++static int mt7988_mdc_mdio0_funcs[] = { 1, 1 };
++
++static const int mt7988_2p5g_ext_mdio_pins[] = { 28, 29 };
++static int mt7988_2p5g_ext_mdio_funcs[] = { 6, 6 };
++
++static const int mt7988_gbe_ext_mdio_pins[] = { 30, 31 };
++static int mt7988_gbe_ext_mdio_funcs[] = { 6, 6 };
++
++static const int mt7988_mdc_mdio1_pins[] = { 69, 70 };
++static int mt7988_mdc_mdio1_funcs[] = { 1, 1 };
++
++/* pcie */
++static const int mt7988_pcie_wake_n0_0_pins[] = { 7 };
++static int mt7988_pcie_wake_n0_0_funcs[] = { 1 };
++
++static const int mt7988_pcie_clk_req_n0_0_pins[] = { 8 };
++static int mt7988_pcie_clk_req_n0_0_funcs[] = { 1 };
++
++static const int mt7988_pcie_wake_n3_0_pins[] = { 9 };
++static int mt7988_pcie_wake_n3_0_funcs[] = { 1 };
++
++static const int mt7988_pcie_clk_req_n3_pins[] = { 10 };
++static int mt7988_pcie_clk_req_n3_funcs[] = { 1 };
++
++static const int mt7988_pcie_clk_req_n0_1_pins[] = { 10 };
++static int mt7988_pcie_clk_req_n0_1_funcs[] = { 2 };
++
++static const int mt7988_pcie_p0_phy_i2c_pins[] = { 7, 8 };
++static int mt7988_pcie_p0_phy_i2c_funcs[] = { 3, 3 };
++
++static const int mt7988_pcie_p1_phy_i2c_pins[] = { 7, 8 };
++static int mt7988_pcie_p1_phy_i2c_funcs[] = { 4, 4 };
++
++static const int mt7988_pcie_p3_phy_i2c_pins[] = { 9, 10 };
++static int mt7988_pcie_p3_phy_i2c_funcs[] = { 4, 4 };
++
++static const int mt7988_pcie_p2_phy_i2c_pins[] = { 7, 8 };
++static int mt7988_pcie_p2_phy_i2c_funcs[] = { 5, 5 };
++
++static const int mt7988_ckm_phy_i2c_pins[] = { 9, 10 };
++static int mt7988_ckm_phy_i2c_funcs[] = { 5, 5 };
++
++static const int mt7988_pcie_wake_n0_1_pins[] = { 13 };
++static int mt7988_pcie_wake_n0_1_funcs[] = { 2 };
++
++static const int mt7988_pcie_wake_n3_1_pins[] = { 14 };
++static int mt7988_pcie_wake_n3_1_funcs[] = { 2 };
++
++static const int mt7988_pcie_2l_0_pereset_pins[] = { 19 };
++static int mt7988_pcie_2l_0_pereset_funcs[] = { 1 };
++
++static const int mt7988_pcie_1l_1_pereset_pins[] = { 20 };
++static int mt7988_pcie_1l_1_pereset_funcs[] = { 1 };
++
++static const int mt7988_pcie_clk_req_n2_1_pins[] = { 63 };
++static int mt7988_pcie_clk_req_n2_1_funcs[] = { 2 };
++
++static const int mt7988_pcie_2l_1_pereset_pins[] = { 73 };
++static int mt7988_pcie_2l_1_pereset_funcs[] = { 1 };
++
++static const int mt7988_pcie_1l_0_pereset_pins[] = { 74 };
++static int mt7988_pcie_1l_0_pereset_funcs[] = { 1 };
++
++static const int mt7988_pcie_wake_n1_0_pins[] = { 75 };
++static int mt7988_pcie_wake_n1_0_funcs[] = { 1 };
++
++static const int mt7988_pcie_clk_req_n1_pins[] = { 76 };
++static int mt7988_pcie_clk_req_n1_funcs[] = { 1 };
++
++static const int mt7988_pcie_wake_n2_0_pins[] = { 77 };
++static int mt7988_pcie_wake_n2_0_funcs[] = { 1 };
++
++static const int mt7988_pcie_clk_req_n2_0_pins[] = { 78 };
++static int mt7988_pcie_clk_req_n2_0_funcs[] = { 1 };
++
++static const int mt7988_pcie_wake_n2_1_pins[] = { 79 };
++static int mt7988_pcie_wake_n2_1_funcs[] = { 2 };
++
++/* pmic */
++static const int mt7988_pmic_pins[] = { 11 };
++static int mt7988_pmic_funcs[] = { 1 };
++
++/* watchdog */
++static const int mt7988_watchdog_pins[] = { 12 };
++static int mt7988_watchdog_funcs[] = { 1 };
++
++/* spi */
++static const int mt7988_spi0_wp_hold_pins[] = { 22, 23 };
++static int mt7988_spi0_wp_hold_funcs[] = { 1, 1 };
++
++static const int mt7988_spi0_pins[] = { 24, 25, 26, 27 };
++static int mt7988_spi0_funcs[] = { 1, 1, 1, 1 };
++
++static const int mt7988_spi1_pins[] = { 28, 29, 30, 31 };
++static int mt7988_spi1_funcs[] = { 1, 1, 1, 1 };
++
++static const int mt7988_spi2_pins[] = { 32, 33, 34, 35 };
++static int mt7988_spi2_funcs[] = { 1, 1, 1, 1 };
++
++static const int mt7988_spi2_wp_hold_pins[] = { 36, 37 };
++static int mt7988_spi2_wp_hold_funcs[] = { 1, 1 };
++
++/* flash */
++static const int mt7988_snfi_pins[] = { 22, 23, 24, 25, 26, 27 };
++static int mt7988_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
++
++static const int mt7988_emmc_45_pins[] = {
++      21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
++};
++static int mt7988_emmc_45_funcs[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
++
++static const int mt7988_sdcard_pins[] = { 32, 33, 34, 35, 36, 37 };
++static int mt7988_sdcard_funcs[] = { 5, 5, 5, 5, 5, 5 };
++
++static const int mt7988_emmc_51_pins[] = { 38, 39, 40, 41, 42, 43,
++                                   44, 45, 46, 47, 48, 49 };
++static int mt7988_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
++
++/* uart */
++static const int mt7988_uart2_pins[] = { 0, 1, 2, 3 };
++static int mt7988_uart2_funcs[] = { 1, 1, 1, 1 };
++
++static const int mt7988_tops_uart0_0_pins[] = { 22, 23 };
++static int mt7988_tops_uart0_0_funcs[] = { 3, 3 };
++
++static const int mt7988_uart2_0_pins[] = { 28, 29, 30, 31 };
++static int mt7988_uart2_0_funcs[] = { 2, 2, 2, 2 };
++
++static const int mt7988_uart1_0_pins[] = { 32, 33, 34, 35 };
++static int mt7988_uart1_0_funcs[] = { 2, 2, 2, 2 };
++
++static const int mt7988_uart2_1_pins[] = { 32, 33, 34, 35 };
++static int mt7988_uart2_1_funcs[] = { 3, 3, 3, 3 };
++
++static const int mt7988_net_wo0_uart_txd_0_pins[] = { 28 };
++static int mt7988_net_wo0_uart_txd_0_funcs[] = { 3 };
++
++static const int mt7988_net_wo1_uart_txd_0_pins[] = { 29 };
++static int mt7988_net_wo1_uart_txd_0_funcs[] = { 3 };
++
++static const int mt7988_net_wo2_uart_txd_0_pins[] = { 30 };
++static int mt7988_net_wo2_uart_txd_0_funcs[] = { 3 };
++
++static const int mt7988_tops_uart1_0_pins[] = { 28, 29 };
++static int mt7988_tops_uart1_0_funcs[] = { 4, 4 };
++
++static const int mt7988_tops_uart0_1_pins[] = { 30, 31 };
++static int mt7988_tops_uart0_1_funcs[] = { 4, 4 };
++
++static const int mt7988_tops_uart1_1_pins[] = { 36, 37 };
++static int mt7988_tops_uart1_1_funcs[] = { 3, 3 };
++
++static const int mt7988_uart0_pins[] = { 55, 56 };
++static int mt7988_uart0_funcs[] = { 1, 1 };
++
++static const int mt7988_tops_uart0_2_pins[] = { 55, 56 };
++static int mt7988_tops_uart0_2_funcs[] = { 2, 2 };
++
++static const int mt7988_uart2_2_pins[] = { 50, 51, 52, 53 };
++static int mt7988_uart2_2_funcs[] = { 2, 2, 2, 2 };
++
++static const int mt7988_uart1_1_pins[] = { 58, 59, 60, 61 };
++static int mt7988_uart1_1_funcs[] = { 2, 2, 2, 2 };
++
++static const int mt7988_uart2_3_pins[] = { 58, 59, 60, 61 };
++static int mt7988_uart2_3_funcs[] = { 3, 3, 3, 3 };
++
++static const int mt7988_uart1_2_pins[] = { 80, 81, 82, 83 };
++static int mt7988_uart1_2_funcs[] = { 1, 1, 1, 1 };
++
++static const int mt7988_uart1_2_lite_pins[] = { 80, 81 };
++static int mt7988_uart1_2_lite_funcs[] = { 1, 1 };
++
++static const int mt7988_tops_uart1_2_pins[] = { 80, 81 };
++static int mt7988_tops_uart1_2_funcs[] = { 4, 4, };
++
++static const int mt7988_net_wo0_uart_txd_1_pins[] = { 80 };
++static int mt7988_net_wo0_uart_txd_1_funcs[] = { 3 };
++
++static const int mt7988_net_wo1_uart_txd_1_pins[] = { 81 };
++static int mt7988_net_wo1_uart_txd_1_funcs[] = { 3 };
++
++static const int mt7988_net_wo2_uart_txd_1_pins[] = { 82 };
++static int mt7988_net_wo2_uart_txd_1_funcs[] = { 3 };
++
++/* udi */
++static const int mt7988_udi_pins[] = { 32, 33, 34, 35, 36 };
++static int mt7988_udi_funcs[] = { 4, 4, 4, 4, 4 };
++
++/* i2s */
++static const int mt7988_i2s_pins[] = { 50, 51, 52, 53, 54 };
++static int mt7988_i2s_funcs[] = { 1, 1, 1, 1, 1 };
++
++/* pcm */
++static const int mt7988_pcm_pins[] = { 50, 51, 52, 53 };
++static int mt7988_pcm_funcs[] = { 1, 1, 1, 1 };
++
++/* led */
++static const int mt7988_gbe0_led1_pins[] = { 58 };
++static int mt7988_gbe0_led1_funcs[] = { 6 };
++static const int mt7988_gbe1_led1_pins[] = { 59 };
++static int mt7988_gbe1_led1_funcs[] = { 6 };
++static const int mt7988_gbe2_led1_pins[] = { 60 };
++static int mt7988_gbe2_led1_funcs[] = { 6 };
++static const int mt7988_gbe3_led1_pins[] = { 61 };
++static int mt7988_gbe3_led1_funcs[] = { 6 };
++
++static const int mt7988_2p5gbe_led1_pins[] = { 62 };
++static int mt7988_2p5gbe_led1_funcs[] = { 6 };
++
++static const int mt7988_gbe0_led0_pins[] = { 64 };
++static int mt7988_gbe0_led0_funcs[] = { 1 };
++static const int mt7988_gbe1_led0_pins[] = { 65 };
++static int mt7988_gbe1_led0_funcs[] = { 1 };
++static const int mt7988_gbe2_led0_pins[] = { 66 };
++static int mt7988_gbe2_led0_funcs[] = { 1 };
++static const int mt7988_gbe3_led0_pins[] = { 67 };
++static int mt7988_gbe3_led0_funcs[] = { 1 };
++
++static const int mt7988_2p5gbe_led0_pins[] = { 68 };
++static int mt7988_2p5gbe_led0_funcs[] = { 1 };
++
++/* usb */
++static const int mt7988_drv_vbus_p1_pins[] = { 63 };
++static int mt7988_drv_vbus_p1_funcs[] = { 1 };
++
++static const int mt7988_drv_vbus_pins[] = { 79 };
++static int mt7988_drv_vbus_funcs[] = { 1 };
++
++static const struct group_desc mt7988_groups[] = {
++      /*  @GPIO(0,1,2,3): uart2 */
++      PINCTRL_PIN_GROUP("uart2", mt7988_uart2),
++      /*  @GPIO(0,1,2,3,4): tops_jtag0_0 */
++      PINCTRL_PIN_GROUP("tops_jtag0_0", mt7988_tops_jtag0_0),
++      /*  @GPIO(2,3): int_usxgmii */
++      PINCTRL_PIN_GROUP("int_usxgmii", mt7988_int_usxgmii),
++      /*  @GPIO(0,1,2,3,4): dfd */
++      PINCTRL_PIN_GROUP("dfd", mt7988_dfd),
++      /*  @GPIO(0,1): xfi_phy0_i2c0 */
++      PINCTRL_PIN_GROUP("xfi_phy0_i2c0", mt7988_xfi_phy0_i2c0),
++      /*  @GPIO(0,1): xfi_phy1_i2c0 */
++      PINCTRL_PIN_GROUP("xfi_phy1_i2c0", mt7988_xfi_phy1_i2c0),
++      /*  @GPIO(3,4): xfi_phy_pll_i2c0 */
++      PINCTRL_PIN_GROUP("xfi_phy_pll_i2c0", mt7988_xfi_phy_pll_i2c0),
++      /*  @GPIO(3,4): xfi_phy_pll_i2c1 */
++      PINCTRL_PIN_GROUP("xfi_phy_pll_i2c1", mt7988_xfi_phy_pll_i2c1),
++      /*  @GPIO(4): pwm7 */
++      PINCTRL_PIN_GROUP("pwm7_0", mt7988_pwm7_0),
++      /*  @GPIO(5,6) i2c0_0 */
++      PINCTRL_PIN_GROUP("i2c0_0", mt7988_i2c0_0),
++      /*  @GPIO(5,6) i2c1_sfp */
++      PINCTRL_PIN_GROUP("i2c1_sfp", mt7988_i2c1_sfp),
++      /*  @GPIO(5,6) xfi_pextp_phy0_i2c */
++      PINCTRL_PIN_GROUP("xfi_pextp_phy0_i2c", mt7988_xfi_pextp_phy0_i2c),
++      /*  @GPIO(5,6) xfi_pextp_phy1_i2c */
++      PINCTRL_PIN_GROUP("xfi_pextp_phy1_i2c", mt7988_xfi_pextp_phy1_i2c),
++      /*  @GPIO(5,6) mdc_mdio0 */
++      PINCTRL_PIN_GROUP("mdc_mdio0", mt7988_mdc_mdio0),
++      /*  @GPIO(7): pcie_wake_n0_0 */
++      PINCTRL_PIN_GROUP("pcie_wake_n0_0", mt7988_pcie_wake_n0_0),
++      /*  @GPIO(8): pcie_clk_req_n0_0 */
++      PINCTRL_PIN_GROUP("pcie_clk_req_n0_0", mt7988_pcie_clk_req_n0_0),
++      /*  @GPIO(9): pcie_wake_n3_0 */
++      PINCTRL_PIN_GROUP("pcie_wake_n3_0", mt7988_pcie_wake_n3_0),
++      /*  @GPIO(10): pcie_clk_req_n3 */
++      PINCTRL_PIN_GROUP("pcie_clk_req_n3", mt7988_pcie_clk_req_n3),
++      /*  @GPIO(10): pcie_clk_req_n0_1 */
++      PINCTRL_PIN_GROUP("pcie_clk_req_n0_1", mt7988_pcie_clk_req_n0_1),
++      /*  @GPIO(7,8) pcie_p0_phy_i2c */
++      PINCTRL_PIN_GROUP("pcie_p0_phy_i2c", mt7988_pcie_p0_phy_i2c),
++      /*  @GPIO(7,8) pcie_p1_phy_i2c */
++      PINCTRL_PIN_GROUP("pcie_p1_phy_i2c", mt7988_pcie_p1_phy_i2c),
++      /*  @GPIO(7,8) pcie_p2_phy_i2c */
++      PINCTRL_PIN_GROUP("pcie_p2_phy_i2c", mt7988_pcie_p2_phy_i2c),
++      /*  @GPIO(9,10) pcie_p3_phy_i2c */
++      PINCTRL_PIN_GROUP("pcie_p3_phy_i2c", mt7988_pcie_p3_phy_i2c),
++      /*  @GPIO(9,10) ckm_phy_i2c */
++      PINCTRL_PIN_GROUP("ckm_phy_i2c", mt7988_ckm_phy_i2c),
++      /*  @GPIO(11): pmic */
++      PINCTRL_PIN_GROUP("pcie_pmic", mt7988_pmic),
++      /*  @GPIO(12): watchdog */
++      PINCTRL_PIN_GROUP("watchdog", mt7988_watchdog),
++      /*  @GPIO(13): pcie_wake_n0_1 */
++      PINCTRL_PIN_GROUP("pcie_wake_n0_1", mt7988_pcie_wake_n0_1),
++      /*  @GPIO(14): pcie_wake_n3_1 */
++      PINCTRL_PIN_GROUP("pcie_wake_n3_1", mt7988_pcie_wake_n3_1),
++      /*  @GPIO(15,16) i2c0_1 */
++      PINCTRL_PIN_GROUP("i2c0_1", mt7988_i2c0_1),
++      /*  @GPIO(15,16) u30_phy_i2c0 */
++      PINCTRL_PIN_GROUP("u30_phy_i2c0", mt7988_u30_phy_i2c0),
++      /*  @GPIO(15,16) u32_phy_i2c0 */
++      PINCTRL_PIN_GROUP("u32_phy_i2c0", mt7988_u32_phy_i2c0),
++      /*  @GPIO(15,16) xfi_phy0_i2c1 */
++      PINCTRL_PIN_GROUP("xfi_phy0_i2c1", mt7988_xfi_phy0_i2c1),
++      /*  @GPIO(15,16) xfi_phy1_i2c1 */
++      PINCTRL_PIN_GROUP("xfi_phy1_i2c1", mt7988_xfi_phy1_i2c1),
++      /*  @GPIO(15,16) xfi_phy_pll_i2c2 */
++      PINCTRL_PIN_GROUP("xfi_phy_pll_i2c2", mt7988_xfi_phy_pll_i2c2),
++      /*  @GPIO(17,18) i2c1_0 */
++      PINCTRL_PIN_GROUP("i2c1_0", mt7988_i2c1_0),
++      /*  @GPIO(17,18) u30_phy_i2c1 */
++      PINCTRL_PIN_GROUP("u30_phy_i2c1", mt7988_u30_phy_i2c1),
++      /*  @GPIO(17,18) u32_phy_i2c1 */
++      PINCTRL_PIN_GROUP("u32_phy_i2c1", mt7988_u32_phy_i2c1),
++      /*  @GPIO(17,18) xfi_phy_pll_i2c3 */
++      PINCTRL_PIN_GROUP("xfi_phy_pll_i2c3", mt7988_xfi_phy_pll_i2c3),
++      /*  @GPIO(17,18) sgmii0_i2c */
++      PINCTRL_PIN_GROUP("sgmii0_i2c", mt7988_sgmii0_i2c),
++      /*  @GPIO(17,18) sgmii1_i2c */
++      PINCTRL_PIN_GROUP("sgmii1_i2c", mt7988_sgmii1_i2c),
++      /*  @GPIO(19): pcie_2l_0_pereset */
++      PINCTRL_PIN_GROUP("pcie_2l_0_pereset", mt7988_pcie_2l_0_pereset),
++      /*  @GPIO(20): pcie_1l_1_pereset */
++      PINCTRL_PIN_GROUP("pcie_1l_1_pereset", mt7988_pcie_1l_1_pereset),
++      /*  @GPIO(21): pwm1 */
++      PINCTRL_PIN_GROUP("pwm1", mt7988_pwm1),
++      /*  @GPIO(22,23) spi0_wp_hold */
++      PINCTRL_PIN_GROUP("spi0_wp_hold", mt7988_spi0_wp_hold),
++      /*  @GPIO(24,25,26,27) spi0 */
++      PINCTRL_PIN_GROUP("spi0", mt7988_spi0),
++      /*  @GPIO(28,29,30,31) spi1 */
++      PINCTRL_PIN_GROUP("spi1", mt7988_spi1),
++      /*  @GPIO(32,33,34,35) spi2 */
++      PINCTRL_PIN_GROUP("spi2", mt7988_spi2),
++      /*  @GPIO(36,37) spi2_wp_hold */
++      PINCTRL_PIN_GROUP("spi2_wp_hold", mt7988_spi2_wp_hold),
++      /*  @GPIO(22,23,24,25,26,27) snfi */
++      PINCTRL_PIN_GROUP("snfi", mt7988_snfi),
++      /*  @GPIO(22,23) tops_uart0_0 */
++      PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart0_0),
++      /*  @GPIO(28,29,30,31) uart2_0 */
++      PINCTRL_PIN_GROUP("uart2_0", mt7988_uart2_0),
++      /*  @GPIO(32,33,34,35) uart1_0 */
++      PINCTRL_PIN_GROUP("uart1_0", mt7988_uart1_0),
++      /*  @GPIO(32,33,34,35) uart2_1 */
++      PINCTRL_PIN_GROUP("uart2_1", mt7988_uart2_1),
++      /*  @GPIO(28) net_wo0_uart_txd_0 */
++      PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
++      /*  @GPIO(29) net_wo1_uart_txd_0 */
++      PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
++      /*  @GPIO(30) net_wo2_uart_txd_0 */
++      PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
++      /*  @GPIO(28,29) tops_uart1_0 */
++      PINCTRL_PIN_GROUP("tops_uart0_0", mt7988_tops_uart1_0),
++      /*  @GPIO(30,31) tops_uart0_1 */
++      PINCTRL_PIN_GROUP("tops_uart0_1", mt7988_tops_uart0_1),
++      /*  @GPIO(36,37) tops_uart1_1 */
++      PINCTRL_PIN_GROUP("tops_uart1_1", mt7988_tops_uart1_1),
++      /*  @GPIO(32,33,34,35,36) udi */
++      PINCTRL_PIN_GROUP("udi", mt7988_udi),
++      /*  @GPIO(21,28,29,30,31,32,33,34,35,36,37) emmc_45 */
++      PINCTRL_PIN_GROUP("emmc_45", mt7988_emmc_45),
++      /*  @GPIO(32,33,34,35,36,37) sdcard */
++      PINCTRL_PIN_GROUP("sdcard", mt7988_sdcard),
++      /*  @GPIO(38,39,40,41,42,43,44,45,46,47,48,49) emmc_51 */
++      PINCTRL_PIN_GROUP("emmc_51", mt7988_emmc_51),
++      /*  @GPIO(28,29) 2p5g_ext_mdio */
++      PINCTRL_PIN_GROUP("2p5g_ext_mdio", mt7988_2p5g_ext_mdio),
++      /*  @GPIO(30,31) gbe_ext_mdio */
++      PINCTRL_PIN_GROUP("gbe_ext_mdio", mt7988_gbe_ext_mdio),
++      /*  @GPIO(50,51,52,53,54) i2s */
++      PINCTRL_PIN_GROUP("i2s", mt7988_i2s),
++      /*  @GPIO(50,51,52,53) pcm */
++      PINCTRL_PIN_GROUP("pcm", mt7988_pcm),
++      /*  @GPIO(55,56) uart0 */
++      PINCTRL_PIN_GROUP("uart0", mt7988_uart0),
++      /*  @GPIO(55,56) tops_uart0_2 */
++      PINCTRL_PIN_GROUP("tops_uart0_2", mt7988_tops_uart0_2),
++      /*  @GPIO(50,51,52,53) uart2_2 */
++      PINCTRL_PIN_GROUP("uart2_2", mt7988_uart2_2),
++      /*  @GPIO(50,51,52,53,54) wo0_jtag */
++      PINCTRL_PIN_GROUP("wo0_jtag", mt7988_wo0_jtag),
++      /*  @GPIO(50,51,52,53,54) wo1-wo1_jtag */
++      PINCTRL_PIN_GROUP("wo1_jtag", mt7988_wo1_jtag),
++      /*  @GPIO(50,51,52,53,54) wo2_jtag */
++      PINCTRL_PIN_GROUP("wo2_jtag", mt7988_wo2_jtag),
++      /*  @GPIO(57) pwm0 */
++      PINCTRL_PIN_GROUP("pwm0", mt7988_pwm0),
++      /*  @GPIO(58) pwm2_0 */
++      PINCTRL_PIN_GROUP("pwm2_0", mt7988_pwm2_0),
++      /*  @GPIO(59) pwm3_0 */
++      PINCTRL_PIN_GROUP("pwm3_0", mt7988_pwm3_0),
++      /*  @GPIO(60) pwm4_0 */
++      PINCTRL_PIN_GROUP("pwm4_0", mt7988_pwm4_0),
++      /*  @GPIO(61) pwm5_0 */
++      PINCTRL_PIN_GROUP("pwm5_0", mt7988_pwm5_0),
++      /*  @GPIO(58,59,60,61,62) jtag */
++      PINCTRL_PIN_GROUP("jtag", mt7988_jtag),
++      /*  @GPIO(58,59,60,61,62) tops_jtag0_1 */
++      PINCTRL_PIN_GROUP("tops_jtag0_1", mt7988_tops_jtag0_1),
++      /*  @GPIO(58,59,60,61) uart2_3 */
++      PINCTRL_PIN_GROUP("uart2_3", mt7988_uart2_3),
++      /*  @GPIO(58,59,60,61) uart1_1 */
++      PINCTRL_PIN_GROUP("uart1_1", mt7988_uart1_1),
++      /*  @GPIO(58,59,60,61) gbe_led1 */
++      PINCTRL_PIN_GROUP("gbe0_led1", mt7988_gbe0_led1),
++      PINCTRL_PIN_GROUP("gbe1_led1", mt7988_gbe1_led1),
++      PINCTRL_PIN_GROUP("gbe2_led1", mt7988_gbe2_led1),
++      PINCTRL_PIN_GROUP("gbe3_led1", mt7988_gbe3_led1),
++      /*  @GPIO(62) pwm6_0 */
++      PINCTRL_PIN_GROUP("pwm6_0", mt7988_pwm6_0),
++      /*  @GPIO(62) 2p5gbe_led1 */
++      PINCTRL_PIN_GROUP("2p5gbe_led1", mt7988_2p5gbe_led1),
++      /*  @GPIO(64,65,66,67) gbe_led0 */
++      PINCTRL_PIN_GROUP("gbe0_led0", mt7988_gbe0_led0),
++      PINCTRL_PIN_GROUP("gbe1_led0", mt7988_gbe1_led0),
++      PINCTRL_PIN_GROUP("gbe2_led0", mt7988_gbe2_led0),
++      PINCTRL_PIN_GROUP("gbe3_led0", mt7988_gbe3_led0),
++      /*  @GPIO(68) 2p5gbe_led0 */
++      PINCTRL_PIN_GROUP("2p5gbe_led0", mt7988_2p5gbe_led0),
++      /*  @GPIO(63) drv_vbus_p1 */
++      PINCTRL_PIN_GROUP("drv_vbus_p1", mt7988_drv_vbus_p1),
++      /*  @GPIO(63) pcie_clk_req_n2_1 */
++      PINCTRL_PIN_GROUP("pcie_clk_req_n2_1", mt7988_pcie_clk_req_n2_1),
++      /*  @GPIO(69, 70) mdc_mdio1 */
++      PINCTRL_PIN_GROUP("mdc_mdio1", mt7988_mdc_mdio1),
++      /*  @GPIO(69, 70) i2c1_2 */
++      PINCTRL_PIN_GROUP("i2c1_2", mt7988_i2c1_2),
++      /*  @GPIO(69) pwm6 */
++      PINCTRL_PIN_GROUP("pwm6", mt7988_pwm6),
++      /*  @GPIO(70) pwm7 */
++      PINCTRL_PIN_GROUP("pwm7", mt7988_pwm7),
++      /*  @GPIO(69,70) i2c2_0 */
++      PINCTRL_PIN_GROUP("i2c2_0", mt7988_i2c2_0),
++      /*  @GPIO(71,72) i2c2_1 */
++      PINCTRL_PIN_GROUP("i2c2_1", mt7988_i2c2_1),
++      /*  @GPIO(73) pcie_2l_1_pereset */
++      PINCTRL_PIN_GROUP("pcie_2l_1_pereset", mt7988_pcie_2l_1_pereset),
++      /*  @GPIO(74) pcie_1l_0_pereset */
++      PINCTRL_PIN_GROUP("pcie_1l_0_pereset", mt7988_pcie_1l_0_pereset),
++      /*  @GPIO(75) pcie_wake_n1_0 */
++      PINCTRL_PIN_GROUP("pcie_wake_n1_0", mt7988_pcie_wake_n1_0),
++      /*  @GPIO(76) pcie_clk_req_n1 */
++      PINCTRL_PIN_GROUP("pcie_clk_req_n1", mt7988_pcie_clk_req_n1),
++      /*  @GPIO(77) pcie_wake_n2_0 */
++      PINCTRL_PIN_GROUP("pcie_wake_n2_0", mt7988_pcie_wake_n2_0),
++      /*  @GPIO(78) pcie_clk_req_n2_0 */
++      PINCTRL_PIN_GROUP("pcie_clk_req_n2_0", mt7988_pcie_clk_req_n2_0),
++      /*  @GPIO(79) drv_vbus */
++      PINCTRL_PIN_GROUP("drv_vbus", mt7988_drv_vbus),
++      /*  @GPIO(79) pcie_wake_n2_1 */
++      PINCTRL_PIN_GROUP("pcie_wake_n2_1", mt7988_pcie_wake_n2_1),
++      /*  @GPIO(80,81,82,83) uart1_2 */
++      PINCTRL_PIN_GROUP("uart1_2", mt7988_uart1_2),
++      /*  @GPIO(80,81) uart1_2_lite */
++      PINCTRL_PIN_GROUP("uart1_2_lite", mt7988_uart1_2_lite),
++      /*  @GPIO(80) pwm2 */
++      PINCTRL_PIN_GROUP("pwm2", mt7988_pwm2),
++      /*  @GPIO(81) pwm3 */
++      PINCTRL_PIN_GROUP("pwm3", mt7988_pwm3),
++      /*  @GPIO(82) pwm4 */
++      PINCTRL_PIN_GROUP("pwm4", mt7988_pwm4),
++      /*  @GPIO(83) pwm5 */
++      PINCTRL_PIN_GROUP("pwm5", mt7988_pwm5),
++      /*  @GPIO(80) net_wo0_uart_txd_0 */
++      PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7988_net_wo0_uart_txd_0),
++      /*  @GPIO(81) net_wo1_uart_txd_0 */
++      PINCTRL_PIN_GROUP("net_wo1_uart_txd_0", mt7988_net_wo1_uart_txd_0),
++      /*  @GPIO(82) net_wo2_uart_txd_0 */
++      PINCTRL_PIN_GROUP("net_wo2_uart_txd_0", mt7988_net_wo2_uart_txd_0),
++      /*  @GPIO(80,81) tops_uart1_2 */
++      PINCTRL_PIN_GROUP("tops_uart1_2", mt7988_tops_uart1_2),
++      /*  @GPIO(80) net_wo0_uart_txd_1 */
++      PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7988_net_wo0_uart_txd_1),
++      /*  @GPIO(81) net_wo1_uart_txd_1 */
++      PINCTRL_PIN_GROUP("net_wo1_uart_txd_1", mt7988_net_wo1_uart_txd_1),
++      /*  @GPIO(82) net_wo2_uart_txd_1 */
++      PINCTRL_PIN_GROUP("net_wo2_uart_txd_1", mt7988_net_wo2_uart_txd_1),
++};
++
++/* 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 mt7988_jtag_groups[] = {
++      "tops_jtag0_0", "wo0_jtag", "wo1_jtag",
++      "wo2_jtag",     "jtag",     "tops_jtag0_1",
++};
++static const char * const mt7988_int_usxgmii_groups[] = {
++      "int_usxgmii",
++};
++static const char * const mt7988_pwm_groups[] = {
++      "pwm0", "pwm1", "pwm2", "pwm2_0", "pwm3", "pwm3_0", "pwm4", "pwm4_0",
++      "pwm5", "pwm5_0", "pwm6", "pwm6_0", "pwm7", "pwm7_0",
++
++};
++static const char * const mt7988_dfd_groups[] = {
++      "dfd",
++};
++static const char * const mt7988_i2c_groups[] = {
++      "xfi_phy0_i2c0",
++      "xfi_phy1_i2c0",
++      "xfi_phy_pll_i2c0",
++      "xfi_phy_pll_i2c1",
++      "i2c0_0",
++      "i2c1_sfp",
++      "xfi_pextp_phy0_i2c",
++      "xfi_pextp_phy1_i2c",
++      "i2c0_1",
++      "u30_phy_i2c0",
++      "u32_phy_i2c0",
++      "xfi_phy0_i2c1",
++      "xfi_phy1_i2c1",
++      "xfi_phy_pll_i2c2",
++      "i2c1_0",
++      "u30_phy_i2c1",
++      "u32_phy_i2c1",
++      "xfi_phy_pll_i2c3",
++      "sgmii0_i2c",
++      "sgmii1_i2c",
++      "i2c1_2",
++      "i2c2_0",
++      "i2c2_1",
++};
++static const char * const mt7988_ethernet_groups[] = {
++      "mdc_mdio0",
++      "2p5g_ext_mdio",
++      "gbe_ext_mdio",
++      "mdc_mdio1",
++};
++static const char * const mt7988_pcie_groups[] = {
++      "pcie_wake_n0_0",    "pcie_clk_req_n0_0", "pcie_wake_n3_0",
++      "pcie_clk_req_n3",   "pcie_p0_phy_i2c",   "pcie_p1_phy_i2c",
++      "pcie_p3_phy_i2c",   "pcie_p2_phy_i2c",   "ckm_phy_i2c",
++      "pcie_wake_n0_1",    "pcie_wake_n3_1",    "pcie_2l_0_pereset",
++      "pcie_1l_1_pereset", "pcie_clk_req_n2_1", "pcie_2l_1_pereset",
++      "pcie_1l_0_pereset", "pcie_wake_n1_0",    "pcie_clk_req_n1",
++      "pcie_wake_n2_0",    "pcie_clk_req_n2_0", "pcie_wake_n2_1",
++      "pcie_clk_req_n0_1"
++};
++static const char * const mt7988_pmic_groups[] = {
++      "pmic",
++};
++static const char * const mt7988_wdt_groups[] = {
++      "watchdog",
++};
++static const char * const mt7988_spi_groups[] = {
++      "spi0", "spi0_wp_hold", "spi1", "spi2", "spi2_wp_hold",
++};
++static const char * const mt7988_flash_groups[] = { "emmc_45", "sdcard", "snfi",
++                                                  "emmc_51" };
++static const char * const mt7988_uart_groups[] = {
++      "uart2",
++      "tops_uart0_0",
++      "uart2_0",
++      "uart1_0",
++      "uart2_1",
++      "net_wo0_uart_txd_0",
++      "net_wo1_uart_txd_0",
++      "net_wo2_uart_txd_0",
++      "tops_uart1_0",
++      "ops_uart0_1",
++      "ops_uart1_1",
++      "uart0",
++      "tops_uart0_2",
++      "uart1_1",
++      "uart2_3",
++      "uart1_2",
++      "uart1_2_lite",
++      "tops_uart1_2",
++      "net_wo0_uart_txd_1",
++      "net_wo1_uart_txd_1",
++      "net_wo2_uart_txd_1",
++};
++static const char * const mt7988_udi_groups[] = {
++      "udi",
++};
++static const char * const mt7988_audio_groups[] = {
++      "i2s", "pcm",
++};
++static const char * const mt7988_led_groups[] = {
++      "gbe0_led1", "gbe1_led1", "gbe2_led1", "gbe3_led1", "2p5gbe_led1",
++      "gbe0_led0", "gbe1_led0", "gbe2_led0", "gbe3_led0", "2p5gbe_led0",
++      "wf5g_led0",   "wf5g_led1",
++};
++static const char * const mt7988_usb_groups[] = {
++      "drv_vbus",
++      "drv_vbus_p1",
++};
++
++static const struct function_desc mt7988_functions[] = {
++      { { "audio", mt7988_audio_groups, ARRAY_SIZE(mt7988_audio_groups) },
++        NULL },
++      { { "jtag", mt7988_jtag_groups, ARRAY_SIZE(mt7988_jtag_groups) },
++        NULL },
++      { { "int_usxgmii", mt7988_int_usxgmii_groups,
++          ARRAY_SIZE(mt7988_int_usxgmii_groups) },
++        NULL },
++      { { "pwm", mt7988_pwm_groups, ARRAY_SIZE(mt7988_pwm_groups) }, NULL },
++      { { "dfd", mt7988_dfd_groups, ARRAY_SIZE(mt7988_dfd_groups) }, NULL },
++      { { "i2c", mt7988_i2c_groups, ARRAY_SIZE(mt7988_i2c_groups) }, NULL },
++      { { "eth", mt7988_ethernet_groups, ARRAY_SIZE(mt7988_ethernet_groups) },
++        NULL },
++      { { "pcie", mt7988_pcie_groups, ARRAY_SIZE(mt7988_pcie_groups) },
++        NULL },
++      { { "pmic", mt7988_pmic_groups, ARRAY_SIZE(mt7988_pmic_groups) },
++        NULL },
++      { { "watchdog", mt7988_wdt_groups, ARRAY_SIZE(mt7988_wdt_groups) },
++        NULL },
++      { { "spi", mt7988_spi_groups, ARRAY_SIZE(mt7988_spi_groups) }, NULL },
++      { { "flash", mt7988_flash_groups, ARRAY_SIZE(mt7988_flash_groups) },
++        NULL },
++      { { "uart", mt7988_uart_groups, ARRAY_SIZE(mt7988_uart_groups) },
++        NULL },
++      { { "udi", mt7988_udi_groups, ARRAY_SIZE(mt7988_udi_groups) }, NULL },
++      { { "usb", mt7988_usb_groups, ARRAY_SIZE(mt7988_usb_groups) }, NULL },
++      { { "led", mt7988_led_groups, ARRAY_SIZE(mt7988_led_groups) }, NULL },
++};
++
++static const struct mtk_eint_hw mt7988_eint_hw = {
++      .port_mask = 7,
++      .ports = 7,
++      .ap_num = ARRAY_SIZE(mt7988_pins),
++      .db_cnt = 16,
++};
++
++static const char * const mt7988_pinctrl_register_base_names[] = {
++      "gpio",  "iocfg_tr", "iocfg_br",
++      "iocfg_rb", "iocfg_lb", "iocfg_tl",
++};
++
++static const struct mtk_pin_soc mt7988_data = {
++      .reg_cal = mt7988_reg_cals,
++      .pins = mt7988_pins,
++      .npins = ARRAY_SIZE(mt7988_pins),
++      .grps = mt7988_groups,
++      .ngrps = ARRAY_SIZE(mt7988_groups),
++      .funcs = mt7988_functions,
++      .nfuncs = ARRAY_SIZE(mt7988_functions),
++      .eint_hw = &mt7988_eint_hw,
++      .gpio_m = 0,
++      .ies_present = false,
++      .base_names = mt7988_pinctrl_register_base_names,
++      .nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
++      .bias_disable_set = mtk_pinconf_bias_disable_set,
++      .bias_disable_get = mtk_pinconf_bias_disable_get,
++      .bias_set = mtk_pinconf_bias_set,
++      .bias_get = mtk_pinconf_bias_get,
++      .pull_type = mt7988_pull_type,
++      .bias_set_combo = mtk_pinconf_bias_set_combo,
++      .bias_get_combo = mtk_pinconf_bias_get_combo,
++      .drive_set = mtk_pinconf_drive_set_rev1,
++      .drive_get = mtk_pinconf_drive_get_rev1,
++      .adv_pull_get = mtk_pinconf_adv_pull_get,
++      .adv_pull_set = mtk_pinconf_adv_pull_set,
++};
++
++static const struct of_device_id mt7988_pinctrl_of_match[] = {
++      { .compatible = "mediatek,mt7988-pinctrl" },
++      {}
++};
++
++static int mt7988_pinctrl_probe(struct platform_device *pdev)
++{
++      return mtk_moore_pinctrl_probe(pdev, &mt7988_data);
++}
++
++static struct platform_driver mt7988_pinctrl_driver = {
++      .driver = {
++              .name = "mt7988-pinctrl",
++              .of_match_table = mt7988_pinctrl_of_match,
++      },
++      .probe = mt7988_pinctrl_probe,
++};
++
++static int __init mt7988_pinctrl_init(void)
++{
++      return platform_driver_register(&mt7988_pinctrl_driver);
++}
++arch_initcall(mt7988_pinctrl_init);
diff --git a/target/linux/mediatek/patches-6.12/012-v6.14-pinctrl-mediatek-Drop-mtk_pinconf_bias_set_pd.patch b/target/linux/mediatek/patches-6.12/012-v6.14-pinctrl-mediatek-Drop-mtk_pinconf_bias_set_pd.patch
new file mode 100644 (file)
index 0000000..e615e39
--- /dev/null
@@ -0,0 +1,41 @@
+From 0e18b099672160698dfbd7c3c82e03e011c907e6 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Wed, 8 Jan 2025 22:52:44 +0100
+Subject: [PATCH] pinctrl: mediatek: Drop mtk_pinconf_bias_set_pd()
+
+This function is unused and causing compile errors, delete it.
+
+Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Link: https://lore.kernel.org/linux-next/20250106164630.4447cd0d@canb.auug.org.au/
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../pinctrl/mediatek/pinctrl-mtk-common-v2.c   | 18 ------------------
+ 1 file changed, 18 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -599,24 +599,6 @@ static int mtk_pinconf_bias_set_pu_pd(st
+       return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+ }
+-static int mtk_pinconf_bias_set_pd(struct mtk_pinctrl *hw,
+-                              const struct mtk_pin_desc *desc,
+-                              u32 pullup, u32 arg)
+-{
+-      int err, pd;
+-
+-      if (arg != MTK_DISABLE && arg != MTK_ENABLE)
+-              return -EINVAL;
+-
+-      if (arg == MTK_DISABLE || pullup)
+-              pd = 0;
+-      else if (!pullup)
+-              pd = 1;
+-
+-      return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
+-
+-}
+-
+ static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
+                               const struct mtk_pin_desc *desc,
+                               u32 pullup, u32 arg)
diff --git a/target/linux/mediatek/patches-6.12/020-v6.13-arm64-dts-mediatek-mt7988-add-UART-controllers.patch b/target/linux/mediatek/patches-6.12/020-v6.13-arm64-dts-mediatek-mt7988-add-UART-controllers.patch
new file mode 100644 (file)
index 0000000..2c0afbe
--- /dev/null
@@ -0,0 +1,71 @@
+From 52e2ca3be4b6d451fef0a2cd337157dd021b830f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Wed, 5 Jun 2024 10:54:33 +0200
+Subject: [PATCH 01/32] arm64: dts: mediatek: mt7988: add UART controllers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+MT7988 has three on-SoC UART controllers that support M16C450 and
+M16550A modes.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20240605085433.26513-2-zajec5@gmail.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 35 ++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -86,7 +86,7 @@
+                       #clock-cells = <1>;
+               };
+-              clock-controller@1001b000 {
++              topckgen: clock-controller@1001b000 {
+                       compatible = "mediatek,mt7988-topckgen", "syscon";
+                       reg = <0 0x1001b000 0 0x1000>;
+                       #clock-cells = <1>;
+@@ -124,6 +124,39 @@
+                       status = "disabled";
+               };
++              serial@11000000 {
++                      compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
++                      reg = <0 0x11000000 0 0x100>;
++                      interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "uart", "wakeup";
++                      clocks = <&topckgen CLK_TOP_UART_SEL>,
++                               <&infracfg CLK_INFRA_52M_UART0_CK>;
++                      clock-names = "baud", "bus";
++                      status = "disabled";
++              };
++
++              serial@11000100 {
++                      compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
++                      reg = <0 0x11000100 0 0x100>;
++                      interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "uart", "wakeup";
++                      clocks = <&topckgen CLK_TOP_UART_SEL>,
++                               <&infracfg CLK_INFRA_52M_UART1_CK>;
++                      clock-names = "baud", "bus";
++                      status = "disabled";
++              };
++
++              serial@11000200 {
++                      compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
++                      reg = <0 0x11000200 0 0x100>;
++                      interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "uart", "wakeup";
++                      clocks = <&topckgen CLK_TOP_UART_SEL>,
++                               <&infracfg CLK_INFRA_52M_UART2_CK>;
++                      clock-names = "baud", "bus";
++                      status = "disabled";
++              };
++
+               i2c@11003000 {
+                       compatible = "mediatek,mt7981-i2c";
+                       reg = <0 0x11003000 0 0x1000>,
diff --git a/target/linux/mediatek/patches-6.12/021-v6.13-arm64-dts-mediatek-mt7988-add-efuse-block.patch b/target/linux/mediatek/patches-6.12/021-v6.13-arm64-dts-mediatek-mt7988-add-efuse-block.patch
new file mode 100644 (file)
index 0000000..bf4e7a3
--- /dev/null
@@ -0,0 +1,35 @@
+From 390529e00d5586eb6d7f4c33c23dee7f43ac14e7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 13 Jun 2024 21:59:33 +0200
+Subject: [PATCH 02/32] arm64: dts: mediatek: mt7988: add efuse block
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+MT7988 (AKA MediaTek Filogic 880) uses efuse for storing calibration
+data.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20240613195933.31089-2-zajec5@gmail.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -234,6 +234,13 @@
+                       #clock-cells = <1>;
+               };
++              efuse@11f50000 {
++                      compatible = "mediatek,mt7988-efuse", "mediatek,efuse";
++                      reg = <0 0x11f50000 0 0x1000>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++              };
++
+               clock-controller@15000000 {
+                       compatible = "mediatek,mt7988-ethsys", "syscon";
+                       reg = <0 0x15000000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/022-v6.14-arm64-dts-mediatek-mt7988-Add-pinctrl-support.patch b/target/linux/mediatek/patches-6.12/022-v6.14-arm64-dts-mediatek-mt7988-Add-pinctrl-support.patch
new file mode 100644 (file)
index 0000000..90ec318
--- /dev/null
@@ -0,0 +1,85 @@
+From a01cc71a8c55e7fc12cb37109953ad9c58a12d4f Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 09:54:29 +0100
+Subject: [PATCH 03/32] arm64: dts: mediatek: mt7988: Add pinctrl support
+
+Add mt7988a pinctrl node.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217085435.9586-5-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 54 +++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -3,6 +3,7 @@
+ #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/phy/phy.h>
++#include <dt-bindings/pinctrl/mt65xx.h>
+ / {
+       compatible = "mediatek,mt7988a";
+@@ -105,6 +106,59 @@
+                       #clock-cells = <1>;
+               };
++              pio: pinctrl@1001f000 {
++                      compatible = "mediatek,mt7988-pinctrl";
++                      reg = <0 0x1001f000 0 0x1000>,
++                            <0 0x11c10000 0 0x1000>,
++                            <0 0x11d00000 0 0x1000>,
++                            <0 0x11d20000 0 0x1000>,
++                            <0 0x11e00000 0 0x1000>,
++                            <0 0x11f00000 0 0x1000>,
++                            <0 0x1000b000 0 0x1000>;
++                      reg-names = "gpio", "iocfg_tr",
++                                  "iocfg_br", "iocfg_rb",
++                                  "iocfg_lb", "iocfg_tl", "eint";
++                      gpio-controller;
++                      #gpio-cells = <2>;
++                      gpio-ranges = <&pio 0 0 84>;
++                      interrupt-controller;
++                      interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-parent = <&gic>;
++                      #interrupt-cells = <2>;
++
++                      pcie0_pins: pcie0-pins {
++                              mux {
++                                      function = "pcie";
++                                      groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
++                                               "pcie_wake_n0_0";
++                              };
++                      };
++
++                      pcie1_pins: pcie1-pins {
++                              mux {
++                                      function = "pcie";
++                                      groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
++                                               "pcie_wake_n1_0";
++                              };
++                      };
++
++                      pcie2_pins: pcie2-pins {
++                              mux {
++                                      function = "pcie";
++                                      groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
++                                               "pcie_wake_n2_0";
++                              };
++                      };
++
++                      pcie3_pins: pcie3-pins {
++                              mux {
++                                      function = "pcie";
++                                      groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
++                                               "pcie_wake_n3_0";
++                              };
++                      };
++              };
++
+               pwm@10048000 {
+                       compatible = "mediatek,mt7988-pwm";
+                       reg = <0 0x10048000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/023-v6.14-arm64-dts-mediatek-mt7988-Add-reserved-memory.patch b/target/linux/mediatek/patches-6.12/023-v6.14-arm64-dts-mediatek-mt7988-Add-reserved-memory.patch
new file mode 100644 (file)
index 0000000..043530c
--- /dev/null
@@ -0,0 +1,37 @@
+From b3bb498ff23f5bcaa95614e0f8c9176690af8acb Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:15 +0100
+Subject: [PATCH 04/32] arm64: dts: mediatek: mt7988: Add reserved memory
+
+Add memory range handled by ATF to not be touched by linux kernel.
+ATF is SoC specific and not board-specific so add it to mt7988.dtsi.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-2-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -62,6 +62,18 @@
+               method = "smc";
+       };
++      reserved-memory {
++              #address-cells = <2>;
++              #size-cells = <2>;
++              ranges;
++
++              /* 320 KiB reserved for ARM Trusted Firmware (BL31 and BL32) */
++              secmon@43000000 {
++                      reg = <0 0x43000000 0 0x50000>;
++                      no-map;
++              };
++      };
++
+       soc {
+               compatible = "simple-bus";
+               ranges;
diff --git a/target/linux/mediatek/patches-6.12/024-v6.14-arm64-dts-mediatek-mt7988-Add-mmc-support.patch b/target/linux/mediatek/patches-6.12/024-v6.14-arm64-dts-mediatek-mt7988-Add-mmc-support.patch
new file mode 100644 (file)
index 0000000..a52f443
--- /dev/null
@@ -0,0 +1,52 @@
+From de6ba1a3ef621762394e841888de3e0ed127e20a Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:16 +0100
+Subject: [PATCH 05/32] arm64: dts: mediatek: mt7988: Add mmc support
+
+Add devicetree node for MMC controller.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-3-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -112,7 +112,7 @@
+                       #reset-cells = <1>;
+               };
+-              clock-controller@1001e000 {
++              apmixedsys: clock-controller@1001e000 {
+                       compatible = "mediatek,mt7988-apmixedsys";
+                       reg = <0 0x1001e000 0 0x1000>;
+                       #clock-cells = <1>;
+@@ -293,6 +293,25 @@
+                       clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
+               };
++              mmc0: mmc@11230000 {
++                      compatible = "mediatek,mt7988-mmc";
++                      reg = <0 0x11230000 0 0x1000>,
++                            <0 0x11D60000 0 0x1000>;
++                      interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_MSDC400>,
++                               <&infracfg CLK_INFRA_MSDC2_HCK>,
++                               <&infracfg CLK_INFRA_66M_MSDC_0_HCK>,
++                               <&infracfg CLK_INFRA_133M_MSDC_0_HCK>;
++                      assigned-clocks = <&topckgen CLK_TOP_EMMC_250M_SEL>,
++                                        <&topckgen CLK_TOP_EMMC_400M_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_NET1PLL_D5_D2>,
++                                               <&apmixedsys CLK_APMIXED_MSDCPLL>;
++                      clock-names = "source", "hclk", "axi_cg", "ahb_cg";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
+               clock-controller@11f40000 {
+                       compatible = "mediatek,mt7988-xfi-pll";
+                       reg = <0 0x11f40000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/025-v6.14-arm64-dts-mediatek-mt7988-Add-lvts-node.patch b/target/linux/mediatek/patches-6.12/025-v6.14-arm64-dts-mediatek-mt7988-Add-lvts-node.patch
new file mode 100644 (file)
index 0000000..b878d20
--- /dev/null
@@ -0,0 +1,62 @@
+From f07e0e093c42736df56f4830179c19f48f8b0725 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:17 +0100
+Subject: [PATCH 06/32] arm64: dts: mediatek: mt7988: Add lvts node
+
+Add Low Voltage Thermal Sensor (LVTS) node for mt7988 SoC.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-4-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -4,6 +4,7 @@
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/phy/phy.h>
+ #include <dt-bindings/pinctrl/mt65xx.h>
++#include <dt-bindings/reset/mediatek,mt7988-resets.h>
+ / {
+       compatible = "mediatek,mt7988a";
+@@ -97,6 +98,7 @@
+                       compatible = "mediatek,mt7988-infracfg", "syscon";
+                       reg = <0 0x10001000 0 0x1000>;
+                       #clock-cells = <1>;
++                      #reset-cells = <1>;
+               };
+               topckgen: clock-controller@1001b000 {
+@@ -265,6 +267,17 @@
+                       status = "disabled";
+               };
++              lvts: lvts@1100a000 {
++                      compatible = "mediatek,mt7988-lvts-ap";
++                      #thermal-sensor-cells = <1>;
++                      reg = <0 0x1100a000 0 0x1000>;
++                      clocks = <&infracfg CLK_INFRA_26M_THERM_SYSTEM>;
++                      interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
++                      resets = <&infracfg MT7988_INFRA_RST1_THERM_CTRL_SWRST>;
++                      nvmem-cells = <&lvts_calibration>;
++                      nvmem-cell-names = "lvts-calib-data-1";
++              };
++
+               usb@11190000 {
+                       compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
+                       reg = <0 0x11190000 0 0x2e00>,
+@@ -324,6 +337,10 @@
+                       reg = <0 0x11f50000 0 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
++
++                      lvts_calibration: calib@918 {
++                              reg = <0x918 0x28>;
++                      };
+               };
+               clock-controller@15000000 {
diff --git a/target/linux/mediatek/patches-6.12/026-v6.14-arm64-dts-mediatek-mt7988-Add-thermal-zone.patch b/target/linux/mediatek/patches-6.12/026-v6.14-arm64-dts-mediatek-mt7988-Add-thermal-zone.patch
new file mode 100644 (file)
index 0000000..e0ff078
--- /dev/null
@@ -0,0 +1,39 @@
+From 122ed9fc41b948d79ac357f95f5438a4bd6786b8 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:18 +0100
+Subject: [PATCH 07/32] arm64: dts: mediatek: mt7988: Add thermal-zone
+
+Add basic thermal-zone node.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-5-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -358,6 +358,21 @@
+               };
+       };
++      thermal-zones {
++              cpu_thermal: cpu-thermal {
++                      polling-delay-passive = <1000>;
++                      polling-delay = <1000>;
++                      thermal-sensors = <&lvts 0>;
++                      trips {
++                              cpu_trip_crit: crit {
++                                      temperature = <125000>;
++                                      hysteresis = <2000>;
++                                      type = "critical";
++                              };
++                      };
++              };
++      };
++
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupt-parent = <&gic>;
diff --git a/target/linux/mediatek/patches-6.12/027-v6.14-arm64-dts-mediatek-mt7988-Add-mcu-sys-node-for-cpu.patch b/target/linux/mediatek/patches-6.12/027-v6.14-arm64-dts-mediatek-mt7988-Add-mcu-sys-node-for-cpu.patch
new file mode 100644 (file)
index 0000000..551dca3
--- /dev/null
@@ -0,0 +1,31 @@
+From 7fa08d530548ed57752703e9f011eeeb809ef9b0 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:20 +0100
+Subject: [PATCH 08/32] arm64: dts: mediatek: mt7988: Add mcu-sys node for cpu
+
+In preparation for adding support for CPU DVFS and clock tables for it,
+add the MCUSYS clock controller node.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-7-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -192,6 +192,12 @@
+                       status = "disabled";
+               };
++              mcusys: mcusys@100e0000 {
++                      compatible = "mediatek,mt7988-mcusys", "syscon";
++                      reg = <0 0x100e0000 0 0x1000>;
++                      #clock-cells = <1>;
++              };
++
+               serial@11000000 {
+                       compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
+                       reg = <0 0x11000000 0 0x100>;
diff --git a/target/linux/mediatek/patches-6.12/028-v6.14-arm64-dts-mediatek-mt7988-Add-CPU-OPP-table-for-cloc.patch b/target/linux/mediatek/patches-6.12/028-v6.14-arm64-dts-mediatek-mt7988-Add-CPU-OPP-table-for-cloc.patch
new file mode 100644 (file)
index 0000000..e2bec75
--- /dev/null
@@ -0,0 +1,84 @@
+From b10331c8faa1208c61fb98d9b65da2828e239113 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:21 +0100
+Subject: [PATCH 09/32] arm64: dts: mediatek: mt7988: Add CPU OPP table for
+ clock scaling
+
+Add operating points defining frequency/voltages of cpu cores.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-8-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 38 +++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -21,6 +21,10 @@
+                       reg = <0x0>;
+                       device_type = "cpu";
+                       enable-method = "psci";
++                      clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
++                               <&topckgen CLK_TOP_XTAL>;
++                      clock-names = "cpu", "intermediate";
++                      operating-points-v2 = <&cluster0_opp>;
+               };
+               cpu@1 {
+@@ -28,6 +32,10 @@
+                       reg = <0x1>;
+                       device_type = "cpu";
+                       enable-method = "psci";
++                      clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
++                               <&topckgen CLK_TOP_XTAL>;
++                      clock-names = "cpu", "intermediate";
++                      operating-points-v2 = <&cluster0_opp>;
+               };
+               cpu@2 {
+@@ -35,6 +43,10 @@
+                       reg = <0x2>;
+                       device_type = "cpu";
+                       enable-method = "psci";
++                      clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
++                               <&topckgen CLK_TOP_XTAL>;
++                      clock-names = "cpu", "intermediate";
++                      operating-points-v2 = <&cluster0_opp>;
+               };
+               cpu@3 {
+@@ -42,6 +54,32 @@
+                       reg = <0x3>;
+                       device_type = "cpu";
+                       enable-method = "psci";
++                      clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
++                               <&topckgen CLK_TOP_XTAL>;
++                      clock-names = "cpu", "intermediate";
++                      operating-points-v2 = <&cluster0_opp>;
++              };
++
++              cluster0_opp: opp-table-0 {
++                      compatible = "operating-points-v2";
++                      opp-shared;
++
++                      opp-800000000 {
++                              opp-hz = /bits/ 64 <800000000>;
++                              opp-microvolt = <850000>;
++                      };
++                      opp-1100000000 {
++                              opp-hz = /bits/ 64 <1100000000>;
++                              opp-microvolt = <850000>;
++                      };
++                      opp-1500000000 {
++                              opp-hz = /bits/ 64 <1500000000>;
++                              opp-microvolt = <850000>;
++                      };
++                      opp-1800000000 {
++                              opp-hz = /bits/ 64 <1800000000>;
++                              opp-microvolt = <900000>;
++                      };
+               };
+       };
diff --git a/target/linux/mediatek/patches-6.12/029-v6.14-arm64-dts-mediatek-mt7988-Disable-usb-controllers-by.patch b/target/linux/mediatek/patches-6.12/029-v6.14-arm64-dts-mediatek-mt7988-Disable-usb-controllers-by.patch
new file mode 100644 (file)
index 0000000..f65d23b
--- /dev/null
@@ -0,0 +1,34 @@
+From 39bb12c26f556046e55f3638e2e4184bfbfd0564 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:22 +0100
+Subject: [PATCH 10/32] arm64: dts: mediatek: mt7988: Disable usb controllers
+ by default
+
+The controllers should be enabled at board level if used.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-9-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -334,6 +334,7 @@
+                                <&infracfg CLK_INFRA_133M_USB_HCK>,
+                                <&infracfg CLK_INFRA_USB_XHCI>;
+                       clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
++                      status = "disabled";
+               };
+               usb@11200000 {
+@@ -348,6 +349,7 @@
+                                <&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>,
+                                <&infracfg CLK_INFRA_USB_XHCI_CK_P1>;
+                       clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
++                      status = "disabled";
+               };
+               mmc0: mmc@11230000 {
diff --git a/target/linux/mediatek/patches-6.12/030-v6.14-arm64-dts-mediatek-mt7988-Add-t-phy-for-ssusb1.patch b/target/linux/mediatek/patches-6.12/030-v6.14-arm64-dts-mediatek-mt7988-Add-t-phy-for-ssusb1.patch
new file mode 100644 (file)
index 0000000..c53db06
--- /dev/null
@@ -0,0 +1,59 @@
+From 46d056b6c2376d3ef866f9ab5212879c97588892 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:23 +0100
+Subject: [PATCH 11/32] arm64: dts: mediatek: mt7988: Add t-phy for ssusb1
+
+USB controller needs phys for working properly.
+On mt7988 ssusb0 uses a xs-phy, ssusb uses t-phy.
+For now add the t-phy for ssusb1. We can reuse the mt7986 compatible
+here.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-10-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 25 +++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -349,6 +349,8 @@
+                                <&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>,
+                                <&infracfg CLK_INFRA_USB_XHCI_CK_P1>;
+                       clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
++                      phys = <&tphyu2port0 PHY_TYPE_USB2>,
++                             <&tphyu3port0 PHY_TYPE_USB3>;
+                       status = "disabled";
+               };
+@@ -371,6 +373,29 @@
+                       status = "disabled";
+               };
++              t-phy@11c50000 {
++                      compatible = "mediatek,mt7986-tphy",
++                                   "mediatek,generic-tphy-v2";
++                      #address-cells = <2>;
++                      #size-cells = <2>;
++                      ranges;
++                      status = "disabled";
++
++                      tphyu2port0: usb-phy@11c50000 {
++                              reg = <0 0x11c50000 0 0x700>;
++                              clocks = <&infracfg CLK_INFRA_USB_UTMI_CK_P1>;
++                              clock-names = "ref";
++                              #phy-cells = <1>;
++                      };
++
++                      tphyu3port0: usb-phy@11c50700 {
++                              reg = <0 0x11c50700 0 0x900>;
++                              clocks = <&infracfg CLK_INFRA_USB_PIPE_CK_P1>;
++                              clock-names = "ref";
++                              #phy-cells = <1>;
++                      };
++              };
++
+               clock-controller@11f40000 {
+                       compatible = "mediatek,mt7988-xfi-pll";
+                       reg = <0 0x11f40000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/031-v6.14-arm64-dts-mediatek-mt7988-Add-pcie-nodes.patch b/target/linux/mediatek/patches-6.12/031-v6.14-arm64-dts-mediatek-mt7988-Add-pcie-nodes.patch
new file mode 100644 (file)
index 0000000..fe27e52
--- /dev/null
@@ -0,0 +1,176 @@
+From aac2eb27ee500ca2828fe0fd1895ec6f9ef83787 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:24 +0100
+Subject: [PATCH 12/32] arm64: dts: mediatek: mt7988: Add pcie nodes
+
+Add pcie controllers for mt7988. Reuse mt7986 compatible.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-11-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 152 ++++++++++++++++++++++
+ 1 file changed, 152 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -373,6 +373,158 @@
+                       status = "disabled";
+               };
++              pcie@11280000 {
++                      compatible = "mediatek,mt7986-pcie",
++                                   "mediatek,mt8192-pcie";
++                      device_type = "pci";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      reg = <0 0x11280000 0 0x2000>;
++                      reg-names = "pcie-mac";
++                      linux,pci-domain = <3>;
++                      interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
++                      bus-range = <0x00 0xff>;
++                      ranges = <0x81000000 0x00 0x20000000 0x00
++                                0x20000000 0x00 0x00200000>,
++                               <0x82000000 0x00 0x20200000 0x00
++                                0x20200000 0x00 0x07e00000>;
++                      clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P2>,
++                               <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P2>,
++                               <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P2>,
++                               <&infracfg CLK_INFRA_133M_PCIE_CK_P2>;
++                      clock-names = "pl_250m", "tl_26m", "peri_26m",
++                                    "top_133m";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&pcie2_pins>;
++                      status = "disabled";
++
++                      #interrupt-cells = <1>;
++                      interrupt-map-mask = <0 0 0 0x7>;
++                      interrupt-map = <0 0 0 1 &pcie_intc2 0>,
++                                      <0 0 0 2 &pcie_intc2 1>,
++                                      <0 0 0 3 &pcie_intc2 2>,
++                                      <0 0 0 4 &pcie_intc2 3>;
++                      pcie_intc2: interrupt-controller {
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                              interrupt-controller;
++                      };
++              };
++
++              pcie@11290000 {
++                      compatible = "mediatek,mt7986-pcie",
++                                   "mediatek,mt8192-pcie";
++                      device_type = "pci";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      reg = <0 0x11290000 0 0x2000>;
++                      reg-names = "pcie-mac";
++                      linux,pci-domain = <2>;
++                      interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
++                      bus-range = <0x00 0xff>;
++                      ranges = <0x81000000 0x00 0x28000000 0x00
++                                0x28000000 0x00 0x00200000>,
++                               <0x82000000 0x00 0x28200000 0x00
++                                0x28200000 0x00 0x07e00000>;
++                      clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P3>,
++                               <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P3>,
++                               <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P3>,
++                               <&infracfg CLK_INFRA_133M_PCIE_CK_P3>;
++                      clock-names = "pl_250m", "tl_26m", "peri_26m",
++                                    "top_133m";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&pcie3_pins>;
++                      status = "disabled";
++
++                      #interrupt-cells = <1>;
++                      interrupt-map-mask = <0 0 0 0x7>;
++                      interrupt-map = <0 0 0 1 &pcie_intc3 0>,
++                                      <0 0 0 2 &pcie_intc3 1>,
++                                      <0 0 0 3 &pcie_intc3 2>,
++                                      <0 0 0 4 &pcie_intc3 3>;
++                      pcie_intc3: interrupt-controller {
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                              interrupt-controller;
++                      };
++              };
++
++              pcie@11300000 {
++                      compatible = "mediatek,mt7986-pcie",
++                                   "mediatek,mt8192-pcie";
++                      device_type = "pci";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      reg = <0 0x11300000 0 0x2000>;
++                      reg-names = "pcie-mac";
++                      linux,pci-domain = <0>;
++                      interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
++                      bus-range = <0x00 0xff>;
++                      ranges = <0x81000000 0x00 0x30000000 0x00
++                                0x30000000 0x00 0x00200000>,
++                               <0x82000000 0x00 0x30200000 0x00
++                                0x30200000 0x00 0x07e00000>;
++                      clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P0>,
++                               <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P0>,
++                               <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P0>,
++                               <&infracfg CLK_INFRA_133M_PCIE_CK_P0>;
++                      clock-names = "pl_250m", "tl_26m", "peri_26m",
++                                    "top_133m";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&pcie0_pins>;
++                      status = "disabled";
++
++                      #interrupt-cells = <1>;
++                      interrupt-map-mask = <0 0 0 0x7>;
++                      interrupt-map = <0 0 0 1 &pcie_intc0 0>,
++                                      <0 0 0 2 &pcie_intc0 1>,
++                                      <0 0 0 3 &pcie_intc0 2>,
++                                      <0 0 0 4 &pcie_intc0 3>;
++                      pcie_intc0: interrupt-controller {
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                              interrupt-controller;
++                      };
++              };
++
++              pcie@11310000 {
++                      compatible = "mediatek,mt7986-pcie",
++                                   "mediatek,mt8192-pcie";
++                      device_type = "pci";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      reg = <0 0x11310000 0 0x2000>;
++                      reg-names = "pcie-mac";
++                      linux,pci-domain = <1>;
++                      interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
++                      bus-range = <0x00 0xff>;
++                      ranges = <0x81000000 0x00 0x38000000 0x00
++                                0x38000000 0x00 0x00200000>,
++                               <0x82000000 0x00 0x38200000 0x00
++                                0x38200000 0x00 0x07e00000>;
++                      clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P1>,
++                               <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P1>,
++                               <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P1>,
++                               <&infracfg CLK_INFRA_133M_PCIE_CK_P1>;
++                      clock-names = "pl_250m", "tl_26m", "peri_26m",
++                                    "top_133m";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&pcie1_pins>;
++                      status = "disabled";
++
++                      #interrupt-cells = <1>;
++                      interrupt-map-mask = <0 0 0 0x7>;
++                      interrupt-map = <0 0 0 1 &pcie_intc1 0>,
++                                      <0 0 0 2 &pcie_intc1 1>,
++                                      <0 0 0 3 &pcie_intc1 2>,
++                                      <0 0 0 4 &pcie_intc1 3>;
++                      pcie_intc1: interrupt-controller {
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                              interrupt-controller;
++                      };
++              };
++
+               t-phy@11c50000 {
+                       compatible = "mediatek,mt7986-tphy",
+                                    "mediatek,generic-tphy-v2";
diff --git a/target/linux/mediatek/patches-6.12/032-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-pinctrl-subnod.patch b/target/linux/mediatek/patches-6.12/032-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-pinctrl-subnod.patch
new file mode 100644 (file)
index 0000000..6f0080e
--- /dev/null
@@ -0,0 +1,211 @@
+From 6b116c43782a153bcde18bd54d3220d81b476859 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 09:54:30 +0100
+Subject: [PATCH 13/32] arm64: dts: mediatek: mt7988a-bpi-r4: Add pinctrl
+ subnodes for bpi-r4
+
+Add board specific pinctrl configurations on Bananapi R4.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217085435.9586-6-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 189 ++++++++++++++++++
+ 1 file changed, 189 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -9,3 +9,192 @@
+       model = "Banana Pi BPI-R4";
+       chassis-type = "embedded";
+ };
++
++&pio {
++      mdio0_pins: mdio0-pins {
++              mux {
++                      function = "eth";
++                      groups = "mdc_mdio0";
++              };
++
++              conf {
++                      pins = "SMI_0_MDC", "SMI_0_MDIO";
++                      drive-strength = <8>;
++              };
++      };
++
++      i2c0_pins: i2c0-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c0_1";
++              };
++      };
++
++      i2c1_pins: i2c1-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c1_0";
++              };
++      };
++
++      i2c1_sfp_pins: i2c1-sfp-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c1_sfp";
++              };
++      };
++
++      i2c2_0_pins: i2c2-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c2_0";
++              };
++      };
++
++      i2c2_1_pins: i2c2-g1-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c2_1";
++              };
++      };
++
++      gbe0_led0_pins: gbe0-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe0_led0";
++              };
++      };
++
++      gbe1_led0_pins: gbe1-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe1_led0";
++              };
++      };
++
++      gbe2_led0_pins: gbe2-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe2_led0";
++              };
++      };
++
++      gbe3_led0_pins: gbe3-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe3_led0";
++              };
++      };
++
++      gbe0_led1_pins: gbe0-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe0_led1";
++              };
++      };
++
++      gbe1_led1_pins: gbe1-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe1_led1";
++              };
++      };
++
++      gbe2_led1_pins: gbe2-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe2_led1";
++              };
++      };
++
++      gbe3_led1_pins: gbe3-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe3_led1";
++              };
++      };
++
++      i2p5gbe_led0_pins: 2p5gbe-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "2p5gbe_led0";
++              };
++      };
++
++      i2p5gbe_led1_pins: 2p5gbe-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "2p5gbe_led1";
++              };
++      };
++
++      mmc0_pins_emmc_45: mmc0-emmc-45-pins {
++              mux {
++                      function = "flash";
++                      groups = "emmc_45";
++              };
++      };
++
++      mmc0_pins_emmc_51: mmc0-emmc-51-pins {
++              mux {
++                      function = "flash";
++                      groups = "emmc_51";
++              };
++      };
++
++      mmc0_pins_sdcard: mmc0-sdcard-pins {
++              mux {
++                      function = "flash";
++                      groups = "sdcard";
++              };
++      };
++
++      uart0_pins: uart0-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart0";
++              };
++      };
++
++      snfi_pins: snfi-pins {
++              mux {
++                      function = "flash";
++                      groups = "snfi";
++              };
++      };
++
++      spi0_pins: spi0-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0";
++              };
++      };
++
++      spi0_flash_pins: spi0-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0", "spi0_wp_hold";
++              };
++      };
++
++      spi1_pins: spi1-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi1";
++              };
++      };
++
++      spi2_pins: spi2-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi2";
++              };
++      };
++
++      spi2_flash_pins: spi2-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi2", "spi2_wp_hold";
++              };
++      };
++};
diff --git a/target/linux/mediatek/patches-6.12/033-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-watchdog.patch b/target/linux/mediatek/patches-6.12/033-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-watchdog.patch
new file mode 100644 (file)
index 0000000..2ce47ed
--- /dev/null
@@ -0,0 +1,25 @@
+From 6b6f2f1ee88b8b5763f4112babbc9fc45a94999a Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:25 +0100
+Subject: [PATCH 14/32] arm64: dts: mediatek: mt7988a-bpi-r4: Enable watchdog
+
+Enable the watchdog on Bananapi R4 board.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-12-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -198,3 +198,7 @@
+               };
+       };
+ };
++
++&watchdog {
++      status = "okay";
++};
diff --git a/target/linux/mediatek/patches-6.12/034-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-fixed-regulato.patch b/target/linux/mediatek/patches-6.12/034-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-fixed-regulato.patch
new file mode 100644 (file)
index 0000000..fb383d0
--- /dev/null
@@ -0,0 +1,48 @@
+From 72b0a6f181c5ca417405e594c80d724baee54813 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:26 +0100
+Subject: [PATCH 15/32] arm64: dts: mediatek: mt7988a-bpi-r4: Add fixed
+ regulators for 1v8 and 3v3
+
+Add regulator nodes used for mmc to Bananapi R4 board.
+This board has 1 MMC controller used for SDMMC and eMMC where only one can
+be used at one time, selected by hardware switches. SD uses 3v3 for both
+supplies and emmc uses both regulators.
+So defining both regulators in board dts and referencing them in the dt
+overlay.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-13-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts   | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -8,6 +8,24 @@
+       compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+       model = "Banana Pi BPI-R4";
+       chassis-type = "embedded";
++
++      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;
++      };
+ };
+ &pio {
diff --git a/target/linux/mediatek/patches-6.12/035-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-thermal-config.patch b/target/linux/mediatek/patches-6.12/035-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-thermal-config.patch
new file mode 100644 (file)
index 0000000..3273e74
--- /dev/null
@@ -0,0 +1,54 @@
+From 67511ea667d3c4da827588fd460772562d7b054e Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:28 +0100
+Subject: [PATCH 16/32] arm64: dts: mediatek: mt7988a-bpi-r4: Add thermal
+ configuration
+
+Add additional thermal trips to Bananapi R4 board.
+SoC only contains the critical trip.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-15-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 28 +++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -28,6 +28,34 @@
+       };
+ };
++&cpu_thermal {
++      trips {
++              cpu_trip_hot: hot {
++                      temperature = <120000>;
++                      hysteresis = <2000>;
++                      type = "hot";
++              };
++
++              cpu_trip_active_high: active-high {
++                      temperature = <115000>;
++                      hysteresis = <2000>;
++                      type = "active";
++              };
++
++              cpu_trip_active_med: active-med {
++                      temperature = <85000>;
++                      hysteresis = <2000>;
++                      type = "active";
++              };
++
++              cpu_trip_active_low: active-low {
++                      temperature = <40000>;
++                      hysteresis = <2000>;
++                      type = "active";
++              };
++      };
++};
++
+ &pio {
+       mdio0_pins: mdio0-pins {
+               mux {
diff --git a/target/linux/mediatek/patches-6.12/036-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-serial0-deb.patch b/target/linux/mediatek/patches-6.12/036-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-serial0-deb.patch
new file mode 100644 (file)
index 0000000..c1d872d
--- /dev/null
@@ -0,0 +1,41 @@
+From a9df5ed2333b01546b4f906e2f6fd21dd5b146aa Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:29 +0100
+Subject: [PATCH 17/32] arm64: dts: mediatek: mt7988a-bpi-r4: Enable serial0
+ debug uart
+
+Enable the debug uart on Bananapi R4 board.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-16-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -245,6 +245,10 @@
+       };
+ };
++&serial0 {
++      status = "okay";
++};
++
+ &watchdog {
+       status = "okay";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -236,7 +236,7 @@
+                       #clock-cells = <1>;
+               };
+-              serial@11000000 {
++              serial0: serial@11000000 {
+                       compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
+                       reg = <0 0x11000000 0 0x100>;
+                       interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/target/linux/mediatek/patches-6.12/037-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-default-UART-s.patch b/target/linux/mediatek/patches-6.12/037-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-default-UART-s.patch
new file mode 100644 (file)
index 0000000..d75b3e5
--- /dev/null
@@ -0,0 +1,29 @@
+From 3dfb0dcb194e3f32ed931747131be08bfc429522 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:30 +0100
+Subject: [PATCH 18/32] arm64: dts: mediatek: mt7988a-bpi-r4: Add default UART
+ stdout
+
+Add chosen node on Bananapi R4 board with stdout and default bootargs.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-17-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -9,6 +9,10 @@
+       model = "Banana Pi BPI-R4";
+       chassis-type = "embedded";
++      chosen {
++              stdout-path = "serial0:115200n8";
++      };
++
+       reg_1p8v: regulator-1p8v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-1.8V";
diff --git a/target/linux/mediatek/patches-6.12/038-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-I2C-control.patch b/target/linux/mediatek/patches-6.12/038-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-I2C-control.patch
new file mode 100644 (file)
index 0000000..4f48edd
--- /dev/null
@@ -0,0 +1,72 @@
+From 90d4eb65db14a3f2e776d2a8b1dc832e70198328 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:31 +0100
+Subject: [PATCH 19/32] arm64: dts: mediatek: mt7988a-bpi-r4: Enable I2C
+ controllers
+
+Enable the I2C0, I2C2 controllers found on the BananaPi R4 board.
+Both controllers are not accessible from user and having fixed spare
+devices. I2C0 have a pmic connected, I2C2 is used with I2C-multiplexer
+for e.g. SFP cages.
+The missing I2C1 is connected to GPIO header which can have either GPIO
+mode or I2C mode.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-18-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts    | 12 ++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi            |  6 +++---
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -60,6 +60,18 @@
+       };
+ };
++&i2c0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c0_pins>;
++      status = "okay";
++};
++
++&i2c2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c2_1_pins>;
++      status = "okay";
++};
++
+ &pio {
+       mdio0_pins: mdio0-pins {
+               mux {
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -269,7 +269,7 @@
+                       status = "disabled";
+               };
+-              i2c@11003000 {
++              i2c0: i2c@11003000 {
+                       compatible = "mediatek,mt7981-i2c";
+                       reg = <0 0x11003000 0 0x1000>,
+                             <0 0x10217080 0 0x80>;
+@@ -283,7 +283,7 @@
+                       status = "disabled";
+               };
+-              i2c@11004000 {
++              i2c1: i2c@11004000 {
+                       compatible = "mediatek,mt7981-i2c";
+                       reg = <0 0x11004000 0 0x1000>,
+                             <0 0x10217100 0 0x80>;
+@@ -297,7 +297,7 @@
+                       status = "disabled";
+               };
+-              i2c@11005000 {
++              i2c2: i2c@11005000 {
+                       compatible = "mediatek,mt7981-i2c";
+                       reg = <0 0x11005000 0 0x1000>,
+                             <0 0x10217180 0 0x80>;
diff --git a/target/linux/mediatek/patches-6.12/039-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-PCA9545-I2C-Mu.patch b/target/linux/mediatek/patches-6.12/039-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-PCA9545-I2C-Mu.patch
new file mode 100644 (file)
index 0000000..117479b
--- /dev/null
@@ -0,0 +1,74 @@
+From dde7d741329616025e4cfa350eb3935b495ae140 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:32 +0100
+Subject: [PATCH 20/32] arm64: dts: mediatek: mt7988a-bpi-r4: Add PCA9545 I2C
+ Mux
+
+Bananapi R4 uses an i2c multiplexer for SFP slots, rtc and eeprom.
+Add its node to the right i2c controller.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-19-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 41 +++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -2,6 +2,8 @@
+ /dts-v1/;
++#include <dt-bindings/gpio/gpio.h>
++
+ #include "mt7988a.dtsi"
+ / {
+@@ -70,6 +72,45 @@
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_1_pins>;
+       status = "okay";
++
++      pca9545: i2c-mux@70 {
++              compatible = "nxp,pca9545";
++              reg = <0x70>;
++              reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              i2c@0 {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      reg = <0>;
++
++                      pcf8563: rtc@51 {
++                              compatible = "nxp,pcf8563";
++                              reg = <0x51>;
++                              #clock-cells = <0>;
++                      };
++
++                      eeprom@57 {
++                              compatible = "atmel,24c02";
++                              reg = <0x57>;
++                              size = <256>;
++                      };
++
++              };
++
++              i2c_sfp1: i2c@1 {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      reg = <1>;
++              };
++
++              i2c_sfp2: i2c@2 {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      reg = <2>;
++              };
++      };
+ };
+ &pio {
diff --git a/target/linux/mediatek/patches-6.12/040-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-t-phy-for-s.patch b/target/linux/mediatek/patches-6.12/040-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-t-phy-for-s.patch
new file mode 100644 (file)
index 0000000..e16b30e
--- /dev/null
@@ -0,0 +1,41 @@
+From dfe00be85da20d9823d39775c92139c569a7960d Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:33 +0100
+Subject: [PATCH 21/32] arm64: dts: mediatek: mt7988a-bpi-r4: Enable t-phy for
+ ssusb1
+
+Bananapi R4 uses t-phy for usb. Enable its node at board level.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-20-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -306,6 +306,10 @@
+       status = "okay";
+ };
++&tphy {
++      status = "okay";
++};
++
+ &watchdog {
+       status = "okay";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -525,7 +525,7 @@
+                       };
+               };
+-              t-phy@11c50000 {
++              tphy: t-phy@11c50000 {
+                       compatible = "mediatek,mt7986-tphy",
+                                    "mediatek,generic-tphy-v2";
+                       #address-cells = <2>;
diff --git a/target/linux/mediatek/patches-6.12/041-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-ssusb1-on-b.patch b/target/linux/mediatek/patches-6.12/041-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-ssusb1-on-b.patch
new file mode 100644 (file)
index 0000000..d1892c6
--- /dev/null
@@ -0,0 +1,41 @@
+From 2b03ef47273db52e0c0010e963c3626e6842204f Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:34 +0100
+Subject: [PATCH 22/32] arm64: dts: mediatek: mt7988a-bpi-r4: Enable ssusb1 on
+ bpi-r4
+
+Enable usb on Bananapi R4 board.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-21-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -306,6 +306,10 @@
+       status = "okay";
+ };
++&ssusb1 {
++      status = "okay";
++};
++
+ &tphy {
+       status = "okay";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -337,7 +337,7 @@
+                       status = "disabled";
+               };
+-              usb@11200000 {
++              ssusb1: usb@11200000 {
+                       compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
+                       reg = <0 0x11200000 0 0x2e00>,
+                             <0 0x11203e00 0 0x0100>;
diff --git a/target/linux/mediatek/patches-6.12/042-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-pwm.patch b/target/linux/mediatek/patches-6.12/042-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-pwm.patch
new file mode 100644 (file)
index 0000000..4e24607
--- /dev/null
@@ -0,0 +1,40 @@
+From b074487a4180aeee440b61fc00a865fc2a4bd32a Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:35 +0100
+Subject: [PATCH 23/32] arm64: dts: mediatek: mt7988a-bpi-r4: Enable pwm
+
+Enable pwm on Bananapi R4 board.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-22-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi                | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -302,6 +302,10 @@
+       };
+ };
++&pwm {
++      status = "okay";
++};
++
+ &serial0 {
+       status = "okay";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -211,7 +211,7 @@
+                       };
+               };
+-              pwm@10048000 {
++              pwm: pwm@10048000 {
+                       compatible = "mediatek,mt7988-pwm";
+                       reg = <0 0x10048000 0 0x1000>;
+                       clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>,
diff --git a/target/linux/mediatek/patches-6.12/043-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-pcie.patch b/target/linux/mediatek/patches-6.12/043-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Enable-pcie.patch
new file mode 100644 (file)
index 0000000..a25d235
--- /dev/null
@@ -0,0 +1,83 @@
+From 72bc814e8609e8be59dff8bc6e0e185b5005ace8 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 17 Dec 2024 10:12:36 +0100
+Subject: [PATCH 24/32] arm64: dts: mediatek: mt7988a-bpi-r4: Enable pcie
+
+Enable the pci controllers on BPI-R4.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241217091238.16032-23-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 20 +++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi     |  8 ++++----
+ 2 files changed, 24 insertions(+), 4 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -113,6 +113,26 @@
+       };
+ };
++/* mPCIe SIM2 */
++&pcie0 {
++      status = "okay";
++};
++
++/* mPCIe SIM3 */
++&pcie1 {
++      status = "okay";
++};
++
++/* M.2 key-B SIM1 */
++&pcie2 {
++      status = "okay";
++};
++
++/* M.2 key-M SSD */
++&pcie3 {
++      status = "okay";
++};
++
+ &pio {
+       mdio0_pins: mdio0-pins {
+               mux {
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -373,7 +373,7 @@
+                       status = "disabled";
+               };
+-              pcie@11280000 {
++              pcie2: pcie@11280000 {
+                       compatible = "mediatek,mt7986-pcie",
+                                    "mediatek,mt8192-pcie";
+                       device_type = "pci";
+@@ -411,7 +411,7 @@
+                       };
+               };
+-              pcie@11290000 {
++              pcie3: pcie@11290000 {
+                       compatible = "mediatek,mt7986-pcie",
+                                    "mediatek,mt8192-pcie";
+                       device_type = "pci";
+@@ -449,7 +449,7 @@
+                       };
+               };
+-              pcie@11300000 {
++              pcie0: pcie@11300000 {
+                       compatible = "mediatek,mt7986-pcie",
+                                    "mediatek,mt8192-pcie";
+                       device_type = "pci";
+@@ -487,7 +487,7 @@
+                       };
+               };
+-              pcie@11310000 {
++              pcie1: pcie@11310000 {
+                       compatible = "mediatek,mt7986-pcie",
+                                    "mediatek,mt8192-pcie";
+                       device_type = "pci";
diff --git a/target/linux/mediatek/patches-6.12/044-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-MediaTek-MT668.patch b/target/linux/mediatek/patches-6.12/044-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-MediaTek-MT668.patch
new file mode 100644 (file)
index 0000000..26a5990
--- /dev/null
@@ -0,0 +1,96 @@
+From 84087157052afba2f61cea7c99ccabfe9681b643 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 20 Dec 2024 17:38:35 +0100
+Subject: [PATCH 25/32] arm64: dts: mediatek: mt7988a-bpi-r4: Add MediaTek
+ MT6682A/RT5190A PMIC
+
+Bananapi R4 Board contains a MT6682A pmic which is compatible to rt5190a.
+Add its node to the i2 controller.
+
+The BananaPi R4 board has a MediaTek MT6682A PMIC, a rebrand of the
+Richtek RT5190A chip, connected to the I2C0 bus.
+
+Add the relevant node and, while at it, also configure the regulators
+from this PMIC that are used on this board.
+
+Only Buck2/Buck3 voltage can be controlled by software.
+
+BUCK4 input is 5V from BUCK1 output, and the resistor (mapped to RP30/RP31
+on BPI-R4) configures BUCK4 output to 1.8V.
+LDO input is 3.3V from 3.3VD, and the resistor (mapped to RP38/RP40 on
+BPI-R4) configures LDO output to 1.8V.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241220163838.114786-2-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 50 +++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -3,6 +3,7 @@
+ /dts-v1/;
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
+ #include "mt7988a.dtsi"
+@@ -66,6 +67,55 @@
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+       status = "okay";
++
++      rt5190a_64: rt5190a@64 {
++              compatible = "richtek,rt5190a";
++              reg = <0x64>;
++              vin2-supply = <&rt5190_buck1>;
++              vin3-supply = <&rt5190_buck1>;
++              vin4-supply = <&rt5190_buck1>;
++
++              regulators {
++                      rt5190_buck1: buck1 {
++                              regulator-name = "rt5190a-buck1";
++                              regulator-min-microvolt = <5090000>;
++                              regulator-max-microvolt = <5090000>;
++                              regulator-allowed-modes =
++                              <RT5190A_OPMODE_AUTO>, <RT5190A_OPMODE_FPWM>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      buck2 {
++                              regulator-name = "vcore";
++                              regulator-min-microvolt = <600000>;
++                              regulator-max-microvolt = <1400000>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      rt5190_buck3: buck3 {
++                              regulator-name = "vproc";
++                              regulator-min-microvolt = <600000>;
++                              regulator-max-microvolt = <1400000>;
++                              regulator-boot-on;
++                      };
++                      buck4 {
++                              regulator-name = "rt5190a-buck4";
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-allowed-modes =
++                              <RT5190A_OPMODE_AUTO>, <RT5190A_OPMODE_FPWM>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      ldo {
++                              regulator-name = "rt5190a-ldo";
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++              };
++      };
+ };
+ &i2c2 {
diff --git a/target/linux/mediatek/patches-6.12/045-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-proc-supply-fo.patch b/target/linux/mediatek/patches-6.12/045-v6.14-arm64-dts-mediatek-mt7988a-bpi-r4-Add-proc-supply-fo.patch
new file mode 100644 (file)
index 0000000..c605e90
--- /dev/null
@@ -0,0 +1,80 @@
+From c0a17ddd90c2094dfe4610b0d965db8a3b987e32 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 20 Dec 2024 17:38:36 +0100
+Subject: [PATCH 26/32] arm64: dts: mediatek: mt7988a-bpi-r4: Add proc-supply
+ for cpus
+
+Add proc-supply property to cpus on Bananapi R4 board.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20241220163838.114786-3-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts     | 16 ++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi        |  8 ++++----
+ 2 files changed, 20 insertions(+), 4 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -35,6 +35,22 @@
+       };
+ };
++&cpu0 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu1 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu2 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu3 {
++      proc-supply = <&rt5190_buck3>;
++};
++
+ &cpu_thermal {
+       trips {
+               cpu_trip_hot: hot {
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -16,7 +16,7 @@
+               #address-cells = <1>;
+               #size-cells = <0>;
+-              cpu@0 {
++              cpu0: cpu@0 {
+                       compatible = "arm,cortex-a73";
+                       reg = <0x0>;
+                       device_type = "cpu";
+@@ -27,7 +27,7 @@
+                       operating-points-v2 = <&cluster0_opp>;
+               };
+-              cpu@1 {
++              cpu1: cpu@1 {
+                       compatible = "arm,cortex-a73";
+                       reg = <0x1>;
+                       device_type = "cpu";
+@@ -38,7 +38,7 @@
+                       operating-points-v2 = <&cluster0_opp>;
+               };
+-              cpu@2 {
++              cpu2: cpu@2 {
+                       compatible = "arm,cortex-a73";
+                       reg = <0x2>;
+                       device_type = "cpu";
+@@ -49,7 +49,7 @@
+                       operating-points-v2 = <&cluster0_opp>;
+               };
+-              cpu@3 {
++              cpu3: cpu@3 {
+                       compatible = "arm,cortex-a73";
+                       reg = <0x3>;
+                       device_type = "cpu";
diff --git a/target/linux/mediatek/patches-6.12/050-v6.16-phy-mediatek-xsphy-support-type-switch-by-pericfg.patch b/target/linux/mediatek/patches-6.12/050-v6.16-phy-mediatek-xsphy-support-type-switch-by-pericfg.patch
new file mode 100644 (file)
index 0000000..a543ecb
--- /dev/null
@@ -0,0 +1,169 @@
+From b7ae3528a588a4006ff9c9cc581efa317df1c1ed Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Apr 2025 15:24:29 +0200
+Subject: [PATCH] phy: mediatek: xsphy: support type switch by pericfg
+
+Patch from Sam Shih <sam.shih@mediatek.com> found in MediaTek SDK
+released under GPL.
+
+Get syscon and use it to set the PHY type.
+Extend support to PCIe and SGMII mode in addition to USB2 and USB3.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ drivers/phy/mediatek/phy-mtk-xsphy.c | 85 +++++++++++++++++++++++++++-
+ 1 file changed, 84 insertions(+), 1 deletion(-)
+
+--- a/drivers/phy/mediatek/phy-mtk-xsphy.c
++++ b/drivers/phy/mediatek/phy-mtk-xsphy.c
+@@ -11,10 +11,12 @@
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/iopoll.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/of_address.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/regmap.h>
+ #include "phy-mtk-io.h"
+@@ -81,12 +83,22 @@
+ #define XSP_SR_COEF_DIVISOR   1000
+ #define XSP_FM_DET_CYCLE_CNT  1024
++/* PHY switch between pcie/usb3/sgmii */
++#define USB_PHY_SWITCH_CTRL   0x0
++#define RG_PHY_SW_TYPE                GENMASK(3, 0)
++#define RG_PHY_SW_PCIE                0x0
++#define RG_PHY_SW_USB3                0x1
++#define RG_PHY_SW_SGMII               0x2
++
+ struct xsphy_instance {
+       struct phy *phy;
+       void __iomem *port_base;
+       struct clk *ref_clk;    /* reference clock of anolog phy */
+       u32 index;
+       u32 type;
++      struct regmap *type_sw;
++      u32 type_sw_reg;
++      u32 type_sw_index;
+       /* only for HQA test */
+       int efuse_intr;
+       int efuse_tx_imp;
+@@ -259,6 +271,10 @@ static void phy_parse_property(struct mt
+                       inst->efuse_intr, inst->efuse_tx_imp,
+                       inst->efuse_rx_imp);
+               break;
++      case PHY_TYPE_PCIE:
++      case PHY_TYPE_SGMII:
++              /* nothing to do */
++              break;
+       default:
+               dev_err(xsphy->dev, "incompatible phy type\n");
+               return;
+@@ -305,6 +321,62 @@ static void u3_phy_props_set(struct mtk_
+                                    RG_XTP_LN0_RX_IMPSEL, inst->efuse_rx_imp);
+ }
++/* type switch for usb3/pcie/sgmii */
++static int phy_type_syscon_get(struct xsphy_instance *instance,
++                             struct device_node *dn)
++{
++      struct of_phandle_args args;
++      int ret;
++
++      /* type switch function is optional */
++      if (!of_property_present(dn, "mediatek,syscon-type"))
++              return 0;
++
++      ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
++                                             2, 0, &args);
++      if (ret)
++              return ret;
++
++      instance->type_sw_reg = args.args[0];
++      instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
++      instance->type_sw = syscon_node_to_regmap(args.np);
++      of_node_put(args.np);
++      dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
++               instance->type_sw_reg, instance->type_sw_index);
++
++      return PTR_ERR_OR_ZERO(instance->type_sw);
++}
++
++static int phy_type_set(struct xsphy_instance *instance)
++{
++      int type;
++      u32 offset;
++
++      if (!instance->type_sw)
++              return 0;
++
++      switch (instance->type) {
++      case PHY_TYPE_USB3:
++              type = RG_PHY_SW_USB3;
++              break;
++      case PHY_TYPE_PCIE:
++              type = RG_PHY_SW_PCIE;
++              break;
++      case PHY_TYPE_SGMII:
++              type = RG_PHY_SW_SGMII;
++              break;
++      case PHY_TYPE_USB2:
++      default:
++              return 0;
++      }
++
++      offset = instance->type_sw_index * BITS_PER_BYTE;
++      regmap_update_bits(instance->type_sw, instance->type_sw_reg,
++                         RG_PHY_SW_TYPE << offset, type << offset);
++
++      return 0;
++}
++
+ static int mtk_phy_init(struct phy *phy)
+ {
+       struct xsphy_instance *inst = phy_get_drvdata(phy);
+@@ -325,6 +397,10 @@ static int mtk_phy_init(struct phy *phy)
+       case PHY_TYPE_USB3:
+               u3_phy_props_set(xsphy, inst);
+               break;
++      case PHY_TYPE_PCIE:
++      case PHY_TYPE_SGMII:
++              /* nothing to do, only used to set type */
++              break;
+       default:
+               dev_err(xsphy->dev, "incompatible phy type\n");
+               clk_disable_unprepare(inst->ref_clk);
+@@ -403,12 +479,15 @@ static struct phy *mtk_phy_xlate(struct
+       inst->type = args->args[0];
+       if (!(inst->type == PHY_TYPE_USB2 ||
+-            inst->type == PHY_TYPE_USB3)) {
++            inst->type == PHY_TYPE_USB3 ||
++            inst->type == PHY_TYPE_PCIE ||
++            inst->type == PHY_TYPE_SGMII)) {
+               dev_err(dev, "unsupported phy type: %d\n", inst->type);
+               return ERR_PTR(-EINVAL);
+       }
+       phy_parse_property(xsphy, inst);
++      phy_type_set(inst);
+       return inst->phy;
+ }
+@@ -510,6 +589,10 @@ static int mtk_xsphy_probe(struct platfo
+                       dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
+                       return PTR_ERR(inst->ref_clk);
+               }
++
++              retval = phy_type_syscon_get(inst, child_np);
++              if (retval)
++                      return retval;
+       }
+       provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
diff --git a/target/linux/mediatek/patches-6.12/051-v6.16-hwrng-mtk-Add-struct-device-pointer-to-device-contex.patch b/target/linux/mediatek/patches-6.12/051-v6.16-hwrng-mtk-Add-struct-device-pointer-to-device-contex.patch
new file mode 100644 (file)
index 0000000..70c771d
--- /dev/null
@@ -0,0 +1,60 @@
+From f9c0c36eefaa8c6ee224634bf9c0b8b4ed87b43a Mon Sep 17 00:00:00 2001
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+Date: Thu, 10 Apr 2025 18:22:38 +0300
+Subject: [PATCH] hwrng: mtk - Add struct device pointer to device context struct
+
+Add a struct device pointer field to the device's context struct. This
+makes using the unsigned long priv pointer in struct hwrng unnecessary, so
+remove that one as well.
+
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/char/hw_random/mtk-rng.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/char/hw_random/mtk-rng.c
++++ b/drivers/char/hw_random/mtk-rng.c
+@@ -36,6 +36,7 @@ struct mtk_rng {
+       void __iomem *base;
+       struct clk *clk;
+       struct hwrng rng;
++      struct device *dev;
+ };
+ static int mtk_rng_init(struct hwrng *rng)
+@@ -85,7 +86,7 @@ static int mtk_rng_read(struct hwrng *rn
+       struct mtk_rng *priv = to_mtk_rng(rng);
+       int retval = 0;
+-      pm_runtime_get_sync((struct device *)priv->rng.priv);
++      pm_runtime_get_sync(priv->dev);
+       while (max >= sizeof(u32)) {
+               if (!mtk_rng_wait_ready(rng, wait))
+@@ -97,8 +98,8 @@ static int mtk_rng_read(struct hwrng *rn
+               max -= sizeof(u32);
+       }
+-      pm_runtime_mark_last_busy((struct device *)priv->rng.priv);
+-      pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv);
++      pm_runtime_mark_last_busy(priv->dev);
++      pm_runtime_put_sync_autosuspend(priv->dev);
+       return retval || !wait ? retval : -EIO;
+ }
+@@ -112,13 +113,13 @@ static int mtk_rng_probe(struct platform
+       if (!priv)
+               return -ENOMEM;
++      priv->dev = &pdev->dev;
+       priv->rng.name = pdev->name;
+ #ifndef CONFIG_PM
+       priv->rng.init = mtk_rng_init;
+       priv->rng.cleanup = mtk_rng_cleanup;
+ #endif
+       priv->rng.read = mtk_rng_read;
+-      priv->rng.priv = (unsigned long)&pdev->dev;
+       priv->rng.quality = 900;
+       priv->clk = devm_clk_get(&pdev->dev, "rng");
diff --git a/target/linux/mediatek/patches-6.12/060-v6.13-mmc-mtk-sd-add-support-for-mt7988.patch b/target/linux/mediatek/patches-6.12/060-v6.13-mmc-mtk-sd-add-support-for-mt7988.patch
new file mode 100644 (file)
index 0000000..126ae5f
--- /dev/null
@@ -0,0 +1,28 @@
+From de6840095f8ed542308279c4f24fa42ba27c2dd3 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sat, 12 Oct 2024 16:38:23 +0200
+Subject: [PATCH] mmc: mtk-sd: add support for mt7988
+
+Add support for mmc on MT7988 SoC.
+
+We can use mt7986 platform data in driver, but mt7988 needs different
+clocks so for binding we need own compatible.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Message-ID: <20241012143826.7690-3-linux@fw-web.de>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -631,6 +631,7 @@ static const struct of_device_id msdc_of
+       { .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat},
+       { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
+       { .compatible = "mediatek,mt7986-mmc", .data = &mt7986_compat},
++      { .compatible = "mediatek,mt7988-mmc", .data = &mt7986_compat},
+       { .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat},
+       { .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat},
+       { .compatible = "mediatek,mt8183-mmc", .data = &mt8183_compat},
diff --git a/target/linux/mediatek/patches-6.12/061-v6.19-arm64-dts-mediatek-mt7986-bpi-r3-Change-fan-PWM-valu.patch b/target/linux/mediatek/patches-6.12/061-v6.19-arm64-dts-mediatek-mt7986-bpi-r3-Change-fan-PWM-valu.patch
new file mode 100644 (file)
index 0000000..4b27031
--- /dev/null
@@ -0,0 +1,72 @@
+From 5f271fe1365b63f67fc384ca8d50d473d09de0d1 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Date: Tue, 3 Dec 2024 07:33:55 +0300
+Subject: [PATCH] arm64: dts: mediatek: mt7986-bpi-r3: Change fan PWM value for
+ mid speed
+
+Popular cheap PWM fans for this machine, like the ones coming in
+heatsink+fan combos will not work properly at the currently defined
+medium speed. Trying different pwm setting using a command
+
+  echo $value > /sys/devices/platform/pwm-fan/hwmon/hwmon1/pwm1
+
+I found:
+
+  pwm1 value     fan rotation speed   cpu temperature     notes
+  -----------------------------------------------------------------
+    0            maximal              31.5 Celsius        too noisy
+   40            optimal              35.2 Celsius        no noise hearable
+   95            minimal
+   above 95      does not rotate      55.5 Celsius
+  -----------------------------------------------------------------
+
+Thus only cpu-active-high and cpu-active-low modes are usable.
+I think this is wrong.
+
+This patch fixes cpu-active-medium settings for bpi-r3 board.
+
+I know, the patch is not ideal as it can break pwm fan for some users.
+Likely this is the only official mt7986-bpi-r3 heatsink+fan solution
+available on the market.
+
+This patch may not be enough. Users may wants to tweak their thermal_zone0
+trip points, thus tuning fan rotation speed depending on cpu temperature.
+That can be done on the base of the following example:
+
+  === example =========
+  # cpu temperature below 25 Celsius degrees, no rotation
+  echo 25000 > /sys/class/thermal/thermal_zone0/trip_point_4_temp
+  # cpu temperature in [25..32] Celsius degrees, normal rotation speed
+  echo 32000 > /sys/class/thermal/thermal_zone0/trip_point_3_temp
+  # cpu temperature above 50 Celsius degrees, max rotation speed
+  echo 50000 > /sys/class/thermal/thermal_zone0/trip_point_2_temp
+  =====================
+
+Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
+Acked-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+---
+Changes from v1 to v2:
+ * improve patch description
+
+Changes from v2 to v3:
+ * added question to Frank Wunderlich
+
+Changes from v3 to v4:
+ * Acked by Frank Wunderlich
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -42,7 +42,7 @@
+               compatible = "pwm-fan";
+               #cooling-cells = <2>;
+               /* cooling level (0, 1, 2) - pwm inverted */
+-              cooling-levels = <255 96 0>;
++              cooling-levels = <255 40 0>;
+               pwms = <&pwm 0 10000>;
+               status = "okay";
+       };
diff --git a/target/linux/mediatek/patches-6.12/062-v6.18-arm64-dts-mediatek-add-thermal-sensor-support-on-mt7.patch b/target/linux/mediatek/patches-6.12/062-v6.18-arm64-dts-mediatek-add-thermal-sensor-support-on-mt7.patch
new file mode 100644 (file)
index 0000000..444c64d
--- /dev/null
@@ -0,0 +1,69 @@
+From 0da6f7a0ab5322eb6d091a9c89d799adfeae078d Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2@wp.pl>
+Date: Sun, 7 Sep 2025 13:15:09 +0200
+Subject: [PATCH] arm64: dts: mediatek: add thermal sensor support on mt7981
+
+The temperature sensor in the MT7981 is same as in the MT7986.
+
+Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250907111742.23195-2-olek2@wp.pl
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 31 ++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
+@@ -76,7 +76,7 @@
+                       #reset-cells = <1>;
+               };
+-              clock-controller@1001e000 {
++              apmixedsys: clock-controller@1001e000 {
+                       compatible = "mediatek,mt7981-apmixedsys";
+                       reg = <0 0x1001e000 0 0x1000>;
+                       #clock-cells = <1>;
+@@ -184,6 +184,31 @@
+                       status = "disabled";
+               };
++              thermal@1100c800 {
++                      compatible = "mediatek,mt7981-thermal",
++                                   "mediatek,mt7986-thermal";
++                      reg = <0 0x1100c800 0 0x800>;
++                      interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_THERM_CK>,
++                               <&infracfg CLK_INFRA_ADC_26M_CK>;
++                      clock-names = "therm", "auxadc";
++                      nvmem-cells = <&thermal_calibration>;
++                      nvmem-cell-names = "calibration-data";
++                      #thermal-sensor-cells = <1>;
++                      mediatek,auxadc = <&auxadc>;
++                      mediatek,apmixedsys = <&apmixedsys>;
++              };
++
++              auxadc: adc@1100d000 {
++                      compatible = "mediatek,mt7981-auxadc",
++                                   "mediatek,mt7986-auxadc";
++                      reg = <0 0x1100d000 0 0x1000>;
++                      clocks = <&infracfg CLK_INFRA_ADC_26M_CK>;
++                      clock-names = "main";
++                      #io-channel-cells = <1>;
++                      status = "disabled";
++              };
++
+               pio: pinctrl@11d00000 {
+                       compatible = "mediatek,mt7981-pinctrl";
+                       reg = <0 0x11d00000 0 0x1000>,
+@@ -211,6 +236,10 @@
+                       reg = <0 0x11f20000 0 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
++
++                      thermal_calibration: thermal-calib@274 {
++                              reg = <0x274 0xc>;
++                      };
+               };
+               clock-controller@15000000 {
diff --git a/target/linux/mediatek/patches-6.12/070-v7.0-pinctrl-mediatek-enable-ies_present-flag-for-MT798x.patch b/target/linux/mediatek/patches-6.12/070-v7.0-pinctrl-mediatek-enable-ies_present-flag-for-MT798x.patch
new file mode 100644 (file)
index 0000000..4726373
--- /dev/null
@@ -0,0 +1,59 @@
+From 6da9f0cc2717158857f8b8b9369523d0d6770c07 Mon Sep 17 00:00:00 2001
+From: Shiji Yang <yangshiji66@outlook.com>
+Date: Sat, 17 Jan 2026 11:04:37 +0800
+Subject: [PATCH] pinctrl: mediatek: enable ies_present flag for MT798x
+
+The MT798x series SoCs have IES regiter definitions. I think we
+must enable the ies_present flag to correctly configure the pin
+input mode.
+
+Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
+Signed-off-by: Linus Walleij <linusw@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7981.c | 2 +-
+ drivers/pinctrl/mediatek/pinctrl-mt7986.c | 4 ++--
+ drivers/pinctrl/mediatek/pinctrl-mt7988.c | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+@@ -1019,7 +1019,7 @@ static struct mtk_pin_soc mt7981_data =
+       .nfuncs = ARRAY_SIZE(mt7981_functions),
+       .eint_hw = &mt7981_eint_hw,
+       .gpio_m = 0,
+-      .ies_present = false,
++      .ies_present = true,
+       .base_names = mt7981_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
+       .bias_disable_set = mtk_pinconf_bias_disable_set,
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+@@ -919,7 +919,7 @@ static struct mtk_pin_soc mt7986a_data =
+       .nfuncs = ARRAY_SIZE(mt7986_functions),
+       .eint_hw = &mt7986a_eint_hw,
+       .gpio_m = 0,
+-      .ies_present = false,
++      .ies_present = true,
+       .base_names = mt7986_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+       .bias_disable_set = mtk_pinconf_bias_disable_set,
+@@ -945,7 +945,7 @@ static struct mtk_pin_soc mt7986b_data =
+       .nfuncs = ARRAY_SIZE(mt7986_functions),
+       .eint_hw = &mt7986b_eint_hw,
+       .gpio_m = 0,
+-      .ies_present = false,
++      .ies_present = true,
+       .base_names = mt7986_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+       .bias_disable_set = mtk_pinconf_bias_disable_set,
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7988.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c
+@@ -1515,7 +1515,7 @@ static const struct mtk_pin_soc mt7988_d
+       .nfuncs = ARRAY_SIZE(mt7988_functions),
+       .eint_hw = &mt7988_eint_hw,
+       .gpio_m = 0,
+-      .ies_present = false,
++      .ies_present = true,
+       .base_names = mt7988_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names),
+       .bias_disable_set = mtk_pinconf_bias_disable_set,
diff --git a/target/linux/mediatek/patches-6.12/100-dts-update-mt7622-rfb1.patch b/target/linux/mediatek/patches-6.12/100-dts-update-mt7622-rfb1.patch
new file mode 100644 (file)
index 0000000..311e629
--- /dev/null
@@ -0,0 +1,130 @@
+From c46ccb69d17e584479df849a107423175a143c83 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 24 Oct 2020 21:15:20 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7622-rfb1: update copyright, fix bootargs and GPIO polarity
+
+Update the copyright header, add an explicit console= argument to the
+chosen/bootargs property, and fix the GPIO polarity flags on the
+factory and WPS button keys to use GPIO_ACTIVE_LOW.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -1,7 +1,6 @@
+ /*
+- * Copyright (c) 2017 MediaTek Inc.
+- * Author: Ming Huang <ming.huang@mediatek.com>
+- *       Sean Wang <sean.wang@mediatek.com>
++ * Copyright (c) 2018 MediaTek Inc.
++ * Author: Ryder Lee <ryder.lee@mediatek.com>
+  *
+  * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+  */
+@@ -24,7 +23,7 @@
+       chosen {
+               stdout-path = "serial0:115200n8";
+-              bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
++              bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
+       };
+       cpus {
+@@ -45,18 +44,18 @@
+               key-factory {
+                       label = "factory";
+                       linux,code = <BTN_0>;
+-                      gpios = <&pio 0 0>;
++                      gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+               };
+               key-wps {
+                       label = "wps";
+                       linux,code = <KEY_WPS_BUTTON>;
+-                      gpios = <&pio 102 0>;
++                      gpios = <&pio 102 GPIO_ACTIVE_LOW>;
+               };
+       };
+       memory@40000000 {
+-              reg = <0 0x40000000 0 0x20000000>;
++              reg = <0 0x40000000 0 0x40000000>;
+               device_type = "memory";
+       };
+@@ -134,9 +133,9 @@
+               #address-cells = <1>;
+               #size-cells = <0>;
+-              switch@0 {
++              switch@1f {
+                       compatible = "mediatek,mt7531";
+-                      reg = <0>;
++                      reg = <31>;
+                       reset-gpios = <&pio 54 0>;
+                       ports {
+@@ -145,22 +144,22 @@
+                               port@0 {
+                                       reg = <0>;
+-                                      label = "lan0";
++                                      label = "lan1";
+                               };
+                               port@1 {
+                                       reg = <1>;
+-                                      label = "lan1";
++                                      label = "lan2";
+                               };
+                               port@2 {
+                                       reg = <2>;
+-                                      label = "lan2";
++                                      label = "lan3";
+                               };
+                               port@3 {
+                                       reg = <3>;
+-                                      label = "lan3";
++                                      label = "lan4";
+                               };
+                               port@4 {
+@@ -264,7 +263,22 @@
+       status = "okay";
+ };
++&pcie1 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pcie1_pins>;
++      status = "okay";
++};
++
+ &pio {
++      /* Attention: GPIO 90 is used to switch between PCIe@1,0 and
++       * SATA functions. i.e. output-high: PCIe, output-low: SATA
++       */
++      asm_sel {
++              gpio-hog;
++              gpios = <90 GPIO_ACTIVE_HIGH>;
++              output-high;
++      };
++
+       /* eMMC is shared pin with parallel NAND */
+       emmc_pins_default: emmc-pins-default {
+               mux {
+@@ -541,11 +555,11 @@
+ };
+ &sata {
+-      status = "okay";
++      status = "disabled";
+ };
+ &sata_phy {
+-      status = "okay";
++      status = "disabled";
+ };
+ &spi0 {
diff --git a/target/linux/mediatek/patches-6.12/101-dts-update-mt7629-rfb.patch b/target/linux/mediatek/patches-6.12/101-dts-update-mt7629-rfb.patch
new file mode 100644 (file)
index 0000000..058b707
--- /dev/null
@@ -0,0 +1,73 @@
+From c46ccb69d17e584479df849a107423175a143c83 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 24 Oct 2020 21:15:20 +0200
+Subject: [PATCH] arm: dts: mediatek: mt7629-rfb: add earlycon/console bootargs and MAC address nvmem cells
+
+Add earlycon= and console= to chosen/bootargs, and wire the two Ethernet
+MACs (gmac0, gmac1) to their respective MAC address stored in the factory
+partition via nvmem-cells.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/arch/arm/boot/dts/mediatek/mt7629-rfb.dts
++++ b/arch/arm/boot/dts/mediatek/mt7629-rfb.dts
+@@ -18,6 +18,7 @@
+       chosen {
+               stdout-path = "serial0:115200n8";
++              bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8";
+       };
+       gpio-keys {
+@@ -70,6 +71,10 @@
+               compatible = "mediatek,eth-mac";
+               reg = <0>;
+               phy-mode = "2500base-x";
++
++              nvmem-cells = <&macaddr_factory_2a>;
++              nvmem-cell-names = "mac-address";
++
+               fixed-link {
+                       speed = <2500>;
+                       full-duplex;
+@@ -82,6 +87,9 @@
+               reg = <1>;
+               phy-mode = "gmii";
+               phy-handle = <&phy0>;
++
++              nvmem-cells = <&macaddr_factory_24>;
++              nvmem-cell-names = "mac-address";
+       };
+       mdio: mdio-bus {
+@@ -133,8 +141,9 @@
+                       };
+                       partition@b0000 {
+-                              label = "kernel";
++                              label = "firmware";
+                               reg = <0xb0000 0xb50000>;
++                              compatible = "denx,fit";
+                       };
+               };
+       };
+@@ -273,3 +282,19 @@
+       pinctrl-0 = <&watchdog_pins>;
+       status = "okay";
+ };
++
++&factory {
++      nvmem-layout {
++              compatible = "fixed-layout";
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              macaddr_factory_24: macaddr@24 {
++                      reg = <0x24 0x6>;
++              };
++
++              macaddr_factory_2a: macaddr@2a {
++                      reg = <0x2a 0x6>;
++              };
++      };
++};
diff --git a/target/linux/mediatek/patches-6.12/103-mt7623-enable-arch-timer.patch b/target/linux/mediatek/patches-6.12/103-mt7623-enable-arch-timer.patch
new file mode 100644 (file)
index 0000000..04df7b9
--- /dev/null
@@ -0,0 +1,20 @@
+From d6a596012150960f0f3a214d31bbac4b607dbd1e Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Fri, 29 Apr 2022 10:40:56 +0800
+Subject: [PATCH] arm: mediatek: select arch timer for mt7623
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ arch/arm/mach-mediatek/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/mach-mediatek/Kconfig
++++ b/arch/arm/mach-mediatek/Kconfig
+@@ -26,6 +26,7 @@ config MACH_MT6592
+ config MACH_MT7623
+       bool "MediaTek MT7623 SoCs support"
+       default ARCH_MEDIATEK
++      select HAVE_ARM_ARCH_TIMER
+ config MACH_MT7629
+       bool "MediaTek MT7629 SoCs support"
diff --git a/target/linux/mediatek/patches-6.12/104-mt7622-add-snor-irq.patch b/target/linux/mediatek/patches-6.12/104-mt7622-add-snor-irq.patch
new file mode 100644 (file)
index 0000000..1150758
--- /dev/null
@@ -0,0 +1,20 @@
+From 99cd44487e2e7205e1521a52faf498dfda6f100c Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Sat, 30 Apr 2022 20:24:07 +0800
+Subject: [PATCH] mediatek: mt7622: add irq for spi-nor controller
+
+Save some CPU from unnecessary polling and make SPI flash reading
+a tiny bit faster.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -575,6 +575,7 @@
+               compatible = "mediatek,mt7622-nor",
+                            "mediatek,mt8173-nor";
+               reg = <0 0x11014000 0 0xe0>;
++              interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_LOW>;
+               clocks = <&pericfg CLK_PERI_FLASH_PD>,
+                        <&topckgen CLK_TOP_FLASH_SEL>;
+               clock-names = "spi", "sf";
diff --git a/target/linux/mediatek/patches-6.12/105-dts-mt7622-enable-pstore.patch b/target/linux/mediatek/patches-6.12/105-dts-mt7622-enable-pstore.patch
new file mode 100644 (file)
index 0000000..04aff0d
--- /dev/null
@@ -0,0 +1,26 @@
+From e1adb1fa39dd5ef97280ad1b2bb9e8ff4c43674f Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 7 May 2021 16:53:09 +0100
+Subject: [PATCH] arm64: dts: mediatek: mt7622: reserve memory for ramoops/pstore
+
+Reserve 64KiB of memory for crashlogs and enable PSTORE feature in
+kernel config for MT7622.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -135,6 +135,13 @@
+               #size-cells = <2>;
+               ranges;
++              /* 64 KiB reserved for ramoops/pstore */
++              ramoops@42ff0000 {
++                      compatible = "ramoops";
++                      reg = <0 0x42ff0000 0 0x10000>;
++                      record-size = <0x1000>;
++              };
++
+               /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+               secmon_reserved: secmon@43000000 {
+                       reg = <0 0x43000000 0 0x30000>;
diff --git a/target/linux/mediatek/patches-6.12/106-dts-mt7622-disable_btif.patch b/target/linux/mediatek/patches-6.12/106-dts-mt7622-disable_btif.patch
new file mode 100644 (file)
index 0000000..9faf83d
--- /dev/null
@@ -0,0 +1,35 @@
+From 50416c18dd309fec75b6911221905cd0c0139b25 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 21 Dec 2023 21:20:17 +0100
+Subject: [PATCH] mediatek: disable btif for mt7622 devices
+
+It breaks built-in SoC WLAN. Can be re-enabled after we've figured out the cause
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -109,10 +109,6 @@
+       status = "disabled";
+ };
+-&btif {
+-      status = "okay";
+-};
+-
+ &cir {
+       pinctrl-names = "default";
+       pinctrl-0 = <&irrx_pins>;
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -90,10 +90,6 @@
+       status = "disabled";
+ };
+-&btif {
+-      status = "okay";
+-};
+-
+ &cir {
+       pinctrl-names = "default";
+       pinctrl-0 = <&irrx_pins>;
diff --git a/target/linux/mediatek/patches-6.12/110-dts-fix-bpi2-console.patch b/target/linux/mediatek/patches-6.12/110-dts-fix-bpi2-console.patch
new file mode 100644 (file)
index 0000000..2b5b806
--- /dev/null
@@ -0,0 +1,20 @@
+From 25d9df670b850a4e3702e084ff249baa1670ae3f Mon Sep 17 00:00:00 2001
+From: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+Date: Mon, 10 Feb 2020 09:33:15 +0100
+Subject: [PATCH] arm: dts: mediatek: mt7623n-bpi-r2: add console= to bootargs
+
+Add an explicit console=ttyS2,115200n8 argument to the chosen/bootargs
+property so that a serial console is available during early boot.
+
+Signed-off-by: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+---
+--- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
+@@ -19,6 +19,7 @@
+       chosen {
+               stdout-path = "serial2:115200n8";
++              bootargs = "console=ttyS2,115200n8 console=tty1";
+       };
+       connector {
diff --git a/target/linux/mediatek/patches-6.12/111-dts-fix-bpi64-console.patch b/target/linux/mediatek/patches-6.12/111-dts-fix-bpi64-console.patch
new file mode 100644 (file)
index 0000000..9d0c2d3
--- /dev/null
@@ -0,0 +1,21 @@
+From 25d9df670b850a4e3702e084ff249baa1670ae3f Mon Sep 17 00:00:00 2001
+From: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+Date: Mon, 10 Feb 2020 09:33:15 +0100
+Subject: [PATCH] arm64: dts: mediatek: mt7622-bpi-r64: add console= to bootargs
+
+Add an explicit console=ttyS0,115200n1 argument to the chosen/bootargs
+property so that a serial console is available during early boot.
+
+Signed-off-by: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -24,7 +24,7 @@
+       chosen {
+               stdout-path = "serial0:115200n8";
+-              bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
++              bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
+       };
+       cpus {
diff --git a/target/linux/mediatek/patches-6.12/112-dts-fix-bpi64-lan-names.patch b/target/linux/mediatek/patches-6.12/112-dts-fix-bpi64-lan-names.patch
new file mode 100644 (file)
index 0000000..b94701e
--- /dev/null
@@ -0,0 +1,48 @@
+From dfa0a38d1f4d5bbac768569e3769ae4438a57e73 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 27 Feb 2021 14:17:09 +0000
+Subject: [PATCH] arm64: dts: mediatek: mt7622-bpi-r64: fix LAN port numbering and add ethernet alias
+
+Renumber the switch LAN port labels from lan0/lan1/lan2 to lan1/lan2/lan3
+to match the silkscreen labelling on the board, and add an ethernet0 alias
+pointing to gmac0.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -20,6 +20,7 @@
+       aliases {
+               serial0 = &uart0;
++              ethernet0 = &gmac0;
+       };
+       chosen {
+@@ -164,22 +165,22 @@
+                               port@1 {
+                                       reg = <1>;
+-                                      label = "lan0";
++                                      label = "lan1";
+                               };
+                               port@2 {
+                                       reg = <2>;
+-                                      label = "lan1";
++                                      label = "lan2";
+                               };
+                               port@3 {
+                                       reg = <3>;
+-                                      label = "lan2";
++                                      label = "lan3";
+                               };
+                               port@4 {
+                                       reg = <4>;
+-                                      label = "lan3";
++                                      label = "lan4";
+                               };
+                               port@5 {
diff --git a/target/linux/mediatek/patches-6.12/113-dts-fix-bpi64-leds-and-buttons.patch b/target/linux/mediatek/patches-6.12/113-dts-fix-bpi64-leds-and-buttons.patch
new file mode 100644 (file)
index 0000000..722c8ef
--- /dev/null
@@ -0,0 +1,61 @@
+From dfa0a38d1f4d5bbac768569e3769ae4438a57e73 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 27 Feb 2021 14:17:09 +0000
+Subject: [PATCH] arm64: dts: mediatek: mt7622-bpi-r64: add LED aliases, fix button labels and MMC aliases
+
+Add led-boot/led-failsafe/led-running/led-upgrade aliases pointing to
+the system LEDs, add mmc0/mmc1 aliases for correct MMC device ordering,
+rename the factory button to "reset" with KEY_RESTART, and update the
+LED gpio-hog and label names to match their physical function.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -21,6 +21,12 @@
+       aliases {
+               serial0 = &uart0;
+               ethernet0 = &gmac0;
++              led-boot = &led_system_green;
++              led-failsafe = &led_system_blue;
++              led-running = &led_system_green;
++              led-upgrade = &led_system_blue;
++              mmc0 = &mmc0;
++              mmc1 = &mmc1;
+       };
+       chosen {
+@@ -44,8 +50,8 @@
+               compatible = "gpio-keys";
+               factory-key {
+-                      label = "factory";
+-                      linux,code = <BTN_0>;
++                      label = "reset";
++                      linux,code = <KEY_RESTART>;
+                       gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
+               };
+@@ -59,17 +65,17 @@
+       leds {
+               compatible = "gpio-leds";
+-              led-0 {
++              led_system_green: led-0 {
+                       label = "bpi-r64:pio:green";
+                       color = <LED_COLOR_ID_GREEN>;
+                       gpios = <&pio 89 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+-              led-1 {
+-                      label = "bpi-r64:pio:red";
+-                      color = <LED_COLOR_ID_RED>;
+-                      gpios = <&pio 88 GPIO_ACTIVE_HIGH>;
++              led_system_blue: led-1 {
++                      label = "bpi-r64:pio:blue";
++                      color = <LED_COLOR_ID_BLUE>;
++                      gpios = <&pio 85 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+       };
diff --git a/target/linux/mediatek/patches-6.12/114-dts-bpi64-disable-rtc.patch b/target/linux/mediatek/patches-6.12/114-dts-bpi64-disable-rtc.patch
new file mode 100644 (file)
index 0000000..caf969d
--- /dev/null
@@ -0,0 +1,24 @@
+From 8dd0215676a304456d25ff3ac4542c7303831a90 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 6 Mar 2021 18:38:30 +0000
+Subject: [PATCH] mediatek: disable RTC on Bananapi R64
+
+The in-SoC RTC of the Bananapi R64 is more disruptive than useful
+without a battery connected. Disable it to not have Linux use the
+RTC provided time 2000-01-01 00:00:00 after power-loss.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -599,6 +599,10 @@
+       status = "okay";
+ };
++&rtc {
++      status = "disabled";
++};
++
+ &sata {
+       status = "disabled";
+ };
diff --git a/target/linux/mediatek/patches-6.12/115-Revert-arm64-dts-mediatek-fix-t-phy-unit-name.patch b/target/linux/mediatek/patches-6.12/115-Revert-arm64-dts-mediatek-fix-t-phy-unit-name.patch
new file mode 100644 (file)
index 0000000..1d53cef
--- /dev/null
@@ -0,0 +1,33 @@
+From 4c4baed29b168e9bf39545a945a9523ea280cb44 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 1 Feb 2025 04:24:17 +0000
+Subject: [PATCH 1/2] Revert "arm64: dts: mediatek: fix t-phy unit name"
+
+This reverts commit 963c3b0c47ec29b4c49c9f45965cd066f419d17f.
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi  | 2 +-
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -908,7 +908,7 @@
+               status = "disabled";
+       };
+-      sata_phy: t-phy {
++      sata_phy: t-phy@1a243000 {
+               compatible = "mediatek,mt7622-tphy",
+                            "mediatek,generic-tphy-v1";
+               #address-cells = <2>;
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -428,7 +428,7 @@
+                       };
+               };
+-              pcie_phy: t-phy {
++              pcie_phy: t-phy@11c00000 {
+                       compatible = "mediatek,mt7986-tphy",
+                                    "mediatek,generic-tphy-v2";
+                       ranges;
diff --git a/target/linux/mediatek/patches-6.12/116-arm64-dts-mediatek-mt7622-readd-syscon-to-pciesys-no.patch b/target/linux/mediatek/patches-6.12/116-arm64-dts-mediatek-mt7622-readd-syscon-to-pciesys-no.patch
new file mode 100644 (file)
index 0000000..4ae72fd
--- /dev/null
@@ -0,0 +1,33 @@
+From 98bc223d174c7f544e8f6c4f0caa8fa144f2f4dc Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 28 Jun 2024 12:55:40 +0200
+Subject: [PATCH 2/2] arm64: dts: mediatek: mt7622: readd syscon to pciesys
+ node
+
+Sata node reference the pciesys with the property mediatek,phy-node
+and that is used as a syscon to access the pciesys regs.
+
+Readd the syscon compatible to pciesys node to restore correct
+functionality of the SATA interface.
+
+Fixes: 3ba5a6159434 ("arm64: dts: mediatek: mt7622: fix clock controllers")
+Reported-by: Frank Wunderlich <frank-w@public-files.de>
+Co-developed-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Cc: stable@vger.kernel.org
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -798,7 +798,7 @@
+       };
+       pciesys: clock-controller@1a100800 {
+-              compatible = "mediatek,mt7622-pciesys";
++              compatible = "mediatek,mt7622-pciesys", "syscon";
+               reg = <0 0x1a100800 0 0x1000>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
diff --git a/target/linux/mediatek/patches-6.12/117-complete-mt7981b-dtsi.patch b/target/linux/mediatek/patches-6.12/117-complete-mt7981b-dtsi.patch
new file mode 100644 (file)
index 0000000..51305b9
--- /dev/null
@@ -0,0 +1,657 @@
+From 3986156b3ba97a9c280f4dfe0efbccf52e1fc488 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 28 Dec 2022 23:44:42 +0000
+Subject: [PATCH] complete mt7981 dts
+
+working:
+ * Ethernet (fully working incl. ppe)
+ * UART
+ * SPI-NAND flash
+ * thermal sensors (SoC and mxl-gpy)
+ * random number generator via SMC
+ * USB 1.1, 2.0 and 3.0
+ * WiFi with MT7976C 2.4G+5G DBDC incl. WED offloading
+ * PWM
+
+--- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
+@@ -1,7 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0-only OR MIT
+ #include <dt-bindings/clock/mediatek,mt7981-clk.h>
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/linux-event-codes.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/mux/mux.h>
++#include <dt-bindings/pinctrl/mt65xx.h>
++#include <dt-bindings/phy/phy.h>
+ #include <dt-bindings/reset/mt7986-resets.h>
+ / {
+@@ -41,6 +48,57 @@
+               method = "smc";
+       };
++      fan: pwm-fan {
++              compatible = "pwm-fan";
++              /* cooling level (0, 1, 2, 3) : (0% duty, 50% duty, 75% duty, 100% duty) */
++              cooling-levels = <0 128 192 255>;
++              #cooling-cells = <2>;
++              status = "disabled";
++      };
++
++      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;
++      };
++
++      reserved-memory {
++              #address-cells = <2>;
++              #size-cells = <2>;
++              ranges;
++
++              /* 64 KiB reserved for ramoops/pstore */
++              ramoops@42ff0000 {
++                      compatible = "ramoops";
++                      reg = <0 0x42ff0000 0 0x10000>;
++                      record-size = <0x1000>;
++              };
++
++              /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
++              secmon_reserved: secmon@43000000 {
++                      reg = <0 0x43000000 0 0x30000>;
++                      no-map;
++              };
++
++              wmcpu_emi: wmcpu-reserved@47c80000 {
++                      reg = <0 0x47c80000 0 0x100000>;
++                      no-map;
++              };
++
++              wo_emi0: wo-emi@47d80000 {
++                      reg = <0 0x47d80000 0 0x40000>;
++                      no-map;
++              };
++
++              wo_data: wo-data@47dc0000 {
++                      reg = <0 0x47dc0000 0 0x240000>;
++                      no-map;
++              };
++      };
++
+       soc {
+               compatible = "simple-bus";
+               ranges;
+@@ -77,12 +135,12 @@
+               };
+               apmixedsys: clock-controller@1001e000 {
+-                      compatible = "mediatek,mt7981-apmixedsys";
++                      compatible = "mediatek,mt7981-apmixedsys", "syscon";
+                       reg = <0 0x1001e000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+-              pwm@10048000 {
++              pwm: pwm@10048000 {
+                       compatible = "mediatek,mt7981-pwm";
+                       reg = <0 0x10048000 0 0x1000>;
+                       clocks = <&infracfg CLK_INFRA_PWM_STA>,
+@@ -94,7 +152,21 @@
+                       #pwm-cells = <2>;
+               };
+-              serial@11002000 {
++              crypto: crypto@10320000 {
++                      compatible = "inside-secure,safexcel-eip97";
++                      reg = <0 0x10320000 0 0x40000>;
++                      interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "ring0", "ring1", "ring2", "ring3";
++                      clocks = <&topckgen CLK_TOP_EIP97B>;
++                      clock-names = "top_eip97_ck";
++                      assigned-clocks = <&topckgen CLK_TOP_EIP97B_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_CB_NET1_D5>;
++              };
++
++              uart0: serial@11002000 {
+                       compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart";
+                       reg = <0 0x11002000 0 0x100>;
+                       interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+@@ -105,7 +177,7 @@
+                       status = "disabled";
+               };
+-              serial@11003000 {
++              uart1: serial@11003000 {
+                       compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart";
+                       reg = <0 0x11003000 0 0x100>;
+                       interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+@@ -116,7 +188,7 @@
+                       status = "disabled";
+               };
+-              serial@11004000 {
++              uart2: serial@11004000 {
+                       compatible = "mediatek,mt7981-uart", "mediatek,mt6577-uart";
+                       reg = <0 0x11004000 0 0x100>;
+                       interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+@@ -127,11 +199,12 @@
+                       status = "disabled";
+               };
+-              i2c@11007000 {
++              i2c0: i2c@11007000 {
+                       compatible = "mediatek,mt7981-i2c";
+                       reg = <0 0x11007000 0 0x1000>,
+                             <0 0x10217080 0 0x80>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
++                      clock-div = <1>;
+                       clocks = <&infracfg CLK_INFRA_I2C0_CK>,
+                                <&infracfg CLK_INFRA_AP_DMA_CK>,
+                                <&infracfg CLK_INFRA_I2C_MCK_CK>,
+@@ -142,7 +215,7 @@
+                       status = "disabled";
+               };
+-              spi@11009000 {
++              spi2: spi@11009000 {
+                       compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm";
+                       reg = <0 0x11009000 0 0x1000>;
+                       interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+@@ -156,7 +229,7 @@
+                       status = "disabled";
+               };
+-              spi@1100a000 {
++              spi0: spi@1100a000 {
+                       compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm";
+                       reg = <0 0x1100a000 0 0x1000>;
+                       interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+@@ -170,7 +243,7 @@
+                       status = "disabled";
+               };
+-              spi@1100b000 {
++              spi1: spi@1100b000 {
+                       compatible = "mediatek,mt7981-spi-ipm", "mediatek,spi-ipm";
+                       reg = <0 0x1100b000 0 0x1000>;
+                       interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+@@ -184,7 +257,7 @@
+                       status = "disabled";
+               };
+-              thermal@1100c800 {
++              thermal: thermal@1100c800 {
+                       compatible = "mediatek,mt7981-thermal",
+                                    "mediatek,mt7986-thermal";
+                       reg = <0 0x1100c800 0 0x800>;
+@@ -201,12 +274,48 @@
+               auxadc: adc@1100d000 {
+                       compatible = "mediatek,mt7981-auxadc",
+-                                   "mediatek,mt7986-auxadc";
++                                   "mediatek,mt7986-auxadc",
++                                   "mediatek,mt7622-auxadc";
+                       reg = <0 0x1100d000 0 0x1000>;
+-                      clocks = <&infracfg CLK_INFRA_ADC_26M_CK>;
+-                      clock-names = "main";
++                      clocks = <&infracfg CLK_INFRA_ADC_26M_CK>,
++                               <&infracfg CLK_INFRA_ADC_FRC_CK>;
++                      clock-names = "main", "32k";
+                       #io-channel-cells = <1>;
++              };
++
++              pcie: pcie@11280000 {
++                      compatible = "mediatek,mt7981-pcie",
++                                   "mediatek,mt8192-pcie";
++                      device_type = "pci";
++                      reg = <0 0x11280000 0 0x4000>;
++                      reg-names = "pcie-mac";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
++                      bus-range = <0x00 0xff>;
++                      ranges = <0x82000000 0 0x20000000
++                                0x0 0x20000000 0 0x10000000>;
+                       status = "disabled";
++
++                      clocks = <&infracfg CLK_INFRA_IPCIE_CK>,
++                               <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
++                               <&infracfg CLK_INFRA_IPCIER_CK>,
++                               <&infracfg CLK_INFRA_IPCIEB_CK>;
++
++                      phys = <&u3port0 PHY_TYPE_PCIE>;
++                      phy-names = "pcie-phy";
++
++                      #interrupt-cells = <1>;
++                      interrupt-map-mask = <0 0 0 7>;
++                      interrupt-map = <0 0 0 1 &pcie_intc 0>,
++                                      <0 0 0 2 &pcie_intc 1>,
++                                      <0 0 0 3 &pcie_intc 2>,
++                                      <0 0 0 4 &pcie_intc 3>;
++                      pcie_intc: interrupt-controller {
++                              interrupt-controller;
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                      };
+               };
+               pio: pinctrl@11d00000 {
+@@ -229,6 +338,35 @@
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       #interrupt-cells = <2>;
++
++                      mdio_pins: mdc-mdio-pins {
++                              mux {
++                                      function = "eth";
++                                      groups = "smi_mdc_mdio";
++                              };
++                      };
++
++                      uart0_pins: uart0-pins {
++                              mux {
++                                      function = "uart";
++                                      groups = "uart0";
++                              };
++                      };
++
++                      wifi_dbdc_pins: wifi-dbdc-pins {
++                              mux {
++                                      function = "eth";
++                                      groups = "wf0_mode1";
++                              };
++                              conf {
++                                      pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4",
++                                             "WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6",
++                                             "WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10",
++                                             "WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ",
++                                             "WF_CBA_RESETB", "WF_DIG_RESETB";
++                                      drive-strength = <MTK_DRIVE_4mA>;
++                              };
++                      };
+               };
+               efuse@11f20000 {
+@@ -240,17 +378,293 @@
+                       thermal_calibration: thermal-calib@274 {
+                               reg = <0x274 0xc>;
+                       };
++
++                      phy_calibration: phy-calib@8dc {
++                              reg = <0x8dc 0x10>;
++                      };
++
++                      comb_rx_imp_p0: usb3-rx-imp@8c8 {
++                              reg = <0x8c8 1>;
++                              bits = <0 5>;
++                      };
++
++                      comb_tx_imp_p0: usb3-tx-imp@8c8 {
++                              reg = <0x8c8 2>;
++                              bits = <5 5>;
++                      };
++
++                      comb_intr_p0: usb3-intr@8c9 {
++                              reg = <0x8c9 1>;
++                              bits = <2 6>;
++                      };
+               };
+-              clock-controller@15000000 {
++              ethsys: clock-controller@15000000 {
+                       compatible = "mediatek,mt7981-ethsys", "syscon";
+                       reg = <0 0x15000000 0 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
+-              wifi@18000000 {
++              wed: wed@15010000 {
++                      compatible = "mediatek,mt7981-wed",
++                                   "mediatek,mt7986-wed",
++                                   "syscon";
++                      reg = <0 0x15010000 0 0x1000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
++                      memory-region = <&wo_emi0>, <&wo_data>;
++                      memory-region-names = "wo-emi", "wo-data";
++                      mediatek,wo-ccif = <&wo_ccif0>;
++                      mediatek,wo-ilm = <&wo_ilm0>;
++                      mediatek,wo-dlm = <&wo_dlm0>;
++                      mediatek,wo-cpuboot = <&wo_cpuboot>;
++              };
++
++              eth: ethernet@15100000 {
++                      compatible = "mediatek,mt7981-eth";
++                      reg = <0 0x15100000 0 0x80000>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ethsys CLK_ETH_FE_EN>,
++                              <&ethsys CLK_ETH_GP2_EN>,
++                              <&ethsys CLK_ETH_GP1_EN>,
++                              <&ethsys CLK_ETH_WOCPU0_EN>,
++                              <&sgmiisys0 CLK_SGM0_TX_EN>,
++                              <&sgmiisys0 CLK_SGM0_RX_EN>,
++                              <&sgmiisys0 CLK_SGM0_CK0_EN>,
++                              <&sgmiisys0 CLK_SGM0_CDR_CK0_EN>,
++                              <&sgmiisys1 CLK_SGM1_TX_EN>,
++                              <&sgmiisys1 CLK_SGM1_RX_EN>,
++                              <&sgmiisys1 CLK_SGM1_CK1_EN>,
++                              <&sgmiisys1 CLK_SGM1_CDR_CK1_EN>,
++                              <&topckgen CLK_TOP_SGM_REG>,
++                              <&topckgen CLK_TOP_NETSYS_SEL>,
++                              <&topckgen CLK_TOP_NETSYS_500M_SEL>;
++                      clock-names = "fe", "gp2", "gp1", "wocpu0",
++                                              "sgmii_tx250m", "sgmii_rx250m",
++                                              "sgmii_cdr_ref", "sgmii_cdr_fb",
++                                              "sgmii2_tx250m", "sgmii2_rx250m",
++                                              "sgmii2_cdr_ref", "sgmii2_cdr_fb",
++                                              "sgmii_ck", "netsys0", "netsys1";
++                      assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
++                                        <&topckgen CLK_TOP_SGM_325M_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_CB_NET2_800M>,
++                                               <&topckgen CLK_TOP_CB_SGM_325M>;
++                      mediatek,ethsys = <&ethsys>;
++                      mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
++                      mediatek,infracfg = <&topmisc>;
++                      mediatek,wed = <&wed>;
++                      mediatek,wed-pcie = <&wed_pcie>;
++                      status = "disabled";
++
++                      mdio_bus: mdio-bus {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              int_gbe_phy: ethernet-phy@0 {
++                                      reg = <0>;
++                                      compatible = "ethernet-phy-ieee802.3-c22";
++                                      phy-mode = "gmii";
++                                      phy-is-integrated;
++                                      nvmem-cells = <&phy_calibration>;
++                                      nvmem-cell-names = "phy-cal-data";
++
++                                      leds {
++                                              #address-cells = <1>;
++                                              #size-cells = <0>;
++
++                                              int_gbe_phy_led0: int-gbe-phy-led0@0 {
++                                                      reg = <0>;
++                                                      function = LED_FUNCTION_LAN;
++                                                      status = "disabled";
++                                              };
++
++                                              int_gbe_phy_led1: int-gbe-phy-led1@1 {
++                                                      reg = <1>;
++                                                      function = LED_FUNCTION_LAN;
++                                                      status = "disabled";
++                                              };
++                                      };
++                              };
++                      };
++              };
++
++              wo_dlm0: syscon@151e8000 {
++                      compatible = "mediatek,mt7986-wo-dlm", "syscon";
++                      reg = <0 0x151e8000 0 0x2000>;
++              };
++
++              wo_ilm0: syscon@151e0000 {
++                      compatible = "mediatek,mt7986-wo-ilm", "syscon";
++                      reg = <0 0x151e0000 0 0x8000>;
++              };
++
++              wo_cpuboot: syscon@15194000 {
++                      compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
++                      reg = <0 0x15194000 0 0x1000>;
++              };
++
++              wo_ccif0: syscon@151a5000 {
++                      compatible = "mediatek,mt7986-wo-ccif", "syscon";
++                      reg = <0 0x151a5000 0 0x1000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
++              };
++
++              sgmiisys0: syscon@10060000 {
++                      compatible = "mediatek,mt7981-sgmiisys_0", "mediatek,mt7986-sgmiisys_0", "syscon";
++                      reg = <0 0x10060000 0 0x1000>;
++                      mediatek,pnswap;
++                      #clock-cells = <1>;
++              };
++
++              sgmiisys1: syscon@10070000 {
++                      compatible = "mediatek,mt7981-sgmiisys_1", "mediatek,mt7986-sgmiisys_1", "syscon";
++                      reg = <0 0x10070000 0 0x1000>;
++                      #clock-cells = <1>;
++              };
++
++              topmisc: topmisc@11d10000 {
++                      compatible = "mediatek,mt7981-topmisc", "syscon";
++                      reg = <0 0x11d10000 0 0x10000>;
++                      #clock-cells = <1>;
++              };
++
++              snand: snfi@11005000 {
++                      compatible = "mediatek,mt7986-snand";
++                      reg = <0 0x11005000 0 0x1000>, <0 0x11006000 0 0x1000>;
++                      reg-names = "nfi", "ecc";
++                      interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_SPINFI1_CK>,
++                               <&infracfg CLK_INFRA_NFI1_CK>,
++                               <&infracfg CLK_INFRA_NFI_HCK_CK>;
++                      clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
++                      assigned-clocks = <&topckgen CLK_TOP_SPINFI_SEL>,
++                                        <&topckgen CLK_TOP_NFI1X_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D8>,
++                                               <&topckgen CLK_TOP_CB_M_D8>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
++              mmc0: mmc@11230000 {
++                      compatible = "mediatek,mt7986-mmc",
++                                              "mediatek,mt7981-mmc";
++                      reg = <0 0x11230000 0 0x1000>, <0 0x11c20000 0 0x1000>;
++                      interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_MSDC_CK>,
++                               <&infracfg CLK_INFRA_MSDC_HCK_CK>,
++                               <&infracfg CLK_INFRA_MSDC_66M_CK>,
++                               <&infracfg CLK_INFRA_MSDC_133M_CK>;
++                      assigned-clocks = <&topckgen CLK_TOP_EMMC_208M_SEL>,
++                                        <&topckgen CLK_TOP_EMMC_400M_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
++                                               <&topckgen CLK_TOP_CB_NET2_D2>;
++                      clock-names = "source", "hclk", "axi_cg", "ahb_cg";
++                      status = "disabled";
++              };
++
++              wed_pcie: wed_pcie@10003000 {
++                      compatible = "mediatek,wed_pcie", "syscon";
++                      reg = <0 0x10003000 0 0x10>;
++              };
++
++              consys: consys@10000000 {
++                      compatible = "mediatek,mt7981-consys";
++                      reg = <0 0x10000000 0 0x8600000>;
++                      memory-region = <&wmcpu_emi>;
++              };
++
++              xhci: usb@11200000 {
++                      compatible = "mediatek,mt7986-xhci",
++                                   "mediatek,mtk-xhci";
++                      reg = <0 0x11200000 0 0x2e00>,
++                            <0 0x11203e00 0 0x0100>;
++                      reg-names = "mac", "ippc";
++                      interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>,
++                               <&infracfg CLK_INFRA_IUSB_CK>,
++                               <&infracfg CLK_INFRA_IUSB_133_CK>,
++                               <&infracfg CLK_INFRA_IUSB_66M_CK>,
++                               <&topckgen CLK_TOP_U2U3_XHCI_SEL>;
++                      clock-names = "sys_ck",
++                                    "ref_ck",
++                                    "mcu_ck",
++                                    "dma_ck",
++                                    "xhci_ck";
++                      phys = <&u2port0 PHY_TYPE_USB2>,
++                             <&u3port0 PHY_TYPE_USB3>;
++                      vusb33-supply = <&reg_3p3v>;
++                      status = "disabled";
++              };
++
++              usb_phy: usb-phy@11e10000 {
++                      compatible = "mediatek,mt7981",
++                                   "mediatek,generic-tphy-v2";
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++                      ranges = <0 0 0x11e10000 0x1700>;
++                      status = "disabled";
++
++                      u2port0: usb-phy@0 {
++                              reg = <0x0 0x700>;
++                              clocks = <&topckgen CLK_TOP_USB_FRMCNT_SEL>;
++                              clock-names = "ref";
++                              #phy-cells = <1>;
++                      };
++
++                      u3port0: usb-phy@700 {
++                              reg = <0x700 0x900>;
++                              clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>;
++                              clock-names = "ref";
++                              #phy-cells = <1>;
++                              mediatek,syscon-type = <&topmisc 0x218 0>;
++                              nvmem-cells = <&comb_intr_p0>,
++                                            <&comb_rx_imp_p0>,
++                                            <&comb_tx_imp_p0>;
++                              nvmem-cell-names = "intr", "rx_imp", "tx_imp";
++                              status = "okay";
++                      };
++              };
++
++
++              afe: audio-controller@11210000 {
++                      compatible = "mediatek,mt79xx-audio";
++                      reg = <0 0x11210000 0 0x9000>;
++                      interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_AUD_BUS_CK>,
++                               <&infracfg CLK_INFRA_AUD_26M_CK>,
++                               <&infracfg CLK_INFRA_AUD_L_CK>,
++                               <&infracfg CLK_INFRA_AUD_AUD_CK>,
++                               <&infracfg CLK_INFRA_AUD_EG2_CK>,
++                               <&topckgen CLK_TOP_AUD_SEL>;
++                      clock-names = "aud_bus_ck",
++                                    "aud_26m_ck",
++                                    "aud_l_ck",
++                                    "aud_aud_ck",
++                                    "aud_eg2_ck",
++                                    "aud_sel";
++                      assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>,
++                                        <&topckgen CLK_TOP_A1SYS_SEL>,
++                                        <&topckgen CLK_TOP_AUD_L_SEL>,
++                                        <&topckgen CLK_TOP_A_TUNER_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_CB_APLL2_196M>,
++                                               <&topckgen CLK_TOP_APLL2_D4>,
++                                               <&topckgen CLK_TOP_CB_APLL2_196M>,
++                                               <&topckgen CLK_TOP_APLL2_D4>;
++                      status = "disabled";
++              };
++
++              wifi: wifi@18000000 {
+                       compatible = "mediatek,mt7981-wmac";
++                      pinctrl-0 = <&wifi_dbdc_pins>;
++                      pinctrl-names = "dbdc";
+                       reg = <0 0x18000000 0 0x1000000>,
+                             <0 0x10003000 0 0x1000>,
+                             <0 0x11d10000 0 0x1000>;
+@@ -263,6 +677,67 @@
+                       clock-names = "mcu", "ap2conn";
+                       resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>;
+                       reset-names = "consys";
++                      memory-region = <&wmcpu_emi>;
++                      status = "disabled";
++              };
++      };
++
++      thermal-zones {
++              cpu_thermal: cpu-thermal {
++                      polling-delay-passive = <1000>;
++                      polling-delay = <1000>;
++                      thermal-sensors = <&thermal 0>;
++                      trips {
++                              cpu_trip_crit: crit {
++                                      temperature = <125000>;
++                                      hysteresis = <2000>;
++                                      type = "critical";
++                              };
++
++                              cpu_trip_hot: hot {
++                                      temperature = <120000>;
++                                      hysteresis = <2000>;
++                                      type = "hot";
++                              };
++
++                              cpu_trip_active_high: active-high {
++                                      temperature = <115000>;
++                                      hysteresis = <2000>;
++                                      type = "active";
++                              };
++
++                              cpu_trip_active_med: active-med {
++                                      temperature = <85000>;
++                                      hysteresis = <2000>;
++                                      type = "active";
++                              };
++
++                              cpu_trip_active_low: active-low {
++                                      temperature = <60000>;
++                                      hysteresis = <2000>;
++                                      type = "active";
++                              };
++                      };
++
++                      cooling-maps {
++                              cpu-active-high {
++                                      /* active: set fan to cooling level 3 */
++                                      cooling-device = <&fan 3 3>;
++                                      trip = <&cpu_trip_active_high>;
++                              };
++
++                              cpu-active-med {
++                                      /* active: set fan to cooling level 2 */
++                                      cooling-device = <&fan 2 2>;
++                                      trip = <&cpu_trip_active_med>;
++                              };
++
++                              cpu-active-low {
++                                      /* passive: set fan to cooling level 1 */
++                                      cooling-device = <&fan 1 1>;
++                                      trip = <&cpu_trip_active_low>;
++                              };
++                      };
+               };
+       };
+@@ -274,4 +749,8 @@
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+       };
++
++      trng {
++              compatible = "mediatek,mt7981-rng";
++      };
+ };
diff --git a/target/linux/mediatek/patches-6.12/119-pinctrl-mediatek-MT7981-some-register-map-fixes.patch b/target/linux/mediatek/patches-6.12/119-pinctrl-mediatek-MT7981-some-register-map-fixes.patch
new file mode 100644 (file)
index 0000000..fce4529
--- /dev/null
@@ -0,0 +1,76 @@
+From 2b4d8df6054acb13cae20889c40102c93df2edd6 Mon Sep 17 00:00:00 2001
+From: developer <developer@mediatek.com>
+Date: Tue, 6 Jan 2026 19:52:11 +0800
+Subject: [PATCH] pinctrl: mediatek: MT7981: some register map fixes
+
+Fix mt7981 pinctrl setting mistake including:
+1) Wrong pinctrl bits length
+2) Wrong pinctrl register offset
+
+Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/52579dd19e62df5aff784462e133e14bfe4a7726
+Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7981.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+@@ -48,7 +48,7 @@ static const struct mtk_pin_field_calc m
+       PIN_FIELD_BASE(9, 9, 5, 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(11, 11, 5, 0x20, 0x10, 10, 1),
+       PIN_FIELD_BASE(12, 12, 5, 0x20, 0x10, 7, 1),
+       PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1),
+@@ -157,7 +157,7 @@ static const struct mtk_pin_field_calc m
+       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(44, 44, 7, 0x70, 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),
+@@ -221,8 +221,8 @@ static const struct mtk_pin_field_calc m
+       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(3, 3, 4, 0x00, 0x10, 18, 3),
++      PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 3),
+       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),
+@@ -230,9 +230,9 @@ static const struct mtk_pin_field_calc m
+       PIN_FIELD_BASE(9, 9, 5, 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(11, 11, 5, 0x10, 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(13, 13, 5, 0x10, 0x10, 3, 3),
+       PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3),
+@@ -244,7 +244,7 @@ static const struct mtk_pin_field_calc m
+       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(23, 23, 2, 0x10, 0x10, 0, 3),
+       PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3),
+       PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3),
+@@ -310,7 +310,7 @@ static const struct mtk_pin_field_calc m
+       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(20, 20, 2, 0x30, 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),
diff --git a/target/linux/mediatek/patches-6.12/121-hack-spi-nand-1b-bbm.patch b/target/linux/mediatek/patches-6.12/121-hack-spi-nand-1b-bbm.patch
new file mode 100644 (file)
index 0000000..21459e1
--- /dev/null
@@ -0,0 +1,31 @@
+From 2138956bdc3145fac26d2ba8ac966f31d33cd290 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Thu, 7 Apr 2022 10:05:56 +0800
+Subject: [PATCH] mediatek: spi-nand: check for 1 byte BBM only
+
+the OOB layout in MTK SNFI uses the 2nd byte, and anything using OOB
+will make the block a bad-block in spi-nand driver.
+Hack it for now. We need a proper solution upstream.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -924,7 +924,7 @@ static int spinand_mtd_write(struct mtd_
+ static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
+ {
+       struct spinand_device *spinand = nand_to_spinand(nand);
+-      u8 marker[2] = { };
++      u8 marker[1] = { };
+       struct nand_page_io_req req = {
+               .pos = *pos,
+               .ooblen = sizeof(marker),
+@@ -943,7 +943,7 @@ static bool spinand_isbad(struct nand_de
+               spinand_read_page(spinand, &req);
+       }
+-      if (marker[0] != 0xff || marker[1] != 0xff)
++      if (marker[0] != 0xff)
+               return true;
+       return false;
diff --git a/target/linux/mediatek/patches-6.12/130-dts-mt7629-add-snand-support.patch b/target/linux/mediatek/patches-6.12/130-dts-mt7629-add-snand-support.patch
new file mode 100644 (file)
index 0000000..c7cd525
--- /dev/null
@@ -0,0 +1,94 @@
+From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001
+From: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
+Date: Thu, 6 Jun 2019 16:29:04 +0800
+Subject: [PATCH] spi: spi-mem: Mediatek: Add SPI Nand support for MT7629
+
+Signed-off-by: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
+---
+ arch/arm/boot/dts/mediatek/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++
+ arch/arm/boot/dts/mediatek/mt7629.dtsi    | 22 ++++++++++++++++
+ 3 files changed, 79 insertions(+)
+
+--- a/arch/arm/boot/dts/mediatek/mt7629.dtsi
++++ b/arch/arm/boot/dts/mediatek/mt7629.dtsi
+@@ -271,6 +271,27 @@
+                       status = "disabled";
+               };
++              snfi: spi@1100d000 {
++                      compatible = "mediatek,mt7629-snand";
++                      reg = <0x1100d000 0x1000>;
++                      interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
++                      clocks = <&pericfg CLK_PERI_NFI_PD>, <&pericfg CLK_PERI_SNFI_PD>;
++                      clock-names = "nfi_clk", "pad_clk";
++                      nand-ecc-engine = <&bch>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
++              bch: ecc@1100e000 {
++                      compatible = "mediatek,mt7622-ecc";
++                      reg = <0x1100e000 0x1000>;
++                      interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_LOW>;
++                      clocks = <&pericfg CLK_PERI_NFIECC_PD>;
++                      clock-names = "nfiecc_clk";
++                      status = "disabled";
++              };
++
+               spi: spi@1100a000 {
+                       compatible = "mediatek,mt7629-spi",
+                                    "mediatek,mt7622-spi";
+--- a/arch/arm/boot/dts/mediatek/mt7629-rfb.dts
++++ b/arch/arm/boot/dts/mediatek/mt7629-rfb.dts
+@@ -255,6 +255,50 @@
+       };
+ };
++&bch {
++      status = "okay";
++};
++
++&snfi {
++      pinctrl-names = "default";
++      pinctrl-0 = <&serial_nand_pins>;
++      status = "okay";
++      flash@0 {
++              compatible = "spi-nand";
++              reg = <0>;
++              spi-tx-bus-width = <4>;
++              spi-rx-bus-width = <4>;
++              nand-ecc-engine = <&snfi>;
++
++              partitions {
++                      compatible = "fixed-partitions";
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      partition@0 {
++                              label = "Bootloader";
++                              reg = <0x00000 0x0100000>;
++                              read-only;
++                      };
++
++                      partition@100000 {
++                              label = "Config";
++                              reg = <0x100000 0x0040000>;
++                      };
++
++                      partition@140000 {
++                              label = "factory";
++                              reg = <0x140000 0x0080000>;
++                      };
++
++                      partition@1c0000 {
++                              label = "firmware";
++                              reg = <0x1c0000 0x1000000>;
++                      };
++              };
++      };
++};
++
+ &spi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_pins>;
diff --git a/target/linux/mediatek/patches-6.12/131-dts-mt7622-add-snand-support.patch b/target/linux/mediatek/patches-6.12/131-dts-mt7622-add-snand-support.patch
new file mode 100644 (file)
index 0000000..5293abc
--- /dev/null
@@ -0,0 +1,79 @@
+From d3f058db1cb9b2d43764cd0d84fdc2779f0abacf Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Fri, 27 Mar 2020 15:34:33 +0100
+Subject: [PATCH] arm64: dts: mediatek: mt7622-rfb1: add SPI-NAND flash node
+
+Add a spi-nand child node to the snfi controller with quad-IO bus widths,
+an ECC engine reference, and a fixed-partitions layout covering the full
+flash address space of the SPI-NAND device populated on the RFB1 board.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -558,6 +558,65 @@
+       status = "disabled";
+ };
++&bch {
++      status = "okay";
++};
++
++&snfi {
++      pinctrl-names = "default";
++      pinctrl-0 = <&serial_nand_pins>;
++      status = "okay";
++      flash@0 {
++              compatible = "spi-nand";
++              reg = <0>;
++              spi-tx-bus-width = <4>;
++              spi-rx-bus-width = <4>;
++              nand-ecc-engine = <&snfi>;
++
++              partitions {
++                      compatible = "fixed-partitions";
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      partition@0 {
++                              label = "Preloader";
++                              reg = <0x00000 0x0080000>;
++                              read-only;
++                      };
++
++                      partition@80000 {
++                              label = "ATF";
++                              reg = <0x80000 0x0040000>;
++                      };
++
++                      partition@c0000 {
++                              label = "Bootloader";
++                              reg = <0xc0000 0x0080000>;
++                      };
++
++                      partition@140000 {
++                              label = "Config";
++                              reg = <0x140000 0x0080000>;
++                      };
++
++                      partition@1c0000 {
++                              label = "Factory";
++                              reg = <0x1c0000 0x0100000>;
++                      };
++
++                      partition@200000 {
++                              label = "firmware";
++                              reg = <0x2c0000 0x2000000>;
++                      };
++
++                      partition@2200000 {
++                              label = "User_data";
++                              reg = <0x22c0000 0x4000000>;
++                      };
++              };
++      };
++};
++
+ &spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spic0_pins>;
diff --git a/target/linux/mediatek/patches-6.12/140-dts-fix-wmac-support-for-mt7622-rfb1.patch b/target/linux/mediatek/patches-6.12/140-dts-fix-wmac-support-for-mt7622-rfb1.patch
new file mode 100644 (file)
index 0000000..6c9f5dc
--- /dev/null
@@ -0,0 +1,29 @@
+From c46ccb69d17e584479df849a107423175a143c83 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 24 Oct 2020 21:15:20 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7622-rfb1: wire EEPROM to wmac from factory partition
+
+Label the factory partition node so it can be referenced by phandle, and
+add a mediatek,mtd-eeprom property to the wmac node pointing at the
+factory partition to supply the calibration data at offset 0x0000.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -599,7 +599,7 @@
+                               reg = <0x140000 0x0080000>;
+                       };
+-                      partition@1c0000 {
++                      factory: partition@1c0000 {
+                               label = "Factory";
+                               reg = <0x1c0000 0x0100000>;
+                       };
+@@ -660,5 +660,6 @@
+ &wmac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&wmac_pins>;
++      mediatek,mtd-eeprom = <&factory 0x0000>;
+       status = "okay";
+ };
diff --git a/target/linux/mediatek/patches-6.12/150-dts-mt7623-eip97-inside-secure-support.patch b/target/linux/mediatek/patches-6.12/150-dts-mt7623-eip97-inside-secure-support.patch
new file mode 100644 (file)
index 0000000..9e96a5a
--- /dev/null
@@ -0,0 +1,37 @@
+From 127ad76311079a842578e788a8af364f3910c676 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 4 Jun 2020 14:20:34 +0200
+Subject: [PATCH] arm: dts: mediatek: mt7623: switch crypto to inside-secure,safexcel-eip97
+
+Switch the DTS compatible string of the crypto engine node from
+"mediatek,eip97-crypto" to "inside-secure,safexcel-eip97" to bind to
+the upstream Inside Secure SafeXcel driver. Update the interrupt list
+to match and add interrupt-names, and remove the now-unused power-domain
+and clock-names properties.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+--- a/arch/arm/boot/dts/mediatek/mt7623.dtsi
++++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi
+@@ -995,17 +995,15 @@
+       };
+       crypto: crypto@1b240000 {
+-              compatible = "mediatek,eip97-crypto";
++              compatible = "inside-secure,safexcel-eip97";
+               reg = <0 0x1b240000 0 0x20000>;
+               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_SPI 83 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>,
+-                           <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>,
+-                           <GIC_SPI 97 IRQ_TYPE_LEVEL_LOW>;
++                           <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
++              interrupt-names = "ring0", "ring1", "ring2", "ring3";
+               clocks = <&ethsys CLK_ETHSYS_CRYPTO>;
+-              clock-names = "cryp";
+-              power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
+-              status = "disabled";
++              status = "okay";
+       };
+       bdpsys: syscon@1c000000 {
diff --git a/target/linux/mediatek/patches-6.12/160-dts-mt7623-bpi-r2-earlycon.patch b/target/linux/mediatek/patches-6.12/160-dts-mt7623-bpi-r2-earlycon.patch
new file mode 100644 (file)
index 0000000..85a8bb9
--- /dev/null
@@ -0,0 +1,22 @@
+From 25d9df670b850a4e3702e084ff249baa1670ae3f Mon Sep 17 00:00:00 2001
+From: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+Date: Mon, 10 Feb 2020 09:33:15 +0100
+Subject: [PATCH] arm: dts: mediatek: mt7623n-bpi-r2: add earlycon= to bootargs
+
+Add earlycon=uart8250,mmio32,0x11004000 to the chosen/bootargs property
+so that kernel messages are available on the serial console before the
+full UART driver is initialised.
+
+Signed-off-by: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+---
+--- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
+@@ -19,7 +19,7 @@
+       chosen {
+               stdout-path = "serial2:115200n8";
+-              bootargs = "console=ttyS2,115200n8 console=tty1";
++              bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
+       };
+       connector {
diff --git a/target/linux/mediatek/patches-6.12/161-dts-mt7623-bpi-r2-mmc-device-order.patch b/target/linux/mediatek/patches-6.12/161-dts-mt7623-bpi-r2-mmc-device-order.patch
new file mode 100644 (file)
index 0000000..eb9ba49
--- /dev/null
@@ -0,0 +1,22 @@
+From 25d9df670b850a4e3702e084ff249baa1670ae3f Mon Sep 17 00:00:00 2001
+From: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+Date: Mon, 10 Feb 2020 09:33:15 +0100
+Subject: [PATCH] arm: dts: mediatek: mt7623n-bpi-r2: add mmc device order aliases
+
+Add mmc0 and mmc1 aliases to fix the MMC controller enumeration order,
+ensuring the SD card slot and eMMC are always assigned predictable
+device numbers regardless of probe order.
+
+Signed-off-by: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+---
+--- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
+@@ -15,6 +15,8 @@
+       aliases {
+               serial2 = &uart2;
++              mmc0 = &mmc0;
++              mmc1 = &mmc1;
+       };
+       chosen {
diff --git a/target/linux/mediatek/patches-6.12/162-dts-mt7623-bpi-r2-led-aliases.patch b/target/linux/mediatek/patches-6.12/162-dts-mt7623-bpi-r2-led-aliases.patch
new file mode 100644 (file)
index 0000000..11cb722
--- /dev/null
@@ -0,0 +1,38 @@
+From 21c7a8593d86175c0764d23e77bb019fd9617f53 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 1 Oct 2021 23:25:48 +0100
+Subject: [PATCH] mediatek: mt7623: bpi-r2: add LED aliases
+
+Add aliases for LEDs in device tree of the BPi-R2.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
+@@ -17,6 +17,10 @@
+               serial2 = &uart2;
+               mmc0 = &mmc0;
+               mmc1 = &mmc1;
++              led-boot = &led_system_green;
++              led-failsafe = &led_system_blue;
++              led-running = &led_system_green;
++              led-upgrade = &led_system_blue;
+       };
+       chosen {
+@@ -112,13 +116,13 @@
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins_a>;
+-              blue {
++              led_system_blue: blue {
+                       label = "bpi-r2:pio:blue";
+                       gpios = <&pio 240 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+-              green {
++              led_system_green: green {
+                       label = "bpi-r2:pio:green";
+                       gpios = <&pio 241 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
diff --git a/target/linux/mediatek/patches-6.12/163-dts-mt7623-bpi-r2-ethernet-alias.patch b/target/linux/mediatek/patches-6.12/163-dts-mt7623-bpi-r2-ethernet-alias.patch
new file mode 100644 (file)
index 0000000..455f3b0
--- /dev/null
@@ -0,0 +1,20 @@
+From 25d9df670b850a4e3702e084ff249baa1670ae3f Mon Sep 17 00:00:00 2001
+From: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+Date: Mon, 10 Feb 2020 09:33:15 +0100
+Subject: [PATCH] arm: dts: mediatek: mt7623n-bpi-r2: add ethernet0 alias
+
+Add an ethernet0 alias pointing to gmac0 so that the primary Ethernet
+interface is consistently named by the kernel.
+
+Signed-off-by: Mark-MC Lee (李明昌) <Mark-MC.Lee@mediatek.com>
+---
+--- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
+@@ -15,6 +15,7 @@
+       aliases {
+               serial2 = &uart2;
++              ethernet0 = &gmac0;
+               mmc0 = &mmc0;
+               mmc1 = &mmc1;
+               led-boot = &led_system_green;
diff --git a/target/linux/mediatek/patches-6.12/164-dts-mt7623-bpi-r2-rootdisk-for-fitblk.patch b/target/linux/mediatek/patches-6.12/164-dts-mt7623-bpi-r2-rootdisk-for-fitblk.patch
new file mode 100644 (file)
index 0000000..91ef678
--- /dev/null
@@ -0,0 +1,66 @@
+From 6368ed1ae5b628898b33273c8950f7b7575e4414 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 24 Feb 2024 03:00:27 +0000
+Subject: [PATCH] mediatek: mt7623: phase out uImage.FIT partition parser
+
+Use the new fitblk driver on the BananaPi R2 as well as UniElec U7623.
+Introduce boot device selection for fitblk's /chosen/rootdisk
+handle, similar to how it is already done on MT7622, MT7986 and MT7988.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts
+@@ -26,7 +26,9 @@
+       chosen {
+               stdout-path = "serial2:115200n8";
+-              bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
++              bootargs = "root=/dev/fit0 rootwait earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
++              rootdisk-emmc = <&emmc_rootdisk>;
++              rootdisk-sd = <&sd_rootdisk>;
+       };
+       connector {
+@@ -338,6 +340,20 @@
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_1p8v>;
+       non-removable;
++      #address-cells = <1>;
++      #size-cells = <0>;
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              partitions {
++                      compatible = "msdos-partitions";
++                      emmc_rootdisk: block-partition-fit {
++                              partno = <3>;
++                      };
++              };
++      };
+ };
+ &mmc1 {
+@@ -351,6 +367,20 @@
+       cd-gpios = <&pio 261 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_3p3v>;
++      #address-cells = <1>;
++      #size-cells = <0>;
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              partitions {
++                      compatible = "msdos-partitions";
++                      sd_rootdisk: block-partition-fit {
++                              partno = <3>;
++                      };
++              };
++      };
+ };
+ &mt6323keys {
diff --git a/target/linux/mediatek/patches-6.12/170-arm64-dts-mediatek-mt7988a-bpi-r4-allow-hw-variants-.patch b/target/linux/mediatek/patches-6.12/170-arm64-dts-mediatek-mt7988a-bpi-r4-allow-hw-variants-.patch
new file mode 100644 (file)
index 0000000..6216f59
--- /dev/null
@@ -0,0 +1,876 @@
+From df3c7a5128f88e658bd4519154d5e896519e740a Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 22 Apr 2025 15:24:25 +0200
+Subject: [PATCH 27/32] arm64: dts: mediatek: mt7988a-bpi-r4: allow hw variants
+ of bpi-r4
+
+Sinovoip has released other variants of Bananapi-R4 board.
+The known changes affecting only the LAN SFP+ slot which is replaced
+by a 2.5G phy with optional PoE.
+
+Just move the common parts to a new dtsi and keep differences (only
+i2c for lan-sfp) in dts.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogiaocchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/Makefile         |   6 +
+ .../mediatek/mt7988a-bananapi-bpi-r4-2g5.dts  |  11 +
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts  | 400 +-----------------
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 399 +++++++++++++++++
+ 4 files changed, 421 insertions(+), 395 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+
+--- a/arch/arm64/boot/dts/mediatek/Makefile
++++ b/arch/arm64/boot/dts/mediatek/Makefile
+@@ -21,6 +21,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-b
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5.dtb
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb
+@@ -90,3 +93,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pu
+ # Device tree overlays support
+ DTC_FLAGS_mt7986a-bananapi-bpi-r3 := -@
+ DTC_FLAGS_mt7986a-bananapi-bpi-r3-mini := -@
++DTC_FLAGS_mt7988a-bananapi-bpi-r4 := -@
++DTC_FLAGS_mt7988a-bananapi-bpi-r4-2g5 := -@
++DTC_FLAGS_mt8395-radxa-nio-12l := -@
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts
+@@ -0,0 +1,11 @@
++// SPDX-License-Identifier: GPL-2.0-only OR MIT
++
++/dts-v1/;
++
++#include "mt7988a-bananapi-bpi-r4.dtsi"
++
++/ {
++      compatible = "bananapi,bpi-r4-2g5", "bananapi,bpi-r4", "mediatek,mt7988a";
++      model = "Banana Pi BPI-R4 (1x SFP+, 1x 2.5GbE)";
++      chassis-type = "embedded";
++};
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -2,408 +2,18 @@
+ /dts-v1/;
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
+-
+-#include "mt7988a.dtsi"
++#include "mt7988a-bananapi-bpi-r4.dtsi"
+ / {
+       compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+-      model = "Banana Pi BPI-R4";
++      model = "Banana Pi BPI-R4 (2x SFP+)";
+       chassis-type = "embedded";
+-
+-      chosen {
+-              stdout-path = "serial0:115200n8";
+-      };
+-
+-      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;
+-      };
+ };
+-&cpu0 {
+-      proc-supply = <&rt5190_buck3>;
+-};
+-
+-&cpu1 {
+-      proc-supply = <&rt5190_buck3>;
+-};
+-
+-&cpu2 {
+-      proc-supply = <&rt5190_buck3>;
+-};
+-
+-&cpu3 {
+-      proc-supply = <&rt5190_buck3>;
+-};
+-
+-&cpu_thermal {
+-      trips {
+-              cpu_trip_hot: hot {
+-                      temperature = <120000>;
+-                      hysteresis = <2000>;
+-                      type = "hot";
+-              };
+-
+-              cpu_trip_active_high: active-high {
+-                      temperature = <115000>;
+-                      hysteresis = <2000>;
+-                      type = "active";
+-              };
+-
+-              cpu_trip_active_med: active-med {
+-                      temperature = <85000>;
+-                      hysteresis = <2000>;
+-                      type = "active";
+-              };
+-
+-              cpu_trip_active_low: active-low {
+-                      temperature = <40000>;
+-                      hysteresis = <2000>;
+-                      type = "active";
+-              };
+-      };
+-};
+-
+-&i2c0 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c0_pins>;
+-      status = "okay";
+-
+-      rt5190a_64: rt5190a@64 {
+-              compatible = "richtek,rt5190a";
+-              reg = <0x64>;
+-              vin2-supply = <&rt5190_buck1>;
+-              vin3-supply = <&rt5190_buck1>;
+-              vin4-supply = <&rt5190_buck1>;
+-
+-              regulators {
+-                      rt5190_buck1: buck1 {
+-                              regulator-name = "rt5190a-buck1";
+-                              regulator-min-microvolt = <5090000>;
+-                              regulator-max-microvolt = <5090000>;
+-                              regulator-allowed-modes =
+-                              <RT5190A_OPMODE_AUTO>, <RT5190A_OPMODE_FPWM>;
+-                              regulator-boot-on;
+-                              regulator-always-on;
+-                      };
+-                      buck2 {
+-                              regulator-name = "vcore";
+-                              regulator-min-microvolt = <600000>;
+-                              regulator-max-microvolt = <1400000>;
+-                              regulator-boot-on;
+-                              regulator-always-on;
+-                      };
+-                      rt5190_buck3: buck3 {
+-                              regulator-name = "vproc";
+-                              regulator-min-microvolt = <600000>;
+-                              regulator-max-microvolt = <1400000>;
+-                              regulator-boot-on;
+-                      };
+-                      buck4 {
+-                              regulator-name = "rt5190a-buck4";
+-                              regulator-min-microvolt = <1800000>;
+-                              regulator-max-microvolt = <1800000>;
+-                              regulator-allowed-modes =
+-                              <RT5190A_OPMODE_AUTO>, <RT5190A_OPMODE_FPWM>;
+-                              regulator-boot-on;
+-                              regulator-always-on;
+-                      };
+-                      ldo {
+-                              regulator-name = "rt5190a-ldo";
+-                              regulator-min-microvolt = <1800000>;
+-                              regulator-max-microvolt = <1800000>;
+-                              regulator-boot-on;
+-                              regulator-always-on;
+-                      };
+-              };
+-      };
+-};
+-
+-&i2c2 {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&i2c2_1_pins>;
+-      status = "okay";
+-
+-      pca9545: i2c-mux@70 {
+-              compatible = "nxp,pca9545";
+-              reg = <0x70>;
+-              reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
++&pca9545 {
++      i2c_sfp2: i2c@2 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+-
+-              i2c@0 {
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-                      reg = <0>;
+-
+-                      pcf8563: rtc@51 {
+-                              compatible = "nxp,pcf8563";
+-                              reg = <0x51>;
+-                              #clock-cells = <0>;
+-                      };
+-
+-                      eeprom@57 {
+-                              compatible = "atmel,24c02";
+-                              reg = <0x57>;
+-                              size = <256>;
+-                      };
+-
+-              };
+-
+-              i2c_sfp1: i2c@1 {
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-                      reg = <1>;
+-              };
+-
+-              i2c_sfp2: i2c@2 {
+-                      #address-cells = <1>;
+-                      #size-cells = <0>;
+-                      reg = <2>;
+-              };
+-      };
+-};
+-
+-/* mPCIe SIM2 */
+-&pcie0 {
+-      status = "okay";
+-};
+-
+-/* mPCIe SIM3 */
+-&pcie1 {
+-      status = "okay";
+-};
+-
+-/* M.2 key-B SIM1 */
+-&pcie2 {
+-      status = "okay";
+-};
+-
+-/* M.2 key-M SSD */
+-&pcie3 {
+-      status = "okay";
+-};
+-
+-&pio {
+-      mdio0_pins: mdio0-pins {
+-              mux {
+-                      function = "eth";
+-                      groups = "mdc_mdio0";
+-              };
+-
+-              conf {
+-                      pins = "SMI_0_MDC", "SMI_0_MDIO";
+-                      drive-strength = <8>;
+-              };
+-      };
+-
+-      i2c0_pins: i2c0-g0-pins {
+-              mux {
+-                      function = "i2c";
+-                      groups = "i2c0_1";
+-              };
+-      };
+-
+-      i2c1_pins: i2c1-g0-pins {
+-              mux {
+-                      function = "i2c";
+-                      groups = "i2c1_0";
+-              };
+-      };
+-
+-      i2c1_sfp_pins: i2c1-sfp-g0-pins {
+-              mux {
+-                      function = "i2c";
+-                      groups = "i2c1_sfp";
+-              };
+-      };
+-
+-      i2c2_0_pins: i2c2-g0-pins {
+-              mux {
+-                      function = "i2c";
+-                      groups = "i2c2_0";
+-              };
++              reg = <2>;
+       };
+-
+-      i2c2_1_pins: i2c2-g1-pins {
+-              mux {
+-                      function = "i2c";
+-                      groups = "i2c2_1";
+-              };
+-      };
+-
+-      gbe0_led0_pins: gbe0-led0-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe0_led0";
+-              };
+-      };
+-
+-      gbe1_led0_pins: gbe1-led0-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe1_led0";
+-              };
+-      };
+-
+-      gbe2_led0_pins: gbe2-led0-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe2_led0";
+-              };
+-      };
+-
+-      gbe3_led0_pins: gbe3-led0-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe3_led0";
+-              };
+-      };
+-
+-      gbe0_led1_pins: gbe0-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe0_led1";
+-              };
+-      };
+-
+-      gbe1_led1_pins: gbe1-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe1_led1";
+-              };
+-      };
+-
+-      gbe2_led1_pins: gbe2-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe2_led1";
+-              };
+-      };
+-
+-      gbe3_led1_pins: gbe3-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe3_led1";
+-              };
+-      };
+-
+-      i2p5gbe_led0_pins: 2p5gbe-led0-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "2p5gbe_led0";
+-              };
+-      };
+-
+-      i2p5gbe_led1_pins: 2p5gbe-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "2p5gbe_led1";
+-              };
+-      };
+-
+-      mmc0_pins_emmc_45: mmc0-emmc-45-pins {
+-              mux {
+-                      function = "flash";
+-                      groups = "emmc_45";
+-              };
+-      };
+-
+-      mmc0_pins_emmc_51: mmc0-emmc-51-pins {
+-              mux {
+-                      function = "flash";
+-                      groups = "emmc_51";
+-              };
+-      };
+-
+-      mmc0_pins_sdcard: mmc0-sdcard-pins {
+-              mux {
+-                      function = "flash";
+-                      groups = "sdcard";
+-              };
+-      };
+-
+-      uart0_pins: uart0-pins {
+-              mux {
+-                      function = "uart";
+-                      groups =  "uart0";
+-              };
+-      };
+-
+-      snfi_pins: snfi-pins {
+-              mux {
+-                      function = "flash";
+-                      groups = "snfi";
+-              };
+-      };
+-
+-      spi0_pins: spi0-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi0";
+-              };
+-      };
+-
+-      spi0_flash_pins: spi0-flash-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi0", "spi0_wp_hold";
+-              };
+-      };
+-
+-      spi1_pins: spi1-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi1";
+-              };
+-      };
+-
+-      spi2_pins: spi2-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi2";
+-              };
+-      };
+-
+-      spi2_flash_pins: spi2-flash-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi2", "spi2_wp_hold";
+-              };
+-      };
+-};
+-
+-&pwm {
+-      status = "okay";
+-};
+-
+-&serial0 {
+-      status = "okay";
+-};
+-
+-&ssusb1 {
+-      status = "okay";
+-};
+-
+-&tphy {
+-      status = "okay";
+-};
+-
+-&watchdog {
+-      status = "okay";
+ };
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -0,0 +1,399 @@
++// SPDX-License-Identifier: GPL-2.0-only OR MIT
++
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
++
++#include "mt7988a.dtsi"
++
++/ {
++      chosen {
++              stdout-path = "serial0:115200n8";
++      };
++
++      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;
++      };
++};
++
++&cpu0 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu1 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu2 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu3 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu_thermal {
++      trips {
++              cpu_trip_hot: hot {
++                      temperature = <120000>;
++                      hysteresis = <2000>;
++                      type = "hot";
++              };
++
++              cpu_trip_active_high: active-high {
++                      temperature = <115000>;
++                      hysteresis = <2000>;
++                      type = "active";
++              };
++
++              cpu_trip_active_med: active-med {
++                      temperature = <85000>;
++                      hysteresis = <2000>;
++                      type = "active";
++              };
++
++              cpu_trip_active_low: active-low {
++                      temperature = <40000>;
++                      hysteresis = <2000>;
++                      type = "active";
++              };
++      };
++};
++
++&i2c0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c0_pins>;
++      status = "okay";
++
++      rt5190a_64: rt5190a@64 {
++              compatible = "richtek,rt5190a";
++              reg = <0x64>;
++              vin2-supply = <&rt5190_buck1>;
++              vin3-supply = <&rt5190_buck1>;
++              vin4-supply = <&rt5190_buck1>;
++
++              regulators {
++                      rt5190_buck1: buck1 {
++                              regulator-name = "rt5190a-buck1";
++                              regulator-min-microvolt = <5090000>;
++                              regulator-max-microvolt = <5090000>;
++                              regulator-allowed-modes =
++                              <RT5190A_OPMODE_AUTO>, <RT5190A_OPMODE_FPWM>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      buck2 {
++                              regulator-name = "vcore";
++                              regulator-min-microvolt = <600000>;
++                              regulator-max-microvolt = <1400000>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      rt5190_buck3: buck3 {
++                              regulator-name = "vproc";
++                              regulator-min-microvolt = <600000>;
++                              regulator-max-microvolt = <1400000>;
++                              regulator-boot-on;
++                      };
++                      buck4 {
++                              regulator-name = "rt5190a-buck4";
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-allowed-modes =
++                              <RT5190A_OPMODE_AUTO>, <RT5190A_OPMODE_FPWM>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      ldo {
++                              regulator-name = "rt5190a-ldo";
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++              };
++      };
++};
++
++&i2c2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c2_1_pins>;
++      status = "okay";
++
++      pca9545: i2c-mux@70 {
++              compatible = "nxp,pca9545";
++              reg = <0x70>;
++              reset-gpios = <&pio 5 GPIO_ACTIVE_LOW>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              i2c@0 {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      reg = <0>;
++
++                      pcf8563: rtc@51 {
++                              compatible = "nxp,pcf8563";
++                              reg = <0x51>;
++                              #clock-cells = <0>;
++                      };
++
++                      eeprom@57 {
++                              compatible = "atmel,24c02";
++                              reg = <0x57>;
++                              size = <256>;
++                      };
++
++              };
++
++              i2c_sfp1: i2c@1 {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      reg = <1>;
++              };
++      };
++};
++
++/* mPCIe SIM2 */
++&pcie0 {
++      status = "okay";
++};
++
++/* mPCIe SIM3 */
++&pcie1 {
++      status = "okay";
++};
++
++/* M.2 key-B SIM1 */
++&pcie2 {
++      status = "okay";
++};
++
++/* M.2 key-M SSD */
++&pcie3 {
++      status = "okay";
++};
++
++&pio {
++      mdio0_pins: mdio0-pins {
++              mux {
++                      function = "eth";
++                      groups = "mdc_mdio0";
++              };
++
++              conf {
++                      pins = "SMI_0_MDC", "SMI_0_MDIO";
++                      drive-strength = <8>;
++              };
++      };
++
++      i2c0_pins: i2c0-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c0_1";
++              };
++      };
++
++      i2c1_pins: i2c1-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c1_0";
++              };
++      };
++
++      i2c1_sfp_pins: i2c1-sfp-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c1_sfp";
++              };
++      };
++
++      i2c2_0_pins: i2c2-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c2_0";
++              };
++      };
++
++      i2c2_1_pins: i2c2-g1-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c2_1";
++              };
++      };
++
++      gbe0_led0_pins: gbe0-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe0_led0";
++              };
++      };
++
++      gbe1_led0_pins: gbe1-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe1_led0";
++              };
++      };
++
++      gbe2_led0_pins: gbe2-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe2_led0";
++              };
++      };
++
++      gbe3_led0_pins: gbe3-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe3_led0";
++              };
++      };
++
++      gbe0_led1_pins: gbe0-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe0_led1";
++              };
++      };
++
++      gbe1_led1_pins: gbe1-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe1_led1";
++              };
++      };
++
++      gbe2_led1_pins: gbe2-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe2_led1";
++              };
++      };
++
++      gbe3_led1_pins: gbe3-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe3_led1";
++              };
++      };
++
++      i2p5gbe_led0_pins: 2p5gbe-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "2p5gbe_led0";
++              };
++      };
++
++      i2p5gbe_led1_pins: 2p5gbe-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "2p5gbe_led1";
++              };
++      };
++
++      mmc0_pins_emmc_45: mmc0-emmc-45-pins {
++              mux {
++                      function = "flash";
++                      groups = "emmc_45";
++              };
++      };
++
++      mmc0_pins_emmc_51: mmc0-emmc-51-pins {
++              mux {
++                      function = "flash";
++                      groups = "emmc_51";
++              };
++      };
++
++      mmc0_pins_sdcard: mmc0-sdcard-pins {
++              mux {
++                      function = "flash";
++                      groups = "sdcard";
++              };
++      };
++
++      uart0_pins: uart0-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart0";
++              };
++      };
++
++      snfi_pins: snfi-pins {
++              mux {
++                      function = "flash";
++                      groups = "snfi";
++              };
++      };
++
++      spi0_pins: spi0-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0";
++              };
++      };
++
++      spi0_flash_pins: spi0-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0", "spi0_wp_hold";
++              };
++      };
++
++      spi1_pins: spi1-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi1";
++              };
++      };
++
++      spi2_pins: spi2-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi2";
++              };
++      };
++
++      spi2_flash_pins: spi2-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi2", "spi2_wp_hold";
++              };
++      };
++};
++
++&pwm {
++      status = "okay";
++};
++
++&serial0 {
++      status = "okay";
++};
++
++&ssusb1 {
++      status = "okay";
++};
++
++&tphy {
++      status = "okay";
++};
++
++&watchdog {
++      status = "okay";
++};
diff --git a/target/linux/mediatek/patches-6.12/171-v6.16-arm64-dts-mediatek-mt7988-Add-xsphy-for-ssusb0-pcie2.patch b/target/linux/mediatek/patches-6.12/171-v6.16-arm64-dts-mediatek-mt7988-Add-xsphy-for-ssusb0-pcie2.patch
new file mode 100644 (file)
index 0000000..18f1ddc
--- /dev/null
@@ -0,0 +1,75 @@
+From 2400b24dfecea9a628f63089bf7eeb9a43b91021 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 22 Apr 2025 15:24:30 +0200
+Subject: [PATCH 28/32] arm64: dts: mediatek: mt7988: Add xsphy for ssusb0/pcie2
+
+First usb and third pcie controller on mt7988 need a xs-phy to work
+properly.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250422132438.15735-8-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 36 +++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -334,6 +334,8 @@
+                                <&infracfg CLK_INFRA_133M_USB_HCK>,
+                                <&infracfg CLK_INFRA_USB_XHCI>;
+                       clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
++                      phys = <&xphyu2port0 PHY_TYPE_USB2>,
++                             <&xphyu3port0 PHY_TYPE_USB3>;
+                       status = "disabled";
+               };
+@@ -398,6 +400,9 @@
+                       pinctrl-0 = <&pcie2_pins>;
+                       status = "disabled";
++                      phys = <&xphyu3port0 PHY_TYPE_PCIE>;
++                      phy-names = "pcie-phy";
++
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0x7>;
+                       interrupt-map = <0 0 0 1 &pcie_intc2 0>,
+@@ -548,6 +553,37 @@
+                       };
+               };
++
++              topmisc: system-controller@11d10084 {
++                      compatible = "mediatek,mt7988-topmisc",
++                                   "syscon";
++                      reg = <0 0x11d10084 0 0xff80>;
++              };
++
++              xs-phy@11e10000 {
++                      compatible = "mediatek,mt7988-xsphy",
++                                   "mediatek,xsphy";
++                      #address-cells = <2>;
++                      #size-cells = <2>;
++                      ranges;
++                      status = "disabled";
++
++                      xphyu2port0: usb-phy@11e10000 {
++                              reg = <0 0x11e10000 0 0x400>;
++                              clocks = <&infracfg CLK_INFRA_USB_UTMI>;
++                              clock-names = "ref";
++                              #phy-cells = <1>;
++                      };
++
++                      xphyu3port0: usb-phy@11e13000 {
++                              reg = <0 0x11e13400 0 0x500>;
++                              clocks = <&infracfg CLK_INFRA_USB_PIPE>;
++                              clock-names = "ref";
++                              #phy-cells = <1>;
++                              mediatek,syscon-type = <&topmisc 0x194 0>;
++                      };
++              };
++
+               clock-controller@11f40000 {
+                       compatible = "mediatek,mt7988-xfi-pll";
+                       reg = <0 0x11f40000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/172-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-enable-xsphy.patch b/target/linux/mediatek/patches-6.12/172-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-enable-xsphy.patch
new file mode 100644 (file)
index 0000000..d02bca2
--- /dev/null
@@ -0,0 +1,37 @@
+From bb5872c4b6cb0a8687b424b9970b2c3cca2ededd Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Tue, 22 Apr 2025 15:24:31 +0200
+Subject: [PATCH 29/32] arm64: dts: mediatek: mt7988a-bpi-r4: enable xsphy
+
+Enable XS-Phy on Bananapi R4 for pcie2.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250422132438.15735-9-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi                 | 2 +-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -397,3 +397,7 @@
+ &watchdog {
+       status = "okay";
+ };
++
++&xsphy {
++      status = "okay";
++};
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -560,7 +560,7 @@
+                       reg = <0 0x11d10084 0 0xff80>;
+               };
+-              xs-phy@11e10000 {
++              xsphy: xs-phy@11e10000 {
+                       compatible = "mediatek,mt7988-xsphy",
+                                    "mediatek,xsphy";
+                       #address-cells = <2>;
diff --git a/target/linux/mediatek/patches-6.12/173-dts-mt7988a-Add-built-in-ethernet-phy-firmware-node.patch b/target/linux/mediatek/patches-6.12/173-dts-mt7988a-Add-built-in-ethernet-phy-firmware-node.patch
new file mode 100644 (file)
index 0000000..698f821
--- /dev/null
@@ -0,0 +1,27 @@
+From 6cf55d4520eb4ef3ed2cc3726a765a89b0071d8b Mon Sep 17 00:00:00 2001
+From: Sky Huang <skylake.huang@mediatek.com>
+Date: Wed, 19 Feb 2025 16:39:09 +0800
+Subject: [PATCH 30/32] dts: mt7988a: Add built-in ethernet phy firmware node
+
+Add built-in ethernet phy firmware node in mt7988a.dtsi.
+
+Signed-off-by: Sky Huang <skylake.huang@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -322,6 +322,12 @@
+                       nvmem-cell-names = "lvts-calib-data-1";
+               };
++              phyfw: phy-firmware@f000000 {
++                      compatible = "mediatek,2p5gphy-fw";
++                      reg = <0 0x0f100000 0 0x20000>,
++                            <0 0x0f0f0018 0 0x20>;
++              };
++
+               usb@11190000 {
+                       compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
+                       reg = <0 0x11190000 0 0x2e00>,
diff --git a/target/linux/mediatek/patches-6.12/174-v6.16-arm64-dts-mediatek-mt7988-add-spi-controllers.patch b/target/linux/mediatek/patches-6.12/174-v6.16-arm64-dts-mediatek-mt7988-add-spi-controllers.patch
new file mode 100644 (file)
index 0000000..d634671
--- /dev/null
@@ -0,0 +1,69 @@
+From bf7c2ce439ca811dc1697b4bc19ab57bd8f13be3 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 16 May 2025 20:01:35 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7988: add spi controllers
+
+Add SPI controllers for mt7988.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20250516180147.10416-6-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 45 +++++++++++++++++++++++
+ 1 file changed, 45 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -311,6 +311,51 @@
+                       status = "disabled";
+               };
++              spi0: spi@11007000 {
++                      compatible = "mediatek,mt7988-spi-quad", "mediatek,spi-ipm";
++                      reg = <0 0x11007000 0 0x100>;
++                      interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&topckgen CLK_TOP_MPLL_D2>,
++                               <&topckgen CLK_TOP_SPI_SEL>,
++                               <&infracfg CLK_INFRA_104M_SPI0>,
++                               <&infracfg CLK_INFRA_66M_SPI0_HCK>;
++                      clock-names = "parent-clk", "sel-clk", "spi-clk",
++                                    "hclk";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
++              spi1: spi@11008000 {
++                      compatible = "mediatek,mt7988-spi-single", "mediatek,spi-ipm";
++                      reg = <0 0x11008000 0 0x100>;
++                      interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&topckgen CLK_TOP_MPLL_D2>,
++                               <&topckgen CLK_TOP_SPIM_MST_SEL>,
++                               <&infracfg CLK_INFRA_104M_SPI1>,
++                               <&infracfg CLK_INFRA_66M_SPI1_HCK>;
++                      clock-names = "parent-clk", "sel-clk", "spi-clk",
++                                    "hclk";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
++              spi2: spi@11009000 {
++                      compatible = "mediatek,mt7988-spi-quad", "mediatek,spi-ipm";
++                      reg = <0 0x11009000 0 0x100>;
++                      interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&topckgen CLK_TOP_MPLL_D2>,
++                               <&topckgen CLK_TOP_SPI_SEL>,
++                               <&infracfg CLK_INFRA_104M_SPI2_BCK>,
++                               <&infracfg CLK_INFRA_66M_SPI2_HCK>;
++                      clock-names = "parent-clk", "sel-clk", "spi-clk",
++                                    "hclk";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
+               lvts: lvts@1100a000 {
+                       compatible = "mediatek,mt7988-lvts-ap";
+                       #thermal-sensor-cells = <1>;
diff --git a/target/linux/mediatek/patches-6.12/175-v6.16-arm64-dts-mediatek-mt7988-move-uart0-and-spi1-pins-t.patch b/target/linux/mediatek/patches-6.12/175-v6.16-arm64-dts-mediatek-mt7988-move-uart0-and-spi1-pins-t.patch
new file mode 100644 (file)
index 0000000..54d829c
--- /dev/null
@@ -0,0 +1,90 @@
+From b9ebd166b006f77cef4530b4bf4a291a112da4f2 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 16 May 2025 20:01:36 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7988: move uart0 and spi1 pins to soc
+ dtsi
+
+In order to use uart0 or spi1 there is only 1 possible pin definition
+so move them to soc dtsi to reuse them in other boards and avoiding
+conflict if defined twice.
+
+Suggested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20250516180147.10416-7-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi  | 14 --------------
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi      | 18 ++++++++++++++++++
+ 2 files changed, 18 insertions(+), 14 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -328,13 +328,6 @@
+               };
+       };
+-      uart0_pins: uart0-pins {
+-              mux {
+-                      function = "uart";
+-                      groups =  "uart0";
+-              };
+-      };
+-
+       snfi_pins: snfi-pins {
+               mux {
+                       function = "flash";
+@@ -356,13 +349,6 @@
+               };
+       };
+-      spi1_pins: spi1-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi1";
+-              };
+-      };
+-
+       spi2_pins: spi2-pins {
+               mux {
+                       function = "spi";
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -209,6 +209,20 @@
+                                                "pcie_wake_n3_0";
+                               };
+                       };
++
++                      spi1_pins: spi1-pins {
++                              mux {
++                                      function = "spi";
++                                      groups = "spi1";
++                              };
++                      };
++
++                      uart0_pins: uart0-pins {
++                              mux {
++                                      function = "uart";
++                                      groups =  "uart0";
++                              };
++                      };
+               };
+               pwm: pwm@10048000 {
+@@ -244,6 +258,8 @@
+                       clocks = <&topckgen CLK_TOP_UART_SEL>,
+                                <&infracfg CLK_INFRA_52M_UART0_CK>;
+                       clock-names = "baud", "bus";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&uart0_pins>;
+                       status = "disabled";
+               };
+@@ -338,6 +354,8 @@
+                                     "hclk";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&spi1_pins>;
+                       status = "disabled";
+               };
diff --git a/target/linux/mediatek/patches-6.12/176-v6.17-arm64-dts-mediatek-mt7988-add-cci-node.patch b/target/linux/mediatek/patches-6.12/176-v6.17-arm64-dts-mediatek-mt7988-add-cci-node.patch
new file mode 100644 (file)
index 0000000..42a4aed
--- /dev/null
@@ -0,0 +1,86 @@
+From 0cbdb6d04689f8c05074e348c8e0a42b229ef9a3 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 6 Jul 2025 15:22:03 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7988: add cci node
+
+Add cci devicetree node for cpu frequency scaling.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250706132213.20412-9-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 33 +++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -12,6 +12,35 @@
+       #address-cells = <2>;
+       #size-cells = <2>;
++      cci: cci {
++              compatible = "mediatek,mt7988-cci", "mediatek,mt8183-cci";
++              clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>,
++                       <&topckgen CLK_TOP_XTAL>;
++              clock-names = "cci", "intermediate";
++              operating-points-v2 = <&cci_opp>;
++      };
++
++      cci_opp: opp-table-cci {
++              compatible = "operating-points-v2";
++              opp-shared;
++              opp-480000000 {
++                      opp-hz = /bits/ 64 <480000000>;
++                      opp-microvolt = <850000>;
++              };
++              opp-660000000 {
++                      opp-hz = /bits/ 64 <660000000>;
++                      opp-microvolt = <850000>;
++              };
++              opp-900000000 {
++                      opp-hz = /bits/ 64 <900000000>;
++                      opp-microvolt = <850000>;
++              };
++              opp-1080000000 {
++                      opp-hz = /bits/ 64 <1080000000>;
++                      opp-microvolt = <900000>;
++              };
++      };
++
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+@@ -25,6 +54,7 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      mediatek,cci = <&cci>;
+               };
+               cpu1: cpu@1 {
+@@ -36,6 +66,7 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      mediatek,cci = <&cci>;
+               };
+               cpu2: cpu@2 {
+@@ -47,6 +78,7 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      mediatek,cci = <&cci>;
+               };
+               cpu3: cpu@3 {
+@@ -58,6 +90,7 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      mediatek,cci = <&cci>;
+               };
+               cluster0_opp: opp-table-0 {
diff --git a/target/linux/mediatek/patches-6.12/177-v6.16-arm64-dts-mediatek-mt7988-add-phy-calibration-efuse-.patch b/target/linux/mediatek/patches-6.12/177-v6.16-arm64-dts-mediatek-mt7988-add-phy-calibration-efuse-.patch
new file mode 100644 (file)
index 0000000..b657e22
--- /dev/null
@@ -0,0 +1,42 @@
+From e4950b016c727feb0c39ad12cfcb6182c9ef3814 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 16 May 2025 20:01:38 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7988: add phy calibration efuse
+ subnodes
+
+MT7988 contains buildin mt753x switch which needs calibration data from
+efuse.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20250516180147.10416-9-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -702,6 +702,22 @@
+                       lvts_calibration: calib@918 {
+                               reg = <0x918 0x28>;
+                       };
++
++                      phy_calibration_p0: calib@940 {
++                              reg = <0x940 0x10>;
++                      };
++
++                      phy_calibration_p1: calib@954 {
++                              reg = <0x954 0x10>;
++                      };
++
++                      phy_calibration_p2: calib@968 {
++                              reg = <0x968 0x10>;
++                      };
++
++                      phy_calibration_p3: calib@97c {
++                              reg = <0x97c 0x10>;
++                      };
+               };
+               clock-controller@15000000 {
diff --git a/target/linux/mediatek/patches-6.12/178-arm64-dts-mediatek-mt7988-add-basic-ethernet-nodes.patch b/target/linux/mediatek/patches-6.12/178-arm64-dts-mediatek-mt7988-add-basic-ethernet-nodes.patch
new file mode 100644 (file)
index 0000000..15c8ad7
--- /dev/null
@@ -0,0 +1,213 @@
+From patchwork Sun May 11 14:19:24 2025
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Frank Wunderlich <linux@fw-web.de>
+X-Patchwork-Id: 14084161
+From: Frank Wunderlich <linux@fw-web.de>
+To: Andrew Lunn <andrew@lunn.ch>,
+       Vladimir Oltean <olteanv@gmail.com>,
+       "David S. Miller" <davem@davemloft.net>,
+       Eric Dumazet <edumazet@google.com>,
+       Jakub Kicinski <kuba@kernel.org>,
+       Paolo Abeni <pabeni@redhat.com>,
+       Rob Herring <robh@kernel.org>,
+       Krzysztof Kozlowski <krzk+dt@kernel.org>,
+       Conor Dooley <conor+dt@kernel.org>,
+       Matthias Brugger <matthias.bgg@gmail.com>,
+       AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Subject: [PATCH v1 08/14] arm64: dts: mediatek: mt7988: add basic
+ ethernet-nodes
+Date: Sun, 11 May 2025 16:19:24 +0200
+Message-ID: <20250511141942.10284-9-linux@fw-web.de>
+X-Mailer: git-send-email 2.43.0
+In-Reply-To: <20250511141942.10284-1-linux@fw-web.de>
+References: <20250511141942.10284-1-linux@fw-web.de>
+MIME-Version: 1.0
+X-Mail-ID: 5c8e73b6-e2d6-4898-90c0-375604707c20
+X-BeenThere: linux-mediatek@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: <linux-mediatek.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
+List-Post: <mailto:linux-mediatek@lists.infradead.org>
+List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
+Cc: devicetree@vger.kernel.org, Landen Chao <Landen.Chao@mediatek.com>,
+       =?utf-8?b?QXLEsW7DpyDDnE5BTA==?= <arinc.unal@arinc9.com>,
+ netdev@vger.kernel.org, Sean Wang <sean.wang@mediatek.com>,
+ Daniel Golle <daniel@makrotopia.org>, linux-kernel@vger.kernel.org,
+ DENG Qingfang <dqfext@gmail.com>, linux-mediatek@lists.infradead.org,
+ Lorenzo Bianconi <lorenzo@kernel.org>, linux-arm-kernel@lists.infradead.org,
+ Felix Fietkau <nbd@nbd.name>
+Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
+Errors-To: 
+ linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org
+
+From: Frank Wunderlich <frank-w@public-files.de>
+
+Add basic ethernet related nodes.
+
+Mac1+2 needs pcs (sgmii+usxgmii) to work correctly which will be linked
+later when driver is merged.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 124 +++++++++++++++++++++-
+ 1 file changed, 121 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -686,7 +686,28 @@
+                       };
+               };
+-              clock-controller@11f40000 {
++              xfi_tphy0: phy@11f20000 {
++                      compatible = "mediatek,mt7988-xfi-tphy";
++                      reg = <0 0x11f20000 0 0x10000>;
++                      resets = <&watchdog 14>;
++                      clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>,
++                               <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
++                      clock-names = "xfipll", "topxtal";
++                      mediatek,usxgmii-performance-errata;
++                      #phy-cells = <0>;
++              };
++
++              xfi_tphy1: phy@11f30000 {
++                      compatible = "mediatek,mt7988-xfi-tphy";
++                      reg = <0 0x11f30000 0 0x10000>;
++                      resets = <&watchdog 15>;
++                      clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>,
++                               <&topckgen CLK_TOP_XFI_PHY_1_XTAL_SEL>;
++                      clock-names = "xfipll", "topxtal";
++                      #phy-cells = <0>;
++              };
++
++              xfi_pll: clock-controller@11f40000 {
+                       compatible = "mediatek,mt7988-xfi-pll";
+                       reg = <0 0x11f40000 0 0x1000>;
+                       resets = <&watchdog 16>;
+@@ -720,19 +741,116 @@
+                       };
+               };
+-              clock-controller@15000000 {
++              ethsys: clock-controller@15000000 {
+                       compatible = "mediatek,mt7988-ethsys", "syscon";
+                       reg = <0 0x15000000 0 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
+-              clock-controller@15031000 {
++              ethwarp: clock-controller@15031000 {
+                       compatible = "mediatek,mt7988-ethwarp";
+                       reg = <0 0x15031000 0 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
++
++              eth: ethernet@15100000 {
++                      compatible = "mediatek,mt7988-eth";
++                      reg = <0 0x15100000 0 0x80000>,
++                            <0 0x15400000 0 0x200000>;
++                      interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ethsys CLK_ETHDMA_CRYPT0_EN>,
++                               <&ethsys CLK_ETHDMA_FE_EN>,
++                               <&ethsys CLK_ETHDMA_GP2_EN>,
++                               <&ethsys CLK_ETHDMA_GP1_EN>,
++                               <&ethsys CLK_ETHDMA_GP3_EN>,
++                               <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
++                               <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
++                               <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
++                               <&ethsys CLK_ETHDMA_ESW_EN>,
++                               <&topckgen CLK_TOP_ETH_GMII_SEL>,
++                               <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
++                               <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
++                               <&topckgen CLK_TOP_ETH_SYS_SEL>,
++                               <&topckgen CLK_TOP_ETH_XGMII_SEL>,
++                               <&topckgen CLK_TOP_ETH_MII_SEL>,
++                               <&topckgen CLK_TOP_NETSYS_SEL>,
++                               <&topckgen CLK_TOP_NETSYS_500M_SEL>,
++                               <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
++                               <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
++                               <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
++                               <&topckgen CLK_TOP_NETSYS_WARP_SEL>,
++                               <&ethsys CLK_ETHDMA_XGP1_EN>,
++                               <&ethsys CLK_ETHDMA_XGP2_EN>,
++                               <&ethsys CLK_ETHDMA_XGP3_EN>;
++                      clock-names = "crypto", "fe", "gp2", "gp1",
++                                    "gp3",
++                                    "ethwarp_wocpu2", "ethwarp_wocpu1",
++                                    "ethwarp_wocpu0", "esw", "top_eth_gmii_sel",
++                                    "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
++                                    "top_eth_sys_sel", "top_eth_xgmii_sel",
++                                    "top_eth_mii_sel", "top_netsys_sel",
++                                    "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
++                                    "top_netsys_sync_250m_sel",
++                                    "top_netsys_ppefb_250m_sel",
++                                    "top_netsys_warp_sel","xgp1", "xgp2", "xgp3";
++                      assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
++                                        <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
++                                        <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
++                                        <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
++                                        <&topckgen CLK_TOP_SGM_0_SEL>,
++                                        <&topckgen CLK_TOP_SGM_1_SEL>;
++                      assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
++                                               <&topckgen CLK_TOP_NET1PLL_D4>,
++                                               <&topckgen CLK_TOP_NET1PLL_D8_D4>,
++                                               <&topckgen CLK_TOP_NET1PLL_D8_D4>,
++                                               <&apmixedsys CLK_APMIXED_SGMPLL>,
++                                               <&apmixedsys CLK_APMIXED_SGMPLL>;
++                      mediatek,ethsys = <&ethsys>;
++                      mediatek,infracfg = <&topmisc>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      gmac0: mac@0 {
++                              compatible = "mediatek,eth-mac";
++                              reg = <0>;
++                              phy-mode = "internal";
++
++                              fixed-link {
++                                      speed = <10000>;
++                                      full-duplex;
++                                      pause;
++                              };
++                      };
++
++                      gmac1: mac@1 {
++                              compatible = "mediatek,eth-mac";
++                              reg = <1>;
++                              status = "disabled";
++                      };
++
++                      gmac2: mac@2 {
++                              compatible = "mediatek,eth-mac";
++                              reg = <2>;
++                              status = "disabled";
++                      };
++
++                      mdio_bus: mdio-bus {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              /* internal 2.5G PHY */
++                              int_2p5g_phy: ethernet-phy@f {
++                                      reg = <15>;
++                                      compatible = "ethernet-phy-ieee802.3-c45";
++                                      phy-mode = "internal";
++                              };
++                      };
++              };
+       };
+       thermal-zones {
diff --git a/target/linux/mediatek/patches-6.12/179-arm64-dts-mediatek-mt7988-add-switch-node.patch b/target/linux/mediatek/patches-6.12/179-arm64-dts-mediatek-mt7988-add-switch-node.patch
new file mode 100644 (file)
index 0000000..de43734
--- /dev/null
@@ -0,0 +1,228 @@
+From patchwork Sun May 11 14:19:25 2025
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Frank Wunderlich <linux@fw-web.de>
+X-Patchwork-Id: 14084123
+From: Frank Wunderlich <linux@fw-web.de>
+To: Andrew Lunn <andrew@lunn.ch>,
+       Vladimir Oltean <olteanv@gmail.com>,
+       "David S. Miller" <davem@davemloft.net>,
+       Eric Dumazet <edumazet@google.com>,
+       Jakub Kicinski <kuba@kernel.org>,
+       Paolo Abeni <pabeni@redhat.com>,
+       Rob Herring <robh@kernel.org>,
+       Krzysztof Kozlowski <krzk+dt@kernel.org>,
+       Conor Dooley <conor+dt@kernel.org>,
+       Matthias Brugger <matthias.bgg@gmail.com>,
+       AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Subject: [PATCH v1 09/14] arm64: dts: mediatek: mt7988: add switch node
+Date: Sun, 11 May 2025 16:19:25 +0200
+Message-ID: <20250511141942.10284-10-linux@fw-web.de>
+X-Mailer: git-send-email 2.43.0
+In-Reply-To: <20250511141942.10284-1-linux@fw-web.de>
+References: <20250511141942.10284-1-linux@fw-web.de>
+MIME-Version: 1.0
+X-Mail-ID: a24ecea1-b7fd-4cb4-a93d-b29036e2e6ac
+X-BeenThere: linux-mediatek@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: <linux-mediatek.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
+List-Post: <mailto:linux-mediatek@lists.infradead.org>
+List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
+Cc: devicetree@vger.kernel.org, Landen Chao <Landen.Chao@mediatek.com>,
+       =?utf-8?b?QXLEsW7DpyDDnE5BTA==?= <arinc.unal@arinc9.com>,
+ netdev@vger.kernel.org, Sean Wang <sean.wang@mediatek.com>,
+ Daniel Golle <daniel@makrotopia.org>, linux-kernel@vger.kernel.org,
+ DENG Qingfang <dqfext@gmail.com>, linux-mediatek@lists.infradead.org,
+ Lorenzo Bianconi <lorenzo@kernel.org>, linux-arm-kernel@lists.infradead.org,
+ Felix Fietkau <nbd@nbd.name>
+Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
+Errors-To: 
+ linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org
+
+From: Frank Wunderlich <frank-w@public-files.de>
+
+Add mt7988 builtin mt753x switch nodes.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 166 ++++++++++++++++++++++
+ 1 file changed, 166 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -5,6 +5,7 @@
+ #include <dt-bindings/phy/phy.h>
+ #include <dt-bindings/pinctrl/mt65xx.h>
+ #include <dt-bindings/reset/mediatek,mt7988-resets.h>
++#include <dt-bindings/leds/common.h>
+ / {
+       compatible = "mediatek,mt7988a";
+@@ -748,6 +749,159 @@
+                       #reset-cells = <1>;
+               };
++              switch: switch@15020000 {
++                      compatible = "mediatek,mt7988-switch";
++                      reg = <0 0x15020000 0 0x8000>;
++                      interrupt-controller;
++                      #interrupt-cells = <1>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
++                      resets = <&ethwarp MT7988_ETHWARP_RST_SWITCH>;
++
++                      ports {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              gsw_port0: port@0 {
++                                      reg = <0>;
++                                      phy-mode = "internal";
++                                      phy-handle = <&gsw_phy0>;
++                              };
++
++                              gsw_port1: port@1 {
++                                      reg = <1>;
++                                      phy-mode = "internal";
++                                      phy-handle = <&gsw_phy1>;
++                              };
++
++                              gsw_port2: port@2 {
++                                      reg = <2>;
++                                      phy-mode = "internal";
++                                      phy-handle = <&gsw_phy2>;
++                              };
++
++                              gsw_port3: port@3 {
++                                      reg = <3>;
++                                      phy-mode = "internal";
++                                      phy-handle = <&gsw_phy3>;
++                              };
++
++                              port@6 {
++                                      reg = <6>;
++                                      ethernet = <&gmac0>;
++                                      phy-mode = "internal";
++
++                                      fixed-link {
++                                              speed = <10000>;
++                                              full-duplex;
++                                              pause;
++                                      };
++                              };
++                      };
++
++                      mdio {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++                              mediatek,pio = <&pio>;
++
++                              gsw_phy0: ethernet-phy@0 {
++                                      compatible = "ethernet-phy-ieee802.3-c22";
++                                      reg = <0>;
++                                      interrupts = <0>;
++                                      phy-mode = "internal";
++                                      nvmem-cells = <&phy_calibration_p0>;
++                                      nvmem-cell-names = "phy-cal-data";
++
++                                      leds {
++                                              #address-cells = <1>;
++                                              #size-cells = <0>;
++
++                                              gsw_phy0_led0: led@0 {
++                                                      reg = <0>;
++                                                      status = "disabled";
++                                              };
++
++                                              gsw_phy0_led1: led@1 {
++                                                      reg = <1>;
++                                                      status = "disabled";
++                                              };
++                                      };
++                              };
++
++                              gsw_phy1: ethernet-phy@1 {
++                                      compatible = "ethernet-phy-ieee802.3-c22";
++                                      reg = <1>;
++                                      interrupts = <1>;
++                                      phy-mode = "internal";
++                                      nvmem-cells = <&phy_calibration_p1>;
++                                      nvmem-cell-names = "phy-cal-data";
++
++                                      leds {
++                                              #address-cells = <1>;
++                                              #size-cells = <0>;
++
++                                              gsw_phy1_led0: led@0 {
++                                                      reg = <0>;
++                                                      status = "disabled";
++                                              };
++
++                                              gsw_phy1_led1: led@1 {
++                                                      reg = <1>;
++                                                      status = "disabled";
++                                              };
++                                      };
++                              };
++
++                              gsw_phy2: ethernet-phy@2 {
++                                      compatible = "ethernet-phy-ieee802.3-c22";
++                                      reg = <2>;
++                                      interrupts = <2>;
++                                      phy-mode = "internal";
++                                      nvmem-cells = <&phy_calibration_p2>;
++                                      nvmem-cell-names = "phy-cal-data";
++
++                                      leds {
++                                              #address-cells = <1>;
++                                              #size-cells = <0>;
++
++                                              gsw_phy2_led0: led@0 {
++                                                      reg = <0>;
++                                                      status = "disabled";
++                                              };
++
++                                              gsw_phy2_led1: led@1 {
++                                                      reg = <1>;
++                                                      status = "disabled";
++                                              };
++                                      };
++                              };
++
++                              gsw_phy3: ethernet-phy@3 {
++                                      compatible = "ethernet-phy-ieee802.3-c22";
++                                      reg = <3>;
++                                      interrupts = <3>;
++                                      phy-mode = "internal";
++                                      nvmem-cells = <&phy_calibration_p3>;
++                                      nvmem-cell-names = "phy-cal-data";
++
++                                      leds {
++                                              #address-cells = <1>;
++                                              #size-cells = <0>;
++
++                                              gsw_phy3_led0: led@0 {
++                                                      reg = <0>;
++                                                      status = "disabled";
++                                              };
++
++                                              gsw_phy3_led1: led@1 {
++                                                      reg = <1>;
++                                                      status = "disabled";
++                                              };
++                                      };
++                              };
++                      };
++              };
++
+               ethwarp: clock-controller@15031000 {
+                       compatible = "mediatek,mt7988-ethwarp";
+                       reg = <0 0x15031000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/180-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-Add-fan-and-coolin.patch b/target/linux/mediatek/patches-6.12/180-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-Add-fan-and-coolin.patch
new file mode 100644 (file)
index 0000000..9b616ce
--- /dev/null
@@ -0,0 +1,59 @@
+From 0f63e96e2ab422d1d35def1da75d3df299bf503e Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 16 May 2025 20:01:41 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7988a-bpi-r4: Add fan and coolingmaps
+
+Add Fan and cooling maps for Bananapi-R4 board.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20250516180147.10416-12-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 29 +++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -12,6 +12,15 @@
+               stdout-path = "serial0:115200n8";
+       };
++      fan: pwm-fan {
++              compatible = "pwm-fan";
++              /* cooling level (0, 1, 2, 3) : (0% duty, 30% duty, 50% duty, 100% duty) */
++              cooling-levels = <0 80 128 255>;
++              #cooling-cells = <2>;
++              pwms = <&pwm 0 50000>;
++              status = "okay";
++      };
++
+       reg_1p8v: regulator-1p8v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-1.8V";
+@@ -73,6 +82,26 @@
+                       type = "active";
+               };
+       };
++
++      cooling-maps {
++              map-cpu-active-high {
++                      /* active: set fan to cooling level 2 */
++                      cooling-device = <&fan 3 3>;
++                      trip = <&cpu_trip_active_high>;
++              };
++
++              map-cpu-active-med {
++                      /* active: set fan to cooling level 1 */
++                      cooling-device = <&fan 2 2>;
++                      trip = <&cpu_trip_active_med>;
++              };
++
++              map-cpu-active-low {
++                      /* active: set fan to cooling level 0 */
++                      cooling-device = <&fan 1 1>;
++                      trip = <&cpu_trip_active_low>;
++              };
++      };
+ };
+ &i2c0 {
diff --git a/target/linux/mediatek/patches-6.12/181-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-configure-spi-node.patch b/target/linux/mediatek/patches-6.12/181-v6.16-arm64-dts-mediatek-mt7988a-bpi-r4-configure-spi-node.patch
new file mode 100644 (file)
index 0000000..cffc022
--- /dev/null
@@ -0,0 +1,55 @@
+From 6b7642e9d095d33d8034b8b396a2de9e5ecb25a7 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 16 May 2025 20:01:42 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7988a-bpi-r4: configure spi-nodes
+
+Configure and enable SPI nodes on Bananapi R4 board.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20250516180147.10416-13-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 32 +++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -401,6 +401,38 @@
+       status = "okay";
+ };
++&spi0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spi0_flash_pins>;
++      status = "okay";
++
++      spi_nand: flash@0 {
++              compatible = "spi-nand";
++              reg = <0>;
++              spi-max-frequency = <52000000>;
++              spi-tx-bus-width = <4>;
++              spi-rx-bus-width = <4>;
++      };
++};
++
++&spi1 {
++      status = "okay";
++};
++
++&spi_nand {
++      partitions {
++              compatible = "fixed-partitions";
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              partition@0 {
++                      label = "bl2";
++                      reg = <0x0 0x200000>;
++                      read-only;
++              };
++      };
++};
++
+ &ssusb1 {
+       status = "okay";
+ };
diff --git a/target/linux/mediatek/patches-6.12/182-v6.17-arm64-dts-mediatek-mt7988a-bpi-r4-add-proc-supply-fo.patch b/target/linux/mediatek/patches-6.12/182-v6.17-arm64-dts-mediatek-mt7988a-bpi-r4-add-proc-supply-fo.patch
new file mode 100644 (file)
index 0000000..68858e7
--- /dev/null
@@ -0,0 +1,28 @@
+From b5a4ad957114b59a74b3e3f598ae0785dd86cd32 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 6 Jul 2025 15:22:06 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7988a-bpi-r4: add proc-supply for cci
+
+CCI requires proc-supply. Add it on board level.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20250706132213.20412-12-linux@fw-web.de
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -40,6 +40,10 @@
+       };
+ };
++&cci {
++      proc-supply = <&rt5190_buck3>;
++};
++
+ &cpu0 {
+       proc-supply = <&rt5190_buck3>;
+ };
diff --git a/target/linux/mediatek/patches-6.12/183-arm64-dts-mediatek-mt7988a-bpi-r4-add-sfp-cages-and-link-to-gmac.patch b/target/linux/mediatek/patches-6.12/183-arm64-dts-mediatek-mt7988a-bpi-r4-add-sfp-cages-and-link-to-gmac.patch
new file mode 100644 (file)
index 0000000..9861dc0
--- /dev/null
@@ -0,0 +1,138 @@
+From patchwork Sun May 11 14:26:53 2025
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Frank Wunderlich <frank-w@public-files.de>
+X-Patchwork-Id: 14084128
+From: Frank Wunderlich <frank-w@public-files.de>
+To: Andrew Lunn <andrew@lunn.ch>,
+       Vladimir Oltean <olteanv@gmail.com>,
+       "David S. Miller" <davem@davemloft.net>,
+       Eric Dumazet <edumazet@google.com>,
+       Jakub Kicinski <kuba@kernel.org>,
+       Paolo Abeni <pabeni@redhat.com>,
+       Rob Herring <robh@kernel.org>,
+       Krzysztof Kozlowski <krzk+dt@kernel.org>,
+       Conor Dooley <conor+dt@kernel.org>,
+       Matthias Brugger <matthias.bgg@gmail.com>,
+       AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Subject: [PATCH v1 13/14] arm64: dts: mediatek: mt7988a-bpi-r4: add sfp cages
+ and link to gmac
+Date: Sun, 11 May 2025 16:26:53 +0200
+Message-ID: <20250511142655.11007-4-frank-w@public-files.de>
+X-Mailer: git-send-email 2.43.0
+In-Reply-To: <20250511142655.11007-1-frank-w@public-files.de>
+References: <20250511142655.11007-1-frank-w@public-files.de>
+MIME-Version: 1.0
+X-BeenThere: linux-mediatek@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: <linux-mediatek.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
+List-Post: <mailto:linux-mediatek@lists.infradead.org>
+List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
+Cc: devicetree@vger.kernel.org, Landen Chao <Landen.Chao@mediatek.com>,
+       =?utf-8?b?QXLEsW7DpyDDnE5BTA==?= <arinc.unal@arinc9.com>,
+ netdev@vger.kernel.org, Sean Wang <sean.wang@mediatek.com>,
+ Daniel Golle <daniel@makrotopia.org>, linux-kernel@vger.kernel.org,
+ DENG Qingfang <dqfext@gmail.com>, linux-mediatek@lists.infradead.org,
+ Lorenzo Bianconi <lorenzo@kernel.org>, linux-arm-kernel@lists.infradead.org,
+ Felix Fietkau <nbd@nbd.name>
+Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
+Errors-To: 
+ linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org
+
+Add SFP cages to Bananapi-R4 board. The 2.5g phy variant only contains the
+wan-SFP, so add this to common dtsi and the lan-sfp only to the dual-SFP
+variant.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ .../mediatek/mt7988a-bananapi-bpi-r4-2g5.dts   | 11 +++++++++++
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dts   | 18 ++++++++++++++++++
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi  | 18 ++++++++++++++++++
+ 3 files changed, 47 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts
+@@ -9,3 +9,14 @@
+       model = "Banana Pi BPI-R4 (1x SFP+, 1x 2.5GbE)";
+       chassis-type = "embedded";
+ };
++
++&gmac1 {
++      phy-mode = "internal";
++      phy-connection-type = "internal";
++      phy = <&int_2p5g_phy>;
++};
++
++&int_2p5g_phy {
++      pinctrl-names = "i2p5gbe-led";
++      pinctrl-0 = <&i2p5gbe_led0_pins>;
++};
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -8,6 +8,24 @@
+       compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+       model = "Banana Pi BPI-R4 (2x SFP+)";
+       chassis-type = "embedded";
++
++      /* SFP2 cage (LAN) */
++      sfp2: sfp2 {
++              compatible = "sff,sfp";
++              i2c-bus = <&i2c_sfp2>;
++              los-gpios = <&pio 2 GPIO_ACTIVE_HIGH>;
++              mod-def0-gpios = <&pio 83 GPIO_ACTIVE_LOW>;
++              tx-disable-gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
++              tx-fault-gpios = <&pio 1 GPIO_ACTIVE_HIGH>;
++              rate-select0-gpios = <&pio 3 GPIO_ACTIVE_LOW>;
++              maximum-power-milliwatt = <3000>;
++      };
++};
++
++&gmac1 {
++      sfp = <&sfp2>;
++      managed = "in-band-status";
++      phy-mode = "usxgmii";
+ };
+ &pca9545 {
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -38,6 +38,18 @@
+               regulator-boot-on;
+               regulator-always-on;
+       };
++
++      /* SFP1 cage (WAN) */
++      sfp1: sfp1 {
++              compatible = "sff,sfp";
++              i2c-bus = <&i2c_sfp1>;
++              los-gpios = <&pio 54 GPIO_ACTIVE_HIGH>;
++              mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>;
++              tx-disable-gpios = <&pio 70 GPIO_ACTIVE_HIGH>;
++              tx-fault-gpios = <&pio 69 GPIO_ACTIVE_HIGH>;
++              rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>;
++              maximum-power-milliwatt = <3000>;
++      };
+ };
+ &cci {
+@@ -108,6 +120,12 @@
+       };
+ };
++&gmac2 {
++      sfp = <&sfp1>;
++      managed = "in-band-status";
++      phy-mode = "usxgmii";
++};
++
+ &i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
diff --git a/target/linux/mediatek/patches-6.12/184-arm64-dts-mediatek-mt7988a-bpi-r4-configure-switch-phys-and-leds.patch b/target/linux/mediatek/patches-6.12/184-arm64-dts-mediatek-mt7988a-bpi-r4-configure-switch-phys-and-leds.patch
new file mode 100644 (file)
index 0000000..0bdc6c9
--- /dev/null
@@ -0,0 +1,113 @@
+From patchwork Sun May 11 14:26:54 2025
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Frank Wunderlich <frank-w@public-files.de>
+X-Patchwork-Id: 14084132
+From: Frank Wunderlich <frank-w@public-files.de>
+To: Andrew Lunn <andrew@lunn.ch>,
+       Vladimir Oltean <olteanv@gmail.com>,
+       "David S. Miller" <davem@davemloft.net>,
+       Eric Dumazet <edumazet@google.com>,
+       Jakub Kicinski <kuba@kernel.org>,
+       Paolo Abeni <pabeni@redhat.com>,
+       Rob Herring <robh@kernel.org>,
+       Krzysztof Kozlowski <krzk+dt@kernel.org>,
+       Conor Dooley <conor+dt@kernel.org>,
+       Matthias Brugger <matthias.bgg@gmail.com>,
+       AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Subject: [PATCH v1 14/14] arm64: dts: mediatek: mt7988a-bpi-r4: configure
+ switch phys and leds
+Date: Sun, 11 May 2025 16:26:54 +0200
+Message-ID: <20250511142655.11007-5-frank-w@public-files.de>
+X-Mailer: git-send-email 2.43.0
+In-Reply-To: <20250511142655.11007-1-frank-w@public-files.de>
+References: <20250511142655.11007-1-frank-w@public-files.de>
+MIME-Version: 1.0
+X-BeenThere: linux-mediatek@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: <linux-mediatek.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
+List-Post: <mailto:linux-mediatek@lists.infradead.org>
+List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
+Cc: devicetree@vger.kernel.org, Landen Chao <Landen.Chao@mediatek.com>,
+       =?utf-8?b?QXLEsW7DpyDDnE5BTA==?= <arinc.unal@arinc9.com>,
+ netdev@vger.kernel.org, Sean Wang <sean.wang@mediatek.com>,
+ Daniel Golle <daniel@makrotopia.org>, linux-kernel@vger.kernel.org,
+ DENG Qingfang <dqfext@gmail.com>, linux-mediatek@lists.infradead.org,
+ Lorenzo Bianconi <lorenzo@kernel.org>, linux-arm-kernel@lists.infradead.org,
+ Felix Fietkau <nbd@nbd.name>
+Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
+Errors-To: 
+ linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org
+
+Assign pinctrl to switch phys and leds.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ .../dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi | 40 +++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -126,6 +126,54 @@
+       phy-mode = "usxgmii";
+ };
++&gsw_phy0 {
++      pinctrl-names = "gbe-led";
++      label = "wan";
++      pinctrl-0 = <&gbe0_led0_pins>;
++};
++
++&gsw_phy0_led0 {
++      status = "okay";
++      function = LED_FUNCTION_WAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_phy1 {
++      pinctrl-names = "gbe-led";
++      label = "lan1";
++      pinctrl-0 = <&gbe1_led0_pins>;
++};
++
++&gsw_phy1_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_phy2 {
++      pinctrl-names = "gbe-led";
++      label = "lan2";
++      pinctrl-0 = <&gbe2_led0_pins>;
++};
++
++&gsw_phy2_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_phy3 {
++      pinctrl-names = "gbe-led";
++      label = "lan3";
++      pinctrl-0 = <&gbe3_led0_pins>;
++};
++
++&gsw_phy3_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
+ &i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
diff --git a/target/linux/mediatek/patches-6.12/185-arm64-dts-mt7988a-add-serial1-and-serial2-aliases.patch b/target/linux/mediatek/patches-6.12/185-arm64-dts-mt7988a-add-serial1-and-serial2-aliases.patch
new file mode 100644 (file)
index 0000000..efa2121
--- /dev/null
@@ -0,0 +1,33 @@
+From 109a9c8409f85d777f8ffa3fe145498a1fec0f1e Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 8 May 2025 04:03:58 +0100
+Subject: [PATCH] arm64: dts: mt7988a: add serial1 and serial2 aliases
+
+Add aliases serial1 and serial2, so boards can make use of the
+auxilary UARTs of the MediaTek MT7988 SoC.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -297,7 +297,7 @@
+                       status = "disabled";
+               };
+-              serial@11000100 {
++              serial1: serial@11000100 {
+                       compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
+                       reg = <0 0x11000100 0 0x100>;
+                       interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+@@ -308,7 +308,7 @@
+                       status = "disabled";
+               };
+-              serial@11000200 {
++              serial2: serial@11000200 {
+                       compatible = "mediatek,mt7988-uart", "mediatek,mt6577-uart";
+                       reg = <0 0x11000200 0 0x100>;
+                       interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/target/linux/mediatek/patches-6.12/186-arm64-dts-mt7988a-complete-dtsi.patch b/target/linux/mediatek/patches-6.12/186-arm64-dts-mt7988a-complete-dtsi.patch
new file mode 100644 (file)
index 0000000..b7c609f
--- /dev/null
@@ -0,0 +1,235 @@
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 26 Jun 2025 00:54:32 +0100
+Subject: [PATCH] arm64: dts: mt7988a: complete dtsi
+
+Work-in-progress patch to complete mt7988a.dtsi
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -193,7 +193,7 @@
+               };
+               pio: pinctrl@1001f000 {
+-                      compatible = "mediatek,mt7988-pinctrl";
++                      compatible = "mediatek,mt7988-pinctrl", "syscon";
+                       reg = <0 0x1001f000 0 0x1000>,
+                             <0 0x11c10000 0 0x1000>,
+                             <0 0x11d00000 0 0x1000>,
+@@ -212,6 +212,13 @@
+                       interrupt-parent = <&gic>;
+                       #interrupt-cells = <2>;
++                      snfi_pins: snfi-pins {
++                              mux {
++                                      function = "flash";
++                                      groups = "snfi";
++                              };
++                      };
++
+                       pcie0_pins: pcie0-pins {
+                               mux {
+                                       function = "pcie";
+@@ -278,6 +285,60 @@
+                       status = "disabled";
+               };
++              sgmiisys0: syscon@10060000 {
++                      compatible = "mediatek,mt7988-sgmiisys",
++                                   "mediatek,mt7988-sgmiisys0",
++                                   "syscon",
++                                   "simple-mfd";
++                      reg = <0 0x10060000 0 0x1000>;
++                      resets = <&watchdog 1>;
++                      #clock-cells = <1>;
++
++                      sgmiipcs0: pcs {
++                              compatible = "mediatek,mt7988-sgmii";
++                              clocks = <&topckgen CLK_TOP_SGM_0_SEL>,
++                                       <&sgmiisys0 CLK_SGM0_TX_EN>,
++                                       <&sgmiisys0 CLK_SGM0_RX_EN>;
++                              clock-names = "sgmii_sel", "sgmii_tx", "sgmii_rx";
++                              #pcs-cells = <0>;
++                      };
++              };
++
++              sgmiisys1: syscon@10070000 {
++                      compatible = "mediatek,mt7988-sgmiisys",
++                                   "mediatek,mt7988-sgmiisys1",
++                                   "syscon",
++                                   "simple-mfd";
++                      reg = <0 0x10070000 0 0x1000>;
++                      resets = <&watchdog 2>;
++                      #clock-cells = <1>;
++
++                      sgmiipcs1: pcs {
++                              compatible = "mediatek,mt7988-sgmii";
++                              clocks = <&topckgen CLK_TOP_SGM_1_SEL>,
++                                       <&sgmiisys1 CLK_SGM1_TX_EN>,
++                                       <&sgmiisys1 CLK_SGM1_RX_EN>;
++                              clock-names = "sgmii_sel", "sgmii_tx", "sgmii_rx";
++                              #pcs-cells = <0>;
++                      };
++              };
++
++              usxgmiisys0: pcs@10080000 {
++                      compatible = "mediatek,mt7988-usxgmiisys";
++                      reg = <0 0x10080000 0 0x1000>;
++                      resets = <&watchdog 12>;
++                      clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>;
++                      #pcs-cells = <0>;
++              };
++
++              usxgmiisys1: pcs@10081000 {
++                      compatible = "mediatek,mt7988-usxgmiisys";
++                      reg = <0 0x10081000 0 0x1000>;
++                      resets = <&watchdog 13>;
++                      clocks = <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>;
++                      #pcs-cells = <0>;
++              };
++
+               mcusys: mcusys@100e0000 {
+                       compatible = "mediatek,mt7988-mcusys", "syscon";
+                       reg = <0 0x100e0000 0 0x1000>;
+@@ -319,6 +380,32 @@
+                       status = "disabled";
+               };
++              snand: spi@11001000 {
++                      compatible = "mediatek,mt7986-snand";
++                      reg = <0 0x11001000 0 0x1000>;
++                      interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_SPINFI>,
++                               <&infracfg CLK_INFRA_NFI>,
++                               <&infracfg CLK_INFRA_66M_NFI_HCK>;
++                      clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
++                      nand-ecc-engine = <&bch>;
++                      mediatek,quad-spi;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&snfi_pins>;
++                      status = "disabled";
++              };
++
++              bch: ecc@11002000 {
++                      compatible = "mediatek,mt7686-ecc";
++                      reg = <0 0x11002000 0 0x1000>;
++                      interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_NFI>;
++                      clock-names = "nfiecc_clk";
++                      status = "disabled";
++              };
++
+               i2c0: i2c@11003000 {
+                       compatible = "mediatek,mt7981-i2c";
+                       reg = <0 0x11003000 0 0x1000>,
+@@ -425,7 +512,7 @@
+                             <0 0x0f0f0018 0 0x20>;
+               };
+-              usb@11190000 {
++              ssusb0: usb@11190000 {
+                       compatible = "mediatek,mt7988-xhci", "mediatek,mtk-xhci";
+                       reg = <0 0x11190000 0 0x2e00>,
+                             <0 0x11193e00 0 0x0100>;
+@@ -459,6 +546,35 @@
+                       status = "disabled";
+               };
++              afe: audio-controller@11210000 {
++                      compatible = "mediatek,mt79xx-audio";
++                      reg = <0 0x11210000 0 0x9000>;
++                      interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_66M_AUD_SLV_BCK>,
++                               <&infracfg CLK_INFRA_AUD_26M>,
++                               <&infracfg CLK_INFRA_AUD_L>,
++                               <&infracfg CLK_INFRA_AUD_AUD>,
++                               <&infracfg CLK_INFRA_AUD_EG2>,
++                               <&topckgen CLK_TOP_AUD_SEL>,
++                               <&topckgen CLK_TOP_AUD_I2S_M>;
++                      clock-names = "aud_bus_ck",
++                                    "aud_26m_ck",
++                                    "aud_l_ck",
++                                    "aud_aud_ck",
++                                    "aud_eg2_ck",
++                                    "aud_sel",
++                                    "aud_i2s_m";
++                      assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>,
++                                        <&topckgen CLK_TOP_A1SYS_SEL>,
++                                        <&topckgen CLK_TOP_AUD_L_SEL>,
++                                        <&topckgen CLK_TOP_A_TUNER_SEL>;
++                      assigned-clock-parents = <&apmixedsys CLK_APMIXED_APLL2>,
++                                               <&topckgen CLK_TOP_APLL2_D4>,
++                                               <&apmixedsys CLK_APMIXED_APLL2>,
++                                               <&topckgen CLK_TOP_APLL2_D4>;
++                      status = "disabled";
++              };
++
+               mmc0: mmc@11230000 {
+                       compatible = "mediatek,mt7988-mmc";
+                       reg = <0 0x11230000 0 0x1000>,
+@@ -721,6 +837,10 @@
+                       #address-cells = <1>;
+                       #size-cells = <1>;
++                      cpufreq_calibration: calib@278 {
++                              reg = <0x278 0x1>;
++                      };
++
+                       lvts_calibration: calib@918 {
+                               reg = <0x918 0x28>;
+                       };
+@@ -984,12 +1104,16 @@
+                       gmac1: mac@1 {
+                               compatible = "mediatek,eth-mac";
+                               reg = <1>;
++                              pcs-handle = <&sgmiipcs1>, <&usxgmiisys1>;
++                              phys = <&xfi_tphy1>;
+                               status = "disabled";
+                       };
+                       gmac2: mac@2 {
+                               compatible = "mediatek,eth-mac";
+                               reg = <2>;
++                              pcs-handle = <&sgmiipcs0>, <&usxgmiisys0>;
++                              phys = <&xfi_tphy0>;
+                               status = "disabled";
+                       };
+@@ -1002,9 +1126,37 @@
+                                       reg = <15>;
+                                       compatible = "ethernet-phy-ieee802.3-c45";
+                                       phy-mode = "internal";
++
++                                      leds {
++                                              #address-cells = <1>;
++                                              #size-cells = <0>;
++
++                                              i2p5gbe_led0: i2p5gbe-led0@0 {
++                                                      reg = <0>;
++                                                      function = LED_FUNCTION_LAN;
++                                                      status = "disabled";
++                                              };
++
++                                              i2p5gbe_led1: i2p5gbe-led1@1 {
++                                                      reg = <1>;
++                                                      function = LED_FUNCTION_LAN;
++                                                      status = "disabled";
++                                              };
++                                      };
+                               };
+                       };
+               };
++
++              crypto: crypto@15600000 {
++                      compatible = "inside-secure,safexcel-eip197b";
++                      reg = <0 0x15600000 0 0x180000>;
++                      interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "ring0", "ring1", "ring2", "ring3";
++                      status = "okay";
++              };
+       };
+       thermal-zones {
diff --git a/target/linux/mediatek/patches-6.12/187-arm64-dts-mediatek-fix-mt7981-spim-clock.patch b/target/linux/mediatek/patches-6.12/187-arm64-dts-mediatek-fix-mt7981-spim-clock.patch
new file mode 100644 (file)
index 0000000..9e89a19
--- /dev/null
@@ -0,0 +1,53 @@
+From 0c74ae06ed6b6c9627712a74ecee4e61bbd4092d Mon Sep 17 00:00:00 2001
+From: developer <developer@mediatek.com>
+Date: Mon, 19 Jan 2026 21:42:29 +0800
+Subject: [PATCH] arm64: dts: mediatek: fix mt7981 spim clock
+
+1) Add spi0/1/2 clock parent setting
+2) Fix spi1 clock_sel to CLK_TOP_SPIM_MST_SEL
+
+Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/836034ca0baad57e4c287a62ccc5677c60be0e18
+Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7981b.dtsi | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
+@@ -223,6 +223,10 @@
+                                <&topckgen CLK_TOP_SPI_SEL>,
+                                <&infracfg CLK_INFRA_SPI2_CK>,
+                                <&infracfg CLK_INFRA_SPI2_HCK_CK>;
++                      assigned-clocks = <&topckgen CLK_TOP_SPI_SEL>,
++                                        <&infracfg CLK_INFRA_SPI2_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
++                                               <&topckgen CLK_TOP_SPI_SEL>;
+                       clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+@@ -237,6 +241,10 @@
+                                <&topckgen CLK_TOP_SPI_SEL>,
+                                <&infracfg CLK_INFRA_SPI0_CK>,
+                                <&infracfg CLK_INFRA_SPI0_HCK_CK>;
++                      assigned-clocks = <&topckgen CLK_TOP_SPI_SEL>,
++                                        <&infracfg CLK_INFRA_SPI0_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
++                                               <&topckgen CLK_TOP_SPI_SEL>;
+                       clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+@@ -248,9 +256,13 @@
+                       reg = <0 0x1100b000 0 0x1000>;
+                       interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&topckgen CLK_TOP_CB_M_D2>,
+-                               <&topckgen CLK_TOP_SPI_SEL>,
++                               <&topckgen CLK_TOP_SPIM_MST_SEL>,
+                                <&infracfg CLK_INFRA_SPI1_CK>,
+                                <&infracfg CLK_INFRA_SPI1_HCK_CK>;
++                      assigned-clocks = <&topckgen CLK_TOP_SPIM_MST_SEL>,
++                                        <&infracfg CLK_INFRA_SPI1_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
++                                               <&topckgen CLK_TOP_SPIM_MST_SEL>;
+                       clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
diff --git a/target/linux/mediatek/patches-6.12/188-arm64-dts-mediatek-add-MT7988A-reference-board-devic.patch b/target/linux/mediatek/patches-6.12/188-arm64-dts-mediatek-add-MT7988A-reference-board-devic.patch
new file mode 100644 (file)
index 0000000..0e0236c
--- /dev/null
@@ -0,0 +1,1293 @@
+From bb72bb160130c35fa4b7dedd0f881085f0af1313 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 22 Feb 2023 19:15:49 +0000
+Subject: [PATCH 31/32] dts: arm64: mediatek: add MT7988A reference board
+ device tree
+
+Complete device tree include for the MediaTek MT7988A SoC and make use
+of it by adding the device tree of the MediaTek MT7988A Reference Board
+as well as overlays for various options regarding the connected
+network interfaces and storage devices present.
+
+Available options for GMAC1 (eth0):
+ * internal 4-port 1GE switch
+
+Available options for GMAC2 (eth1):
+ * internal 2.5G PHY
+ * external MaxLinear 2.5G PHY
+ * external Aquantia AQR113C PHY
+ * SFP+ cage
+
+Available options for GMAC3 (eth2):
+ * external MaxLinear 2.5G PHY
+ * external Aquantia AQR113C PHY
+ * SFP+ cage
+
+Available storage options:
+ * eMMC
+ * SNFI (ECC-less SPI-NAND with BCH done in SoC)
+ * SPI-NAND (with ECC done by the flash die)
+ * SPI-NOR
+ * SD card
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+--- a/arch/arm64/boot/dts/mediatek/Makefile
++++ b/arch/arm64/boot/dts/mediatek/Makefile
+@@ -24,6 +24,19 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-b
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-2g5.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-emmc.dtbo
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4-sd.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb.dtb
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-emmc.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth1-aqr.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth1-i2p5g-phy.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth1-mxl.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth1-sfp.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth2-aqr.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth2-mxl.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-eth2-sfp.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-sd.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-snfi-nand.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-spim-nand.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-rfb-spim-nor.dtbo
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-emmc.dtso
+@@ -0,0 +1,62 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2021 MediaTek Inc.
++ * Author: Frank Wunderlich <frank-w@public-files.de>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&mmc0>;
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      pinctrl-names = "default", "state_uhs";
++                      pinctrl-0 = <&mmc0_pins_emmc_51>;
++                      pinctrl-1 = <&mmc0_pins_emmc_51>;
++                      bus-width = <8>;
++                      max-frequency = <200000000>;
++                      cap-mmc-highspeed;
++                      mmc-hs200-1_8v;
++                      mmc-hs400-1_8v;
++                      hs400-ds-delay = <0x12814>;
++                      vqmmc-supply = <&reg_1p8v>;
++                      vmmc-supply = <&reg_3p3v>;
++                      non-removable;
++                      no-sd;
++                      no-sdio;
++                      status = "okay";
++
++                      card@0 {
++                              compatible = "mmc-card";
++                              reg = <0>;
++
++                              partitions {
++                                      compatible = "gpt-partitions";
++
++                                      block-partition-env {
++                                              partname = "ubootenv";
++                                              nvmem-layout {
++                                                      compatible = "u-boot,env-layout";
++                                              };
++                                      };
++
++                                      emmc_root: block-partition-production {
++                                              partname = "production";
++                                      };
++                              };
++                      };
++              };
++      };
++
++      fragment@1 {
++              target-path = "/chosen";
++              __overlay__ {
++                      rootdisk-emmc = <&emmc_root>;
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-aqr.dtso
+@@ -0,0 +1,41 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&mdio_bus>;
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* external Aquantia AQR113C */
++                      phy0: ethernet-phy@0 {
++                              reg = <0>;
++                              compatible = "ethernet-phy-ieee802.3-c45";
++                              reset-gpios = <&pio 72 GPIO_ACTIVE_LOW>;
++                              reset-assert-us = <100000>;
++                              reset-deassert-us = <221000>;
++                      };
++              };
++      };
++
++      fragment@1 {
++              target = <&gmac1>;
++              __overlay__ {
++                      phy-mode = "usxgmii";
++                      phy-connection-type = "usxgmii";
++                      phy = <&phy0>;
++                      status = "okay";
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-i2p5g-phy.dtso
+@@ -0,0 +1,30 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&gmac1>;
++              __overlay__ {
++                      phy-mode = "internal";
++                      phy-connection-type = "internal";
++                      phy = <&int_2p5g_phy>;
++                      status = "okay";
++              };
++      };
++
++      fragment@1 {
++              target = <&int_2p5g_phy>;
++              __overlay__ {
++                      pinctrl-names = "i2p5gbe-led";
++                      pinctrl-0 = <&i2p5gbe_led0_pins>;
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-mxl.dtso
+@@ -0,0 +1,39 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&mdio_bus>;
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* external Maxlinear GPY211C */
++                      phy13: ethernet-phy@13 {
++                              reg = <13>;
++                              compatible = "ethernet-phy-ieee802.3-c45";
++                              phy-mode = "2500base-x";
++                      };
++              };
++      };
++
++      fragment@1 {
++              target = <&gmac1>;
++              __overlay__ {
++                      phy-mode = "2500base-x";
++                      phy-connection-type = "2500base-x";
++                      phy = <&phy13>;
++                      status = "okay";
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth1-sfp.dtso
+@@ -0,0 +1,47 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&i2c2>;
++              __overlay__ {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&i2c2_pins>;
++                      status = "okay";
++              };
++      };
++
++      fragment@1 {
++              target-path = "/";
++              __overlay__ {
++                      sfp_esp1: sfp@1 {
++                              compatible = "sff,sfp";
++                              i2c-bus = <&i2c2>;
++                              mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>;
++                              los-gpios = <&pio 81 GPIO_ACTIVE_HIGH>;
++                              tx-disable-gpios = <&pio 36 GPIO_ACTIVE_HIGH>;
++                              maximum-power-milliwatt = <3000>;
++                      };
++              };
++      };
++
++      fragment@2 {
++              target = <&gmac1>;
++              __overlay__ {
++                      phy-mode = "10gbase-r";
++                      managed = "in-band-status";
++                      sfp = <&sfp_esp1>;
++                      status = "okay";
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-aqr.dtso
+@@ -0,0 +1,41 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&mdio_bus>;
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* external Aquantia AQR113C */
++                      phy8: ethernet-phy@8 {
++                              reg = <8>;
++                              compatible = "ethernet-phy-ieee802.3-c45";
++                              reset-gpios = <&pio 71 GPIO_ACTIVE_LOW>;
++                              reset-assert-us = <100000>;
++                              reset-deassert-us = <221000>;
++                      };
++              };
++      };
++
++      fragment@1 {
++              target = <&gmac2>;
++              __overlay__ {
++                      phy-mode = "usxgmii";
++                      phy-connection-type = "usxgmii";
++                      phy = <&phy8>;
++                      status = "okay";
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-mxl.dtso
+@@ -0,0 +1,39 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&mdio_bus>;
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      /* external Maxlinear GPY211C */
++                      phy5: ethernet-phy@5 {
++                              reg = <5>;
++                              compatible = "ethernet-phy-ieee802.3-c45";
++                              phy-mode = "2500base-x";
++                      };
++              };
++      };
++
++      fragment@1 {
++              target = <&gmac2>;
++              __overlay__ {
++                      phy-mode = "2500base-x";
++                      phy-connection-type = "2500base-x";
++                      phy = <&phy5>;
++                      status = "okay";
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-eth2-sfp.dtso
+@@ -0,0 +1,47 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&i2c1>;
++              __overlay__ {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&i2c1_pins>;
++                      status = "okay";
++              };
++      };
++
++      fragment@1 {
++              target-path = "/";
++              __overlay__ {
++                      sfp_esp0: sfp@0 {
++                              compatible = "sff,sfp";
++                              i2c-bus = <&i2c1>;
++                              mod-def0-gpios = <&pio 35 GPIO_ACTIVE_LOW>;
++                              los-gpios = <&pio 33 GPIO_ACTIVE_HIGH>;
++                              tx-disable-gpios = <&pio 29 GPIO_ACTIVE_HIGH>;
++                              maximum-power-milliwatt = <3000>;
++                      };
++              };
++      };
++
++      fragment@2 {
++              target = <&gmac2>;
++              __overlay__ {
++                      phy-mode = "10gbase-r";
++                      managed = "in-band-status";
++                      sfp = <&sfp_esp0>;
++                      status = "okay";
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-sd.dtso
+@@ -0,0 +1,60 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2023 MediaTek Inc.
++ * Author: Frank Wunderlich <frank-w@public-files.de>
++ */
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target-path = <&mmc0>;
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      pinctrl-names = "default", "state_uhs";
++                      pinctrl-0 = <&mmc0_pins_sdcard>;
++                      pinctrl-1 = <&mmc0_pins_sdcard>;
++                      cd-gpios = <&pio 69 GPIO_ACTIVE_LOW>;
++                      bus-width = <4>;
++                      max-frequency = <52000000>;
++                      cap-sd-highspeed;
++                      vmmc-supply = <&reg_3p3v>;
++                      vqmmc-supply = <&reg_3p3v>;
++                      no-mmc;
++                      status = "okay";
++
++                      card@0 {
++                              compatible = "mmc-card";
++                              reg = <0>;
++
++                              partitions {
++                                      compatible = "gpt-partitions";
++
++                                      block-partition-env {
++                                              partname = "ubootenv";
++                                              nvmem-layout {
++                                                      compatible = "u-boot,env-layout";
++                                              };
++                                      };
++
++                                      sd_root: block-partition-production {
++                                              partname = "production";
++                                      };
++                              };
++                      };
++              };
++      };
++
++      fragment@1 {
++              target-path = "/chosen";
++              __overlay__ {
++                      rootdisk-sd = <&sd_root>;
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-snfi-nand.dtso
+@@ -0,0 +1,85 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&snand>;
++              __overlay__ {
++                      status = "okay";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      flash@0 {
++                              compatible = "spi-nand";
++                              reg = <0>;
++                              spi-max-frequency = <52000000>;
++                              spi-tx-bus-width = <4>;
++                              spi-rx-bus-width = <4>;
++
++                              partitions {
++                                      compatible = "fixed-partitions";
++                                      #address-cells = <1>;
++                                      #size-cells = <1>;
++
++                                      partition@0 {
++                                              label = "BL2";
++                                              reg = <0x00000 0x0200000>;
++                                              read-only;
++                                      };
++
++                                      ubi_part: partition@200000 {
++                                              label = "ubi";
++                                              reg = <0x0200000 0x7e00000>;
++                                              compatible = "linux,ubi";
++
++                                              volumes {
++                                                      ubi-volume-ubootenv {
++                                                              volname = "ubootenv";
++                                                              nvmem-layout {
++                                                                      compatible = "u-boot,env-redundant-bool";
++                                                              };
++                                                      };
++
++                                                      ubi-volume-ubootenv2 {
++                                                              volname = "ubootenv2";
++                                                              nvmem-layout {
++                                                                      compatible = "u-boot,env-redundant-bool";
++                                                              };
++                                                      };
++
++                                                      snfi_root: ubi-volume-fit {
++                                                              volname = "fit";
++                                                      };
++                                              };
++                                      };
++                              };
++                      };
++              };
++      };
++
++      fragment@1 {
++              target = <&bch>;
++              __overlay__ {
++                      status = "okay";
++              };
++      };
++
++      fragment@2 {
++              target-path = "/chosen";
++              __overlay__ {
++                      /*
++                       * U-Boot currently cannot detect diffrentiate between
++                       * SD and SNFI boot media and always uses rootdisk-sd in
++                       * both cases
++                       */
++                      rootdisk-sd = <&snfi_root>;
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand-factory.dtso
+@@ -0,0 +1,87 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&ubi_part>;
++
++              __overlay__ {
++                      volumes {
++                              ubi_factory: ubi-volume-factory {
++                                      volname = "factory";
++
++                                      nvmem-layout {
++                                              compatible = "fixed-layout";
++                                              #address-cells = <1>;
++                                              #size-cells = <1>;
++
++                                              eeprom_wmac: eeprom@0 {
++                                                      reg = <0x0 0x1e00>;
++                                              };
++
++                                              gmac2_mac: eeprom@fffee {
++                                                      reg = <0xfffee 0x6>;
++                                              };
++
++                                              gmac1_mac: eeprom@ffff4 {
++                                                      reg = <0xffff4 0x6>;
++                                              };
++
++                                              gmac0_mac: eeprom@ffffa {
++                                                      reg = <0xffffa 0x6>;
++                                              };
++                                      };
++                              };
++                      };
++              };
++      };
++
++      fragment@1 {
++              target = <&pcie0>;
++              __overlay__ {
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++
++                      pcie@0,0 {
++                              reg = <0x0000 0 0 0 0>;
++                              #address-cells = <3>;
++                              #size-cells = <2>;
++
++                              wifi@0,0 {
++                                      compatible = "mediatek,mt76";
++                                      reg = <0x0000 0 0 0 0>;
++                                      nvmem-cell-names = "eeprom";
++                                      nvmem-cells = <&eeprom_wmac>;
++                              };
++                      };
++              };
++      };
++
++      fragment@2 {
++              target = <&gmac0>;
++              __overlay__ {
++                      nvmem-cell-names = "mac-address";
++                      nvmem-cells = <&gmac0_mac>;
++              };
++      };
++
++      fragment@3 {
++              target = <&gmac1>;
++              __overlay__ {
++                      nvmem-cell-names = "mac-address";
++                      nvmem-cells = <&gmac1_mac>;
++              };
++      };
++
++      fragment@4 {
++              target = <&gmac2>;
++              __overlay__ {
++                      nvmem-cell-names = "mac-address";
++                      nvmem-cells = <&gmac2_mac>;
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nand.dtso
+@@ -0,0 +1,77 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&spi0>;
++              __overlay__ {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&spi0_flash_pins>;
++                      status = "okay";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      flash@0 {
++                              compatible = "spi-nand";
++                              reg = <0>;
++                              spi-max-frequency = <52000000>;
++                              spi-tx-bus-width = <4>;
++                              spi-rx-bus-width = <4>;
++
++                              partitions {
++                                      compatible = "fixed-partitions";
++                                      #address-cells = <1>;
++                                      #size-cells = <1>;
++
++                                      partition@0 {
++                                              label = "BL2";
++                                              reg = <0x00000 0x0200000>;
++                                              read-only;
++                                      };
++
++                                      ubi_part: partition@200000 {
++                                              label = "ubi";
++                                              reg = <0x0200000 0x7e00000>;
++                                              compatible = "linux,ubi";
++
++                                              volumes {
++                                                      ubi-volume-ubootenv {
++                                                              volname = "ubootenv";
++                                                              nvmem-layout {
++                                                                      compatible = "u-boot,env-redundant-bool";
++                                                              };
++                                                      };
++
++                                                      ubi-volume-ubootenv2 {
++                                                              volname = "ubootenv2";
++                                                              nvmem-layout {
++                                                                      compatible = "u-boot,env-redundant-bool";
++                                                              };
++                                                      };
++
++                                                      ubi_root: ubi-volume-fit {
++                                                              volname = "fit";
++                                                      };
++
++                                              };
++                                      };
++                              };
++                      };
++              };
++      };
++
++      fragment@1 {
++              target-path = "/chosen";
++              __overlay__ {
++                      rootdisk-spim-nand = <&ubi_root>;
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb-spim-nor.dtso
+@@ -0,0 +1,69 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "mediatek,mt7988a-rfb", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&spi2>;
++              __overlay__ {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&spi2_flash_pins>;
++                      status = "okay";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++
++                      flash@0 {
++                              #address-cells = <1>;
++                              #size-cells = <1>;
++                              compatible = "jedec,spi-nor";
++                              spi-cal-enable;
++                              spi-cal-mode = "read-data";
++                              spi-cal-datalen = <7>;
++                              spi-cal-data = /bits/ 8 <
++                                      0x53 0x46 0x5F 0x42 0x4F 0x4F 0x54>; /* SF_BOOT */
++                              spi-cal-addrlen = <1>;
++                              spi-cal-addr = /bits/ 32 <0x0>;
++                              reg = <0>;
++                              spi-max-frequency = <52000000>;
++                              spi-tx-bus-width = <4>;
++                              spi-rx-bus-width = <4>;
++
++                              partition@0 {
++                                      label = "BL2";
++                                      reg = <0x0 0x40000>;
++                              };
++                              partition@40000 {
++                                      label = "u-boot-env";
++                                      reg = <0x40000 0x10000>;
++                              };
++                              partition@50000 {
++                                      label = "Factory";
++                                      reg = <0x50000 0x200000>;
++                              };
++                              partition@250000 {
++                                      label = "FIP";
++                                      reg = <0x250000 0x80000>;
++                              };
++                              nor_root: partition@2D0000 {
++                                      label = "firmware";
++                                      reg = <0x2d0000 0x1d30000>;
++                                      compatible = "denx,fit";
++                              };
++                      };
++              };
++      };
++
++      fragment@1 {
++              target-path = "/chosen";
++              __overlay__ {
++                      rootdisk-nor = <&nor_root>;
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-rfb.dts
+@@ -0,0 +1,471 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2022 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++#include <dt-bindings/pinctrl/mt65xx.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
++
++#include "mt7988a.dtsi"
++
++/ {
++      model = "MediaTek MT7988A Reference Board";
++      compatible = "mediatek,mt7988a-rfb",
++                   "mediatek,mt7988a";
++
++      chosen {
++              bootargs = "console=ttyS0,115200n1 \
++                          earlycon=uart8250,mmio32,0x11000000 \
++                          pci=pcie_bus_perf";
++      };
++
++      memory@40000000 {
++              reg = <0 0x40000000 0 0x40000000>;
++              device_type = "memory";
++      };
++
++      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;
++      };
++};
++
++&eth {
++      pinctrl-0 = <&mdio0_pins>;
++      pinctrl-names = "default";
++};
++
++&gmac0 {
++      status = "okay";
++};
++
++&cpu0 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu1 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu2 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cpu3 {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&cci {
++      proc-supply = <&rt5190_buck3>;
++};
++
++&eth {
++      status = "okay";
++};
++
++&switch {
++      status = "okay";
++};
++
++&gsw_phy0 {
++      pinctrl-names = "gbe-led";
++      pinctrl-0 = <&gbe0_led0_pins>;
++};
++
++&gsw_phy0_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_port0 {
++      label = "lan0";
++};
++
++&gsw_phy1 {
++      pinctrl-names = "gbe-led";
++      pinctrl-0 = <&gbe1_led0_pins>;
++};
++
++&gsw_phy1_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_port1 {
++      label = "lan1";
++};
++
++&gsw_phy2 {
++      pinctrl-names = "gbe-led";
++      pinctrl-0 = <&gbe2_led0_pins>;
++};
++
++&gsw_phy2_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_port2 {
++      label = "lan2";
++};
++
++&gsw_phy3 {
++      pinctrl-names = "gbe-led";
++      pinctrl-0 = <&gbe3_led0_pins>;
++};
++
++&gsw_phy3_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_port3 {
++      label = "lan3";
++};
++
++&i2c0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c0_pins>;
++      status = "okay";
++
++      rt5190a_64: rt5190a@64 {
++              compatible = "richtek,rt5190a";
++              reg = <0x64>;
++              /*interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;*/
++              vin2-supply = <&rt5190_buck1>;
++              vin3-supply = <&rt5190_buck1>;
++              vin4-supply = <&rt5190_buck1>;
++
++              regulators {
++                      rt5190_buck1: buck1 {
++                              regulator-name = "rt5190a-buck1";
++                              regulator-min-microvolt = <5090000>;
++                              regulator-max-microvolt = <5090000>;
++                              regulator-allowed-modes =
++                              <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      buck2 {
++                              regulator-name = "vcore";
++                              regulator-min-microvolt = <600000>;
++                              regulator-max-microvolt = <1400000>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      rt5190_buck3: buck3 {
++                              regulator-name = "vproc";
++                              regulator-min-microvolt = <600000>;
++                              regulator-max-microvolt = <1400000>;
++                              regulator-boot-on;
++                      };
++                      buck4 {
++                              regulator-name = "rt5190a-buck4";
++                              regulator-min-microvolt = <850000>;
++                              regulator-max-microvolt = <850000>;
++                              regulator-allowed-modes =
++                              <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++                      ldo {
++                              regulator-name = "rt5190a-ldo";
++                              regulator-min-microvolt = <1200000>;
++                              regulator-max-microvolt = <1200000>;
++                              regulator-boot-on;
++                              regulator-always-on;
++                      };
++              };
++      };
++};
++
++&pcie0 {
++      status = "okay";
++};
++
++&pcie1 {
++      status = "okay";
++};
++
++&pcie2 {
++      status = "disabled";
++};
++
++&pcie3 {
++      status = "okay";
++};
++
++&pio {
++      mdio0_pins: mdio0-pins {
++              mux {
++                      function = "eth";
++                      groups = "mdc_mdio0";
++              };
++
++              conf {
++                      groups = "mdc_mdio0";
++                      drive-strength = <MTK_DRIVE_8mA>;
++              };
++      };
++
++      gbe0_led0_pins: gbe0-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe0_led0";
++              };
++      };
++
++      gbe1_led0_pins: gbe1-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe1_led0";
++              };
++      };
++
++      gbe2_led0_pins: gbe2-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe2_led0";
++              };
++      };
++
++      gbe3_led0_pins: gbe3-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe3_led0";
++              };
++      };
++
++      gbe0_led1_pins: gbe0-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe0_led1";
++              };
++      };
++
++      gbe1_led1_pins: gbe1-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe1_led1";
++              };
++      };
++
++      gbe2_led1_pins: gbe2-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe2_led1";
++              };
++      };
++
++      gbe3_led1_pins: gbe3-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "gbe3_led1";
++              };
++      };
++
++      i2c0_pins: i2c0-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c0_1";
++              };
++      };
++
++      i2c1_pins: i2c1-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c1_0";
++              };
++      };
++
++      i2c1_sfp_pins: i2c1-sfp-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c1_sfp";
++              };
++      };
++
++      i2c2_0_pins: i2c2-g0-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c2_0";
++              };
++      };
++
++      i2c2_1_pins: i2c2-g1-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c2_1";
++              };
++      };
++
++      i2p5gbe_led0_pins: 2p5gbe-led0-pins {
++              mux {
++                      function = "led";
++                      groups = "2p5gbe_led0";
++              };
++      };
++
++      i2p5gbe_led1_pins: 2p5gbe-led1-pins {
++              mux {
++                      function = "led";
++                      groups = "2p5gbe_led1";
++              };
++      };
++
++      mmc0_pins_emmc_51: mmc0-emmc-51-pins {
++              mux {
++                      function = "flash";
++                      groups = "emmc_51";
++              };
++      };
++
++      mmc0_pins_sdcard: mmc0-sdcard-pins {
++              mux {
++                      function = "flash";
++                      groups = "sdcard";
++              };
++      };
++
++      spi0_pins: spi0-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0";
++              };
++      };
++
++      spi0_flash_pins: spi0-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0", "spi0_wp_hold";
++              };
++      };
++
++      spi2_pins: spi2-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi2";
++              };
++      };
++
++      spi2_flash_pins: spi2-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi2", "spi2_wp_hold";
++              };
++      };
++
++      uart0_pins: uart0-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart0";
++              };
++      };
++
++      uart1_0_pins: uart1-0-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart1_0";
++              };
++      };
++
++      uart1_1_pins: uart1-1-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart1_1";
++              };
++      };
++
++      uart1_2_pins: uart1-2-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart1_2";
++              };
++      };
++
++      uart1_2_lite_pins: uart1-2-lite-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart1_2_lite";
++              };
++      };
++
++      uart2_pins: uart2-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart2";
++              };
++      };
++
++      uart2_0_pins: uart2-0-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart2_0";
++              };
++      };
++
++      uart2_1_pins: uart2-1-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart2_1";
++              };
++      };
++
++      uart2_2_pins: uart2-2-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart2_2";
++              };
++      };
++
++      uart2_3_pins: uart2-3-pins {
++              mux {
++                      function = "uart";
++                      groups =  "uart2_3";
++              };
++      };
++};
++
++&ssusb0 {
++      status = "okay";
++};
++
++&ssusb1 {
++      status = "okay";
++};
++
++&tphy {
++      status = "okay";
++};
++
++&serial0 {
++      status = "okay";
++};
++
++&watchdog {
++      status = "okay";
++};
++
++&xsphy {
++      status = "okay";
++};
diff --git a/target/linux/mediatek/patches-6.12/189-arm64-dts-mediatek-mt7988a-complete-bpi-r4.patch b/target/linux/mediatek/patches-6.12/189-arm64-dts-mediatek-mt7988a-complete-bpi-r4.patch
new file mode 100644 (file)
index 0000000..8eccb6f
--- /dev/null
@@ -0,0 +1,488 @@
+From f7fb27b62f0ef45f94f4ec33c608bfad1c7691b3 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 26 Jul 2023 14:56:28 +0100
+Subject: [PATCH 32/32] WIP: add BPi-R4
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-2g5.dts
+@@ -20,3 +20,16 @@
+       pinctrl-names = "i2p5gbe-led";
+       pinctrl-0 = <&i2p5gbe_led0_pins>;
+ };
++
++&gmac1 {
++      phy-mode = "internal";
++      phy-connection-type = "internal";
++      phy = <&int_2p5g_phy>;
++      openwrt,netdev-name = "lan4";
++      status = "okay";
++};
++
++&int_2p5g_phy {
++      pinctrl-names = "i2p5gbe-led";
++      pinctrl-0 = <&i2p5gbe_led0_pins>;
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
+@@ -0,0 +1,56 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2021 MediaTek Inc.
++ * Author: Frank Wunderlich <frank-w@public-files.de>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
++};
++
++&{/soc/mmc@11230000} {
++      pinctrl-names = "default", "state_uhs";
++      pinctrl-0 = <&mmc0_pins_emmc_51>;
++      pinctrl-1 = <&mmc0_pins_emmc_51>;
++      bus-width = <8>;
++      max-frequency = <200000000>;
++      cap-mmc-highspeed;
++      mmc-hs200-1_8v;
++      mmc-hs400-1_8v;
++      hs400-ds-delay = <0x12814>;
++      vqmmc-supply = <&reg_1p8v>;
++      vmmc-supply = <&reg_3p3v>;
++      non-removable;
++      no-sd;
++      no-sdio;
++      #address-cells = <1>;
++      #size-cells = <0>;
++      status = "okay";
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              partitions {
++                      compatible = "gpt-partitions";
++
++                      block-partition-env {
++                              partname = "ubootenv";
++                              nvmem-layout {
++                                      compatible = "u-boot,env-layout";
++                              };
++                      };
++
++                      emmc_rootfs: block-partition-production {
++                              partname = "production";
++                      };
++              };
++      };
++};
++
++&{/chosen} {
++      rootdisk-emmc = <&emmc_rootfs>;
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-rtc.dtso
+@@ -0,0 +1,19 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2023
++ * Author: Daniel Golle <daniel@makrotopia.org>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
++
++      fragment@0 {
++              target = <&pcf8563>;
++              __overlay__ {
++                      status = "okay";
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
+@@ -0,0 +1,54 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2023 MediaTek Inc.
++ * Author: Frank Wunderlich <frank-w@public-files.de>
++ */
++
++/dts-v1/;
++/plugin/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
++};
++
++&{/soc/mmc@11230000} {
++      pinctrl-names = "default", "state_uhs";
++      pinctrl-0 = <&mmc0_pins_sdcard>;
++      pinctrl-1 = <&mmc0_pins_sdcard>;
++      cd-gpios = <&pio 12 GPIO_ACTIVE_LOW>;
++      bus-width = <4>;
++      max-frequency = <52000000>;
++      cap-sd-highspeed;
++      vmmc-supply = <&reg_3p3v>;
++      vqmmc-supply = <&reg_3p3v>;
++      no-mmc;
++      #address-cells = <1>;
++      #size-cells = <0>;
++      status = "okay";
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              partitions {
++                      compatible = "gpt-partitions";
++
++                      block-partition-env {
++                              partname = "ubootenv";
++                              nvmem-layout {
++                                      compatible = "u-boot,env-layout";
++                              };
++                      };
++
++                      sd_rootfs: block-partition-production {
++                              partname = "production";
++                      };
++              };
++      };
++};
++
++&{/chosen} {
++      rootdisk-sd = <&sd_rootfs>;
++};
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
+@@ -35,3 +35,11 @@
+               reg = <2>;
+       };
+ };
++
++&gmac1 {
++      sfp = <&sfp2>;
++      managed = "in-band-status";
++      phy-mode = "usxgmii";
++      openwrt,netdev-name = "sfp-lan";
++      status = "okay";
++};
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
+@@ -3,6 +3,8 @@
+ /dts-v1/;
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
+ #include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
+ #include "mt7988a.dtsi"
+@@ -10,6 +12,8 @@
+ / {
+       chosen {
+               stdout-path = "serial0:115200n8";
++              bootargs = "console=ttyS0,115200n1 pci=pcie_bus_perf ubi.block=0,fit root=/dev/fit0";
++              rootdisk-spim-nand = <&ubi_rootfs>;
+       };
+       fan: pwm-fan {
+@@ -50,6 +54,142 @@
+               rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>;
+               maximum-power-milliwatt = <3000>;
+       };
++
++      aliases {
++              ethernet0 = &gmac0;
++              ethernet1 = &gmac1;
++              ethernet2 = &gmac2;
++              serial0 = &serial0;
++              led-boot = &led_green;
++              led-failsafe = &led_green;
++              led-running = &led_green;
++              led-upgrade = &led_green;
++      };
++
++      memory@40000000 {
++              reg = <0x00 0x40000000 0x00 0x10000000>;
++              device_type = "memory";
++      };
++
++      /* SFP1 cage (WAN) */
++      sfp1: sfp1 {
++              compatible = "sff,sfp";
++              i2c-bus = <&i2c_sfp1>;
++              los-gpios = <&pio 54 GPIO_ACTIVE_HIGH>;
++              mod-def0-gpios = <&pio 82 GPIO_ACTIVE_LOW>;
++              tx-disable-gpios = <&pio 70 GPIO_ACTIVE_HIGH>;
++              tx-fault-gpios = <&pio 69 GPIO_ACTIVE_HIGH>;
++              rate-select0-gpios = <&pio 21 GPIO_ACTIVE_LOW>;
++              maximum-power-milliwatt = <3000>;
++      };
++
++      gpio-keys {
++              compatible = "gpio-keys";
++
++              wps {
++                      label = "WPS";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&pio 14 GPIO_ACTIVE_LOW>;
++              };
++      };
++
++      gpio-leds {
++              compatible = "gpio-leds";
++
++              led_green: led-green {
++                      function = LED_FUNCTION_STATUS;
++                      color = <LED_COLOR_ID_GREEN>;
++                      gpios = <&pio 79 GPIO_ACTIVE_HIGH>;
++                      default-state = "on";
++              };
++
++              led_blue: led-blue {
++                      function = LED_FUNCTION_WPS;
++                      color = <LED_COLOR_ID_BLUE>;
++                      gpios = <&pio 63 GPIO_ACTIVE_HIGH>;
++                      default-state = "off";
++              };
++      };
++};
++
++&eth {
++      status = "okay";
++};
++
++&gmac0 {
++      status = "okay";
++};
++
++&gmac2 {
++      sfp = <&sfp1>;
++      managed = "in-band-status";
++      phy-mode = "usxgmii";
++      openwrt,netdev-name = "sfp-wan";
++      status = "okay";
++};
++
++&switch {
++      status = "okay";
++};
++
++&gsw_phy0 {
++      pinctrl-names = "gbe-led";
++      pinctrl-0 = <&gbe0_led0_pins>;
++};
++
++&gsw_port0 {
++      label = "wan";
++};
++
++&gsw_phy0_led0 {
++      status = "okay";
++      function = LED_FUNCTION_WAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_phy1 {
++      pinctrl-names = "gbe-led";
++      pinctrl-0 = <&gbe1_led0_pins>;
++};
++
++&gsw_port1 {
++      label = "lan1";
++};
++
++&gsw_phy1_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_phy2 {
++      pinctrl-names = "gbe-led";
++      pinctrl-0 = <&gbe2_led0_pins>;
++};
++
++&gsw_port2 {
++      label = "lan2";
++};
++
++&gsw_phy2_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
++};
++
++&gsw_phy3 {
++      pinctrl-names = "gbe-led";
++      pinctrl-0 = <&gbe3_led0_pins>;
++};
++
++&gsw_port3 {
++      label = "lan3";
++};
++
++&gsw_phy3_led0 {
++      status = "okay";
++      function = LED_FUNCTION_LAN;
++      color = <LED_COLOR_ID_GREEN>;
+ };
+ &cci {
+@@ -174,6 +314,10 @@
+       color = <LED_COLOR_ID_GREEN>;
+ };
++&cci {
++      proc-supply = <&rt5190_buck3>;
++};
++
+ &i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0_pins>;
+@@ -265,6 +409,14 @@
+                       #size-cells = <0>;
+                       reg = <1>;
+               };
++
++              i2c_wifi: i2c@3 {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      reg = <3>;
++
++                      status = "disabled";
++              };
+       };
+ };
+@@ -364,34 +516,6 @@
+               };
+       };
+-      gbe0_led1_pins: gbe0-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe0_led1";
+-              };
+-      };
+-
+-      gbe1_led1_pins: gbe1-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe1_led1";
+-              };
+-      };
+-
+-      gbe2_led1_pins: gbe2-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe2_led1";
+-              };
+-      };
+-
+-      gbe3_led1_pins: gbe3-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "gbe3_led1";
+-              };
+-      };
+-
+       i2p5gbe_led0_pins: 2p5gbe-led0-pins {
+               mux {
+                       function = "led";
+@@ -399,13 +523,6 @@
+               };
+       };
+-      i2p5gbe_led1_pins: 2p5gbe-led1-pins {
+-              mux {
+-                      function = "led";
+-                      groups = "2p5gbe_led1";
+-              };
+-      };
+-
+       mmc0_pins_emmc_45: mmc0-emmc-45-pins {
+               mux {
+                       function = "flash";
+@@ -427,40 +544,12 @@
+               };
+       };
+-      snfi_pins: snfi-pins {
+-              mux {
+-                      function = "flash";
+-                      groups = "snfi";
+-              };
+-      };
+-
+-      spi0_pins: spi0-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi0";
+-              };
+-      };
+-
+       spi0_flash_pins: spi0-flash-pins {
+               mux {
+                       function = "spi";
+                       groups = "spi0", "spi0_wp_hold";
+               };
+       };
+-
+-      spi2_pins: spi2-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi2";
+-              };
+-      };
+-
+-      spi2_flash_pins: spi2-flash-pins {
+-              mux {
+-                      function = "spi";
+-                      groups = "spi2", "spi2_wp_hold";
+-              };
+-      };
+ };
+ &pwm {
+@@ -500,6 +589,32 @@
+                       reg = <0x0 0x200000>;
+                       read-only;
+               };
++
++              partition@200000 {
++                      label = "ubi";
++                      reg = <0x200000 0x7e00000>;
++                      compatible = "linux,ubi";
++
++                      volumes {
++                              ubi-volume-ubootenv {
++                                      volname = "ubootenv";
++                                      nvmem-layout {
++                                              compatible = "u-boot,env-redundant-bool-layout";
++                                      };
++                              };
++
++                              ubi-volume-ubootenv2 {
++                                      volname = "ubootenv2";
++                                      nvmem-layout {
++                                              compatible = "u-boot,env-redundant-bool-layout";
++                                      };
++                              };
++
++                              ubi_rootfs: ubi-volume-fit {
++                                      volname = "fit";
++                              };
++                      };
++              };
+       };
+ };
diff --git a/target/linux/mediatek/patches-6.12/190-arm64-dts-mediatek-mt7622-fix-GICv2-range.patch b/target/linux/mediatek/patches-6.12/190-arm64-dts-mediatek-mt7622-fix-GICv2-range.patch
new file mode 100644 (file)
index 0000000..bf68231
--- /dev/null
@@ -0,0 +1,106 @@
+From patchwork Tue Apr 26 19:51:36 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 12827872
+Return-Path: 
+ <linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org>
+X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
+       aws-us-west-2-korg-lkml-1.web.codeaurora.org
+Received: from bombadil.infradead.org (bombadil.infradead.org
+ [198.137.202.133])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by smtp.lore.kernel.org (Postfix) with ESMTPS id BACF3C433EF
+       for <linux-arm-kernel@archiver.kernel.org>;
+ Tue, 26 Apr 2022 19:53:05 +0000 (UTC)
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=bombadil.20210309; h=Sender:
+       Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:
+       List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Subject:Cc:To:
+       From:Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:
+       Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:
+       List-Owner; bh=OWGSxvlKoyPWz6b629RNINucULo6oOdFssAIiJETWRg=; b=T0HEjee0FX3hlb
+       x5jl7xLK5sKM0pkE2oRgwzthbFlNg8ST1j/2GkgcgT0S2Bi0vRfFxHeu/RKzS9RmiVnKJnPGL8ctg
+       WoBLyO5i+NcmosGoy6MmoOjGTNhj/+3q3Z1jRLBSJ4ySSP22X77YeuJTmVzySPUllQhWvDhjMVCR9
+       QBRmQdc6gCAg3IYGEbWwS2TG+UHveDCeZRWxMzrwI8UPadNCRFROwugmiQ3mdU41lHCTDpnlfuRJh
+       o1igLKfMBLz+D8rFYvDh7FfkcKkY6lNoswA2HKUun1MEzgoyQKmITPnG2maX/BvJJuj/B3ZJShh4k
+       AZHmXoQxq1mrsm2FxfnQ==;
+Received: from localhost ([::1] helo=bombadil.infradead.org)
+       by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
+       id 1njRE5-00G05D-9z; Tue, 26 Apr 2022 19:51:57 +0000
+Received: from fudo.makrotopia.org ([2a07:2ec0:3002::71])
+ by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
+ id 1njRE1-00G03h-9H; Tue, 26 Apr 2022 19:51:55 +0000
+Received: from local
+ by fudo.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256)
+ (Exim 4.94.2) (envelope-from <daniel@makrotopia.org>)
+ id 1njRDu-0006aF-4F; Tue, 26 Apr 2022 21:51:46 +0200
+Date: Tue, 26 Apr 2022 20:51:36 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+To: devicetree@vger.kernel.org, linux-mediatek@lists.infradead.org,
+ linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
+Cc: Rob Herring <robh+dt@kernel.org>,
+ Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
+ Matthias Brugger <matthias.bgg@gmail.com>
+Subject: [PATCH] arm64: dts: mediatek: mt7622: fix GICv2 range
+Message-ID: <YmhNSLgp/yg8Vr1F@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20220426_125153_359242_EA3D452C 
+X-CRM114-Status: GOOD (  12.45  )
+X-BeenThere: linux-arm-kernel@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: <linux-arm-kernel.lists.infradead.org>
+List-Unsubscribe: 
+ <http://lists.infradead.org/mailman/options/linux-arm-kernel>,
+ <mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
+List-Post: <mailto:linux-arm-kernel@lists.infradead.org>
+List-Help: <mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>
+List-Subscribe: 
+ <http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,
+ <mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>
+Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
+Errors-To: 
+ linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org
+
+With the current range specified for the CPU interface there is an
+error message at boot:
+
+GIC: GICv2 detected, but range too small and irqchip.gicv2_force_probe not set
+
+Setting irqchip.gicv2_force_probe=1 in bootargs results in:
+
+GIC: Aliased GICv2 at 0x0000000010320000, trying to find the canonical range over 128kB
+GIC: Adjusting CPU interface base to 0x000000001032f000
+GIC: Using split EOI/Deactivate mode
+
+Using the adjusted CPU interface base and 8K size results in only the
+final line remaining and fully working system as well as /proc/interrupts
+showing additional IPI3,4,5,6:
+
+IPI3:         0          0       CPU stop (for crash dump) interrupts
+IPI4:         0          0       Timer broadcast interrupts
+IPI5:         0          0       IRQ work interrupts
+IPI6:         0          0       CPU wake-up interrupts
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -345,7 +345,7 @@
+               #interrupt-cells = <3>;
+               interrupt-parent = <&gic>;
+               reg = <0 0x10310000 0 0x1000>,
+-                    <0 0x10320000 0 0x1000>,
++                    <0 0x1032f000 0 0x2000>,
+                     <0 0x10340000 0 0x2000>,
+                     <0 0x10360000 0 0x2000>;
+       };
diff --git a/target/linux/mediatek/patches-6.12/193-dts-mt7623-thermal_zone_fix.patch b/target/linux/mediatek/patches-6.12/193-dts-mt7623-thermal_zone_fix.patch
new file mode 100644 (file)
index 0000000..da9ba5f
--- /dev/null
@@ -0,0 +1,48 @@
+From 824d56e753a588fcfd650db1822e34a02a48bb77 Mon Sep 17 00:00:00 2001
+From: Bruno Umuarama <anonimou_eu@hotmail.com>
+Date: Thu, 13 Oct 2022 21:18:21 +0000
+Subject: [PATCH] mediatek: mt7623: fix thermal zone
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Raising the temperatures for passive and active trips. @VA1DER
+proposed at issue 9396 to remove passive trip. This commit relates to
+his suggestion.
+
+Without this patch. the CPU will be throttled all the way down to 98MHz
+if the temperature rises even a degree above the trip point, and it was
+further discovered that if the internal temperature of the device is
+above the first trip point temperature when it boots then it will start
+in a throttled state and even
+$ echo disabled > /sys/class/thermal/thermal_zone0/mode
+will have no effect.
+
+The patch increases the passive trip point and active cooling map. The
+throttling temperature will then be at 77°C and 82°C, which is still a
+low enough temperature for ARM devices to not be in the real danger
+zone, and gives some operational headroom.
+
+Signed-off-by: Bruno Umuarama <anonimou_eu@hotmail.com>
+---
+ arch/arm/boot/dts/mediatek/mt7623.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/mediatek/mt7623.dtsi
++++ b/arch/arm/boot/dts/mediatek/mt7623.dtsi
+@@ -160,13 +160,13 @@
+                               trips {
+                                       cpu_passive: cpu-passive {
+-                                              temperature = <57000>;
++                                              temperature = <77000>;
+                                               hysteresis = <2000>;
+                                               type = "passive";
+                                       };
+                                       cpu_active: cpu-active {
+-                                              temperature = <67000>;
++                                              temperature = <82000>;
+                                               hysteresis = <2000>;
+                                               type = "active";
+                                       };
diff --git a/target/linux/mediatek/patches-6.12/194-dts-mt7968a-add-ramoops.patch b/target/linux/mediatek/patches-6.12/194-dts-mt7968a-add-ramoops.patch
new file mode 100644 (file)
index 0000000..680c90a
--- /dev/null
@@ -0,0 +1,27 @@
+From e1adb1fa39dd5ef97280ad1b2bb9e8ff4c43674f Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 7 May 2021 16:53:09 +0100
+Subject: [PATCH] arm64: dts: mediatek: mt7986a: reserve memory for ramoops/pstore
+
+Reserve 64 KiB of memory at 0x42ff0000 in the MT7986a DTSI for the
+ramoops/pstore driver so that kernel crash logs survive a reboot.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -68,6 +68,14 @@
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
++
++              /* 64 KiB reserved for ramoops/pstore */
++              ramoops@42ff0000 {
++                      compatible = "ramoops";
++                      reg = <0 0x42ff0000 0 0x10000>;
++                      record-size = <0x1000>;
++              };
++
+               /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+               secmon_reserved: secmon@43000000 {
+                       reg = <0 0x43000000 0 0x30000>;
diff --git a/target/linux/mediatek/patches-6.12/195-dts-mt7986a-bpi-r3-leds-port-names-and-wifi-eeprom.patch b/target/linux/mediatek/patches-6.12/195-dts-mt7986a-bpi-r3-leds-port-names-and-wifi-eeprom.patch
new file mode 100644 (file)
index 0000000..2554f88
--- /dev/null
@@ -0,0 +1,208 @@
+From 7a0ec001ff79b12beefb8f3773820bfedebbb340 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 4 Jun 2023 15:56:15 +0100
+Subject: [PATCH] arm64: dts: mediatek: mt7986a-bpi-r3: fix LED/LAN port naming and wire WiFi EEPROM
+
+Add led-boot/led-failsafe/led-running/led-upgrade aliases pointing to
+the green and blue system LEDs, renumber the switch LAN port labels from
+lan0/lan1/lan2 to lan1/lan2/lan3 to match the board silkscreen, and wire
+the built-in WiFi EEPROM from the factory partition.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -23,6 +23,10 @@
+               serial0 = &uart0;
+               ethernet0 = &gmac0;
+               ethernet1 = &gmac1;
++              led-boot = &green_led;
++              led-failsafe = &green_led;
++              led-running = &green_led;
++              led-upgrade = &blue_led;
+       };
+       chosen {
+@@ -418,27 +422,27 @@
+               port@1 {
+                       reg = <1>;
+-                      label = "lan0";
++                      label = "lan1";
+               };
+               port@2 {
+                       reg = <2>;
+-                      label = "lan1";
++                      label = "lan2";
+               };
+               port@3 {
+                       reg = <3>;
+-                      label = "lan2";
++                      label = "lan3";
+               };
+               port@4 {
+                       reg = <4>;
+-                      label = "lan3";
++                      label = "lan4";
+               };
+               port5: port@5 {
+                       reg = <5>;
+-                      label = "lan4";
++                      label = "sfp2";
+                       phy-mode = "2500base-x";
+                       sfp = <&sfp2>;
+                       managed = "in-band-status";
+@@ -489,9 +493,137 @@
+ &wifi {
+       status = "okay";
+-      pinctrl-names = "default", "dbdc";
++      pinctrl-names = "default";
+       pinctrl-0 = <&wf_2g_5g_pins>, <&wf_led_pins>;
+-      pinctrl-1 = <&wf_dbdc_pins>, <&wf_led_pins>;
++
++      mediatek,eeprom-data = <0x86790900 0x000c4326 0x60000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x01000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000800 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x24649090 0x00280000 0x05100000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00021e00 0x021e0002 0x1e00021e 0x00022800 0x02280002 0x28000228 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00008080 0x8080fdf7
++                              0x0903150d 0x80808080 0x80808080 0x05050d0d 0x1313c6c6 0xc3c3c200 0x00c200c2 0x00008182
++                              0x8585c2c2 0x82828282 0x858500c2 0xc2000081 0x82858587 0x87c2c200 0x81818285 0x858787c2
++                              0xc2000081 0x82858587 0x87c2c200 0x00818285 0x858787c2 0xc2000081 0x82858587 0x87c4c4c2
++                              0xc100c300 0xc3c3c100 0x818383c3 0xc3c3c100 0x81838300 0xc2c2c2c0 0x81828484 0x000000c3
++                              0xc3c3c100 0x81838386 0x86c3c3c3 0xc1008183 0x838686c2 0xc2c2c081 0x82848486 0x86c3c3c3
++                              0xc1008183 0x838686c3 0xc3c3c100 0x81838386 0x86c3c3c3 0xc1008183 0x83868622 0x28002228
++                              0x00222800 0x22280000 0xdddddddd 0xdddddddd 0xddbbbbbb 0xccccccdd 0xdddddddd 0xdddddddd
++                              0xeeeeeecc 0xccccdddd 0xdddddddd 0x004a5662 0x0000004a 0x56620000 0x004a5662 0x0000004a
++                              0x56620000 0x88888888 0x33333326 0x26262626 0x26262600 0x33333326 0x26262626 0x26262600
++                              0x33333326 0x26262626 0x26262600 0x33333326 0x26262626 0x26262600 0x00000000 0xf0f0cc00
++                              0x00000000 0x0000aaaa 0xaabbbbbb 0xcccccccc 0xccccbbbb 0xbbbbbbbb 0xbbbbbbaa 0xaaaabbbb
++                              0xbbaaaaaa 0x999999aa 0xaaaabbbb 0xbbcccccc 0x00000000 0x0000aaaa 0xaa000000 0xbbbbbbbb
++                              0xbbbbaaaa 0xaa999999 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaaaaaa 0xaaaabbbb 0xbbbbbbbb
++                              0x00000000 0x00000000 0x00000000 0x99999999 0x9999aaaa 0xaaaaaaaa 0x999999aa 0xaaaaaaaa
++                              0xaaaaaaaa 0xaaaaaaaa 0xaaaabbbb 0xbbbbbbbb 0x00000000 0x0000eeee 0xeeffffff 0xcccccccc
++                              0xccccdddd 0xddbbbbbb 0xccccccbb 0xbbbbbbbb 0xbbbbbbbb 0xbbbbbbbb 0xbbbbcccc 0xccdddddd
++                              0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051
++                              0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200
++                              0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e
++                              0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051
++                              0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200
++                              0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e 0x00516200 0x686e0051 0x6200686e
++                              0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888 0x88888888
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000001 0x06000100 0x01050002 0x00ff0300
++                              0xf900fe03 0x00000000 0x00000000 0x0000009b 0x6e370000 0x00000000 0x00fc0009 0x0a00fe00
++                              0x060700fe 0x00070800 0x05000b0a 0x00000000 0x00000000 0x000000e2 0x96460000 0x00000000
++                              0x000400f7 0xf8000300 0xfcfe0003 0x00fbfc00 0xee00e3f2 0x00000000 0x00000000 0x00000011
++                              0xbb550000 0x00000000 0x000600f6 0xfc000300 0xfbfe0004 0x00fafe00 0xf600ecf2 0x00000000
++                              0x00000000 0x0000001f 0xbf580000 0x00000000 0x000600f5 0xf6000400 0xf8f90004 0x00f7f800
++                              0xf700f0f4 0x00000000 0x00000000 0x00000024 0xbe570000 0x00000000 0x000800f8 0xfe000600
++                              0xf8fd0007 0x00f9fe00 0xf500f0f4 0x00000000 0x00000000 0x0000002d 0xd6610000 0x00000000
++                              0x000400f7 0xfc000500 0xf7fc0005 0x00f7fc00 0xf900f5f8 0x00000000 0x00000000 0x00000026
++                              0xd96e0000 0x00000000 0x000400f7 0xf9000600 0xf5f70005 0x00f5f800 0xf900f4f7 0x00000000
++                              0x00000000 0x0000001b 0xce690000 0x00000000 0x000300f8 0xf8000600 0xf6f60004 0x00f6f700
++                              0xf900f4f7 0x00000000 0x00000000 0x00000018 0xd8720000 0x00000000 0x00000000 0x02404002
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0xc1c2c1c2 0x41c341c3 0x3fc13fc1 0x40c13fc2 0x3fc240c1 0x41c040c0 0x3fc23fc2 0x40c13fc2
++                              0x3fc140c0 0x41c040c0 0x3fc33fc3 0x40c23fc2 0x3fc240c1 0x41c040c0 0x3fc23fc2 0x40c23fc2
++                              0x3fc140c1 0x41c040c0 0x00000000 0x00000000 0x41c741c7 0xc1c7c1c7 0x00000000 0x00000000
++                              0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0
++                              0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0 0x3fc03fc0
++                              0x00a0ce00 0x00000000 0xb6840000 0x00000000 0x00000000 0x00000000 0x18181818 0x18181818
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x004b5763 0x0000004b 0x57630000 0x004b5763 0x0000004b 0x57630000 0x88888888 0x08474759
++                              0x69780849 0x49596d7a 0x0849495a 0x6d790848 0x48596c78 0x08484858 0x6a780848 0x48586a78
++                              0x08484858 0x6c78084a 0x4a5b6d79 0x08474759 0x697a0848 0x48596b79 0x08484859 0x6c7a0848
++                              0x48586c79 0x08484857 0x68770848 0x48576877 0x08484857 0x6a77084a 0x4a5a6a77 0x08464659
++                              0x69790848 0x48586b79 0x08484858 0x6c7a0848 0x48596c79 0x08484857 0x68770848 0x48576877
++                              0x08494958 0x6d7a084b 0x4b5c6c77 0x0847475a 0x6a7b0849 0x495a6e7c 0x0849495a 0x6e7c0849
++                              0x495b6e7c 0x08494959 0x6a7a0849 0x49596a7a 0x084a4a5a 0x6f7d084b 0x4b5c6e7b 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x85848484
++                              0xc3c4c4c5 0xc4c3c33f 0xc3c3c2c2 0xc2c2c03f 0xc3c3c3c4 0xc4c4c33f 0xc2c2c2c2 0xc1c3c1c1
++                              0xc0c08282 0x83848686 0x88880000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00001111 0x00000000
++                              0x8080f703 0x10808080 0x80050d13 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x000000a4 0xce000000 0x0000b684 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000>;
+       led {
+               led-active-low;
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+@@ -55,6 +55,7 @@
+                       partition@c00000 {
+                               label = "fit";
+                               reg = <0xc00000 0x1400000>;
++                              compatible = "denx,fit";
+                       };
+               };
+       };
diff --git a/target/linux/mediatek/patches-6.12/196-dts-mt7986a-bpi-r3-use-all-ubi-nand-layout.patch b/target/linux/mediatek/patches-6.12/196-dts-mt7986a-bpi-r3-use-all-ubi-nand-layout.patch
new file mode 100644 (file)
index 0000000..f2d1967
--- /dev/null
@@ -0,0 +1,127 @@
+From 61137a88952e125c574aa35209fd581591d8796a Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 18 Jan 2024 22:15:35 +0000
+Subject: [PATCH] arm64: dts: mediatek: mt7986a-bpi-r3: add fitblk rootdisk for eMMC and NAND overlays
+
+Add GPT block partition and mmc-card nodes to the eMMC dtso overlay so
+that fitblk can find the production partition via /chosen/rootdisk-emmc,
+and update the NAND dtso overlay to wire up the UBI volume used as the
+root filesystem via /chosen/rootdisk-nand.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
+@@ -21,5 +21,24 @@
+       non-removable;
+       no-sd;
+       no-sdio;
++      #address-cells = <1>;
++      #size-cells = <0>;
+       status = "okay";
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              partitions {
++                      compatible = "gpt-partitions";
++
++                      emmc_rootdisk: block-partition-production {
++                              partname = "production";
++                      };
++              };
++      };
++};
++
++&{/chosen} {
++      rootdisk-emmc = <&emmc_rootdisk>;
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+@@ -29,25 +29,24 @@
+                       partition@0 {
+                               label = "bl2";
+-                              reg = <0x0 0x100000>;
+-                              read-only;
++                              reg = <0x0 0x200000>;
+                       };
+-                      partition@100000 {
+-                              label = "reserved";
+-                              reg = <0x100000 0x280000>;
+-                      };
+-
+-                      partition@380000 {
+-                              label = "fip";
+-                              reg = <0x380000 0x200000>;
+-                              read-only;
+-                      };
+-
+-                      partition@580000 {
++                      partition@200000 {
+                               label = "ubi";
+-                              reg = <0x580000 0x7a80000>;
++                              reg = <0x200000 0x7e00000>;
++                              compatible = "linux,ubi";
++
++                              volumes {
++                                      nand_rootdisk: ubi-volume-fit {
++                                              volname = "fit";
++                                      };
++                              };
+                       };
+               };
+       };
+ };
++
++&{/chosen} {
++      rootdisk-spim-nand = <&nand_rootdisk>;
++};
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+@@ -52,7 +52,7 @@
+                               reg = <0x180000 0xa80000>;
+                       };
+-                      partition@c00000 {
++                      nor_rootdisk: partition@c00000 {
+                               label = "fit";
+                               reg = <0xc00000 0x1400000>;
+                               compatible = "denx,fit";
+@@ -60,3 +60,7 @@
+               };
+       };
+ };
++
++&{/chosen} {
++      rootdisk-nor = <&nor_rootdisk>;
++};
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
+@@ -15,5 +15,24 @@
+       bus-width = <4>;
+       max-frequency = <52000000>;
+       cap-sd-highspeed;
++      #address-cells = <1>;
++      #size-cells = <0>;
+       status = "okay";
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              partitions {
++                      compatible = "gpt-partitions";
++
++                      sd_rootdisk: block-partition-production {
++                              partname = "production";
++                      };
++              };
++      };
++};
++
++&{/chosen} {
++      rootdisk-sd = <&sd_rootdisk>;
+ };
diff --git a/target/linux/mediatek/patches-6.12/198-dts-mt7988a-enable-wed.patch b/target/linux/mediatek/patches-6.12/198-dts-mt7988a-enable-wed.patch
new file mode 100644 (file)
index 0000000..45ae596
--- /dev/null
@@ -0,0 +1,177 @@
+From 4dd35ca6747a57261f3b10982a4a8cc765d6549f Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 17 Jul 2025 18:45:48 +0200
+Subject: [PATCH] target: mediatek: Enable WED for MT7988 devices running 6.12.x kernels
+
+Add WED related nodes to the device tree of the MT7988 SoC family.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -145,6 +145,32 @@
+                       reg = <0 0x43000000 0 0x50000>;
+                       no-map;
+               };
++
++              wmcpu_emi: wmcpu-reserved@47cc0000 {
++                      reg = <0 0x47cc0000 0 0x00100000>;
++                      no-map;
++              };
++
++              wo_emi0: wo-emi@4f600000 {
++                      reg = <0 0x4f600000 0 0x40000>;
++                      no-map;
++              };
++
++              wo_emi1: wo-emi@4f640000 {
++                      reg = <0 0x4f640000 0 0x40000>;
++                      no-map;
++              };
++
++              wo_emi2: wo-emi@4f680000 {
++                      reg = <0 0x4f680000 0 0x40000>;
++                      no-map;
++              };
++
++              wo_data: wo-data@4f700000 {
++                      reg = <0 0x4f700000 0 0x800000>;
++                      no-map;
++                      shared = <1>;
++              };
+       };
+       soc {
+@@ -867,6 +893,50 @@
+                       reg = <0 0x15000000 0 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++              };
++
++              wed0: wed@15010000 {
++                      compatible = "mediatek,mt7988-wed",
++                                   "syscon";
++                      reg = <0 0x15010000 0 0x2000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
++                      memory-region = <&wo_emi0>, <&wo_data>;
++                      memory-region-names = "wo-emi", "wo-data";
++                      mediatek,wo-ccif = <&wo_ccif0>;
++                      mediatek,wo-ilm = <&wo_ilm0>;
++                      mediatek,wo-dlm = <&wo_dlm0>;
++                      mediatek,wo-cpuboot = <&wo_cpuboot0>;
++              };
++
++              wed1: wed@15012000 {
++                      compatible = "mediatek,mt7988-wed",
++                                   "syscon";
++                      reg = <0 0x15012000 0 0x2000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
++                      memory-region = <&wo_emi1>, <&wo_data>;
++                      memory-region-names = "wo-emi", "wo-data";
++                      mediatek,wo-ccif = <&wo_ccif1>;
++                      mediatek,wo-ilm = <&wo_ilm1>;
++                      mediatek,wo-dlm = <&wo_dlm1>;
++                      mediatek,wo-cpuboot = <&wo_cpuboot1>;
++              };
++
++              wed2: wed@15014000 {
++                      compatible = "mediatek,mt7988-wed",
++                                   "syscon";
++                      reg = <0 0x15014000 0 0x2000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
++                      memory-region = <&wo_emi2>, <&wo_data>;
++                      memory-region-names = "wo-emi", "wo-data";
++                      mediatek,wo-ccif = <&wo_ccif2>;
++                      mediatek,wo-ilm = <&wo_ilm2>;
++                      mediatek,wo-dlm = <&wo_dlm2>;
++                      mediatek,wo-cpuboot = <&wo_cpuboot2>;
+               };
+               switch: switch@15020000 {
+@@ -1086,6 +1156,7 @@
+                                                <&apmixedsys CLK_APMIXED_SGMPLL>;
+                       mediatek,ethsys = <&ethsys>;
+                       mediatek,infracfg = <&topmisc>;
++                      mediatek,wed = <&wed0>, <&wed1>, <&wed2>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+@@ -1147,6 +1218,72 @@
+                       };
+               };
++              wo_ccif0: syscon@151a5000 {
++                      compatible = "mediatek,mt7988-wo-ccif", "syscon";
++                      reg = <0 0x151a5000 0 0x1000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
++              };
++
++              wo_ccif1: syscon@152a5000 {
++                      compatible = "mediatek,mt7988-wo-ccif", "syscon";
++                      reg = <0 0x152a5000 0 0x1000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
++              };
++
++              wo_ccif2: syscon@153a5000 {
++                      compatible = "mediatek,mt7988-wo-ccif", "syscon";
++                      reg = <0 0x153a5000 0 0x1000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>;
++              };
++
++              wo_ilm0: syscon@151e0000 {
++                      compatible = "mediatek,mt7988-wo-ilm", "syscon";
++                      reg = <0 0x151e0000 0 0x8000>;
++              };
++
++              wo_ilm1: syscon@152e0000 {
++                      compatible = "mediatek,mt7988-wo-ilm", "syscon";
++                      reg = <0 0x152e0000 0 0x8000>;
++              };
++
++              wo_ilm2: syscon@153e0000 {
++                      compatible = "mediatek,mt7988-wo-ilm", "syscon";
++                      reg = <0 0x153e0000 0 0x8000>;
++              };
++
++              wo_dlm0: syscon@151e8000 {
++                      compatible = "mediatek,mt7988-wo-dlm", "syscon";
++                      reg = <0 0x151e8000 0 0x2000>;
++              };
++
++              wo_dlm1: syscon@152e8000 {
++                      compatible = "mediatek,mt7988-wo-dlm", "syscon";
++                      reg = <0 0x152e8000 0 0x2000>;
++              };
++
++              wo_dlm2: syscon@153e8000 {
++                      compatible = "mediatek,mt7988-wo-dlm", "syscon";
++                      reg = <0 0x153e8000 0 0x2000>;
++              };
++
++              wo_cpuboot0: syscon@15194000 {
++                      compatible = "mediatek,mt7988-wo-cpuboot", "syscon";
++                      reg = <0 0x15194000 0 0x1000>;
++              };
++
++              wo_cpuboot1: syscon@15294000 {
++                      compatible = "mediatek,mt7988-wo-cpuboot", "syscon";
++                      reg = <0 0x15294000 0 0x1000>;
++              };
++
++              wo_cpuboot2: syscon@15394000 {
++                      compatible = "mediatek,mt7988-wo-cpuboot", "syscon";
++                      reg = <0 0x15394000 0 0x1000>;
++              };
++
+               crypto: crypto@15600000 {
+                       compatible = "inside-secure,safexcel-eip197b";
+                       reg = <0 0x15600000 0 0x180000>;
diff --git a/target/linux/mediatek/patches-6.12/199-arm64-dts-mediatek-mt7986-increase-ATF-reserved-memo.patch b/target/linux/mediatek/patches-6.12/199-arm64-dts-mediatek-mt7986-increase-ATF-reserved-memo.patch
new file mode 100644 (file)
index 0000000..8cef5ba
--- /dev/null
@@ -0,0 +1,29 @@
+From 236317dd4e55512933dcdaec3d0b4a0824f5e5bd Mon Sep 17 00:00:00 2001
+From: Shiji Yang <yangshiji66@outlook.com>
+Date: Sun, 10 Aug 2025 18:11:01 +0800
+Subject: [PATCH] arm64: dts: mediatek: mt7986: increase ATF reserved memory to
+ 256 kiB
+
+The latest Mediatek open-source Trusted Firmware-A project has
+reserved 256 KiB for BL2 and BL31. It is better to increase the
+reserved memory region in the Linux kernel to protect the data.
+
+Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -76,9 +76,9 @@
+                       record-size = <0x1000>;
+               };
+-              /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
++              /* 256 KiB reserved for ARM Trusted Firmware (BL31 + BL32) */
+               secmon_reserved: secmon@43000000 {
+-                      reg = <0 0x43000000 0 0x30000>;
++                      reg = <0 0x43000000 0 0x40000>;
+                       no-map;
+               };
diff --git a/target/linux/mediatek/patches-6.12/200-phy-phy-mtk-tphy-Add-hifsys-support.patch b/target/linux/mediatek/patches-6.12/200-phy-phy-mtk-tphy-Add-hifsys-support.patch
new file mode 100644 (file)
index 0000000..5c482f6
--- /dev/null
@@ -0,0 +1,66 @@
+From 28f9a5e2a3f5441ab5594669ed82da11e32277a9 Mon Sep 17 00:00:00 2001
+From: Kristian Evensen <kristian.evensen@gmail.com>
+Date: Mon, 30 Apr 2018 14:38:01 +0200
+Subject: [PATCH] phy: phy-mtk-tphy: Add hifsys-support
+
+---
+ drivers/phy/mediatek/phy-mtk-tphy.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -18,6 +18,8 @@
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+ #include "phy-mtk-io.h"
+@@ -271,6 +273,9 @@
+ #define USER_BUF_LEN(count) min_t(size_t, 8, (count))
++#define HIF_SYSCFG1                   0x14
++#define HIF_SYSCFG1_PHY2_MASK         (0x3 << 20)
++
+ enum mtk_phy_version {
+       MTK_PHY_V1 = 1,
+       MTK_PHY_V2,
+@@ -339,6 +344,7 @@ struct mtk_tphy {
+       void __iomem *sif_base; /* only shared sif */
+       const struct mtk_phy_pdata *pdata;
+       struct mtk_phy_instance **phys;
++      struct regmap *hif;
+       int nphys;
+       int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */
+       int src_coef; /* coefficient for slew rate calibrate */
+@@ -973,6 +979,10 @@ static void pcie_phy_instance_init(struc
+       if (tphy->pdata->version != MTK_PHY_V1)
+               return;
++      if (tphy->hif)
++              regmap_update_bits(tphy->hif, HIF_SYSCFG1,
++                                 HIF_SYSCFG1_PHY2_MASK, 0);
++
+       mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG0,
+                           P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H,
+                           FIELD_PREP(P3A_RG_XTAL_EXT_PE1H, 0x2) |
+@@ -1621,6 +1631,16 @@ static int mtk_tphy_probe(struct platfor
+                                        &tphy->src_coef);
+       }
++      if (of_property_present(np, "mediatek,phy-switch")) {
++              tphy->hif = syscon_regmap_lookup_by_phandle(np,
++                                                          "mediatek,phy-switch");
++              if (IS_ERR(tphy->hif)) {
++                      dev_err(&pdev->dev,
++                              "missing \"mediatek,phy-switch\" phandle\n");
++                      return PTR_ERR(tphy->hif);
++              }
++      }
++
+       port = 0;
+       for_each_child_of_node_scoped(np, child_np) {
+               struct mtk_phy_instance *instance;
diff --git a/target/linux/mediatek/patches-6.12/210-PM-devfreq-mtk-cci-use-devres-for-resource-managemen.patch b/target/linux/mediatek/patches-6.12/210-PM-devfreq-mtk-cci-use-devres-for-resource-managemen.patch
new file mode 100644 (file)
index 0000000..1777c72
--- /dev/null
@@ -0,0 +1,241 @@
+From b61fcc3c7f95734e14741d8787fc9eb69b8437d4 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 11 Apr 2026 22:47:15 +0100
+Subject: [PATCH 1/2] PM / devfreq: mtk-cci: use devres for resource management
+ in probe
+
+Convert mtk_ccifreq_probe() to use devm-managed resource cleanup
+instead of manual goto-based error handling.
+
+This pattern (devm_add_action_or_reset with a regulator disable
+callback) is well-established in the kernel, used by drivers such as
+ads7846, max6639 and others.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/devfreq/mtk-cci-devfreq.c | 150 +++++++++++++++---------------
+ 1 file changed, 73 insertions(+), 77 deletions(-)
+
+--- a/drivers/devfreq/mtk-cci-devfreq.c
++++ b/drivers/devfreq/mtk-cci-devfreq.c
+@@ -246,6 +246,21 @@ static struct devfreq_dev_profile mtk_cc
+       .target = mtk_ccifreq_target,
+ };
++static void mtk_ccifreq_regulator_disable(void *data)
++{
++      regulator_disable(data);
++}
++
++static void mtk_ccifreq_clk_disable_unprepare(void *data)
++{
++      clk_disable_unprepare(data);
++}
++
++static void mtk_ccifreq_opp_of_remove_table(void *data)
++{
++      dev_pm_opp_of_remove_table(data);
++}
++
+ static int mtk_ccifreq_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+@@ -266,44 +281,47 @@ static int mtk_ccifreq_probe(struct plat
+       platform_set_drvdata(pdev, drv);
+       drv->cci_clk = devm_clk_get(dev, "cci");
+-      if (IS_ERR(drv->cci_clk)) {
+-              ret = PTR_ERR(drv->cci_clk);
+-              return dev_err_probe(dev, ret, "failed to get cci clk\n");
+-      }
++      if (IS_ERR(drv->cci_clk))
++              return dev_err_probe(dev, PTR_ERR(drv->cci_clk),
++                                   "failed to get cci clk\n");
+       drv->inter_clk = devm_clk_get(dev, "intermediate");
+-      if (IS_ERR(drv->inter_clk)) {
+-              ret = PTR_ERR(drv->inter_clk);
+-              return dev_err_probe(dev, ret,
++      if (IS_ERR(drv->inter_clk))
++              return dev_err_probe(dev, PTR_ERR(drv->inter_clk),
+                                    "failed to get intermediate clk\n");
+-      }
+       drv->proc_reg = devm_regulator_get_optional(dev, "proc");
+-      if (IS_ERR(drv->proc_reg)) {
+-              ret = PTR_ERR(drv->proc_reg);
+-              return dev_err_probe(dev, ret,
++      if (IS_ERR(drv->proc_reg))
++              return dev_err_probe(dev, PTR_ERR(drv->proc_reg),
+                                    "failed to get proc regulator\n");
+-      }
+       ret = regulator_enable(drv->proc_reg);
+-      if (ret) {
+-              dev_err(dev, "failed to enable proc regulator\n");
++      if (ret)
++              return dev_err_probe(dev, ret,
++                                   "failed to enable proc regulator\n");
++
++      ret = devm_add_action_or_reset(dev, mtk_ccifreq_regulator_disable,
++                                     drv->proc_reg);
++      if (ret)
+               return ret;
+-      }
+       drv->sram_reg = devm_regulator_get_optional(dev, "sram");
+       if (IS_ERR(drv->sram_reg)) {
+-              ret = PTR_ERR(drv->sram_reg);
+-              if (ret == -EPROBE_DEFER)
+-                      goto out_free_resources;
++              if (PTR_ERR(drv->sram_reg) == -EPROBE_DEFER)
++                      return -EPROBE_DEFER;
+               drv->sram_reg = NULL;
+       } else {
+               ret = regulator_enable(drv->sram_reg);
+-              if (ret) {
+-                      dev_err(dev, "failed to enable sram regulator\n");
+-                      goto out_free_resources;
+-              }
++              if (ret)
++                      return dev_err_probe(dev, ret,
++                                           "failed to enable sram regulator\n");
++
++              ret = devm_add_action_or_reset(dev,
++                                             mtk_ccifreq_regulator_disable,
++                                             drv->sram_reg);
++              if (ret)
++                      return ret;
+       }
+       /*
+@@ -317,31 +335,36 @@ static int mtk_ccifreq_probe(struct plat
+       ret = clk_prepare_enable(drv->cci_clk);
+       if (ret)
+-              goto out_free_resources;
++              return ret;
++
++      ret = devm_add_action_or_reset(dev, mtk_ccifreq_clk_disable_unprepare,
++                                     drv->cci_clk);
++      if (ret)
++              return ret;
+       ret = dev_pm_opp_of_add_table(dev);
+-      if (ret) {
+-              dev_err(dev, "failed to add opp table: %d\n", ret);
+-              goto out_disable_cci_clk;
+-      }
++      if (ret)
++              return dev_err_probe(dev, ret, "failed to add opp table\n");
++
++      ret = devm_add_action_or_reset(dev, mtk_ccifreq_opp_of_remove_table,
++                                     dev);
++      if (ret)
++              return ret;
+       rate = clk_get_rate(drv->inter_clk);
+       opp = dev_pm_opp_find_freq_ceil(dev, &rate);
+-      if (IS_ERR(opp)) {
+-              ret = PTR_ERR(opp);
+-              dev_err(dev, "failed to get intermediate opp: %d\n", ret);
+-              goto out_remove_opp_table;
+-      }
++      if (IS_ERR(opp))
++              return dev_err_probe(dev, PTR_ERR(opp),
++                                   "failed to get intermediate opp\n");
++
+       drv->inter_voltage = dev_pm_opp_get_voltage(opp);
+       dev_pm_opp_put(opp);
+       rate = U32_MAX;
+       opp = dev_pm_opp_find_freq_floor(drv->dev, &rate);
+-      if (IS_ERR(opp)) {
+-              dev_err(dev, "failed to get opp\n");
+-              ret = PTR_ERR(opp);
+-              goto out_remove_opp_table;
+-      }
++      if (IS_ERR(opp))
++              return dev_err_probe(dev, PTR_ERR(opp),
++                                   "failed to get opp\n");
+       opp_volt = dev_pm_opp_get_voltage(opp);
+       dev_pm_opp_put(opp);
+@@ -349,63 +372,36 @@ static int mtk_ccifreq_probe(struct plat
+       if (ret) {
+               dev_err(dev, "failed to scale to highest voltage %lu in proc_reg\n",
+                       opp_volt);
+-              goto out_remove_opp_table;
++              return ret;
+       }
+       passive_data = devm_kzalloc(dev, sizeof(*passive_data), GFP_KERNEL);
+-      if (!passive_data) {
+-              ret = -ENOMEM;
+-              goto out_remove_opp_table;
+-      }
++      if (!passive_data)
++              return -ENOMEM;
+       passive_data->parent_type = CPUFREQ_PARENT_DEV;
+       drv->devfreq = devm_devfreq_add_device(dev, &mtk_ccifreq_profile,
+                                              DEVFREQ_GOV_PASSIVE,
+                                              passive_data);
+-      if (IS_ERR(drv->devfreq)) {
+-              ret = -EPROBE_DEFER;
+-              dev_err(dev, "failed to add devfreq device: %ld\n",
+-                      PTR_ERR(drv->devfreq));
+-              goto out_remove_opp_table;
+-      }
++      if (IS_ERR(drv->devfreq))
++              return dev_err_probe(dev, -EPROBE_DEFER,
++                                   "failed to add devfreq device: %ld\n",
++                                   PTR_ERR(drv->devfreq));
+       drv->opp_nb.notifier_call = mtk_ccifreq_opp_notifier;
+       ret = dev_pm_opp_register_notifier(dev, &drv->opp_nb);
+-      if (ret) {
+-              dev_err(dev, "failed to register opp notifier: %d\n", ret);
+-              goto out_remove_opp_table;
+-      }
+-      return 0;
+-
+-out_remove_opp_table:
+-      dev_pm_opp_of_remove_table(dev);
+-
+-out_disable_cci_clk:
+-      clk_disable_unprepare(drv->cci_clk);
+-
+-out_free_resources:
+-      if (regulator_is_enabled(drv->proc_reg))
+-              regulator_disable(drv->proc_reg);
+-      if (!IS_ERR_OR_NULL(drv->sram_reg) &&
+-          regulator_is_enabled(drv->sram_reg))
+-              regulator_disable(drv->sram_reg);
++      if (ret)
++              return dev_err_probe(dev, ret,
++                                   "failed to register opp notifier\n");
+-      return ret;
++      return 0;
+ }
+ static void mtk_ccifreq_remove(struct platform_device *pdev)
+ {
+-      struct device *dev = &pdev->dev;
+-      struct mtk_ccifreq_drv *drv;
+-
+-      drv = platform_get_drvdata(pdev);
++      struct mtk_ccifreq_drv *drv = platform_get_drvdata(pdev);
+-      dev_pm_opp_unregister_notifier(dev, &drv->opp_nb);
+-      dev_pm_opp_of_remove_table(dev);
+-      clk_disable_unprepare(drv->cci_clk);
+-      regulator_disable(drv->proc_reg);
+-      if (drv->sram_reg)
+-              regulator_disable(drv->sram_reg);
++      dev_pm_opp_unregister_notifier(&pdev->dev, &drv->opp_nb);
+ }
+ static const struct mtk_ccifreq_platform_data mt8183_platform_data = {
diff --git a/target/linux/mediatek/patches-6.12/211-PM-devfreq-mtk-cci-check-cpufreq-availability-early.patch b/target/linux/mediatek/patches-6.12/211-PM-devfreq-mtk-cci-check-cpufreq-availability-early.patch
new file mode 100644 (file)
index 0000000..d18e226
--- /dev/null
@@ -0,0 +1,53 @@
+From b19968e432fe2ebe3af4bc9190923edb70b6aeee Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 13 Apr 2026 15:22:05 +0100
+Subject: [PATCH 2/2] PM / devfreq: mtk-cci: check cpufreq availability early
+
+Check spufreq availablility early at probe so -EPROBE_DEFER is emitted
+before touching any regulators.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/devfreq/mtk-cci-devfreq.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/drivers/devfreq/mtk-cci-devfreq.c
++++ b/drivers/devfreq/mtk-cci-devfreq.c
+@@ -4,6 +4,7 @@
+  */
+ #include <linux/clk.h>
++#include <linux/cpufreq.h>
+ #include <linux/devfreq.h>
+ #include <linux/minmax.h>
+ #include <linux/module.h>
+@@ -263,13 +264,28 @@ static void mtk_ccifreq_opp_of_remove_ta
+ static int mtk_ccifreq_probe(struct platform_device *pdev)
+ {
++      struct devfreq_passive_data *passive_data;
+       struct device *dev = &pdev->dev;
++      struct cpufreq_policy *policy;
+       struct mtk_ccifreq_drv *drv;
+-      struct devfreq_passive_data *passive_data;
+       struct dev_pm_opp *opp;
+       unsigned long rate, opp_volt;
+       int ret;
++      /*
++       * Check if cpufreq is available before touching any regulators.
++       * The passive devfreq governor needs cpufreq as its parent and
++       * will return -EPROBE_DEFER if it is not yet registered. If we
++       * enable the proc regulator (CPU core power) before this check,
++       * the subsequent probe failure causes devres to disable that
++       * regulator, potentially cutting CPU core voltage and hanging
++       * the system.
++       */
++      policy = cpufreq_cpu_get(0);
++      if (!policy)
++              return -EPROBE_DEFER;
++      cpufreq_cpu_put(policy);
++
+       drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
+       if (!drv)
+               return -ENOMEM;
diff --git a/target/linux/mediatek/patches-6.12/255-clk-mediatek-mt7988-infracfg-SPI0-clocks-are-not-critical.patch b/target/linux/mediatek/patches-6.12/255-clk-mediatek-mt7988-infracfg-SPI0-clocks-are-not-critical.patch
new file mode 100644 (file)
index 0000000..ed34719
--- /dev/null
@@ -0,0 +1,65 @@
+From patchwork Fri Nov  1 03:19:39 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13858671
+Return-Path: 
+ <linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org>
+Date: Fri, 1 Nov 2024 03:19:39 +0000
+From: Daniel Golle <daniel@makrotopia.org>
+To: linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org,
+ linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, Uwe
+       =?iso-8859-1?q?Kleine-K=F6nig?= <u.kleine-koenig@baylibre.com>,
+ Sam Shih <sam.shih@mediatek.com>, Frank Wunderlich <frank-w@public-files.de>,
+ Daniel Golle <daniel@makrotopia.org>,
+ AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
+ Matthias Brugger <matthias.bgg@gmail.com>, Stephen Boyd <sboyd@kernel.org>,
+ Michael Turquette <mturquette@baylibre.com>
+Subject: [PATCH] clk: mediatek: mt7988-infracfg: SPI0 clocks are not critical
+Message-ID: <ZyRIy22aS_Yjoavg@pidgin.makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+X-BeenThere: linux-mediatek@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: <linux-mediatek.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-mediatek/>
+List-Post: <mailto:linux-mediatek@lists.infradead.org>
+List-Help: <mailto:linux-mediatek-request@lists.infradead.org?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mediatek>,
+ <mailto:linux-mediatek-request@lists.infradead.org?subject=subscribe>
+Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
+Errors-To: 
+ linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org
+
+SPI0 clocks have wrongly been marked as critical while, probably due
+to the SPI driver not requesting them. This can (and should) be addressed
+in device tree instead.
+Remove CLK_IS_CRITICAL flag from clocks related to SPI0.
+
+Fixes: 4b4719437d85 ("clk: mediatek: add drivers for MT7988 SoC")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/clk/mediatek/clk-mt7988-infracfg.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt7988-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
+@@ -196,12 +196,10 @@ static const struct mtk_gate infra_clks[
+       GATE_INFRA2(CLK_INFRA_SPINFI, "infra_f_fspinfi", "spinfi_sel", 10),
+       GATE_INFRA2_FLAGS(CLK_INFRA_66M_NFI_HCK, "infra_hf_66m_nfi_hck", "sysaxi_sel", 11,
+                         CLK_IS_CRITICAL),
+-      GATE_INFRA2_FLAGS(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0", "infra_mux_spi0_sel", 12,
+-                        CLK_IS_CRITICAL),
++      GATE_INFRA2(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0", "infra_mux_spi0_sel", 12),
+       GATE_INFRA2(CLK_INFRA_104M_SPI1, "infra_hf_104m_spi1", "infra_mux_spi1_sel", 13),
+       GATE_INFRA2(CLK_INFRA_104M_SPI2_BCK, "infra_hf_104m_spi2_bck", "infra_mux_spi2_sel", 14),
+-      GATE_INFRA2_FLAGS(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck", "sysaxi_sel", 15,
+-                        CLK_IS_CRITICAL),
++      GATE_INFRA2(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck", "sysaxi_sel", 15),
+       GATE_INFRA2(CLK_INFRA_66M_SPI1_HCK, "infra_hf_66m_spi1_hck", "sysaxi_sel", 16),
+       GATE_INFRA2(CLK_INFRA_66M_SPI2_HCK, "infra_hf_66m_spi2_hck", "sysaxi_sel", 17),
+       GATE_INFRA2(CLK_INFRA_66M_FLASHIF_AXI, "infra_hf_66m_flashif_axi", "sysaxi_sel", 18),
diff --git a/target/linux/mediatek/patches-6.12/320-hwrng-mtk-add-support-for-hw-access-via-SMCC.patch b/target/linux/mediatek/patches-6.12/320-hwrng-mtk-add-support-for-hw-access-via-SMCC.patch
new file mode 100644 (file)
index 0000000..9bd9d0a
--- /dev/null
@@ -0,0 +1,212 @@
+From d211e2184d820207d14f5e8f84938c639875bf0d Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 3 Mar 2026 23:45:46 +0000
+Subject: [PATCH] hwrng: mtk - add support for hw access via SMCC
+
+Newer versions of ARM TrustedFirmware-A on MediaTek's ARMv8 SoCs no longer
+allow accessing the TRNG from outside of the trusted firmware.
+Instead, a vendor-defined custom Secure Monitor Call can be used to
+acquire random bytes.
+Add support for newer SoCs (MT7981, MT7987, MT7988). On MT7986 the best bet
+is to test if firmware blocks direct access to the hwrng and if so, expect
+the SMCC interface to be usable.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/char/hw_random/mtk-rng.c | 128 ++++++++++++++++++++++++++-----
+ 1 file changed, 107 insertions(+), 21 deletions(-)
+
+--- a/drivers/char/hw_random/mtk-rng.c
++++ b/drivers/char/hw_random/mtk-rng.c
+@@ -3,6 +3,7 @@
+  * Driver for Mediatek Hardware Random Number Generator
+  *
+  * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com>
++ * Copyright (C) 2026 Daniel Golle <daniel@makrotopia.org>
+  */
+ #define MTK_RNG_DEV KBUILD_MODNAME
+@@ -17,6 +18,8 @@
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
++#include <linux/arm-smccc.h>
++#include <linux/soc/mediatek/mtk_sip_svc.h>
+ /* Runtime PM autosuspend timeout: */
+ #define RNG_AUTOSUSPEND_TIMEOUT               100
+@@ -30,6 +33,11 @@
+ #define RNG_DATA                      0x08
++/* Driver feature flags */
++#define MTK_RNG_SMC                   BIT(0)
++
++#define MTK_SIP_KERNEL_GET_RND                MTK_SIP_SMC_CMD(0x550)
++
+ #define to_mtk_rng(p) container_of(p, struct mtk_rng, rng)
+ struct mtk_rng {
+@@ -37,6 +45,7 @@ struct mtk_rng {
+       struct clk *clk;
+       struct hwrng rng;
+       struct device *dev;
++      unsigned long flags;
+ };
+ static int mtk_rng_init(struct hwrng *rng)
+@@ -104,6 +113,56 @@ static int mtk_rng_read(struct hwrng *rn
+       return retval || !wait ? retval : -EIO;
+ }
++static int mtk_rng_read_smc(struct hwrng *rng, void *buf, size_t max,
++                          bool wait)
++{
++      struct arm_smccc_res res;
++      int retval = 0;
++
++      while (max >= sizeof(u32)) {
++              arm_smccc_smc(MTK_SIP_KERNEL_GET_RND, 0, 0, 0, 0, 0, 0, 0,
++                            &res);
++              if (res.a0)
++                      break;
++
++              *(u32 *)buf = res.a1;
++              retval += sizeof(u32);
++              buf += sizeof(u32);
++              max -= sizeof(u32);
++      }
++
++      return retval || !wait ? retval : -EIO;
++}
++
++static bool mtk_rng_hw_accessible(struct mtk_rng *priv)
++{
++      u32 val;
++      int err;
++
++      err = clk_prepare_enable(priv->clk);
++      if (err)
++              return false;
++
++      val = readl(priv->base + RNG_CTRL);
++      val |= RNG_EN;
++      writel(val, priv->base + RNG_CTRL);
++
++      val = readl(priv->base + RNG_CTRL);
++
++      if (val & RNG_EN) {
++              /* HW is accessible, clean up: disable RNG and clock */
++              writel(val & ~RNG_EN, priv->base + RNG_CTRL);
++              clk_disable_unprepare(priv->clk);
++              return true;
++      }
++
++      /*
++       * If TF-A blocks direct access, the register reads back as 0.
++       * Leave the clock enabled as TF-A's SMC handler needs it.
++       */
++      return false;
++}
++
+ static int mtk_rng_probe(struct platform_device *pdev)
+ {
+       int ret;
+@@ -115,23 +174,42 @@ static int mtk_rng_probe(struct platform
+       priv->dev = &pdev->dev;
+       priv->rng.name = pdev->name;
+-#ifndef CONFIG_PM
+-      priv->rng.init = mtk_rng_init;
+-      priv->rng.cleanup = mtk_rng_cleanup;
+-#endif
+-      priv->rng.read = mtk_rng_read;
+       priv->rng.quality = 900;
++      priv->flags = (unsigned long)device_get_match_data(&pdev->dev);
+-      priv->clk = devm_clk_get(&pdev->dev, "rng");
+-      if (IS_ERR(priv->clk)) {
+-              ret = PTR_ERR(priv->clk);
+-              dev_err(&pdev->dev, "no clock for device: %d\n", ret);
+-              return ret;
++      if (!(priv->flags & MTK_RNG_SMC)) {
++              priv->clk = devm_clk_get(&pdev->dev, "rng");
++              if (IS_ERR(priv->clk)) {
++                      ret = PTR_ERR(priv->clk);
++                      dev_err(&pdev->dev, "no clock for device: %d\n", ret);
++                      return ret;
++              }
++
++              priv->base = devm_platform_ioremap_resource(pdev, 0);
++              if (IS_ERR(priv->base))
++                      return PTR_ERR(priv->base);
++
++              if (IS_ENABLED(CONFIG_HAVE_ARM_SMCCC) &&
++                  of_device_is_compatible(pdev->dev.of_node,
++                                          "mediatek,mt7986-rng") &&
++                  !mtk_rng_hw_accessible(priv)) {
++                      priv->flags |= MTK_RNG_SMC;
++                      dev_info(&pdev->dev,
++                               "HW RNG not MMIO accessible, using SMC\n");
++              }
+       }
+-      priv->base = devm_platform_ioremap_resource(pdev, 0);
+-      if (IS_ERR(priv->base))
+-              return PTR_ERR(priv->base);
++      if (priv->flags & MTK_RNG_SMC) {
++              if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC))
++                      return -ENODEV;
++              priv->rng.read = mtk_rng_read_smc;
++      } else {
++#ifndef CONFIG_PM
++              priv->rng.init = mtk_rng_init;
++              priv->rng.cleanup = mtk_rng_cleanup;
++#endif
++              priv->rng.read = mtk_rng_read;
++      }
+       ret = devm_hwrng_register(&pdev->dev, &priv->rng);
+       if (ret) {
+@@ -140,12 +218,15 @@ static int mtk_rng_probe(struct platform
+               return ret;
+       }
+-      dev_set_drvdata(&pdev->dev, priv);
+-      pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT);
+-      pm_runtime_use_autosuspend(&pdev->dev);
+-      ret = devm_pm_runtime_enable(&pdev->dev);
+-      if (ret)
+-              return ret;
++      if (!(priv->flags & MTK_RNG_SMC)) {
++              dev_set_drvdata(&pdev->dev, priv);
++              pm_runtime_set_autosuspend_delay(&pdev->dev,
++                                               RNG_AUTOSUSPEND_TIMEOUT);
++              pm_runtime_use_autosuspend(&pdev->dev);
++              ret = devm_pm_runtime_enable(&pdev->dev);
++              if (ret)
++                      return ret;
++      }
+       dev_info(&pdev->dev, "registered RNG driver\n");
+@@ -182,8 +263,12 @@ static const struct dev_pm_ops mtk_rng_p
+ #endif        /* CONFIG_PM */
+ static const struct of_device_id mtk_rng_match[] = {
+-      { .compatible = "mediatek,mt7986-rng" },
+       { .compatible = "mediatek,mt7623-rng" },
++      { .compatible = "mediatek,mt7622-rng" },
++      { .compatible = "mediatek,mt7981-rng", .data = (void *)MTK_RNG_SMC },
++      { .compatible = "mediatek,mt7986-rng" },
++      { .compatible = "mediatek,mt7987-rng", .data = (void *)MTK_RNG_SMC },
++      { .compatible = "mediatek,mt7988-rng", .data = (void *)MTK_RNG_SMC },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, mtk_rng_match);
+@@ -201,4 +286,5 @@ module_platform_driver(mtk_rng_driver);
+ MODULE_DESCRIPTION("Mediatek Random Number Generator Driver");
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+ MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/patches-6.12/330-snand-mtk-bmt-support.patch b/target/linux/mediatek/patches-6.12/330-snand-mtk-bmt-support.patch
new file mode 100644 (file)
index 0000000..28e63eb
--- /dev/null
@@ -0,0 +1,46 @@
+From 68d5efaa10cf0689521fe05e386e3a1e11d8cb29 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Thu, 7 Apr 2022 10:16:47 +0800
+Subject: [PATCH] mtd: spinand: attach/detach MTK BMT on probe/remove
+
+Call mtk_bmt_attach() after the MTD device is registered in
+spinand_probe() and mtk_bmt_detach() before it is unregistered in
+spinand_remove() to enable the MediaTek bad block management table for
+SPI-NAND devices.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -19,6 +19,7 @@
+ #include <linux/string.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/spi-mem.h>
++#include <linux/mtd/mtk_bmt.h>
+ static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
+ {
+@@ -1604,6 +1605,7 @@ static int spinand_probe(struct spi_mem
+       if (ret)
+               return ret;
++      mtk_bmt_attach(mtd);
+       ret = mtd_device_register(mtd, NULL, 0);
+       if (ret)
+               goto err_spinand_cleanup;
+@@ -1611,6 +1613,7 @@ static int spinand_probe(struct spi_mem
+       return 0;
+ err_spinand_cleanup:
++      mtk_bmt_detach(mtd);
+       spinand_cleanup(spinand);
+       return ret;
+@@ -1629,6 +1632,7 @@ static int spinand_remove(struct spi_mem
+       if (ret)
+               return ret;
++      mtk_bmt_detach(mtd);
+       spinand_cleanup(spinand);
+       return 0;
diff --git a/target/linux/mediatek/patches-6.12/331-mt7622-rfb1-enable-bmt.patch b/target/linux/mediatek/patches-6.12/331-mt7622-rfb1-enable-bmt.patch
new file mode 100644 (file)
index 0000000..d1bc35f
--- /dev/null
@@ -0,0 +1,17 @@
+From f9a28d216d65b55e1139e2c73d016c5e77d7fe0b Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 4 Dec 2021 22:46:00 +0100
+Subject: [PATCH] mediatek: enable bmt on mt7622-rfb1
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -572,6 +572,7 @@
+               spi-tx-bus-width = <4>;
+               spi-rx-bus-width = <4>;
+               nand-ecc-engine = <&snfi>;
++              mediatek,bmt-v2;
+               partitions {
+                       compatible = "fixed-partitions";
diff --git a/target/linux/mediatek/patches-6.12/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch b/target/linux/mediatek/patches-6.12/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch
new file mode 100644 (file)
index 0000000..05a02bd
--- /dev/null
@@ -0,0 +1,123 @@
+From 5f49a5c9b16330e0df8f639310e4715dcad71947 Mon Sep 17 00:00:00 2001
+From: Davide Fioravanti <pantanastyle@gmail.com>
+Date: Fri, 8 Jan 2021 15:35:24 +0100
+Subject: [PATCH] mtd: spinand: Add support for the Fidelix FM35X1GA
+
+Datasheet: http://www.hobos.com.cn/upload/datasheet/DS35X1GAXXX_100_rev00.pdf
+
+Signed-off-by: Davide Fioravanti <pantanastyle@gmail.com>
+---
+ drivers/mtd/nand/spi/Makefile  |  2 +-
+ drivers/mtd/nand/spi/core.c    |  1 +
+ drivers/mtd/nand/spi/fidelix.c | 76 ++++++++++++++++++++++++++++++++++
+ include/linux/mtd/spinand.h    |  1 +
+ 4 files changed, 79 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/mtd/nand/spi/fidelix.c
+
+--- a/drivers/mtd/nand/spi/Makefile
++++ b/drivers/mtd/nand/spi/Makefile
+@@ -1,4 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0
+-spinand-objs := core.o alliancememory.o ato.o esmt.o etron.o fmsh.o foresee.o gigadevice.o
++spinand-objs := core.o alliancememory.o ato.o esmt.o etron.o fidelix.o fmsh.o foresee.o gigadevice.o
+ spinand-objs += macronix.o micron.o paragon.o skyhigh.o toshiba.o winbond.o xtx.o
+ obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1189,6 +1189,7 @@ static const struct spinand_manufacturer
+       &esmt_c8_spinand_manufacturer,
+       &etron_spinand_manufacturer,
+       &fmsh_spinand_manufacturer,
++      &fidelix_spinand_manufacturer,
+       &foresee_spinand_manufacturer,
+       &gigadevice_spinand_manufacturer,
+       &macronix_spinand_manufacturer,
+--- /dev/null
++++ b/drivers/mtd/nand/spi/fidelix.c
+@@ -0,0 +1,76 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2020 Davide Fioravanti <pantanastyle@gmail.com>
++ */
++
++#include <linux/device.h>
++#include <linux/kernel.h>
++#include <linux/mtd/spinand.h>
++
++#define SPINAND_MFR_FIDELIX           0xE5
++#define FIDELIX_ECCSR_MASK            0x0F
++
++static SPINAND_OP_VARIANTS(read_cache_variants,
++              SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
++
++static SPINAND_OP_VARIANTS(write_cache_variants,
++              SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
++              SPINAND_PROG_LOAD(true, 0, NULL, 0));
++
++static SPINAND_OP_VARIANTS(update_cache_variants,
++              SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
++              SPINAND_PROG_LOAD(true, 0, NULL, 0));
++
++static int fm35x1ga_ooblayout_ecc(struct mtd_info *mtd, int section,
++                                struct mtd_oob_region *region)
++{
++      if (section > 3)
++              return -ERANGE;
++
++      region->offset = (16 * section) + 8;
++      region->length = 8;
++
++      return 0;
++}
++
++static int fm35x1ga_ooblayout_free(struct mtd_info *mtd, int section,
++                                 struct mtd_oob_region *region)
++{
++      if (section > 3)
++              return -ERANGE;
++
++      region->offset = (16 * section) + 2;
++      region->length = 6;
++
++      return 0;
++}
++
++static const struct mtd_ooblayout_ops fm35x1ga_ooblayout = {
++      .ecc = fm35x1ga_ooblayout_ecc,
++      .free = fm35x1ga_ooblayout_free,
++};
++
++static const struct spinand_info fidelix_spinand_table[] = {
++      SPINAND_INFO("FM35X1GA",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71),
++                   NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&fm35x1ga_ooblayout, NULL)),
++};
++
++static const struct spinand_manufacturer_ops fidelix_spinand_manuf_ops = {
++};
++
++const struct spinand_manufacturer fidelix_spinand_manufacturer = {
++      .id = SPINAND_MFR_FIDELIX,
++      .name = "Fidelix",
++      .chips = fidelix_spinand_table,
++      .nchips = ARRAY_SIZE(fidelix_spinand_table),
++      .ops = &fidelix_spinand_manuf_ops,
++};
+--- a/include/linux/mtd/spinand.h
++++ b/include/linux/mtd/spinand.h
+@@ -266,6 +266,7 @@ extern const struct spinand_manufacturer
+ extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
+ extern const struct spinand_manufacturer etron_spinand_manufacturer;
+ extern const struct spinand_manufacturer fmsh_spinand_manufacturer;
++extern const struct spinand_manufacturer fidelix_spinand_manufacturer;
+ extern const struct spinand_manufacturer foresee_spinand_manufacturer;
+ extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
+ extern const struct spinand_manufacturer macronix_spinand_manufacturer;
diff --git a/target/linux/mediatek/patches-6.12/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch b/target/linux/mediatek/patches-6.12/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch
new file mode 100644 (file)
index 0000000..c52ed76
--- /dev/null
@@ -0,0 +1,45 @@
+From patchwork Fri Apr 19 16:59:07 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13636668
+Return-Path: 
+ <linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org>
+Date: Fri, 19 Apr 2024 17:59:07 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+To: "Rafael J. Wysocki" <rafael@kernel.org>,
+       Viresh Kumar <viresh.kumar@linaro.org>,
+       Matthias Brugger <matthias.bgg@gmail.com>,
+       AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
+       linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org,
+       linux-arm-kernel@lists.infradead.org,
+       linux-mediatek@lists.infradead.org
+Subject: [PATCH] cpufreq: mediatek: Add support for MT7988A
+Message-ID: 
+ <acf4fb446aacfbf6ce7b6e94bf3aad303e0ad4d1.1713545923.git.daniel@makrotopia.org>
+Content-Disposition: inline
+List-Id: <linux-mediatek.lists.infradead.org>
+
+From: Sam Shih <sam.shih@mediatek.com>
+
+This add cpufreq support for mediatek MT7988A SoC.
+
+The platform data of MT7988A is different from previous MediaTek SoCs,
+so we add a new compatible and platform data for it.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -744,6 +744,7 @@ static const struct of_device_id mtk_cpu
+       { .compatible = "mediatek,mt7622", .data = &mt7622_platform_data },
+       { .compatible = "mediatek,mt7623", .data = &mt7623_platform_data },
+       { .compatible = "mediatek,mt7988a", .data = &mt7988_platform_data },
++      { .compatible = "mediatek,mt7988d", .data = &mt7988_platform_data },
+       { .compatible = "mediatek,mt8167", .data = &mt8516_platform_data },
+       { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data },
+       { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data },
diff --git a/target/linux/mediatek/patches-6.12/360-pinctrl-mediatek-add-mt7987-pinctrl-support.patch b/target/linux/mediatek/patches-6.12/360-pinctrl-mediatek-add-mt7987-pinctrl-support.patch
new file mode 100644 (file)
index 0000000..061a14c
--- /dev/null
@@ -0,0 +1,793 @@
+From e37d53fb387eb788dff33cdc4c1009543e2ccd5f Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Mon, 20 Jan 2025 19:49:34 +0800
+Subject: [PATCH 1/2] pinctrl: mediatek: add mt7987 pinctrl support
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/pinctrl/mediatek/Kconfig          |   6 +
+ drivers/pinctrl/mediatek/Makefile         |   1 +
+ drivers/pinctrl/mediatek/pinctrl-mt7987.c | 752 ++++++++++++++++++++++
+ 3 files changed, 759 insertions(+)
+ create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7987.c
+
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -187,6 +187,13 @@ config PINCTRL_MT7986
+       default ARM64 && ARCH_MEDIATEK
+       select PINCTRL_MTK_MOORE
++config PINCTRL_MT7987
++      bool "Mediatek MT7987 pin control"
++      depends on OF
++      depends on ARM64 || COMPILE_TEST
++      default ARM64 && ARCH_MEDIATEK
++      select PINCTRL_MTK_MOORE
++
+ config PINCTRL_MT7988
+       bool "Mediatek MT7988 pin control"
+       depends on OF
+--- a/drivers/pinctrl/mediatek/Makefile
++++ b/drivers/pinctrl/mediatek/Makefile
+@@ -27,6 +27,7 @@ obj-$(CONFIG_PINCTRL_MT7623)         += pinctrl
+ obj-$(CONFIG_PINCTRL_MT7629)          += pinctrl-mt7629.o
+ obj-$(CONFIG_PINCTRL_MT7981)          += pinctrl-mt7981.o
+ obj-$(CONFIG_PINCTRL_MT7986)          += pinctrl-mt7986.o
++obj-$(CONFIG_PINCTRL_MT7987)          += pinctrl-mt7987.o
+ obj-$(CONFIG_PINCTRL_MT7988)          += pinctrl-mt7988.o
+ obj-$(CONFIG_PINCTRL_MT8167)          += pinctrl-mt8167.o
+ obj-$(CONFIG_PINCTRL_MT8173)          += pinctrl-mt8173.o
+--- /dev/null
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7987.c
+@@ -0,0 +1,751 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * The MT7987 driver based on Linux generic pinctrl binding.
++ *
++ * Copyright (C) 2020 MediaTek Inc.
++ * Author: Tim.Kuo <Tim.Kuo@mediatek.com>
++ */
++
++#include "pinctrl-moore.h"
++
++enum MT7987_PINCTRL_REG_PAGE {
++      GPIO_BASE,
++      IOCFG_RB_BASE,
++      IOCFG_LB_BASE,
++      IOCFG_RT1_BASE,
++      IOCFG_RT2_BASE,
++      IOCFG_TL_BASE,
++};
++
++#define MT7987_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
++
++#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
++                     _x_bits)                                                \
++      PIN_FIELD_CALC(_s_pin, _e_pin, _i_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_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
++                     _x_bits, 32, 0)
++
++
++#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,    \
++                      _x_bits)                                               \
++      PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
++                     _x_bits, 32, 1)
++
++static const struct mtk_pin_field_calc mt7987_pin_mode_range[] = {
++      PIN_FIELD(0, 49, 0x300, 0x10, 0, 4),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_dir_range[] = {
++      PIN_FIELD(0, 49, 0x0, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_di_range[] = {
++      PIN_FIELD(0, 49, 0x200, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_do_range[] = {
++      PIN_FIELD(0, 49, 0x100, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_ies_range[] = {
++      PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x20, 0x10, 11, 1),
++      PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x20, 0x10, 4, 1),
++      PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x10, 0x10, 2, 1),
++      PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x10, 0x10, 1, 1),
++      PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x10, 0x10, 0, 1),
++      PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x10, 0x10, 3, 1),
++      PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x10, 0x10, 4, 1),
++      PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x20, 0x10, 15, 1),
++      PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x20, 0x10, 7, 1),
++      PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x20, 0x10, 6, 1),
++      PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x20, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x20, 0x10, 5, 1),
++      PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x20, 0x10, 8, 1),
++      PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x20, 0x10, 9, 1),
++      PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x20, 0x10, 12, 1),
++      PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x20, 0x10, 11, 1),
++      PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x20, 0x10, 10, 1),
++      PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x20, 0x10, 13, 1),
++      PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x20, 0x10, 14, 1),
++      PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x20, 0x10, 9, 1),
++      PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x20, 0x10, 7, 1),
++      PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x20, 0x10, 8, 1),
++      PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x20, 0x10, 10, 1),
++      PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x20, 0x10, 5, 1),
++      PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x20, 0x10, 6, 1),
++      PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x20, 0x10, 4, 1),
++      PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x20, 0x10, 5, 1),
++      PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x20, 0x10, 4, 1),
++      PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x20, 0x10, 5, 1),
++      PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x20, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x20, 0x10, 9, 1),
++      PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x20, 0x10, 10, 1),
++      PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x20, 0x10, 7, 1),
++      PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x20, 0x10, 8, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_smt_range[] = {
++      PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x90, 0x10, 3, 1),
++      PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x90, 0x10, 2, 1),
++      PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x90, 0x10, 11, 1),
++      PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x90, 0x10, 2, 1),
++      PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x90, 0x10, 1, 1),
++      PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x90, 0x10, 3, 1),
++      PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x90, 0x10, 0, 1),
++      PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x90, 0x10, 4, 1),
++      PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x70, 0x10, 2, 1),
++      PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x70, 0x10, 1, 1),
++      PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x70, 0x10, 0, 1),
++      PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x70, 0x10, 3, 1),
++      PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x70, 0x10, 4, 1),
++      PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0xA0, 0x10, 0, 1),
++      PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0xA0, 0x10, 15, 1),
++      PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0xA0, 0x10, 3, 1),
++      PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0xA0, 0x10, 7, 1),
++      PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0xA0, 0x10, 6, 1),
++      PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0xA0, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0xA0, 0x10, 5, 1),
++      PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0xA0, 0x10, 8, 1),
++      PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0xA0, 0x10, 9, 1),
++      PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0xA0, 0x10, 12, 1),
++      PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0xA0, 0x10, 11, 1),
++      PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0xA0, 0x10, 10, 1),
++      PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0xA0, 0x10, 13, 1),
++      PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0xA0, 0x10, 14, 1),
++      PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x90, 0x10, 9, 1),
++      PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x90, 0x10, 7, 1),
++      PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x90, 0x10, 8, 1),
++      PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x90, 0x10, 10, 1),
++      PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x90, 0x10, 5, 1),
++      PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x90, 0x10, 6, 1),
++      PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
++      PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x60, 0x10, 0, 1),
++      PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x60, 0x10, 4, 1),
++      PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x60, 0x10, 3, 1),
++      PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x60, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x60, 0x10, 5, 1),
++      PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0xA0, 0x10, 1, 1),
++      PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0xA0, 0x10, 2, 1),
++      PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x90, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x90, 0x10, 1, 1),
++      PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x90, 0x10, 4, 1),
++      PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x90, 0x10, 5, 1),
++      PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x90, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x90, 0x10, 9, 1),
++      PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x90, 0x10, 10, 1),
++      PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x90, 0x10, 7, 1),
++      PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x90, 0x10, 8, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_pu_range[] = {
++      PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x40, 0x10, 5, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_pd_range[] = {
++      PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x30, 0x10, 5, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_drv_range[] = {
++      PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x0, 0x10, 9, 3),
++      PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x0, 0x10, 6, 3),
++      PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x10, 0x10, 3, 3),
++      PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x0, 0x10, 6, 3),
++      PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x0, 0x10, 3, 3),
++      PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x0, 0x10, 9, 3),
++      PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x0, 0x10, 0, 3),
++      PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x0, 0x10, 12, 3),
++      PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x0, 0x10, 6, 3),
++      PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x0, 0x10, 3, 3),
++      PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x0, 0x10, 0, 3),
++      PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x0, 0x10, 9, 3),
++      PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x0, 0x10, 12, 3),
++      PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x0, 0x10, 0, 3),
++      PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x10, 0x10, 15, 3),
++      PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x0, 0x10, 9, 3),
++      PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x0, 0x10, 21, 3),
++      PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x0, 0x10, 18, 3),
++      PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x0, 0x10, 12, 3),
++      PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x0, 0x10, 15, 3),
++      PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x0, 0x10, 24, 3),
++      PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x0, 0x10, 27, 3),
++      PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x10, 0x10, 6, 3),
++      PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x10, 0x10, 3, 3),
++      PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x10, 0x10, 0, 3),
++      PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x10, 0x10, 9, 3),
++      PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x10, 0x10, 12, 3),
++      PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x0, 0x10, 27, 3),
++      PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x0, 0x10, 21, 3),
++      PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x0, 0x10, 24, 3),
++      PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x10, 0x10, 0, 3),
++      PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x0, 0x10, 15, 3),
++      PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x0, 0x10, 18, 3),
++      PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x0, 0x10, 6, 3),
++      PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x0, 0x10, 0, 3),
++      PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x0, 0x10, 12, 3),
++      PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x0, 0x10, 9, 3),
++      PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x0, 0x10, 3, 3),
++      PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x0, 0x10, 15, 3),
++      PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x0, 0x10, 3, 3),
++      PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x0, 0x10, 6, 3),
++      PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x0, 0x10, 0, 3),
++      PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x0, 0x10, 3, 3),
++      PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x0, 0x10, 12, 3),
++      PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x0, 0x10, 15, 3),
++      PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x0, 0x10, 18, 3),
++      PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x0, 0x10, 27, 3),
++      PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x10, 0x10, 0, 3),
++      PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x0, 0x10, 21, 3),
++      PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x0, 0x10, 24, 3),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_pupd_range[] = {
++      PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x30, 0x10, 11, 1),
++      PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x20, 0x10, 4, 1),
++      PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x30, 0x10, 15, 1),
++      PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x30, 0x10, 7, 1),
++      PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x30, 0x10, 6, 1),
++      PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x30, 0x10, 8, 1),
++      PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x30, 0x10, 9, 1),
++      PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x30, 0x10, 12, 1),
++      PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x30, 0x10, 11, 1),
++      PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x30, 0x10, 10, 1),
++      PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x30, 0x10, 13, 1),
++      PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x30, 0x10, 14, 1),
++      PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x30, 0x10, 9, 1),
++      PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x30, 0x10, 7, 1),
++      PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x30, 0x10, 8, 1),
++      PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x30, 0x10, 10, 1),
++      PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x30, 0x10, 6, 1),
++
++      PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x30, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x30, 0x10, 9, 1),
++      PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x30, 0x10, 10, 1),
++      PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x30, 0x10, 7, 1),
++      PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x30, 0x10, 8, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_r0_range[] = {
++      PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x40, 0x10, 11, 1),
++      PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x40, 0x10, 15, 1),
++      PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x40, 0x10, 7, 1),
++      PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x40, 0x10, 6, 1),
++      PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x40, 0x10, 8, 1),
++      PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x40, 0x10, 9, 1),
++      PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x40, 0x10, 12, 1),
++      PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x40, 0x10, 11, 1),
++      PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x40, 0x10, 10, 1),
++      PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x40, 0x10, 13, 1),
++      PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x40, 0x10, 14, 1),
++      PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x40, 0x10, 9, 1),
++      PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x40, 0x10, 7, 1),
++      PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x40, 0x10, 8, 1),
++      PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x40, 0x10, 10, 1),
++      PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x40, 0x10, 6, 1),
++
++      PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x40, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x40, 0x10, 9, 1),
++      PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x40, 0x10, 10, 1),
++      PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x40, 0x10, 7, 1),
++      PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x40, 0x10, 8, 1),
++};
++
++static const struct mtk_pin_field_calc mt7987_pin_r1_range[] = {
++      PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x50, 0x10, 11, 1),
++      PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x50, 0x10, 4, 1),
++      PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x50, 0x10, 15, 1),
++      PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x50, 0x10, 7, 1),
++      PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x50, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x50, 0x10, 8, 1),
++      PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x50, 0x10, 9, 1),
++      PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x50, 0x10, 12, 1),
++      PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x50, 0x10, 11, 1),
++      PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x50, 0x10, 10, 1),
++      PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x50, 0x10, 13, 1),
++      PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x50, 0x10, 14, 1),
++      PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x50, 0x10, 9, 1),
++      PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x50, 0x10, 7, 1),
++      PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x50, 0x10, 8, 1),
++      PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x50, 0x10, 10, 1),
++      PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x50, 0x10, 6, 1),
++
++      PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x50, 0x10, 4, 1),
++      PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x50, 0x10, 9, 1),
++      PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x50, 0x10, 10, 1),
++      PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x50, 0x10, 7, 1),
++      PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x50, 0x10, 8, 1),
++};
++
++static const unsigned int mt7987_pull_type[] = {
++      MTK_PULL_PUPD_R1R0_TYPE,/*0*/ MTK_PULL_PUPD_R1R0_TYPE,/*1*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*2*/ MTK_PULL_PUPD_R1R0_TYPE,/*3*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*4*/ MTK_PULL_PUPD_R1R0_TYPE,/*5*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*6*/ MTK_PULL_PUPD_R1R0_TYPE,/*7*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*8*/ MTK_PULL_PUPD_R1R0_TYPE,/*9*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*10*/ MTK_PULL_PUPD_R1R0_TYPE,/*11*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*12*/ MTK_PULL_PUPD_R1R0_TYPE,/*13*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*14*/ MTK_PULL_PUPD_R1R0_TYPE,/*15*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*16*/ MTK_PULL_PUPD_R1R0_TYPE,/*17*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*18*/ MTK_PULL_PUPD_R1R0_TYPE,/*19*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*24*/ MTK_PULL_PUPD_R1R0_TYPE,/*25*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*26*/ MTK_PULL_PUPD_R1R0_TYPE,/*27*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*28*/ MTK_PULL_PUPD_R1R0_TYPE,/*29*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*30*/ MTK_PULL_PUPD_R1R0_TYPE,/*31*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*32*/ MTK_PULL_PU_PD_TYPE,/*33*/
++      MTK_PULL_PU_PD_TYPE,/*34*/ MTK_PULL_PU_PD_TYPE,/*35*/
++      MTK_PULL_PU_PD_TYPE,/*36*/ MTK_PULL_PU_PD_TYPE,/*37*/
++      MTK_PULL_PU_PD_TYPE,/*38*/ MTK_PULL_PUPD_R1R0_TYPE,/*39*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*44*/ MTK_PULL_PUPD_R1R0_TYPE,/*45*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*46*/ MTK_PULL_PUPD_R1R0_TYPE,/*47*/
++      MTK_PULL_PUPD_R1R0_TYPE,/*48*/ MTK_PULL_PUPD_R1R0_TYPE,/*49*/
++};
++
++static const struct mtk_pin_reg_calc mt7987_reg_cals[] = {
++      [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7987_pin_mode_range),
++      [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7987_pin_dir_range),
++      [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7987_pin_di_range),
++      [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7987_pin_do_range),
++      [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7987_pin_smt_range),
++      [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7987_pin_ies_range),
++      [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7987_pin_pu_range),
++      [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7987_pin_pd_range),
++      [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7987_pin_drv_range),
++      [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7987_pin_pupd_range),
++      [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7987_pin_r0_range),
++      [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7987_pin_r1_range),
++};
++
++static const struct mtk_pin_desc mt7987_pins[] = {
++      MT7987_PIN(0, "GPIO_WPS"),
++      MT7987_PIN(1, "GPIO_RESET"),
++      MT7987_PIN(2, "SYS_WATCHDOG"),
++      MT7987_PIN(3, "JTAG_JTDO"),
++      MT7987_PIN(4, "JTAG_JTDI"),
++      MT7987_PIN(5, "JTAG_JTMS"),
++      MT7987_PIN(6, "JTAG_JTCLK"),
++      MT7987_PIN(7, "JTAG_JTRST_N"),
++      MT7987_PIN(8, "PCM_DTX_I2S_DOUT"),
++      MT7987_PIN(9, "PCM_DRX_I2S_DIN"),
++      MT7987_PIN(10, "PCM_CLK_I2S_BCLK"),
++      MT7987_PIN(11, "PCM_FS_I2S_LRCK"),
++      MT7987_PIN(12, "PCM_MCK_I2S_MCLK"),
++      MT7987_PIN(13, "PWM0"),
++      MT7987_PIN(14, "USB_VBUS"),
++      MT7987_PIN(15, "SPI0_CLK"),
++      MT7987_PIN(16, "SPI0_MOSI"),
++      MT7987_PIN(17, "SPI0_MISO"),
++      MT7987_PIN(18, "SPI0_CS"),
++      MT7987_PIN(19, "SPI0_HOLD"),
++      MT7987_PIN(20, "SPI0_WP"),
++      MT7987_PIN(21, "SPI1_CLK"),
++      MT7987_PIN(22, "SPI1_MOSI"),
++      MT7987_PIN(23, "SPI1_MISO"),
++      MT7987_PIN(24, "SPI1_CS"),
++      MT7987_PIN(25, "SPI2_CLK"),
++      MT7987_PIN(26, "SPI2_MOSI"),
++      MT7987_PIN(27, "SPI2_MISO"),
++      MT7987_PIN(28, "SPI2_CS"),
++      MT7987_PIN(29, "SPI2_HOLD"),
++      MT7987_PIN(30, "SPI2_WP"),
++      MT7987_PIN(31, "UART0_RXD"),
++      MT7987_PIN(32, "UART0_TXD"),
++      MT7987_PIN(33, "PCIE_PERESET_N_0"),
++      MT7987_PIN(34, "PCIE_CLK_REQ_0"),
++      MT7987_PIN(35, "PCIE_WAKE_N_0"),
++      MT7987_PIN(36, "PCIE_PERESET_N_1"),
++      MT7987_PIN(37, "PCIE_CLK_REQ_1"),
++      MT7987_PIN(38, "PCIE_WAKE_N_1"),
++      MT7987_PIN(39, "SMI_MDC"),
++      MT7987_PIN(40, "SMI_MDIO"),
++      MT7987_PIN(41, "GBE_INT"),
++      MT7987_PIN(42, "GBE_RESET"),
++      MT7987_PIN(43, "I2C_SCLK"),
++      MT7987_PIN(44, "I2C_SDATA"),
++      MT7987_PIN(45, "2P5G_LED0"),
++      MT7987_PIN(46, "UART1_RXD"),
++      MT7987_PIN(47, "UART1_TXD"),
++      MT7987_PIN(48, "UART1_CTS"),
++      MT7987_PIN(49, "UART1_RTS"),
++};
++
++/* watchdog */
++static int mt7987_watchdog_pins[] = {2};
++static int mt7987_watchdog_funcs[] = {1};
++
++/* jtag */
++static int mt7987_jtag_pins[] = {3, 4, 5, 6, 7};
++static int mt7987_jtag_funcs[] = {1, 1, 1, 1, 1};
++
++/* i2s */
++static int mt7987_i2s_pins[] = { 8, 9, 10, 11, 12 };
++static int mt7987_i2s_funcs[] = { 1, 1, 1, 1, 1 };
++
++/* pcm */
++static int mt7987_pcm_pins[] = { 8, 9, 10, 11 };
++static int mt7987_pcm_funcs[] = { 1, 1, 1, 1 };
++
++/* uart */
++static int mt7987_uart0_pins[] = {31, 32};
++static int mt7987_uart0_funcs[] = {1, 1};
++
++static int mt7987_uart1_0_pins[] = {3, 4, 5, 6};
++static int mt7987_uart1_0_funcs[] = {3, 3, 3, 3};
++
++static int mt7987_uart1_0_lite_pins[] = {3, 4};
++static int mt7987_uart1_0_lite_funcs[] = {3, 3};
++
++static int mt7987_uart1_1_pins[] = {21, 22, 23, 24};
++static int mt7987_uart1_1_funcs[] = {3, 3, 3, 3};
++
++static int mt7987_uart1_2_pins[] = {46, 47, 48, 49};
++static int mt7987_uart1_2_funcs[] = {1, 1, 1, 1};
++
++static int mt7987_uart2_0_pins[] = {8, 9, 10, 11};
++static int mt7987_uart2_0_funcs[] = {2, 2, 2, 2};
++
++static int mt7987_uart2_1_pins[] = {25, 26, 27, 28};
++static int mt7987_uart2_1_funcs[] = {2, 2, 2, 2};
++
++/* pwm */
++static int mt7987_pwm0_pins[] = {13};
++static int mt7987_pwm0_funcs[] = {1};
++
++static int mt7987_pwm1_0_pins[] = {7};
++static int mt7987_pwm1_0_funcs[] = {3};
++
++static int mt7987_pwm1_1_pins[] = {43};
++static int mt7987_pwm1_1_funcs[] = {2};
++
++static int mt7987_pwm2_0_pins[] = {12};
++static int mt7987_pwm2_0_funcs[] = {2};
++
++static int mt7987_pwm2_1_pins[] = {44};
++static int mt7987_pwm2_1_funcs[] = {2};
++
++/* vbus */
++static int mt7987_drv_vbus_p1_pins[] = {14};
++static int mt7987_drv_vbus_p1_funcs[] = {1};
++
++static int mt7987_drv_vbus_pins[] = {48};
++static int mt7987_drv_vbus_funcs[] = {3};
++
++/* 2p5gbe_led */
++static int mt7987_2p5gbe_led0_pins[] = {45};
++static int mt7987_2p5gbe_led0_funcs[] = {1};
++
++static int mt7987_2p5gbe_led1_0_pins[] = {13};
++static int mt7987_2p5gbe_led1_0_funcs[] = {2};
++
++static int mt7987_2p5gbe_led1_1_pins[] = {49};
++static int mt7987_2p5gbe_led1_1_funcs[] = {3};
++
++/* mdc, mdio */
++static int mt7987_2p5g_ext_mdc_mdio_pins[] = {23, 24};
++static int mt7987_2p5g_ext_mdc_mdio_funcs[] = {4, 4};
++
++static int mt7987_mdc_mdio_pins[] = {39, 40};
++static int mt7987_mdc_mdio_funcs[] = {1, 1};
++
++/* spi */
++static int mt7987_spi0_pins[] = {15, 16, 17, 18};
++static int mt7987_spi0_funcs[] = {1, 1, 1, 1};
++
++static int mt7987_spi0_wp_hold_pins[] = {19, 20};
++static int mt7987_spi0_wp_hold_funcs[] = {1, 1};
++
++static int mt7987_spi1_pins[] = {21, 22, 23, 24};
++static int mt7987_spi1_funcs[] = {1, 1, 1, 1};
++
++static int mt7987_spi1_1_pins[] = {46, 47, 48, 49};
++static int mt7987_spi1_1_funcs[] = {2, 2, 2, 2};
++
++static int mt7987_spi2_pins[] = {25, 26, 27, 28};
++static int mt7987_spi2_funcs[] = {1, 1, 1, 1};
++
++static int mt7987_spi2_wp_hold_pins[] = {29, 30};
++static int mt7987_spi2_wp_hold_funcs[] = {1, 1};
++
++/* emmc */
++static int mt7987_emmc_45_pins[] = {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
++static int mt7987_emmc_45_funcs[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
++
++/* sd */
++static int mt7987_sd_pins[] = {15, 16, 17, 18, 23, 24};
++static int mt7987_sd_funcs[] = {2, 2, 2, 2, 2, 2};
++
++/* i2c */
++static int mt7987_i2c0_0_pins[] = {29, 30};
++static int mt7987_i2c0_0_funcs[] = {2, 2};
++
++static int mt7987_i2c0_1_pins[] = {39, 40};
++static int mt7987_i2c0_1_funcs[] = {2, 2};
++
++static int mt7987_i2c0_2_pins[] = {43, 44};
++static int mt7987_i2c0_2_funcs[] = {1, 1};
++
++/* pcie */
++static int mt7987_pcie0_pereset_pins[] = {33};
++static int mt7987_pcie0_pereset_funcs[] = {1};
++
++static int mt7987_pcie0_clkreq_pins[] = {34};
++static int mt7987_pcie0_clkreq_funcs[] = {1};
++
++static int mt7987_pcie0_wake_pins[] = {35};
++static int mt7987_pcie0_wake_funcs[] = {1};
++
++static int mt7987_pcie1_pereset_pins[] = {36};
++static int mt7987_pcie1_pereset_funcs[] = {1};
++
++static int mt7987_pcie1_clkreq_pins[] = {37};
++static int mt7987_pcie1_clkreq_funcs[] = {1};
++
++static int mt7987_pcie1_wake_pins[] = {38};
++static int mt7987_pcie1_wake_funcs[] = {1};
++
++static int mt7987_pcie_phy_i2c_pins[] = {43, 44};
++static int mt7987_pcie_phy_i2c_funcs[] = {3, 3};
++
++static const struct group_desc mt7987_groups[] = {
++      PINCTRL_PIN_GROUP("watchdog", mt7987_watchdog),
++      PINCTRL_PIN_GROUP("jtag", mt7987_jtag),
++      PINCTRL_PIN_GROUP("i2s", mt7987_i2s),
++      PINCTRL_PIN_GROUP("pcm", mt7987_pcm),
++      PINCTRL_PIN_GROUP("uart0", mt7987_uart0),
++      PINCTRL_PIN_GROUP("uart1_0", mt7987_uart1_0),
++      PINCTRL_PIN_GROUP("uart1_0_lite", mt7987_uart1_0_lite),
++      PINCTRL_PIN_GROUP("uart1_1", mt7987_uart1_1),
++      PINCTRL_PIN_GROUP("uart1_2", mt7987_uart1_2),
++      PINCTRL_PIN_GROUP("uart2_0", mt7987_uart2_0),
++      PINCTRL_PIN_GROUP("uart2_1", mt7987_uart2_1),
++      PINCTRL_PIN_GROUP("pwm0", mt7987_pwm0),
++      PINCTRL_PIN_GROUP("pwm1_0", mt7987_pwm1_0),
++      PINCTRL_PIN_GROUP("pwm1_1", mt7987_pwm1_1),
++      PINCTRL_PIN_GROUP("pwm2_0", mt7987_pwm2_0),
++      PINCTRL_PIN_GROUP("pwm2_1", mt7987_pwm2_1),
++      PINCTRL_PIN_GROUP("drv_vbus_p1", mt7987_drv_vbus_p1),
++      PINCTRL_PIN_GROUP("drv_vbus", mt7987_drv_vbus),
++      PINCTRL_PIN_GROUP("2p5gbe_led0", mt7987_2p5gbe_led0),
++      PINCTRL_PIN_GROUP("2p5gbe_led1_0", mt7987_2p5gbe_led1_0),
++      PINCTRL_PIN_GROUP("2p5gbe_led1_1", mt7987_2p5gbe_led1_1),
++      PINCTRL_PIN_GROUP("2p5g_ext_mdc_mdio", mt7987_2p5g_ext_mdc_mdio),
++      PINCTRL_PIN_GROUP("mdc_mdio", mt7987_mdc_mdio),
++      PINCTRL_PIN_GROUP("spi0", mt7987_spi0),
++      PINCTRL_PIN_GROUP("spi0_wp_hold", mt7987_spi0_wp_hold),
++      PINCTRL_PIN_GROUP("spi1", mt7987_spi1),
++      PINCTRL_PIN_GROUP("spi1_1", mt7987_spi1_1),
++      PINCTRL_PIN_GROUP("spi2", mt7987_spi2),
++      PINCTRL_PIN_GROUP("spi2_wp_hold", mt7987_spi2_wp_hold),
++      PINCTRL_PIN_GROUP("emmc_45", mt7987_emmc_45),
++      PINCTRL_PIN_GROUP("sd", mt7987_sd),
++      PINCTRL_PIN_GROUP("i2c0_0", mt7987_i2c0_0),
++      PINCTRL_PIN_GROUP("i2c0_1", mt7987_i2c0_1),
++      PINCTRL_PIN_GROUP("i2c0_2", mt7987_i2c0_2),
++      PINCTRL_PIN_GROUP("pcie0_pereset", mt7987_pcie0_pereset),
++      PINCTRL_PIN_GROUP("pcie0_clkreq", mt7987_pcie0_clkreq),
++      PINCTRL_PIN_GROUP("pcie0_wake", mt7987_pcie0_wake),
++      PINCTRL_PIN_GROUP("pcie1_pereset", mt7987_pcie1_pereset),
++      PINCTRL_PIN_GROUP("pcie1_clkreq", mt7987_pcie1_clkreq),
++      PINCTRL_PIN_GROUP("pcie1_wake", mt7987_pcie1_wake),
++      PINCTRL_PIN_GROUP("pcie1_pcie_phy_i2c", mt7987_pcie_phy_i2c),
++};
++
++static const char *const mt7987_audio_groups[] = {"i2s", "pcm",};
++static const char *const mt7987_wdt_groups[] = {"watchdog",};
++static const char *const mt7987_jtag_groups[] = {"jtag",};
++static const char *const mt7987_uart_groups[] = {"uart0", "uart1_0",
++                                               "uart1_0_lite", "uart1_1",
++                                               "uart1_2", "uart2_0",
++                                               "uart2_1",};
++static const char *const mt7987_pwm_groups[] = {"pwm0", "pwm1_0", "pwm1_1", "pwm2_0",
++                                             "pwm2_1",};
++static const char *const mt7987_usb_groups[] = {"drv_vbus_p1", "drv_vbus",};
++static const char *const mt7987_led_groups[] = {"2p5gbe_led0", "2p5gbe_led1_0",
++                                             "2p5gbe_led1_1",};
++static const char *const mt7987_ethernet_groups[] = {"2p5g_ext_mdc_mdio", "mdc_mdio",};
++static const char *const mt7987_spi_groups[] = {"spi0", "spi0_wp_hold", "spi1",
++                                              "spi1_1", "spi2", "spi2_wp_hold",};
++static const char *const mt7987_flash_groups[] = {"emmc_45", "sd",};
++static const char *const mt7987_i2c_groups[] = {"i2c0_0", "i2c0_1", "i2c0_2",};
++static const char *const mt7987_pcie_groups[] = {"pcie_phy_i2c", "pcie0_pereset",
++                                               "pcie0_clkreq", "pcie0_wake",
++                                               "pcie1_pereset", "pcie1_clkreq",
++                                               "pcie1_wake",};
++
++
++static const struct function_desc mt7987_functions[] = {
++      { {"audio", mt7987_audio_groups, ARRAY_SIZE(mt7987_audio_groups)}, NULL },
++      { {"wdt", mt7987_wdt_groups, ARRAY_SIZE(mt7987_wdt_groups)}, NULL },
++      { {"jtag", mt7987_jtag_groups, ARRAY_SIZE(mt7987_jtag_groups)}, NULL },
++      { {"uart", mt7987_uart_groups, ARRAY_SIZE(mt7987_uart_groups)}, NULL },
++      { {"pwm", mt7987_pwm_groups, ARRAY_SIZE(mt7987_pwm_groups)}, NULL },
++      { {"usb", mt7987_usb_groups, ARRAY_SIZE(mt7987_usb_groups)}, NULL },
++      { {"led", mt7987_led_groups, ARRAY_SIZE(mt7987_led_groups)}, NULL },
++      { {"eth", mt7987_ethernet_groups, ARRAY_SIZE(mt7987_ethernet_groups)}, NULL },
++      { {"spi", mt7987_spi_groups, ARRAY_SIZE(mt7987_spi_groups)}, NULL },
++      { {"flash", mt7987_flash_groups, ARRAY_SIZE(mt7987_flash_groups)}, NULL },
++      { {"i2c", mt7987_i2c_groups, ARRAY_SIZE(mt7987_i2c_groups)}, NULL },
++      { {"pcie", mt7987_pcie_groups, ARRAY_SIZE(mt7987_pcie_groups)}, NULL },
++};
++
++static const struct mtk_eint_hw mt7987_eint_hw = {
++      .port_mask = 7,
++      .ports = 7,
++      .ap_num = ARRAY_SIZE(mt7987_pins),
++      .db_cnt = 16,
++};
++
++static const char * const mt7987_pinctrl_register_base_names[] = {
++      "gpio", "iocfg_rb", "iocfg_lb", "iocfg_rt1", "iocfg_rt2", "iocfg_tl",
++};
++
++static struct mtk_pin_soc mt7987_data = {
++      .reg_cal = mt7987_reg_cals,
++      .pins = mt7987_pins,
++      .npins = ARRAY_SIZE(mt7987_pins),
++      .grps = mt7987_groups,
++      .ngrps = ARRAY_SIZE(mt7987_groups),
++      .funcs = mt7987_functions,
++      .nfuncs = ARRAY_SIZE(mt7987_functions),
++      .eint_hw = &mt7987_eint_hw,
++      .gpio_m = 0,
++      .ies_present = true,
++      .base_names = mt7987_pinctrl_register_base_names,
++      .nbase_names = ARRAY_SIZE(mt7987_pinctrl_register_base_names),
++      .bias_disable_set = mtk_pinconf_bias_disable_set,
++      .bias_disable_get = mtk_pinconf_bias_disable_get,
++      .bias_set = mtk_pinconf_bias_set,
++      .bias_get = mtk_pinconf_bias_get,
++      .pull_type = mt7987_pull_type,
++      .bias_set_combo = mtk_pinconf_bias_set_combo,
++      .bias_get_combo = mtk_pinconf_bias_get_combo,
++      .drive_set = mtk_pinconf_drive_set_rev1,
++      .drive_get = mtk_pinconf_drive_get_rev1,
++      .adv_pull_get = mtk_pinconf_adv_pull_get,
++      .adv_pull_set = mtk_pinconf_adv_pull_set,
++};
++
++static const struct of_device_id mt7987_pinctrl_of_match[] = {
++      {
++              .compatible = "mediatek,mt7987-pinctrl",
++      },
++      {}
++};
++
++static int mt7987_pinctrl_probe(struct platform_device *pdev)
++{
++      return mtk_moore_pinctrl_probe(pdev, &mt7987_data);
++}
++
++static struct platform_driver mt7987_pinctrl_driver = {
++      .driver = {
++              .name = "mt7987-pinctrl",
++              .of_match_table = mt7987_pinctrl_of_match,
++      },
++      .probe = mt7987_pinctrl_probe,
++};
++
++static int __init mt7987_pinctrl_init(void)
++{
++      return platform_driver_register(&mt7987_pinctrl_driver);
++}
++arch_initcall(mt7987_pinctrl_init);
diff --git a/target/linux/mediatek/patches-6.12/361-clk-mediatek-add-mt7987-clock-drivers-support.patch b/target/linux/mediatek/patches-6.12/361-clk-mediatek-add-mt7987-clock-drivers-support.patch
new file mode 100644 (file)
index 0000000..249e239
--- /dev/null
@@ -0,0 +1,1187 @@
+From 08b3847982f4c470ff1ac0761bed0d8d83f1fd49 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Mon, 20 Jan 2025 19:50:03 +0800
+Subject: [PATCH 2/2] clk: mediatek: add mt7987 clock drivers support
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/clk/mediatek/Kconfig                  |   9 +
+ drivers/clk/mediatek/Makefile                 |   5 +
+ drivers/clk/mediatek/clk-mt7987-apmixed.c     | 116 +++++++
+ drivers/clk/mediatek/clk-mt7987-eth.c         |  94 +++++
+ drivers/clk/mediatek/clk-mt7987-infracfg.c    | 328 ++++++++++++++++++
+ drivers/clk/mediatek/clk-mt7987-mcusys.c      |  47 +++
+ drivers/clk/mediatek/clk-mt7987-topckgen.c    | 311 +++++++++++++++++
+ .../dt-bindings/clock/mediatek,mt7987-clk.h   | 206 +++++++++++
+ .../reset/mediatek,mt7987-resets.h            |  10 +
+ 9 files changed, 1126 insertions(+)
+ create mode 100644 drivers/clk/mediatek/clk-mt7987-apmixed.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7987-eth.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7987-infracfg.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7987-mcusys.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7987-topckgen.c
+ create mode 100644 include/dt-bindings/clock/mediatek,mt7987-clk.h
+ create mode 100644 include/dt-bindings/reset/mediatek,mt7987-resets.h
+
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -423,6 +423,15 @@ config COMMON_CLK_MT7986_ETHSYS
+         This driver adds support for clocks for Ethernet and SGMII
+         required on MediaTek MT7986 SoC.
++config COMMON_CLK_MT7987
++      tristate "Clock driver for MediaTek MT7987"
++      depends on ARCH_MEDIATEK || COMPILE_TEST
++      select COMMON_CLK_MEDIATEK
++      default ARCH_MEDIATEK
++      help
++        This driver supports MediaTek MT7987 basic clocks and clocks
++        required for various periperals found on this SoC.
++
+ config COMMON_CLK_MT7988
+       tristate "Clock driver for MediaTek MT7988"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -62,6 +62,11 @@ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-m
+ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
+ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
+ obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
++obj-$(CONFIG_COMMON_CLK_MT7987) += clk-mt7987-apmixed.o
++obj-$(CONFIG_COMMON_CLK_MT7987) += clk-mt7987-eth.o
++obj-$(CONFIG_COMMON_CLK_MT7987) += clk-mt7987-infracfg.o
++obj-$(CONFIG_COMMON_CLK_MT7987) += clk-mt7987-mcusys.o
++obj-$(CONFIG_COMMON_CLK_MT7987) += clk-mt7987-topckgen.o
+ obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-apmixed.o
+ obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-topckgen.o
+ obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-infracfg.o
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7987-apmixed.c
+@@ -0,0 +1,116 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2024 MediaTek Inc.
++ * Author: Lu Tang <Lu.Tang@mediatek.com>
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include "clk-mtk.h"
++#include "clk-gate.h"
++#include "clk-mux.h"
++#include "clk-pll.h"
++#include <dt-bindings/clock/mediatek,mt7987-clk.h>
++
++#define MT7987_PLL_FMAX (2500UL * MHZ)
++#define MT7987_PCW_CHG_SHIFT 2
++
++#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask,     \
++            _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,         \
++            _tuner_en_bit, _pcw_reg, _pcw_shift, _pcw_chg_reg, _div_table,   \
++            _parent_name)                                                    \
++      {                                                                      \
++              .id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg,    \
++              .en_mask = _en_mask, .flags = _flags,                          \
++              .rst_bar_mask = BIT(_rst_bar_mask), .fmax = MT7987_PLL_FMAX,   \
++              .pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \
++              .tuner_reg = _tuner_reg, .tuner_en_reg = _tuner_en_reg,        \
++              .tuner_en_bit = _tuner_en_bit, .pcw_reg = _pcw_reg,            \
++              .pcw_shift = _pcw_shift, .pcw_chg_reg = _pcw_chg_reg,          \
++              .pcw_chg_bit = MT7987_PCW_CHG_SHIFT,                           \
++              .div_table = _div_table, .parent_name = _parent_name,          \
++      }
++
++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask,     \
++          _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,         \
++          _tuner_en_bit, _pcw_reg, _pcw_shift, _pcw_chg_reg, _parent_name) \
++      PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask,   \
++            _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg,       \
++            _tuner_en_bit, _pcw_reg, _pcw_shift, _pcw_chg_reg, NULL,       \
++            _parent_name)
++
++static const struct mtk_pll_div_table mt7987_arm_ll_div[] = {
++      { .div = 0, .freq = 2000000000 },
++      { .div = 1, .freq = 1500000000 },
++      { .div = 2, .freq = 750000000 },
++      { .div = 3, .freq = 375000000 },
++      {} /* sentinel */
++};
++
++static const struct mtk_pll_data plls[] = {
++      PLL(CLK_APMIXED_MPLL, "mpll", 0x0114, 0x0120, 0xff000001, HAVE_RST_BAR,
++          23, 32, 0x0114, 4, 0, 0, 0, 0x0118, 0, 0x0114, "clkxtal"),
++      PLL(CLK_APMIXED_APLL2, "apll2", 0x0134, 0x0140, 0x00000001, 0, 0, 32,
++          0x0134, 4, 0x0704, 0x0700, 1, 0x0138, 0, 0x0134, "clkxtal"),
++      PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0144, 0x0150, 0xff000001,
++          HAVE_RST_BAR | PLL_AO, 23, 32, 0x0144, 4, 0, 0, 0, 0x0148, 0,
++          0x0144, "clkxtal"),
++      PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0154, 0x0160, 0xff000001,
++          HAVE_RST_BAR | PLL_AO, 23, 32, 0x0154, 4, 0, 0, 0, 0x0158, 0,
++          0x0154, "clkxtal"),
++      PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0164, 0x0170, 0x00000001, 0,
++          0, 32, 0x0164, 4, 0, 0, 0, 0x0168, 0, 0x0164, "clkxtal"),
++      PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0174, 0x0180, 0x00000001, 0, 0, 32,
++          0x0174, 4, 0, 0, 0, 0x0178, 0, 0x0174, "clkxtal"),
++      PLL_B(CLK_APMIXED_ARM_LL, "arm_ll", 0x0104, 0x0110, 0x00000001,
++            PLL_AO, 0, 32, 0x0104, 4, 0, 0, 0, 0x0108, 0, 0x0104,
++            mt7987_arm_ll_div, "clkxtal"),
++      PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0124, 0x0130, 0x00000001, 0, 0,
++          32, 0x0124, 4, 0, 0, 0, 0x0128, 0, 0x0124, "clkxtal"),
++};
++
++static const struct of_device_id of_match_clk_mt7987_apmixed[] = {
++      { .compatible = "mediatek,mt7987-apmixedsys" },
++      { /* sentinel */ }
++};
++
++static int clk_mt7987_apmixed_probe(struct platform_device *pdev)
++{
++      struct clk_hw_onecell_data *clk_data;
++      struct device_node *node = pdev->dev.of_node;
++      int r;
++
++      clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
++      if (!clk_data)
++              return -ENOMEM;
++
++      r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
++      if (r)
++              goto free_apmixed_data;
++
++      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
++      if (r)
++              goto unregister_plls;
++
++      return r;
++
++unregister_plls:
++      mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
++free_apmixed_data:
++      mtk_free_clk_data(clk_data);
++      return r;
++}
++
++static struct platform_driver clk_mt7987_apmixed_drv = {
++      .probe = clk_mt7987_apmixed_probe,
++      .driver = {
++              .name = "mt7987-apmixedsys",
++              .of_match_table = of_match_clk_mt7987_apmixed,
++      },
++};
++builtin_platform_driver(clk_mt7987_apmixed_drv);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7987-eth.c
+@@ -0,0 +1,94 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2024 MediaTek Inc.
++ * Author: Lu Tang <Lu.Tang@mediatek.com>
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include "clk-mtk.h"
++#include "clk-gate.h"
++#include <dt-bindings/clock/mediatek,mt7987-clk.h>
++
++static const struct mtk_gate_regs ethdma_cg_regs = {
++      .set_ofs = 0x30,
++      .clr_ofs = 0x30,
++      .sta_ofs = 0x30,
++};
++
++#define GATE_ETHDMA(_id, _name, _parent, _shift)                  \
++      {                                                         \
++              .id = _id, .name = _name, .parent_name = _parent, \
++              .regs = &ethdma_cg_regs, .shift = _shift,         \
++              .ops = &mtk_clk_gate_ops_no_setclr_inv,           \
++      }
++
++static const struct mtk_gate ethdma_clks[] = {
++      GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en", "netsys_2x_sel", 6),
++      GATE_ETHDMA(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en", "netsys_500m_sel", 7),
++      GATE_ETHDMA(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en", "netsys_500m_sel", 8),
++      GATE_ETHDMA(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", "netsys_500m_sel", 10),
++};
++
++static const struct mtk_clk_desc ethdma_desc = {
++      .clks = ethdma_clks,
++      .num_clks = ARRAY_SIZE(ethdma_clks),
++};
++
++static const struct mtk_gate_regs sgmii_cg_regs = {
++      .set_ofs = 0xe4,
++      .clr_ofs = 0xe4,
++      .sta_ofs = 0xe4,
++};
++
++#define GATE_SGMII(_id, _name, _parent, _shift)                   \
++      {                                                         \
++              .id = _id, .name = _name, .parent_name = _parent, \
++              .regs = &sgmii_cg_regs, .shift = _shift,          \
++              .ops = &mtk_clk_gate_ops_no_setclr_inv,           \
++      }
++
++static const struct mtk_gate sgmii0_clks[] = {
++      GATE_SGMII(CLK_SGM0_TX_EN, "sgm0_tx_en", "clkxtal", 2),
++      GATE_SGMII(CLK_SGM0_RX_EN, "sgm0_rx_en", "clkxtal", 3),
++};
++
++static const struct mtk_clk_desc sgmii0_desc = {
++      .clks = sgmii0_clks,
++      .num_clks = ARRAY_SIZE(sgmii0_clks),
++};
++
++static const struct mtk_gate sgmii1_clks[] = {
++      GATE_SGMII(CLK_SGM1_TX_EN, "sgm1_tx_en", "clkxtal", 2),
++      GATE_SGMII(CLK_SGM1_RX_EN, "sgm1_rx_en", "clkxtal", 3),
++};
++
++static const struct mtk_clk_desc sgmii1_desc = {
++      .clks = sgmii1_clks,
++      .num_clks = ARRAY_SIZE(sgmii1_clks),
++};
++
++static const struct of_device_id of_match_clk_mt7987_eth[] = {
++      { .compatible = "mediatek,mt7987-ethsys", .data = &ethdma_desc },
++      { .compatible = "mediatek,mt7987-sgmiisys0", .data = &sgmii0_desc },
++      { .compatible = "mediatek,mt7987-sgmiisys1", .data = &sgmii1_desc },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_match_clk_mt7987_eth);
++
++static struct platform_driver clk_mt7987_eth_drv = {
++      .driver = {
++              .name = "clk-mt7987-eth",
++              .of_match_table = of_match_clk_mt7987_eth,
++      },
++      .probe = mtk_clk_simple_probe,
++      .remove_new = mtk_clk_simple_remove,
++};
++module_platform_driver(clk_mt7987_eth_drv);
++
++MODULE_DESCRIPTION("MediaTek MT7987 Ethernet clocks driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7987-infracfg.c
+@@ -0,0 +1,325 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2024 MediaTek Inc.
++ * Author: Lu Tang <Lu.Tang@mediatek.com>
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/mfd/syscon.h>
++#include "clk-mtk.h"
++#include "clk-mux.h"
++#include "clk-gate.h"
++#include <dt-bindings/clock/mediatek,mt7987-clk.h>
++#include <dt-bindings/reset/mediatek,mt7987-resets.h>
++
++#define MT7987_INFRA_RST0_SET_OFFSET  0x70
++#define MT7987_INFRA_RST1_SET_OFFSET  0x80
++
++static DEFINE_SPINLOCK(mt7987_clk_lock);
++
++static const char *const infra_mux_uart0_parents[] = { "csw_infra_f26m_sel",
++                                                     "uart_sel" };
++
++static const char *const infra_mux_uart1_parents[] = { "csw_infra_f26m_sel",
++                                                     "uart_sel" };
++
++static const char *const infra_mux_uart2_parents[] = { "csw_infra_f26m_sel",
++                                                     "uart_sel" };
++
++static const char *const infra_mux_spi0_parents[] = {
++      "i2c_sel",
++      "spi_sel"
++};
++
++static const char *const infra_mux_spi1_parents[] = {
++      "i2c_sel",
++      "spim_mst_sel"
++};
++
++static const char *const infra_mux_spi2_bck_parents[] = {
++      "i2c_sel",
++      "spi_sel"
++};
++
++static const char *const infra_pwm_bck_parents[] = { "cb_rtc_32p7k",
++                                                   "csw_infra_f26m_sel",
++                                                   "sysaxi_sel", "pwm_sel" };
++
++static const char *const infra_pcie_gfmux_tl_ck_o_p0_parents[] = {
++      "cb_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
++      "pextp_tl_ck_sel"
++};
++
++static const char *const infra_pcie_gfmux_tl_ck_o_p1_parents[] = {
++      "cb_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
++      "pextp_tl_ck_p1_sel"
++};
++
++static struct mtk_mux infra_muxes[] = {
++      /* MODULE_CLK_SEL_0 */
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART0_SEL, "infra_mux_uart0_sel",
++                           infra_mux_uart0_parents, 0x0018, 0x0010, 0x0014,
++                           0, 1, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART1_SEL, "infra_mux_uart1_sel",
++                           infra_mux_uart1_parents, 0x0018, 0x0010, 0x0014,
++                           1, 1, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART2_SEL, "infra_mux_uart2_sel",
++                           infra_mux_uart2_parents, 0x0018, 0x0010, 0x0014,
++                           2, 1, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI0_SEL, "infra_mux_spi0_sel",
++                           infra_mux_spi0_parents, 0x0018, 0x0010, 0x0014, 4,
++                           1, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI1_SEL, "infra_mux_spi1_sel",
++                           infra_mux_spi1_parents, 0x0018, 0x0010, 0x0014, 5,
++                           1, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI2_BCK_SEL,
++                           "infra_mux_spi2_bck_sel",
++                           infra_mux_spi2_bck_parents, 0x0018, 0x0010,
++                           0x0014, 6, 1, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BCK_SEL, "infra_pwm_bck_sel",
++                           infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 14,
++                           2, -1, -1, -1),
++      /* MODULE_CLK_SEL_1 */
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL,
++                           "infra_pcie_gfmux_tl_ck_o_p0_sel",
++                           infra_pcie_gfmux_tl_ck_o_p0_parents, 0x0028,
++                           0x0020, 0x0024, 0, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL,
++                           "infra_pcie_gfmux_tl_ck_o_p1_sel",
++                           infra_pcie_gfmux_tl_ck_o_p1_parents, 0x0028,
++                           0x0020, 0x0024, 2, 2, -1, -1, -1),
++};
++
++static const struct mtk_gate_regs infra0_cg_regs = {
++      .set_ofs = 0x10,
++      .clr_ofs = 0x14,
++      .sta_ofs = 0x18,
++};
++
++static const struct mtk_gate_regs infra1_cg_regs = {
++      .set_ofs = 0x40,
++      .clr_ofs = 0x44,
++      .sta_ofs = 0x48,
++};
++
++static const struct mtk_gate_regs infra2_cg_regs = {
++      .set_ofs = 0x50,
++      .clr_ofs = 0x54,
++      .sta_ofs = 0x58,
++};
++
++static const struct mtk_gate_regs infra3_cg_regs = {
++      .set_ofs = 0x60,
++      .clr_ofs = 0x64,
++      .sta_ofs = 0x68,
++};
++
++#define GATE_INFRA0(_id, _name, _parent, _shift)                  \
++      {                                                         \
++              .id = _id, .name = _name, .parent_name = _parent, \
++              .regs = &infra0_cg_regs, .shift = _shift,         \
++              .ops = &mtk_clk_gate_ops_setclr,                  \
++      }
++
++#define GATE_INFRA1(_id, _name, _parent, _shift)                  \
++      {                                                         \
++              .id = _id, .name = _name, .parent_name = _parent, \
++              .regs = &infra1_cg_regs, .shift = _shift,         \
++              .ops = &mtk_clk_gate_ops_setclr,                  \
++      }
++
++#define GATE_INFRA2(_id, _name, _parent, _shift)                  \
++      {                                                         \
++              .id = _id, .name = _name, .parent_name = _parent, \
++              .regs = &infra2_cg_regs, .shift = _shift,         \
++              .ops = &mtk_clk_gate_ops_setclr,                  \
++      }
++
++#define GATE_INFRA3(_id, _name, _parent, _shift)                  \
++      {                                                         \
++              .id = _id, .name = _name, .parent_name = _parent, \
++              .regs = &infra3_cg_regs, .shift = _shift,         \
++              .ops = &mtk_clk_gate_ops_setclr,                  \
++      }
++
++#define GATE_CRITICAL(_id, _name, _parent, _regs, _shift)                 \
++      {                                                                 \
++              .id = _id, .name = _name, .parent_name = _parent,         \
++              .regs = _regs, .shift = _shift, .flags = CLK_IS_CRITICAL, \
++              .ops = &mtk_clk_gate_ops_setclr,                          \
++      }
++
++static const struct mtk_gate infra_clks[] __initconst = {
++      /* INFRA1 */
++      GATE_INFRA1(CLK_INFRA_66M_GPT_BCK, "infra_hf_66m_gpt_bck",
++                  "sysaxi_sel", 0),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_HCK, "infra_hf_66m_pwm_hck",
++                  "sysaxi_sel", 1),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_BCK, "infra_hf_66m_pwm_bck",
++                  "infra_pwm_bck_sel", 2),
++      GATE_INFRA1(CLK_INFRA_133M_CQDMA_BCK, "infra_hf_133m_cqdma_bck",
++                  "sysaxi_sel", 12),
++      GATE_INFRA1(CLK_INFRA_66M_AUD_SLV_BCK, "infra_66m_aud_slv_bck",
++                  "sysaxi_sel", 13),
++      GATE_INFRA1(CLK_INFRA_AUD_26M, "infra_f_faud_26m",
++                  "csw_infra_f26m_sel", 14),
++      GATE_INFRA1(CLK_INFRA_AUD_L, "infra_f_faud_l", "aud_l_sel", 15),
++      GATE_INFRA1(CLK_INFRA_AUD_AUD, "infra_f_aud_aud", "a1sys_sel", 16),
++      GATE_INFRA1(CLK_INFRA_AUD_EG2, "infra_f_faud_eg2", "a_tuner_sel", 18),
++      GATE_INFRA1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m",
++                  "csw_infra_f26m_sel", 19),
++      GATE_CRITICAL(CLK_INFRA_133M_DBG_ACKM, "infra_hf_133m_dbg_ackm",
++                    "sysaxi_sel", &infra1_cg_regs, 20),
++      GATE_INFRA1(CLK_INFRA_66M_AP_DMA_BCK, "infra_66m_ap_dma_bck",
++                  "sysaxi_sel", 21),
++      GATE_INFRA1(CLK_INFRA_MSDC200_SRC, "infra_f_fmsdc200_src",
++                  "emmc_200m_sel", 28),
++      GATE_CRITICAL(CLK_INFRA_66M_SEJ_BCK, "infra_hf_66m_sej_bck",
++                    "sysaxi_sel", &infra1_cg_regs, 29),
++      GATE_CRITICAL(CLK_INFRA_PRE_CK_SEJ_F13M, "infra_pre_ck_sej_f13m",
++                  "csw_infra_f26m_sel", &infra1_cg_regs, 30),
++      GATE_CRITICAL(CLK_INFRA_66M_TRNG, "infra_hf_66m_trng", "sysaxi_sel",
++                    &infra1_cg_regs, 31),
++      /* INFRA2 */
++      GATE_INFRA2(CLK_INFRA_26M_THERM_SYSTEM, "infra_hf_26m_therm_system",
++                  "csw_infra_f26m_sel", 0),
++      GATE_INFRA2(CLK_INFRA_I2C_BCK, "infra_i2c_bck", "i2c_sel", 1),
++      GATE_INFRA2(CLK_INFRA_66M_UART0_PCK, "infra_hf_66m_uart0_pck",
++                  "sysaxi_sel", 3),
++      GATE_INFRA2(CLK_INFRA_66M_UART1_PCK, "infra_hf_66m_uart1_pck",
++                  "sysaxi_sel", 4),
++      GATE_INFRA2(CLK_INFRA_66M_UART2_PCK, "infra_hf_66m_uart2_pck",
++                  "sysaxi_sel", 5),
++      GATE_INFRA2(CLK_INFRA_52M_UART0_CK, "infra_f_52m_uart0",
++                  "infra_mux_uart0_sel", 3),
++      GATE_INFRA2(CLK_INFRA_52M_UART1_CK, "infra_f_52m_uart1",
++                  "infra_mux_uart1_sel", 4),
++      GATE_INFRA2(CLK_INFRA_52M_UART2_CK, "infra_f_52m_uart2",
++                  "infra_mux_uart2_sel", 5),
++      GATE_INFRA2(CLK_INFRA_NFI, "infra_f_fnfi", "nfi_sel", 9),
++      GATE_CRITICAL(CLK_INFRA_66M_NFI_HCK, "infra_hf_66m_nfi_hck",
++                    "sysaxi_sel", &infra2_cg_regs, 11),
++      GATE_INFRA2(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0",
++                  "infra_mux_spi0_sel", 12),
++      GATE_INFRA2(CLK_INFRA_104M_SPI1, "infra_hf_104m_spi1",
++                  "infra_mux_spi1_sel", 13),
++      GATE_INFRA2(CLK_INFRA_104M_SPI2_BCK, "infra_hf_104m_spi2_bck",
++                  "infra_mux_spi2_bck_sel", 14),
++      GATE_INFRA2(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck",
++                  "sysaxi_sel", 15),
++      GATE_INFRA2(CLK_INFRA_66M_SPI1_HCK, "infra_hf_66m_spi1_hck",
++                  "sysaxi_sel", 16),
++      GATE_INFRA2(CLK_INFRA_66M_SPI2_HCK, "infra_hf_66m_spi2_hck",
++                  "sysaxi_sel", 17),
++      GATE_INFRA2(CLK_INFRA_66M_FLASHIF_AXI, "infra_hf_66m_flashif_axi",
++                  "sysaxi_sel", 18),
++      GATE_CRITICAL(CLK_INFRA_RTC, "infra_f_frtc", "cb_rtc_32k",
++                    &infra2_cg_regs, 19),
++      GATE_INFRA2(CLK_INFRA_26M_ADC_BCK, "infra_f_26m_adc_bck",
++                  "csw_infra_f26m_sel", 20),
++      GATE_INFRA2(CLK_INFRA_RC_ADC, "infra_f_frc_adc", "infra_f_26m_adc_bck",
++                  21),
++      GATE_INFRA2(CLK_INFRA_MSDC400, "infra_f_fmsdc400", "emmc_400m_sel",
++                  22),
++      GATE_INFRA2(CLK_INFRA_MSDC2_HCK, "infra_f_fmsdc2_hck", "emmc_250m_sel",
++                  23),
++      GATE_INFRA2(CLK_INFRA_133M_MSDC_0_HCK, "infra_hf_133m_msdc_0_hck",
++                  "sysaxi_sel", 24),
++      GATE_INFRA2(CLK_INFRA_66M_MSDC_0_HCK, "infra_66m_msdc_0_hck",
++                  "sysaxi_sel", 25),
++      GATE_INFRA2(CLK_INFRA_133M_CPUM_BCK, "infra_hf_133m_cpum_bck",
++                  "sysaxi_sel", 26),
++      GATE_INFRA2(CLK_INFRA_BIST2FPC, "infra_hf_fbist2fpc", "nfi_sel", 27),
++      GATE_INFRA2(CLK_INFRA_I2C_X16W_MCK_CK_P1,
++                  "infra_hf_i2c_x16w_mck_ck_p1", "sysaxi_sel", 29),
++      GATE_INFRA2(CLK_INFRA_I2C_X16W_PCK_CK_P1,
++                  "infra_hf_i2c_x16w_pck_ck_p1", "sysaxi_sel", 31),
++      /* INFRA3 */
++      GATE_INFRA3(CLK_INFRA_133M_USB_HCK, "infra_133m_usb_hck", "sysaxi_sel",
++                  0),
++      GATE_INFRA3(CLK_INFRA_133M_USB_HCK_CK_P1, "infra_133m_usb_hck_ck_p1",
++                  "sysaxi_sel", 1),
++      GATE_INFRA3(CLK_INFRA_66M_USB_HCK, "infra_66m_usb_hck", "sysaxi_sel",
++                  2),
++      GATE_INFRA3(CLK_INFRA_66M_USB_HCK_CK_P1, "infra_66m_usb_hck_ck_p1",
++                  "sysaxi_sel", 3),
++      GATE_INFRA3(CLK_INFRA_USB_SYS_CK_P1, "infra_usb_sys_ck_p1",
++                  "usb_sys_p1_sel", 5),
++      GATE_INFRA3(CLK_INFRA_USB_CK_P1, "infra_usb_ck_p1", "cb_cksq_40m", 7),
++      GATE_CRITICAL(CLK_INFRA_USB_FRMCNT_CK_P1, "infra_usb_frmcnt_ck_p1",
++                    "cksq_40m_d2", &infra3_cg_regs, 9),
++      GATE_CRITICAL(CLK_INFRA_USB_PIPE_CK_P1, "infra_usb_pipe_ck_p1",
++                    "usb_phy_sel", &infra3_cg_regs, 11),
++      GATE_INFRA3(CLK_INFRA_USB_UTMI_CK_P1, "infra_usb_utmi_ck_p1",
++                  "clkxtal", 13),
++      GATE_INFRA3(CLK_INFRA_USB_XHCI_CK_P1, "infra_usb_xhci_ck_p1",
++                  "usb_xhci_p1_sel", 15),
++      GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P0, "infra_pcie_gfmux_tl_ck_p0",
++                  "infra_pcie_gfmux_tl_ck_o_p0_sel", 20),
++      GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P1, "infra_pcie_gfmux_tl_ck_p1",
++                  "infra_pcie_gfmux_tl_ck_o_p1_sel", 21),
++      GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P0, "infra_pcie_pipe_ck_p0", "clkxtal",
++                  24),
++      GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P1, "infra_pcie_pipe_ck_p1", "clkxtal",
++                  25),
++      GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P0, "infra_133m_pcie_ck_p0",
++                  "sysaxi_sel", 28),
++      GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P1, "infra_133m_pcie_ck_p1",
++                  "sysaxi_sel", 29),
++      /* INFRA0 */
++      GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P0,
++                  "infra_pcie_peri_ck_26m_ck_p0", "csw_infra_f26m_sel", 7),
++      GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P1,
++                  "infra_pcie_peri_ck_26m_ck_p1", "csw_infra_f26m_sel", 8),
++};
++
++static u16 infra_rst_ofs[] = {
++      MT7987_INFRA_RST0_SET_OFFSET,
++      MT7987_INFRA_RST1_SET_OFFSET,
++};
++
++static u16 infra_idx_map[] = {
++      [MT7987_INFRA_RST0_PEXTP_MAC_SWRST] = 0 * RST_NR_PER_BANK + 6,
++      [MT7987_INFRA_RST1_THERM_CTRL_SWRST] = 1 * RST_NR_PER_BANK + 9,
++};
++
++static struct mtk_clk_rst_desc infra_rst_desc = {
++      .version = MTK_RST_SET_CLR,
++      .rst_bank_ofs = infra_rst_ofs,
++      .rst_bank_nr = ARRAY_SIZE(infra_rst_ofs),
++      .rst_idx_map = infra_idx_map,
++      .rst_idx_map_nr = ARRAY_SIZE(infra_idx_map),
++};
++
++static const struct mtk_clk_desc infra_desc = {
++      .clks = infra_clks,
++      .num_clks = ARRAY_SIZE(infra_clks),
++      .mux_clks = infra_muxes,
++      .num_mux_clks = ARRAY_SIZE(infra_muxes),
++      .clk_lock = &mt7987_clk_lock,
++      .rst_desc = &infra_rst_desc,
++};
++
++static const struct of_device_id of_match_clk_mt7987_infracfg[] = {
++      { .compatible = "mediatek,mt7987-infracfg", .data = &infra_desc },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_match_clk_mt7987_infracfg);
++
++static struct platform_driver clk_mt7987_infracfg_drv = {
++      .driver = {
++              .name = "clk-mt7987-infracfg",
++              .of_match_table = of_match_clk_mt7987_infracfg,
++      },
++      .probe = mtk_clk_simple_probe,
++      .remove_new = mtk_clk_simple_remove,
++};
++module_platform_driver(clk_mt7987_infracfg_drv);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7987-mcusys.c
+@@ -0,0 +1,47 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2024 MediaTek Inc.
++ * Author: Lu Tang <Lu.Tang@mediatek.com>
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include "clk-mtk.h"
++#include "clk-gate.h"
++#include "clk-mux.h"
++#include <dt-bindings/clock/mediatek,mt7987-clk.h>
++
++static DEFINE_SPINLOCK(mt7987_clk_lock);
++static const char *const mcu_bus_div_parents[] = { "cb_cksq_40m", "arm_ll" };
++
++static struct mtk_composite mcu_muxes[] = {
++      MUX_GATE_FLAGS(CLK_MCU_BUS_DIV_SEL, "mcu_bus_div_sel",
++                     mcu_bus_div_parents, 0x7C0, 9, 1, -1, CLK_IS_CRITICAL),
++};
++
++static const struct mtk_clk_desc mcusys_desc = {
++      .composite_clks = mcu_muxes,
++      .num_composite_clks = ARRAY_SIZE(mcu_muxes),
++      .clk_lock = &mt7987_clk_lock,
++};
++
++static const struct of_device_id of_match_clk_mt7987_mcusys[] = {
++      { .compatible = "mediatek,mt7987-mcusys", .data = &mcusys_desc },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_match_clk_mt7987_mcusys);
++
++static struct platform_driver clk_mt7987_mcusys_drv = {
++      .driver = {
++              .name = "clk-mt7987-mcusys",
++              .of_match_table = of_match_clk_mt7987_mcusys,
++      },
++      .probe = mtk_clk_simple_probe,
++      .remove_new = mtk_clk_simple_remove,
++};
++module_platform_driver(clk_mt7987_mcusys_drv);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7987-topckgen.c
+@@ -0,0 +1,311 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2024 MediaTek Inc.
++ * Author: Lu Tang <Lu.Tang@mediatek.com>
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ */
++
++#include <linux/clk-provider.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include "clk-mtk.h"
++#include "clk-gate.h"
++#include "clk-mux.h"
++#include <dt-bindings/clock/mediatek,mt7987-clk.h>
++
++static DEFINE_SPINLOCK(mt7987_clk_lock);
++
++static const struct mtk_fixed_factor top_divs[] __initconst = {
++      FACTOR(CLK_TOP_CB_M_D2, "cb_m_d2", "mpll", 1, 2),
++      FACTOR(CLK_TOP_CB_M_D3, "cb_m_d3", "mpll", 1, 3),
++      FACTOR(CLK_TOP_M_D3_D2, "m_d3_d2", "mpll", 1, 6),
++      FACTOR(CLK_TOP_CB_M_D4, "cb_m_d4", "mpll", 1, 4),
++      FACTOR(CLK_TOP_CB_M_D8, "cb_m_d8", "mpll", 1, 8),
++      FACTOR(CLK_TOP_M_D8_D2, "m_d8_d2", "mpll", 1, 16),
++      FACTOR(CLK_TOP_CB_APLL2_D4, "cb_apll2_d4", "apll2", 1, 4),
++      FACTOR(CLK_TOP_CB_NET1_D3, "cb_net1_d3", "net1pll", 1, 3),
++      FACTOR(CLK_TOP_CB_NET1_D4, "cb_net1_d4", "net1pll", 1, 4),
++      FACTOR(CLK_TOP_CB_NET1_D5, "cb_net1_d5", "net1pll", 1, 5),
++      FACTOR(CLK_TOP_NET1_D5_D2, "net1_d5_d2", "net1pll", 1, 10),
++      FACTOR(CLK_TOP_NET1_D5_D4, "net1_d5_d4", "net1pll", 1, 20),
++      FACTOR(CLK_TOP_CB_NET1_D7, "cb_net1_d7", "net1pll", 1, 7),
++      FACTOR(CLK_TOP_NET1_D7_D2, "net1_d7_d2", "net1pll", 1, 14),
++      FACTOR(CLK_TOP_NET1_D7_D4, "net1_d7_d4", "net1pll", 1, 28),
++      FACTOR(CLK_TOP_NET1_D8_D2, "net1_d8_d2", "net1pll", 1, 16),
++      FACTOR(CLK_TOP_NET1_D8_D4, "net1_d8_d4", "net1pll", 1, 32),
++      FACTOR(CLK_TOP_NET1_D8_D8, "net1_d8_d8", "net1pll", 1, 64),
++      FACTOR(CLK_TOP_NET1_D8_D16, "net1_d8_d16", "net1pll", 1, 128),
++      FACTOR(CLK_TOP_CB_NET2_D2, "cb_net2_d2", "net2pll", 1, 2),
++      FACTOR(CLK_TOP_CB_NET2_D4, "cb_net2_d4", "net2pll", 1, 4),
++      FACTOR(CLK_TOP_NET2_D4_D4, "net2_d4_d4", "net2pll", 1, 16),
++      FACTOR(CLK_TOP_NET2_D4_D8, "net2_d4_d8", "net2pll", 1, 32),
++      FACTOR(CLK_TOP_CB_NET2_D6, "cb_net2_d6", "net2pll", 1, 6),
++      FACTOR(CLK_TOP_NET2_D7_D2, "net2_d7_d2", "net2pll", 1, 14),
++      FACTOR(CLK_TOP_CB_NET2_D8, "cb_net2_d8", "net2pll", 1, 8),
++      FACTOR(CLK_TOP_MSDC_D2, "msdc_d2", "msdcpll", 1, 2),
++      FACTOR(CLK_TOP_CB_CKSQ_40M, "cb_cksq_40m", "clkxtal", 1, 1),
++      FACTOR(CLK_TOP_CKSQ_40M_D2, "cksq_40m_d2", "cb_cksq_40m", 1, 2),
++      FACTOR(CLK_TOP_CB_RTC_32K, "cb_rtc_32k", "cb_cksq_40m", 1, 1250),
++      FACTOR(CLK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", "cb_cksq_40m", 1, 1221),
++};
++
++static const char *const netsys_parents[] = { "cb_cksq_40m", "cb_net2_d2" };
++
++static const char *const netsys_500m_parents[] = { "cb_cksq_40m", "cb_net1_d5",
++                                                 "net1_d5_d2" };
++
++static const char *const netsys_2x_parents[] = { "cb_cksq_40m", "net2pll" };
++
++static const char *const eth_gmii_parents[] = { "cb_cksq_40m", "net1_d5_d4" };
++
++static const char *const eip_parents[] = { "cb_cksq_40m", "cb_net1_d3",
++                                         "net2pll", "cb_net1_d4",
++                                         "cb_net1_d5" };
++
++static const char *const axi_infra_parents[] = { "cb_cksq_40m", "net1_d8_d2" };
++
++static const char *const uart_parents[] = { "cb_cksq_40m", "cb_m_d8",
++                                          "m_d8_d2" };
++
++static const char *const emmc_250m_parents[] = { "cb_cksq_40m", "net1_d5_d2",
++                                               "net1_d7_d2" };
++
++static const char *const emmc_400m_parents[] = { "cb_cksq_40m", "msdcpll",
++                                               "cb_net1_d7",  "cb_m_d2",
++                                               "net1_d7_d2",  "cb_net2_d6" };
++
++static const char *const spi_parents[] = { "cb_cksq_40m", "cb_m_d2",
++                                         "net1_d7_d2",  "net1_d8_d2",
++                                         "cb_net2_d6",  "net1_d5_d4",
++                                         "cb_m_d4",     "net1_d8_d4" };
++
++static const char *const nfi_parents[] = {
++      "cksq_40m_d2", "net1_d8_d2", "cb_m_d3", "net1_d5_d4", "cb_m_d4",
++      "net1_d7_d4",  "net1_d8_d4", "m_d3_d2", "net2_d7_d2", "cb_m_d8"
++};
++
++static const char *const pwm_parents[] = { "cb_cksq_40m", "net1_d8_d2",
++                                         "net1_d5_d4",  "cb_m_d4",
++                                         "m_d8_d2",     "cb_rtc_32k" };
++
++static const char *const i2c_parents[] = { "cb_cksq_40m", "net1_d5_d4",
++                                         "cb_m_d4", "net1_d8_d4" };
++
++static const char *const pcie_mbist_250m_parents[] = { "cb_cksq_40m",
++                                                     "net1_d5_d2" };
++
++static const char *const pextp_tl_ck_parents[] = { "cb_cksq_40m", "cb_net2_d6",
++                                                 "net1_d7_d4", "m_d8_d2",
++                                                 "cb_rtc_32k" };
++
++static const char *const aud_parents[] = { "cb_cksq_40m", "apll2" };
++
++static const char *const a1sys_parents[] = { "cb_cksq_40m", "cb_apll2_d4" };
++
++static const char *const aud_l_parents[] = { "cb_cksq_40m", "apll2",
++                                           "m_d8_d2" };
++
++static const char *const usb_phy_parents[] = { "cksq_40m_d2", "m_d8_d2" };
++
++static const char *const sgm_0_parents[] = { "cb_cksq_40m", "sgmpll" };
++
++static const char *const sgm_sbus_0_parents[] = { "cb_cksq_40m",
++                                                "net1_d8_d4" };
++
++static const char *const sysapb_parents[] = { "cb_cksq_40m", "m_d3_d2" };
++
++static const char *const eth_refck_50m_parents[] = { "cb_cksq_40m",
++                                                   "net2_d4_d4" };
++
++static const char *const eth_sys_200m_parents[] = { "cb_cksq_40m",
++                                                  "cb_net2_d4" };
++
++static const char *const eth_xgmii_parents[] = { "cksq_40m_d2", "net1_d8_d8",
++                                               "net1_d8_d16" };
++
++static const char *const dramc_md32_parents[] = { "cb_cksq_40m", "cb_m_d2",
++                                                "wedmcupll" };
++
++static const char *const da_xtp_glb_p0_parents[] = { "cb_cksq_40m",
++                                                   "cb_net2_d8" };
++
++static const char *const da_ckm_xtal_parents[] = { "cb_cksq_40m", "m_d8_d2" };
++
++static const char *const eth_mii_parents[] = { "cksq_40m_d2", "net2_d4_d8" };
++
++static const char *const emmc_200m_parents[] = { "cb_cksq_40m", "msdc_d2",
++                                               "net1_d7_d2", "cb_net2_d6",
++                                               "net1_d7_d4" };
++
++static struct mtk_mux top_muxes[] = {
++      /* CLK_CFG_0 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
++                           0x000, 0x004, 0x008, 0, 1, 7, 0x1C0, 0),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
++                           netsys_500m_parents, 0x000, 0x004, 0x008, 8, 2,
++                           15, 0x1C0, 1),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
++                           netsys_2x_parents, 0x000, 0x004, 0x008, 16, 1, 23,
++                           0x1C0, 2),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_GMII_SEL, "eth_gmii_sel",
++                           eth_gmii_parents, 0x000, 0x004, 0x008, 24, 1, 31,
++                           0x1C0, 3),
++      /* CLK_CFG_1 */
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_EIP_SEL, "eip_sel", eip_parents,
++                                 0x010, 0x014, 0x018, 0, 3, 7, 0x1C0, 4,
++                                 CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_INFRA_SEL, "axi_infra_sel",
++                                 axi_infra_parents, 0x010, 0x014, 0x018, 8,
++                                 1, 15, 0x1C0, 5, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010,
++                           0x014, 0x018, 16, 2, 23, 0x1C0, 6),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel",
++                           emmc_250m_parents, 0x010, 0x014, 0x018, 24, 2, 31,
++                           0x1C0, 7),
++      /* CLK_CFG_2 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_400M_SEL, "emmc_400m_sel",
++                           emmc_400m_parents, 0x020, 0x024, 0x028, 0, 3, 7,
++                           0x1C0, 8),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x020,
++                           0x024, 0x028, 8, 3, 15, 0x1C0, 9),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
++                           0x020, 0x024, 0x028, 16, 3, 23, 0x1C0, 10),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI_SEL, "nfi_sel", nfi_parents, 0x020,
++                           0x024, 0x028, 24, 4, 31, 0x1C0, 11),
++      /* CLK_CFG_3 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x030,
++                           0x034, 0x038, 0, 3, 7, 0x1C0, 12),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x030,
++                           0x034, 0x038, 8, 2, 15, 0x1C0, 13),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PCIE_MBIST_250M_SEL,
++                           "pcie_mbist_250m_sel", pcie_mbist_250m_parents,
++                           0x030, 0x034, 0x038, 16, 1, 23, 0x1C0, 14),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
++                           pextp_tl_ck_parents, 0x030, 0x034, 0x038, 24, 3,
++                           31, 0x1C0, 15),
++      /* CLK_CFG_4 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P1_SEL, "pextp_tl_ck_p1_sel",
++                           pextp_tl_ck_parents, 0x040, 0x044, 0x048, 0, 3, 7,
++                           0x1C0, 16),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_SYS_P1_SEL, "usb_sys_p1_sel",
++                           eth_gmii_parents, 0x040, 0x044, 0x048, 8, 1, 15,
++                           0x1C0, 17),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_XHCI_P1_SEL, "usb_xhci_p1_sel",
++                           eth_gmii_parents, 0x040, 0x044, 0x048, 16, 1, 23,
++                           0x1C0, 18),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x040,
++                           0x044, 0x048, 24, 1, 31, 0x1C0, 19),
++      /* CLK_CFG_5 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
++                           0x050, 0x054, 0x058, 0, 1, 7, 0x1C0, 20),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
++                           0x050, 0x054, 0x058, 8, 2, 15, 0x1C0, 21),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel", a1sys_parents,
++                           0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_PHY_SEL, "usb_phy_sel",
++                           usb_phy_parents, 0x050, 0x054, 0x058, 24, 1, 31,
++                           0x1C0, 23),
++      /* CLK_CFG_6 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_0_SEL, "sgm_0_sel", sgm_0_parents,
++                           0x060, 0x064, 0x068, 0, 1, 7, 0x1C0, 24),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_SBUS_0_SEL, "sgm_sbus_0_sel",
++                                 sgm_sbus_0_parents, 0x060, 0x064, 0x068, 8,
++                                 1, 15, 0x1C0, 25, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_1_SEL, "sgm_1_sel", sgm_0_parents,
++                           0x060, 0x064, 0x068, 16, 1, 23, 0x1C0, 26),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_SBUS_1_SEL, "sgm_sbus_1_sel",
++                                 sgm_sbus_0_parents, 0x060, 0x064, 0x068, 24,
++                                 1, 31, 0x1C0, 27, CLK_IS_CRITICAL),
++      /* CLK_CFG_7 */
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel",
++                                 axi_infra_parents, 0x070, 0x074, 0x078, 0,
++                                 1, 7, 0x1C0, 28, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel",
++                                 sysapb_parents, 0x070, 0x074, 0x078, 8, 1,
++                                 15, 0x1C0, 29, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_REFCK_50M_SEL, "eth_refck_50m_sel",
++                           eth_refck_50m_parents, 0x070, 0x074, 0x078, 16, 1,
++                           23, 0x1C0, 30),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SYS_200M_SEL, "eth_sys_200m_sel",
++                           eth_sys_200m_parents, 0x070, 0x074, 0x078, 24, 1,
++                           31, 0x1C4, 0),
++      /* CLK_CFG_8 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SYS_SEL, "eth_sys_sel",
++                           pcie_mbist_250m_parents, 0x080, 0x084, 0x088, 0,
++                           1, 7, 0x1C4, 1),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_XGMII_SEL, "eth_xgmii_sel",
++                           eth_xgmii_parents, 0x080, 0x084, 0x088, 8, 2, 15,
++                           0x1C4, 2),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel",
++                                 usb_phy_parents, 0x080, 0x084, 0x088, 16, 1,
++                                 23, 0x1C4, 3, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
++                                 dramc_md32_parents, 0x080, 0x084, 0x088, 24,
++                                 2, 31, 0x1C4, 4, CLK_IS_CRITICAL),
++      /* CLK_CFG_9 */
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_INFRA_F26M_SEL,
++                                 "csw_infra_f26m_sel", usb_phy_parents,
++                                 0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5,
++                                 CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_PEXTP_P0_SEL, "pextp_p0_sel",
++                                 usb_phy_parents, 0x090, 0x094, 0x098, 8, 1,
++                                 15, 0x1C4, 6, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_PEXTP_P1_SEL, "pextp_p1_sel",
++                                 usb_phy_parents, 0x090, 0x094, 0x098, 16, 1,
++                                 23, 0x1C4, 7, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P0_SEL, "da_xtp_glb_p0_sel",
++                           da_xtp_glb_p0_parents, 0x090, 0x094, 0x098, 24, 1,
++                           31, 0x1C4, 8),
++      /* CLK_CFG_10 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P1_SEL, "da_xtp_glb_p1_sel",
++                           da_xtp_glb_p0_parents, 0x0A0, 0x0A4, 0x0A8, 0, 1,
++                           7, 0x1C4, 9),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_CKM_SEL, "ckm_sel", usb_phy_parents,
++                           0x0A0, 0x0A4, 0x0A8, 8, 1, 15, 0x1C4, 10),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_CKM_XTAL_SEL, "da_ckm_xtal_sel",
++                           da_ckm_xtal_parents, 0x0A0, 0x0A4, 0x0A8, 16, 1,
++                           23, 0x1C4, 11),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_SEL, "pextp_sel", usb_phy_parents,
++                           0x0A0, 0x0A4, 0x0A8, 24, 1, 31, 0x1C4, 12),
++      /* CLK_CFG_11 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_MII_SEL, "eth_mii_sel",
++                           eth_mii_parents, 0x0B0, 0x0B4, 0x0B8, 0, 1, 7,
++                           0x1C4, 13),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_200M_SEL, "emmc_200m_sel",
++                           emmc_200m_parents, 0x0B0, 0x0B4, 0x0B8, 8, 3, 15,
++                           0x1C4, 14),
++};
++
++static const struct mtk_composite top_adj_divs[] = {
++      DIV_GATE(CLK_TOP_AUD_I2S_M, "aud_i2s_m", "aud_sel", 0x0420, 0, 0x0420,
++               8, 8),
++};
++
++static const struct mtk_clk_desc topck_desc = {
++      .factor_clks = top_divs,
++      .num_factor_clks = ARRAY_SIZE(top_divs),
++      .mux_clks = top_muxes,
++      .num_mux_clks = ARRAY_SIZE(top_muxes),
++      .composite_clks = top_adj_divs,
++      .num_composite_clks = ARRAY_SIZE(top_adj_divs),
++      .clk_lock = &mt7987_clk_lock,
++};
++
++static const struct of_device_id of_match_clk_mt7987_topckgen[] = {
++      { .compatible = "mediatek,mt7987-topckgen", .data = &topck_desc },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_match_clk_mt7987_topckgen);
++
++static struct platform_driver clk_mt7987_topckgen_drv = {
++      .probe = mtk_clk_simple_probe,
++      .remove_new = mtk_clk_simple_remove,
++      .driver = {
++              .name = "clk-mt7987-topckgen",
++              .of_match_table = of_match_clk_mt7987_topckgen,
++      },
++};
++module_platform_driver(clk_mt7987_topckgen_drv);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/include/dt-bindings/clock/mediatek,mt7987-clk.h
+@@ -0,0 +1,206 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++/*
++ * Copyright (c) 2024 MediaTek Inc.
++ * Author: Lu Tang <Lu.Tang@mediatek.com>
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ */
++
++#ifndef _DT_BINDINGS_CLK_MT7987_H
++#define _DT_BINDINGS_CLK_MT7987_H
++
++/* INFRACFG */
++
++#define CLK_INFRA_MUX_UART0_SEL                       0
++#define CLK_INFRA_MUX_UART1_SEL                       1
++#define CLK_INFRA_MUX_UART2_SEL                       2
++#define CLK_INFRA_MUX_SPI0_SEL                        3
++#define CLK_INFRA_MUX_SPI1_SEL                        4
++#define CLK_INFRA_MUX_SPI2_BCK_SEL            5
++#define CLK_INFRA_PWM_BCK_SEL                 6
++#define CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL      7
++#define CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL      8
++#define CLK_INFRA_66M_GPT_BCK                 9
++#define CLK_INFRA_66M_PWM_HCK                 10
++#define CLK_INFRA_66M_PWM_BCK                 11
++#define CLK_INFRA_133M_CQDMA_BCK              12
++#define CLK_INFRA_66M_AUD_SLV_BCK             13
++#define CLK_INFRA_AUD_26M                     14
++#define CLK_INFRA_AUD_L                               15
++#define CLK_INFRA_AUD_AUD                     16
++#define CLK_INFRA_AUD_EG2                     17
++#define CLK_INFRA_DRAMC_F26M                  18
++#define CLK_INFRA_133M_DBG_ACKM                       19
++#define CLK_INFRA_66M_AP_DMA_BCK              20
++#define CLK_INFRA_MSDC200_SRC                 21
++#define CLK_INFRA_66M_SEJ_BCK                 22
++#define CLK_INFRA_PRE_CK_SEJ_F13M             23
++#define CLK_INFRA_66M_TRNG                    24
++#define CLK_INFRA_26M_THERM_SYSTEM            25
++#define CLK_INFRA_I2C_BCK                     26
++#define CLK_INFRA_66M_UART0_PCK                       27
++#define CLK_INFRA_66M_UART1_PCK                       28
++#define CLK_INFRA_66M_UART2_PCK                       29
++#define CLK_INFRA_52M_UART0_CK                        30
++#define CLK_INFRA_52M_UART1_CK                        31
++#define CLK_INFRA_52M_UART2_CK                        32
++#define CLK_INFRA_NFI                         33
++#define CLK_INFRA_66M_NFI_HCK                 34
++#define CLK_INFRA_104M_SPI0                   35
++#define CLK_INFRA_104M_SPI1                   36
++#define CLK_INFRA_104M_SPI2_BCK                       37
++#define CLK_INFRA_66M_SPI0_HCK                        38
++#define CLK_INFRA_66M_SPI1_HCK                        39
++#define CLK_INFRA_66M_SPI2_HCK                        40
++#define CLK_INFRA_66M_FLASHIF_AXI             41
++#define CLK_INFRA_RTC                         42
++#define CLK_INFRA_26M_ADC_BCK                 43
++#define CLK_INFRA_RC_ADC                      44
++#define CLK_INFRA_MSDC400                     45
++#define CLK_INFRA_MSDC2_HCK                   46
++#define CLK_INFRA_133M_MSDC_0_HCK             47
++#define CLK_INFRA_66M_MSDC_0_HCK              48
++#define CLK_INFRA_133M_CPUM_BCK                       49
++#define CLK_INFRA_BIST2FPC                    50
++#define CLK_INFRA_I2C_X16W_MCK_CK_P1          51
++#define CLK_INFRA_I2C_X16W_PCK_CK_P1          52
++#define CLK_INFRA_133M_USB_HCK                        53
++#define CLK_INFRA_133M_USB_HCK_CK_P1          54
++#define CLK_INFRA_66M_USB_HCK                 55
++#define CLK_INFRA_66M_USB_HCK_CK_P1           56
++#define CLK_INFRA_USB_SYS_CK_P1                       57
++#define CLK_INFRA_USB_CK_P1                   58
++#define CLK_INFRA_USB_FRMCNT_CK_P1            59
++#define CLK_INFRA_USB_PIPE_CK_P1              60
++#define CLK_INFRA_USB_UTMI_CK_P1              61
++#define CLK_INFRA_USB_XHCI_CK_P1              62
++#define CLK_INFRA_PCIE_GFMUX_TL_P0            63
++#define CLK_INFRA_PCIE_GFMUX_TL_P1            64
++#define CLK_INFRA_PCIE_PIPE_P0                        65
++#define CLK_INFRA_PCIE_PIPE_P1                        66
++#define CLK_INFRA_133M_PCIE_CK_P0             67
++#define CLK_INFRA_133M_PCIE_CK_P1             68
++#define CLK_INFRA_PCIE_PERI_26M_CK_P0         69
++#define CLK_INFRA_PCIE_PERI_26M_CK_P1         70
++#define CLK_INFRA_NR_CLK                      71
++
++/* TOPCKGEN */
++
++#define CLK_TOP_CB_M_D2                               0
++#define CLK_TOP_CB_M_D3                               1
++#define CLK_TOP_M_D3_D2                               2
++#define CLK_TOP_CB_M_D4                               3
++#define CLK_TOP_CB_M_D8                               4
++#define CLK_TOP_M_D8_D2                               5
++#define CLK_TOP_CB_APLL2_D4                   6
++#define CLK_TOP_CB_NET1_D3                    7
++#define CLK_TOP_CB_NET1_D4                    8
++#define CLK_TOP_CB_NET1_D5                    9
++#define CLK_TOP_NET1_D5_D2                    10
++#define CLK_TOP_NET1_D5_D4                    11
++#define CLK_TOP_CB_NET1_D7                    12
++#define CLK_TOP_NET1_D7_D2                    13
++#define CLK_TOP_NET1_D7_D4                    14
++#define CLK_TOP_NET1_D8_D2                    15
++#define CLK_TOP_NET1_D8_D4                    16
++#define CLK_TOP_NET1_D8_D8                    17
++#define CLK_TOP_NET1_D8_D16                   18
++#define CLK_TOP_CB_NET2_D2                    19
++#define CLK_TOP_CB_NET2_D4                    20
++#define CLK_TOP_NET2_D4_D4                    21
++#define CLK_TOP_NET2_D4_D8                    22
++#define CLK_TOP_CB_NET2_D6                    23
++#define CLK_TOP_NET2_D7_D2                    24
++#define CLK_TOP_CB_NET2_D8                    25
++#define CLK_TOP_MSDC_D2                               26
++#define CLK_TOP_CB_CKSQ_40M                   27
++#define CLK_TOP_CKSQ_40M_D2                   28
++#define CLK_TOP_CB_RTC_32K                    29
++#define CLK_TOP_CB_RTC_32P7K                  30
++#define CLK_TOP_NETSYS_SEL                    31
++#define CLK_TOP_NETSYS_500M_SEL                       32
++#define CLK_TOP_NETSYS_2X_SEL                 33
++#define CLK_TOP_ETH_GMII_SEL                  34
++#define CLK_TOP_EIP_SEL                               35
++#define CLK_TOP_AXI_INFRA_SEL                 36
++#define CLK_TOP_UART_SEL                      37
++#define CLK_TOP_EMMC_250M_SEL                 38
++#define CLK_TOP_EMMC_400M_SEL                 39
++#define CLK_TOP_SPI_SEL                               40
++#define CLK_TOP_SPIM_MST_SEL                  41
++#define CLK_TOP_NFI_SEL                               42
++#define CLK_TOP_PWM_SEL                               43
++#define CLK_TOP_I2C_SEL                               44
++#define CLK_TOP_PCIE_MBIST_250M_SEL           45
++#define CLK_TOP_PEXTP_TL_SEL                  46
++#define CLK_TOP_PEXTP_TL_P1_SEL                       47
++#define CLK_TOP_USB_SYS_P1_SEL                        48
++#define CLK_TOP_USB_XHCI_P1_SEL                       49
++#define CLK_TOP_AUD_SEL                               50
++#define CLK_TOP_A1SYS_SEL                     51
++#define CLK_TOP_AUD_L_SEL                     52
++#define CLK_TOP_A_TUNER_SEL                   53
++#define CLK_TOP_USB_PHY_SEL                   54
++#define CLK_TOP_SGM_0_SEL                     55
++#define CLK_TOP_SGM_SBUS_0_SEL                        56
++#define CLK_TOP_SGM_1_SEL                     57
++#define CLK_TOP_SGM_SBUS_1_SEL                        58
++#define CLK_TOP_SYSAXI_SEL                    59
++#define CLK_TOP_SYSAPB_SEL                    60
++#define CLK_TOP_ETH_REFCK_50M_SEL             61
++#define CLK_TOP_ETH_SYS_200M_SEL              62
++#define CLK_TOP_ETH_SYS_SEL                   63
++#define CLK_TOP_ETH_XGMII_SEL                 64
++#define CLK_TOP_DRAMC_SEL                     65
++#define CLK_TOP_DRAMC_MD32_SEL                        66
++#define CLK_TOP_INFRA_F26M_SEL                        67
++#define CLK_TOP_PEXTP_P0_SEL                  68
++#define CLK_TOP_PEXTP_P1_SEL                  69
++#define CLK_TOP_DA_XTP_GLB_P0_SEL             70
++#define CLK_TOP_DA_XTP_GLB_P1_SEL             71
++#define CLK_TOP_CKM_SEL                               72
++#define CLK_TOP_DA_CKM_XTAL_SEL                       73
++#define CLK_TOP_PEXTP_SEL                     74
++#define CLK_TOP_ETH_MII_SEL                   75
++#define CLK_TOP_EMMC_200M_SEL                 76
++#define CLK_TOP_AUD_I2S_M                     77
++#define CLK_TOP_NR_CLK                                78
++
++/* APMIXEDSYS */
++
++#define CLK_APMIXED_MPLL                      0
++#define CLK_APMIXED_APLL2                     1
++#define CLK_APMIXED_NET1PLL                   2
++#define CLK_APMIXED_NET2PLL                   3
++#define CLK_APMIXED_WEDMCUPLL                 4
++#define CLK_APMIXED_SGMPLL                    5
++#define CLK_APMIXED_ARM_LL                    6
++#define CLK_APMIXED_MSDCPLL                   7
++#define CLK_APMIXED_NR_CLK                    8
++
++/* MCUSYS */
++
++#define CLK_MCU_BUS_DIV_SEL                   0
++#define CLK_MCU_NR_CLK                                1
++
++/* SGMIISYS_0 */
++
++#define CLK_SGM0_TX_EN                                0
++#define CLK_SGM0_RX_EN                                1
++#define CLK_SGMII0_NR_CLK                     2
++
++/* SGMIISYS_1 */
++
++#define CLK_SGM1_TX_EN                                0
++#define CLK_SGM1_RX_EN                                1
++#define CLK_SGMII1_NR_CLK                     2
++
++/* ETHDMA */
++
++#define CLK_ETHDMA_FE_EN                      0
++#define CLK_ETHDMA_GP2_EN                     1
++#define CLK_ETHDMA_GP1_EN                     2
++#define CLK_ETHDMA_GP3_EN                     3
++#define CLK_ETHDMA_NR_CLK                     4
++
++#endif /* _DT_BINDINGS_CLK_MT7987_H */
++
+--- /dev/null
++++ b/include/dt-bindings/reset/mediatek,mt7987-resets.h
+@@ -0,0 +1,10 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++
++#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7987
++#define _DT_BINDINGS_RESET_CONTROLLER_MT7987
++
++/* INFRA resets */
++#define MT7987_INFRA_RST0_PEXTP_MAC_SWRST     0
++#define MT7987_INFRA_RST1_THERM_CTRL_SWRST    1
++
++#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7987 */
diff --git a/target/linux/mediatek/patches-6.12/400-crypto-add-eip97-inside-secure-support.patch b/target/linux/mediatek/patches-6.12/400-crypto-add-eip97-inside-secure-support.patch
new file mode 100644 (file)
index 0000000..5727f5e
--- /dev/null
@@ -0,0 +1,39 @@
+From 127ad76311079a842578e788a8af364f3910c676 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Thu, 4 Jun 2020 14:20:34 +0200
+Subject: [PATCH] crypto: inside-secure: set TX max commands for EIP97 HW2.1/2.3
+
+EIP97 HW2.1 and HW2.3 use a different register field for the maximum
+number of TX commands than EIP197. Add an else branch to set
+EIP97_MST_CTRL_TX_MAX_CMD(4) (16 commands) for the EIP97 hardware
+variant, and add the corresponding EIP97_MST_CTRL_TX_MAX_CMD() macro.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -608,6 +608,14 @@ static int safexcel_hw_init(struct safex
+               val |= EIP197_MST_CTRL_TX_MAX_CMD(5);
+               writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
+       }
++      /*
++       * Set maximum number of TX commands to 2^4 = 16 for EIP97 HW2.1/HW2.3
++       */
++      else {
++              val = 0;
++              val |= EIP97_MST_CTRL_TX_MAX_CMD(4);
++              writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
++      }
+       /* Configure wr/rd cache values */
+       writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) |
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -315,6 +315,7 @@
+ #define EIP197_MST_CTRL_RD_CACHE(n)           (((n) & 0xf) << 0)
+ #define EIP197_MST_CTRL_WD_CACHE(n)           (((n) & 0xf) << 4)
+ #define EIP197_MST_CTRL_TX_MAX_CMD(n)         (((n) & 0xf) << 20)
++#define EIP97_MST_CTRL_TX_MAX_CMD(n)          (((n) & 0xf) << 4)
+ #define EIP197_MST_CTRL_BYTE_SWAP             BIT(24)
+ #define EIP197_MST_CTRL_NO_BYTE_SWAP          BIT(25)
+ #define EIP197_MST_CTRL_BYTE_SWAP_BITS          GENMASK(25, 24)
diff --git a/target/linux/mediatek/patches-6.12/401-crypto-fix-eip97-cache-incoherent.patch b/target/linux/mediatek/patches-6.12/401-crypto-fix-eip97-cache-incoherent.patch
new file mode 100644 (file)
index 0000000..eb15990
--- /dev/null
@@ -0,0 +1,38 @@
+From 4841ac042e00df7e29d305eb92f68994ebc739fd Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Tue, 1 Sep 2020 09:09:13 +0200
+Subject: [PATCH] crypto: inside-secure: align ahash state and len to cache line size
+
+On non-coherent DMA systems the ahash request state[] array and the len
+field must each be aligned to the system cache line size (64 bytes) to
+prevent DMA coherency issues. Add SYSTEM_CACHELINE_SIZE (64) and use it
+as the alignment for both fields.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -743,6 +743,9 @@ struct safexcel_priv_data {
+ /* Priority we use for advertising our algorithms */
+ #define SAFEXCEL_CRA_PRIORITY         300
++/* System cache line size */
++#define SYSTEM_CACHELINE_SIZE         64
++
+ /* SM3 digest result for zero length message */
+ #define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \
+                               "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -55,9 +55,9 @@ struct safexcel_ahash_req {
+       u8 block_sz;    /* block size, only set once */
+       u8 digest_sz;   /* output digest size, only set once */
+       __le32 state[SHA3_512_BLOCK_SIZE /
+-                   sizeof(__le32)] __aligned(sizeof(__le32));
++                   sizeof(__le32)] __aligned(SYSTEM_CACHELINE_SIZE);
+-      u64 len;
++      u64 len __aligned(SYSTEM_CACHELINE_SIZE);
+       u64 processed;
+       u8 cache[HASH_CACHE_SIZE] __aligned(sizeof(u32));
diff --git a/target/linux/mediatek/patches-6.12/410-bt-mtk-serial-fix.patch b/target/linux/mediatek/patches-6.12/410-bt-mtk-serial-fix.patch
new file mode 100644 (file)
index 0000000..cce3dca
--- /dev/null
@@ -0,0 +1,45 @@
+From 66458c49aa14ebc9ba2e4f9b6a323b8ff122807b Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Fri, 2 Aug 2019 10:33:28 +0200
+Subject: [PATCH] serial: 8250: add UART_CAP_NMOD flag to skip set_termios for MT Bluetooth UART
+
+The Bluetooth UART on MediaTek SoCs does not support termios
+configuration. Add a new UART_CAP_NMOD capability flag and set it on
+PORT_NPCM so that serial8250_do_set_termios() returns immediately
+without touching the hardware when this flag is present.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -86,6 +86,7 @@ struct serial8250_config {
+                                        * STOP PARITY EPAR SPAR WLEN5 WLEN6
+                                        */
+ #define UART_CAP_NOTEMT       BIT(18) /* UART without interrupt on TEMT available */
++#define UART_CAP_NMOD BIT(19) /* UART doesn't do termios */
+ #define UART_BUG_QUOT BIT(0)  /* UART has buggy quot LSB */
+ #define UART_BUG_TXEN BIT(1)  /* UART has buggy TX IIR status */
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -276,7 +276,7 @@ static const struct serial8250_config ua
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO |
+                                 UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
+-              .flags          = UART_CAP_FIFO,
++              .flags          = UART_CAP_FIFO | UART_CAP_NMOD,
+       },
+       [PORT_NPCM] = {
+               .name           = "Nuvoton 16550",
+@@ -2735,6 +2735,11 @@ serial8250_do_set_termios(struct uart_po
+       unsigned long flags;
+       unsigned int baud, quot, frac = 0;
++      if (up->capabilities & UART_CAP_NMOD) {
++              termios->c_cflag = 0;
++              return;
++      }
++
+       if (up->capabilities & UART_CAP_MINI) {
+               termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR);
+               if ((termios->c_cflag & CSIZE) == CS5 ||
diff --git a/target/linux/mediatek/patches-6.12/411-mtd-spinand-fix-support-for-FORESEE.patch b/target/linux/mediatek/patches-6.12/411-mtd-spinand-fix-support-for-FORESEE.patch
new file mode 100644 (file)
index 0000000..b88c138
--- /dev/null
@@ -0,0 +1,32 @@
+From edc7cb910433e05eac61b13d94163f1e07fa6af4 Mon Sep 17 00:00:00 2001
+From: Dim Fish <dimfish@gmail.com>
+Date: Thu, 3 Jul 2025 18:06:18 +0300
+Subject: [PATCH] mediatek: spinand: force update_cache_variants to use reset for Foresee NAND
+
+Force update_cache_variantsvariants to use reset for Foresee NAND with bad blocks.
+
+Tested on Xiaomi AX3000T + F35SQA001G with bad blocks and without bad blocks
+
+Signed-off-by: Dim Fish <dimfish@gmail.com>
+Link: https://github.com/openwrt/openwrt/pull/17963
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+Force update_cache_variants to use reset for Foresee NAND with bad blocks
+
+Tested on Xiaomi AX3000T + F35SQA001G with bad blocks and without bad blocks
+
+Signed-off-by: Dim Fish <dimfish@gmail.com>
+
+--- a/drivers/mtd/nand/spi/foresee.c
++++ b/drivers/mtd/nand/spi/foresee.c
+@@ -22,8 +22,8 @@ static SPINAND_OP_VARIANTS(write_cache_v
+               SPINAND_PROG_LOAD(true, 0, NULL, 0));
+ static SPINAND_OP_VARIANTS(update_cache_variants,
+-              SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+-              SPINAND_PROG_LOAD(false, 0, NULL, 0));
++              SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
++              SPINAND_PROG_LOAD(true, 0, NULL, 0));
+ static int f35sqa002g_ooblayout_ecc(struct mtd_info *mtd, int section,
+                                   struct mtd_oob_region *region)
diff --git a/target/linux/mediatek/patches-6.12/431-drivers-spi-mt65xx-Move-chip_config-to-driver-s-priv.patch b/target/linux/mediatek/patches-6.12/431-drivers-spi-mt65xx-Move-chip_config-to-driver-s-priv.patch
new file mode 100644 (file)
index 0000000..74e9bd9
--- /dev/null
@@ -0,0 +1,131 @@
+From bfa7cf42e610d820b935b4805aa80484d591cb1f Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Thu, 23 Jun 2022 18:29:51 +0800
+Subject: [PATCH 1/6] drivers: spi-mt65xx: Move chip_config to driver's private
+ data
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/spi/spi-mt65xx.c                 | 28 ++++++++++--------------
+ include/linux/platform_data/spi-mt65xx.h | 17 --------------
+ 2 files changed, 11 insertions(+), 34 deletions(-)
+ delete mode 100644 include/linux/platform_data/spi-mt65xx.h
+
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -15,7 +15,6 @@
+ #include <linux/gpio/consumer.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/platform_device.h>
+-#include <linux/platform_data/spi-mt65xx.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/spi-mem.h>
+@@ -172,6 +171,8 @@ struct mtk_spi {
+       struct device *dev;
+       dma_addr_t tx_dma;
+       dma_addr_t rx_dma;
++      u32 sample_sel;
++      u32 get_tick_dly;
+ };
+ static const struct mtk_spi_compatible mtk_common_compat;
+@@ -217,15 +218,6 @@ static const struct mtk_spi_compatible m
+       .no_need_unprepare = true,
+ };
+-/*
+- * A piece of default chip info unless the platform
+- * supplies it.
+- */
+-static const struct mtk_chip_config mtk_default_chip_info = {
+-      .sample_sel = 0,
+-      .tick_delay = 0,
+-};
+-
+ static const struct of_device_id mtk_spi_of_match[] = {
+       { .compatible = "mediatek,spi-ipm",
+               .data = (void *)&mtk_ipm_compat,
+@@ -353,7 +345,6 @@ static int mtk_spi_hw_init(struct spi_co
+ {
+       u16 cpha, cpol;
+       u32 reg_val;
+-      struct mtk_chip_config *chip_config = spi->controller_data;
+       struct mtk_spi *mdata = spi_controller_get_devdata(host);
+       cpha = spi->mode & SPI_CPHA ? 1 : 0;
+@@ -403,7 +394,7 @@ static int mtk_spi_hw_init(struct spi_co
+               else
+                       reg_val &= ~SPI_CMD_CS_POL;
+-              if (chip_config->sample_sel)
++              if (mdata->sample_sel)
+                       reg_val |= SPI_CMD_SAMPLE_SEL;
+               else
+                       reg_val &= ~SPI_CMD_SAMPLE_SEL;
+@@ -430,20 +421,20 @@ static int mtk_spi_hw_init(struct spi_co
+               if (mdata->dev_comp->ipm_design) {
+                       reg_val = readl(mdata->base + SPI_CMD_REG);
+                       reg_val &= ~SPI_CMD_IPM_GET_TICKDLY_MASK;
+-                      reg_val |= ((chip_config->tick_delay & 0x7)
++                      reg_val |= ((mdata->get_tick_dly & 0x7)
+                                   << SPI_CMD_IPM_GET_TICKDLY_OFFSET);
+                       writel(reg_val, mdata->base + SPI_CMD_REG);
+               } else {
+                       reg_val = readl(mdata->base + SPI_CFG1_REG);
+                       reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK;
+-                      reg_val |= ((chip_config->tick_delay & 0x7)
++                      reg_val |= ((mdata->get_tick_dly & 0x7)
+                                   << SPI_CFG1_GET_TICK_DLY_OFFSET);
+                       writel(reg_val, mdata->base + SPI_CFG1_REG);
+               }
+       } else {
+               reg_val = readl(mdata->base + SPI_CFG1_REG);
+               reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK_V1;
+-              reg_val |= ((chip_config->tick_delay & 0x3)
++              reg_val |= ((mdata->get_tick_dly & 0x3)
+                           << SPI_CFG1_GET_TICK_DLY_OFFSET_V1);
+               writel(reg_val, mdata->base + SPI_CFG1_REG);
+       }
+@@ -733,9 +724,6 @@ static int mtk_spi_setup(struct spi_devi
+ {
+       struct mtk_spi *mdata = spi_controller_get_devdata(spi->controller);
+-      if (!spi->controller_data)
+-              spi->controller_data = (void *)&mtk_default_chip_info;
+-
+       if (mdata->dev_comp->need_pad_sel && spi_get_csgpiod(spi, 0))
+               /* CS de-asserted, gpiolib will handle inversion */
+               gpiod_direction_output(spi_get_csgpiod(spi, 0), 0);
+@@ -1146,6 +1134,11 @@ static int mtk_spi_probe(struct platform
+       host->use_gpio_descriptors = true;
+       mdata = spi_controller_get_devdata(host);
++
++      /* Set device configs to default first. Calibrate it later. */
++      mdata->sample_sel = 0;
++      mdata->get_tick_dly = 2;
++
+       mdata->dev_comp = device_get_match_data(dev);
+       if (mdata->dev_comp->enhance_timing)
+--- a/include/linux/platform_data/spi-mt65xx.h
++++ /dev/null
+@@ -1,17 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
+-/*
+- *  MTK SPI bus driver definitions
+- *
+- * Copyright (c) 2015 MediaTek Inc.
+- * Author: Leilk Liu <leilk.liu@mediatek.com>
+- */
+-
+-#ifndef ____LINUX_PLATFORM_DATA_SPI_MTK_H
+-#define ____LINUX_PLATFORM_DATA_SPI_MTK_H
+-
+-/* Board specific platform_data */
+-struct mtk_chip_config {
+-      u32 sample_sel;
+-      u32 tick_delay;
+-};
+-#endif
diff --git a/target/linux/mediatek/patches-6.12/432-drivers-spi-Add-support-for-dynamic-calibration.patch b/target/linux/mediatek/patches-6.12/432-drivers-spi-Add-support-for-dynamic-calibration.patch
new file mode 100644 (file)
index 0000000..4e51dc2
--- /dev/null
@@ -0,0 +1,236 @@
+From aaff78437f09d4b86da84ce5983fb7c5be0538d2 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Thu, 23 Jun 2022 18:35:52 +0800
+Subject: [PATCH 2/6] drivers: spi: Add support for dynamic calibration
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/spi/spi.c       | 137 ++++++++++++++++++++++++++++++++++++++++
+ include/linux/spi/spi.h |  42 ++++++++++++
+ 2 files changed, 179 insertions(+)
+
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -1489,6 +1489,70 @@ static int spi_transfer_wait(struct spi_
+       return 0;
+ }
++int spi_do_calibration(struct spi_controller *ctlr, struct spi_device *spi,
++      int (*cal_read)(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen), void *drv_priv)
++{
++      int datalen = ctlr->cal_rule->datalen;
++      int addrlen = ctlr->cal_rule->addrlen;
++      u8 *buf;
++      int ret;
++      int i;
++      struct list_head *cal_head, *listptr;
++      struct spi_cal_target *target;
++
++      /* Calculate calibration result */
++      int hit_val, total_hit, origin;
++      bool hit;
++
++      /* Make sure we can start calibration */
++      if(!ctlr->cal_target || !ctlr->cal_rule || !ctlr->append_caldata)
++              return 0;
++
++      buf = kzalloc(datalen * sizeof(u8), GFP_KERNEL);
++      if(!buf)
++              return -ENOMEM;
++
++      ret = ctlr->append_caldata(ctlr);
++      if (ret)
++              goto cal_end;
++
++      cal_head = ctlr->cal_target;
++      list_for_each(listptr, cal_head) {
++              target = list_entry(listptr, struct spi_cal_target, list);
++
++              hit = false;
++              hit_val = 0;
++              total_hit = 0;
++              origin = *target->cal_item;
++
++              for(i=target->cal_min; i<=target->cal_max; i+=target->step) {
++                      *target->cal_item = i;
++                      ret = (*cal_read)(drv_priv, ctlr->cal_rule->addr, addrlen, buf, datalen);
++                      if(ret)
++                              break;
++                      dev_dbg(&spi->dev, "controller cal item value: 0x%x\n", i);
++                      if(memcmp(ctlr->cal_rule->match_data, buf, datalen * sizeof(u8)) == 0) {
++                              hit = true;
++                              hit_val += i;
++                              total_hit++;
++                              dev_dbg(&spi->dev, "golden data matches data read!\n");
++                      }
++              }
++              if(hit) {
++                      *target->cal_item = DIV_ROUND_CLOSEST(hit_val, total_hit);
++                      dev_info(&spi->dev, "calibration result: 0x%x", *target->cal_item);
++              } else {
++                      *target->cal_item = origin;
++                      dev_warn(&spi->dev, "calibration failed, fallback to default: 0x%x", origin);
++              }
++      }
++
++cal_end:
++      kfree(buf);
++      return ret? ret: 0;
++}
++EXPORT_SYMBOL_GPL(spi_do_calibration);
++
+ static void _spi_transfer_delay_ns(u32 ns)
+ {
+       if (!ns)
+@@ -2347,6 +2411,75 @@ void spi_flush_queue(struct spi_controll
+ /*-------------------------------------------------------------------------*/
+ #if defined(CONFIG_OF)
++static inline void alloc_cal_data(struct list_head **cal_target,
++      struct spi_cal_rule **cal_rule, bool enable)
++{
++      if(enable) {
++              *cal_target = kmalloc(sizeof(struct list_head), GFP_KERNEL);
++              INIT_LIST_HEAD(*cal_target);
++              *cal_rule = kmalloc(sizeof(struct spi_cal_rule), GFP_KERNEL);
++      } else {
++              kfree(*cal_target);
++              kfree(*cal_rule);
++      }
++}
++
++static int of_spi_parse_cal_dt(struct spi_controller *ctlr, struct spi_device *spi,
++                         struct device_node *nc)
++{
++      u32 value;
++      int rc;
++      const char *cal_mode;
++
++      rc = of_property_read_bool(nc, "spi-cal-enable");
++      if (rc)
++              alloc_cal_data(&ctlr->cal_target, &ctlr->cal_rule, true);
++      else
++              return 0;
++
++      rc = of_property_read_string(nc, "spi-cal-mode", &cal_mode);
++      if(!rc) {
++              if(strcmp("read-data", cal_mode) == 0){
++                      ctlr->cal_rule->mode = SPI_CAL_READ_DATA;
++              } else if(strcmp("read-pp", cal_mode) == 0) {
++                      ctlr->cal_rule->mode = SPI_CAL_READ_PP;
++                      return 0;
++              } else if(strcmp("read-sfdp", cal_mode) == 0){
++                      ctlr->cal_rule->mode = SPI_CAL_READ_SFDP;
++                      return 0;
++              }
++      } else
++              goto err;
++
++      ctlr->cal_rule->datalen = 0;
++      rc = of_property_read_u32(nc, "spi-cal-datalen", &value);
++      if(!rc && value > 0) {
++              ctlr->cal_rule->datalen = value;
++
++              ctlr->cal_rule->match_data = kzalloc(value * sizeof(u8), GFP_KERNEL);
++              rc = of_property_read_u8_array(nc, "spi-cal-data",
++                              ctlr->cal_rule->match_data, value);
++              if(rc)
++                      kfree(ctlr->cal_rule->match_data);
++      }
++
++      rc = of_property_read_u32(nc, "spi-cal-addrlen", &value);
++      if(!rc && value > 0) {
++              ctlr->cal_rule->addrlen = value;
++
++              ctlr->cal_rule->addr = kzalloc(value * sizeof(u32), GFP_KERNEL);
++              rc = of_property_read_u32_array(nc, "spi-cal-addr",
++                              ctlr->cal_rule->addr, value);
++              if(rc)
++                      kfree(ctlr->cal_rule->addr);
++      }
++      return 0;
++
++err:
++      alloc_cal_data(&ctlr->cal_target, &ctlr->cal_rule, false);
++      return 0;
++}
++
+ static void of_spi_parse_dt_cs_delay(struct device_node *nc,
+                                    struct spi_delay *delay, const char *prop)
+ {
+@@ -2511,6 +2644,10 @@ of_register_spi_device(struct spi_contro
+       if (rc)
+               goto err_out;
++      rc = of_spi_parse_cal_dt(ctlr, spi, nc);
++      if (rc)
++              goto err_out;
++
+       /* Store a pointer to the node in the device structure */
+       of_node_get(nc);
+--- a/include/linux/spi/spi.h
++++ b/include/linux/spi/spi.h
+@@ -348,6 +348,40 @@ struct spi_driver {
+       struct device_driver    driver;
+ };
++enum {
++      SPI_CAL_READ_DATA = 0,
++      SPI_CAL_READ_PP = 1, /* only for SPI-NAND */
++      SPI_CAL_READ_SFDP = 2, /* only for SPI-NOR */
++};
++
++struct nand_addr {
++      unsigned int lun;
++      unsigned int plane;
++      unsigned int eraseblock;
++      unsigned int page;
++      unsigned int dataoffs;
++};
++
++/**
++ * Read calibration rule from device dts node.
++ * Once calibration result matches the rule, we regard is as success.
++ */
++struct spi_cal_rule {
++      int datalen;
++      u8 *match_data;
++      int addrlen;
++      u32 *addr;
++      int mode;
++};
++
++struct spi_cal_target {
++      u32 *cal_item;
++      int cal_min; /* min of cal_item */
++      int cal_max; /* max of cal_item */
++      int step; /* Increase/decrease cal_item */
++      struct list_head list;
++};
++
+ #define to_spi_driver(__drv)   \
+       ( __drv ? container_of_const(__drv, struct spi_driver, driver) : NULL )
+@@ -754,6 +788,11 @@ struct spi_controller {
+       void                    *dummy_rx;
+       void                    *dummy_tx;
++      /* For calibration */
++      int (*append_caldata)(struct spi_controller *ctlr);
++      struct list_head *cal_target;
++      struct spi_cal_rule *cal_rule;
++
+       int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
+       /*
+@@ -1657,6 +1696,9 @@ spi_register_board_info(struct spi_board
+       { return 0; }
+ #endif
++extern int spi_do_calibration(struct spi_controller *ctlr,
++      struct spi_device *spi, int (*cal_read)(void *, u32 *, int, u8 *, int), void *drv_priv);
++
+ /*
+  * If you're hotplugging an adapter with devices (parport, USB, etc)
+  * use spi_new_device() to describe each device.  You can also call
diff --git a/target/linux/mediatek/patches-6.12/433-drivers-spi-mem-Add-spi-calibration-hook.patch b/target/linux/mediatek/patches-6.12/433-drivers-spi-mem-Add-spi-calibration-hook.patch
new file mode 100644 (file)
index 0000000..60c8f81
--- /dev/null
@@ -0,0 +1,41 @@
+From fa0aaf2a0532053b925f6fbb9c8d0e516370fb68 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Thu, 23 Jun 2022 18:37:55 +0800
+Subject: [PATCH 3/6] drivers: spi-mem: Add spi calibration hook
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/spi/spi-mem.c       | 8 ++++++++
+ include/linux/spi/spi-mem.h | 4 ++++
+ 2 files changed, 12 insertions(+)
+
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -497,6 +497,14 @@ int spi_mem_exec_op(struct spi_mem *mem,
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_exec_op);
++int spi_mem_do_calibration(struct spi_mem *mem,
++      int (*cal_read)(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen),
++      void *priv)
++{
++      return spi_do_calibration(mem->spi->controller, mem->spi, cal_read, priv);
++}
++EXPORT_SYMBOL_GPL(spi_mem_do_calibration);
++
+ /**
+  * spi_mem_get_name() - Return the SPI mem device name to be used by the
+  *                    upper layer if necessary
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -390,6 +390,10 @@ bool spi_mem_supports_op(struct spi_mem
+ int spi_mem_exec_op(struct spi_mem *mem,
+                   const struct spi_mem_op *op);
++int spi_mem_do_calibration(struct spi_mem *mem,
++                      int (*cal_read)(void *, u32 *, int, u8 *, int),
++                      void *priv);
++
+ const char *spi_mem_get_name(struct spi_mem *mem);
+ struct spi_mem_dirmap_desc *
diff --git a/target/linux/mediatek/patches-6.12/434-drivers-spi-mt65xx-Add-controller-s-calibration-para.patch b/target/linux/mediatek/patches-6.12/434-drivers-spi-mt65xx-Add-controller-s-calibration-para.patch
new file mode 100644 (file)
index 0000000..a7815d5
--- /dev/null
@@ -0,0 +1,43 @@
+From 655dfc90d438a8e223317f197b888a92de3df3a1 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Thu, 23 Jun 2022 18:39:03 +0800
+Subject: [PATCH 4/6] drivers: spi-mt65xx: Add controller's calibration
+ paramter
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/spi/spi-mt65xx.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -842,6 +842,21 @@ static irqreturn_t mtk_spi_interrupt(int
+       return IRQ_WAKE_THREAD;
+ }
++static int mtk_spi_append_caldata(struct spi_controller *ctlr)
++{
++      struct spi_cal_target *cal_target = kmalloc(sizeof(*cal_target), GFP_KERNEL);
++      struct mtk_spi *mdata = spi_controller_get_devdata(ctlr);
++
++      cal_target->cal_item = &mdata->get_tick_dly;
++      cal_target->cal_min = 0;
++      cal_target->cal_max = 7;
++      cal_target->step = 1;
++
++      list_add(&cal_target->list, ctlr->cal_target);
++
++      return 0;
++}
++
+ static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
+                                     struct spi_mem_op *op)
+ {
+@@ -1132,6 +1147,7 @@ static int mtk_spi_probe(struct platform
+       host->setup = mtk_spi_setup;
+       host->set_cs_timing = mtk_spi_set_hw_cs_timing;
+       host->use_gpio_descriptors = true;
++      host->append_caldata = mtk_spi_append_caldata;
+       mdata = spi_controller_get_devdata(host);
diff --git a/target/linux/mediatek/patches-6.12/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch b/target/linux/mediatek/patches-6.12/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch
new file mode 100644 (file)
index 0000000..b33315f
--- /dev/null
@@ -0,0 +1,81 @@
+From eef758fee8d25f56086eaaf7df1edb19929ced1a Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Thu, 23 Jun 2022 18:39:56 +0800
+Subject: [PATCH 5/6] drivers: mtd: spinand: Add calibration support for
+ spinand
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/mtd/nand/spi/core.c | 54 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1228,6 +1228,56 @@ static int spinand_manufacturer_match(st
+       return -EOPNOTSUPP;
+ }
++static int spinand_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen) {
++      struct spinand_device *spinand = (struct spinand_device *)priv;
++      struct device *dev = &spinand->spimem->spi->dev;
++      struct spi_mem_op op = SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, buf, readlen);
++      struct nand_pos pos;
++      struct nand_page_io_req req;
++      u8 status;
++      int ret;
++
++      if(addrlen != sizeof(struct nand_addr)/sizeof(unsigned int)) {
++              dev_err(dev, "Must provide correct addr(length) for spinand calibration\n");
++              return -EINVAL;
++      }
++
++      ret = spinand_reset_op(spinand);
++      if (ret)
++              return ret;
++
++      /* We should store our golden data in first target because
++       * we can't switch target at this moment.
++       */
++      pos = (struct nand_pos){
++              .target = 0,
++              .lun = *addr,
++              .plane = *(addr+1),
++              .eraseblock = *(addr+2),
++              .page = *(addr+3),
++      };
++
++      req = (struct nand_page_io_req){
++              .pos = pos,
++              .dataoffs = *(addr+4),
++              .datalen = readlen,
++              .databuf.in = buf,
++              .mode = MTD_OPS_AUTO_OOB,
++      };
++
++      ret = spinand_load_page_op(spinand, &req);
++      if (ret)
++              return ret;
++
++      ret = spinand_wait(spinand, &status);
++      if (ret < 0)
++              return ret;
++
++      ret = spi_mem_exec_op(spinand->spimem, &op);
++
++      return 0;
++}
++
+ static int spinand_id_detect(struct spinand_device *spinand)
+ {
+       u8 *id = spinand->id.data;
+@@ -1481,6 +1531,10 @@ static int spinand_init(struct spinand_d
+       if (!spinand->scratchbuf)
+               return -ENOMEM;
++      ret = spi_mem_do_calibration(spinand->spimem, spinand_cal_read, spinand);
++      if (ret)
++              dev_err(dev, "Failed to calibrate SPI-NAND (err = %d)\n", ret);
++
+       ret = spinand_detect(spinand);
+       if (ret)
+               goto err_free_bufs;
diff --git a/target/linux/mediatek/patches-6.12/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch b/target/linux/mediatek/patches-6.12/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch
new file mode 100644 (file)
index 0000000..04fa9ee
--- /dev/null
@@ -0,0 +1,57 @@
+From 7ec7de94c87654e6cc3f8f604b2f65c003f3e5dc Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Thu, 23 Jun 2022 18:40:59 +0800
+Subject: [PATCH 6/6] drivers: mtd: spi-nor: Add calibration support for
+ spi-nor
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/mtd/nand/spi/core.c |  5 ++++-
+ drivers/mtd/spi-nor/core.c  | 15 +++++++++++++++
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1269,7 +1269,10 @@ static int spinand_cal_read(void *priv,
+       if (ret)
+               return ret;
+-      ret = spinand_wait(spinand, &status);
++      ret = spinand_wait(spinand,
++                         SPINAND_READ_INITIAL_DELAY_US,
++                         SPINAND_READ_POLL_DELAY_US,
++                         &status);
+       if (ret < 0)
+               return ret;
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -3441,6 +3441,18 @@ static const struct flash_info *spi_nor_
+       return NULL;
+ }
++static int spi_nor_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen)
++{
++      struct spi_nor *nor = (struct spi_nor *)priv;
++
++      nor->reg_proto = SNOR_PROTO_1_1_1;
++      nor->read_proto = SNOR_PROTO_1_1_1;
++      nor->read_opcode = SPINOR_OP_READ;
++      nor->read_dummy = 0;
++
++      return nor->controller_ops->read(nor, *addr, readlen, buf);
++}
++
+ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
+                                                      const char *name)
+ {
+@@ -3615,6 +3627,9 @@ int spi_nor_scan(struct spi_nor *nor, co
+       if (ret)
+               return ret;
++      if(nor->spimem)
++              spi_mem_do_calibration(nor->spimem, spi_nor_cal_read, nor);
++
+       info = spi_nor_get_flash_info(nor, name);
+       if (IS_ERR(info))
+               return PTR_ERR(info);
diff --git a/target/linux/mediatek/patches-6.12/450-nvmem-add-layout-for-Adtran-devices.patch b/target/linux/mediatek/patches-6.12/450-nvmem-add-layout-for-Adtran-devices.patch
new file mode 100644 (file)
index 0000000..e1852e5
--- /dev/null
@@ -0,0 +1,192 @@
+From c22bc82183c2dea64919f975473ec518738baa3e Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 12 Jul 2023 13:38:35 +0100
+Subject: [PATCH] nvmem: add layout for Adtran devices
+
+Adtran stores unique factory data on GPT partitions on the eMMC.
+Using blk-nvmem the 'mfginfo' partition gets exposes as NVMEM provider.
+
+Add layout driver to parse mfginfo, mainly to provide MAC addresses to
+Ethernet and wireless interfaces.
+
+Variable names are converted to lower-case and '_' is replaced with '-'
+in order to comply with the device tree node naming convention.
+The main MAC address always ends on a 0 and up to 16 addresses are
+alocated for each device to use for various interfaces.
+
+Implement post-processing function for 'MFG_MAC' variable ('mfg-mac'
+node name in device tree) adding the nvmem cell index to the least
+significant digit of the MAC address.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/nvmem/layouts/Kconfig  |   9 +++
+ drivers/nvmem/layouts/Makefile |   1 +
+ drivers/nvmem/layouts/adtran.c | 135 +++++++++++++++++++++++++++++++++
+ 3 files changed, 145 insertions(+)
+ create mode 100644 drivers/nvmem/layouts/adtran.c
+
+--- a/drivers/nvmem/layouts/Kconfig
++++ b/drivers/nvmem/layouts/Kconfig
+@@ -8,6 +8,15 @@ if NVMEM_LAYOUTS
+ menu "Layout Types"
++config NVMEM_LAYOUT_ADTRAN
++      tristate "Adtran mfginfo layout support"
++      select GENERIC_NET_UTILS
++      help
++        Say Y here if you want to support the layout used by Adtran for
++        mfginfo.
++
++        If unsure, say N.
++
+ config NVMEM_LAYOUT_SL28_VPD
+       tristate "Kontron sl28 VPD layout support"
+       select CRC8
+--- a/drivers/nvmem/layouts/Makefile
++++ b/drivers/nvmem/layouts/Makefile
+@@ -6,4 +6,5 @@
+ obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
+ obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
+ obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
++obj-$(CONFIG_NVMEM_LAYOUT_ADTRAN) += adtran.o
+ obj-$(CONFIG_NVMEM_LAYOUT_ASCII_ENV) += ascii-env.o
+--- /dev/null
++++ b/drivers/nvmem/layouts/adtran.c
+@@ -0,0 +1,135 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <linux/ctype.h>
++#include <linux/etherdevice.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/nvmem-provider.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++
++/*
++ * Adtran devices usually come with a main MAC address ending on 0 and
++ * hence may have up to 16 MAC addresses per device.
++ * The main MAC address is stored as variable MFG_MAC in ASCII format.
++ */
++static int adtran_mac_address_pp(void *priv, const char *id, int index,
++                                unsigned int offset, void *buf,
++                                size_t bytes)
++{
++      u8 mac[ETH_ALEN];
++
++      if (WARN_ON(bytes != 3 * ETH_ALEN - 1))
++              return -EINVAL;
++
++      if (!mac_pton(buf, mac))
++              return -EINVAL;
++
++      if (index)
++              eth_addr_add(mac, index);
++
++      ether_addr_copy(buf, mac);
++
++      return 0;
++}
++
++static int adtran_add_cells(struct nvmem_layout *layout)
++{
++      struct nvmem_device *nvmem = layout->nvmem;
++      struct nvmem_cell_info info;
++      struct device_node *layout_np;
++      char mfginfo[1024], *c, *t, *p;
++      int ret = -EINVAL;
++
++      ret = nvmem_device_read(nvmem, 0, sizeof(mfginfo), mfginfo);
++      if (ret < 0)
++              return ret;
++      else if (ret != sizeof(mfginfo))
++              return -EIO;
++
++      layout_np = of_nvmem_layout_get_container(nvmem);
++      if (!layout_np)
++              return -ENOENT;
++
++      c = mfginfo;
++      while (*c != 0xff) {
++              memset(&info, 0, sizeof(info));
++              if (*c == '#')
++                      goto nextline;
++
++              t = strchr(c, '=');
++              if (!t)
++                      goto nextline;
++
++              *t = '\0';
++              ++t;
++              info.offset = t - mfginfo;
++              /* process variable name: convert to lower-case, '_' -> '-' */
++              p = c;
++              do {
++                      *p = tolower(*p);
++                      if (*p == '_')
++                              *p = '-';
++              } while (*++p);
++              info.name = c;
++              c = strchr(t, 0xa); /* find newline */
++              if (!c)
++                      break;
++
++              info.bytes = c - t;
++              if (!strcmp(info.name, "mfg-mac")) {
++                      info.raw_len = info.bytes;
++                      info.bytes = ETH_ALEN;
++                      info.read_post_process = adtran_mac_address_pp;
++              }
++
++              info.np = of_get_child_by_name(layout_np, info.name);
++              ret = nvmem_add_one_cell(nvmem, &info);
++              if (ret)
++                      break;
++
++              ++c;
++              continue;
++
++nextline:
++              c = strchr(c, 0xa); /* find newline */
++              if (!c)
++                      break;
++              ++c;
++      }
++
++      of_node_put(layout_np);
++
++      return ret;
++}
++
++static int adtran_probe(struct nvmem_layout *layout)
++{
++      layout->add_cells = adtran_add_cells;
++
++      return nvmem_layout_register(layout);
++}
++
++static void adtran_remove(struct nvmem_layout *layout)
++{
++      nvmem_layout_unregister(layout);
++}
++
++static const struct of_device_id adtran_of_match_table[] = {
++      { .compatible = "adtran,mfginfo" },
++      {},
++};
++MODULE_DEVICE_TABLE(of, adtran_of_match_table);
++
++static struct nvmem_layout_driver adtran_layout = {
++      .driver = {
++              .owner = THIS_MODULE,
++              .name = "adtran-layout",
++              .of_match_table = adtran_of_match_table,
++      },
++      .probe = adtran_probe,
++      .remove = adtran_remove,
++};
++module_nvmem_layout_driver(adtran_layout);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
++MODULE_DESCRIPTION("NVMEM layout driver for Adtran mfginfo");
diff --git a/target/linux/mediatek/patches-6.12/500-gsw-rtl8367s-mt7622-support.patch b/target/linux/mediatek/patches-6.12/500-gsw-rtl8367s-mt7622-support.patch
new file mode 100644 (file)
index 0000000..c558ce3
--- /dev/null
@@ -0,0 +1,36 @@
+From c46ccb69d17e584479df849a107423175a143c83 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 24 Oct 2020 21:15:20 +0200
+Subject: [PATCH] net: phy: add RTL8367S gigabit switch Kconfig/Makefile entry for MT7622
+
+Add a CONFIG_RTL8367S_GSW Kconfig option and the corresponding
+obj-$(CONFIG_RTL8367S_GSW) Makefile entry to allow building the
+out-of-tree RTL8367S gigabit switch driver used on MT7622 boards.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -443,6 +443,12 @@ config ROCKCHIP_PHY
+       help
+         Currently supports the integrated Ethernet PHY.
++config RTL8367S_GSW
++      tristate "rtl8367 Gigabit Switch support for mt7622"
++      depends on NET_VENDOR_MEDIATEK
++      help
++        This driver supports rtl8367s in mt7622
++
+ config SMSC_PHY
+       tristate "SMSC PHYs"
+       select CRC16
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -113,6 +113,7 @@ obj-$(CONFIG_REALTEK_PHY)  += realtek/
+ obj-y                         += rtl8261n/
+ obj-$(CONFIG_RENESAS_PHY)     += uPD60620.o
+ obj-$(CONFIG_ROCKCHIP_PHY)    += rockchip.o
++obj-$(CONFIG_RTL8367S_GSW)    += rtk/
+ obj-$(CONFIG_SMSC_PHY)                += smsc.o
+ obj-$(CONFIG_STE10XP)         += ste10Xp.o
+ obj-$(CONFIG_TERANETICS_PHY)  += teranetics.o
diff --git a/target/linux/mediatek/patches-6.12/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch b/target/linux/mediatek/patches-6.12/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch
new file mode 100644 (file)
index 0000000..764fe76
--- /dev/null
@@ -0,0 +1,39 @@
+From ade563ba84496406243b3699a27b3de7e08399e7 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 27 Mar 2022 12:54:03 +0200
+Subject: [PATCH] arm64: dts: mediatek: mt7622: add PCIe slot child nodes
+
+Add named slot0 and slot1 child nodes to the pcie0 and pcie1 host
+controllers in mt7622.dtsi so that device tree overlays can target
+specific PCIe slots by phandle.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -844,6 +844,12 @@
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+               };
++
++              slot0: pcie@0,0 {
++                      reg = <0x0000 0 0 0 0>;
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++              };
+       };
+       pcie1: pcie@1a145000 {
+@@ -882,6 +888,12 @@
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+               };
++
++              slot1: pcie@1,0 {
++                      reg = <0x0800 0 0 0 0>;
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++              };
+       };
+       sata: sata@1a200000 {
diff --git a/target/linux/mediatek/patches-6.12/610-pcie-mediatek-fix-clearing-interrupt-status.patch b/target/linux/mediatek/patches-6.12/610-pcie-mediatek-fix-clearing-interrupt-status.patch
new file mode 100644 (file)
index 0000000..e31e02d
--- /dev/null
@@ -0,0 +1,23 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 4 Sep 2020 18:33:27 +0200
+Subject: [PATCH] pcie-mediatek: fix clearing interrupt status
+
+Clearing the status needs to happen after running the handler, otherwise
+we will get an extra spurious interrupt after the cause has been cleared
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -601,9 +601,9 @@ static void mtk_pcie_intr_handler(struct
+       if (status & INTX_MASK) {
+               for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) {
+                       /* Clear the INTx */
+-                      writel(1 << bit, port->base + PCIE_INT_STATUS);
+                       generic_handle_domain_irq(port->irq_domain,
+                                                 bit - INTX_SHIFT);
++                      writel(1 << bit, port->base + PCIE_INT_STATUS);
+               }
+       }
diff --git a/target/linux/mediatek/patches-6.12/611-pcie-mediatek-gen3-PERST-for-100ms.patch b/target/linux/mediatek/patches-6.12/611-pcie-mediatek-gen3-PERST-for-100ms.patch
new file mode 100644 (file)
index 0000000..f3d308a
--- /dev/null
@@ -0,0 +1,29 @@
+From 6a2e17d5c1451025396ba523e9f2d112212c7261 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 3 Oct 2023 02:32:35 +0100
+Subject: [PATCH] mediatek: fix PCIe #PERST being de-asserted too early
+
+The driver for MediaTek gen3 PCIe hosts de-asserts all reset
+signals at the same time using a single register write operation.
+Delay the de-assertion of the #PERST signal by 100ms as some PCIe
+devices fail to come up otherwise.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/drivers/pci/controller/pcie-mediatek-gen3.c
++++ b/drivers/pci/controller/pcie-mediatek-gen3.c
+@@ -416,7 +416,13 @@ static int mtk_pcie_startup_port(struct
+       msleep(100);
+       /* De-assert reset signals */
+-      val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB);
++      val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB);
++      writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
++
++      msleep(100);
++
++      /* De-assert PERST# signals */
++      val &= ~(PCIE_PE_RSTB);
+       writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
+       /* Check if the link is up or not */
diff --git a/target/linux/mediatek/patches-6.12/700-net-phy-mediatek-Add-2.5Gphy-firmware-dt-bindings-an.patch b/target/linux/mediatek/patches-6.12/700-net-phy-mediatek-Add-2.5Gphy-firmware-dt-bindings-an.patch
new file mode 100644 (file)
index 0000000..9996501
--- /dev/null
@@ -0,0 +1,71 @@
+From 955a80b20fad77dd73ec17ab64d7eb8014cb59c7 Mon Sep 17 00:00:00 2001
+From: Sky Huang <skylake.huang@mediatek.com>
+Date: Wed, 19 Feb 2025 16:39:08 +0800
+Subject: [PATCH 19/20] net: phy: mediatek: Add 2.5Gphy firmware dt-bindings
+ and dts node
+
+Add 2.5Gphy firmware dt-bindings and dts node since mtk-2p5ge
+driver requires firmware to run. Also, update MAINTAINERS for
+MediaTek's built-in 2.5Gphy dt-bindings and change MAINTAINER's name.
+
+Signed-off-by: Sky Huang <skylake.huang@mediatek.com>
+---
+ .../bindings/net/mediatek,2p5gphy-fw.yaml     | 37 +++++++++++++++++++
+ MAINTAINERS                                   |  3 +-
+ 2 files changed, 39 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml
+@@ -0,0 +1,37 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/net/mediatek,2p5gphy-fw.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: MediaTek Built-in 2.5G Ethernet PHY
++
++maintainers:
++  - Sky Huang <SkyLake.Huang@mediatek.com>
++
++description: |
++  MediaTek Built-in 2.5G Ethernet PHY needs to load firmware so it can
++  run correctly.
++
++properties:
++  compatible:
++    const: "mediatek,2p5gphy-fw"
++
++  reg:
++    items:
++      - description: pmb firmware load address
++      - description: firmware trigger register
++
++required:
++  - compatible
++  - reg
++
++additionalProperties: false
++
++examples:
++  - |
++    phyfw: phy-firmware@f000000 {
++      compatible = "mediatek,2p5gphy-fw";
++      reg = <0 0x0f100000 0 0x20000>,
++            <0 0x0f0f0018 0 0x20>;
++    };
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -14439,9 +14439,10 @@ F:    include/linux/pcs/pcs-mtk-usxgmii.h
+ MEDIATEK ETHERNET PHY DRIVERS
+ M:    Daniel Golle <daniel@makrotopia.org>
+ M:    Qingfang Deng <dqfext@gmail.com>
+-M:    SkyLake Huang <SkyLake.Huang@mediatek.com>
++M:    Sky Huang <SkyLake.Huang@mediatek.com>
+ L:    netdev@vger.kernel.org
+ S:    Maintained
++F:    Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml
+ F:    drivers/net/phy/mediatek/mtk-ge-soc.c
+ F:    drivers/net/phy/mediatek/mtk-phy-lib.c
+ F:    drivers/net/phy/mediatek/mtk-ge.c
diff --git a/target/linux/mediatek/patches-6.12/701-net-phy-mediatek-add-driver-for-built-in-2.5G-ethern.patch b/target/linux/mediatek/patches-6.12/701-net-phy-mediatek-add-driver-for-built-in-2.5G-ethern.patch
new file mode 100644 (file)
index 0000000..ff7aa40
--- /dev/null
@@ -0,0 +1,399 @@
+From 4eb44972db02c2b704f0ef5c891f29f25440a063 Mon Sep 17 00:00:00 2001
+From: Sky Huang <skylake.huang@mediatek.com>
+Date: Wed, 19 Feb 2025 16:39:10 +0800
+Subject: [PATCH 20/20] net: phy: mediatek: add driver for built-in 2.5G
+ ethernet PHY on MT7988
+
+Add support for internal 2.5Gphy on MT7988. This driver will load
+necessary firmware and add appropriate time delay to make sure
+that firmware works stably. Also, certain control registers will
+be set to fix link-up issues.
+
+Signed-off-by: Sky Huang <skylake.huang@mediatek.com>
+---
+ MAINTAINERS                          |   1 +
+ drivers/net/phy/mediatek/Kconfig     |  11 +
+ drivers/net/phy/mediatek/Makefile    |   1 +
+ drivers/net/phy/mediatek/mtk-2p5ge.c | 342 +++++++++++++++++++++++++++
+ 4 files changed, 355 insertions(+)
+ create mode 100644 drivers/net/phy/mediatek/mtk-2p5ge.c
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -14443,6 +14443,7 @@ M:     Sky Huang <SkyLake.Huang@mediatek.com
+ L:    netdev@vger.kernel.org
+ S:    Maintained
+ F:    Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml
++F:    drivers/net/phy/mediatek/mtk-2p5ge.c
+ F:    drivers/net/phy/mediatek/mtk-ge-soc.c
+ F:    drivers/net/phy/mediatek/mtk-phy-lib.c
+ F:    drivers/net/phy/mediatek/mtk-ge.c
+--- a/drivers/net/phy/mediatek/Kconfig
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -26,3 +26,14 @@ config MEDIATEK_GE_SOC_PHY
+         the MT7981 and MT7988 SoCs. These PHYs need calibration data
+         present in the SoCs efuse and will dynamically calibrate VCM
+         (common-mode voltage) during startup.
++
++config MEDIATEK_2P5GE_PHY
++      tristate "MediaTek 2.5Gb Ethernet PHYs"
++      depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
++      select MTK_NET_PHYLIB
++      help
++        Supports MediaTek SoC built-in 2.5Gb Ethernet PHYs.
++
++        This will load necessary firmware and add appropriate time delay.
++        Accelerate this procedure through internal pbus instead of MDIO
++        bus. Certain link-up issues will also be fixed here.
+--- a/drivers/net/phy/mediatek/Makefile
++++ b/drivers/net/phy/mediatek/Makefile
+@@ -2,3 +2,4 @@
+ obj-$(CONFIG_MTK_NET_PHYLIB)          += mtk-phy-lib.o
+ obj-$(CONFIG_MEDIATEK_GE_PHY)         += mtk-ge.o
+ obj-$(CONFIG_MEDIATEK_GE_SOC_PHY)     += mtk-ge-soc.o
++obj-$(CONFIG_MEDIATEK_2P5GE_PHY)      += mtk-2p5ge.o
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-2p5ge.c
+@@ -0,0 +1,342 @@
++// SPDX-License-Identifier: GPL-2.0+
++#include <linux/bitfield.h>
++#include <linux/firmware.h>
++#include <linux/module.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/of_address.h>
++#include <linux/platform_device.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/phy.h>
++#include <linux/pm_domain.h>
++#include <linux/pm_runtime.h>
++
++#include "mtk.h"
++
++#define MTK_2P5GPHY_ID_MT7988 (0x00339c11)
++
++#define MT7988_2P5GE_PMB_FW           "mediatek/mt7988/i2p5ge-phy-pmb.bin"
++#define MT7988_2P5GE_PMB_FW_SIZE      (0x20000)
++#define MD32_EN_CFG                   (0x18)
++#define   MD32_EN                     BIT(0)
++
++#define BASE100T_STATUS_EXTEND                (0x10)
++#define BASE1000T_STATUS_EXTEND               (0x11)
++#define EXTEND_CTRL_AND_STATUS                (0x16)
++
++#define PHY_AUX_CTRL_STATUS           (0x1d)
++#define   PHY_AUX_DPX_MASK            GENMASK(5, 5)
++#define   PHY_AUX_SPEED_MASK          GENMASK(4, 2)
++
++/* Registers on MDIO_MMD_VEND1 */
++#define MTK_PHY_LPI_PCS_DSP_CTRL              (0x121)
++#define   MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK        GENMASK(12, 8)
++
++#define MTK_PHY_HOST_CMD1             0x800e
++#define MTK_PHY_HOST_CMD2             0x800f
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
++#define AUTO_NP_10XEN                         BIT(6)
++
++struct mtk_i2p5ge_phy_priv {
++      bool fw_loaded;
++};
++
++enum {
++      PHY_AUX_SPD_10 = 0,
++      PHY_AUX_SPD_100,
++      PHY_AUX_SPD_1000,
++      PHY_AUX_SPD_2500,
++};
++
++static int mt798x_2p5ge_phy_load_fw(struct phy_device *phydev)
++{
++      struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++      void __iomem *mcu_csr_base, *pmb_addr;
++      struct device *dev = &phydev->mdio.dev;
++      const struct firmware *fw;
++      struct device_node *np;
++      int ret, i;
++      u32 reg;
++
++      np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw");
++      if (!np)
++              return -ENOENT;
++
++      pmb_addr = of_iomap(np, 0);
++      if (!pmb_addr)
++              return -ENOMEM;
++      mcu_csr_base = of_iomap(np, 1);
++      if (!mcu_csr_base) {
++              ret = -ENOMEM;
++              goto free_pmb;
++      }
++
++      ret = request_firmware(&fw, MT7988_2P5GE_PMB_FW, dev);
++      if (ret) {
++              dev_err(dev, "failed to load firmware: %s, ret: %d\n",
++                      MT7988_2P5GE_PMB_FW, ret);
++              goto free;
++      }
++
++      if (fw->size != MT7988_2P5GE_PMB_FW_SIZE) {
++              dev_err(dev, "Firmware size 0x%zx != 0x%x\n",
++                      fw->size, MT7988_2P5GE_PMB_FW_SIZE);
++              ret = -EINVAL;
++              goto release_fw;
++      }
++
++      reg = readw(mcu_csr_base + MD32_EN_CFG);
++      if (reg & MD32_EN) {
++              phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
++              usleep_range(10000, 11000);
++      }
++      phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
++
++      /* Write magic number to safely stall MCU */
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_HOST_CMD1, 0x1100);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_HOST_CMD2, 0x00df);
++
++      for (i = 0; i < MT7988_2P5GE_PMB_FW_SIZE - 1; i += 4)
++              writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
++
++      if (!priv->fw_loaded)
++              dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n",
++                       be16_to_cpu(*((__be16 *)(fw->data +
++                                                MT7988_2P5GE_PMB_FW_SIZE - 8))),
++                       *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 6),
++                       *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 5),
++                       *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 2),
++                       *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 1));
++
++      writew(reg & ~MD32_EN, mcu_csr_base + MD32_EN_CFG);
++      writew(reg | MD32_EN, mcu_csr_base + MD32_EN_CFG);
++      phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
++      /* We need a delay here to stabilize initialization of MCU */
++      usleep_range(7000, 8000);
++
++      priv->fw_loaded = true;
++
++release_fw:
++      release_firmware(fw);
++free:
++      iounmap(mcu_csr_base);
++free_pmb:
++      iounmap(pmb_addr);
++
++      return ret;
++}
++
++static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev)
++{
++      struct pinctrl *pinctrl;
++      int ret;
++
++      /* Check if PHY interface type is compatible */
++      if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
++              return -ENODEV;
++
++      ret = mt798x_2p5ge_phy_load_fw(phydev);
++      if (ret < 0)
++              return ret;
++
++      /* Setup LED */
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
++                       MTK_PHY_LED_ON_POLARITY | MTK_PHY_LED_ON_LINK10 |
++                       MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK1000 |
++                       MTK_PHY_LED_ON_LINK2500);
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
++                       MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX);
++
++      /* Switch pinctrl after setting polarity to avoid bogus blinking */
++      pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
++      if (IS_ERR(pinctrl) && PTR_ERR(pinctrl) != -ENODEV)
++              dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL,
++                     MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0);
++
++      /* Enable 16-bit next page exchange bit if 1000-BT isn't advertising */
++      mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AUTO_NP_10XEN,
++                    FIELD_PREP(AUTO_NP_10XEN, 0x1));
++
++      /* Enable HW auto downshift */
++      phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
++                       MTK_PHY_AUX_CTRL_AND_STATUS,
++                       0, MTK_PHY_ENABLE_DOWNSHIFT);
++
++      return 0;
++}
++
++static int mt798x_2p5ge_phy_config_aneg(struct phy_device *phydev)
++{
++      bool changed = false;
++      u32 adv;
++      int ret;
++
++      ret = genphy_c45_an_config_aneg(phydev);
++      if (ret < 0)
++              return ret;
++      if (ret > 0)
++              changed = true;
++
++      /* Clause 45 doesn't define 1000BaseT support. Use Clause 22 instead in
++       * our design.
++       */
++      adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
++      ret = phy_modify_changed(phydev, MII_CTRL1000, ADVERTISE_1000FULL, adv);
++      if (ret < 0)
++              return ret;
++      if (ret > 0)
++              changed = true;
++
++      return __genphy_config_aneg(phydev, changed);
++}
++
++static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev)
++{
++      int ret;
++
++      ret = genphy_c45_pma_read_abilities(phydev);
++      if (ret)
++              return ret;
++
++      /* This phy can't handle collision, and neither can (XFI)MAC it's
++       * connected to. Although it can do HDX handshake, it doesn't support
++       * CSMA/CD that HDX requires.
++       */
++      linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
++                         phydev->supported);
++
++      return 0;
++}
++
++static int mt798x_2p5ge_phy_read_status(struct phy_device *phydev)
++{
++      int ret;
++
++      /* When MDIO_STAT1_LSTATUS is raised genphy_c45_read_link(), this phy
++       * actually hasn't finished AN. So use CL22's link update function
++       * instead.
++       */
++      ret = genphy_update_link(phydev);
++      if (ret)
++              return ret;
++
++      phydev->speed = SPEED_UNKNOWN;
++      phydev->duplex = DUPLEX_UNKNOWN;
++      phydev->pause = 0;
++      phydev->asym_pause = 0;
++
++      /* We'll read link speed through vendor specific registers down below.
++       * So remove phy_resolve_aneg_linkmode (AN on) & genphy_c45_read_pma
++       * (AN off).
++       */
++      if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
++              ret = genphy_c45_read_lpa(phydev);
++              if (ret < 0)
++                      return ret;
++
++              /* Clause 45 doesn't define 1000BaseT support. Read the link
++               * partner's 1G advertisement via Clause 22.
++               */
++              ret = phy_read(phydev, MII_STAT1000);
++              if (ret < 0)
++                      return ret;
++              mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
++      } else if (phydev->autoneg == AUTONEG_DISABLE) {
++              linkmode_zero(phydev->lp_advertising);
++      }
++
++      if (phydev->link) {
++              ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
++              if (ret < 0)
++                      return ret;
++
++              switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
++              case PHY_AUX_SPD_10:
++                      phydev->speed = SPEED_10;
++                      break;
++              case PHY_AUX_SPD_100:
++                      phydev->speed = SPEED_100;
++                      break;
++              case PHY_AUX_SPD_1000:
++                      phydev->speed = SPEED_1000;
++                      break;
++              case PHY_AUX_SPD_2500:
++                      phydev->speed = SPEED_2500;
++                      break;
++              }
++
++              phydev->duplex = DUPLEX_FULL;
++              /* FIXME:
++               * The current firmware always enables rate adaptation mode.
++               */
++              phydev->rate_matching = RATE_MATCH_PAUSE;
++      }
++
++      return 0;
++}
++
++static int mt798x_2p5ge_phy_get_rate_matching(struct phy_device *phydev,
++                                            phy_interface_t iface)
++{
++      return RATE_MATCH_PAUSE;
++}
++
++static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)
++{
++      struct mtk_i2p5ge_phy_priv *priv;
++
++      priv = devm_kzalloc(&phydev->mdio.dev,
++                          sizeof(struct mtk_i2p5ge_phy_priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++
++      switch (phydev->drv->phy_id) {
++      case MTK_2P5GPHY_ID_MT7988:
++              /* The original hardware only sets MDIO_DEVS_PMAPMD */
++              phydev->c45_ids.mmds_present |= MDIO_DEVS_PCS |
++                                              MDIO_DEVS_AN |
++                                              MDIO_DEVS_VEND1 |
++                                              MDIO_DEVS_VEND2;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      priv->fw_loaded = false;
++      phydev->priv = priv;
++
++      return 0;
++}
++
++static struct phy_driver mtk_2p5gephy_driver[] = {
++      {
++              PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7988),
++              .name = "MediaTek MT7988 2.5GbE PHY",
++              .probe = mt798x_2p5ge_phy_probe,
++              .config_init = mt798x_2p5ge_phy_config_init,
++              .config_aneg = mt798x_2p5ge_phy_config_aneg,
++              .get_features = mt798x_2p5ge_phy_get_features,
++              .read_status = mt798x_2p5ge_phy_read_status,
++              .get_rate_matching = mt798x_2p5ge_phy_get_rate_matching,
++              .suspend = genphy_suspend,
++              .resume = genphy_resume,
++              .read_page = mtk_phy_read_page,
++              .write_page = mtk_phy_write_page,
++      },
++};
++
++module_phy_driver(mtk_2p5gephy_driver);
++
++static const struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
++      { PHY_ID_MATCH_VENDOR(0x00339c00) },
++      { }
++};
++
++MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
++MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
++MODULE_FIRMWARE(MT7988_2P5GE_PMB_FW);
diff --git a/target/linux/mediatek/patches-6.12/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch b/target/linux/mediatek/patches-6.12/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch
new file mode 100644 (file)
index 0000000..1642cfe
--- /dev/null
@@ -0,0 +1,91 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 4 Sep 2020 18:42:42 +0200
+Subject: [PATCH] pci: pcie-mediatek: add support for coherent DMA
+
+It improves performance by eliminating the need for a cache flush for DMA on
+attached devices
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -832,6 +832,9 @@
+               bus-range = <0x00 0xff>;
+               ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
+               status = "disabled";
++              dma-coherent;
++              mediatek,hifsys = <&hifsys>;
++              mediatek,cci-control = <&cci_control2>;
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 7>;
+@@ -876,6 +879,9 @@
+               bus-range = <0x00 0xff>;
+               ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
+               status = "disabled";
++              dma-coherent;
++              mediatek,hifsys = <&hifsys>;
++              mediatek,cci-control = <&cci_control2>;
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 7>;
+@@ -937,7 +943,7 @@
+       };
+       hifsys: clock-controller@1af00000 {
+-              compatible = "mediatek,mt7622-hifsys";
++              compatible = "mediatek,mt7622-hifsys", "syscon";
+               reg = <0 0x1af00000 0 0x70>;
+               #clock-cells = <1>;
+       };
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -20,6 +20,7 @@
+ #include <linux/of_address.h>
+ #include <linux/of_pci.h>
+ #include <linux/of_platform.h>
++#include <linux/of_address.h>
+ #include <linux/pci.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+@@ -139,6 +140,11 @@
+ #define PCIE_LINK_STATUS_V2   0x804
+ #define PCIE_PORT_LINKUP_V2   BIT(10)
++/* DMA channel mapping */
++#define HIFSYS_DMA_AG_MAP     0x008
++#define HIFSYS_DMA_AG_MAP_PCIE0       BIT(0)
++#define HIFSYS_DMA_AG_MAP_PCIE1       BIT(1)
++
+ struct mtk_pcie_port;
+ /**
+@@ -1047,6 +1053,27 @@ static int mtk_pcie_setup(struct mtk_pci
+       struct mtk_pcie_port *port, *tmp;
+       int err, slot;
++      if (of_dma_is_coherent(node)) {
++              struct regmap *con;
++              u32 mask;
++
++              con = syscon_regmap_lookup_by_phandle(node,
++                                                    "mediatek,cci-control");
++              /* enable CPU/bus coherency */
++              if (!IS_ERR(con))
++                      regmap_write(con, 0, 3);
++
++              con = syscon_regmap_lookup_by_phandle(node,
++                                                    "mediatek,hifsys");
++              if (IS_ERR(con)) {
++                      dev_err(dev, "missing hifsys node\n");
++                      return PTR_ERR(con);
++              }
++
++              mask = HIFSYS_DMA_AG_MAP_PCIE0 | HIFSYS_DMA_AG_MAP_PCIE1;
++              regmap_update_bits(con, HIFSYS_DMA_AG_MAP, mask, mask);
++      }
++
+       slot = of_get_pci_domain_nr(dev->of_node);
+       if (slot < 0) {
+               for_each_available_child_of_node(node, child) {
diff --git a/target/linux/mediatek/patches-6.12/721-dts-mt7622-mediatek-fix-300mhz.patch b/target/linux/mediatek/patches-6.12/721-dts-mt7622-mediatek-fix-300mhz.patch
new file mode 100644 (file)
index 0000000..f9a5fdb
--- /dev/null
@@ -0,0 +1,27 @@
+From: Jip de Beer <gpk6x3591g0l@opayq.com>
+Date: Sun, 9 Jan 2022 13:14:04 +0100
+Subject: [PATCH] mediatek mt7622: fix 300mhz typo in dts
+
+The lowest frequency should be 300MHz, since that is the label
+assigned to the OPP in the mt7622.dtsi device tree, while there is one
+missing zero in the actual value.
+
+To be clear, the lowest frequency should be 300MHz instead of 30MHz.
+
+As mentioned @dangowrt on the OpenWrt forum there is no benefit in
+leaving 30MHz as the lowest frequency.
+
+Signed-off-by: Jip de Beer <gpk6x3591g0l@opayq.com>
+Signed-off-by: Fritz D. Ansel <fdansel@yandex.ru>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -24,7 +24,7 @@
+               compatible = "operating-points-v2";
+               opp-shared;
+               opp-300000000 {
+-                      opp-hz = /bits/ 64 <30000000>;
++                      opp-hz = /bits/ 64 <300000000>;
+                       opp-microvolt = <950000>;
+               };
diff --git a/target/linux/mediatek/patches-6.12/722-remove-300Hz-to-prevent-freeze.patch b/target/linux/mediatek/patches-6.12/722-remove-300Hz-to-prevent-freeze.patch
new file mode 100644 (file)
index 0000000..003e8b6
--- /dev/null
@@ -0,0 +1,42 @@
+From d0d6b8e1833c587d0c50cac4f6324aa93b0bc8fc Mon Sep 17 00:00:00 2001
+From: John Audia <therealgraysky@proton.me>
+Date: Wed, 6 Jul 2022 11:49:50 -0400
+Subject: [PATCH] mt7622: remove 300 MHz from dts
+
+Due to the bug described here[1], remove the 300 MHz clock to avoid a low
+voltage condition that can cause a hang when rebooting the RT3200/E8450.
+
+This solution is probably better than the script-based work-around[2].
+
+1. https://forum.openwrt.org/t/belkin-rt3200-linksys-e8450-wifi-ax-discussion/94302/1490
+2. https://github.com/openwrt/openwrt/pull/5025
+
+Signed-off-by: John Audia <therealgraysky@proton.me>
+Tested-by: Rui Salvaterra <rsalvaterra@gmail.com>
+Tested-by: John Audia <therealgraysky@proton.me>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -23,11 +23,17 @@
+       cpu_opp_table: opp-table {
+               compatible = "operating-points-v2";
+               opp-shared;
+-              opp-300000000 {
+-                      opp-hz = /bits/ 64 <300000000>;
+-                      opp-microvolt = <950000>;
+-              };
+-
++              /* Due to the bug described at the link below, remove the 300 MHz clock to avoid a low
++               * voltage condition that can cause a hang when rebooting the RT3200/E8450.
++               *
++               * https://forum.openwrt.org/t/belkin-rt3200-linksys-e8450-wifi-ax-discussion/94302/1490
++               *
++               * opp-300000000 {
++               *      opp-hz = /bits/ 64 <300000000>;
++               *      opp-microvolt = <950000>;
++               * };
++               *
++               */
+               opp-437500000 {
+                       opp-hz = /bits/ 64 <437500000>;
+                       opp-microvolt = <1000000>;
diff --git a/target/linux/mediatek/patches-6.12/734-net-phy-add-Airoha-EN8801SC-PHY.patch b/target/linux/mediatek/patches-6.12/734-net-phy-add-Airoha-EN8801SC-PHY.patch
new file mode 100644 (file)
index 0000000..4ebaffd
--- /dev/null
@@ -0,0 +1,38 @@
+From 5314e73cb941b47e6866b49b3b78c25e32d62df8 Mon Sep 17 00:00:00 2001
+From: Robert Marko <robert.marko@sartura.hr>
+Date: Sat, 23 Mar 2024 20:21:14 +0100
+Subject: [PATCH] net: phy: add Airoha EN8801SC PHY
+
+Airoha EN8801SC Gigabit PHY is used on Edgecore EAP111, so include a
+modified version of MTK SDK driver.
+
+Signed-off-by: Robert Marko <robert.marko@sartura.hr>
+---
+ drivers/net/phy/Kconfig  | 5 +++++
+ drivers/net/phy/Makefile | 1 +
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -165,6 +165,11 @@ config AS21XXX_PHY
+         AS21210PB1 that all register with the PHY ID 0x7500 0x7500
+         before the firmware is loaded.
++config AIROHA_EN8801SC_PHY
++      tristate "Airoha EN8801SC Gigabit PHY"
++      help
++        Currently supports the Airoha EN8801SC PHY.
++
+ config AIR_EN8811H_PHY
+       tristate "Airoha EN8811H 2.5 Gigabit PHY"
+       help
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -50,6 +50,7 @@ obj-y                                += $(sfp-obj-y) $(sfp-obj-m)
+ obj-$(CONFIG_ADIN_PHY)                += adin.o
+ obj-$(CONFIG_ADIN1100_PHY)    += adin1100.o
++obj-$(CONFIG_AIROHA_EN8801SC_PHY)   += en8801sc.o
+ obj-$(CONFIG_AIR_EN8811H_PHY)   += air_en8811h.o
+ obj-$(CONFIG_AMD_PHY)         += amd.o
+ obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o
diff --git a/target/linux/mediatek/patches-6.12/736-net-pcs-mtk_usxgmii-add-polarity-control.patch b/target/linux/mediatek/patches-6.12/736-net-pcs-mtk_usxgmii-add-polarity-control.patch
new file mode 100644 (file)
index 0000000..3b0b06b
--- /dev/null
@@ -0,0 +1,65 @@
+From ddfae94a14bf0fc301505da75825dfe473525a33 Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Tue, 29 Oct 2024 13:40:11 +0100
+Subject: [PATCH] mediatek: add support for swapping the polarity on usxgmii interfaces
+
+This patch comes from the MTK SDK.
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+--- a/drivers/net/pcs/pcs-mtk-usxgmii.c
++++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
+@@ -52,6 +52,12 @@
+ #define USXGMII_LPA                           GENMASK(15, 0)
+ #define USXGMII_LPA_LATCH                     BIT(31)
++/* Register to control PCS polarity */
++#define RG_PHY_TOP_CTRL0                      0x82C
++#define USXGMII_PN_SWAP_MASK                  GENMASK(1, 0)
++#define USXGMII_PN_SWAP_RX                    BIT(1)
++#define USXGMII_PN_SWAP_TX                    BIT(0)
++
+ /* Register to read PCS link status */
+ #define RG_PCS_RX_STATUS0                     0x904
+ #define RG_PCS_RX_STATUS_UPDATE                       BIT(16)
+@@ -74,6 +80,7 @@ struct mtk_usxgmii_pcs {
+       struct clk                      *clk;
+       struct reset_control            *reset;
+       phy_interface_t                 interface;
++      unsigned int                    polarity;
+       unsigned int                    neg_mode;
+       struct list_head                node;
+ };
+@@ -155,6 +162,10 @@ static int mtk_usxgmii_pcs_config(struct
+       mtk_usxgmii_reset(mpcs);
++      /* Configure the interface polarity */
++      mtk_m32(mpcs, RG_PHY_TOP_CTRL0,
++              USXGMII_PN_SWAP_MASK, mpcs->polarity);
++
+       /* Setup USXGMII AN ctrl */
+       mtk_m32(mpcs, RG_PCS_AN_CTRL0,
+               USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
+@@ -332,6 +343,7 @@ static const struct phylink_pcs_ops mtk_
+ static int mtk_usxgmii_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
++      struct device_node *np = dev->of_node;
+       struct mtk_usxgmii_pcs *mpcs;
+       mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL);
+@@ -342,6 +354,13 @@ static int mtk_usxgmii_probe(struct plat
+       if (IS_ERR(mpcs->base))
+               return PTR_ERR(mpcs->base);
++      if (of_property_read_bool(np->parent, "mediatek,pnswap"))
++              mpcs->polarity = USXGMII_PN_SWAP_TX | USXGMII_PN_SWAP_RX;
++      else if (of_property_read_bool(np, "mediatek,pnswap-tx"))
++              mpcs->polarity = USXGMII_PN_SWAP_TX;
++      else if (of_property_read_bool(np, "mediatek,pnswap-rx"))
++              mpcs->polarity = USXGMII_PN_SWAP_RX;
++
+       mpcs->dev = dev;
+       mpcs->pcs.ops = &mtk_usxgmii_pcs_ops;
+       mpcs->pcs.poll = true;
diff --git a/target/linux/mediatek/patches-6.12/737-net-dsa-add-Airoha-AN8855.patch b/target/linux/mediatek/patches-6.12/737-net-dsa-add-Airoha-AN8855.patch
new file mode 100644 (file)
index 0000000..1885405
--- /dev/null
@@ -0,0 +1,309 @@
+From: Christian Marangi <ansuelsmth@gmail.com>
+To: Christian Marangi <ansuelsmth@gmail.com>,
+       Lee Jones <lee@kernel.org>, Rob Herring <robh@kernel.org>,
+       Krzysztof Kozlowski <krzk+dt@kernel.org>,
+       Conor Dooley <conor+dt@kernel.org>,
+       Andrew Lunn <andrew+netdev@lunn.ch>,
+       "David S. Miller" <davem@davemloft.net>,
+       Eric Dumazet <edumazet@google.com>,
+       Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
+       Vladimir Oltean <olteanv@gmail.com>,
+       Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
+       Heiner Kallweit <hkallweit1@gmail.com>,
+       Russell King <linux@armlinux.org.uk>,
+       Matthias Brugger <matthias.bgg@gmail.com>,
+       AngeloGioacchino Del Regno
+       <angelogioacchino.delregno@collabora.com>,
+       linux-arm-kernel@lists.infradead.org,
+       linux-mediatek@lists.infradead.org, netdev@vger.kernel.org,
+       devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
+       upstream@airoha.com
+Subject: [net-next PATCH v11 0/9] net: dsa: Add Airoha AN8855 support
+Date: Mon,  9 Dec 2024 14:44:17 +0100  [thread overview]
+Message-ID: <20241209134459.27110-1-ansuelsmth@gmail.com> (raw)
+
+This small series add the initial support for the Airoha AN8855 Switch.
+
+It's a 5 port Gigabit Switch with SGMII/HSGMII upstream port.
+
+This is starting to get in the wild and there are already some router
+having this switch chip.
+
+It's conceptually similar to mediatek switch but register and bits
+are different. And there is that massive Hell that is the PCS
+configuration.
+Saddly for that part we have absolutely NO documentation currently.
+
+There is this special thing where PHY needs to be calibrated with values
+from the switch efuse. (the thing have a whole cpu timer and MCU)
+
+Changes v11:
+- Address reviews from Christophe (spell mistake + dev_err_probe)
+- Fix kconfig dependency for MFD driver (depends on MDIO_DEVICE instead of MDIO)
+  (indirectly fix link error for mdio APIs)
+- Fix copy-paste error for MFD driver of_table
+- Fix compilation error for PHY (move NVMEM to .config)
+- Drop unneeded NVMEM node from MDIO example schema (from Andrew)
+- Adapt MFD example schema to MDIO reg property restrictions
+Changes v10:
+- Entire rework to MFD + split to MDIO, EFUSE, SWITCH separate drivers
+- Drop EEE OPs (while Russell finish RFC for EEE changes)
+- Use new pcs_inpand OPs
+- Drop AN restart function and move to pcs_config
+- Enable assisted_learning and disable CPU learn (preparation for fdb_isolation)
+- Move EFUSE read in Internal PHY driver to .config to handle EPROBE_DEFER
+  (needed now that NVMEM driver is register externally instead of internally to switch
+   node)
+Changes v9:
+- Error out on using 5G speed as currently not supported
+- Add missing MAC_2500FD in phylink mac_capabilities
+- Add comment and improve if condition for an8855_phylink_mac_config
+Changes v8:
+- Add port Fast Age support
+- Add support for Port Isolation
+- Use correct register for Learning Disable
+- Add support for Ageing Time OP
+- Set default PVID to 0 by default
+- Add mdb OPs
+- Add port change MTU
+- Fix support for Upper VLAN
+Changes v7:
+- Fix devm_dsa_register_switch wrong export symbol
+Changes v6:
+- Drop standard MIB and handle with ethtool OPs (as requested by Jakub)
+- Cosmetic: use bool instead of 0 or 1
+Changes v5:
+- Add devm_dsa_register_switch() patch
+- Add Reviewed-by tag for DT patch
+Changes v4:
+- Set regmap readable_table static (mute compilation warning)
+- Add support for port_bridge flags (LEARNING, FLOOD)
+- Reset fdb struct in fdb_dump
+- Drop support_asym_pause in port_enable
+- Add define for get_phy_flags
+- Fix bug for port not inititially part of a bridge
+  (in an8855_setup the port matrix was always cleared but
+   the CPU port was never initially added)
+- Disable learning and flood for user port by default
+- Set CPU port to flood and learning by default
+- Correctly AND force duplex and flow control in an8855_phylink_mac_link_up
+- Drop RGMII from pcs_config
+- Check ret in "Disable AN if not in autoneg"
+- Use devm_mutex_init
+- Fix typo for AN8855_PORT_CHECK_MODE
+- Better define AN8855_STP_LISTENING = AN8855_STP_BLOCKING
+- Fix typo in AN8855_PHY_EN_DOWN_SHIFT
+- Use paged helper for PHY
+- Skip calibration in config_init if priv not defined
+Changes v3:
+- Out of RFC
+- Switch PHY code to select_page API
+- Better describe masks and bits in PHY driver for ADC register
+- Drop raw values and use define for mii read/write
+- Switch to absolute PHY address
+- Replace raw values with mask and bits for pcs_config
+- Fix typo for ext-surge property name
+- Drop support for relocating Switch base PHY address on the bus
+Changes v2:
+- Drop mutex guard patch
+- Drop guard usage in DSA driver
+- Use __mdiobus_write/read
+- Check return condition and return errors for mii read/write
+- Fix wrong logic for EEE
+- Fix link_down (don't force link down with autoneg)
+- Fix forcing speed on sgmii autoneg
+- Better document link speed for sgmii reg
+- Use standard define for sgmii reg
+- Imlement nvmem support to expose switch EFUSE
+- Rework PHY calibration with the use of NVMEM producer/consumer
+- Update DT with new NVMEM property
+- Move aneg validation for 2500-basex in pcs_config
+- Move r50Ohm table and function to PHY driver
+
+Christian Marangi (9):
+  dt-bindings: nvmem: Document support for Airoha AN8855 Switch EFUSE
+  dt-bindings: net: Document support for Airoha AN8855 Switch Virtual
+    MDIO
+  dt-bindings: net: dsa: Document support for Airoha AN8855 DSA Switch
+  dt-bindings: mfd: Document support for Airoha AN8855 Switch SoC
+  mfd: an8855: Add support for Airoha AN8855 Switch MFD
+  net: mdio: Add Airoha AN8855 Switch MDIO Passtrough
+  nvmem: an8855: Add support for Airoha AN8855 Switch EFUSE
+  net: dsa: Add Airoha AN8855 5-Port Gigabit DSA Switch driver
+  net: phy: Add Airoha AN8855 Internal Switch Gigabit PHY
+
+ .../bindings/mfd/airoha,an8855-mfd.yaml       |  178 ++
+ .../bindings/net/airoha,an8855-mdio.yaml      |   56 +
+ .../net/dsa/airoha,an8855-switch.yaml         |  105 +
+ .../bindings/nvmem/airoha,an8855-efuse.yaml   |  123 +
+ MAINTAINERS                                   |   17 +
+ drivers/mfd/Kconfig                           |   10 +
+ drivers/mfd/Makefile                          |    1 +
+ drivers/mfd/airoha-an8855.c                   |  278 ++
+ drivers/net/dsa/Kconfig                       |    9 +
+ drivers/net/dsa/Makefile                      |    1 +
+ drivers/net/dsa/an8855.c                      | 2310 +++++++++++++++++
+ drivers/net/dsa/an8855.h                      |  783 ++++++
+ drivers/net/mdio/Kconfig                      |    9 +
+ drivers/net/mdio/Makefile                     |    1 +
+ drivers/net/mdio/mdio-an8855.c                |  113 +
+ drivers/net/phy/Kconfig                       |    5 +
+ drivers/net/phy/Makefile                      |    1 +
+ drivers/net/phy/air_an8855.c                  |  267 ++
+ drivers/nvmem/Kconfig                         |   11 +
+ drivers/nvmem/Makefile                        |    2 +
+ drivers/nvmem/an8855-efuse.c                  |   63 +
+ include/linux/mfd/airoha-an8855-mfd.h         |   41 +
+ 22 files changed, 4384 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mfd/airoha,an8855-mfd.yaml
+ create mode 100644 Documentation/devicetree/bindings/net/airoha,an8855-mdio.yaml
+ create mode 100644 Documentation/devicetree/bindings/net/dsa/airoha,an8855-switch.yaml
+ create mode 100644 Documentation/devicetree/bindings/nvmem/airoha,an8855-efuse.yaml
+ create mode 100644 drivers/mfd/airoha-an8855.c
+ create mode 100644 drivers/net/dsa/an8855.c
+ create mode 100644 drivers/net/dsa/an8855.h
+ create mode 100644 drivers/net/mdio/mdio-an8855.c
+ create mode 100644 drivers/net/phy/air_an8855.c
+ create mode 100644 drivers/nvmem/an8855-efuse.c
+ create mode 100644 include/linux/mfd/airoha-an8855-mfd.h
+
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -53,6 +53,16 @@ config MFD_ALTERA_SYSMGR
+         using regmap_mmio accesses for ARM32 parts and SMC calls to
+         EL3 for ARM64 parts.
++config MFD_AIROHA_AN8855
++      tristate "Airoha AN8855 Switch MFD"
++      select MFD_CORE
++      select MDIO_DEVICE
++      depends on NETDEVICES && OF
++      help
++        Support for the Airoha AN8855 Switch MFD. This is a SoC Switch
++        that provides various peripherals. Currently it provides a
++        DSA switch and a NVMEM provider.
++
+ config MFD_ACT8945A
+       tristate "Active-semi ACT8945A"
+       select MFD_CORE
+--- a/drivers/mfd/Makefile
++++ b/drivers/mfd/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_MFD_88PM800)      += 88pm800.o 8
+ obj-$(CONFIG_MFD_88PM805)     += 88pm805.o 88pm80x.o
+ obj-$(CONFIG_MFD_88PM886_PMIC)        += 88pm886.o
+ obj-$(CONFIG_MFD_ACT8945A)    += act8945a.o
++obj-$(CONFIG_MFD_AIROHA_AN8855)       += airoha-an8855.o
+ obj-$(CONFIG_MFD_SM501)               += sm501.o
+ obj-$(CONFIG_ARCH_BCM2835)    += bcm2835-pm.o
+ obj-$(CONFIG_MFD_BCM590XX)    += bcm590xx.o
+--- a/drivers/net/dsa/Kconfig
++++ b/drivers/net/dsa/Kconfig
+@@ -24,6 +24,15 @@ config NET_DSA_LOOP
+         This enables support for a fake mock-up switch chip which
+         exercises the DSA APIs.
++config NET_DSA_AN8855
++      tristate "Airoha AN8855 Ethernet switch support"
++      depends on MFD_AIROHA_AN8855
++      depends on NET_DSA
++      select NET_DSA_TAG_MTK
++      help
++        This enables support for the Airoha AN8855 Ethernet switch
++        chip.
++
+ source "drivers/net/dsa/hirschmann/Kconfig"
+ config NET_DSA_LANTIQ_GSWIP
+--- a/drivers/net/dsa/Makefile
++++ b/drivers/net/dsa/Makefile
+@@ -6,6 +6,7 @@ ifdef CONFIG_NET_DSA_LOOP
+ obj-$(CONFIG_FIXED_PHY)               += dsa_loop_bdinfo.o
+ endif
+ obj-$(CONFIG_NET_DSA_KS8995)  += ks8995.o
++obj-$(CONFIG_NET_DSA_AN8855)  += an8855.o
+ obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
+ obj-$(CONFIG_NET_DSA_MT7530)  += mt7530.o
+ obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
+--- a/drivers/net/mdio/Kconfig
++++ b/drivers/net/mdio/Kconfig
+@@ -61,6 +61,15 @@ config MDIO_XGENE
+         This module provides a driver for the MDIO busses found in the
+         APM X-Gene SoC's.
++config MDIO_AN8855
++      tristate "Airoha AN8855 Switch MDIO bus controller"
++      depends on MFD_AIROHA_AN8855
++      depends on OF_MDIO
++      help
++        This module provides a driver for the Airoha AN8855 Switch
++        that requires a MDIO passtrough as switch address is shared
++        with the internal PHYs and requires additional page handling.
++
+ config MDIO_ASPEED
+       tristate "ASPEED MDIO bus controller"
+       depends on ARCH_ASPEED || COMPILE_TEST
+--- a/drivers/net/mdio/Makefile
++++ b/drivers/net/mdio/Makefile
+@@ -5,6 +5,7 @@ obj-$(CONFIG_ACPI_MDIO)                += acpi_mdio.o
+ obj-$(CONFIG_FWNODE_MDIO)     += fwnode_mdio.o
+ obj-$(CONFIG_OF_MDIO)         += of_mdio.o
++obj-$(CONFIG_MDIO_AN8855)             += mdio-an8855.o
+ obj-$(CONFIG_MDIO_ASPEED)             += mdio-aspeed.o
+ obj-$(CONFIG_MDIO_BCM_IPROC)          += mdio-bcm-iproc.o
+ obj-$(CONFIG_MDIO_BCM_UNIMAC)         += mdio-bcm-unimac.o
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -170,6 +170,11 @@ config AIROHA_EN8801SC_PHY
+       help
+         Currently supports the Airoha EN8801SC PHY.
++config AIR_AN8855_PHY
++      tristate "Airoha AN8855 Internal Gigabit PHY"
++      help
++        Currently supports the internal Airoha AN8855 Switch PHY.
++
+ config AIR_EN8811H_PHY
+       tristate "Airoha EN8811H 2.5 Gigabit PHY"
+       help
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -51,6 +51,7 @@ obj-y                                += $(sfp-obj-y) $(sfp-obj-m)
+ obj-$(CONFIG_ADIN_PHY)                += adin.o
+ obj-$(CONFIG_ADIN1100_PHY)    += adin1100.o
+ obj-$(CONFIG_AIROHA_EN8801SC_PHY)   += en8801sc.o
++obj-$(CONFIG_AIR_AN8855_PHY)          += air_an8855.o
+ obj-$(CONFIG_AIR_EN8811H_PHY)   += air_en8811h.o
+ obj-$(CONFIG_AMD_PHY)         += amd.o
+ obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -29,6 +29,17 @@ source "drivers/nvmem/layouts/Kconfig"
+ # Devices
++config NVMEM_AN8855_EFUSE
++      tristate "Airoha AN8855 eFuse support"
++      depends on MFD_AIROHA_AN8855 || COMPILE_TEST
++      help
++        Say y here to enable support for reading eFuses on Airoha AN8855
++        Switch. These are e.g. used to store factory programmed
++        calibration data required for the PHY.
++
++        This driver can also be built as a module. If so, the module will
++        be called nvmem-an8855-efuse.
++
+ config NVMEM_APPLE_EFUSES
+       tristate "Apple eFuse support"
+       depends on ARCH_APPLE || COMPILE_TEST
+--- a/drivers/nvmem/Makefile
++++ b/drivers/nvmem/Makefile
+@@ -10,6 +10,8 @@ nvmem_layouts-y                      := layouts.o
+ obj-y                         += layouts/
+ # Devices
++obj-$(CONFIG_NVMEM_AN8855_EFUSE)      += nvmem-an8855-efuse.o
++nvmem-an8855-efuse-y                  := an8855-efuse.o
+ obj-$(CONFIG_NVMEM_APPLE_EFUSES)      += nvmem-apple-efuses.o
+ nvmem-apple-efuses-y                  := apple-efuses.o
+ obj-$(CONFIG_NVMEM_BCM_OCOTP)         += nvmem-bcm-ocotp.o
diff --git a/target/linux/mediatek/patches-6.12/740-net-pcs-mtk_lynxi-add-mt7987-support.patch b/target/linux/mediatek/patches-6.12/740-net-pcs-mtk_lynxi-add-mt7987-support.patch
new file mode 100644 (file)
index 0000000..d4d09b6
--- /dev/null
@@ -0,0 +1,36 @@
+From 6e9ec5ade644eeb136c6b827d72fac80bf2c3817 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Fri, 9 May 2025 13:22:14 +0800
+Subject: [PATCH] net: pcs: mtk_lynxi add mt7987 support
+
+Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+---
+ drivers/net/pcs/pcs-mtk-lynxi.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/pcs/pcs-mtk-lynxi.c
++++ b/drivers/net/pcs/pcs-mtk-lynxi.c
+@@ -413,9 +413,12 @@ static int mtk_pcs_lynxi_probe(struct pl
+       if (of_property_read_bool(np->parent, "mediatek,pnswap"))
+               flags |= MTK_SGMII_FLAG_PN_SWAP;
+-      mpcs->rstc = of_reset_control_get_shared(np->parent, NULL);
+-      if (IS_ERR(mpcs->rstc))
+-              return PTR_ERR(mpcs->rstc);
++      if (of_parse_phandle(np->parent, "resets", 0)) {
++              mpcs->rstc = of_reset_control_get_shared(np->parent, NULL);
++              if (IS_ERR(mpcs->rstc))
++                      return PTR_ERR(mpcs->rstc);
++      } else
++              mpcs->rstc = NULL;
+       reset_control_deassert(mpcs->rstc);
+       mpcs->sgmii_sel = devm_clk_get_enabled(dev, "sgmii_sel");
+@@ -462,6 +465,7 @@ static void mtk_pcs_lynxi_remove(struct
+ }
+ static const struct of_device_id mtk_pcs_lynxi_of_match[] = {
++      { .compatible = "mediatek,mt7987-sgmii", .data = (void *)MTK_NETSYS_V3_AMA_RGC3 },
+       { .compatible = "mediatek,mt7988-sgmii", .data = (void *)MTK_NETSYS_V3_AMA_RGC3 },
+       { /* sentinel */ },
+ };
diff --git a/target/linux/mediatek/patches-6.12/741-net-pcs-mtk-lynxi-add-phya-tx-rx-clock-path.patch b/target/linux/mediatek/patches-6.12/741-net-pcs-mtk-lynxi-add-phya-tx-rx-clock-path.patch
new file mode 100644 (file)
index 0000000..eef6e36
--- /dev/null
@@ -0,0 +1,89 @@
+From be193994deca7cc3ca6ddedc6efd06182b032f21 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Tue, 6 May 2025 12:53:37 +0800
+Subject: [PATCH] net: pcs: mtk-lynxi: add phya tx rx clock path
+
+In NETSYSv3.1, the SGMII hardware introduces a new clock path from PHYA.
+Consequently, users can switch the SGMII PCS to this new clock source
+for better performance on the MT7987.
+
+Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+---
+--- a/drivers/net/pcs/pcs-mtk-lynxi.c
++++ b/drivers/net/pcs/pcs-mtk-lynxi.c
+@@ -25,6 +25,7 @@
+ #define SGMSYS_PCS_CONTROL_1          0x0
+ #define SGMII_BMCR                    GENMASK(15, 0)
+ #define SGMII_BMSR                    GENMASK(31, 16)
++#define SGMII_REF_CK_SEL              BIT(24)
+ #define SGMSYS_PCS_DEVICE_ID          0x4
+ #define SGMII_LYNXI_DEV_ID            0x4d544950
+@@ -52,6 +53,8 @@
+ #define SGMII_SPEED_1000              FIELD_PREP(SGMII_SPEED_MASK, 2)
+ #define SGMII_DUPLEX_HALF             BIT(4)
+ #define SGMII_REMOTE_FAULT_DIS                BIT(8)
++#define SGMII_TRXBUF_THR_MASK         GENMASK(31, 16)
++#define SGMII_TRXBUF_THR(x)           FIELD_PREP(SGMII_TRXBUF_THR_MASK, (x))
+ /* Register to reset SGMII design */
+ #define SGMSYS_RESERVED_0             0x34
+@@ -166,7 +169,7 @@ static int mtk_pcs_lynxi_config(struct p
+ {
+       struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+       bool mode_changed = false, changed;
+-      unsigned int rgc3, sgm_mode, bmcr = 0;
++      unsigned int rgc3, sgm_mode, bmcr = 0, trxbuf_thr = 0x3112;
+       int advertise, link_timer;
+       advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
+@@ -193,6 +196,12 @@ static int mtk_pcs_lynxi_config(struct p
+                       bmcr = BMCR_ANENABLE;
+       }
++      /* Configure SGMII PCS clock source */
++      if (mpcs->flags & MTK_SGMII_FLAG_PHYA_TRX_CK) {
++              bmcr |= SGMII_REF_CK_SEL;
++              trxbuf_thr = 0x2111;
++      }
++
+       if (mpcs->interface != interface) {
+               link_timer = phylink_get_link_timer_ns(interface);
+               if (link_timer < 0)
+@@ -235,12 +244,14 @@ static int mtk_pcs_lynxi_config(struct p
+       /* Update the sgmsys mode register */
+       regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
++                         SGMII_TRXBUF_THR_MASK |
+                          SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
+-                         SGMII_IF_MODE_SGMII, sgm_mode);
++                         SGMII_IF_MODE_SGMII,
++                         SGMII_TRXBUF_THR(trxbuf_thr) | sgm_mode);
+       /* Update the BMCR */
+       regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
+-                         BMCR_ANENABLE, bmcr);
++                         SGMII_REF_CK_SEL | BMCR_ANENABLE, bmcr);
+       /* Release PHYA power down state
+        * Only removing bit SGMII_PHYA_PWD isn't enough.
+@@ -413,6 +424,9 @@ static int mtk_pcs_lynxi_probe(struct pl
+       if (of_property_read_bool(np->parent, "mediatek,pnswap"))
+               flags |= MTK_SGMII_FLAG_PN_SWAP;
++      if (of_property_read_bool(np->parent, "mediatek,phya_trx_ck"))
++              flags |= MTK_SGMII_FLAG_PHYA_TRX_CK;
++
+       if (of_parse_phandle(np->parent, "resets", 0)) {
+               mpcs->rstc = of_reset_control_get_shared(np->parent, NULL);
+               if (IS_ERR(mpcs->rstc))
+--- a/include/linux/pcs/pcs-mtk-lynxi.h
++++ b/include/linux/pcs/pcs-mtk-lynxi.h
+@@ -6,6 +6,7 @@
+ #include <linux/regmap.h>
+ #define MTK_SGMII_FLAG_PN_SWAP BIT(0)
++#define MTK_SGMII_FLAG_PHYA_TRX_CK BIT(2)
+ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
+                                        struct regmap *regmap,
+                                        u32 ana_rgc3, u32 flags);
diff --git a/target/linux/mediatek/patches-6.12/750-net-ethernet-mtk_eth_soc-add-mt7987-support.patch b/target/linux/mediatek/patches-6.12/750-net-ethernet-mtk_eth_soc-add-mt7987-support.patch
new file mode 100644 (file)
index 0000000..d274255
--- /dev/null
@@ -0,0 +1,325 @@
+From 56973433cbea9f91f5f7eddebbc361ffc2bd6156 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Mon, 26 May 2025 13:20:42 +0800
+Subject: [PATCH] net: ethernet: mtk_eth_soc: add mt7987 support
+
+Without this patch, users are unable to bring up ETH driver on the
+mt7987.
+
+Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_path.c |   9 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 138 ++++++++++++++++---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h  |  70 ++++++++--
+ 3 files changed, 179 insertions(+), 38 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
+@@ -106,13 +106,14 @@ static int set_mux_gmac2_gmac0_to_gephy(
+       return 0;
+ }
+-static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
++static int set_mux_u3_gmac23_to_qphy(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0, mask = 0, reg = 0;
+       bool updated = true;
+       switch (path) {
+       case MTK_ETH_PATH_GMAC2_SGMII:
++      case MTK_ETH_PATH_GMAC3_SGMII:
+               if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) {
+                       reg = USB_PHY_SWITCH_REG;
+                       val = SGMII_QPHY_SEL;
+@@ -281,9 +282,9 @@ static const struct mtk_eth_muxc mtk_eth
+               .cap_bit = MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY,
+               .set_path = set_mux_gmac2_gmac0_to_gephy,
+       }, {
+-              .name = "mux_u3_gmac2_to_qphy",
+-              .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
+-              .set_path = set_mux_u3_gmac2_to_qphy,
++              .name = "mux_u3_gmac23_to_qphy",
++              .cap_bit = MTK_ETH_MUX_U3_GMAC23_TO_QPHY,
++              .set_path = set_mux_u3_gmac23_to_qphy,
+       }, {
+               .name = "mux_gmac2_to_2p5gphy",
+               .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -817,10 +817,16 @@ static void mtk_set_queue_speed(struct m
+               return;
+       val = MTK_QTX_SCH_MIN_RATE_EN |
+-            /* minimum: 10 Mbps */
+-            FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
+-            FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
+             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
++      /* minimum: 10 Mbps */
++      if (mtk_is_netsys_v3_or_greater(eth) &&
++          (eth->soc->caps != MT7988_CAPS)) {
++              val |= FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN_V3, 1) |
++                     FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP_V3, 4);
++      } else {
++              val |= FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
++                     FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4);
++      }
+       if (mtk_is_netsys_v1(eth))
+               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
+@@ -847,6 +853,30 @@ static void mtk_set_queue_speed(struct m
+               default:
+                       break;
+               }
++      } else if (mtk_is_netsys_v3_or_greater(eth) &&
++                 (eth->soc->caps != MT7988_CAPS)) {
++              switch (speed) {
++              case SPEED_10:
++                      val |= MTK_QTX_SCH_MAX_RATE_EN_V3 |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN_V3, 1) |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP_V3, 4) |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT_V3, 1);
++                      break;
++              case SPEED_100:
++                      val |= MTK_QTX_SCH_MAX_RATE_EN_V3 |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN_V3, 1) |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP_V3, 5) |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT_V3, 1);
++                      break;
++              case SPEED_1000:
++                      val |= MTK_QTX_SCH_MAX_RATE_EN_V3 |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN_V3, 1) |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP_V3, 6) |
++                             FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT_V3, 10);
++                      break;
++              default:
++                      break;
++              }
+       } else {
+               switch (speed) {
+               case SPEED_10:
+@@ -935,7 +965,7 @@ static void mtk_xgdm_mac_link_up(struct
+               return;
+       /* Eliminate the interference(before link-up) caused by PHY noise */
+-      mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
++      mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->hw, mac->id));
+       mdelay(20);
+       mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
+@@ -2908,10 +2938,16 @@ static int mtk_tx_alloc(struct mtk_eth *
+                       mtk_w32(eth, val, soc->reg_map->qdma.qtx_cfg + ofs);
+                       val = MTK_QTX_SCH_MIN_RATE_EN |
+-                            /* minimum: 10 Mbps */
+-                            FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
+-                            FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
+                             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
++                      /* minimum: 10 Mbps */
++                      if (mtk_is_netsys_v3_or_greater(eth) &&
++                          (eth->soc->caps != MT7988_CAPS)) {
++                              val |= FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN_V3, 1) |
++                                     FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP_V3, 4);
++                      } else {
++                              val |= FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
++                                     FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4);
++                      }
+                       if (mtk_is_netsys_v1(eth))
+                               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
+                       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
+@@ -5892,6 +5928,36 @@ static const struct mtk_soc_data mt7986_
+       },
+ };
++static const struct mtk_soc_data mt7987_data = {
++      .reg_map = &mt7988_reg_map,
++      .ana_rgc3 = 0x128,
++      .caps = MT7987_CAPS,
++      .hw_features = MTK_HW_FEATURES,
++      .required_clks = MT7987_CLKS_BITMAP,
++      .required_pctl = false,
++      .version = 3,
++      .offload_version = 2,
++      .ppe_num = 2,
++      .hash_offset = 4,
++      .has_accounting = true,
++      .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
++      .tx = {
++              DESC_SIZE(struct mtk_tx_dma_v2),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
++              .dma_len_offset = 8,
++              .dma_size = MTK_DMA_SIZE(2K),
++              .fq_dma_size = MTK_DMA_SIZE(4K),
++      },
++      .rx = {
++              DESC_SIZE(struct mtk_rx_dma_v2),
++              .irq_done_mask = MTK_RX_DONE_INT_V2,
++              .dma_l4_valid = RX_DMA_L4_VALID_V2,
++              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
++              .dma_len_offset = 8,
++              .dma_size = MTK_DMA_SIZE(2K),
++      },
++};
++
+ static const struct mtk_soc_data mt7988_data = {
+       .reg_map = &mt7988_reg_map,
+       .ana_rgc3 = 0x128,
+@@ -5953,6 +6019,7 @@ const struct of_device_id of_mtk_match[]
+       { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
+       { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
+       { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
++      { .compatible = "mediatek,mt7987-eth", .data = &mt7987_data },
+       { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
+       { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
+       {},
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -262,6 +262,13 @@
+ #define MTK_QTX_SCH_MAX_RATE_MAN      GENMASK(10, 4)
+ #define MTK_QTX_SCH_MAX_RATE_EXP      GENMASK(3, 0)
++#define MTK_QTX_SCH_MAX_RATE_EN_V3    BIT(26)
++#define MTK_QTX_SCH_MIN_RATE_MAN_V3   GENMASK(25, 19)
++#define MTK_QTX_SCH_MIN_RATE_EXP_V3   GENMASK(18, 16)
++#define MTK_QTX_SCH_MAX_RATE_WEIGHT_V3        GENMASK(15, 10)
++#define MTK_QTX_SCH_MAX_RATE_MAN_V3   GENMASK(9, 3)
++#define MTK_QTX_SCH_MAX_RATE_EXP_V3   GENMASK(2, 0)
++
+ /* QDMA TX Scheduler Rate Control Register */
+ #define MTK_QDMA_TX_SCH_MAX_WFQ               BIT(15)
+@@ -536,9 +543,23 @@
+ #define XMAC_MCR_FORCE_RX_FC  BIT(4)
+ /* XFI Mac logic reset registers */
+-#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10)
++#define MTK_XMAC_LOGIC_RST(eth, x)    (MTK_XMAC_BASE(x) +                             \
++                                      (MTK_HAS_CAPS((eth)->soc->caps, MTK_XGMAC_V2) ? \
++                                      0x820 : 0x10))
+ #define XMAC_LOGIC_RST                BIT(0)
++/* XFI Mac status force registers */
++#define MTK_XMAC_STS(x)               (MTK_XMAC_MCR(x) + 0x14)
++
++/* XFI Mac status force registers */
++#define MTK_XMAC_STS_FRC(x)   (MTK_XMAC_MCR(x) + 0x18)
++#define XMAC_FORCE_RX_FC_MODE BIT(13)
++#define XMAC_FORCE_TX_FC_MODE BIT(12)
++#define XMAC_FORCE_LINK_MODE  BIT(8)
++#define XMAC_FORCE_RX_FC      BIT(5)
++#define XMAC_FORCE_TX_FC      BIT(4)
++#define XMAC_FORCE_LINK               BIT(0)
++
+ /* XFI Mac count global control */
+ #define MTK_XMAC_CNT_CTRL(x)  (MTK_XMAC_BASE(x) + 0x100)
+ #define XMAC_GLB_CNTCLR               BIT(0)
+@@ -834,6 +855,17 @@ enum mtk_clks_map {
+                                BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+                                BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+                                BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
++#define MT7987_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) |  BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP3) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL))
+ #define MT7988_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
+                                BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
+                                BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
+@@ -990,12 +1022,14 @@ enum mkt_eth_capabilities {
+       MTK_RSTCTRL_PPE2_BIT,
+       MTK_U3_COPHY_V2_BIT,
+       MTK_SRAM_BIT,
++      MTK_XGMAC_BIT,
++      MTK_XGMAC_V2_BIT,
+       MTK_36BIT_DMA_BIT,
+       /* MUX BITS*/
+       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
+       MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
+-      MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
++      MTK_ETH_MUX_U3_GMAC23_TO_QPHY_BIT,
+       MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
+       MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
+       MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
+@@ -1037,14 +1071,16 @@ enum mkt_eth_capabilities {
+ #define MTK_RSTCTRL_PPE2      BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+ #define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
+ #define MTK_SRAM              BIT_ULL(MTK_SRAM_BIT)
++#define MTK_XGMAC             BIT_ULL(MTK_XGMAC_BIT)
++#define MTK_XGMAC_V2          BIT_ULL(MTK_XGMAC_V2_BIT)
+ #define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+       BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
+ #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY      \
+       BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
+-#define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
+-      BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
++#define MTK_ETH_MUX_U3_GMAC23_TO_QPHY         \
++      BIT_ULL(MTK_ETH_MUX_U3_GMAC23_TO_QPHY_BIT)
+ #define MTK_ETH_MUX_GMAC2_TO_2P5GPHY          \
+       BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
+ #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
+@@ -1076,12 +1112,13 @@ enum mkt_eth_capabilities {
+ #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
+ #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
+ #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
+-#define MTK_GMAC2_2P5GPHY     (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
++#define MTK_GMAC2_2P5GPHY     (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY | MTK_XGMAC)
++#define MTK_GMAC2_2P5GPHY_V2  (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY | MTK_XGMAC_V2)
+ #define MTK_GMAC3_SGMII               (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
+ #define MTK_GDM1_ESW          (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
+-#define MTK_GMAC1_USXGMII     (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
+-#define MTK_GMAC2_USXGMII     (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
+-#define MTK_GMAC3_USXGMII     (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
++#define MTK_GMAC1_USXGMII     (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII | MTK_XGMAC)
++#define MTK_GMAC2_USXGMII     (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII | MTK_XGMAC)
++#define MTK_GMAC3_USXGMII     (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII | MTK_XGMAC)
+ /* MUXes present on SoCs */
+ /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
+@@ -1091,9 +1128,9 @@ enum mkt_eth_capabilities {
+ #define MTK_MUX_GMAC2_GMAC0_TO_GEPHY    \
+       (MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_MUX | MTK_INFRA)
+-/* 0: U3 -> QPHY, 1: GMAC2 -> QPHY */
+-#define MTK_MUX_U3_GMAC2_TO_QPHY        \
+-      (MTK_ETH_MUX_U3_GMAC2_TO_QPHY | MTK_MUX | MTK_INFRA)
++/* 0: U3 -> QPHY, 1: GMACx -> QPHY where x is 2 or 3 */
++#define MTK_MUX_U3_GMAC23_TO_QPHY        \
++      (MTK_ETH_MUX_U3_GMAC23_TO_QPHY | MTK_MUX | MTK_INFRA)
+ /* 2: GMAC1 -> SGMII, 3: GMAC2 -> SGMII */
+ #define MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII      \
+@@ -1133,18 +1170,24 @@ enum mkt_eth_capabilities {
+ #define MT7629_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
+                     MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \
+                     MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \
+-                    MTK_MUX_U3_GMAC2_TO_QPHY | \
++                    MTK_MUX_U3_GMAC23_TO_QPHY | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
+ #define MT7981_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+-                    MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
++                    MTK_MUX_U3_GMAC23_TO_QPHY | MTK_U3_COPHY_V2 | \
+                     MTK_RSTCTRL_PPE1 | MTK_SRAM)
+ #define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1 | MTK_SRAM)
++#define MT7987_CAPS  (MTK_36BIT_DMA | MTK_GMAC1_SGMII | \
++                    MTK_GMAC2_2P5GPHY_V2 | MTK_GMAC2_SGMII | MTK_GMAC3_SGMII | \
++                    MTK_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \
++                    MTK_MUX_U3_GMAC23_TO_QPHY | MTK_U3_COPHY_V2 | \
++                    MTK_QDMA | MTK_RSTCTRL_PPE1)
++
+ #define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \
+                     MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \
+                     MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \
diff --git a/target/linux/mediatek/patches-6.12/751-net-ethernet-mtk_eth_soc-revise-hardware-configuration-for-mt7987.patch b/target/linux/mediatek/patches-6.12/751-net-ethernet-mtk_eth_soc-revise-hardware-configuration-for-mt7987.patch
new file mode 100644 (file)
index 0000000..cef30ef
--- /dev/null
@@ -0,0 +1,79 @@
+From 5ef0b04d30efff8f171e30bfbe876c00e3b9036a Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Fri, 9 May 2025 09:49:04 +0800
+Subject: [PATCH] net: ethernet: mtk_eth_soc: revise hardware configuration for
+ mt7987
+
+Change hardware configuration for the MT7987.
+ - Enable PSE drop mechanism when the WDMA Rx ring full
+ - Enable PSE no-drop mechanism for packets from the WDMA Tx
+
+Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 +++++++++++++--------
+ 1 file changed, 31 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4461,27 +4461,40 @@ static int mtk_hw_init(struct mtk_eth *e
+               mtk_w32(eth, PSE_DUMMY_WORK_GDM(1) | PSE_DUMMY_WORK_GDM(2) |
+                       PSE_DUMMY_WORK_GDM(3) | DUMMY_PAGE_THR, PSE_DUMY_REQ);
+-              /* PSE free buffer drop threshold */
+-              mtk_w32(eth, 0x00600009, PSE_IQ_REV(8));
+-
+-              /* PSE should not drop port8, port9 and port13 packets from
+-               * WDMA Tx
+-               */
+-              mtk_w32(eth, 0x00002300, PSE_DROP_CFG);
+-
+-              /* PSE should drop packets to port8, port9 and port13 on WDMA Rx
+-               * ring full
+-               */
+-              mtk_w32(eth, 0x00002300, PSE_PPE_DROP(0));
+-              mtk_w32(eth, 0x00002300, PSE_PPE_DROP(1));
+-              mtk_w32(eth, 0x00002300, PSE_PPE_DROP(2));
+-
+-              /* GDM and CDM Threshold */
+-              mtk_w32(eth, 0x08000707, MTK_CDMW0_THRES);
+-              mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
+-
+-              /* Disable GDM1 RX CRC stripping */
+-              mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0));
++              if (eth->soc->caps == MT7988_CAPS) {
++                      /* PSE free buffer drop threshold */
++                      mtk_w32(eth, 0x00600009, PSE_IQ_REV(8));
++
++                      /* PSE should not drop port8, port9 and port13 packets
++                       * from WDMA Tx
++                       */
++                      mtk_w32(eth, 0x00002300, PSE_DROP_CFG);
++
++                      /* PSE should drop packets to port8, port9 and port13
++                       * on WDMA Rx ring full
++                       */
++                      mtk_w32(eth, 0x00002300, PSE_PPE_DROP(0));
++                      mtk_w32(eth, 0x00002300, PSE_PPE_DROP(1));
++                      mtk_w32(eth, 0x00002300, PSE_PPE_DROP(2));
++
++                      /* GDM and CDM Threshold */
++                      mtk_w32(eth, 0x08000707, MTK_CDMW0_THRES);
++                      mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
++              } else if (eth->soc->caps == MT7987_CAPS) {
++                      /* PSE should not drop port8 packets from WDMA Tx */
++                      mtk_w32(eth, 0x00000100, PSE_DROP_CFG);
++
++                      /* PSE should drop packets to port8 on WDMA Rx ring
++                       * full
++                       */
++                      mtk_w32(eth, 0x00000100, PSE_PPE_DROP(0));
++                      mtk_w32(eth, 0x00000100, PSE_PPE_DROP(1));
++              }
++
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_ESW)) {
++                      /* Disable GDM1 RX CRC stripping */
++                      mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0));
++              }
+               /* PSE GDM3 MIB counter has incorrect hw default values,
+                * so the driver ought to read clear the values beforehand
diff --git a/target/linux/mediatek/patches-6.12/752-net-phy-mediatek-i2p5g-add-support-for-mt7987.patch b/target/linux/mediatek/patches-6.12/752-net-phy-mediatek-i2p5g-add-support-for-mt7987.patch
new file mode 100644 (file)
index 0000000..54a5ae3
--- /dev/null
@@ -0,0 +1,419 @@
+From d62fc50ff42223df2bd82c1ea0f1786ea26d3f08 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 5 Oct 2025 03:39:52 +0100
+Subject: [PATCH] net: phy: mediatek: add 2.5G PHY support for MT7987
+
+Add MT7987 PHY ID, firmware file paths (PMB and DSPBitTb blobs), and the
+necessary PMD/XBZ register definitions. Extend the driver probe path to
+load and initialise the MT7987-specific firmware and configure the
+internal 2.5G PHY hardware.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/drivers/net/phy/mediatek/mtk-2p5ge.c
++++ b/drivers/net/phy/mediatek/mtk-2p5ge.c
+@@ -12,13 +12,77 @@
+ #include "mtk.h"
++#define MTK_2P5GPHY_ID_MT7987 (0x00339c91)
+ #define MTK_2P5GPHY_ID_MT7988 (0x00339c11)
++#define MT7987_2P5GE_PMB_FW           "mediatek/mt7987/i2p5ge-phy-pmb.bin"
++#define MT7987_2P5GE_PMB_FW_SIZE      (0x18000)
++#define MT7987_2P5GE_DSPBITTB \
++      "mediatek/mt7987/i2p5ge-phy-DSPBitTb.bin"
++#define MT7987_2P5GE_DSPBITTB_SIZE    (0x7000)
++
+ #define MT7988_2P5GE_PMB_FW           "mediatek/mt7988/i2p5ge-phy-pmb.bin"
+ #define MT7988_2P5GE_PMB_FW_SIZE      (0x20000)
++
++#define MTK_2P5GPHY_PMD_REG_BASE      (0x0f010000)
++#define MTK_2P5GPHY_PMD_REG_LEN               (0x210)
++#define DO_NOT_RESET                  (0x28)
++#define   DO_NOT_RESET_XBZ            BIT(0)
++#define   DO_NOT_RESET_PMA            BIT(3)
++#define   DO_NOT_RESET_RX             BIT(5)
++#define FNPLL_PWR_CTRL1                       (0x208)
++#define   RG_SPEED_MASK                       GENMASK(3, 0)
++#define   RG_SPEED_2500                       BIT(3)
++#define   RG_SPEED_100                        BIT(0)
++#define FNPLL_PWR_CTRL_STATUS         (0x20c)
++#define   RG_STABLE_MASK              GENMASK(3, 0)
++#define   RG_SPEED_2500_STABLE                BIT(3)
++#define   RG_SPEED_100_STABLE         BIT(0)
++
++#define MTK_2P5GPHY_XBZ_PCS_REG_BASE  (0x0f030000)
++#define MTK_2P5GPHY_XBZ_PCS_REG_LEN   (0x844)
++#define PHY_CTRL_CONFIG                       (0x200)
++#define PMU_WP                                (0x800)
++#define   WRITE_PROTECT_KEY           (0xCAFEF00D)
++#define PMU_PMA_AUTO_CFG              (0x820)
++#define   POWER_ON_AUTO_MODE          BIT(16)
++#define   PMU_AUTO_MODE_EN            BIT(0)
++#define PMU_PMA_STATUS                        (0x840)
++#define   CLK_IS_DISABLED             BIT(3)
++
++#define MTK_2P5GPHY_XBZ_PMA_RX_BASE   (0x0f080000)
++#define MTK_2P5GPHY_XBZ_PMA_RX_LEN    (0x5228)
++#define SMEM_WDAT0                    (0x5000)
++#define SMEM_WDAT1                    (0x5004)
++#define SMEM_WDAT2                    (0x5008)
++#define SMEM_WDAT3                    (0x500c)
++#define SMEM_CTRL                     (0x5024)
++#define   SMEM_HW_RDATA_ZERO          BIT(24)
++#define SMEM_ADDR_REF_ADDR            (0x502c)
++#define CM_CTRL_P01                   (0x5100)
++#define CM_CTRL_P23                   (0x5124)
++#define DM_CTRL_P01                   (0x5200)
++#define DM_CTRL_P23                   (0x5224)
++
++#define MTK_2P5GPHY_CHIP_SCU_BASE     (0x0f0cf800)
++#define MTK_2P5GPHY_CHIP_SCU_LEN      (0x12c)
++#define SYS_SW_RESET                  (0x128)
++#define   RESET_RST_CNT                       BIT(0)
++
++#define MTK_2P5GPHY_MCU_CSR_BASE      (0x0f0f0000)
++#define MTK_2P5GPHY_MCU_CSR_LEN               (0x20)
+ #define MD32_EN_CFG                   (0x18)
+ #define   MD32_EN                     BIT(0)
++#define MTK_2P5GPHY_PMB_FW_BASE               (0x0f100000)
++//#define MTK_2P5GPHY_PMB_FW_LEN              MT7988_2P5GE_PMB_FW_SIZE
++
++#define MTK_2P5GPHY_APB_BASE          (0x11c30000)
++#define MTK_2P5GPHY_APB_LEN           (0x9c)
++#define SW_RESET                      (0x94)
++#define   MD32_RESTART_EN_CLEAR               BIT(9)
++
++
+ #define BASE100T_STATUS_EXTEND                (0x10)
+ #define BASE1000T_STATUS_EXTEND               (0x11)
+ #define EXTEND_CTRL_AND_STATUS                (0x16)
+@@ -31,6 +95,14 @@
+ #define MTK_PHY_LPI_PCS_DSP_CTRL              (0x121)
+ #define   MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK        GENMASK(12, 8)
++#define MTK_PHY_LINK_STATUS_RELATED           (0x147)
++#define   MTK_PHY_BYPASS_LINK_STATUS_OK               BIT(4)
++#define   MTK_PHY_FORCE_LINK_STATUS_HCD               BIT(3)
++
++#define MTK_PHY_AN_FORCE_SPEED_REG            (0x313)
++#define   MTK_PHY_MASTER_FORCE_SPEED_SEL_EN   BIT(7)
++#define   MTK_PHY_MASTER_FORCE_SPEED_SEL_MASK GENMASK(6, 0)
++
+ #define MTK_PHY_HOST_CMD1             0x800e
+ #define MTK_PHY_HOST_CMD2             0x800f
+ /* Registers on Token Ring debug nodes */
+@@ -48,7 +120,249 @@ enum {
+       PHY_AUX_SPD_2500,
+ };
+-static int mt798x_2p5ge_phy_load_fw(struct phy_device *phydev)
++static int mt7987_2p5ge_phy_load_fw(struct phy_device *phydev)
++{
++      struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++      struct device *dev = &phydev->mdio.dev;
++      void __iomem *xbz_pcs_reg_base;
++      void __iomem *xbz_pma_rx_base;
++      void __iomem *chip_scu_base;
++      void __iomem *pmd_reg_base;
++      void __iomem *mcu_csr_base;
++      const struct firmware *fw;
++      void __iomem *apb_base;
++      void __iomem *pmb_addr;
++      int ret, i;
++      u32 reg;
++
++      if (priv->fw_loaded)
++              return 0;
++
++      apb_base = ioremap(MTK_2P5GPHY_APB_BASE,
++                         MTK_2P5GPHY_APB_LEN);
++      if (!apb_base)
++              return -ENOMEM;
++
++      pmd_reg_base = ioremap(MTK_2P5GPHY_PMD_REG_BASE,
++                             MTK_2P5GPHY_PMD_REG_LEN);
++      if (!pmd_reg_base) {
++              ret = -ENOMEM;
++              goto free_apb;
++      }
++
++      xbz_pcs_reg_base = ioremap(MTK_2P5GPHY_XBZ_PCS_REG_BASE,
++                                 MTK_2P5GPHY_XBZ_PCS_REG_LEN);
++      if (!xbz_pcs_reg_base) {
++              ret = -ENOMEM;
++              goto free_pmd;
++      }
++
++      xbz_pma_rx_base = ioremap(MTK_2P5GPHY_XBZ_PMA_RX_BASE,
++                                MTK_2P5GPHY_XBZ_PMA_RX_LEN);
++      if (!xbz_pma_rx_base) {
++              ret = -ENOMEM;
++              goto free_pcs;
++      }
++
++      chip_scu_base = ioremap(MTK_2P5GPHY_CHIP_SCU_BASE,
++                              MTK_2P5GPHY_CHIP_SCU_LEN);
++      if (!chip_scu_base) {
++              ret = -ENOMEM;
++              goto free_pma;
++      }
++
++      mcu_csr_base = ioremap(MTK_2P5GPHY_MCU_CSR_BASE,
++                             MTK_2P5GPHY_MCU_CSR_LEN);
++      if (!mcu_csr_base) {
++              ret = -ENOMEM;
++              goto free_chip_scu;
++      }
++
++      pmb_addr = ioremap(MTK_2P5GPHY_PMB_FW_BASE, MT7987_2P5GE_PMB_FW_SIZE);
++      if (!pmb_addr) {
++              return -ENOMEM;
++              goto free_mcu_csr;
++      }
++
++      ret = request_firmware(&fw, MT7987_2P5GE_PMB_FW, dev);
++      if (ret) {
++              dev_err(dev, "failed to load firmware: %s, ret: %d\n",
++                      MT7987_2P5GE_PMB_FW, ret);
++              goto free_pmb_addr;
++      }
++
++      if (fw->size != MT7987_2P5GE_PMB_FW_SIZE) {
++              dev_err(dev, "PMb firmware size 0x%zx != 0x%x\n",
++                      fw->size, MT7987_2P5GE_PMB_FW_SIZE);
++              ret = -EINVAL;
++              goto release_fw;
++      }
++
++      /* Force 2.5Gphy back to AN state */
++      phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
++      usleep_range(5000, 6000);
++      phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
++
++      reg = readw(apb_base + SW_RESET);
++      writew(reg & ~MD32_RESTART_EN_CLEAR, apb_base + SW_RESET);
++      writew(reg | MD32_RESTART_EN_CLEAR, apb_base + SW_RESET);
++      writew(reg & ~MD32_RESTART_EN_CLEAR, apb_base + SW_RESET);
++
++      reg = readw(mcu_csr_base + MD32_EN_CFG);
++      writew(reg & ~MD32_EN, mcu_csr_base + MD32_EN_CFG);
++
++      for (i = 0; i < MT7987_2P5GE_PMB_FW_SIZE - 1; i += 4)
++              writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
++      dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n",
++               be16_to_cpu(*((__be16 *)(fw->data +
++                                        MT7987_2P5GE_PMB_FW_SIZE - 8))),
++               *(fw->data + MT7987_2P5GE_PMB_FW_SIZE - 6),
++               *(fw->data + MT7987_2P5GE_PMB_FW_SIZE - 5),
++               *(fw->data + MT7987_2P5GE_PMB_FW_SIZE - 2),
++               *(fw->data + MT7987_2P5GE_PMB_FW_SIZE - 1));
++      release_firmware(fw);
++
++      /* Enable 100Mbps module clock. */
++      writel(FIELD_PREP(RG_SPEED_MASK, RG_SPEED_100),
++             pmd_reg_base + FNPLL_PWR_CTRL1);
++
++      /* Check if 100Mbps module clock is ready. */
++      ret = readl_poll_timeout(pmd_reg_base + FNPLL_PWR_CTRL_STATUS, reg,
++                               reg & RG_SPEED_100_STABLE, 1, 10000);
++      if (ret)
++              dev_err(dev, "Fail to enable 100Mbps module clock: %d\n", ret);
++
++      /* Enable 2.5Gbps module clock. */
++      writel(FIELD_PREP(RG_SPEED_MASK, RG_SPEED_2500),
++             pmd_reg_base + FNPLL_PWR_CTRL1);
++
++      /* Check if 2.5Gbps module clock is ready. */
++      ret = readl_poll_timeout(pmd_reg_base + FNPLL_PWR_CTRL_STATUS, reg,
++                               reg & RG_SPEED_2500_STABLE, 1, 10000);
++
++      if (ret)
++              dev_err(dev, "Fail to enable 2.5Gbps module clock: %d\n", ret);
++
++      /* Disable AN */
++      phy_clear_bits(phydev, MII_BMCR, BMCR_ANENABLE);
++
++      /* Force to run at 2.5G speed */
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_AN_FORCE_SPEED_REG,
++                     MTK_PHY_MASTER_FORCE_SPEED_SEL_MASK,
++                     MTK_PHY_MASTER_FORCE_SPEED_SEL_EN |
++                     FIELD_PREP(MTK_PHY_MASTER_FORCE_SPEED_SEL_MASK, 0x1b));
++
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_RELATED,
++                       MTK_PHY_BYPASS_LINK_STATUS_OK |
++                       MTK_PHY_FORCE_LINK_STATUS_HCD);
++
++      /* Set xbz, pma and rx as "do not reset" in order to input DSP code. */
++      reg = readl(pmd_reg_base + DO_NOT_RESET);
++      reg |= DO_NOT_RESET_XBZ | DO_NOT_RESET_PMA | DO_NOT_RESET_RX;
++      writel(reg, pmd_reg_base + DO_NOT_RESET);
++
++      reg = readl(chip_scu_base + SYS_SW_RESET);
++      writel(reg & ~RESET_RST_CNT, chip_scu_base + SYS_SW_RESET);
++
++      writel(WRITE_PROTECT_KEY, xbz_pcs_reg_base + PMU_WP);
++
++      reg = readl(xbz_pcs_reg_base + PMU_PMA_AUTO_CFG);
++      reg |= PMU_AUTO_MODE_EN | POWER_ON_AUTO_MODE;
++      writel(reg, xbz_pcs_reg_base + PMU_PMA_AUTO_CFG);
++
++      /* Check if clock in auto mode is disabled. */
++      ret = readl_poll_timeout(xbz_pcs_reg_base + PMU_PMA_STATUS, reg,
++                               (reg & CLK_IS_DISABLED) == 0x0, 1, 100000);
++      if (ret)
++              dev_err(dev, "Clock isn't disabled in auto mode: %d\n", ret);
++
++      reg = readl(xbz_pma_rx_base + SMEM_CTRL);
++      writel(reg | SMEM_HW_RDATA_ZERO, xbz_pma_rx_base + SMEM_CTRL);
++
++      reg = readl(xbz_pcs_reg_base + PHY_CTRL_CONFIG);
++      writel(reg | BIT(16), xbz_pcs_reg_base + PHY_CTRL_CONFIG);
++
++      /* Initialize data memory */
++      reg = readl(xbz_pma_rx_base + DM_CTRL_P01);
++      writel(reg | BIT(28), xbz_pma_rx_base + DM_CTRL_P01);
++      reg = readl(xbz_pma_rx_base + DM_CTRL_P23);
++      writel(reg | BIT(28), xbz_pma_rx_base + DM_CTRL_P23);
++
++      /* Initialize coefficient memory */
++      reg = readl(xbz_pma_rx_base + CM_CTRL_P01);
++      writel(reg | BIT(28), xbz_pma_rx_base + CM_CTRL_P01);
++      reg = readl(xbz_pma_rx_base + CM_CTRL_P23);
++      writel(reg | BIT(28), xbz_pma_rx_base + CM_CTRL_P23);
++
++      /* Initilize PM offset */
++      writel(0, xbz_pma_rx_base + SMEM_ADDR_REF_ADDR);
++
++      ret = request_firmware(&fw, MT7987_2P5GE_DSPBITTB, dev);
++      if (ret) {
++              dev_err(dev, "failed to load firmware: %s, ret: %d\n",
++                      MT7987_2P5GE_DSPBITTB, ret);
++              goto free_pmb_addr;
++      }
++      if (fw->size != MT7987_2P5GE_DSPBITTB_SIZE) {
++              dev_err(dev, "DSPBITTB size 0x%zx != 0x%x\n",
++                      fw->size, MT7987_2P5GE_DSPBITTB_SIZE);
++              ret = -EINVAL;
++              goto release_fw;
++      }
++
++      for (i = 0; i < fw->size - 1; i += 16) {
++              writel(*((uint32_t *)(fw->data + i)),
++                     xbz_pma_rx_base + SMEM_WDAT0);
++              writel(*((uint32_t *)(fw->data + i + 0x4)),
++                     xbz_pma_rx_base + SMEM_WDAT1);
++              writel(*((uint32_t *)(fw->data + i + 0x8)),
++                     xbz_pma_rx_base + SMEM_WDAT2);
++              writel(*((uint32_t *)(fw->data + i + 0xc)),
++                     xbz_pma_rx_base + SMEM_WDAT3);
++      }
++
++      reg = readl(xbz_pma_rx_base + DM_CTRL_P01);
++      writel(reg & ~BIT(28), xbz_pma_rx_base + DM_CTRL_P01);
++
++      reg = readl(xbz_pma_rx_base + DM_CTRL_P23);
++      writel(reg & ~BIT(28), xbz_pma_rx_base + DM_CTRL_P23);
++
++      reg = readl(xbz_pma_rx_base + CM_CTRL_P01);
++      writel(reg & ~BIT(28), xbz_pma_rx_base + CM_CTRL_P01);
++
++      reg = readl(xbz_pma_rx_base + CM_CTRL_P23);
++      writel(reg & ~BIT(28), xbz_pma_rx_base + CM_CTRL_P23);
++
++      reg = readw(mcu_csr_base + MD32_EN_CFG);
++      writew(reg | MD32_EN, mcu_csr_base + MD32_EN_CFG);
++      phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
++      /* We need a delay here to stabilize initialization of MCU */
++      usleep_range(7000, 8000);
++      dev_info(dev, "Firmware loading/trigger ok.\n");
++
++      priv->fw_loaded = true;
++
++release_fw:
++      release_firmware(fw);
++free_pmb_addr:
++      iounmap(pmb_addr);
++free_mcu_csr:
++      iounmap(mcu_csr_base);
++free_chip_scu:
++      iounmap(chip_scu_base);
++free_pma:
++      iounmap(xbz_pma_rx_base);
++free_pcs:
++      iounmap(xbz_pcs_reg_base);
++free_pmd:
++      iounmap(pmd_reg_base);
++free_apb:
++      iounmap(apb_base);
++
++      return ret;
++}
++
++static int mt7988_2p5ge_phy_load_fw(struct phy_device *phydev)
+ {
+       struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
+       void __iomem *mcu_csr_base, *pmb_addr;
+@@ -135,15 +449,27 @@ static int mt798x_2p5ge_phy_config_init(
+       if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
+               return -ENODEV;
+-      ret = mt798x_2p5ge_phy_load_fw(phydev);
++      switch (phydev->drv->phy_id) {
++      case MTK_2P5GPHY_ID_MT7987:
++              ret = mt7987_2p5ge_phy_load_fw(phydev);
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
++                                 MTK_PHY_LED_ON_POLARITY);
++              break;
++      case MTK_2P5GPHY_ID_MT7988:
++              ret = mt7988_2p5ge_phy_load_fw(phydev);
++              phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
++                               MTK_PHY_LED_ON_POLARITY);
++              break;
++      default:
++              return -EINVAL;
++      }
+       if (ret < 0)
+               return ret;
+       /* Setup LED */
+       phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
+-                       MTK_PHY_LED_ON_POLARITY | MTK_PHY_LED_ON_LINK10 |
+-                       MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK1000 |
+-                       MTK_PHY_LED_ON_LINK2500);
++                       MTK_PHY_LED_ON_LINK10 | MTK_PHY_LED_ON_LINK100 |
++                       MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK2500);
+       phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
+                        MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX);
+@@ -293,6 +619,7 @@ static int mt798x_2p5ge_phy_probe(struct
+               return -ENOMEM;
+       switch (phydev->drv->phy_id) {
++      case MTK_2P5GPHY_ID_MT7987:
+       case MTK_2P5GPHY_ID_MT7988:
+               /* The original hardware only sets MDIO_DEVS_PMAPMD */
+               phydev->c45_ids.mmds_present |= MDIO_DEVS_PCS |
+@@ -312,6 +639,20 @@ static int mt798x_2p5ge_phy_probe(struct
+ static struct phy_driver mtk_2p5gephy_driver[] = {
+       {
++              PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7987),
++              .name = "MediaTek MT7987 2.5GbE PHY",
++              .probe = mt798x_2p5ge_phy_probe,
++              .config_init = mt798x_2p5ge_phy_config_init,
++              .config_aneg = mt798x_2p5ge_phy_config_aneg,
++              .get_features = mt798x_2p5ge_phy_get_features,
++              .read_status = mt798x_2p5ge_phy_read_status,
++              .get_rate_matching = mt798x_2p5ge_phy_get_rate_matching,
++              .suspend = genphy_suspend,
++              .resume = genphy_resume,
++              .read_page = mtk_phy_read_page,
++              .write_page = mtk_phy_write_page,
++      },
++      {
+               PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7988),
+               .name = "MediaTek MT7988 2.5GbE PHY",
+               .probe = mt798x_2p5ge_phy_probe,
diff --git a/target/linux/mediatek/patches-6.12/821-add-pwm-feature-for-mt7987.patch b/target/linux/mediatek/patches-6.12/821-add-pwm-feature-for-mt7987.patch
new file mode 100644 (file)
index 0000000..5b8fe7e
--- /dev/null
@@ -0,0 +1,44 @@
+From 7f4532a2bffdb0aebcabc2a672c4b97670e002a5 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Mon, 3 Mar 2025 14:33:33 +0800
+Subject: [PATCH] add pwm reg-v3 support for mt7987
+
+---
+ drivers/pwm/pwm-mediatek.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/pwm/pwm-mediatek.c
++++ b/drivers/pwm/pwm-mediatek.c
+@@ -64,6 +64,10 @@ static const unsigned int mtk_pwm_reg_of
+       0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240
+ };
++static const unsigned int mtk_pwm_reg_offset_v3[] = {
++      0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x600, 0x700, 0x0800
++};
++
+ static inline struct pwm_mediatek_chip *
+ to_pwm_mediatek_chip(struct pwm_chip *chip)
+ {
+@@ -350,6 +354,13 @@ static const struct pwm_mediatek_of_data
+       .reg_offset = mtk_pwm_reg_offset_v1,
+ };
++static const struct pwm_mediatek_of_data mt7987_pwm_data = {
++      .num_pwms = 3,
++      .pwm45_fixup = false,
++      .has_ck_26m_sel = false,
++      .reg_offset = mtk_pwm_reg_offset_v3,
++};
++
+ static const struct pwm_mediatek_of_data mt7988_pwm_data = {
+       .num_pwms = 8,
+       .pwm45_fixup = false,
+@@ -387,6 +398,7 @@ static const struct of_device_id pwm_med
+       { .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
+       { .compatible = "mediatek,mt7981-pwm", .data = &mt7981_pwm_data },
+       { .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
++      { .compatible = "mediatek,mt7987-pwm", .data = &mt7987_pwm_data },
+       { .compatible = "mediatek,mt7988-pwm", .data = &mt7988_pwm_data },
+       { .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
+       { .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
diff --git a/target/linux/mediatek/patches-6.12/830-thermal-drivers-mediatek-lvts_thermal-Add-irq_enable-support.patch b/target/linux/mediatek/patches-6.12/830-thermal-drivers-mediatek-lvts_thermal-Add-irq_enable-support.patch
new file mode 100644 (file)
index 0000000..ff1fd3e
--- /dev/null
@@ -0,0 +1,148 @@
+From: Chad Monroe <chad@monroe.io>
+Date: Mon, 01 Sep 2025 06:42:10 -0700
+Subject: [PATCH] thermal/drivers/mediatek/lvts_thermal: Add irq_enable
+ support.
+
+Allow interrupt support to be disabled as some SoCs don't support it.
+
+Signed-off-by: Chad Monroe <chad@monroe.io>
+---
+ drivers/thermal/mediatek/lvts_thermal.c |   33 ++++++++++++++++------
+ 1 file changed, 25 insertions(+), 8 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -127,6 +127,7 @@ struct lvts_data {
+       const struct lvts_ctrl_data *lvts_ctrl;
+       const u32 *conn_cmd;
+       const u32 *init_cmd;
++      bool irq_enable;
+       int num_lvts_ctrl;
+       int num_conn_cmd;
+       int num_init_cmd;
+@@ -408,6 +409,10 @@ static int lvts_set_trips(struct thermal
+               lvts_ctrl->high_thresh = high;
+               lvts_ctrl->low_thresh = low;
+       }
++
++      if (!lvts_data->irq_enable)
++              return 0;
++
+       lvts_update_irq_mask(lvts_ctrl);
+       if (!should_update_thresh)
+@@ -921,6 +926,8 @@ static void lvts_write_config(struct lvt
+ static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
+ {
++      const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
++
+       /*
+        * LVTS_PROTCTL : Thermal Protection Sensor Selection
+        *
+@@ -954,7 +961,8 @@ static int lvts_irq_init(struct lvts_ctr
+        * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS
+        * register, except we set the bits to enable the interrupt.
+        */
+-      writel(0, LVTS_MONINT(lvts_ctrl->base));
++      if (lvts_data->irq_enable)
++              writel(0, LVTS_MONINT(lvts_ctrl->base));
+       return 0;
+ }
+@@ -1338,9 +1346,11 @@ static int lvts_probe(struct platform_de
+       if (IS_ERR(lvts_td->reset))
+               return dev_err_probe(dev, PTR_ERR(lvts_td->reset), "Failed to get reset control\n");
+-      irq = platform_get_irq(pdev, 0);
+-      if (irq < 0)
+-              return irq;
++      if (lvts_data->irq_enable) {
++              irq = platform_get_irq(pdev, 0);
++              if (irq < 0)
++                      return irq;
++      }
+       golden_temp_offset = lvts_data->temp_offset;
+@@ -1352,10 +1362,12 @@ static int lvts_probe(struct platform_de
+        * At this point the LVTS is initialized and enabled. We can
+        * safely enable the interrupt.
+        */
+-      ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
+-                                      IRQF_ONESHOT, dev_name(dev), lvts_td);
+-      if (ret)
+-              return dev_err_probe(dev, ret, "Failed to request interrupt\n");
++      if (lvts_data->irq_enable) {
++              ret = devm_request_threaded_irq(dev, irq, NULL, lvts_irq_handler,
++                                              IRQF_ONESHOT, dev_name(dev), lvts_td);
++              if (ret)
++                      return dev_err_probe(dev, ret, "Failed to request interrupt\n");
++      }
+       platform_set_drvdata(pdev, lvts_td);
+@@ -1754,6 +1766,7 @@ static const struct lvts_ctrl_data mt819
+ };
+ static const struct lvts_data mt7988_lvts_ap_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt7988_lvts_ap_data_ctrl,
+       .conn_cmd       = mt7988_conn_cmds,
+       .init_cmd       = mt7988_init_cmds,
+@@ -1766,6 +1779,7 @@ static const struct lvts_data mt7988_lvt
+ };
+ static const struct lvts_data mt8186_lvts_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8186_lvts_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1779,6 +1793,7 @@ static const struct lvts_data mt8186_lvt
+ };
+ static const struct lvts_data mt8188_lvts_mcu_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8188_lvts_mcu_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1792,6 +1807,7 @@ static const struct lvts_data mt8188_lvt
+ };
+ static const struct lvts_data mt8188_lvts_ap_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8188_lvts_ap_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1805,6 +1821,7 @@ static const struct lvts_data mt8188_lvt
+ };
+ static const struct lvts_data mt8192_lvts_mcu_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8192_lvts_mcu_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1818,6 +1835,7 @@ static const struct lvts_data mt8192_lvt
+ };
+ static const struct lvts_data mt8192_lvts_ap_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8192_lvts_ap_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1831,6 +1849,7 @@ static const struct lvts_data mt8192_lvt
+ };
+ static const struct lvts_data mt8195_lvts_mcu_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8195_lvts_mcu_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
+@@ -1844,6 +1863,7 @@ static const struct lvts_data mt8195_lvt
+ };
+ static const struct lvts_data mt8195_lvts_ap_data = {
++      .irq_enable     = true,
+       .lvts_ctrl      = mt8195_lvts_ap_data_ctrl,
+       .conn_cmd       = default_conn_cmds,
+       .init_cmd       = default_init_cmds,
diff --git a/target/linux/mediatek/patches-6.12/831-thermal-drivers-mediatek-lvts_thermal-Add-MT7987-support.patch b/target/linux/mediatek/patches-6.12/831-thermal-drivers-mediatek-lvts_thermal-Add-MT7987-support.patch
new file mode 100644 (file)
index 0000000..7cd4aff
--- /dev/null
@@ -0,0 +1,106 @@
+From: Chad Monroe <chad@monroe.io>
+Date: Mon, 01 Sep 2025 06:44:04 -0700
+Subject: [PATCH] thermal/drivers/mediatek/lvts_thermal: Add MT7987 support 
+
+Add support for Mediatek MT7987 LVTS. Based patch[1] from vendor  SDK.
+
+1: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/742007e189ffcc95783924cea1150f574b6eb71e
+
+Signed-off-by: Chad Monroe <chad@monroe.io>
+---
+ drivers/thermal/mediatek/lvts_thermal.c             |   36 ++++++++++
+ include/dt-bindings/thermal/mediatek,lvts-thermal.h |    3 
+ 2 files changed, 39 insertions(+)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -87,6 +87,8 @@
+ #define LVTS_COEFF_B_MT8195                   250460
+ #define LVTS_COEFF_A_MT7988                   -204650
+ #define LVTS_COEFF_B_MT7988                   204650
++#define LVTS_COEFF_A_MT7987                   -204650
++#define LVTS_COEFF_B_MT7987                   204650
+ #define LVTS_MSR_IMMEDIATE_MODE               0
+ #define LVTS_MSR_FILTERED_MODE                1
+@@ -1385,6 +1387,19 @@ static void lvts_remove(struct platform_
+               lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
+ }
++static const struct lvts_ctrl_data mt7987_lvts_ap_data_ctrl[] = {
++      {
++              .lvts_sensor = {
++                      { .dt_id = MT7987_CPU,
++                        .cal_offsets = { 0x04, 0x05, 0x06 } },
++                      { .dt_id = MT7987_ETH2P5G,
++                        .cal_offsets = { 0x08, 0x09, 0x0a } },
++              },
++              VALID_SENSOR_MAP(1, 1, 0, 0),
++              .offset = 0x0,
++      },
++};
++
+ static const struct lvts_ctrl_data mt7988_lvts_ap_data_ctrl[] = {
+       {
+               .lvts_sensor = {
+@@ -1455,6 +1470,7 @@ static int lvts_resume(struct device *de
+ }
+ static const u32 default_conn_cmds[] = { 0xC103FFFF, 0xC502FF55 };
++static const u32 mt7987_conn_cmds[] = { 0xC103FFFF, 0xC502FC55 };
+ static const u32 mt7988_conn_cmds[] = { 0xC103FFFF, 0xC502FC55 };
+ /*
+@@ -1467,6 +1483,12 @@ static const u32 default_init_cmds[] = {
+       0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
+ };
++static const u32 mt7987_init_cmds[] = {
++      0xC1030300, 0xC1030420, 0xC1030500, 0xC10307A6, 0xC10308C7,
++      0xC103098D, 0xC1030C7C, 0xC1030AA8, 0xC10308CE, 0xC10308C7,
++      0xC1030B04, 0xC1030E01, 0xC10306B8
++};
++
+ static const u32 mt7988_init_cmds[] = {
+       0xC1030300, 0xC1030420, 0xC1030500, 0xC10307A6, 0xC1030CFC,
+       0xC1030A8C, 0xC103098D, 0xC10308F1, 0xC1030B04, 0xC1030E01,
+@@ -1765,6 +1787,19 @@ static const struct lvts_ctrl_data mt819
+       }
+ };
++static const struct lvts_data mt7987_lvts_ap_data = {
++      .irq_enable     = false,
++      .lvts_ctrl      = mt7987_lvts_ap_data_ctrl,
++      .conn_cmd       = mt7987_conn_cmds,
++      .init_cmd       = mt7987_init_cmds,
++      .num_lvts_ctrl  = ARRAY_SIZE(mt7987_lvts_ap_data_ctrl),
++      .num_conn_cmd   = ARRAY_SIZE(mt7987_conn_cmds),
++      .num_init_cmd   = ARRAY_SIZE(mt7987_init_cmds),
++      .temp_factor    = LVTS_COEFF_A_MT7987,
++      .temp_offset    = LVTS_COEFF_B_MT7987,
++      .gt_calib_bit_offset = 24,
++};
++
+ static const struct lvts_data mt7988_lvts_ap_data = {
+       .irq_enable     = true,
+       .lvts_ctrl      = mt7988_lvts_ap_data_ctrl,
+@@ -1877,6 +1912,7 @@ static const struct lvts_data mt8195_lvt
+ };
+ static const struct of_device_id lvts_of_match[] = {
++      { .compatible = "mediatek,mt7987-lvts-ap", .data = &mt7987_lvts_ap_data },
+       { .compatible = "mediatek,mt7988-lvts-ap", .data = &mt7988_lvts_ap_data },
+       { .compatible = "mediatek,mt8186-lvts", .data = &mt8186_lvts_data },
+       { .compatible = "mediatek,mt8188-lvts-mcu", .data = &mt8188_lvts_mcu_data },
+--- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h
++++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
+@@ -7,6 +7,9 @@
+ #ifndef __MEDIATEK_LVTS_DT_H
+ #define __MEDIATEK_LVTS_DT_H
++#define MT7987_CPU            0
++#define MT7987_ETH2P5G                1
++
+ #define MT7988_CPU_0          0
+ #define MT7988_CPU_1          1
+ #define MT7988_ETH2P5G_0      2
diff --git a/target/linux/mediatek/patches-6.12/840-cpufreq-add-support-to-adjust-cpu-volt-by-efuse-cali.patch b/target/linux/mediatek/patches-6.12/840-cpufreq-add-support-to-adjust-cpu-volt-by-efuse-cali.patch
new file mode 100644 (file)
index 0000000..9aebab6
--- /dev/null
@@ -0,0 +1,106 @@
+From fbb1d181782f990c0ac5f39d4aa9eda5c39cb442 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Tue, 4 Mar 2025 19:28:14 +0800
+Subject: [PATCH 1/2] cpufreq: add support to adjust cpu volt by efuse
+ calibration data
+
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 81 ++++++++++++++++++++++++++++--
+ 1 file changed, 76 insertions(+), 5 deletions(-)
+
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -15,14 +15,26 @@
+ #include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
+ #include <linux/regulator/consumer.h>
++#include <linux/nvmem-consumer.h>
++
++struct mtk_cpufreq_corr_data {
++      unsigned int freq;
++      unsigned int vbase;
++      unsigned int vscale;
++      unsigned int vmax;
++};
+ struct mtk_cpufreq_platform_data {
++      /* cpufreq correction data specification */
++      const struct mtk_cpufreq_corr_data *corr_data;
+       int min_volt_shift;
+       int max_volt_shift;
+       int proc_max_volt;
+       int sram_min_volt;
+       int sram_max_volt;
+       bool ccifreq_supported;
++      /* whether voltage correction via nvmem is supported */
++      bool nvmem_volt_corr;
+ };
+ /*
+@@ -197,6 +209,50 @@ static bool is_ccifreq_ready(struct mtk_
+       return true;
+ }
++static int mtk_cpufreq_nvmem_volt_corr(struct mtk_cpu_dvfs_info *info,
++                                    struct cpufreq_policy *policy)
++{
++      const struct mtk_cpufreq_corr_data *corr_data;
++      unsigned int target_voltage;
++      struct nvmem_cell *cell;
++      unsigned int cal_data;
++      const u8 *buf;
++      size_t len;
++      int i;
++
++      cell = nvmem_cell_get(info->cpu_dev, "calibration-data");
++      if (IS_ERR(cell))
++              return PTR_ERR(cell);
++
++      buf = nvmem_cell_read(cell, &len);
++      nvmem_cell_put(cell);
++      if (IS_ERR(buf))
++              return PTR_ERR(buf);
++
++      cal_data = buf[0] & 0x1f;
++      pr_debug("%s: read vbinning value: %d\n", __func__, cal_data);
++      kfree(buf);
++      if (!info->soc_data->corr_data) {
++              pr_err("voltage correction data not found\n");
++              return -EINVAL;
++      }
++
++      corr_data = &info->soc_data->corr_data[0];
++      for (i = 0 ; i < corr_data->freq ; i++) {
++              target_voltage =  corr_data->vbase + cal_data * corr_data->vscale;
++              if (target_voltage > corr_data->vmax) {
++                      pr_warn("freq %u exceeds max voltage\n", corr_data->freq);
++                      pr_warn("force update voltage to %u\n", corr_data->vmax);
++                      target_voltage = corr_data->vmax;
++              }
++              dev_pm_opp_remove(info->cpu_dev, corr_data->freq);
++              dev_pm_opp_add(info->cpu_dev, corr_data->freq, target_voltage);
++              corr_data = &info->soc_data->corr_data[i + 1];
++      }
++
++      return 0;
++}
++
+ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
+                                 unsigned int index)
+ {
+@@ -584,6 +640,15 @@ static int mtk_cpufreq_init(struct cpufr
+               return -EINVAL;
+       }
++      if (info->soc_data->nvmem_volt_corr) {
++              ret = mtk_cpufreq_nvmem_volt_corr(info, policy);
++              if (ret) {
++                      pr_err("failed to correction voltage for cpu%d: %d\n",
++                             policy->cpu, ret);
++                      return ret;
++              }
++      }
++
+       ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
+       if (ret) {
+               dev_err(info->cpu_dev,
diff --git a/target/linux/mediatek/patches-6.12/841-cpufreq-add-cpu-volt-correction-support-for-mt7988.patch b/target/linux/mediatek/patches-6.12/841-cpufreq-add-cpu-volt-correction-support-for-mt7988.patch
new file mode 100644 (file)
index 0000000..a6422b6
--- /dev/null
@@ -0,0 +1,45 @@
+From 2595e31220f8e515714a71deb781e3fdf8c483ef Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 5 Oct 2025 03:42:19 +0100
+Subject: [PATCH] cpufreq: mediatek: add nvmem-based CPU voltage correction for MT7988
+
+Add mt7988_volt_corr_data[] with correction parameters for the 1800 MHz
+OPP and enable the nvmem_volt_corr path in the MT7988 platform data,
+allowing the CPU voltage to be adjusted based on calibration values read
+from the efuse. Raise proc_max_volt to 1120000 uV accordingly.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -741,6 +741,16 @@ static struct platform_driver mtk_cpufre
+       .probe          = mtk_cpufreq_probe,
+ };
++struct mtk_cpufreq_corr_data mt7988_volt_corr_data[] = {
++      {
++              .freq = 1800000000,
++              .vbase = 850000,
++              .vscale = 10000,
++              .vmax = 1120000,
++      },
++      { } /* sentinel */
++};
++
+ static const struct mtk_cpufreq_platform_data mt2701_platform_data = {
+       .min_volt_shift = 100000,
+       .max_volt_shift = 200000,
+@@ -769,10 +779,12 @@ static const struct mtk_cpufreq_platform
+ static const struct mtk_cpufreq_platform_data mt7988_platform_data = {
+       .min_volt_shift = 100000,
+       .max_volt_shift = 200000,
+-      .proc_max_volt = 900000,
++      .proc_max_volt = 1120000,
+       .sram_min_volt = 0,
+       .sram_max_volt = 1150000,
+       .ccifreq_supported = true,
++      .nvmem_volt_corr = 1,
++      .corr_data = mt7988_volt_corr_data,
+ };
+ static const struct mtk_cpufreq_platform_data mt8183_platform_data = {
diff --git a/target/linux/mediatek/patches-6.12/842-mediatek-enable-using-efuse-cali-data-for-mt7988-cpu-volt.patch b/target/linux/mediatek/patches-6.12/842-mediatek-enable-using-efuse-cali-data-for-mt7988-cpu-volt.patch
new file mode 100644 (file)
index 0000000..30115a2
--- /dev/null
@@ -0,0 +1,48 @@
+From c776eb44070d009375559d8c6eb8790edfe129a9 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Tue, 4 Mar 2025 19:35:14 +0800
+Subject: [PATCH 2/2] cpufreq: mt7988: enable using efuse calibration data for
+ adjusting cpu volt
+
+---
+ arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -55,6 +55,8 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      nvmem-cells = <&cpufreq_calibration>;
++                      nvmem-cell-names = "calibration-data";
+                       mediatek,cci = <&cci>;
+               };
+@@ -67,6 +69,8 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      nvmem-cells = <&cpufreq_calibration>;
++                      nvmem-cell-names = "calibration-data";
+                       mediatek,cci = <&cci>;
+               };
+@@ -79,6 +83,8 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      nvmem-cells = <&cpufreq_calibration>;
++                      nvmem-cell-names = "calibration-data";
+                       mediatek,cci = <&cci>;
+               };
+@@ -91,6 +97,8 @@
+                                <&topckgen CLK_TOP_XTAL>;
+                       clock-names = "cpu", "intermediate";
+                       operating-points-v2 = <&cluster0_opp>;
++                      nvmem-cells = <&cpufreq_calibration>;
++                      nvmem-cell-names = "calibration-data";
+                       mediatek,cci = <&cci>;
+               };
diff --git a/target/linux/mediatek/patches-6.12/843-cpufreq-add-support-to-fix-voltage-cpu.patch b/target/linux/mediatek/patches-6.12/843-cpufreq-add-support-to-fix-voltage-cpu.patch
new file mode 100644 (file)
index 0000000..8185cda
--- /dev/null
@@ -0,0 +1,33 @@
+From 2595e31220f8e515714a71deb781e3fdf8c483ef Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 5 Oct 2025 03:42:19 +0100
+Subject: [PATCH] cpufreq: mediatek: add proc_fixed_volt flag to skip voltage scaling
+
+Add a proc_fixed_volt boolean to mtk_cpufreq_platform_data. When set,
+mtk_cpufreq_set_voltage() returns immediately without programming the
+regulator, for SoCs where the CPU core voltage is fixed in hardware and
+must not be touched by software.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -35,6 +35,8 @@ struct mtk_cpufreq_platform_data {
+       bool ccifreq_supported;
+       /* whether voltage correction via nvmem is supported */
+       bool nvmem_volt_corr;
++      /* Flag indicating whether the processor voltage is fixed */
++      bool proc_fixed_volt;
+ };
+ /*
+@@ -176,6 +178,9 @@ static int mtk_cpufreq_set_voltage(struc
+       const struct mtk_cpufreq_platform_data *soc_data = info->soc_data;
+       int ret;
++      if (soc_data->proc_fixed_volt)
++              return 0;
++
+       if (info->need_voltage_tracking)
+               ret = mtk_cpufreq_voltage_tracking(info, vproc);
+       else
diff --git a/target/linux/mediatek/patches-6.12/844-cpufreq-mediatek-Add-support-for-MT7987.patch b/target/linux/mediatek/patches-6.12/844-cpufreq-mediatek-Add-support-for-MT7987.patch
new file mode 100644 (file)
index 0000000..5901b45
--- /dev/null
@@ -0,0 +1,34 @@
+From 2595e31220f8e515714a71deb781e3fdf8c483ef Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 5 Oct 2025 03:42:19 +0100
+Subject: [PATCH] cpufreq: mediatek: add platform data and DT match for MT7987
+
+Add mt7987_platform_data with proc_max_volt=1023000 uV and
+proc_fixed_volt=true (the MT7987 CPU voltage is not software-
+controllable), and register it for the "mediatek,mt7987" DT compatible.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -781,6 +781,12 @@ static const struct mtk_cpufreq_platform
+       .ccifreq_supported = false,
+ };
++static const struct mtk_cpufreq_platform_data mt7987_platform_data = {
++      .proc_max_volt = 1023000,
++      .ccifreq_supported = false,
++      .proc_fixed_volt = true,
++};
++
+ static const struct mtk_cpufreq_platform_data mt7988_platform_data = {
+       .min_volt_shift = 100000,
+       .max_volt_shift = 200000,
+@@ -825,6 +831,7 @@ static const struct of_device_id mtk_cpu
+       { .compatible = "mediatek,mt2712", .data = &mt2701_platform_data },
+       { .compatible = "mediatek,mt7622", .data = &mt7622_platform_data },
+       { .compatible = "mediatek,mt7623", .data = &mt7623_platform_data },
++      { .compatible = "mediatek,mt7987", .data = &mt7987_platform_data },
+       { .compatible = "mediatek,mt7988a", .data = &mt7988_platform_data },
+       { .compatible = "mediatek,mt7988d", .data = &mt7988_platform_data },
+       { .compatible = "mediatek,mt8167", .data = &mt8516_platform_data },
diff --git a/target/linux/mediatek/patches-6.12/862-arm64-dts-mt7986-add-afe.patch b/target/linux/mediatek/patches-6.12/862-arm64-dts-mt7986-add-afe.patch
new file mode 100644 (file)
index 0000000..1b768f6
--- /dev/null
@@ -0,0 +1,41 @@
+From 1c09b694a1e9378931085e77d834a4d9786a5356 Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Thu, 7 Sep 2023 10:54:37 +0800
+Subject: [PATCH] arm64: dts: mt7986: add afe
+
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi     | 23 +++++++++++
+ 1 files changed, 23 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -202,6 +202,29 @@
+                       #interrupt-cells = <2>;
+               };
++              afe: audio-controller@11210000 {
++                      compatible = "mediatek,mt7986-afe";
++                      reg = <0 0x11210000 0 0x9000>;
++                      #sound-dai-cells = <0>;
++                      interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&infracfg CLK_INFRA_AUD_BUS_CK>,
++                               <&infracfg CLK_INFRA_AUD_26M_CK>,
++                               <&infracfg CLK_INFRA_AUD_L_CK>,
++                               <&infracfg CLK_INFRA_AUD_AUD_CK>,
++                               <&infracfg CLK_INFRA_AUD_EG2_CK>;
++                      clock-names = "aud_bus_ck",
++                                    "aud_26m_ck",
++                                    "aud_l_ck",
++                                    "aud_aud_ck",
++                                    "aud_eg2_ck";
++                      assigned-clocks = <&topckgen CLK_TOP_A1SYS_SEL>,
++                                        <&topckgen CLK_TOP_AUD_L_SEL>,
++                                        <&topckgen CLK_TOP_A_TUNER_SEL>;
++                      assigned-clock-parents = <&topckgen CLK_TOP_APLL2_D4>,
++                                               <&apmixedsys CLK_APMIXED_APLL2>,
++                                               <&topckgen CLK_TOP_APLL2_D4>;
++              };
++
+               pwm: pwm@10048000 {
+                       compatible = "mediatek,mt7986-pwm";
+                       reg = <0 0x10048000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/863-arm64-dts-mt7986-add-sound-wm8960.patch b/target/linux/mediatek/patches-6.12/863-arm64-dts-mt7986-add-sound-wm8960.patch
new file mode 100644 (file)
index 0000000..db51bf1
--- /dev/null
@@ -0,0 +1,62 @@
+From 1c09b694a1e9378931085e77d834a4d9786a5356 Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Thu, 7 Sep 2023 10:54:37 +0800
+Subject: [PATCH] arm64: dts: mt7986: add sound wm8960
+
+---
+ .../dts/mediatek/mt7986a-rfb-spim-nand.dts    | 39 +++++++++++++++++++
+ 1 files changed, 39 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts
+@@ -4,6 +4,36 @@
+ / {
+       compatible = "mediatek,mt7986a-rfb-snand";
++
++      sound_wm8960 {
++              compatible = "mediatek,mt7986-wm8960-sound";
++              audio-routing = "Headphone", "HP_L",
++                              "Headphone", "HP_R",
++                              "LINPUT1", "AMIC",
++                              "RINPUT1", "AMIC";
++
++              status = "okay";
++
++              platform {
++                      sound-dai = <&afe>;
++              };
++
++              codec {
++                      sound-dai = <&wm8960>;
++              };
++      };
++};
++
++&i2c0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c_pins>;
++      status = "okay";
++
++      wm8960: wm8960@1a {
++              compatible = "wlf,wm8960";
++              #sound-dai-cells = <0>;
++              reg = <0x1a>;
++      };
+ };
+ &spi0 {
+@@ -48,3 +78,13 @@
+ &wifi {
+       mediatek,mtd-eeprom = <&factory 0>;
+ };
++
++&pio {
++      i2c_pins: i2c-pins-3-4 {
++              mux {
++                      function = "i2c";
++                      groups = "i2c";
++              };
++      };
++};
++
diff --git a/target/linux/mediatek/patches-6.12/864-arm64-dts-mt7986-add-sound-overlay-for-bpi-r3.patch b/target/linux/mediatek/patches-6.12/864-arm64-dts-mt7986-add-sound-overlay-for-bpi-r3.patch
new file mode 100644 (file)
index 0000000..dd21397
--- /dev/null
@@ -0,0 +1,123 @@
+From 957a0921e20257bd94b7f5ace6e07a68e8388499 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 10 Dec 2023 23:09:00 +0000
+Subject: [PATCH] mediatek: bananapi-r3: add overlay for ReSpeaker 2-mic hat
+
+Add DT overlay to allow using the ReSpeaker 2-mic hat connected to
+the 26-pin header of the BananaPi BPi-R3.
+
+Supported sample formats: S16_LE, S24_LE, S32_LE
+Supported sample rates: 8/12/16/24/32/48/96/192 kHz
+
+          |  BPi-R3  |  ReSpeaker 2-mic
+  Signal  |  26-pin  |  40-pin
+----------+----------+-------------------
+ VCC 5V   |    2     |    2
+ I2C SDA  |    3     |    3
+ I2C SCL  |    5     |    5
+ GND      |    6     |    6
+ PCM CLK  |   12     |   12
+ PCM FS   |   15     |   35
+ PCM DIN  |   26     |   38
+ GND      |   25     |   39
+ PCM DOUT |   22     |   40
+
+Once connected, install the driver and tell U-Boot to apply the DT
+overlay:
+
+opkg kmod-sound-soc-mt7986-wm8960
+fw_setenv bootconf_base "config-mt7986a-bananapi-bpi-r3#mt7986a-bananapi-bpi-r3-respeaker-2mics"
+reboot
+
+To setup the ReSpeaker for Stereo out on the Headphone plug:
+
+amixer sset 'Right Output Mixer PCM' on
+amixer sset 'Left Output Mixer PCM' on
+amixer sset 'PCM Playback -6dB' off
+amixer sset 'O018 I150_Switch' on
+amixer sset 'O019 I151_Switch' on
+amixer sset 'O124 I032_Switch' on
+amixer sset 'O125 I033_Switch' on
+amixer sset 'Headphone' 121
+amixer sset 'Playback' 255
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-respeaker-2mics.dtso
+@@ -0,0 +1,65 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2023 MediaTek Inc.
++ * Author: Maso Huang <Maso.Huang@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
++
++      fragment@0 {
++              target-path = "/";
++              __overlay__ {
++                      sound_wm8960 {
++                              compatible = "mediatek,mt7986-wm8960-sound";
++                              audio-routing = "Headphone", "HP_L",
++                                      "Headphone", "HP_R",
++                                      "LINPUT1", "AMIC",
++                                      "RINPUT1", "AMIC";
++
++                              status = "okay";
++
++                              platform {
++                                      sound-dai = <&afe>;
++                              };
++
++                              codec {
++                                      sound-dai = <&wm8960>;
++                              };
++                      };
++              };
++      };
++
++      fragment@1 {
++              target = <&i2c0>;
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&i2c_pins>;
++                      clock-frequency = <400000>;
++                      status = "okay";
++
++                      wm8960: wm8960@1a {
++                              compatible = "wlf,wm8960";
++                              #sound-dai-cells = <0>;
++                              reg = <0x1a>;
++                      };
++              };
++      };
++
++      fragment@2 {
++              target = <&pio>;
++              __overlay__ {
++                      i2c_pins: i2c-pins-3-4 {
++                              mux {
++                                      function = "i2c";
++                                      groups = "i2c";
++                              };
++                      };
++              };
++      };
++};
+--- a/arch/arm64/boot/dts/mediatek/Makefile
++++ b/arch/arm64/boot/dts/mediatek/Makefile
+@@ -18,6 +18,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-b
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-respeaker-2mics.dtbo
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb
diff --git a/target/linux/mediatek/patches-6.12/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch b/target/linux/mediatek/patches-6.12/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch
new file mode 100644 (file)
index 0000000..03038d3
--- /dev/null
@@ -0,0 +1,78 @@
+From b40f707f71d4e1fee9b2c20d62e235c5aba5533b Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 17 Mar 2021 17:36:54 +0000
+Subject: [PATCH] arm64: dts: mediatek: mt7622-bpi-r64: add SATA/PCIe1 DT overlays
+
+The Bananapi BPi-R64 got a SATA interface which cannot be used at the
+same time as the second mPCIe slot. The decission is made by hogging
+GPIO 90.
+Embed two addtional DT overlay blobs into the image to allow bootloader
+selection of either SATA or PCIE1 feature.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -323,7 +323,7 @@
+       /* Attention: GPIO 90 is used to switch between PCIe@1,0 and
+        * SATA functions. i.e. output-high: PCIe, output-low: SATA
+        */
+-      asm_sel {
++      asmsel: asm_sel {
+               gpio-hog;
+               gpios = <90 GPIO_ACTIVE_HIGH>;
+               output-high;
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-sata.dtso
+@@ -0,0 +1,31 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
++
++#include <dt-bindings/gpio/gpio.h>
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r64", "mediatek,mt7622";
++
++      fragment@0 {
++              target = <&asmsel>;
++              __overlay__ {
++                      gpios = <90 GPIO_ACTIVE_LOW>;
++              };
++      };
++
++      fragment@1 {
++              target = <&sata>;
++              __overlay__ {
++                      status = "okay";
++              };
++      };
++
++      fragment@2 {
++              target = <&sata_phy>;
++              __overlay__ {
++                      status = "okay";
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-pcie1.dtso
+@@ -0,0 +1,17 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
++
++#include <dt-bindings/gpio/gpio.h>
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r64", "mediatek,mt7622";
++
++      fragment@0 {
++              target = <&asmsel>;
++              __overlay__ {
++                      gpios = <90 GPIO_ACTIVE_HIGH>;
++              };
++      };
++};
diff --git a/target/linux/mediatek/patches-6.12/901-arm-add-cmdline-override.patch b/target/linux/mediatek/patches-6.12/901-arm-add-cmdline-override.patch
new file mode 100644 (file)
index 0000000..b127b0e
--- /dev/null
@@ -0,0 +1,68 @@
+From c27279dc26a26b8ad054882d4c5f86a85526fd16 Mon Sep 17 00:00:00 2001
+From: Yoonji Park <koreapyj@dcmys.kr>
+Date: Mon, 6 Jun 2022 07:44:48 +0000
+Subject: [PATCH] arm: arm64: of: add CMDLINE_OVERRIDE to support chosen/bootargs-override
+
+Add a CONFIG_CMDLINE_OVERRIDE Kconfig option for both ARM and ARM64 and
+handle the corresponding "bootargs-override" property in
+early_init_dt_scan_chosen(). When the property is present in the DT
+chosen node its value fully replaces the kernel command line, which is
+useful on devices where the bootloader sets bootargs that cannot be
+edited.
+
+Signed-off-by: Yoonji Park <koreapyj@dcmys.kr>
+---
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1505,6 +1505,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
+ endchoice
++config CMDLINE_OVERRIDE
++      bool "Use alternative cmdline from device tree"
++      help
++        Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can
++        be used, this is not a good option for kernels that are shared across
++        devices. This setting enables using "chosen/cmdline-override" as the
++        cmdline if it exists in the device tree.
++
+ config CMDLINE
+       string "Default kernel command string"
+       default ""
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -1053,6 +1053,17 @@ int __init early_init_dt_scan_chosen(cha
+       if (p != NULL && l > 0)
+               strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE));
++    /* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different
++     * device tree option of chosen/bootargs-override. This is
++     * helpful on boards where u-boot sets bootargs, and is unable
++     * to be modified.
++     */
++#ifdef CONFIG_CMDLINE_OVERRIDE
++      p = of_get_flat_dt_prop(node, "bootargs-override", &l);
++      if (p != NULL && l > 0)
++              strscpy(cmdline, p, min((int)l, COMMAND_LINE_SIZE));
++#endif
++
+ handle_cmdline:
+       /*
+        * CONFIG_CMDLINE is meant to be a default in case nothing else
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -2383,6 +2383,14 @@ config CMDLINE_FORCE
+ endchoice
++config CMDLINE_OVERRIDE
++      bool "Use alternative cmdline from device tree"
++      help
++        Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can
++        be used, this is not a good option for kernels that are shared across
++        devices. This setting enables using "chosen/cmdline-override" as the
++        cmdline if it exists in the device tree.
++
+ config EFI_STUB
+       bool
diff --git a/target/linux/mediatek/patches-6.12/910-dts-mt7622-bpi-r64-wifi-eeprom.patch b/target/linux/mediatek/patches-6.12/910-dts-mt7622-bpi-r64-wifi-eeprom.patch
new file mode 100644 (file)
index 0000000..0e6eb3e
--- /dev/null
@@ -0,0 +1,45 @@
+From 3a93704a63cf018187411108d241c35ec83992c0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 20 Aug 2021 18:31:48 +0100
+Subject: [PATCH] mediatek: add EEPROM data for BPi-R64 2.4GHz wmac
+
+EEPROM data extracted from vendor image found at
+http://forum.banana-pi.org/t/bpi-r64-mt7622-mac80211-wifi-driver/10246/77
+http://forum.banana-pi.org/uploads/short-url/jworbyBYpvrw9VQ2sx92B9z6DWS.bin
+
+MAC address in the EEPROM has been zero'd which results in random
+address on boot.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -650,5 +650,28 @@
+ };
+ &wmac {
++      mediatek,eeprom-data = <0x22760500      0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x44000020      0x0             0x10002000
++                              0x4400          0x4000000       0x0             0x0
++                              0x200000b3      0x40b6c3c3      0x26000000      0x41c42600
++                              0x41c4          0x26000000      0xc0c52600      0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x0             0x0             0xc6c6
++                              0xc3c3c2c1      0xc300c3        0x818181        0x83c1c182
++                              0x83838382      0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0x84002e00      0x90000087      0x8a000000      0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0xb000009       0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x0             0x0             0x0
++                              0x0             0x0             0x0             0x7707>;
++
+       status = "okay";
+ };
diff --git a/target/linux/mediatek/patches-6.12/911-dts-mt7622-bpi-r64-add-rootdisk.patch b/target/linux/mediatek/patches-6.12/911-dts-mt7622-bpi-r64-add-rootdisk.patch
new file mode 100644 (file)
index 0000000..c6c5045
--- /dev/null
@@ -0,0 +1,119 @@
+From 208f6c1232901835708eb4ace44ae17628fc12f5 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 21 Jan 2024 23:50:02 +0000
+Subject: [PATCH] mediatek: mt7622: convert BPi-R64 to all-UBI layout and fitblk
+
+Modernize bootloader and flash memory layout of the BPi-R64 similar to
+how it has also been done for the BPi-R3.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -32,6 +32,9 @@
+       chosen {
+               stdout-path = "serial0:115200n8";
+               bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
++              rootdisk-emmc = <&emmc_rootfs>;
++              rootdisk-sd = <&sd_rootfs>;
++              rootdisk-snfi = <&ubi_rootfs>;
+       };
+       cpus {
+@@ -245,6 +248,28 @@
+       assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>;
+       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
+       non-removable;
++      #address-cells = <1>;
++      #size-cells = <0>;
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              block {
++                      compatible = "block-device";
++                      partitions {
++                              block-partition-env {
++                                      partname = "ubootenv";
++                                      nvmem-layout {
++                                              compatible = "u-boot,env";
++                                      };
++                              };
++                              emmc_rootfs: block-partition-production {
++                                      partname = "production";
++                              };
++                      };
++              };
++      };
+ };
+ &mmc1 {
+@@ -260,6 +285,28 @@
+       vqmmc-supply = <&reg_3p3v>;
+       assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>;
+       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
++      #address-cells = <1>;
++      #size-cells = <0>;
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              block {
++                      compatible = "block-device";
++                      partitions {
++                              block-partition-env {
++                                      partname = "ubootenv";
++                                      nvmem-layout {
++                                              compatible = "u-boot,env";
++                                      };
++                              };
++                              sd_rootfs: block-partition-production {
++                                      partname = "production";
++                              };
++                      };
++              };
++      };
+ };
+ &nandc {
+@@ -293,15 +340,30 @@
+                               read-only;
+                       };
+-                      partition@80000 {
+-                              label = "fip";
+-                              reg = <0x80000 0x200000>;
+-                              read-only;
+-                      };
+-
+-                      ubi: partition@280000 {
++                      ubi: partition@80000 {
+                               label = "ubi";
+-                              reg = <0x280000 0x7d80000>;
++                              reg = <0x80000 0x7f80000>;
++                              compatible = "linux,ubi";
++
++                              volumes {
++                                      ubi-volume-ubootenv {
++                                              volname = "ubootenv";
++                                              nvmem-layout {
++                                                      compatible = "u-boot,env-redundant-bool";
++                                              };
++                                      };
++
++                                      ubi-volume-ubootenv2 {
++                                              volname = "ubootenv2";
++                                              nvmem-layout {
++                                                      compatible = "u-boot,env-redundant-bool";
++                                              };
++                                      };
++
++                                      ubi_rootfs: ubi-volume-fit {
++                                              volname = "fit";
++                                      };
++                              };
+                       };
+               };
+       };
diff --git a/target/linux/mediatek/patches-6.12/911-dts-mt7988a-bpi-r4-be14-wifi-eeprom.patch b/target/linux/mediatek/patches-6.12/911-dts-mt7988a-bpi-r4-be14-wifi-eeprom.patch
new file mode 100644 (file)
index 0000000..7523033
--- /dev/null
@@ -0,0 +1,314 @@
+From 561e3cf678970ae29a719e559943d260a9ba18bb Mon Sep 17 00:00:00 2001
+From: Daniel Pawlik <pawlik.dan@gmail.com>
+Date: Mon, 16 Mar 2026 14:26:51 +0100
+Subject: [PATCH] mediatek: device tree overlay for BPI-R4 with BE14 module
+
+Some Banana Pi BPI-R4 BE14 WiFi modules are shipped with zeroed
+tx_power fields in EEPROM (2G/5G/6G). This leads to low transmit power
+on affected bands.
+This overlay provides known-good EEPROM data (including correct tx_power
+values for 2G/5G/6G bands) dumped from a working BE14 module.
+
+To enable BE14 overlay, add into u-boot bootconf_extra
+parameter: 'mt7988a-bananapi-bpi-r4-wifi-be14'.
+You can use example script:
+
+    overlay="mt7988a-bananapi-bpi-r4-wifi-be14"
+    current="$(fw_printenv -n bootconf_extra 2>/dev/null)"
+    if [ -n "${current}" ]; then
+        fw_setenv bootconf_extra "${current}#${overlay}"
+    else
+        fw_setenv bootconf_extra "${overlay}"
+    fi
+
+Earlier proposal proposed in [1] was fallback to default values if
+invalid EEPROM content is detected.
+
+[1] https://github.com/openwrt/openwrt/pull/19503/
+
+Fixes: https://github.com/openwrt/openwrt/issues/17489
+Signed-off-by: Daniel Pawlik <pawlik.dan@gmail.com>
+---
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-wifi-be14.dtso
+@@ -0,0 +1,280 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Device tree overlay for the BananaPi BPI-R4 with BE14 WiFi module.
++ * Some BE14 modules are shipped with zeroed or incorrect EEPROM
++ * calibration data. This overlay provides known-good EEPROM data
++ * (including correct tx_power values for 2G/5G/6G bands) dumped
++ * from a working BE14 module.
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
++};
++
++&i2c_wifi {
++      status = "okay";
++
++      eeprom@50 {
++              compatible = "atmel,24c02";
++              reg = <0x50>;
++              address-bits = <8>;
++              page-size = <8>;
++              size = <256>;
++      };
++};
++
++&pcie0 {
++      pcie@0,0 {
++              reg = <0x0000 0 0 0 0>;
++              #address-cells = <3>;
++              #size-cells = <2>;
++
++              wifi@0,0 {
++                      reg = <0x0000 0 0 0 0>;
++
++                      mediatek,eeprom-data = <0x90790400 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0xae682613 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x80000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0xae882613 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x80000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x11131b1a 0x131b0808 0xe00a0a0a 0x00008038
++                                              0x8000001a 0x03000000 0x01010000 0x00100001 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x04070489 0x00000080 0x18090489 0x42888300
++                                              0x1c090489 0x96000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000007 0x00000000 0x00000000 0xf24b0bc8 0x3ba5fd5f
++                                              0x02800000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0xaf89003c 0xaf8900cb 0x8900a889 0x008c0a00 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x004153c7 0x0044539e 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0xa1a3a081 0xa1990091 0x00910091 0x00910000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x0c000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x22222222 0x66447766 0x44776644 0x77664477
++                                              0x66447766 0x44444466 0x44444466 0x44444466 0x44444466 0x44444400 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00800080
++                                              0x00800a0a 0x00404040 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000002 0x20000000 0x00000220 0x00000000 0x00022000 0x00000000 0x02200000 0x00000002
++                                              0x20000000 0x00000220 0x00000000 0x00022000 0x00000000 0x02200000 0x00000002 0x20000000
++                                              0x00000220 0x00000000 0x00022000 0x00000000 0x02200000 0x00000002 0x20000000 0x00000220
++                                              0x00000000 0x00022000 0x00000000 0x02200000 0x00000002 0x27000000 0x00000227 0x00000000
++                                              0x00022700 0x00000000 0x02270000 0x00000002 0x27000000 0x00000227 0x00000000 0x00022700
++                                              0x00000000 0x02270000 0x00000002 0x27000000 0x00000227 0x00000000 0x00022700 0x00000000
++                                              0x02270000 0x00000002 0x27000000 0x00000227 0x00000000 0x00022700 0x00000000 0x02270000
++                                              0x00000002 0x00000000 0x00000200 0x00000000 0x00020000 0x00000000 0x02000000 0x00000002
++                                              0x27000000 0x00000227 0x00000000 0x00022700 0x00000000 0x02270000 0x00000002 0x27000000
++                                              0x00000227 0x00000000 0x00022700 0x00000000 0x02270000 0x00000002 0x27000000 0x00000227
++                                              0x00000000 0x00022700 0x00000000 0x02270000 0x00000002 0x27000000 0x00000227 0x00000000
++                                              0x02270000 0x00000000 0x02270000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x02020280 0x7f000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x20252b31 0x363b4146
++                                              0x00564c52 0x575d6167 0x6d10161c 0x22282e35 0x3c005042 0x484e545a 0x60660000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00b40000 0x00b40000 0x00000000 0x00000000
++                                              0x00000000 0x0000c400 0xb9008800 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x000040bd 0x40bd40bd 0x40bd40bd
++                                              0x40bd40bd 0x40bd40c8 0x40c640c6 0x40c740c7 0x40c840c7 0x40c640c7 0x40c740c7 0x40c640c5
++                                              0x40c640c6 0x40c540c4 0x40c440c4 0x40c30000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x02000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x000000d1 0xd1d1dddd 0xdde9e9e9 0xf5f5f501 0x01010909 0x09151515 0xd1d1d1dd 0xdddde9e9
++                                              0xe9f5f5f5 0xfdfdfd09 0x09091515 0x15d1d1d1 0xdddddde9 0xe9e9f5f5 0xf5ffffff 0x07070719
++                                              0x1919d7d7 0xd7e3e3e3 0xefefeff7 0xf7f70303 0x03171717 0x1f1f1fcf 0xcfcfdbdb 0xdbe7e7e7
++                                              0xf3f3f3ff 0xffff1313 0x13171717 0xd7d7d7e3 0xe3e3efef 0xeff7f7f7 0x03030311 0x11111919
++                                              0x19cfcfcf 0xdbdbdbe7 0xe7e7f3f3 0xf3ffffff 0x13131317 0x1717d7d7 0xd7e3e3e3 0xefefeff7
++                                              0xf7f70303 0x03111111 0x191919cf 0xcfcfdbdb 0xdbe7e7e7 0xf3f3f3ff 0xffff1313 0x13171717
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00350035 0x0035002d 0x00300000 0x00000000
++                                              0x00000000 0x00000000 0x00cdcd00 0x00000000 0x00000000 0x00000000 0x0000c400 0xc4009600
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x29272727 0x27250000 0x00000000 0x00000000 0x22242424 0x21212121 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000080 0x80c18080 0x80808080 0x80808080 0x80808080 0x808080c1
++                                              0x80c180c1 0xc18080c1 0x80808080 0x80808080 0x80808000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00808080 0x80808080 0x80808080
++                                              0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080
++                                              0x80808080 0x80808080 0x80808080 0x80808080 0x80000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0xc6c6c4c4 0xc30000c1 0xc1c18383 0x83838386 0x86c1c183 0x83838383 0x8686c1c1 0xc1818181
++                                              0x82838585 0x86868888 0xc1c1c181 0x81818283 0x85858686 0x8888c1c1 0xc1818181 0x82838585
++                                              0x86868888 0xc1c1c181 0x81818283 0x85858686 0x8888c1c1 0xc1818181 0x82838585 0x86868888
++                                              0xc1c1c181 0x81818283 0x85858686 0x8888c1c1 0xc1818181 0x82838585 0x86868888 0xc1c5c5c3
++                                              0xc100c2c2 0xc2c2c2c1 0x00818383 0xc1c1c1c1 0x00008183 0x83c2c1c1 0xc1c10000 0x818383c1
++                                              0xc2c2c2c2 0xc1008183 0x83848487 0x87c2c1c1 0xc1c10000 0x81838384 0x848888c1 0xc1c1c1c1
++                                              0x00008183 0x83868689 0x89c1c181 0x81838484 0x84858686 0x88888b8b 0x8281c2c2 0xc2c2c100
++                                              0x81838384 0x848787c2 0xc2c2c2c2 0xc1008183 0x83848487 0x87c2c2c2 0xc2c2c100 0x81838384
++                                              0x848787c2 0xc2c2c2c2 0xc1008183 0x83848487 0x87c2c2c2 0xc2c2c100 0x81838384 0x848787c2
++                                              0xc1c1c1c1 0x00008183 0x83868689 0x89c18181 0x83848484 0x85868688 0x888b8b81 0x81818384
++                                              0x84848586 0x8688888b 0x8b81c5c5 0xc3c100c2 0xc2c2c200 0x81828383 0x85858787 0xc2c2c2c2
++                                              0xc2008182 0x83838585 0x8787c2c1 0xc1c1c181 0x82838484 0x86868a8a 0xc1c18282 0x84848484
++                                              0x84858586 0x868c8c82 0x82c2c2c2 0xc2008182 0x83838585 0x8787c2c2 0xc2c2c200 0x81828383
++                                              0x85858787 0xc2c2c2c2 0xc2008182 0x83838585 0x8787c2c2 0xc2c2c200 0x81828383 0x85858787
++                                              0xc2c2c2c2 0xc2008182 0x83838585 0x8787c2c1 0xc1c1c181 0x82838484 0x86868a8a 0xc1c18282
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x84848484 0x84858586 0x868c8c82 0x82828284 0x84848484 0x85858686 0x8c8c8282 0x87878888
++                                              0x88888888 0x8888888d 0x8d878787 0x87888888 0x88888888 0x88888d8d 0x87878787 0x88888888
++                                              0x88888888 0x888d8d87 0x87878788 0x88888888 0x88888888 0x8d8d8787 0x00818181 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x82830000 0x00000000 0xc4c1c4c1 0x80c280c1
++                                              0xc180c1c2 0xc3c1c4c1 0xc1c280c3 0xc1c1c1c3 0xc4c4c5c1 0xc2c480c4 0xc3c2c2c2 0x80808080
++                                              0x80808080 0x80808080 0x00000000 0x00000000 0x00000000 0x80808080 0x80808080 0x80808080
++                                              0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080
++                                              0x80808080 0x00000000 0x00000000 0x00000000 0x85868685 0x80828481 0x87868584 0x82c1c286
++                                              0x87828387 0x85828d8d 0x8d909090 0x85838486 0x82808180 0x868480c1 0x80c1c284 0x86818086
++                                              0x81808d8d 0x8d909090 0x83848386 0x81c18080 0x87858280 0xc1c2c483 0x86808086 0x82808d8d
++                                              0x8d909090 0x8c8c8c8c 0x8c8c8c8c 0x8f8f8f8f 0x8f8f8d8e 0x8e8e8e91 0x91918d8d 0x8d909090
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x80808080
++                                              0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080
++                                              0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080
++                                              0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080 0x80808080
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x80808080 0x80808080 0x80808080 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000a00 0x000c0000 0x0d000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x2f7f7f7f 0x13110f2c 0x007f7f00 0x110a0000 0x2f7f7f7f 0x13110f2c 0x007f7f00 0x110a0000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
++                                              0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000>;
++              };
++      };
++};
diff --git a/target/linux/mediatek/patches-6.12/920-block-partitions-msdos-add-OF-node-by-partition-numb.patch b/target/linux/mediatek/patches-6.12/920-block-partitions-msdos-add-OF-node-by-partition-numb.patch
new file mode 100644 (file)
index 0000000..f2c3aa4
--- /dev/null
@@ -0,0 +1,98 @@
+From 391630263f08dc853b111c6c3325a0ec510fe5fb Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 9 May 2025 02:38:51 +0100
+Subject: [PATCH] block: partitions: msdos: add OF node by partition number
+
+A hack for some legacy boards...
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ block/partitions/msdos.c | 66 +++++++++++++++++++++++++++++++++-------
+ 1 file changed, 55 insertions(+), 11 deletions(-)
+
+--- a/block/partitions/msdos.c
++++ b/block/partitions/msdos.c
+@@ -27,6 +27,7 @@
+  */
+ #include <linux/msdos_fs.h>
+ #include <linux/msdos_partition.h>
++#include <linux/of.h>
+ #include "check.h"
+ #include "efi.h"
+@@ -116,6 +117,26 @@ static void set_info(struct parsed_parti
+       state->parts[slot].has_info = true;
+ }
++static struct device_node *find_partno_of_node(struct device_node *partitions_np,
++                                                int partno)
++{
++      int np_partno;
++
++      if (!partitions_np ||
++          !of_device_is_compatible(partitions_np, "msdos-partitions"))
++              return NULL;
++
++      for_each_available_child_of_node_scoped(partitions_np, np) {
++              if (!of_property_read_u32(np, "partno", &np_partno) &&
++                  partno != np_partno)
++                      continue;
++
++              return np;
++      }
++
++      return NULL;
++}
++
+ /*
+  * Create devices for each logical partition in an extended partition.
+  * The logical partitions form a linked list, with each entry being
+@@ -131,6 +152,8 @@ static void parse_extended(struct parsed
+                          sector_t first_sector, sector_t first_size,
+                          u32 disksig)
+ {
++      struct device *ddev = disk_to_dev(state->disk);
++      struct device_node *partitions_np = of_node_get(ddev->of_node);
+       struct msdos_partition *p;
+       Sector sect;
+       unsigned char *data;
+@@ -190,7 +213,8 @@ static void parse_extended(struct parsed
+                                       continue;
+                       }
+-                      put_partition(state, state->next, next, size);
++                      of_put_partition(state, state->next, next, size,
++                                       find_partno_of_node(partitions_np, state->next));
+                       set_info(state, state->next, disksig);
+                       if (p->sys_ind == LINUX_RAID_PARTITION)
+                               state->parts[state->next].flags = ADDPART_FLAG_RAID;
+@@ -580,6 +604,8 @@ static struct {
+ int msdos_partition(struct parsed_partitions *state)
+ {
++      struct device *ddev = disk_to_dev(state->disk);
++      struct device_node *partitions_np = of_node_get(ddev->of_node);
+       sector_t sector_size;
+       Sector sect;
+       unsigned char *data;
+@@ -676,14 +702,18 @@ int msdos_partition(struct parsed_partit
+                       sector_t n = 2;
+                       n = min(size, max(sector_size, n));
+-                      put_partition(state, slot, start, n);
++                      of_put_partition(state, slot, start, n,
++                                       find_partno_of_node(partitions_np,
++                                                           slot));
+                       strlcat(state->pp_buf, " <", PAGE_SIZE);
+                       parse_extended(state, start, size, disksig);
+                       strlcat(state->pp_buf, " >", PAGE_SIZE);
+                       continue;
+               }
+-              put_partition(state, slot, start, size);
++              of_put_partition(state, slot, start, size,
++                               find_partno_of_node(partitions_np,
++                                                   slot));
+               set_info(state, slot, disksig);
+               if (p->sys_ind == LINUX_RAID_PARTITION)
+                       state->parts[slot].flags = ADDPART_FLAG_RAID;
diff --git a/target/linux/mediatek/patches-6.12/930-spi-mt65xx-enable-sel-clk.patch b/target/linux/mediatek/patches-6.12/930-spi-mt65xx-enable-sel-clk.patch
new file mode 100644 (file)
index 0000000..b15dde1
--- /dev/null
@@ -0,0 +1,30 @@
+From 335c1e7cfdfd477a1106ca05c96ff8949ecd953f Mon Sep 17 00:00:00 2001
+From: Furong Xu <xfr@outlook.com>
+Date: Fri, 16 Dec 2022 21:13:37 +0800
+Subject: [PATCH] mediatek: enable sel_clk for spi-mt65xx
+
+Without explicitly enabling sel_clk, clk_disable_unused() will disable
+it when boot is done, causing CPU hang on SPI1 register access on MT7986.
+Explicitly enable sel_clk to make SPI1 functional.
+
+Signed-off-by: Furong Xu <xfr@outlook.com>
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -1237,8 +1237,15 @@ static int mtk_spi_probe(struct platform
+       if (ret < 0)
+               return dev_err_probe(dev, ret, "failed to enable hclk\n");
++      ret = clk_prepare_enable(mdata->sel_clk);
++      if (ret < 0) {
++              clk_disable_unprepare(mdata->spi_hclk);
++              return dev_err_probe(dev, ret, "failed to enable sel_clk\n");
++      }
++
+       ret = clk_prepare_enable(mdata->spi_clk);
+       if (ret < 0) {
++              clk_disable_unprepare(mdata->sel_clk);
+               clk_disable_unprepare(mdata->spi_hclk);
+               return dev_err_probe(dev, ret, "failed to enable spi_clk\n");
+       }
diff --git a/target/linux/mediatek/patches-6.12/940-net-ethernet-mtk_wed-rename-mtk_wed_get_memory_regio.patch b/target/linux/mediatek/patches-6.12/940-net-ethernet-mtk_wed-rename-mtk_wed_get_memory_regio.patch
new file mode 100644 (file)
index 0000000..465f0ea
--- /dev/null
@@ -0,0 +1,37 @@
+From 3cf212c4ce6cd72c09bc47f35f539ba0afd4d106 Mon Sep 17 00:00:00 2001
+Message-Id: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 12 Mar 2023 16:40:31 +0100
+Subject: [PATCH net-next 1/2] net: ethernet: mtk_wed: rename
+ mtk_wed_get_memory_region in mtk_wed_get_reserved_memory_region
+
+This is a preliminary patch to move wed ilm/dlm and cpuboot properties in
+dedicated dts nodes.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+@@ -234,8 +234,8 @@ int mtk_wed_mcu_msg_update(struct mtk_we
+ }
+ static int
+-mtk_wed_get_memory_region(struct mtk_wed_hw *hw, int index,
+-                        struct mtk_wed_wo_memory_region *region)
++mtk_wed_get_reserved_memory_region(struct mtk_wed_hw *hw, int index,
++                                 struct mtk_wed_wo_memory_region *region)
+ {
+       struct reserved_mem *rmem;
+       struct device_node *np;
+@@ -325,7 +325,7 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
+               if (index < 0)
+                       continue;
+-              ret = mtk_wed_get_memory_region(wo->hw, index, &mem_region[i]);
++              ret = mtk_wed_get_reserved_memory_region(wo->hw, index, &mem_region[i]);
+               if (ret)
+                       return ret;
+       }
diff --git a/target/linux/mediatek/patches-6.12/941-arm64-dts-mt7986-move-cpuboot-in-a-dedicated-node.patch b/target/linux/mediatek/patches-6.12/941-arm64-dts-mt7986-move-cpuboot-in-a-dedicated-node.patch
new file mode 100644 (file)
index 0000000..a75a297
--- /dev/null
@@ -0,0 +1,66 @@
+From 247e566e3459481f1fa98733534bfed767e18b42 Mon Sep 17 00:00:00 2001
+Message-Id: <247e566e3459481f1fa98733534bfed767e18b42.1678620342.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sat, 11 Mar 2023 16:32:41 +0100
+Subject: [PATCH net-next] arm64: dts: mt7986: move cpuboot in a dedicated node
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -121,12 +121,6 @@
+                       reg = <0 0x151f8000 0 0x2000>;
+                       no-map;
+               };
+-
+-              wo_boot: wo-boot@15194000 {
+-                      reg = <0 0x15194000 0 0x1000>;
+-                      no-map;
+-              };
+-
+       };
+       soc {
+@@ -533,10 +527,11 @@
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+                       memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>,
+-                                      <&wo_data>, <&wo_boot>;
++                                      <&wo_data>;
+                       memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
+-                                            "wo-data", "wo-boot";
++                                            "wo-data";
+                       mediatek,wo-ccif = <&wo_ccif0>;
++                      mediatek,wo-cpuboot = <&wo_cpuboot>;
+               };
+               wed1: wed@15011000 {
+@@ -546,10 +541,11 @@
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+                       memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>,
+-                                      <&wo_data>, <&wo_boot>;
++                                      <&wo_data>;
+                       memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
+-                                            "wo-data", "wo-boot";
++                                            "wo-data";
+                       mediatek,wo-ccif = <&wo_ccif1>;
++                      mediatek,wo-cpuboot = <&wo_cpuboot>;
+               };
+               eth: ethernet@15100000 {
+@@ -607,6 +603,11 @@
+                       interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+               };
++              wo_cpuboot: syscon@15194000 {
++                      compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
++                      reg = <0 0x15194000 0 0x1000>;
++              };
++
+               wifi: wifi@18000000 {
+                       compatible = "mediatek,mt7986-wmac";
+                       reg = <0 0x18000000 0 0x1000000>,
diff --git a/target/linux/mediatek/patches-6.12/942-net-ethernet-mtk_wed-move-cpuboot-in-a-dedicated-dts.patch b/target/linux/mediatek/patches-6.12/942-net-ethernet-mtk_wed-move-cpuboot-in-a-dedicated-dts.patch
new file mode 100644 (file)
index 0000000..43014c5
--- /dev/null
@@ -0,0 +1,103 @@
+From f292d1bf83ec160bef2532b58aa08f5b71041923 Mon Sep 17 00:00:00 2001
+Message-Id: <f292d1bf83ec160bef2532b58aa08f5b71041923.1678716918.git.lorenzo@kernel.org>
+In-Reply-To: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org>
+References: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sat, 11 Mar 2023 18:13:04 +0100
+Subject: [PATCH net-next 2/2] net: ethernet: mtk_wed: move cpuboot in a
+ dedicated dts node
+
+Since the cpuboot memory region is not part of the RAM SoC, move cpuboot
+in a deidicated syscon node.
+This patch helps to keep backward-compatibility with older version of
+uboot codebase where we have a limit of 8 reserved-memory dts child
+nodes.
+Keep backward-compatibility with older dts version where cpuboot was
+defined as reserved-memory child node.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 34 +++++++++++++++++----
+ drivers/net/ethernet/mediatek/mtk_wed_wo.h  |  3 +-
+ 2 files changed, 30 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+@@ -32,14 +32,25 @@ static struct mtk_wed_wo_memory_region m
+       },
+ };
+-static u32 wo_r32(u32 reg)
++static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg)
+ {
+-      return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
++      u32 val;
++
++      if (!wo->boot_regmap)
++              return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
++
++      if (regmap_read(wo->boot_regmap, reg, &val))
++              val = ~0;
++
++      return val;
+ }
+-static void wo_w32(u32 reg, u32 val)
++static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val)
+ {
+-      writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
++      if (wo->boot_regmap)
++              regmap_write(wo->boot_regmap, reg, val);
++      else
++              writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg);
+ }
+ static struct sk_buff *
+@@ -317,6 +328,9 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
+       u32 val, boot_cr;
+       int ret, i;
++      wo->boot_regmap = syscon_regmap_lookup_by_phandle(wo->hw->node,
++                                                        "mediatek,wo-cpuboot");
++
+       /* load firmware region metadata */
+       for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
+               int index = of_property_match_string(wo->hw->node,
+@@ -325,6 +339,9 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
+               if (index < 0)
+                       continue;
++              if (index == MTK_WED_WO_REGION_BOOT && !IS_ERR(wo->boot_regmap))
++                      continue;
++
+               ret = mtk_wed_get_reserved_memory_region(wo->hw, index, &mem_region[i]);
+               if (ret)
+                       return ret;
+@@ -373,13 +390,13 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
+               boot_cr = MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR;
+       else
+               boot_cr = MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
+-      wo_w32(boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
++      wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16);
+       /* wo firmware reset */
+-      wo_w32(MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
++      wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
+-      val = wo_r32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
++      val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
+             MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
+-      wo_w32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
++      wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
+ out:
+       release_firmware(fw);
+--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+@@ -231,6 +231,7 @@ struct mtk_wed_wo_queue {
+ struct mtk_wed_wo {
+       struct mtk_wed_hw *hw;
++      struct regmap *boot_regmap;
+       struct mtk_wed_wo_queue q_tx;
+       struct mtk_wed_wo_queue q_rx;
diff --git a/target/linux/mediatek/patches-6.12/943-net-ethernet-mtk_wed-move-ilm-a-dedicated-dts-node.patch b/target/linux/mediatek/patches-6.12/943-net-ethernet-mtk_wed-move-ilm-a-dedicated-dts-node.patch
new file mode 100644 (file)
index 0000000..641c259
--- /dev/null
@@ -0,0 +1,86 @@
+From f3565e6c2276411275e707a5442d3f69cc111273 Mon Sep 17 00:00:00 2001
+Message-Id: <f3565e6c2276411275e707a5442d3f69cc111273.1678718888.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 12 Mar 2023 18:51:47 +0100
+Subject: [PATCH net-next 1/3] net: ethernet: mtk_wed: move ilm a dedicated dts
+ node
+
+Since the ilm memory region is not part of the RAM SoC, move ilm in a
+deidicated syscon node.
+This patch helps to keep backward-compatibility with older version of
+uboot codebase where we have a limit of 8 reserved-memory dts child
+nodes.
+Keep backward-compatibility with older dts version where ilm was defined
+as reserved-memory child node.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 55 ++++++++++++++++++---
+ 1 file changed, 49 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+@@ -320,6 +320,39 @@ next:
+ }
+ static int
++mtk_wed_mcu_load_ilm(struct mtk_wed_wo *wo)
++{
++      struct mtk_wed_wo_memory_region *ilm_region;
++      struct resource res;
++      struct device_node *np;
++      int ret;
++
++      np = of_parse_phandle(wo->hw->node, "mediatek,wo-ilm", 0);
++      if (!np)
++              return 0;
++
++      ret = of_address_to_resource(np, 0, &res);
++      of_node_put(np);
++
++      if (ret < 0)
++              return ret;
++
++      ilm_region = &mem_region[MTK_WED_WO_REGION_ILM];
++      ilm_region->phy_addr = res.start;
++      ilm_region->size = resource_size(&res);
++      ilm_region->addr = devm_ioremap(wo->hw->dev, res.start,
++                                      resource_size(&res));
++
++      if (!IS_ERR(ilm_region->addr))
++              return 0;
++
++      ret = PTR_ERR(ilm_region->addr);
++      ilm_region->addr = NULL;
++
++      return ret;
++}
++
++static int
+ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
+ {
+       const struct mtk_wed_fw_trailer *trailer;
+@@ -328,14 +361,20 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
+       u32 val, boot_cr;
+       int ret, i;
++      mtk_wed_mcu_load_ilm(wo);
+       wo->boot_regmap = syscon_regmap_lookup_by_phandle(wo->hw->node,
+                                                         "mediatek,wo-cpuboot");
+       /* load firmware region metadata */
+       for (i = 0; i < ARRAY_SIZE(mem_region); i++) {
+-              int index = of_property_match_string(wo->hw->node,
+-                                                   "memory-region-names",
+-                                                   mem_region[i].name);
++              int index;
++
++              if (mem_region[i].addr)
++                      continue;
++
++              index = of_property_match_string(wo->hw->node,
++                                               "memory-region-names",
++                                               mem_region[i].name);
+               if (index < 0)
+                       continue;
diff --git a/target/linux/mediatek/patches-6.12/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch b/target/linux/mediatek/patches-6.12/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch
new file mode 100644 (file)
index 0000000..a7a854d
--- /dev/null
@@ -0,0 +1,57 @@
+From b74ba226be2c45091b93bd49192bdd6d2178729e Mon Sep 17 00:00:00 2001
+Message-Id: <b74ba226be2c45091b93bd49192bdd6d2178729e.1678718888.git.lorenzo@kernel.org>
+In-Reply-To: <f3565e6c2276411275e707a5442d3f69cc111273.1678718888.git.lorenzo@kernel.org>
+References: <f3565e6c2276411275e707a5442d3f69cc111273.1678718888.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Mon, 13 Mar 2023 15:45:16 +0100
+Subject: [PATCH net-next 3/3] net: ethernet: mtk_wed: move dlm a dedicated dts
+ node
+
+Since the dlm memory region is not part of the RAM SoC, move dlm in a
+deidicated syscon node.
+This patch helps to keep backward-compatibility with older version of
+uboot codebase where we have a limit of 8 reserved-memory dts child
+nodes.
+Keep backward-compatibility with older dts version where dlm was defined
+as reserved-memory child node.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_wed.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -1333,6 +1333,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device
+       struct device_node *np;
+       int index;
++      np = of_parse_phandle(dev->hw->node, "mediatek,wo-dlm", 0);
++      if (np) {
++              struct resource res;
++              int ret;
++
++              ret = of_address_to_resource(np, 0, &res);
++              of_node_put(np);
++
++              if (ret < 0)
++                      return ret;
++
++              dev->rro.miod_phys = res.start;
++              goto out;
++      }
++
++      /* For backward compatibility, we need to check if DLM
++       * node is defined through reserved memory property.
++       */
+       index = of_property_match_string(dev->hw->node, "memory-region-names",
+                                        "wo-dlm");
+       if (index < 0)
+@@ -1349,6 +1367,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device
+               return -ENODEV;
+       dev->rro.miod_phys = rmem->base;
++out:
+       dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys;
+       return mtk_wed_rro_ring_alloc(dev, &dev->rro.ring,
diff --git a/target/linux/mediatek/patches-6.12/945-arm64-dts-mt7986-move-ilm-in-a-dedicated-node.patch b/target/linux/mediatek/patches-6.12/945-arm64-dts-mt7986-move-ilm-in-a-dedicated-node.patch
new file mode 100644 (file)
index 0000000..c64b3b3
--- /dev/null
@@ -0,0 +1,83 @@
+From 01561065af5bf1d2a4244896d897e3a1eafbcd46 Mon Sep 17 00:00:00 2001
+Message-Id: <01561065af5bf1d2a4244896d897e3a1eafbcd46.1678717704.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Mon, 13 Mar 2023 15:10:56 +0100
+Subject: [PATCH net-next] arm64: dts: mt7986: move ilm in a dedicated node
+
+Since the ilm memory region is not part of the RAM SoC, move ilm in a
+deidicated syscon node.
+This patch helps to keep backward-compatibility with older version of
+uboot codebase where we have a limit of 8 reserved-memory dts child
+nodes.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 34 +++++++++++------------
+ 1 file changed, 16 insertions(+), 18 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -97,16 +97,6 @@
+                       no-map;
+               };
+-              wo_ilm0: wo-ilm@151e0000 {
+-                      reg = <0 0x151e0000 0 0x8000>;
+-                      no-map;
+-              };
+-
+-              wo_ilm1: wo-ilm@151f0000 {
+-                      reg = <0 0x151f0000 0 0x8000>;
+-                      no-map;
+-              };
+-
+               wo_data: wo-data@4fd80000 {
+                       reg = <0 0x4fd80000 0 0x240000>;
+                       no-map;
+@@ -526,11 +516,10 @@
+                       reg = <0 0x15010000 0 0x1000>;
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+-                      memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>,
+-                                      <&wo_data>;
+-                      memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
+-                                            "wo-data";
++                      memory-region = <&wo_emi0>, <&wo_dlm0>, <&wo_data>;
++                      memory-region-names = "wo-emi", "wo-dlm", "wo-data";
+                       mediatek,wo-ccif = <&wo_ccif0>;
++                      mediatek,wo-ilm = <&wo_ilm0>;
+                       mediatek,wo-cpuboot = <&wo_cpuboot>;
+               };
+@@ -540,11 +529,10 @@
+                       reg = <0 0x15011000 0 0x1000>;
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+-                      memory-region = <&wo_emi1>, <&wo_ilm1>, <&wo_dlm1>,
+-                                      <&wo_data>;
+-                      memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
+-                                            "wo-data";
++                      memory-region = <&wo_emi1>, <&wo_dlm1>, <&wo_data>;
++                      memory-region-names = "wo-emi", "wo-dlm", "wo-data";
+                       mediatek,wo-ccif = <&wo_ccif1>;
++                      mediatek,wo-ilm = <&wo_ilm1>;
+                       mediatek,wo-cpuboot = <&wo_cpuboot>;
+               };
+@@ -603,6 +591,16 @@
+                       interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+               };
++              wo_ilm0: syscon@151e0000 {
++                      compatible = "mediatek,mt7986-wo-ilm", "syscon";
++                      reg = <0 0x151e0000 0 0x8000>;
++              };
++
++              wo_ilm1: syscon@151f0000 {
++                      compatible = "mediatek,mt7986-wo-ilm", "syscon";
++                      reg = <0 0x151f0000 0 0x8000>;
++              };
++
+               wo_cpuboot: syscon@15194000 {
+                       compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
+                       reg = <0 0x15194000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/946-arm64-dts-mt7986-move-dlm-in-a-dedicated-node.patch b/target/linux/mediatek/patches-6.12/946-arm64-dts-mt7986-move-dlm-in-a-dedicated-node.patch
new file mode 100644 (file)
index 0000000..13fe1f7
--- /dev/null
@@ -0,0 +1,81 @@
+From 9f76be683a8ec498563c294bc1cc279468058302 Mon Sep 17 00:00:00 2001
+Message-Id: <9f76be683a8ec498563c294bc1cc279468058302.1678719283.git.lorenzo@kernel.org>
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Mon, 13 Mar 2023 15:53:30 +0100
+Subject: [PATCH net-next] arm64: dts: mt7986: move dlm in a dedicated node
+
+Since the dlm memory region is not part of the RAM SoC, move dlm in a
+deidicated syscon node.
+This patch helps to keep backward-compatibility with older version of
+uboot codebase where we have a limit of 8 reserved-memory dts child
+nodes.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 30 ++++++++++++-----------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -101,16 +101,6 @@
+                       reg = <0 0x4fd80000 0 0x240000>;
+                       no-map;
+               };
+-
+-              wo_dlm0: wo-dlm@151e8000 {
+-                      reg = <0 0x151e8000 0 0x2000>;
+-                      no-map;
+-              };
+-
+-              wo_dlm1: wo-dlm@151f8000 {
+-                      reg = <0 0x151f8000 0 0x2000>;
+-                      no-map;
+-              };
+       };
+       soc {
+@@ -516,10 +506,11 @@
+                       reg = <0 0x15010000 0 0x1000>;
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+-                      memory-region = <&wo_emi0>, <&wo_dlm0>, <&wo_data>;
+-                      memory-region-names = "wo-emi", "wo-dlm", "wo-data";
++                      memory-region = <&wo_emi0>, <&wo_data>;
++                      memory-region-names = "wo-emi", "wo-data";
+                       mediatek,wo-ccif = <&wo_ccif0>;
+                       mediatek,wo-ilm = <&wo_ilm0>;
++                      mediatek,wo-dlm = <&wo_dlm0>;
+                       mediatek,wo-cpuboot = <&wo_cpuboot>;
+               };
+@@ -529,10 +520,11 @@
+                       reg = <0 0x15011000 0 0x1000>;
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+-                      memory-region = <&wo_emi1>, <&wo_dlm1>, <&wo_data>;
+-                      memory-region-names = "wo-emi", "wo-dlm", "wo-data";
++                      memory-region = <&wo_emi1>, <&wo_data>;
++                      memory-region-names = "wo-emi", "wo-data";
+                       mediatek,wo-ccif = <&wo_ccif1>;
+                       mediatek,wo-ilm = <&wo_ilm1>;
++                      mediatek,wo-dlm = <&wo_dlm1>;
+                       mediatek,wo-cpuboot = <&wo_cpuboot>;
+               };
+@@ -601,6 +593,16 @@
+                       reg = <0 0x151f0000 0 0x8000>;
+               };
++              wo_dlm0: syscon@151e8000 {
++                      compatible = "mediatek,mt7986-wo-dlm", "syscon";
++                      reg = <0 0x151e8000 0 0x2000>;
++              };
++
++              wo_dlm1: syscon@151f8000 {
++                      compatible = "mediatek,mt7986-wo-dlm", "syscon";
++                      reg = <0 0x151f8000 0 0x2000>;
++              };
++
+               wo_cpuboot: syscon@15194000 {
+                       compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
+                       reg = <0 0x15194000 0 0x1000>;
diff --git a/target/linux/mediatek/patches-6.12/950-smartrg-i2c-led-driver.patch b/target/linux/mediatek/patches-6.12/950-smartrg-i2c-led-driver.patch
new file mode 100644 (file)
index 0000000..5bc3deb
--- /dev/null
@@ -0,0 +1,44 @@
+From a270f61c00c7d5a62664b85baa56a8ab1a242f8d Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 17 Nov 2023 02:01:34 +0000
+Subject: [PATCH] mediatek: import driver for Adtran SmartRG RGBW LED
+
+Import driver for I2C-connected HolTek MCU controlling the RGBW LED
+found in Adtran SmartRG devices.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+---
+ drivers/leds/Kconfig  |   10 ++++++++++
+ drivers/leds/Makefile |    1 +
+ 2 files changed, 11 insertions(+)
+
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -977,6 +977,16 @@ source "drivers/leds/flash/Kconfig"
+ comment "RGB LED drivers"
+ source "drivers/leds/rgb/Kconfig"
++config LEDS_SMARTRG_LED
++      tristate "LED support for Adtran SmartRG"
++      depends on LEDS_CLASS && I2C && OF
++      help
++        This option enables support for the Adtran SmartRG platform
++        system LED driver.
++
++        To compile this driver as a module, choose M here: the module
++        will be called leds-smartrg-system.
++
+ comment "LED Triggers"
+ source "drivers/leds/trigger/Kconfig"
+--- a/drivers/leds/Makefile
++++ b/drivers/leds/Makefile
+@@ -81,6 +81,7 @@ obj-$(CONFIG_LEDS_POWERNV)           += leds-powe
+ obj-$(CONFIG_LEDS_PWM)                        += leds-pwm.o
+ obj-$(CONFIG_LEDS_REGULATOR)          += leds-regulator.o
+ obj-$(CONFIG_LEDS_SC27XX_BLTC)                += leds-sc27xx-bltc.o
++obj-$(CONFIG_LEDS_SMARTRG_LED)                += leds-smartrg-system.o
+ obj-$(CONFIG_LEDS_ST1202)             += leds-st1202.o
+ obj-$(CONFIG_LEDS_SUN50I_A100)                += leds-sun50i-a100.o
+ obj-$(CONFIG_LEDS_SUNFIRE)            += leds-sunfire.o
diff --git a/target/linux/mediatek/patches-6.12/955-dts-mt7968a-bpi-r3-add-label-to-gmac-for-sfp1-port.patch b/target/linux/mediatek/patches-6.12/955-dts-mt7968a-bpi-r3-add-label-to-gmac-for-sfp1-port.patch
new file mode 100644 (file)
index 0000000..b0c3bc0
--- /dev/null
@@ -0,0 +1,24 @@
+From 84fc59c0d5285a0a0fe50e3cb2a85f6224362c55 Mon Sep 17 00:00:00 2001
+From: Jonas Jelonek <jelonek.jonas@gmail.com>
+Date: Sun, 10 Nov 2024 00:43:23 +0000
+Subject: [PATCH] mediatek: filogic: bpi-r3: set netdev-name for sfp1 port
+
+Sets openwrt,netdev-name for the gmac1 node in the dts of BPI-R3, which
+corresponds to the sfp1 slot, to have a proper naming and match the
+label on the official BPI-R3 metal case. This renames the port from eth1
+to sfp1.
+The COMPAT_VERSION is increased to denote that configuration has to be
+adjusted manually.
+
+Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -195,6 +195,7 @@
+               phy-mode = "2500base-x";
+               sfp = <&sfp1>;
+               managed = "in-band-status";
++              openwrt,netdev-name = "sfp1";
+       };
+       mdio: mdio-bus {
diff --git a/target/linux/mediatek/patches-6.12/960-asus-hack-u-boot-ignore-mtdparts.patch b/target/linux/mediatek/patches-6.12/960-asus-hack-u-boot-ignore-mtdparts.patch
new file mode 100644 (file)
index 0000000..da27916
--- /dev/null
@@ -0,0 +1,47 @@
+From 30a04cf5b6ffa1249df72ccd98cef05f37890f89 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 6 Feb 2025 05:07:20 +0000
+Subject: [PATCH] mtd: spinand: add work-around to prevent bootloader wiping
+ mtdparts
+
+ASUS makes use of U-Boot's fdt_fixup_mtdparts() function which applies
+the partitions defined in U-Boot's mtdparts and mtdids environment
+variables to the devicetree passed over to Linux.
+
+The undesired side-effect is that in this way also all additional
+properties and child nodes get wiped, preventing NVMEM cells to be
+defined for MTD partitions or UBI volumes.
+
+To work-around this issue, add an additional compatible string
+'u-boot-dont-touch-spi-nand' which can be used instead of 'spi-nand' in
+case the replacement of the MTD partitions by U-Boot should be skipped
+alltogether.
+
+In practise this is mostly relevant for SPI-NAND which anyway comes only
+with two partitions nowadays: 'Bootloader' and 'UBI_DEV'. Hence this
+work-around is applicable for SPI-NAND only. Similar work-arounds for
+other MTD devices can be created as well should they actually be needed.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/mtd/nand/spi/core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1698,6 +1698,7 @@ static int spinand_remove(struct spi_mem
+ static const struct spi_device_id spinand_ids[] = {
+       { .name = "spi-nand" },
++      { .name = "u-boot-dont-touch-spi-nand" },
+       { /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(spi, spinand_ids);
+@@ -1705,6 +1706,7 @@ MODULE_DEVICE_TABLE(spi, spinand_ids);
+ #ifdef CONFIG_OF
+ static const struct of_device_id spinand_of_ids[] = {
+       { .compatible = "spi-nand" },
++      { .compatible = "u-boot-dont-touch-spi-nand" },
+       { /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(of, spinand_of_ids);
diff --git a/target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch b/target/linux/mediatek/patches-6.12/965-dts-mt7988a-add-trng-support.patch
new file mode 100644 (file)
index 0000000..1c3eb58
--- /dev/null
@@ -0,0 +1,30 @@
+From afcec128c572eb1064472b772ffba3f44e2dbfeb Mon Sep 17 00:00:00 2001
+From: Marcos Alano <marcoshalano@gmail.com>
+Date: Sun, 14 Sep 2025 22:32:12 -0300
+Subject: [PATCH] mediatek: add support for trng on mt7988a
+
+Add support for trng on mt7988a.
+
+Tested on Banana Pi BPI-R4.
+
+Signed-off-by: Marcos Alano <marcoshalano@gmail.com>
+---
+arm64: dts: mediatek: mt7988: add trng node
+
+Add support for trng on mt7988a.
+
+Tested on Banana Pi BPI-R4.
+
+Signed-off-by: Marcos Alano <marcoshalano@gmail.com>
+---
+--- a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
+@@ -1327,4 +1327,8 @@
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+       };
++
++      trng {
++              compatible = "mediatek,mt7988-rng";
++      };
+ };
diff --git a/target/linux/mediatek/patches-6.12/966-pcie-mediatek-gen3-Add-WIFI-HW-reset-flow.patch b/target/linux/mediatek/patches-6.12/966-pcie-mediatek-gen3-Add-WIFI-HW-reset-flow.patch
new file mode 100644 (file)
index 0000000..ae60a96
--- /dev/null
@@ -0,0 +1,88 @@
+From f566462daef92eb0074013e32d0332116fc3a2eb Mon Sep 17 00:00:00 2001
+From: Jianguo Zhang <jianguo.zhang@mediatek.com>
+Date: Tue, 14 Oct 2025 16:00:03 +0800
+Subject: [PATCH] pcie: mediatek-gen3: Add WIFI HW reset flow
+
+[Description]
+Add WIFI HW reset before PCIe host detects EP device for reboot.
+
+[Release-log]
+NA
+
+Signed-off-by: Jianguo Zhang <jianguo.zhang@mediatek.com>
+---
+ drivers/pci/controller/pcie-mediatek-gen3.c | 29 +++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/drivers/pci/controller/pcie-mediatek-gen3.c
++++ b/drivers/pci/controller/pcie-mediatek-gen3.c
+@@ -10,6 +10,8 @@
+ #include <linux/clk.h>
+ #include <linux/clk-provider.h>
+ #include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/iopoll.h>
+ #include <linux/irq.h>
+ #include <linux/irqchip/chained_irq.h>
+@@ -18,6 +20,7 @@
+ #include <linux/module.h>
+ #include <linux/msi.h>
+ #include <linux/of_device.h>
++#include <linux/of_gpio.h>
+ #include <linux/of_pci.h>
+ #include <linux/pci.h>
+ #include <linux/phy/phy.h>
+@@ -160,6 +163,8 @@ struct mtk_msi_set {
+  * @phy: PHY controller block
+  * @clks: PCIe clocks
+  * @num_clks: PCIe clocks count for this port
++ * @wifi_reset: reset pin for WIFI chip
++ * @wifi_reset_delay_ms: delay time for WIFI chip reset
+  * @irq: PCIe controller interrupt number
+  * @saved_irq_state: IRQ enable state saved at suspend time
+  * @irq_lock: lock protecting IRQ register access
+@@ -181,6 +186,9 @@ struct mtk_gen3_pcie {
+       struct clk_bulk_data *clks;
+       int num_clks;
++      struct gpio_desc *wifi_reset;
++      u32 wifi_reset_delay_ms;
++
+       int irq;
+       u32 saved_irq_state;
+       raw_spinlock_t irq_lock;
+@@ -402,6 +410,12 @@ static int mtk_pcie_startup_port(struct
+       val |= PCIE_DISABLE_DVFSRC_VLT_REQ;
+       writel_relaxed(val, pcie->base + PCIE_MISC_CTRL_REG);
++      if (pcie->wifi_reset) {
++              gpiod_set_value_cansleep(pcie->wifi_reset, 1);
++              msleep(pcie->wifi_reset_delay_ms);
++              gpiod_set_value_cansleep(pcie->wifi_reset, 0);
++      }
++
+       /* Assert all reset signals */
+       val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
+       val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB;
+@@ -864,6 +878,20 @@ static int mtk_pcie_parse_port(struct mt
+               return pcie->num_clks;
+       }
++      ret = of_property_read_u32(dev->of_node, "wifi-reset-msleep",
++                                 &pcie->wifi_reset_delay_ms);
++      if (!ret) {
++              pcie->wifi_reset = devm_gpiod_get_optional(dev, "wifi-reset",
++                                                         GPIOD_OUT_LOW);
++              if (IS_ERR(pcie->wifi_reset)) {
++                      ret = PTR_ERR(pcie->wifi_reset);
++                      if (ret != -EPROBE_DEFER)
++                              dev_err(dev,
++                                      "failed to request WIFI reset gpio\n");
++                      return ret;
++              }
++      }
++
+       return 0;
+ }
index a04a36dd90b168f60d78c0a64369c7b2d96e40e1..341055e5d81bc0e85f2705365c1a9f0493fccb2a 100644 (file)
@@ -1,7 +1,7 @@
 From afcec128c572eb1064472b772ffba3f44e2dbfeb Mon Sep 17 00:00:00 2001
 From: Marcos Alano <marcoshalano@gmail.com>
 Date: Sun, 14 Sep 2025 22:32:12 -0300
-Subject: [PATCH] mediatek: add support for trng on mt7988a
+Subject: [PATCH] arm64: dts: mediatek: mt7988: add trng node
 
 Add support for trng on mt7988a.