mediatek: copy patches-6.1 to patches-6.6
authorDaniel Golle <daniel@makrotopia.org>
Fri, 1 Mar 2024 01:56:57 +0000 (01:56 +0000)
committerDaniel Golle <daniel@makrotopia.org>
Mon, 11 Mar 2024 21:22:12 +0000 (21:22 +0000)
Copy patches from patches-6.1 to patches-6.6. No changes.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
204 files changed:
target/linux/mediatek/patches-6.6/000-v6.2-kbuild-Allow-DTB-overlays-to-built-from-.dtso-named-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/001-v6.2-arm64-dts-mediatek-mt7986-add-support-for-RX-Wireles.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/002-v6.2-arm64-dts-mt7986-harmonize-device-node-order.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/003-v6.2-arm64-dts-mt7986-add-crypto-related-device-nodes.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/004-v6.2-arm64-dts-mt7986-add-i2c-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/005-v6.2-arm64-dts-mediatek-mt7986-Add-SoC-compatible.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/006-v6.2-arm64-dts-mt7986-add-spi-related-device-nodes.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/007-v6.3-arm64-dts-mt7986-add-usb-related-device-nodes.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/008-v6.3-arm64-dts-mt7986-add-mmc-related-device-nodes.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/009-v6.3-arm64-dts-mt7986-add-pcie-related-device-nodes.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/010-v6.3-arm64-dts-mt7986-add-Bananapi-R3.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/011-v6.5-arm64-mediatek-Propagate-chassis-type-where-possible.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/012-v6.5-arm64-dts-mt7986-add-PWM.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/013-v6.5-arm64-dts-mt7986-add-PWM-to-BPI-R3.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/014-v6.5-arm64-dts-mt7986-set-Wifi-Leds-low-active-for-BPI-R3.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/015-v6.5-arm64-dts-mt7986-use-size-of-reserved-partition-for-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/016-v6.5-arm64-dts-mt7986-add-thermal-and-efuse.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/017-v6.5-arm64-dts-mt7986-add-thermal-zones.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/018-v6.5-arm64-dts-mt7986-add-pwm-fan-and-cooling-maps-to-BPI.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/019-v6.5-arm64-dts-mt7986-increase-bl2-partition-on-NAND-of-B.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/020-v6.7-arm64-dts-mt7986-define-3W-max-power-to-both-SFP-on-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/021-v6.7-arm64-dts-mt7986-change-cooling-trips.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/022-v6.7-arm64-dts-mt7986-change-thermal-trips-on-BPI-R3.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/100-dts-update-mt7622-rfb1.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/101-dts-update-mt7629-rfb.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/103-mt7623-enable-arch-timer.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/104-mt7622-add-snor-irq.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/105-dts-mt7622-enable-pstore.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/106-dts-mt7622-disable_btif.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/110-dts-fix-bpi2-console.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/111-dts-fix-bpi64-console.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/112-dts-fix-bpi64-lan-names.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/113-dts-fix-bpi64-leds-and-buttons.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/114-dts-bpi64-disable-rtc.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/115-v6.5-arm64-dts-mt7622-declare-SPI-NAND-present-on-BPI-R64.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/121-hack-spi-nand-1b-bbm.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/130-dts-mt7629-add-snand-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/131-dts-mt7622-add-snand-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/140-dts-fix-wmac-support-for-mt7622-rfb1.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/150-dts-mt7623-eip97-inside-secure-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/160-dts-mt7623-bpi-r2-earlycon.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/161-dts-mt7623-bpi-r2-mmc-device-order.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/162-dts-mt7623-bpi-r2-led-aliases.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/163-dts-mt7623-bpi-r2-ethernet-alias.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/164-dts-mt7623-bpi-r2-rootdisk-for-fitblk.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/180-v6.5-arm64-dts-mt7622-handle-interrupts-from-MT7531-switc.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/190-arm64-dts-mediatek-mt7622-fix-GICv2-range.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/193-dts-mt7623-thermal_zone_fix.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/194-dts-mt7968a-add-ramoops.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/195-dts-mt7986a-bpi-r3-leds-port-names-and-wifi-eeprom.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/196-dts-mt7986a-bpi-r3-use-all-ubi-nand-layout.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/200-phy-phy-mtk-tphy-Add-hifsys-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/210-v6.2-pinctrl-mt7986-allow-configuring-uart-rx-tx-and-rts-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/211-v6.2-pinctrl-mediatek-add-pull_type-attribute-for-mediate.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/215-v6.3-pinctrl-add-mt7981-pinctrl-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/216-v6.3-pinctrl-mediatek-add-missing-options-to-PINCTRL_MT79.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/217-v6.5-pinctrl-mediatek-fix-pull_type-data-for-MT7981.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/218-pinctrl-mediatek-mt7981-add-additional-uart-groups.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/219-v6.6-pinctrl-mediatek-assign-functions-to-configure-pin-b.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/220-v6.3-clk-mediatek-clk-gate-Propagate-struct-device-with-m.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/221-v6.3-clk-mediatek-cpumux-Propagate-struct-device-where-po.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/222-v6.3-clk-mediatek-clk-mtk-Propagate-struct-device-for-com.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/223-v6.3-clk-mediatek-clk-mux-Propagate-struct-device-for-mtk.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/224-v6.3-clk-mediatek-clk-mtk-Add-dummy-clock-ops.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/225-v6.3-clk-mediatek-Switch-to-mtk_clk_simple_probe-where-po.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/226-v6.3-clk-mediatek-clk-mtk-Extend-mtk_clk_simple_probe.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/227-v6.3-clk-mediatek-clk-mt7986-topckgen-Properly-keep-some-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/228-v6.3-clk-mediatek-clk-mt7986-topckgen-Migrate-to-mtk_clk_.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/229-v6.4-clk-mediatek-mt7986-apmixed-Use-PLL_AO-flag-to-set-c.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/230-v6.4-dt-bindings-clock-mediatek-add-mt7981-clock-IDs.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/231-v6.4-clk-mediatek-add-MT7981-clock-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/232-clk-mediatek-mt7981-topckgen-flag-SGM_REG_SEL-as-cri.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/240-pinctrl-mediatek-add-support-for-MT7988-SoC.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/241-v6.3-dt-bindings-clock-Add-compatibles-for-MT7981.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/242-v6.4-dt-bindings-arm-mediatek-sgmiisys-Convert-to-DT-sche.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/243-v6.4-dt-bindings-net-pcs-mediatek-sgmiisys-add-MT7981-SoC.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/244-v6.8-dt-bindings-arm-mediatek-move-ethsys-controller-conv.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/245-v6.8-dt-bindings-reset-mediatek-add-MT7988-ethwarp-reset-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/246-v6.8-dt-bindings-clock-mediatek-add-MT7988-clock-IDs.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/247-v6.8-dt-bindings-clock-mediatek-add-clock-controllers-of-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/248-v6.8-clk-mediatek-add-pcw_chg_bit-control-for-PLLs-of-MT7.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/249-v6.8-clk-mediatek-add-drivers-for-MT7988-SoC.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/250-clk-mediatek-add-infracfg-reset-controller-for-mt798.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/250-dt-bindings-reset-mediatek-add-MT7988-reset-IDs.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/251-v6.8-watchdog-mediatek-mt7988-add-wdt-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/252-clk-mediatek-mt7988-infracfg-fix-clocks-for-2nd-PCIe.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/320-v6.2-mmc-mediatek-add-support-for-MT7986-SoC.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/321-v6.2-mmc-mtk-sd-add-Inline-Crypto-Engine-clock-control.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/322-v6.2-mmc-mtk-sd-fix-two-spelling-mistakes-in-comment.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/323-v6.2-mmc-Avoid-open-coding-by-using-mmc_op_tuning.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/331-mt7622-rfb1-enable-bmt.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/400-crypto-add-eip97-inside-secure-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/401-crypto-fix-eip97-cache-incoherent.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/405-v6.2-mt7986-trng-add-rng-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/410-bt-mtk-serial-fix.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/431-drivers-spi-mt65xx-Move-chip_config-to-driver-s-priv.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/433-drivers-spi-mem-Add-spi-calibration-hook.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/434-drivers-spi-mt65xx-Add-controller-s-calibration-para.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/500-gsw-rtl8367s-mt7622-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/601-PCI-mediatek-Assert-PERST-for-100ms-for-power-and-cl.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/610-pcie-mediatek-fix-clearing-interrupt-status.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/611-pcie-mediatek-gen3-PERST-for-100ms.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/721-dts-mt7622-mediatek-fix-300mhz.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/722-remove-300Hz-to-prevent-freeze.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/730-v6.5-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/731-v6.5-net-phy-mediatek-ge-soc-support-PHY-LEDs.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/734-v6.8-net-phy-mediatek-ge-soc-sync-driver-with-MediaTek-SD.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/804-v6.2-pwm-add-mt7986-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/826-v6.2-pinctrl-mediatek-extend-pinctrl-moore-to-support-new.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.3-01-thermal-drivers-mtk_thermal-Fix-kernel-doc-function-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.3-02-thermal-drivers-mtk_thermal-Use-devm_platform_get_an.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.3-03-thermal-drivers-mtk-Use-function-pointer-for-raw_to_.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.3-04-thermal-drivers-mtk-Add-support-for-MT7986-and-MT798.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.3-05-thermal-drivers-mediatek-Relocate-driver-to-mediatek.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.3-06-thermal-drivers-mediatek-Add-the-Low-Voltage-Thermal.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-07-dt-bindings-thermal-mediatek-Add-LVTS-thermal-contro.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-08-dt-bindings-thermal-mediatek-Add-AP-domain-to-LVTS-t.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-09-thermal-core-Add-a-thermal-zone-devdata-accessor.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-10-thermal-core-Add-thermal_zone_device-structure-type-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-11-thermal-core-Use-the-thermal-zone-devdata-accessor-i.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-12-thermal-hwmon-Use-the-right-device-for-devm_thermal_.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-13-thermal-Don-t-use-device-internal-thermal-zone-struc.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-14-thermal-Use-thermal_zone_device_type-accessor.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-15-thermal-drivers-mediatek-Control-buffer-enablement-t.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-16-thermal-drivers-mediatek-Add-support-for-MT8365-SoC.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-17-thermal-drivers-mediatek-Add-delay-after-thermal-ban.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-18-thermal-drivers-mediatek-lvts_thermal-Fix-sensor-1-i.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-19-thermal-drivers-mediatek-lvts_thermal-Add-AP-domain-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-20-Revert-thermal-drivers-mediatek-Add-delay-after-ther.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-21-thermal-drivers-mediatek-Add-temperature-constraints.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-22-thermal-drivers-mediatek-Use-devm_of_iomap-to-avoid-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-23-thermal-drivers-mediatek-Change-clk_prepare_enable-t.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-24-thermal-drivers-mediatek-Use-of_address_to_resource.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-25-Revert-thermal-drivers-mediatek-Use-devm_of_iomap-to.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-26-thermal-drivers-mediatek-lvts_thermal-Register-therm.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-27-thermal-drivers-mediatek-lvts_thermal-Remove-redunda.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-29-thermal-drivers-mediatek-lvts_thermal-Handle-IRQ-on-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-30-thermal-drivers-mediatek-lvts_thermal-Honor-sensors-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-31-thermal-drivers-mediatek-lvts_thermal-Use-offset-thr.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-32-thermal-drivers-mediatek-lvts_thermal-Disable-undesi.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-33-thermal-drivers-mediatek-lvts_thermal-Don-t-leave-th.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-34-thermal-drivers-mediatek-lvts_thermal-Manage-thresho.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-35-thermal-drivers-mediatek-lvts-Fix-parameter-check-in.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-36-thermal-drivers-mediatek-Clean-up-redundant-dev_err_.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.4-37-thermal-drivers-mediatek-lvts_thermal-Make-readings-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.6-38-thermal-drivers-mediatek-auxadc_thermal-Removed-call.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-41-dt-bindings-thermal-mediatek-Add-LVTS-thermal-sensor.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-43-thermal-drivers-mediatek-lvts_thermal-Fix-error-chec.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-44-thermal-drivers-mediatek-Fix-probe-for-THERMAL_V2.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-46-dt-bindings-thermal-mediatek-Add-LVTS-thermal-contro.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/830-v6.7-48-thermal-drivers-mediatek-lvts_thermal-Update-calibra.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/831-thermal-drivers-mediatek-Fix-control-buffer-enablement-on-MT7896.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/851-v6.2-i2c-mediatek-add-mt7986-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/852-v6.3-i2c-mt65xx-Use-devm_platform_get_and_ioremap_resourc.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/853-v6.3-i2c-mt65xx-drop-of_match_ptr-for-ID-table.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/854-v6.4-i2c-mediatek-add-support-for-MT7981-SoC.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/855-i2c-mt65xx-allow-optional-pmic-clock.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.6-01-ASoC-mediatek-mt7986-add-common-header.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.6-02-ASoC-mediatek-mt7986-support-etdm-in-platform-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.6-03-ASoC-mediatek-mt7986-add-platform-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.6-04-ASoC-mediatek-mt7986-add-machine-driver-with-wm8960.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.6-05-ASoC-dt-bindings-mediatek-mt7986-wm8960-add-mt7986-w.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.6-06-ASoC-dt-bindings-mediatek-mt7986-afe-add-audio-afe-d.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.7-07-ASoC-mediatek-mt7986-drop-the-remove-callback-of-mt7.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.7-08-ASoC-mediatek-mt7986-remove-the-mt7986_wm8960_priv-s.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/860-v6.7-09-ASoC-mediatek-mt7986-add-sample-rate-checker.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/861-pending-10-ASoC-mediatek-mt7986-silence-error-in-case-of-EPROBE.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/862-arm64-dts-mt7986-add-afe.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/863-arm64-dts-mt7986-add-sound-wm8960.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/864-arm64-dts-mt7986-add-sound-overlay-for-bpi-r3.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/910-dts-mt7622-bpi-r64-wifi-eeprom.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/930-spi-mt65xx-enable-sel-clk.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/940-net-ethernet-mtk_wed-rename-mtk_wed_get_memory_regio.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/941-arm64-dts-mt7986-move-cpuboot-in-a-dedicated-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/942-net-ethernet-mtk_wed-move-cpuboot-in-a-dedicated-dts.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/943-net-ethernet-mtk_wed-move-ilm-a-dedicated-dts-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/945-arm64-dts-mt7986-move-ilm-in-a-dedicated-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/946-arm64-dts-mt7986-move-dlm-in-a-dedicated-node.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/950-smartrg-i2c-led-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/961-net-ethernet-mediatek-split-tx-and-rx-fields-in-mtk_.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/962-net-ethernet-mediatek-use-QDMA-instead-of-ADMAv2-on-.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.6/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch [new file with mode: 0644]

diff --git a/target/linux/mediatek/patches-6.6/000-v6.2-kbuild-Allow-DTB-overlays-to-built-from-.dtso-named-.patch b/target/linux/mediatek/patches-6.6/000-v6.2-kbuild-Allow-DTB-overlays-to-built-from-.dtso-named-.patch
new file mode 100644 (file)
index 0000000..17c5c60
--- /dev/null
@@ -0,0 +1,44 @@
+From 363547d2191cbc32ca954ba75d72908712398ff2 Mon Sep 17 00:00:00 2001
+From: Andrew Davis <afd@ti.com>
+Date: Mon, 24 Oct 2022 12:34:28 -0500
+Subject: [PATCH] kbuild: Allow DTB overlays to built from .dtso named source
+ files
+
+Currently DTB Overlays (.dtbo) are build from source files with the same
+extension (.dts) as the base DTs (.dtb). This may become confusing and
+even lead to wrong results. For example, a composite DTB (created from a
+base DTB and a set of overlays) might have the same name as one of the
+overlays that create it.
+
+Different files should be generated from differently named sources.
+ .dtb  <-> .dts
+ .dtbo <-> .dtso
+
+We do not remove the ability to compile DTBO files from .dts files here,
+only add a new rule allowing the .dtso file name. The current .dts named
+overlays can be renamed with time. After all have been renamed we can
+remove the other rule.
+
+Signed-off-by: Andrew Davis <afd@ti.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Frank Rowand <frowand.list@gmail.com>
+Tested-by: Frank Rowand <frowand.list@gmail.com>
+Link: https://lore.kernel.org/r/20221024173434.32518-2-afd@ti.com
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ scripts/Makefile.lib | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/scripts/Makefile.lib
++++ b/scripts/Makefile.lib
+@@ -408,6 +408,9 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_T
+ $(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE
+       $(call if_changed_dep,dtc)
++$(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE
++      $(call if_changed_dep,dtc)
++
+ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
+ # Bzip2
diff --git a/target/linux/mediatek/patches-6.6/001-v6.2-arm64-dts-mediatek-mt7986-add-support-for-RX-Wireles.patch b/target/linux/mediatek/patches-6.6/001-v6.2-arm64-dts-mediatek-mt7986-add-support-for-RX-Wireles.patch
new file mode 100644 (file)
index 0000000..970e0f9
--- /dev/null
@@ -0,0 +1,106 @@
+From 2c4daed9580164522859fa100128be408cc69be2 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sat, 5 Nov 2022 23:36:16 +0100
+Subject: [PATCH 01/19] arm64: dts: mediatek: mt7986: add support for RX
+ Wireless Ethernet Dispatch
+
+Similar to TX Wireless Ethernet Dispatch, introduce RX Wireless Ethernet
+Dispatch to offload traffic received by the wlan interface to lan/wan
+one.
+
+Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
+Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 65 +++++++++++++++++++++++
+ 1 file changed, 65 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -76,6 +76,47 @@
+                       no-map;
+                       reg = <0 0x4fc00000 0 0x00100000>;
+               };
++
++              wo_emi0: wo-emi@4fd00000 {
++                      reg = <0 0x4fd00000 0 0x40000>;
++                      no-map;
++              };
++
++              wo_emi1: wo-emi@4fd40000 {
++                      reg = <0 0x4fd40000 0 0x40000>;
++                      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;
++              };
++
++              wo_dlm0: wo-dlm@151e8000 {
++                      reg = <0 0x151e8000 0 0x2000>;
++                      no-map;
++              };
++
++              wo_dlm1: wo-dlm@151f8000 {
++                      reg = <0 0x151f8000 0 0x2000>;
++                      no-map;
++              };
++
++              wo_boot: wo-boot@15194000 {
++                      reg = <0 0x15194000 0 0x1000>;
++                      no-map;
++              };
++
+       };
+       timer {
+@@ -239,6 +280,11 @@
+                       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>, <&wo_boot>;
++                      memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
++                                            "wo-data", "wo-boot";
++                      mediatek,wo-ccif = <&wo_ccif0>;
+               };
+               wed1: wed@15011000 {
+@@ -247,6 +293,25 @@
+                       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>, <&wo_boot>;
++                      memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
++                                            "wo-data", "wo-boot";
++                      mediatek,wo-ccif = <&wo_ccif1>;
++              };
++
++              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>;
++              };
++
++              wo_ccif1: syscon@151ad000 {
++                      compatible = "mediatek,mt7986-wo-ccif", "syscon";
++                      reg = <0 0x151ad000 0 0x1000>;
++                      interrupt-parent = <&gic>;
++                      interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+               };
+               eth: ethernet@15100000 {
diff --git a/target/linux/mediatek/patches-6.6/002-v6.2-arm64-dts-mt7986-harmonize-device-node-order.patch b/target/linux/mediatek/patches-6.6/002-v6.2-arm64-dts-mt7986-harmonize-device-node-order.patch
new file mode 100644 (file)
index 0000000..b509168
--- /dev/null
@@ -0,0 +1,166 @@
+From 438e53828c08cf0e8a65b61cf6ce1e4b6620551a Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sun, 6 Nov 2022 09:50:24 +0100
+Subject: [PATCH 02/19] arm64: dts: mt7986: harmonize device node order
+
+This arrange device tree nodes in alphabetical order.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.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/r/20221106085034.12582-2-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 94 ++++++++++----------
+ arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 22 ++---
+ 2 files changed, 58 insertions(+), 58 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+@@ -54,6 +54,53 @@
+       };
+ };
++&pio {
++      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 = <4>;
++              };
++      };
++
++      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";
++                      drive-strength = <4>;
++              };
++      };
++};
++
+ &switch {
+       ports {
+               #address-cells = <1>;
+@@ -121,50 +168,3 @@
+       pinctrl-0 = <&wf_2g_5g_pins>;
+       pinctrl-1 = <&wf_dbdc_pins>;
+ };
+-
+-&pio {
+-      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 = <4>;
+-              };
+-      };
+-
+-      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";
+-                      drive-strength = <4>;
+-              };
+-      };
+-};
+--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+@@ -25,10 +25,6 @@
+       };
+ };
+-&uart0 {
+-      status = "okay";
+-};
+-
+ &eth {
+       status = "okay";
+@@ -99,13 +95,6 @@
+       };
+ };
+-&wifi {
+-      status = "okay";
+-      pinctrl-names = "default", "dbdc";
+-      pinctrl-0 = <&wf_2g_5g_pins>;
+-      pinctrl-1 = <&wf_dbdc_pins>;
+-};
+-
+ &pio {
+       wf_2g_5g_pins: wf-2g-5g-pins {
+               mux {
+@@ -138,3 +127,14 @@
+               };
+       };
+ };
++
++&uart0 {
++      status = "okay";
++};
++
++&wifi {
++      status = "okay";
++      pinctrl-names = "default", "dbdc";
++      pinctrl-0 = <&wf_2g_5g_pins>;
++      pinctrl-1 = <&wf_dbdc_pins>;
++};
diff --git a/target/linux/mediatek/patches-6.6/003-v6.2-arm64-dts-mt7986-add-crypto-related-device-nodes.patch b/target/linux/mediatek/patches-6.6/003-v6.2-arm64-dts-mt7986-add-crypto-related-device-nodes.patch
new file mode 100644 (file)
index 0000000..5706531
--- /dev/null
@@ -0,0 +1,68 @@
+From ffb05357b47f06b2b4d1e14ba89169e28feb727b Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sun, 6 Nov 2022 09:50:27 +0100
+Subject: [PATCH 03/19] arm64: dts: mt7986: add crypto related device nodes
+
+This patch adds crypto engine support for MT7986.
+
+Signed-off-by: Vic Wu <vic.wu@mediatek.com>
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20221106085034.12582-5-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts |  4 ++++
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi    | 15 +++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts |  4 ++++
+ 3 files changed, 23 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+@@ -25,6 +25,10 @@
+       };
+ };
++&crypto {
++      status = "okay";
++};
++
+ &eth {
+       status = "okay";
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -223,6 +223,21 @@
+                       status = "disabled";
+               };
++              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 = <&infracfg CLK_INFRA_EIP97_CK>;
++                      clock-names = "infra_eip97_ck";
++                      assigned-clocks = <&topckgen CLK_TOP_EIP_B_SEL>;
++                      assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>;
++                      status = "disabled";
++              };
++
+               uart0: serial@11002000 {
+                       compatible = "mediatek,mt7986-uart",
+                                    "mediatek,mt6577-uart";
+--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+@@ -25,6 +25,10 @@
+       };
+ };
++&crypto {
++      status = "okay";
++};
++
+ &eth {
+       status = "okay";
diff --git a/target/linux/mediatek/patches-6.6/004-v6.2-arm64-dts-mt7986-add-i2c-node.patch b/target/linux/mediatek/patches-6.6/004-v6.2-arm64-dts-mt7986-add-i2c-node.patch
new file mode 100644 (file)
index 0000000..0e5b77a
--- /dev/null
@@ -0,0 +1,37 @@
+From b49b7dc404ded1d89cbc568d875009a5c1ed4ef6 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 6 Nov 2022 09:50:29 +0100
+Subject: [PATCH 04/19] arm64: dts: mt7986: add i2c node
+
+Add i2c Node to mt7986 devicetree.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20221106085034.12582-7-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -279,6 +279,20 @@
+                       status = "disabled";
+               };
++              i2c0: i2c@11008000 {
++                      compatible = "mediatek,mt7986-i2c";
++                      reg = <0 0x11008000 0 0x90>,
++                            <0 0x10217080 0 0x80>;
++                      interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
++                      clock-div = <5>;
++                      clocks = <&infracfg CLK_INFRA_I2C0_CK>,
++                               <&infracfg CLK_INFRA_AP_DMA_CK>;
++                      clock-names = "main", "dma";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
+               ethsys: syscon@15000000 {
+                        #address-cells = <1>;
+                        #size-cells = <1>;
diff --git a/target/linux/mediatek/patches-6.6/005-v6.2-arm64-dts-mediatek-mt7986-Add-SoC-compatible.patch b/target/linux/mediatek/patches-6.6/005-v6.2-arm64-dts-mediatek-mt7986-Add-SoC-compatible.patch
new file mode 100644 (file)
index 0000000..8201b47
--- /dev/null
@@ -0,0 +1,61 @@
+From 2cd6022800d6da7822e169f3e6f7f790c1431445 Mon Sep 17 00:00:00 2001
+From: Matthias Brugger <mbrugger@suse.com>
+Date: Mon, 14 Nov 2022 13:16:53 +0100
+Subject: [PATCH 05/19] arm64: dts: mediatek: mt7986: Add SoC compatible
+
+Missing SoC compatible in the board file causes dt bindings check.
+
+Signed-off-by: Matthias Brugger <mbrugger@suse.com>
+Link: https://lore.kernel.org/r/20221114121653.14739-1-matthias.bgg@kernel.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 2 +-
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi    | 1 +
+ arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 2 +-
+ arch/arm64/boot/dts/mediatek/mt7986b.dtsi    | 3 +++
+ 4 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+@@ -9,7 +9,7 @@
+ / {
+       model = "MediaTek MT7986a RFB";
+-      compatible = "mediatek,mt7986a-rfb";
++      compatible = "mediatek,mt7986a-rfb", "mediatek,mt7986a";
+       aliases {
+               serial0 = &uart0;
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -10,6 +10,7 @@
+ #include <dt-bindings/reset/mt7986-resets.h>
+ / {
++      compatible = "mediatek,mt7986a";
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+@@ -9,7 +9,7 @@
+ / {
+       model = "MediaTek MT7986b RFB";
+-      compatible = "mediatek,mt7986b-rfb";
++      compatible = "mediatek,mt7986b-rfb", "mediatek,mt7986b";
+       aliases {
+               serial0 = &uart0;
+--- a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+@@ -5,6 +5,9 @@
+  */
+ #include "mt7986a.dtsi"
++/ {
++      compatible = "mediatek,mt7986b";
++};
+ &pio {
+       compatible = "mediatek,mt7986b-pinctrl";
diff --git a/target/linux/mediatek/patches-6.6/006-v6.2-arm64-dts-mt7986-add-spi-related-device-nodes.patch b/target/linux/mediatek/patches-6.6/006-v6.2-arm64-dts-mt7986-add-spi-related-device-nodes.patch
new file mode 100644 (file)
index 0000000..3e5e3d8
--- /dev/null
@@ -0,0 +1,157 @@
+From f4029538f063a845dc9aae46cce4cf386e6253a5 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 18 Nov 2022 20:01:21 +0100
+Subject: [PATCH 06/19] arm64: dts: mt7986: add spi related device nodes
+
+This patch adds spi support for MT7986.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.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/r/20221118190126.100895-7-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 35 ++++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi    | 28 ++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 35 ++++++++++++++++++++
+ 3 files changed, 98 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+@@ -59,6 +59,20 @@
+ };
+ &pio {
++      spi_flash_pins: spi-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0", "spi0_wp_hold";
++              };
++      };
++
++      spic_pins: spic-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi1_2";
++              };
++      };
++
+       uart1_pins: uart1-pins {
+               mux {
+                       function = "uart";
+@@ -105,6 +119,27 @@
+       };
+ };
++&spi0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spi_flash_pins>;
++      cs-gpios = <0>, <0>;
++      status = "okay";
++      spi_nand: spi_nand@0 {
++              compatible = "spi-nand";
++              reg = <0>;
++              spi-max-frequency = <10000000>;
++              spi-tx-bus-width = <4>;
++              spi-rx-bus-width = <4>;
++      };
++};
++
++&spi1 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spic_pins>;
++      cs-gpios = <0>, <0>;
++      status = "okay";
++};
++
+ &switch {
+       ports {
+               #address-cells = <1>;
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -294,6 +294,34 @@
+                       status = "disabled";
+               };
++              spi0: spi@1100a000 {
++                      compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      reg = <0 0x1100a000 0 0x100>;
++                      interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&topckgen CLK_TOP_MPLL_D2>,
++                               <&topckgen CLK_TOP_SPI_SEL>,
++                               <&infracfg CLK_INFRA_SPI0_CK>,
++                               <&infracfg CLK_INFRA_SPI0_HCK_CK>;
++                      clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
++                      status = "disabled";
++              };
++
++              spi1: spi@1100b000 {
++                      compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      reg = <0 0x1100b000 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_SPI1_CK>,
++                               <&infracfg CLK_INFRA_SPI1_HCK_CK>;
++                      clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
++                      status = "disabled";
++              };
++
+               ethsys: syscon@15000000 {
+                        #address-cells = <1>;
+                        #size-cells = <1>;
+--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+@@ -100,6 +100,20 @@
+ };
+ &pio {
++      spi_flash_pins: spi-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0", "spi0_wp_hold";
++              };
++      };
++
++      spic_pins: spic-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi1_2";
++              };
++      };
++
+       wf_2g_5g_pins: wf-2g-5g-pins {
+               mux {
+                       function = "wifi";
+@@ -132,6 +146,27 @@
+       };
+ };
++&spi0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spi_flash_pins>;
++      cs-gpios = <0>, <0>;
++      status = "okay";
++      spi_nand: spi_nand@0 {
++              compatible = "spi-nand";
++              reg = <0>;
++              spi-max-frequency = <10000000>;
++              spi-tx-bus-width = <4>;
++              spi-rx-bus-width = <4>;
++      };
++};
++
++&spi1 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spic_pins>;
++      cs-gpios = <0>, <0>;
++      status = "okay";
++};
++
+ &uart0 {
+       status = "okay";
+ };
diff --git a/target/linux/mediatek/patches-6.6/007-v6.3-arm64-dts-mt7986-add-usb-related-device-nodes.patch b/target/linux/mediatek/patches-6.6/007-v6.3-arm64-dts-mt7986-add-usb-related-device-nodes.patch
new file mode 100644 (file)
index 0000000..53567c6
--- /dev/null
@@ -0,0 +1,127 @@
+From 9e8e24ab716098e617195ce29b88e84608bf2108 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 6 Jan 2023 16:28:42 +0100
+Subject: [PATCH 07/19] arm64: dts: mt7986: add usb related device nodes
+
+This patch adds USB support for MT7986.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Link: https://lore.kernel.org/r/20230106152845.88717-3-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts |  8 +++
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi    | 55 ++++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts |  8 +++
+ 3 files changed, 71 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+@@ -140,6 +140,10 @@
+       status = "okay";
+ };
++&ssusb {
++      status = "okay";
++};
++
+ &switch {
+       ports {
+               #address-cells = <1>;
+@@ -201,6 +205,10 @@
+       status = "okay";
+ };
++&usb_phy {
++      status = "okay";
++};
++
+ &wifi {
+       status = "okay";
+       pinctrl-names = "default", "dbdc";
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -322,6 +322,61 @@
+                       status = "disabled";
+               };
++              ssusb: 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>,
++                             <&u2port1 PHY_TYPE_USB2>;
++                      status = "disabled";
++              };
++
++              usb_phy: t-phy@11e10000 {
++                      compatible = "mediatek,mt7986-tphy",
++                                   "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_DA_U2_REFSEL>,
++                                       <&topckgen CLK_TOP_DA_U2_CK_1P_SEL>;
++                              clock-names = "ref", "da_ref";
++                              #phy-cells = <1>;
++                      };
++
++                      u3port0: usb-phy@700 {
++                              reg = <0x700 0x900>;
++                              clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>;
++                              clock-names = "ref";
++                              #phy-cells = <1>;
++                      };
++
++                      u2port1: usb-phy@1000 {
++                              reg = <0x1000 0x700>;
++                              clocks = <&topckgen CLK_TOP_DA_U2_REFSEL>,
++                                       <&topckgen CLK_TOP_DA_U2_CK_1P_SEL>;
++                              clock-names = "ref", "da_ref";
++                              #phy-cells = <1>;
++                      };
++              };
++
+               ethsys: syscon@15000000 {
+                        #address-cells = <1>;
+                        #size-cells = <1>;
+--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+@@ -167,10 +167,18 @@
+       status = "okay";
+ };
++&ssusb {
++      status = "okay";
++};
++
+ &uart0 {
+       status = "okay";
+ };
++&usb_phy {
++      status = "okay";
++};
++
+ &wifi {
+       status = "okay";
+       pinctrl-names = "default", "dbdc";
diff --git a/target/linux/mediatek/patches-6.6/008-v6.3-arm64-dts-mt7986-add-mmc-related-device-nodes.patch b/target/linux/mediatek/patches-6.6/008-v6.3-arm64-dts-mt7986-add-mmc-related-device-nodes.patch
new file mode 100644 (file)
index 0000000..9c0a481
--- /dev/null
@@ -0,0 +1,160 @@
+From c1744e9e75a6a8abc7c893f349bcbf725b9c0d74 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 6 Jan 2023 16:28:43 +0100
+Subject: [PATCH 08/19] arm64: dts: mt7986: add mmc related device nodes
+
+This patch adds mmc support for MT7986.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20230106152845.88717-4-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 96 ++++++++++++++++++++
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi    | 15 +++
+ 2 files changed, 111 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+@@ -5,6 +5,8 @@
+  */
+ /dts-v1/;
++#include <dt-bindings/pinctrl/mt65xx.h>
++
+ #include "mt7986a.dtsi"
+ / {
+@@ -23,6 +25,24 @@
+               device_type = "memory";
+               reg = <0 0x40000000 0 0x40000000>;
+       };
++
++      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;
++      };
+ };
+ &crypto {
+@@ -58,7 +78,83 @@
+       };
+ };
++&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";
++};
++
+ &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 = <4>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
++              };
++              conf-clk {
++                      pins = "EMMC_CK";
++                      drive-strength = <6>;
++                      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 = <4>;
++                      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 = <4>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
++              };
++              conf-clk {
++                      pins = "EMMC_CK";
++                      drive-strength = <6>;
++                      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 = <4>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
++              };
++      };
++
+       spi_flash_pins: spi-flash-pins {
+               mux {
+                       function = "spi";
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -345,6 +345,21 @@
+                       status = "disabled";
+               };
++              mmc0: mmc@11230000 {
++                      compatible = "mediatek,mt7986-mmc";
++                      reg = <0 0x11230000 0 0x1000>,
++                            <0 0x11c20000 0 0x1000>;
++                      interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>,
++                               <&infracfg CLK_INFRA_MSDC_HCK_CK>,
++                               <&infracfg CLK_INFRA_MSDC_CK>,
++                               <&infracfg CLK_INFRA_MSDC_133M_CK>,
++                               <&infracfg CLK_INFRA_MSDC_66M_CK>;
++                      clock-names = "source", "hclk", "source_cg", "bus_clk",
++                                    "sys_cg";
++                      status = "disabled";
++              };
++
+               usb_phy: t-phy@11e10000 {
+                       compatible = "mediatek,mt7986-tphy",
+                                    "mediatek,generic-tphy-v2";
diff --git a/target/linux/mediatek/patches-6.6/009-v6.3-arm64-dts-mt7986-add-pcie-related-device-nodes.patch b/target/linux/mediatek/patches-6.6/009-v6.3-arm64-dts-mt7986-add-pcie-related-device-nodes.patch
new file mode 100644 (file)
index 0000000..adc6394
--- /dev/null
@@ -0,0 +1,118 @@
+From 87a42ef1d6cf602e4aa40555b4404cad6149a90f Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 6 Jan 2023 16:28:44 +0100
+Subject: [PATCH 09/19] arm64: dts: mt7986: add pcie related device nodes
+
+This patch adds PCIe support for MT7986.
+
+Signed-off-by: Jieyy Yang <jieyy.yang@mediatek.com>
+Signed-off-by: Sam Shih <sam.shih@mediatek.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/r/20230106152845.88717-5-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 16 ++++++
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi    | 52 ++++++++++++++++++++
+ 2 files changed, 68 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+@@ -93,6 +93,15 @@
+       non-removable;
+       no-sd;
+       no-sdio;
++};
++
++&pcie {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pcie_pins>;
++      status = "okay";
++};
++
++&pcie_phy {
+       status = "okay";
+ };
+@@ -155,6 +164,13 @@
+               };
+       };
++      pcie_pins: pcie-pins {
++              mux {
++                      function = "pcie";
++                      groups = "pcie_clk", "pcie_wake", "pcie_pereset";
++              };
++      };
++
+       spi_flash_pins: spi-flash-pins {
+               mux {
+                       function = "spi";
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -8,6 +8,7 @@
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/mt7986-clk.h>
+ #include <dt-bindings/reset/mt7986-resets.h>
++#include <dt-bindings/phy/phy.h>
+ / {
+       compatible = "mediatek,mt7986a";
+@@ -360,6 +361,57 @@
+                       status = "disabled";
+               };
++              pcie: pcie@11280000 {
++                      compatible = "mediatek,mt7986-pcie",
++                                   "mediatek,mt8192-pcie";
++                      device_type = "pci";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      reg = <0x00 0x11280000 0x00 0x4000>;
++                      reg-names = "pcie-mac";
++                      interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
++                      bus-range = <0x00 0xff>;
++                      ranges = <0x82000000 0x00 0x20000000 0x00
++                                0x20000000 0x00 0x10000000>;
++                      clocks = <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
++                               <&infracfg CLK_INFRA_IPCIE_CK>,
++                               <&infracfg CLK_INFRA_IPCIER_CK>,
++                               <&infracfg CLK_INFRA_IPCIEB_CK>;
++                      clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m";
++                      status = "disabled";
++
++                      phys = <&pcie_port PHY_TYPE_PCIE>;
++                      phy-names = "pcie-phy";
++
++                      #interrupt-cells = <1>;
++                      interrupt-map-mask = <0 0 0 0x7>;
++                      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 {
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                              interrupt-controller;
++                      };
++              };
++
++              pcie_phy: t-phy@11c00000 {
++                      compatible = "mediatek,mt7986-tphy",
++                                   "mediatek,generic-tphy-v2";
++                      #address-cells = <2>;
++                      #size-cells = <2>;
++                      ranges;
++                      status = "disabled";
++
++                      pcie_port: pcie-phy@11c00000 {
++                              reg = <0 0x11c00000 0 0x20000>;
++                              clocks = <&clk40m>;
++                              clock-names = "ref";
++                              #phy-cells = <1>;
++                      };
++              };
++
+               usb_phy: t-phy@11e10000 {
+                       compatible = "mediatek,mt7986-tphy",
+                                    "mediatek,generic-tphy-v2";
diff --git a/target/linux/mediatek/patches-6.6/010-v6.3-arm64-dts-mt7986-add-Bananapi-R3.patch b/target/linux/mediatek/patches-6.6/010-v6.3-arm64-dts-mt7986-add-Bananapi-R3.patch
new file mode 100644 (file)
index 0000000..38f159c
--- /dev/null
@@ -0,0 +1,689 @@
+From a751f7412e0098801673b80bc7a4738ae7d710ce Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 6 Jan 2023 16:28:45 +0100
+Subject: [PATCH 10/19] arm64: dts: mt7986: add Bananapi R3
+
+Add support for Bananapi R3 SBC.
+
+- SD/eMMC support (switching first 4 bits of data-bus with sw6/D)
+- SPI-NAND/NOR support (switched CS by sw5/C)
+- all rj45 ports and both SFP working (eth1/lan4)
+- all USB-Ports + SIM-Slot tested
+- i2c and all uarts tested
+- wifi tested (with eeprom calibration data)
+
+The device can boot from all 4 storage options. Both, SPI and MMC, can
+be switched using hardware switches on the board, see
+https://wiki.banana-pi.org/Banana_Pi_BPI-R3#Jumper_setting
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20230106152845.88717-6-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/Makefile         |   5 +
+ .../mt7986a-bananapi-bpi-r3-emmc.dtso         |  29 ++
+ .../mt7986a-bananapi-bpi-r3-nand.dtso         |  55 +++
+ .../mediatek/mt7986a-bananapi-bpi-r3-nor.dtso |  68 +++
+ .../mediatek/mt7986a-bananapi-bpi-r3-sd.dtso  |  23 +
+ .../dts/mediatek/mt7986a-bananapi-bpi-r3.dts  | 450 ++++++++++++++++++
+ 6 files changed, 630 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
+ create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+
+--- a/arch/arm64/boot/dts/mediatek/Makefile
++++ b/arch/arm64/boot/dts/mediatek/Makefile
+@@ -7,6 +7,11 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-ev
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3.dtb
++dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-emmc.dtbo
++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-rfb.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
+ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
+@@ -0,0 +1,29 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2021 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
++
++      fragment@0 {
++              target-path = "/soc/mmc@11230000";
++              __overlay__ {
++                      bus-width = <8>;
++                      max-frequency = <200000000>;
++                      cap-mmc-highspeed;
++                      mmc-hs200-1_8v;
++                      mmc-hs400-1_8v;
++                      hs400-ds-delay = <0x14014>;
++                      non-removable;
++                      no-sd;
++                      no-sdio;
++                      status = "okay";
++              };
++      };
++};
++
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso
+@@ -0,0 +1,55 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
++/*
++ * Authors: Daniel Golle <daniel@makrotopia.org>
++ *          Frank Wunderlich <frank-w@public-files.de>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
++
++      fragment@0 {
++              target-path = "/soc/spi@1100a000";
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      spi_nand: spi_nand@0 {
++                              compatible = "spi-nand";
++                              reg = <0>;
++                              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 = <0x0 0x80000>;
++                                              read-only;
++                                      };
++
++                                      partition@80000 {
++                                              label = "reserved";
++                                              reg = <0x80000 0x300000>;
++                                      };
++
++                                      partition@380000 {
++                                              label = "fip";
++                                              reg = <0x380000 0x200000>;
++                                              read-only;
++                                      };
++
++                                      partition@580000 {
++                                              label = "ubi";
++                                              reg = <0x580000 0x7a80000>;
++                                      };
++                              };
++                      };
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+@@ -0,0 +1,68 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
++/*
++ * Authors: Daniel Golle <daniel@makrotopia.org>
++ *          Frank Wunderlich <frank-w@public-files.de>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
++
++      fragment@0 {
++              target-path = "/soc/spi@1100a000";
++              __overlay__ {
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      flash@0 {
++                              compatible = "jedec,spi-nor";
++                              reg = <0>;
++                              spi-max-frequency = <10000000>;
++
++                              partitions {
++                                      compatible = "fixed-partitions";
++                                      #address-cells = <1>;
++                                      #size-cells = <1>;
++
++                                      partition@0 {
++                                              label = "bl2";
++                                              reg = <0x0 0x20000>;
++                                              read-only;
++                                      };
++
++                                      partition@20000 {
++                                              label = "reserved";
++                                              reg = <0x20000 0x20000>;
++                                      };
++
++                                      partition@40000 {
++                                              label = "u-boot-env";
++                                              reg = <0x40000 0x40000>;
++                                      };
++
++                                      partition@80000 {
++                                              label = "reserved2";
++                                              reg = <0x80000 0x80000>;
++                                      };
++
++                                      partition@100000 {
++                                              label = "fip";
++                                              reg = <0x100000 0x80000>;
++                                              read-only;
++                                      };
++
++                                      partition@180000 {
++                                              label = "recovery";
++                                              reg = <0x180000 0xa80000>;
++                                      };
++
++                                      partition@c00000 {
++                                              label = "fit";
++                                              reg = <0xc00000 0x1400000>;
++                                      };
++                              };
++                      };
++              };
++      };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-sd.dtso
+@@ -0,0 +1,23 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2021 MediaTek Inc.
++ * Author: Sam.Shih <sam.shih@mediatek.com>
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++      compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
++
++      fragment@0 {
++              target-path = "/soc/mmc@11230000";
++              __overlay__ {
++                      bus-width = <4>;
++                      max-frequency = <52000000>;
++                      cap-sd-highspeed;
++                      status = "okay";
++              };
++      };
++};
++
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -0,0 +1,450 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Copyright (C) 2021 MediaTek Inc.
++ * Authors: Sam.Shih <sam.shih@mediatek.com>
++ *          Frank Wunderlich <frank-w@public-files.de>
++ *          Daniel Golle <daniel@makrotopia.org>
++ */
++
++/dts-v1/;
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pinctrl/mt65xx.h>
++
++#include "mt7986a.dtsi"
++
++/ {
++      model = "Bananapi BPI-R3";
++      compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
++
++      aliases {
++              serial0 = &uart0;
++              ethernet0 = &gmac0;
++              ethernet1 = &gmac1;
++      };
++
++      chosen {
++              stdout-path = "serial0:115200n8";
++      };
++
++      dcin: regulator-12vd {
++              compatible = "regulator-fixed";
++              regulator-name = "12vd";
++              regulator-min-microvolt = <12000000>;
++              regulator-max-microvolt = <12000000>;
++              regulator-boot-on;
++              regulator-always-on;
++      };
++
++      gpio-keys {
++              compatible = "gpio-keys";
++
++              reset-key {
++                      label = "reset";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&pio 9 GPIO_ACTIVE_LOW>;
++              };
++
++              wps-key {
++                      label = "wps";
++                      linux,code = <KEY_WPS_BUTTON>;
++                      gpios = <&pio 10 GPIO_ACTIVE_LOW>;
++              };
++      };
++
++      /* i2c of the left SFP cage (wan) */
++      i2c_sfp1: i2c-gpio-0 {
++              compatible = "i2c-gpio";
++              sda-gpios = <&pio 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++              scl-gpios = <&pio 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++      };
++
++      /* i2c of the right SFP cage (lan) */
++      i2c_sfp2: i2c-gpio-1 {
++              compatible = "i2c-gpio";
++              sda-gpios = <&pio 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++              scl-gpios = <&pio 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++              i2c-gpio,delay-us = <2>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++      };
++
++      leds {
++              compatible = "gpio-leds";
++
++              green_led: led-0 {
++                      color = <LED_COLOR_ID_GREEN>;
++                      function = LED_FUNCTION_POWER;
++                      gpios = <&pio 69 GPIO_ACTIVE_HIGH>;
++                      default-state = "on";
++              };
++
++              blue_led: led-1 {
++                      color = <LED_COLOR_ID_BLUE>;
++                      function = LED_FUNCTION_STATUS;
++                      gpios = <&pio 86 GPIO_ACTIVE_HIGH>;
++                      default-state = "off";
++              };
++      };
++
++      reg_1p8v: regulator-1p8v {
++              compatible = "regulator-fixed";
++              regulator-name = "1.8vd";
++              regulator-min-microvolt = <1800000>;
++              regulator-max-microvolt = <1800000>;
++              regulator-boot-on;
++              regulator-always-on;
++              vin-supply = <&dcin>;
++      };
++
++      reg_3p3v: regulator-3p3v {
++              compatible = "regulator-fixed";
++              regulator-name = "3.3vd";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              regulator-boot-on;
++              regulator-always-on;
++              vin-supply = <&dcin>;
++      };
++
++      /* left SFP cage (wan) */
++      sfp1: sfp-1 {
++              compatible = "sff,sfp";
++              i2c-bus = <&i2c_sfp1>;
++              los-gpios = <&pio 46 GPIO_ACTIVE_HIGH>;
++              mod-def0-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
++              tx-disable-gpios = <&pio 20 GPIO_ACTIVE_HIGH>;
++              tx-fault-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
++      };
++
++      /* right SFP cage (lan) */
++      sfp2: sfp-2 {
++              compatible = "sff,sfp";
++              i2c-bus = <&i2c_sfp2>;
++              los-gpios = <&pio 31 GPIO_ACTIVE_HIGH>;
++              mod-def0-gpios = <&pio 47 GPIO_ACTIVE_LOW>;
++              tx-disable-gpios = <&pio 15 GPIO_ACTIVE_HIGH>;
++              tx-fault-gpios = <&pio 48 GPIO_ACTIVE_HIGH>;
++      };
++};
++
++&crypto {
++      status = "okay";
++};
++
++&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";
++              sfp = <&sfp1>;
++              managed = "in-band-status";
++      };
++
++      mdio: mdio-bus {
++              #address-cells = <1>;
++              #size-cells = <0>;
++      };
++};
++
++&mdio {
++      switch: switch@1f {
++              compatible = "mediatek,mt7531";
++              reg = <31>;
++              interrupt-controller;
++              #interrupt-cells = <1>;
++              interrupt-parent = <&pio>;
++              interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
++              reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>;
++      };
++};
++
++&mmc0 {
++      pinctrl-names = "default", "state_uhs";
++      pinctrl-0 = <&mmc0_pins_default>;
++      pinctrl-1 = <&mmc0_pins_uhs>;
++      vmmc-supply = <&reg_3p3v>;
++      vqmmc-supply = <&reg_1p8v>;
++};
++
++&i2c0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c_pins>;
++      status = "okay";
++};
++
++&pcie {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pcie_pins>;
++      status = "okay";
++};
++
++&pcie_phy {
++      status = "okay";
++};
++
++&pio {
++      i2c_pins: i2c-pins {
++              mux {
++                      function = "i2c";
++                      groups = "i2c";
++              };
++      };
++
++      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 = <4>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
++              };
++              conf-clk {
++                      pins = "EMMC_CK";
++                      drive-strength = <6>;
++                      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 = <4>;
++                      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 = <4>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
++              };
++              conf-clk {
++                      pins = "EMMC_CK";
++                      drive-strength = <6>;
++                      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 = <4>;
++                      bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
++              };
++      };
++
++      pcie_pins: pcie-pins {
++              mux {
++                      function = "pcie";
++                      groups = "pcie_clk", "pcie_pereset";
++              };
++      };
++
++      spi_flash_pins: spi-flash-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi0", "spi0_wp_hold";
++              };
++      };
++
++      spic_pins: spic-pins {
++              mux {
++                      function = "spi";
++                      groups = "spi1_0";
++              };
++      };
++
++      uart1_pins: uart1-pins {
++              mux {
++                      function = "uart";
++                      groups = "uart1_rx_tx";
++              };
++      };
++
++      uart2_pins: uart2-pins {
++              mux {
++                      function = "uart";
++                      groups = "uart2_0_rx_tx";
++              };
++      };
++
++      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 = <4>;
++              };
++      };
++
++      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 = <4>;
++              };
++      };
++
++      wf_led_pins: wf-led-pins {
++              mux {
++                      function = "led";
++                      groups = "wifi_led";
++              };
++      };
++};
++
++&spi0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spi_flash_pins>;
++      status = "okay";
++};
++
++&spi1 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spic_pins>;
++      status = "okay";
++};
++
++&ssusb {
++      status = "okay";
++};
++
++&switch {
++      ports {
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              port@0 {
++                      reg = <0>;
++                      label = "wan";
++              };
++
++              port@1 {
++                      reg = <1>;
++                      label = "lan0";
++              };
++
++              port@2 {
++                      reg = <2>;
++                      label = "lan1";
++              };
++
++              port@3 {
++                      reg = <3>;
++                      label = "lan2";
++              };
++
++              port@4 {
++                      reg = <4>;
++                      label = "lan3";
++              };
++
++              port5: port@5 {
++                      reg = <5>;
++                      label = "lan4";
++                      phy-mode = "2500base-x";
++                      sfp = <&sfp2>;
++                      managed = "in-band-status";
++              };
++
++              port@6 {
++                      reg = <6>;
++                      label = "cpu";
++                      ethernet = <&gmac0>;
++                      phy-mode = "2500base-x";
++
++                      fixed-link {
++                              speed = <2500>;
++                              full-duplex;
++                              pause;
++                      };
++              };
++      };
++};
++
++&trng {
++      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";
++};
++
++&watchdog {
++      status = "okay";
++};
++
++&wifi {
++      status = "okay";
++      pinctrl-names = "default", "dbdc";
++      pinctrl-0 = <&wf_2g_5g_pins>, <&wf_led_pins>;
++      pinctrl-1 = <&wf_dbdc_pins>, <&wf_led_pins>;
++};
++
diff --git a/target/linux/mediatek/patches-6.6/011-v6.5-arm64-mediatek-Propagate-chassis-type-where-possible.patch b/target/linux/mediatek/patches-6.6/011-v6.5-arm64-mediatek-Propagate-chassis-type-where-possible.patch
new file mode 100644 (file)
index 0000000..7903833
--- /dev/null
@@ -0,0 +1,323 @@
+From 4c2d5411f4b101f7aa0fd74f80109e3afd6dc967 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Wed, 17 May 2023 12:11:08 +0200
+Subject: [PATCH 11/19] arm64: mediatek: Propagate chassis-type where possible
+
+The chassis-type string identifies the form-factor of the system:
+add this property to all device trees of devices for which the form
+factor is known.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230517101108.205654-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt2712-evb.dts                      | 1 +
+ arch/arm64/boot/dts/mediatek/mt6755-evb.dts                      | 1 +
+ arch/arm64/boot/dts/mediatek/mt6779-evb.dts                      | 1 +
+ arch/arm64/boot/dts/mediatek/mt6795-evb.dts                      | 1 +
+ arch/arm64/boot/dts/mediatek/mt6797-evb.dts                      | 1 +
+ arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts                  | 1 +
+ arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts         | 1 +
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts                     | 1 +
+ arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts         | 1 +
+ arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts                     | 1 +
+ arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts                     | 1 +
+ arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts                  | 1 +
+ arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts            | 1 +
+ arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts                 | 1 +
+ arch/arm64/boot/dts/mediatek/mt8173-elm.dts                      | 1 +
+ arch/arm64/boot/dts/mediatek/mt8173-evb.dts                      | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-evb.dts                      | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts     | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts       | 1 +
+ .../boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts     | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu-sku22.dts       | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts             | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku16.dts       | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku272.dts      | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku288.dts      | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts         | 1 +
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts       | 1 +
+ arch/arm64/boot/dts/mediatek/mt8186-evb.dts                      | 1 +
+ 28 files changed, 28 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+@@ -11,6 +11,7 @@
+ / {
+       model = "MediaTek MT2712 evaluation board";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt2712-evb", "mediatek,mt2712";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt6755-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt6755-evb.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "MediaTek MT6755 EVB";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt6755-evb", "mediatek,mt6755";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt6779-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt6779-evb.dts
+@@ -10,6 +10,7 @@
+ / {
+       model = "MediaTek MT6779 EVB";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt6779-evb", "mediatek,mt6779";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt6795-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt6795-evb.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "MediaTek MT6795 Evaluation Board";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt6795-evb", "mediatek,mt6795";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt6797-evb.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "MediaTek MT6797 Evaluation Board";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt6797-evb", "mediatek,mt6797";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts
++++ b/arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts
+@@ -12,6 +12,7 @@
+ / {
+       model = "Mediatek X20 Development Board";
++      chassis-type = "embedded";
+       compatible = "archermind,mt6797-x20-dev", "mediatek,mt6797";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -15,6 +15,7 @@
+ / {
+       model = "Bananapi BPI-R64";
++      chassis-type = "embedded";
+       compatible = "bananapi,bpi-r64", "mediatek,mt7622";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -15,6 +15,7 @@
+ / {
+       model = "MediaTek MT7622 RFB1 board";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -16,6 +16,7 @@
+ / {
+       model = "Bananapi BPI-R3";
++      chassis-type = "embedded";
+       compatible = "bananapi,bpi-r3", "mediatek,mt7986a";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+@@ -11,6 +11,7 @@
+ / {
+       model = "MediaTek MT7986a RFB";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt7986a-rfb", "mediatek,mt7986a";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "MediaTek MT7986b RFB";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt7986b-rfb", "mediatek,mt7986b";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dts
+@@ -11,6 +11,7 @@
+ / {
+       model = "Pumpkin MT8167";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt8167-pumpkin", "mediatek,mt8167";
+       memory@40000000 {
+--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
+@@ -8,6 +8,7 @@
+ / {
+       model = "Google Hanawl";
++      chassis-type = "laptop";
+       compatible = "google,hana-rev7", "mediatek,mt8173";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dts
+@@ -8,6 +8,7 @@
+ / {
+       model = "Google Hana";
++      chassis-type = "laptop";
+       compatible = "google,hana-rev6", "google,hana-rev5",
+                    "google,hana-rev4", "google,hana-rev3",
+                    "google,hana", "mediatek,mt8173";
+--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dts
+@@ -8,6 +8,7 @@
+ / {
+       model = "Google Elm";
++      chassis-type = "laptop";
+       compatible = "google,elm-rev8", "google,elm-rev7", "google,elm-rev6",
+                    "google,elm-rev5", "google,elm-rev4", "google,elm-rev3",
+                    "google,elm", "mediatek,mt8173";
+--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+@@ -10,6 +10,7 @@
+ / {
+       model = "MediaTek MT8173 evaluation board";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt8173-evb", "mediatek,mt8173";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-evb.dts
+@@ -11,6 +11,7 @@
+ / {
+       model = "MediaTek MT8183 evaluation board";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt8183-evb", "mediatek,mt8183";
+       aliases {
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "Google burnet board";
++      chassis-type = "convertible";
+       compatible = "google,burnet", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "Google damu board";
++      chassis-type = "convertible";
+       compatible = "google,damu", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "Google juniper sku16 board";
++      chassis-type = "convertible";
+       compatible = "google,juniper-sku16", "google,juniper", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu-sku22.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu-sku22.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "MediaTek kakadu board sku22";
++      chassis-type = "tablet";
+       compatible = "google,kakadu-rev3-sku22", "google,kakadu-rev2-sku22",
+                    "google,kakadu", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts
+@@ -9,6 +9,7 @@
+ / {
+       model = "MediaTek kakadu board";
++      chassis-type = "tablet";
+       compatible = "google,kakadu-rev3", "google,kakadu-rev2",
+                       "google,kakadu", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku16.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku16.dts
+@@ -12,6 +12,7 @@
+ / {
+       model = "MediaTek kodama sku16 board";
++      chassis-type = "tablet";
+       compatible = "google,kodama-sku16", "google,kodama", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku272.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku272.dts
+@@ -12,6 +12,7 @@
+ / {
+       model = "MediaTek kodama sku272 board";
++      chassis-type = "tablet";
+       compatible = "google,kodama-sku272", "google,kodama", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku288.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama-sku288.dts
+@@ -12,6 +12,7 @@
+ / {
+       model = "MediaTek kodama sku288 board";
++      chassis-type = "tablet";
+       compatible = "google,kodama-sku288", "google,kodama", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
+@@ -14,6 +14,7 @@
+ / {
+       model = "MediaTek krane sku0 board";
++      chassis-type = "tablet";
+       compatible = "google,krane-sku0", "google,krane", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
+@@ -14,6 +14,7 @@
+ / {
+       model = "MediaTek krane sku176 board";
++      chassis-type = "tablet";
+       compatible = "google,krane-sku176", "google,krane", "mediatek,mt8183";
+ };
+--- a/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
+@@ -7,6 +7,7 @@
+ / {
+       model = "MediaTek MT8186 evaluation board";
++      chassis-type = "embedded";
+       compatible = "mediatek,mt8186-evb", "mediatek,mt8186";
+       aliases {
diff --git a/target/linux/mediatek/patches-6.6/012-v6.5-arm64-dts-mt7986-add-PWM.patch b/target/linux/mediatek/patches-6.6/012-v6.5-arm64-dts-mt7986-add-PWM.patch
new file mode 100644 (file)
index 0000000..e8c4794
--- /dev/null
@@ -0,0 +1,38 @@
+From 3b92c547e3d4a35c6214b3e7fa1103d0749d83b1 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 21 Apr 2023 15:20:44 +0200
+Subject: [PATCH 12/19] arm64: dts: mt7986: add PWM
+
+This adds pwm node to mt7986.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20230421132047.42166-5-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -240,6 +240,20 @@
+                       status = "disabled";
+               };
++              pwm: pwm@10048000 {
++                      compatible = "mediatek,mt7986-pwm";
++                      reg = <0 0x10048000 0 0x1000>;
++                      #clock-cells = <1>;
++                      #pwm-cells = <2>;
++                      interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&topckgen CLK_TOP_PWM_SEL>,
++                               <&infracfg CLK_INFRA_PWM_STA>,
++                               <&infracfg CLK_INFRA_PWM1_CK>,
++                               <&infracfg CLK_INFRA_PWM2_CK>;
++                      clock-names = "top", "main", "pwm1", "pwm2";
++                      status = "disabled";
++              };
++
+               uart0: serial@11002000 {
+                       compatible = "mediatek,mt7986-uart",
+                                    "mediatek,mt6577-uart";
diff --git a/target/linux/mediatek/patches-6.6/013-v6.5-arm64-dts-mt7986-add-PWM-to-BPI-R3.patch b/target/linux/mediatek/patches-6.6/013-v6.5-arm64-dts-mt7986-add-PWM-to-BPI-R3.patch
new file mode 100644 (file)
index 0000000..ce908e3
--- /dev/null
@@ -0,0 +1,43 @@
+From 35e482bb599df010b4869017ff576dbb7a4d4c2e Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 21 Apr 2023 15:20:45 +0200
+Subject: [PATCH 13/19] arm64: dts: mt7986: add PWM to BPI-R3
+
+Add pwm node and pinctrl to BananaPi R3 devicetree.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Link: https://lore.kernel.org/r/20230421132047.42166-6-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts   | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -275,6 +275,13 @@
+               };
+       };
++      pwm_pins: pwm-pins {
++              mux {
++                      function = "pwm";
++                      groups = "pwm0", "pwm1_0";
++              };
++      };
++
+       spi_flash_pins: spi-flash-pins {
+               mux {
+                       function = "spi";
+@@ -345,6 +352,12 @@
+       };
+ };
++&pwm {
++      pinctrl-names = "default";
++      pinctrl-0 = <&pwm_pins>;
++      status = "okay";
++};
++
+ &spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_flash_pins>;
diff --git a/target/linux/mediatek/patches-6.6/014-v6.5-arm64-dts-mt7986-set-Wifi-Leds-low-active-for-BPI-R3.patch b/target/linux/mediatek/patches-6.6/014-v6.5-arm64-dts-mt7986-set-Wifi-Leds-low-active-for-BPI-R3.patch
new file mode 100644 (file)
index 0000000..c7b3848
--- /dev/null
@@ -0,0 +1,27 @@
+From ccdda5714446db8690505371442f7807f5d7c6fc Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 5 Feb 2023 18:48:33 +0100
+Subject: [PATCH 14/19] arm64: dts: mt7986: set Wifi Leds low-active for BPI-R3
+
+Leds for Wifi are low-active, so add property to devicetree.
+
+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/20230205174833.107050-1-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -460,5 +460,9 @@
+       pinctrl-names = "default", "dbdc";
+       pinctrl-0 = <&wf_2g_5g_pins>, <&wf_led_pins>;
+       pinctrl-1 = <&wf_dbdc_pins>, <&wf_led_pins>;
++
++      led {
++              led-active-low;
++      };
+ };
diff --git a/target/linux/mediatek/patches-6.6/015-v6.5-arm64-dts-mt7986-use-size-of-reserved-partition-for-.patch b/target/linux/mediatek/patches-6.6/015-v6.5-arm64-dts-mt7986-use-size-of-reserved-partition-for-.patch
new file mode 100644 (file)
index 0000000..0b84f14
--- /dev/null
@@ -0,0 +1,46 @@
+From 1423b4b780adcf3994e63a5988a62d5d1d509bb1 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 28 May 2023 13:33:42 +0200
+Subject: [PATCH 15/19] arm64: dts: mt7986: use size of reserved partition for
+ bl2
+
+To store uncompressed bl2 more space is required than partition is
+actually defined.
+
+There is currently no known usage of this reserved partition.
+Openwrt uses same partition layout.
+
+We added same change to u-boot with commit d7bb1099 [1].
+
+[1] https://source.denx.de/u-boot/u-boot/-/commit/d7bb109900c1ca754a0198b9afb50e3161ffc21e
+
+Cc: stable@vger.kernel.org
+Fixes: 8e01fb15b815 ("arm64: dts: mt7986: add Bananapi R3")
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/20230528113343.7649-1-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso     | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nor.dtso
+@@ -27,15 +27,10 @@
+                                       partition@0 {
+                                               label = "bl2";
+-                                              reg = <0x0 0x20000>;
++                                              reg = <0x0 0x40000>;
+                                               read-only;
+                                       };
+-                                      partition@20000 {
+-                                              label = "reserved";
+-                                              reg = <0x20000 0x20000>;
+-                                      };
+-
+                                       partition@40000 {
+                                               label = "u-boot-env";
+                                               reg = <0x40000 0x40000>;
diff --git a/target/linux/mediatek/patches-6.6/016-v6.5-arm64-dts-mt7986-add-thermal-and-efuse.patch b/target/linux/mediatek/patches-6.6/016-v6.5-arm64-dts-mt7986-add-thermal-and-efuse.patch
new file mode 100644 (file)
index 0000000..0d12079
--- /dev/null
@@ -0,0 +1,80 @@
+From 40a5a767d698ef7a71f8be851ea18b0a7a8b47bd Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 30 May 2023 22:12:33 +0200
+Subject: [PATCH 16/19] arm64: dts: mt7986: add thermal and efuse
+
+Add thermal related nodes to mt7986 devicetree.
+
+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/20230530201235.22330-3-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 36 ++++++++++++++++++++++-
+ 1 file changed, 35 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -337,6 +337,15 @@
+                       status = "disabled";
+               };
++              auxadc: adc@1100d000 {
++                      compatible = "mediatek,mt7986-auxadc";
++                      reg = <0 0x1100d000 0 0x1000>;
++                      clocks = <&infracfg CLK_INFRA_ADC_26M_CK>;
++                      clock-names = "main";
++                      #io-channel-cells = <1>;
++                      status = "disabled";
++              };
++
+               ssusb: usb@11200000 {
+                       compatible = "mediatek,mt7986-xhci",
+                                    "mediatek,mtk-xhci";
+@@ -375,6 +384,21 @@
+                       status = "disabled";
+               };
++              thermal: thermal@1100c800 {
++                      #thermal-sensor-cells = <1>;
++                      compatible = "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>,
++                               <&infracfg CLK_INFRA_ADC_FRC_CK>;
++                      clock-names = "therm", "auxadc", "adc_32k";
++                      mediatek,auxadc = <&auxadc>;
++                      mediatek,apmixedsys = <&apmixedsys>;
++                      nvmem-cells = <&thermal_calibration>;
++                      nvmem-cell-names = "calibration-data";
++              };
++
+               pcie: pcie@11280000 {
+                       compatible = "mediatek,mt7986-pcie",
+                                    "mediatek,mt8192-pcie";
+@@ -426,6 +450,17 @@
+                       };
+               };
++              efuse: efuse@11d00000 {
++                      compatible = "mediatek,mt7986-efuse", "mediatek,efuse";
++                      reg = <0 0x11d00000 0 0x1000>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      thermal_calibration: calib@274 {
++                              reg = <0x274 0xc>;
++                      };
++              };
++
+               usb_phy: t-phy@11e10000 {
+                       compatible = "mediatek,mt7986-tphy",
+                                    "mediatek,generic-tphy-v2";
+@@ -567,5 +602,4 @@
+                       memory-region = <&wmcpu_emi>;
+               };
+       };
+-
+ };
diff --git a/target/linux/mediatek/patches-6.6/017-v6.5-arm64-dts-mt7986-add-thermal-zones.patch b/target/linux/mediatek/patches-6.6/017-v6.5-arm64-dts-mt7986-add-thermal-zones.patch
new file mode 100644 (file)
index 0000000..3fe3e88
--- /dev/null
@@ -0,0 +1,51 @@
+From bb78d0cf5117517f1ed296ae71048945d9107675 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 30 May 2023 22:12:34 +0200
+Subject: [PATCH 17/19] arm64: dts: mt7986: add thermal-zones
+
+Add thermal-zones to mt7986 devicetree.
+
+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/20230530201235.22330-4-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 28 +++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -602,4 +602,32 @@
+                       memory-region = <&wmcpu_emi>;
+               };
+       };
++
++      thermal-zones {
++              cpu_thermal: cpu-thermal {
++                      polling-delay-passive = <1000>;
++                      polling-delay = <1000>;
++                      thermal-sensors = <&thermal 0>;
++
++                      trips {
++                              cpu_trip_active_high: active-high {
++                                      temperature = <115000>;
++                                      hysteresis = <2000>;
++                                      type = "active";
++                              };
++
++                              cpu_trip_active_low: active-low {
++                                      temperature = <85000>;
++                                      hysteresis = <2000>;
++                                      type = "active";
++                              };
++
++                              cpu_trip_passive: passive {
++                                      temperature = <40000>;
++                                      hysteresis = <2000>;
++                                      type = "passive";
++                              };
++                      };
++              };
++      };
+ };
diff --git a/target/linux/mediatek/patches-6.6/018-v6.5-arm64-dts-mt7986-add-pwm-fan-and-cooling-maps-to-BPI.patch b/target/linux/mediatek/patches-6.6/018-v6.5-arm64-dts-mt7986-add-pwm-fan-and-cooling-maps-to-BPI.patch
new file mode 100644 (file)
index 0000000..ca7d872
--- /dev/null
@@ -0,0 +1,64 @@
+From 5d90603b09e5814ffc38c47e79ccf9bc564f9296 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 30 May 2023 22:12:35 +0200
+Subject: [PATCH 18/19] arm64: dts: mt7986: add pwm-fan and cooling-maps to
+ BPI-R3 dts
+
+Add pwm-fan and cooling-maps to BananaPi-R3 devicetree.
+
+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/20230530201235.22330-5-linux@fw-web.de
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ .../dts/mediatek/mt7986a-bananapi-bpi-r3.dts  | 31 +++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -38,6 +38,15 @@
+               regulator-always-on;
+       };
++      fan: pwm-fan {
++              compatible = "pwm-fan";
++              #cooling-cells = <2>;
++              /* cooling level (0, 1, 2) - pwm inverted */
++              cooling-levels = <255 96 0>;
++              pwms = <&pwm 0 10000 0>;
++              status = "okay";
++      };
++
+       gpio-keys {
+               compatible = "gpio-keys";
+@@ -133,6 +142,28 @@
+       };
+ };
++&cpu_thermal {
++      cooling-maps {
++              cpu-active-high {
++                      /* active: set fan to cooling level 2 */
++                      cooling-device = <&fan 2 2>;
++                      trip = <&cpu_trip_active_high>;
++              };
++
++              cpu-active-low {
++                      /* active: set fan to cooling level 1 */
++                      cooling-device = <&fan 1 1>;
++                      trip = <&cpu_trip_active_low>;
++              };
++
++              cpu-passive {
++                      /* passive: set fan to cooling level 0 */
++                      cooling-device = <&fan 0 0>;
++                      trip = <&cpu_trip_passive>;
++              };
++      };
++};
++
+ &crypto {
+       status = "okay";
+ };
diff --git a/target/linux/mediatek/patches-6.6/019-v6.5-arm64-dts-mt7986-increase-bl2-partition-on-NAND-of-B.patch b/target/linux/mediatek/patches-6.6/019-v6.5-arm64-dts-mt7986-increase-bl2-partition-on-NAND-of-B.patch
new file mode 100644 (file)
index 0000000..9cc6cad
--- /dev/null
@@ -0,0 +1,41 @@
+From 6dd3b939370094eb79529683be84500f3c757404 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 6 Jun 2023 16:43:20 +0100
+Subject: [PATCH 19/19] arm64: dts: mt7986: increase bl2 partition on NAND of
+ Bananapi R3
+
+The bootrom burned into the MT7986 SoC will try multiple locations on
+the SPI-NAND flash to load bl2 in case the bl2 image located at the the
+previously attempted offset is corrupt.
+
+Use 0x100000 instead of 0x80000 as partition size for bl2 on SPI-NAND,
+allowing for up to four redundant copies of bl2 (typically sized a
+bit less than 0x40000).
+
+Fixes: 8e01fb15b8157 ("arm64: dts: mt7986: add Bananapi R3")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/ZH9UGF99RgzrHZ88@makrotopia.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso     | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- 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,13 +29,13 @@
+                                       partition@0 {
+                                               label = "bl2";
+-                                              reg = <0x0 0x80000>;
++                                              reg = <0x0 0x100000>;
+                                               read-only;
+                                       };
+-                                      partition@80000 {
++                                      partition@100000 {
+                                               label = "reserved";
+-                                              reg = <0x80000 0x300000>;
++                                              reg = <0x100000 0x280000>;
+                                       };
+                                       partition@380000 {
diff --git a/target/linux/mediatek/patches-6.6/020-v6.7-arm64-dts-mt7986-define-3W-max-power-to-both-SFP-on-.patch b/target/linux/mediatek/patches-6.6/020-v6.7-arm64-dts-mt7986-define-3W-max-power-to-both-SFP-on-.patch
new file mode 100644 (file)
index 0000000..8cba3b2
--- /dev/null
@@ -0,0 +1,34 @@
+From f8ed4088ed9c61ae92193da6130d04c37e7b19f2 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 20 Aug 2023 17:31:33 +0200
+Subject: [PATCH 20/22] arm64: dts: mt7986: define 3W max power to both SFP on
+ BPI-R3
+
+All SFP power supplies are connected to the system VDD33 which is 3v3/8A.
+Set 3A per SFP slot to allow SFPs work which need more power than the
+default 1W.
+
+Fixes: 8e01fb15b815 ("arm64: dts: mt7986: add Bananapi R3")
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -126,6 +126,7 @@
+               compatible = "sff,sfp";
+               i2c-bus = <&i2c_sfp1>;
+               los-gpios = <&pio 46 GPIO_ACTIVE_HIGH>;
++              maximum-power-milliwatt = <3000>;
+               mod-def0-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
+               tx-disable-gpios = <&pio 20 GPIO_ACTIVE_HIGH>;
+               tx-fault-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
+@@ -137,6 +138,7 @@
+               i2c-bus = <&i2c_sfp2>;
+               los-gpios = <&pio 31 GPIO_ACTIVE_HIGH>;
+               mod-def0-gpios = <&pio 47 GPIO_ACTIVE_LOW>;
++              maximum-power-milliwatt = <3000>;
+               tx-disable-gpios = <&pio 15 GPIO_ACTIVE_HIGH>;
+               tx-fault-gpios = <&pio 48 GPIO_ACTIVE_HIGH>;
+       };
diff --git a/target/linux/mediatek/patches-6.6/021-v6.7-arm64-dts-mt7986-change-cooling-trips.patch b/target/linux/mediatek/patches-6.6/021-v6.7-arm64-dts-mt7986-change-cooling-trips.patch
new file mode 100644 (file)
index 0000000..20d4468
--- /dev/null
@@ -0,0 +1,59 @@
+From aa3d6df9803c267725dc72286bb91602b7579882 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 20 Aug 2023 17:31:34 +0200
+Subject: [PATCH 21/22] arm64: dts: mt7986: change cooling trips
+
+Add Critical and hot trips for emergency system shutdown and limiting
+system load.
+
+Change passive trip to active to make sure fan is activated on the
+lowest trip.
+
+Fixes: 1f5be05132f3 ("arm64: dts: mt7986: add thermal-zones")
+Suggested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -610,22 +610,34 @@
+                       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_low: active-low {
++                              cpu_trip_active_med: active-med {
+                                       temperature = <85000>;
+                                       hysteresis = <2000>;
+                                       type = "active";
+                               };
+-                              cpu_trip_passive: passive {
+-                                      temperature = <40000>;
++                              cpu_trip_active_low: active-low {
++                                      temperature = <60000>;
+                                       hysteresis = <2000>;
+-                                      type = "passive";
++                                      type = "active";
+                               };
+                       };
+               };
diff --git a/target/linux/mediatek/patches-6.6/022-v6.7-arm64-dts-mt7986-change-thermal-trips-on-BPI-R3.patch b/target/linux/mediatek/patches-6.6/022-v6.7-arm64-dts-mt7986-change-thermal-trips-on-BPI-R3.patch
new file mode 100644 (file)
index 0000000..7166ab6
--- /dev/null
@@ -0,0 +1,38 @@
+From 6ddf23526955b8dbedfeaa57e691261fd73f9d4e Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 20 Aug 2023 17:31:35 +0200
+Subject: [PATCH 22/22] arm64: dts: mt7986: change thermal trips on BPI-R3
+
+Apply new naming after mt7986 thermal trips were changed.
+
+Fixes: c26f779a2295 ("arm64: dts: mt7986: add pwm-fan and cooling-maps to BPI-R3 dts")
+Suggested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ .../boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts      | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+@@ -152,16 +152,16 @@
+                       trip = <&cpu_trip_active_high>;
+               };
+-              cpu-active-low {
++              cpu-active-med {
+                       /* active: set fan to cooling level 1 */
+                       cooling-device = <&fan 1 1>;
+-                      trip = <&cpu_trip_active_low>;
++                      trip = <&cpu_trip_active_med>;
+               };
+-              cpu-passive {
+-                      /* passive: set fan to cooling level 0 */
++              cpu-active-low {
++                      /* active: set fan to cooling level 0 */
+                       cooling-device = <&fan 0 0>;
+-                      trip = <&cpu_trip_passive>;
++                      trip = <&cpu_trip_active_low>;
+               };
+       };
+ };
diff --git a/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch b/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch
new file mode 100644 (file)
index 0000000..bb87c20
--- /dev/null
@@ -0,0 +1,216 @@
+From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001
+From: OpenWrt community <openwrt-devel@lists.openwrt.org>
+Date: Wed, 13 Jul 2022 13:37:33 +0200
+Subject: [PATCH] kernel: add block fit partition parser
+
+---
+ block/blk.h                     |  2 ++
+ block/partitions/Kconfig        |  7 +++++++
+ block/partitions/Makefile       |  1 +
+ block/partitions/check.h        |  3 +++
+ block/partitions/core.c         | 17 +++++++++++++++++
+ block/partitions/efi.c          |  8 ++++++++
+ block/partitions/efi.h          |  3 +++
+ block/partitions/msdos.c        | 10 ++++++++++
+ drivers/mtd/mtd_blkdevs.c       |  2 ++
+ drivers/mtd/ubi/block.c         |  3 +++
+ include/linux/msdos_partition.h |  1 +
+ 11 files changed, 57 insertions(+)
+
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -414,6 +414,8 @@ void blk_free_ext_minor(unsigned int min
+ #define ADDPART_FLAG_NONE     0
+ #define ADDPART_FLAG_RAID     1
+ #define ADDPART_FLAG_WHOLEDISK        2
++#define ADDPART_FLAG_READONLY 4
++#define ADDPART_FLAG_ROOTDEV  8
+ int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
+               sector_t length);
+ int bdev_del_partition(struct gendisk *disk, int partno);
+--- a/block/partitions/Kconfig
++++ b/block/partitions/Kconfig
+@@ -103,6 +103,13 @@ config ATARI_PARTITION
+         Say Y here if you would like to use hard disks under Linux which
+         were partitioned under the Atari OS.
++config FIT_PARTITION
++      bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
++      default n
++      help
++        Say Y here if your system needs to mount the filesystem part of
++        a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
++
+ config IBM_PARTITION
+       bool "IBM disk label and partition support"
+       depends on PARTITION_ADVANCED && S390
+--- a/block/partitions/Makefile
++++ b/block/partitions/Makefile
+@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
+ obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
+ obj-$(CONFIG_ATARI_PARTITION) += atari.o
+ obj-$(CONFIG_AIX_PARTITION) += aix.o
++obj-$(CONFIG_FIT_PARTITION) += fit.o
+ obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
+ obj-$(CONFIG_MAC_PARTITION) += mac.o
+ obj-$(CONFIG_LDM_PARTITION) += ldm.o
+--- a/block/partitions/check.h
++++ b/block/partitions/check.h
+@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partit
+ int atari_partition(struct parsed_partitions *state);
+ int cmdline_partition(struct parsed_partitions *state);
+ int efi_partition(struct parsed_partitions *state);
++int fit_partition(struct parsed_partitions *state);
+ int ibm_partition(struct parsed_partitions *);
+ int karma_partition(struct parsed_partitions *state);
+ int ldm_partition(struct parsed_partitions *state);
+@@ -67,3 +68,5 @@ int sgi_partition(struct parsed_partitio
+ int sun_partition(struct parsed_partitions *state);
+ int sysv68_partition(struct parsed_partitions *state);
+ int ultrix_partition(struct parsed_partitions *state);
++
++int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain);
+--- a/block/partitions/core.c
++++ b/block/partitions/core.c
+@@ -11,6 +11,9 @@
+ #include <linux/vmalloc.h>
+ #include <linux/raid/detect.h>
+ #include <linux/property.h>
++#ifdef CONFIG_FIT_PARTITION
++#include <linux/root_dev.h>
++#endif
+ #include "check.h"
+@@ -48,6 +51,9 @@ static int (*check_part[])(struct parsed
+ #ifdef CONFIG_EFI_PARTITION
+       efi_partition,          /* this must come before msdos */
+ #endif
++#ifdef CONFIG_FIT_PARTITION
++      fit_partition,
++#endif
+ #ifdef CONFIG_SGI_PARTITION
+       sgi_partition,
+ #endif
+@@ -439,6 +445,11 @@ static struct block_device *add_partitio
+                       goto out_del;
+       }
++#ifdef CONFIG_FIT_PARTITION
++      if (flags & ADDPART_FLAG_READONLY)
++              bdev->bd_read_only = true;
++#endif
++
+       /* everything is up and running, commence */
+       err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
+       if (err)
+@@ -631,6 +642,11 @@ static bool blk_add_partition(struct gen
+           (state->parts[p].flags & ADDPART_FLAG_RAID))
+               md_autodetect_dev(part->bd_dev);
++#ifdef CONFIG_FIT_PARTITION
++      if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0)
++              ROOT_DEV = part->bd_dev;
++#endif
++
+       return true;
+ }
+--- a/block/partitions/efi.c
++++ b/block/partitions/efi.c
+@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio
+       gpt_entry *ptes = NULL;
+       u32 i;
+       unsigned ssz = queue_logical_block_size(state->disk->queue) / 512;
++#ifdef CONFIG_FIT_PARTITION
++      u32 extra_slot = 64;
++#endif
+       if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
+               kfree(gpt);
+@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio
+                               ARRAY_SIZE(ptes[i].partition_name));
+               utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
+               state->parts[i + 1].has_info = true;
++#ifdef CONFIG_FIT_PARTITION
++              /* If this is a U-Boot FIT volume it may have subpartitions */
++              if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
++                      (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
++#endif
+       }
+       kfree(ptes);
+       kfree(gpt);
+--- a/block/partitions/efi.h
++++ b/block/partitions/efi.h
+@@ -51,6 +51,9 @@
+ #define PARTITION_LINUX_LVM_GUID \
+     EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
+               0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
++#define PARTITION_LINUX_FIT_GUID \
++    EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
++              0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
+ typedef struct _gpt_header {
+       __le64 signature;
+--- a/block/partitions/msdos.c
++++ b/block/partitions/msdos.c
+@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa
+ #endif /* CONFIG_MINIX_SUBPARTITION */
+ }
++static void parse_fit_mbr(struct parsed_partitions *state,
++                        sector_t offset, sector_t size, int origin)
++{
++#ifdef CONFIG_FIT_PARTITION
++      u32 extra_slot = 64;
++      (void) parse_fit_partitions(state, offset, size, &extra_slot, 1);
++#endif /* CONFIG_FIT_PARTITION */
++}
++
+ static struct {
+       unsigned char id;
+       void (*parse)(struct parsed_partitions *, sector_t, sector_t, int);
+@@ -575,6 +584,7 @@ static struct {
+       {UNIXWARE_PARTITION, parse_unixware},
+       {SOLARIS_X86_PARTITION, parse_solaris_x86},
+       {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
++      {FIT_PARTITION, parse_fit_mbr},
+       {0, NULL},
+ };
+--- a/drivers/mtd/mtd_blkdevs.c
++++ b/drivers/mtd/mtd_blkdevs.c
+@@ -359,7 +359,9 @@ int add_mtd_blktrans_dev(struct mtd_blkt
+       } else {
+               snprintf(gd->disk_name, sizeof(gd->disk_name),
+                        "%s%d", tr->name, new->devnum);
+-              gd->flags |= GENHD_FL_NO_PART;
++
++              if (!IS_ENABLED(CONFIG_FIT_PARTITION) || mtd_type_is_nand(new->mtd))
++                      gd->flags |= GENHD_FL_NO_PART;
+       }
+       set_capacity(gd, ((u64)new->size * tr->blksize) >> 9);
+--- a/drivers/mtd/ubi/block.c
++++ b/drivers/mtd/ubi/block.c
+@@ -432,7 +432,9 @@ int ubiblock_create(struct ubi_volume_in
+               ret = -ENODEV;
+               goto out_cleanup_disk;
+       }
+-      gd->flags |= GENHD_FL_NO_PART;
++      if (!IS_ENABLED(CONFIG_FIT_PARTITION))
++              gd->flags |= GENHD_FL_NO_PART;
++
+       gd->private_data = dev;
+       sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
+       set_capacity(gd, disk_capacity);
+--- a/include/linux/msdos_partition.h
++++ b/include/linux/msdos_partition.h
+@@ -31,6 +31,7 @@ enum msdos_sys_ind {
+       LINUX_LVM_PARTITION = 0x8e,
+       LINUX_RAID_PARTITION = 0xfd,    /* autodetect RAID partition */
++      FIT_PARTITION = 0x2e,           /* U-Boot uImage.FIT */
+       SOLARIS_X86_PARTITION = 0x82,   /* also Linux swap partitions */
+       NEW_SOLARIS_X86_PARTITION = 0xbf,
diff --git a/target/linux/mediatek/patches-6.6/100-dts-update-mt7622-rfb1.patch b/target/linux/mediatek/patches-6.6/100-dts-update-mt7622-rfb1.patch
new file mode 100644 (file)
index 0000000..d5bd9a3
--- /dev/null
@@ -0,0 +1,107 @@
+--- 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>;
+       };
+       reg_1p8v: regulator-1p8v {
+@@ -132,22 +131,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 {
+@@ -240,7 +239,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 {
+@@ -517,11 +531,11 @@
+ };
+ &sata {
+-      status = "okay";
++      status = "disabled";
+ };
+ &sata_phy {
+-      status = "okay";
++      status = "disabled";
+ };
+ &spi0 {
diff --git a/target/linux/mediatek/patches-6.6/101-dts-update-mt7629-rfb.patch b/target/linux/mediatek/patches-6.6/101-dts-update-mt7629-rfb.patch
new file mode 100644 (file)
index 0000000..b177037
--- /dev/null
@@ -0,0 +1,60 @@
+--- a/arch/arm/boot/dts/mt7629-rfb.dts
++++ b/arch/arm/boot/dts/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,17 @@
+       pinctrl-0 = <&watchdog_pins>;
+       status = "okay";
+ };
++
++&factory {
++      compatible = "nvmem-cells";
++      #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.6/103-mt7623-enable-arch-timer.patch b/target/linux/mediatek/patches-6.6/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.6/104-mt7622-add-snor-irq.patch b/target/linux/mediatek/patches-6.6/104-mt7622-add-snor-irq.patch
new file mode 100644 (file)
index 0000000..0d9c91f
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -578,6 +578,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.6/105-dts-mt7622-enable-pstore.patch b/target/linux/mediatek/patches-6.6/105-dts-mt7622-enable-pstore.patch
new file mode 100644 (file)
index 0000000..93da722
--- /dev/null
@@ -0,0 +1,16 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -134,6 +134,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.6/106-dts-mt7622-disable_btif.patch b/target/linux/mediatek/patches-6.6/106-dts-mt7622-disable_btif.patch
new file mode 100644 (file)
index 0000000..fc6a8f3
--- /dev/null
@@ -0,0 +1,26 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -108,10 +108,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
+@@ -89,10 +89,6 @@
+       status = "disabled";
+ };
+-&btif {
+-      status = "okay";
+-};
+-
+ &cir {
+       pinctrl-names = "default";
+       pinctrl-0 = <&irrx_pins>;
diff --git a/target/linux/mediatek/patches-6.6/110-dts-fix-bpi2-console.patch b/target/linux/mediatek/patches-6.6/110-dts-fix-bpi2-console.patch
new file mode 100644 (file)
index 0000000..8dc53d2
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/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.6/111-dts-fix-bpi64-console.patch b/target/linux/mediatek/patches-6.6/111-dts-fix-bpi64-console.patch
new file mode 100644 (file)
index 0000000..f77f10c
--- /dev/null
@@ -0,0 +1,11 @@
+--- 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.6/112-dts-fix-bpi64-lan-names.patch b/target/linux/mediatek/patches-6.6/112-dts-fix-bpi64-lan-names.patch
new file mode 100644 (file)
index 0000000..b012a48
--- /dev/null
@@ -0,0 +1,37 @@
+--- 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 {
+@@ -160,22 +161,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@6 {
diff --git a/target/linux/mediatek/patches-6.6/113-dts-fix-bpi64-leds-and-buttons.patch b/target/linux/mediatek/patches-6.6/113-dts-fix-bpi64-leds-and-buttons.patch
new file mode 100644 (file)
index 0000000..1cca6f3
--- /dev/null
@@ -0,0 +1,49 @@
+--- 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.6/114-dts-bpi64-disable-rtc.patch b/target/linux/mediatek/patches-6.6/114-dts-bpi64-disable-rtc.patch
new file mode 100644 (file)
index 0000000..0d32408
--- /dev/null
@@ -0,0 +1,21 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -556,12 +556,16 @@
+       status = "okay";
+ };
++&rtc {
++      status = "disabled";
++};
++
+ &sata {
+-      status = "disable";
++      status = "disabled";
+ };
+ &sata_phy {
+-      status = "disable";
++      status = "disabled";
+ };
+ &spi0 {
diff --git a/target/linux/mediatek/patches-6.6/115-v6.5-arm64-dts-mt7622-declare-SPI-NAND-present-on-BPI-R64.patch b/target/linux/mediatek/patches-6.6/115-v6.5-arm64-dts-mt7622-declare-SPI-NAND-present-on-BPI-R64.patch
new file mode 100644 (file)
index 0000000..5fc5531
--- /dev/null
@@ -0,0 +1,70 @@
+From d278f43f25beedfd0cb784d1dd0a9e7e8c8f123f Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 19 Apr 2023 20:15:53 +0100
+Subject: [PATCH] arm64: dts: mt7622: declare SPI-NAND present on BPI-R64
+
+The SPI-NOR node in the device tree of the BananaPi R64 has most likely
+been copied from the reference board's device tree even though the R64
+comes with an SPI-NAND chip rather than SPI-NOR.
+
+Setup the Serial NAND Flash Interface (SNFI) controller, enable
+hardware BCH error detection and correction engine and add the SPI-NAND
+chip including basic partitions,
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/ZEA96dmaXqTpk8u8@makrotopia.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ .../dts/mediatek/mt7622-bananapi-bpi-r64.dts  | 38 ++++++++++++++++---
+ 1 file changed, 33 insertions(+), 5 deletions(-)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -253,14 +253,42 @@
+       status = "disabled";
+ };
+-&nor_flash {
+-      pinctrl-names = "default";
+-      pinctrl-0 = <&spi_nor_pins>;
+-      status = "disabled";
++&bch {
++      status = "okay";
++};
++&snfi {
++      pinctrl-names = "default";
++      pinctrl-0 = <&serial_nand_pins>;
++      status = "okay";
+       flash@0 {
+-              compatible = "jedec,spi-nor";
++              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 = "bl2";
++                              reg = <0x0 0x80000>;
++                              read-only;
++                      };
++
++                      partition@80000 {
++                              label = "fip";
++                              reg = <0x80000 0x200000>;
++                              read-only;
++                      };
++
++                      ubi: partition@280000 {
++                              label = "ubi";
++                              reg = <0x280000 0x7d80000>;
++                      };
++              };
+       };
+ };
diff --git a/target/linux/mediatek/patches-6.6/121-hack-spi-nand-1b-bbm.patch b/target/linux/mediatek/patches-6.6/121-hack-spi-nand-1b-bbm.patch
new file mode 100644 (file)
index 0000000..ff5521c
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -724,7 +724,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),
+@@ -735,7 +735,7 @@ static bool spinand_isbad(struct nand_de
+       spinand_select_target(spinand, pos->target);
+       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.6/130-dts-mt7629-add-snand-support.patch b/target/linux/mediatek/patches-6.6/130-dts-mt7629-add-snand-support.patch
new file mode 100644 (file)
index 0000000..82654e6
--- /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/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++
+ arch/arm/boot/dts/mt7629.dtsi    | 22 ++++++++++++++++
+ 3 files changed, 79 insertions(+)
+
+--- a/arch/arm/boot/dts/mt7629.dtsi
++++ b/arch/arm/boot/dts/mt7629.dtsi
+@@ -272,6 +272,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/mt7629-rfb.dts
++++ b/arch/arm/boot/dts/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.6/131-dts-mt7622-add-snand-support.patch b/target/linux/mediatek/patches-6.6/131-dts-mt7622-add-snand-support.patch
new file mode 100644 (file)
index 0000000..d6e0ab1
--- /dev/null
@@ -0,0 +1,68 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -534,6 +534,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.6/140-dts-fix-wmac-support-for-mt7622-rfb1.patch b/target/linux/mediatek/patches-6.6/140-dts-fix-wmac-support-for-mt7622-rfb1.patch
new file mode 100644 (file)
index 0000000..117d5ab
--- /dev/null
@@ -0,0 +1,18 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -575,7 +575,7 @@
+                               reg = <0x140000 0x0080000>;
+                       };
+-                      partition@1c0000 {
++                      factory: partition@1c0000 {
+                               label = "Factory";
+                               reg = <0x1c0000 0x0100000>;
+                       };
+@@ -636,5 +636,6 @@
+ &wmac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&wmac_pins>;
++      mediatek,mtd-eeprom = <&factory 0x0000>;
+       status = "okay";
+ };
diff --git a/target/linux/mediatek/patches-6.6/150-dts-mt7623-eip97-inside-secure-support.patch b/target/linux/mediatek/patches-6.6/150-dts-mt7623-eip97-inside-secure-support.patch
new file mode 100644 (file)
index 0000000..0860a22
--- /dev/null
@@ -0,0 +1,24 @@
+--- a/arch/arm/boot/dts/mt7623.dtsi
++++ b/arch/arm/boot/dts/mt7623.dtsi
+@@ -984,17 +984,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.6/160-dts-mt7623-bpi-r2-earlycon.patch b/target/linux/mediatek/patches-6.6/160-dts-mt7623-bpi-r2-earlycon.patch
new file mode 100644 (file)
index 0000000..091cffc
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/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.6/161-dts-mt7623-bpi-r2-mmc-device-order.patch b/target/linux/mediatek/patches-6.6/161-dts-mt7623-bpi-r2-mmc-device-order.patch
new file mode 100644 (file)
index 0000000..d1bafc1
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/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.6/162-dts-mt7623-bpi-r2-led-aliases.patch b/target/linux/mediatek/patches-6.6/162-dts-mt7623-bpi-r2-led-aliases.patch
new file mode 100644 (file)
index 0000000..f6745ad
--- /dev/null
@@ -0,0 +1,29 @@
+--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/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.6/163-dts-mt7623-bpi-r2-ethernet-alias.patch b/target/linux/mediatek/patches-6.6/163-dts-mt7623-bpi-r2-ethernet-alias.patch
new file mode 100644 (file)
index 0000000..b1dd75a
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/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.6/164-dts-mt7623-bpi-r2-rootdisk-for-fitblk.patch b/target/linux/mediatek/patches-6.6/164-dts-mt7623-bpi-r2-rootdisk-for-fitblk.patch
new file mode 100644 (file)
index 0000000..2675aa2
--- /dev/null
@@ -0,0 +1,55 @@
+--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
++++ b/arch/arm/boot/dts/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 earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
++              rootdisk-emmc = <&emmc_rootdisk>;
++              rootdisk-sd = <&sd_rootdisk>;
+       };
+       connector {
+@@ -315,6 +317,20 @@
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_1p8v>;
+       non-removable;
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              block {
++                      compatible = "block-device";
++                      partitions {
++                              emmc_rootdisk: block-partition-fit {
++                                      partno = <3>;
++                              };
++                      };
++              };
++      };
+ };
+ &mmc1 {
+@@ -328,6 +344,20 @@
+       cd-gpios = <&pio 261 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_3p3v>;
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              block {
++                      compatible = "block-device";
++                      partitions {
++                              sd_rootdisk: block-partition-fit {
++                                      partno = <3>;
++                              };
++                      };
++              };
++      };
+ };
+ &mt6323_leds {
diff --git a/target/linux/mediatek/patches-6.6/180-v6.5-arm64-dts-mt7622-handle-interrupts-from-MT7531-switc.patch b/target/linux/mediatek/patches-6.6/180-v6.5-arm64-dts-mt7622-handle-interrupts-from-MT7531-switc.patch
new file mode 100644 (file)
index 0000000..0a971c1
--- /dev/null
@@ -0,0 +1,32 @@
+From 983f37ee08acb60435744f1b1e2afea2d2a09c48 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 19 Apr 2023 20:16:29 +0100
+Subject: [PATCH] arm64: dts: mt7622: handle interrupts from MT7531 switch on
+ BPI-R64
+
+Since commit ba751e28d442 ("net: dsa: mt7530: add interrupt support")
+the mt7530 driver can act as an interrupt controller. Wire up irq line
+of the MT7531 switch on the BananaPi BPi-R64 board, so the status of
+the PHYs of the five 1000Base-T ports doesn't need to be polled any
+more.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/ZEA-DV_OsmFg5egL@makrotopia.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -154,6 +154,10 @@
+               switch@0 {
+                       compatible = "mediatek,mt7531";
+                       reg = <0>;
++                      interrupt-controller;
++                      #interrupt-cells = <1>;
++                      interrupt-parent = <&pio>;
++                      interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
+                       reset-gpios = <&pio 54 0>;
+                       ports {
diff --git a/target/linux/mediatek/patches-6.6/190-arm64-dts-mediatek-mt7622-fix-GICv2-range.patch b/target/linux/mediatek/patches-6.6/190-arm64-dts-mediatek-mt7622-fix-GICv2-range.patch
new file mode 100644 (file)
index 0000000..1e04d23
--- /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
+@@ -346,7 +346,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.6/193-dts-mt7623-thermal_zone_fix.patch b/target/linux/mediatek/patches-6.6/193-dts-mt7623-thermal_zone_fix.patch
new file mode 100644 (file)
index 0000000..1cfb53d
--- /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/mt7623.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/mt7623.dtsi
++++ b/arch/arm/boot/dts/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.6/194-dts-mt7968a-add-ramoops.patch b/target/linux/mediatek/patches-6.6/194-dts-mt7968a-add-ramoops.patch
new file mode 100644 (file)
index 0000000..161c1e7
--- /dev/null
@@ -0,0 +1,17 @@
+--- 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.6/195-dts-mt7986a-bpi-r3-leds-port-names-and-wifi-eeprom.patch b/target/linux/mediatek/patches-6.6/195-dts-mt7986a-bpi-r3-leds-port-names-and-wifi-eeprom.patch
new file mode 100644 (file)
index 0000000..336920b
--- /dev/null
@@ -0,0 +1,196 @@
+--- 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 {
+@@ -419,27 +423,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";
+@@ -490,9 +494,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.6/196-dts-mt7986a-bpi-r3-use-all-ubi-nand-layout.patch b/target/linux/mediatek/patches-6.6/196-dts-mt7986a-bpi-r3-use-all-ubi-nand-layout.patch
new file mode 100644 (file)
index 0000000..38510c0
--- /dev/null
@@ -0,0 +1,131 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtso
+@@ -23,7 +23,27 @@
+                       no-sd;
+                       no-sdio;
+                       status = "okay";
++
++                      card@0 {
++                              compatible = "mmc-card";
++                              reg = <0>;
++
++                              block {
++                                      compatible = "block-device";
++                                      partitions {
++                                              emmc_rootdisk: block-partition-production {
++                                                      partname = "production";
++                                              };
++                                      };
++                              };
++                      };
+               };
+       };
+-};
++      fragment@1 {
++              target-path = "/chosen";
++              __overlay__ {
++                      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,27 +29,30 @@
+                                       partition@0 {
+                                               label = "bl2";
+-                                              reg = <0x0 0x100000>;
++                                              reg = <0x0 0x200000>;
+                                               read-only;
+                                       };
+-                                      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";
++                                                      };
++                                              };
+                                       };
+                               };
+                       };
+               };
+       };
++
++      fragment@1 {
++              target-path = "/chosen";
++              __overlay__ {
++                      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";
+@@ -61,4 +61,11 @@
+                       };
+               };
+       };
++
++      fragment@1 {
++              target-path = "/chosen";
++              __overlay__ {
++                      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
+@@ -17,6 +17,27 @@
+                       max-frequency = <52000000>;
+                       cap-sd-highspeed;
+                       status = "okay";
++
++                      card@0 {
++                              compatible = "mmc-card";
++                              reg = <0>;
++
++                              block {
++                                      compatible = "block-device";
++                                      partitions {
++                                              sd_rootdisk: block-partition-production {
++                                                      partname = "production";
++                                              };
++                                      };
++                              };
++                      };
++              };
++      };
++
++      fragment@1 {
++              target-path = "/chosen";
++              __overlay__ {
++                      rootdisk-sd = <&sd_rootdisk>;
+               };
+       };
+ };
diff --git a/target/linux/mediatek/patches-6.6/200-phy-phy-mtk-tphy-Add-hifsys-support.patch b/target/linux/mediatek/patches-6.6/200-phy-phy-mtk-tphy-Add-hifsys-support.patch
new file mode 100644 (file)
index 0000000..6347533
--- /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
+@@ -17,6 +17,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"
+@@ -264,6 +266,9 @@
+ #define TPHY_CLKS_CNT 2
++#define HIF_SYSCFG1                   0x14
++#define HIF_SYSCFG1_PHY2_MASK         (0x3 << 20)
++
+ enum mtk_phy_version {
+       MTK_PHY_V1 = 1,
+       MTK_PHY_V2,
+@@ -331,6 +336,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 */
+@@ -596,6 +602,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) |
+@@ -1241,6 +1251,16 @@ static int mtk_tphy_probe(struct platfor
+                                        &tphy->src_coef);
+       }
++      if (of_find_property(np, "mediatek,phy-switch", NULL)) {
++              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(np, child_np) {
+               struct mtk_phy_instance *instance;
diff --git a/target/linux/mediatek/patches-6.6/210-v6.2-pinctrl-mt7986-allow-configuring-uart-rx-tx-and-rts-.patch b/target/linux/mediatek/patches-6.6/210-v6.2-pinctrl-mt7986-allow-configuring-uart-rx-tx-and-rts-.patch
new file mode 100644 (file)
index 0000000..3e16a53
--- /dev/null
@@ -0,0 +1,88 @@
+From f76e8bc416bebb0f7b9f57b1247eae945421c0b9 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sat, 8 Oct 2022 18:48:06 +0200
+Subject: [PATCH 1/2] pinctrl: mt7986: allow configuring uart rx/tx and rts/cts
+ separately
+
+Some mt7986 boards use uart rts/cts pins as gpio,
+This patch allows to change rts/cts to gpio mode, but keep
+rx/tx as UART function.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Link: https://lore.kernel.org/r/20221008164807.113590-1-linux@fw-web.de
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7986.c | 32 ++++++++++++++++++-----
+ 1 file changed, 25 insertions(+), 7 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+@@ -675,11 +675,17 @@ static int mt7986_uart1_1_funcs[] = { 4,
+ static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, };
+ static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, };
+-static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, };
+-static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, };
++static int mt7986_uart1_2_rx_tx_pins[] = { 29, 30, };
++static int mt7986_uart1_2_rx_tx_funcs[] = { 3, 3, };
+-static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, };
+-static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, };
++static int mt7986_uart1_2_cts_rts_pins[] = { 31, 32, };
++static int mt7986_uart1_2_cts_rts_funcs[] = { 3, 3, };
++
++static int mt7986_uart2_0_rx_tx_pins[] = { 29, 30, };
++static int mt7986_uart2_0_rx_tx_funcs[] = { 4, 4, };
++
++static int mt7986_uart2_0_cts_rts_pins[] = { 31, 32, };
++static int mt7986_uart2_0_cts_rts_funcs[] = { 4, 4, };
+ static int mt7986_spi0_pins[] = { 33, 34, 35, 36, };
+ static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, };
+@@ -708,6 +714,12 @@ static int mt7986_pcie_reset_funcs[] = {
+ static int mt7986_uart1_pins[] = { 42, 43, 44, 45, };
+ static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, };
++static int mt7986_uart1_rx_tx_pins[] = { 42, 43, };
++static int mt7986_uart1_rx_tx_funcs[] = { 1, 1, };
++
++static int mt7986_uart1_cts_rts_pins[] = { 44, 45, };
++static int mt7986_uart1_cts_rts_funcs[] = { 1, 1, };
++
+ static int mt7986_uart2_pins[] = { 46, 47, 48, 49, };
+ static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, };
+@@ -749,6 +761,8 @@ static const struct group_desc mt7986_gr
+       PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led),
+       PINCTRL_PIN_GROUP("i2c", mt7986_i2c),
+       PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0),
++      PINCTRL_PIN_GROUP("uart1_rx_tx", mt7986_uart1_rx_tx),
++      PINCTRL_PIN_GROUP("uart1_cts_rts", mt7986_uart1_cts_rts),
+       PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk),
+       PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake),
+       PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0),
+@@ -760,8 +774,10 @@ static const struct group_desc mt7986_gr
+       PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1),
+       PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1),
+       PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2),
+-      PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2),
+-      PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0),
++      PINCTRL_PIN_GROUP("uart1_2_rx_tx", mt7986_uart1_2_rx_tx),
++      PINCTRL_PIN_GROUP("uart1_2_cts_rts", mt7986_uart1_2_cts_rts),
++      PINCTRL_PIN_GROUP("uart2_0_rx_tx", mt7986_uart2_0_rx_tx),
++      PINCTRL_PIN_GROUP("uart2_0_cts_rts", mt7986_uart2_0_cts_rts),
+       PINCTRL_PIN_GROUP("spi0", mt7986_spi0),
+       PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold),
+       PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1),
+@@ -800,7 +816,9 @@ static const char *mt7986_pwm_groups[] =
+ static const char *mt7986_spi_groups[] = {
+       "spi0", "spi0_wp_hold", "spi1_0", "spi1_1", "spi1_2", "spi1_3", };
+ static const char *mt7986_uart_groups[] = {
+-      "uart1_0", "uart1_1", "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts",
++      "uart1_0", "uart1_1", "uart1_rx_tx", "uart1_cts_rts",
++      "uart1_2_rx_tx", "uart1_2_cts_rts",
++      "uart1_3_rx_tx", "uart1_3_cts_rts", "uart2_0_rx_tx", "uart2_0_cts_rts",
+       "uart2_0", "uart2_1", "uart0", "uart1", "uart2",
+ };
+ static const char *mt7986_wdt_groups[] = { "watchdog", };
diff --git a/target/linux/mediatek/patches-6.6/211-v6.2-pinctrl-mediatek-add-pull_type-attribute-for-mediate.patch b/target/linux/mediatek/patches-6.6/211-v6.2-pinctrl-mediatek-add-pull_type-attribute-for-mediate.patch
new file mode 100644 (file)
index 0000000..47ded1a
--- /dev/null
@@ -0,0 +1,100 @@
+From 822d774abbcc66b811e28c68b59b40b964ba5b46 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sun, 6 Nov 2022 09:01:13 +0100
+Subject: [PATCH 2/2] pinctrl: mediatek: add pull_type attribute for mediatek
+ MT7986 SoC
+
+Commit fb34a9ae383a ("pinctrl: mediatek: support rsel feature")
+add SoC specify 'pull_type' attribute for bias configuration.
+
+This patch add pull_type attribute to pinctrl-mt7986.c, and make
+bias_set_combo and bias_get_combo available to mediatek MT7986 SoC.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.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/r/20221106080114.7426-7-linux@fw-web.de
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7986.c | 56 +++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+@@ -407,6 +407,60 @@ static const struct mtk_pin_field_calc m
+       PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
+ };
++static const unsigned int mt7986_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_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_PUPD_R1R0_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_PU_PD_TYPE,/*69*/
++      MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/
++      MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/
++      MTK_PULL_PU_PD_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_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/
++      MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/
++      MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/
++      MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/
++      MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/
++      MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/
++      MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/
++      MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/
++      MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/
++      MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_TYPE,/*99*/
++      MTK_PULL_PU_PD_TYPE,/*100*/
++};
++
+ static const struct mtk_pin_reg_calc mt7986_reg_cals[] = {
+       [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range),
+       [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range),
+@@ -868,6 +922,7 @@ static struct mtk_pin_soc mt7986a_data =
+       .ies_present = false,
+       .base_names = mt7986_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
++      .pull_type = mt7986_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,
+@@ -889,6 +944,7 @@ static struct mtk_pin_soc mt7986b_data =
+       .ies_present = false,
+       .base_names = mt7986_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
++      .pull_type = mt7986_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,
diff --git a/target/linux/mediatek/patches-6.6/215-v6.3-pinctrl-add-mt7981-pinctrl-driver.patch b/target/linux/mediatek/patches-6.6/215-v6.3-pinctrl-add-mt7981-pinctrl-driver.patch
new file mode 100644 (file)
index 0000000..46dfa24
--- /dev/null
@@ -0,0 +1,1094 @@
+From 6c83b2d94fcca735cf7d8aa7a55a4957eb404a9d Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 26 Jan 2023 00:34:56 +0000
+Subject: [PATCH] pinctrl: add mt7981 pinctrl driver
+
+Add pinctrl driver for the MediaTek MT7981 SoC, based on the driver
+which can also be found the SDK.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/ef5112946d16cacc67e65e439ba7b52a9950c1bb.1674693008.git.daniel@makrotopia.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/Kconfig          |    5 +
+ drivers/pinctrl/mediatek/Makefile         |    1 +
+ drivers/pinctrl/mediatek/pinctrl-mt7981.c | 1048 +++++++++++++++++++++
+ 3 files changed, 1054 insertions(+)
+ create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7981.c
+
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -127,6 +127,11 @@ config PINCTRL_MT7622
+       default ARM64 && ARCH_MEDIATEK
+       select PINCTRL_MTK_MOORE
++config PINCTRL_MT7981
++      bool "Mediatek MT7981 pin control"
++      depends on OF
++      select PINCTRL_MTK_MOORE
++
+ config PINCTRL_MT7986
+       bool "Mediatek MT7986 pin control"
+       depends on OF
+--- a/drivers/pinctrl/mediatek/Makefile
++++ b/drivers/pinctrl/mediatek/Makefile
+@@ -18,6 +18,7 @@ obj-$(CONFIG_PINCTRL_MT6797) += pinctrl-
+ obj-$(CONFIG_PINCTRL_MT7622)  += pinctrl-mt7622.o
+ obj-$(CONFIG_PINCTRL_MT7623)  += pinctrl-mt7623.o
+ obj-$(CONFIG_PINCTRL_MT7629)  += pinctrl-mt7629.o
++obj-$(CONFIG_PINCTRL_MT7981)  += pinctrl-mt7981.o
+ obj-$(CONFIG_PINCTRL_MT7986)  += pinctrl-mt7986.o
+ obj-$(CONFIG_PINCTRL_MT8167)  += pinctrl-mt8167.o
+ obj-$(CONFIG_PINCTRL_MT8173)  += pinctrl-mt8173.o
+--- /dev/null
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+@@ -0,0 +1,1048 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * The MT7981 driver based on Linux generic pinctrl binding.
++ *
++ * Copyright (C) 2020 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ */
++
++#include "pinctrl-moore.h"
++
++#define MT7981_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 mt7981_pin_mode_range[] = {
++      PIN_FIELD(0, 56, 0x300, 0x10, 0, 4),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_dir_range[] = {
++      PIN_FIELD(0, 56, 0x0, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_di_range[] = {
++      PIN_FIELD(0, 56, 0x200, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_do_range[] = {
++      PIN_FIELD(0, 56, 0x100, 0x10, 0, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_ies_range[] = {
++      PIN_FIELD_BASE(0, 0, 1, 0x10, 0x10, 1, 1),
++      PIN_FIELD_BASE(1, 1, 1, 0x10, 0x10, 0, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x20, 0x10, 6, 1),
++      PIN_FIELD_BASE(3, 3, 4, 0x20, 0x10, 6, 1),
++      PIN_FIELD_BASE(4, 4, 4, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(5, 5, 4, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(6, 6, 4, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(7, 7, 4, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0x20, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(9, 9, 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(12, 12, 5, 0x20, 0x10, 7, 1),
++      PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1),
++
++      PIN_FIELD_BASE(14, 14, 4, 0x20, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(15, 15, 2, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(16, 16, 2, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(17, 17, 2, 0x20, 0x10, 5, 1),
++      PIN_FIELD_BASE(18, 18, 2, 0x20, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, 2, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(20, 20, 2, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(21, 21, 2, 0x20, 0x10, 6, 1),
++      PIN_FIELD_BASE(22, 22, 2, 0x20, 0x10, 7, 1),
++      PIN_FIELD_BASE(23, 23, 2, 0x20, 0x10, 10, 1),
++      PIN_FIELD_BASE(24, 24, 2, 0x20, 0x10, 9, 1),
++      PIN_FIELD_BASE(25, 25, 2, 0x20, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(26, 26, 5, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(27, 27, 5, 0x20, 0x10, 4, 1),
++      PIN_FIELD_BASE(28, 28, 5, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(29, 29, 5, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(30, 30, 5, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(31, 31, 5, 0x20, 0x10, 5, 1),
++
++      PIN_FIELD_BASE(32, 32, 1, 0x10, 0x10, 2, 1),
++      PIN_FIELD_BASE(33, 33, 1, 0x10, 0x10, 3, 1),
++
++      PIN_FIELD_BASE(34, 34, 4, 0x20, 0x10, 5, 1),
++      PIN_FIELD_BASE(35, 35, 4, 0x20, 0x10, 7, 1),
++
++      PIN_FIELD_BASE(36, 36, 3, 0x10, 0x10, 2, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0x10, 0x10, 3, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 0, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 1, 1),
++
++      PIN_FIELD_BASE(40, 40, 7, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(41, 41, 7, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, 7, 0x30, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 7, 0x30, 0x10, 7, 1),
++      PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
++      PIN_FIELD_BASE(45, 45, 7, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(46, 46, 7, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(47, 47, 7, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(48, 48, 7, 0x30, 0x10, 6, 1),
++      PIN_FIELD_BASE(49, 49, 7, 0x30, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(50, 50, 6, 0x10, 0x10, 0, 1),
++      PIN_FIELD_BASE(51, 51, 6, 0x10, 0x10, 2, 1),
++      PIN_FIELD_BASE(52, 52, 6, 0x10, 0x10, 3, 1),
++      PIN_FIELD_BASE(53, 53, 6, 0x10, 0x10, 4, 1),
++      PIN_FIELD_BASE(54, 54, 6, 0x10, 0x10, 5, 1),
++      PIN_FIELD_BASE(55, 55, 6, 0x10, 0x10, 6, 1),
++      PIN_FIELD_BASE(56, 56, 6, 0x10, 0x10, 1, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_smt_range[] = {
++      PIN_FIELD_BASE(0, 0, 1, 0x60, 0x10, 1, 1),
++      PIN_FIELD_BASE(1, 1, 1, 0x60, 0x10, 0, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x90, 0x10, 6, 1),
++      PIN_FIELD_BASE(3, 3, 4, 0x80, 0x10, 6, 1),
++      PIN_FIELD_BASE(4, 4, 4, 0x80, 0x10, 2, 1),
++      PIN_FIELD_BASE(5, 5, 4, 0x80, 0x10, 1, 1),
++      PIN_FIELD_BASE(6, 6, 4, 0x80, 0x10, 3, 1),
++      PIN_FIELD_BASE(7, 7, 4, 0x80, 0x10, 0, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0x80, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(9, 9, 5, 0x90, 0x10, 9, 1),
++      PIN_FIELD_BASE(10, 10, 5, 0x90, 0x10, 8, 1),
++      PIN_FIELD_BASE(11, 11, 5, 0x90, 0x10, 10, 1),
++      PIN_FIELD_BASE(12, 12, 5, 0x90, 0x10, 7, 1),
++      PIN_FIELD_BASE(13, 13, 5, 0x90, 0x10, 11, 1),
++
++      PIN_FIELD_BASE(14, 14, 4, 0x80, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(15, 15, 2, 0x90, 0x10, 0, 1),
++      PIN_FIELD_BASE(16, 16, 2, 0x90, 0x10, 1, 1),
++      PIN_FIELD_BASE(17, 17, 2, 0x90, 0x10, 5, 1),
++      PIN_FIELD_BASE(18, 18, 2, 0x90, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, 2, 0x90, 0x10, 2, 1),
++      PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
++      PIN_FIELD_BASE(21, 21, 2, 0x90, 0x10, 6, 1),
++      PIN_FIELD_BASE(22, 22, 2, 0x90, 0x10, 7, 1),
++      PIN_FIELD_BASE(23, 23, 2, 0x90, 0x10, 10, 1),
++      PIN_FIELD_BASE(24, 24, 2, 0x90, 0x10, 9, 1),
++      PIN_FIELD_BASE(25, 25, 2, 0x90, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(26, 26, 5, 0x90, 0x10, 0, 1),
++      PIN_FIELD_BASE(27, 27, 5, 0x90, 0x10, 4, 1),
++      PIN_FIELD_BASE(28, 28, 5, 0x90, 0x10, 3, 1),
++      PIN_FIELD_BASE(29, 29, 5, 0x90, 0x10, 1, 1),
++      PIN_FIELD_BASE(30, 30, 5, 0x90, 0x10, 2, 1),
++      PIN_FIELD_BASE(31, 31, 5, 0x90, 0x10, 5, 1),
++
++      PIN_FIELD_BASE(32, 32, 1, 0x60, 0x10, 2, 1),
++      PIN_FIELD_BASE(33, 33, 1, 0x60, 0x10, 3, 1),
++
++      PIN_FIELD_BASE(34, 34, 4, 0x80, 0x10, 5, 1),
++      PIN_FIELD_BASE(35, 35, 4, 0x80, 0x10, 7, 1),
++
++      PIN_FIELD_BASE(36, 36, 3, 0x60, 0x10, 2, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 3, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x60, 0x10, 0, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x60, 0x10, 1, 1),
++
++      PIN_FIELD_BASE(40, 40, 7, 0x70, 0x10, 1, 1),
++      PIN_FIELD_BASE(41, 41, 7, 0x70, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, 7, 0x70, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 7, 0x70, 0x10, 7, 1),
++      PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
++      PIN_FIELD_BASE(45, 45, 7, 0x70, 0x10, 3, 1),
++      PIN_FIELD_BASE(46, 46, 7, 0x70, 0x10, 4, 1),
++      PIN_FIELD_BASE(47, 47, 7, 0x70, 0x10, 5, 1),
++      PIN_FIELD_BASE(48, 48, 7, 0x70, 0x10, 6, 1),
++      PIN_FIELD_BASE(49, 49, 7, 0x70, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(50, 50, 6, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(51, 51, 6, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(52, 52, 6, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(53, 53, 6, 0x50, 0x10, 4, 1),
++      PIN_FIELD_BASE(54, 54, 6, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(55, 55, 6, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(56, 56, 6, 0x50, 0x10, 1, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_pu_range[] = {
++      PIN_FIELD_BASE(40, 40, 7, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(41, 41, 7, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, 7, 0x50, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 7, 0x50, 0x10, 7, 1),
++      PIN_FIELD_BASE(44, 44, 7, 0x50, 0x10, 8, 1),
++      PIN_FIELD_BASE(45, 45, 7, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(46, 46, 7, 0x50, 0x10, 4, 1),
++      PIN_FIELD_BASE(47, 47, 7, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(48, 48, 7, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(49, 49, 7, 0x50, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(50, 50, 6, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(51, 51, 6, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(52, 52, 6, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(53, 53, 6, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(54, 54, 6, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(55, 55, 6, 0x30, 0x10, 6, 1),
++      PIN_FIELD_BASE(56, 56, 6, 0x30, 0x10, 1, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_pd_range[] = {
++      PIN_FIELD_BASE(40, 40, 7, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(41, 41, 7, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(42, 42, 7, 0x40, 0x10, 9, 1),
++      PIN_FIELD_BASE(43, 43, 7, 0x40, 0x10, 7, 1),
++      PIN_FIELD_BASE(44, 44, 7, 0x40, 0x10, 8, 1),
++      PIN_FIELD_BASE(45, 45, 7, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(46, 46, 7, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(47, 47, 7, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(48, 48, 7, 0x40, 0x10, 6, 1),
++      PIN_FIELD_BASE(49, 49, 7, 0x40, 0x10, 2, 1),
++
++      PIN_FIELD_BASE(50, 50, 6, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(51, 51, 6, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(52, 52, 6, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(53, 53, 6, 0x20, 0x10, 4, 1),
++      PIN_FIELD_BASE(54, 54, 6, 0x20, 0x10, 5, 1),
++      PIN_FIELD_BASE(55, 55, 6, 0x20, 0x10, 6, 1),
++      PIN_FIELD_BASE(56, 56, 6, 0x20, 0x10, 1, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_drv_range[] = {
++      PIN_FIELD_BASE(0, 0, 1, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(1, 1, 1, 0x00, 0x10, 0, 3),
++
++      PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 18, 3),
++
++      PIN_FIELD_BASE(3, 3, 4, 0x00, 0x10, 18, 1),
++      PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 1),
++      PIN_FIELD_BASE(5, 5, 4, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(6, 6, 4, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 12, 3),
++
++      PIN_FIELD_BASE(9, 9, 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(12, 12, 5, 0x00, 0x10, 21, 3),
++      PIN_FIELD_BASE(13, 13, 5, 0x00, 0x10, 3, 3),
++
++      PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3),
++
++      PIN_FIELD_BASE(15, 15, 2, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(16, 16, 2, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(17, 17, 2, 0x00, 0x10, 15, 3),
++      PIN_FIELD_BASE(18, 18, 2, 0x00, 0x10, 12, 3),
++      PIN_FIELD_BASE(19, 19, 2, 0x00, 0x10, 6, 3),
++      PIN_FIELD_BASE(20, 20, 2, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(21, 21, 2, 0x00, 0x10, 18, 3),
++      PIN_FIELD_BASE(22, 22, 2, 0x00, 0x10, 21, 3),
++      PIN_FIELD_BASE(23, 23, 2, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3),
++      PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3),
++
++      PIN_FIELD_BASE(26, 26, 5, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(27, 27, 5, 0x00, 0x10, 12, 3),
++      PIN_FIELD_BASE(28, 28, 5, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(29, 29, 5, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(30, 30, 5, 0x00, 0x10, 6, 3),
++      PIN_FIELD_BASE(31, 31, 5, 0x00, 0x10, 15, 3),
++
++      PIN_FIELD_BASE(32, 32, 1, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(33, 33, 1, 0x00, 0x10, 12, 3),
++
++      PIN_FIELD_BASE(34, 34, 4, 0x00, 0x10, 15, 3),
++      PIN_FIELD_BASE(35, 35, 4, 0x00, 0x10, 21, 3),
++
++      PIN_FIELD_BASE(36, 36, 3, 0x00, 0x10, 6, 3),
++      PIN_FIELD_BASE(37, 37, 3, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(38, 38, 3, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(39, 39, 3, 0x00, 0x10, 3, 3),
++
++      PIN_FIELD_BASE(40, 40, 7, 0x00, 0x10, 3, 3),
++      PIN_FIELD_BASE(41, 41, 7, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(42, 42, 7, 0x00, 0x10, 27, 3),
++      PIN_FIELD_BASE(43, 43, 7, 0x00, 0x10, 21, 3),
++      PIN_FIELD_BASE(44, 44, 7, 0x00, 0x10, 24, 3),
++      PIN_FIELD_BASE(45, 45, 7, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(46, 46, 7, 0x00, 0x10, 12, 3),
++      PIN_FIELD_BASE(47, 47, 7, 0x00, 0x10, 15, 3),
++      PIN_FIELD_BASE(48, 48, 7, 0x00, 0x10, 18, 3),
++      PIN_FIELD_BASE(49, 49, 7, 0x00, 0x10, 6, 3),
++
++      PIN_FIELD_BASE(50, 50, 6, 0x00, 0x10, 0, 3),
++      PIN_FIELD_BASE(51, 51, 6, 0x00, 0x10, 6, 3),
++      PIN_FIELD_BASE(52, 52, 6, 0x00, 0x10, 9, 3),
++      PIN_FIELD_BASE(53, 53, 6, 0x00, 0x10, 12, 3),
++      PIN_FIELD_BASE(54, 54, 6, 0x00, 0x10, 15, 3),
++      PIN_FIELD_BASE(55, 55, 6, 0x00, 0x10, 18, 3),
++      PIN_FIELD_BASE(56, 56, 6, 0x00, 0x10, 3, 3),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_pupd_range[] = {
++      PIN_FIELD_BASE(0, 0, 1, 0x20, 0x10, 1, 1),
++      PIN_FIELD_BASE(1, 1, 1, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 6, 1),
++      PIN_FIELD_BASE(3, 3, 4, 0x30, 0x10, 6, 1),
++      PIN_FIELD_BASE(4, 4, 4, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(5, 5, 4, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(6, 6, 4, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(9, 9, 5, 0x30, 0x10, 9, 1),
++      PIN_FIELD_BASE(10, 10, 5, 0x30, 0x10, 8, 1),
++      PIN_FIELD_BASE(11, 11, 5, 0x30, 0x10, 10, 1),
++      PIN_FIELD_BASE(12, 12, 5, 0x30, 0x10, 7, 1),
++      PIN_FIELD_BASE(13, 13, 5, 0x30, 0x10, 11, 1),
++
++      PIN_FIELD_BASE(14, 14, 4, 0x30, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(15, 15, 2, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(16, 16, 2, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(17, 17, 2, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(18, 18, 2, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, 2, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
++      PIN_FIELD_BASE(21, 21, 2, 0x30, 0x10, 6, 1),
++      PIN_FIELD_BASE(22, 22, 2, 0x30, 0x10, 7, 1),
++      PIN_FIELD_BASE(23, 23, 2, 0x30, 0x10, 10, 1),
++      PIN_FIELD_BASE(24, 24, 2, 0x30, 0x10, 9, 1),
++      PIN_FIELD_BASE(25, 25, 2, 0x30, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(26, 26, 5, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(27, 27, 5, 0x30, 0x10, 4, 1),
++      PIN_FIELD_BASE(28, 28, 5, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(29, 29, 5, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(30, 30, 5, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(31, 31, 5, 0x30, 0x10, 5, 1),
++
++      PIN_FIELD_BASE(32, 32, 1, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(33, 33, 1, 0x20, 0x10, 3, 1),
++
++      PIN_FIELD_BASE(34, 34, 4, 0x30, 0x10, 5, 1),
++      PIN_FIELD_BASE(35, 35, 4, 0x30, 0x10, 7, 1),
++
++      PIN_FIELD_BASE(36, 36, 3, 0x20, 0x10, 2, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0x20, 0x10, 3, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x20, 0x10, 0, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x20, 0x10, 1, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_r0_range[] = {
++      PIN_FIELD_BASE(0, 0, 1, 0x30, 0x10, 1, 1),
++      PIN_FIELD_BASE(1, 1, 1, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x40, 0x10, 6, 1),
++      PIN_FIELD_BASE(3, 3, 4, 0x40, 0x10, 6, 1),
++      PIN_FIELD_BASE(4, 4, 4, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(5, 5, 4, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(6, 6, 4, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(9, 9, 5, 0x40, 0x10, 9, 1),
++      PIN_FIELD_BASE(10, 10, 5, 0x40, 0x10, 8, 1),
++      PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
++      PIN_FIELD_BASE(12, 12, 5, 0x40, 0x10, 7, 1),
++      PIN_FIELD_BASE(13, 13, 5, 0x40, 0x10, 11, 1),
++
++      PIN_FIELD_BASE(14, 14, 4, 0x40, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(15, 15, 2, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(16, 16, 2, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(17, 17, 2, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(18, 18, 2, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, 2, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(20, 20, 2, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(21, 21, 2, 0x40, 0x10, 6, 1),
++      PIN_FIELD_BASE(22, 22, 2, 0x40, 0x10, 7, 1),
++      PIN_FIELD_BASE(23, 23, 2, 0x40, 0x10, 10, 1),
++      PIN_FIELD_BASE(24, 24, 2, 0x40, 0x10, 9, 1),
++      PIN_FIELD_BASE(25, 25, 2, 0x40, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(26, 26, 5, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(27, 27, 5, 0x40, 0x10, 4, 1),
++      PIN_FIELD_BASE(28, 28, 5, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(29, 29, 5, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(30, 30, 5, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(31, 31, 5, 0x40, 0x10, 5, 1),
++
++      PIN_FIELD_BASE(32, 32, 1, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(33, 33, 1, 0x30, 0x10, 3, 1),
++
++      PIN_FIELD_BASE(34, 34, 4, 0x40, 0x10, 5, 1),
++      PIN_FIELD_BASE(35, 35, 4, 0x40, 0x10, 7, 1),
++
++      PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 2, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 3, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x30, 0x10, 0, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x30, 0x10, 1, 1),
++};
++
++static const struct mtk_pin_field_calc mt7981_pin_r1_range[] = {
++      PIN_FIELD_BASE(0, 0, 1, 0x40, 0x10, 1, 1),
++      PIN_FIELD_BASE(1, 1, 1, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(3, 3, 4, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(4, 4, 4, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(5, 5, 4, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(6, 6, 4, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(7, 7, 4, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(8, 8, 4, 0x50, 0x10, 4, 1),
++
++      PIN_FIELD_BASE(9, 9, 5, 0x50, 0x10, 9, 1),
++      PIN_FIELD_BASE(10, 10, 5, 0x50, 0x10, 8, 1),
++      PIN_FIELD_BASE(11, 11, 5, 0x50, 0x10, 10, 1),
++      PIN_FIELD_BASE(12, 12, 5, 0x50, 0x10, 7, 1),
++      PIN_FIELD_BASE(13, 13, 5, 0x50, 0x10, 11, 1),
++
++      PIN_FIELD_BASE(14, 14, 4, 0x50, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(15, 15, 2, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(16, 16, 2, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(17, 17, 2, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(18, 18, 2, 0x50, 0x10, 4, 1),
++      PIN_FIELD_BASE(19, 19, 2, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(20, 20, 2, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(21, 21, 2, 0x50, 0x10, 6, 1),
++      PIN_FIELD_BASE(22, 22, 2, 0x50, 0x10, 7, 1),
++      PIN_FIELD_BASE(23, 23, 2, 0x50, 0x10, 10, 1),
++      PIN_FIELD_BASE(24, 24, 2, 0x50, 0x10, 9, 1),
++      PIN_FIELD_BASE(25, 25, 2, 0x50, 0x10, 8, 1),
++
++      PIN_FIELD_BASE(26, 26, 5, 0x50, 0x10, 0, 1),
++      PIN_FIELD_BASE(27, 27, 5, 0x50, 0x10, 4, 1),
++      PIN_FIELD_BASE(28, 28, 5, 0x50, 0x10, 3, 1),
++      PIN_FIELD_BASE(29, 29, 5, 0x50, 0x10, 1, 1),
++      PIN_FIELD_BASE(30, 30, 5, 0x50, 0x10, 2, 1),
++      PIN_FIELD_BASE(31, 31, 5, 0x50, 0x10, 5, 1),
++
++      PIN_FIELD_BASE(32, 32, 1, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(33, 33, 1, 0x40, 0x10, 3, 1),
++
++      PIN_FIELD_BASE(34, 34, 4, 0x50, 0x10, 5, 1),
++      PIN_FIELD_BASE(35, 35, 4, 0x50, 0x10, 7, 1),
++
++      PIN_FIELD_BASE(36, 36, 3, 0x40, 0x10, 2, 1),
++      PIN_FIELD_BASE(37, 37, 3, 0x40, 0x10, 3, 1),
++      PIN_FIELD_BASE(38, 38, 3, 0x40, 0x10, 0, 1),
++      PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1),
++};
++
++static const unsigned int mt7981_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_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_PUPD_R1R0_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_PU_PD_TYPE,/*69*/
++      MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/
++      MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/
++      MTK_PULL_PU_PD_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_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/
++      MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/
++      MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/
++      MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/
++      MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/
++      MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/
++      MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/
++      MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/
++      MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/
++      MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_TYPE,/*99*/
++      MTK_PULL_PU_PD_TYPE,/*100*/
++};
++
++static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
++      [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range),
++      [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range),
++      [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7981_pin_di_range),
++      [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7981_pin_do_range),
++      [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7981_pin_smt_range),
++      [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7981_pin_ies_range),
++      [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7981_pin_pu_range),
++      [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7981_pin_pd_range),
++      [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7981_pin_drv_range),
++      [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7981_pin_pupd_range),
++      [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7981_pin_r0_range),
++      [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7981_pin_r1_range),
++};
++
++static const struct mtk_pin_desc mt7981_pins[] = {
++      MT7981_PIN(0, "GPIO_WPS"),
++      MT7981_PIN(1, "GPIO_RESET"),
++      MT7981_PIN(2, "SYS_WATCHDOG"),
++      MT7981_PIN(3, "PCIE_PERESET_N"),
++      MT7981_PIN(4, "JTAG_JTDO"),
++      MT7981_PIN(5, "JTAG_JTDI"),
++      MT7981_PIN(6, "JTAG_JTMS"),
++      MT7981_PIN(7, "JTAG_JTCLK"),
++      MT7981_PIN(8, "JTAG_JTRST_N"),
++      MT7981_PIN(9, "WO_JTAG_JTDO"),
++      MT7981_PIN(10, "WO_JTAG_JTDI"),
++      MT7981_PIN(11, "WO_JTAG_JTMS"),
++      MT7981_PIN(12, "WO_JTAG_JTCLK"),
++      MT7981_PIN(13, "WO_JTAG_JTRST_N"),
++      MT7981_PIN(14, "USB_VBUS"),
++      MT7981_PIN(15, "PWM0"),
++      MT7981_PIN(16, "SPI0_CLK"),
++      MT7981_PIN(17, "SPI0_MOSI"),
++      MT7981_PIN(18, "SPI0_MISO"),
++      MT7981_PIN(19, "SPI0_CS"),
++      MT7981_PIN(20, "SPI0_HOLD"),
++      MT7981_PIN(21, "SPI0_WP"),
++      MT7981_PIN(22, "SPI1_CLK"),
++      MT7981_PIN(23, "SPI1_MOSI"),
++      MT7981_PIN(24, "SPI1_MISO"),
++      MT7981_PIN(25, "SPI1_CS"),
++      MT7981_PIN(26, "SPI2_CLK"),
++      MT7981_PIN(27, "SPI2_MOSI"),
++      MT7981_PIN(28, "SPI2_MISO"),
++      MT7981_PIN(29, "SPI2_CS"),
++      MT7981_PIN(30, "SPI2_HOLD"),
++      MT7981_PIN(31, "SPI2_WP"),
++      MT7981_PIN(32, "UART0_RXD"),
++      MT7981_PIN(33, "UART0_TXD"),
++      MT7981_PIN(34, "PCIE_CLK_REQ"),
++      MT7981_PIN(35, "PCIE_WAKE_N"),
++      MT7981_PIN(36, "SMI_MDC"),
++      MT7981_PIN(37, "SMI_MDIO"),
++      MT7981_PIN(38, "GBE_INT"),
++      MT7981_PIN(39, "GBE_RESET"),
++      MT7981_PIN(40, "WF_DIG_RESETB"),
++      MT7981_PIN(41, "WF_CBA_RESETB"),
++      MT7981_PIN(42, "WF_XO_REQ"),
++      MT7981_PIN(43, "WF_TOP_CLK"),
++      MT7981_PIN(44, "WF_TOP_DATA"),
++      MT7981_PIN(45, "WF_HB1"),
++      MT7981_PIN(46, "WF_HB2"),
++      MT7981_PIN(47, "WF_HB3"),
++      MT7981_PIN(48, "WF_HB4"),
++      MT7981_PIN(49, "WF_HB0"),
++      MT7981_PIN(50, "WF_HB0_B"),
++      MT7981_PIN(51, "WF_HB5"),
++      MT7981_PIN(52, "WF_HB6"),
++      MT7981_PIN(53, "WF_HB7"),
++      MT7981_PIN(54, "WF_HB8"),
++      MT7981_PIN(55, "WF_HB9"),
++      MT7981_PIN(56, "WF_HB10"),
++};
++
++/* List all groups consisting of these pins dedicated to the enablement of
++ * certain hardware block and the corresponding mode for all of the pins.
++ * The hardware probably has multiple combinations of these pinouts.
++ */
++
++/* WA_AICE */
++static int mt7981_wa_aice1_pins[] = { 0, 1, };
++static int mt7981_wa_aice1_funcs[] = { 2, 2, };
++
++static int mt7981_wa_aice2_pins[] = { 0, 1, };
++static int mt7981_wa_aice2_funcs[] = { 3, 3, };
++
++static int mt7981_wa_aice3_pins[] = { 28, 29, };
++static int mt7981_wa_aice3_funcs[] = { 3, 3, };
++
++static int mt7981_wm_aice1_pins[] = { 9, 10, };
++static int mt7981_wm_aice1_funcs[] = { 2, 2, };
++
++static int mt7981_wm_aice2_pins[] = { 30, 31, };
++static int mt7981_wm_aice2_funcs[] = { 5, 5, };
++
++/* WM_UART */
++static int mt7981_wm_uart_0_pins[] = { 0, 1, };
++static int mt7981_wm_uart_0_funcs[] = { 5, 5, };
++
++static int mt7981_wm_uart_1_pins[] = { 20, 21, };
++static int mt7981_wm_uart_1_funcs[] = { 4, 4, };
++
++static int mt7981_wm_uart_2_pins[] = { 30, 31, };
++static int mt7981_wm_uart_2_funcs[] = { 3, 3, };
++
++/* DFD */
++static int mt7981_dfd_pins[] = { 0, 1, 4, 5, };
++static int mt7981_dfd_funcs[] = { 5, 5, 6, 6, };
++
++/* SYS_WATCHDOG */
++static int mt7981_watchdog_pins[] = { 2, };
++static int mt7981_watchdog_funcs[] = { 1, };
++
++static int mt7981_watchdog1_pins[] = { 13, };
++static int mt7981_watchdog1_funcs[] = { 5, };
++
++/* PCIE_PERESET_N */
++static int mt7981_pcie_pereset_pins[] = { 3, };
++static int mt7981_pcie_pereset_funcs[] = { 1, };
++
++/* JTAG */
++static int mt7981_jtag_pins[] = { 4, 5, 6, 7, 8, };
++static int mt7981_jtag_funcs[] = { 1, 1, 1, 1, 1, };
++
++/* WM_JTAG */
++static int mt7981_wm_jtag_0_pins[] = { 4, 5, 6, 7, 8, };
++static int mt7981_wm_jtag_0_funcs[] = { 2, 2, 2, 2, 2, };
++
++static int mt7981_wm_jtag_1_pins[] = { 20, 21, 22, 23, 24, };
++static int mt7981_wm_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
++
++/* WO0_JTAG */
++static int mt7981_wo0_jtag_0_pins[] = { 9, 10, 11, 12, 13, };
++static int mt7981_wo0_jtag_0_funcs[] = { 1, 1, 1, 1, 1, };
++
++static int mt7981_wo0_jtag_1_pins[] = { 25, 26, 27, 28, 29, };
++static int mt7981_wo0_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
++
++/* UART2 */
++static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, };
++static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, };
++
++/* GBE_LED0 */
++static int mt7981_gbe_led0_pins[] = { 8, };
++static int mt7981_gbe_led0_funcs[] = { 3, };
++
++/* PTA_EXT */
++static int mt7981_pta_ext_0_pins[] = { 4, 5, 6, };
++static int mt7981_pta_ext_0_funcs[] = { 4, 4, 4, };
++
++static int mt7981_pta_ext_1_pins[] = { 22, 23, 24, };
++static int mt7981_pta_ext_1_funcs[] = { 4, 4, 4, };
++
++/* PWM2 */
++static int mt7981_pwm2_pins[] = { 7, };
++static int mt7981_pwm2_funcs[] = { 4, };
++
++/* NET_WO0_UART_TXD */
++static int mt7981_net_wo0_uart_txd_0_pins[] = { 8, };
++static int mt7981_net_wo0_uart_txd_0_funcs[] = { 4, };
++
++static int mt7981_net_wo0_uart_txd_1_pins[] = { 14, };
++static int mt7981_net_wo0_uart_txd_1_funcs[] = { 3, };
++
++static int mt7981_net_wo0_uart_txd_2_pins[] = { 15, };
++static int mt7981_net_wo0_uart_txd_2_funcs[] = { 4, };
++
++/* SPI1 */
++static int mt7981_spi1_0_pins[] = { 4, 5, 6, 7, };
++static int mt7981_spi1_0_funcs[] = { 5, 5, 5, 5, };
++
++/* I2C */
++static int mt7981_i2c0_0_pins[] = { 6, 7, };
++static int mt7981_i2c0_0_funcs[] = { 6, 6, };
++
++static int mt7981_i2c0_1_pins[] = { 30, 31, };
++static int mt7981_i2c0_1_funcs[] = { 4, 4, };
++
++static int mt7981_i2c0_2_pins[] = { 36, 37, };
++static int mt7981_i2c0_2_funcs[] = { 2, 2, };
++
++static int mt7981_u2_phy_i2c_pins[] = { 30, 31, };
++static int mt7981_u2_phy_i2c_funcs[] = { 6, 6, };
++
++static int mt7981_u3_phy_i2c_pins[] = { 32, 33, };
++static int mt7981_u3_phy_i2c_funcs[] = { 3, 3, };
++
++static int mt7981_sgmii1_phy_i2c_pins[] = { 32, 33, };
++static int mt7981_sgmii1_phy_i2c_funcs[] = { 2, 2, };
++
++static int mt7981_sgmii0_phy_i2c_pins[] = { 32, 33, };
++static int mt7981_sgmii0_phy_i2c_funcs[] = { 5, 5, };
++
++/* DFD_NTRST */
++static int mt7981_dfd_ntrst_pins[] = { 8, };
++static int mt7981_dfd_ntrst_funcs[] = { 6, };
++
++/* PWM0 */
++static int mt7981_pwm0_0_pins[] = { 13, };
++static int mt7981_pwm0_0_funcs[] = { 2, };
++
++static int mt7981_pwm0_1_pins[] = { 15, };
++static int mt7981_pwm0_1_funcs[] = { 1, };
++
++/* PWM1 */
++static int mt7981_pwm1_0_pins[] = { 14, };
++static int mt7981_pwm1_0_funcs[] = { 2, };
++
++static int mt7981_pwm1_1_pins[] = { 15, };
++static int mt7981_pwm1_1_funcs[] = { 3, };
++
++/* GBE_LED1 */
++static int mt7981_gbe_led1_pins[] = { 13, };
++static int mt7981_gbe_led1_funcs[] = { 3, };
++
++/* PCM */
++static int mt7981_pcm_pins[] = { 9, 10, 11, 12, 13, 25 };
++static int mt7981_pcm_funcs[] = { 4, 4, 4, 4, 4, 4, };
++
++/* UDI */
++static int mt7981_udi_pins[] = { 9, 10, 11, 12, 13, };
++static int mt7981_udi_funcs[] = { 6, 6, 6, 6, 6, };
++
++/* DRV_VBUS */
++static int mt7981_drv_vbus_pins[] = { 14, };
++static int mt7981_drv_vbus_funcs[] = { 1, };
++
++/* EMMC */
++static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, };
++static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
++
++/* SNFI */
++static int mt7981_snfi_pins[] = { 16, 17, 18, 19, 20, 21, };
++static int mt7981_snfi_funcs[] = { 3, 3, 3, 3, 3, 3, };
++
++/* SPI0 */
++static int mt7981_spi0_pins[] = { 16, 17, 18, 19, };
++static int mt7981_spi0_funcs[] = { 1, 1, 1, 1, };
++
++/* SPI0 */
++static int mt7981_spi0_wp_hold_pins[] = { 20, 21, };
++static int mt7981_spi0_wp_hold_funcs[] = { 1, 1, };
++
++/* SPI1 */
++static int mt7981_spi1_1_pins[] = { 22, 23, 24, 25, };
++static int mt7981_spi1_1_funcs[] = { 1, 1, 1, 1, };
++
++/* SPI2 */
++static int mt7981_spi2_pins[] = { 26, 27, 28, 29, };
++static int mt7981_spi2_funcs[] = { 1, 1, 1, 1, };
++
++/* SPI2 */
++static int mt7981_spi2_wp_hold_pins[] = { 30, 31, };
++static int mt7981_spi2_wp_hold_funcs[] = { 1, 1, };
++
++/* UART1 */
++static int mt7981_uart1_0_pins[] = { 16, 17, 18, 19, };
++static int mt7981_uart1_0_funcs[] = { 4, 4, 4, 4, };
++
++static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, };
++static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, };
++
++/* UART2 */
++static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
++static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
++
++/* UART0 */
++static int mt7981_uart0_pins[] = { 32, 33, };
++static int mt7981_uart0_funcs[] = { 1, 1, };
++
++/* PCIE_CLK_REQ */
++static int mt7981_pcie_clk_pins[] = { 34, };
++static int mt7981_pcie_clk_funcs[] = { 2, };
++
++/* PCIE_WAKE_N */
++static int mt7981_pcie_wake_pins[] = { 35, };
++static int mt7981_pcie_wake_funcs[] = { 2, };
++
++/* MDC_MDIO */
++static int mt7981_smi_mdc_mdio_pins[] = { 36, 37, };
++static int mt7981_smi_mdc_mdio_funcs[] = { 1, 1, };
++
++static int mt7981_gbe_ext_mdc_mdio_pins[] = { 36, 37, };
++static int mt7981_gbe_ext_mdc_mdio_funcs[] = { 3, 3, };
++
++/* WF0_MODE1 */
++static int mt7981_wf0_mode1_pins[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 };
++static int mt7981_wf0_mode1_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
++
++/* WF0_MODE3 */
++static int mt7981_wf0_mode3_pins[] = { 45, 46, 47, 48, 49, 51 };
++static int mt7981_wf0_mode3_funcs[] = { 2, 2, 2, 2, 2, 2 };
++
++/* WF2G_LED */
++static int mt7981_wf2g_led0_pins[] = { 30, };
++static int mt7981_wf2g_led0_funcs[] = { 2, };
++
++static int mt7981_wf2g_led1_pins[] = { 34, };
++static int mt7981_wf2g_led1_funcs[] = { 1, };
++
++/* WF5G_LED */
++static int mt7981_wf5g_led0_pins[] = { 31, };
++static int mt7981_wf5g_led0_funcs[] = { 2, };
++
++static int mt7981_wf5g_led1_pins[] = { 35, };
++static int mt7981_wf5g_led1_funcs[] = { 1, };
++
++/* MT7531_INT */
++static int mt7981_mt7531_int_pins[] = { 38, };
++static int mt7981_mt7531_int_funcs[] = { 1, };
++
++/* ANT_SEL */
++static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 34, 35 };
++static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
++
++static const struct group_desc mt7981_groups[] = {
++      /* @GPIO(0,1): WA_AICE(2) */
++      PINCTRL_PIN_GROUP("wa_aice1", mt7981_wa_aice1),
++      /* @GPIO(0,1): WA_AICE(3) */
++      PINCTRL_PIN_GROUP("wa_aice2", mt7981_wa_aice2),
++      /* @GPIO(0,1): WM_UART(5) */
++      PINCTRL_PIN_GROUP("wm_uart_0", mt7981_wm_uart_0),
++      /* @GPIO(0,1,4,5): DFD(6) */
++      PINCTRL_PIN_GROUP("dfd", mt7981_dfd),
++      /* @GPIO(2): SYS_WATCHDOG(1) */
++      PINCTRL_PIN_GROUP("watchdog", mt7981_watchdog),
++      /* @GPIO(3): PCIE_PERESET_N(1) */
++      PINCTRL_PIN_GROUP("pcie_pereset", mt7981_pcie_pereset),
++      /* @GPIO(4,8) JTAG(1) */
++      PINCTRL_PIN_GROUP("jtag", mt7981_jtag),
++      /* @GPIO(4,8) WM_JTAG(2) */
++      PINCTRL_PIN_GROUP("wm_jtag_0", mt7981_wm_jtag_0),
++      /* @GPIO(9,13) WO0_JTAG(1) */
++      PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0),
++      /* @GPIO(4,7) WM_JTAG(3) */
++      PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0),
++      /* @GPIO(8) GBE_LED0(3) */
++      PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0),
++      /* @GPIO(4,6) PTA_EXT(4) */
++      PINCTRL_PIN_GROUP("pta_ext_0", mt7981_pta_ext_0),
++      /* @GPIO(7) PWM2(4) */
++      PINCTRL_PIN_GROUP("pwm2", mt7981_pwm2),
++      /* @GPIO(8) NET_WO0_UART_TXD(4) */
++      PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7981_net_wo0_uart_txd_0),
++      /* @GPIO(4,7) SPI1(5) */
++      PINCTRL_PIN_GROUP("spi1_0", mt7981_spi1_0),
++      /* @GPIO(6,7) I2C(5) */
++      PINCTRL_PIN_GROUP("i2c0_0", mt7981_i2c0_0),
++      /* @GPIO(0,1,4,5): DFD_NTRST(6) */
++      PINCTRL_PIN_GROUP("dfd_ntrst", mt7981_dfd_ntrst),
++      /* @GPIO(9,10): WM_AICE(2) */
++      PINCTRL_PIN_GROUP("wm_aice1", mt7981_wm_aice1),
++      /* @GPIO(13): PWM0(2) */
++      PINCTRL_PIN_GROUP("pwm0_0", mt7981_pwm0_0),
++      /* @GPIO(15): PWM0(1) */
++      PINCTRL_PIN_GROUP("pwm0_1", mt7981_pwm0_1),
++      /* @GPIO(14): PWM1(2) */
++      PINCTRL_PIN_GROUP("pwm1_0", mt7981_pwm1_0),
++      /* @GPIO(15): PWM1(3) */
++      PINCTRL_PIN_GROUP("pwm1_1", mt7981_pwm1_1),
++      /* @GPIO(14) NET_WO0_UART_TXD(3) */
++      PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7981_net_wo0_uart_txd_1),
++      /* @GPIO(15) NET_WO0_UART_TXD(4) */
++      PINCTRL_PIN_GROUP("net_wo0_uart_txd_2", mt7981_net_wo0_uart_txd_2),
++      /* @GPIO(13) GBE_LED0(3) */
++      PINCTRL_PIN_GROUP("gbe_led1", mt7981_gbe_led1),
++      /* @GPIO(9,13) PCM(4) */
++      PINCTRL_PIN_GROUP("pcm", mt7981_pcm),
++      /* @GPIO(13): SYS_WATCHDOG1(5) */
++      PINCTRL_PIN_GROUP("watchdog1", mt7981_watchdog1),
++      /* @GPIO(9,13) UDI(4) */
++      PINCTRL_PIN_GROUP("udi", mt7981_udi),
++      /* @GPIO(14) DRV_VBUS(1) */
++      PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus),
++      /* @GPIO(15,25): EMMC(2) */
++      PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45),
++      /* @GPIO(16,21): SNFI(3) */
++      PINCTRL_PIN_GROUP("snfi", mt7981_snfi),
++      /* @GPIO(16,19): SPI0(1) */
++      PINCTRL_PIN_GROUP("spi0", mt7981_spi0),
++      /* @GPIO(20,21): SPI0(1) */
++      PINCTRL_PIN_GROUP("spi0_wp_hold", mt7981_spi0_wp_hold),
++      /* @GPIO(22,25) SPI1(1) */
++      PINCTRL_PIN_GROUP("spi1_1", mt7981_spi1_1),
++      /* @GPIO(26,29): SPI2(1) */
++      PINCTRL_PIN_GROUP("spi2", mt7981_spi2),
++      /* @GPIO(30,31): SPI0(1) */
++      PINCTRL_PIN_GROUP("spi2_wp_hold", mt7981_spi2_wp_hold),
++      /* @GPIO(16,19): UART1(4) */
++      PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0),
++      /* @GPIO(26,29): UART1(2) */
++      PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
++      /* @GPIO(22,25): UART1(3) */
++      PINCTRL_PIN_GROUP("uart2_1", mt7981_uart2_1),
++      /* @GPIO(22,24) PTA_EXT(4) */
++      PINCTRL_PIN_GROUP("pta_ext_1", mt7981_pta_ext_1),
++      /* @GPIO(20,21): WM_UART(4) */
++      PINCTRL_PIN_GROUP("wm_aurt_1", mt7981_wm_uart_1),
++      /* @GPIO(30,31): WM_UART(3) */
++      PINCTRL_PIN_GROUP("wm_aurt_2", mt7981_wm_uart_2),
++      /* @GPIO(20,24) WM_JTAG(5) */
++      PINCTRL_PIN_GROUP("wm_jtag_1", mt7981_wm_jtag_1),
++      /* @GPIO(25,29) WO0_JTAG(5) */
++      PINCTRL_PIN_GROUP("wo0_jtag_1", mt7981_wo0_jtag_1),
++      /* @GPIO(28,29): WA_AICE(3) */
++      PINCTRL_PIN_GROUP("wa_aice3", mt7981_wa_aice3),
++      /* @GPIO(30,31): WM_AICE(5) */
++      PINCTRL_PIN_GROUP("wm_aice2", mt7981_wm_aice2),
++      /* @GPIO(30,31): I2C(4) */
++      PINCTRL_PIN_GROUP("i2c0_1", mt7981_i2c0_1),
++      /* @GPIO(30,31): I2C(6) */
++      PINCTRL_PIN_GROUP("u2_phy_i2c", mt7981_u2_phy_i2c),
++      /* @GPIO(32,33): I2C(1) */
++      PINCTRL_PIN_GROUP("uart0", mt7981_uart0),
++      /* @GPIO(32,33): I2C(2) */
++      PINCTRL_PIN_GROUP("sgmii1_phy_i2c", mt7981_sgmii1_phy_i2c),
++      /* @GPIO(32,33): I2C(3) */
++      PINCTRL_PIN_GROUP("u3_phy_i2c", mt7981_u3_phy_i2c),
++      /* @GPIO(32,33): I2C(5) */
++      PINCTRL_PIN_GROUP("sgmii0_phy_i2c", mt7981_sgmii0_phy_i2c),
++      /* @GPIO(34): PCIE_CLK_REQ(2) */
++      PINCTRL_PIN_GROUP("pcie_clk", mt7981_pcie_clk),
++      /* @GPIO(35): PCIE_WAKE_N(2) */
++      PINCTRL_PIN_GROUP("pcie_wake", mt7981_pcie_wake),
++      /* @GPIO(36,37): I2C(2) */
++      PINCTRL_PIN_GROUP("i2c0_2", mt7981_i2c0_2),
++      /* @GPIO(36,37): MDC_MDIO(1) */
++      PINCTRL_PIN_GROUP("smi_mdc_mdio", mt7981_smi_mdc_mdio),
++      /* @GPIO(36,37): MDC_MDIO(3) */
++      PINCTRL_PIN_GROUP("gbe_ext_mdc_mdio", mt7981_gbe_ext_mdc_mdio),
++      /* @GPIO(69,85): WF0_MODE1(1) */
++      PINCTRL_PIN_GROUP("wf0_mode1", mt7981_wf0_mode1),
++      /* @GPIO(74,80): WF0_MODE3(3) */
++      PINCTRL_PIN_GROUP("wf0_mode3", mt7981_wf0_mode3),
++      /* @GPIO(30): WF2G_LED(2) */
++      PINCTRL_PIN_GROUP("wf2g_led0", mt7981_wf2g_led0),
++      /* @GPIO(34): WF2G_LED(1) */
++      PINCTRL_PIN_GROUP("wf2g_led1", mt7981_wf2g_led1),
++      /* @GPIO(31): WF5G_LED(2) */
++      PINCTRL_PIN_GROUP("wf5g_led0", mt7981_wf5g_led0),
++      /* @GPIO(35): WF5G_LED(1) */
++      PINCTRL_PIN_GROUP("wf5g_led1", mt7981_wf5g_led1),
++      /* @GPIO(38): MT7531_INT(1) */
++      PINCTRL_PIN_GROUP("mt7531_int", mt7981_mt7531_int),
++      /* @GPIO(14,15,26,17,18,19,20,21,22,23,24,25,34,35): ANT_SEL(1) */
++      PINCTRL_PIN_GROUP("ant_sel", mt7981_ant_sel),
++};
++
++/* 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 *mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", "wm_aice1_1",
++      "wa_aice3", "wm_aice1_2", };
++static const char *mt7981_uart_groups[] = { "wm_uart_0", "uart2_0",
++      "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2",
++      "uart1_0", "uart1_1", "uart2_1", "wm_aurt_1", "wm_aurt_2", "uart0", };
++static const char *mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
++static const char *mt7981_wdt_groups[] = { "watchdog", "watchdog1", };
++static const char *mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk", "pcie_wake", };
++static const char *mt7981_jtag_groups[] = { "jtag", "wm_jtag_0", "wo0_jtag_0",
++      "wo0_jtag_1", "wm_jtag_1", };
++static const char *mt7981_led_groups[] = { "gbe_led0", "gbe_led1", "wf2g_led0",
++      "wf2g_led1", "wf5g_led0", "wf5g_led1", };
++static const char *mt7981_pta_groups[] = { "pta_ext_0", "pta_ext_1", };
++static const char *mt7981_pwm_groups[] = { "pwm2", "pwm0_0", "pwm0_1",
++      "pwm1_0", "pwm1_1", };
++static const char *mt7981_spi_groups[] = { "spi1_0", "spi0", "spi0_wp_hold", "spi1_1", "spi2",
++      "spi2_wp_hold", };
++static const char *mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1", "u2_phy_i2c",
++      "sgmii1_phy_i2c", "u3_phy_i2c", "sgmii0_phy_i2c", "i2c0_2", };
++static const char *mt7981_pcm_groups[] = { "pcm", };
++static const char *mt7981_udi_groups[] = { "udi", };
++static const char *mt7981_usb_groups[] = { "drv_vbus", };
++static const char *mt7981_flash_groups[] = { "emmc_45", "snfi", };
++static const char *mt7981_ethernet_groups[] = { "smi_mdc_mdio", "gbe_ext_mdc_mdio",
++      "wf0_mode1", "wf0_mode3", "mt7531_int", };
++static const char *mt7981_ant_groups[] = { "ant_sel", };
++
++static const struct function_desc mt7981_functions[] = {
++      {"wa_aice",     mt7981_wa_aice_groups, ARRAY_SIZE(mt7981_wa_aice_groups)},
++      {"dfd", mt7981_dfd_groups, ARRAY_SIZE(mt7981_dfd_groups)},
++      {"jtag", mt7981_jtag_groups, ARRAY_SIZE(mt7981_jtag_groups)},
++      {"pta", mt7981_pta_groups, ARRAY_SIZE(mt7981_pta_groups)},
++      {"pcm", mt7981_pcm_groups, ARRAY_SIZE(mt7981_pcm_groups)},
++      {"udi", mt7981_udi_groups, ARRAY_SIZE(mt7981_udi_groups)},
++      {"usb", mt7981_usb_groups, ARRAY_SIZE(mt7981_usb_groups)},
++      {"ant", mt7981_ant_groups, ARRAY_SIZE(mt7981_ant_groups)},
++      {"eth", mt7981_ethernet_groups, ARRAY_SIZE(mt7981_ethernet_groups)},
++      {"i2c", mt7981_i2c_groups, ARRAY_SIZE(mt7981_i2c_groups)},
++      {"led", mt7981_led_groups, ARRAY_SIZE(mt7981_led_groups)},
++      {"pwm", mt7981_pwm_groups, ARRAY_SIZE(mt7981_pwm_groups)},
++      {"spi", mt7981_spi_groups, ARRAY_SIZE(mt7981_spi_groups)},
++      {"uart", mt7981_uart_groups, ARRAY_SIZE(mt7981_uart_groups)},
++      {"watchdog", mt7981_wdt_groups, ARRAY_SIZE(mt7981_wdt_groups)},
++      {"flash", mt7981_flash_groups, ARRAY_SIZE(mt7981_flash_groups)},
++      {"pcie", mt7981_pcie_groups, ARRAY_SIZE(mt7981_pcie_groups)},
++};
++
++static const struct mtk_eint_hw mt7981_eint_hw = {
++      .port_mask = 7,
++      .ports     = 7,
++      .ap_num    = ARRAY_SIZE(mt7981_pins),
++      .db_cnt    = 16,
++};
++
++static const char * const mt7981_pinctrl_register_base_names[] = {
++      "gpio", "iocfg_rt", "iocfg_rm", "iocfg_rb",
++      "iocfg_lb", "iocfg_bl", "iocfg_tm", "iocfg_tl",
++};
++
++static struct mtk_pin_soc mt7981_data = {
++      .reg_cal = mt7981_reg_cals,
++      .pins = mt7981_pins,
++      .npins = ARRAY_SIZE(mt7981_pins),
++      .grps = mt7981_groups,
++      .ngrps = ARRAY_SIZE(mt7981_groups),
++      .funcs = mt7981_functions,
++      .nfuncs = ARRAY_SIZE(mt7981_functions),
++      .eint_hw = &mt7981_eint_hw,
++      .gpio_m = 0,
++      .ies_present = false,
++      .base_names = mt7981_pinctrl_register_base_names,
++      .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
++      .pull_type = mt7981_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 mt7981_pinctrl_of_match[] = {
++      { .compatible = "mediatek,mt7981-pinctrl", },
++      {}
++};
++
++static int mt7981_pinctrl_probe(struct platform_device *pdev)
++{
++      return mtk_moore_pinctrl_probe(pdev, &mt7981_data);
++}
++
++static struct platform_driver mt7981_pinctrl_driver = {
++      .driver = {
++              .name = "mt7981-pinctrl",
++              .of_match_table = mt7981_pinctrl_of_match,
++      },
++      .probe = mt7981_pinctrl_probe,
++};
++
++static int __init mt7981_pinctrl_init(void)
++{
++      return platform_driver_register(&mt7981_pinctrl_driver);
++}
++arch_initcall(mt7981_pinctrl_init);
diff --git a/target/linux/mediatek/patches-6.6/216-v6.3-pinctrl-mediatek-add-missing-options-to-PINCTRL_MT79.patch b/target/linux/mediatek/patches-6.6/216-v6.3-pinctrl-mediatek-add-missing-options-to-PINCTRL_MT79.patch
new file mode 100644 (file)
index 0000000..995e0dc
--- /dev/null
@@ -0,0 +1,30 @@
+From c0ad453e94e5c404efbcf668648d07eaa1a71ed7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Sat, 18 Feb 2023 09:51:06 +0300
+Subject: [PATCH] pinctrl: mediatek: add missing options to PINCTRL_MT7981
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are options missing from PINCTRL_MT7981 whilst being on every other
+pin controller. Add them.
+
+Signed-off-by: Arınç ÃœNAL <arinc.unal@arinc9.com>
+Acked-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/20230218065108.8958-1-arinc.unal@arinc9.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/Kconfig | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -130,6 +130,8 @@ config PINCTRL_MT7622
+ config PINCTRL_MT7981
+       bool "Mediatek MT7981 pin control"
+       depends on OF
++      depends on ARM64 || COMPILE_TEST
++      default ARM64 && ARCH_MEDIATEK
+       select PINCTRL_MTK_MOORE
+ config PINCTRL_MT7986
diff --git a/target/linux/mediatek/patches-6.6/217-v6.5-pinctrl-mediatek-fix-pull_type-data-for-MT7981.patch b/target/linux/mediatek/patches-6.6/217-v6.5-pinctrl-mediatek-fix-pull_type-data-for-MT7981.patch
new file mode 100644 (file)
index 0000000..db25616
--- /dev/null
@@ -0,0 +1,76 @@
+From 8f6f16fe1553ce63edfb98a39ef9d4754a0c39bf Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 18 Aug 2023 04:02:35 +0100
+Subject: [PATCH] pinctrl: mediatek: fix pull_type data for MT7981
+
+MediaTek has released pull_type data for MT7981 in their SDK.
+Use it and set functions to configure pin bias.
+
+Fixes: 6c83b2d94fcc ("pinctrl: add mt7981 pinctrl driver")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/7bcc8ead25dbfabc7f5a85d066224a926fbb4941.1692327317.git.daniel@makrotopia.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7981.c | 44 +++++++----------------
+ 1 file changed, 13 insertions(+), 31 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+@@ -457,37 +457,15 @@ static const unsigned int mt7981_pull_ty
+       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_PUPD_R1R0_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_PU_PD_TYPE,/*69*/
+-      MTK_PULL_PU_PD_TYPE,/*70*/ MTK_PULL_PU_PD_TYPE,/*71*/
+-      MTK_PULL_PU_PD_TYPE,/*72*/ MTK_PULL_PU_PD_TYPE,/*73*/
+-      MTK_PULL_PU_PD_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_PU_PD_TYPE,/*80*/ MTK_PULL_PU_PD_TYPE,/*81*/
+-      MTK_PULL_PU_PD_TYPE,/*82*/ MTK_PULL_PU_PD_TYPE,/*83*/
+-      MTK_PULL_PU_PD_TYPE,/*84*/ MTK_PULL_PU_PD_TYPE,/*85*/
+-      MTK_PULL_PU_PD_TYPE,/*86*/ MTK_PULL_PU_PD_TYPE,/*87*/
+-      MTK_PULL_PU_PD_TYPE,/*88*/ MTK_PULL_PU_PD_TYPE,/*89*/
+-      MTK_PULL_PU_PD_TYPE,/*90*/ MTK_PULL_PU_PD_TYPE,/*91*/
+-      MTK_PULL_PU_PD_TYPE,/*92*/ MTK_PULL_PU_PD_TYPE,/*93*/
+-      MTK_PULL_PU_PD_TYPE,/*94*/ MTK_PULL_PU_PD_TYPE,/*95*/
+-      MTK_PULL_PU_PD_TYPE,/*96*/ MTK_PULL_PU_PD_TYPE,/*97*/
+-      MTK_PULL_PU_PD_TYPE,/*98*/ MTK_PULL_PU_PD_TYPE,/*99*/
+-      MTK_PULL_PU_PD_TYPE,/*100*/
++      MTK_PULL_PU_PD_TYPE,/*40*/ MTK_PULL_PU_PD_TYPE,/*41*/
++      MTK_PULL_PU_PD_TYPE,/*42*/ MTK_PULL_PU_PD_TYPE,/*43*/
++      MTK_PULL_PU_PD_TYPE,/*44*/ MTK_PULL_PU_PD_TYPE,/*45*/
++      MTK_PULL_PU_PD_TYPE,/*46*/ MTK_PULL_PU_PD_TYPE,/*47*/
++      MTK_PULL_PU_PD_TYPE,/*48*/ MTK_PULL_PU_PD_TYPE,/*49*/
++      MTK_PULL_PU_PD_TYPE,/*50*/ MTK_PULL_PU_PD_TYPE,/*51*/
++      MTK_PULL_PU_PD_TYPE,/*52*/ MTK_PULL_PU_PD_TYPE,/*53*/
++      MTK_PULL_PU_PD_TYPE,/*54*/ MTK_PULL_PU_PD_TYPE,/*55*/
++      MTK_PULL_PU_PD_TYPE,/*56*/
+ };
+ static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
+@@ -1014,6 +992,10 @@ static struct mtk_pin_soc mt7981_data =
+       .ies_present = false,
+       .base_names = mt7981_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7981_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 = mt7981_pull_type,
+       .bias_set_combo = mtk_pinconf_bias_set_combo,
+       .bias_get_combo = mtk_pinconf_bias_get_combo,
diff --git a/target/linux/mediatek/patches-6.6/218-pinctrl-mediatek-mt7981-add-additional-uart-groups.patch b/target/linux/mediatek/patches-6.6/218-pinctrl-mediatek-mt7981-add-additional-uart-groups.patch
new file mode 100644 (file)
index 0000000..d2f0558
--- /dev/null
@@ -0,0 +1,65 @@
+From 11db447f257231e08065989100311df57b7f1f1c Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 26 Aug 2023 21:06:14 +0100
+Subject: [PATCH] pinctrl: mediatek: mt7981: add additional uart groups
+
+Add uart2_0_tx_rx (pin 4, 5) and uart1_2 (pins 9, 10) groups.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7981.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+@@ -611,6 +611,9 @@ static int mt7981_wo0_jtag_1_funcs[] = {
+ static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, };
+ static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, };
++static int mt7981_uart2_0_tx_rx_pins[] = { 4, 5, };
++static int mt7981_uart2_0_tx_rx_funcs[] = { 3, 3, };
++
+ /* GBE_LED0 */
+ static int mt7981_gbe_led0_pins[] = { 8, };
+ static int mt7981_gbe_led0_funcs[] = { 3, };
+@@ -731,6 +734,9 @@ static int mt7981_uart1_0_funcs[] = { 4,
+ static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, };
+ static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, };
++static int mt7981_uart1_2_pins[] = { 9, 10, };
++static int mt7981_uart1_2_funcs[] = { 2, 2, };
++
+ /* UART2 */
+ static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
+ static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
+@@ -805,6 +811,8 @@ static const struct group_desc mt7981_gr
+       PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0),
+       /* @GPIO(4,7) WM_JTAG(3) */
+       PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0),
++      /* @GPIO(4,5) WM_JTAG(4) */
++      PINCTRL_PIN_GROUP("uart2_0_tx_rx", mt7981_uart2_0_tx_rx),
+       /* @GPIO(8) GBE_LED0(3) */
+       PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0),
+       /* @GPIO(4,6) PTA_EXT(4) */
+@@ -861,6 +869,8 @@ static const struct group_desc mt7981_gr
+       PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0),
+       /* @GPIO(26,29): UART1(2) */
+       PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
++      /* @GPIO(9,10): UART1(2) */
++      PINCTRL_PIN_GROUP("uart1_2", mt7981_uart1_2),
+       /* @GPIO(22,25): UART1(3) */
+       PINCTRL_PIN_GROUP("uart2_1", mt7981_uart2_1),
+       /* @GPIO(22,24) PTA_EXT(4) */
+@@ -922,9 +932,9 @@ static const struct group_desc mt7981_gr
+  */
+ static const char *mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", "wm_aice1_1",
+       "wa_aice3", "wm_aice1_2", };
+-static const char *mt7981_uart_groups[] = { "wm_uart_0", "uart2_0",
+-      "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2",
+-      "uart1_0", "uart1_1", "uart2_1", "wm_aurt_1", "wm_aurt_2", "uart0", };
++static const char *mt7981_uart_groups[] = { "net_wo0_uart_txd_0", "net_wo0_uart_txd_1",
++      "net_wo0_uart_txd_2", "uart0", "uart1_0", "uart1_1", "uart1_2", "uart2_0",
++      "uart2_0_tx_rx", "uart2_1", "wm_uart_0", "wm_aurt_1", "wm_aurt_2", };
+ static const char *mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
+ static const char *mt7981_wdt_groups[] = { "watchdog", "watchdog1", };
+ static const char *mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk", "pcie_wake", };
diff --git a/target/linux/mediatek/patches-6.6/219-v6.6-pinctrl-mediatek-assign-functions-to-configure-pin-b.patch b/target/linux/mediatek/patches-6.6/219-v6.6-pinctrl-mediatek-assign-functions-to-configure-pin-b.patch
new file mode 100644 (file)
index 0000000..7992a02
--- /dev/null
@@ -0,0 +1,41 @@
+From 0d8387fba9f151220e48dc3dcdc2335539708f13 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 18 Aug 2023 04:03:26 +0100
+Subject: [PATCH] pinctrl: mediatek: assign functions to configure pin bias on
+ MT7986
+
+Assign bias_disable_get/set and bias_get/set functions to allow
+configuring pin bias on MT7986.
+
+Fixes: 2c58d8dc9cd0 ("pinctrl: mediatek: add pull_type attribute for mediatek MT7986 SoC")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/47f72372354312a839b9337e09476aadcc206e8b.1692327317.git.daniel@makrotopia.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt7986.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+@@ -922,6 +922,10 @@ static struct mtk_pin_soc mt7986a_data =
+       .ies_present = false,
+       .base_names = mt7986_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7986_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 = mt7986_pull_type,
+       .bias_set_combo = mtk_pinconf_bias_set_combo,
+       .bias_get_combo = mtk_pinconf_bias_get_combo,
+@@ -944,6 +948,10 @@ static struct mtk_pin_soc mt7986b_data =
+       .ies_present = false,
+       .base_names = mt7986_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7986_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 = mt7986_pull_type,
+       .bias_set_combo = mtk_pinconf_bias_set_combo,
+       .bias_get_combo = mtk_pinconf_bias_get_combo,
diff --git a/target/linux/mediatek/patches-6.6/220-v6.3-clk-mediatek-clk-gate-Propagate-struct-device-with-m.patch b/target/linux/mediatek/patches-6.6/220-v6.3-clk-mediatek-clk-gate-Propagate-struct-device-with-m.patch
new file mode 100644 (file)
index 0000000..af5715e
--- /dev/null
@@ -0,0 +1,536 @@
+From fe5c8d03f3de89ae058e365b783f8c1314f47490 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:33 +0100
+Subject: [PATCH 01/15] clk: mediatek: clk-gate: Propagate struct device with
+ mtk_clk_register_gates()
+
+Commit e4c23e19aa2a ("clk: mediatek: Register clock gate with device")
+introduces a helper function for the sole purpose of propagating a
+struct device pointer to the clk API when registering the mtk-gate
+clocks to take advantage of Runtime PM when/where needed and where
+a power domain is defined in devicetree.
+
+Function mtk_clk_register_gates() then becomes a wrapper around the
+new mtk_clk_register_gates_with_dev() function that will simply pass
+NULL as struct device: this is essential when registering drivers
+with CLK_OF_DECLARE instead of as a platform device, as there will
+be no struct device to pass... but we can as well simply have only
+one function that always takes such pointer as a param and pass NULL
+when unavoidable.
+
+This commit removes the mtk_clk_register_gates() wrapper and renames
+mtk_clk_register_gates_with_dev() to the former and all of the calls
+to either of the two functions were fixed in all drivers in order to
+reflect this change; also, to improve consistency with other kernel
+functions, the pointer to struct device was moved as the first param.
+
+Since a lot of MediaTek clock drivers are actually registering as a
+platform device, but were still registering the mtk-gate clocks
+without passing any struct device to the clock framework, they've
+been changed to pass a valid one now, as to make all those platforms
+able to use runtime power management where available.
+
+While at it, some much needed indentation changes were also done.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Tested-by: Miles Chen <miles.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230120092053.182923-4-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+
+[daniel@makrotopia.org: dropped parts not relevant for OpenWrt]
+---
+ drivers/clk/mediatek/clk-gate.c            | 23 +++++++---------------
+ drivers/clk/mediatek/clk-gate.h            |  7 +------
+ drivers/clk/mediatek/clk-mt2701-aud.c      |  4 ++--
+ drivers/clk/mediatek/clk-mt2701-eth.c      |  4 ++--
+ drivers/clk/mediatek/clk-mt2701-g3d.c      |  2 +-
+ drivers/clk/mediatek/clk-mt2701-hif.c      |  4 ++--
+ drivers/clk/mediatek/clk-mt2701-mm.c       |  4 ++--
+ drivers/clk/mediatek/clk-mt2701.c          | 12 +++++------
+ drivers/clk/mediatek/clk-mt2712-mm.c       |  4 ++--
+ drivers/clk/mediatek/clk-mt2712.c          | 12 +++++------
+ drivers/clk/mediatek/clk-mt7622-aud.c      |  4 ++--
+ drivers/clk/mediatek/clk-mt7622-eth.c      |  8 ++++----
+ drivers/clk/mediatek/clk-mt7622-hif.c      |  8 ++++----
+ drivers/clk/mediatek/clk-mt7622.c          | 14 ++++++-------
+ drivers/clk/mediatek/clk-mt7629-eth.c      |  7 ++++---
+ drivers/clk/mediatek/clk-mt7629-hif.c      |  8 ++++----
+ drivers/clk/mediatek/clk-mt7629.c          | 10 +++++-----
+ drivers/clk/mediatek/clk-mt7986-eth.c      | 10 +++++-----
+ drivers/clk/mediatek/clk-mt7986-infracfg.c |  4 ++--
+ 19 files changed, 68 insertions(+), 81 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-gate.c
++++ b/drivers/clk/mediatek/clk-gate.c
+@@ -152,12 +152,12 @@ const struct clk_ops mtk_clk_gate_ops_no
+ };
+ EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
+-static struct clk_hw *mtk_clk_register_gate(const char *name,
++static struct clk_hw *mtk_clk_register_gate(struct device *dev, const char *name,
+                                        const char *parent_name,
+                                        struct regmap *regmap, int set_ofs,
+                                        int clr_ofs, int sta_ofs, u8 bit,
+                                        const struct clk_ops *ops,
+-                                       unsigned long flags, struct device *dev)
++                                       unsigned long flags)
+ {
+       struct mtk_clk_gate *cg;
+       int ret;
+@@ -202,10 +202,9 @@ static void mtk_clk_unregister_gate(stru
+       kfree(cg);
+ }
+-int mtk_clk_register_gates_with_dev(struct device_node *node,
+-                                  const struct mtk_gate *clks, int num,
+-                                  struct clk_hw_onecell_data *clk_data,
+-                                  struct device *dev)
++int mtk_clk_register_gates(struct device *dev, struct device_node *node,
++                         const struct mtk_gate *clks, int num,
++                         struct clk_hw_onecell_data *clk_data)
+ {
+       int i;
+       struct clk_hw *hw;
+@@ -229,13 +228,13 @@ int mtk_clk_register_gates_with_dev(stru
+                       continue;
+               }
+-              hw = mtk_clk_register_gate(gate->name, gate->parent_name,
++              hw = mtk_clk_register_gate(dev, gate->name, gate->parent_name,
+                                           regmap,
+                                           gate->regs->set_ofs,
+                                           gate->regs->clr_ofs,
+                                           gate->regs->sta_ofs,
+                                           gate->shift, gate->ops,
+-                                          gate->flags, dev);
++                                          gate->flags);
+               if (IS_ERR(hw)) {
+                       pr_err("Failed to register clk %s: %pe\n", gate->name,
+@@ -261,14 +260,6 @@ err:
+       return PTR_ERR(hw);
+ }
+-EXPORT_SYMBOL_GPL(mtk_clk_register_gates_with_dev);
+-
+-int mtk_clk_register_gates(struct device_node *node,
+-                         const struct mtk_gate *clks, int num,
+-                         struct clk_hw_onecell_data *clk_data)
+-{
+-      return mtk_clk_register_gates_with_dev(node, clks, num, clk_data, NULL);
+-}
+ EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
+ void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
+--- a/drivers/clk/mediatek/clk-gate.h
++++ b/drivers/clk/mediatek/clk-gate.h
+@@ -50,15 +50,10 @@ struct mtk_gate {
+ #define GATE_MTK(_id, _name, _parent, _regs, _shift, _ops)            \
+       GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift, _ops, 0)
+-int mtk_clk_register_gates(struct device_node *node,
++int mtk_clk_register_gates(struct device *dev, struct device_node *node,
+                          const struct mtk_gate *clks, int num,
+                          struct clk_hw_onecell_data *clk_data);
+-int mtk_clk_register_gates_with_dev(struct device_node *node,
+-                                  const struct mtk_gate *clks, int num,
+-                                  struct clk_hw_onecell_data *clk_data,
+-                                  struct device *dev);
+-
+ void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
+                             struct clk_hw_onecell_data *clk_data);
+--- a/drivers/clk/mediatek/clk-mt2701-aud.c
++++ b/drivers/clk/mediatek/clk-mt2701-aud.c
+@@ -127,8 +127,8 @@ static int clk_mt2701_aud_probe(struct p
+       clk_data = mtk_alloc_clk_data(CLK_AUD_NR);
+-      mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, audio_clks,
++                             ARRAY_SIZE(audio_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r) {
+--- a/drivers/clk/mediatek/clk-mt2701-eth.c
++++ b/drivers/clk/mediatek/clk-mt2701-eth.c
+@@ -51,8 +51,8 @@ static int clk_mt2701_eth_probe(struct p
+       clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
+-      mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
+-                                              clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, eth_clks,
++                             ARRAY_SIZE(eth_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+--- a/drivers/clk/mediatek/clk-mt2701-g3d.c
++++ b/drivers/clk/mediatek/clk-mt2701-g3d.c
+@@ -45,7 +45,7 @@ static int clk_mt2701_g3dsys_init(struct
+       clk_data = mtk_alloc_clk_data(CLK_G3DSYS_NR);
+-      mtk_clk_register_gates(node, g3d_clks, ARRAY_SIZE(g3d_clks),
++      mtk_clk_register_gates(&pdev->dev, node, g3d_clks, ARRAY_SIZE(g3d_clks),
+                              clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+--- a/drivers/clk/mediatek/clk-mt2701-hif.c
++++ b/drivers/clk/mediatek/clk-mt2701-hif.c
+@@ -48,8 +48,8 @@ static int clk_mt2701_hif_probe(struct p
+       clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
+-      mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
+-                                              clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, hif_clks,
++                             ARRAY_SIZE(hif_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r) {
+--- a/drivers/clk/mediatek/clk-mt2701-mm.c
++++ b/drivers/clk/mediatek/clk-mt2701-mm.c
+@@ -76,8 +76,8 @@ static int clk_mt2701_mm_probe(struct pl
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR);
+-      mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+-                                              clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, mm_clks,
++                             ARRAY_SIZE(mm_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -685,8 +685,8 @@ static int mtk_topckgen_init(struct plat
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
+                               base, &mt2701_clk_lock, clk_data);
+-      mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
+-                                              clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, top_clks,
++                             ARRAY_SIZE(top_clks), clk_data);
+       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ }
+@@ -789,8 +789,8 @@ static int mtk_infrasys_init(struct plat
+               }
+       }
+-      mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+-                                              infra_clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, infra_clks,
++                             ARRAY_SIZE(infra_clks), infra_clk_data);
+       mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
+                                               infra_clk_data);
+@@ -902,8 +902,8 @@ static int mtk_pericfg_init(struct platf
+       if (!clk_data)
+               return -ENOMEM;
+-      mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+-                                              clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, peri_clks,
++                             ARRAY_SIZE(peri_clks), clk_data);
+       mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
+                       &mt2701_clk_lock, clk_data);
+--- a/drivers/clk/mediatek/clk-mt2712-mm.c
++++ b/drivers/clk/mediatek/clk-mt2712-mm.c
+@@ -117,8 +117,8 @@ static int clk_mt2712_mm_probe(struct pl
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+-      mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+-                      clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, mm_clks,
++                             ARRAY_SIZE(mm_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+--- a/drivers/clk/mediatek/clk-mt2712.c
++++ b/drivers/clk/mediatek/clk-mt2712.c
+@@ -1324,8 +1324,8 @@ static int clk_mt2712_top_probe(struct p
+                       &mt2712_clk_lock, top_clk_data);
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
+                       &mt2712_clk_lock, top_clk_data);
+-      mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
+-                      top_clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, top_clks,
++                             ARRAY_SIZE(top_clks), top_clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, top_clk_data);
+@@ -1344,8 +1344,8 @@ static int clk_mt2712_infra_probe(struct
+       clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+-      mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+-                      clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, infra_clks,
++                             ARRAY_SIZE(infra_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+@@ -1366,8 +1366,8 @@ static int clk_mt2712_peri_probe(struct
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+-      mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+-                      clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, peri_clks,
++                             ARRAY_SIZE(peri_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+--- a/drivers/clk/mediatek/clk-mt7622-aud.c
++++ b/drivers/clk/mediatek/clk-mt7622-aud.c
+@@ -114,8 +114,8 @@ static int clk_mt7622_audiosys_init(stru
+       clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
+-      mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, audio_clks,
++                             ARRAY_SIZE(audio_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r) {
+--- a/drivers/clk/mediatek/clk-mt7622-eth.c
++++ b/drivers/clk/mediatek/clk-mt7622-eth.c
+@@ -69,8 +69,8 @@ static int clk_mt7622_ethsys_init(struct
+       clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK);
+-      mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, eth_clks,
++                             ARRAY_SIZE(eth_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+@@ -91,8 +91,8 @@ static int clk_mt7622_sgmiisys_init(stru
+       clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK);
+-      mtk_clk_register_gates(node, sgmii_clks, ARRAY_SIZE(sgmii_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, sgmii_clks,
++                             ARRAY_SIZE(sgmii_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+--- a/drivers/clk/mediatek/clk-mt7622-hif.c
++++ b/drivers/clk/mediatek/clk-mt7622-hif.c
+@@ -80,8 +80,8 @@ static int clk_mt7622_ssusbsys_init(stru
+       clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK);
+-      mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, ssusb_clks,
++                             ARRAY_SIZE(ssusb_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+@@ -102,8 +102,8 @@ static int clk_mt7622_pciesys_init(struc
+       clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK);
+-      mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, pcie_clks,
++                             ARRAY_SIZE(pcie_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+--- a/drivers/clk/mediatek/clk-mt7622.c
++++ b/drivers/clk/mediatek/clk-mt7622.c
+@@ -621,8 +621,8 @@ static int mtk_topckgen_init(struct plat
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
+                                 base, &mt7622_clk_lock, clk_data);
+-      mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, top_clks,
++                             ARRAY_SIZE(top_clks), clk_data);
+       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ }
+@@ -635,8 +635,8 @@ static int mtk_infrasys_init(struct plat
+       clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+-      mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, infra_clks,
++                             ARRAY_SIZE(infra_clks), clk_data);
+       mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
+                                 clk_data);
+@@ -663,7 +663,7 @@ static int mtk_apmixedsys_init(struct pl
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls),
+                             clk_data);
+-      mtk_clk_register_gates(node, apmixed_clks,
++      mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,
+                              ARRAY_SIZE(apmixed_clks), clk_data);
+       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+@@ -682,8 +682,8 @@ static int mtk_pericfg_init(struct platf
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+-      mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, peri_clks,
++                             ARRAY_SIZE(peri_clks), clk_data);
+       mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
+                                   &mt7622_clk_lock, clk_data);
+--- a/drivers/clk/mediatek/clk-mt7629-eth.c
++++ b/drivers/clk/mediatek/clk-mt7629-eth.c
+@@ -82,7 +82,8 @@ static int clk_mt7629_ethsys_init(struct
+       if (!clk_data)
+               return -ENOMEM;
+-      mtk_clk_register_gates(node, eth_clks, CLK_ETH_NR_CLK, clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, eth_clks,
++                             CLK_ETH_NR_CLK, clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+@@ -106,8 +107,8 @@ static int clk_mt7629_sgmiisys_init(stru
+       if (!clk_data)
+               return -ENOMEM;
+-      mtk_clk_register_gates(node, sgmii_clks[id++], CLK_SGMII_NR_CLK,
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, sgmii_clks[id++],
++                             CLK_SGMII_NR_CLK, clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+--- a/drivers/clk/mediatek/clk-mt7629-hif.c
++++ b/drivers/clk/mediatek/clk-mt7629-hif.c
+@@ -75,8 +75,8 @@ static int clk_mt7629_ssusbsys_init(stru
+       clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK);
+-      mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, ssusb_clks,
++                             ARRAY_SIZE(ssusb_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+@@ -97,8 +97,8 @@ static int clk_mt7629_pciesys_init(struc
+       clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK);
+-      mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, pcie_clks,
++                             ARRAY_SIZE(pcie_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+--- a/drivers/clk/mediatek/clk-mt7629.c
++++ b/drivers/clk/mediatek/clk-mt7629.c
+@@ -585,8 +585,8 @@ static int mtk_infrasys_init(struct plat
+       if (!clk_data)
+               return -ENOMEM;
+-      mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, infra_clks,
++                             ARRAY_SIZE(infra_clks), clk_data);
+       mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
+                                 clk_data);
+@@ -610,8 +610,8 @@ static int mtk_pericfg_init(struct platf
+       if (!clk_data)
+               return -ENOMEM;
+-      mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, peri_clks,
++                             ARRAY_SIZE(peri_clks), clk_data);
+       mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
+                                   &mt7629_clk_lock, clk_data);
+@@ -637,7 +637,7 @@ static int mtk_apmixedsys_init(struct pl
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls),
+                             clk_data);
+-      mtk_clk_register_gates(node, apmixed_clks,
++      mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,
+                              ARRAY_SIZE(apmixed_clks), clk_data);
+       clk_prepare_enable(clk_data->hws[CLK_APMIXED_ARMPLL]->clk);
+--- a/drivers/clk/mediatek/clk-mt7986-eth.c
++++ b/drivers/clk/mediatek/clk-mt7986-eth.c
+@@ -72,8 +72,8 @@ static void __init mtk_sgmiisys_0_init(s
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
+-      mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
+-                             clk_data);
++      mtk_clk_register_gates(NULL, node, sgmii0_clks,
++                             ARRAY_SIZE(sgmii0_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+@@ -90,8 +90,8 @@ static void __init mtk_sgmiisys_1_init(s
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
+-      mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
+-                             clk_data);
++      mtk_clk_register_gates(NULL, node, sgmii1_clks,
++                             ARRAY_SIZE(sgmii1_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+@@ -109,7 +109,7 @@ static void __init mtk_ethsys_init(struc
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(eth_clks));
+-      mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
++      mtk_clk_register_gates(NULL, node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+--- a/drivers/clk/mediatek/clk-mt7986-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
+@@ -180,8 +180,8 @@ static int clk_mt7986_infracfg_probe(str
+       mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+       mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
+                              &mt7986_clk_lock, clk_data);
+-      mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+-                             clk_data);
++      mtk_clk_register_gates(&pdev->dev, node, infra_clks,
++                             ARRAY_SIZE(infra_clks), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r) {
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -459,8 +459,8 @@ int mtk_clk_simple_probe(struct platform
+       if (!clk_data)
+               return -ENOMEM;
+-      r = mtk_clk_register_gates_with_dev(node, mcd->clks, mcd->num_clks,
+-                                          clk_data, &pdev->dev);
++      r = mtk_clk_register_gates(&pdev->dev, node, mcd->clks, mcd->num_clks,
++                                 clk_data);
+       if (r)
+               goto free_data;
diff --git a/target/linux/mediatek/patches-6.6/221-v6.3-clk-mediatek-cpumux-Propagate-struct-device-where-po.patch b/target/linux/mediatek/patches-6.6/221-v6.3-clk-mediatek-cpumux-Propagate-struct-device-where-po.patch
new file mode 100644 (file)
index 0000000..223155c
--- /dev/null
@@ -0,0 +1,140 @@
+From b888303c7d23d7bd0c8667cfc657669e5d153fea Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:34 +0100
+Subject: [PATCH 02/15] clk: mediatek: cpumux: Propagate struct device where
+ possible
+
+Take a pointer to a struct device in mtk_clk_register_cpumuxes() and
+propagate the same to mtk_clk_register_cpumux() => clk_hw_register().
+Even though runtime pm is unlikely to be used with CPU muxes, this
+helps with code consistency and possibly opens to commonization of
+some mtk_clk_register_(x) functions.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Tested-by: Miles Chen <miles.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230120092053.182923-5-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/clk-cpumux.c          | 8 ++++----
+ drivers/clk/mediatek/clk-cpumux.h          | 2 +-
+ drivers/clk/mediatek/clk-mt2701.c          | 2 +-
+ drivers/clk/mediatek/clk-mt6795-infracfg.c | 3 ++-
+ drivers/clk/mediatek/clk-mt7622.c          | 4 ++--
+ drivers/clk/mediatek/clk-mt7629.c          | 4 ++--
+ drivers/clk/mediatek/clk-mt8173.c          | 4 ++--
+ 7 files changed, 14 insertions(+), 13 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-cpumux.c
++++ b/drivers/clk/mediatek/clk-cpumux.c
+@@ -58,7 +58,7 @@ static const struct clk_ops clk_cpumux_o
+ };
+ static struct clk_hw *
+-mtk_clk_register_cpumux(const struct mtk_composite *mux,
++mtk_clk_register_cpumux(struct device *dev, const struct mtk_composite *mux,
+                       struct regmap *regmap)
+ {
+       struct mtk_clk_cpumux *cpumux;
+@@ -81,7 +81,7 @@ mtk_clk_register_cpumux(const struct mtk
+       cpumux->regmap = regmap;
+       cpumux->hw.init = &init;
+-      ret = clk_hw_register(NULL, &cpumux->hw);
++      ret = clk_hw_register(dev, &cpumux->hw);
+       if (ret) {
+               kfree(cpumux);
+               return ERR_PTR(ret);
+@@ -102,7 +102,7 @@ static void mtk_clk_unregister_cpumux(st
+       kfree(cpumux);
+ }
+-int mtk_clk_register_cpumuxes(struct device_node *node,
++int mtk_clk_register_cpumuxes(struct device *dev, struct device_node *node,
+                             const struct mtk_composite *clks, int num,
+                             struct clk_hw_onecell_data *clk_data)
+ {
+@@ -125,7 +125,7 @@ int mtk_clk_register_cpumuxes(struct dev
+                       continue;
+               }
+-              hw = mtk_clk_register_cpumux(mux, regmap);
++              hw = mtk_clk_register_cpumux(dev, mux, regmap);
+               if (IS_ERR(hw)) {
+                       pr_err("Failed to register clk %s: %pe\n", mux->name,
+                              hw);
+--- a/drivers/clk/mediatek/clk-cpumux.h
++++ b/drivers/clk/mediatek/clk-cpumux.h
+@@ -11,7 +11,7 @@ struct clk_hw_onecell_data;
+ struct device_node;
+ struct mtk_composite;
+-int mtk_clk_register_cpumuxes(struct device_node *node,
++int mtk_clk_register_cpumuxes(struct device *dev, struct device_node *node,
+                             const struct mtk_composite *clks, int num,
+                             struct clk_hw_onecell_data *clk_data);
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -761,7 +761,7 @@ static void __init mtk_infrasys_init_ear
+       mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
+                                               infra_clk_data);
+-      mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
++      mtk_clk_register_cpumuxes(NULL, node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
+                                 infra_clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+--- a/drivers/clk/mediatek/clk-mt6795-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt6795-infracfg.c
+@@ -105,7 +105,8 @@ static int clk_mt6795_infracfg_probe(str
+       if (ret)
+               goto free_clk_data;
+-      ret = mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes), clk_data);
++      ret = mtk_clk_register_cpumuxes(&pdev->dev, node, cpu_muxes,
++                                      ARRAY_SIZE(cpu_muxes), clk_data);
+       if (ret)
+               goto unregister_gates;
+--- a/drivers/clk/mediatek/clk-mt7622.c
++++ b/drivers/clk/mediatek/clk-mt7622.c
+@@ -638,8 +638,8 @@ static int mtk_infrasys_init(struct plat
+       mtk_clk_register_gates(&pdev->dev, node, infra_clks,
+                              ARRAY_SIZE(infra_clks), clk_data);
+-      mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
+-                                clk_data);
++      mtk_clk_register_cpumuxes(&pdev->dev, node, infra_muxes,
++                                ARRAY_SIZE(infra_muxes), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+                                  clk_data);
+--- a/drivers/clk/mediatek/clk-mt7629.c
++++ b/drivers/clk/mediatek/clk-mt7629.c
+@@ -588,8 +588,8 @@ static int mtk_infrasys_init(struct plat
+       mtk_clk_register_gates(&pdev->dev, node, infra_clks,
+                              ARRAY_SIZE(infra_clks), clk_data);
+-      mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
+-                                clk_data);
++      mtk_clk_register_cpumuxes(&pdev->dev, node, infra_muxes,
++                                ARRAY_SIZE(infra_muxes), clk_data);
+       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+                                     clk_data);
+--- a/drivers/clk/mediatek/clk-mt8173.c
++++ b/drivers/clk/mediatek/clk-mt8173.c
+@@ -892,8 +892,8 @@ static void __init mtk_infrasys_init(str
+                                               clk_data);
+       mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+-      mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
+-                                clk_data);
++      mtk_clk_register_cpumuxes(NULL, node, cpu_muxes,
++                                ARRAY_SIZE(cpu_muxes), clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
diff --git a/target/linux/mediatek/patches-6.6/222-v6.3-clk-mediatek-clk-mtk-Propagate-struct-device-for-com.patch b/target/linux/mediatek/patches-6.6/222-v6.3-clk-mediatek-clk-mtk-Propagate-struct-device-for-com.patch
new file mode 100644 (file)
index 0000000..eca1b61
--- /dev/null
@@ -0,0 +1,181 @@
+From f23375db001ec0fe9f565be75eff43adde15407e Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:35 +0100
+Subject: [PATCH 03/15] clk: mediatek: clk-mtk: Propagate struct device for
+ composites
+
+Like done for cpumux clocks, propagate struct device for composite
+clocks registered through clk-mtk helpers to be able to get runtime
+pm support for MTK clocks.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Miles Chen <miles.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230120092053.182923-6-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+
+[daniel@makrotopia.org: remove parts not relevant for OpenWrt]
+---
+ drivers/clk/mediatek/clk-mt2701.c | 10 ++++++----
+ drivers/clk/mediatek/clk-mt2712.c | 12 ++++++++----
+ drivers/clk/mediatek/clk-mt7622.c |  8 +++++---
+ drivers/clk/mediatek/clk-mt7629.c |  8 +++++---
+ drivers/clk/mediatek/clk-mtk.c    | 11 ++++++-----
+ drivers/clk/mediatek/clk-mtk.h    |  3 ++-
+ 6 files changed, 32 insertions(+), 20 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -679,8 +679,9 @@ static int mtk_topckgen_init(struct plat
+       mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
+                                                               clk_data);
+-      mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
+-                              base, &mt2701_clk_lock, clk_data);
++      mtk_clk_register_composites(&pdev->dev, top_muxes,
++                                  ARRAY_SIZE(top_muxes), base,
++                                  &mt2701_clk_lock, clk_data);
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
+                               base, &mt2701_clk_lock, clk_data);
+@@ -905,8 +906,9 @@ static int mtk_pericfg_init(struct platf
+       mtk_clk_register_gates(&pdev->dev, node, peri_clks,
+                              ARRAY_SIZE(peri_clks), clk_data);
+-      mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
+-                      &mt2701_clk_lock, clk_data);
++      mtk_clk_register_composites(&pdev->dev, peri_muxs,
++                                  ARRAY_SIZE(peri_muxs), base,
++                                  &mt2701_clk_lock, clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+--- a/drivers/clk/mediatek/clk-mt2712.c
++++ b/drivers/clk/mediatek/clk-mt2712.c
+@@ -1320,8 +1320,9 @@ static int clk_mt2712_top_probe(struct p
+       mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
+                       top_clk_data);
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+-      mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+-                      &mt2712_clk_lock, top_clk_data);
++      mtk_clk_register_composites(&pdev->dev, top_muxes,
++                                  ARRAY_SIZE(top_muxes), base,
++                                  &mt2712_clk_lock, top_clk_data);
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
+                       &mt2712_clk_lock, top_clk_data);
+       mtk_clk_register_gates(&pdev->dev, node, top_clks,
+@@ -1395,8 +1396,11 @@ static int clk_mt2712_mcu_probe(struct p
+       clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
+-      mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
+-                      &mt2712_clk_lock, clk_data);
++      r = mtk_clk_register_composites(&pdev->dev, mcu_muxes,
++                                      ARRAY_SIZE(mcu_muxes), base,
++                                      &mt2712_clk_lock, clk_data);
++      if (r)
++              dev_err(&pdev->dev, "Could not register composites: %d\n", r);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+--- a/drivers/clk/mediatek/clk-mt7622.c
++++ b/drivers/clk/mediatek/clk-mt7622.c
+@@ -615,8 +615,9 @@ static int mtk_topckgen_init(struct plat
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
+                                clk_data);
+-      mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
+-                                  base, &mt7622_clk_lock, clk_data);
++      mtk_clk_register_composites(&pdev->dev, top_muxes,
++                                  ARRAY_SIZE(top_muxes), base,
++                                  &mt7622_clk_lock, clk_data);
+       mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
+                                 base, &mt7622_clk_lock, clk_data);
+@@ -685,7 +686,8 @@ static int mtk_pericfg_init(struct platf
+       mtk_clk_register_gates(&pdev->dev, node, peri_clks,
+                              ARRAY_SIZE(peri_clks), clk_data);
+-      mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
++      mtk_clk_register_composites(&pdev->dev, peri_muxes,
++                                  ARRAY_SIZE(peri_muxes), base,
+                                   &mt7622_clk_lock, clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+--- a/drivers/clk/mediatek/clk-mt7629.c
++++ b/drivers/clk/mediatek/clk-mt7629.c
+@@ -566,8 +566,9 @@ static int mtk_topckgen_init(struct plat
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
+                                clk_data);
+-      mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
+-                                  base, &mt7629_clk_lock, clk_data);
++      mtk_clk_register_composites(&pdev->dev, top_muxes,
++                                  ARRAY_SIZE(top_muxes), base,
++                                  &mt7629_clk_lock, clk_data);
+       clk_prepare_enable(clk_data->hws[CLK_TOP_AXI_SEL]->clk);
+       clk_prepare_enable(clk_data->hws[CLK_TOP_MEM_SEL]->clk);
+@@ -613,7 +614,8 @@ static int mtk_pericfg_init(struct platf
+       mtk_clk_register_gates(&pdev->dev, node, peri_clks,
+                              ARRAY_SIZE(peri_clks), clk_data);
+-      mtk_clk_register_composites(peri_muxes, ARRAY_SIZE(peri_muxes), base,
++      mtk_clk_register_composites(&pdev->dev, peri_muxes,
++                                  ARRAY_SIZE(peri_muxes), base,
+                                   &mt7629_clk_lock, clk_data);
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -197,8 +197,8 @@ void mtk_clk_unregister_factors(const st
+ }
+ EXPORT_SYMBOL_GPL(mtk_clk_unregister_factors);
+-static struct clk_hw *mtk_clk_register_composite(const struct mtk_composite *mc,
+-              void __iomem *base, spinlock_t *lock)
++static struct clk_hw *mtk_clk_register_composite(struct device *dev,
++              const struct mtk_composite *mc, void __iomem *base, spinlock_t *lock)
+ {
+       struct clk_hw *hw;
+       struct clk_mux *mux = NULL;
+@@ -264,7 +264,7 @@ static struct clk_hw *mtk_clk_register_c
+               div_ops = &clk_divider_ops;
+       }
+-      hw = clk_hw_register_composite(NULL, mc->name, parent_names, num_parents,
++      hw = clk_hw_register_composite(dev, mc->name, parent_names, num_parents,
+               mux_hw, mux_ops,
+               div_hw, div_ops,
+               gate_hw, gate_ops,
+@@ -308,7 +308,8 @@ static void mtk_clk_unregister_composite
+       kfree(mux);
+ }
+-int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
++int mtk_clk_register_composites(struct device *dev,
++                              const struct mtk_composite *mcs, int num,
+                               void __iomem *base, spinlock_t *lock,
+                               struct clk_hw_onecell_data *clk_data)
+ {
+@@ -327,7 +328,7 @@ int mtk_clk_register_composites(const st
+                       continue;
+               }
+-              hw = mtk_clk_register_composite(mc, base, lock);
++              hw = mtk_clk_register_composite(dev, mc, base, lock);
+               if (IS_ERR(hw)) {
+                       pr_err("Failed to register clk %s: %pe\n", mc->name,
+--- a/drivers/clk/mediatek/clk-mtk.h
++++ b/drivers/clk/mediatek/clk-mtk.h
+@@ -149,7 +149,8 @@ struct mtk_composite {
+               .flags = 0,                                             \
+       }
+-int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
++int mtk_clk_register_composites(struct device *dev,
++                              const struct mtk_composite *mcs, int num,
+                               void __iomem *base, spinlock_t *lock,
+                               struct clk_hw_onecell_data *clk_data);
+ void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
diff --git a/target/linux/mediatek/patches-6.6/223-v6.3-clk-mediatek-clk-mux-Propagate-struct-device-for-mtk.patch b/target/linux/mediatek/patches-6.6/223-v6.3-clk-mediatek-clk-mux-Propagate-struct-device-for-mtk.patch
new file mode 100644 (file)
index 0000000..a50422d
--- /dev/null
@@ -0,0 +1,103 @@
+From 5d911479e4c732729bfa798e4a9e3e5aec3e30a7 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:36 +0100
+Subject: [PATCH 04/15] clk: mediatek: clk-mux: Propagate struct device for
+ mtk-mux
+
+Like done for other clocks, propagate struct device for mtk mux clocks
+registered through clk-mux helpers to enable runtime pm support.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Miles Chen <miles.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230120092053.182923-7-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+
+[daniel@makrotopia.org: removed parts not relevant for OpenWrt]
+---
+ drivers/clk/mediatek/clk-mt7986-infracfg.c |  3 ++-
+ drivers/clk/mediatek/clk-mt7986-topckgen.c |  3 ++-
+ drivers/clk/mediatek/clk-mux.c             | 14 ++++++++------
+ drivers/clk/mediatek/clk-mux.h             |  3 ++-
+ 4 files changed, 14 insertions(+), 9 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt7986-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
+@@ -178,7 +178,8 @@ static int clk_mt7986_infracfg_probe(str
+               return -ENOMEM;
+       mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+-      mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
++      mtk_clk_register_muxes(&pdev->dev, infra_muxes,
++                             ARRAY_SIZE(infra_muxes), node,
+                              &mt7986_clk_lock, clk_data);
+       mtk_clk_register_gates(&pdev->dev, node, infra_clks,
+                              ARRAY_SIZE(infra_clks), clk_data);
+--- a/drivers/clk/mediatek/clk-mt7986-topckgen.c
++++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
+@@ -303,7 +303,8 @@ static int clk_mt7986_topckgen_probe(str
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+                                   clk_data);
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+-      mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
++      mtk_clk_register_muxes(&pdev->dev, top_muxes,
++                             ARRAY_SIZE(top_muxes), node,
+                              &mt7986_clk_lock, clk_data);
+       clk_prepare_enable(clk_data->hws[CLK_TOP_SYSAXI_SEL]->clk);
+--- a/drivers/clk/mediatek/clk-mux.c
++++ b/drivers/clk/mediatek/clk-mux.c
+@@ -154,9 +154,10 @@ const struct clk_ops mtk_mux_gate_clr_se
+ };
+ EXPORT_SYMBOL_GPL(mtk_mux_gate_clr_set_upd_ops);
+-static struct clk_hw *mtk_clk_register_mux(const struct mtk_mux *mux,
+-                               struct regmap *regmap,
+-                               spinlock_t *lock)
++static struct clk_hw *mtk_clk_register_mux(struct device *dev,
++                                         const struct mtk_mux *mux,
++                                         struct regmap *regmap,
++                                         spinlock_t *lock)
+ {
+       struct mtk_clk_mux *clk_mux;
+       struct clk_init_data init = {};
+@@ -177,7 +178,7 @@ static struct clk_hw *mtk_clk_register_m
+       clk_mux->lock = lock;
+       clk_mux->hw.init = &init;
+-      ret = clk_hw_register(NULL, &clk_mux->hw);
++      ret = clk_hw_register(dev, &clk_mux->hw);
+       if (ret) {
+               kfree(clk_mux);
+               return ERR_PTR(ret);
+@@ -198,7 +199,8 @@ static void mtk_clk_unregister_mux(struc
+       kfree(mux);
+ }
+-int mtk_clk_register_muxes(const struct mtk_mux *muxes,
++int mtk_clk_register_muxes(struct device *dev,
++                         const struct mtk_mux *muxes,
+                          int num, struct device_node *node,
+                          spinlock_t *lock,
+                          struct clk_hw_onecell_data *clk_data)
+@@ -222,7 +224,7 @@ int mtk_clk_register_muxes(const struct
+                       continue;
+               }
+-              hw = mtk_clk_register_mux(mux, regmap, lock);
++              hw = mtk_clk_register_mux(dev, mux, regmap, lock);
+               if (IS_ERR(hw)) {
+                       pr_err("Failed to register clk %s: %pe\n", mux->name,
+--- a/drivers/clk/mediatek/clk-mux.h
++++ b/drivers/clk/mediatek/clk-mux.h
+@@ -83,7 +83,8 @@ extern const struct clk_ops mtk_mux_gate
+                       0, _upd_ofs, _upd, CLK_SET_RATE_PARENT,         \
+                       mtk_mux_clr_set_upd_ops)
+-int mtk_clk_register_muxes(const struct mtk_mux *muxes,
++int mtk_clk_register_muxes(struct device *dev,
++                         const struct mtk_mux *muxes,
+                          int num, struct device_node *node,
+                          spinlock_t *lock,
+                          struct clk_hw_onecell_data *clk_data);
diff --git a/target/linux/mediatek/patches-6.6/224-v6.3-clk-mediatek-clk-mtk-Add-dummy-clock-ops.patch b/target/linux/mediatek/patches-6.6/224-v6.3-clk-mediatek-clk-mtk-Add-dummy-clock-ops.patch
new file mode 100644 (file)
index 0000000..de2e697
--- /dev/null
@@ -0,0 +1,74 @@
+From b8eb1081d267708ba976525a1fe2162901b34f3a Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:37 +0100
+Subject: [PATCH] clk: mediatek: clk-mtk: Add dummy clock ops
+
+In order to migrate some (few) old clock drivers to the common
+mtk_clk_simple_probe() function, add dummy clock ops to be able
+to insert a dummy clock with ID 0 at the beginning of the list.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Miles Chen <miles.chen@mediatek.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Tested-by: Miles Chen <miles.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230120092053.182923-8-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/clk-mtk.c | 16 ++++++++++++++++
+ drivers/clk/mediatek/clk-mtk.h | 19 +++++++++++++++++++
+ 2 files changed, 35 insertions(+)
+
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -18,6 +18,22 @@
+ #include "clk-mtk.h"
+ #include "clk-gate.h"
++const struct mtk_gate_regs cg_regs_dummy = { 0, 0, 0 };
++EXPORT_SYMBOL_GPL(cg_regs_dummy);
++
++static int mtk_clk_dummy_enable(struct clk_hw *hw)
++{
++      return 0;
++}
++
++static void mtk_clk_dummy_disable(struct clk_hw *hw) { }
++
++const struct clk_ops mtk_clk_dummy_ops = {
++      .enable         = mtk_clk_dummy_enable,
++      .disable        = mtk_clk_dummy_disable,
++};
++EXPORT_SYMBOL_GPL(mtk_clk_dummy_ops);
++
+ static void mtk_init_clk_data(struct clk_hw_onecell_data *clk_data,
+                             unsigned int clk_num)
+ {
+--- a/drivers/clk/mediatek/clk-mtk.h
++++ b/drivers/clk/mediatek/clk-mtk.h
+@@ -22,6 +22,25 @@
+ struct platform_device;
++/*
++ * We need the clock IDs to start from zero but to maintain devicetree
++ * backwards compatibility we can't change bindings to start from zero.
++ * Only a few platforms are affected, so we solve issues given by the
++ * commonized MTK clocks probe function(s) by adding a dummy clock at
++ * the beginning where needed.
++ */
++#define CLK_DUMMY             0
++
++extern const struct clk_ops mtk_clk_dummy_ops;
++extern const struct mtk_gate_regs cg_regs_dummy;
++
++#define GATE_DUMMY(_id, _name) {                              \
++              .id = _id,                                      \
++              .name = _name,                                  \
++              .regs = &cg_regs_dummy,                         \
++              .ops = &mtk_clk_dummy_ops,                      \
++      }
++
+ struct mtk_fixed_clk {
+       int id;
+       const char *name;
diff --git a/target/linux/mediatek/patches-6.6/225-v6.3-clk-mediatek-Switch-to-mtk_clk_simple_probe-where-po.patch b/target/linux/mediatek/patches-6.6/225-v6.3-clk-mediatek-Switch-to-mtk_clk_simple_probe-where-po.patch
new file mode 100644 (file)
index 0000000..becfcd0
--- /dev/null
@@ -0,0 +1,790 @@
+From c26e28015b74af73e0b299f6ad3ff22931e600b4 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:41 +0100
+Subject: [PATCH 05/15] clk: mediatek: Switch to mtk_clk_simple_probe() where
+ possible
+
+mtk_clk_simple_probe() is a function that registers mtk gate clocks
+and, if reset data is present, a reset controller and across all of
+the MTK clock drivers, such a function is duplicated many times:
+switch to the common mtk_clk_simple_probe() function for all of the
+clock drivers that are registering as platform drivers.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Miles Chen <miles.chen@mediatek.com>
+Tested-by: Miles Chen <miles.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230120092053.182923-12-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+
+[daniel@makrotopia.org: removed parts not relevant for OpenWrt]
+---
+ drivers/clk/mediatek/clk-mt2701-aud.c | 31 ++++++----
+ drivers/clk/mediatek/clk-mt2701-eth.c | 36 ++++--------
+ drivers/clk/mediatek/clk-mt2701-g3d.c | 56 ++++--------------
+ drivers/clk/mediatek/clk-mt2701-hif.c | 38 ++++--------
+ drivers/clk/mediatek/clk-mt2712.c     | 83 ++++++++++----------------
+ drivers/clk/mediatek/clk-mt7622-aud.c | 54 ++++++-----------
+ drivers/clk/mediatek/clk-mt7622-eth.c | 82 +++++---------------------
+ drivers/clk/mediatek/clk-mt7622-hif.c | 85 +++++----------------------
+ drivers/clk/mediatek/clk-mt7629-hif.c | 85 +++++----------------------
+ 9 files changed, 144 insertions(+), 406 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt2701-aud.c
++++ b/drivers/clk/mediatek/clk-mt2701-aud.c
+@@ -52,6 +52,7 @@ static const struct mtk_gate_regs audio3
+ };
+ static const struct mtk_gate audio_clks[] = {
++      GATE_DUMMY(CLK_DUMMY, "aud_dummy"),
+       /* AUDIO0 */
+       GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2),
+       GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20),
+@@ -114,29 +115,27 @@ static const struct mtk_gate audio_clks[
+       GATE_AUDIO3(CLK_AUD_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14),
+ };
++static const struct mtk_clk_desc audio_desc = {
++      .clks = audio_clks,
++      .num_clks = ARRAY_SIZE(audio_clks),
++};
++
+ static const struct of_device_id of_match_clk_mt2701_aud[] = {
+-      { .compatible = "mediatek,mt2701-audsys", },
+-      {}
++      { .compatible = "mediatek,mt2701-audsys", .data = &audio_desc },
++      { /* sentinel */ }
+ };
+ static int clk_mt2701_aud_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(CLK_AUD_NR);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, audio_clks,
+-                             ARRAY_SIZE(audio_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
++      r = mtk_clk_simple_probe(pdev);
+       if (r) {
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+-              goto err_clk_provider;
++              return r;
+       }
+       r = devm_of_platform_populate(&pdev->dev);
+@@ -146,13 +145,19 @@ static int clk_mt2701_aud_probe(struct p
+       return 0;
+ err_plat_populate:
+-      of_clk_del_provider(node);
+-err_clk_provider:
++      mtk_clk_simple_remove(pdev);
+       return r;
+ }
++static int clk_mt2701_aud_remove(struct platform_device *pdev)
++{
++      of_platform_depopulate(&pdev->dev);
++      return mtk_clk_simple_remove(pdev);
++}
++
+ static struct platform_driver clk_mt2701_aud_drv = {
+       .probe = clk_mt2701_aud_probe,
++      .remove = clk_mt2701_aud_remove,
+       .driver = {
+               .name = "clk-mt2701-aud",
+               .of_match_table = of_match_clk_mt2701_aud,
+--- a/drivers/clk/mediatek/clk-mt2701-eth.c
++++ b/drivers/clk/mediatek/clk-mt2701-eth.c
+@@ -20,6 +20,7 @@ static const struct mtk_gate_regs eth_cg
+       GATE_MTK(_id, _name, _parent, &eth_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+ static const struct mtk_gate eth_clks[] = {
++      GATE_DUMMY(CLK_DUMMY, "eth_dummy"),
+       GATE_ETH(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
+       GATE_ETH(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
+       GATE_ETH(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
+@@ -38,35 +39,20 @@ static const struct mtk_clk_rst_desc clk
+       .rst_bank_nr = ARRAY_SIZE(rst_ofs),
+ };
+-static const struct of_device_id of_match_clk_mt2701_eth[] = {
+-      { .compatible = "mediatek,mt2701-ethsys", },
+-      {}
++static const struct mtk_clk_desc eth_desc = {
++      .clks = eth_clks,
++      .num_clks = ARRAY_SIZE(eth_clks),
++      .rst_desc = &clk_rst_desc,
+ };
+-static int clk_mt2701_eth_probe(struct platform_device *pdev)
+-{
+-      struct clk_hw_onecell_data *clk_data;
+-      int r;
+-      struct device_node *node = pdev->dev.of_node;
+-
+-      clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, eth_clks,
+-                             ARRAY_SIZE(eth_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
+-
+-      return r;
+-}
++static const struct of_device_id of_match_clk_mt2701_eth[] = {
++      { .compatible = "mediatek,mt2701-ethsys", .data = &eth_desc },
++      { /* sentinel */ }
++};
+ static struct platform_driver clk_mt2701_eth_drv = {
+-      .probe = clk_mt2701_eth_probe,
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt2701-eth",
+               .of_match_table = of_match_clk_mt2701_eth,
+--- a/drivers/clk/mediatek/clk-mt2701-g3d.c
++++ b/drivers/clk/mediatek/clk-mt2701-g3d.c
+@@ -26,6 +26,7 @@ static const struct mtk_gate_regs g3d_cg
+ };
+ static const struct mtk_gate g3d_clks[] = {
++      GATE_DUMMY(CLK_DUMMY, "g3d_dummy"),
+       GATE_G3D(CLK_G3DSYS_CORE, "g3d_core", "mfg_sel", 0),
+ };
+@@ -37,57 +38,20 @@ static const struct mtk_clk_rst_desc clk
+       .rst_bank_nr = ARRAY_SIZE(rst_ofs),
+ };
+-static int clk_mt2701_g3dsys_init(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(CLK_G3DSYS_NR);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, g3d_clks, ARRAY_SIZE(g3d_clks),
+-                             clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
+-
+-      return r;
+-}
++static const struct mtk_clk_desc g3d_desc = {
++      .clks = g3d_clks,
++      .num_clks = ARRAY_SIZE(g3d_clks),
++      .rst_desc = &clk_rst_desc,
++};
+ static const struct of_device_id of_match_clk_mt2701_g3d[] = {
+-      {
+-              .compatible = "mediatek,mt2701-g3dsys",
+-              .data = clk_mt2701_g3dsys_init,
+-      }, {
+-              /* sentinel */
+-      }
++      { .compatible = "mediatek,mt2701-g3dsys", .data = &g3d_desc },
++      { /* sentinel */ }
+ };
+-static int clk_mt2701_g3d_probe(struct platform_device *pdev)
+-{
+-      int (*clk_init)(struct platform_device *);
+-      int r;
+-
+-      clk_init = of_device_get_match_data(&pdev->dev);
+-      if (!clk_init)
+-              return -EINVAL;
+-
+-      r = clk_init(pdev);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      return r;
+-}
+-
+ static struct platform_driver clk_mt2701_g3d_drv = {
+-      .probe = clk_mt2701_g3d_probe,
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt2701-g3d",
+               .of_match_table = of_match_clk_mt2701_g3d,
+--- a/drivers/clk/mediatek/clk-mt2701-hif.c
++++ b/drivers/clk/mediatek/clk-mt2701-hif.c
+@@ -20,6 +20,7 @@ static const struct mtk_gate_regs hif_cg
+       GATE_MTK(_id, _name, _parent, &hif_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+ static const struct mtk_gate hif_clks[] = {
++      GATE_DUMMY(CLK_DUMMY, "hif_dummy"),
+       GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
+       GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22),
+       GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24),
+@@ -35,37 +36,20 @@ static const struct mtk_clk_rst_desc clk
+       .rst_bank_nr = ARRAY_SIZE(rst_ofs),
+ };
+-static const struct of_device_id of_match_clk_mt2701_hif[] = {
+-      { .compatible = "mediatek,mt2701-hifsys", },
+-      {}
++static const struct mtk_clk_desc hif_desc = {
++      .clks = hif_clks,
++      .num_clks = ARRAY_SIZE(hif_clks),
++      .rst_desc = &clk_rst_desc,
+ };
+-static int clk_mt2701_hif_probe(struct platform_device *pdev)
+-{
+-      struct clk_hw_onecell_data *clk_data;
+-      int r;
+-      struct device_node *node = pdev->dev.of_node;
+-
+-      clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, hif_clks,
+-                             ARRAY_SIZE(hif_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r) {
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-              return r;
+-      }
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
+-
+-      return 0;
+-}
++static const struct of_device_id of_match_clk_mt2701_hif[] = {
++      { .compatible = "mediatek,mt2701-hifsys", .data = &hif_desc },
++      { /* sentinel */ }
++};
+ static struct platform_driver clk_mt2701_hif_drv = {
+-      .probe = clk_mt2701_hif_probe,
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt2701-hif",
+               .of_match_table = of_match_clk_mt2701_hif,
+--- a/drivers/clk/mediatek/clk-mt2712.c
++++ b/drivers/clk/mediatek/clk-mt2712.c
+@@ -1337,50 +1337,6 @@ static int clk_mt2712_top_probe(struct p
+       return r;
+ }
+-static int clk_mt2712_infra_probe(struct platform_device *pdev)
+-{
+-      struct clk_hw_onecell_data *clk_data;
+-      int r;
+-      struct device_node *node = pdev->dev.of_node;
+-
+-      clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, infra_clks,
+-                             ARRAY_SIZE(infra_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-
+-      if (r != 0)
+-              pr_err("%s(): could not register clock provider: %d\n",
+-                      __func__, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc[0]);
+-
+-      return r;
+-}
+-
+-static int clk_mt2712_peri_probe(struct platform_device *pdev)
+-{
+-      struct clk_hw_onecell_data *clk_data;
+-      int r;
+-      struct device_node *node = pdev->dev.of_node;
+-
+-      clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, peri_clks,
+-                             ARRAY_SIZE(peri_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-
+-      if (r != 0)
+-              pr_err("%s(): could not register clock provider: %d\n",
+-                      __func__, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc[1]);
+-
+-      return r;
+-}
+-
+ static int clk_mt2712_mcu_probe(struct platform_device *pdev)
+ {
+       struct clk_hw_onecell_data *clk_data;
+@@ -1419,12 +1375,6 @@ static const struct of_device_id of_matc
+               .compatible = "mediatek,mt2712-topckgen",
+               .data = clk_mt2712_top_probe,
+       }, {
+-              .compatible = "mediatek,mt2712-infracfg",
+-              .data = clk_mt2712_infra_probe,
+-      }, {
+-              .compatible = "mediatek,mt2712-pericfg",
+-              .data = clk_mt2712_peri_probe,
+-      }, {
+               .compatible = "mediatek,mt2712-mcucfg",
+               .data = clk_mt2712_mcu_probe,
+       }, {
+@@ -1450,6 +1400,33 @@ static int clk_mt2712_probe(struct platf
+       return r;
+ }
++static const struct mtk_clk_desc infra_desc = {
++      .clks = infra_clks,
++      .num_clks = ARRAY_SIZE(infra_clks),
++      .rst_desc = &clk_rst_desc[0],
++};
++
++static const struct mtk_clk_desc peri_desc = {
++      .clks = peri_clks,
++      .num_clks = ARRAY_SIZE(peri_clks),
++      .rst_desc = &clk_rst_desc[1],
++};
++
++static const struct of_device_id of_match_clk_mt2712_simple[] = {
++      { .compatible = "mediatek,mt2712-infracfg", .data = &infra_desc },
++      { .compatible = "mediatek,mt2712-pericfg", .data = &peri_desc, },
++      { /* sentinel */ }
++};
++
++static struct platform_driver clk_mt2712_simple_drv = {
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
++      .driver = {
++              .name = "clk-mt2712-simple",
++              .of_match_table = of_match_clk_mt2712_simple,
++      },
++};
++
+ static struct platform_driver clk_mt2712_drv = {
+       .probe = clk_mt2712_probe,
+       .driver = {
+@@ -1460,7 +1437,11 @@ static struct platform_driver clk_mt2712
+ static int __init clk_mt2712_init(void)
+ {
+-      return platform_driver_register(&clk_mt2712_drv);
++      int ret = platform_driver_register(&clk_mt2712_drv);
++
++      if (ret)
++              return ret;
++      return platform_driver_register(&clk_mt2712_simple_drv);
+ }
+ arch_initcall(clk_mt2712_init);
+--- a/drivers/clk/mediatek/clk-mt7622-aud.c
++++ b/drivers/clk/mediatek/clk-mt7622-aud.c
+@@ -106,24 +106,22 @@ static const struct mtk_gate audio_clks[
+       GATE_AUDIO3(CLK_AUDIO_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14),
+ };
+-static int clk_mt7622_audiosys_init(struct platform_device *pdev)
++static const struct mtk_clk_desc audio_desc = {
++      .clks = audio_clks,
++      .num_clks = ARRAY_SIZE(audio_clks),
++};
++
++static int clk_mt7622_aud_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(CLK_AUDIO_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, audio_clks,
+-                             ARRAY_SIZE(audio_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
++      r = mtk_clk_simple_probe(pdev);
+       if (r) {
+               dev_err(&pdev->dev,
+                       "could not register clock provider: %s: %d\n",
+                       pdev->name, r);
+-              goto err_clk_provider;
++              return r;
+       }
+       r = devm_of_platform_populate(&pdev->dev);
+@@ -133,40 +131,24 @@ static int clk_mt7622_audiosys_init(stru
+       return 0;
+ err_plat_populate:
+-      of_clk_del_provider(node);
+-err_clk_provider:
++      mtk_clk_simple_remove(pdev);
+       return r;
+ }
+-static const struct of_device_id of_match_clk_mt7622_aud[] = {
+-      {
+-              .compatible = "mediatek,mt7622-audsys",
+-              .data = clk_mt7622_audiosys_init,
+-      }, {
+-              /* sentinel */
+-      }
+-};
+-
+-static int clk_mt7622_aud_probe(struct platform_device *pdev)
++static int clk_mt7622_aud_remove(struct platform_device *pdev)
+ {
+-      int (*clk_init)(struct platform_device *);
+-      int r;
+-
+-      clk_init = of_device_get_match_data(&pdev->dev);
+-      if (!clk_init)
+-              return -EINVAL;
+-
+-      r = clk_init(pdev);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      return r;
++      of_platform_depopulate(&pdev->dev);
++      return mtk_clk_simple_remove(pdev);
+ }
++static const struct of_device_id of_match_clk_mt7622_aud[] = {
++      { .compatible = "mediatek,mt7622-audsys", .data = &audio_desc },
++      { /* sentinel */ }
++};
++
+ static struct platform_driver clk_mt7622_aud_drv = {
+       .probe = clk_mt7622_aud_probe,
++      .remove = clk_mt7622_aud_remove,
+       .driver = {
+               .name = "clk-mt7622-aud",
+               .of_match_table = of_match_clk_mt7622_aud,
+--- a/drivers/clk/mediatek/clk-mt7622-eth.c
++++ b/drivers/clk/mediatek/clk-mt7622-eth.c
+@@ -61,80 +61,26 @@ static const struct mtk_clk_rst_desc clk
+       .rst_bank_nr = ARRAY_SIZE(rst_ofs),
+ };
+-static int clk_mt7622_ethsys_init(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(CLK_ETH_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, eth_clks,
+-                             ARRAY_SIZE(eth_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
+-
+-      return r;
+-}
+-
+-static int clk_mt7622_sgmiisys_init(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(CLK_SGMII_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, sgmii_clks,
+-                             ARRAY_SIZE(sgmii_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
++static const struct mtk_clk_desc eth_desc = {
++      .clks = eth_clks,
++      .num_clks = ARRAY_SIZE(eth_clks),
++      .rst_desc = &clk_rst_desc,
++};
+-      return r;
+-}
++static const struct mtk_clk_desc sgmii_desc = {
++      .clks = sgmii_clks,
++      .num_clks = ARRAY_SIZE(sgmii_clks),
++};
+ static const struct of_device_id of_match_clk_mt7622_eth[] = {
+-      {
+-              .compatible = "mediatek,mt7622-ethsys",
+-              .data = clk_mt7622_ethsys_init,
+-      }, {
+-              .compatible = "mediatek,mt7622-sgmiisys",
+-              .data = clk_mt7622_sgmiisys_init,
+-      }, {
+-              /* sentinel */
+-      }
++      { .compatible = "mediatek,mt7622-ethsys", .data = &eth_desc },
++      { .compatible = "mediatek,mt7622-sgmiisys", .data = &sgmii_desc },
++      { /* sentinel */ }
+ };
+-static int clk_mt7622_eth_probe(struct platform_device *pdev)
+-{
+-      int (*clk_init)(struct platform_device *);
+-      int r;
+-
+-      clk_init = of_device_get_match_data(&pdev->dev);
+-      if (!clk_init)
+-              return -EINVAL;
+-
+-      r = clk_init(pdev);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      return r;
+-}
+-
+ static struct platform_driver clk_mt7622_eth_drv = {
+-      .probe = clk_mt7622_eth_probe,
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt7622-eth",
+               .of_match_table = of_match_clk_mt7622_eth,
+--- a/drivers/clk/mediatek/clk-mt7622-hif.c
++++ b/drivers/clk/mediatek/clk-mt7622-hif.c
+@@ -72,82 +72,27 @@ static const struct mtk_clk_rst_desc clk
+       .rst_bank_nr = ARRAY_SIZE(rst_ofs),
+ };
+-static int clk_mt7622_ssusbsys_init(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(CLK_SSUSB_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, ssusb_clks,
+-                             ARRAY_SIZE(ssusb_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
+-
+-      return r;
+-}
+-
+-static int clk_mt7622_pciesys_init(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(CLK_PCIE_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, pcie_clks,
+-                             ARRAY_SIZE(pcie_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
++static const struct mtk_clk_desc ssusb_desc = {
++      .clks = ssusb_clks,
++      .num_clks = ARRAY_SIZE(ssusb_clks),
++      .rst_desc = &clk_rst_desc,
++};
+-      return r;
+-}
++static const struct mtk_clk_desc pcie_desc = {
++      .clks = pcie_clks,
++      .num_clks = ARRAY_SIZE(pcie_clks),
++      .rst_desc = &clk_rst_desc,
++};
+ static const struct of_device_id of_match_clk_mt7622_hif[] = {
+-      {
+-              .compatible = "mediatek,mt7622-pciesys",
+-              .data = clk_mt7622_pciesys_init,
+-      }, {
+-              .compatible = "mediatek,mt7622-ssusbsys",
+-              .data = clk_mt7622_ssusbsys_init,
+-      }, {
+-              /* sentinel */
+-      }
++      { .compatible = "mediatek,mt7622-pciesys", .data = &pcie_desc },
++      { .compatible = "mediatek,mt7622-ssusbsys", .data = &ssusb_desc },
++      { /* sentinel */ }
+ };
+-static int clk_mt7622_hif_probe(struct platform_device *pdev)
+-{
+-      int (*clk_init)(struct platform_device *);
+-      int r;
+-
+-      clk_init = of_device_get_match_data(&pdev->dev);
+-      if (!clk_init)
+-              return -EINVAL;
+-
+-      r = clk_init(pdev);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      return r;
+-}
+-
+ static struct platform_driver clk_mt7622_hif_drv = {
+-      .probe = clk_mt7622_hif_probe,
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt7622-hif",
+               .of_match_table = of_match_clk_mt7622_hif,
+--- a/drivers/clk/mediatek/clk-mt7629-hif.c
++++ b/drivers/clk/mediatek/clk-mt7629-hif.c
+@@ -67,82 +67,27 @@ static const struct mtk_clk_rst_desc clk
+       .rst_bank_nr = ARRAY_SIZE(rst_ofs),
+ };
+-static int clk_mt7629_ssusbsys_init(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(CLK_SSUSB_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, ssusb_clks,
+-                             ARRAY_SIZE(ssusb_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
+-
+-      return r;
+-}
+-
+-static int clk_mt7629_pciesys_init(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(CLK_PCIE_NR_CLK);
+-
+-      mtk_clk_register_gates(&pdev->dev, node, pcie_clks,
+-                             ARRAY_SIZE(pcie_clks), clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
++static const struct mtk_clk_desc ssusb_desc = {
++      .clks = ssusb_clks,
++      .num_clks = ARRAY_SIZE(ssusb_clks),
++      .rst_desc = &clk_rst_desc,
++};
+-      return r;
+-}
++static const struct mtk_clk_desc pcie_desc = {
++      .clks = pcie_clks,
++      .num_clks = ARRAY_SIZE(pcie_clks),
++      .rst_desc = &clk_rst_desc,
++};
+ static const struct of_device_id of_match_clk_mt7629_hif[] = {
+-      {
+-              .compatible = "mediatek,mt7629-pciesys",
+-              .data = clk_mt7629_pciesys_init,
+-      }, {
+-              .compatible = "mediatek,mt7629-ssusbsys",
+-              .data = clk_mt7629_ssusbsys_init,
+-      }, {
+-              /* sentinel */
+-      }
++      { .compatible = "mediatek,mt7629-pciesys", .data = &pcie_desc },
++      { .compatible = "mediatek,mt7629-ssusbsys", .data = &ssusb_desc },
++      { /* sentinel */ }
+ };
+-static int clk_mt7629_hif_probe(struct platform_device *pdev)
+-{
+-      int (*clk_init)(struct platform_device *);
+-      int r;
+-
+-      clk_init = of_device_get_match_data(&pdev->dev);
+-      if (!clk_init)
+-              return -EINVAL;
+-
+-      r = clk_init(pdev);
+-      if (r)
+-              dev_err(&pdev->dev,
+-                      "could not register clock provider: %s: %d\n",
+-                      pdev->name, r);
+-
+-      return r;
+-}
+-
+ static struct platform_driver clk_mt7629_hif_drv = {
+-      .probe = clk_mt7629_hif_probe,
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt7629-hif",
+               .of_match_table = of_match_clk_mt7629_hif,
diff --git a/target/linux/mediatek/patches-6.6/226-v6.3-clk-mediatek-clk-mtk-Extend-mtk_clk_simple_probe.patch b/target/linux/mediatek/patches-6.6/226-v6.3-clk-mediatek-clk-mtk-Extend-mtk_clk_simple_probe.patch
new file mode 100644 (file)
index 0000000..ad02df1
--- /dev/null
@@ -0,0 +1,189 @@
+From 7b6183108c8ccf0dc295f39cdf78bd8078455636 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:42 +0100
+Subject: [PATCH] clk: mediatek: clk-mtk: Extend mtk_clk_simple_probe()
+
+As a preparation to increase probe functions commonization across
+various MediaTek SoC clock controller drivers, extend function
+mtk_clk_simple_probe() to be able to register not only gates, but
+also fixed clocks, factors, muxes and composites.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Miles Chen <miles.chen@mediatek.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Tested-by: Miles Chen <miles.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230120092053.182923-13-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/clk-mtk.c | 101 ++++++++++++++++++++++++++++++---
+ drivers/clk/mediatek/clk-mtk.h |  10 ++++
+ 2 files changed, 103 insertions(+), 8 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -11,12 +11,14 @@
+ #include <linux/mfd/syscon.h>
+ #include <linux/module.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 "clk-mtk.h"
+ #include "clk-gate.h"
++#include "clk-mux.h"
+ const struct mtk_gate_regs cg_regs_dummy = { 0, 0, 0 };
+ EXPORT_SYMBOL_GPL(cg_regs_dummy);
+@@ -466,20 +468,71 @@ int mtk_clk_simple_probe(struct platform
+       const struct mtk_clk_desc *mcd;
+       struct clk_hw_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+-      int r;
++      void __iomem *base;
++      int num_clks, r;
+       mcd = of_device_get_match_data(&pdev->dev);
+       if (!mcd)
+               return -EINVAL;
+-      clk_data = mtk_alloc_clk_data(mcd->num_clks);
++      /* Composite clocks needs us to pass iomem pointer */
++      if (mcd->composite_clks) {
++              if (!mcd->shared_io)
++                      base = devm_platform_ioremap_resource(pdev, 0);
++              else
++                      base = of_iomap(node, 0);
++
++              if (IS_ERR_OR_NULL(base))
++                      return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM;
++      }
++
++      /* Calculate how many clk_hw_onecell_data entries to allocate */
++      num_clks = mcd->num_clks + mcd->num_composite_clks;
++      num_clks += mcd->num_fixed_clks + mcd->num_factor_clks;
++      num_clks += mcd->num_mux_clks;
++
++      clk_data = mtk_alloc_clk_data(num_clks);
+       if (!clk_data)
+               return -ENOMEM;
+-      r = mtk_clk_register_gates(&pdev->dev, node, mcd->clks, mcd->num_clks,
+-                                 clk_data);
+-      if (r)
+-              goto free_data;
++      if (mcd->fixed_clks) {
++              r = mtk_clk_register_fixed_clks(mcd->fixed_clks,
++                                              mcd->num_fixed_clks, clk_data);
++              if (r)
++                      goto free_data;
++      }
++
++      if (mcd->factor_clks) {
++              r = mtk_clk_register_factors(mcd->factor_clks,
++                                           mcd->num_factor_clks, clk_data);
++              if (r)
++                      goto unregister_fixed_clks;
++      }
++
++      if (mcd->mux_clks) {
++              r = mtk_clk_register_muxes(&pdev->dev, mcd->mux_clks,
++                                         mcd->num_mux_clks, node,
++                                         mcd->clk_lock, clk_data);
++              if (r)
++                      goto unregister_factors;
++      };
++
++      if (mcd->composite_clks) {
++              /* We don't check composite_lock because it's optional */
++              r = mtk_clk_register_composites(&pdev->dev,
++                                              mcd->composite_clks,
++                                              mcd->num_composite_clks,
++                                              base, mcd->clk_lock, clk_data);
++              if (r)
++                      goto unregister_muxes;
++      }
++
++      if (mcd->clks) {
++              r = mtk_clk_register_gates(&pdev->dev, node, mcd->clks,
++                                         mcd->num_clks, clk_data);
++              if (r)
++                      goto unregister_composites;
++      }
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r)
+@@ -497,9 +550,28 @@ int mtk_clk_simple_probe(struct platform
+       return r;
+ unregister_clks:
+-      mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
++      if (mcd->clks)
++              mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
++unregister_composites:
++      if (mcd->composite_clks)
++              mtk_clk_unregister_composites(mcd->composite_clks,
++                                            mcd->num_composite_clks, clk_data);
++unregister_muxes:
++      if (mcd->mux_clks)
++              mtk_clk_unregister_muxes(mcd->mux_clks,
++                                       mcd->num_mux_clks, clk_data);
++unregister_factors:
++      if (mcd->factor_clks)
++              mtk_clk_unregister_factors(mcd->factor_clks,
++                                         mcd->num_factor_clks, clk_data);
++unregister_fixed_clks:
++      if (mcd->fixed_clks)
++              mtk_clk_unregister_fixed_clks(mcd->fixed_clks,
++                                            mcd->num_fixed_clks, clk_data);
+ free_data:
+       mtk_free_clk_data(clk_data);
++      if (mcd->shared_io && base)
++              iounmap(base);
+       return r;
+ }
+ EXPORT_SYMBOL_GPL(mtk_clk_simple_probe);
+@@ -511,7 +583,20 @@ int mtk_clk_simple_remove(struct platfor
+       struct device_node *node = pdev->dev.of_node;
+       of_clk_del_provider(node);
+-      mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
++      if (mcd->clks)
++              mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
++      if (mcd->composite_clks)
++              mtk_clk_unregister_composites(mcd->composite_clks,
++                                            mcd->num_composite_clks, clk_data);
++      if (mcd->mux_clks)
++              mtk_clk_unregister_muxes(mcd->mux_clks,
++                                       mcd->num_mux_clks, clk_data);
++      if (mcd->factor_clks)
++              mtk_clk_unregister_factors(mcd->factor_clks,
++                                         mcd->num_factor_clks, clk_data);
++      if (mcd->fixed_clks)
++              mtk_clk_unregister_fixed_clks(mcd->fixed_clks,
++                                            mcd->num_fixed_clks, clk_data);
+       mtk_free_clk_data(clk_data);
+       return 0;
+--- a/drivers/clk/mediatek/clk-mtk.h
++++ b/drivers/clk/mediatek/clk-mtk.h
+@@ -215,7 +215,17 @@ void mtk_clk_unregister_ref2usb_tx(struc
+ struct mtk_clk_desc {
+       const struct mtk_gate *clks;
+       size_t num_clks;
++      const struct mtk_composite *composite_clks;
++      size_t num_composite_clks;
++      const struct mtk_fixed_clk *fixed_clks;
++      size_t num_fixed_clks;
++      const struct mtk_fixed_factor *factor_clks;
++      size_t num_factor_clks;
++      const struct mtk_mux *mux_clks;
++      size_t num_mux_clks;
+       const struct mtk_clk_rst_desc *rst_desc;
++      spinlock_t *clk_lock;
++      bool shared_io;
+ };
+ int mtk_clk_simple_probe(struct platform_device *pdev);
diff --git a/target/linux/mediatek/patches-6.6/227-v6.3-clk-mediatek-clk-mt7986-topckgen-Properly-keep-some-.patch b/target/linux/mediatek/patches-6.6/227-v6.3-clk-mediatek-clk-mt7986-topckgen-Properly-keep-some-.patch
new file mode 100644 (file)
index 0000000..bf9a172
--- /dev/null
@@ -0,0 +1,97 @@
+From 3511004225ce917a4aa6e6ac61481ac60f08f401 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:52 +0100
+Subject: [PATCH 06/15] clk: mediatek: clk-mt7986-topckgen: Properly keep some
+ clocks enabled
+
+Instead of calling clk_prepare_enable() on a bunch of clocks at probe
+time, set the CLK_IS_CRITICAL flag to the same as these are required
+to be always on, and this is the right way of achieving that.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: Miles Chen <miles.chen@mediatek.com>
+Link: https://lore.kernel.org/r/20230120092053.182923-23-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt7986-topckgen.c | 46 +++++++++++-----------
+ 1 file changed, 24 insertions(+), 22 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt7986-topckgen.c
++++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
+@@ -202,16 +202,23 @@ static const struct mtk_mux top_muxes[]
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel",
+                            f_26m_adc_parents, 0x020, 0x024, 0x028, 16, 1, 23,
+                            0x1C0, 10),
+-      MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents,
+-                           0x020, 0x024, 0x028, 24, 1, 31, 0x1C0, 11),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel",
++                                 f_26m_adc_parents, 0x020, 0x024, 0x028,
++                                 24, 1, 31, 0x1C0, 11,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
+       /* CLK_CFG_3 */
+-      MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
+-                           dramc_md32_parents, 0x030, 0x034, 0x038, 0, 1, 7,
+-                           0x1C0, 12),
+-      MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents,
+-                           0x030, 0x034, 0x038, 8, 2, 15, 0x1C0, 13),
+-      MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents,
+-                           0x030, 0x034, 0x038, 16, 2, 23, 0x1C0, 14),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
++                                 dramc_md32_parents, 0x030, 0x034, 0x038,
++                                 0, 1, 7, 0x1C0, 12,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel",
++                                 sysaxi_parents, 0x030, 0x034, 0x038,
++                                 8, 2, 15, 0x1C0, 13,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel",
++                                 sysapb_parents, 0x030, 0x034, 0x038,
++                                 16, 2, 23, 0x1C0, 14,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
+                            arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1,
+                            31, 0x1C0, 15),
+@@ -234,9 +241,10 @@ static const struct mtk_mux top_muxes[]
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
+                            sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
+                            0x1C0, 21),
+-      MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel",
+-                           sgm_reg_parents, 0x050, 0x054, 0x058, 16, 1, 23,
+-                           0x1C0, 22),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel",
++                                 sgm_reg_parents, 0x050, 0x054, 0x058,
++                                 16, 1, 23, 0x1C0, 22,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
+                            0x050, 0x054, 0x058, 24, 1, 31, 0x1C0, 23),
+       /* CLK_CFG_6 */
+@@ -252,9 +260,10 @@ static const struct mtk_mux top_muxes[]
+                            f_26m_adc_parents, 0x060, 0x064, 0x068, 24, 1, 31,
+                            0x1C0, 27),
+       /* CLK_CFG_7 */
+-      MUX_GATE_CLR_SET_UPD(CLK_TOP_F26M_SEL, "csw_f26m_sel",
+-                           f_26m_adc_parents, 0x070, 0x074, 0x078, 0, 1, 7,
+-                           0x1C0, 28),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_F26M_SEL, "csw_f26m_sel",
++                                 f_26m_adc_parents, 0x070, 0x074, 0x078,
++                                 0, 1, 7, 0x1C0, 28,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
+                            0x070, 0x074, 0x078, 8, 2, 15, 0x1C0, 29),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
+@@ -307,13 +316,6 @@ static int clk_mt7986_topckgen_probe(str
+                              ARRAY_SIZE(top_muxes), node,
+                              &mt7986_clk_lock, clk_data);
+-      clk_prepare_enable(clk_data->hws[CLK_TOP_SYSAXI_SEL]->clk);
+-      clk_prepare_enable(clk_data->hws[CLK_TOP_SYSAPB_SEL]->clk);
+-      clk_prepare_enable(clk_data->hws[CLK_TOP_DRAMC_SEL]->clk);
+-      clk_prepare_enable(clk_data->hws[CLK_TOP_DRAMC_MD32_SEL]->clk);
+-      clk_prepare_enable(clk_data->hws[CLK_TOP_F26M_SEL]->clk);
+-      clk_prepare_enable(clk_data->hws[CLK_TOP_SGM_REG_SEL]->clk);
+-
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r) {
diff --git a/target/linux/mediatek/patches-6.6/228-v6.3-clk-mediatek-clk-mt7986-topckgen-Migrate-to-mtk_clk_.patch b/target/linux/mediatek/patches-6.6/228-v6.3-clk-mediatek-clk-mt7986-topckgen-Migrate-to-mtk_clk_.patch
new file mode 100644 (file)
index 0000000..d77b859
--- /dev/null
@@ -0,0 +1,88 @@
+From 9ce3b4e4719d4eec38b2c8da939c073835573d1d Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Fri, 20 Jan 2023 10:20:53 +0100
+Subject: [PATCH 07/15] clk: mediatek: clk-mt7986-topckgen: Migrate to
+ mtk_clk_simple_probe()
+
+There are no more non-common calls in clk_mt7986_topckgen_probe():
+migrate this driver to mtk_clk_simple_probe().
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Miles Chen <miles.chen@mediatek.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Link: https://lore.kernel.org/r/20230120092053.182923-24-angelogioacchino.delregno@collabora.com
+Tested-by: Mingming Su <mingming.su@mediatek.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt7986-topckgen.c | 55 +++++-----------------
+ 1 file changed, 13 insertions(+), 42 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt7986-topckgen.c
++++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
+@@ -290,53 +290,24 @@ static const struct mtk_mux top_muxes[]
+                            0x1C4, 5),
+ };
+-static int clk_mt7986_topckgen_probe(struct platform_device *pdev)
+-{
+-      struct clk_hw_onecell_data *clk_data;
+-      struct device_node *node = pdev->dev.of_node;
+-      int r;
+-      void __iomem *base;
+-      int nr = ARRAY_SIZE(top_fixed_clks) + ARRAY_SIZE(top_divs) +
+-               ARRAY_SIZE(top_muxes);
+-
+-      base = of_iomap(node, 0);
+-      if (!base) {
+-              pr_err("%s(): ioremap failed\n", __func__);
+-              return -ENOMEM;
+-      }
+-
+-      clk_data = mtk_alloc_clk_data(nr);
+-      if (!clk_data)
+-              return -ENOMEM;
+-
+-      mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+-                                  clk_data);
+-      mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+-      mtk_clk_register_muxes(&pdev->dev, top_muxes,
+-                             ARRAY_SIZE(top_muxes), node,
+-                             &mt7986_clk_lock, clk_data);
+-
+-      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-
+-      if (r) {
+-              pr_err("%s(): could not register clock provider: %d\n",
+-                     __func__, r);
+-              goto free_topckgen_data;
+-      }
+-      return r;
+-
+-free_topckgen_data:
+-      mtk_free_clk_data(clk_data);
+-      return r;
+-}
++static const struct mtk_clk_desc topck_desc = {
++      .fixed_clks = top_fixed_clks,
++      .num_fixed_clks = ARRAY_SIZE(top_fixed_clks),
++      .factor_clks = top_divs,
++      .num_factor_clks = ARRAY_SIZE(top_divs),
++      .mux_clks = top_muxes,
++      .num_mux_clks = ARRAY_SIZE(top_muxes),
++      .clk_lock = &mt7986_clk_lock,
++};
+ static const struct of_device_id of_match_clk_mt7986_topckgen[] = {
+-      { .compatible = "mediatek,mt7986-topckgen", },
+-      {}
++      { .compatible = "mediatek,mt7986-topckgen", .data = &topck_desc },
++      { /* sentinel */ }
+ };
+ static struct platform_driver clk_mt7986_topckgen_drv = {
+-      .probe = clk_mt7986_topckgen_probe,
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
+       .driver = {
+               .name = "clk-mt7986-topckgen",
+               .of_match_table = of_match_clk_mt7986_topckgen,
diff --git a/target/linux/mediatek/patches-6.6/229-v6.4-clk-mediatek-mt7986-apmixed-Use-PLL_AO-flag-to-set-c.patch b/target/linux/mediatek/patches-6.6/229-v6.4-clk-mediatek-mt7986-apmixed-Use-PLL_AO-flag-to-set-c.patch
new file mode 100644 (file)
index 0000000..a47dd4b
--- /dev/null
@@ -0,0 +1,38 @@
+From 06abdc84080729dc2c54946e1712c5ee1589ca1c Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Mon, 6 Mar 2023 15:05:21 +0100
+Subject: [PATCH 13/15] clk: mediatek: mt7986-apmixed: Use PLL_AO flag to set
+ critical clock
+
+Instead of calling clk_prepare_enable() at probe time, add the PLL_AO
+flag to CLK_APMIXED_ARMPLL clock: this will set CLK_IS_CRITICAL.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/20230306140543.1813621-33-angelogioacchino.delregno@collabora.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/clk-mt7986-apmixed.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt7986-apmixed.c
++++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c
+@@ -42,7 +42,7 @@
+                "clkxtal")
+ static const struct mtk_pll_data plls[] = {
+-      PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x0, 0, 32,
++      PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x0, PLL_AO, 32,
+           0x0200, 4, 0, 0x0204, 0),
+       PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x0, 0, 32,
+           0x0210, 4, 0, 0x0214, 0),
+@@ -77,8 +77,6 @@ static int clk_mt7986_apmixed_probe(stru
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+-      clk_prepare_enable(clk_data->hws[CLK_APMIXED_ARMPLL]->clk);
+-
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+       if (r) {
+               pr_err("%s(): could not register clock provider: %d\n",
diff --git a/target/linux/mediatek/patches-6.6/230-v6.4-dt-bindings-clock-mediatek-add-mt7981-clock-IDs.patch b/target/linux/mediatek/patches-6.6/230-v6.4-dt-bindings-clock-mediatek-add-mt7981-clock-IDs.patch
new file mode 100644 (file)
index 0000000..ae76940
--- /dev/null
@@ -0,0 +1,237 @@
+From a6473d0f9f07b1196f3a67099826f50a2a4e84e8 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 26 Jan 2023 03:34:05 +0000
+Subject: [PATCH] dt-bindings: clock: mediatek: add mt7981 clock IDs
+
+Add MT7981 clock dt-bindings, include topckgen, apmixedsys,
+infracfg, and ethernet subsystem clocks.
+
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/e353d32b5a4481766519a037afe1ed44e31ece1a.1674703830.git.daniel@makrotopia.org
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ .../dt-bindings/clock/mediatek,mt7981-clk.h   | 215 ++++++++++++++++++
+ 1 file changed, 215 insertions(+)
+ create mode 100644 include/dt-bindings/clock/mediatek,mt7981-clk.h
+
+--- /dev/null
++++ b/include/dt-bindings/clock/mediatek,mt7981-clk.h
+@@ -0,0 +1,215 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++/*
++ * Copyright (c) 2021 MediaTek Inc.
++ * Author: Wenzhen.Yu <wenzhen.yu@mediatek.com>
++ * Author: Jianhui Zhao <zhaojh329@gmail.com>
++ * Author: Daniel Golle <daniel@makrotopia.org>
++ */
++
++#ifndef _DT_BINDINGS_CLK_MT7981_H
++#define _DT_BINDINGS_CLK_MT7981_H
++
++/* TOPCKGEN */
++#define CLK_TOP_CB_CKSQ_40M           0
++#define CLK_TOP_CB_M_416M             1
++#define CLK_TOP_CB_M_D2                       2
++#define CLK_TOP_CB_M_D3                       3
++#define CLK_TOP_M_D3_D2                       4
++#define CLK_TOP_CB_M_D4                       5
++#define CLK_TOP_CB_M_D8                       6
++#define CLK_TOP_M_D8_D2                       7
++#define CLK_TOP_CB_MM_720M            8
++#define CLK_TOP_CB_MM_D2              9
++#define CLK_TOP_CB_MM_D3              10
++#define CLK_TOP_CB_MM_D3_D5           11
++#define CLK_TOP_CB_MM_D4              12
++#define CLK_TOP_CB_MM_D6              13
++#define CLK_TOP_MM_D6_D2              14
++#define CLK_TOP_CB_MM_D8              15
++#define CLK_TOP_CB_APLL2_196M         16
++#define CLK_TOP_APLL2_D2              17
++#define CLK_TOP_APLL2_D4              18
++#define CLK_TOP_NET1_2500M            19
++#define CLK_TOP_CB_NET1_D4            20
++#define CLK_TOP_CB_NET1_D5            21
++#define CLK_TOP_NET1_D5_D2            22
++#define CLK_TOP_NET1_D5_D4            23
++#define CLK_TOP_CB_NET1_D8            24
++#define CLK_TOP_NET1_D8_D2            25
++#define CLK_TOP_NET1_D8_D4            26
++#define CLK_TOP_CB_NET2_800M          27
++#define CLK_TOP_CB_NET2_D2            28
++#define CLK_TOP_CB_NET2_D4            29
++#define CLK_TOP_NET2_D4_D2            30
++#define CLK_TOP_NET2_D4_D4            31
++#define CLK_TOP_CB_NET2_D6            32
++#define CLK_TOP_CB_WEDMCU_208M                33
++#define CLK_TOP_CB_SGM_325M           34
++#define CLK_TOP_CKSQ_40M_D2           35
++#define CLK_TOP_CB_RTC_32K            36
++#define CLK_TOP_CB_RTC_32P7K          37
++#define CLK_TOP_USB_TX250M            38
++#define CLK_TOP_FAUD                  39
++#define CLK_TOP_NFI1X                 40
++#define CLK_TOP_USB_EQ_RX250M         41
++#define CLK_TOP_USB_CDR_CK            42
++#define CLK_TOP_USB_LN0_CK            43
++#define CLK_TOP_SPINFI_BCK            44
++#define CLK_TOP_SPI                   45
++#define CLK_TOP_SPIM_MST              46
++#define CLK_TOP_UART_BCK              47
++#define CLK_TOP_PWM_BCK                       48
++#define CLK_TOP_I2C_BCK                       49
++#define CLK_TOP_PEXTP_TL              50
++#define CLK_TOP_EMMC_208M             51
++#define CLK_TOP_EMMC_400M             52
++#define CLK_TOP_DRAMC_REF             53
++#define CLK_TOP_DRAMC_MD32            54
++#define CLK_TOP_SYSAXI                        55
++#define CLK_TOP_SYSAPB                        56
++#define CLK_TOP_ARM_DB_MAIN           57
++#define CLK_TOP_AP2CNN_HOST           58
++#define CLK_TOP_NETSYS                        59
++#define CLK_TOP_NETSYS_500M           60
++#define CLK_TOP_NETSYS_WED_MCU                61
++#define CLK_TOP_NETSYS_2X             62
++#define CLK_TOP_SGM_325M              63
++#define CLK_TOP_SGM_REG                       64
++#define CLK_TOP_F26M                  65
++#define CLK_TOP_EIP97B                        66
++#define CLK_TOP_USB3_PHY              67
++#define CLK_TOP_AUD                   68
++#define CLK_TOP_A1SYS                 69
++#define CLK_TOP_AUD_L                 70
++#define CLK_TOP_A_TUNER                       71
++#define CLK_TOP_U2U3_REF              72
++#define CLK_TOP_U2U3_SYS              73
++#define CLK_TOP_U2U3_XHCI             74
++#define CLK_TOP_USB_FRMCNT            75
++#define CLK_TOP_NFI1X_SEL             76
++#define CLK_TOP_SPINFI_SEL            77
++#define CLK_TOP_SPI_SEL                       78
++#define CLK_TOP_SPIM_MST_SEL          79
++#define CLK_TOP_UART_SEL              80
++#define CLK_TOP_PWM_SEL                       81
++#define CLK_TOP_I2C_SEL                       82
++#define CLK_TOP_PEXTP_TL_SEL          83
++#define CLK_TOP_EMMC_208M_SEL         84
++#define CLK_TOP_EMMC_400M_SEL         85
++#define CLK_TOP_F26M_SEL              86
++#define CLK_TOP_DRAMC_SEL             87
++#define CLK_TOP_DRAMC_MD32_SEL                88
++#define CLK_TOP_SYSAXI_SEL            89
++#define CLK_TOP_SYSAPB_SEL            90
++#define CLK_TOP_ARM_DB_MAIN_SEL               91
++#define CLK_TOP_AP2CNN_HOST_SEL               92
++#define CLK_TOP_NETSYS_SEL            93
++#define CLK_TOP_NETSYS_500M_SEL               94
++#define CLK_TOP_NETSYS_MCU_SEL                95
++#define CLK_TOP_NETSYS_2X_SEL         96
++#define CLK_TOP_SGM_325M_SEL          97
++#define CLK_TOP_SGM_REG_SEL           98
++#define CLK_TOP_EIP97B_SEL            99
++#define CLK_TOP_USB3_PHY_SEL          100
++#define CLK_TOP_AUD_SEL                       101
++#define CLK_TOP_A1SYS_SEL             102
++#define CLK_TOP_AUD_L_SEL             103
++#define CLK_TOP_A_TUNER_SEL           104
++#define CLK_TOP_U2U3_SEL              105
++#define CLK_TOP_U2U3_SYS_SEL          106
++#define CLK_TOP_U2U3_XHCI_SEL         107
++#define CLK_TOP_USB_FRMCNT_SEL                108
++#define CLK_TOP_AUD_I2S_M             109
++
++/* INFRACFG */
++#define CLK_INFRA_66M_MCK             0
++#define CLK_INFRA_UART0_SEL           1
++#define CLK_INFRA_UART1_SEL           2
++#define CLK_INFRA_UART2_SEL           3
++#define CLK_INFRA_SPI0_SEL            4
++#define CLK_INFRA_SPI1_SEL            5
++#define CLK_INFRA_SPI2_SEL            6
++#define CLK_INFRA_PWM1_SEL            7
++#define CLK_INFRA_PWM2_SEL            8
++#define CLK_INFRA_PWM3_SEL            9
++#define CLK_INFRA_PWM_BSEL            10
++#define CLK_INFRA_PCIE_SEL            11
++#define CLK_INFRA_GPT_STA             12
++#define CLK_INFRA_PWM_HCK             13
++#define CLK_INFRA_PWM_STA             14
++#define CLK_INFRA_PWM1_CK             15
++#define CLK_INFRA_PWM2_CK             16
++#define CLK_INFRA_PWM3_CK             17
++#define CLK_INFRA_CQ_DMA_CK           18
++#define CLK_INFRA_AUD_BUS_CK          19
++#define CLK_INFRA_AUD_26M_CK          20
++#define CLK_INFRA_AUD_L_CK            21
++#define CLK_INFRA_AUD_AUD_CK          22
++#define CLK_INFRA_AUD_EG2_CK          23
++#define CLK_INFRA_DRAMC_26M_CK                24
++#define CLK_INFRA_DBG_CK              25
++#define CLK_INFRA_AP_DMA_CK           26
++#define CLK_INFRA_SEJ_CK              27
++#define CLK_INFRA_SEJ_13M_CK          28
++#define CLK_INFRA_THERM_CK            29
++#define CLK_INFRA_I2C0_CK             30
++#define CLK_INFRA_UART0_CK            31
++#define CLK_INFRA_UART1_CK            32
++#define CLK_INFRA_UART2_CK            33
++#define CLK_INFRA_SPI2_CK             34
++#define CLK_INFRA_SPI2_HCK_CK         35
++#define CLK_INFRA_NFI1_CK             36
++#define CLK_INFRA_SPINFI1_CK          37
++#define CLK_INFRA_NFI_HCK_CK          38
++#define CLK_INFRA_SPI0_CK             39
++#define CLK_INFRA_SPI1_CK             40
++#define CLK_INFRA_SPI0_HCK_CK         41
++#define CLK_INFRA_SPI1_HCK_CK         42
++#define CLK_INFRA_FRTC_CK             43
++#define CLK_INFRA_MSDC_CK             44
++#define CLK_INFRA_MSDC_HCK_CK         45
++#define CLK_INFRA_MSDC_133M_CK                46
++#define CLK_INFRA_MSDC_66M_CK         47
++#define CLK_INFRA_ADC_26M_CK          48
++#define CLK_INFRA_ADC_FRC_CK          49
++#define CLK_INFRA_FBIST2FPC_CK                50
++#define CLK_INFRA_I2C_MCK_CK          51
++#define CLK_INFRA_I2C_PCK_CK          52
++#define CLK_INFRA_IUSB_133_CK         53
++#define CLK_INFRA_IUSB_66M_CK         54
++#define CLK_INFRA_IUSB_SYS_CK         55
++#define CLK_INFRA_IUSB_CK             56
++#define CLK_INFRA_IPCIE_CK            57
++#define CLK_INFRA_IPCIE_PIPE_CK               58
++#define CLK_INFRA_IPCIER_CK           59
++#define CLK_INFRA_IPCIEB_CK           60
++
++/* APMIXEDSYS */
++#define CLK_APMIXED_ARMPLL            0
++#define CLK_APMIXED_NET2PLL           1
++#define CLK_APMIXED_MMPLL             2
++#define CLK_APMIXED_SGMPLL            3
++#define CLK_APMIXED_WEDMCUPLL         4
++#define CLK_APMIXED_NET1PLL           5
++#define CLK_APMIXED_MPLL              6
++#define CLK_APMIXED_APLL2             7
++
++/* SGMIISYS_0 */
++#define CLK_SGM0_TX_EN                        0
++#define CLK_SGM0_RX_EN                        1
++#define CLK_SGM0_CK0_EN                       2
++#define CLK_SGM0_CDR_CK0_EN           3
++
++/* SGMIISYS_1 */
++#define CLK_SGM1_TX_EN                        0
++#define CLK_SGM1_RX_EN                        1
++#define CLK_SGM1_CK1_EN                       2
++#define CLK_SGM1_CDR_CK1_EN           3
++
++/* ETHSYS */
++#define CLK_ETH_FE_EN                 0
++#define CLK_ETH_GP2_EN                        1
++#define CLK_ETH_GP1_EN                        2
++#define CLK_ETH_WOCPU0_EN             3
++
++#endif /* _DT_BINDINGS_CLK_MT7981_H */
diff --git a/target/linux/mediatek/patches-6.6/231-v6.4-clk-mediatek-add-MT7981-clock-support.patch b/target/linux/mediatek/patches-6.6/231-v6.4-clk-mediatek-add-MT7981-clock-support.patch
new file mode 100644 (file)
index 0000000..f9dd94a
--- /dev/null
@@ -0,0 +1,932 @@
+From 8efeeb9c8b4ecf4fb4a74be9403aba951403bbaa Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 26 Jan 2023 03:34:24 +0000
+Subject: [PATCH] clk: mediatek: add MT7981 clock support
+
+Add MT7981 clock support, include topckgen, apmixedsys, infracfg and
+ethernet subsystem clocks.
+
+The drivers are based on clk-mt7981.c which can be found in MediaTek's
+SDK sources. To be fit for upstream inclusion the driver has been split
+into clock domains and the infracfg part has been significantly
+de-bloated by removing all the 1:1 factors (aliases).
+
+Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/8136eb5b2049177bc2f6d3e0f2aefecc342d626f.1674703830.git.daniel@makrotopia.org
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+[sboyd@kernel.org: Add module license]
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/Kconfig               |  17 +
+ drivers/clk/mediatek/Makefile              |   4 +
+ drivers/clk/mediatek/clk-mt7981-apmixed.c  | 102 +++++
+ drivers/clk/mediatek/clk-mt7981-eth.c      | 118 ++++++
+ drivers/clk/mediatek/clk-mt7981-infracfg.c | 207 ++++++++++
+ drivers/clk/mediatek/clk-mt7981-topckgen.c | 422 +++++++++++++++++++++
+ 6 files changed, 870 insertions(+)
+ create mode 100644 drivers/clk/mediatek/clk-mt7981-apmixed.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7981-eth.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7981-infracfg.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7981-topckgen.c
+
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -381,6 +381,23 @@ config COMMON_CLK_MT7629_HIFSYS
+         This driver supports MediaTek MT7629 HIFSYS clocks providing
+         to PCI-E and USB.
++config COMMON_CLK_MT7981
++      bool "Clock driver for MediaTek MT7981"
++      depends on ARCH_MEDIATEK || COMPILE_TEST
++      select COMMON_CLK_MEDIATEK
++      default ARCH_MEDIATEK
++      help
++        This driver supports MediaTek MT7981 basic clocks and clocks
++        required for various peripherals found on this SoC.
++
++config COMMON_CLK_MT7981_ETHSYS
++      tristate "Clock driver for MediaTek MT7981 ETHSYS"
++      depends on COMMON_CLK_MT7981
++      default COMMON_CLK_MT7981
++      help
++        This driver adds support for clocks for Ethernet and SGMII
++        required on MediaTek MT7981 SoC.
++
+ config COMMON_CLK_MT7986
+       bool "Clock driver for MediaTek MT7986"
+       depends on ARCH_MEDIATEK || COMPILE_TEST
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -52,6 +52,10 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) +
+ obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
+ obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
+ obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
++obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-apmixed.o
++obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-topckgen.o
++obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-infracfg.o
++obj-$(CONFIG_COMMON_CLK_MT7981_ETHSYS) += clk-mt7981-eth.o
+ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
+ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
+ obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7981-apmixed.c
+@@ -0,0 +1,102 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2021 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
++ * Author: Jianhui Zhao <zhaojh329@gmail.com>
++ * Author: Daniel Golle <daniel@makrotopia.org>
++ */
++
++#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-gate.h"
++#include "clk-mtk.h"
++#include "clk-mux.h"
++#include "clk-pll.h"
++
++#include <dt-bindings/clock/mediatek,mt7981-clk.h>
++#include <linux/clk.h>
++
++#define MT7981_PLL_FMAX (2500UL * MHZ)
++#define CON0_MT7981_RST_BAR BIT(27)
++
++#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
++               _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift,         \
++               _div_table, _parent_name)                                     \
++      {                                                                      \
++              .id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg,    \
++              .en_mask = _en_mask, .flags = _flags,                          \
++              .rst_bar_mask = CON0_MT7981_RST_BAR, .fmax = MT7981_PLL_FMAX,  \
++              .pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \
++              .tuner_reg = _tuner_reg, .pcw_reg = _pcw_reg,                  \
++              .pcw_shift = _pcw_shift, .div_table = _div_table,              \
++              .parent_name = _parent_name,                                   \
++      }
++
++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg,   \
++          _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift)                       \
++      PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
++               _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, NULL,   \
++               "clkxtal")
++
++static const struct mtk_pll_data plls[] = {
++      PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, PLL_AO,
++          32, 0x0200, 4, 0, 0x0204, 0),
++      PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x00000001, 0, 32,
++          0x0210, 4, 0, 0x0214, 0),
++      PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0220, 0x022C, 0x00000001, 0, 32,
++          0x0220, 4, 0, 0x0224, 0),
++      PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0230, 0x023C, 0x00000001, 0, 32,
++          0x0230, 4, 0, 0x0234, 0),
++      PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0240, 0x024C, 0x00000001, 0, 32,
++          0x0240, 4, 0, 0x0244, 0),
++      PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0250, 0x025C, 0x00000001, 0, 32,
++          0x0250, 4, 0, 0x0254, 0),
++      PLL(CLK_APMIXED_MPLL, "mpll", 0x0260, 0x0270, 0x00000001, 0, 32,
++          0x0260, 4, 0, 0x0264, 0),
++      PLL(CLK_APMIXED_APLL2, "apll2", 0x0278, 0x0288, 0x00000001, 0, 32,
++          0x0278, 4, 0, 0x027C, 0),
++};
++
++static const struct of_device_id of_match_clk_mt7981_apmixed[] = {
++      { .compatible = "mediatek,mt7981-apmixedsys", },
++      { /* sentinel */ }
++};
++
++static int clk_mt7981_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;
++
++      mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
++
++      r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
++      if (r) {
++              pr_err("%s(): could not register clock provider: %d\n",
++                     __func__, r);
++              goto free_apmixed_data;
++      }
++      return r;
++
++free_apmixed_data:
++      mtk_free_clk_data(clk_data);
++      return r;
++}
++
++static struct platform_driver clk_mt7981_apmixed_drv = {
++      .probe = clk_mt7981_apmixed_probe,
++      .driver = {
++              .name = "clk-mt7981-apmixed",
++              .of_match_table = of_match_clk_mt7981_apmixed,
++      },
++};
++builtin_platform_driver(clk_mt7981_apmixed_drv);
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7981-eth.c
+@@ -0,0 +1,118 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2021 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
++ * Author: Jianhui Zhao <zhaojh329@gmail.com>
++ * Author: Daniel Golle <daniel@makrotopia.org>
++ */
++
++#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,mt7981-clk.h>
++
++static const struct mtk_gate_regs sgmii0_cg_regs = {
++      .set_ofs = 0xE4,
++      .clr_ofs = 0xE4,
++      .sta_ofs = 0xE4,
++};
++
++#define GATE_SGMII0(_id, _name, _parent, _shift) {    \
++              .id = _id,                              \
++              .name = _name,                          \
++              .parent_name = _parent,                 \
++              .regs = &sgmii0_cg_regs,                        \
++              .shift = _shift,                        \
++              .ops = &mtk_clk_gate_ops_no_setclr_inv, \
++      }
++
++static const struct mtk_gate sgmii0_clks[] __initconst = {
++      GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "usb_tx250m", 2),
++      GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "usb_eq_rx250m", 3),
++      GATE_SGMII0(CLK_SGM0_CK0_EN, "sgm0_ck0_en", "usb_ln0", 4),
++      GATE_SGMII0(CLK_SGM0_CDR_CK0_EN, "sgm0_cdr_ck0_en", "usb_cdr", 5),
++};
++
++static const struct mtk_gate_regs sgmii1_cg_regs = {
++      .set_ofs = 0xE4,
++      .clr_ofs = 0xE4,
++      .sta_ofs = 0xE4,
++};
++
++#define GATE_SGMII1(_id, _name, _parent, _shift) {    \
++              .id = _id,                              \
++              .name = _name,                          \
++              .parent_name = _parent,                 \
++              .regs = &sgmii1_cg_regs,                        \
++              .shift = _shift,                        \
++              .ops = &mtk_clk_gate_ops_no_setclr_inv, \
++      }
++
++static const struct mtk_gate sgmii1_clks[] __initconst = {
++      GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "usb_tx250m", 2),
++      GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "usb_eq_rx250m", 3),
++      GATE_SGMII1(CLK_SGM1_CK1_EN, "sgm1_ck1_en", "usb_ln0", 4),
++      GATE_SGMII1(CLK_SGM1_CDR_CK1_EN, "sgm1_cdr_ck1_en", "usb_cdr", 5),
++};
++
++static const struct mtk_gate_regs eth_cg_regs = {
++      .set_ofs = 0x30,
++      .clr_ofs = 0x30,
++      .sta_ofs = 0x30,
++};
++
++#define GATE_ETH(_id, _name, _parent, _shift) {       \
++              .id = _id,                              \
++              .name = _name,                          \
++              .parent_name = _parent,                 \
++              .regs = &eth_cg_regs,                   \
++              .shift = _shift,                        \
++              .ops = &mtk_clk_gate_ops_no_setclr_inv, \
++      }
++
++static const struct mtk_gate eth_clks[] __initconst = {
++      GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x", 6),
++      GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m", 7),
++      GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m", 8),
++      GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", "netsys_wed_mcu", 15),
++};
++
++static const struct mtk_clk_desc eth_desc = {
++      .clks = eth_clks,
++      .num_clks = ARRAY_SIZE(eth_clks),
++};
++
++static const struct mtk_clk_desc sgmii0_desc = {
++      .clks = sgmii0_clks,
++      .num_clks = ARRAY_SIZE(sgmii0_clks),
++};
++
++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_mt7981_eth[] = {
++      { .compatible = "mediatek,mt7981-ethsys", .data = &eth_desc },
++      { .compatible = "mediatek,mt7981-sgmiisys_0", .data = &sgmii0_desc },
++      { .compatible = "mediatek,mt7981-sgmiisys_1", .data = &sgmii1_desc },
++      { /* sentinel */ }
++};
++
++static struct platform_driver clk_mt7981_eth_drv = {
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
++      .driver = {
++              .name = "clk-mt7981-eth",
++              .of_match_table = of_match_clk_mt7981_eth,
++      },
++};
++module_platform_driver(clk_mt7981_eth_drv);
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7981-infracfg.c
+@@ -0,0 +1,207 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2021 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
++ * Author: Jianhui Zhao <zhaojh329@gmail.com>
++ * Author: Daniel Golle <daniel@makrotopia.org>
++ */
++
++#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,mt7981-clk.h>
++#include <linux/clk.h>
++
++static DEFINE_SPINLOCK(mt7981_clk_lock);
++
++static const struct mtk_fixed_factor infra_divs[] = {
++      FACTOR(CLK_INFRA_66M_MCK, "infra_66m_mck", "sysaxi_sel", 1, 2),
++};
++
++static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel",
++                                                              "uart_sel" };
++
++static const char *const infra_spi0_parents[] __initconst = { "i2c_sel",
++                                                            "spi_sel" };
++
++static const char *const infra_spi1_parents[] __initconst = { "i2c_sel",
++                                                            "spim_mst_sel" };
++
++static const char *const infra_pwm1_parents[] __initconst = { "pwm_sel" };
++
++static const char *const infra_pwm_bsel_parents[] __initconst = {
++      "cb_rtc_32p7k", "csw_f26m_sel", "infra_66m_mck", "pwm_sel"
++};
++
++static const char *const infra_pcie_parents[] __initconst = {
++      "cb_rtc_32p7k", "csw_f26m_sel", "cb_cksq_40m", "pextp_tl_ck_sel"
++};
++
++static const struct mtk_mux infra_muxes[] = {
++      /* MODULE_CLK_SEL_0 */
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel",
++                           infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel",
++                           infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel",
++                           infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel",
++                           infra_spi0_parents, 0x0018, 0x0010, 0x0014, 4, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel",
++                           infra_spi1_parents, 0x0018, 0x0010, 0x0014, 5, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI2_SEL, "infra_spi2_sel",
++                           infra_spi0_parents, 0x0018, 0x0010, 0x0014, 6, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel",
++                           infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 9, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel",
++                           infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 11, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM3_SEL, "infra_pwm3_sel",
++                           infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 15, 1,
++                           -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel",
++                           infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13,
++                           2, -1, -1, -1),
++      /* MODULE_CLK_SEL_1 */
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel",
++                           infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2,
++                           -1, -1, -1),
++};
++
++static const struct mtk_gate_regs infra0_cg_regs = {
++      .set_ofs = 0x40,
++      .clr_ofs = 0x44,
++      .sta_ofs = 0x48,
++};
++
++static const struct mtk_gate_regs infra1_cg_regs = {
++      .set_ofs = 0x50,
++      .clr_ofs = 0x54,
++      .sta_ofs = 0x58,
++};
++
++static const struct mtk_gate_regs infra2_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,                               \
++      }
++
++static const struct mtk_gate infra_clks[] = {
++      /* INFRA0 */
++      GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta", "infra_66m_mck", 0),
++      GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck", "infra_66m_mck", 1),
++      GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta", "infra_pwm_bsel", 2),
++      GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1", "infra_pwm1_sel", 3),
++      GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2", "infra_pwm2_sel", 4),
++      GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma", "sysaxi", 6),
++
++      GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus", "sysaxi", 8),
++      GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m", "csw_f26m_sel", 9),
++      GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l", "aud_l", 10),
++      GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud", "a1sys", 11),
++      GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2", "a_tuner", 13),
++      GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", "csw_f26m_sel",
++                  14),
++      GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg", "infra_66m_mck", 15),
++      GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma", "infra_66m_mck", 16),
++      GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej", "infra_66m_mck", 24),
++      GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m", "csw_f26m_sel", 25),
++      GATE_INFRA0(CLK_INFRA_PWM3_CK, "infra_pwm3", "infra_pwm3_sel", 27),
++      /* INFRA1 */
++      GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm", "csw_f26m_sel", 0),
++      GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0", "i2c_bck", 1),
++      GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0", "infra_uart0_sel", 2),
++      GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1", "infra_uart1_sel", 3),
++      GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2", "infra_uart2_sel", 4),
++      GATE_INFRA1(CLK_INFRA_SPI2_CK, "infra_spi2", "infra_spi2_sel", 6),
++      GATE_INFRA1(CLK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", "infra_66m_mck", 7),
++      GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1", "nfi1x", 8),
++      GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1", "spinfi_bck", 9),
++      GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck", "infra_66m_mck", 10),
++      GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0", "infra_spi0_sel", 11),
++      GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1", "infra_spi1_sel", 12),
++      GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", "infra_66m_mck",
++                  13),
++      GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", "infra_66m_mck",
++                  14),
++      GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc", "cb_rtc_32k", 15),
++      GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc", "emmc_400m", 16),
++      GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", "emmc_208m", 17),
++      GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m", "sysaxi", 18),
++      GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "sysaxi", 19),
++      GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "infra_adc_frc", 20),
++      GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m", 21),
++      GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x", 23),
++      GATE_INFRA1(CLK_INFRA_I2C_MCK_CK, "infra_i2c_mck", "sysaxi", 25),
++      GATE_INFRA1(CLK_INFRA_I2C_PCK_CK, "infra_i2c_pck", "infra_66m_mck", 26),
++      /* INFRA2 */
++      GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133", "sysaxi", 0),
++      GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m", "sysaxi", 1),
++      GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", "u2u3_sys", 2),
++      GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb", "u2u3_ref", 3),
++      GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie", "pextp_tl", 12),
++      GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe", "cb_cksq_40m",
++                  13),
++      GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier", "csw_f26m", 14),
++      GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb", "sysaxi", 15),
++};
++
++static const struct mtk_clk_desc infracfg_desc = {
++      .factor_clks = infra_divs,
++      .num_factor_clks = ARRAY_SIZE(infra_divs),
++      .mux_clks = infra_muxes,
++      .num_mux_clks = ARRAY_SIZE(infra_muxes),
++      .clks = infra_clks,
++      .num_clks = ARRAY_SIZE(infra_clks),
++      .clk_lock = &mt7981_clk_lock,
++};
++
++static const struct of_device_id of_match_clk_mt7981_infracfg[] = {
++      { .compatible = "mediatek,mt7981-infracfg", .data = &infracfg_desc },
++      { /* sentinel */ }
++};
++
++static struct platform_driver clk_mt7981_infracfg_drv = {
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
++      .driver = {
++              .name = "clk-mt7981-infracfg",
++              .of_match_table = of_match_clk_mt7981_infracfg,
++      },
++};
++builtin_platform_driver(clk_mt7981_infracfg_drv);
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7981-topckgen.c
+@@ -0,0 +1,422 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2021 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
++ * Author: Jianhui Zhao <zhaojh329@gmail.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,mt7981-clk.h>
++#include <linux/clk.h>
++
++static DEFINE_SPINLOCK(mt7981_clk_lock);
++
++static const struct mtk_fixed_factor top_divs[] = {
++      FACTOR(CLK_TOP_CB_CKSQ_40M, "cb_cksq_40m", "clkxtal", 1, 1),
++      FACTOR(CLK_TOP_CB_M_416M, "cb_m_416m", "mpll", 1, 1),
++      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, 2),
++      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_MM_720M, "cb_mm_720m", "mmpll", 1, 1),
++      FACTOR(CLK_TOP_CB_MM_D2, "cb_mm_d2", "mmpll", 1, 2),
++      FACTOR(CLK_TOP_CB_MM_D3, "cb_mm_d3", "mmpll", 1, 3),
++      FACTOR(CLK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", "mmpll", 1, 15),
++      FACTOR(CLK_TOP_CB_MM_D4, "cb_mm_d4", "mmpll", 1, 4),
++      FACTOR(CLK_TOP_CB_MM_D6, "cb_mm_d6", "mmpll", 1, 6),
++      FACTOR(CLK_TOP_MM_D6_D2, "mm_d6_d2", "mmpll", 1, 12),
++      FACTOR(CLK_TOP_CB_MM_D8, "cb_mm_d8", "mmpll", 1, 8),
++      FACTOR(CLK_TOP_CB_APLL2_196M, "cb_apll2_196m", "apll2", 1, 1),
++      FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1, 2),
++      FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
++      FACTOR(CLK_TOP_NET1_2500M, "net1_2500m", "net1pll", 1, 1),
++      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_D8, "cb_net1_d8", "net1pll", 1, 8),
++      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_CB_NET2_800M, "cb_net2_800m", "net2pll", 1, 1),
++      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_D2, "net2_d4_d2", "net2pll", 1, 8),
++      FACTOR(CLK_TOP_NET2_D4_D4, "net2_d4_d4", "net2pll", 1, 16),
++      FACTOR(CLK_TOP_CB_NET2_D6, "cb_net2_d6", "net2pll", 1, 6),
++      FACTOR(CLK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m", "wedmcupll", 1, 1),
++      FACTOR(CLK_TOP_CB_SGM_325M, "cb_sgm_325m", "sgmpll", 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, 1220),
++      FACTOR(CLK_TOP_USB_TX250M, "usb_tx250m", "cb_cksq_40m", 1, 1),
++      FACTOR(CLK_TOP_FAUD, "faud", "aud_sel", 1, 1),
++      FACTOR(CLK_TOP_NFI1X, "nfi1x", "nfi1x_sel", 1, 1),
++      FACTOR(CLK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", "cb_cksq_40m", 1, 1),
++      FACTOR(CLK_TOP_USB_CDR_CK, "usb_cdr", "cb_cksq_40m", 1, 1),
++      FACTOR(CLK_TOP_USB_LN0_CK, "usb_ln0", "cb_cksq_40m", 1, 1),
++      FACTOR(CLK_TOP_SPINFI_BCK, "spinfi_bck", "spinfi_sel", 1, 1),
++      FACTOR(CLK_TOP_SPI, "spi", "spi_sel", 1, 1),
++      FACTOR(CLK_TOP_SPIM_MST, "spim_mst", "spim_mst_sel", 1, 1),
++      FACTOR(CLK_TOP_UART_BCK, "uart_bck", "uart_sel", 1, 1),
++      FACTOR(CLK_TOP_PWM_BCK, "pwm_bck", "pwm_sel", 1, 1),
++      FACTOR(CLK_TOP_I2C_BCK, "i2c_bck", "i2c_sel", 1, 1),
++      FACTOR(CLK_TOP_PEXTP_TL, "pextp_tl", "pextp_tl_ck_sel", 1, 1),
++      FACTOR(CLK_TOP_EMMC_208M, "emmc_208m", "emmc_208m_sel", 1, 1),
++      FACTOR(CLK_TOP_EMMC_400M, "emmc_400m", "emmc_400m_sel", 1, 1),
++      FACTOR(CLK_TOP_DRAMC_REF, "dramc_ref", "dramc_sel", 1, 1),
++      FACTOR(CLK_TOP_DRAMC_MD32, "dramc_md32", "dramc_md32_sel", 1, 1),
++      FACTOR(CLK_TOP_SYSAXI, "sysaxi", "sysaxi_sel", 1, 1),
++      FACTOR(CLK_TOP_SYSAPB, "sysapb", "sysapb_sel", 1, 1),
++      FACTOR(CLK_TOP_ARM_DB_MAIN, "arm_db_main", "arm_db_main_sel", 1, 1),
++      FACTOR(CLK_TOP_AP2CNN_HOST, "ap2cnn_host", "ap2cnn_host_sel", 1, 1),
++      FACTOR(CLK_TOP_NETSYS, "netsys", "netsys_sel", 1, 1),
++      FACTOR(CLK_TOP_NETSYS_500M, "netsys_500m", "netsys_500m_sel", 1, 1),
++      FACTOR(CLK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", "netsys_mcu_sel", 1, 1),
++      FACTOR(CLK_TOP_NETSYS_2X, "netsys_2x", "netsys_2x_sel", 1, 1),
++      FACTOR(CLK_TOP_SGM_325M, "sgm_325m", "sgm_325m_sel", 1, 1),
++      FACTOR(CLK_TOP_SGM_REG, "sgm_reg", "sgm_reg_sel", 1, 1),
++      FACTOR(CLK_TOP_F26M, "csw_f26m", "csw_f26m_sel", 1, 1),
++      FACTOR(CLK_TOP_EIP97B, "eip97b", "eip97b_sel", 1, 1),
++      FACTOR(CLK_TOP_USB3_PHY, "usb3_phy", "usb3_phy_sel", 1, 1),
++      FACTOR(CLK_TOP_AUD, "aud", "faud", 1, 1),
++      FACTOR(CLK_TOP_A1SYS, "a1sys", "a1sys_sel", 1, 1),
++      FACTOR(CLK_TOP_AUD_L, "aud_l", "aud_l_sel", 1, 1),
++      FACTOR(CLK_TOP_A_TUNER, "a_tuner", "a_tuner_sel", 1, 1),
++      FACTOR(CLK_TOP_U2U3_REF, "u2u3_ref", "u2u3_sel", 1, 1),
++      FACTOR(CLK_TOP_U2U3_SYS, "u2u3_sys", "u2u3_sys_sel", 1, 1),
++      FACTOR(CLK_TOP_U2U3_XHCI, "u2u3_xhci", "u2u3_xhci_sel", 1, 1),
++      FACTOR(CLK_TOP_USB_FRMCNT, "usb_frmcnt", "usb_frmcnt_sel", 1, 1),
++};
++
++static const char * const nfi1x_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_mm_d4",
++      "net1_d8_d2",
++      "cb_net2_d6",
++      "cb_m_d4",
++      "cb_mm_d8",
++      "net1_d8_d4",
++      "cb_m_d8"
++};
++
++static const char * const spinfi_parents[] __initconst = {
++      "cksq_40m_d2",
++      "cb_cksq_40m",
++      "net1_d5_d4",
++      "cb_m_d4",
++      "cb_mm_d8",
++      "net1_d8_d4",
++      "mm_d6_d2",
++      "cb_m_d8"
++};
++
++static const char * const spi_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_m_d2",
++      "cb_mm_d4",
++      "net1_d8_d2",
++      "cb_net2_d6",
++      "net1_d5_d4",
++      "cb_m_d4",
++      "net1_d8_d4"
++};
++
++static const char * const uart_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_m_d8",
++      "m_d8_d2"
++};
++
++static const char * const pwm_parents[] __initconst = {
++      "cb_cksq_40m",
++      "net1_d8_d2",
++      "net1_d5_d4",
++      "cb_m_d4",
++      "m_d8_d2",
++      "cb_rtc_32k"
++};
++
++static const char * const i2c_parents[] __initconst = {
++      "cb_cksq_40m",
++      "net1_d5_d4",
++      "cb_m_d4",
++      "net1_d8_d4"
++};
++
++static const char * const pextp_tl_ck_parents[] __initconst = {
++      "cb_cksq_40m",
++      "net1_d5_d4",
++      "cb_m_d4",
++      "cb_rtc_32k"
++};
++
++static const char * const emmc_208m_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_m_d2",
++      "cb_net2_d4",
++      "cb_apll2_196m",
++      "cb_mm_d4",
++      "net1_d8_d2",
++      "cb_mm_d6"
++};
++
++static const char * const emmc_400m_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_net2_d2",
++      "cb_mm_d2",
++      "cb_net2_d2"
++};
++
++static const char * const csw_f26m_parents[] __initconst = {
++      "cksq_40m_d2",
++      "m_d8_d2"
++};
++
++static const char * const dramc_md32_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_m_d2",
++      "cb_wedmcu_208m"
++};
++
++static const char * const sysaxi_parents[] __initconst = {
++      "cb_cksq_40m",
++      "net1_d8_d2"
++};
++
++static const char * const sysapb_parents[] __initconst = {
++      "cb_cksq_40m",
++      "m_d3_d2"
++};
++
++static const char * const arm_db_main_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_net2_d6"
++};
++
++static const char * const ap2cnn_host_parents[] __initconst = {
++      "cb_cksq_40m",
++      "net1_d8_d4"
++};
++
++static const char * const netsys_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_mm_d2"
++};
++
++static const char * const netsys_500m_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_net1_d5"
++};
++
++static const char * const netsys_mcu_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_mm_720m",
++      "cb_net1_d4",
++      "cb_net1_d5",
++      "cb_m_416m"
++};
++
++static const char * const netsys_2x_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_net2_800m",
++      "cb_mm_720m"
++};
++
++static const char * const sgm_325m_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_sgm_325m"
++};
++
++static const char * const sgm_reg_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_net2_d4"
++};
++
++static const char * const eip97b_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_net1_d5",
++      "cb_m_416m",
++      "cb_mm_d2",
++      "net1_d5_d2"
++};
++
++static const char * const aud_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_apll2_196m"
++};
++
++static const char * const a1sys_parents[] __initconst = {
++      "cb_cksq_40m",
++      "apll2_d4"
++};
++
++static const char * const aud_l_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_apll2_196m",
++      "m_d8_d2"
++};
++
++static const char * const a_tuner_parents[] __initconst = {
++      "cb_cksq_40m",
++      "apll2_d4",
++      "m_d8_d2"
++};
++
++static const char * const u2u3_parents[] __initconst = {
++      "cb_cksq_40m",
++      "m_d8_d2"
++};
++
++static const char * const u2u3_sys_parents[] __initconst = {
++      "cb_cksq_40m",
++      "net1_d5_d4"
++};
++
++static const char * const usb_frmcnt_parents[] __initconst = {
++      "cb_cksq_40m",
++      "cb_mm_d3_d5"
++};
++
++static const struct mtk_mux top_muxes[] = {
++      /* CLK_CFG_0 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents,
++                           0x000, 0x004, 0x008, 0, 3, 7, 0x1C0, 0),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
++                           0x000, 0x004, 0x008, 8, 3, 15, 0x1C0, 1),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents,
++                           0x000, 0x004, 0x008, 16, 3, 23, 0x1C0, 2),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
++                           0x000, 0x004, 0x008, 24, 3, 31, 0x1C0, 3),
++      /* CLK_CFG_1 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
++                           0x010, 0x014, 0x018, 0, 2, 7, 0x1C0, 4),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
++                           0x010, 0x014, 0x018, 8, 3, 15, 0x1C0, 5),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents,
++                           0x010, 0x014, 0x018, 16, 2, 23, 0x1C0, 6),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
++                           pextp_tl_ck_parents, 0x010, 0x014, 0x018, 24, 2, 31,
++                           0x1C0, 7),
++      /* CLK_CFG_2 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_208M_SEL, "emmc_208m_sel",
++                           emmc_208m_parents, 0x020, 0x024, 0x028, 0, 3, 7,
++                           0x1C0, 8),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_400M_SEL, "emmc_400m_sel",
++                           emmc_400m_parents, 0x020, 0x024, 0x028, 8, 2, 15,
++                           0x1C0, 9),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_F26M_SEL, "csw_f26m_sel",
++                                 csw_f26m_parents, 0x020, 0x024, 0x028, 16, 1, 23,
++                                 0x1C0, 10,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel",
++                                 csw_f26m_parents, 0x020, 0x024, 0x028, 24, 1,
++                                 31, 0x1C0, 11,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
++      /* CLK_CFG_3 */
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
++                                 dramc_md32_parents, 0x030, 0x034, 0x038, 0, 2,
++                                 7, 0x1C0, 12,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel",
++                                 sysaxi_parents, 0x030, 0x034, 0x038, 8, 1, 15,
++                                 0x1C0, 13,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel",
++                                 sysapb_parents, 0x030, 0x034, 0x038, 16, 1,
++                                 23, 0x1C0, 14,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
++                           arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1, 31,
++                           0x1C0, 15),
++      /* CLK_CFG_4 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel",
++                           ap2cnn_host_parents, 0x040, 0x044, 0x048, 0, 1, 7,
++                           0x1C0, 16),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
++                           0x040, 0x044, 0x048, 8, 1, 15, 0x1C0, 17),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
++                           netsys_500m_parents, 0x040, 0x044, 0x048, 16, 1, 23,
++                           0x1C0, 18),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
++                           netsys_mcu_parents, 0x040, 0x044, 0x048, 24, 3, 31,
++                           0x1C0, 19),
++      /* CLK_CFG_5 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
++                           netsys_2x_parents, 0x050, 0x054, 0x058, 0, 2, 7,
++                           0x1C0, 20),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
++                           sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
++                           0x1C0, 21),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
++                           0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents,
++                           0x050, 0x054, 0x058, 24, 3, 31, 0x1C0, 23),
++      /* CLK_CFG_6 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB3_PHY_SEL, "usb3_phy_sel",
++                           csw_f26m_parents, 0x060, 0x064, 0x068, 0, 1,
++                           7, 0x1C0, 24),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x060,
++                           0x064, 0x068, 8, 1, 15, 0x1C0, 25),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
++                           0x060, 0x064, 0x068, 16, 1, 23, 0x1C0, 26),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
++                           0x060, 0x064, 0x068, 24, 2, 31, 0x1C0, 27),
++      /* CLK_CFG_7 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
++                           a_tuner_parents, 0x070, 0x074, 0x078, 0, 2, 7,
++                           0x1C0, 28),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x070,
++                           0x074, 0x078, 8, 1, 15, 0x1C0, 29),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel",
++                           u2u3_sys_parents, 0x070, 0x074, 0x078, 16, 1, 23,
++                           0x1C0, 30),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel",
++                           u2u3_sys_parents, 0x070, 0x074, 0x078, 24, 1, 31,
++                           0x1C4, 0),
++      /* CLK_CFG_8 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel",
++                           usb_frmcnt_parents, 0x080, 0x084, 0x088, 0, 1, 7,
++                           0x1C4, 1),
++};
++
++static struct mtk_composite top_aud_divs[] = {
++      DIV_GATE(CLK_TOP_AUD_I2S_M, "aud_i2s_m", "aud",
++              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_aud_divs,
++      .num_composite_clks = ARRAY_SIZE(top_aud_divs),
++      .clk_lock = &mt7981_clk_lock,
++};
++
++static const struct of_device_id of_match_clk_mt7981_topckgen[] = {
++      { .compatible = "mediatek,mt7981-topckgen", .data = &topck_desc },
++      { /* sentinel */ }
++};
++
++static struct platform_driver clk_mt7981_topckgen_drv = {
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
++      .driver = {
++              .name = "clk-mt7981-topckgen",
++              .of_match_table = of_match_clk_mt7981_topckgen,
++      },
++};
++builtin_platform_driver(clk_mt7981_topckgen_drv);
diff --git a/target/linux/mediatek/patches-6.6/232-clk-mediatek-mt7981-topckgen-flag-SGM_REG_SEL-as-cri.patch b/target/linux/mediatek/patches-6.6/232-clk-mediatek-mt7981-topckgen-flag-SGM_REG_SEL-as-cri.patch
new file mode 100644 (file)
index 0000000..8820d57
--- /dev/null
@@ -0,0 +1,30 @@
+From fc157139e6b7f8dfb6430ac7191ba754027705e8 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 18 Feb 2024 01:59:59 +0000
+Subject: [PATCH] clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as critical
+
+Without the SGM_REG_SEL clock enabled the system freezes if trying to
+access registers used by MT7981 clock drivers itself.
+Mark SGM_REG_SEL as critical to make sure it is always enabled to
+prevent freezes on boot depending on probe order.
+
+Fixes: 813c3b53b55ba ("clk: mediatek: add MT7981 clock support")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/clk/mediatek/clk-mt7981-topckgen.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt7981-topckgen.c
++++ b/drivers/clk/mediatek/clk-mt7981-topckgen.c
+@@ -359,8 +359,9 @@ static const struct mtk_mux top_muxes[]
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
+                            sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
+                            0x1C0, 21),
+-      MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
+-                           0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
++                                 0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22,
++                                 CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents,
+                            0x050, 0x054, 0x058, 24, 3, 31, 0x1C0, 23),
+       /* CLK_CFG_6 */
diff --git a/target/linux/mediatek/patches-6.6/240-pinctrl-mediatek-add-support-for-MT7988-SoC.patch b/target/linux/mediatek/patches-6.6/240-pinctrl-mediatek-add-support-for-MT7988-SoC.patch
new file mode 100644 (file)
index 0000000..a365f08
--- /dev/null
@@ -0,0 +1,26 @@
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -141,6 +141,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 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
+@@ -20,6 +20,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
diff --git a/target/linux/mediatek/patches-6.6/241-v6.3-dt-bindings-clock-Add-compatibles-for-MT7981.patch b/target/linux/mediatek/patches-6.6/241-v6.3-dt-bindings-clock-Add-compatibles-for-MT7981.patch
new file mode 100644 (file)
index 0000000..ad4ecdf
--- /dev/null
@@ -0,0 +1,75 @@
+From cc4d9e0c77494fcf6bccbc57e23db0007cf681b7 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 26 Jan 2023 03:33:46 +0000
+Subject: [PATCH] dt-bindings: clock: Add compatibles for MT7981
+
+Add compatible string for MT7981 to existing bindings at
+ - mediatek,apmixedsys.yaml
+ - mediatek,topckgen.yaml
+ - mediatek,ethsys.txt
+ - mediatek,infracfg.yaml
+ - mediatek,sgmiisys.txt
+
+Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/cc85ee470c781ff4013f6c21c92c0a21574b12b2.1674703830.git.daniel@makrotopia.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ .../devicetree/bindings/arm/mediatek/mediatek,ethsys.txt        | 1 +
+ .../devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml     | 1 +
+ .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt      | 2 ++
+ .../devicetree/bindings/clock/mediatek,apmixedsys.yaml          | 1 +
+ Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml  | 1 +
+ 5 files changed, 6 insertions(+)
+
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+@@ -10,6 +10,7 @@ Required Properties:
+       - "mediatek,mt7622-ethsys", "syscon"
+       - "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
+       - "mediatek,mt7629-ethsys", "syscon"
++      - "mediatek,mt7981-ethsys", "syscon"
+       - "mediatek,mt7986-ethsys", "syscon"
+ - #clock-cells: Must be 1
+ - #reset-cells: Must be 1
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
+@@ -28,6 +28,7 @@ properties:
+               - mediatek,mt6797-infracfg
+               - mediatek,mt7622-infracfg
+               - mediatek,mt7629-infracfg
++              - mediatek,mt7981-infracfg
+               - mediatek,mt7986-infracfg
+               - mediatek,mt8135-infracfg
+               - mediatek,mt8167-infracfg
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
+@@ -8,6 +8,8 @@ Required Properties:
+ - compatible: Should be:
+       - "mediatek,mt7622-sgmiisys", "syscon"
+       - "mediatek,mt7629-sgmiisys", "syscon"
++      - "mediatek,mt7981-sgmiisys_0", "syscon"
++      - "mediatek,mt7981-sgmiisys_1", "syscon"
+       - "mediatek,mt7986-sgmiisys_0", "syscon"
+       - "mediatek,mt7986-sgmiisys_1", "syscon"
+ - #clock-cells: Must be 1
+--- a/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
++++ b/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
+@@ -20,6 +20,7 @@ properties:
+       - enum:
+           - mediatek,mt6797-apmixedsys
+           - mediatek,mt7622-apmixedsys
++          - mediatek,mt7981-apmixedsys
+           - mediatek,mt7986-apmixedsys
+           - mediatek,mt8135-apmixedsys
+           - mediatek,mt8173-apmixedsys
+--- a/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
++++ b/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
+@@ -35,6 +35,7 @@ properties:
+               - mediatek,mt6779-topckgen
+               - mediatek,mt6795-topckgen
+               - mediatek,mt7629-topckgen
++              - mediatek,mt7981-topckgen
+               - mediatek,mt7986-topckgen
+               - mediatek,mt8167-topckgen
+               - mediatek,mt8183-topckgen
diff --git a/target/linux/mediatek/patches-6.6/242-v6.4-dt-bindings-arm-mediatek-sgmiisys-Convert-to-DT-sche.patch b/target/linux/mediatek/patches-6.6/242-v6.4-dt-bindings-arm-mediatek-sgmiisys-Convert-to-DT-sche.patch
new file mode 100644 (file)
index 0000000..48d3d4e
--- /dev/null
@@ -0,0 +1,107 @@
+From d4f08a703565abf47baa5a77d05365cf4598d55c Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 19 Mar 2023 12:56:52 +0000
+Subject: [PATCH 1/2] dt-bindings: arm: mediatek: sgmiisys: Convert to DT
+ schema
+
+Convert mediatek,sgmiiisys bindings to DT schema format.
+Add maintainer Matthias Brugger, no maintainers were listed in the
+original documentation.
+As this node is also referenced by the Ethernet controller and used
+as SGMII PCS add this fact to the description.
+Move the file to Documentation/devicetree/bindings/net/pcs/ which seems
+more appropriate given that the great majority of registers are related
+to SGMII PCS functionality and only one register represents clock bits.
+
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ .../arm/mediatek/mediatek,sgmiisys.txt        | 27 ----------
+ .../bindings/net/pcs/mediatek,sgmiisys.yaml   | 49 +++++++++++++++++++
+ 2 files changed, 49 insertions(+), 27 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
+ create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
+
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
++++ /dev/null
+@@ -1,27 +0,0 @@
+-MediaTek SGMIISYS controller
+-============================
+-
+-The MediaTek SGMIISYS controller provides various clocks to the system.
+-
+-Required Properties:
+-
+-- compatible: Should be:
+-      - "mediatek,mt7622-sgmiisys", "syscon"
+-      - "mediatek,mt7629-sgmiisys", "syscon"
+-      - "mediatek,mt7981-sgmiisys_0", "syscon"
+-      - "mediatek,mt7981-sgmiisys_1", "syscon"
+-      - "mediatek,mt7986-sgmiisys_0", "syscon"
+-      - "mediatek,mt7986-sgmiisys_1", "syscon"
+-- #clock-cells: Must be 1
+-
+-The SGMIISYS controller uses the common clk binding from
+-Documentation/devicetree/bindings/clock/clock-bindings.txt
+-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+-
+-Example:
+-
+-sgmiisys: sgmiisys@1b128000 {
+-      compatible = "mediatek,mt7622-sgmiisys", "syscon";
+-      reg = <0 0x1b128000 0 0x1000>;
+-      #clock-cells = <1>;
+-};
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
+@@ -0,0 +1,49 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/net/pcs/mediatek,sgmiisys.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: MediaTek SGMIISYS Controller
++
++maintainers:
++  - Matthias Brugger <matthias.bgg@gmail.com>
++
++description:
++  The MediaTek SGMIISYS controller provides a SGMII PCS and some clocks
++  to the ethernet subsystem to which it is attached.
++
++properties:
++  compatible:
++    items:
++      - enum:
++          - mediatek,mt7622-sgmiisys
++          - mediatek,mt7629-sgmiisys
++          - mediatek,mt7986-sgmiisys_0
++          - mediatek,mt7986-sgmiisys_1
++      - const: syscon
++
++  reg:
++    maxItems: 1
++
++  '#clock-cells':
++    const: 1
++
++required:
++  - compatible
++  - reg
++  - '#clock-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    soc {
++      #address-cells = <2>;
++      #size-cells = <2>;
++      sgmiisys: syscon@1b128000 {
++        compatible = "mediatek,mt7622-sgmiisys", "syscon";
++        reg = <0 0x1b128000 0 0x1000>;
++        #clock-cells = <1>;
++      };
++    };
diff --git a/target/linux/mediatek/patches-6.6/243-v6.4-dt-bindings-net-pcs-mediatek-sgmiisys-add-MT7981-SoC.patch b/target/linux/mediatek/patches-6.6/243-v6.4-dt-bindings-net-pcs-mediatek-sgmiisys-add-MT7981-SoC.patch
new file mode 100644 (file)
index 0000000..62a64b9
--- /dev/null
@@ -0,0 +1,37 @@
+From 4f7eb19c4f44078100659f6ba073b0cc7191bc91 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 19 Mar 2023 12:57:04 +0000
+Subject: [PATCH 2/2] dt-bindings: net: pcs: mediatek,sgmiisys: add MT7981 SoC
+
+Add mediatek,pnswap boolean property needed on many boards using the
+MediaTek MT7981 SoC.
+
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ .../devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml      | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
++++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
+@@ -19,6 +19,8 @@ properties:
+       - enum:
+           - mediatek,mt7622-sgmiisys
+           - mediatek,mt7629-sgmiisys
++          - mediatek,mt7981-sgmiisys_0
++          - mediatek,mt7981-sgmiisys_1
+           - mediatek,mt7986-sgmiisys_0
+           - mediatek,mt7986-sgmiisys_1
+       - const: syscon
+@@ -29,6 +31,10 @@ properties:
+   '#clock-cells':
+     const: 1
++  mediatek,pnswap:
++    description: Invert polarity of the SGMII data lanes
++    type: boolean
++
+ required:
+   - compatible
+   - reg
diff --git a/target/linux/mediatek/patches-6.6/244-v6.8-dt-bindings-arm-mediatek-move-ethsys-controller-conv.patch b/target/linux/mediatek/patches-6.6/244-v6.8-dt-bindings-arm-mediatek-move-ethsys-controller-conv.patch
new file mode 100644 (file)
index 0000000..946db82
--- /dev/null
@@ -0,0 +1,113 @@
+From 94b0f301f6ee92f79a2fe2c655dfdbdfe2aec536 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Sun, 19 Nov 2023 22:24:16 +0100
+Subject: [PATCH] dt-bindings: arm: mediatek: move ethsys controller & convert
+ to DT schema
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+DT schema helps validating DTS files. Binding was moved to clock/ as
+this hardware is a clock provider. Example required a small fix for
+"reg" value (1 address cell + 1 size cell).
+
+Signed-off-by: RafaÅ‚ MiÅ‚ecki <rafal@milecki.pl>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20231119212416.2682-1-zajec5@gmail.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ .../bindings/arm/mediatek/mediatek,ethsys.txt | 29 ----------
+ .../bindings/clock/mediatek,ethsys.yaml       | 54 +++++++++++++++++++
+ 2 files changed, 54 insertions(+), 29 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+ create mode 100644 Documentation/devicetree/bindings/clock/mediatek,ethsys.yaml
+
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
++++ /dev/null
+@@ -1,29 +0,0 @@
+-Mediatek ethsys controller
+-============================
+-
+-The Mediatek ethsys controller provides various clocks to the system.
+-
+-Required Properties:
+-
+-- compatible: Should be:
+-      - "mediatek,mt2701-ethsys", "syscon"
+-      - "mediatek,mt7622-ethsys", "syscon"
+-      - "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
+-      - "mediatek,mt7629-ethsys", "syscon"
+-      - "mediatek,mt7981-ethsys", "syscon"
+-      - "mediatek,mt7986-ethsys", "syscon"
+-- #clock-cells: Must be 1
+-- #reset-cells: Must be 1
+-
+-The ethsys controller uses the common clk binding from
+-Documentation/devicetree/bindings/clock/clock-bindings.txt
+-The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+-
+-Example:
+-
+-ethsys: clock-controller@1b000000 {
+-      compatible = "mediatek,mt2701-ethsys", "syscon";
+-      reg = <0 0x1b000000 0 0x1000>;
+-      #clock-cells = <1>;
+-      #reset-cells = <1>;
+-};
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/mediatek,ethsys.yaml
+@@ -0,0 +1,54 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/mediatek,ethsys.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Mediatek ethsys controller
++
++description:
++  The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++maintainers:
++  - James Liao <jamesjj.liao@mediatek.com>
++
++properties:
++  compatible:
++    oneOf:
++      - items:
++          - enum:
++              - mediatek,mt2701-ethsys
++              - mediatek,mt7622-ethsys
++              - mediatek,mt7629-ethsys
++              - mediatek,mt7981-ethsys
++              - mediatek,mt7986-ethsys
++          - const: syscon
++      - items:
++          - const: mediatek,mt7623-ethsys
++          - const: mediatek,mt2701-ethsys
++          - const: syscon
++
++  reg:
++    maxItems: 1
++
++  "#clock-cells":
++    const: 1
++
++  "#reset-cells":
++    const: 1
++
++required:
++  - reg
++  - "#clock-cells"
++  - "#reset-cells"
++
++additionalProperties: false
++
++examples:
++  - |
++    clock-controller@1b000000 {
++        compatible = "mediatek,mt2701-ethsys", "syscon";
++        reg = <0x1b000000 0x1000>;
++        #clock-cells = <1>;
++        #reset-cells = <1>;
++    };
diff --git a/target/linux/mediatek/patches-6.6/245-v6.8-dt-bindings-reset-mediatek-add-MT7988-ethwarp-reset-.patch b/target/linux/mediatek/patches-6.6/245-v6.8-dt-bindings-reset-mediatek-add-MT7988-ethwarp-reset-.patch
new file mode 100644 (file)
index 0000000..47f05e9
--- /dev/null
@@ -0,0 +1,35 @@
+From 5cfa3beb7761cb84be77225902e018d9d3f9b973 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 17 Dec 2023 21:49:45 +0000
+Subject: [PATCH 1/4] dt-bindings: reset: mediatek: add MT7988 ethwarp reset
+ IDs
+
+Add reset ID for ethwarp subsystem allowing to reset the built-in
+Ethernet switch of the MediaTek MT7988 SoC.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/0c14bbacf471683af67ffa7572bfa1d5c45a0b5d.1702849494.git.daniel@makrotopia.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ include/dt-bindings/reset/mediatek,mt7988-resets.h | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+ create mode 100644 include/dt-bindings/reset/mediatek,mt7988-resets.h
+
+--- /dev/null
++++ b/include/dt-bindings/reset/mediatek,mt7988-resets.h
+@@ -0,0 +1,13 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++/*
++ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
++ * Author: Daniel Golle <daniel@makrotopia.org>
++ */
++
++#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7988
++#define _DT_BINDINGS_RESET_CONTROLLER_MT7988
++
++/* ETHWARP resets */
++#define MT7988_ETHWARP_RST_SWITCH             0
++
++#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7988 */
diff --git a/target/linux/mediatek/patches-6.6/246-v6.8-dt-bindings-clock-mediatek-add-MT7988-clock-IDs.patch b/target/linux/mediatek/patches-6.6/246-v6.8-dt-bindings-clock-mediatek-add-MT7988-clock-IDs.patch
new file mode 100644 (file)
index 0000000..cf5cae6
--- /dev/null
@@ -0,0 +1,302 @@
+From 8187e001de156e99ef95366ffd10d627ed090826 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sun, 17 Dec 2023 21:49:33 +0000
+Subject: [PATCH] dt-bindings: clock: mediatek: add MT7988 clock IDs
+
+Add MT7988 clock dt-bindings for topckgen, apmixedsys, infracfg,
+ethernet and xfipll subsystem clocks.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/27f99db432e9ccc804cc5b6501d7d17d72cae879.1702849494.git.daniel@makrotopia.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ .../dt-bindings/clock/mediatek,mt7988-clk.h   | 280 ++++++++++++++++++
+ 1 file changed, 280 insertions(+)
+ create mode 100644 include/dt-bindings/clock/mediatek,mt7988-clk.h
+
+--- /dev/null
++++ b/include/dt-bindings/clock/mediatek,mt7988-clk.h
+@@ -0,0 +1,280 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
++ */
++
++#ifndef _DT_BINDINGS_CLK_MT7988_H
++#define _DT_BINDINGS_CLK_MT7988_H
++
++/* APMIXEDSYS */
++
++#define CLK_APMIXED_NETSYSPLL                 0
++#define CLK_APMIXED_MPLL                      1
++#define CLK_APMIXED_MMPLL                     2
++#define CLK_APMIXED_APLL2                     3
++#define CLK_APMIXED_NET1PLL                   4
++#define CLK_APMIXED_NET2PLL                   5
++#define CLK_APMIXED_WEDMCUPLL                 6
++#define CLK_APMIXED_SGMPLL                    7
++#define CLK_APMIXED_ARM_B                     8
++#define CLK_APMIXED_CCIPLL2_B                 9
++#define CLK_APMIXED_USXGMIIPLL                        10
++#define CLK_APMIXED_MSDCPLL                   11
++
++/* TOPCKGEN */
++
++#define CLK_TOP_XTAL                          0
++#define CLK_TOP_XTAL_D2                               1
++#define CLK_TOP_RTC_32K                               2
++#define CLK_TOP_RTC_32P7K                     3
++#define CLK_TOP_MPLL_D2                               4
++#define CLK_TOP_MPLL_D3_D2                    5
++#define CLK_TOP_MPLL_D4                               6
++#define CLK_TOP_MPLL_D8                               7
++#define CLK_TOP_MPLL_D8_D2                    8
++#define CLK_TOP_MMPLL_D2                      9
++#define CLK_TOP_MMPLL_D3_D5                   10
++#define CLK_TOP_MMPLL_D4                      11
++#define CLK_TOP_MMPLL_D6_D2                   12
++#define CLK_TOP_MMPLL_D8                      13
++#define CLK_TOP_APLL2_D4                      14
++#define CLK_TOP_NET1PLL_D4                    15
++#define CLK_TOP_NET1PLL_D5                    16
++#define CLK_TOP_NET1PLL_D5_D2                 17
++#define CLK_TOP_NET1PLL_D5_D4                 18
++#define CLK_TOP_NET1PLL_D8                    19
++#define CLK_TOP_NET1PLL_D8_D2                 20
++#define CLK_TOP_NET1PLL_D8_D4                 21
++#define CLK_TOP_NET1PLL_D8_D8                 22
++#define CLK_TOP_NET1PLL_D8_D16                        23
++#define CLK_TOP_NET2PLL_D2                    24
++#define CLK_TOP_NET2PLL_D4                    25
++#define CLK_TOP_NET2PLL_D4_D4                 26
++#define CLK_TOP_NET2PLL_D4_D8                 27
++#define CLK_TOP_NET2PLL_D6                    28
++#define CLK_TOP_NET2PLL_D8                    29
++#define CLK_TOP_NETSYS_SEL                    30
++#define CLK_TOP_NETSYS_500M_SEL                       31
++#define CLK_TOP_NETSYS_2X_SEL                 32
++#define CLK_TOP_NETSYS_GSW_SEL                        33
++#define CLK_TOP_ETH_GMII_SEL                  34
++#define CLK_TOP_NETSYS_MCU_SEL                        35
++#define CLK_TOP_NETSYS_PAO_2X_SEL             36
++#define CLK_TOP_EIP197_SEL                    37
++#define CLK_TOP_AXI_INFRA_SEL                 38
++#define CLK_TOP_UART_SEL                      39
++#define CLK_TOP_EMMC_250M_SEL                 40
++#define CLK_TOP_EMMC_400M_SEL                 41
++#define CLK_TOP_SPI_SEL                               42
++#define CLK_TOP_SPIM_MST_SEL                  43
++#define CLK_TOP_NFI1X_SEL                     44
++#define CLK_TOP_SPINFI_SEL                    45
++#define CLK_TOP_PWM_SEL                               46
++#define CLK_TOP_I2C_SEL                               47
++#define CLK_TOP_PCIE_MBIST_250M_SEL           48
++#define CLK_TOP_PEXTP_TL_SEL                  49
++#define CLK_TOP_PEXTP_TL_P1_SEL                       50
++#define CLK_TOP_PEXTP_TL_P2_SEL                       51
++#define CLK_TOP_PEXTP_TL_P3_SEL                       52
++#define CLK_TOP_USB_SYS_SEL                   53
++#define CLK_TOP_USB_SYS_P1_SEL                        54
++#define CLK_TOP_USB_XHCI_SEL                  55
++#define CLK_TOP_USB_XHCI_P1_SEL                       56
++#define CLK_TOP_USB_FRMCNT_SEL                        57
++#define CLK_TOP_USB_FRMCNT_P1_SEL             58
++#define CLK_TOP_AUD_SEL                               59
++#define CLK_TOP_A1SYS_SEL                     60
++#define CLK_TOP_AUD_L_SEL                     61
++#define CLK_TOP_A_TUNER_SEL                   62
++#define CLK_TOP_SSPXTP_SEL                    63
++#define CLK_TOP_USB_PHY_SEL                   64
++#define CLK_TOP_USXGMII_SBUS_0_SEL            65
++#define CLK_TOP_USXGMII_SBUS_1_SEL            66
++#define CLK_TOP_SGM_0_SEL                     67
++#define CLK_TOP_SGM_SBUS_0_SEL                        68
++#define CLK_TOP_SGM_1_SEL                     69
++#define CLK_TOP_SGM_SBUS_1_SEL                        70
++#define CLK_TOP_XFI_PHY_0_XTAL_SEL            71
++#define CLK_TOP_XFI_PHY_1_XTAL_SEL            72
++#define CLK_TOP_SYSAXI_SEL                    73
++#define CLK_TOP_SYSAPB_SEL                    74
++#define CLK_TOP_ETH_REFCK_50M_SEL             75
++#define CLK_TOP_ETH_SYS_200M_SEL              76
++#define CLK_TOP_ETH_SYS_SEL                   77
++#define CLK_TOP_ETH_XGMII_SEL                 78
++#define CLK_TOP_BUS_TOPS_SEL                  79
++#define CLK_TOP_NPU_TOPS_SEL                  80
++#define CLK_TOP_DRAMC_SEL                     81
++#define CLK_TOP_DRAMC_MD32_SEL                        82
++#define CLK_TOP_INFRA_F26M_SEL                        83
++#define CLK_TOP_PEXTP_P0_SEL                  84
++#define CLK_TOP_PEXTP_P1_SEL                  85
++#define CLK_TOP_PEXTP_P2_SEL                  86
++#define CLK_TOP_PEXTP_P3_SEL                  87
++#define CLK_TOP_DA_XTP_GLB_P0_SEL             88
++#define CLK_TOP_DA_XTP_GLB_P1_SEL             89
++#define CLK_TOP_DA_XTP_GLB_P2_SEL             90
++#define CLK_TOP_DA_XTP_GLB_P3_SEL             91
++#define CLK_TOP_CKM_SEL                               92
++#define CLK_TOP_DA_SEL                                93
++#define CLK_TOP_PEXTP_SEL                     94
++#define CLK_TOP_TOPS_P2_26M_SEL                       95
++#define CLK_TOP_MCUSYS_BACKUP_625M_SEL                96
++#define CLK_TOP_NETSYS_SYNC_250M_SEL          97
++#define CLK_TOP_MACSEC_SEL                    98
++#define CLK_TOP_NETSYS_TOPS_400M_SEL          99
++#define CLK_TOP_NETSYS_PPEFB_250M_SEL         100
++#define CLK_TOP_NETSYS_WARP_SEL                       101
++#define CLK_TOP_ETH_MII_SEL                   102
++#define CLK_TOP_NPU_SEL                               103
++#define CLK_TOP_AUD_I2S_M                     104
++
++/* MCUSYS */
++
++#define CLK_MCU_BUS_DIV_SEL                   0
++#define CLK_MCU_ARM_DIV_SEL                   1
++
++/* INFRACFG_AO */
++
++#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_SEL                        5
++#define CLK_INFRA_PWM_SEL                     6
++#define CLK_INFRA_PWM_CK1_SEL                 7
++#define CLK_INFRA_PWM_CK2_SEL                 8
++#define CLK_INFRA_PWM_CK3_SEL                 9
++#define CLK_INFRA_PWM_CK4_SEL                 10
++#define CLK_INFRA_PWM_CK5_SEL                 11
++#define CLK_INFRA_PWM_CK6_SEL                 12
++#define CLK_INFRA_PWM_CK7_SEL                 13
++#define CLK_INFRA_PWM_CK8_SEL                 14
++#define CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL      15
++#define CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL      16
++#define CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL      17
++#define CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL      18
++
++/* INFRACFG */
++
++#define CLK_INFRA_PCIE_PERI_26M_CK_P0         19
++#define CLK_INFRA_PCIE_PERI_26M_CK_P1         20
++#define CLK_INFRA_PCIE_PERI_26M_CK_P2         21
++#define CLK_INFRA_PCIE_PERI_26M_CK_P3         22
++#define CLK_INFRA_66M_GPT_BCK                 23
++#define CLK_INFRA_66M_PWM_HCK                 24
++#define CLK_INFRA_66M_PWM_BCK                 25
++#define CLK_INFRA_66M_PWM_CK1                 26
++#define CLK_INFRA_66M_PWM_CK2                 27
++#define CLK_INFRA_66M_PWM_CK3                 28
++#define CLK_INFRA_66M_PWM_CK4                 29
++#define CLK_INFRA_66M_PWM_CK5                 30
++#define CLK_INFRA_66M_PWM_CK6                 31
++#define CLK_INFRA_66M_PWM_CK7                 32
++#define CLK_INFRA_66M_PWM_CK8                 33
++#define CLK_INFRA_133M_CQDMA_BCK              34
++#define CLK_INFRA_66M_AUD_SLV_BCK             35
++#define CLK_INFRA_AUD_26M                     36
++#define CLK_INFRA_AUD_L                               37
++#define CLK_INFRA_AUD_AUD                     38
++#define CLK_INFRA_AUD_EG2                     39
++#define CLK_INFRA_DRAMC_F26M                  40
++#define CLK_INFRA_133M_DBG_ACKM                       41
++#define CLK_INFRA_66M_AP_DMA_BCK              42
++#define CLK_INFRA_66M_SEJ_BCK                 43
++#define CLK_INFRA_PRE_CK_SEJ_F13M             44
++#define CLK_INFRA_26M_THERM_SYSTEM            45
++#define CLK_INFRA_I2C_BCK                     46
++#define CLK_INFRA_52M_UART0_CK                        47
++#define CLK_INFRA_52M_UART1_CK                        48
++#define CLK_INFRA_52M_UART2_CK                        49
++#define CLK_INFRA_NFI                         50
++#define CLK_INFRA_SPINFI                      51
++#define CLK_INFRA_66M_NFI_HCK                 52
++#define CLK_INFRA_104M_SPI0                   53
++#define CLK_INFRA_104M_SPI1                   54
++#define CLK_INFRA_104M_SPI2_BCK                       55
++#define CLK_INFRA_66M_SPI0_HCK                        56
++#define CLK_INFRA_66M_SPI1_HCK                        57
++#define CLK_INFRA_66M_SPI2_HCK                        58
++#define CLK_INFRA_66M_FLASHIF_AXI             59
++#define CLK_INFRA_RTC                         60
++#define CLK_INFRA_26M_ADC_BCK                 61
++#define CLK_INFRA_RC_ADC                      62
++#define CLK_INFRA_MSDC400                     63
++#define CLK_INFRA_MSDC2_HCK                   64
++#define CLK_INFRA_133M_MSDC_0_HCK             65
++#define CLK_INFRA_66M_MSDC_0_HCK              66
++#define CLK_INFRA_133M_CPUM_BCK                       67
++#define CLK_INFRA_BIST2FPC                    68
++#define CLK_INFRA_I2C_X16W_MCK_CK_P1          69
++#define CLK_INFRA_I2C_X16W_PCK_CK_P1          70
++#define CLK_INFRA_133M_USB_HCK                        71
++#define CLK_INFRA_133M_USB_HCK_CK_P1          72
++#define CLK_INFRA_66M_USB_HCK                 73
++#define CLK_INFRA_66M_USB_HCK_CK_P1           74
++#define CLK_INFRA_USB_SYS                     75
++#define CLK_INFRA_USB_SYS_CK_P1                       76
++#define CLK_INFRA_USB_REF                     77
++#define CLK_INFRA_USB_CK_P1                   78
++#define CLK_INFRA_USB_FRMCNT                  79
++#define CLK_INFRA_USB_FRMCNT_CK_P1            80
++#define CLK_INFRA_USB_PIPE                    81
++#define CLK_INFRA_USB_PIPE_CK_P1              82
++#define CLK_INFRA_USB_UTMI                    83
++#define CLK_INFRA_USB_UTMI_CK_P1              84
++#define CLK_INFRA_USB_XHCI                    85
++#define CLK_INFRA_USB_XHCI_CK_P1              86
++#define CLK_INFRA_PCIE_GFMUX_TL_P0            87
++#define CLK_INFRA_PCIE_GFMUX_TL_P1            88
++#define CLK_INFRA_PCIE_GFMUX_TL_P2            89
++#define CLK_INFRA_PCIE_GFMUX_TL_P3            90
++#define CLK_INFRA_PCIE_PIPE_P0                        91
++#define CLK_INFRA_PCIE_PIPE_P1                        92
++#define CLK_INFRA_PCIE_PIPE_P2                        93
++#define CLK_INFRA_PCIE_PIPE_P3                        94
++#define CLK_INFRA_133M_PCIE_CK_P0             95
++#define CLK_INFRA_133M_PCIE_CK_P1             96
++#define CLK_INFRA_133M_PCIE_CK_P2             97
++#define CLK_INFRA_133M_PCIE_CK_P3             98
++
++/* ETHDMA */
++
++#define CLK_ETHDMA_XGP1_EN                    0
++#define CLK_ETHDMA_XGP2_EN                    1
++#define CLK_ETHDMA_XGP3_EN                    2
++#define CLK_ETHDMA_FE_EN                      3
++#define CLK_ETHDMA_GP2_EN                     4
++#define CLK_ETHDMA_GP1_EN                     5
++#define CLK_ETHDMA_GP3_EN                     6
++#define CLK_ETHDMA_ESW_EN                     7
++#define CLK_ETHDMA_CRYPT0_EN                  8
++#define CLK_ETHDMA_NR_CLK                     9
++
++/* 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
++
++/* ETHWARP */
++
++#define CLK_ETHWARP_WOCPU2_EN                 0
++#define CLK_ETHWARP_WOCPU1_EN                 1
++#define CLK_ETHWARP_WOCPU0_EN                 2
++#define CLK_ETHWARP_NR_CLK                    3
++
++/* XFIPLL */
++#define CLK_XFIPLL_PLL                                0
++#define CLK_XFIPLL_PLL_EN                     1
++
++#endif /* _DT_BINDINGS_CLK_MT7988_H */
diff --git a/target/linux/mediatek/patches-6.6/247-v6.8-dt-bindings-clock-mediatek-add-clock-controllers-of-.patch b/target/linux/mediatek/patches-6.6/247-v6.8-dt-bindings-clock-mediatek-add-clock-controllers-of-.patch
new file mode 100644 (file)
index 0000000..79088b4
--- /dev/null
@@ -0,0 +1,260 @@
+From afd36e9d91b0a840983b829a9e95407d8151f7e7 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 17 Dec 2023 21:49:55 +0000
+Subject: [PATCH 2/4] dt-bindings: clock: mediatek: add clock controllers of
+ MT7988
+
+Add various clock controllers found in the MT7988 SoC to existing
+bindings (if applicable) and add files for the new ethwarp, mcusys
+and xfi-pll clock controllers not previously present in any SoC.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/07e76a544ce4392bcb88e34d5480e99bb7994618.1702849494.git.daniel@makrotopia.org
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ .../arm/mediatek/mediatek,infracfg.yaml       |  1 +
+ .../bindings/clock/mediatek,apmixedsys.yaml   |  1 +
+ .../bindings/clock/mediatek,ethsys.yaml       |  1 +
+ .../clock/mediatek,mt7988-ethwarp.yaml        | 52 +++++++++++++++
+ .../clock/mediatek,mt7988-xfi-pll.yaml        | 48 ++++++++++++++
+ .../bindings/clock/mediatek,topckgen.yaml     |  2 +
+ .../bindings/net/pcs/mediatek,sgmiisys.yaml   | 65 ++++++++++++++++---
+ 7 files changed, 161 insertions(+), 9 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7988-ethwarp.yaml
+ create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mt7988-xfi-pll.yaml
+
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.yaml
+@@ -30,6 +30,7 @@ properties:
+               - mediatek,mt7629-infracfg
+               - mediatek,mt7981-infracfg
+               - mediatek,mt7986-infracfg
++              - mediatek,mt7988-infracfg
+               - mediatek,mt8135-infracfg
+               - mediatek,mt8167-infracfg
+               - mediatek,mt8173-infracfg
+--- a/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
++++ b/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml
+@@ -22,6 +22,7 @@ properties:
+           - mediatek,mt7622-apmixedsys
+           - mediatek,mt7981-apmixedsys
+           - mediatek,mt7986-apmixedsys
++          - mediatek,mt7988-apmixedsys
+           - mediatek,mt8135-apmixedsys
+           - mediatek,mt8173-apmixedsys
+           - mediatek,mt8516-apmixedsys
+--- a/Documentation/devicetree/bindings/clock/mediatek,ethsys.yaml
++++ b/Documentation/devicetree/bindings/clock/mediatek,ethsys.yaml
+@@ -22,6 +22,7 @@ properties:
+               - mediatek,mt7629-ethsys
+               - mediatek,mt7981-ethsys
+               - mediatek,mt7986-ethsys
++              - mediatek,mt7988-ethsys
+           - const: syscon
+       - items:
+           - const: mediatek,mt7623-ethsys
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/mediatek,mt7988-ethwarp.yaml
+@@ -0,0 +1,52 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/mediatek,mt7988-ethwarp.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: MediaTek MT7988 ethwarp Controller
++
++maintainers:
++  - Daniel Golle <daniel@makrotopia.org>
++
++description:
++  The Mediatek MT7988 ethwarp controller provides clocks and resets for the
++  Ethernet related subsystems found the MT7988 SoC.
++  The clock values can be found in <dt-bindings/clock/mt*-clk.h>.
++
++properties:
++  compatible:
++    items:
++      - const: mediatek,mt7988-ethwarp
++
++  reg:
++    maxItems: 1
++
++  '#clock-cells':
++    const: 1
++
++  '#reset-cells':
++    const: 1
++
++required:
++  - compatible
++  - reg
++  - '#clock-cells'
++  - '#reset-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    #include <dt-bindings/reset/ti-syscon.h>
++    soc {
++        #address-cells = <2>;
++        #size-cells = <2>;
++
++        clock-controller@15031000 {
++            compatible = "mediatek,mt7988-ethwarp";
++            reg = <0 0x15031000 0 0x1000>;
++            #clock-cells = <1>;
++            #reset-cells = <1>;
++        };
++    };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/clock/mediatek,mt7988-xfi-pll.yaml
+@@ -0,0 +1,48 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/clock/mediatek,mt7988-xfi-pll.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: MediaTek MT7988 XFI PLL Clock Controller
++
++maintainers:
++  - Daniel Golle <daniel@makrotopia.org>
++
++description:
++  The MediaTek XFI PLL controller provides the 156.25MHz clock for the
++  Ethernet SerDes PHY from the 40MHz top_xtal clock.
++
++properties:
++  compatible:
++    const: mediatek,mt7988-xfi-pll
++
++  reg:
++    maxItems: 1
++
++  resets:
++    maxItems: 1
++
++  '#clock-cells':
++    const: 1
++
++required:
++  - compatible
++  - reg
++  - resets
++  - '#clock-cells'
++
++additionalProperties: false
++
++examples:
++  - |
++    soc {
++        #address-cells = <2>;
++        #size-cells = <2>;
++        clock-controller@11f40000 {
++            compatible = "mediatek,mt7988-xfi-pll";
++            reg = <0 0x11f40000 0 0x1000>;
++            resets = <&watchdog 16>;
++            #clock-cells = <1>;
++        };
++    };
+--- a/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
++++ b/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml
+@@ -37,6 +37,8 @@ properties:
+               - mediatek,mt7629-topckgen
+               - mediatek,mt7981-topckgen
+               - mediatek,mt7986-topckgen
++              - mediatek,mt7988-mcusys
++              - mediatek,mt7988-topckgen
+               - mediatek,mt8167-topckgen
+               - mediatek,mt8183-topckgen
+           - const: syscon
+--- a/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
++++ b/Documentation/devicetree/bindings/net/pcs/mediatek,sgmiisys.yaml
+@@ -15,15 +15,22 @@ description:
+ properties:
+   compatible:
+-    items:
+-      - enum:
+-          - mediatek,mt7622-sgmiisys
+-          - mediatek,mt7629-sgmiisys
+-          - mediatek,mt7981-sgmiisys_0
+-          - mediatek,mt7981-sgmiisys_1
+-          - mediatek,mt7986-sgmiisys_0
+-          - mediatek,mt7986-sgmiisys_1
+-      - const: syscon
++    oneOf:
++      - items:
++          - enum:
++              - mediatek,mt7622-sgmiisys
++              - mediatek,mt7629-sgmiisys
++              - mediatek,mt7981-sgmiisys_0
++              - mediatek,mt7981-sgmiisys_1
++              - mediatek,mt7986-sgmiisys_0
++              - mediatek,mt7986-sgmiisys_1
++          - const: syscon
++      - items:
++          - enum:
++              - mediatek,mt7988-sgmiisys0
++              - mediatek,mt7988-sgmiisys1
++          - const: simple-mfd
++          - const: syscon
+   reg:
+     maxItems: 1
+@@ -35,11 +42,51 @@ properties:
+     description: Invert polarity of the SGMII data lanes
+     type: boolean
++  pcs:
++    type: object
++    description: MediaTek LynxI HSGMII PCS
++    properties:
++      compatible:
++        const: mediatek,mt7988-sgmii
++
++      clocks:
++        maxItems: 3
++
++      clock-names:
++        items:
++          - const: sgmii_sel
++          - const: sgmii_tx
++          - const: sgmii_rx
++
++    required:
++      - compatible
++      - clocks
++      - clock-names
++
++    additionalProperties: false
++
+ required:
+   - compatible
+   - reg
+   - '#clock-cells'
++allOf:
++  - if:
++      properties:
++        compatible:
++          contains:
++            enum:
++              - mediatek,mt7988-sgmiisys0
++              - mediatek,mt7988-sgmiisys1
++
++    then:
++      required:
++        - pcs
++
++    else:
++      properties:
++        pcs: false
++
+ additionalProperties: false
+ examples:
diff --git a/target/linux/mediatek/patches-6.6/248-v6.8-clk-mediatek-add-pcw_chg_bit-control-for-PLLs-of-MT7.patch b/target/linux/mediatek/patches-6.6/248-v6.8-clk-mediatek-add-pcw_chg_bit-control-for-PLLs-of-MT7.patch
new file mode 100644 (file)
index 0000000..ca37fc7
--- /dev/null
@@ -0,0 +1,50 @@
+From d9bf944beaaad1890ad3fcb755c61e1c7e4c5630 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sun, 17 Dec 2023 21:50:07 +0000
+Subject: [PATCH 3/4] clk: mediatek: add pcw_chg_bit control for PLLs of MT7988
+
+Introduce pcw_chg_bit member to struct mtk_pll_data and use it instead
+of the previously hardcoded PCW_CHG_MASK macro if set.
+This will needed for clocks on the MT7988 SoC.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/3b9c65ddb08c8bedf790aacf29871af026b6f0b7.1702849494.git.daniel@makrotopia.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/clk-pll.c | 5 +++--
+ drivers/clk/mediatek/clk-pll.h | 1 +
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-pll.c
++++ b/drivers/clk/mediatek/clk-pll.c
+@@ -23,7 +23,7 @@
+ #define CON0_BASE_EN          BIT(0)
+ #define CON0_PWR_ON           BIT(0)
+ #define CON0_ISO_EN           BIT(1)
+-#define PCW_CHG_MASK          BIT(31)
++#define PCW_CHG_BIT           31
+ #define AUDPLL_TUNER_EN               BIT(31)
+@@ -141,7 +141,8 @@ static void mtk_pll_set_rate_regs(struct
+                       pll->data->pcw_shift);
+       val |= pcw << pll->data->pcw_shift;
+       writel(val, pll->pcw_addr);
+-      chg = readl(pll->pcw_chg_addr) | PCW_CHG_MASK;
++      chg = readl(pll->pcw_chg_addr) |
++            BIT(pll->data->pcw_chg_bit ? : PCW_CHG_BIT);
+       writel(chg, pll->pcw_chg_addr);
+       if (pll->tuner_addr)
+               writel(val + 1, pll->tuner_addr);
+--- a/drivers/clk/mediatek/clk-pll.h
++++ b/drivers/clk/mediatek/clk-pll.h
+@@ -46,6 +46,7 @@ struct mtk_pll_data {
+       const char *parent_name;
+       u32 en_reg;
+       u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
++      u8 pcw_chg_bit;
+ };
+ int mtk_clk_register_plls(struct device_node *node,
diff --git a/target/linux/mediatek/patches-6.6/249-v6.8-clk-mediatek-add-drivers-for-MT7988-SoC.patch b/target/linux/mediatek/patches-6.6/249-v6.8-clk-mediatek-add-drivers-for-MT7988-SoC.patch
new file mode 100644 (file)
index 0000000..61664b9
--- /dev/null
@@ -0,0 +1,1026 @@
+From 4b4719437d85f0173d344f2c76fa1a5b7f7d184b Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sun, 17 Dec 2023 21:50:15 +0000
+Subject: [PATCH 4/4] clk: mediatek: add drivers for MT7988 SoC
+
+Add APMIXED, ETH, INFRACFG and TOPCKGEN clock drivers which are
+typical MediaTek designs.
+
+Also add driver for XFIPLL clock generating the 156.25MHz clock for
+the XFI SerDes. It needs an undocumented software workaround and has
+an unknown internal design.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/c7574d808e2da1a530182f0fd790c1337c336e1b.1702849494.git.daniel@makrotopia.org
+[sboyd@kernel.org: Add module license to infracfg file]
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+---
+ drivers/clk/mediatek/Kconfig               |   9 +
+ drivers/clk/mediatek/Makefile              |   5 +
+ drivers/clk/mediatek/clk-mt7988-apmixed.c  | 114 ++++++++
+ drivers/clk/mediatek/clk-mt7988-eth.c      | 150 ++++++++++
+ drivers/clk/mediatek/clk-mt7988-infracfg.c | 275 +++++++++++++++++
+ drivers/clk/mediatek/clk-mt7988-topckgen.c | 325 +++++++++++++++++++++
+ drivers/clk/mediatek/clk-mt7988-xfipll.c   |  82 ++++++
+ 7 files changed, 960 insertions(+)
+ create mode 100644 drivers/clk/mediatek/clk-mt7988-apmixed.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7988-eth.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7988-infracfg.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7988-topckgen.c
+ create mode 100644 drivers/clk/mediatek/clk-mt7988-xfipll.c
+
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -415,6 +415,15 @@ config COMMON_CLK_MT7986_ETHSYS
+         This driver adds support for clocks for Ethernet and SGMII
+         required on MediaTek MT7986 SoC.
++config COMMON_CLK_MT7988
++      tristate "Clock driver for MediaTek MT7988"
++      depends on ARCH_MEDIATEK || COMPILE_TEST
++      select COMMON_CLK_MEDIATEK
++      default ARCH_MEDIATEK
++      help
++        This driver supports MediaTek MT7988 basic clocks and clocks
++        required for various periperals found on this SoC.
++
+ config COMMON_CLK_MT8135
+       bool "Clock driver for MediaTek MT8135"
+       depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -60,6 +60,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_MT7988) += clk-mt7988-apmixed.o
++obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-topckgen.o
++obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-infracfg.o
++obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-eth.o
++obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-xfipll.o
+ obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
+ obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
+ obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7988-apmixed.c
+@@ -0,0 +1,114 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Xiufeng Li <Xiufeng.Li@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,mt7988-clk.h>
++
++#define MT7988_PLL_FMAX (2500UL * MHZ)
++#define MT7988_PCW_CHG_BIT 2
++
++#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)                                                                       \
++      {                                                                                       \
++              .id = _id,                                                                      \
++              .name = _name,                                                                  \
++              .reg = _reg,                                                                    \
++              .pwr_reg = _pwr_reg,                                                            \
++              .en_mask = _en_mask,                                                            \
++              .flags = _flags,                                                                \
++              .rst_bar_mask = BIT(_rst_bar_mask),                                             \
++              .fmax = MT7988_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 = MT7988_PCW_CHG_BIT,                                              \
++              .parent_name = "clkxtal",                                                       \
++      }
++
++static const struct mtk_pll_data plls[] = {
++      PLL(CLK_APMIXED_NETSYSPLL, "netsyspll", 0x0104, 0x0110, 0x00000001, 0, 0, 32, 0x0104, 4, 0,
++          0, 0, 0x0108, 0, 0x0104),
++      PLL(CLK_APMIXED_MPLL, "mpll", 0x0114, 0x0120, 0xff000001, HAVE_RST_BAR, 23, 32, 0x0114, 4,
++          0, 0, 0, 0x0118, 0, 0x0114),
++      PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0124, 0x0130, 0xff000001, HAVE_RST_BAR, 23, 32, 0x0124, 4,
++          0, 0, 0, 0x0128, 0, 0x0124),
++      PLL(CLK_APMIXED_APLL2, "apll2", 0x0134, 0x0140, 0x00000001, 0, 0, 32, 0x0134, 4, 0x0704,
++          0x0700, 1, 0x0138, 0, 0x0134),
++      PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0144, 0x0150, 0xff000001, HAVE_RST_BAR, 23, 32,
++          0x0144, 4, 0, 0, 0, 0x0148, 0, 0x0144),
++      PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0154, 0x0160, 0xff000001, (HAVE_RST_BAR | PLL_AO), 23,
++          32, 0x0154, 4, 0, 0, 0, 0x0158, 0, 0x0154),
++      PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0164, 0x0170, 0x00000001, 0, 0, 32, 0x0164, 4, 0,
++          0, 0, 0x0168, 0, 0x0164),
++      PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0174, 0x0180, 0x00000001, 0, 0, 32, 0x0174, 4, 0, 0, 0,
++          0x0178, 0, 0x0174),
++      PLL(CLK_APMIXED_ARM_B, "arm_b", 0x0204, 0x0210, 0xff000001, (HAVE_RST_BAR | PLL_AO), 23, 32,
++          0x0204, 4, 0, 0, 0, 0x0208, 0, 0x0204),
++      PLL(CLK_APMIXED_CCIPLL2_B, "ccipll2_b", 0x0214, 0x0220, 0xff000001, HAVE_RST_BAR, 23, 32,
++          0x0214, 4, 0, 0, 0, 0x0218, 0, 0x0214),
++      PLL(CLK_APMIXED_USXGMIIPLL, "usxgmiipll", 0x0304, 0x0310, 0xff000001, HAVE_RST_BAR, 23, 32,
++          0x0304, 4, 0, 0, 0, 0x0308, 0, 0x0304),
++      PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0314, 0x0320, 0x00000001, 0, 0, 32, 0x0314, 4, 0, 0,
++          0, 0x0318, 0, 0x0314),
++};
++
++static const struct of_device_id of_match_clk_mt7988_apmixed[] = {
++      { .compatible = "mediatek,mt7988-apmixedsys" },
++      { /* sentinel */ }
++};
++
++static int clk_mt7988_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_mt7988_apmixed_drv = {
++      .probe = clk_mt7988_apmixed_probe,
++      .driver = {
++              .name = "clk-mt7988-apmixed",
++              .of_match_table = of_match_clk_mt7988_apmixed,
++      },
++};
++builtin_platform_driver(clk_mt7988_apmixed_drv);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7988-eth.c
+@@ -0,0 +1,150 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Xiufeng Li <Xiufeng.Li@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 "reset.h"
++#include <dt-bindings/clock/mediatek,mt7988-clk.h>
++#include <dt-bindings/reset/mediatek,mt7988-resets.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_XGP1_EN, "ethdma_xgp1_en", "top_xtal", 0),
++      GATE_ETHDMA(CLK_ETHDMA_XGP2_EN, "ethdma_xgp2_en", "top_xtal", 1),
++      GATE_ETHDMA(CLK_ETHDMA_XGP3_EN, "ethdma_xgp3_en", "top_xtal", 2),
++      GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en", "netsys_2x_sel", 6),
++      GATE_ETHDMA(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en", "top_xtal", 7),
++      GATE_ETHDMA(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en", "top_xtal", 8),
++      GATE_ETHDMA(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", "top_xtal", 10),
++      GATE_ETHDMA(CLK_ETHDMA_ESW_EN, "ethdma_esw_en", "netsys_gsw_sel", 16),
++      GATE_ETHDMA(CLK_ETHDMA_CRYPT0_EN, "ethdma_crypt0_en", "eip197_sel", 29),
++};
++
++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", "top_xtal", 2),
++      GATE_SGMII(CLK_SGM0_RX_EN, "sgm0_rx_en", "top_xtal", 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", "top_xtal", 2),
++      GATE_SGMII(CLK_SGM1_RX_EN, "sgm1_rx_en", "top_xtal", 3),
++};
++
++static const struct mtk_clk_desc sgmii1_desc = {
++      .clks = sgmii1_clks,
++      .num_clks = ARRAY_SIZE(sgmii1_clks),
++};
++
++static const struct mtk_gate_regs ethwarp_cg_regs = {
++      .set_ofs = 0x14,
++      .clr_ofs = 0x14,
++      .sta_ofs = 0x14,
++};
++
++#define GATE_ETHWARP(_id, _name, _parent, _shift)             \
++      {                                                       \
++              .id = _id,                                      \
++              .name = _name,                                  \
++              .parent_name = _parent,                         \
++              .regs = &ethwarp_cg_regs,                       \
++              .shift = _shift,                                \
++              .ops = &mtk_clk_gate_ops_no_setclr_inv,         \
++      }
++
++static const struct mtk_gate ethwarp_clks[] = {
++      GATE_ETHWARP(CLK_ETHWARP_WOCPU2_EN, "ethwarp_wocpu2_en", "netsys_mcu_sel", 13),
++      GATE_ETHWARP(CLK_ETHWARP_WOCPU1_EN, "ethwarp_wocpu1_en", "netsys_mcu_sel", 14),
++      GATE_ETHWARP(CLK_ETHWARP_WOCPU0_EN, "ethwarp_wocpu0_en", "netsys_mcu_sel", 15),
++};
++
++static u16 ethwarp_rst_ofs[] = { 0x8 };
++
++static u16 ethwarp_idx_map[] = {
++      [MT7988_ETHWARP_RST_SWITCH] = 9,
++};
++
++static const struct mtk_clk_rst_desc ethwarp_rst_desc = {
++      .version = MTK_RST_SIMPLE,
++      .rst_bank_ofs = ethwarp_rst_ofs,
++      .rst_bank_nr = ARRAY_SIZE(ethwarp_rst_ofs),
++      .rst_idx_map = ethwarp_idx_map,
++      .rst_idx_map_nr = ARRAY_SIZE(ethwarp_idx_map),
++};
++
++static const struct mtk_clk_desc ethwarp_desc = {
++      .clks = ethwarp_clks,
++      .num_clks = ARRAY_SIZE(ethwarp_clks),
++      .rst_desc = &ethwarp_rst_desc,
++};
++
++static const struct of_device_id of_match_clk_mt7988_eth[] = {
++      { .compatible = "mediatek,mt7988-ethsys", .data = &ethdma_desc },
++      { .compatible = "mediatek,mt7988-sgmiisys0", .data = &sgmii0_desc },
++      { .compatible = "mediatek,mt7988-sgmiisys1", .data = &sgmii1_desc },
++      { .compatible = "mediatek,mt7988-ethwarp", .data = &ethwarp_desc },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_eth);
++
++static struct platform_driver clk_mt7988_eth_drv = {
++      .driver = {
++              .name = "clk-mt7988-eth",
++              .of_match_table = of_match_clk_mt7988_eth,
++      },
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
++};
++module_platform_driver(clk_mt7988_eth_drv);
++
++MODULE_DESCRIPTION("MediaTek MT7988 Ethernet clocks driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
+@@ -0,0 +1,275 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Xiufeng Li <Xiufeng.Li@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,mt7988-clk.h>
++
++static DEFINE_SPINLOCK(mt7988_clk_lock);
++
++static const char *const infra_mux_uart0_parents[] __initconst = { "csw_infra_f26m_sel",
++                                                                 "uart_sel" };
++
++static const char *const infra_mux_uart1_parents[] __initconst = { "csw_infra_f26m_sel",
++                                                                 "uart_sel" };
++
++static const char *const infra_mux_uart2_parents[] __initconst = { "csw_infra_f26m_sel",
++                                                                 "uart_sel" };
++
++static const char *const infra_mux_spi0_parents[] __initconst = { "i2c_sel", "spi_sel" };
++
++static const char *const infra_mux_spi1_parents[] __initconst = { "i2c_sel", "spim_mst_sel" };
++
++static const char *const infra_pwm_bck_parents[] __initconst = { "top_rtc_32p7k",
++                                                               "csw_infra_f26m_sel", "sysaxi_sel",
++                                                               "pwm_sel" };
++
++static const char *const infra_pcie_gfmux_tl_ck_o_p0_parents[] __initconst = {
++      "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel", "pextp_tl_sel"
++};
++
++static const char *const infra_pcie_gfmux_tl_ck_o_p1_parents[] __initconst = {
++      "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel", "pextp_tl_p1_sel"
++};
++
++static const char *const infra_pcie_gfmux_tl_ck_o_p2_parents[] __initconst = {
++      "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel", "pextp_tl_p2_sel"
++};
++
++static const char *const infra_pcie_gfmux_tl_ck_o_p3_parents[] __initconst = {
++      "top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel", "pextp_tl_p3_sel"
++};
++
++static const 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_SEL, "infra_mux_spi2_sel", infra_mux_spi0_parents,
++                           0x0018, 0x0010, 0x0014, 6, 1, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_SEL, "infra_pwm_sel", infra_pwm_bck_parents, 0x0018,
++                           0x0010, 0x0014, 14, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK1_SEL, "infra_pwm_ck1_sel", infra_pwm_bck_parents,
++                           0x0018, 0x0010, 0x0014, 16, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK2_SEL, "infra_pwm_ck2_sel", infra_pwm_bck_parents,
++                           0x0018, 0x0010, 0x0014, 18, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK3_SEL, "infra_pwm_ck3_sel", infra_pwm_bck_parents,
++                           0x0018, 0x0010, 0x0014, 20, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK4_SEL, "infra_pwm_ck4_sel", infra_pwm_bck_parents,
++                           0x0018, 0x0010, 0x0014, 22, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK5_SEL, "infra_pwm_ck5_sel", infra_pwm_bck_parents,
++                           0x0018, 0x0010, 0x0014, 24, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK6_SEL, "infra_pwm_ck6_sel", infra_pwm_bck_parents,
++                           0x0018, 0x0010, 0x0014, 26, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK7_SEL, "infra_pwm_ck7_sel", infra_pwm_bck_parents,
++                           0x0018, 0x0010, 0x0014, 28, 2, -1, -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK8_SEL, "infra_pwm_ck8_sel", infra_pwm_bck_parents,
++                           0x0018, 0x0010, 0x0014, 30, 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_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_o_p1_sel",
++                           infra_pcie_gfmux_tl_ck_o_p1_parents, 0x0028, 0x0020, 0x0024, 2, 2, -1,
++                           -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL, "infra_pcie_gfmux_tl_o_p2_sel",
++                           infra_pcie_gfmux_tl_ck_o_p2_parents, 0x0028, 0x0020, 0x0024, 4, 2, -1,
++                           -1, -1),
++      MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL, "infra_pcie_gfmux_tl_o_p3_sel",
++                           infra_pcie_gfmux_tl_ck_o_p3_parents, 0x0028, 0x0020, 0x0024, 6, 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_FLAGS(_id, _name, _parent, _shift, _flags)                                 \
++      GATE_MTK_FLAGS(_id, _name, _parent, &infra0_cg_regs, _shift, &mtk_clk_gate_ops_setclr, \
++                     _flags)
++
++#define GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, _flags)                                 \
++      GATE_MTK_FLAGS(_id, _name, _parent, &infra1_cg_regs, _shift, &mtk_clk_gate_ops_setclr, \
++                     _flags)
++
++#define GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, _flags)                                 \
++      GATE_MTK_FLAGS(_id, _name, _parent, &infra2_cg_regs, _shift, &mtk_clk_gate_ops_setclr, \
++                     _flags)
++
++#define GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, _flags)                                 \
++      GATE_MTK_FLAGS(_id, _name, _parent, &infra3_cg_regs, _shift, &mtk_clk_gate_ops_setclr, \
++                     _flags)
++
++#define GATE_INFRA0(_id, _name, _parent, _shift) GATE_INFRA0_FLAGS(_id, _name, _parent, _shift, 0)
++
++#define GATE_INFRA1(_id, _name, _parent, _shift) GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, 0)
++
++#define GATE_INFRA2(_id, _name, _parent, _shift) GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, 0)
++
++#define GATE_INFRA3(_id, _name, _parent, _shift) GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, 0)
++
++static const struct mtk_gate infra_clks[] = {
++      /* 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),
++      GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P2, "infra_pcie_peri_ck_26m_ck_p2",
++                  "csw_infra_f26m_sel", 9),
++      GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P3, "infra_pcie_peri_ck_26m_ck_p3",
++                  "csw_infra_f26m_sel", 10),
++      /* 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_sel", 2),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_CK1, "infra_hf_66m_pwm_ck1", "infra_pwm_ck1_sel", 3),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_CK2, "infra_hf_66m_pwm_ck2", "infra_pwm_ck2_sel", 4),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_CK3, "infra_hf_66m_pwm_ck3", "infra_pwm_ck3_sel", 5),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_CK4, "infra_hf_66m_pwm_ck4", "infra_pwm_ck4_sel", 6),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_CK5, "infra_hf_66m_pwm_ck5", "infra_pwm_ck5_sel", 7),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_CK6, "infra_hf_66m_pwm_ck6", "infra_pwm_ck6_sel", 8),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_CK7, "infra_hf_66m_pwm_ck7", "infra_pwm_ck7_sel", 9),
++      GATE_INFRA1(CLK_INFRA_66M_PWM_CK8, "infra_hf_66m_pwm_ck8", "infra_pwm_ck8_sel", 10),
++      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_FLAGS(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "csw_infra_f26m_sel", 19,
++                        CLK_IS_CRITICAL),
++      /* JTAG */
++      GATE_INFRA1_FLAGS(CLK_INFRA_133M_DBG_ACKM, "infra_hf_133m_dbg_ackm", "sysaxi_sel", 20,
++                        CLK_IS_CRITICAL),
++      GATE_INFRA1(CLK_INFRA_66M_AP_DMA_BCK, "infra_66m_ap_dma_bck", "sysaxi_sel", 21),
++      GATE_INFRA1(CLK_INFRA_66M_SEJ_BCK, "infra_hf_66m_sej_bck", "sysaxi_sel", 29),
++      GATE_INFRA1(CLK_INFRA_PRE_CK_SEJ_F13M, "infra_pre_ck_sej_f13m", "csw_infra_f26m_sel", 30),
++      /* 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_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", "nfi1x_sel", 9),
++      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_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_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_INFRA2_FLAGS(CLK_INFRA_RTC, "infra_f_frtc", "top_rtc_32k", 19, CLK_IS_CRITICAL),
++      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", "nfi1x_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, "infra_usb_sys", "usb_sys_sel", 4),
++      GATE_INFRA3(CLK_INFRA_USB_SYS_CK_P1, "infra_usb_sys_ck_p1", "usb_sys_p1_sel", 5),
++      GATE_INFRA3(CLK_INFRA_USB_REF, "infra_usb_ref", "top_xtal", 6),
++      GATE_INFRA3(CLK_INFRA_USB_CK_P1, "infra_usb_ck_p1", "top_xtal", 7),
++      GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT, "infra_usb_frmcnt", "usb_frmcnt_sel", 8,
++                        CLK_IS_CRITICAL),
++      GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT_CK_P1, "infra_usb_frmcnt_ck_p1", "usb_frmcnt_p1_sel",
++                        9, CLK_IS_CRITICAL),
++      GATE_INFRA3(CLK_INFRA_USB_PIPE, "infra_usb_pipe", "sspxtp_sel", 10),
++      GATE_INFRA3(CLK_INFRA_USB_PIPE_CK_P1, "infra_usb_pipe_ck_p1", "usb_phy_sel", 11),
++      GATE_INFRA3(CLK_INFRA_USB_UTMI, "infra_usb_utmi", "top_xtal", 12),
++      GATE_INFRA3(CLK_INFRA_USB_UTMI_CK_P1, "infra_usb_utmi_ck_p1", "top_xtal", 13),
++      GATE_INFRA3(CLK_INFRA_USB_XHCI, "infra_usb_xhci", "usb_xhci_sel", 14),
++      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_o_p0_sel", 20),
++      GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P1, "infra_pcie_gfmux_tl_ck_p1",
++                  "infra_pcie_gfmux_tl_o_p1_sel", 21),
++      GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P2, "infra_pcie_gfmux_tl_ck_p2",
++                  "infra_pcie_gfmux_tl_o_p2_sel", 22),
++      GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P3, "infra_pcie_gfmux_tl_ck_p3",
++                  "infra_pcie_gfmux_tl_o_p3_sel", 23),
++      GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P0, "infra_pcie_pipe_ck_p0", "top_xtal", 24),
++      GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P1, "infra_pcie_pipe_ck_p1", "top_xtal", 25),
++      GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P2, "infra_pcie_pipe_ck_p2", "top_xtal", 26),
++      GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P3, "infra_pcie_pipe_ck_p3", "top_xtal", 27),
++      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),
++      GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P2, "infra_133m_pcie_ck_p2", "sysaxi_sel", 30),
++      GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P3, "infra_133m_pcie_ck_p3", "sysaxi_sel", 31),
++};
++
++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 = &mt7988_clk_lock,
++};
++
++static const struct of_device_id of_match_clk_mt7988_infracfg[] = {
++      { .compatible = "mediatek,mt7988-infracfg", .data = &infra_desc },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_infracfg);
++
++static struct platform_driver clk_mt7988_infracfg_drv = {
++      .driver = {
++              .name = "clk-mt7988-infracfg",
++              .of_match_table = of_match_clk_mt7988_infracfg,
++      },
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
++};
++module_platform_driver(clk_mt7988_infracfg_drv);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7988-topckgen.c
+@@ -0,0 +1,325 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Sam Shih <sam.shih@mediatek.com>
++ * Author: Xiufeng Li <Xiufeng.Li@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,mt7988-clk.h>
++
++static DEFINE_SPINLOCK(mt7988_clk_lock);
++
++static const struct mtk_fixed_clk top_fixed_clks[] = {
++      FIXED_CLK(CLK_TOP_XTAL, "top_xtal", "clkxtal", 40000000),
++};
++
++static const struct mtk_fixed_factor top_divs[] = {
++      FACTOR(CLK_TOP_XTAL_D2, "top_xtal_d2", "top_xtal", 1, 2),
++      FACTOR(CLK_TOP_RTC_32K, "top_rtc_32k", "top_xtal", 1, 1250),
++      FACTOR(CLK_TOP_RTC_32P7K, "top_rtc_32p7k", "top_xtal", 1, 1220),
++      FACTOR(CLK_TOP_MPLL_D2, "mpll_d2", "mpll", 1, 2),
++      FACTOR(CLK_TOP_MPLL_D3_D2, "mpll_d3_d2", "mpll", 1, 2),
++      FACTOR(CLK_TOP_MPLL_D4, "mpll_d4", "mpll", 1, 4),
++      FACTOR(CLK_TOP_MPLL_D8, "mpll_d8", "mpll", 1, 8),
++      FACTOR(CLK_TOP_MPLL_D8_D2, "mpll_d8_d2", "mpll", 1, 16),
++      FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
++      FACTOR(CLK_TOP_MMPLL_D3_D5, "mmpll_d3_d5", "mmpll", 1, 15),
++      FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1, 4),
++      FACTOR(CLK_TOP_MMPLL_D6_D2, "mmpll_d6_d2", "mmpll", 1, 12),
++      FACTOR(CLK_TOP_MMPLL_D8, "mmpll_d8", "mmpll", 1, 8),
++      FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
++      FACTOR(CLK_TOP_NET1PLL_D4, "net1pll_d4", "net1pll", 1, 4),
++      FACTOR(CLK_TOP_NET1PLL_D5, "net1pll_d5", "net1pll", 1, 5),
++      FACTOR(CLK_TOP_NET1PLL_D5_D2, "net1pll_d5_d2", "net1pll", 1, 10),
++      FACTOR(CLK_TOP_NET1PLL_D5_D4, "net1pll_d5_d4", "net1pll", 1, 20),
++      FACTOR(CLK_TOP_NET1PLL_D8, "net1pll_d8", "net1pll", 1, 8),
++      FACTOR(CLK_TOP_NET1PLL_D8_D2, "net1pll_d8_d2", "net1pll", 1, 16),
++      FACTOR(CLK_TOP_NET1PLL_D8_D4, "net1pll_d8_d4", "net1pll", 1, 32),
++      FACTOR(CLK_TOP_NET1PLL_D8_D8, "net1pll_d8_d8", "net1pll", 1, 64),
++      FACTOR(CLK_TOP_NET1PLL_D8_D16, "net1pll_d8_d16", "net1pll", 1, 128),
++      FACTOR(CLK_TOP_NET2PLL_D2, "net2pll_d2", "net2pll", 1, 2),
++      FACTOR(CLK_TOP_NET2PLL_D4, "net2pll_d4", "net2pll", 1, 4),
++      FACTOR(CLK_TOP_NET2PLL_D4_D4, "net2pll_d4_d4", "net2pll", 1, 16),
++      FACTOR(CLK_TOP_NET2PLL_D4_D8, "net2pll_d4_d8", "net2pll", 1, 32),
++      FACTOR(CLK_TOP_NET2PLL_D6, "net2pll_d6", "net2pll", 1, 6),
++      FACTOR(CLK_TOP_NET2PLL_D8, "net2pll_d8", "net2pll", 1, 8),
++};
++
++static const char *const netsys_parents[] = { "top_xtal", "net2pll_d2", "mmpll_d2" };
++static const char *const netsys_500m_parents[] = { "top_xtal", "net1pll_d5", "net1pll_d5_d2" };
++static const char *const netsys_2x_parents[] = { "top_xtal", "net2pll", "mmpll" };
++static const char *const netsys_gsw_parents[] = { "top_xtal", "net1pll_d4", "net1pll_d5" };
++static const char *const eth_gmii_parents[] = { "top_xtal", "net1pll_d5_d4" };
++static const char *const netsys_mcu_parents[] = { "top_xtal", "net2pll",    "mmpll",
++                                                "net1pll_d4", "net1pll_d5", "mpll" };
++static const char *const eip197_parents[] = { "top_xtal", "netsyspll",        "net2pll",
++                                            "mmpll",    "net1pll_d4", "net1pll_d5" };
++static const char *const axi_infra_parents[] = { "top_xtal", "net1pll_d8_d2" };
++static const char *const uart_parents[] = { "top_xtal", "mpll_d8", "mpll_d8_d2" };
++static const char *const emmc_250m_parents[] = { "top_xtal", "net1pll_d5_d2", "mmpll_d4" };
++static const char *const emmc_400m_parents[] = { "top_xtal", "msdcpll",        "mmpll_d2",
++                                               "mpll_d2",  "mmpll_d4", "net1pll_d8_d2" };
++static const char *const spi_parents[] = { "top_xtal",            "mpll_d2",      "mmpll_d4",
++                                         "net1pll_d8_d2", "net2pll_d6",   "net1pll_d5_d4",
++                                         "mpll_d4",       "net1pll_d8_d4" };
++static const char *const nfi1x_parents[] = { "top_xtal", "mmpll_d4", "net1pll_d8_d2", "net2pll_d6",
++                                           "mpll_d4",  "mmpll_d8", "net1pll_d8_d4", "mpll_d8" };
++static const char *const spinfi_parents[] = { "top_xtal_d2", "top_xtal", "net1pll_d5_d4",
++                                            "mpll_d4",     "mmpll_d8", "net1pll_d8_d4",
++                                            "mmpll_d6_d2", "mpll_d8" };
++static const char *const pwm_parents[] = { "top_xtal", "net1pll_d8_d2", "net1pll_d5_d4",
++                                         "mpll_d4",  "mpll_d8_d2",    "top_rtc_32k" };
++static const char *const i2c_parents[] = { "top_xtal", "net1pll_d5_d4", "mpll_d4",
++                                         "net1pll_d8_d4" };
++static const char *const pcie_mbist_250m_parents[] = { "top_xtal", "net1pll_d5_d2" };
++static const char *const pextp_tl_ck_parents[] = { "top_xtal", "net2pll_d6", "mmpll_d8",
++                                                 "mpll_d8_d2", "top_rtc_32k" };
++static const char *const usb_frmcnt_parents[] = { "top_xtal", "mmpll_d3_d5" };
++static const char *const aud_parents[] = { "top_xtal", "apll2" };
++static const char *const a1sys_parents[] = { "top_xtal", "apll2_d4" };
++static const char *const aud_l_parents[] = { "top_xtal", "apll2", "mpll_d8_d2" };
++static const char *const sspxtp_parents[] = { "top_xtal_d2", "mpll_d8_d2" };
++static const char *const usxgmii_sbus_0_parents[] = { "top_xtal", "net1pll_d8_d4" };
++static const char *const sgm_0_parents[] = { "top_xtal", "sgmpll" };
++static const char *const sysapb_parents[] = { "top_xtal", "mpll_d3_d2" };
++static const char *const eth_refck_50m_parents[] = { "top_xtal", "net2pll_d4_d4" };
++static const char *const eth_sys_200m_parents[] = { "top_xtal", "net2pll_d4" };
++static const char *const eth_xgmii_parents[] = { "top_xtal_d2", "net1pll_d8_d8", "net1pll_d8_d16" };
++static const char *const bus_tops_parents[] = { "top_xtal", "net1pll_d5", "net2pll_d2" };
++static const char *const npu_tops_parents[] = { "top_xtal", "net2pll" };
++static const char *const dramc_md32_parents[] = { "top_xtal", "mpll_d2", "wedmcupll" };
++static const char *const da_xtp_glb_p0_parents[] = { "top_xtal", "net2pll_d8" };
++static const char *const mcusys_backup_625m_parents[] = { "top_xtal", "net1pll_d4" };
++static const char *const macsec_parents[] = { "top_xtal", "sgmpll", "net1pll_d8" };
++static const char *const netsys_tops_400m_parents[] = { "top_xtal", "net2pll_d2" };
++static const char *const eth_mii_parents[] = { "top_xtal_d2", "net2pll_d4_d8" };
++
++static const 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, 2, 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, 2, 23, 0x1C0, 2),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_GSW_SEL, "netsys_gsw_sel", netsys_gsw_parents, 0x000,
++                           0x004, 0x008, 24, 2, 31, 0x1C0, 3),
++      /* CLK_CFG_1 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_GMII_SEL, "eth_gmii_sel", eth_gmii_parents, 0x010, 0x014,
++                           0x018, 0, 1, 7, 0x1C0, 4),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents, 0x010,
++                           0x014, 0x018, 8, 3, 15, 0x1C0, 5),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_PAO_2X_SEL, "netsys_pao_2x_sel", netsys_mcu_parents,
++                           0x010, 0x014, 0x018, 16, 3, 23, 0x1C0, 6),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP197_SEL, "eip197_sel", eip197_parents, 0x010, 0x014, 0x018,
++                           24, 3, 31, 0x1c0, 7),
++      /* CLK_CFG_2 */
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_INFRA_SEL, "axi_infra_sel", axi_infra_parents, 0x020,
++                                 0x024, 0x028, 0, 1, 7, 0x1C0, 8, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x020, 0x024, 0x028, 8, 2,
++                           15, 0x1c0, 9),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel", emmc_250m_parents, 0x020,
++                           0x024, 0x028, 16, 2, 23, 0x1C0, 10),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents, 0x020,
++                           0x024, 0x028, 24, 3, 31, 0x1C0, 11),
++      /* CLK_CFG_3 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x030, 0x034, 0x038, 0, 3, 7,
++                           0x1c0, 12),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x030, 0x034, 0x038,
++                           8, 3, 15, 0x1c0, 13),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x030, 0x034, 0x038, 16,
++                           3, 23, 0x1c0, 14),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x030, 0x034, 0x038,
++                           24, 3, 31, 0x1c0, 15),
++      /* CLK_CFG_4 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x040, 0x044, 0x048, 0, 3, 7,
++                           0x1c0, 16),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x040, 0x044, 0x048, 8, 2, 15,
++                           0x1c0, 17),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PCIE_MBIST_250M_SEL, "pcie_mbist_250m_sel",
++                           pcie_mbist_250m_parents, 0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_sel", pextp_tl_ck_parents, 0x040,
++                           0x044, 0x048, 24, 3, 31, 0x1C0, 19),
++      /* CLK_CFG_5 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P1_SEL, "pextp_tl_p1_sel", pextp_tl_ck_parents, 0x050,
++                           0x054, 0x058, 0, 3, 7, 0x1C0, 20),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P2_SEL, "pextp_tl_p2_sel", pextp_tl_ck_parents, 0x050,
++                           0x054, 0x058, 8, 3, 15, 0x1C0, 21),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P3_SEL, "pextp_tl_p3_sel", pextp_tl_ck_parents, 0x050,
++                           0x054, 0x058, 16, 3, 23, 0x1C0, 22),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_SYS_SEL, "usb_sys_sel", eth_gmii_parents, 0x050, 0x054,
++                           0x058, 24, 1, 31, 0x1C0, 23),
++      /* CLK_CFG_6 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_SYS_P1_SEL, "usb_sys_p1_sel", eth_gmii_parents, 0x060,
++                           0x064, 0x068, 0, 1, 7, 0x1C0, 24),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_XHCI_SEL, "usb_xhci_sel", eth_gmii_parents, 0x060, 0x064,
++                           0x068, 8, 1, 15, 0x1C0, 25),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_XHCI_P1_SEL, "usb_xhci_p1_sel", eth_gmii_parents, 0x060,
++                           0x064, 0x068, 16, 1, 23, 0x1C0, 26),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel", usb_frmcnt_parents, 0x060,
++                           0x064, 0x068, 24, 1, 31, 0x1C0, 27),
++      /* CLK_CFG_7 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_P1_SEL, "usb_frmcnt_p1_sel", usb_frmcnt_parents,
++                           0x070, 0x074, 0x078, 0, 1, 7, 0x1C0, 28),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x070, 0x074, 0x078, 8, 1, 15,
++                           0x1c0, 29),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x070, 0x074, 0x078, 16,
++                           1, 23, 0x1c0, 30),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x070, 0x074, 0x078, 24,
++                           2, 31, 0x1c4, 0),
++      /* CLK_CFG_8 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel", a1sys_parents, 0x080, 0x084, 0x088,
++                           0, 1, 7, 0x1c4, 1),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SSPXTP_SEL, "sspxtp_sel", sspxtp_parents, 0x080, 0x084, 0x088,
++                           8, 1, 15, 0x1c4, 2),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_PHY_SEL, "usb_phy_sel", sspxtp_parents, 0x080, 0x084,
++                           0x088, 16, 1, 23, 0x1c4, 3),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USXGMII_SBUS_0_SEL, "usxgmii_sbus_0_sel",
++                           usxgmii_sbus_0_parents, 0x080, 0x084, 0x088, 24, 1, 31, 0x1C4, 4),
++      /* CLK_CFG_9 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_USXGMII_SBUS_1_SEL, "usxgmii_sbus_1_sel",
++                           usxgmii_sbus_0_parents, 0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_0_SEL, "sgm_0_sel", sgm_0_parents, 0x090, 0x094, 0x098, 8,
++                           1, 15, 0x1c4, 6),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_SBUS_0_SEL, "sgm_sbus_0_sel", usxgmii_sbus_0_parents,
++                                 0x090, 0x094, 0x098, 16, 1, 23, 0x1C4, 7, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_1_SEL, "sgm_1_sel", sgm_0_parents, 0x090, 0x094, 0x098, 24,
++                           1, 31, 0x1c4, 8),
++      /* CLK_CFG_10 */
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_SBUS_1_SEL, "sgm_sbus_1_sel", usxgmii_sbus_0_parents,
++                                 0x0a0, 0x0a4, 0x0a8, 0, 1, 7, 0x1C4, 9, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_XFI_PHY_0_XTAL_SEL, "xfi_phy_0_xtal_sel", sspxtp_parents,
++                           0x0a0, 0x0a4, 0x0a8, 8, 1, 15, 0x1C4, 10),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_XFI_PHY_1_XTAL_SEL, "xfi_phy_1_xtal_sel", sspxtp_parents,
++                           0x0a0, 0x0a4, 0x0a8, 16, 1, 23, 0x1C4, 11),
++      /* CLK_CFG_11 */
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", axi_infra_parents, 0x0a0,
++                                 0x0a4, 0x0a8, 24, 1, 31, 0x1C4, 12, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x0b0, 0x0b4,
++                                 0x0b8, 0, 1, 7, 0x1c4, 13, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_REFCK_50M_SEL, "eth_refck_50m_sel", eth_refck_50m_parents,
++                           0x0b0, 0x0b4, 0x0b8, 8, 1, 15, 0x1C4, 14),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SYS_200M_SEL, "eth_sys_200m_sel", eth_sys_200m_parents,
++                           0x0b0, 0x0b4, 0x0b8, 16, 1, 23, 0x1C4, 15),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SYS_SEL, "eth_sys_sel", pcie_mbist_250m_parents, 0x0b0,
++                           0x0b4, 0x0b8, 24, 1, 31, 0x1C4, 16),
++      /* CLK_CFG_12 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_XGMII_SEL, "eth_xgmii_sel", eth_xgmii_parents, 0x0c0,
++                           0x0c4, 0x0c8, 0, 2, 7, 0x1C4, 17),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_BUS_TOPS_SEL, "bus_tops_sel", bus_tops_parents, 0x0c0, 0x0c4,
++                           0x0c8, 8, 2, 15, 0x1C4, 18),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NPU_TOPS_SEL, "npu_tops_sel", npu_tops_parents, 0x0c0, 0x0c4,
++                           0x0c8, 16, 1, 23, 0x1C4, 19),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel", sspxtp_parents, 0x0c0, 0x0c4,
++                                 0x0c8, 24, 1, 31, 0x1C4, 20, CLK_IS_CRITICAL),
++      /* CLK_CFG_13 */
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents,
++                                 0x0d0, 0x0d4, 0x0d8, 0, 2, 7, 0x1C4, 21, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_INFRA_F26M_SEL, "csw_infra_f26m_sel", sspxtp_parents,
++                                 0x0d0, 0x0d4, 0x0d8, 8, 1, 15, 0x1C4, 22, CLK_IS_CRITICAL),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P0_SEL, "pextp_p0_sel", sspxtp_parents, 0x0d0, 0x0d4,
++                           0x0d8, 16, 1, 23, 0x1C4, 23),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P1_SEL, "pextp_p1_sel", sspxtp_parents, 0x0d0, 0x0d4,
++                           0x0d8, 24, 1, 31, 0x1C4, 24),
++      /* CLK_CFG_14 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P2_SEL, "pextp_p2_sel", sspxtp_parents, 0x0e0, 0x0e4,
++                           0x0e8, 0, 1, 7, 0x1C4, 25),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P3_SEL, "pextp_p3_sel", sspxtp_parents, 0x0e0, 0x0e4,
++                           0x0e8, 8, 1, 15, 0x1C4, 26),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P0_SEL, "da_xtp_glb_p0_sel", da_xtp_glb_p0_parents,
++                           0x0e0, 0x0e4, 0x0e8, 16, 1, 23, 0x1C4, 27),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P1_SEL, "da_xtp_glb_p1_sel", da_xtp_glb_p0_parents,
++                           0x0e0, 0x0e4, 0x0e8, 24, 1, 31, 0x1C4, 28),
++      /* CLK_CFG_15 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P2_SEL, "da_xtp_glb_p2_sel", da_xtp_glb_p0_parents,
++                           0x0f0, 0x0f4, 0x0f8, 0, 1, 7, 0x1C4, 29),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P3_SEL, "da_xtp_glb_p3_sel", da_xtp_glb_p0_parents,
++                           0x0f0, 0x0f4, 0x0f8, 8, 1, 15, 0x1C4, 30),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_CKM_SEL, "ckm_sel", sspxtp_parents, 0x0F0, 0x0f4, 0x0f8, 16, 1,
++                           23, 0x1c8, 0),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_SEL, "da_sel", sspxtp_parents, 0x0f0, 0x0f4, 0x0f8, 24, 1,
++                           31, 0x1C8, 1),
++      /* CLK_CFG_16 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_SEL, "pextp_sel", sspxtp_parents, 0x0100, 0x104, 0x108,
++                           0, 1, 7, 0x1c8, 2),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_TOPS_P2_26M_SEL, "tops_p2_26m_sel", sspxtp_parents, 0x0100,
++                           0x104, 0x108, 8, 1, 15, 0x1C8, 3),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_MCUSYS_BACKUP_625M_SEL, "mcusys_backup_625m_sel",
++                           mcusys_backup_625m_parents, 0x0100, 0x104, 0x108, 16, 1, 23, 0x1C8, 4),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SYNC_250M_SEL, "netsys_sync_250m_sel",
++                           pcie_mbist_250m_parents, 0x0100, 0x104, 0x108, 24, 1, 31, 0x1c8, 5),
++      /* CLK_CFG_17 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_MACSEC_SEL, "macsec_sel", macsec_parents, 0x0110, 0x114, 0x118,
++                           0, 2, 7, 0x1c8, 6),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_TOPS_400M_SEL, "netsys_tops_400m_sel",
++                           netsys_tops_400m_parents, 0x0110, 0x114, 0x118, 8, 1, 15, 0x1c8, 7),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_PPEFB_250M_SEL, "netsys_ppefb_250m_sel",
++                           pcie_mbist_250m_parents, 0x0110, 0x114, 0x118, 16, 1, 23, 0x1c8, 8),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_WARP_SEL, "netsys_warp_sel", netsys_parents, 0x0110,
++                           0x114, 0x118, 24, 2, 31, 0x1C8, 9),
++      /* CLK_CFG_18 */
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_MII_SEL, "eth_mii_sel", eth_mii_parents, 0x0120, 0x124,
++                           0x128, 0, 1, 7, 0x1c8, 10),
++      MUX_GATE_CLR_SET_UPD(CLK_TOP_NPU_SEL, "ck_npu_sel", netsys_2x_parents, 0x0120, 0x124, 0x128,
++                           8, 2, 15, 0x1c8, 11),
++};
++
++static const struct mtk_composite top_aud_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 = {
++      .fixed_clks = top_fixed_clks,
++      .num_fixed_clks = ARRAY_SIZE(top_fixed_clks),
++      .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_aud_divs,
++      .num_composite_clks = ARRAY_SIZE(top_aud_divs),
++      .clk_lock = &mt7988_clk_lock,
++};
++
++static const char *const mcu_bus_div_parents[] = { "top_xtal", "ccipll2_b", "net1pll_d4" };
++
++static const char *const mcu_arm_div_parents[] = { "top_xtal", "arm_b", "net1pll_d4" };
++
++static struct mtk_composite mcu_muxes[] = {
++      /* bus_pll_divider_cfg */
++      MUX_GATE_FLAGS(CLK_MCU_BUS_DIV_SEL, "mcu_bus_div_sel", mcu_bus_div_parents, 0x7C0, 9, 2, -1,
++                     CLK_IS_CRITICAL),
++      /* mp2_pll_divider_cfg */
++      MUX_GATE_FLAGS(CLK_MCU_ARM_DIV_SEL, "mcu_arm_div_sel", mcu_arm_div_parents, 0x7A8, 9, 2, -1,
++                     CLK_IS_CRITICAL),
++};
++
++static const struct mtk_clk_desc mcusys_desc = {
++      .composite_clks = mcu_muxes,
++      .num_composite_clks = ARRAY_SIZE(mcu_muxes),
++};
++
++static const struct of_device_id of_match_clk_mt7988_topckgen[] = {
++      { .compatible = "mediatek,mt7988-topckgen", .data = &topck_desc },
++      { .compatible = "mediatek,mt7988-mcusys", .data = &mcusys_desc },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_topckgen);
++
++static struct platform_driver clk_mt7988_topckgen_drv = {
++      .probe = mtk_clk_simple_probe,
++      .remove = mtk_clk_simple_remove,
++      .driver = {
++              .name = "clk-mt7988-topckgen",
++              .of_match_table = of_match_clk_mt7988_topckgen,
++      },
++};
++module_platform_driver(clk_mt7988_topckgen_drv);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt7988-xfipll.c
+@@ -0,0 +1,82 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
++ */
++
++#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,mt7988-clk.h>
++
++/* Register to control USXGMII XFI PLL analog */
++#define XFI_PLL_ANA_GLB8              0x108
++#define RG_XFI_PLL_ANA_SWWA           0x02283248
++
++static const struct mtk_gate_regs xfipll_cg_regs = {
++      .set_ofs = 0x8,
++      .clr_ofs = 0x8,
++      .sta_ofs = 0x8,
++};
++
++#define GATE_XFIPLL(_id, _name, _parent, _shift)              \
++      {                                                       \
++              .id = _id,                                      \
++              .name = _name,                                  \
++              .parent_name = _parent,                         \
++              .regs = &xfipll_cg_regs,                        \
++              .shift = _shift,                                \
++              .ops = &mtk_clk_gate_ops_no_setclr_inv,         \
++      }
++
++static const struct mtk_fixed_factor xfipll_divs[] = {
++      FACTOR(CLK_XFIPLL_PLL, "xfipll_pll", "top_xtal", 125, 32),
++};
++
++static const struct mtk_gate xfipll_clks[] = {
++      GATE_XFIPLL(CLK_XFIPLL_PLL_EN, "xfipll_pll_en", "xfipll_pll", 31),
++};
++
++static const struct mtk_clk_desc xfipll_desc = {
++      .clks = xfipll_clks,
++      .num_clks = ARRAY_SIZE(xfipll_clks),
++      .factor_clks = xfipll_divs,
++      .num_factor_clks = ARRAY_SIZE(xfipll_divs),
++};
++
++static int clk_mt7988_xfipll_probe(struct platform_device *pdev)
++{
++      struct device_node *node = pdev->dev.of_node;
++      void __iomem *base = of_iomap(node, 0);
++
++      if (!base)
++              return -ENOMEM;
++
++      /* Apply software workaround for USXGMII PLL TCL issue */
++      writel(RG_XFI_PLL_ANA_SWWA, base + XFI_PLL_ANA_GLB8);
++      iounmap(base);
++
++      return mtk_clk_simple_probe(pdev);
++};
++
++static const struct of_device_id of_match_clk_mt7988_xfipll[] = {
++      { .compatible = "mediatek,mt7988-xfi-pll", .data = &xfipll_desc },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_xfipll);
++
++static struct platform_driver clk_mt7988_xfipll_drv = {
++      .driver = {
++              .name = "clk-mt7988-xfipll",
++              .of_match_table = of_match_clk_mt7988_xfipll,
++      },
++      .probe = clk_mt7988_xfipll_probe,
++      .remove = mtk_clk_simple_remove,
++};
++module_platform_driver(clk_mt7988_xfipll_drv);
++
++MODULE_DESCRIPTION("MediaTek MT7988 XFI PLL clock driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/patches-6.6/250-clk-mediatek-add-infracfg-reset-controller-for-mt798.patch b/target/linux/mediatek/patches-6.6/250-clk-mediatek-add-infracfg-reset-controller-for-mt798.patch
new file mode 100644 (file)
index 0000000..cecf095
--- /dev/null
@@ -0,0 +1,57 @@
+From 26ced94177b150710d94cf365002a09cc48950e9 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Wed, 17 Jan 2024 19:41:11 +0100
+Subject: [PATCH] clk: mediatek: add infracfg reset controller for mt7988
+
+Infracfg can also operate as reset controller, add support for it.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ drivers/clk/mediatek/clk-mt7988-infracfg.c | 23 ++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+--- a/drivers/clk/mediatek/clk-mt7988-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
+@@ -14,6 +14,10 @@
+ #include "clk-gate.h"
+ #include "clk-mux.h"
+ #include <dt-bindings/clock/mediatek,mt7988-clk.h>
++#include <dt-bindings/reset/mediatek,mt7988-resets.h>
++
++#define       MT7988_INFRA_RST0_SET_OFFSET    0x70
++#define       MT7988_INFRA_RST1_SET_OFFSET    0x80
+ static DEFINE_SPINLOCK(mt7988_clk_lock);
+@@ -249,12 +253,31 @@ static const struct mtk_gate infra_clks[
+       GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P3, "infra_133m_pcie_ck_p3", "sysaxi_sel", 31),
+ };
++static u16 infra_rst_ofs[] = {
++      MT7988_INFRA_RST0_SET_OFFSET,
++      MT7988_INFRA_RST1_SET_OFFSET,
++};
++
++static u16 infra_idx_map[] = {
++      [MT7988_INFRA_RST0_PEXTP_MAC_SWRST] = 0 * RST_NR_PER_BANK + 6,
++      [MT7988_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 = &mt7988_clk_lock,
++      .rst_desc = &infra_rst_desc,
+ };
+ static const struct of_device_id of_match_clk_mt7988_infracfg[] = {
diff --git a/target/linux/mediatek/patches-6.6/250-dt-bindings-reset-mediatek-add-MT7988-reset-IDs.patch b/target/linux/mediatek/patches-6.6/250-dt-bindings-reset-mediatek-add-MT7988-reset-IDs.patch
new file mode 100644 (file)
index 0000000..d353074
--- /dev/null
@@ -0,0 +1,25 @@
+From 3c810da3206f2e52c92f9f15a87f05db4bbba734 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Wed, 17 Jan 2024 19:41:10 +0100
+Subject: [PATCH] dt-bindings: reset: mediatek: add MT7988 reset IDs
+
+Add reset constants for using as index in driver and dts.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+---
+ include/dt-bindings/reset/mediatek,mt7988-resets.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/include/dt-bindings/reset/mediatek,mt7988-resets.h
++++ b/include/dt-bindings/reset/mediatek,mt7988-resets.h
+@@ -10,4 +10,10 @@
+ /* ETHWARP resets */
+ #define MT7988_ETHWARP_RST_SWITCH             0
++/* INFRA resets */
++#define MT7988_INFRA_RST0_PEXTP_MAC_SWRST     0
++#define MT7988_INFRA_RST1_THERM_CTRL_SWRST    1
++
++
+ #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7988 */
++
diff --git a/target/linux/mediatek/patches-6.6/251-v6.8-watchdog-mediatek-mt7988-add-wdt-support.patch b/target/linux/mediatek/patches-6.6/251-v6.8-watchdog-mediatek-mt7988-add-wdt-support.patch
new file mode 100644 (file)
index 0000000..cb49ce1
--- /dev/null
@@ -0,0 +1,125 @@
+From 137c9e08e5e542d58aa606b0bb4f0990117309a0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 20 Nov 2023 18:22:31 +0000
+Subject: [PATCH] watchdog: mediatek: mt7988: add wdt support
+
+Add support for watchdog and reset generator unit of the MediaTek
+MT7988 SoC.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/c0cf5f701801cce60470853fa15f1d9dced78c4f.1700504385.git.daniel@makrotopia.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+---
+ drivers/watchdog/mtk_wdt.c | 42 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+--- a/drivers/watchdog/mtk_wdt.c
++++ b/drivers/watchdog/mtk_wdt.c
+@@ -56,9 +56,13 @@
+ #define WDT_SWSYSRST          0x18U
+ #define WDT_SWSYS_RST_KEY     0x88000000
++#define WDT_SWSYSRST_EN               0xfc
++
+ #define DRV_NAME              "mtk-wdt"
+ #define DRV_VERSION           "1.0"
++#define MT7988_TOPRGU_SW_RST_NUM      24
++
+ static bool nowayout = WATCHDOG_NOWAYOUT;
+ static unsigned int timeout;
+@@ -68,10 +72,12 @@ struct mtk_wdt_dev {
+       spinlock_t lock; /* protects WDT_SWSYSRST reg */
+       struct reset_controller_dev rcdev;
+       bool disable_wdt_extrst;
++      bool has_swsysrst_en;
+ };
+ struct mtk_wdt_data {
+       int toprgu_sw_rst_num;
++      bool has_swsysrst_en;
+ };
+ static const struct mtk_wdt_data mt2712_data = {
+@@ -82,6 +88,11 @@ static const struct mtk_wdt_data mt7986_
+       .toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
+ };
++static const struct mtk_wdt_data mt7988_data = {
++      .toprgu_sw_rst_num = MT7988_TOPRGU_SW_RST_NUM,
++      .has_swsysrst_en = true,
++};
++
+ static const struct mtk_wdt_data mt8183_data = {
+       .toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
+ };
+@@ -98,6 +109,28 @@ static const struct mtk_wdt_data mt8195_
+       .toprgu_sw_rst_num = MT8195_TOPRGU_SW_RST_NUM,
+ };
++/**
++ * toprgu_reset_sw_en_unlocked() - enable/disable software control for reset bit
++ * @data: Pointer to instance of driver data.
++ * @id: Bit number identifying the reset to be enabled or disabled.
++ * @enable: If true, enable software control for that bit, disable otherwise.
++ *
++ * Context: The caller must hold lock of struct mtk_wdt_dev.
++ */
++static void toprgu_reset_sw_en_unlocked(struct mtk_wdt_dev *data,
++                                      unsigned long id, bool enable)
++{
++      u32 tmp;
++
++      tmp = readl(data->wdt_base + WDT_SWSYSRST_EN);
++      if (enable)
++              tmp |= BIT(id);
++      else
++              tmp &= ~BIT(id);
++
++      writel(tmp, data->wdt_base + WDT_SWSYSRST_EN);
++}
++
+ static int toprgu_reset_update(struct reset_controller_dev *rcdev,
+                              unsigned long id, bool assert)
+ {
+@@ -108,6 +141,9 @@ static int toprgu_reset_update(struct re
+       spin_lock_irqsave(&data->lock, flags);
++      if (assert && data->has_swsysrst_en)
++              toprgu_reset_sw_en_unlocked(data, id, true);
++
+       tmp = readl(data->wdt_base + WDT_SWSYSRST);
+       if (assert)
+               tmp |= BIT(id);
+@@ -116,6 +152,9 @@ static int toprgu_reset_update(struct re
+       tmp |= WDT_SWSYS_RST_KEY;
+       writel(tmp, data->wdt_base + WDT_SWSYSRST);
++      if (!assert && data->has_swsysrst_en)
++              toprgu_reset_sw_en_unlocked(data, id, false);
++
+       spin_unlock_irqrestore(&data->lock, flags);
+       return 0;
+@@ -393,6 +432,8 @@ static int mtk_wdt_probe(struct platform
+                                                      wdt_data->toprgu_sw_rst_num);
+               if (err)
+                       return err;
++
++              mtk_wdt->has_swsysrst_en = wdt_data->has_swsysrst_en;
+       }
+       mtk_wdt->disable_wdt_extrst =
+@@ -427,6 +468,7 @@ static const struct of_device_id mtk_wdt
+       { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
+       { .compatible = "mediatek,mt6589-wdt" },
+       { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
++      { .compatible = "mediatek,mt7988-wdt", .data = &mt7988_data },
+       { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
+       { .compatible = "mediatek,mt8186-wdt", .data = &mt8186_data },
+       { .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
diff --git a/target/linux/mediatek/patches-6.6/252-clk-mediatek-mt7988-infracfg-fix-clocks-for-2nd-PCIe.patch b/target/linux/mediatek/patches-6.6/252-clk-mediatek-mt7988-infracfg-fix-clocks-for-2nd-PCIe.patch
new file mode 100644 (file)
index 0000000..c4760b9
--- /dev/null
@@ -0,0 +1,31 @@
+From c202f510bbaa34ab5d65a69a61e0e72761374b17 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 11 Mar 2024 17:14:19 +0000
+Subject: [PATCH] clk: mediatek: mt7988-infracfg: fix clocks for 2nd PCIe port
+
+Due to what seems to be an undocumented oddity in MediaTek's MT7988
+SoC design the CLK_INFRA_PCIE_PERI_26M_CK_P2 clock requires
+CLK_INFRA_PCIE_PERI_26M_CK_P3 to be enabled.
+
+This currently leads to PCIe port 2 not working in Linux.
+
+Reflect the apparent relationship in the clk driver to make sure PCIe
+port 2 of the MT7988 SoC works.
+
+Suggested-by: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/clk/mediatek/clk-mt7988-infracfg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/mediatek/clk-mt7988-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt7988-infracfg.c
+@@ -156,7 +156,7 @@ static const struct mtk_gate infra_clks[
+       GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P1, "infra_pcie_peri_ck_26m_ck_p1",
+                   "csw_infra_f26m_sel", 8),
+       GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P2, "infra_pcie_peri_ck_26m_ck_p2",
+-                  "csw_infra_f26m_sel", 9),
++                  "infra_pcie_peri_ck_26m_ck_p3", 9),
+       GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P3, "infra_pcie_peri_ck_26m_ck_p3",
+                   "csw_infra_f26m_sel", 10),
+       /* INFRA1 */
diff --git a/target/linux/mediatek/patches-6.6/320-v6.2-mmc-mediatek-add-support-for-MT7986-SoC.patch b/target/linux/mediatek/patches-6.6/320-v6.2-mmc-mediatek-add-support-for-MT7986-SoC.patch
new file mode 100644 (file)
index 0000000..5e3afd8
--- /dev/null
@@ -0,0 +1,47 @@
+From 24e961b93d292d0dd6380213d22a071a99ea787d Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Tue, 25 Oct 2022 15:29:53 +0200
+Subject: [PATCH 1/6] mmc: mediatek: add support for MT7986 SoC
+
+Adding mt7986 own characteristics and of_device_id to have support
+of MT7986 SoC.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.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/r/20221025132953.81286-7-linux@fw-web.de
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -552,6 +552,19 @@ static const struct mtk_mmc_compatible m
+       .support_64g = false,
+ };
++static const struct mtk_mmc_compatible mt7986_compat = {
++      .clk_div_bits = 12,
++      .recheck_sdio_irq = true,
++      .hs400_tune = false,
++      .pad_tune_reg = MSDC_PAD_TUNE0,
++      .async_fifo = true,
++      .data_tune = true,
++      .busy_check = true,
++      .stop_clk_fix = true,
++      .enhance_rx = true,
++      .support_64g = true,
++};
++
+ static const struct mtk_mmc_compatible mt8135_compat = {
+       .clk_div_bits = 8,
+       .recheck_sdio_irq = true,
+@@ -609,6 +622,7 @@ static const struct of_device_id msdc_of
+       { .compatible = "mediatek,mt6795-mmc", .data = &mt6795_compat},
+       { .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat},
+       { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
++      { .compatible = "mediatek,mt7986-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.6/321-v6.2-mmc-mtk-sd-add-Inline-Crypto-Engine-clock-control.patch b/target/linux/mediatek/patches-6.6/321-v6.2-mmc-mtk-sd-add-Inline-Crypto-Engine-clock-control.patch
new file mode 100644 (file)
index 0000000..db2802b
--- /dev/null
@@ -0,0 +1,57 @@
+From 7b438d0377fbd520b475a68bdd9de1692393f22d Mon Sep 17 00:00:00 2001
+From: Mengqi Zhang <mengqi.zhang@mediatek.com>
+Date: Sun, 6 Nov 2022 11:39:24 +0800
+Subject: [PATCH 2/6] mmc: mtk-sd: add Inline Crypto Engine clock control
+
+Add crypto clock control and ungate it before CQHCI init.
+
+Signed-off-by: Mengqi Zhang <mengqi.zhang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221106033924.9854-2-mengqi.zhang@mediatek.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -452,6 +452,7 @@ struct msdc_host {
+       struct clk *bus_clk;    /* bus clock which used to access register */
+       struct clk *src_clk_cg; /* msdc source clock control gate */
+       struct clk *sys_clk_cg; /* msdc subsys clock control gate */
++      struct clk *crypto_clk; /* msdc crypto clock control gate */
+       struct clk_bulk_data bulk_clks[MSDC_NR_CLOCKS];
+       u32 mclk;               /* mmc subsystem clock frequency */
+       u32 src_clk_freq;       /* source clock frequency */
+@@ -840,6 +841,7 @@ static void msdc_set_busy_timeout(struct
+ static void msdc_gate_clock(struct msdc_host *host)
+ {
+       clk_bulk_disable_unprepare(MSDC_NR_CLOCKS, host->bulk_clks);
++      clk_disable_unprepare(host->crypto_clk);
+       clk_disable_unprepare(host->src_clk_cg);
+       clk_disable_unprepare(host->src_clk);
+       clk_disable_unprepare(host->bus_clk);
+@@ -855,6 +857,7 @@ static int msdc_ungate_clock(struct msdc
+       clk_prepare_enable(host->bus_clk);
+       clk_prepare_enable(host->src_clk);
+       clk_prepare_enable(host->src_clk_cg);
++      clk_prepare_enable(host->crypto_clk);
+       ret = clk_bulk_prepare_enable(MSDC_NR_CLOCKS, host->bulk_clks);
+       if (ret) {
+               dev_err(host->dev, "Cannot enable pclk/axi/ahb clock gates\n");
+@@ -2670,6 +2673,15 @@ static int msdc_drv_probe(struct platfor
+               goto host_free;
+       }
++      /* only eMMC has crypto property */
++      if (!(mmc->caps2 & MMC_CAP2_NO_MMC)) {
++              host->crypto_clk = devm_clk_get_optional(&pdev->dev, "crypto");
++              if (IS_ERR(host->crypto_clk))
++                      host->crypto_clk = NULL;
++              else
++                      mmc->caps2 |= MMC_CAP2_CRYPTO;
++      }
++
+       host->irq = platform_get_irq(pdev, 0);
+       if (host->irq < 0) {
+               ret = host->irq;
diff --git a/target/linux/mediatek/patches-6.6/322-v6.2-mmc-mtk-sd-fix-two-spelling-mistakes-in-comment.patch b/target/linux/mediatek/patches-6.6/322-v6.2-mmc-mtk-sd-fix-two-spelling-mistakes-in-comment.patch
new file mode 100644 (file)
index 0000000..921d249
--- /dev/null
@@ -0,0 +1,36 @@
+From 4b323f02b6e8df1b04292635ef829e7f723bf50e Mon Sep 17 00:00:00 2001
+From: Yu Zhe <yuzhe@nfschina.com>
+Date: Thu, 10 Nov 2022 15:28:19 +0800
+Subject: [PATCH 3/6] mmc: mtk-sd: fix two spelling mistakes in comment
+
+spelling mistake fix : "alreay" -> "already"
+                      "checksume" -> "checksum"
+
+Signed-off-by: Yu Zhe <yuzhe@nfschina.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221110072819.11530-1-yuzhe@nfschina.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -750,7 +750,7 @@ static inline void msdc_dma_setup(struct
+               else
+                       bd[j].bd_info &= ~BDMA_DESC_EOL;
+-              /* checksume need to clear first */
++              /* checksum need to clear first */
+               bd[j].bd_info &= ~BDMA_DESC_CHECKSUM;
+               bd[j].bd_info |= msdc_dma_calcs((u8 *)(&bd[j]), 16) << 8;
+       }
+@@ -1229,7 +1229,7 @@ static bool msdc_cmd_done(struct msdc_ho
+                    !host->hs400_tuning))
+                       /*
+                        * should not clear fifo/interrupt as the tune data
+-                       * may have alreay come when cmd19/cmd21 gets response
++                       * may have already come when cmd19/cmd21 gets response
+                        * CRC error.
+                        */
+                       msdc_reset_hw(host);
diff --git a/target/linux/mediatek/patches-6.6/323-v6.2-mmc-Avoid-open-coding-by-using-mmc_op_tuning.patch b/target/linux/mediatek/patches-6.6/323-v6.2-mmc-Avoid-open-coding-by-using-mmc_op_tuning.patch
new file mode 100644 (file)
index 0000000..8e2151e
--- /dev/null
@@ -0,0 +1,39 @@
+From b98e7e8daf0ebab9dcc36812378a71e1be0b5089 Mon Sep 17 00:00:00 2001
+From: ChanWoo Lee <cw9316.lee@samsung.com>
+Date: Thu, 24 Nov 2022 17:00:31 +0900
+Subject: [PATCH 4/6] mmc: Avoid open coding by using mmc_op_tuning()
+
+Replace code with the already defined function. No functional changes.
+
+Signed-off-by: ChanWoo Lee <cw9316.lee@samsung.com>
+Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20221124080031.14690-1-cw9316.lee@samsung.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/mtk-sd.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -1224,9 +1224,7 @@ static bool msdc_cmd_done(struct msdc_ho
+       if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
+               if (events & MSDC_INT_CMDTMO ||
+-                  (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
+-                   cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
+-                   !host->hs400_tuning))
++                  (!mmc_op_tuning(cmd->opcode) && !host->hs400_tuning))
+                       /*
+                        * should not clear fifo/interrupt as the tune data
+                        * may have already come when cmd19/cmd21 gets response
+@@ -1320,9 +1318,7 @@ static void msdc_cmd_next(struct msdc_ho
+ {
+       if ((cmd->error &&
+           !(cmd->error == -EILSEQ &&
+-            (cmd->opcode == MMC_SEND_TUNING_BLOCK ||
+-             cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200 ||
+-             host->hs400_tuning))) ||
++            (mmc_op_tuning(cmd->opcode) || host->hs400_tuning))) ||
+           (mrq->sbc && mrq->sbc->error))
+               msdc_request_done(host, mrq);
+       else if (cmd == mrq->sbc)
diff --git a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch
new file mode 100644 (file)
index 0000000..55a308e
--- /dev/null
@@ -0,0 +1,34 @@
+--- 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)
+ {
+@@ -1344,6 +1345,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;
+@@ -1351,6 +1353,7 @@ static int spinand_probe(struct spi_mem
+       return 0;
+ err_spinand_cleanup:
++      mtk_bmt_detach(mtd);
+       spinand_cleanup(spinand);
+       return ret;
+@@ -1369,6 +1372,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.6/331-mt7622-rfb1-enable-bmt.patch b/target/linux/mediatek/patches-6.6/331-mt7622-rfb1-enable-bmt.patch
new file mode 100644 (file)
index 0000000..3e95670
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -548,6 +548,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.6/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch b/target/linux/mediatek/patches-6.6/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch
new file mode 100644 (file)
index 0000000..ec66363
--- /dev/null
@@ -0,0 +1,122 @@
+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,3 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0
+-spinand-objs := core.o ato.o esmt.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
++spinand-objs := core.o ato.o esmt.o etron.o fidelix.o gigadevice.o macronix.o micron.o paragon.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
+@@ -940,6 +940,7 @@ static const struct nand_ops spinand_ops
+ static const struct spinand_manufacturer *spinand_manufacturers[] = {
+       &ato_spinand_manufacturer,
+       &esmt_c8_spinand_manufacturer,
++      &fidelix_spinand_manufacturer,
+       &etron_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(false, 0, NULL, 0),
++              SPINAND_PROG_LOAD(false, 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
+@@ -263,6 +263,7 @@ struct spinand_manufacturer {
+ extern const struct spinand_manufacturer ato_spinand_manufacturer;
+ extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
+ extern const struct spinand_manufacturer etron_spinand_manufacturer;
++extern const struct spinand_manufacturer fidelix_spinand_manufacturer;
+ extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
+ extern const struct spinand_manufacturer macronix_spinand_manufacturer;
+ extern const struct spinand_manufacturer micron_spinand_manufacturer;
diff --git a/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch b/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch
new file mode 100644 (file)
index 0000000..49cd62d
--- /dev/null
@@ -0,0 +1,41 @@
+From 4983a1517e7ddbc6f53fc07607e4ebeb51412843 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Tue, 28 Feb 2023 19:59:22 +0800
+Subject: [PATCH 21/21] cpufreq: mediatek: Add support for MT7988
+
+This add cpufreq support for mediatek MT7988 SoC.
+
+The platform data of MT7988 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
+@@ -709,6 +709,15 @@ static const struct mtk_cpufreq_platform
+       .ccifreq_supported = false,
+ };
++static const struct mtk_cpufreq_platform_data mt7988_platform_data = {
++      .min_volt_shift = 100000,
++      .max_volt_shift = 200000,
++      .proc_max_volt = 900000,
++      .sram_min_volt = 0,
++      .sram_max_volt = 1150000,
++      .ccifreq_supported = true,
++};
++
+ static const struct mtk_cpufreq_platform_data mt8183_platform_data = {
+       .min_volt_shift = 100000,
+       .max_volt_shift = 200000,
+@@ -742,6 +751,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,mt7988", .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.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch b/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch
new file mode 100644 (file)
index 0000000..1fcb1e6
--- /dev/null
@@ -0,0 +1,99 @@
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -601,6 +601,30 @@ out:
+       return err;
+ }
++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)
++              pd = 0;
++      else if ((arg == MTK_ENABLE) && pullup)
++              pd = 0;
++      else if ((arg == MTK_ENABLE) && !pullup)
++              pd = 1;
++      else {
++              err = -EINVAL;
++              goto out;
++      }
++
++      err = 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,
+                               const struct mtk_pin_desc *desc,
+                               u32 pullup, u32 arg)
+@@ -755,6 +779,12 @@ int mtk_pinconf_bias_set_combo(struct mt
+                       return err;
+       }
++      if (try_all_type & MTK_PULL_PD_TYPE) {
++              err = mtk_pinconf_bias_set_pd(hw, desc, pullup, arg);
++              if (!err)
++                      return err;
++    }
++
+       if (try_all_type & MTK_PULL_PU_PD_TYPE) {
+               err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+               if (!err)
+@@ -875,6 +905,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)
+@@ -943,6 +996,12 @@ int mtk_pinconf_bias_get_combo(struct mt
+               if (!err)
+                       return err;
+       }
++
++      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);
+--- 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.6/400-crypto-add-eip97-inside-secure-support.patch b/target/linux/mediatek/patches-6.6/400-crypto-add-eip97-inside-secure-support.patch
new file mode 100644 (file)
index 0000000..25ca948
--- /dev/null
@@ -0,0 +1,27 @@
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -600,6 +600,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.6/401-crypto-fix-eip97-cache-incoherent.patch b/target/linux/mediatek/patches-6.6/401-crypto-fix-eip97-cache-incoherent.patch
new file mode 100644 (file)
index 0000000..186c66f
--- /dev/null
@@ -0,0 +1,26 @@
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -737,6 +737,9 @@ enum safexcel_eip_version {
+ /* 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.6/405-v6.2-mt7986-trng-add-rng-support.patch b/target/linux/mediatek/patches-6.6/405-v6.2-mt7986-trng-add-rng-support.patch
new file mode 100644 (file)
index 0000000..615a1a1
--- /dev/null
@@ -0,0 +1,43 @@
+From f1da27b7c4191f78ed81d3dabf64c769f896296c Mon Sep 17 00:00:00 2001
+From: "Mingming.Su" <Mingming.Su@mediatek.com>
+Date: Sat, 8 Oct 2022 18:45:53 +0200
+Subject: [PATCH] hwrng: mtk - add mt7986 support
+
+1. Add trng compatible name for MT7986
+2. Fix mtk_rng_wait_ready() function
+
+Signed-off-by: Mingming.Su <Mingming.Su@mediatek.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/char/hw_random/mtk-rng.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/hw_random/mtk-rng.c
++++ b/drivers/char/hw_random/mtk-rng.c
+@@ -22,7 +22,7 @@
+ #define RNG_AUTOSUSPEND_TIMEOUT               100
+ #define USEC_POLL                     2
+-#define TIMEOUT_POLL                  20
++#define TIMEOUT_POLL                  60
+ #define RNG_CTRL                      0x00
+ #define RNG_EN                                BIT(0)
+@@ -77,7 +77,7 @@ static bool mtk_rng_wait_ready(struct hw
+               readl_poll_timeout_atomic(priv->base + RNG_CTRL, ready,
+                                         ready & RNG_READY, USEC_POLL,
+                                         TIMEOUT_POLL);
+-      return !!ready;
++      return !!(ready & RNG_READY);
+ }
+ static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+@@ -179,6 +179,7 @@ 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" },
+       {},
+ };
diff --git a/target/linux/mediatek/patches-6.6/410-bt-mtk-serial-fix.patch b/target/linux/mediatek/patches-6.6/410-bt-mtk-serial-fix.patch
new file mode 100644 (file)
index 0000000..5b94c92
--- /dev/null
@@ -0,0 +1,33 @@
+--- 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
+@@ -287,7 +287,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",
+@@ -2773,6 +2773,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.6/431-drivers-spi-mt65xx-Move-chip_config-to-driver-s-priv.patch b/target/linux/mediatek/patches-6.6/431-drivers-spi-mt65xx-Move-chip_config-to-driver-s-priv.patch
new file mode 100644 (file)
index 0000000..8c2c80d
--- /dev/null
@@ -0,0 +1,130 @@
+From bfd3acc428085742d754a6d328d1a93ebf9451df 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                 | 29 +++++++++---------------
+ include/linux/platform_data/spi-mt65xx.h | 17 --------------
+ 2 files changed, 11 insertions(+), 35 deletions(-)
+ delete mode 100644 include/linux/platform_data/spi-mt65xx.h
+
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -14,7 +14,6 @@
+ #include <linux/of.h>
+ #include <linux/gpio/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>
+@@ -171,6 +170,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;
+@@ -216,15 +217,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,
+@@ -352,7 +344,6 @@ static int mtk_spi_hw_init(struct spi_ma
+ {
+       u16 cpha, cpol;
+       u32 reg_val;
+-      struct mtk_chip_config *chip_config = spi->controller_data;
+       struct mtk_spi *mdata = spi_master_get_devdata(master);
+       cpha = spi->mode & SPI_CPHA ? 1 : 0;
+@@ -402,7 +393,7 @@ static int mtk_spi_hw_init(struct spi_ma
+               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;
+@@ -429,20 +420,20 @@ static int mtk_spi_hw_init(struct spi_ma
+               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);
+       }
+@@ -732,9 +723,6 @@ static int mtk_spi_setup(struct spi_devi
+ {
+       struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
+-      if (!spi->controller_data)
+-              spi->controller_data = (void *)&mtk_default_chip_info;
+-
+       if (mdata->dev_comp->need_pad_sel && spi->cs_gpiod)
+               /* CS de-asserted, gpiolib will handle inversion */
+               gpiod_direction_output(spi->cs_gpiod, 0);
+@@ -1138,6 +1126,10 @@ static int mtk_spi_probe(struct platform
+       mdata = spi_master_get_devdata(master);
+       mdata->dev_comp = device_get_match_data(dev);
++      /* Set device configs to default first. Calibrate it later. */
++      mdata->sample_sel = 0;
++      mdata->get_tick_dly = 2;
++
+       if (mdata->dev_comp->enhance_timing)
+               master->mode_bits |= SPI_CS_HIGH;
+--- 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.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch b/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch
new file mode 100644 (file)
index 0000000..b2c9df4
--- /dev/null
@@ -0,0 +1,236 @@
+From 2ade0172154e50c8a2bfd8634c6eff943cffea29 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
+@@ -1385,6 +1385,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)
+@@ -2223,6 +2287,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 int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
+                          struct device_node *nc)
+ {
+@@ -2341,6 +2474,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);
+       spi->dev.of_node = nc;
+--- a/include/linux/spi/spi.h
++++ b/include/linux/spi/spi.h
+@@ -318,6 +318,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;
++};
++
+ static inline struct spi_driver *to_spi_driver(struct device_driver *drv)
+ {
+       return drv ? container_of(drv, struct spi_driver, driver) : NULL;
+@@ -703,6 +737,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);
+       /*
+@@ -1510,6 +1549,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
+  * spi_unregister_device() to start making that device vanish, but
diff --git a/target/linux/mediatek/patches-6.6/433-drivers-spi-mem-Add-spi-calibration-hook.patch b/target/linux/mediatek/patches-6.6/433-drivers-spi-mem-Add-spi-calibration-hook.patch
new file mode 100644 (file)
index 0000000..e87d63d
--- /dev/null
@@ -0,0 +1,41 @@
+From 06640a5da2973318c06e516da16a5b579622e7c5 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
+@@ -419,6 +419,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
+@@ -366,6 +366,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.6/434-drivers-spi-mt65xx-Add-controller-s-calibration-para.patch b/target/linux/mediatek/patches-6.6/434-drivers-spi-mt65xx-Add-controller-s-calibration-para.patch
new file mode 100644 (file)
index 0000000..ee3dc27
--- /dev/null
@@ -0,0 +1,43 @@
+From d278c7a0bf730318a7ccf8d0a8b434c813e23fd0 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
+@@ -832,6 +832,21 @@ static irqreturn_t mtk_spi_interrupt(int
+       return IRQ_HANDLED;
+ }
++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_master_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)
+ {
+@@ -1122,6 +1137,7 @@ static int mtk_spi_probe(struct platform
+       master->setup = mtk_spi_setup;
+       master->set_cs_timing = mtk_spi_set_hw_cs_timing;
+       master->use_gpio_descriptors = true;
++      master->append_caldata = mtk_spi_append_caldata;
+       mdata = spi_master_get_devdata(master);
+       mdata->dev_comp = device_get_match_data(dev);
diff --git a/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch b/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch
new file mode 100644 (file)
index 0000000..3991d89
--- /dev/null
@@ -0,0 +1,81 @@
+From 7670ec4a14891a1a182b98a9c403ffbf6b49e4b1 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
+@@ -978,6 +978,56 @@ static int spinand_manufacturer_match(st
+       return -ENOTSUPP;
+ }
++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;
+@@ -1228,6 +1278,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.6/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch b/target/linux/mediatek/patches-6.6/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch
new file mode 100644 (file)
index 0000000..1f747d1
--- /dev/null
@@ -0,0 +1,57 @@
+From f3fe3b15eca7908eaac57f9b8387a5dbc45ec5b2 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
+@@ -1019,7 +1019,10 @@ int spinand_cal_read(void *priv, u32 *ad
+       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
+@@ -2900,6 +2900,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)
+ {
+@@ -3003,6 +3015,9 @@ int spi_nor_scan(struct spi_nor *nor, co
+       if (!nor->bouncebuf)
+               return -ENOMEM;
++      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.6/500-gsw-rtl8367s-mt7622-support.patch b/target/linux/mediatek/patches-6.6/500-gsw-rtl8367s-mt7622-support.patch
new file mode 100644 (file)
index 0000000..487990a
--- /dev/null
@@ -0,0 +1,25 @@
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -384,6 +384,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"
+       help
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -95,6 +95,7 @@ obj-$(CONFIG_QSEMI_PHY)              += qsemi.o
+ obj-$(CONFIG_REALTEK_PHY)     += realtek.o
+ 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.6/601-PCI-mediatek-Assert-PERST-for-100ms-for-power-and-cl.patch b/target/linux/mediatek/patches-6.6/601-PCI-mediatek-Assert-PERST-for-100ms-for-power-and-cl.patch
new file mode 100644 (file)
index 0000000..983fde7
--- /dev/null
@@ -0,0 +1,34 @@
+From: qizhong cheng <qizhong.cheng@mediatek.com>
+Date: Mon, 27 Dec 2021 21:31:10 +0800
+Subject: [PATCH] PCI: mediatek: Assert PERST# for 100ms for power and clock to
+ stabilize
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Described in PCIe CEM specification sections 2.2 (PERST# Signal) and
+2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should
+be delayed 100ms (TPVPERL) for the power and clock to become stable.
+
+Link: https://lore.kernel.org/r/20211227133110.14500-1-qizhong.cheng@mediatek.com
+Signed-off-by: qizhong cheng <qizhong.cheng@mediatek.com>
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Pali Rohár <pali@kernel.org>
+---
+
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -708,6 +708,13 @@ static int mtk_pcie_startup_port_v2(stru
+        */
+       msleep(100);
++      /*
++       * Described in PCIe CEM specification sections 2.2 (PERST# Signal) and
++       * 2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should
++       * be delayed 100ms (TPVPERL) for the power and clock to become stable.
++       */
++      msleep(100);
++
+       /* De-assert PHY, PE, PIPE, MAC and configuration reset */
+       val = readl(port->base + PCIE_RST_CTRL);
+       val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |
diff --git a/target/linux/mediatek/patches-6.6/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch b/target/linux/mediatek/patches-6.6/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch
new file mode 100644 (file)
index 0000000..bf479ab
--- /dev/null
@@ -0,0 +1,28 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -849,6 +849,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 {
+@@ -887,6 +893,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.6/610-pcie-mediatek-fix-clearing-interrupt-status.patch b/target/linux/mediatek/patches-6.6/610-pcie-mediatek-fix-clearing-interrupt-status.patch
new file mode 100644 (file)
index 0000000..2a49b22
--- /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
+@@ -607,9 +607,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.6/611-pcie-mediatek-gen3-PERST-for-100ms.patch b/target/linux/mediatek/patches-6.6/611-pcie-mediatek-gen3-PERST-for-100ms.patch
new file mode 100644 (file)
index 0000000..32b4237
--- /dev/null
@@ -0,0 +1,17 @@
+--- a/drivers/pci/controller/pcie-mediatek-gen3.c
++++ b/drivers/pci/controller/pcie-mediatek-gen3.c
+@@ -375,7 +375,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.6/615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch b/target/linux/mediatek/patches-6.6/615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch
new file mode 100644 (file)
index 0000000..a597f70
--- /dev/null
@@ -0,0 +1,167 @@
+From 50cefacc6c001eea1d9b1c78ba27304566f304f1 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 2 Jun 2023 13:06:26 +0800
+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>
+---
+ drivers/phy/mediatek/phy-mtk-xsphy.c | 81 +++++++++++++++++++++++++++-
+ 1 file changed, 80 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_read_bool(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;
+ }
+@@ -515,6 +594,10 @@ static int mtk_xsphy_probe(struct platfo
+                       retval = PTR_ERR(inst->ref_clk);
+                       goto put_child;
+               }
++
++              retval = phy_type_syscon_get(inst, child_np);
++              if (retval)
++                      goto put_child;
+       }
+       provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
diff --git a/target/linux/mediatek/patches-6.6/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch b/target/linux/mediatek/patches-6.6/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch
new file mode 100644 (file)
index 0000000..76ee2fc
--- /dev/null
@@ -0,0 +1,82 @@
+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
+@@ -837,6 +837,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>;
+@@ -881,6 +884,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>;
+--- 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;
+ /**
+@@ -1060,6 +1066,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.6/721-dts-mt7622-mediatek-fix-300mhz.patch b/target/linux/mediatek/patches-6.6/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.6/722-remove-300Hz-to-prevent-freeze.patch b/target/linux/mediatek/patches-6.6/722-remove-300Hz-to-prevent-freeze.patch
new file mode 100644 (file)
index 0000000..5206949
--- /dev/null
@@ -0,0 +1,25 @@
+--- 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.6/730-v6.5-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch b/target/linux/mediatek/patches-6.6/730-v6.5-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch
new file mode 100644 (file)
index 0000000..0bbf9ac
--- /dev/null
@@ -0,0 +1,1204 @@
+From 98c485eaf509bc0e2a85f9b58d17cd501f274c4e Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 11 Jun 2023 00:48:10 +0100
+Subject: [PATCH] net: phy: add driver for MediaTek SoC built-in GE PHYs
+
+Some of MediaTek's Filogic SoCs come with built-in gigabit Ethernet
+PHYs which require calibration data from the SoC's efuse.
+Despite the similar design the driver doesn't share any code with the
+existing mediatek-ge.c.
+Add support for such PHYs by introducing a new driver with basic
+support for MediaTek SoCs MT7981 and MT7988 built-in 1GE PHYs.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ MAINTAINERS                       |    9 +
+ drivers/net/phy/Kconfig           |   12 +
+ drivers/net/phy/Makefile          |    1 +
+ drivers/net/phy/mediatek-ge-soc.c | 1116 +++++++++++++++++++++++++++++
+ drivers/net/phy/mediatek-ge.c     |    3 +-
+ 5 files changed, 1140 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/net/phy/mediatek-ge-soc.c
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -12938,6 +12938,15 @@ F:    drivers/net/pcs/pcs-mtk-usxgmii.c
+ F:    include/linux/pcs/pcs-mtk-lynxi.h
+ 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>
++L:    netdev@vger.kernel.org
++S:    Maintained
++F:    drivers/net/phy/mediatek-ge-soc.c
++F:    drivers/net/phy/mediatek-ge.c
++
+ MEDIATEK I2C CONTROLLER DRIVER
+ M:    Qii Wang <qii.wang@mediatek.com>
+ L:    linux-i2c@vger.kernel.org
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -314,6 +314,18 @@ config MEDIATEK_GE_PHY
+       help
+         Supports the MediaTek Gigabit Ethernet PHYs.
++config MEDIATEK_GE_SOC_PHY
++      tristate "MediaTek SoC Ethernet PHYs"
++      depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
++      select NVMEM_MTK_EFUSE
++      help
++        Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
++
++        Include support for built-in Ethernet PHYs which are present in
++        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 MICREL_PHY
+       tristate "Micrel PHYs"
+       depends on PTP_1588_CLOCK_OPTIONAL
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -80,6 +80,7 @@ obj-$(CONFIG_MARVELL_PHY)    += marvell.o
+ obj-$(CONFIG_MARVELL_88X2222_PHY)     += marvell-88x2222.o
+ obj-$(CONFIG_MAXLINEAR_GPHY)  += mxl-gpy.o
+ obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
++obj-$(CONFIG_MEDIATEK_GE_SOC_PHY)     += mediatek-ge-soc.o
+ obj-$(CONFIG_MESON_GXL_PHY)   += meson-gxl.o
+ obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
+ obj-$(CONFIG_MICREL_PHY)      += micrel.o
+--- /dev/null
++++ b/drivers/net/phy/mediatek-ge-soc.c
+@@ -0,0 +1,1116 @@
++// SPDX-License-Identifier: GPL-2.0+
++#include <linux/bitfield.h>
++#include <linux/module.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/of_address.h>
++#include <linux/of_platform.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/phy.h>
++
++#define MTK_GPHY_ID_MT7981                    0x03a29461
++#define MTK_GPHY_ID_MT7988                    0x03a29481
++
++#define MTK_EXT_PAGE_ACCESS                   0x1f
++#define MTK_PHY_PAGE_STANDARD                 0x0000
++#define MTK_PHY_PAGE_EXTENDED_3                       0x0003
++
++#define MTK_PHY_LPI_REG_14                    0x14
++#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK      GENMASK(8, 0)
++
++#define MTK_PHY_LPI_REG_1c                    0x1c
++#define MTK_PHY_SMI_DET_ON_THRESH_MASK                GENMASK(13, 8)
++
++#define MTK_PHY_PAGE_EXTENDED_2A30            0x2a30
++#define MTK_PHY_PAGE_EXTENDED_52B5            0x52b5
++
++#define ANALOG_INTERNAL_OPERATION_MAX_US      20
++#define TXRESERVE_MIN                         0
++#define TXRESERVE_MAX                         7
++
++#define MTK_PHY_ANARG_RG                      0x10
++#define   MTK_PHY_TCLKOFFSET_MASK             GENMASK(12, 8)
++
++/* Registers on MDIO_MMD_VEND1 */
++#define MTK_PHY_TXVLD_DA_RG                   0x12
++#define   MTK_PHY_DA_TX_I2MPB_A_GBE_MASK      GENMASK(15, 10)
++#define   MTK_PHY_DA_TX_I2MPB_A_TBT_MASK      GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_A2         0x16
++#define   MTK_PHY_DA_TX_I2MPB_A_HBT_MASK      GENMASK(15, 10)
++#define   MTK_PHY_DA_TX_I2MPB_A_TST_MASK      GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_B1         0x17
++#define   MTK_PHY_DA_TX_I2MPB_B_GBE_MASK      GENMASK(13, 8)
++#define   MTK_PHY_DA_TX_I2MPB_B_TBT_MASK      GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_B2         0x18
++#define   MTK_PHY_DA_TX_I2MPB_B_HBT_MASK      GENMASK(13, 8)
++#define   MTK_PHY_DA_TX_I2MPB_B_TST_MASK      GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_C1         0x19
++#define   MTK_PHY_DA_TX_I2MPB_C_GBE_MASK      GENMASK(13, 8)
++#define   MTK_PHY_DA_TX_I2MPB_C_TBT_MASK      GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_C2         0x20
++#define   MTK_PHY_DA_TX_I2MPB_C_HBT_MASK      GENMASK(13, 8)
++#define   MTK_PHY_DA_TX_I2MPB_C_TST_MASK      GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_D1         0x21
++#define   MTK_PHY_DA_TX_I2MPB_D_GBE_MASK      GENMASK(13, 8)
++#define   MTK_PHY_DA_TX_I2MPB_D_TBT_MASK      GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_D2         0x22
++#define   MTK_PHY_DA_TX_I2MPB_D_HBT_MASK      GENMASK(13, 8)
++#define   MTK_PHY_DA_TX_I2MPB_D_TST_MASK      GENMASK(5, 0)
++
++#define MTK_PHY_RXADC_CTRL_RG7                        0xc6
++#define   MTK_PHY_DA_AD_BUF_BIAS_LP_MASK      GENMASK(9, 8)
++
++#define MTK_PHY_RXADC_CTRL_RG9                        0xc8
++#define   MTK_PHY_DA_RX_PSBN_TBT_MASK         GENMASK(14, 12)
++#define   MTK_PHY_DA_RX_PSBN_HBT_MASK         GENMASK(10, 8)
++#define   MTK_PHY_DA_RX_PSBN_GBE_MASK         GENMASK(6, 4)
++#define   MTK_PHY_DA_RX_PSBN_LP_MASK          GENMASK(2, 0)
++
++#define MTK_PHY_LDO_OUTPUT_V                  0xd7
++
++#define MTK_PHY_RG_ANA_CAL_RG0                        0xdb
++#define   MTK_PHY_RG_CAL_CKINV                        BIT(12)
++#define   MTK_PHY_RG_ANA_CALEN                        BIT(8)
++#define   MTK_PHY_RG_ZCALEN_A                 BIT(0)
++
++#define MTK_PHY_RG_ANA_CAL_RG1                        0xdc
++#define   MTK_PHY_RG_ZCALEN_B                 BIT(12)
++#define   MTK_PHY_RG_ZCALEN_C                 BIT(8)
++#define   MTK_PHY_RG_ZCALEN_D                 BIT(4)
++#define   MTK_PHY_RG_TXVOS_CALEN              BIT(0)
++
++#define MTK_PHY_RG_ANA_CAL_RG5                        0xe0
++#define   MTK_PHY_RG_REXT_TRIM_MASK           GENMASK(13, 8)
++
++#define MTK_PHY_RG_TX_FILTER                  0xfe
++
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120    0x120
++#define   MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK       GENMASK(12, 8)
++#define   MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK       GENMASK(4, 0)
++
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122    0x122
++#define   MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK     GENMASK(7, 0)
++
++#define MTK_PHY_RG_TESTMUX_ADC_CTRL           0x144
++#define   MTK_PHY_RG_TXEN_DIG_MASK            GENMASK(5, 5)
++
++#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B               0x172
++#define   MTK_PHY_CR_TX_AMP_OFFSET_A_MASK     GENMASK(13, 8)
++#define   MTK_PHY_CR_TX_AMP_OFFSET_B_MASK     GENMASK(6, 0)
++
++#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D               0x173
++#define   MTK_PHY_CR_TX_AMP_OFFSET_C_MASK     GENMASK(13, 8)
++#define   MTK_PHY_CR_TX_AMP_OFFSET_D_MASK     GENMASK(6, 0)
++
++#define MTK_PHY_RG_AD_CAL_COMP                        0x17a
++#define   MTK_PHY_AD_CAL_COMP_OUT_SHIFT               (8)
++
++#define MTK_PHY_RG_AD_CAL_CLK                 0x17b
++#define   MTK_PHY_DA_CAL_CLK                  BIT(0)
++
++#define MTK_PHY_RG_AD_CALIN                   0x17c
++#define   MTK_PHY_DA_CALIN_FLAG                       BIT(0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_A             0x17d
++#define   MTK_PHY_DASN_DAC_IN0_A_MASK         GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_B             0x17e
++#define   MTK_PHY_DASN_DAC_IN0_B_MASK         GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_C             0x17f
++#define   MTK_PHY_DASN_DAC_IN0_C_MASK         GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_D             0x180
++#define   MTK_PHY_DASN_DAC_IN0_D_MASK         GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_A             0x181
++#define   MTK_PHY_DASN_DAC_IN1_A_MASK         GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_B             0x182
++#define   MTK_PHY_DASN_DAC_IN1_B_MASK         GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_C             0x183
++#define   MTK_PHY_DASN_DAC_IN1_C_MASK         GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_D             0x184
++#define   MTK_PHY_DASN_DAC_IN1_D_MASK         GENMASK(9, 0)
++
++#define MTK_PHY_RG_DEV1E_REG19b                       0x19b
++#define   MTK_PHY_BYPASS_DSP_LPI_READY                BIT(8)
++
++#define MTK_PHY_RG_LP_IIR2_K1_L                       0x22a
++#define MTK_PHY_RG_LP_IIR2_K1_U                       0x22b
++#define MTK_PHY_RG_LP_IIR2_K2_L                       0x22c
++#define MTK_PHY_RG_LP_IIR2_K2_U                       0x22d
++#define MTK_PHY_RG_LP_IIR2_K3_L                       0x22e
++#define MTK_PHY_RG_LP_IIR2_K3_U                       0x22f
++#define MTK_PHY_RG_LP_IIR2_K4_L                       0x230
++#define MTK_PHY_RG_LP_IIR2_K4_U                       0x231
++#define MTK_PHY_RG_LP_IIR2_K5_L                       0x232
++#define MTK_PHY_RG_LP_IIR2_K5_U                       0x233
++
++#define MTK_PHY_RG_DEV1E_REG234                       0x234
++#define   MTK_PHY_TR_OPEN_LOOP_EN_MASK                GENMASK(0, 0)
++#define   MTK_PHY_LPF_X_AVERAGE_MASK          GENMASK(7, 4)
++#define   MTK_PHY_TR_LP_IIR_EEE_EN            BIT(12)
++
++#define MTK_PHY_RG_LPF_CNT_VAL                        0x235
++
++#define MTK_PHY_RG_DEV1E_REG238                       0x238
++#define   MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK  GENMASK(8, 0)
++#define   MTK_PHY_LPI_SLV_SEND_TX_EN          BIT(12)
++
++#define MTK_PHY_RG_DEV1E_REG239                       0x239
++#define   MTK_PHY_LPI_SEND_LOC_TIMER_MASK     GENMASK(8, 0)
++#define   MTK_PHY_LPI_TXPCS_LOC_RCV           BIT(12)
++
++#define MTK_PHY_RG_DEV1E_REG27C                       0x27c
++#define   MTK_PHY_VGASTATE_FFE_THR_ST1_MASK   GENMASK(12, 8)
++#define MTK_PHY_RG_DEV1E_REG27D                       0x27d
++#define   MTK_PHY_VGASTATE_FFE_THR_ST2_MASK   GENMASK(4, 0)
++
++#define MTK_PHY_RG_DEV1E_REG2C7                       0x2c7
++#define   MTK_PHY_MAX_GAIN_MASK                       GENMASK(4, 0)
++#define   MTK_PHY_MIN_GAIN_MASK                       GENMASK(12, 8)
++
++#define MTK_PHY_RG_DEV1E_REG2D1                       0x2d1
++#define   MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK        GENMASK(7, 0)
++#define   MTK_PHY_LPI_SKIP_SD_SLV_TR          BIT(8)
++#define   MTK_PHY_LPI_TR_READY                        BIT(9)
++#define   MTK_PHY_LPI_VCO_EEE_STG0_EN         BIT(10)
++
++#define MTK_PHY_RG_DEV1E_REG323                       0x323
++#define   MTK_PHY_EEE_WAKE_MAS_INT_DC         BIT(0)
++#define   MTK_PHY_EEE_WAKE_SLV_INT_DC         BIT(4)
++
++#define MTK_PHY_RG_DEV1E_REG324                       0x324
++#define   MTK_PHY_SMI_DETCNT_MAX_MASK         GENMASK(5, 0)
++#define   MTK_PHY_SMI_DET_MAX_EN              BIT(8)
++
++#define MTK_PHY_RG_DEV1E_REG326                       0x326
++#define   MTK_PHY_LPI_MODE_SD_ON              BIT(0)
++#define   MTK_PHY_RESET_RANDUPD_CNT           BIT(1)
++#define   MTK_PHY_TREC_UPDATE_ENAB_CLR                BIT(2)
++#define   MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF       BIT(4)
++#define   MTK_PHY_TR_READY_SKIP_AFE_WAKEUP    BIT(5)
++
++#define MTK_PHY_LDO_PUMP_EN_PAIRAB            0x502
++#define MTK_PHY_LDO_PUMP_EN_PAIRCD            0x503
++
++#define MTK_PHY_DA_TX_R50_PAIR_A              0x53d
++#define MTK_PHY_DA_TX_R50_PAIR_B              0x53e
++#define MTK_PHY_DA_TX_R50_PAIR_C              0x53f
++#define MTK_PHY_DA_TX_R50_PAIR_D              0x540
++
++#define MTK_PHY_RG_BG_RASEL                   0x115
++#define   MTK_PHY_RG_BG_RASEL_MASK            GENMASK(2, 0)
++
++/* These macro privides efuse parsing for internal phy. */
++#define EFS_DA_TX_I2MPB_A(x)                  (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_B(x)                  (((x) >> 6) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_C(x)                  (((x) >> 12) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_D(x)                  (((x) >> 18) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_A(x)             (((x) >> 24) & GENMASK(5, 0))
++
++#define EFS_DA_TX_AMP_OFFSET_B(x)             (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_C(x)             (((x) >> 6) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_D(x)             (((x) >> 12) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_A(x)                    (((x) >> 18) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_B(x)                    (((x) >> 24) & GENMASK(5, 0))
++
++#define EFS_DA_TX_R50_C(x)                    (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_D(x)                    (((x) >> 6) & GENMASK(5, 0))
++
++#define EFS_RG_BG_RASEL(x)                    (((x) >> 4) & GENMASK(2, 0))
++#define EFS_RG_REXT_TRIM(x)                   (((x) >> 7) & GENMASK(5, 0))
++
++enum {
++      NO_PAIR,
++      PAIR_A,
++      PAIR_B,
++      PAIR_C,
++      PAIR_D,
++};
++
++enum {
++      GPHY_PORT0,
++      GPHY_PORT1,
++      GPHY_PORT2,
++      GPHY_PORT3,
++};
++
++enum calibration_mode {
++      EFUSE_K,
++      SW_K
++};
++
++enum CAL_ITEM {
++      REXT,
++      TX_OFFSET,
++      TX_AMP,
++      TX_R50,
++      TX_VCM
++};
++
++enum CAL_MODE {
++      EFUSE_M,
++      SW_M
++};
++
++static int mtk_socphy_read_page(struct phy_device *phydev)
++{
++      return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
++}
++
++static int mtk_socphy_write_page(struct phy_device *phydev, int page)
++{
++      return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
++}
++
++/* One calibration cycle consists of:
++ * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
++ *   until AD_CAL_COMP is ready to output calibration result.
++ * 2.Wait until DA_CAL_CLK is available.
++ * 3.Fetch AD_CAL_COMP_OUT.
++ */
++static int cal_cycle(struct phy_device *phydev, int devad,
++                   u32 regnum, u16 mask, u16 cal_val)
++{
++      int reg_val;
++      int ret;
++
++      phy_modify_mmd(phydev, devad, regnum,
++                     mask, cal_val);
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
++                       MTK_PHY_DA_CALIN_FLAG);
++
++      ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
++                                      MTK_PHY_RG_AD_CAL_CLK, reg_val,
++                                      reg_val & MTK_PHY_DA_CAL_CLK, 500,
++                                      ANALOG_INTERNAL_OPERATION_MAX_US, false);
++      if (ret) {
++              phydev_err(phydev, "Calibration cycle timeout\n");
++              return ret;
++      }
++
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
++                         MTK_PHY_DA_CALIN_FLAG);
++      ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
++                         MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
++      phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
++
++      return ret;
++}
++
++static int rext_fill_result(struct phy_device *phydev, u16 *buf)
++{
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
++                     MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
++                     MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
++
++      return 0;
++}
++
++static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++      u16 rext_cal_val[2];
++
++      rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
++      rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
++      rext_fill_result(phydev, rext_cal_val);
++
++      return 0;
++}
++
++static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
++{
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
++                     MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
++                     MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
++                     MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
++                     MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
++
++      return 0;
++}
++
++static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++      u16 tx_offset_cal_val[4];
++
++      tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
++      tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
++      tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
++      tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
++
++      tx_offset_fill_result(phydev, tx_offset_cal_val);
++
++      return 0;
++}
++
++static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
++{
++      int i;
++      int bias[16] = {};
++      const int vals_9461[16] = { 7, 1, 4, 7,
++                                  7, 1, 4, 7,
++                                  7, 1, 4, 7,
++                                  7, 1, 4, 7 };
++      const int vals_9481[16] = { 10, 6, 6, 10,
++                                  10, 6, 6, 10,
++                                  10, 6, 6, 10,
++                                  10, 6, 6, 10 };
++      switch (phydev->drv->phy_id) {
++      case MTK_GPHY_ID_MT7981:
++              /* We add some calibration to efuse values
++               * due to board level influence.
++               * GBE: +7, TBT: +1, HBT: +4, TST: +7
++               */
++              memcpy(bias, (const void *)vals_9461, sizeof(bias));
++              break;
++      case MTK_GPHY_ID_MT7988:
++              memcpy(bias, (const void *)vals_9481, sizeof(bias));
++              break;
++      }
++
++      /* Prevent overflow */
++      for (i = 0; i < 12; i++) {
++              if (buf[i >> 2] + bias[i] > 63) {
++                      buf[i >> 2] = 63;
++                      bias[i] = 0;
++              }
++      }
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
++                     MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
++                     MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
++                     MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
++                     MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
++                     MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
++                     MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
++                     MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
++                     MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
++                     MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
++                     MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
++                     MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
++                     MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
++                     MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
++                     MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
++                     MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
++                     MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
++
++      return 0;
++}
++
++static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++      u16 tx_amp_cal_val[4];
++
++      tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
++      tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
++      tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
++      tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
++      tx_amp_fill_result(phydev, tx_amp_cal_val);
++
++      return 0;
++}
++
++static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
++                            u8 txg_calen_x)
++{
++      int bias = 0;
++      u16 reg, val;
++
++      if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
++              bias = -2;
++
++      val = clamp_val(bias + tx_r50_cal_val, 0, 63);
++
++      switch (txg_calen_x) {
++      case PAIR_A:
++              reg = MTK_PHY_DA_TX_R50_PAIR_A;
++              break;
++      case PAIR_B:
++              reg = MTK_PHY_DA_TX_R50_PAIR_B;
++              break;
++      case PAIR_C:
++              reg = MTK_PHY_DA_TX_R50_PAIR_C;
++              break;
++      case PAIR_D:
++              reg = MTK_PHY_DA_TX_R50_PAIR_D;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
++
++      return 0;
++}
++
++static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
++                          u8 txg_calen_x)
++{
++      u16 tx_r50_cal_val;
++
++      switch (txg_calen_x) {
++      case PAIR_A:
++              tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
++              break;
++      case PAIR_B:
++              tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
++              break;
++      case PAIR_C:
++              tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
++              break;
++      case PAIR_D:
++              tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
++              break;
++      default:
++              return -EINVAL;
++      }
++      tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
++
++      return 0;
++}
++
++static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
++{
++      u8 lower_idx, upper_idx, txreserve_val;
++      u8 lower_ret, upper_ret;
++      int ret;
++
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++                       MTK_PHY_RG_ANA_CALEN);
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++                         MTK_PHY_RG_CAL_CKINV);
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++                       MTK_PHY_RG_TXVOS_CALEN);
++
++      switch (rg_txreserve_x) {
++      case PAIR_A:
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                                 MTK_PHY_RG_DASN_DAC_IN0_A,
++                                 MTK_PHY_DASN_DAC_IN0_A_MASK);
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                                 MTK_PHY_RG_DASN_DAC_IN1_A,
++                                 MTK_PHY_DASN_DAC_IN1_A_MASK);
++              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++                               MTK_PHY_RG_ANA_CAL_RG0,
++                               MTK_PHY_RG_ZCALEN_A);
++              break;
++      case PAIR_B:
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                                 MTK_PHY_RG_DASN_DAC_IN0_B,
++                                 MTK_PHY_DASN_DAC_IN0_B_MASK);
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                                 MTK_PHY_RG_DASN_DAC_IN1_B,
++                                 MTK_PHY_DASN_DAC_IN1_B_MASK);
++              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++                               MTK_PHY_RG_ANA_CAL_RG1,
++                               MTK_PHY_RG_ZCALEN_B);
++              break;
++      case PAIR_C:
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                                 MTK_PHY_RG_DASN_DAC_IN0_C,
++                                 MTK_PHY_DASN_DAC_IN0_C_MASK);
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                                 MTK_PHY_RG_DASN_DAC_IN1_C,
++                                 MTK_PHY_DASN_DAC_IN1_C_MASK);
++              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++                               MTK_PHY_RG_ANA_CAL_RG1,
++                               MTK_PHY_RG_ZCALEN_C);
++              break;
++      case PAIR_D:
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                                 MTK_PHY_RG_DASN_DAC_IN0_D,
++                                 MTK_PHY_DASN_DAC_IN0_D_MASK);
++              phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                                 MTK_PHY_RG_DASN_DAC_IN1_D,
++                                 MTK_PHY_DASN_DAC_IN1_D_MASK);
++              phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++                               MTK_PHY_RG_ANA_CAL_RG1,
++                               MTK_PHY_RG_ZCALEN_D);
++              break;
++      default:
++              ret = -EINVAL;
++              goto restore;
++      }
++
++      lower_idx = TXRESERVE_MIN;
++      upper_idx = TXRESERVE_MAX;
++
++      phydev_dbg(phydev, "Start TX-VCM SW cal.\n");
++      while ((upper_idx - lower_idx) > 1) {
++              txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
++              ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++                              MTK_PHY_DA_RX_PSBN_TBT_MASK |
++                              MTK_PHY_DA_RX_PSBN_HBT_MASK |
++                              MTK_PHY_DA_RX_PSBN_GBE_MASK |
++                              MTK_PHY_DA_RX_PSBN_LP_MASK,
++                              txreserve_val << 12 | txreserve_val << 8 |
++                              txreserve_val << 4 | txreserve_val);
++              if (ret == 1) {
++                      upper_idx = txreserve_val;
++                      upper_ret = ret;
++              } else if (ret == 0) {
++                      lower_idx = txreserve_val;
++                      lower_ret = ret;
++              } else {
++                      goto restore;
++              }
++      }
++
++      if (lower_idx == TXRESERVE_MIN) {
++              lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
++                                    MTK_PHY_RXADC_CTRL_RG9,
++                                    MTK_PHY_DA_RX_PSBN_TBT_MASK |
++                                    MTK_PHY_DA_RX_PSBN_HBT_MASK |
++                                    MTK_PHY_DA_RX_PSBN_GBE_MASK |
++                                    MTK_PHY_DA_RX_PSBN_LP_MASK,
++                                    lower_idx << 12 | lower_idx << 8 |
++                                    lower_idx << 4 | lower_idx);
++              ret = lower_ret;
++      } else if (upper_idx == TXRESERVE_MAX) {
++              upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
++                                    MTK_PHY_RXADC_CTRL_RG9,
++                                    MTK_PHY_DA_RX_PSBN_TBT_MASK |
++                                    MTK_PHY_DA_RX_PSBN_HBT_MASK |
++                                    MTK_PHY_DA_RX_PSBN_GBE_MASK |
++                                    MTK_PHY_DA_RX_PSBN_LP_MASK,
++                                    upper_idx << 12 | upper_idx << 8 |
++                                    upper_idx << 4 | upper_idx);
++              ret = upper_ret;
++      }
++      if (ret < 0)
++              goto restore;
++
++      /* We calibrate TX-VCM in different logic. Check upper index and then
++       * lower index. If this calibration is valid, apply lower index's result.
++       */
++      ret = upper_ret - lower_ret;
++      if (ret == 1) {
++              ret = 0;
++              /* Make sure we use upper_idx in our calibration system */
++              cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++                        MTK_PHY_DA_RX_PSBN_TBT_MASK |
++                        MTK_PHY_DA_RX_PSBN_HBT_MASK |
++                        MTK_PHY_DA_RX_PSBN_GBE_MASK |
++                        MTK_PHY_DA_RX_PSBN_LP_MASK,
++                        upper_idx << 12 | upper_idx << 8 |
++                        upper_idx << 4 | upper_idx);
++              phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
++      } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
++                 lower_ret == 1) {
++              ret = 0;
++              cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++                        MTK_PHY_DA_RX_PSBN_TBT_MASK |
++                        MTK_PHY_DA_RX_PSBN_HBT_MASK |
++                        MTK_PHY_DA_RX_PSBN_GBE_MASK |
++                        MTK_PHY_DA_RX_PSBN_LP_MASK,
++                        lower_idx << 12 | lower_idx << 8 |
++                        lower_idx << 4 | lower_idx);
++              phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n",
++                          lower_idx);
++      } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
++                 lower_ret == 0) {
++              ret = 0;
++              phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",
++                          upper_idx);
++      } else {
++              ret = -EINVAL;
++      }
++
++restore:
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++                         MTK_PHY_RG_ANA_CALEN);
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++                         MTK_PHY_RG_TXVOS_CALEN);
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++                         MTK_PHY_RG_ZCALEN_A);
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++                         MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
++                         MTK_PHY_RG_ZCALEN_D);
++
++      return ret;
++}
++
++static void mt798x_phy_common_finetune(struct phy_device *phydev)
++{
++      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++      /* EnabRandUpdTrig = 1 */
++      __phy_write(phydev, 0x11, 0x2f00);
++      __phy_write(phydev, 0x12, 0xe);
++      __phy_write(phydev, 0x10, 0x8fb0);
++
++      /* NormMseLoThresh = 85 */
++      __phy_write(phydev, 0x11, 0x55a0);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x83aa);
++
++      /* TrFreeze = 0 */
++      __phy_write(phydev, 0x11, 0x0);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x9686);
++
++      /* SSTrKp1000Slv = 5 */
++      __phy_write(phydev, 0x11, 0xbaef);
++      __phy_write(phydev, 0x12, 0x2e);
++      __phy_write(phydev, 0x10, 0x968c);
++
++      /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
++       * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
++       */
++      __phy_write(phydev, 0x11, 0xd10a);
++      __phy_write(phydev, 0x12, 0x34);
++      __phy_write(phydev, 0x10, 0x8f82);
++
++      /* VcoSlicerThreshBitsHigh */
++      __phy_write(phydev, 0x11, 0x5555);
++      __phy_write(phydev, 0x12, 0x55);
++      __phy_write(phydev, 0x10, 0x8ec0);
++      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++      /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
++                     MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++                     BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
++
++      /* rg_tr_lpf_cnt_val = 512 */
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
++
++      /* IIR2 related */
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
++
++      /* FFE peaking */
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
++                     MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
++                     MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
++
++      /* Disable LDO pump */
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
++      /* Adjust LDO output voltage */
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
++}
++
++static void mt7981_phy_finetune(struct phy_device *phydev)
++{
++      u16 val[8] = { 0x01ce, 0x01c1,
++                     0x020f, 0x0202,
++                     0x03d0, 0x03c0,
++                     0x0013, 0x0005 };
++      int i, k;
++
++      /* 100M eye finetune:
++       * Keep middle level of TX MLT3 shapper as default.
++       * Only change TX MLT3 overshoot level here.
++       */
++      for (k = 0, i = 1; i < 12; i++) {
++              if (i % 3 == 0)
++                      continue;
++              phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
++      }
++
++      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++      /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
++      __phy_write(phydev, 0x11, 0xc71);
++      __phy_write(phydev, 0x12, 0xc);
++      __phy_write(phydev, 0x10, 0x8fae);
++
++      /* ResetSyncOffset = 6 */
++      __phy_write(phydev, 0x11, 0x600);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x8fc0);
++
++      /* VgaDecRate = 1 */
++      __phy_write(phydev, 0x11, 0x4c2a);
++      __phy_write(phydev, 0x12, 0x3e);
++      __phy_write(phydev, 0x10, 0x8fa4);
++
++      /* FfeUpdGainForce = 4 */
++      __phy_write(phydev, 0x11, 0x240);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x9680);
++
++      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++}
++
++static void mt7988_phy_finetune(struct phy_device *phydev)
++{
++      u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
++                      0x020d, 0x0206, 0x0384, 0x03d0,
++                      0x03c6, 0x030a, 0x0011, 0x0005 };
++      int i;
++
++      /* Set default MLT3 shaper first */
++      for (i = 0; i < 12; i++)
++              phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
++
++      /* TCT finetune */
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
++
++      /* Disable TX power saving */
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
++                     MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
++
++      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++
++      /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
++      __phy_write(phydev, 0x11, 0x671);
++      __phy_write(phydev, 0x12, 0xc);
++      __phy_write(phydev, 0x10, 0x8fae);
++
++      /* ResetSyncOffset = 5 */
++      __phy_write(phydev, 0x11, 0x500);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x8fc0);
++
++      /* VgaDecRate is 1 at default on mt7988 */
++
++      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
++      /* TxClkOffset = 2 */
++      __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
++                   FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
++      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++}
++
++static void mt798x_phy_eee(struct phy_device *phydev)
++{
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,
++                     MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |
++                     MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,
++                     FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |
++                     FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
++                     MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++                                0xff));
++
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                         MTK_PHY_RG_TESTMUX_ADC_CTRL,
++                         MTK_PHY_RG_TXEN_DIG_MASK);
++
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++                       MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);
++
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++                         MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,
++                     MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |
++                     MTK_PHY_LPI_SLV_SEND_TX_EN,
++                     FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
++                     MTK_PHY_LPI_SEND_LOC_TIMER_MASK |
++                     MTK_PHY_LPI_TXPCS_LOC_RCV,
++                     FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117));
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
++                     MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
++                     FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
++                     FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,
++                     MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
++                     FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
++                                0x33) |
++                     MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |
++                     MTK_PHY_LPI_VCO_EEE_STG0_EN);
++
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,
++                       MTK_PHY_EEE_WAKE_MAS_INT_DC |
++                       MTK_PHY_EEE_WAKE_SLV_INT_DC);
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,
++                     MTK_PHY_SMI_DETCNT_MAX_MASK,
++                     FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |
++                     MTK_PHY_SMI_DET_MAX_EN);
++
++      phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,
++                       MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |
++                       MTK_PHY_TREC_UPDATE_ENAB_CLR |
++                       MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |
++                       MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
++
++      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++      /* Regsigdet_sel_1000 = 0 */
++      __phy_write(phydev, 0x11, 0xb);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x9690);
++
++      /* REG_EEE_st2TrKf1000 = 3 */
++      __phy_write(phydev, 0x11, 0x114f);
++      __phy_write(phydev, 0x12, 0x2);
++      __phy_write(phydev, 0x10, 0x969a);
++
++      /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
++      __phy_write(phydev, 0x11, 0x3028);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x969e);
++
++      /* RegEEE_slv_wake_int_timer_tar = 8 */
++      __phy_write(phydev, 0x11, 0x5010);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x96a0);
++
++      /* RegEEE_trfreeze_timer2 = 586 */
++      __phy_write(phydev, 0x11, 0x24a);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x96a8);
++
++      /* RegEEE100Stg1_tar = 16 */
++      __phy_write(phydev, 0x11, 0x3210);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x96b8);
++
++      /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */
++      __phy_write(phydev, 0x11, 0x1463);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x96ca);
++
++      /* DfeTailEnableVgaThresh1000 = 27 */
++      __phy_write(phydev, 0x11, 0x36);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x8f80);
++      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
++      __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
++                   FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
++
++      __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
++                   FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));
++      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++                     MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
++                     MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++                     FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
++}
++
++static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
++                u8 start_pair, u8 end_pair)
++{
++      u8 pair_n;
++      int ret;
++
++      for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
++              /* TX_OFFSET & TX_AMP have no SW calibration. */
++              switch (cal_item) {
++              case TX_VCM:
++                      ret = tx_vcm_cal_sw(phydev, pair_n);
++                      break;
++              default:
++                      return -EINVAL;
++              }
++              if (ret)
++                      return ret;
++      }
++      return 0;
++}
++
++static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
++                   u8 start_pair, u8 end_pair, u32 *buf)
++{
++      u8 pair_n;
++      int ret;
++
++      for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
++              /* TX_VCM has no efuse calibration. */
++              switch (cal_item) {
++              case REXT:
++                      ret = rext_cal_efuse(phydev, buf);
++                      break;
++              case TX_OFFSET:
++                      ret = tx_offset_cal_efuse(phydev, buf);
++                      break;
++              case TX_AMP:
++                      ret = tx_amp_cal_efuse(phydev, buf);
++                      break;
++              case TX_R50:
++                      ret = tx_r50_cal_efuse(phydev, buf, pair_n);
++                      break;
++              default:
++                      return -EINVAL;
++              }
++              if (ret)
++                      return ret;
++      }
++
++      return 0;
++}
++
++static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
++                   enum CAL_MODE cal_mode, u8 start_pair,
++                   u8 end_pair, u32 *buf)
++{
++      int ret;
++
++      switch (cal_mode) {
++      case EFUSE_M:
++              ret = cal_efuse(phydev, cal_item, start_pair,
++                              end_pair, buf);
++              break;
++      case SW_M:
++              ret = cal_sw(phydev, cal_item, start_pair, end_pair);
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      if (ret) {
++              phydev_err(phydev, "cal %d failed\n", cal_item);
++              return -EIO;
++      }
++
++      return 0;
++}
++
++static int mt798x_phy_calibration(struct phy_device *phydev)
++{
++      int ret = 0;
++      u32 *buf;
++      size_t len;
++      struct nvmem_cell *cell;
++
++      cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
++      if (IS_ERR(cell)) {
++              if (PTR_ERR(cell) == -EPROBE_DEFER)
++                      return PTR_ERR(cell);
++              return 0;
++      }
++
++      buf = (u32 *)nvmem_cell_read(cell, &len);
++      if (IS_ERR(buf))
++              return PTR_ERR(buf);
++      nvmem_cell_put(cell);
++
++      if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
++              phydev_err(phydev, "invalid efuse data\n");
++              ret = -EINVAL;
++              goto out;
++      }
++
++      ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++      if (ret)
++              goto out;
++      ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++      if (ret)
++              goto out;
++      ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++      if (ret)
++              goto out;
++      ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
++      if (ret)
++              goto out;
++      ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
++      if (ret)
++              goto out;
++
++out:
++      kfree(buf);
++      return ret;
++}
++
++static int mt798x_phy_config_init(struct phy_device *phydev)
++{
++      switch (phydev->drv->phy_id) {
++      case MTK_GPHY_ID_MT7981:
++              mt7981_phy_finetune(phydev);
++              break;
++      case MTK_GPHY_ID_MT7988:
++              mt7988_phy_finetune(phydev);
++              break;
++      }
++
++      mt798x_phy_common_finetune(phydev);
++      mt798x_phy_eee(phydev);
++
++      return mt798x_phy_calibration(phydev);
++}
++
++static struct phy_driver mtk_socphy_driver[] = {
++      {
++              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
++              .name           = "MediaTek MT7981 PHY",
++              .config_init    = mt798x_phy_config_init,
++              .config_intr    = genphy_no_config_intr,
++              .handle_interrupt = genphy_handle_interrupt_no_ack,
++              .probe          = mt798x_phy_calibration,
++              .suspend        = genphy_suspend,
++              .resume         = genphy_resume,
++              .read_page      = mtk_socphy_read_page,
++              .write_page     = mtk_socphy_write_page,
++      },
++      {
++              PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
++              .name           = "MediaTek MT7988 PHY",
++              .config_init    = mt798x_phy_config_init,
++              .config_intr    = genphy_no_config_intr,
++              .handle_interrupt = genphy_handle_interrupt_no_ack,
++              .probe          = mt798x_phy_calibration,
++              .suspend        = genphy_suspend,
++              .resume         = genphy_resume,
++              .read_page      = mtk_socphy_read_page,
++              .write_page     = mtk_socphy_write_page,
++      },
++};
++
++module_phy_driver(mtk_socphy_driver);
++
++static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
++      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
++      { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
++      { }
++};
++
++MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
++MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);
+--- a/drivers/net/phy/mediatek-ge.c
++++ b/drivers/net/phy/mediatek-ge.c
+@@ -136,7 +136,8 @@ static struct phy_driver mtk_gephy_drive
+ module_phy_driver(mtk_gephy_driver);
+ static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
+-      { PHY_ID_MATCH_VENDOR(0x03a29400) },
++      { PHY_ID_MATCH_EXACT(0x03a29441) },
++      { PHY_ID_MATCH_EXACT(0x03a29412) },
+       { }
+ };
diff --git a/target/linux/mediatek/patches-6.6/731-v6.5-net-phy-mediatek-ge-soc-support-PHY-LEDs.patch b/target/linux/mediatek/patches-6.6/731-v6.5-net-phy-mediatek-ge-soc-support-PHY-LEDs.patch
new file mode 100644 (file)
index 0000000..286ce96
--- /dev/null
@@ -0,0 +1,524 @@
+From c66937b0f8dbb4c6c043663c702b1053fb47fab2 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 14 Aug 2023 02:58:14 +0100
+Subject: [PATCH] net: phy: mediatek-ge-soc: support PHY LEDs
+
+Implement netdev trigger and primitive bliking offloading as well as
+simple set_brigthness function for both PHY LEDs of the in-SoC PHYs
+found in MT7981 and MT7988.
+
+For MT7988, read boottrap register and apply LED polarities accordingly
+to get uniform behavior from all LEDs on MT7988.
+This requires syscon phandle 'mediatek,pio' present in parenting MDIO bus
+which should point to the syscon holding the boottrap register.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/dc324d48c00cd7350f3a506eaa785324cae97372.1691977904.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/mediatek-ge-soc.c | 435 +++++++++++++++++++++++++++++-
+ 1 file changed, 426 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/mediatek-ge-soc.c
++++ b/drivers/net/phy/mediatek-ge-soc.c
+@@ -1,11 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ #include <linux/bitfield.h>
++#include <linux/bitmap.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/nvmem-consumer.h>
+ #include <linux/of_address.h>
+ #include <linux/of_platform.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/phy.h>
++#include <linux/regmap.h>
+ #define MTK_GPHY_ID_MT7981                    0x03a29461
+ #define MTK_GPHY_ID_MT7988                    0x03a29481
+@@ -208,9 +211,42 @@
+ #define MTK_PHY_DA_TX_R50_PAIR_C              0x53f
+ #define MTK_PHY_DA_TX_R50_PAIR_D              0x540
++/* Registers on MDIO_MMD_VEND2 */
++#define MTK_PHY_LED0_ON_CTRL                  0x24
++#define MTK_PHY_LED1_ON_CTRL                  0x26
++#define   MTK_PHY_LED_ON_MASK                 GENMASK(6, 0)
++#define   MTK_PHY_LED_ON_LINK1000             BIT(0)
++#define   MTK_PHY_LED_ON_LINK100              BIT(1)
++#define   MTK_PHY_LED_ON_LINK10                       BIT(2)
++#define   MTK_PHY_LED_ON_LINKDOWN             BIT(3)
++#define   MTK_PHY_LED_ON_FDX                  BIT(4) /* Full duplex */
++#define   MTK_PHY_LED_ON_HDX                  BIT(5) /* Half duplex */
++#define   MTK_PHY_LED_ON_FORCE_ON             BIT(6)
++#define   MTK_PHY_LED_ON_POLARITY             BIT(14)
++#define   MTK_PHY_LED_ON_ENABLE                       BIT(15)
++
++#define MTK_PHY_LED0_BLINK_CTRL                       0x25
++#define MTK_PHY_LED1_BLINK_CTRL                       0x27
++#define   MTK_PHY_LED_BLINK_1000TX            BIT(0)
++#define   MTK_PHY_LED_BLINK_1000RX            BIT(1)
++#define   MTK_PHY_LED_BLINK_100TX             BIT(2)
++#define   MTK_PHY_LED_BLINK_100RX             BIT(3)
++#define   MTK_PHY_LED_BLINK_10TX              BIT(4)
++#define   MTK_PHY_LED_BLINK_10RX              BIT(5)
++#define   MTK_PHY_LED_BLINK_COLLISION         BIT(6)
++#define   MTK_PHY_LED_BLINK_RX_CRC_ERR                BIT(7)
++#define   MTK_PHY_LED_BLINK_RX_IDLE_ERR               BIT(8)
++#define   MTK_PHY_LED_BLINK_FORCE_BLINK               BIT(9)
++
++#define MTK_PHY_LED1_DEFAULT_POLARITIES               BIT(1)
++
+ #define MTK_PHY_RG_BG_RASEL                   0x115
+ #define   MTK_PHY_RG_BG_RASEL_MASK            GENMASK(2, 0)
++/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
++#define RG_GPIO_MISC_TPBANK0                  0x6f0
++#define   RG_GPIO_MISC_TPBANK0_BOOTMODE               GENMASK(11, 8)
++
+ /* These macro privides efuse parsing for internal phy. */
+ #define EFS_DA_TX_I2MPB_A(x)                  (((x) >> 0) & GENMASK(5, 0))
+ #define EFS_DA_TX_I2MPB_B(x)                  (((x) >> 6) & GENMASK(5, 0))
+@@ -238,13 +274,6 @@ enum {
+       PAIR_D,
+ };
+-enum {
+-      GPHY_PORT0,
+-      GPHY_PORT1,
+-      GPHY_PORT2,
+-      GPHY_PORT3,
+-};
+-
+ enum calibration_mode {
+       EFUSE_K,
+       SW_K
+@@ -263,6 +292,19 @@ enum CAL_MODE {
+       SW_M
+ };
++#define MTK_PHY_LED_STATE_FORCE_ON    0
++#define MTK_PHY_LED_STATE_FORCE_BLINK 1
++#define MTK_PHY_LED_STATE_NETDEV      2
++
++struct mtk_socphy_priv {
++      unsigned long           led_state;
++};
++
++struct mtk_socphy_shared {
++      u32                     boottrap;
++      struct mtk_socphy_priv  priv[4];
++};
++
+ static int mtk_socphy_read_page(struct phy_device *phydev)
+ {
+       return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+@@ -1073,6 +1115,371 @@ static int mt798x_phy_config_init(struct
+       return mt798x_phy_calibration(phydev);
+ }
++static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
++                                  bool on)
++{
++      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++      struct mtk_socphy_priv *priv = phydev->priv;
++      bool changed;
++
++      if (on)
++              changed = !test_and_set_bit(bit_on, &priv->led_state);
++      else
++              changed = !!test_and_clear_bit(bit_on, &priv->led_state);
++
++      changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
++                                      (index ? 16 : 0), &priv->led_state);
++      if (changed)
++              return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++                                    MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++                                    MTK_PHY_LED_ON_MASK,
++                                    on ? MTK_PHY_LED_ON_FORCE_ON : 0);
++      else
++              return 0;
++}
++
++static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
++                                     bool blinking)
++{
++      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
++      struct mtk_socphy_priv *priv = phydev->priv;
++      bool changed;
++
++      if (blinking)
++              changed = !test_and_set_bit(bit_blink, &priv->led_state);
++      else
++              changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
++
++      changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
++                            (index ? 16 : 0), &priv->led_state);
++      if (changed)
++              return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++                                   MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
++                                   blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
++      else
++              return 0;
++}
++
++static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
++                                  unsigned long *delay_on,
++                                  unsigned long *delay_off)
++{
++      bool blinking = false;
++      int err = 0;
++
++      if (index > 1)
++              return -EINVAL;
++
++      if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
++              blinking = true;
++              *delay_on = 50;
++              *delay_off = 50;
++      }
++
++      err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
++      if (err)
++              return err;
++
++      return mt798x_phy_hw_led_on_set(phydev, index, false);
++}
++
++static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
++                                       u8 index, enum led_brightness value)
++{
++      int err;
++
++      err = mt798x_phy_hw_led_blink_set(phydev, index, false);
++      if (err)
++              return err;
++
++      return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
++}
++
++static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++                                               BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++                                               BIT(TRIGGER_NETDEV_LINK)        |
++                                               BIT(TRIGGER_NETDEV_LINK_10)     |
++                                               BIT(TRIGGER_NETDEV_LINK_100)    |
++                                               BIT(TRIGGER_NETDEV_LINK_1000)   |
++                                               BIT(TRIGGER_NETDEV_RX)          |
++                                               BIT(TRIGGER_NETDEV_TX));
++
++static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++                                        unsigned long rules)
++{
++      if (index > 1)
++              return -EINVAL;
++
++      /* All combinations of the supported triggers are allowed */
++      if (rules & ~supported_triggers)
++              return -EOPNOTSUPP;
++
++      return 0;
++};
++
++static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
++                                       unsigned long *rules)
++{
++      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
++      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++      struct mtk_socphy_priv *priv = phydev->priv;
++      int on, blink;
++
++      if (index > 1)
++              return -EINVAL;
++
++      on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++                        index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
++
++      if (on < 0)
++              return -EIO;
++
++      blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++                           index ? MTK_PHY_LED1_BLINK_CTRL :
++                                   MTK_PHY_LED0_BLINK_CTRL);
++      if (blink < 0)
++              return -EIO;
++
++      if ((on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 |
++                 MTK_PHY_LED_ON_LINK10)) ||
++          (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX |
++                    MTK_PHY_LED_BLINK_10RX | MTK_PHY_LED_BLINK_1000TX |
++                    MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX)))
++              set_bit(bit_netdev, &priv->led_state);
++      else
++              clear_bit(bit_netdev, &priv->led_state);
++
++      if (on & MTK_PHY_LED_ON_FORCE_ON)
++              set_bit(bit_on, &priv->led_state);
++      else
++              clear_bit(bit_on, &priv->led_state);
++
++      if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
++              set_bit(bit_blink, &priv->led_state);
++      else
++              clear_bit(bit_blink, &priv->led_state);
++
++      if (!rules)
++              return 0;
++
++      if (on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK10))
++              *rules |= BIT(TRIGGER_NETDEV_LINK);
++
++      if (on & MTK_PHY_LED_ON_LINK10)
++              *rules |= BIT(TRIGGER_NETDEV_LINK_10);
++
++      if (on & MTK_PHY_LED_ON_LINK100)
++              *rules |= BIT(TRIGGER_NETDEV_LINK_100);
++
++      if (on & MTK_PHY_LED_ON_LINK1000)
++              *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
++
++      if (on & MTK_PHY_LED_ON_FDX)
++              *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
++
++      if (on & MTK_PHY_LED_ON_HDX)
++              *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
++
++      if (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX | MTK_PHY_LED_BLINK_10RX))
++              *rules |= BIT(TRIGGER_NETDEV_RX);
++
++      if (blink & (MTK_PHY_LED_BLINK_1000TX | MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX))
++              *rules |= BIT(TRIGGER_NETDEV_TX);
++
++      return 0;
++};
++
++static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
++                                       unsigned long rules)
++{
++      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++      struct mtk_socphy_priv *priv = phydev->priv;
++      u16 on = 0, blink = 0;
++      int ret;
++
++      if (index > 1)
++              return -EINVAL;
++
++      if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
++              on |= MTK_PHY_LED_ON_FDX;
++
++      if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
++              on |= MTK_PHY_LED_ON_HDX;
++
++      if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
++              on |= MTK_PHY_LED_ON_LINK10;
++
++      if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
++              on |= MTK_PHY_LED_ON_LINK100;
++
++      if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
++              on |= MTK_PHY_LED_ON_LINK1000;
++
++      if (rules & BIT(TRIGGER_NETDEV_RX)) {
++              blink |= MTK_PHY_LED_BLINK_10RX  |
++                       MTK_PHY_LED_BLINK_100RX |
++                       MTK_PHY_LED_BLINK_1000RX;
++      }
++
++      if (rules & BIT(TRIGGER_NETDEV_TX)) {
++              blink |= MTK_PHY_LED_BLINK_10TX  |
++                       MTK_PHY_LED_BLINK_100TX |
++                       MTK_PHY_LED_BLINK_1000TX;
++      }
++
++      if (blink || on)
++              set_bit(bit_netdev, &priv->led_state);
++      else
++              clear_bit(bit_netdev, &priv->led_state);
++
++      ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++                              MTK_PHY_LED1_ON_CTRL :
++                              MTK_PHY_LED0_ON_CTRL,
++                           MTK_PHY_LED_ON_FDX     |
++                           MTK_PHY_LED_ON_HDX     |
++                           MTK_PHY_LED_ON_LINK10  |
++                           MTK_PHY_LED_ON_LINK100 |
++                           MTK_PHY_LED_ON_LINK1000,
++                           on);
++
++      if (ret)
++              return ret;
++
++      return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++                              MTK_PHY_LED1_BLINK_CTRL :
++                              MTK_PHY_LED0_BLINK_CTRL, blink);
++};
++
++static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
++{
++      struct mtk_socphy_shared *priv = phydev->shared->priv;
++      u32 polarities;
++
++      if (led_num == 0)
++              polarities = ~(priv->boottrap);
++      else
++              polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
++
++      if (polarities & BIT(phydev->mdio.addr))
++              return true;
++
++      return false;
++}
++
++static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
++{
++      struct pinctrl *pinctrl;
++      int index;
++
++      /* Setup LED polarity according to bootstrap use of LED pins */
++      for (index = 0; index < 2; ++index)
++              phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++                              MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++                             MTK_PHY_LED_ON_POLARITY,
++                             mt7988_phy_led_get_polarity(phydev, index) ?
++                              MTK_PHY_LED_ON_POLARITY : 0);
++
++      /* Only now setup pinctrl to avoid bogus blinking */
++      pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
++      if (IS_ERR(pinctrl))
++              dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
++
++      return 0;
++}
++
++static int mt7988_phy_probe_shared(struct phy_device *phydev)
++{
++      struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
++      struct mtk_socphy_shared *shared = phydev->shared->priv;
++      struct regmap *regmap;
++      u32 reg;
++      int ret;
++
++      /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
++       * LED_C and LED_D respectively. At the same time those pins are used to
++       * bootstrap configuration of the reference clock source (LED_A),
++       * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
++       * In practise this is done using a LED and a resistor pulling the pin
++       * either to GND or to VIO.
++       * The detected value at boot time is accessible at run-time using the
++       * TPBANK0 register located in the gpio base of the pinctrl, in order
++       * to read it here it needs to be referenced by a phandle called
++       * 'mediatek,pio' in the MDIO bus hosting the PHY.
++       * The 4 bits in TPBANK0 are kept as package shared data and are used to
++       * set LED polarity for each of the LED0.
++       */
++      regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
++      if (IS_ERR(regmap))
++              return PTR_ERR(regmap);
++
++      ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
++      if (ret)
++              return ret;
++
++      shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
++
++      return 0;
++}
++
++static void mt798x_phy_leds_state_init(struct phy_device *phydev)
++{
++      int i;
++
++      for (i = 0; i < 2; ++i)
++              mt798x_phy_led_hw_control_get(phydev, i, NULL);
++}
++
++static int mt7988_phy_probe(struct phy_device *phydev)
++{
++      struct mtk_socphy_shared *shared;
++      struct mtk_socphy_priv *priv;
++      int err;
++
++      if (phydev->mdio.addr > 3)
++              return -EINVAL;
++
++      err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
++                                  sizeof(struct mtk_socphy_shared));
++      if (err)
++              return err;
++
++      if (phy_package_probe_once(phydev)) {
++              err = mt7988_phy_probe_shared(phydev);
++              if (err)
++                      return err;
++      }
++
++      shared = phydev->shared->priv;
++      priv = &shared->priv[phydev->mdio.addr];
++
++      phydev->priv = priv;
++
++      mt798x_phy_leds_state_init(phydev);
++
++      err = mt7988_phy_fix_leds_polarities(phydev);
++      if (err)
++              return err;
++
++      return mt798x_phy_calibration(phydev);
++}
++
++static int mt7981_phy_probe(struct phy_device *phydev)
++{
++      struct mtk_socphy_priv *priv;
++
++      priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
++                          GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++
++      phydev->priv = priv;
++
++      mt798x_phy_leds_state_init(phydev);
++
++      return mt798x_phy_calibration(phydev);
++}
++
+ static struct phy_driver mtk_socphy_driver[] = {
+       {
+               PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+@@ -1080,11 +1487,16 @@ static struct phy_driver mtk_socphy_driv
+               .config_init    = mt798x_phy_config_init,
+               .config_intr    = genphy_no_config_intr,
+               .handle_interrupt = genphy_handle_interrupt_no_ack,
+-              .probe          = mt798x_phy_calibration,
++              .probe          = mt7981_phy_probe,
+               .suspend        = genphy_suspend,
+               .resume         = genphy_resume,
+               .read_page      = mtk_socphy_read_page,
+               .write_page     = mtk_socphy_write_page,
++              .led_blink_set  = mt798x_phy_led_blink_set,
++              .led_brightness_set = mt798x_phy_led_brightness_set,
++              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++              .led_hw_control_set = mt798x_phy_led_hw_control_set,
++              .led_hw_control_get = mt798x_phy_led_hw_control_get,
+       },
+       {
+               PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
+@@ -1092,11 +1504,16 @@ static struct phy_driver mtk_socphy_driv
+               .config_init    = mt798x_phy_config_init,
+               .config_intr    = genphy_no_config_intr,
+               .handle_interrupt = genphy_handle_interrupt_no_ack,
+-              .probe          = mt798x_phy_calibration,
++              .probe          = mt7988_phy_probe,
+               .suspend        = genphy_suspend,
+               .resume         = genphy_resume,
+               .read_page      = mtk_socphy_read_page,
+               .write_page     = mtk_socphy_write_page,
++              .led_blink_set  = mt798x_phy_led_blink_set,
++              .led_brightness_set = mt798x_phy_led_brightness_set,
++              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++              .led_hw_control_set = mt798x_phy_led_hw_control_set,
++              .led_hw_control_get = mt798x_phy_led_hw_control_get,
+       },
+ };
diff --git a/target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch b/target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch
new file mode 100644 (file)
index 0000000..76d8b0e
--- /dev/null
@@ -0,0 +1,63 @@
+From a969b663c866129ed9eb217785a6574fbe826f1d Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 6 Apr 2023 23:36:50 +0100
+Subject: [PATCH] net: phy: mxl-gpy: don't use SGMII AN if using phylink
+
+MAC drivers using phylink expect SGMII in-band-status to be switched off
+when attached to a PHY. Make sure this is the case also for mxl-gpy which
+keeps SGMII in-band-status in case of SGMII interface mode is used.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/mxl-gpy.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -371,8 +371,11 @@ static bool gpy_2500basex_chk(struct phy
+       phydev->speed = SPEED_2500;
+       phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
+-      phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
+-                     VSPEC1_SGMII_CTRL_ANEN, 0);
++
++      if (!phydev->phylink)
++              phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
++                             VSPEC1_SGMII_CTRL_ANEN, 0);
++
+       return true;
+ }
+@@ -396,6 +399,14 @@ static int gpy_config_aneg(struct phy_de
+       u32 adv;
+       int ret;
++      /* Disable SGMII auto-negotiation if using phylink */
++      if (phydev->phylink) {
++              ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
++                                   VSPEC1_SGMII_CTRL_ANEN, 0);
++              if (ret < 0)
++                      return ret;
++      }
++
+       if (phydev->autoneg == AUTONEG_DISABLE) {
+               /* Configure half duplex with genphy_setup_forced,
+                * because genphy_c45_pma_setup_forced does not support.
+@@ -486,6 +497,8 @@ static void gpy_update_interface(struct
+       switch (phydev->speed) {
+       case SPEED_2500:
+               phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
++              if (phydev->phylink)
++                      break;
+               ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
+                                    VSPEC1_SGMII_CTRL_ANEN, 0);
+               if (ret < 0)
+@@ -497,7 +510,7 @@ static void gpy_update_interface(struct
+       case SPEED_100:
+       case SPEED_10:
+               phydev->interface = PHY_INTERFACE_MODE_SGMII;
+-              if (gpy_sgmii_aneg_en(phydev))
++              if (phydev->phylink || gpy_sgmii_aneg_en(phydev))
+                       break;
+               /* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed
+                * if ANEG is disabled (in 2500-BaseX mode).
diff --git a/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch b/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch
new file mode 100644 (file)
index 0000000..b4c07a4
--- /dev/null
@@ -0,0 +1,39 @@
+From 128dc09b0af36772062142ce9e85b19c84ac789a Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 28 Feb 2023 17:53:37 +0000
+Subject: [PATCH] net: phy: add driver for MediaTek 2.5G PHY
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/Kconfig          |   7 ++
+ drivers/net/phy/Makefile         |   1 +
+ drivers/net/phy/mediatek-2p5ge.c | 220 +++++++++++++++++++++++++++++++
+ 3 files changed, 226 insertions(+)
+ create mode 100644 drivers/net/phy/mediatek-2p5ge.c
+
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -326,6 +326,13 @@ config MEDIATEK_GE_SOC_PHY
+         present in the SoCs efuse and will dynamically calibrate VCM
+         (common-mode voltage) during startup.
++config MEDIATEK_2P5G_PHY
++      tristate "MediaTek 2.5G Ethernet PHY"
++      depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
++      default NET_MEDIATEK_SOC
++      help
++        Supports the MediaTek 2.5G Ethernet PHY.
++
+ config MICREL_PHY
+       tristate "Micrel PHYs"
+       depends on PTP_1588_CLOCK_OPTIONAL
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -79,6 +79,7 @@ obj-$(CONFIG_MARVELL_10G_PHY)        += marvell
+ obj-$(CONFIG_MARVELL_PHY)     += marvell.o
+ obj-$(CONFIG_MARVELL_88X2222_PHY)     += marvell-88x2222.o
+ obj-$(CONFIG_MAXLINEAR_GPHY)  += mxl-gpy.o
++obj-$(CONFIG_MEDIATEK_2P5G_PHY)       += mediatek-2p5ge.o
+ obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
+ obj-$(CONFIG_MEDIATEK_GE_SOC_PHY)     += mediatek-ge-soc.o
+ obj-$(CONFIG_MESON_GXL_PHY)   += meson-gxl.o
diff --git a/target/linux/mediatek/patches-6.6/734-v6.8-net-phy-mediatek-ge-soc-sync-driver-with-MediaTek-SD.patch b/target/linux/mediatek/patches-6.6/734-v6.8-net-phy-mediatek-ge-soc-sync-driver-with-MediaTek-SD.patch
new file mode 100644 (file)
index 0000000..5daa62b
--- /dev/null
@@ -0,0 +1,270 @@
+From f2195279c234c0f618946424b8236026126bc595 Mon Sep 17 00:00:00 2001
+Message-ID: <f2195279c234c0f618946424b8236026126bc595.1706071311.git.daniel@makrotopia.org>
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 24 Jan 2024 02:27:04 +0000
+Subject: [PATCH net] net: phy: mediatek-ge-soc: sync driver with MediaTek SDK
+To: Daniel Golle <daniel@makrotopia.org>,
+    Qingfang Deng <dqfext@gmail.com>,
+    SkyLake Huang <SkyLake.Huang@mediatek.com>,
+    Andrew Lunn <andrew@lunn.ch>,
+    Heiner Kallweit <hkallweit1@gmail.com>,
+    Russell King <linux@armlinux.org.uk>,
+    David S. Miller <davem@davemloft.net>,
+    Eric Dumazet <edumazet@google.com>,
+    Jakub Kicinski <kuba@kernel.org>,
+    Paolo Abeni <pabeni@redhat.com>,
+    Matthias Brugger <matthias.bgg@gmail.com>,
+    AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
+    netdev@vger.kernel.org,
+    linux-kernel@vger.kernel.org,
+    linux-arm-kernel@lists.infradead.org,
+    linux-mediatek@lists.infradead.org
+
+Sync initialization and calibration routines with MediaTek's reference
+driver. Improves compliance and resolves link stability issues with
+CH340 IoT devices connected to MT798x built-in PHYs.
+
+Fixes: 98c485eaf509 ("net: phy: add driver for MediaTek SoC built-in GE PHYs")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/mediatek-ge-soc.c | 147 ++++++++++++++++--------------
+ 1 file changed, 81 insertions(+), 66 deletions(-)
+
+--- a/drivers/net/phy/mediatek-ge-soc.c
++++ b/drivers/net/phy/mediatek-ge-soc.c
+@@ -491,7 +491,7 @@ static int tx_r50_fill_result(struct phy
+       u16 reg, val;
+       if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
+-              bias = -2;
++              bias = -1;
+       val = clamp_val(bias + tx_r50_cal_val, 0, 63);
+@@ -707,6 +707,11 @@ restore:
+ static void mt798x_phy_common_finetune(struct phy_device *phydev)
+ {
+       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++      /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
++      __phy_write(phydev, 0x11, 0xc71);
++      __phy_write(phydev, 0x12, 0xc);
++      __phy_write(phydev, 0x10, 0x8fae);
++
+       /* EnabRandUpdTrig = 1 */
+       __phy_write(phydev, 0x11, 0x2f00);
+       __phy_write(phydev, 0x12, 0xe);
+@@ -717,15 +722,56 @@ static void mt798x_phy_common_finetune(s
+       __phy_write(phydev, 0x12, 0x0);
+       __phy_write(phydev, 0x10, 0x83aa);
+-      /* TrFreeze = 0 */
++      /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
++      __phy_write(phydev, 0x11, 0x240);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x9680);
++
++      /* TrFreeze = 0 (mt7988 default) */
+       __phy_write(phydev, 0x11, 0x0);
+       __phy_write(phydev, 0x12, 0x0);
+       __phy_write(phydev, 0x10, 0x9686);
++      /* SSTrKp100 = 5 */
++      /* SSTrKf100 = 6 */
++      /* SSTrKp1000Mas = 5 */
++      /* SSTrKf1000Mas = 6 */
+       /* SSTrKp1000Slv = 5 */
++      /* SSTrKf1000Slv = 6 */
+       __phy_write(phydev, 0x11, 0xbaef);
+       __phy_write(phydev, 0x12, 0x2e);
+       __phy_write(phydev, 0x10, 0x968c);
++      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++}
++
++static void mt7981_phy_finetune(struct phy_device *phydev)
++{
++      u16 val[8] = { 0x01ce, 0x01c1,
++                     0x020f, 0x0202,
++                     0x03d0, 0x03c0,
++                     0x0013, 0x0005 };
++      int i, k;
++
++      /* 100M eye finetune:
++       * Keep middle level of TX MLT3 shapper as default.
++       * Only change TX MLT3 overshoot level here.
++       */
++      for (k = 0, i = 1; i < 12; i++) {
++              if (i % 3 == 0)
++                      continue;
++              phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
++      }
++
++      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++      /* ResetSyncOffset = 6 */
++      __phy_write(phydev, 0x11, 0x600);
++      __phy_write(phydev, 0x12, 0x0);
++      __phy_write(phydev, 0x10, 0x8fc0);
++
++      /* VgaDecRate = 1 */
++      __phy_write(phydev, 0x11, 0x4c2a);
++      __phy_write(phydev, 0x12, 0x3e);
++      __phy_write(phydev, 0x10, 0x8fa4);
+       /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
+        * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
+@@ -740,7 +786,7 @@ static void mt798x_phy_common_finetune(s
+       __phy_write(phydev, 0x10, 0x8ec0);
+       phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-      /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
++      /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
+       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+                      MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
+                      BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
+@@ -773,48 +819,6 @@ static void mt798x_phy_common_finetune(s
+       phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
+ }
+-static void mt7981_phy_finetune(struct phy_device *phydev)
+-{
+-      u16 val[8] = { 0x01ce, 0x01c1,
+-                     0x020f, 0x0202,
+-                     0x03d0, 0x03c0,
+-                     0x0013, 0x0005 };
+-      int i, k;
+-
+-      /* 100M eye finetune:
+-       * Keep middle level of TX MLT3 shapper as default.
+-       * Only change TX MLT3 overshoot level here.
+-       */
+-      for (k = 0, i = 1; i < 12; i++) {
+-              if (i % 3 == 0)
+-                      continue;
+-              phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
+-      }
+-
+-      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+-      /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
+-      __phy_write(phydev, 0x11, 0xc71);
+-      __phy_write(phydev, 0x12, 0xc);
+-      __phy_write(phydev, 0x10, 0x8fae);
+-
+-      /* ResetSyncOffset = 6 */
+-      __phy_write(phydev, 0x11, 0x600);
+-      __phy_write(phydev, 0x12, 0x0);
+-      __phy_write(phydev, 0x10, 0x8fc0);
+-
+-      /* VgaDecRate = 1 */
+-      __phy_write(phydev, 0x11, 0x4c2a);
+-      __phy_write(phydev, 0x12, 0x3e);
+-      __phy_write(phydev, 0x10, 0x8fa4);
+-
+-      /* FfeUpdGainForce = 4 */
+-      __phy_write(phydev, 0x11, 0x240);
+-      __phy_write(phydev, 0x12, 0x0);
+-      __phy_write(phydev, 0x10, 0x9680);
+-
+-      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-}
+-
+ static void mt7988_phy_finetune(struct phy_device *phydev)
+ {
+       u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
+@@ -829,17 +833,7 @@ static void mt7988_phy_finetune(struct p
+       /* TCT finetune */
+       phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
+-      /* Disable TX power saving */
+-      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
+-                     MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
+-
+       phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+-
+-      /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
+-      __phy_write(phydev, 0x11, 0x671);
+-      __phy_write(phydev, 0x12, 0xc);
+-      __phy_write(phydev, 0x10, 0x8fae);
+-
+       /* ResetSyncOffset = 5 */
+       __phy_write(phydev, 0x11, 0x500);
+       __phy_write(phydev, 0x12, 0x0);
+@@ -847,13 +841,27 @@ static void mt7988_phy_finetune(struct p
+       /* VgaDecRate is 1 at default on mt7988 */
+-      phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++      /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
++       * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
++       */
++      __phy_write(phydev, 0x11, 0xb90a);
++      __phy_write(phydev, 0x12, 0x6f);
++      __phy_write(phydev, 0x10, 0x8f82);
++
++      /* RemAckCntLimitCtrl = 1 */
++      __phy_write(phydev, 0x11, 0xfbba);
++      __phy_write(phydev, 0x12, 0xc3);
++      __phy_write(phydev, 0x10, 0x87f8);
+-      phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
+-      /* TxClkOffset = 2 */
+-      __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
+-                   FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
+       phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++      /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
++                     MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++                     BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
++
++      /* rg_tr_lpf_cnt_val = 1023 */
++      phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
+ }
+ static void mt798x_phy_eee(struct phy_device *phydev)
+@@ -886,11 +894,11 @@ static void mt798x_phy_eee(struct phy_de
+                      MTK_PHY_LPI_SLV_SEND_TX_EN,
+                      FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
+-      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
+-                     MTK_PHY_LPI_SEND_LOC_TIMER_MASK |
+-                     MTK_PHY_LPI_TXPCS_LOC_RCV,
+-                     FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117));
++      /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
++      phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
++                         MTK_PHY_LPI_TXPCS_LOC_RCV);
++      /* This also fixes some IoT issues, such as CH340 */
+       phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
+                      MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
+                      FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
+@@ -924,7 +932,7 @@ static void mt798x_phy_eee(struct phy_de
+       __phy_write(phydev, 0x12, 0x0);
+       __phy_write(phydev, 0x10, 0x9690);
+-      /* REG_EEE_st2TrKf1000 = 3 */
++      /* REG_EEE_st2TrKf1000 = 2 */
+       __phy_write(phydev, 0x11, 0x114f);
+       __phy_write(phydev, 0x12, 0x2);
+       __phy_write(phydev, 0x10, 0x969a);
+@@ -949,7 +957,7 @@ static void mt798x_phy_eee(struct phy_de
+       __phy_write(phydev, 0x12, 0x0);
+       __phy_write(phydev, 0x10, 0x96b8);
+-      /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */
++      /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
+       __phy_write(phydev, 0x11, 0x1463);
+       __phy_write(phydev, 0x12, 0x0);
+       __phy_write(phydev, 0x10, 0x96ca);
+@@ -1461,6 +1469,13 @@ static int mt7988_phy_probe(struct phy_d
+       if (err)
+               return err;
++      /* Disable TX power saving at probing to:
++       * 1. Meet common mode compliance test criteria
++       * 2. Make sure that TX-VCM calibration works fine
++       */
++      phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
++                     MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
++
+       return mt798x_phy_calibration(phydev);
+ }
diff --git a/target/linux/mediatek/patches-6.6/804-v6.2-pwm-add-mt7986-support.patch b/target/linux/mediatek/patches-6.6/804-v6.2-pwm-add-mt7986-support.patch
new file mode 100644 (file)
index 0000000..0c73d52
--- /dev/null
@@ -0,0 +1,23 @@
+--- a/drivers/pwm/pwm-mediatek.c
++++ b/drivers/pwm/pwm-mediatek.c
+@@ -329,6 +329,12 @@ static const struct pwm_mediatek_of_data
+       .has_ck_26m_sel = true,
+ };
++static const struct pwm_mediatek_of_data mt7986_pwm_data = {
++      .num_pwms = 2,
++      .pwm45_fixup = false,
++      .has_ck_26m_sel = true,
++};
++
+ static const struct pwm_mediatek_of_data mt8516_pwm_data = {
+       .num_pwms = 5,
+       .pwm45_fixup = false,
+@@ -342,6 +348,7 @@ static const struct of_device_id pwm_med
+       { .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
+       { .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
+       { .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
++      { .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
+       { .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
+       { .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
+       { .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
diff --git a/target/linux/mediatek/patches-6.6/826-v6.2-pinctrl-mediatek-extend-pinctrl-moore-to-support-new.patch b/target/linux/mediatek/patches-6.6/826-v6.2-pinctrl-mediatek-extend-pinctrl-moore-to-support-new.patch
new file mode 100644 (file)
index 0000000..f130fdb
--- /dev/null
@@ -0,0 +1,129 @@
+From fae82621ac33e2a4a96220c56e90d1ec6237d394 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sun, 6 Nov 2022 09:01:12 +0100
+Subject: [PATCH] pinctrl: mediatek: extend pinctrl-moore to support new bias
+ functions
+
+Commit fb34a9ae383a ("pinctrl: mediatek: support rsel feature")
+introduced SoC specify 'pull_type' attribute to mtk_pinconf_bias_set_combo
+and mtk_pinconf_bias_get_combo, and make the functions able to support
+almost all Mediatek SoCs that use pinctrl-mtk-common-v2.c.
+
+This patch enables pinctrl_moore to support these functions.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.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/r/20221106080114.7426-6-linux@fw-web.de
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-moore.c | 49 ++++++++++++++++++++----
+ 1 file changed, 42 insertions(+), 7 deletions(-)
+
+--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
++++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
+@@ -8,6 +8,7 @@
+  *
+  */
++#include <dt-bindings/pinctrl/mt65xx.h>
+ #include <linux/gpio/driver.h>
+ #include "pinctrl-moore.h"
+@@ -105,7 +106,7 @@ static int mtk_pinconf_get(struct pinctr
+ {
+       struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+       u32 param = pinconf_to_config_param(*config);
+-      int val, val2, err, reg, ret = 1;
++      int val, val2, err, pullup, reg, ret = 1;
+       const struct mtk_pin_desc *desc;
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+@@ -114,7 +115,13 @@ static int mtk_pinconf_get(struct pinctr
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+-              if (hw->soc->bias_disable_get) {
++              if (hw->soc->bias_get_combo) {
++                      err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++                      if (err)
++                              return err;
++                      if (ret != MTK_PUPD_SET_R1R0_00 && ret != MTK_DISABLE)
++                              return -EINVAL;
++              } else if (hw->soc->bias_disable_get) {
+                       err = hw->soc->bias_disable_get(hw, desc, &ret);
+                       if (err)
+                               return err;
+@@ -123,7 +130,15 @@ static int mtk_pinconf_get(struct pinctr
+               }
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              if (hw->soc->bias_get) {
++              if (hw->soc->bias_get_combo) {
++                      err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++                      if (err)
++                              return err;
++                      if (ret == MTK_PUPD_SET_R1R0_00 || ret == MTK_DISABLE)
++                              return -EINVAL;
++                      if (!pullup)
++                              return -EINVAL;
++              } else if (hw->soc->bias_get) {
+                       err = hw->soc->bias_get(hw, desc, 1, &ret);
+                       if (err)
+                               return err;
+@@ -132,7 +147,15 @@ static int mtk_pinconf_get(struct pinctr
+               }
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_get) {
++              if (hw->soc->bias_get_combo) {
++                      err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++                      if (err)
++                              return err;
++                      if (ret == MTK_PUPD_SET_R1R0_00 || ret == MTK_DISABLE)
++                              return -EINVAL;
++                      if (pullup)
++                              return -EINVAL;
++              } else if (hw->soc->bias_get) {
+                       err = hw->soc->bias_get(hw, desc, 0, &ret);
+                       if (err)
+                               return err;
+@@ -235,7 +258,11 @@ static int mtk_pinconf_set(struct pinctr
+               switch (param) {
+               case PIN_CONFIG_BIAS_DISABLE:
+-                      if (hw->soc->bias_disable_set) {
++                      if (hw->soc->bias_set_combo) {
++                              err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
++                              if (err)
++                                      return err;
++                      } else if (hw->soc->bias_disable_set) {
+                               err = hw->soc->bias_disable_set(hw, desc);
+                               if (err)
+                                       return err;
+@@ -244,7 +271,11 @@ static int mtk_pinconf_set(struct pinctr
+                       }
+                       break;
+               case PIN_CONFIG_BIAS_PULL_UP:
+-                      if (hw->soc->bias_set) {
++                      if (hw->soc->bias_set_combo) {
++                              err = hw->soc->bias_set_combo(hw, desc, 1, arg);
++                              if (err)
++                                      return err;
++                      } else if (hw->soc->bias_set) {
+                               err = hw->soc->bias_set(hw, desc, 1);
+                               if (err)
+                                       return err;
+@@ -253,7 +284,11 @@ static int mtk_pinconf_set(struct pinctr
+                       }
+                       break;
+               case PIN_CONFIG_BIAS_PULL_DOWN:
+-                      if (hw->soc->bias_set) {
++                      if (hw->soc->bias_set_combo) {
++                              err = hw->soc->bias_set_combo(hw, desc, 0, arg);
++                              if (err)
++                                      return err;
++                      } else if (hw->soc->bias_set) {
+                               err = hw->soc->bias_set(hw, desc, 0);
+                               if (err)
+                                       return err;
diff --git a/target/linux/mediatek/patches-6.6/830-v6.3-01-thermal-drivers-mtk_thermal-Fix-kernel-doc-function-.patch b/target/linux/mediatek/patches-6.6/830-v6.3-01-thermal-drivers-mtk_thermal-Fix-kernel-doc-function-.patch
new file mode 100644 (file)
index 0000000..694b73a
--- /dev/null
@@ -0,0 +1,37 @@
+From f167da186acf90847e1a6d3716e253825a6218ec Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Thu, 12 Jan 2023 22:44:49 -0800
+Subject: [PATCH 01/42] thermal/drivers/mtk_thermal: Fix kernel-doc function
+ name
+
+Use the correct function name in a kernel-doc comment to prevent
+a warning:
+
+drivers/thermal/mtk_thermal.c:562: warning: expecting prototype for raw_to_mcelsius(). Prototype was for raw_to_mcelsius_v1() instead
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Amit Kucheria <amitk@kernel.org>
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+Cc: linux-pm@vger.kernel.org
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: linux-mediatek@lists.infradead.org
+Link: https://lore.kernel.org/r/20230113064449.15061-1-rdunlap@infradead.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/thermal/mtk_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thermal/mtk_thermal.c
++++ b/drivers/thermal/mtk_thermal.c
+@@ -550,7 +550,7 @@ static const struct mtk_thermal_data mt8
+ };
+ /**
+- * raw_to_mcelsius - convert a raw ADC value to mcelsius
++ * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
+  * @mt:       The thermal controller
+  * @sensno:   sensor number
+  * @raw:      raw ADC value
diff --git a/target/linux/mediatek/patches-6.6/830-v6.3-02-thermal-drivers-mtk_thermal-Use-devm_platform_get_an.patch b/target/linux/mediatek/patches-6.6/830-v6.3-02-thermal-drivers-mtk_thermal-Use-devm_platform_get_an.patch
new file mode 100644 (file)
index 0000000..aaed9d7
--- /dev/null
@@ -0,0 +1,37 @@
+From 255509232417ee71fd606cb957d44cf6544f0c43 Mon Sep 17 00:00:00 2001
+From: ye xingchen <ye.xingchen@zte.com.cn>
+Date: Wed, 18 Jan 2023 16:37:47 +0800
+Subject: [PATCH 02/42] thermal/drivers/mtk_thermal: Use
+ devm_platform_get_and_ioremap_resource()
+
+Convert platform_get_resource(), devm_ioremap_resource() to a single
+call to devm_platform_get_and_ioremap_resource(), as this is exactly
+what this function does.
+
+Signed-off-by: ye xingchen <ye.xingchen@zte.com.cn>
+Link: https://lore.kernel.org/r/202301181637472073620@zte.com.cn
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/thermal/mtk_thermal.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/thermal/mtk_thermal.c
++++ b/drivers/thermal/mtk_thermal.c
+@@ -990,7 +990,6 @@ static int mtk_thermal_probe(struct plat
+       int ret, i, ctrl_id;
+       struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
+       struct mtk_thermal *mt;
+-      struct resource *res;
+       u64 auxadc_phys_base, apmixed_phys_base;
+       struct thermal_zone_device *tzdev;
+       void __iomem *apmixed_base, *auxadc_base;
+@@ -1009,8 +1008,7 @@ static int mtk_thermal_probe(struct plat
+       if (IS_ERR(mt->clk_auxadc))
+               return PTR_ERR(mt->clk_auxadc);
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      mt->thermal_base = devm_ioremap_resource(&pdev->dev, res);
++      mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+       if (IS_ERR(mt->thermal_base))
+               return PTR_ERR(mt->thermal_base);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.3-03-thermal-drivers-mtk-Use-function-pointer-for-raw_to_.patch b/target/linux/mediatek/patches-6.6/830-v6.3-03-thermal-drivers-mtk-Use-function-pointer-for-raw_to_.patch
new file mode 100644 (file)
index 0000000..215b0fd
--- /dev/null
@@ -0,0 +1,60 @@
+From ca86dbd309ba03bef38ae91f037e2030bb671ab7 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 18 Jan 2023 15:40:39 +0000
+Subject: [PATCH 03/42] thermal/drivers/mtk: Use function pointer for
+ raw_to_mcelsius
+
+Instead of having if-else logic selecting either raw_to_mcelsius_v1 or
+raw_to_mcelsius_v2 in mtk_thermal_bank_temperature introduce a function
+pointer raw_to_mcelsius to struct mtk_thermal which is initialized in the
+probe function.
+
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Link: https://lore.kernel.org/r/69c17529e8418da3eec703dde31e1b01e5b0f7e8.1674055882.git.daniel@makrotopia.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/thermal/mtk_thermal.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/thermal/mtk_thermal.c
++++ b/drivers/thermal/mtk_thermal.c
+@@ -292,6 +292,8 @@ struct mtk_thermal {
+       const struct mtk_thermal_data *conf;
+       struct mtk_thermal_bank banks[MAX_NUM_ZONES];
++
++      int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
+ };
+ /* MT8183 thermal sensor data */
+@@ -656,13 +658,9 @@ static int mtk_thermal_bank_temperature(
+       for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
+               raw = readl(mt->thermal_base + conf->msr[i]);
+-              if (mt->conf->version == MTK_THERMAL_V1) {
+-                      temp = raw_to_mcelsius_v1(
+-                              mt, conf->bank_data[bank->id].sensors[i], raw);
+-              } else {
+-                      temp = raw_to_mcelsius_v2(
+-                              mt, conf->bank_data[bank->id].sensors[i], raw);
+-              }
++              temp = mt->raw_to_mcelsius(
++                      mt, conf->bank_data[bank->id].sensors[i], raw);
++
+               /*
+                * The first read of a sensor often contains very high bogus
+@@ -1073,6 +1071,11 @@ static int mtk_thermal_probe(struct plat
+               mtk_thermal_release_periodic_ts(mt, auxadc_base);
+       }
++      if (mt->conf->version == MTK_THERMAL_V1)
++              mt->raw_to_mcelsius = raw_to_mcelsius_v1;
++      else
++              mt->raw_to_mcelsius = raw_to_mcelsius_v2;
++
+       for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
+               for (i = 0; i < mt->conf->num_banks; i++)
+                       mtk_thermal_init_bank(mt, i, apmixed_phys_base,
diff --git a/target/linux/mediatek/patches-6.6/830-v6.3-04-thermal-drivers-mtk-Add-support-for-MT7986-and-MT798.patch b/target/linux/mediatek/patches-6.6/830-v6.3-04-thermal-drivers-mtk-Add-support-for-MT7986-and-MT798.patch
new file mode 100644 (file)
index 0000000..ef20067
--- /dev/null
@@ -0,0 +1,236 @@
+From aec1d89dccc7cba04fdb3e52dfda328f3302ba17 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 18 Jan 2023 15:40:58 +0000
+Subject: [PATCH 04/42] thermal/drivers/mtk: Add support for MT7986 and MT7981
+
+Add support for V3 generation thermal found in MT7986 and MT7981 SoCs.
+Brings code to assign values from efuse as well as new function to
+convert raw temperature to millidegree celsius, as found in MediaTek's
+SDK sources (but cleaned up and de-duplicated)
+
+[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/baf36c7eef477aae1f8f2653b6c29e2caf48475b
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/2d341fc45266217249586eb4bd3be3ac4ca83a12.1674055882.git.daniel@makrotopia.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/thermal/mtk_thermal.c | 128 ++++++++++++++++++++++++++++++++--
+ 1 file changed, 124 insertions(+), 4 deletions(-)
+
+--- a/drivers/thermal/mtk_thermal.c
++++ b/drivers/thermal/mtk_thermal.c
+@@ -150,6 +150,20 @@
+ #define CALIB_BUF1_VALID_V2(x)                (((x) >> 4) & 0x1)
+ #define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
++/*
++ * Layout of the fuses providing the calibration data
++ * These macros can be used for MT7981 and MT7986.
++ */
++#define CALIB_BUF0_ADC_GE_V3(x)               (((x) >> 0) & 0x3ff)
++#define CALIB_BUF0_DEGC_CALI_V3(x)    (((x) >> 20) & 0x3f)
++#define CALIB_BUF0_O_SLOPE_V3(x)      (((x) >> 26) & 0x3f)
++#define CALIB_BUF1_VTS_TS1_V3(x)      (((x) >> 0) & 0x1ff)
++#define CALIB_BUF1_VTS_TS2_V3(x)      (((x) >> 21) & 0x1ff)
++#define CALIB_BUF1_VTS_TSABB_V3(x)    (((x) >> 9) & 0x1ff)
++#define CALIB_BUF1_VALID_V3(x)                (((x) >> 18) & 0x1)
++#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
++#define CALIB_BUF1_ID_V3(x)           (((x) >> 20) & 0x1)
++
+ enum {
+       VTS1,
+       VTS2,
+@@ -163,6 +177,7 @@ enum {
+ enum mtk_thermal_version {
+       MTK_THERMAL_V1 = 1,
+       MTK_THERMAL_V2,
++      MTK_THERMAL_V3,
+ };
+ /* MT2701 thermal sensors */
+@@ -245,6 +260,27 @@ enum mtk_thermal_version {
+ /* The calibration coefficient of sensor  */
+ #define MT8183_CALIBRATION    153
++/* AUXADC channel 11 is used for the temperature sensors */
++#define MT7986_TEMP_AUXADC_CHANNEL    11
++
++/* The total number of temperature sensors in the MT7986 */
++#define MT7986_NUM_SENSORS            1
++
++/* The number of banks in the MT7986 */
++#define MT7986_NUM_ZONES              1
++
++/* The number of sensing points per bank */
++#define MT7986_NUM_SENSORS_PER_ZONE   1
++
++/* MT7986 thermal sensors */
++#define MT7986_TS1                    0
++
++/* The number of controller in the MT7986 */
++#define MT7986_NUM_CONTROLLER         1
++
++/* The calibration coefficient of sensor  */
++#define MT7986_CALIBRATION            165
++
+ struct mtk_thermal;
+ struct thermal_bank_cfg {
+@@ -388,6 +424,14 @@ static const int mt7622_mux_values[MT762
+ static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
+ static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
++/* MT7986 thermal sensor data */
++static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
++static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
++static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
++static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
++static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
++static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
++
+ /*
+  * The MT8173 thermal controller has four banks. Each bank can read up to
+  * four temperature sensors simultaneously. The MT8173 has a total of 5
+@@ -551,6 +595,30 @@ static const struct mtk_thermal_data mt8
+       .version = MTK_THERMAL_V1,
+ };
++/*
++ * MT7986 uses AUXADC Channel 11 for raw data access.
++ */
++static const struct mtk_thermal_data mt7986_thermal_data = {
++      .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
++      .num_banks = MT7986_NUM_ZONES,
++      .num_sensors = MT7986_NUM_SENSORS,
++      .vts_index = mt7986_vts_index,
++      .cali_val = MT7986_CALIBRATION,
++      .num_controller = MT7986_NUM_CONTROLLER,
++      .controller_offset = mt7986_tc_offset,
++      .need_switch_bank = true,
++      .bank_data = {
++              {
++                      .num_sensors = 1,
++                      .sensors = mt7986_bank_data,
++              },
++      },
++      .msr = mt7986_msr,
++      .adcpnp = mt7986_adcpnp,
++      .sensor_mux_values = mt7986_mux_values,
++      .version = MTK_THERMAL_V3,
++};
++
+ /**
+  * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
+  * @mt:       The thermal controller
+@@ -605,6 +673,22 @@ static int raw_to_mcelsius_v2(struct mtk
+       return (format_2 - tmp) * 100;
+ }
++static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
++{
++      s32 tmp;
++
++      if (raw == 0)
++              return 0;
++
++      raw &= 0xfff;
++      tmp = 100000 * 15 / 16 * 10000;
++      tmp /= 4096 - 512 + mt->adc_ge;
++      tmp /= 1490;
++      tmp *= raw - mt->vts[sensno] - 2900;
++
++      return mt->degc_cali * 500 - tmp;
++}
++
+ /**
+  * mtk_thermal_get_bank - get bank
+  * @bank:     The bank
+@@ -885,6 +969,25 @@ static int mtk_thermal_extract_efuse_v2(
+       return 0;
+ }
++static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
++{
++      if (!CALIB_BUF1_VALID_V3(buf[1]))
++              return -EINVAL;
++
++      mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
++      mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
++      mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
++      mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
++      mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
++      mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
++      mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
++
++      if (CALIB_BUF1_ID_V3(buf[1]) == 0)
++              mt->o_slope = 0;
++
++      return 0;
++}
++
+ static int mtk_thermal_get_calibration_data(struct device *dev,
+                                           struct mtk_thermal *mt)
+ {
+@@ -895,6 +998,7 @@ static int mtk_thermal_get_calibration_d
+       /* Start with default values */
+       mt->adc_ge = 512;
++      mt->adc_oe = 512;
+       for (i = 0; i < mt->conf->num_sensors; i++)
+               mt->vts[i] = 260;
+       mt->degc_cali = 40;
+@@ -920,10 +1024,20 @@ static int mtk_thermal_get_calibration_d
+               goto out;
+       }
+-      if (mt->conf->version == MTK_THERMAL_V1)
++      switch (mt->conf->version) {
++      case MTK_THERMAL_V1:
+               ret = mtk_thermal_extract_efuse_v1(mt, buf);
+-      else
++              break;
++      case MTK_THERMAL_V2:
+               ret = mtk_thermal_extract_efuse_v2(mt, buf);
++              break;
++      case MTK_THERMAL_V3:
++              ret = mtk_thermal_extract_efuse_v3(mt, buf);
++              break;
++      default:
++              ret = -EINVAL;
++              break;
++      }
+       if (ret) {
+               dev_info(dev, "Device not calibrated, using default calibration values\n");
+@@ -954,6 +1068,10 @@ static const struct of_device_id mtk_the
+               .data = (void *)&mt7622_thermal_data,
+       },
+       {
++              .compatible = "mediatek,mt7986-thermal",
++              .data = (void *)&mt7986_thermal_data,
++      },
++      {
+               .compatible = "mediatek,mt8183-thermal",
+               .data = (void *)&mt8183_thermal_data,
+       }, {
+@@ -1066,15 +1184,17 @@ static int mtk_thermal_probe(struct plat
+               goto err_disable_clk_auxadc;
+       }
+-      if (mt->conf->version == MTK_THERMAL_V2) {
++      if (mt->conf->version != MTK_THERMAL_V1) {
+               mtk_thermal_turn_on_buffer(apmixed_base);
+               mtk_thermal_release_periodic_ts(mt, auxadc_base);
+       }
+       if (mt->conf->version == MTK_THERMAL_V1)
+               mt->raw_to_mcelsius = raw_to_mcelsius_v1;
+-      else
++      else if (mt->conf->version == MTK_THERMAL_V2)
+               mt->raw_to_mcelsius = raw_to_mcelsius_v2;
++      else
++              mt->raw_to_mcelsius = raw_to_mcelsius_v3;
+       for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
+               for (i = 0; i < mt->conf->num_banks; i++)
diff --git a/target/linux/mediatek/patches-6.6/830-v6.3-05-thermal-drivers-mediatek-Relocate-driver-to-mediatek.patch b/target/linux/mediatek/patches-6.6/830-v6.3-05-thermal-drivers-mediatek-Relocate-driver-to-mediatek.patch
new file mode 100644 (file)
index 0000000..e102a33
--- /dev/null
@@ -0,0 +1,2602 @@
+From 5e3aac197a74914ccec2732a89c29d960730d28f Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Thu, 9 Feb 2023 11:56:23 +0100
+Subject: [PATCH 05/42] thermal/drivers/mediatek: Relocate driver to mediatek
+ folder
+
+Add MediaTek proprietary folder to upstream more thermal zone and cooler
+drivers, relocate the original thermal controller driver to it, and rename it
+as "auxadc_thermal.c" to show its purpose more clearly.
+
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230209105628.50294-2-bchihi@baylibre.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/thermal/Kconfig                       | 14 ++++---------
+ drivers/thermal/Makefile                      |  2 +-
+ drivers/thermal/mediatek/Kconfig              | 21 +++++++++++++++++++
+ drivers/thermal/mediatek/Makefile             |  1 +
+ .../auxadc_thermal.c}                         |  2 +-
+ 5 files changed, 28 insertions(+), 12 deletions(-)
+ create mode 100644 drivers/thermal/mediatek/Kconfig
+ create mode 100644 drivers/thermal/mediatek/Makefile
+ rename drivers/thermal/{mtk_thermal.c => mediatek/auxadc_thermal.c} (99%)
+
+--- a/drivers/thermal/Kconfig
++++ b/drivers/thermal/Kconfig
+@@ -412,16 +412,10 @@ config DA9062_THERMAL
+         zone.
+         Compatible with the DA9062 and DA9061 PMICs.
+-config MTK_THERMAL
+-      tristate "Temperature sensor driver for mediatek SoCs"
+-      depends on ARCH_MEDIATEK || COMPILE_TEST
+-      depends on HAS_IOMEM
+-      depends on NVMEM || NVMEM=n
+-      depends on RESET_CONTROLLER
+-      default y
+-      help
+-        Enable this option if you want to have support for thermal management
+-        controller present in Mediatek SoCs
++menu "Mediatek thermal drivers"
++depends on ARCH_MEDIATEK || COMPILE_TEST
++source "drivers/thermal/mediatek/Kconfig"
++endmenu
+ config AMLOGIC_THERMAL
+       tristate "Amlogic Thermal Support"
+--- a/drivers/thermal/Makefile
++++ b/drivers/thermal/Makefile
+@@ -55,7 +55,7 @@ obj-y                                += st/
+ obj-y                         += qcom/
+ obj-y                         += tegra/
+ obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
+-obj-$(CONFIG_MTK_THERMAL)     += mtk_thermal.o
++obj-y                         += mediatek/
+ obj-$(CONFIG_GENERIC_ADC_THERMAL)     += thermal-generic-adc.o
+ obj-$(CONFIG_UNIPHIER_THERMAL)        += uniphier_thermal.o
+ obj-$(CONFIG_AMLOGIC_THERMAL)     += amlogic_thermal.o
+--- /dev/null
++++ b/drivers/thermal/mediatek/Kconfig
+@@ -0,0 +1,21 @@
++config MTK_THERMAL
++      tristate "MediaTek thermal drivers"
++      depends on THERMAL_OF
++      help
++        This is the option for MediaTek thermal software solutions.
++        Please enable corresponding options to get temperature
++        information from thermal sensors or turn on throttle
++        mechaisms for thermal mitigation.
++
++if MTK_THERMAL
++
++config MTK_SOC_THERMAL
++      tristate "AUXADC temperature sensor driver for MediaTek SoCs"
++      depends on HAS_IOMEM
++      help
++        Enable this option if you want to get SoC temperature
++        information for MediaTek platforms.
++        This driver configures thermal controllers to collect
++        temperature via AUXADC interface.
++
++endif
+--- /dev/null
++++ b/drivers/thermal/mediatek/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_MTK_SOC_THERMAL) += auxadc_thermal.o
+--- a/drivers/thermal/mtk_thermal.c
++++ /dev/null
+@@ -1,1254 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-only
+-/*
+- * Copyright (c) 2015 MediaTek Inc.
+- * Author: Hanyi Wu <hanyi.wu@mediatek.com>
+- *         Sascha Hauer <s.hauer@pengutronix.de>
+- *         Dawei Chien <dawei.chien@mediatek.com>
+- *         Louis Yu <louis.yu@mediatek.com>
+- */
+-
+-#include <linux/clk.h>
+-#include <linux/delay.h>
+-#include <linux/interrupt.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/nvmem-consumer.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/io.h>
+-#include <linux/thermal.h>
+-#include <linux/reset.h>
+-#include <linux/types.h>
+-
+-#include "thermal_hwmon.h"
+-
+-/* AUXADC Registers */
+-#define AUXADC_CON1_SET_V     0x008
+-#define AUXADC_CON1_CLR_V     0x00c
+-#define AUXADC_CON2_V         0x010
+-#define AUXADC_DATA(channel)  (0x14 + (channel) * 4)
+-
+-#define APMIXED_SYS_TS_CON1   0x604
+-
+-/* Thermal Controller Registers */
+-#define TEMP_MONCTL0          0x000
+-#define TEMP_MONCTL1          0x004
+-#define TEMP_MONCTL2          0x008
+-#define TEMP_MONIDET0         0x014
+-#define TEMP_MONIDET1         0x018
+-#define TEMP_MSRCTL0          0x038
+-#define TEMP_MSRCTL1          0x03c
+-#define TEMP_AHBPOLL          0x040
+-#define TEMP_AHBTO            0x044
+-#define TEMP_ADCPNP0          0x048
+-#define TEMP_ADCPNP1          0x04c
+-#define TEMP_ADCPNP2          0x050
+-#define TEMP_ADCPNP3          0x0b4
+-
+-#define TEMP_ADCMUX           0x054
+-#define TEMP_ADCEN            0x060
+-#define TEMP_PNPMUXADDR               0x064
+-#define TEMP_ADCMUXADDR               0x068
+-#define TEMP_ADCENADDR                0x074
+-#define TEMP_ADCVALIDADDR     0x078
+-#define TEMP_ADCVOLTADDR      0x07c
+-#define TEMP_RDCTRL           0x080
+-#define TEMP_ADCVALIDMASK     0x084
+-#define TEMP_ADCVOLTAGESHIFT  0x088
+-#define TEMP_ADCWRITECTRL     0x08c
+-#define TEMP_MSR0             0x090
+-#define TEMP_MSR1             0x094
+-#define TEMP_MSR2             0x098
+-#define TEMP_MSR3             0x0B8
+-
+-#define TEMP_SPARE0           0x0f0
+-
+-#define TEMP_ADCPNP0_1          0x148
+-#define TEMP_ADCPNP1_1          0x14c
+-#define TEMP_ADCPNP2_1          0x150
+-#define TEMP_MSR0_1             0x190
+-#define TEMP_MSR1_1             0x194
+-#define TEMP_MSR2_1             0x198
+-#define TEMP_ADCPNP3_1          0x1b4
+-#define TEMP_MSR3_1             0x1B8
+-
+-#define PTPCORESEL            0x400
+-
+-#define TEMP_MONCTL1_PERIOD_UNIT(x)   ((x) & 0x3ff)
+-
+-#define TEMP_MONCTL2_FILTER_INTERVAL(x)       (((x) & 0x3ff) << 16)
+-#define TEMP_MONCTL2_SENSOR_INTERVAL(x)       ((x) & 0x3ff)
+-
+-#define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x)     (x)
+-
+-#define TEMP_ADCWRITECTRL_ADC_PNP_WRITE               BIT(0)
+-#define TEMP_ADCWRITECTRL_ADC_MUX_WRITE               BIT(1)
+-
+-#define TEMP_ADCVALIDMASK_VALID_HIGH          BIT(5)
+-#define TEMP_ADCVALIDMASK_VALID_POS(bit)      (bit)
+-
+-/* MT8173 thermal sensors */
+-#define MT8173_TS1    0
+-#define MT8173_TS2    1
+-#define MT8173_TS3    2
+-#define MT8173_TS4    3
+-#define MT8173_TSABB  4
+-
+-/* AUXADC channel 11 is used for the temperature sensors */
+-#define MT8173_TEMP_AUXADC_CHANNEL    11
+-
+-/* The total number of temperature sensors in the MT8173 */
+-#define MT8173_NUM_SENSORS            5
+-
+-/* The number of banks in the MT8173 */
+-#define MT8173_NUM_ZONES              4
+-
+-/* The number of sensing points per bank */
+-#define MT8173_NUM_SENSORS_PER_ZONE   4
+-
+-/* The number of controller in the MT8173 */
+-#define MT8173_NUM_CONTROLLER         1
+-
+-/* The calibration coefficient of sensor  */
+-#define MT8173_CALIBRATION    165
+-
+-/*
+- * Layout of the fuses providing the calibration data
+- * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
+- * MT8183 has 6 sensors and needs 6 VTS calibration data.
+- * MT8173 has 5 sensors and needs 5 VTS calibration data.
+- * MT2701 has 3 sensors and needs 3 VTS calibration data.
+- * MT2712 has 4 sensors and needs 4 VTS calibration data.
+- */
+-#define CALIB_BUF0_VALID_V1           BIT(0)
+-#define CALIB_BUF1_ADC_GE_V1(x)               (((x) >> 22) & 0x3ff)
+-#define CALIB_BUF0_VTS_TS1_V1(x)      (((x) >> 17) & 0x1ff)
+-#define CALIB_BUF0_VTS_TS2_V1(x)      (((x) >> 8) & 0x1ff)
+-#define CALIB_BUF1_VTS_TS3_V1(x)      (((x) >> 0) & 0x1ff)
+-#define CALIB_BUF2_VTS_TS4_V1(x)      (((x) >> 23) & 0x1ff)
+-#define CALIB_BUF2_VTS_TS5_V1(x)      (((x) >> 5) & 0x1ff)
+-#define CALIB_BUF2_VTS_TSABB_V1(x)    (((x) >> 14) & 0x1ff)
+-#define CALIB_BUF0_DEGC_CALI_V1(x)    (((x) >> 1) & 0x3f)
+-#define CALIB_BUF0_O_SLOPE_V1(x)      (((x) >> 26) & 0x3f)
+-#define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1)
+-#define CALIB_BUF1_ID_V1(x)           (((x) >> 9) & 0x1)
+-
+-/*
+- * Layout of the fuses providing the calibration data
+- * These macros could be used for MT7622.
+- */
+-#define CALIB_BUF0_ADC_OE_V2(x)               (((x) >> 22) & 0x3ff)
+-#define CALIB_BUF0_ADC_GE_V2(x)               (((x) >> 12) & 0x3ff)
+-#define CALIB_BUF0_DEGC_CALI_V2(x)    (((x) >> 6) & 0x3f)
+-#define CALIB_BUF0_O_SLOPE_V2(x)      (((x) >> 0) & 0x3f)
+-#define CALIB_BUF1_VTS_TS1_V2(x)      (((x) >> 23) & 0x1ff)
+-#define CALIB_BUF1_VTS_TS2_V2(x)      (((x) >> 14) & 0x1ff)
+-#define CALIB_BUF1_VTS_TSABB_V2(x)    (((x) >> 5) & 0x1ff)
+-#define CALIB_BUF1_VALID_V2(x)                (((x) >> 4) & 0x1)
+-#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
+-
+-/*
+- * Layout of the fuses providing the calibration data
+- * These macros can be used for MT7981 and MT7986.
+- */
+-#define CALIB_BUF0_ADC_GE_V3(x)               (((x) >> 0) & 0x3ff)
+-#define CALIB_BUF0_DEGC_CALI_V3(x)    (((x) >> 20) & 0x3f)
+-#define CALIB_BUF0_O_SLOPE_V3(x)      (((x) >> 26) & 0x3f)
+-#define CALIB_BUF1_VTS_TS1_V3(x)      (((x) >> 0) & 0x1ff)
+-#define CALIB_BUF1_VTS_TS2_V3(x)      (((x) >> 21) & 0x1ff)
+-#define CALIB_BUF1_VTS_TSABB_V3(x)    (((x) >> 9) & 0x1ff)
+-#define CALIB_BUF1_VALID_V3(x)                (((x) >> 18) & 0x1)
+-#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
+-#define CALIB_BUF1_ID_V3(x)           (((x) >> 20) & 0x1)
+-
+-enum {
+-      VTS1,
+-      VTS2,
+-      VTS3,
+-      VTS4,
+-      VTS5,
+-      VTSABB,
+-      MAX_NUM_VTS,
+-};
+-
+-enum mtk_thermal_version {
+-      MTK_THERMAL_V1 = 1,
+-      MTK_THERMAL_V2,
+-      MTK_THERMAL_V3,
+-};
+-
+-/* MT2701 thermal sensors */
+-#define MT2701_TS1    0
+-#define MT2701_TS2    1
+-#define MT2701_TSABB  2
+-
+-/* AUXADC channel 11 is used for the temperature sensors */
+-#define MT2701_TEMP_AUXADC_CHANNEL    11
+-
+-/* The total number of temperature sensors in the MT2701 */
+-#define MT2701_NUM_SENSORS    3
+-
+-/* The number of sensing points per bank */
+-#define MT2701_NUM_SENSORS_PER_ZONE   3
+-
+-/* The number of controller in the MT2701 */
+-#define MT2701_NUM_CONTROLLER         1
+-
+-/* The calibration coefficient of sensor  */
+-#define MT2701_CALIBRATION    165
+-
+-/* MT2712 thermal sensors */
+-#define MT2712_TS1    0
+-#define MT2712_TS2    1
+-#define MT2712_TS3    2
+-#define MT2712_TS4    3
+-
+-/* AUXADC channel 11 is used for the temperature sensors */
+-#define MT2712_TEMP_AUXADC_CHANNEL    11
+-
+-/* The total number of temperature sensors in the MT2712 */
+-#define MT2712_NUM_SENSORS    4
+-
+-/* The number of sensing points per bank */
+-#define MT2712_NUM_SENSORS_PER_ZONE   4
+-
+-/* The number of controller in the MT2712 */
+-#define MT2712_NUM_CONTROLLER         1
+-
+-/* The calibration coefficient of sensor  */
+-#define MT2712_CALIBRATION    165
+-
+-#define MT7622_TEMP_AUXADC_CHANNEL    11
+-#define MT7622_NUM_SENSORS            1
+-#define MT7622_NUM_ZONES              1
+-#define MT7622_NUM_SENSORS_PER_ZONE   1
+-#define MT7622_TS1    0
+-#define MT7622_NUM_CONTROLLER         1
+-
+-/* The maximum number of banks */
+-#define MAX_NUM_ZONES         8
+-
+-/* The calibration coefficient of sensor  */
+-#define MT7622_CALIBRATION    165
+-
+-/* MT8183 thermal sensors */
+-#define MT8183_TS1    0
+-#define MT8183_TS2    1
+-#define MT8183_TS3    2
+-#define MT8183_TS4    3
+-#define MT8183_TS5    4
+-#define MT8183_TSABB  5
+-
+-/* AUXADC channel  is used for the temperature sensors */
+-#define MT8183_TEMP_AUXADC_CHANNEL    11
+-
+-/* The total number of temperature sensors in the MT8183 */
+-#define MT8183_NUM_SENSORS    6
+-
+-/* The number of banks in the MT8183 */
+-#define MT8183_NUM_ZONES               1
+-
+-/* The number of sensing points per bank */
+-#define MT8183_NUM_SENSORS_PER_ZONE    6
+-
+-/* The number of controller in the MT8183 */
+-#define MT8183_NUM_CONTROLLER         2
+-
+-/* The calibration coefficient of sensor  */
+-#define MT8183_CALIBRATION    153
+-
+-/* AUXADC channel 11 is used for the temperature sensors */
+-#define MT7986_TEMP_AUXADC_CHANNEL    11
+-
+-/* The total number of temperature sensors in the MT7986 */
+-#define MT7986_NUM_SENSORS            1
+-
+-/* The number of banks in the MT7986 */
+-#define MT7986_NUM_ZONES              1
+-
+-/* The number of sensing points per bank */
+-#define MT7986_NUM_SENSORS_PER_ZONE   1
+-
+-/* MT7986 thermal sensors */
+-#define MT7986_TS1                    0
+-
+-/* The number of controller in the MT7986 */
+-#define MT7986_NUM_CONTROLLER         1
+-
+-/* The calibration coefficient of sensor  */
+-#define MT7986_CALIBRATION            165
+-
+-struct mtk_thermal;
+-
+-struct thermal_bank_cfg {
+-      unsigned int num_sensors;
+-      const int *sensors;
+-};
+-
+-struct mtk_thermal_bank {
+-      struct mtk_thermal *mt;
+-      int id;
+-};
+-
+-struct mtk_thermal_data {
+-      s32 num_banks;
+-      s32 num_sensors;
+-      s32 auxadc_channel;
+-      const int *vts_index;
+-      const int *sensor_mux_values;
+-      const int *msr;
+-      const int *adcpnp;
+-      const int cali_val;
+-      const int num_controller;
+-      const int *controller_offset;
+-      bool need_switch_bank;
+-      struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
+-      enum mtk_thermal_version version;
+-};
+-
+-struct mtk_thermal {
+-      struct device *dev;
+-      void __iomem *thermal_base;
+-
+-      struct clk *clk_peri_therm;
+-      struct clk *clk_auxadc;
+-      /* lock: for getting and putting banks */
+-      struct mutex lock;
+-
+-      /* Calibration values */
+-      s32 adc_ge;
+-      s32 adc_oe;
+-      s32 degc_cali;
+-      s32 o_slope;
+-      s32 o_slope_sign;
+-      s32 vts[MAX_NUM_VTS];
+-
+-      const struct mtk_thermal_data *conf;
+-      struct mtk_thermal_bank banks[MAX_NUM_ZONES];
+-
+-      int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
+-};
+-
+-/* MT8183 thermal sensor data */
+-static const int mt8183_bank_data[MT8183_NUM_SENSORS] = {
+-      MT8183_TS1, MT8183_TS2, MT8183_TS3, MT8183_TS4, MT8183_TS5, MT8183_TSABB
+-};
+-
+-static const int mt8183_msr[MT8183_NUM_SENSORS_PER_ZONE] = {
+-      TEMP_MSR0_1, TEMP_MSR1_1, TEMP_MSR2_1, TEMP_MSR1, TEMP_MSR0, TEMP_MSR3_1
+-};
+-
+-static const int mt8183_adcpnp[MT8183_NUM_SENSORS_PER_ZONE] = {
+-      TEMP_ADCPNP0_1, TEMP_ADCPNP1_1, TEMP_ADCPNP2_1,
+-      TEMP_ADCPNP1, TEMP_ADCPNP0, TEMP_ADCPNP3_1
+-};
+-
+-static const int mt8183_mux_values[MT8183_NUM_SENSORS] = { 0, 1, 2, 3, 4, 0 };
+-static const int mt8183_tc_offset[MT8183_NUM_CONTROLLER] = {0x0, 0x100};
+-
+-static const int mt8183_vts_index[MT8183_NUM_SENSORS] = {
+-      VTS1, VTS2, VTS3, VTS4, VTS5, VTSABB
+-};
+-
+-/* MT8173 thermal sensor data */
+-static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
+-      { MT8173_TS2, MT8173_TS3 },
+-      { MT8173_TS2, MT8173_TS4 },
+-      { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
+-      { MT8173_TS2 },
+-};
+-
+-static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = {
+-      TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
+-};
+-
+-static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
+-      TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
+-};
+-
+-static const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
+-static const int mt8173_tc_offset[MT8173_NUM_CONTROLLER] = { 0x0, };
+-
+-static const int mt8173_vts_index[MT8173_NUM_SENSORS] = {
+-      VTS1, VTS2, VTS3, VTS4, VTSABB
+-};
+-
+-/* MT2701 thermal sensor data */
+-static const int mt2701_bank_data[MT2701_NUM_SENSORS] = {
+-      MT2701_TS1, MT2701_TS2, MT2701_TSABB
+-};
+-
+-static const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = {
+-      TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
+-};
+-
+-static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = {
+-      TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
+-};
+-
+-static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 };
+-static const int mt2701_tc_offset[MT2701_NUM_CONTROLLER] = { 0x0, };
+-
+-static const int mt2701_vts_index[MT2701_NUM_SENSORS] = {
+-      VTS1, VTS2, VTS3
+-};
+-
+-/* MT2712 thermal sensor data */
+-static const int mt2712_bank_data[MT2712_NUM_SENSORS] = {
+-      MT2712_TS1, MT2712_TS2, MT2712_TS3, MT2712_TS4
+-};
+-
+-static const int mt2712_msr[MT2712_NUM_SENSORS_PER_ZONE] = {
+-      TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
+-};
+-
+-static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = {
+-      TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
+-};
+-
+-static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 };
+-static const int mt2712_tc_offset[MT2712_NUM_CONTROLLER] = { 0x0, };
+-
+-static const int mt2712_vts_index[MT2712_NUM_SENSORS] = {
+-      VTS1, VTS2, VTS3, VTS4
+-};
+-
+-/* MT7622 thermal sensor data */
+-static const int mt7622_bank_data[MT7622_NUM_SENSORS] = { MT7622_TS1, };
+-static const int mt7622_msr[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
+-static const int mt7622_adcpnp[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
+-static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
+-static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
+-static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
+-
+-/* MT7986 thermal sensor data */
+-static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
+-static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
+-static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
+-static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
+-static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
+-static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
+-
+-/*
+- * The MT8173 thermal controller has four banks. Each bank can read up to
+- * four temperature sensors simultaneously. The MT8173 has a total of 5
+- * temperature sensors. We use each bank to measure a certain area of the
+- * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple
+- * areas, hence is used in different banks.
+- *
+- * The thermal core only gets the maximum temperature of all banks, so
+- * the bank concept wouldn't be necessary here. However, the SVS (Smart
+- * Voltage Scaling) unit makes its decisions based on the same bank
+- * data, and this indeed needs the temperatures of the individual banks
+- * for making better decisions.
+- */
+-static const struct mtk_thermal_data mt8173_thermal_data = {
+-      .auxadc_channel = MT8173_TEMP_AUXADC_CHANNEL,
+-      .num_banks = MT8173_NUM_ZONES,
+-      .num_sensors = MT8173_NUM_SENSORS,
+-      .vts_index = mt8173_vts_index,
+-      .cali_val = MT8173_CALIBRATION,
+-      .num_controller = MT8173_NUM_CONTROLLER,
+-      .controller_offset = mt8173_tc_offset,
+-      .need_switch_bank = true,
+-      .bank_data = {
+-              {
+-                      .num_sensors = 2,
+-                      .sensors = mt8173_bank_data[0],
+-              }, {
+-                      .num_sensors = 2,
+-                      .sensors = mt8173_bank_data[1],
+-              }, {
+-                      .num_sensors = 3,
+-                      .sensors = mt8173_bank_data[2],
+-              }, {
+-                      .num_sensors = 1,
+-                      .sensors = mt8173_bank_data[3],
+-              },
+-      },
+-      .msr = mt8173_msr,
+-      .adcpnp = mt8173_adcpnp,
+-      .sensor_mux_values = mt8173_mux_values,
+-      .version = MTK_THERMAL_V1,
+-};
+-
+-/*
+- * The MT2701 thermal controller has one bank, which can read up to
+- * three temperature sensors simultaneously. The MT2701 has a total of 3
+- * temperature sensors.
+- *
+- * The thermal core only gets the maximum temperature of this one bank,
+- * so the bank concept wouldn't be necessary here. However, the SVS (Smart
+- * Voltage Scaling) unit makes its decisions based on the same bank
+- * data.
+- */
+-static const struct mtk_thermal_data mt2701_thermal_data = {
+-      .auxadc_channel = MT2701_TEMP_AUXADC_CHANNEL,
+-      .num_banks = 1,
+-      .num_sensors = MT2701_NUM_SENSORS,
+-      .vts_index = mt2701_vts_index,
+-      .cali_val = MT2701_CALIBRATION,
+-      .num_controller = MT2701_NUM_CONTROLLER,
+-      .controller_offset = mt2701_tc_offset,
+-      .need_switch_bank = true,
+-      .bank_data = {
+-              {
+-                      .num_sensors = 3,
+-                      .sensors = mt2701_bank_data,
+-              },
+-      },
+-      .msr = mt2701_msr,
+-      .adcpnp = mt2701_adcpnp,
+-      .sensor_mux_values = mt2701_mux_values,
+-      .version = MTK_THERMAL_V1,
+-};
+-
+-/*
+- * The MT2712 thermal controller has one bank, which can read up to
+- * four temperature sensors simultaneously. The MT2712 has a total of 4
+- * temperature sensors.
+- *
+- * The thermal core only gets the maximum temperature of this one bank,
+- * so the bank concept wouldn't be necessary here. However, the SVS (Smart
+- * Voltage Scaling) unit makes its decisions based on the same bank
+- * data.
+- */
+-static const struct mtk_thermal_data mt2712_thermal_data = {
+-      .auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL,
+-      .num_banks = 1,
+-      .num_sensors = MT2712_NUM_SENSORS,
+-      .vts_index = mt2712_vts_index,
+-      .cali_val = MT2712_CALIBRATION,
+-      .num_controller = MT2712_NUM_CONTROLLER,
+-      .controller_offset = mt2712_tc_offset,
+-      .need_switch_bank = true,
+-      .bank_data = {
+-              {
+-                      .num_sensors = 4,
+-                      .sensors = mt2712_bank_data,
+-              },
+-      },
+-      .msr = mt2712_msr,
+-      .adcpnp = mt2712_adcpnp,
+-      .sensor_mux_values = mt2712_mux_values,
+-      .version = MTK_THERMAL_V1,
+-};
+-
+-/*
+- * MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
+- * access.
+- */
+-static const struct mtk_thermal_data mt7622_thermal_data = {
+-      .auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL,
+-      .num_banks = MT7622_NUM_ZONES,
+-      .num_sensors = MT7622_NUM_SENSORS,
+-      .vts_index = mt7622_vts_index,
+-      .cali_val = MT7622_CALIBRATION,
+-      .num_controller = MT7622_NUM_CONTROLLER,
+-      .controller_offset = mt7622_tc_offset,
+-      .need_switch_bank = true,
+-      .bank_data = {
+-              {
+-                      .num_sensors = 1,
+-                      .sensors = mt7622_bank_data,
+-              },
+-      },
+-      .msr = mt7622_msr,
+-      .adcpnp = mt7622_adcpnp,
+-      .sensor_mux_values = mt7622_mux_values,
+-      .version = MTK_THERMAL_V2,
+-};
+-
+-/*
+- * The MT8183 thermal controller has one bank for the current SW framework.
+- * The MT8183 has a total of 6 temperature sensors.
+- * There are two thermal controller to control the six sensor.
+- * The first one bind 2 sensor, and the other bind 4 sensors.
+- * The thermal core only gets the maximum temperature of all sensor, so
+- * the bank concept wouldn't be necessary here. However, the SVS (Smart
+- * Voltage Scaling) unit makes its decisions based on the same bank
+- * data, and this indeed needs the temperatures of the individual banks
+- * for making better decisions.
+- */
+-static const struct mtk_thermal_data mt8183_thermal_data = {
+-      .auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL,
+-      .num_banks = MT8183_NUM_ZONES,
+-      .num_sensors = MT8183_NUM_SENSORS,
+-      .vts_index = mt8183_vts_index,
+-      .cali_val = MT8183_CALIBRATION,
+-      .num_controller = MT8183_NUM_CONTROLLER,
+-      .controller_offset = mt8183_tc_offset,
+-      .need_switch_bank = false,
+-      .bank_data = {
+-              {
+-                      .num_sensors = 6,
+-                      .sensors = mt8183_bank_data,
+-              },
+-      },
+-
+-      .msr = mt8183_msr,
+-      .adcpnp = mt8183_adcpnp,
+-      .sensor_mux_values = mt8183_mux_values,
+-      .version = MTK_THERMAL_V1,
+-};
+-
+-/*
+- * MT7986 uses AUXADC Channel 11 for raw data access.
+- */
+-static const struct mtk_thermal_data mt7986_thermal_data = {
+-      .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
+-      .num_banks = MT7986_NUM_ZONES,
+-      .num_sensors = MT7986_NUM_SENSORS,
+-      .vts_index = mt7986_vts_index,
+-      .cali_val = MT7986_CALIBRATION,
+-      .num_controller = MT7986_NUM_CONTROLLER,
+-      .controller_offset = mt7986_tc_offset,
+-      .need_switch_bank = true,
+-      .bank_data = {
+-              {
+-                      .num_sensors = 1,
+-                      .sensors = mt7986_bank_data,
+-              },
+-      },
+-      .msr = mt7986_msr,
+-      .adcpnp = mt7986_adcpnp,
+-      .sensor_mux_values = mt7986_mux_values,
+-      .version = MTK_THERMAL_V3,
+-};
+-
+-/**
+- * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
+- * @mt:       The thermal controller
+- * @sensno:   sensor number
+- * @raw:      raw ADC value
+- *
+- * This converts the raw ADC value to mcelsius using the SoC specific
+- * calibration constants
+- */
+-static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
+-{
+-      s32 tmp;
+-
+-      raw &= 0xfff;
+-
+-      tmp = 203450520 << 3;
+-      tmp /= mt->conf->cali_val + mt->o_slope;
+-      tmp /= 10000 + mt->adc_ge;
+-      tmp *= raw - mt->vts[sensno] - 3350;
+-      tmp >>= 3;
+-
+-      return mt->degc_cali * 500 - tmp;
+-}
+-
+-static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
+-{
+-      s32 format_1;
+-      s32 format_2;
+-      s32 g_oe;
+-      s32 g_gain;
+-      s32 g_x_roomt;
+-      s32 tmp;
+-
+-      if (raw == 0)
+-              return 0;
+-
+-      raw &= 0xfff;
+-      g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12);
+-      g_oe = mt->adc_oe - 512;
+-      format_1 = mt->vts[VTS2] + 3105 - g_oe;
+-      format_2 = (mt->degc_cali * 10) >> 1;
+-      g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain;
+-
+-      tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt;
+-      tmp = tmp * 10 * 100 / 11;
+-
+-      if (mt->o_slope_sign == 0)
+-              tmp = tmp / (165 - mt->o_slope);
+-      else
+-              tmp = tmp / (165 + mt->o_slope);
+-
+-      return (format_2 - tmp) * 100;
+-}
+-
+-static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
+-{
+-      s32 tmp;
+-
+-      if (raw == 0)
+-              return 0;
+-
+-      raw &= 0xfff;
+-      tmp = 100000 * 15 / 16 * 10000;
+-      tmp /= 4096 - 512 + mt->adc_ge;
+-      tmp /= 1490;
+-      tmp *= raw - mt->vts[sensno] - 2900;
+-
+-      return mt->degc_cali * 500 - tmp;
+-}
+-
+-/**
+- * mtk_thermal_get_bank - get bank
+- * @bank:     The bank
+- *
+- * The bank registers are banked, we have to select a bank in the
+- * PTPCORESEL register to access it.
+- */
+-static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank)
+-{
+-      struct mtk_thermal *mt = bank->mt;
+-      u32 val;
+-
+-      if (mt->conf->need_switch_bank) {
+-              mutex_lock(&mt->lock);
+-
+-              val = readl(mt->thermal_base + PTPCORESEL);
+-              val &= ~0xf;
+-              val |= bank->id;
+-              writel(val, mt->thermal_base + PTPCORESEL);
+-      }
+-}
+-
+-/**
+- * mtk_thermal_put_bank - release bank
+- * @bank:     The bank
+- *
+- * release a bank previously taken with mtk_thermal_get_bank,
+- */
+-static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
+-{
+-      struct mtk_thermal *mt = bank->mt;
+-
+-      if (mt->conf->need_switch_bank)
+-              mutex_unlock(&mt->lock);
+-}
+-
+-/**
+- * mtk_thermal_bank_temperature - get the temperature of a bank
+- * @bank:     The bank
+- *
+- * The temperature of a bank is considered the maximum temperature of
+- * the sensors associated to the bank.
+- */
+-static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
+-{
+-      struct mtk_thermal *mt = bank->mt;
+-      const struct mtk_thermal_data *conf = mt->conf;
+-      int i, temp = INT_MIN, max = INT_MIN;
+-      u32 raw;
+-
+-      for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
+-              raw = readl(mt->thermal_base + conf->msr[i]);
+-
+-              temp = mt->raw_to_mcelsius(
+-                      mt, conf->bank_data[bank->id].sensors[i], raw);
+-
+-
+-              /*
+-               * The first read of a sensor often contains very high bogus
+-               * temperature value. Filter these out so that the system does
+-               * not immediately shut down.
+-               */
+-              if (temp > 200000)
+-                      temp = 0;
+-
+-              if (temp > max)
+-                      max = temp;
+-      }
+-
+-      return max;
+-}
+-
+-static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature)
+-{
+-      struct mtk_thermal *mt = tz->devdata;
+-      int i;
+-      int tempmax = INT_MIN;
+-
+-      for (i = 0; i < mt->conf->num_banks; i++) {
+-              struct mtk_thermal_bank *bank = &mt->banks[i];
+-
+-              mtk_thermal_get_bank(bank);
+-
+-              tempmax = max(tempmax, mtk_thermal_bank_temperature(bank));
+-
+-              mtk_thermal_put_bank(bank);
+-      }
+-
+-      *temperature = tempmax;
+-
+-      return 0;
+-}
+-
+-static const struct thermal_zone_device_ops mtk_thermal_ops = {
+-      .get_temp = mtk_read_temp,
+-};
+-
+-static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
+-                                u32 apmixed_phys_base, u32 auxadc_phys_base,
+-                                int ctrl_id)
+-{
+-      struct mtk_thermal_bank *bank = &mt->banks[num];
+-      const struct mtk_thermal_data *conf = mt->conf;
+-      int i;
+-
+-      int offset = mt->conf->controller_offset[ctrl_id];
+-      void __iomem *controller_base = mt->thermal_base + offset;
+-
+-      bank->id = num;
+-      bank->mt = mt;
+-
+-      mtk_thermal_get_bank(bank);
+-
+-      /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
+-      writel(TEMP_MONCTL1_PERIOD_UNIT(12), controller_base + TEMP_MONCTL1);
+-
+-      /*
+-       * filt interval is 1 * 46.540us = 46.54us,
+-       * sen interval is 429 * 46.540us = 19.96ms
+-       */
+-      writel(TEMP_MONCTL2_FILTER_INTERVAL(1) |
+-                      TEMP_MONCTL2_SENSOR_INTERVAL(429),
+-                      controller_base + TEMP_MONCTL2);
+-
+-      /* poll is set to 10u */
+-      writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768),
+-             controller_base + TEMP_AHBPOLL);
+-
+-      /* temperature sampling control, 1 sample */
+-      writel(0x0, controller_base + TEMP_MSRCTL0);
+-
+-      /* exceed this polling time, IRQ would be inserted */
+-      writel(0xffffffff, controller_base + TEMP_AHBTO);
+-
+-      /* number of interrupts per event, 1 is enough */
+-      writel(0x0, controller_base + TEMP_MONIDET0);
+-      writel(0x0, controller_base + TEMP_MONIDET1);
+-
+-      /*
+-       * The MT8173 thermal controller does not have its own ADC. Instead it
+-       * uses AHB bus accesses to control the AUXADC. To do this the thermal
+-       * controller has to be programmed with the physical addresses of the
+-       * AUXADC registers and with the various bit positions in the AUXADC.
+-       * Also the thermal controller controls a mux in the APMIXEDSYS register
+-       * space.
+-       */
+-
+-      /*
+-       * this value will be stored to TEMP_PNPMUXADDR (TEMP_SPARE0)
+-       * automatically by hw
+-       */
+-      writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCMUX);
+-
+-      /* AHB address for auxadc mux selection */
+-      writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
+-             controller_base + TEMP_ADCMUXADDR);
+-
+-      if (mt->conf->version == MTK_THERMAL_V1) {
+-              /* AHB address for pnp sensor mux selection */
+-              writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
+-                     controller_base + TEMP_PNPMUXADDR);
+-      }
+-
+-      /* AHB value for auxadc enable */
+-      writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCEN);
+-
+-      /* AHB address for auxadc enable (channel 0 immediate mode selected) */
+-      writel(auxadc_phys_base + AUXADC_CON1_SET_V,
+-             controller_base + TEMP_ADCENADDR);
+-
+-      /* AHB address for auxadc valid bit */
+-      writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
+-             controller_base + TEMP_ADCVALIDADDR);
+-
+-      /* AHB address for auxadc voltage output */
+-      writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
+-             controller_base + TEMP_ADCVOLTADDR);
+-
+-      /* read valid & voltage are at the same register */
+-      writel(0x0, controller_base + TEMP_RDCTRL);
+-
+-      /* indicate where the valid bit is */
+-      writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12),
+-             controller_base + TEMP_ADCVALIDMASK);
+-
+-      /* no shift */
+-      writel(0x0, controller_base + TEMP_ADCVOLTAGESHIFT);
+-
+-      /* enable auxadc mux write transaction */
+-      writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
+-              controller_base + TEMP_ADCWRITECTRL);
+-
+-      for (i = 0; i < conf->bank_data[num].num_sensors; i++)
+-              writel(conf->sensor_mux_values[conf->bank_data[num].sensors[i]],
+-                     mt->thermal_base + conf->adcpnp[i]);
+-
+-      writel((1 << conf->bank_data[num].num_sensors) - 1,
+-             controller_base + TEMP_MONCTL0);
+-
+-      writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE |
+-             TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
+-             controller_base + TEMP_ADCWRITECTRL);
+-
+-      mtk_thermal_put_bank(bank);
+-}
+-
+-static u64 of_get_phys_base(struct device_node *np)
+-{
+-      u64 size64;
+-      const __be32 *regaddr_p;
+-
+-      regaddr_p = of_get_address(np, 0, &size64, NULL);
+-      if (!regaddr_p)
+-              return OF_BAD_ADDR;
+-
+-      return of_translate_address(np, regaddr_p);
+-}
+-
+-static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
+-{
+-      int i;
+-
+-      if (!(buf[0] & CALIB_BUF0_VALID_V1))
+-              return -EINVAL;
+-
+-      mt->adc_ge = CALIB_BUF1_ADC_GE_V1(buf[1]);
+-
+-      for (i = 0; i < mt->conf->num_sensors; i++) {
+-              switch (mt->conf->vts_index[i]) {
+-              case VTS1:
+-                      mt->vts[VTS1] = CALIB_BUF0_VTS_TS1_V1(buf[0]);
+-                      break;
+-              case VTS2:
+-                      mt->vts[VTS2] = CALIB_BUF0_VTS_TS2_V1(buf[0]);
+-                      break;
+-              case VTS3:
+-                      mt->vts[VTS3] = CALIB_BUF1_VTS_TS3_V1(buf[1]);
+-                      break;
+-              case VTS4:
+-                      mt->vts[VTS4] = CALIB_BUF2_VTS_TS4_V1(buf[2]);
+-                      break;
+-              case VTS5:
+-                      mt->vts[VTS5] = CALIB_BUF2_VTS_TS5_V1(buf[2]);
+-                      break;
+-              case VTSABB:
+-                      mt->vts[VTSABB] =
+-                              CALIB_BUF2_VTS_TSABB_V1(buf[2]);
+-                      break;
+-              default:
+-                      break;
+-              }
+-      }
+-
+-      mt->degc_cali = CALIB_BUF0_DEGC_CALI_V1(buf[0]);
+-      if (CALIB_BUF1_ID_V1(buf[1]) &
+-          CALIB_BUF0_O_SLOPE_SIGN_V1(buf[0]))
+-              mt->o_slope = -CALIB_BUF0_O_SLOPE_V1(buf[0]);
+-      else
+-              mt->o_slope = CALIB_BUF0_O_SLOPE_V1(buf[0]);
+-
+-      return 0;
+-}
+-
+-static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
+-{
+-      if (!CALIB_BUF1_VALID_V2(buf[1]))
+-              return -EINVAL;
+-
+-      mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]);
+-      mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]);
+-      mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]);
+-      mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]);
+-      mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]);
+-      mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]);
+-      mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]);
+-      mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]);
+-
+-      return 0;
+-}
+-
+-static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
+-{
+-      if (!CALIB_BUF1_VALID_V3(buf[1]))
+-              return -EINVAL;
+-
+-      mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
+-      mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
+-      mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
+-      mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
+-      mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
+-      mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
+-      mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
+-
+-      if (CALIB_BUF1_ID_V3(buf[1]) == 0)
+-              mt->o_slope = 0;
+-
+-      return 0;
+-}
+-
+-static int mtk_thermal_get_calibration_data(struct device *dev,
+-                                          struct mtk_thermal *mt)
+-{
+-      struct nvmem_cell *cell;
+-      u32 *buf;
+-      size_t len;
+-      int i, ret = 0;
+-
+-      /* Start with default values */
+-      mt->adc_ge = 512;
+-      mt->adc_oe = 512;
+-      for (i = 0; i < mt->conf->num_sensors; i++)
+-              mt->vts[i] = 260;
+-      mt->degc_cali = 40;
+-      mt->o_slope = 0;
+-
+-      cell = nvmem_cell_get(dev, "calibration-data");
+-      if (IS_ERR(cell)) {
+-              if (PTR_ERR(cell) == -EPROBE_DEFER)
+-                      return PTR_ERR(cell);
+-              return 0;
+-      }
+-
+-      buf = (u32 *)nvmem_cell_read(cell, &len);
+-
+-      nvmem_cell_put(cell);
+-
+-      if (IS_ERR(buf))
+-              return PTR_ERR(buf);
+-
+-      if (len < 3 * sizeof(u32)) {
+-              dev_warn(dev, "invalid calibration data\n");
+-              ret = -EINVAL;
+-              goto out;
+-      }
+-
+-      switch (mt->conf->version) {
+-      case MTK_THERMAL_V1:
+-              ret = mtk_thermal_extract_efuse_v1(mt, buf);
+-              break;
+-      case MTK_THERMAL_V2:
+-              ret = mtk_thermal_extract_efuse_v2(mt, buf);
+-              break;
+-      case MTK_THERMAL_V3:
+-              ret = mtk_thermal_extract_efuse_v3(mt, buf);
+-              break;
+-      default:
+-              ret = -EINVAL;
+-              break;
+-      }
+-
+-      if (ret) {
+-              dev_info(dev, "Device not calibrated, using default calibration values\n");
+-              ret = 0;
+-      }
+-
+-out:
+-      kfree(buf);
+-
+-      return ret;
+-}
+-
+-static const struct of_device_id mtk_thermal_of_match[] = {
+-      {
+-              .compatible = "mediatek,mt8173-thermal",
+-              .data = (void *)&mt8173_thermal_data,
+-      },
+-      {
+-              .compatible = "mediatek,mt2701-thermal",
+-              .data = (void *)&mt2701_thermal_data,
+-      },
+-      {
+-              .compatible = "mediatek,mt2712-thermal",
+-              .data = (void *)&mt2712_thermal_data,
+-      },
+-      {
+-              .compatible = "mediatek,mt7622-thermal",
+-              .data = (void *)&mt7622_thermal_data,
+-      },
+-      {
+-              .compatible = "mediatek,mt7986-thermal",
+-              .data = (void *)&mt7986_thermal_data,
+-      },
+-      {
+-              .compatible = "mediatek,mt8183-thermal",
+-              .data = (void *)&mt8183_thermal_data,
+-      }, {
+-      },
+-};
+-MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
+-
+-static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
+-{
+-      int tmp;
+-
+-      tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
+-      tmp &= ~(0x37);
+-      tmp |= 0x1;
+-      writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
+-      udelay(200);
+-}
+-
+-static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt,
+-                                          void __iomem *auxadc_base)
+-{
+-      int tmp;
+-
+-      writel(0x800, auxadc_base + AUXADC_CON1_SET_V);
+-      writel(0x1, mt->thermal_base + TEMP_MONCTL0);
+-      tmp = readl(mt->thermal_base + TEMP_MSRCTL1);
+-      writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1);
+-}
+-
+-static int mtk_thermal_probe(struct platform_device *pdev)
+-{
+-      int ret, i, ctrl_id;
+-      struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
+-      struct mtk_thermal *mt;
+-      u64 auxadc_phys_base, apmixed_phys_base;
+-      struct thermal_zone_device *tzdev;
+-      void __iomem *apmixed_base, *auxadc_base;
+-
+-      mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
+-      if (!mt)
+-              return -ENOMEM;
+-
+-      mt->conf = of_device_get_match_data(&pdev->dev);
+-
+-      mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
+-      if (IS_ERR(mt->clk_peri_therm))
+-              return PTR_ERR(mt->clk_peri_therm);
+-
+-      mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
+-      if (IS_ERR(mt->clk_auxadc))
+-              return PTR_ERR(mt->clk_auxadc);
+-
+-      mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+-      if (IS_ERR(mt->thermal_base))
+-              return PTR_ERR(mt->thermal_base);
+-
+-      ret = mtk_thermal_get_calibration_data(&pdev->dev, mt);
+-      if (ret)
+-              return ret;
+-
+-      mutex_init(&mt->lock);
+-
+-      mt->dev = &pdev->dev;
+-
+-      auxadc = of_parse_phandle(np, "mediatek,auxadc", 0);
+-      if (!auxadc) {
+-              dev_err(&pdev->dev, "missing auxadc node\n");
+-              return -ENODEV;
+-      }
+-
+-      auxadc_base = of_iomap(auxadc, 0);
+-      auxadc_phys_base = of_get_phys_base(auxadc);
+-
+-      of_node_put(auxadc);
+-
+-      if (auxadc_phys_base == OF_BAD_ADDR) {
+-              dev_err(&pdev->dev, "Can't get auxadc phys address\n");
+-              return -EINVAL;
+-      }
+-
+-      apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0);
+-      if (!apmixedsys) {
+-              dev_err(&pdev->dev, "missing apmixedsys node\n");
+-              return -ENODEV;
+-      }
+-
+-      apmixed_base = of_iomap(apmixedsys, 0);
+-      apmixed_phys_base = of_get_phys_base(apmixedsys);
+-
+-      of_node_put(apmixedsys);
+-
+-      if (apmixed_phys_base == OF_BAD_ADDR) {
+-              dev_err(&pdev->dev, "Can't get auxadc phys address\n");
+-              return -EINVAL;
+-      }
+-
+-      ret = device_reset_optional(&pdev->dev);
+-      if (ret)
+-              return ret;
+-
+-      ret = clk_prepare_enable(mt->clk_auxadc);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
+-              return ret;
+-      }
+-
+-      ret = clk_prepare_enable(mt->clk_peri_therm);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
+-              goto err_disable_clk_auxadc;
+-      }
+-
+-      if (mt->conf->version != MTK_THERMAL_V1) {
+-              mtk_thermal_turn_on_buffer(apmixed_base);
+-              mtk_thermal_release_periodic_ts(mt, auxadc_base);
+-      }
+-
+-      if (mt->conf->version == MTK_THERMAL_V1)
+-              mt->raw_to_mcelsius = raw_to_mcelsius_v1;
+-      else if (mt->conf->version == MTK_THERMAL_V2)
+-              mt->raw_to_mcelsius = raw_to_mcelsius_v2;
+-      else
+-              mt->raw_to_mcelsius = raw_to_mcelsius_v3;
+-
+-      for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
+-              for (i = 0; i < mt->conf->num_banks; i++)
+-                      mtk_thermal_init_bank(mt, i, apmixed_phys_base,
+-                                            auxadc_phys_base, ctrl_id);
+-
+-      platform_set_drvdata(pdev, mt);
+-
+-      tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
+-                                            &mtk_thermal_ops);
+-      if (IS_ERR(tzdev)) {
+-              ret = PTR_ERR(tzdev);
+-              goto err_disable_clk_peri_therm;
+-      }
+-
+-      ret = devm_thermal_add_hwmon_sysfs(tzdev);
+-      if (ret)
+-              dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
+-
+-      return 0;
+-
+-err_disable_clk_peri_therm:
+-      clk_disable_unprepare(mt->clk_peri_therm);
+-err_disable_clk_auxadc:
+-      clk_disable_unprepare(mt->clk_auxadc);
+-
+-      return ret;
+-}
+-
+-static int mtk_thermal_remove(struct platform_device *pdev)
+-{
+-      struct mtk_thermal *mt = platform_get_drvdata(pdev);
+-
+-      clk_disable_unprepare(mt->clk_peri_therm);
+-      clk_disable_unprepare(mt->clk_auxadc);
+-
+-      return 0;
+-}
+-
+-static struct platform_driver mtk_thermal_driver = {
+-      .probe = mtk_thermal_probe,
+-      .remove = mtk_thermal_remove,
+-      .driver = {
+-              .name = "mtk-thermal",
+-              .of_match_table = mtk_thermal_of_match,
+-      },
+-};
+-
+-module_platform_driver(mtk_thermal_driver);
+-
+-MODULE_AUTHOR("Michael Kao <michael.kao@mediatek.com>");
+-MODULE_AUTHOR("Louis Yu <louis.yu@mediatek.com>");
+-MODULE_AUTHOR("Dawei Chien <dawei.chien@mediatek.com>");
+-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+-MODULE_AUTHOR("Hanyi Wu <hanyi.wu@mediatek.com>");
+-MODULE_DESCRIPTION("Mediatek thermal driver");
+-MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -0,0 +1,1254 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (c) 2015 MediaTek Inc.
++ * Author: Hanyi Wu <hanyi.wu@mediatek.com>
++ *         Sascha Hauer <s.hauer@pengutronix.de>
++ *         Dawei Chien <dawei.chien@mediatek.com>
++ *         Louis Yu <louis.yu@mediatek.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/nvmem-consumer.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/io.h>
++#include <linux/thermal.h>
++#include <linux/reset.h>
++#include <linux/types.h>
++
++#include "../thermal_hwmon.h"
++
++/* AUXADC Registers */
++#define AUXADC_CON1_SET_V     0x008
++#define AUXADC_CON1_CLR_V     0x00c
++#define AUXADC_CON2_V         0x010
++#define AUXADC_DATA(channel)  (0x14 + (channel) * 4)
++
++#define APMIXED_SYS_TS_CON1   0x604
++
++/* Thermal Controller Registers */
++#define TEMP_MONCTL0          0x000
++#define TEMP_MONCTL1          0x004
++#define TEMP_MONCTL2          0x008
++#define TEMP_MONIDET0         0x014
++#define TEMP_MONIDET1         0x018
++#define TEMP_MSRCTL0          0x038
++#define TEMP_MSRCTL1          0x03c
++#define TEMP_AHBPOLL          0x040
++#define TEMP_AHBTO            0x044
++#define TEMP_ADCPNP0          0x048
++#define TEMP_ADCPNP1          0x04c
++#define TEMP_ADCPNP2          0x050
++#define TEMP_ADCPNP3          0x0b4
++
++#define TEMP_ADCMUX           0x054
++#define TEMP_ADCEN            0x060
++#define TEMP_PNPMUXADDR               0x064
++#define TEMP_ADCMUXADDR               0x068
++#define TEMP_ADCENADDR                0x074
++#define TEMP_ADCVALIDADDR     0x078
++#define TEMP_ADCVOLTADDR      0x07c
++#define TEMP_RDCTRL           0x080
++#define TEMP_ADCVALIDMASK     0x084
++#define TEMP_ADCVOLTAGESHIFT  0x088
++#define TEMP_ADCWRITECTRL     0x08c
++#define TEMP_MSR0             0x090
++#define TEMP_MSR1             0x094
++#define TEMP_MSR2             0x098
++#define TEMP_MSR3             0x0B8
++
++#define TEMP_SPARE0           0x0f0
++
++#define TEMP_ADCPNP0_1          0x148
++#define TEMP_ADCPNP1_1          0x14c
++#define TEMP_ADCPNP2_1          0x150
++#define TEMP_MSR0_1             0x190
++#define TEMP_MSR1_1             0x194
++#define TEMP_MSR2_1             0x198
++#define TEMP_ADCPNP3_1          0x1b4
++#define TEMP_MSR3_1             0x1B8
++
++#define PTPCORESEL            0x400
++
++#define TEMP_MONCTL1_PERIOD_UNIT(x)   ((x) & 0x3ff)
++
++#define TEMP_MONCTL2_FILTER_INTERVAL(x)       (((x) & 0x3ff) << 16)
++#define TEMP_MONCTL2_SENSOR_INTERVAL(x)       ((x) & 0x3ff)
++
++#define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x)     (x)
++
++#define TEMP_ADCWRITECTRL_ADC_PNP_WRITE               BIT(0)
++#define TEMP_ADCWRITECTRL_ADC_MUX_WRITE               BIT(1)
++
++#define TEMP_ADCVALIDMASK_VALID_HIGH          BIT(5)
++#define TEMP_ADCVALIDMASK_VALID_POS(bit)      (bit)
++
++/* MT8173 thermal sensors */
++#define MT8173_TS1    0
++#define MT8173_TS2    1
++#define MT8173_TS3    2
++#define MT8173_TS4    3
++#define MT8173_TSABB  4
++
++/* AUXADC channel 11 is used for the temperature sensors */
++#define MT8173_TEMP_AUXADC_CHANNEL    11
++
++/* The total number of temperature sensors in the MT8173 */
++#define MT8173_NUM_SENSORS            5
++
++/* The number of banks in the MT8173 */
++#define MT8173_NUM_ZONES              4
++
++/* The number of sensing points per bank */
++#define MT8173_NUM_SENSORS_PER_ZONE   4
++
++/* The number of controller in the MT8173 */
++#define MT8173_NUM_CONTROLLER         1
++
++/* The calibration coefficient of sensor  */
++#define MT8173_CALIBRATION    165
++
++/*
++ * Layout of the fuses providing the calibration data
++ * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
++ * MT8183 has 6 sensors and needs 6 VTS calibration data.
++ * MT8173 has 5 sensors and needs 5 VTS calibration data.
++ * MT2701 has 3 sensors and needs 3 VTS calibration data.
++ * MT2712 has 4 sensors and needs 4 VTS calibration data.
++ */
++#define CALIB_BUF0_VALID_V1           BIT(0)
++#define CALIB_BUF1_ADC_GE_V1(x)               (((x) >> 22) & 0x3ff)
++#define CALIB_BUF0_VTS_TS1_V1(x)      (((x) >> 17) & 0x1ff)
++#define CALIB_BUF0_VTS_TS2_V1(x)      (((x) >> 8) & 0x1ff)
++#define CALIB_BUF1_VTS_TS3_V1(x)      (((x) >> 0) & 0x1ff)
++#define CALIB_BUF2_VTS_TS4_V1(x)      (((x) >> 23) & 0x1ff)
++#define CALIB_BUF2_VTS_TS5_V1(x)      (((x) >> 5) & 0x1ff)
++#define CALIB_BUF2_VTS_TSABB_V1(x)    (((x) >> 14) & 0x1ff)
++#define CALIB_BUF0_DEGC_CALI_V1(x)    (((x) >> 1) & 0x3f)
++#define CALIB_BUF0_O_SLOPE_V1(x)      (((x) >> 26) & 0x3f)
++#define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1)
++#define CALIB_BUF1_ID_V1(x)           (((x) >> 9) & 0x1)
++
++/*
++ * Layout of the fuses providing the calibration data
++ * These macros could be used for MT7622.
++ */
++#define CALIB_BUF0_ADC_OE_V2(x)               (((x) >> 22) & 0x3ff)
++#define CALIB_BUF0_ADC_GE_V2(x)               (((x) >> 12) & 0x3ff)
++#define CALIB_BUF0_DEGC_CALI_V2(x)    (((x) >> 6) & 0x3f)
++#define CALIB_BUF0_O_SLOPE_V2(x)      (((x) >> 0) & 0x3f)
++#define CALIB_BUF1_VTS_TS1_V2(x)      (((x) >> 23) & 0x1ff)
++#define CALIB_BUF1_VTS_TS2_V2(x)      (((x) >> 14) & 0x1ff)
++#define CALIB_BUF1_VTS_TSABB_V2(x)    (((x) >> 5) & 0x1ff)
++#define CALIB_BUF1_VALID_V2(x)                (((x) >> 4) & 0x1)
++#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
++
++/*
++ * Layout of the fuses providing the calibration data
++ * These macros can be used for MT7981 and MT7986.
++ */
++#define CALIB_BUF0_ADC_GE_V3(x)               (((x) >> 0) & 0x3ff)
++#define CALIB_BUF0_DEGC_CALI_V3(x)    (((x) >> 20) & 0x3f)
++#define CALIB_BUF0_O_SLOPE_V3(x)      (((x) >> 26) & 0x3f)
++#define CALIB_BUF1_VTS_TS1_V3(x)      (((x) >> 0) & 0x1ff)
++#define CALIB_BUF1_VTS_TS2_V3(x)      (((x) >> 21) & 0x1ff)
++#define CALIB_BUF1_VTS_TSABB_V3(x)    (((x) >> 9) & 0x1ff)
++#define CALIB_BUF1_VALID_V3(x)                (((x) >> 18) & 0x1)
++#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
++#define CALIB_BUF1_ID_V3(x)           (((x) >> 20) & 0x1)
++
++enum {
++      VTS1,
++      VTS2,
++      VTS3,
++      VTS4,
++      VTS5,
++      VTSABB,
++      MAX_NUM_VTS,
++};
++
++enum mtk_thermal_version {
++      MTK_THERMAL_V1 = 1,
++      MTK_THERMAL_V2,
++      MTK_THERMAL_V3,
++};
++
++/* MT2701 thermal sensors */
++#define MT2701_TS1    0
++#define MT2701_TS2    1
++#define MT2701_TSABB  2
++
++/* AUXADC channel 11 is used for the temperature sensors */
++#define MT2701_TEMP_AUXADC_CHANNEL    11
++
++/* The total number of temperature sensors in the MT2701 */
++#define MT2701_NUM_SENSORS    3
++
++/* The number of sensing points per bank */
++#define MT2701_NUM_SENSORS_PER_ZONE   3
++
++/* The number of controller in the MT2701 */
++#define MT2701_NUM_CONTROLLER         1
++
++/* The calibration coefficient of sensor  */
++#define MT2701_CALIBRATION    165
++
++/* MT2712 thermal sensors */
++#define MT2712_TS1    0
++#define MT2712_TS2    1
++#define MT2712_TS3    2
++#define MT2712_TS4    3
++
++/* AUXADC channel 11 is used for the temperature sensors */
++#define MT2712_TEMP_AUXADC_CHANNEL    11
++
++/* The total number of temperature sensors in the MT2712 */
++#define MT2712_NUM_SENSORS    4
++
++/* The number of sensing points per bank */
++#define MT2712_NUM_SENSORS_PER_ZONE   4
++
++/* The number of controller in the MT2712 */
++#define MT2712_NUM_CONTROLLER         1
++
++/* The calibration coefficient of sensor  */
++#define MT2712_CALIBRATION    165
++
++#define MT7622_TEMP_AUXADC_CHANNEL    11
++#define MT7622_NUM_SENSORS            1
++#define MT7622_NUM_ZONES              1
++#define MT7622_NUM_SENSORS_PER_ZONE   1
++#define MT7622_TS1    0
++#define MT7622_NUM_CONTROLLER         1
++
++/* The maximum number of banks */
++#define MAX_NUM_ZONES         8
++
++/* The calibration coefficient of sensor  */
++#define MT7622_CALIBRATION    165
++
++/* MT8183 thermal sensors */
++#define MT8183_TS1    0
++#define MT8183_TS2    1
++#define MT8183_TS3    2
++#define MT8183_TS4    3
++#define MT8183_TS5    4
++#define MT8183_TSABB  5
++
++/* AUXADC channel  is used for the temperature sensors */
++#define MT8183_TEMP_AUXADC_CHANNEL    11
++
++/* The total number of temperature sensors in the MT8183 */
++#define MT8183_NUM_SENSORS    6
++
++/* The number of banks in the MT8183 */
++#define MT8183_NUM_ZONES               1
++
++/* The number of sensing points per bank */
++#define MT8183_NUM_SENSORS_PER_ZONE    6
++
++/* The number of controller in the MT8183 */
++#define MT8183_NUM_CONTROLLER         2
++
++/* The calibration coefficient of sensor  */
++#define MT8183_CALIBRATION    153
++
++/* AUXADC channel 11 is used for the temperature sensors */
++#define MT7986_TEMP_AUXADC_CHANNEL    11
++
++/* The total number of temperature sensors in the MT7986 */
++#define MT7986_NUM_SENSORS            1
++
++/* The number of banks in the MT7986 */
++#define MT7986_NUM_ZONES              1
++
++/* The number of sensing points per bank */
++#define MT7986_NUM_SENSORS_PER_ZONE   1
++
++/* MT7986 thermal sensors */
++#define MT7986_TS1                    0
++
++/* The number of controller in the MT7986 */
++#define MT7986_NUM_CONTROLLER         1
++
++/* The calibration coefficient of sensor  */
++#define MT7986_CALIBRATION            165
++
++struct mtk_thermal;
++
++struct thermal_bank_cfg {
++      unsigned int num_sensors;
++      const int *sensors;
++};
++
++struct mtk_thermal_bank {
++      struct mtk_thermal *mt;
++      int id;
++};
++
++struct mtk_thermal_data {
++      s32 num_banks;
++      s32 num_sensors;
++      s32 auxadc_channel;
++      const int *vts_index;
++      const int *sensor_mux_values;
++      const int *msr;
++      const int *adcpnp;
++      const int cali_val;
++      const int num_controller;
++      const int *controller_offset;
++      bool need_switch_bank;
++      struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
++      enum mtk_thermal_version version;
++};
++
++struct mtk_thermal {
++      struct device *dev;
++      void __iomem *thermal_base;
++
++      struct clk *clk_peri_therm;
++      struct clk *clk_auxadc;
++      /* lock: for getting and putting banks */
++      struct mutex lock;
++
++      /* Calibration values */
++      s32 adc_ge;
++      s32 adc_oe;
++      s32 degc_cali;
++      s32 o_slope;
++      s32 o_slope_sign;
++      s32 vts[MAX_NUM_VTS];
++
++      const struct mtk_thermal_data *conf;
++      struct mtk_thermal_bank banks[MAX_NUM_ZONES];
++
++      int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
++};
++
++/* MT8183 thermal sensor data */
++static const int mt8183_bank_data[MT8183_NUM_SENSORS] = {
++      MT8183_TS1, MT8183_TS2, MT8183_TS3, MT8183_TS4, MT8183_TS5, MT8183_TSABB
++};
++
++static const int mt8183_msr[MT8183_NUM_SENSORS_PER_ZONE] = {
++      TEMP_MSR0_1, TEMP_MSR1_1, TEMP_MSR2_1, TEMP_MSR1, TEMP_MSR0, TEMP_MSR3_1
++};
++
++static const int mt8183_adcpnp[MT8183_NUM_SENSORS_PER_ZONE] = {
++      TEMP_ADCPNP0_1, TEMP_ADCPNP1_1, TEMP_ADCPNP2_1,
++      TEMP_ADCPNP1, TEMP_ADCPNP0, TEMP_ADCPNP3_1
++};
++
++static const int mt8183_mux_values[MT8183_NUM_SENSORS] = { 0, 1, 2, 3, 4, 0 };
++static const int mt8183_tc_offset[MT8183_NUM_CONTROLLER] = {0x0, 0x100};
++
++static const int mt8183_vts_index[MT8183_NUM_SENSORS] = {
++      VTS1, VTS2, VTS3, VTS4, VTS5, VTSABB
++};
++
++/* MT8173 thermal sensor data */
++static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
++      { MT8173_TS2, MT8173_TS3 },
++      { MT8173_TS2, MT8173_TS4 },
++      { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
++      { MT8173_TS2 },
++};
++
++static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = {
++      TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
++};
++
++static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
++      TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
++};
++
++static const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
++static const int mt8173_tc_offset[MT8173_NUM_CONTROLLER] = { 0x0, };
++
++static const int mt8173_vts_index[MT8173_NUM_SENSORS] = {
++      VTS1, VTS2, VTS3, VTS4, VTSABB
++};
++
++/* MT2701 thermal sensor data */
++static const int mt2701_bank_data[MT2701_NUM_SENSORS] = {
++      MT2701_TS1, MT2701_TS2, MT2701_TSABB
++};
++
++static const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = {
++      TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
++};
++
++static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = {
++      TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
++};
++
++static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 };
++static const int mt2701_tc_offset[MT2701_NUM_CONTROLLER] = { 0x0, };
++
++static const int mt2701_vts_index[MT2701_NUM_SENSORS] = {
++      VTS1, VTS2, VTS3
++};
++
++/* MT2712 thermal sensor data */
++static const int mt2712_bank_data[MT2712_NUM_SENSORS] = {
++      MT2712_TS1, MT2712_TS2, MT2712_TS3, MT2712_TS4
++};
++
++static const int mt2712_msr[MT2712_NUM_SENSORS_PER_ZONE] = {
++      TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
++};
++
++static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = {
++      TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
++};
++
++static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 };
++static const int mt2712_tc_offset[MT2712_NUM_CONTROLLER] = { 0x0, };
++
++static const int mt2712_vts_index[MT2712_NUM_SENSORS] = {
++      VTS1, VTS2, VTS3, VTS4
++};
++
++/* MT7622 thermal sensor data */
++static const int mt7622_bank_data[MT7622_NUM_SENSORS] = { MT7622_TS1, };
++static const int mt7622_msr[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
++static const int mt7622_adcpnp[MT7622_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
++static const int mt7622_mux_values[MT7622_NUM_SENSORS] = { 0, };
++static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
++static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
++
++/* MT7986 thermal sensor data */
++static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
++static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
++static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
++static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
++static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
++static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
++
++/*
++ * The MT8173 thermal controller has four banks. Each bank can read up to
++ * four temperature sensors simultaneously. The MT8173 has a total of 5
++ * temperature sensors. We use each bank to measure a certain area of the
++ * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple
++ * areas, hence is used in different banks.
++ *
++ * The thermal core only gets the maximum temperature of all banks, so
++ * the bank concept wouldn't be necessary here. However, the SVS (Smart
++ * Voltage Scaling) unit makes its decisions based on the same bank
++ * data, and this indeed needs the temperatures of the individual banks
++ * for making better decisions.
++ */
++static const struct mtk_thermal_data mt8173_thermal_data = {
++      .auxadc_channel = MT8173_TEMP_AUXADC_CHANNEL,
++      .num_banks = MT8173_NUM_ZONES,
++      .num_sensors = MT8173_NUM_SENSORS,
++      .vts_index = mt8173_vts_index,
++      .cali_val = MT8173_CALIBRATION,
++      .num_controller = MT8173_NUM_CONTROLLER,
++      .controller_offset = mt8173_tc_offset,
++      .need_switch_bank = true,
++      .bank_data = {
++              {
++                      .num_sensors = 2,
++                      .sensors = mt8173_bank_data[0],
++              }, {
++                      .num_sensors = 2,
++                      .sensors = mt8173_bank_data[1],
++              }, {
++                      .num_sensors = 3,
++                      .sensors = mt8173_bank_data[2],
++              }, {
++                      .num_sensors = 1,
++                      .sensors = mt8173_bank_data[3],
++              },
++      },
++      .msr = mt8173_msr,
++      .adcpnp = mt8173_adcpnp,
++      .sensor_mux_values = mt8173_mux_values,
++      .version = MTK_THERMAL_V1,
++};
++
++/*
++ * The MT2701 thermal controller has one bank, which can read up to
++ * three temperature sensors simultaneously. The MT2701 has a total of 3
++ * temperature sensors.
++ *
++ * The thermal core only gets the maximum temperature of this one bank,
++ * so the bank concept wouldn't be necessary here. However, the SVS (Smart
++ * Voltage Scaling) unit makes its decisions based on the same bank
++ * data.
++ */
++static const struct mtk_thermal_data mt2701_thermal_data = {
++      .auxadc_channel = MT2701_TEMP_AUXADC_CHANNEL,
++      .num_banks = 1,
++      .num_sensors = MT2701_NUM_SENSORS,
++      .vts_index = mt2701_vts_index,
++      .cali_val = MT2701_CALIBRATION,
++      .num_controller = MT2701_NUM_CONTROLLER,
++      .controller_offset = mt2701_tc_offset,
++      .need_switch_bank = true,
++      .bank_data = {
++              {
++                      .num_sensors = 3,
++                      .sensors = mt2701_bank_data,
++              },
++      },
++      .msr = mt2701_msr,
++      .adcpnp = mt2701_adcpnp,
++      .sensor_mux_values = mt2701_mux_values,
++      .version = MTK_THERMAL_V1,
++};
++
++/*
++ * The MT2712 thermal controller has one bank, which can read up to
++ * four temperature sensors simultaneously. The MT2712 has a total of 4
++ * temperature sensors.
++ *
++ * The thermal core only gets the maximum temperature of this one bank,
++ * so the bank concept wouldn't be necessary here. However, the SVS (Smart
++ * Voltage Scaling) unit makes its decisions based on the same bank
++ * data.
++ */
++static const struct mtk_thermal_data mt2712_thermal_data = {
++      .auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL,
++      .num_banks = 1,
++      .num_sensors = MT2712_NUM_SENSORS,
++      .vts_index = mt2712_vts_index,
++      .cali_val = MT2712_CALIBRATION,
++      .num_controller = MT2712_NUM_CONTROLLER,
++      .controller_offset = mt2712_tc_offset,
++      .need_switch_bank = true,
++      .bank_data = {
++              {
++                      .num_sensors = 4,
++                      .sensors = mt2712_bank_data,
++              },
++      },
++      .msr = mt2712_msr,
++      .adcpnp = mt2712_adcpnp,
++      .sensor_mux_values = mt2712_mux_values,
++      .version = MTK_THERMAL_V1,
++};
++
++/*
++ * MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
++ * access.
++ */
++static const struct mtk_thermal_data mt7622_thermal_data = {
++      .auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL,
++      .num_banks = MT7622_NUM_ZONES,
++      .num_sensors = MT7622_NUM_SENSORS,
++      .vts_index = mt7622_vts_index,
++      .cali_val = MT7622_CALIBRATION,
++      .num_controller = MT7622_NUM_CONTROLLER,
++      .controller_offset = mt7622_tc_offset,
++      .need_switch_bank = true,
++      .bank_data = {
++              {
++                      .num_sensors = 1,
++                      .sensors = mt7622_bank_data,
++              },
++      },
++      .msr = mt7622_msr,
++      .adcpnp = mt7622_adcpnp,
++      .sensor_mux_values = mt7622_mux_values,
++      .version = MTK_THERMAL_V2,
++};
++
++/*
++ * The MT8183 thermal controller has one bank for the current SW framework.
++ * The MT8183 has a total of 6 temperature sensors.
++ * There are two thermal controller to control the six sensor.
++ * The first one bind 2 sensor, and the other bind 4 sensors.
++ * The thermal core only gets the maximum temperature of all sensor, so
++ * the bank concept wouldn't be necessary here. However, the SVS (Smart
++ * Voltage Scaling) unit makes its decisions based on the same bank
++ * data, and this indeed needs the temperatures of the individual banks
++ * for making better decisions.
++ */
++static const struct mtk_thermal_data mt8183_thermal_data = {
++      .auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL,
++      .num_banks = MT8183_NUM_ZONES,
++      .num_sensors = MT8183_NUM_SENSORS,
++      .vts_index = mt8183_vts_index,
++      .cali_val = MT8183_CALIBRATION,
++      .num_controller = MT8183_NUM_CONTROLLER,
++      .controller_offset = mt8183_tc_offset,
++      .need_switch_bank = false,
++      .bank_data = {
++              {
++                      .num_sensors = 6,
++                      .sensors = mt8183_bank_data,
++              },
++      },
++
++      .msr = mt8183_msr,
++      .adcpnp = mt8183_adcpnp,
++      .sensor_mux_values = mt8183_mux_values,
++      .version = MTK_THERMAL_V1,
++};
++
++/*
++ * MT7986 uses AUXADC Channel 11 for raw data access.
++ */
++static const struct mtk_thermal_data mt7986_thermal_data = {
++      .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
++      .num_banks = MT7986_NUM_ZONES,
++      .num_sensors = MT7986_NUM_SENSORS,
++      .vts_index = mt7986_vts_index,
++      .cali_val = MT7986_CALIBRATION,
++      .num_controller = MT7986_NUM_CONTROLLER,
++      .controller_offset = mt7986_tc_offset,
++      .need_switch_bank = true,
++      .bank_data = {
++              {
++                      .num_sensors = 1,
++                      .sensors = mt7986_bank_data,
++              },
++      },
++      .msr = mt7986_msr,
++      .adcpnp = mt7986_adcpnp,
++      .sensor_mux_values = mt7986_mux_values,
++      .version = MTK_THERMAL_V3,
++};
++
++/**
++ * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
++ * @mt:       The thermal controller
++ * @sensno:   sensor number
++ * @raw:      raw ADC value
++ *
++ * This converts the raw ADC value to mcelsius using the SoC specific
++ * calibration constants
++ */
++static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
++{
++      s32 tmp;
++
++      raw &= 0xfff;
++
++      tmp = 203450520 << 3;
++      tmp /= mt->conf->cali_val + mt->o_slope;
++      tmp /= 10000 + mt->adc_ge;
++      tmp *= raw - mt->vts[sensno] - 3350;
++      tmp >>= 3;
++
++      return mt->degc_cali * 500 - tmp;
++}
++
++static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
++{
++      s32 format_1;
++      s32 format_2;
++      s32 g_oe;
++      s32 g_gain;
++      s32 g_x_roomt;
++      s32 tmp;
++
++      if (raw == 0)
++              return 0;
++
++      raw &= 0xfff;
++      g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12);
++      g_oe = mt->adc_oe - 512;
++      format_1 = mt->vts[VTS2] + 3105 - g_oe;
++      format_2 = (mt->degc_cali * 10) >> 1;
++      g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain;
++
++      tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt;
++      tmp = tmp * 10 * 100 / 11;
++
++      if (mt->o_slope_sign == 0)
++              tmp = tmp / (165 - mt->o_slope);
++      else
++              tmp = tmp / (165 + mt->o_slope);
++
++      return (format_2 - tmp) * 100;
++}
++
++static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
++{
++      s32 tmp;
++
++      if (raw == 0)
++              return 0;
++
++      raw &= 0xfff;
++      tmp = 100000 * 15 / 16 * 10000;
++      tmp /= 4096 - 512 + mt->adc_ge;
++      tmp /= 1490;
++      tmp *= raw - mt->vts[sensno] - 2900;
++
++      return mt->degc_cali * 500 - tmp;
++}
++
++/**
++ * mtk_thermal_get_bank - get bank
++ * @bank:     The bank
++ *
++ * The bank registers are banked, we have to select a bank in the
++ * PTPCORESEL register to access it.
++ */
++static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank)
++{
++      struct mtk_thermal *mt = bank->mt;
++      u32 val;
++
++      if (mt->conf->need_switch_bank) {
++              mutex_lock(&mt->lock);
++
++              val = readl(mt->thermal_base + PTPCORESEL);
++              val &= ~0xf;
++              val |= bank->id;
++              writel(val, mt->thermal_base + PTPCORESEL);
++      }
++}
++
++/**
++ * mtk_thermal_put_bank - release bank
++ * @bank:     The bank
++ *
++ * release a bank previously taken with mtk_thermal_get_bank,
++ */
++static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
++{
++      struct mtk_thermal *mt = bank->mt;
++
++      if (mt->conf->need_switch_bank)
++              mutex_unlock(&mt->lock);
++}
++
++/**
++ * mtk_thermal_bank_temperature - get the temperature of a bank
++ * @bank:     The bank
++ *
++ * The temperature of a bank is considered the maximum temperature of
++ * the sensors associated to the bank.
++ */
++static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
++{
++      struct mtk_thermal *mt = bank->mt;
++      const struct mtk_thermal_data *conf = mt->conf;
++      int i, temp = INT_MIN, max = INT_MIN;
++      u32 raw;
++
++      for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
++              raw = readl(mt->thermal_base + conf->msr[i]);
++
++              temp = mt->raw_to_mcelsius(
++                      mt, conf->bank_data[bank->id].sensors[i], raw);
++
++
++              /*
++               * The first read of a sensor often contains very high bogus
++               * temperature value. Filter these out so that the system does
++               * not immediately shut down.
++               */
++              if (temp > 200000)
++                      temp = 0;
++
++              if (temp > max)
++                      max = temp;
++      }
++
++      return max;
++}
++
++static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature)
++{
++      struct mtk_thermal *mt = tz->devdata;
++      int i;
++      int tempmax = INT_MIN;
++
++      for (i = 0; i < mt->conf->num_banks; i++) {
++              struct mtk_thermal_bank *bank = &mt->banks[i];
++
++              mtk_thermal_get_bank(bank);
++
++              tempmax = max(tempmax, mtk_thermal_bank_temperature(bank));
++
++              mtk_thermal_put_bank(bank);
++      }
++
++      *temperature = tempmax;
++
++      return 0;
++}
++
++static const struct thermal_zone_device_ops mtk_thermal_ops = {
++      .get_temp = mtk_read_temp,
++};
++
++static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
++                                u32 apmixed_phys_base, u32 auxadc_phys_base,
++                                int ctrl_id)
++{
++      struct mtk_thermal_bank *bank = &mt->banks[num];
++      const struct mtk_thermal_data *conf = mt->conf;
++      int i;
++
++      int offset = mt->conf->controller_offset[ctrl_id];
++      void __iomem *controller_base = mt->thermal_base + offset;
++
++      bank->id = num;
++      bank->mt = mt;
++
++      mtk_thermal_get_bank(bank);
++
++      /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
++      writel(TEMP_MONCTL1_PERIOD_UNIT(12), controller_base + TEMP_MONCTL1);
++
++      /*
++       * filt interval is 1 * 46.540us = 46.54us,
++       * sen interval is 429 * 46.540us = 19.96ms
++       */
++      writel(TEMP_MONCTL2_FILTER_INTERVAL(1) |
++                      TEMP_MONCTL2_SENSOR_INTERVAL(429),
++                      controller_base + TEMP_MONCTL2);
++
++      /* poll is set to 10u */
++      writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768),
++             controller_base + TEMP_AHBPOLL);
++
++      /* temperature sampling control, 1 sample */
++      writel(0x0, controller_base + TEMP_MSRCTL0);
++
++      /* exceed this polling time, IRQ would be inserted */
++      writel(0xffffffff, controller_base + TEMP_AHBTO);
++
++      /* number of interrupts per event, 1 is enough */
++      writel(0x0, controller_base + TEMP_MONIDET0);
++      writel(0x0, controller_base + TEMP_MONIDET1);
++
++      /*
++       * The MT8173 thermal controller does not have its own ADC. Instead it
++       * uses AHB bus accesses to control the AUXADC. To do this the thermal
++       * controller has to be programmed with the physical addresses of the
++       * AUXADC registers and with the various bit positions in the AUXADC.
++       * Also the thermal controller controls a mux in the APMIXEDSYS register
++       * space.
++       */
++
++      /*
++       * this value will be stored to TEMP_PNPMUXADDR (TEMP_SPARE0)
++       * automatically by hw
++       */
++      writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCMUX);
++
++      /* AHB address for auxadc mux selection */
++      writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
++             controller_base + TEMP_ADCMUXADDR);
++
++      if (mt->conf->version == MTK_THERMAL_V1) {
++              /* AHB address for pnp sensor mux selection */
++              writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
++                     controller_base + TEMP_PNPMUXADDR);
++      }
++
++      /* AHB value for auxadc enable */
++      writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCEN);
++
++      /* AHB address for auxadc enable (channel 0 immediate mode selected) */
++      writel(auxadc_phys_base + AUXADC_CON1_SET_V,
++             controller_base + TEMP_ADCENADDR);
++
++      /* AHB address for auxadc valid bit */
++      writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
++             controller_base + TEMP_ADCVALIDADDR);
++
++      /* AHB address for auxadc voltage output */
++      writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
++             controller_base + TEMP_ADCVOLTADDR);
++
++      /* read valid & voltage are at the same register */
++      writel(0x0, controller_base + TEMP_RDCTRL);
++
++      /* indicate where the valid bit is */
++      writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12),
++             controller_base + TEMP_ADCVALIDMASK);
++
++      /* no shift */
++      writel(0x0, controller_base + TEMP_ADCVOLTAGESHIFT);
++
++      /* enable auxadc mux write transaction */
++      writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
++              controller_base + TEMP_ADCWRITECTRL);
++
++      for (i = 0; i < conf->bank_data[num].num_sensors; i++)
++              writel(conf->sensor_mux_values[conf->bank_data[num].sensors[i]],
++                     mt->thermal_base + conf->adcpnp[i]);
++
++      writel((1 << conf->bank_data[num].num_sensors) - 1,
++             controller_base + TEMP_MONCTL0);
++
++      writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE |
++             TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
++             controller_base + TEMP_ADCWRITECTRL);
++
++      mtk_thermal_put_bank(bank);
++}
++
++static u64 of_get_phys_base(struct device_node *np)
++{
++      u64 size64;
++      const __be32 *regaddr_p;
++
++      regaddr_p = of_get_address(np, 0, &size64, NULL);
++      if (!regaddr_p)
++              return OF_BAD_ADDR;
++
++      return of_translate_address(np, regaddr_p);
++}
++
++static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
++{
++      int i;
++
++      if (!(buf[0] & CALIB_BUF0_VALID_V1))
++              return -EINVAL;
++
++      mt->adc_ge = CALIB_BUF1_ADC_GE_V1(buf[1]);
++
++      for (i = 0; i < mt->conf->num_sensors; i++) {
++              switch (mt->conf->vts_index[i]) {
++              case VTS1:
++                      mt->vts[VTS1] = CALIB_BUF0_VTS_TS1_V1(buf[0]);
++                      break;
++              case VTS2:
++                      mt->vts[VTS2] = CALIB_BUF0_VTS_TS2_V1(buf[0]);
++                      break;
++              case VTS3:
++                      mt->vts[VTS3] = CALIB_BUF1_VTS_TS3_V1(buf[1]);
++                      break;
++              case VTS4:
++                      mt->vts[VTS4] = CALIB_BUF2_VTS_TS4_V1(buf[2]);
++                      break;
++              case VTS5:
++                      mt->vts[VTS5] = CALIB_BUF2_VTS_TS5_V1(buf[2]);
++                      break;
++              case VTSABB:
++                      mt->vts[VTSABB] =
++                              CALIB_BUF2_VTS_TSABB_V1(buf[2]);
++                      break;
++              default:
++                      break;
++              }
++      }
++
++      mt->degc_cali = CALIB_BUF0_DEGC_CALI_V1(buf[0]);
++      if (CALIB_BUF1_ID_V1(buf[1]) &
++          CALIB_BUF0_O_SLOPE_SIGN_V1(buf[0]))
++              mt->o_slope = -CALIB_BUF0_O_SLOPE_V1(buf[0]);
++      else
++              mt->o_slope = CALIB_BUF0_O_SLOPE_V1(buf[0]);
++
++      return 0;
++}
++
++static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf)
++{
++      if (!CALIB_BUF1_VALID_V2(buf[1]))
++              return -EINVAL;
++
++      mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]);
++      mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]);
++      mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]);
++      mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]);
++      mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]);
++      mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]);
++      mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]);
++      mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]);
++
++      return 0;
++}
++
++static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
++{
++      if (!CALIB_BUF1_VALID_V3(buf[1]))
++              return -EINVAL;
++
++      mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
++      mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
++      mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
++      mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
++      mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
++      mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
++      mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
++
++      if (CALIB_BUF1_ID_V3(buf[1]) == 0)
++              mt->o_slope = 0;
++
++      return 0;
++}
++
++static int mtk_thermal_get_calibration_data(struct device *dev,
++                                          struct mtk_thermal *mt)
++{
++      struct nvmem_cell *cell;
++      u32 *buf;
++      size_t len;
++      int i, ret = 0;
++
++      /* Start with default values */
++      mt->adc_ge = 512;
++      mt->adc_oe = 512;
++      for (i = 0; i < mt->conf->num_sensors; i++)
++              mt->vts[i] = 260;
++      mt->degc_cali = 40;
++      mt->o_slope = 0;
++
++      cell = nvmem_cell_get(dev, "calibration-data");
++      if (IS_ERR(cell)) {
++              if (PTR_ERR(cell) == -EPROBE_DEFER)
++                      return PTR_ERR(cell);
++              return 0;
++      }
++
++      buf = (u32 *)nvmem_cell_read(cell, &len);
++
++      nvmem_cell_put(cell);
++
++      if (IS_ERR(buf))
++              return PTR_ERR(buf);
++
++      if (len < 3 * sizeof(u32)) {
++              dev_warn(dev, "invalid calibration data\n");
++              ret = -EINVAL;
++              goto out;
++      }
++
++      switch (mt->conf->version) {
++      case MTK_THERMAL_V1:
++              ret = mtk_thermal_extract_efuse_v1(mt, buf);
++              break;
++      case MTK_THERMAL_V2:
++              ret = mtk_thermal_extract_efuse_v2(mt, buf);
++              break;
++      case MTK_THERMAL_V3:
++              ret = mtk_thermal_extract_efuse_v3(mt, buf);
++              break;
++      default:
++              ret = -EINVAL;
++              break;
++      }
++
++      if (ret) {
++              dev_info(dev, "Device not calibrated, using default calibration values\n");
++              ret = 0;
++      }
++
++out:
++      kfree(buf);
++
++      return ret;
++}
++
++static const struct of_device_id mtk_thermal_of_match[] = {
++      {
++              .compatible = "mediatek,mt8173-thermal",
++              .data = (void *)&mt8173_thermal_data,
++      },
++      {
++              .compatible = "mediatek,mt2701-thermal",
++              .data = (void *)&mt2701_thermal_data,
++      },
++      {
++              .compatible = "mediatek,mt2712-thermal",
++              .data = (void *)&mt2712_thermal_data,
++      },
++      {
++              .compatible = "mediatek,mt7622-thermal",
++              .data = (void *)&mt7622_thermal_data,
++      },
++      {
++              .compatible = "mediatek,mt7986-thermal",
++              .data = (void *)&mt7986_thermal_data,
++      },
++      {
++              .compatible = "mediatek,mt8183-thermal",
++              .data = (void *)&mt8183_thermal_data,
++      }, {
++      },
++};
++MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
++
++static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
++{
++      int tmp;
++
++      tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
++      tmp &= ~(0x37);
++      tmp |= 0x1;
++      writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
++      udelay(200);
++}
++
++static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt,
++                                          void __iomem *auxadc_base)
++{
++      int tmp;
++
++      writel(0x800, auxadc_base + AUXADC_CON1_SET_V);
++      writel(0x1, mt->thermal_base + TEMP_MONCTL0);
++      tmp = readl(mt->thermal_base + TEMP_MSRCTL1);
++      writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1);
++}
++
++static int mtk_thermal_probe(struct platform_device *pdev)
++{
++      int ret, i, ctrl_id;
++      struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
++      struct mtk_thermal *mt;
++      u64 auxadc_phys_base, apmixed_phys_base;
++      struct thermal_zone_device *tzdev;
++      void __iomem *apmixed_base, *auxadc_base;
++
++      mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
++      if (!mt)
++              return -ENOMEM;
++
++      mt->conf = of_device_get_match_data(&pdev->dev);
++
++      mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
++      if (IS_ERR(mt->clk_peri_therm))
++              return PTR_ERR(mt->clk_peri_therm);
++
++      mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
++      if (IS_ERR(mt->clk_auxadc))
++              return PTR_ERR(mt->clk_auxadc);
++
++      mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
++      if (IS_ERR(mt->thermal_base))
++              return PTR_ERR(mt->thermal_base);
++
++      ret = mtk_thermal_get_calibration_data(&pdev->dev, mt);
++      if (ret)
++              return ret;
++
++      mutex_init(&mt->lock);
++
++      mt->dev = &pdev->dev;
++
++      auxadc = of_parse_phandle(np, "mediatek,auxadc", 0);
++      if (!auxadc) {
++              dev_err(&pdev->dev, "missing auxadc node\n");
++              return -ENODEV;
++      }
++
++      auxadc_base = of_iomap(auxadc, 0);
++      auxadc_phys_base = of_get_phys_base(auxadc);
++
++      of_node_put(auxadc);
++
++      if (auxadc_phys_base == OF_BAD_ADDR) {
++              dev_err(&pdev->dev, "Can't get auxadc phys address\n");
++              return -EINVAL;
++      }
++
++      apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0);
++      if (!apmixedsys) {
++              dev_err(&pdev->dev, "missing apmixedsys node\n");
++              return -ENODEV;
++      }
++
++      apmixed_base = of_iomap(apmixedsys, 0);
++      apmixed_phys_base = of_get_phys_base(apmixedsys);
++
++      of_node_put(apmixedsys);
++
++      if (apmixed_phys_base == OF_BAD_ADDR) {
++              dev_err(&pdev->dev, "Can't get auxadc phys address\n");
++              return -EINVAL;
++      }
++
++      ret = device_reset_optional(&pdev->dev);
++      if (ret)
++              return ret;
++
++      ret = clk_prepare_enable(mt->clk_auxadc);
++      if (ret) {
++              dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
++              return ret;
++      }
++
++      ret = clk_prepare_enable(mt->clk_peri_therm);
++      if (ret) {
++              dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
++              goto err_disable_clk_auxadc;
++      }
++
++      if (mt->conf->version != MTK_THERMAL_V1) {
++              mtk_thermal_turn_on_buffer(apmixed_base);
++              mtk_thermal_release_periodic_ts(mt, auxadc_base);
++      }
++
++      if (mt->conf->version == MTK_THERMAL_V1)
++              mt->raw_to_mcelsius = raw_to_mcelsius_v1;
++      else if (mt->conf->version == MTK_THERMAL_V2)
++              mt->raw_to_mcelsius = raw_to_mcelsius_v2;
++      else
++              mt->raw_to_mcelsius = raw_to_mcelsius_v3;
++
++      for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++)
++              for (i = 0; i < mt->conf->num_banks; i++)
++                      mtk_thermal_init_bank(mt, i, apmixed_phys_base,
++                                            auxadc_phys_base, ctrl_id);
++
++      platform_set_drvdata(pdev, mt);
++
++      tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
++                                            &mtk_thermal_ops);
++      if (IS_ERR(tzdev)) {
++              ret = PTR_ERR(tzdev);
++              goto err_disable_clk_peri_therm;
++      }
++
++      ret = devm_thermal_add_hwmon_sysfs(tzdev);
++      if (ret)
++              dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
++
++      return 0;
++
++err_disable_clk_peri_therm:
++      clk_disable_unprepare(mt->clk_peri_therm);
++err_disable_clk_auxadc:
++      clk_disable_unprepare(mt->clk_auxadc);
++
++      return ret;
++}
++
++static int mtk_thermal_remove(struct platform_device *pdev)
++{
++      struct mtk_thermal *mt = platform_get_drvdata(pdev);
++
++      clk_disable_unprepare(mt->clk_peri_therm);
++      clk_disable_unprepare(mt->clk_auxadc);
++
++      return 0;
++}
++
++static struct platform_driver mtk_thermal_driver = {
++      .probe = mtk_thermal_probe,
++      .remove = mtk_thermal_remove,
++      .driver = {
++              .name = "mtk-thermal",
++              .of_match_table = mtk_thermal_of_match,
++      },
++};
++
++module_platform_driver(mtk_thermal_driver);
++
++MODULE_AUTHOR("Michael Kao <michael.kao@mediatek.com>");
++MODULE_AUTHOR("Louis Yu <louis.yu@mediatek.com>");
++MODULE_AUTHOR("Dawei Chien <dawei.chien@mediatek.com>");
++MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
++MODULE_AUTHOR("Hanyi Wu <hanyi.wu@mediatek.com>");
++MODULE_DESCRIPTION("Mediatek thermal driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/mediatek/patches-6.6/830-v6.3-06-thermal-drivers-mediatek-Add-the-Low-Voltage-Thermal.patch b/target/linux/mediatek/patches-6.6/830-v6.3-06-thermal-drivers-mediatek-Add-the-Low-Voltage-Thermal.patch
new file mode 100644 (file)
index 0000000..2ae3734
--- /dev/null
@@ -0,0 +1,1298 @@
+From 325fadf27b21f7d79843c3cc282b7f3e6620ad3d Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Thu, 9 Feb 2023 11:56:26 +0100
+Subject: [PATCH 06/42] thermal/drivers/mediatek: Add the Low Voltage Thermal
+ Sensor driver
+
+The Low Voltage Thermal Sensor (LVTS) is a multiple sensors, multi
+controllers contained in a thermal domain.
+
+A thermal domains can be the MCU or the AP.
+
+Each thermal domains contain up to seven controllers, each thermal
+controller handle up to four thermal sensors.
+
+The LVTS has two Finite State Machines (FSM), one to handle the
+functionin temperatures range like hot or cold temperature and another
+one to handle monitoring trip point. The FSM notifies via interrupts
+when a trip point is crossed.
+
+The interrupt is managed at the thermal controller level, so when an
+interrupt occurs, the driver has to find out which sensor triggered
+such an interrupt.
+
+The sampling of the thermal can be filtered or immediate. For the
+former, the LVTS measures several points and applies a low pass
+filter.
+
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+On MT8195 Tomato Chromebook:
+
+Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230209105628.50294-5-bchihi@baylibre.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/thermal/mediatek/Kconfig        |   16 +
+ drivers/thermal/mediatek/Makefile       |    1 +
+ drivers/thermal/mediatek/lvts_thermal.c | 1224 +++++++++++++++++++++++
+ 3 files changed, 1241 insertions(+)
+ create mode 100644 drivers/thermal/mediatek/lvts_thermal.c
+
+--- a/drivers/thermal/mediatek/Kconfig
++++ b/drivers/thermal/mediatek/Kconfig
+@@ -18,4 +18,20 @@ config MTK_SOC_THERMAL
+         This driver configures thermal controllers to collect
+         temperature via AUXADC interface.
++config MTK_LVTS_THERMAL
++        tristate "LVTS Thermal Driver for MediaTek SoCs"
++        depends on HAS_IOMEM
++        help
++          Enable this option if you want to get SoC temperature
++          information for supported MediaTek platforms.
++          This driver configures LVTS (Low Voltage Thermal Sensor)
++          thermal controllers to collect temperatures via ASIF
++          (Analog Serial Interface).
++
++config MTK_LVTS_THERMAL_DEBUGFS
++       bool "LVTS thermal debugfs"
++       depends on MTK_LVTS_THERMAL && DEBUG_FS
++       help
++         Enable this option to debug the internals of the device driver.
++
+ endif
+--- a/drivers/thermal/mediatek/Makefile
++++ b/drivers/thermal/mediatek/Makefile
+@@ -1 +1,2 @@
+ obj-$(CONFIG_MTK_SOC_THERMAL) += auxadc_thermal.o
++obj-$(CONFIG_MTK_LVTS_THERMAL)        += lvts_thermal.o
+--- /dev/null
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -0,0 +1,1224 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Balsam CHIHI <bchihi@baylibre.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/delay.h>
++#include <linux/debugfs.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++#include <linux/thermal.h>
++#include <dt-bindings/thermal/mediatek,lvts-thermal.h>
++
++#define LVTS_MONCTL0(__base)  (__base + 0x0000)
++#define LVTS_MONCTL1(__base)  (__base + 0x0004)
++#define LVTS_MONCTL2(__base)  (__base + 0x0008)
++#define LVTS_MONINT(__base)           (__base + 0x000C)
++#define LVTS_MONINTSTS(__base)        (__base + 0x0010)
++#define LVTS_MONIDET0(__base) (__base + 0x0014)
++#define LVTS_MONIDET1(__base) (__base + 0x0018)
++#define LVTS_MONIDET2(__base) (__base + 0x001C)
++#define LVTS_MONIDET3(__base) (__base + 0x0020)
++#define LVTS_H2NTHRE(__base)  (__base + 0x0024)
++#define LVTS_HTHRE(__base)            (__base + 0x0028)
++#define LVTS_OFFSETH(__base)  (__base + 0x0030)
++#define LVTS_OFFSETL(__base)  (__base + 0x0034)
++#define LVTS_MSRCTL0(__base)  (__base + 0x0038)
++#define LVTS_MSRCTL1(__base)  (__base + 0x003C)
++#define LVTS_TSSEL(__base)            (__base + 0x0040)
++#define LVTS_CALSCALE(__base) (__base + 0x0048)
++#define LVTS_ID(__base)                       (__base + 0x004C)
++#define LVTS_CONFIG(__base)           (__base + 0x0050)
++#define LVTS_EDATA00(__base)  (__base + 0x0054)
++#define LVTS_EDATA01(__base)  (__base + 0x0058)
++#define LVTS_EDATA02(__base)  (__base + 0x005C)
++#define LVTS_EDATA03(__base)  (__base + 0x0060)
++#define LVTS_MSR0(__base)             (__base + 0x0090)
++#define LVTS_MSR1(__base)             (__base + 0x0094)
++#define LVTS_MSR2(__base)             (__base + 0x0098)
++#define LVTS_MSR3(__base)             (__base + 0x009C)
++#define LVTS_IMMD0(__base)            (__base + 0x00A0)
++#define LVTS_IMMD1(__base)            (__base + 0x00A4)
++#define LVTS_IMMD2(__base)            (__base + 0x00A8)
++#define LVTS_IMMD3(__base)            (__base + 0x00AC)
++#define LVTS_PROTCTL(__base)  (__base + 0x00C0)
++#define LVTS_PROTTA(__base)           (__base + 0x00C4)
++#define LVTS_PROTTB(__base)           (__base + 0x00C8)
++#define LVTS_PROTTC(__base)           (__base + 0x00CC)
++#define LVTS_CLKEN(__base)            (__base + 0x00E4)
++
++#define LVTS_PERIOD_UNIT                      ((118 * 1000) / (256 * 38))
++#define LVTS_GROUP_INTERVAL                   1
++#define LVTS_FILTER_INTERVAL          1
++#define LVTS_SENSOR_INTERVAL          1
++#define LVTS_HW_FILTER                                0x2
++#define LVTS_TSSEL_CONF                               0x13121110
++#define LVTS_CALSCALE_CONF                    0x300
++#define LVTS_MONINT_CONF                      0x9FBF7BDE
++
++#define LVTS_INT_SENSOR0                      0x0009001F
++#define LVTS_INT_SENSOR1                      0X000881F0
++#define LVTS_INT_SENSOR2                      0x00247C00
++#define LVTS_INT_SENSOR3                      0x1FC00000
++
++#define LVTS_SENSOR_MAX                               4
++#define LVTS_GOLDEN_TEMP_MAX          62
++#define LVTS_GOLDEN_TEMP_DEFAULT      50
++#define LVTS_COEFF_A                          -250460
++#define LVTS_COEFF_B                          250460
++
++#define LVTS_MSR_IMMEDIATE_MODE               0
++#define LVTS_MSR_FILTERED_MODE                1
++
++#define LVTS_HW_SHUTDOWN_MT8195               105000
++
++static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
++static int coeff_b = LVTS_COEFF_B;
++
++struct lvts_sensor_data {
++      int dt_id;
++};
++
++struct lvts_ctrl_data {
++      struct lvts_sensor_data lvts_sensor[LVTS_SENSOR_MAX];
++      int cal_offset[LVTS_SENSOR_MAX];
++      int hw_tshut_temp;
++      int num_lvts_sensor;
++      int offset;
++      int mode;
++};
++
++struct lvts_data {
++      const struct lvts_ctrl_data *lvts_ctrl;
++      int num_lvts_ctrl;
++};
++
++struct lvts_sensor {
++      struct thermal_zone_device *tz;
++      void __iomem *msr;
++      void __iomem *base;
++      int id;
++      int dt_id;
++};
++
++struct lvts_ctrl {
++      struct lvts_sensor sensors[LVTS_SENSOR_MAX];
++      u32 calibration[LVTS_SENSOR_MAX];
++      u32 hw_tshut_raw_temp;
++      int num_lvts_sensor;
++      int mode;
++      void __iomem *base;
++};
++
++struct lvts_domain {
++      struct lvts_ctrl *lvts_ctrl;
++      struct reset_control *reset;
++      struct clk *clk;
++      int num_lvts_ctrl;
++      void __iomem *base;
++      size_t calib_len;
++      u8 *calib;
++#ifdef CONFIG_DEBUG_FS
++      struct dentry *dom_dentry;
++#endif
++};
++
++#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
++
++#define LVTS_DEBUG_FS_REGS(__reg)             \
++{                                             \
++      .name = __stringify(__reg),             \
++      .offset = __reg(0),                     \
++}
++
++static const struct debugfs_reg32 lvts_regs[] = {
++      LVTS_DEBUG_FS_REGS(LVTS_MONCTL0),
++      LVTS_DEBUG_FS_REGS(LVTS_MONCTL1),
++      LVTS_DEBUG_FS_REGS(LVTS_MONCTL2),
++      LVTS_DEBUG_FS_REGS(LVTS_MONINT),
++      LVTS_DEBUG_FS_REGS(LVTS_MONINTSTS),
++      LVTS_DEBUG_FS_REGS(LVTS_MONIDET0),
++      LVTS_DEBUG_FS_REGS(LVTS_MONIDET1),
++      LVTS_DEBUG_FS_REGS(LVTS_MONIDET2),
++      LVTS_DEBUG_FS_REGS(LVTS_MONIDET3),
++      LVTS_DEBUG_FS_REGS(LVTS_H2NTHRE),
++      LVTS_DEBUG_FS_REGS(LVTS_HTHRE),
++      LVTS_DEBUG_FS_REGS(LVTS_OFFSETH),
++      LVTS_DEBUG_FS_REGS(LVTS_OFFSETL),
++      LVTS_DEBUG_FS_REGS(LVTS_MSRCTL0),
++      LVTS_DEBUG_FS_REGS(LVTS_MSRCTL1),
++      LVTS_DEBUG_FS_REGS(LVTS_TSSEL),
++      LVTS_DEBUG_FS_REGS(LVTS_CALSCALE),
++      LVTS_DEBUG_FS_REGS(LVTS_ID),
++      LVTS_DEBUG_FS_REGS(LVTS_CONFIG),
++      LVTS_DEBUG_FS_REGS(LVTS_EDATA00),
++      LVTS_DEBUG_FS_REGS(LVTS_EDATA01),
++      LVTS_DEBUG_FS_REGS(LVTS_EDATA02),
++      LVTS_DEBUG_FS_REGS(LVTS_EDATA03),
++      LVTS_DEBUG_FS_REGS(LVTS_MSR0),
++      LVTS_DEBUG_FS_REGS(LVTS_MSR1),
++      LVTS_DEBUG_FS_REGS(LVTS_MSR2),
++      LVTS_DEBUG_FS_REGS(LVTS_MSR3),
++      LVTS_DEBUG_FS_REGS(LVTS_IMMD0),
++      LVTS_DEBUG_FS_REGS(LVTS_IMMD1),
++      LVTS_DEBUG_FS_REGS(LVTS_IMMD2),
++      LVTS_DEBUG_FS_REGS(LVTS_IMMD3),
++      LVTS_DEBUG_FS_REGS(LVTS_PROTCTL),
++      LVTS_DEBUG_FS_REGS(LVTS_PROTTA),
++      LVTS_DEBUG_FS_REGS(LVTS_PROTTB),
++      LVTS_DEBUG_FS_REGS(LVTS_PROTTC),
++      LVTS_DEBUG_FS_REGS(LVTS_CLKEN),
++};
++
++static int lvts_debugfs_init(struct device *dev, struct lvts_domain *lvts_td)
++{
++      struct debugfs_regset32 *regset;
++      struct lvts_ctrl *lvts_ctrl;
++      struct dentry *dentry;
++      char name[64];
++      int i;
++
++      lvts_td->dom_dentry = debugfs_create_dir(dev_name(dev), NULL);
++      if (!lvts_td->dom_dentry)
++              return 0;
++
++      for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
++
++              lvts_ctrl = &lvts_td->lvts_ctrl[i];
++
++              sprintf(name, "controller%d", i);
++              dentry = debugfs_create_dir(name, lvts_td->dom_dentry);
++              if (!dentry)
++                      continue;
++
++              regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
++              if (!regset)
++                      continue;
++
++              regset->base = lvts_ctrl->base;
++              regset->regs = lvts_regs;
++              regset->nregs = ARRAY_SIZE(lvts_regs);
++
++              debugfs_create_regset32("registers", 0400, dentry, regset);
++      }
++
++      return 0;
++}
++
++static void lvts_debugfs_exit(struct lvts_domain *lvts_td)
++{
++      debugfs_remove_recursive(lvts_td->dom_dentry);
++}
++
++#else
++
++static inline int lvts_debugfs_init(struct device *dev,
++                                  struct lvts_domain *lvts_td)
++{
++      return 0;
++}
++
++static void lvts_debugfs_exit(struct lvts_domain *lvts_td) { }
++
++#endif
++
++static int lvts_raw_to_temp(u32 raw_temp)
++{
++      int temperature;
++
++      temperature = ((s64)(raw_temp & 0xFFFF) * LVTS_COEFF_A) >> 14;
++      temperature += coeff_b;
++
++      return temperature;
++}
++
++static u32 lvts_temp_to_raw(int temperature)
++{
++      u32 raw_temp = ((s64)(coeff_b - temperature)) << 14;
++
++      raw_temp = div_s64(raw_temp, -LVTS_COEFF_A);
++
++      return raw_temp;
++}
++
++static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
++{
++      struct lvts_sensor *lvts_sensor = tz->devdata;
++      void __iomem *msr = lvts_sensor->msr;
++      u32 value;
++
++      /*
++       * Measurement registers:
++       *
++       * LVTS_MSR[0-3] / LVTS_IMMD[0-3]
++       *
++       * Bits:
++       *
++       * 32-17: Unused
++       * 16   : Valid temperature
++       * 15-0 : Raw temperature
++       */
++      value = readl(msr);
++
++      /*
++       * As the thermal zone temperature will read before the
++       * hardware sensor is fully initialized, we have to check the
++       * validity of the temperature returned when reading the
++       * measurement register. The thermal controller will set the
++       * valid bit temperature only when it is totally initialized.
++       *
++       * Otherwise, we may end up with garbage values out of the
++       * functionning temperature and directly jump to a system
++       * shutdown.
++       */
++      if (!(value & BIT(16)))
++              return -EAGAIN;
++
++      *temp = lvts_raw_to_temp(value & 0xFFFF);
++
++      return 0;
++}
++
++static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
++{
++      struct lvts_sensor *lvts_sensor = tz->devdata;
++      void __iomem *base = lvts_sensor->base;
++      u32 raw_low = lvts_temp_to_raw(low);
++      u32 raw_high = lvts_temp_to_raw(high);
++
++      /*
++       * Hot to normal temperature threshold
++       *
++       * LVTS_H2NTHRE
++       *
++       * Bits:
++       *
++       * 14-0 : Raw temperature for threshold
++       */
++      if (low != -INT_MAX) {
++              dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low);
++              writel(raw_low, LVTS_H2NTHRE(base));
++      }
++
++      /*
++       * Hot temperature threshold
++       *
++       * LVTS_HTHRE
++       *
++       * Bits:
++       *
++       * 14-0 : Raw temperature for threshold
++       */
++      dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high);
++      writel(raw_high, LVTS_HTHRE(base));
++
++      return 0;
++}
++
++static irqreturn_t lvts_ctrl_irq_handler(struct lvts_ctrl *lvts_ctrl)
++{
++      irqreturn_t iret = IRQ_NONE;
++      u32 value;
++      u32 masks[] = {
++              LVTS_INT_SENSOR0,
++              LVTS_INT_SENSOR1,
++              LVTS_INT_SENSOR2,
++              LVTS_INT_SENSOR3
++      };
++      int i;
++
++      /*
++       * Interrupt monitoring status
++       *
++       * LVTS_MONINTST
++       *
++       * Bits:
++       *
++       * 31 : Interrupt for stage 3
++       * 30 : Interrupt for stage 2
++       * 29 : Interrupt for state 1
++       * 28 : Interrupt using filter on sensor 3
++       *
++       * 27 : Interrupt using immediate on sensor 3
++       * 26 : Interrupt normal to hot on sensor 3
++       * 25 : Interrupt high offset on sensor 3
++       * 24 : Interrupt low offset on sensor 3
++       *
++       * 23 : Interrupt hot threshold on sensor 3
++       * 22 : Interrupt cold threshold on sensor 3
++       * 21 : Interrupt using filter on sensor 2
++       * 20 : Interrupt using filter on sensor 1
++       *
++       * 19 : Interrupt using filter on sensor 0
++       * 18 : Interrupt using immediate on sensor 2
++       * 17 : Interrupt using immediate on sensor 1
++       * 16 : Interrupt using immediate on sensor 0
++       *
++       * 15 : Interrupt device access timeout interrupt
++       * 14 : Interrupt normal to hot on sensor 2
++       * 13 : Interrupt high offset interrupt on sensor 2
++       * 12 : Interrupt low offset interrupt on sensor 2
++       *
++       * 11 : Interrupt hot threshold on sensor 2
++       * 10 : Interrupt cold threshold on sensor 2
++       *  9 : Interrupt normal to hot on sensor 1
++       *  8 : Interrupt high offset interrupt on sensor 1
++       *
++       *  7 : Interrupt low offset interrupt on sensor 1
++       *  6 : Interrupt hot threshold on sensor 1
++       *  5 : Interrupt cold threshold on sensor 1
++       *  4 : Interrupt normal to hot on sensor 0
++       *
++       *  3 : Interrupt high offset interrupt on sensor 0
++       *  2 : Interrupt low offset interrupt on sensor 0
++       *  1 : Interrupt hot threshold on sensor 0
++       *  0 : Interrupt cold threshold on sensor 0
++       *
++       * We are interested in the sensor(s) responsible of the
++       * interrupt event. We update the thermal framework with the
++       * thermal zone associated with the sensor. The framework will
++       * take care of the rest whatever the kind of interrupt, we
++       * are only interested in which sensor raised the interrupt.
++       *
++       * sensor 3 interrupt: 0001 1111 1100 0000 0000 0000 0000 0000
++       *                  => 0x1FC00000
++       * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000
++       *                  => 0x00247C00
++       * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000
++       *                  => 0X000881F0
++       * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111
++       *                  => 0x0009001F
++       */
++      value = readl(LVTS_MONINTSTS(lvts_ctrl->base));
++
++      /*
++       * Let's figure out which sensors raised the interrupt
++       *
++       * NOTE: the masks array must be ordered with the index
++       * corresponding to the sensor id eg. index=0, mask for
++       * sensor0.
++       */
++      for (i = 0; i < ARRAY_SIZE(masks); i++) {
++
++              if (!(value & masks[i]))
++                      continue;
++
++              thermal_zone_device_update(lvts_ctrl->sensors[i].tz,
++                                         THERMAL_TRIP_VIOLATED);
++              iret = IRQ_HANDLED;
++      }
++
++      /*
++       * Write back to clear the interrupt status (W1C)
++       */
++      writel(value, LVTS_MONINTSTS(lvts_ctrl->base));
++
++      return iret;
++}
++
++/*
++ * Temperature interrupt handler. Even if the driver supports more
++ * interrupt modes, we use the interrupt when the temperature crosses
++ * the hot threshold the way up and the way down (modulo the
++ * hysteresis).
++ *
++ * Each thermal domain has a couple of interrupts, one for hardware
++ * reset and another one for all the thermal events happening on the
++ * different sensors.
++ *
++ * The interrupt is configured for thermal events when crossing the
++ * hot temperature limit. At each interrupt, we check in every
++ * controller if there is an interrupt pending.
++ */
++static irqreturn_t lvts_irq_handler(int irq, void *data)
++{
++      struct lvts_domain *lvts_td = data;
++      irqreturn_t aux, iret = IRQ_NONE;
++      int i;
++
++      for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
++
++              aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
++              if (aux != IRQ_HANDLED)
++                      continue;
++
++              iret = IRQ_HANDLED;
++      }
++
++      return iret;
++}
++
++static struct thermal_zone_device_ops lvts_ops = {
++      .get_temp = lvts_get_temp,
++      .set_trips = lvts_set_trips,
++};
++
++static int lvts_sensor_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
++                                      const struct lvts_ctrl_data *lvts_ctrl_data)
++{
++      struct lvts_sensor *lvts_sensor = lvts_ctrl->sensors;
++      void __iomem *msr_regs[] = {
++              LVTS_MSR0(lvts_ctrl->base),
++              LVTS_MSR1(lvts_ctrl->base),
++              LVTS_MSR2(lvts_ctrl->base),
++              LVTS_MSR3(lvts_ctrl->base)
++      };
++
++      void __iomem *imm_regs[] = {
++              LVTS_IMMD0(lvts_ctrl->base),
++              LVTS_IMMD1(lvts_ctrl->base),
++              LVTS_IMMD2(lvts_ctrl->base),
++              LVTS_IMMD3(lvts_ctrl->base)
++      };
++
++      int i;
++
++      for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++) {
++
++              int dt_id = lvts_ctrl_data->lvts_sensor[i].dt_id;
++
++              /*
++               * At this point, we don't know which id matches which
++               * sensor. Let's set arbitrally the id from the index.
++               */
++              lvts_sensor[i].id = i;
++
++              /*
++               * The thermal zone registration will set the trip
++               * point interrupt in the thermal controller
++               * register. But this one will be reset in the
++               * initialization after. So we need to post pone the
++               * thermal zone creation after the controller is
++               * setup. For this reason, we store the device tree
++               * node id from the data in the sensor structure
++               */
++              lvts_sensor[i].dt_id = dt_id;
++
++              /*
++               * We assign the base address of the thermal
++               * controller as a back pointer. So it will be
++               * accessible from the different thermal framework ops
++               * as we pass the lvts_sensor pointer as thermal zone
++               * private data.
++               */
++              lvts_sensor[i].base = lvts_ctrl->base;
++
++              /*
++               * Each sensor has its own register address to read from.
++               */
++              lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
++                      imm_regs[i] : msr_regs[i];
++      };
++
++      lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
++
++      return 0;
++}
++
++/*
++ * The efuse blob values follows the sensor enumeration per thermal
++ * controller. The decoding of the stream is as follow:
++ *
++ *                        <--?-> <----big0 ???---> <-sensor0-> <-0->
++ *                        ------------------------------------------
++ * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 |
++ *                        ------------------------------------------
++ *
++ *                        <--sensor1--><-0-> <----big1 ???---> <-sen
++ *                        ------------------------------------------
++ *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
++ *                        ------------------------------------------
++ *
++ *                        sor0-> <-0-> <-sensor1-> <-0-> ..........
++ *                        ------------------------------------------
++ *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
++ *                        ------------------------------------------
++ *
++ * And so on ...
++ *
++ * The data description gives the offset of the calibration data in
++ * this bytes stream for each sensor.
++ *
++ * Each thermal controller can handle up to 4 sensors max, we don't
++ * care if there are less as the array of calibration is sized to 4
++ * anyway. The unused sensor slot will be zeroed.
++ */
++static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
++                                      const struct lvts_ctrl_data *lvts_ctrl_data,
++                                      u8 *efuse_calibration)
++{
++      int i;
++
++      for (i = 0; i < lvts_ctrl_data->num_lvts_sensor; i++)
++              memcpy(&lvts_ctrl->calibration[i],
++                     efuse_calibration + lvts_ctrl_data->cal_offset[i], 2);
++
++      return 0;
++}
++
++/*
++ * The efuse bytes stream can be split into different chunk of
++ * nvmems. This function reads and concatenate those into a single
++ * buffer so it can be read sequentially when initializing the
++ * calibration data.
++ */
++static int lvts_calibration_read(struct device *dev, struct lvts_domain *lvts_td,
++                                      const struct lvts_data *lvts_data)
++{
++      struct device_node *np = dev_of_node(dev);
++      struct nvmem_cell *cell;
++      struct property *prop;
++      const char *cell_name;
++
++      of_property_for_each_string(np, "nvmem-cell-names", prop, cell_name) {
++              size_t len;
++              u8 *efuse;
++
++              cell = of_nvmem_cell_get(np, cell_name);
++              if (IS_ERR(cell)) {
++                      dev_err(dev, "Failed to get cell '%s'\n", cell_name);
++                      return PTR_ERR(cell);
++              }
++
++              efuse = nvmem_cell_read(cell, &len);
++
++              nvmem_cell_put(cell);
++
++              if (IS_ERR(efuse)) {
++                      dev_err(dev, "Failed to read cell '%s'\n", cell_name);
++                      return PTR_ERR(efuse);
++              }
++
++              lvts_td->calib = devm_krealloc(dev, lvts_td->calib,
++                                             lvts_td->calib_len + len, GFP_KERNEL);
++              if (!lvts_td->calib)
++                      return -ENOMEM;
++
++              memcpy(lvts_td->calib + lvts_td->calib_len, efuse, len);
++
++              lvts_td->calib_len += len;
++
++              kfree(efuse);
++      }
++
++      return 0;
++}
++
++static int lvts_golden_temp_init(struct device *dev, u32 *value)
++{
++      u32 gt;
++
++      gt = (*value) >> 24;
++
++      if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
++              golden_temp = gt;
++
++      coeff_b = golden_temp * 500 + LVTS_COEFF_B;
++
++      return 0;
++}
++
++static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
++                                      const struct lvts_data *lvts_data)
++{
++      size_t size = sizeof(*lvts_td->lvts_ctrl) * lvts_data->num_lvts_ctrl;
++      struct lvts_ctrl *lvts_ctrl;
++      int i, ret;
++
++      /*
++       * Create the calibration bytes stream from efuse data
++       */
++      ret = lvts_calibration_read(dev, lvts_td, lvts_data);
++      if (ret)
++              return ret;
++
++      /*
++       * The golden temp information is contained in the first chunk
++       * of efuse data.
++       */
++      ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib);
++      if (ret)
++              return ret;
++
++      lvts_ctrl = devm_kzalloc(dev, size, GFP_KERNEL);
++      if (!lvts_ctrl)
++              return -ENOMEM;
++
++      for (i = 0; i < lvts_data->num_lvts_ctrl; i++) {
++
++              lvts_ctrl[i].base = lvts_td->base + lvts_data->lvts_ctrl[i].offset;
++
++              ret = lvts_sensor_init(dev, &lvts_ctrl[i],
++                                     &lvts_data->lvts_ctrl[i]);
++              if (ret)
++                      return ret;
++
++              ret = lvts_calibration_init(dev, &lvts_ctrl[i],
++                                          &lvts_data->lvts_ctrl[i],
++                                          lvts_td->calib);
++              if (ret)
++                      return ret;
++
++              /*
++               * The mode the ctrl will use to read the temperature
++               * (filtered or immediate)
++               */
++              lvts_ctrl[i].mode = lvts_data->lvts_ctrl[i].mode;
++
++              /*
++               * The temperature to raw temperature must be done
++               * after initializing the calibration.
++               */
++              lvts_ctrl[i].hw_tshut_raw_temp =
++                      lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
++      }
++
++      /*
++       * We no longer need the efuse bytes stream, let's free it
++       */
++      devm_kfree(dev, lvts_td->calib);
++
++      lvts_td->lvts_ctrl = lvts_ctrl;
++      lvts_td->num_lvts_ctrl = lvts_data->num_lvts_ctrl;
++
++      return 0;
++}
++
++/*
++ * At this point the configuration register is the only place in the
++ * driver where we write multiple values. Per hardware constraint,
++ * each write in the configuration register must be separated by a
++ * delay of 2 us.
++ */
++static void lvts_write_config(struct lvts_ctrl *lvts_ctrl, u32 *cmds, int nr_cmds)
++{
++      int i;
++
++      /*
++       * Configuration register
++       */
++      for (i = 0; i < nr_cmds; i++) {
++              writel(cmds[i], LVTS_CONFIG(lvts_ctrl->base));
++              usleep_range(2, 4);
++      }
++}
++
++static int lvts_irq_init(struct lvts_ctrl *lvts_ctrl)
++{
++      /*
++       * LVTS_PROTCTL : Thermal Protection Sensor Selection
++       *
++       * Bits:
++       *
++       * 19-18 : Sensor to base the protection on
++       * 17-16 : Strategy:
++       *         00 : Average of 4 sensors
++       *         01 : Max of 4 sensors
++       *         10 : Selected sensor with bits 19-18
++       *         11 : Reserved
++       */
++      writel(BIT(16), LVTS_PROTCTL(lvts_ctrl->base));
++
++      /*
++       * LVTS_PROTTA : Stage 1 temperature threshold
++       * LVTS_PROTTB : Stage 2 temperature threshold
++       * LVTS_PROTTC : Stage 3 temperature threshold
++       *
++       * Bits:
++       *
++       * 14-0: Raw temperature threshold
++       *
++       * writel(0x0, LVTS_PROTTA(lvts_ctrl->base));
++       * writel(0x0, LVTS_PROTTB(lvts_ctrl->base));
++       */
++      writel(lvts_ctrl->hw_tshut_raw_temp, LVTS_PROTTC(lvts_ctrl->base));
++
++      /*
++       * LVTS_MONINT : Interrupt configuration register
++       *
++       * The LVTS_MONINT register layout is the same as the LVTS_MONINTSTS
++       * register, except we set the bits to enable the interrupt.
++       */
++      writel(LVTS_MONINT_CONF, LVTS_MONINT(lvts_ctrl->base));
++
++      return 0;
++}
++
++static int lvts_domain_reset(struct device *dev, struct reset_control *reset)
++{
++      int ret;
++
++      ret = reset_control_assert(reset);
++      if (ret)
++              return ret;
++
++      return reset_control_deassert(reset);
++}
++
++/*
++ * Enable or disable the clocks of a specified thermal controller
++ */
++static int lvts_ctrl_set_enable(struct lvts_ctrl *lvts_ctrl, int enable)
++{
++      /*
++       * LVTS_CLKEN : Internal LVTS clock
++       *
++       * Bits:
++       *
++       * 0 : enable / disable clock
++       */
++      writel(enable, LVTS_CLKEN(lvts_ctrl->base));
++
++      return 0;
++}
++
++static int lvts_ctrl_connect(struct device *dev, struct lvts_ctrl *lvts_ctrl)
++{
++      u32 id, cmds[] = { 0xC103FFFF, 0xC502FF55 };
++
++      lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
++
++      /*
++       * LVTS_ID : Get ID and status of the thermal controller
++       *
++       * Bits:
++       *
++       * 0-5  : thermal controller id
++       *   7  : thermal controller connection is valid
++       */
++      id = readl(LVTS_ID(lvts_ctrl->base));
++      if (!(id & BIT(7)))
++              return -EIO;
++
++      return 0;
++}
++
++static int lvts_ctrl_initialize(struct device *dev, struct lvts_ctrl *lvts_ctrl)
++{
++      /*
++       * Write device mask: 0xC1030000
++       */
++      u32 cmds[] = {
++              0xC1030E01, 0xC1030CFC, 0xC1030A8C, 0xC103098D, 0xC10308F1,
++              0xC10307A6, 0xC10306B8, 0xC1030500, 0xC1030420, 0xC1030300,
++              0xC1030030, 0xC10300F6, 0xC1030050, 0xC1030060, 0xC10300AC,
++              0xC10300FC, 0xC103009D, 0xC10300F1, 0xC10300E1
++      };
++
++      lvts_write_config(lvts_ctrl, cmds, ARRAY_SIZE(cmds));
++
++      return 0;
++}
++
++static int lvts_ctrl_calibrate(struct device *dev, struct lvts_ctrl *lvts_ctrl)
++{
++      int i;
++      void __iomem *lvts_edata[] = {
++              LVTS_EDATA00(lvts_ctrl->base),
++              LVTS_EDATA01(lvts_ctrl->base),
++              LVTS_EDATA02(lvts_ctrl->base),
++              LVTS_EDATA03(lvts_ctrl->base)
++      };
++
++      /*
++       * LVTS_EDATA0X : Efuse calibration reference value for sensor X
++       *
++       * Bits:
++       *
++       * 20-0 : Efuse value for normalization data
++       */
++      for (i = 0; i < LVTS_SENSOR_MAX; i++)
++              writel(lvts_ctrl->calibration[i], lvts_edata[i]);
++
++      return 0;
++}
++
++static int lvts_ctrl_configure(struct device *dev, struct lvts_ctrl *lvts_ctrl)
++{
++      u32 value;
++
++      /*
++       * LVTS_TSSEL : Sensing point index numbering
++       *
++       * Bits:
++       *
++       * 31-24: ADC Sense 3
++       * 23-16: ADC Sense 2
++       * 15-8 : ADC Sense 1
++       * 7-0  : ADC Sense 0
++       */
++      value = LVTS_TSSEL_CONF;
++      writel(value, LVTS_TSSEL(lvts_ctrl->base));
++
++      /*
++       * LVTS_CALSCALE : ADC voltage round
++       */
++      value = 0x300;
++      value = LVTS_CALSCALE_CONF;
++
++      /*
++       * LVTS_MSRCTL0 : Sensor filtering strategy
++       *
++       * Filters:
++       *
++       * 000 : One sample
++       * 001 : Avg 2 samples
++       * 010 : 4 samples, drop min and max, avg 2 samples
++       * 011 : 6 samples, drop min and max, avg 4 samples
++       * 100 : 10 samples, drop min and max, avg 8 samples
++       * 101 : 18 samples, drop min and max, avg 16 samples
++       *
++       * Bits:
++       *
++       * 0-2  : Sensor0 filter
++       * 3-5  : Sensor1 filter
++       * 6-8  : Sensor2 filter
++       * 9-11 : Sensor3 filter
++       */
++      value = LVTS_HW_FILTER << 9 |  LVTS_HW_FILTER << 6 |
++                      LVTS_HW_FILTER << 3 | LVTS_HW_FILTER;
++      writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
++
++      /*
++       * LVTS_MSRCTL1 : Measurement control
++       *
++       * Bits:
++       *
++       * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
++       * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
++       * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
++       * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
++       *
++       * That configuration will ignore the filtering and the delays
++       * introduced below in MONCTL1 and MONCTL2
++       */
++      if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
++              value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
++              writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
++      }
++
++      /*
++       * LVTS_MONCTL1 : Period unit and group interval configuration
++       *
++       * The clock source of LVTS thermal controller is 26MHz.
++       *
++       * The period unit is a time base for all the interval delays
++       * specified in the registers. By default we use 12. The time
++       * conversion is done by multiplying by 256 and 1/26.10^6
++       *
++       * An interval delay multiplied by the period unit gives the
++       * duration in seconds.
++       *
++       * - Filter interval delay is a delay between two samples of
++       * the same sensor.
++       *
++       * - Sensor interval delay is a delay between two samples of
++       * different sensors.
++       *
++       * - Group interval delay is a delay between different rounds.
++       *
++       * For example:
++       *     If Period unit = C, filter delay = 1, sensor delay = 2, group delay = 1,
++       *     and two sensors, TS1 and TS2, are in a LVTS thermal controller
++       *     and then
++       *     Period unit time = C * 1/26M * 256 = 12 * 38.46ns * 256 = 118.149us
++       *     Filter interval delay = 1 * Period unit = 118.149us
++       *     Sensor interval delay = 2 * Period unit = 236.298us
++       *     Group interval delay = 1 * Period unit = 118.149us
++       *
++       *     TS1    TS1 ... TS1    TS2    TS2 ... TS2    TS1...
++       *        <--> Filter interval delay
++       *                       <--> Sensor interval delay
++       *                                             <--> Group interval delay
++       * Bits:
++       *      29 - 20 : Group interval
++       *      16 - 13 : Send a single interrupt when crossing the hot threshold (1)
++       *                or an interrupt everytime the hot threshold is crossed (0)
++       *       9 - 0  : Period unit
++       *
++       */
++      value = LVTS_GROUP_INTERVAL << 20 | LVTS_PERIOD_UNIT;
++      writel(value, LVTS_MONCTL1(lvts_ctrl->base));
++
++      /*
++       * LVTS_MONCTL2 : Filtering and sensor interval
++       *
++       * Bits:
++       *
++       *      25-16 : Interval unit in PERIOD_UNIT between sample on
++       *              the same sensor, filter interval
++       *       9-0  : Interval unit in PERIOD_UNIT between each sensor
++       *
++       */
++      value = LVTS_FILTER_INTERVAL << 16 | LVTS_SENSOR_INTERVAL;
++      writel(value, LVTS_MONCTL2(lvts_ctrl->base));
++
++      return lvts_irq_init(lvts_ctrl);
++}
++
++static int lvts_ctrl_start(struct device *dev, struct lvts_ctrl *lvts_ctrl)
++{
++      struct lvts_sensor *lvts_sensors = lvts_ctrl->sensors;
++      struct thermal_zone_device *tz;
++      u32 sensor_map = 0;
++      int i;
++
++      for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
++
++              int dt_id = lvts_sensors[i].dt_id;
++
++              tz = devm_thermal_of_zone_register(dev, dt_id, &lvts_sensors[i],
++                                                 &lvts_ops);
++              if (IS_ERR(tz)) {
++                      /*
++                       * This thermal zone is not described in the
++                       * device tree. It is not an error from the
++                       * thermal OF code POV, we just continue.
++                       */
++                      if (PTR_ERR(tz) == -ENODEV)
++                              continue;
++
++                      return PTR_ERR(tz);
++              }
++
++              /*
++               * The thermal zone pointer will be needed in the
++               * interrupt handler, we store it in the sensor
++               * structure. The thermal domain structure will be
++               * passed to the interrupt handler private data as the
++               * interrupt is shared for all the controller
++               * belonging to the thermal domain.
++               */
++              lvts_sensors[i].tz = tz;
++
++              /*
++               * This sensor was correctly associated with a thermal
++               * zone, let's set the corresponding bit in the sensor
++               * map, so we can enable the temperature monitoring in
++               * the hardware thermal controller.
++               */
++              sensor_map |= BIT(i);
++      }
++
++      /*
++       * Bits:
++       *      9: Single point access flow
++       *    0-3: Enable sensing point 0-3
++       *
++       * The initialization of the thermal zones give us
++       * which sensor point to enable. If any thermal zone
++       * was not described in the device tree, it won't be
++       * enabled here in the sensor map.
++       */
++      writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
++
++      return 0;
++}
++
++static int lvts_domain_init(struct device *dev, struct lvts_domain *lvts_td,
++                                      const struct lvts_data *lvts_data)
++{
++      struct lvts_ctrl *lvts_ctrl;
++      int i, ret;
++
++      ret = lvts_ctrl_init(dev, lvts_td, lvts_data);
++      if (ret)
++              return ret;
++
++      ret = lvts_domain_reset(dev, lvts_td->reset);
++      if (ret) {
++              dev_dbg(dev, "Failed to reset domain");
++              return ret;
++      }
++
++      for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
++
++              lvts_ctrl = &lvts_td->lvts_ctrl[i];
++
++              /*
++               * Initialization steps:
++               *
++               * - Enable the clock
++               * - Connect to the LVTS
++               * - Initialize the LVTS
++               * - Prepare the calibration data
++               * - Select monitored sensors
++               * [ Configure sampling ]
++               * [ Configure the interrupt ]
++               * - Start measurement
++               */
++              ret = lvts_ctrl_set_enable(lvts_ctrl, true);
++              if (ret) {
++                      dev_dbg(dev, "Failed to enable LVTS clock");
++                      return ret;
++              }
++
++              ret = lvts_ctrl_connect(dev, lvts_ctrl);
++              if (ret) {
++                      dev_dbg(dev, "Failed to connect to LVTS controller");
++                      return ret;
++              }
++
++              ret = lvts_ctrl_initialize(dev, lvts_ctrl);
++              if (ret) {
++                      dev_dbg(dev, "Failed to initialize controller");
++                      return ret;
++              }
++
++              ret = lvts_ctrl_calibrate(dev, lvts_ctrl);
++              if (ret) {
++                      dev_dbg(dev, "Failed to calibrate controller");
++                      return ret;
++              }
++
++              ret = lvts_ctrl_configure(dev, lvts_ctrl);
++              if (ret) {
++                      dev_dbg(dev, "Failed to configure controller");
++                      return ret;
++              }
++
++              ret = lvts_ctrl_start(dev, lvts_ctrl);
++              if (ret) {
++                      dev_dbg(dev, "Failed to start controller");
++                      return ret;
++              }
++      }
++
++      return lvts_debugfs_init(dev, lvts_td);
++}
++
++static int lvts_probe(struct platform_device *pdev)
++{
++      const struct lvts_data *lvts_data;
++      struct lvts_domain *lvts_td;
++      struct device *dev = &pdev->dev;
++      struct resource *res;
++      int irq, ret;
++
++      lvts_td = devm_kzalloc(dev, sizeof(*lvts_td), GFP_KERNEL);
++      if (!lvts_td)
++              return -ENOMEM;
++
++      lvts_data = of_device_get_match_data(dev);
++
++      lvts_td->clk = devm_clk_get_enabled(dev, NULL);
++      if (IS_ERR(lvts_td->clk))
++              return dev_err_probe(dev, PTR_ERR(lvts_td->clk), "Failed to retrieve clock\n");
++
++      res = platform_get_mem_or_io(pdev, 0);
++      if (!res)
++              return dev_err_probe(dev, (-ENXIO), "No IO resource\n");
++
++      lvts_td->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
++      if (IS_ERR(lvts_td->base))
++              return dev_err_probe(dev, PTR_ERR(lvts_td->base), "Failed to map io resource\n");
++
++      lvts_td->reset = devm_reset_control_get_by_index(dev, 0);
++      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 dev_err_probe(dev, irq, "No irq resource\n");
++
++      ret = lvts_domain_init(dev, lvts_td, lvts_data);
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to initialize the lvts domain\n");
++
++      /*
++       * 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");
++
++      platform_set_drvdata(pdev, lvts_td);
++
++      return 0;
++}
++
++static int lvts_remove(struct platform_device *pdev)
++{
++      struct lvts_domain *lvts_td;
++      int i;
++
++      lvts_td = platform_get_drvdata(pdev);
++
++      for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
++              lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
++
++      lvts_debugfs_exit(lvts_td);
++
++      return 0;
++}
++
++static const struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
++      {
++              .cal_offset = { 0x04, 0x07 },
++              .lvts_sensor = {
++                      { .dt_id = MT8195_MCU_BIG_CPU0 },
++                      { .dt_id = MT8195_MCU_BIG_CPU1 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x0,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
++      },
++      {
++              .cal_offset = { 0x0d, 0x10 },
++              .lvts_sensor = {
++                      { .dt_id = MT8195_MCU_BIG_CPU2 },
++                      { .dt_id = MT8195_MCU_BIG_CPU3 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x100,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
++      },
++      {
++              .cal_offset = { 0x16, 0x19, 0x1c, 0x1f },
++              .lvts_sensor = {
++                      { .dt_id = MT8195_MCU_LITTLE_CPU0 },
++                      { .dt_id = MT8195_MCU_LITTLE_CPU1 },
++                      { .dt_id = MT8195_MCU_LITTLE_CPU2 },
++                      { .dt_id = MT8195_MCU_LITTLE_CPU3 }
++              },
++              .num_lvts_sensor = 4,
++              .offset = 0x200,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
++      }
++};
++
++static const struct lvts_data mt8195_lvts_mcu_data = {
++      .lvts_ctrl      = mt8195_lvts_data_ctrl,
++      .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_data_ctrl),
++};
++
++static const struct of_device_id lvts_of_match[] = {
++      { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
++      {},
++};
++MODULE_DEVICE_TABLE(of, lvts_of_match);
++
++static struct platform_driver lvts_driver = {
++      .probe = lvts_probe,
++      .remove = lvts_remove,
++      .driver = {
++              .name = "mtk-lvts-thermal",
++              .of_match_table = lvts_of_match,
++      },
++};
++module_platform_driver(lvts_driver);
++
++MODULE_AUTHOR("Balsam CHIHI <bchihi@baylibre.com>");
++MODULE_DESCRIPTION("MediaTek LVTS Thermal Driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-07-dt-bindings-thermal-mediatek-Add-LVTS-thermal-contro.patch b/target/linux/mediatek/patches-6.6/830-v6.4-07-dt-bindings-thermal-mediatek-Add-LVTS-thermal-contro.patch
new file mode 100644 (file)
index 0000000..b6a5f64
--- /dev/null
@@ -0,0 +1,186 @@
+From 498e2f7a6e69dcbca24715de2b4b97569fdfeff4 Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Thu, 9 Feb 2023 11:56:24 +0100
+Subject: [PATCH] dt-bindings: thermal: mediatek: Add LVTS thermal controllers
+
+Add LVTS thermal controllers dt-binding definition for mt8192 and mt8195.
+
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20230209105628.50294-3-bchihi@baylibre.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ .../thermal/mediatek,lvts-thermal.yaml        | 142 ++++++++++++++++++
+ .../thermal/mediatek,lvts-thermal.h           |  19 +++
+ 2 files changed, 161 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
+ create mode 100644 include/dt-bindings/thermal/mediatek,lvts-thermal.h
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/thermal/mediatek,lvts-thermal.yaml
+@@ -0,0 +1,142 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/thermal/mediatek,lvts-thermal.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: MediaTek SoC Low Voltage Thermal Sensor (LVTS)
++
++maintainers:
++  - Balsam CHIHI <bchihi@baylibre.com>
++
++description: |
++  LVTS is a thermal management architecture composed of three subsystems,
++  a Sensing device - Thermal Sensing Micro Circuit Unit (TSMCU),
++  a Converter - Low Voltage Thermal Sensor converter (LVTS), and
++  a Digital controller (LVTS_CTRL).
++
++properties:
++  compatible:
++    enum:
++      - mediatek,mt8192-lvts-ap
++      - mediatek,mt8192-lvts-mcu
++      - mediatek,mt8195-lvts-ap
++      - mediatek,mt8195-lvts-mcu
++
++  reg:
++    maxItems: 1
++
++  interrupts:
++    maxItems: 1
++
++  clocks:
++    maxItems: 1
++
++  resets:
++    maxItems: 1
++    description: LVTS reset for clearing temporary data on AP/MCU.
++
++  nvmem-cells:
++    minItems: 1
++    items:
++      - description: Calibration eFuse data 1 for LVTS
++      - description: Calibration eFuse data 2 for LVTS
++
++  nvmem-cell-names:
++    minItems: 1
++    items:
++      - const: lvts-calib-data-1
++      - const: lvts-calib-data-2
++
++  "#thermal-sensor-cells":
++    const: 1
++
++allOf:
++  - $ref: thermal-sensor.yaml#
++
++  - if:
++      properties:
++        compatible:
++          contains:
++            enum:
++              - mediatek,mt8192-lvts-ap
++              - mediatek,mt8192-lvts-mcu
++    then:
++      properties:
++        nvmem-cells:
++          maxItems: 1
++
++        nvmem-cell-names:
++          maxItems: 1
++
++  - if:
++      properties:
++        compatible:
++          contains:
++            enum:
++              - mediatek,mt8195-lvts-ap
++              - mediatek,mt8195-lvts-mcu
++    then:
++      properties:
++        nvmem-cells:
++          minItems: 2
++
++        nvmem-cell-names:
++          minItems: 2
++
++required:
++  - compatible
++  - reg
++  - interrupts
++  - clocks
++  - resets
++  - nvmem-cells
++  - nvmem-cell-names
++  - "#thermal-sensor-cells"
++
++additionalProperties: false
++
++examples:
++  - |
++    #include <dt-bindings/interrupt-controller/arm-gic.h>
++    #include <dt-bindings/clock/mt8195-clk.h>
++    #include <dt-bindings/reset/mt8195-resets.h>
++    #include <dt-bindings/thermal/mediatek,lvts-thermal.h>
++
++    soc {
++      #address-cells = <2>;
++      #size-cells = <2>;
++
++      lvts_mcu: thermal-sensor@11278000 {
++        compatible = "mediatek,mt8195-lvts-mcu";
++        reg = <0 0x11278000 0 0x1000>;
++        interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
++        clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
++        resets = <&infracfg_ao MT8195_INFRA_RST4_THERM_CTRL_MCU_SWRST>;
++        nvmem-cells = <&lvts_efuse_data1 &lvts_efuse_data2>;
++        nvmem-cell-names = "lvts-calib-data-1", "lvts-calib-data-2";
++        #thermal-sensor-cells = <1>;
++      };
++    };
++
++    thermal_zones: thermal-zones {
++      cpu0-thermal {
++        polling-delay = <1000>;
++        polling-delay-passive = <250>;
++        thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>;
++
++        trips {
++          cpu0_alert: trip-alert {
++            temperature = <85000>;
++            hysteresis = <2000>;
++            type = "passive";
++          };
++
++          cpu0_crit: trip-crit {
++            temperature = <100000>;
++            hysteresis = <2000>;
++            type = "critical";
++          };
++        };
++      };
++    };
+--- /dev/null
++++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
+@@ -0,0 +1,19 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Balsam CHIHI <bchihi@baylibre.com>
++ */
++
++#ifndef __MEDIATEK_LVTS_DT_H
++#define __MEDIATEK_LVTS_DT_H
++
++#define MT8195_MCU_BIG_CPU0     0
++#define MT8195_MCU_BIG_CPU1     1
++#define MT8195_MCU_BIG_CPU2     2
++#define MT8195_MCU_BIG_CPU3     3
++#define MT8195_MCU_LITTLE_CPU0  4
++#define MT8195_MCU_LITTLE_CPU1  5
++#define MT8195_MCU_LITTLE_CPU2  6
++#define MT8195_MCU_LITTLE_CPU3  7
++
++#endif /* __MEDIATEK_LVTS_DT_H */
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-08-dt-bindings-thermal-mediatek-Add-AP-domain-to-LVTS-t.patch b/target/linux/mediatek/patches-6.6/830-v6.4-08-dt-bindings-thermal-mediatek-Add-AP-domain-to-LVTS-t.patch
new file mode 100644 (file)
index 0000000..efb0d8b
--- /dev/null
@@ -0,0 +1,35 @@
+From 05aaa7fdb0736262e224369b9b9f1410320fc71b Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Tue, 7 Mar 2023 16:45:21 +0100
+Subject: [PATCH] dt-bindings: thermal: mediatek: Add AP domain to LVTS thermal
+ controllers for mt8195
+
+Add AP Domain to LVTS thermal controllers dt-binding definition for mt8195.
+
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230307154524.118541-2-bchihi@baylibre.com
+---
+ include/dt-bindings/thermal/mediatek,lvts-thermal.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h
++++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
+@@ -16,4 +16,14 @@
+ #define MT8195_MCU_LITTLE_CPU2  6
+ #define MT8195_MCU_LITTLE_CPU3  7
++#define MT8195_AP_VPU0  8
++#define MT8195_AP_VPU1  9
++#define MT8195_AP_GPU0  10
++#define MT8195_AP_GPU1  11
++#define MT8195_AP_VDEC  12
++#define MT8195_AP_IMG   13
++#define MT8195_AP_INFRA 14
++#define MT8195_AP_CAM0  15
++#define MT8195_AP_CAM1  16
++
+ #endif /* __MEDIATEK_LVTS_DT_H */
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-09-thermal-core-Add-a-thermal-zone-devdata-accessor.patch b/target/linux/mediatek/patches-6.6/830-v6.4-09-thermal-core-Add-a-thermal-zone-devdata-accessor.patch
new file mode 100644 (file)
index 0000000..c689693
--- /dev/null
@@ -0,0 +1,65 @@
+From a6ff3c0021468721b96e84892a8cae24bde8d65f Mon Sep 17 00:00:00 2001
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+Date: Wed, 1 Mar 2023 21:14:29 +0100
+Subject: [PATCH] thermal/core: Add a thermal zone 'devdata' accessor
+
+The thermal zone device structure is exposed to the different drivers
+and obviously they access the internals while that should be
+restricted to the core thermal code.
+
+In order to self-encapsulate the thermal core code, we need to prevent
+the drivers accessing directly the thermal zone structure and provide
+accessor functions to deal with.
+
+Provide an accessor to the 'devdata' structure and make use of it in
+the different drivers.
+
+No functional changes intended.
+
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/thermal/thermal_core.c | 6 ++++++
+ include/linux/thermal.h        | 7 +++++++
+ 2 files changed, 13 insertions(+)
+
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1346,6 +1346,12 @@ struct thermal_zone_device *thermal_zone
+ }
+ EXPORT_SYMBOL_GPL(thermal_zone_device_register);
++void *thermal_zone_device_priv(struct thermal_zone_device *tzd)
++{
++      return tzd->devdata;
++}
++EXPORT_SYMBOL_GPL(thermal_zone_device_priv);
++
+ /**
+  * thermal_zone_device_unregister - removes the registered thermal zone device
+  * @tz: the thermal zone device to remove
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -346,6 +346,8 @@ thermal_zone_device_register_with_trips(
+                                       void *, struct thermal_zone_device_ops *,
+                                       struct thermal_zone_params *, int, int);
++void *thermal_zone_device_priv(struct thermal_zone_device *tzd);
++
+ int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
+                                    struct thermal_cooling_device *,
+                                    unsigned long, unsigned long,
+@@ -417,6 +419,11 @@ static inline int thermal_zone_get_offse
+               struct thermal_zone_device *tz)
+ { return -ENODEV; }
++static inline void *thermal_zone_device_priv(struct thermal_zone_device *tz)
++{
++      return NULL;
++}
++
+ static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
+ { return -ENODEV; }
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-10-thermal-core-Add-thermal_zone_device-structure-type-.patch b/target/linux/mediatek/patches-6.6/830-v6.4-10-thermal-core-Add-thermal_zone_device-structure-type-.patch
new file mode 100644 (file)
index 0000000..66d3c9e
--- /dev/null
@@ -0,0 +1,55 @@
+From 072e35c98806100182c0a7263cf4cba09ce43463 Mon Sep 17 00:00:00 2001
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+Date: Wed, 1 Mar 2023 21:14:38 +0100
+Subject: [PATCH] thermal/core: Add thermal_zone_device structure 'type'
+ accessor
+
+The thermal zone device structure is exposed via the exported
+thermal.h header. This structure should stay private the thermal core
+code. In order to encapsulate the structure, let's add an accessor to
+get the 'type' of the thermal zone.
+
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/thermal/thermal_core.c | 6 ++++++
+ include/linux/thermal.h        | 6 ++++++
+ 2 files changed, 12 insertions(+)
+
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1352,6 +1352,12 @@ void *thermal_zone_device_priv(struct th
+ }
+ EXPORT_SYMBOL_GPL(thermal_zone_device_priv);
++const char *thermal_zone_device_type(struct thermal_zone_device *tzd)
++{
++      return tzd->type;
++}
++EXPORT_SYMBOL_GPL(thermal_zone_device_type);
++
+ /**
+  * thermal_zone_device_unregister - removes the registered thermal zone device
+  * @tz: the thermal zone device to remove
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -347,6 +347,7 @@ thermal_zone_device_register_with_trips(
+                                       struct thermal_zone_params *, int, int);
+ void *thermal_zone_device_priv(struct thermal_zone_device *tzd);
++const char *thermal_zone_device_type(struct thermal_zone_device *tzd);
+ int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
+                                    struct thermal_cooling_device *,
+@@ -423,6 +424,11 @@ static inline void *thermal_zone_device_
+ {
+       return NULL;
+ }
++
++static inline const char *thermal_zone_device_type(struct thermal_zone_device *tzd)
++{
++      return NULL;
++}
+ static inline int thermal_zone_device_enable(struct thermal_zone_device *tz)
+ { return -ENODEV; }
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-11-thermal-core-Use-the-thermal-zone-devdata-accessor-i.patch b/target/linux/mediatek/patches-6.6/830-v6.4-11-thermal-core-Use-the-thermal-zone-devdata-accessor-i.patch
new file mode 100644 (file)
index 0000000..57bc910
--- /dev/null
@@ -0,0 +1,74 @@
+From 7d78bab533eb9aa0e5240e25a204e8f416723ed6 Mon Sep 17 00:00:00 2001
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+Date: Wed, 1 Mar 2023 21:14:30 +0100
+Subject: [PATCH 07/42] thermal/core: Use the thermal zone 'devdata' accessor
+ in thermal located drivers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The thermal zone device structure is exposed to the different drivers
+and obviously they access the internals while that should be
+restricted to the core thermal code.
+
+In order to self-encapsulate the thermal core code, we need to prevent
+the drivers accessing directly the thermal zone structure and provide
+accessor functions to deal with.
+
+Use the devdata accessor introduced in the previous patch.
+
+No functional changes intended.
+
+[skipped drivers not relevant for mediatek target]
+
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> #R-Car
+Acked-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek auxadc and lvts
+Reviewed-by: Balsam CHIHI <bchihi@baylibre.com> #Mediatek lvts
+Reviewed-by: Adam Ward <DLG-Adam.Ward.opensource@dm.renesas.com> #da9062
+Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>  #spread
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> #sun8i_thermal
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com> #Broadcom
+Reviewed-by: Dhruva Gole <d-gole@ti.com> # K3 bandgap
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Acked-by: Heiko Stuebner <heiko@sntech.de> #rockchip
+Reviewed-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> #uniphier
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/thermal/mediatek/auxadc_thermal.c           |  2 +-
+ drivers/thermal/mediatek/lvts_thermal.c             |  4 ++--
+ 43 files changed, 71 insertions(+), 73 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -763,7 +763,7 @@ static int mtk_thermal_bank_temperature(
+ static int mtk_read_temp(struct thermal_zone_device *tz, int *temperature)
+ {
+-      struct mtk_thermal *mt = tz->devdata;
++      struct mtk_thermal *mt = thermal_zone_device_priv(tz);
+       int i;
+       int tempmax = INT_MIN;
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -252,7 +252,7 @@ static u32 lvts_temp_to_raw(int temperat
+ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
+ {
+-      struct lvts_sensor *lvts_sensor = tz->devdata;
++      struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
+       void __iomem *msr = lvts_sensor->msr;
+       u32 value;
+@@ -290,7 +290,7 @@ static int lvts_get_temp(struct thermal_
+ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ {
+-      struct lvts_sensor *lvts_sensor = tz->devdata;
++      struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
+       void __iomem *base = lvts_sensor->base;
+       u32 raw_low = lvts_temp_to_raw(low);
+       u32 raw_high = lvts_temp_to_raw(high);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-12-thermal-hwmon-Use-the-right-device-for-devm_thermal_.patch b/target/linux/mediatek/patches-6.6/830-v6.4-12-thermal-hwmon-Use-the-right-device-for-devm_thermal_.patch
new file mode 100644 (file)
index 0000000..647b3b0
--- /dev/null
@@ -0,0 +1,201 @@
+From cc9c60e9cfeeac45d63361fa8c085c43c4bdfe3a Mon Sep 17 00:00:00 2001
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+Date: Wed, 1 Mar 2023 21:14:36 +0100
+Subject: [PATCH 08/42] thermal/hwmon: Use the right device for
+ devm_thermal_add_hwmon_sysfs()
+
+The devres variant of thermal_add_hwmon_sysfs() only takes the thermal
+zone structure pointer as parameter.
+
+Actually, it uses the tz->device to add it in the devres list.
+
+It is preferable to use the device registering the thermal zone
+instead of the thermal zone device itself. That prevents the driver
+accessing the thermal zone structure internals and it is from my POV
+more correct regarding how devm_ is used.
+
+[skipped imx thermal which did not apply cleanly and irrelevant on
+mediatek target]
+
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> #amlogic_thermal
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> #sun8i_thermal
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek auxadc
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/thermal/amlogic_thermal.c                  | 2 +-
+ drivers/thermal/imx_sc_thermal.c                   | 2 +-
+ drivers/thermal/k3_bandgap.c                       | 2 +-
+ drivers/thermal/mediatek/auxadc_thermal.c          | 2 +-
+ drivers/thermal/qcom/qcom-spmi-adc-tm5.c           | 2 +-
+ drivers/thermal/qcom/qcom-spmi-temp-alarm.c        | 2 +-
+ drivers/thermal/qcom/tsens.c                       | 2 +-
+ drivers/thermal/qoriq_thermal.c                    | 2 +-
+ drivers/thermal/sun8i_thermal.c                    | 2 +-
+ drivers/thermal/tegra/tegra30-tsensor.c            | 2 +-
+ drivers/thermal/thermal_hwmon.c                    | 4 ++--
+ drivers/thermal/thermal_hwmon.h                    | 4 ++--
+ drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
+ 13 files changed, 15 insertions(+), 15 deletions(-)
+
+--- a/drivers/thermal/amlogic_thermal.c
++++ b/drivers/thermal/amlogic_thermal.c
+@@ -286,7 +286,7 @@ static int amlogic_thermal_probe(struct
+               return ret;
+       }
+-      if (devm_thermal_add_hwmon_sysfs(pdata->tzd))
++      if (devm_thermal_add_hwmon_sysfs(&pdev->dev, pdata->tzd))
+               dev_warn(&pdev->dev, "Failed to add hwmon sysfs attributes\n");
+       ret = amlogic_thermal_initialize(pdata);
+--- a/drivers/thermal/imx_sc_thermal.c
++++ b/drivers/thermal/imx_sc_thermal.c
+@@ -120,7 +120,7 @@ static int imx_sc_thermal_probe(struct p
+                       return ret;
+               }
+-              if (devm_thermal_add_hwmon_sysfs(sensor->tzd))
++              if (devm_thermal_add_hwmon_sysfs(&pdev->dev, sensor->tzd))
+                       dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n");
+       }
+--- a/drivers/thermal/k3_bandgap.c
++++ b/drivers/thermal/k3_bandgap.c
+@@ -222,7 +222,7 @@ static int k3_bandgap_probe(struct platf
+                       goto err_alloc;
+               }
+-              if (devm_thermal_add_hwmon_sysfs(data[id].tzd))
++              if (devm_thermal_add_hwmon_sysfs(dev, data[id].tzd))
+                       dev_warn(dev, "Failed to add hwmon sysfs attributes\n");
+       }
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -1210,7 +1210,7 @@ static int mtk_thermal_probe(struct plat
+               goto err_disable_clk_peri_therm;
+       }
+-      ret = devm_thermal_add_hwmon_sysfs(tzdev);
++      ret = devm_thermal_add_hwmon_sysfs(&pdev->dev, tzdev);
+       if (ret)
+               dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
+--- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
++++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
+@@ -688,7 +688,7 @@ static int adc_tm5_register_tzd(struct a
+                       return PTR_ERR(tzd);
+               }
+               adc_tm->channels[i].tzd = tzd;
+-              if (devm_thermal_add_hwmon_sysfs(tzd))
++              if (devm_thermal_add_hwmon_sysfs(adc_tm->dev, tzd))
+                       dev_warn(adc_tm->dev,
+                                "Failed to add hwmon sysfs attributes\n");
+       }
+--- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
++++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+@@ -460,7 +460,7 @@ static int qpnp_tm_probe(struct platform
+               return ret;
+       }
+-      if (devm_thermal_add_hwmon_sysfs(chip->tz_dev))
++      if (devm_thermal_add_hwmon_sysfs(&pdev->dev, chip->tz_dev))
+               dev_warn(&pdev->dev,
+                        "Failed to add hwmon sysfs attributes\n");
+--- a/drivers/thermal/qcom/tsens.c
++++ b/drivers/thermal/qcom/tsens.c
+@@ -1056,7 +1056,7 @@ static int tsens_register(struct tsens_p
+               if (priv->ops->enable)
+                       priv->ops->enable(priv, i);
+-              if (devm_thermal_add_hwmon_sysfs(tzd))
++              if (devm_thermal_add_hwmon_sysfs(priv->dev, tzd))
+                       dev_warn(priv->dev,
+                                "Failed to add hwmon sysfs attributes\n");
+       }
+--- a/drivers/thermal/qoriq_thermal.c
++++ b/drivers/thermal/qoriq_thermal.c
+@@ -158,7 +158,7 @@ static int qoriq_tmu_register_tmu_zone(s
+                       return ret;
+               }
+-              if (devm_thermal_add_hwmon_sysfs(tzd))
++              if (devm_thermal_add_hwmon_sysfs(dev, tzd))
+                       dev_warn(dev,
+                                "Failed to add hwmon sysfs attributes\n");
+--- a/drivers/thermal/sun8i_thermal.c
++++ b/drivers/thermal/sun8i_thermal.c
+@@ -468,7 +468,7 @@ static int sun8i_ths_register(struct ths
+               if (IS_ERR(tmdev->sensor[i].tzd))
+                       return PTR_ERR(tmdev->sensor[i].tzd);
+-              if (devm_thermal_add_hwmon_sysfs(tmdev->sensor[i].tzd))
++              if (devm_thermal_add_hwmon_sysfs(tmdev->dev, tmdev->sensor[i].tzd))
+                       dev_warn(tmdev->dev,
+                                "Failed to add hwmon sysfs attributes\n");
+       }
+--- a/drivers/thermal/tegra/tegra30-tsensor.c
++++ b/drivers/thermal/tegra/tegra30-tsensor.c
+@@ -530,7 +530,7 @@ static int tegra_tsensor_register_channe
+               return 0;
+       }
+-      if (devm_thermal_add_hwmon_sysfs(tsc->tzd))
++      if (devm_thermal_add_hwmon_sysfs(ts->dev, tsc->tzd))
+               dev_warn(ts->dev, "failed to add hwmon sysfs attributes\n");
+       return 0;
+--- a/drivers/thermal/thermal_hwmon.c
++++ b/drivers/thermal/thermal_hwmon.c
+@@ -255,7 +255,7 @@ static void devm_thermal_hwmon_release(s
+       thermal_remove_hwmon_sysfs(*(struct thermal_zone_device **)res);
+ }
+-int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
++int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz)
+ {
+       struct thermal_zone_device **ptr;
+       int ret;
+@@ -272,7 +272,7 @@ int devm_thermal_add_hwmon_sysfs(struct
+       }
+       *ptr = tz;
+-      devres_add(&tz->device, ptr);
++      devres_add(dev, ptr);
+       return ret;
+ }
+--- a/drivers/thermal/thermal_hwmon.h
++++ b/drivers/thermal/thermal_hwmon.h
+@@ -17,7 +17,7 @@
+ #ifdef CONFIG_THERMAL_HWMON
+ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
+-int devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz);
++int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz);
+ void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz);
+ #else
+ static inline int
+@@ -27,7 +27,7 @@ thermal_add_hwmon_sysfs(struct thermal_z
+ }
+ static inline int
+-devm_thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
++devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz)
+ {
+       return 0;
+ }
+--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+@@ -182,7 +182,7 @@ int ti_thermal_expose_sensor(struct ti_b
+       ti_bandgap_set_sensor_data(bgp, id, data);
+       ti_bandgap_write_update_interval(bgp, data->sensor_id, interval);
+-      if (devm_thermal_add_hwmon_sysfs(data->ti_thermal))
++      if (devm_thermal_add_hwmon_sysfs(bgp->dev, data->ti_thermal))
+               dev_warn(bgp->dev, "failed to add hwmon sysfs attributes\n");
+       return 0;
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-13-thermal-Don-t-use-device-internal-thermal-zone-struc.patch b/target/linux/mediatek/patches-6.6/830-v6.4-13-thermal-Don-t-use-device-internal-thermal-zone-struc.patch
new file mode 100644 (file)
index 0000000..9dedc2c
--- /dev/null
@@ -0,0 +1,79 @@
+From 5a72b8e4bac753e4dc74dc0a1335d120f63df97a Mon Sep 17 00:00:00 2001
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+Date: Wed, 1 Mar 2023 21:14:37 +0100
+Subject: [PATCH 09/42] thermal: Don't use 'device' internal thermal zone
+ structure field
+
+Some drivers are directly using the thermal zone's 'device' structure
+field.
+
+Use the driver device pointer instead of the thermal zone device when
+it is available.
+
+Remove the traces when they are duplicate with the traces in the core
+code.
+
+[again skipped imx_thermal.c]
+
+Cc: Jean Delvare <jdelvare@suse.com>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Reviewed-by: Balsam CHIHI <bchihi@baylibre.com> #Mediatek LVTS
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek LVTS
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/thermal/mediatek/lvts_thermal.c            | 4 ++--
+ drivers/thermal/thermal_hwmon.c                    | 4 ++--
+ drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -305,7 +305,7 @@ static int lvts_set_trips(struct thermal
+        * 14-0 : Raw temperature for threshold
+        */
+       if (low != -INT_MAX) {
+-              dev_dbg(&tz->device, "Setting low limit temperature interrupt: %d\n", low);
++              pr_debug("%s: Setting low limit temperature interrupt: %d\n", tz->type, low);
+               writel(raw_low, LVTS_H2NTHRE(base));
+       }
+@@ -318,7 +318,7 @@ static int lvts_set_trips(struct thermal
+        *
+        * 14-0 : Raw temperature for threshold
+        */
+-      dev_dbg(&tz->device, "Setting high limit temperature interrupt: %d\n", high);
++      pr_debug("%s: Setting high limit temperature interrupt: %d\n", tz->type, high);
+       writel(raw_high, LVTS_HTHRE(base));
+       return 0;
+--- a/drivers/thermal/thermal_hwmon.c
++++ b/drivers/thermal/thermal_hwmon.c
+@@ -220,14 +220,14 @@ void thermal_remove_hwmon_sysfs(struct t
+       hwmon = thermal_hwmon_lookup_by_type(tz);
+       if (unlikely(!hwmon)) {
+               /* Should never happen... */
+-              dev_dbg(&tz->device, "hwmon device lookup failed!\n");
++              dev_dbg(hwmon->device, "hwmon device lookup failed!\n");
+               return;
+       }
+       temp = thermal_hwmon_lookup_temp(hwmon, tz);
+       if (unlikely(!temp)) {
+               /* Should never happen... */
+-              dev_dbg(&tz->device, "temperature input lookup failed!\n");
++              dev_dbg(hwmon->device, "temperature input lookup failed!\n");
+               return;
+       }
+--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+@@ -43,7 +43,7 @@ static void ti_thermal_work(struct work_
+       thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED);
+-      dev_dbg(&data->ti_thermal->device, "updated thermal zone %s\n",
++      dev_dbg(data->bgp->dev, "updated thermal zone %s\n",
+               data->ti_thermal->type);
+ }
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-14-thermal-Use-thermal_zone_device_type-accessor.patch b/target/linux/mediatek/patches-6.6/830-v6.4-14-thermal-Use-thermal_zone_device_type-accessor.patch
new file mode 100644 (file)
index 0000000..8cec9ab
--- /dev/null
@@ -0,0 +1,62 @@
+From 66b3a292d3fc749e8ec7ac5278a17e8a5757ecbc Mon Sep 17 00:00:00 2001
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+Date: Wed, 1 Mar 2023 21:14:41 +0100
+Subject: [PATCH 10/42] thermal: Use thermal_zone_device_type() accessor
+
+Replace the accesses to 'tz->type' by its accessor version in order to
+self-encapsulate the thermal_zone_device structure.
+
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com> #mlxsw
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> #MediaTek LVTS
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 2 +-
+ drivers/thermal/mediatek/lvts_thermal.c            | 6 ++++--
+ drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
+ 3 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+@@ -168,7 +168,7 @@ mlxsw_thermal_module_trips_update(struct
+       if (crit_temp > emerg_temp) {
+               dev_warn(dev, "%s : Critical threshold %d is above emergency threshold %d\n",
+-                       tz->tzdev->type, crit_temp, emerg_temp);
++                       thermal_zone_device_type(tz->tzdev), crit_temp, emerg_temp);
+               return 0;
+       }
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -305,7 +305,8 @@ static int lvts_set_trips(struct thermal
+        * 14-0 : Raw temperature for threshold
+        */
+       if (low != -INT_MAX) {
+-              pr_debug("%s: Setting low limit temperature interrupt: %d\n", tz->type, low);
++              pr_debug("%s: Setting low limit temperature interrupt: %d\n",
++                       thermal_zone_device_type(tz), low);
+               writel(raw_low, LVTS_H2NTHRE(base));
+       }
+@@ -318,7 +319,8 @@ static int lvts_set_trips(struct thermal
+        *
+        * 14-0 : Raw temperature for threshold
+        */
+-      pr_debug("%s: Setting high limit temperature interrupt: %d\n", tz->type, high);
++      pr_debug("%s: Setting high limit temperature interrupt: %d\n",
++               thermal_zone_device_type(tz), high);
+       writel(raw_high, LVTS_HTHRE(base));
+       return 0;
+--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
+@@ -44,7 +44,7 @@ static void ti_thermal_work(struct work_
+       thermal_zone_device_update(data->ti_thermal, THERMAL_EVENT_UNSPECIFIED);
+       dev_dbg(data->bgp->dev, "updated thermal zone %s\n",
+-              data->ti_thermal->type);
++              thermal_zone_device_type(data->ti_thermal));
+ }
+ /**
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-15-thermal-drivers-mediatek-Control-buffer-enablement-t.patch b/target/linux/mediatek/patches-6.6/830-v6.4-15-thermal-drivers-mediatek-Control-buffer-enablement-t.patch
new file mode 100644 (file)
index 0000000..68f41fd
--- /dev/null
@@ -0,0 +1,81 @@
+From f6658c1c4ae98477d6be00495226c0617354fe76 Mon Sep 17 00:00:00 2001
+From: Markus Schneider-Pargmann <msp@baylibre.com>
+Date: Fri, 27 Jan 2023 16:44:43 +0100
+Subject: [PATCH 11/42] thermal/drivers/mediatek: Control buffer enablement
+ tweaks
+
+Add logic in order to be able to turn on the control buffer on MT8365.
+This change now allows to have control buffer support for MTK_THERMAL_V1,
+and it allows to define the register offset, and mask used to enable it.
+
+Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Signed-off-by: Fabien Parent <fparent@baylibre.com>
+Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-2-55a1ae14af74@baylibre.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 28 +++++++++++++++--------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -307,6 +307,9 @@ struct mtk_thermal_data {
+       bool need_switch_bank;
+       struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
+       enum mtk_thermal_version version;
++      u32 apmixed_buffer_ctl_reg;
++      u32 apmixed_buffer_ctl_mask;
++      u32 apmixed_buffer_ctl_set;
+ };
+ struct mtk_thermal {
+@@ -560,6 +563,9 @@ static const struct mtk_thermal_data mt7
+       .adcpnp = mt7622_adcpnp,
+       .sensor_mux_values = mt7622_mux_values,
+       .version = MTK_THERMAL_V2,
++      .apmixed_buffer_ctl_reg = APMIXED_SYS_TS_CON1,
++      .apmixed_buffer_ctl_mask = GENMASK(31, 6) | BIT(3),
++      .apmixed_buffer_ctl_set = BIT(0),
+ };
+ /*
+@@ -1079,14 +1085,18 @@ static const struct of_device_id mtk_the
+ };
+ MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
+-static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base)
++static void mtk_thermal_turn_on_buffer(struct mtk_thermal *mt,
++                                     void __iomem *apmixed_base)
+ {
+-      int tmp;
++      u32 tmp;
++
++      if (!mt->conf->apmixed_buffer_ctl_reg)
++              return;
+-      tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1);
+-      tmp &= ~(0x37);
+-      tmp |= 0x1;
+-      writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1);
++      tmp = readl(apmixed_base + mt->conf->apmixed_buffer_ctl_reg);
++      tmp &= mt->conf->apmixed_buffer_ctl_mask;
++      tmp |= mt->conf->apmixed_buffer_ctl_set;
++      writel(tmp, apmixed_base + mt->conf->apmixed_buffer_ctl_reg);
+       udelay(200);
+ }
+@@ -1184,10 +1194,10 @@ static int mtk_thermal_probe(struct plat
+               goto err_disable_clk_auxadc;
+       }
+-      if (mt->conf->version != MTK_THERMAL_V1) {
+-              mtk_thermal_turn_on_buffer(apmixed_base);
++      mtk_thermal_turn_on_buffer(mt, apmixed_base);
++
++      if (mt->conf->version != MTK_THERMAL_V2)
+               mtk_thermal_release_periodic_ts(mt, auxadc_base);
+-      }
+       if (mt->conf->version == MTK_THERMAL_V1)
+               mt->raw_to_mcelsius = raw_to_mcelsius_v1;
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-16-thermal-drivers-mediatek-Add-support-for-MT8365-SoC.patch b/target/linux/mediatek/patches-6.6/830-v6.4-16-thermal-drivers-mediatek-Add-support-for-MT8365-SoC.patch
new file mode 100644 (file)
index 0000000..285c6f6
--- /dev/null
@@ -0,0 +1,123 @@
+From c4eff784465f88218dc5eb51320320464db83d3f Mon Sep 17 00:00:00 2001
+From: Fabien Parent <fparent@baylibre.com>
+Date: Fri, 27 Jan 2023 16:44:44 +0100
+Subject: [PATCH 12/42] thermal/drivers/mediatek: Add support for MT8365 SoC
+
+MT8365 is similar to the other SoCs supported by the driver. It has only
+one bank and 3 actual sensors that can be multiplexed. There is another
+one sensor that does not have usable data.
+
+Signed-off-by: Fabien Parent <fparent@baylibre.com>
+Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-3-55a1ae14af74@baylibre.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 68 +++++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -31,6 +31,7 @@
+ #define AUXADC_CON2_V         0x010
+ #define AUXADC_DATA(channel)  (0x14 + (channel) * 4)
++#define APMIXED_SYS_TS_CON0   0x600
+ #define APMIXED_SYS_TS_CON1   0x604
+ /* Thermal Controller Registers */
+@@ -281,6 +282,17 @@ enum mtk_thermal_version {
+ /* The calibration coefficient of sensor  */
+ #define MT7986_CALIBRATION            165
++/* MT8365 */
++#define MT8365_TEMP_AUXADC_CHANNEL 11
++#define MT8365_CALIBRATION 164
++#define MT8365_NUM_CONTROLLER 1
++#define MT8365_NUM_BANKS 1
++#define MT8365_NUM_SENSORS 3
++#define MT8365_NUM_SENSORS_PER_ZONE 3
++#define MT8365_TS1 0
++#define MT8365_TS2 1
++#define MT8365_TS3 2
++
+ struct mtk_thermal;
+ struct thermal_bank_cfg {
+@@ -435,6 +447,24 @@ static const int mt7986_mux_values[MT798
+ static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
+ static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
++/* MT8365 thermal sensor data */
++static const int mt8365_bank_data[MT8365_NUM_SENSORS] = {
++      MT8365_TS1, MT8365_TS2, MT8365_TS3
++};
++
++static const int mt8365_msr[MT8365_NUM_SENSORS_PER_ZONE] = {
++      TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
++};
++
++static const int mt8365_adcpnp[MT8365_NUM_SENSORS_PER_ZONE] = {
++      TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
++};
++
++static const int mt8365_mux_values[MT8365_NUM_SENSORS] = { 0, 1, 2 };
++static const int mt8365_tc_offset[MT8365_NUM_CONTROLLER] = { 0 };
++
++static const int mt8365_vts_index[MT8365_NUM_SENSORS] = { VTS1, VTS2, VTS3 };
++
+ /*
+  * The MT8173 thermal controller has four banks. Each bank can read up to
+  * four temperature sensors simultaneously. The MT8173 has a total of 5
+@@ -510,6 +540,40 @@ static const struct mtk_thermal_data mt2
+ };
+ /*
++ * The MT8365 thermal controller has one bank, which can read up to
++ * four temperature sensors simultaneously. The MT8365 has a total of 3
++ * temperature sensors.
++ *
++ * The thermal core only gets the maximum temperature of this one bank,
++ * so the bank concept wouldn't be necessary here. However, the SVS (Smart
++ * Voltage Scaling) unit makes its decisions based on the same bank
++ * data.
++ */
++static const struct mtk_thermal_data mt8365_thermal_data = {
++      .auxadc_channel = MT8365_TEMP_AUXADC_CHANNEL,
++      .num_banks = MT8365_NUM_BANKS,
++      .num_sensors = MT8365_NUM_SENSORS,
++      .vts_index = mt8365_vts_index,
++      .cali_val = MT8365_CALIBRATION,
++      .num_controller = MT8365_NUM_CONTROLLER,
++      .controller_offset = mt8365_tc_offset,
++      .need_switch_bank = false,
++      .bank_data = {
++              {
++                      .num_sensors = MT8365_NUM_SENSORS,
++                      .sensors = mt8365_bank_data
++              },
++      },
++      .msr = mt8365_msr,
++      .adcpnp = mt8365_adcpnp,
++      .sensor_mux_values = mt8365_mux_values,
++      .version = MTK_THERMAL_V1,
++      .apmixed_buffer_ctl_reg = APMIXED_SYS_TS_CON0,
++      .apmixed_buffer_ctl_mask = (u32) ~GENMASK(29, 28),
++      .apmixed_buffer_ctl_set = 0,
++};
++
++/*
+  * The MT2712 thermal controller has one bank, which can read up to
+  * four temperature sensors simultaneously. The MT2712 has a total of 4
+  * temperature sensors.
+@@ -1080,6 +1144,10 @@ static const struct of_device_id mtk_the
+       {
+               .compatible = "mediatek,mt8183-thermal",
+               .data = (void *)&mt8183_thermal_data,
++      },
++      {
++              .compatible = "mediatek,mt8365-thermal",
++              .data = (void *)&mt8365_thermal_data,
+       }, {
+       },
+ };
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-17-thermal-drivers-mediatek-Add-delay-after-thermal-ban.patch b/target/linux/mediatek/patches-6.6/830-v6.4-17-thermal-drivers-mediatek-Add-delay-after-thermal-ban.patch
new file mode 100644 (file)
index 0000000..5c99aa8
--- /dev/null
@@ -0,0 +1,50 @@
+From 4eead70db74922bc61e9d0b4591524369a335751 Mon Sep 17 00:00:00 2001
+From: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+Date: Fri, 27 Jan 2023 16:44:46 +0100
+Subject: [PATCH 13/42] thermal/drivers/mediatek: Add delay after thermal banks
+ initialization
+
+Thermal sensor reads performed immediately after thermal bank
+initialization returns bogus values. This is currently tackled by returning
+0 if the temperature is bogus (exceeding 200000).
+
+Instead, add a delay between the bank init and the thermal zone device
+register to properly fix this.
+
+Signed-off-by: Michael Kao <michael.kao@mediatek.com>
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Signed-off-by: Amjad Ouled-Ameur <aouledameur@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-5-55a1ae14af74@baylibre.com
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -816,14 +816,6 @@ static int mtk_thermal_bank_temperature(
+                       mt, conf->bank_data[bank->id].sensors[i], raw);
+-              /*
+-               * The first read of a sensor often contains very high bogus
+-               * temperature value. Filter these out so that the system does
+-               * not immediately shut down.
+-               */
+-              if (temp > 200000)
+-                      temp = 0;
+-
+               if (temp > max)
+                       max = temp;
+       }
+@@ -1281,6 +1273,9 @@ static int mtk_thermal_probe(struct plat
+       platform_set_drvdata(pdev, mt);
++      /* Delay for thermal banks to be ready */
++      msleep(30);
++
+       tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
+                                             &mtk_thermal_ops);
+       if (IS_ERR(tzdev)) {
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-18-thermal-drivers-mediatek-lvts_thermal-Fix-sensor-1-i.patch b/target/linux/mediatek/patches-6.6/830-v6.4-18-thermal-drivers-mediatek-lvts_thermal-Fix-sensor-1-i.patch
new file mode 100644 (file)
index 0000000..734f5c1
--- /dev/null
@@ -0,0 +1,46 @@
+From ad9dc9e92367803a4f9576aea0dab110d03fc510 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wenst@chromium.org>
+Date: Tue, 28 Mar 2023 11:10:17 +0800
+Subject: [PATCH 14/42] thermal/drivers/mediatek/lvts_thermal: Fix sensor 1
+ interrupt status bitmask
+
+The binary representation for sensor 1 interrupt status was incorrectly
+assembled, when compared to the full table given in the same comment
+section. The conversion into hex was also incorrect, leading to
+incorrect interrupt status bitmask for sensor 1. This would cause the
+driver to incorrectly identify changes for sensor 1, when in fact it
+was sensor 0, or a sensor access time out.
+
+Fix the binary and hex representations in the comments, and the actual
+bitmask macro.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230328031017.1360976-1-wenst@chromium.org
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -66,7 +66,7 @@
+ #define LVTS_MONINT_CONF                      0x9FBF7BDE
+ #define LVTS_INT_SENSOR0                      0x0009001F
+-#define LVTS_INT_SENSOR1                      0X000881F0
++#define LVTS_INT_SENSOR1                      0x001203E0
+ #define LVTS_INT_SENSOR2                      0x00247C00
+ #define LVTS_INT_SENSOR3                      0x1FC00000
+@@ -395,8 +395,8 @@ static irqreturn_t lvts_ctrl_irq_handler
+        *                  => 0x1FC00000
+        * sensor 2 interrupt: 0000 0000 0010 0100 0111 1100 0000 0000
+        *                  => 0x00247C00
+-       * sensor 1 interrupt: 0000 0000 0001 0001 0000 0011 1110 0000
+-       *                  => 0X000881F0
++       * sensor 1 interrupt: 0000 0000 0001 0010 0000 0011 1110 0000
++       *                  => 0X001203E0
+        * sensor 0 interrupt: 0000 0000 0000 1001 0000 0000 0001 1111
+        *                  => 0x0009001F
+        */
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-19-thermal-drivers-mediatek-lvts_thermal-Add-AP-domain-.patch b/target/linux/mediatek/patches-6.6/830-v6.4-19-thermal-drivers-mediatek-lvts_thermal-Add-AP-domain-.patch
new file mode 100644 (file)
index 0000000..d09c205
--- /dev/null
@@ -0,0 +1,149 @@
+From 9aad43ad3285fc21158fb416830a6156a9a31fa5 Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Tue, 7 Mar 2023 16:45:22 +0100
+Subject: [PATCH 15/42] thermal/drivers/mediatek/lvts_thermal: Add AP domain
+ for mt8195
+
+Add MT8195 AP Domain support to LVTS Driver.
+
+Take the opportunity to update the comments to show calibration data
+information related to the new domain.
+
+[dlezcano]: Massaged a bit the changelog
+
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230307154524.118541-3-bchihi@baylibre.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 94 +++++++++++++++++++------
+ 1 file changed, 74 insertions(+), 20 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -530,29 +530,33 @@ static int lvts_sensor_init(struct devic
+  * The efuse blob values follows the sensor enumeration per thermal
+  * controller. The decoding of the stream is as follow:
+  *
+- *                        <--?-> <----big0 ???---> <-sensor0-> <-0->
+- *                        ------------------------------------------
+- * index in the stream: : | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 |
+- *                        ------------------------------------------
++ * stream index map for MCU Domain :
+  *
+- *                        <--sensor1--><-0-> <----big1 ???---> <-sen
+- *                        ------------------------------------------
+- *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
+- *                        ------------------------------------------
++ * <-----mcu-tc#0-----> <-----sensor#0-----> <-----sensor#1----->
++ *  0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09
+  *
+- *                        sor0-> <-0-> <-sensor1-> <-0-> ..........
+- *                        ------------------------------------------
+- *                        | 0x7 | 0x8 | 0x9 | 0xA | 0xB | OxC | OxD |
+- *                        ------------------------------------------
++ * <-----mcu-tc#1-----> <-----sensor#2-----> <-----sensor#3----->
++ *  0x0A | 0x0B | 0x0C | 0x0D | 0x0E | 0x0F | 0x10 | 0x11 | 0x12
+  *
+- * And so on ...
++ * <-----mcu-tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> <-----sensor#7----->
++ *  0x13 | 0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21
++ *
++ * stream index map for AP Domain :
++ *
++ * <-----ap--tc#0-----> <-----sensor#0-----> <-----sensor#1----->
++ *  0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A
++ *
++ * <-----ap--tc#1-----> <-----sensor#2-----> <-----sensor#3----->
++ *  0x2B | 0x2C | 0x2D | 0x2E | 0x2F | 0x30 | 0x31 | 0x32 | 0x33
++ *
++ * <-----ap--tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6----->
++ *  0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 | 0x3A | 0x3B | 0x3C | 0x3D | 0x3E | 0x3F
++ *
++ * <-----ap--tc#3-----> <-----sensor#7-----> <-----sensor#8----->
++ *  0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 | 0x46 | 0x47 | 0x48
+  *
+  * The data description gives the offset of the calibration data in
+  * this bytes stream for each sensor.
+- *
+- * Each thermal controller can handle up to 4 sensors max, we don't
+- * care if there are less as the array of calibration is sized to 4
+- * anyway. The unused sensor slot will be zeroed.
+  */
+ static int lvts_calibration_init(struct device *dev, struct lvts_ctrl *lvts_ctrl,
+                                       const struct lvts_ctrl_data *lvts_ctrl_data,
+@@ -1165,7 +1169,7 @@ static int lvts_remove(struct platform_d
+       return 0;
+ }
+-static const struct lvts_ctrl_data mt8195_lvts_data_ctrl[] = {
++static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
+       {
+               .cal_offset = { 0x04, 0x07 },
+               .lvts_sensor = {
+@@ -1200,13 +1204,63 @@ static const struct lvts_ctrl_data mt819
+       }
+ };
++static const struct lvts_ctrl_data mt8195_lvts_ap_data_ctrl[] = {
++              {
++              .cal_offset = { 0x25, 0x28 },
++              .lvts_sensor = {
++                      { .dt_id = MT8195_AP_VPU0 },
++                      { .dt_id = MT8195_AP_VPU1 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x0,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
++      },
++      {
++              .cal_offset = { 0x2e, 0x31 },
++              .lvts_sensor = {
++                      { .dt_id = MT8195_AP_GPU0 },
++                      { .dt_id = MT8195_AP_GPU1 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x100,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
++      },
++      {
++              .cal_offset = { 0x37, 0x3a, 0x3d },
++              .lvts_sensor = {
++                      { .dt_id = MT8195_AP_VDEC },
++                      { .dt_id = MT8195_AP_IMG },
++                      { .dt_id = MT8195_AP_INFRA },
++              },
++              .num_lvts_sensor = 3,
++              .offset = 0x200,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
++      },
++      {
++              .cal_offset = { 0x43, 0x46 },
++              .lvts_sensor = {
++                      { .dt_id = MT8195_AP_CAM0 },
++                      { .dt_id = MT8195_AP_CAM1 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x300,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8195,
++      }
++};
++
+ static const struct lvts_data mt8195_lvts_mcu_data = {
+-      .lvts_ctrl      = mt8195_lvts_data_ctrl,
+-      .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_data_ctrl),
++      .lvts_ctrl      = mt8195_lvts_mcu_data_ctrl,
++      .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
++};
++
++static const struct lvts_data mt8195_lvts_ap_data = {
++      .lvts_ctrl      = mt8195_lvts_ap_data_ctrl,
++      .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_ap_data_ctrl),
+ };
+ static const struct of_device_id lvts_of_match[] = {
+       { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
++      { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, lvts_of_match);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-20-Revert-thermal-drivers-mediatek-Add-delay-after-ther.patch b/target/linux/mediatek/patches-6.6/830-v6.4-20-Revert-thermal-drivers-mediatek-Add-delay-after-ther.patch
new file mode 100644 (file)
index 0000000..a48ea37
--- /dev/null
@@ -0,0 +1,53 @@
+From 7105a86760bd9e4d107075cefc75016b693a5542 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Wed, 19 Apr 2023 08:11:45 +0200
+Subject: [PATCH 16/42] Revert "thermal/drivers/mediatek: Add delay after
+ thermal banks initialization"
+
+Some more testing revealed that this commit introduces a regression on some
+MT8173 Chromebooks and at least on one MT6795 Sony Xperia M5 smartphone due
+to the delay being apparently variable and machine specific.
+
+Another solution would be to delay for a bit more (~70ms) but this is not
+feasible for two reasons: first of all, we're adding an even bigger delay
+in a probe function; second, some machines need less, some may need even
+more, making the msleep at probe solution highly suboptimal.
+
+This reverts commit 10debf8c2da8011c8009dd4b3f6d0ab85891c81b.
+
+Fixes: 10debf8c2da8 ("thermal/drivers/mediatek: Add delay after thermal banks initialization")
+Reported-by: "kernelci.org bot" <bot@kernelci.org>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230419061146.22246-2-angelogioacchino.delregno@collabora.com
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -816,6 +816,14 @@ static int mtk_thermal_bank_temperature(
+                       mt, conf->bank_data[bank->id].sensors[i], raw);
++              /*
++               * The first read of a sensor often contains very high bogus
++               * temperature value. Filter these out so that the system does
++               * not immediately shut down.
++               */
++              if (temp > 200000)
++                      temp = 0;
++
+               if (temp > max)
+                       max = temp;
+       }
+@@ -1273,9 +1281,6 @@ static int mtk_thermal_probe(struct plat
+       platform_set_drvdata(pdev, mt);
+-      /* Delay for thermal banks to be ready */
+-      msleep(30);
+-
+       tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
+                                             &mtk_thermal_ops);
+       if (IS_ERR(tzdev)) {
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-21-thermal-drivers-mediatek-Add-temperature-constraints.patch b/target/linux/mediatek/patches-6.6/830-v6.4-21-thermal-drivers-mediatek-Add-temperature-constraints.patch
new file mode 100644 (file)
index 0000000..aae87af
--- /dev/null
@@ -0,0 +1,78 @@
+From 681b652c9dfc4037d4a55b2733e091a4e1a5de18 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Wed, 19 Apr 2023 08:11:46 +0200
+Subject: [PATCH 17/42] thermal/drivers/mediatek: Add temperature constraints
+ to validate read
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The AUXADC thermal v1 allows reading temperature range between -20°C to
+150°C and any value out of this range is invalid.
+
+Add new definitions for MT8173_TEMP_{MIN_MAX} and a new small helper
+mtk_thermal_temp_is_valid() to check if new readings are in range: if
+not, we tell to the API that the reading is invalid by returning
+THERMAL_TEMP_INVALID.
+
+It was chosen to introduce the helper function because, even though this
+temperature range is realistically ok for all, it comes from a downstream
+kernel driver for version 1, but here we also support v2 and v3 which may
+may have wider constraints.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230419061146.22246-3-angelogioacchino.delregno@collabora.com
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 24 +++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -116,6 +116,10 @@
+ /* The calibration coefficient of sensor  */
+ #define MT8173_CALIBRATION    165
++/* Valid temperatures range */
++#define MT8173_TEMP_MIN               -20000
++#define MT8173_TEMP_MAX               150000
++
+ /*
+  * Layout of the fuses providing the calibration data
+  * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
+@@ -689,6 +693,11 @@ static const struct mtk_thermal_data mt7
+       .version = MTK_THERMAL_V3,
+ };
++static bool mtk_thermal_temp_is_valid(int temp)
++{
++      return (temp >= MT8173_TEMP_MIN) && (temp <= MT8173_TEMP_MAX);
++}
++
+ /**
+  * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius
+  * @mt:       The thermal controller
+@@ -815,14 +824,17 @@ static int mtk_thermal_bank_temperature(
+               temp = mt->raw_to_mcelsius(
+                       mt, conf->bank_data[bank->id].sensors[i], raw);
+-
+               /*
+-               * The first read of a sensor often contains very high bogus
+-               * temperature value. Filter these out so that the system does
+-               * not immediately shut down.
++               * Depending on the filt/sen intervals and ADC polling time,
++               * we may need up to 60 milliseconds after initialization: this
++               * will result in the first reading containing an out of range
++               * temperature value.
++               * Validate the reading to both address the aforementioned issue
++               * and to eventually avoid bogus readings during runtime in the
++               * event that the AUXADC gets unstable due to high EMI, etc.
+                */
+-              if (temp > 200000)
+-                      temp = 0;
++              if (!mtk_thermal_temp_is_valid(temp))
++                      temp = THERMAL_TEMP_INVALID;
+               if (temp > max)
+                       max = temp;
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-22-thermal-drivers-mediatek-Use-devm_of_iomap-to-avoid-.patch b/target/linux/mediatek/patches-6.6/830-v6.4-22-thermal-drivers-mediatek-Use-devm_of_iomap-to-avoid-.patch
new file mode 100644 (file)
index 0000000..782684a
--- /dev/null
@@ -0,0 +1,53 @@
+From 458fa1d508de3f17e49d974a0158d9aeff273a58 Mon Sep 17 00:00:00 2001
+From: Kang Chen <void0red@hust.edu.cn>
+Date: Wed, 19 Apr 2023 10:07:48 +0800
+Subject: [PATCH 18/42] thermal/drivers/mediatek: Use devm_of_iomap to avoid
+ resource leak in mtk_thermal_probe
+
+Smatch reports:
+1. mtk_thermal_probe() warn: 'apmixed_base' from of_iomap() not released.
+2. mtk_thermal_probe() warn: 'auxadc_base' from of_iomap() not released.
+
+The original code forgets to release iomap resource when handling errors,
+fix it by switch to devm_of_iomap.
+
+Fixes: 89945047b166 ("thermal: mediatek: Add tsensor support for V2 thermal system")
+Signed-off-by: Kang Chen <void0red@hust.edu.cn>
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230419020749.621257-1-void0red@hust.edu.cn
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -1232,7 +1232,12 @@ static int mtk_thermal_probe(struct plat
+               return -ENODEV;
+       }
+-      auxadc_base = of_iomap(auxadc, 0);
++      auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL);
++      if (IS_ERR(auxadc_base)) {
++              of_node_put(auxadc);
++              return PTR_ERR(auxadc_base);
++      }
++
+       auxadc_phys_base = of_get_phys_base(auxadc);
+       of_node_put(auxadc);
+@@ -1248,7 +1253,12 @@ static int mtk_thermal_probe(struct plat
+               return -ENODEV;
+       }
+-      apmixed_base = of_iomap(apmixedsys, 0);
++      apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL);
++      if (IS_ERR(apmixed_base)) {
++              of_node_put(apmixedsys);
++              return PTR_ERR(apmixed_base);
++      }
++
+       apmixed_phys_base = of_get_phys_base(apmixedsys);
+       of_node_put(apmixedsys);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-23-thermal-drivers-mediatek-Change-clk_prepare_enable-t.patch b/target/linux/mediatek/patches-6.6/830-v6.4-23-thermal-drivers-mediatek-Change-clk_prepare_enable-t.patch
new file mode 100644 (file)
index 0000000..d7896db
--- /dev/null
@@ -0,0 +1,100 @@
+From 227d1856924ec00a4f5bdf5afcf77bc7f3f04e86 Mon Sep 17 00:00:00 2001
+From: Kang Chen <void0red@hust.edu.cn>
+Date: Wed, 19 Apr 2023 10:07:49 +0800
+Subject: [PATCH 19/42] thermal/drivers/mediatek: Change clk_prepare_enable to
+ devm_clk_get_enabled in mtk_thermal_probe
+
+Use devm_clk_get_enabled to do automatic resource management.
+Meanwhile, remove error handling labels in the probe function and
+the whole remove function.
+
+Signed-off-by: Kang Chen <void0red@hust.edu.cn>
+Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230419020749.621257-2-void0red@hust.edu.cn
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 44 +++++------------------
+ 1 file changed, 9 insertions(+), 35 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -1206,14 +1206,6 @@ static int mtk_thermal_probe(struct plat
+       mt->conf = of_device_get_match_data(&pdev->dev);
+-      mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
+-      if (IS_ERR(mt->clk_peri_therm))
+-              return PTR_ERR(mt->clk_peri_therm);
+-
+-      mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
+-      if (IS_ERR(mt->clk_auxadc))
+-              return PTR_ERR(mt->clk_auxadc);
+-
+       mt->thermal_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+       if (IS_ERR(mt->thermal_base))
+               return PTR_ERR(mt->thermal_base);
+@@ -1272,16 +1264,18 @@ static int mtk_thermal_probe(struct plat
+       if (ret)
+               return ret;
+-      ret = clk_prepare_enable(mt->clk_auxadc);
+-      if (ret) {
++      mt->clk_auxadc = devm_clk_get_enabled(&pdev->dev, "auxadc");
++      if (IS_ERR(mt->clk_auxadc)) {
++              ret = PTR_ERR(mt->clk_auxadc);
+               dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
+               return ret;
+       }
+-      ret = clk_prepare_enable(mt->clk_peri_therm);
+-      if (ret) {
++      mt->clk_peri_therm = devm_clk_get_enabled(&pdev->dev, "therm");
++      if (IS_ERR(mt->clk_peri_therm)) {
++              ret = PTR_ERR(mt->clk_peri_therm);
+               dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
+-              goto err_disable_clk_auxadc;
++              return ret;
+       }
+       mtk_thermal_turn_on_buffer(mt, apmixed_base);
+@@ -1305,38 +1299,18 @@ static int mtk_thermal_probe(struct plat
+       tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
+                                             &mtk_thermal_ops);
+-      if (IS_ERR(tzdev)) {
+-              ret = PTR_ERR(tzdev);
+-              goto err_disable_clk_peri_therm;
+-      }
++      if (IS_ERR(tzdev))
++              return PTR_ERR(tzdev);
+       ret = devm_thermal_add_hwmon_sysfs(&pdev->dev, tzdev);
+       if (ret)
+               dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
+       return 0;
+-
+-err_disable_clk_peri_therm:
+-      clk_disable_unprepare(mt->clk_peri_therm);
+-err_disable_clk_auxadc:
+-      clk_disable_unprepare(mt->clk_auxadc);
+-
+-      return ret;
+-}
+-
+-static int mtk_thermal_remove(struct platform_device *pdev)
+-{
+-      struct mtk_thermal *mt = platform_get_drvdata(pdev);
+-
+-      clk_disable_unprepare(mt->clk_peri_therm);
+-      clk_disable_unprepare(mt->clk_auxadc);
+-
+-      return 0;
+ }
+ static struct platform_driver mtk_thermal_driver = {
+       .probe = mtk_thermal_probe,
+-      .remove = mtk_thermal_remove,
+       .driver = {
+               .name = "mtk-thermal",
+               .of_match_table = mtk_thermal_of_match,
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-24-thermal-drivers-mediatek-Use-of_address_to_resource.patch b/target/linux/mediatek/patches-6.6/830-v6.4-24-thermal-drivers-mediatek-Use-of_address_to_resource.patch
new file mode 100644 (file)
index 0000000..fd18a53
--- /dev/null
@@ -0,0 +1,36 @@
+From 655fe2533ac05323a07c19ba079bf2064e7741af Mon Sep 17 00:00:00 2001
+From: Rob Herring <robh@kernel.org>
+Date: Sun, 19 Mar 2023 11:32:31 -0500
+Subject: [PATCH 20/42] thermal/drivers/mediatek: Use of_address_to_resource()
+
+Replace of_get_address() and of_translate_address() calls with single
+call to of_address_to_resource().
+
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230319163231.226738-1-robh@kernel.org
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -979,14 +979,12 @@ static void mtk_thermal_init_bank(struct
+ static u64 of_get_phys_base(struct device_node *np)
+ {
+-      u64 size64;
+-      const __be32 *regaddr_p;
++      struct resource res;
+-      regaddr_p = of_get_address(np, 0, &size64, NULL);
+-      if (!regaddr_p)
++      if (of_address_to_resource(np, 0, &res))
+               return OF_BAD_ADDR;
+-      return of_translate_address(np, regaddr_p);
++      return res.start;
+ }
+ static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf)
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-25-Revert-thermal-drivers-mediatek-Use-devm_of_iomap-to.patch b/target/linux/mediatek/patches-6.6/830-v6.4-25-Revert-thermal-drivers-mediatek-Use-devm_of_iomap-to.patch
new file mode 100644 (file)
index 0000000..c3ff17d
--- /dev/null
@@ -0,0 +1,57 @@
+From 2c380d07215e6fce3ac66cc5af059bc2c2a69f7a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ricardo=20Ca=C3=B1uelo?= <ricardo.canuelo@collabora.com>
+Date: Thu, 25 May 2023 14:18:11 +0200
+Subject: [PATCH 21/42] Revert "thermal/drivers/mediatek: Use devm_of_iomap to
+ avoid resource leak in mtk_thermal_probe"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This reverts commit f05c7b7d9ea9477fcc388476c6f4ade8c66d2d26.
+
+That change was causing a regression in the generic-adc-thermal-probed
+bootrr test as reported in the kernelci-results list [1].
+A proper rework will take longer, so revert it for now.
+
+[1] https://groups.io/g/kernelci-results/message/42660
+
+Fixes: f05c7b7d9ea9 ("thermal/drivers/mediatek: Use devm_of_iomap to avoid resource leak in mtk_thermal_probe")
+Signed-off-by: Ricardo Cañuelo <ricardo.canuelo@collabora.com>
+Suggested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230525121811.3360268-1-ricardo.canuelo@collabora.com
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -1222,12 +1222,7 @@ static int mtk_thermal_probe(struct plat
+               return -ENODEV;
+       }
+-      auxadc_base = devm_of_iomap(&pdev->dev, auxadc, 0, NULL);
+-      if (IS_ERR(auxadc_base)) {
+-              of_node_put(auxadc);
+-              return PTR_ERR(auxadc_base);
+-      }
+-
++      auxadc_base = of_iomap(auxadc, 0);
+       auxadc_phys_base = of_get_phys_base(auxadc);
+       of_node_put(auxadc);
+@@ -1243,12 +1238,7 @@ static int mtk_thermal_probe(struct plat
+               return -ENODEV;
+       }
+-      apmixed_base = devm_of_iomap(&pdev->dev, apmixedsys, 0, NULL);
+-      if (IS_ERR(apmixed_base)) {
+-              of_node_put(apmixedsys);
+-              return PTR_ERR(apmixed_base);
+-      }
+-
++      apmixed_base = of_iomap(apmixedsys, 0);
+       apmixed_phys_base = of_get_phys_base(apmixedsys);
+       of_node_put(apmixedsys);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-26-thermal-drivers-mediatek-lvts_thermal-Register-therm.patch b/target/linux/mediatek/patches-6.6/830-v6.4-26-thermal-drivers-mediatek-lvts_thermal-Register-therm.patch
new file mode 100644 (file)
index 0000000..c445652
--- /dev/null
@@ -0,0 +1,37 @@
+From 496f4b08981d8a788ad5a2073fa1c65a2af1862b Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wenst@chromium.org>
+Date: Tue, 13 Jun 2023 17:13:16 +0800
+Subject: [PATCH 22/42] thermal/drivers/mediatek/lvts_thermal: Register thermal
+ zones as hwmon sensors
+
+Register thermal zones as hwmon sensors to let userspace read
+temperatures using standard hwmon interface.
+
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230613091317.1691247-1-wenst@chromium.org
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -19,6 +19,8 @@
+ #include <linux/thermal.h>
+ #include <dt-bindings/thermal/mediatek,lvts-thermal.h>
++#include "../thermal_hwmon.h"
++
+ #define LVTS_MONCTL0(__base)  (__base + 0x0000)
+ #define LVTS_MONCTL1(__base)  (__base + 0x0004)
+ #define LVTS_MONCTL2(__base)  (__base + 0x0008)
+@@ -996,6 +998,9 @@ static int lvts_ctrl_start(struct device
+                       return PTR_ERR(tz);
+               }
++              if (devm_thermal_add_hwmon_sysfs(dev, tz))
++                      dev_warn(dev, "zone %d: Failed to add hwmon sysfs attributes\n", dt_id);
++
+               /*
+                * The thermal zone pointer will be needed in the
+                * interrupt handler, we store it in the sensor
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-27-thermal-drivers-mediatek-lvts_thermal-Remove-redunda.patch b/target/linux/mediatek/patches-6.6/830-v6.4-27-thermal-drivers-mediatek-lvts_thermal-Remove-redunda.patch
new file mode 100644 (file)
index 0000000..22e7a95
--- /dev/null
@@ -0,0 +1,28 @@
+From 885b9768ce2a66ed5d250822aed53d5114c895da Mon Sep 17 00:00:00 2001
+From: Yangtao Li <frank.li@vivo.com>
+Date: Tue, 20 Jun 2023 17:07:31 +0800
+Subject: [PATCH 23/42] thermal/drivers/mediatek/lvts_thermal: Remove redundant
+ msg in lvts_ctrl_start()
+
+The upper-layer devm_thermal_add_hwmon_sysfs() function can directly
+print error information.
+
+Signed-off-by: Yangtao Li <frank.li@vivo.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230620090732.50025-10-frank.li@vivo.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -998,8 +998,7 @@ static int lvts_ctrl_start(struct device
+                       return PTR_ERR(tz);
+               }
+-              if (devm_thermal_add_hwmon_sysfs(dev, tz))
+-                      dev_warn(dev, "zone %d: Failed to add hwmon sysfs attributes\n", dt_id);
++              devm_thermal_add_hwmon_sysfs(dev, tz);
+               /*
+                * The thermal zone pointer will be needed in the
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-29-thermal-drivers-mediatek-lvts_thermal-Handle-IRQ-on-.patch b/target/linux/mediatek/patches-6.6/830-v6.4-29-thermal-drivers-mediatek-lvts_thermal-Handle-IRQ-on-.patch
new file mode 100644 (file)
index 0000000..bc67727
--- /dev/null
@@ -0,0 +1,40 @@
+From 27b389d9f62c2174f95fe4002b11e77d4cb3ce80 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
+ <nfraprado@collabora.com>
+Date: Thu, 6 Jul 2023 11:37:32 -0400
+Subject: [PATCH 25/42] thermal/drivers/mediatek/lvts_thermal: Handle IRQ on
+ all controllers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There is a single IRQ handler for each LVTS thermal domain, and it is
+supposed to check each of its underlying controllers for the origin of
+the interrupt and clear its status. However due to a typo, only the
+first controller was ever being handled, which resulted in the interrupt
+never being cleared when it happened on the other controllers. Add the
+missing index so interrupts are handled for all controllers.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-2-nfraprado@collabora.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -451,7 +451,7 @@ static irqreturn_t lvts_irq_handler(int
+       for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
+-              aux = lvts_ctrl_irq_handler(lvts_td->lvts_ctrl);
++              aux = lvts_ctrl_irq_handler(&lvts_td->lvts_ctrl[i]);
+               if (aux != IRQ_HANDLED)
+                       continue;
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-30-thermal-drivers-mediatek-lvts_thermal-Honor-sensors-.patch b/target/linux/mediatek/patches-6.6/830-v6.4-30-thermal-drivers-mediatek-lvts_thermal-Honor-sensors-.patch
new file mode 100644 (file)
index 0000000..51d119c
--- /dev/null
@@ -0,0 +1,120 @@
+From 6d827142643ee10c13ff9a1d90f38fb399aa9fff Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
+ <nfraprado@collabora.com>
+Date: Thu, 6 Jul 2023 11:37:33 -0400
+Subject: [PATCH 26/42] thermal/drivers/mediatek/lvts_thermal: Honor sensors in
+ immediate mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Each controller can be configured to operate on immediate or filtered
+mode. On filtered mode, the sensors are enabled by setting the
+corresponding bits in MONCTL0, while on immediate mode, by setting
+MSRCTL1.
+
+Previously, the code would set MSRCTL1 for all four sensors when
+configured to immediate mode, but given that the controller might not
+have all four sensors connected, this would cause interrupts to trigger
+for non-existent sensors. Fix this by handling the MSRCTL1 register
+analogously to the MONCTL0: only enable the sensors that were declared.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-3-nfraprado@collabora.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 57 ++++++++++++++-----------
+ 1 file changed, 33 insertions(+), 24 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -897,24 +897,6 @@ static int lvts_ctrl_configure(struct de
+       writel(value, LVTS_MSRCTL0(lvts_ctrl->base));
+       /*
+-       * LVTS_MSRCTL1 : Measurement control
+-       *
+-       * Bits:
+-       *
+-       * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
+-       * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
+-       * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
+-       * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
+-       *
+-       * That configuration will ignore the filtering and the delays
+-       * introduced below in MONCTL1 and MONCTL2
+-       */
+-      if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
+-              value = BIT(9) | BIT(6) | BIT(5) | BIT(4);
+-              writel(value, LVTS_MSRCTL1(lvts_ctrl->base));
+-      }
+-
+-      /*
+        * LVTS_MONCTL1 : Period unit and group interval configuration
+        *
+        * The clock source of LVTS thermal controller is 26MHz.
+@@ -979,6 +961,15 @@ static int lvts_ctrl_start(struct device
+       struct thermal_zone_device *tz;
+       u32 sensor_map = 0;
+       int i;
++      /*
++       * Bitmaps to enable each sensor on immediate and filtered modes, as
++       * described in MSRCTL1 and MONCTL0 registers below, respectively.
++       */
++      u32 sensor_imm_bitmap[] = { BIT(4), BIT(5), BIT(6), BIT(9) };
++      u32 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };
++
++      u32 *sensor_bitmap = lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE ?
++                           sensor_imm_bitmap : sensor_filt_bitmap;
+       for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++) {
+@@ -1016,20 +1007,38 @@ static int lvts_ctrl_start(struct device
+                * map, so we can enable the temperature monitoring in
+                * the hardware thermal controller.
+                */
+-              sensor_map |= BIT(i);
++              sensor_map |= sensor_bitmap[i];
+       }
+       /*
+-       * Bits:
+-       *      9: Single point access flow
+-       *    0-3: Enable sensing point 0-3
+-       *
+        * The initialization of the thermal zones give us
+        * which sensor point to enable. If any thermal zone
+        * was not described in the device tree, it won't be
+        * enabled here in the sensor map.
+        */
+-      writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
++      if (lvts_ctrl->mode == LVTS_MSR_IMMEDIATE_MODE) {
++              /*
++               * LVTS_MSRCTL1 : Measurement control
++               *
++               * Bits:
++               *
++               * 9: Ignore MSRCTL0 config and do immediate measurement on sensor3
++               * 6: Ignore MSRCTL0 config and do immediate measurement on sensor2
++               * 5: Ignore MSRCTL0 config and do immediate measurement on sensor1
++               * 4: Ignore MSRCTL0 config and do immediate measurement on sensor0
++               *
++               * That configuration will ignore the filtering and the delays
++               * introduced in MONCTL1 and MONCTL2
++               */
++              writel(sensor_map, LVTS_MSRCTL1(lvts_ctrl->base));
++      } else {
++              /*
++               * Bits:
++               *      9: Single point access flow
++               *    0-3: Enable sensing point 0-3
++               */
++              writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
++      }
+       return 0;
+ }
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-31-thermal-drivers-mediatek-lvts_thermal-Use-offset-thr.patch b/target/linux/mediatek/patches-6.6/830-v6.4-31-thermal-drivers-mediatek-lvts_thermal-Use-offset-thr.patch
new file mode 100644 (file)
index 0000000..bfbadee
--- /dev/null
@@ -0,0 +1,77 @@
+From 93bb11dd19bdcc1fc97c7ceababd0db9fde128ad Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
+ <nfraprado@collabora.com>
+Date: Thu, 6 Jul 2023 11:37:34 -0400
+Subject: [PATCH 27/42] thermal/drivers/mediatek/lvts_thermal: Use offset
+ threshold for IRQ
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are two kinds of temperature monitoring interrupts available:
+* High Offset, Low Offset
+* Hot, Hot to normal, Cold
+
+The code currently uses the hot/h2n/cold interrupts, however in a way
+that doesn't work: the cold threshold is left uninitialized, which
+prevents the other thresholds from ever triggering, and the h2n
+interrupt is used as the lower threshold, which prevents the hot
+interrupt from triggering again after the thresholds are updated by the
+thermal framework, since a hot interrupt can only trigger again after
+the hot to normal interrupt has been triggered.
+
+But better yet than addressing those issues, is to use the high/low
+offset interrupts instead. This way only two thresholds need to be
+managed, which have a simpler state machine, making them a better match
+to the thermal framework's high and low thresholds.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-4-nfraprado@collabora.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -298,9 +298,9 @@ static int lvts_set_trips(struct thermal
+       u32 raw_high = lvts_temp_to_raw(high);
+       /*
+-       * Hot to normal temperature threshold
++       * Low offset temperature threshold
+        *
+-       * LVTS_H2NTHRE
++       * LVTS_OFFSETL
+        *
+        * Bits:
+        *
+@@ -309,13 +309,13 @@ static int lvts_set_trips(struct thermal
+       if (low != -INT_MAX) {
+               pr_debug("%s: Setting low limit temperature interrupt: %d\n",
+                        thermal_zone_device_type(tz), low);
+-              writel(raw_low, LVTS_H2NTHRE(base));
++              writel(raw_low, LVTS_OFFSETL(base));
+       }
+       /*
+-       * Hot temperature threshold
++       * High offset temperature threshold
+        *
+-       * LVTS_HTHRE
++       * LVTS_OFFSETH
+        *
+        * Bits:
+        *
+@@ -323,7 +323,7 @@ static int lvts_set_trips(struct thermal
+        */
+       pr_debug("%s: Setting high limit temperature interrupt: %d\n",
+                thermal_zone_device_type(tz), high);
+-      writel(raw_high, LVTS_HTHRE(base));
++      writel(raw_high, LVTS_OFFSETH(base));
+       return 0;
+ }
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-32-thermal-drivers-mediatek-lvts_thermal-Disable-undesi.patch b/target/linux/mediatek/patches-6.6/830-v6.4-32-thermal-drivers-mediatek-lvts_thermal-Disable-undesi.patch
new file mode 100644 (file)
index 0000000..1c35d0a
--- /dev/null
@@ -0,0 +1,51 @@
+From 8f8cab9d3e90acf1db278ef44ad05f10aefb973f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
+ <nfraprado@collabora.com>
+Date: Thu, 6 Jul 2023 11:37:35 -0400
+Subject: [PATCH 28/42] thermal/drivers/mediatek/lvts_thermal: Disable
+ undesired interrupts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Out of the many interrupts supported by the hardware, the only ones of
+interest to the driver currently are:
+* The temperature went over the high offset threshold, for any of the
+  sensors
+* The temperature went below the low offset threshold, for any of the
+  sensors
+* The temperature went over the stage3 threshold
+
+These are the only thresholds configured by the driver through the
+OFFSETH, OFFSETL, and PROTTC registers, respectively.
+
+The current interrupt mask in LVTS_MONINT_CONF, enables many more
+interrupts, including data ready on sensors for both filtered and
+immediate mode. These are not only not handled by the driver, but they
+are also triggered too often, causing unneeded overhead. Disable these
+unnecessary interrupts.
+
+The meaning of each bit can be seen in the comment describing
+LVTS_MONINTST in the IRQ handler.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-5-nfraprado@collabora.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -65,7 +65,7 @@
+ #define LVTS_HW_FILTER                                0x2
+ #define LVTS_TSSEL_CONF                               0x13121110
+ #define LVTS_CALSCALE_CONF                    0x300
+-#define LVTS_MONINT_CONF                      0x9FBF7BDE
++#define LVTS_MONINT_CONF                      0x8300318C
+ #define LVTS_INT_SENSOR0                      0x0009001F
+ #define LVTS_INT_SENSOR1                      0x001203E0
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-33-thermal-drivers-mediatek-lvts_thermal-Don-t-leave-th.patch b/target/linux/mediatek/patches-6.6/830-v6.4-33-thermal-drivers-mediatek-lvts_thermal-Don-t-leave-th.patch
new file mode 100644 (file)
index 0000000..60942fd
--- /dev/null
@@ -0,0 +1,70 @@
+From bd1ccf9408e6155564530af5e09b53ae497fe332 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
+ <nfraprado@collabora.com>
+Date: Thu, 6 Jul 2023 11:37:36 -0400
+Subject: [PATCH 29/42] thermal/drivers/mediatek/lvts_thermal: Don't leave
+ threshold zeroed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The thermal framework might leave the low threshold unset if there
+aren't any lower trip points. This leaves the register zeroed, which
+translates to a very high temperature for the low threshold. The
+interrupt for this threshold is then immediately triggered, and the
+state machine gets stuck, preventing any other temperature monitoring
+interrupts to ever trigger.
+
+(The same happens by not setting the Cold or Hot to Normal thresholds
+when using those)
+
+Set the unused threshold to a valid low value. This value was chosen so
+that for any valid golden temperature read from the efuse, when the
+value is converted to raw and back again to milliCelsius, the result
+doesn't underflow.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-6-nfraprado@collabora.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -83,6 +83,8 @@
+ #define LVTS_HW_SHUTDOWN_MT8195               105000
++#define LVTS_MINIMUM_THRESHOLD                20000
++
+ static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
+ static int coeff_b = LVTS_COEFF_B;
+@@ -294,7 +296,7 @@ static int lvts_set_trips(struct thermal
+ {
+       struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
+       void __iomem *base = lvts_sensor->base;
+-      u32 raw_low = lvts_temp_to_raw(low);
++      u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
+       u32 raw_high = lvts_temp_to_raw(high);
+       /*
+@@ -306,11 +308,9 @@ static int lvts_set_trips(struct thermal
+        *
+        * 14-0 : Raw temperature for threshold
+        */
+-      if (low != -INT_MAX) {
+-              pr_debug("%s: Setting low limit temperature interrupt: %d\n",
+-                       thermal_zone_device_type(tz), low);
+-              writel(raw_low, LVTS_OFFSETL(base));
+-      }
++      pr_debug("%s: Setting low limit temperature interrupt: %d\n",
++               thermal_zone_device_type(tz), low);
++      writel(raw_low, LVTS_OFFSETL(base));
+       /*
+        * High offset temperature threshold
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-34-thermal-drivers-mediatek-lvts_thermal-Manage-thresho.patch b/target/linux/mediatek/patches-6.6/830-v6.4-34-thermal-drivers-mediatek-lvts_thermal-Manage-thresho.patch
new file mode 100644 (file)
index 0000000..e99aa0c
--- /dev/null
@@ -0,0 +1,156 @@
+From d4dd09968cab3249e6148e1c3fccb51824edb411 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
+ <nfraprado@collabora.com>
+Date: Thu, 6 Jul 2023 11:37:37 -0400
+Subject: [PATCH 30/42] thermal/drivers/mediatek/lvts_thermal: Manage threshold
+ between sensors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Each LVTS thermal controller can have up to four sensors, each capable
+of triggering its own interrupt when its measured temperature crosses
+the configured threshold. The threshold for each sensor is handled
+separately by the thermal framework, since each one is registered with
+its own thermal zone and trips. However, the temperature thresholds are
+configured on the controller, and therefore are shared between all
+sensors on that controller.
+
+When the temperature measured by the sensors is different enough to
+cause the thermal framework to configure different thresholds for each
+one, interrupts start triggering on sensors outside the last threshold
+configured.
+
+To address the issue, track the thresholds required by each sensor and
+only actually set the highest one in the hardware, and disable
+interrupts for all sensors outside the current configured range.
+
+Fixes: f5f633b18234 ("thermal/drivers/mediatek: Add the Low Voltage Thermal Sensor driver")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230706153823.201943-7-nfraprado@collabora.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 69 +++++++++++++++++++++++++
+ 1 file changed, 69 insertions(+)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -67,6 +67,11 @@
+ #define LVTS_CALSCALE_CONF                    0x300
+ #define LVTS_MONINT_CONF                      0x8300318C
++#define LVTS_MONINT_OFFSET_SENSOR0            0xC
++#define LVTS_MONINT_OFFSET_SENSOR1            0x180
++#define LVTS_MONINT_OFFSET_SENSOR2            0x3000
++#define LVTS_MONINT_OFFSET_SENSOR3            0x3000000
++
+ #define LVTS_INT_SENSOR0                      0x0009001F
+ #define LVTS_INT_SENSOR1                      0x001203E0
+ #define LVTS_INT_SENSOR2                      0x00247C00
+@@ -112,6 +117,8 @@ struct lvts_sensor {
+       void __iomem *base;
+       int id;
+       int dt_id;
++      int low_thresh;
++      int high_thresh;
+ };
+ struct lvts_ctrl {
+@@ -121,6 +128,8 @@ struct lvts_ctrl {
+       int num_lvts_sensor;
+       int mode;
+       void __iomem *base;
++      int low_thresh;
++      int high_thresh;
+ };
+ struct lvts_domain {
+@@ -292,12 +301,66 @@ static int lvts_get_temp(struct thermal_
+       return 0;
+ }
++static void lvts_update_irq_mask(struct lvts_ctrl *lvts_ctrl)
++{
++      u32 masks[] = {
++              LVTS_MONINT_OFFSET_SENSOR0,
++              LVTS_MONINT_OFFSET_SENSOR1,
++              LVTS_MONINT_OFFSET_SENSOR2,
++              LVTS_MONINT_OFFSET_SENSOR3,
++      };
++      u32 value = 0;
++      int i;
++
++      value = readl(LVTS_MONINT(lvts_ctrl->base));
++
++      for (i = 0; i < ARRAY_SIZE(masks); i++) {
++              if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
++                  && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
++                      value |= masks[i];
++              else
++                      value &= ~masks[i];
++      }
++
++      writel(value, LVTS_MONINT(lvts_ctrl->base));
++}
++
++static bool lvts_should_update_thresh(struct lvts_ctrl *lvts_ctrl, int high)
++{
++      int i;
++
++      if (high > lvts_ctrl->high_thresh)
++              return true;
++
++      for (i = 0; i < lvts_ctrl->num_lvts_sensor; i++)
++              if (lvts_ctrl->sensors[i].high_thresh == lvts_ctrl->high_thresh
++                  && lvts_ctrl->sensors[i].low_thresh == lvts_ctrl->low_thresh)
++                      return false;
++
++      return true;
++}
++
+ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ {
+       struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
++      struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl, sensors[lvts_sensor->id]);
+       void __iomem *base = lvts_sensor->base;
+       u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
+       u32 raw_high = lvts_temp_to_raw(high);
++      bool should_update_thresh;
++
++      lvts_sensor->low_thresh = low;
++      lvts_sensor->high_thresh = high;
++
++      should_update_thresh = lvts_should_update_thresh(lvts_ctrl, high);
++      if (should_update_thresh) {
++              lvts_ctrl->high_thresh = high;
++              lvts_ctrl->low_thresh = low;
++      }
++      lvts_update_irq_mask(lvts_ctrl);
++
++      if (!should_update_thresh)
++              return 0;
+       /*
+        * Low offset temperature threshold
+@@ -521,6 +584,9 @@ static int lvts_sensor_init(struct devic
+                */
+               lvts_sensor[i].msr = lvts_ctrl_data->mode == LVTS_MSR_IMMEDIATE_MODE ?
+                       imm_regs[i] : msr_regs[i];
++
++              lvts_sensor[i].low_thresh = INT_MIN;
++              lvts_sensor[i].high_thresh = INT_MIN;
+       };
+       lvts_ctrl->num_lvts_sensor = lvts_ctrl_data->num_lvts_sensor;
+@@ -688,6 +754,9 @@ static int lvts_ctrl_init(struct device
+                */
+               lvts_ctrl[i].hw_tshut_raw_temp =
+                       lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
++
++              lvts_ctrl[i].low_thresh = INT_MIN;
++              lvts_ctrl[i].high_thresh = INT_MIN;
+       }
+       /*
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-35-thermal-drivers-mediatek-lvts-Fix-parameter-check-in.patch b/target/linux/mediatek/patches-6.6/830-v6.4-35-thermal-drivers-mediatek-lvts-Fix-parameter-check-in.patch
new file mode 100644 (file)
index 0000000..9ce3eeb
--- /dev/null
@@ -0,0 +1,29 @@
+From 5af4904adc8b840987000724977c13c706d3b7d8 Mon Sep 17 00:00:00 2001
+From: Minjie Du <duminjie@vivo.com>
+Date: Thu, 13 Jul 2023 12:24:12 +0800
+Subject: [PATCH 31/42] thermal/drivers/mediatek/lvts: Fix parameter check in
+ lvts_debugfs_init()
+
+The documentation says "If an error occurs, ERR_PTR(-ERROR) will be
+returned" but the current code checks against a NULL pointer returned.
+
+Fix this by checking if IS_ERR().
+
+Signed-off-by: Minjie Du <duminjie@vivo.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230713042413.2519-1-duminjie@vivo.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -201,7 +201,7 @@ static int lvts_debugfs_init(struct devi
+       int i;
+       lvts_td->dom_dentry = debugfs_create_dir(dev_name(dev), NULL);
+-      if (!lvts_td->dom_dentry)
++      if (IS_ERR(lvts_td->dom_dentry))
+               return 0;
+       for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-36-thermal-drivers-mediatek-Clean-up-redundant-dev_err_.patch b/target/linux/mediatek/patches-6.6/830-v6.4-36-thermal-drivers-mediatek-Clean-up-redundant-dev_err_.patch
new file mode 100644 (file)
index 0000000..4841054
--- /dev/null
@@ -0,0 +1,33 @@
+From 6186be80317d1dbda34d35c06c084a083938f2d3 Mon Sep 17 00:00:00 2001
+From: Chen Jiahao <chenjiahao16@huawei.com>
+Date: Wed, 2 Aug 2023 17:45:27 +0800
+Subject: [PATCH 32/42] thermal/drivers/mediatek: Clean up redundant
+ dev_err_probe()
+
+Referring to platform_get_irq()'s definition, the return value has
+already been checked if ret < 0, and printed via dev_err_probe().
+Calling dev_err_probe() one more time outside platform_get_irq()
+is obviously redundant.
+
+Removing dev_err_probe() outside platform_get_irq() to clean up
+above problem.
+
+Signed-off-by: Chen Jiahao <chenjiahao16@huawei.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230802094527.988842-1-chenjiahao16@huawei.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -1216,7 +1216,7 @@ static int lvts_probe(struct platform_de
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+-              return dev_err_probe(dev, irq, "No irq resource\n");
++              return irq;
+       ret = lvts_domain_init(dev, lvts_td, lvts_data);
+       if (ret)
diff --git a/target/linux/mediatek/patches-6.6/830-v6.4-37-thermal-drivers-mediatek-lvts_thermal-Make-readings-.patch b/target/linux/mediatek/patches-6.6/830-v6.4-37-thermal-drivers-mediatek-lvts_thermal-Make-readings-.patch
new file mode 100644 (file)
index 0000000..c88bf98
--- /dev/null
@@ -0,0 +1,95 @@
+From c2ab54ab0425388e65901a7af2fbf69ead968708 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
+ <nfraprado@collabora.com>
+Date: Thu, 13 Jul 2023 11:42:37 -0400
+Subject: [PATCH 33/42] thermal/drivers/mediatek/lvts_thermal: Make readings
+ valid in filtered mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently, when a controller is configured to use filtered mode, thermal
+readings are valid only about 30% of the time.
+
+Upon testing, it was noticed that lowering any of the interval settings
+resulted in an improved rate of valid data. The same was observed when
+decreasing the number of samples for each sensor (which also results in
+quicker measurements).
+
+Retrying the read with a timeout longer than the time it takes to
+resample (about 344us with these settings and 4 sensors) also improves
+the rate.
+
+Lower all timing settings to the minimum, configure the filtering to
+single sample, and poll the measurement register for at least one period
+to improve the data validity on filtered mode.  With these changes in
+place, out of 100000 reads, a single one failed, ie 99.999% of the data
+was valid.
+
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230713154743.611870-1-nfraprado@collabora.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -58,11 +58,11 @@
+ #define LVTS_PROTTC(__base)           (__base + 0x00CC)
+ #define LVTS_CLKEN(__base)            (__base + 0x00E4)
+-#define LVTS_PERIOD_UNIT                      ((118 * 1000) / (256 * 38))
+-#define LVTS_GROUP_INTERVAL                   1
+-#define LVTS_FILTER_INTERVAL          1
+-#define LVTS_SENSOR_INTERVAL          1
+-#define LVTS_HW_FILTER                                0x2
++#define LVTS_PERIOD_UNIT                      0
++#define LVTS_GROUP_INTERVAL                   0
++#define LVTS_FILTER_INTERVAL          0
++#define LVTS_SENSOR_INTERVAL          0
++#define LVTS_HW_FILTER                                0x0
+ #define LVTS_TSSEL_CONF                               0x13121110
+ #define LVTS_CALSCALE_CONF                    0x300
+ #define LVTS_MONINT_CONF                      0x8300318C
+@@ -86,6 +86,9 @@
+ #define LVTS_MSR_IMMEDIATE_MODE               0
+ #define LVTS_MSR_FILTERED_MODE                1
++#define LVTS_MSR_READ_TIMEOUT_US      400
++#define LVTS_MSR_READ_WAIT_US         (LVTS_MSR_READ_TIMEOUT_US / 2)
++
+ #define LVTS_HW_SHUTDOWN_MT8195               105000
+ #define LVTS_MINIMUM_THRESHOLD                20000
+@@ -268,6 +271,7 @@ static int lvts_get_temp(struct thermal_
+       struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
+       void __iomem *msr = lvts_sensor->msr;
+       u32 value;
++      int rc;
+       /*
+        * Measurement registers:
+@@ -280,7 +284,8 @@ static int lvts_get_temp(struct thermal_
+        * 16   : Valid temperature
+        * 15-0 : Raw temperature
+        */
+-      value = readl(msr);
++      rc = readl_poll_timeout(msr, value, value & BIT(16),
++                              LVTS_MSR_READ_WAIT_US, LVTS_MSR_READ_TIMEOUT_US);
+       /*
+        * As the thermal zone temperature will read before the
+@@ -293,7 +298,7 @@ static int lvts_get_temp(struct thermal_
+        * functionning temperature and directly jump to a system
+        * shutdown.
+        */
+-      if (!(value & BIT(16)))
++      if (rc)
+               return -EAGAIN;
+       *temp = lvts_raw_to_temp(value & 0xFFFF);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.6-38-thermal-drivers-mediatek-auxadc_thermal-Removed-call.patch b/target/linux/mediatek/patches-6.6/830-v6.6-38-thermal-drivers-mediatek-auxadc_thermal-Removed-call.patch
new file mode 100644 (file)
index 0000000..994461c
--- /dev/null
@@ -0,0 +1,30 @@
+From c864ff9de3b225b43bb8e08dedb223632323e059 Mon Sep 17 00:00:00 2001
+From: Andrei Coardos <aboutphysycs@gmail.com>
+Date: Fri, 11 Aug 2023 22:28:47 +0300
+Subject: [PATCH 34/42] thermal/drivers/mediatek/auxadc_thermal: Removed call
+ to platform_set_drvdata()
+
+This function call was found to be unnecessary as there is no equivalent
+platform_get_drvdata() call to access the private data of the driver. Also,
+the private data is defined in this driver, so there is no risk of it being
+accessed outside of this driver file.
+
+Signed-off-by: Andrei Coardos <aboutphysycs@gmail.com>
+Reviewed-by: Alexandru Ardelean <alex@shruggie.ro>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230811192847.3838-1-aboutphysycs@gmail.com
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -1283,8 +1283,6 @@ static int mtk_thermal_probe(struct plat
+                       mtk_thermal_init_bank(mt, i, apmixed_phys_base,
+                                             auxadc_phys_base, ctrl_id);
+-      platform_set_drvdata(pdev, mt);
+-
+       tzdev = devm_thermal_of_zone_register(&pdev->dev, 0, mt,
+                                             &mtk_thermal_ops);
+       if (IS_ERR(tzdev))
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch b/target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch
new file mode 100644 (file)
index 0000000..b3bfa37
--- /dev/null
@@ -0,0 +1,58 @@
+From 6cf96078969ec00b873db99bae4e47001290685e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Wed, 27 Sep 2023 21:37:23 +0200
+Subject: [PATCH 35/42] thermal: lvts: Convert to platform remove callback
+ returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -1241,7 +1241,7 @@ static int lvts_probe(struct platform_de
+       return 0;
+ }
+-static int lvts_remove(struct platform_device *pdev)
++static void lvts_remove(struct platform_device *pdev)
+ {
+       struct lvts_domain *lvts_td;
+       int i;
+@@ -1252,8 +1252,6 @@ static int lvts_remove(struct platform_d
+               lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
+       lvts_debugfs_exit(lvts_td);
+-
+-      return 0;
+ }
+ static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
+@@ -1354,7 +1352,7 @@ MODULE_DEVICE_TABLE(of, lvts_of_match);
+ static struct platform_driver lvts_driver = {
+       .probe = lvts_probe,
+-      .remove = lvts_remove,
++      .remove_new = lvts_remove,
+       .driver = {
+               .name = "mtk-lvts-thermal",
+               .of_match_table = lvts_of_match,
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch b/target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch
new file mode 100644 (file)
index 0000000..16a32f5
--- /dev/null
@@ -0,0 +1,198 @@
+From 26cc18a3d6d9eac21c4f4b4bb96147b2c6617c86 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 22 Sep 2023 07:50:19 +0200
+Subject: [PATCH 36/42] thermal/drivers/mediatek/lvts_thermal: Make coeff
+ configurable
+
+The upcoming mt7988 has different temperature coefficients so we
+cannot use constants in the functions lvts_golden_temp_init,
+lvts_golden_temp_init and lvts_raw_to_temp anymore.
+
+Add a field in the lvts_ctrl pointing to the lvts_data which now
+contains the soc-specific temperature coefficents.
+
+To make the code better readable, rename static int coeff_b to
+golden_temp_offset, COEFF_A to temp_factor and COEFF_B to temp_offset.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230922055020.6436-4-linux@fw-web.de
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 51 ++++++++++++++++---------
+ 1 file changed, 34 insertions(+), 17 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -80,8 +80,8 @@
+ #define LVTS_SENSOR_MAX                               4
+ #define LVTS_GOLDEN_TEMP_MAX          62
+ #define LVTS_GOLDEN_TEMP_DEFAULT      50
+-#define LVTS_COEFF_A                          -250460
+-#define LVTS_COEFF_B                          250460
++#define LVTS_COEFF_A_MT8195                   -250460
++#define LVTS_COEFF_B_MT8195                   250460
+ #define LVTS_MSR_IMMEDIATE_MODE               0
+ #define LVTS_MSR_FILTERED_MODE                1
+@@ -94,7 +94,7 @@
+ #define LVTS_MINIMUM_THRESHOLD                20000
+ static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
+-static int coeff_b = LVTS_COEFF_B;
++static int golden_temp_offset;
+ struct lvts_sensor_data {
+       int dt_id;
+@@ -112,6 +112,8 @@ struct lvts_ctrl_data {
+ struct lvts_data {
+       const struct lvts_ctrl_data *lvts_ctrl;
+       int num_lvts_ctrl;
++      int temp_factor;
++      int temp_offset;
+ };
+ struct lvts_sensor {
+@@ -126,6 +128,7 @@ struct lvts_sensor {
+ struct lvts_ctrl {
+       struct lvts_sensor sensors[LVTS_SENSOR_MAX];
++      const struct lvts_data *lvts_data;
+       u32 calibration[LVTS_SENSOR_MAX];
+       u32 hw_tshut_raw_temp;
+       int num_lvts_sensor;
+@@ -247,21 +250,21 @@ static void lvts_debugfs_exit(struct lvt
+ #endif
+-static int lvts_raw_to_temp(u32 raw_temp)
++static int lvts_raw_to_temp(u32 raw_temp, int temp_factor)
+ {
+       int temperature;
+-      temperature = ((s64)(raw_temp & 0xFFFF) * LVTS_COEFF_A) >> 14;
+-      temperature += coeff_b;
++      temperature = ((s64)(raw_temp & 0xFFFF) * temp_factor) >> 14;
++      temperature += golden_temp_offset;
+       return temperature;
+ }
+-static u32 lvts_temp_to_raw(int temperature)
++static u32 lvts_temp_to_raw(int temperature, int temp_factor)
+ {
+-      u32 raw_temp = ((s64)(coeff_b - temperature)) << 14;
++      u32 raw_temp = ((s64)(golden_temp_offset - temperature)) << 14;
+-      raw_temp = div_s64(raw_temp, -LVTS_COEFF_A);
++      raw_temp = div_s64(raw_temp, -temp_factor);
+       return raw_temp;
+ }
+@@ -269,6 +272,9 @@ static u32 lvts_temp_to_raw(int temperat
+ static int lvts_get_temp(struct thermal_zone_device *tz, int *temp)
+ {
+       struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
++      struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
++                                                 sensors[lvts_sensor->id]);
++      const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
+       void __iomem *msr = lvts_sensor->msr;
+       u32 value;
+       int rc;
+@@ -301,7 +307,7 @@ static int lvts_get_temp(struct thermal_
+       if (rc)
+               return -EAGAIN;
+-      *temp = lvts_raw_to_temp(value & 0xFFFF);
++      *temp = lvts_raw_to_temp(value & 0xFFFF, lvts_data->temp_factor);
+       return 0;
+ }
+@@ -348,10 +354,13 @@ static bool lvts_should_update_thresh(st
+ static int lvts_set_trips(struct thermal_zone_device *tz, int low, int high)
+ {
+       struct lvts_sensor *lvts_sensor = thermal_zone_device_priv(tz);
+-      struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl, sensors[lvts_sensor->id]);
++      struct lvts_ctrl *lvts_ctrl = container_of(lvts_sensor, struct lvts_ctrl,
++                                                 sensors[lvts_sensor->id]);
++      const struct lvts_data *lvts_data = lvts_ctrl->lvts_data;
+       void __iomem *base = lvts_sensor->base;
+-      u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD);
+-      u32 raw_high = lvts_temp_to_raw(high);
++      u32 raw_low = lvts_temp_to_raw(low != -INT_MAX ? low : LVTS_MINIMUM_THRESHOLD,
++                                     lvts_data->temp_factor);
++      u32 raw_high = lvts_temp_to_raw(high, lvts_data->temp_factor);
+       bool should_update_thresh;
+       lvts_sensor->low_thresh = low;
+@@ -692,7 +701,7 @@ static int lvts_calibration_read(struct
+       return 0;
+ }
+-static int lvts_golden_temp_init(struct device *dev, u32 *value)
++static int lvts_golden_temp_init(struct device *dev, u32 *value, int temp_offset)
+ {
+       u32 gt;
+@@ -701,7 +710,7 @@ static int lvts_golden_temp_init(struct
+       if (gt && gt < LVTS_GOLDEN_TEMP_MAX)
+               golden_temp = gt;
+-      coeff_b = golden_temp * 500 + LVTS_COEFF_B;
++      golden_temp_offset = golden_temp * 500 + temp_offset;
+       return 0;
+ }
+@@ -724,7 +733,7 @@ static int lvts_ctrl_init(struct device
+        * The golden temp information is contained in the first chunk
+        * of efuse data.
+        */
+-      ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib);
++      ret = lvts_golden_temp_init(dev, (u32 *)lvts_td->calib, lvts_data->temp_offset);
+       if (ret)
+               return ret;
+@@ -735,6 +744,7 @@ static int lvts_ctrl_init(struct device
+       for (i = 0; i < lvts_data->num_lvts_ctrl; i++) {
+               lvts_ctrl[i].base = lvts_td->base + lvts_data->lvts_ctrl[i].offset;
++              lvts_ctrl[i].lvts_data = lvts_data;
+               ret = lvts_sensor_init(dev, &lvts_ctrl[i],
+                                      &lvts_data->lvts_ctrl[i]);
+@@ -758,7 +768,8 @@ static int lvts_ctrl_init(struct device
+                * after initializing the calibration.
+                */
+               lvts_ctrl[i].hw_tshut_raw_temp =
+-                      lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp);
++                      lvts_temp_to_raw(lvts_data->lvts_ctrl[i].hw_tshut_temp,
++                                       lvts_data->temp_factor);
+               lvts_ctrl[i].low_thresh = INT_MIN;
+               lvts_ctrl[i].high_thresh = INT_MIN;
+@@ -1223,6 +1234,8 @@ static int lvts_probe(struct platform_de
+       if (irq < 0)
+               return irq;
++      golden_temp_offset = lvts_data->temp_offset;
++
+       ret = lvts_domain_init(dev, lvts_td, lvts_data);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to initialize the lvts domain\n");
+@@ -1336,11 +1349,15 @@ static const struct lvts_ctrl_data mt819
+ static const struct lvts_data mt8195_lvts_mcu_data = {
+       .lvts_ctrl      = mt8195_lvts_mcu_data_ctrl,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
++      .temp_factor    = LVTS_COEFF_A_MT8195,
++      .temp_offset    = LVTS_COEFF_B_MT8195,
+ };
+ static const struct lvts_data mt8195_lvts_ap_data = {
+       .lvts_ctrl      = mt8195_lvts_ap_data_ctrl,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_ap_data_ctrl),
++      .temp_factor    = LVTS_COEFF_A_MT8195,
++      .temp_offset    = LVTS_COEFF_B_MT8195,
+ };
+ static const struct of_device_id lvts_of_match[] = {
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-41-dt-bindings-thermal-mediatek-Add-LVTS-thermal-sensor.patch b/target/linux/mediatek/patches-6.6/830-v6.7-41-dt-bindings-thermal-mediatek-Add-LVTS-thermal-sensor.patch
new file mode 100644 (file)
index 0000000..1c2146f
--- /dev/null
@@ -0,0 +1,35 @@
+From be2cc09bd5b46f13629d4fcdeac7ad1b18bb1a0b Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 22 Sep 2023 07:50:18 +0200
+Subject: [PATCH] dt-bindings: thermal: mediatek: Add LVTS thermal sensors for
+ mt7988
+
+Add sensor constants for MT7988.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230922055020.6436-3-linux@fw-web.de
+---
+ include/dt-bindings/thermal/mediatek,lvts-thermal.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h
++++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
+@@ -7,6 +7,15 @@
+ #ifndef __MEDIATEK_LVTS_DT_H
+ #define __MEDIATEK_LVTS_DT_H
++#define MT7988_CPU_0          0
++#define MT7988_CPU_1          1
++#define MT7988_ETH2P5G_0      2
++#define MT7988_ETH2P5G_1      3
++#define MT7988_TOPS_0         4
++#define MT7988_TOPS_1         5
++#define MT7988_ETHWARP_0      6
++#define MT7988_ETHWARP_1      7
++
+ #define MT8195_MCU_BIG_CPU0     0
+ #define MT8195_MCU_BIG_CPU1     1
+ #define MT8195_MCU_BIG_CPU2     2
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch b/target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch
new file mode 100644 (file)
index 0000000..97c803a
--- /dev/null
@@ -0,0 +1,91 @@
+From 9924e9b91b43aaa1610a1d59c4caa43785948cf6 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 22 Sep 2023 07:50:20 +0200
+Subject: [PATCH 37/42] thermal/drivers/mediatek/lvts_thermal: Add mt7988
+ support
+
+Add Support for Mediatek Filogic 880/MT7988 LVTS.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230922055020.6436-5-linux@fw-web.de
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 38 +++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -82,6 +82,8 @@
+ #define LVTS_GOLDEN_TEMP_DEFAULT      50
+ #define LVTS_COEFF_A_MT8195                   -250460
+ #define LVTS_COEFF_B_MT8195                   250460
++#define LVTS_COEFF_A_MT7988                   -204650
++#define LVTS_COEFF_B_MT7988                   204650
+ #define LVTS_MSR_IMMEDIATE_MODE               0
+ #define LVTS_MSR_FILTERED_MODE                1
+@@ -89,6 +91,7 @@
+ #define LVTS_MSR_READ_TIMEOUT_US      400
+ #define LVTS_MSR_READ_WAIT_US         (LVTS_MSR_READ_TIMEOUT_US / 2)
++#define LVTS_HW_SHUTDOWN_MT7988               105000
+ #define LVTS_HW_SHUTDOWN_MT8195               105000
+ #define LVTS_MINIMUM_THRESHOLD                20000
+@@ -1267,6 +1270,33 @@ static void lvts_remove(struct platform_
+       lvts_debugfs_exit(lvts_td);
+ }
++static const struct lvts_ctrl_data mt7988_lvts_ap_data_ctrl[] = {
++      {
++              .cal_offset = { 0x00, 0x04, 0x08, 0x0c },
++              .lvts_sensor = {
++                      { .dt_id = MT7988_CPU_0 },
++                      { .dt_id = MT7988_CPU_1 },
++                      { .dt_id = MT7988_ETH2P5G_0 },
++                      { .dt_id = MT7988_ETH2P5G_1 }
++              },
++              .num_lvts_sensor = 4,
++              .offset = 0x0,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT7988,
++      },
++      {
++              .cal_offset = { 0x14, 0x18, 0x1c, 0x20 },
++              .lvts_sensor = {
++                      { .dt_id = MT7988_TOPS_0},
++                      { .dt_id = MT7988_TOPS_1},
++                      { .dt_id = MT7988_ETHWARP_0},
++                      { .dt_id = MT7988_ETHWARP_1}
++              },
++              .num_lvts_sensor = 4,
++              .offset = 0x100,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT7988,
++      }
++};
++
+ static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
+       {
+               .cal_offset = { 0x04, 0x07 },
+@@ -1346,6 +1376,13 @@ static const struct lvts_ctrl_data mt819
+       }
+ };
++static const struct lvts_data mt7988_lvts_ap_data = {
++      .lvts_ctrl      = mt7988_lvts_ap_data_ctrl,
++      .num_lvts_ctrl  = ARRAY_SIZE(mt7988_lvts_ap_data_ctrl),
++      .temp_factor    = LVTS_COEFF_A_MT7988,
++      .temp_offset    = LVTS_COEFF_B_MT7988,
++};
++
+ static const struct lvts_data mt8195_lvts_mcu_data = {
+       .lvts_ctrl      = mt8195_lvts_mcu_data_ctrl,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
+@@ -1361,6 +1398,7 @@ static const struct lvts_data mt8195_lvt
+ };
+ static const struct of_device_id lvts_of_match[] = {
++      { .compatible = "mediatek,mt7988-lvts-ap", .data = &mt7988_lvts_ap_data },
+       { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
+       { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data },
+       {},
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-43-thermal-drivers-mediatek-lvts_thermal-Fix-error-chec.patch b/target/linux/mediatek/patches-6.6/830-v6.7-43-thermal-drivers-mediatek-lvts_thermal-Fix-error-chec.patch
new file mode 100644 (file)
index 0000000..5b212a2
--- /dev/null
@@ -0,0 +1,30 @@
+From fb1bbb5b63e4e3c788a978724749ced57d208054 Mon Sep 17 00:00:00 2001
+From: Minjie Du <duminjie@vivo.com>
+Date: Thu, 21 Sep 2023 17:10:50 +0800
+Subject: [PATCH 38/42] thermal/drivers/mediatek/lvts_thermal: Fix error check
+ in lvts_debugfs_init()
+
+debugfs_create_dir() function returns an error value embedded in
+the pointer (PTR_ERR). Evaluate the return value using IS_ERR
+rather than checking for NULL.
+
+Signed-off-by: Minjie Du <duminjie@vivo.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230921091057.3812-1-duminjie@vivo.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -219,7 +219,7 @@ static int lvts_debugfs_init(struct devi
+               sprintf(name, "controller%d", i);
+               dentry = debugfs_create_dir(name, lvts_td->dom_dentry);
+-              if (!dentry)
++              if (IS_ERR(dentry))
+                       continue;
+               regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-44-thermal-drivers-mediatek-Fix-probe-for-THERMAL_V2.patch b/target/linux/mediatek/patches-6.6/830-v6.7-44-thermal-drivers-mediatek-Fix-probe-for-THERMAL_V2.patch
new file mode 100644 (file)
index 0000000..88f383c
--- /dev/null
@@ -0,0 +1,33 @@
+From e6f43063f2fe9f08b34797bc6d223f7d63b01910 Mon Sep 17 00:00:00 2001
+From: Markus Schneider-Pargmann <msp@baylibre.com>
+Date: Mon, 18 Sep 2023 12:07:06 +0200
+Subject: [PATCH 39/42] thermal/drivers/mediatek: Fix probe for THERMAL_V2
+
+Fix the probe function to call mtk_thermal_release_periodic_ts for
+everything != MTK_THERMAL_V1. This was accidentally changed from V1
+to V2 in the original patch.
+
+Reported-by: Frank Wunderlich <frank-w@public-files.de>
+Closes: https://lore.kernel.org/lkml/B0B3775B-B8D1-4284-814F-4F41EC22F532@public-files.de/
+Reported-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Closes: https://lore.kernel.org/lkml/07a569b9-e691-64ea-dd65-3b49842af33d@linaro.org/
+Fixes: 33140e668b10 ("thermal/drivers/mediatek: Control buffer enablement tweaks")
+Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20230918100706.1229239-1-msp@baylibre.com
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -1268,7 +1268,7 @@ static int mtk_thermal_probe(struct plat
+       mtk_thermal_turn_on_buffer(mt, apmixed_base);
+-      if (mt->conf->version != MTK_THERMAL_V2)
++      if (mt->conf->version != MTK_THERMAL_V1)
+               mtk_thermal_release_periodic_ts(mt, auxadc_base);
+       if (mt->conf->version == MTK_THERMAL_V1)
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch b/target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch
new file mode 100644 (file)
index 0000000..7b4b124
--- /dev/null
@@ -0,0 +1,83 @@
+From a1d874ef3376295ee8ed89b3b5315f4c840ff00b Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Tue, 17 Oct 2023 21:05:42 +0200
+Subject: [PATCH 40/42] thermal/drivers/mediatek/lvts_thermal: Add suspend and
+ resume
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add suspend and resume support to LVTS driver.
+
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+[bero@baylibre.com: suspend/resume in noirq phase]
+Co-developed-by: Bernhard Rosenkränzer <bero@baylibre.com>
+Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20231017190545.157282-3-bero@baylibre.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 37 +++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -1297,6 +1297,38 @@ static const struct lvts_ctrl_data mt798
+       }
+ };
++static int lvts_suspend(struct device *dev)
++{
++      struct lvts_domain *lvts_td;
++      int i;
++
++      lvts_td = dev_get_drvdata(dev);
++
++      for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
++              lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
++
++      clk_disable_unprepare(lvts_td->clk);
++
++      return 0;
++}
++
++static int lvts_resume(struct device *dev)
++{
++      struct lvts_domain *lvts_td;
++      int i, ret;
++
++      lvts_td = dev_get_drvdata(dev);
++
++      ret = clk_prepare_enable(lvts_td->clk);
++      if (ret)
++              return ret;
++
++      for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
++              lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true);
++
++      return 0;
++}
++
+ static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
+       {
+               .cal_offset = { 0x04, 0x07 },
+@@ -1405,12 +1437,17 @@ static const struct of_device_id lvts_of
+ };
+ MODULE_DEVICE_TABLE(of, lvts_of_match);
++static const struct dev_pm_ops lvts_pm_ops = {
++      NOIRQ_SYSTEM_SLEEP_PM_OPS(lvts_suspend, lvts_resume)
++};
++
+ static struct platform_driver lvts_driver = {
+       .probe = lvts_probe,
+       .remove_new = lvts_remove,
+       .driver = {
+               .name = "mtk-lvts-thermal",
+               .of_match_table = lvts_of_match,
++              .pm = &lvts_pm_ops,
+       },
+ };
+ module_platform_driver(lvts_driver);
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-46-dt-bindings-thermal-mediatek-Add-LVTS-thermal-contro.patch b/target/linux/mediatek/patches-6.6/830-v6.7-46-dt-bindings-thermal-mediatek-Add-LVTS-thermal-contro.patch
new file mode 100644 (file)
index 0000000..c278168
--- /dev/null
@@ -0,0 +1,49 @@
+From 0bb4937b58ab712f158588376dbac97f8e9df68e Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Tue, 17 Oct 2023 21:05:41 +0200
+Subject: [PATCH] dt-bindings: thermal: mediatek: Add LVTS thermal controller
+ definition for mt8192
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add LVTS thermal controller definition for MT8192.
+
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20231017190545.157282-2-bero@baylibre.com
+---
+ .../thermal/mediatek,lvts-thermal.h           | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/include/dt-bindings/thermal/mediatek,lvts-thermal.h
++++ b/include/dt-bindings/thermal/mediatek,lvts-thermal.h
+@@ -35,4 +35,23 @@
+ #define MT8195_AP_CAM0  15
+ #define MT8195_AP_CAM1  16
++#define MT8192_MCU_BIG_CPU0     0
++#define MT8192_MCU_BIG_CPU1     1
++#define MT8192_MCU_BIG_CPU2     2
++#define MT8192_MCU_BIG_CPU3     3
++#define MT8192_MCU_LITTLE_CPU0  4
++#define MT8192_MCU_LITTLE_CPU1  5
++#define MT8192_MCU_LITTLE_CPU2  6
++#define MT8192_MCU_LITTLE_CPU3  7
++
++#define MT8192_AP_VPU0  8
++#define MT8192_AP_VPU1  9
++#define MT8192_AP_GPU0  10
++#define MT8192_AP_GPU1  11
++#define MT8192_AP_INFRA 12
++#define MT8192_AP_CAM   13
++#define MT8192_AP_MD0   14
++#define MT8192_AP_MD1   15
++#define MT8192_AP_MD2   16
++
+ #endif /* __MEDIATEK_LVTS_DT_H */
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch b/target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch
new file mode 100644 (file)
index 0000000..6d68a6c
--- /dev/null
@@ -0,0 +1,151 @@
+From 7d8b3864b38d881cf105328ff8569f47446811ad Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Tue, 17 Oct 2023 21:05:43 +0200
+Subject: [PATCH 41/42] thermal/drivers/mediatek/lvts_thermal: Add mt8192
+ support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add LVTS Driver support for MT8192.
+
+Co-developed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+[bero@baylibre.com: cosmetic changes, rebase]
+Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20231017190545.157282-4-bero@baylibre.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 95 +++++++++++++++++++++++++
+ 1 file changed, 95 insertions(+)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -92,6 +92,7 @@
+ #define LVTS_MSR_READ_WAIT_US         (LVTS_MSR_READ_TIMEOUT_US / 2)
+ #define LVTS_HW_SHUTDOWN_MT7988               105000
++#define LVTS_HW_SHUTDOWN_MT8192               105000
+ #define LVTS_HW_SHUTDOWN_MT8195               105000
+ #define LVTS_MINIMUM_THRESHOLD                20000
+@@ -1329,6 +1330,88 @@ static int lvts_resume(struct device *de
+       return 0;
+ }
++static const struct lvts_ctrl_data mt8192_lvts_mcu_data_ctrl[] = {
++      {
++              .cal_offset = { 0x04, 0x08 },
++              .lvts_sensor = {
++                      { .dt_id = MT8192_MCU_BIG_CPU0 },
++                      { .dt_id = MT8192_MCU_BIG_CPU1 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x0,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
++              .mode = LVTS_MSR_FILTERED_MODE,
++      },
++      {
++              .cal_offset = { 0x0c, 0x10 },
++              .lvts_sensor = {
++                      { .dt_id = MT8192_MCU_BIG_CPU2 },
++                      { .dt_id = MT8192_MCU_BIG_CPU3 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x100,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
++              .mode = LVTS_MSR_FILTERED_MODE,
++      },
++      {
++              .cal_offset = { 0x14, 0x18, 0x1c, 0x20 },
++              .lvts_sensor = {
++                      { .dt_id = MT8192_MCU_LITTLE_CPU0 },
++                      { .dt_id = MT8192_MCU_LITTLE_CPU1 },
++                      { .dt_id = MT8192_MCU_LITTLE_CPU2 },
++                      { .dt_id = MT8192_MCU_LITTLE_CPU3 }
++              },
++              .num_lvts_sensor = 4,
++              .offset = 0x200,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
++              .mode = LVTS_MSR_FILTERED_MODE,
++      }
++};
++
++static const struct lvts_ctrl_data mt8192_lvts_ap_data_ctrl[] = {
++              {
++              .cal_offset = { 0x24, 0x28 },
++              .lvts_sensor = {
++                      { .dt_id = MT8192_AP_VPU0 },
++                      { .dt_id = MT8192_AP_VPU1 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x0,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
++      },
++      {
++              .cal_offset = { 0x2c, 0x30 },
++              .lvts_sensor = {
++                      { .dt_id = MT8192_AP_GPU0 },
++                      { .dt_id = MT8192_AP_GPU1 }
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x100,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
++      },
++      {
++              .cal_offset = { 0x34, 0x38 },
++              .lvts_sensor = {
++                      { .dt_id = MT8192_AP_INFRA },
++                      { .dt_id = MT8192_AP_CAM },
++              },
++              .num_lvts_sensor = 2,
++              .offset = 0x200,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
++      },
++      {
++              .cal_offset = { 0x3c, 0x40, 0x44 },
++              .lvts_sensor = {
++                      { .dt_id = MT8192_AP_MD0 },
++                      { .dt_id = MT8192_AP_MD1 },
++                      { .dt_id = MT8192_AP_MD2 }
++              },
++              .num_lvts_sensor = 3,
++              .offset = 0x300,
++              .hw_tshut_temp = LVTS_HW_SHUTDOWN_MT8192,
++      }
++};
++
+ static const struct lvts_ctrl_data mt8195_lvts_mcu_data_ctrl[] = {
+       {
+               .cal_offset = { 0x04, 0x07 },
+@@ -1415,6 +1498,16 @@ static const struct lvts_data mt7988_lvt
+       .temp_offset    = LVTS_COEFF_B_MT7988,
+ };
++static const struct lvts_data mt8192_lvts_mcu_data = {
++      .lvts_ctrl      = mt8192_lvts_mcu_data_ctrl,
++      .num_lvts_ctrl  = ARRAY_SIZE(mt8192_lvts_mcu_data_ctrl),
++};
++
++static const struct lvts_data mt8192_lvts_ap_data = {
++      .lvts_ctrl      = mt8192_lvts_ap_data_ctrl,
++      .num_lvts_ctrl  = ARRAY_SIZE(mt8192_lvts_ap_data_ctrl),
++};
++
+ static const struct lvts_data mt8195_lvts_mcu_data = {
+       .lvts_ctrl      = mt8195_lvts_mcu_data_ctrl,
+       .num_lvts_ctrl  = ARRAY_SIZE(mt8195_lvts_mcu_data_ctrl),
+@@ -1431,6 +1524,8 @@ static const struct lvts_data mt8195_lvt
+ static const struct of_device_id lvts_of_match[] = {
+       { .compatible = "mediatek,mt7988-lvts-ap", .data = &mt7988_lvts_ap_data },
++      { .compatible = "mediatek,mt8192-lvts-mcu", .data = &mt8192_lvts_mcu_data },
++      { .compatible = "mediatek,mt8192-lvts-ap", .data = &mt8192_lvts_ap_data },
+       { .compatible = "mediatek,mt8195-lvts-mcu", .data = &mt8195_lvts_mcu_data },
+       { .compatible = "mediatek,mt8195-lvts-ap", .data = &mt8195_lvts_ap_data },
+       {},
diff --git a/target/linux/mediatek/patches-6.6/830-v6.7-48-thermal-drivers-mediatek-lvts_thermal-Update-calibra.patch b/target/linux/mediatek/patches-6.6/830-v6.7-48-thermal-drivers-mediatek-lvts_thermal-Update-calibra.patch
new file mode 100644 (file)
index 0000000..c20c0b5
--- /dev/null
@@ -0,0 +1,70 @@
+From 5d126a3c87cf7964b28bacf3826eea4266265bce Mon Sep 17 00:00:00 2001
+From: Balsam CHIHI <bchihi@baylibre.com>
+Date: Tue, 17 Oct 2023 21:05:45 +0200
+Subject: [PATCH 42/42] thermal/drivers/mediatek/lvts_thermal: Update
+ calibration data documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Update LVTS calibration data documentation for mt8192 and mt8195.
+
+Signed-off-by: Balsam CHIHI <bchihi@baylibre.com>
+Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+[bero@baylibre.com: Fix issues pointed out by Nícolas F. R. A. Prado <nfraprado@collabora.com>]
+Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Link: https://lore.kernel.org/r/20231017190545.157282-6-bero@baylibre.com
+---
+ drivers/thermal/mediatek/lvts_thermal.c | 31 +++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+--- a/drivers/thermal/mediatek/lvts_thermal.c
++++ b/drivers/thermal/mediatek/lvts_thermal.c
+@@ -616,7 +616,34 @@ static int lvts_sensor_init(struct devic
+  * The efuse blob values follows the sensor enumeration per thermal
+  * controller. The decoding of the stream is as follow:
+  *
+- * stream index map for MCU Domain :
++ * MT8192 :
++ * Stream index map for MCU Domain mt8192 :
++ *
++ * <-----mcu-tc#0-----> <-----sensor#0----->        <-----sensor#1----->
++ *  0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09 | 0x0A | 0x0B
++ *
++ * <-----sensor#2----->        <-----sensor#3----->
++ *  0x0C | 0x0D | 0x0E | 0x0F | 0x10 | 0x11 | 0x12 | 0x13
++ *
++ * <-----sensor#4----->        <-----sensor#5----->        <-----sensor#6----->        <-----sensor#7----->
++ *  0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21 | 0x22 | 0x23
++ *
++ * Stream index map for AP Domain mt8192 :
++ *
++ * <-----sensor#0----->        <-----sensor#1----->
++ *  0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A | 0x2B
++ *
++ * <-----sensor#2----->        <-----sensor#3----->
++ *  0x2C | 0x2D | 0x2E | 0x2F | 0x30 | 0x31 | 0x32 | 0x33
++ *
++ * <-----sensor#4----->        <-----sensor#5----->
++ *  0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 | 0x3A | 0x3B
++ *
++ * <-----sensor#6----->        <-----sensor#7----->        <-----sensor#8----->
++ *  0x3C | 0x3D | 0x3E | 0x3F | 0x40 | 0x41 | 0x42 | 0x43 | 0x44 | 0x45 | 0x46 | 0x47
++ *
++ * MT8195 :
++ * Stream index map for MCU Domain mt8195 :
+  *
+  * <-----mcu-tc#0-----> <-----sensor#0-----> <-----sensor#1----->
+  *  0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x09
+@@ -627,7 +654,7 @@ static int lvts_sensor_init(struct devic
+  * <-----mcu-tc#2-----> <-----sensor#4-----> <-----sensor#5-----> <-----sensor#6-----> <-----sensor#7----->
+  *  0x13 | 0x14 | 0x15 | 0x16 | 0x17 | 0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | 0x20 | 0x21
+  *
+- * stream index map for AP Domain :
++ * Stream index map for AP Domain mt8195 :
+  *
+  * <-----ap--tc#0-----> <-----sensor#0-----> <-----sensor#1----->
+  *  0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 | 0x28 | 0x29 | 0x2A
diff --git a/target/linux/mediatek/patches-6.6/831-thermal-drivers-mediatek-Fix-control-buffer-enablement-on-MT7896.patch b/target/linux/mediatek/patches-6.6/831-thermal-drivers-mediatek-Fix-control-buffer-enablement-on-MT7896.patch
new file mode 100644 (file)
index 0000000..fc17364
--- /dev/null
@@ -0,0 +1,59 @@
+From patchwork Thu Sep  7 11:20:18 2023
+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: 13376356
+From: Frank Wunderlich <linux@fw-web.de>
+To: linux-mediatek@lists.infradead.org
+Subject: [PATCH] thermal/drivers/mediatek: Fix control buffer enablement on
+ MT7896
+Date: Thu,  7 Sep 2023 13:20:18 +0200
+Message-Id: <20230907112018.52811-1-linux@fw-web.de>
+X-Mailer: git-send-email 2.34.1
+MIME-Version: 1.0
+X-Mail-ID: e7eeb8e1-00de-41f6-a5df-ce2e9164136e
+X-BeenThere: linux-mediatek@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: <linux-mediatek.lists.infradead.org>
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>,
+ "Rafael J. Wysocki" <rafael@kernel.org>, linux-pm@vger.kernel.org,
+ Amit Kucheria <amitk@kernel.org>, Daniel Golle <daniel@makrotopia.org>,
+ stable@vger.kernel.org, linux-kernel@vger.kernel.org,
+ Matthias Brugger <matthias.bgg@gmail.com>, Zhang Rui <rui.zhang@intel.com>,
+ linux-arm-kernel@lists.infradead.org,
+ AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Sender: "Linux-mediatek" <linux-mediatek-bounces@lists.infradead.org>
+
+From: Frank Wunderlich <frank-w@public-files.de>
+
+Reading thermal sensor on mt7986 devices returns invalid temperature:
+
+bpi-r3 ~ # cat /sys/class/thermal/thermal_zone0/temp
+ -274000
+
+Fix this by adding missing members in mtk_thermal_data struct which were
+used in mtk_thermal_turn_on_buffer after commit 33140e668b10.
+
+Cc: stable@vger.kernel.org
+Fixes: 33140e668b10 ("thermal/drivers/mediatek: Control buffer enablement tweaks")
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
+---
+ drivers/thermal/mediatek/auxadc_thermal.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/thermal/mediatek/auxadc_thermal.c
++++ b/drivers/thermal/mediatek/auxadc_thermal.c
+@@ -691,6 +691,9 @@ static const struct mtk_thermal_data mt7
+       .adcpnp = mt7986_adcpnp,
+       .sensor_mux_values = mt7986_mux_values,
+       .version = MTK_THERMAL_V3,
++      .apmixed_buffer_ctl_reg = APMIXED_SYS_TS_CON1,
++      .apmixed_buffer_ctl_mask = GENMASK(31, 6) | BIT(3),
++      .apmixed_buffer_ctl_set = BIT(0),
+ };
+ static bool mtk_thermal_temp_is_valid(int temp)
diff --git a/target/linux/mediatek/patches-6.6/851-v6.2-i2c-mediatek-add-mt7986-support.patch b/target/linux/mediatek/patches-6.6/851-v6.2-i2c-mediatek-add-mt7986-support.patch
new file mode 100644 (file)
index 0000000..4c398c5
--- /dev/null
@@ -0,0 +1,44 @@
+From 11f9a0f4e51887ad7b4a2898a368fcd0c2984e89 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 9 Oct 2022 12:16:31 +0200
+Subject: [PATCH 12/16] i2c: mediatek: add mt7986 support
+
+Add i2c support for MT7986 SoC.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -431,6 +431,19 @@ static const struct mtk_i2c_compatible m
+       .max_dma_support = 33,
+ };
++static const struct mtk_i2c_compatible mt7986_compat = {
++      .quirks = &mt7622_i2c_quirks,
++      .regs = mt_i2c_regs_v1,
++      .pmic_i2c = 0,
++      .dcm = 1,
++      .auto_restart = 1,
++      .aux_len_reg = 1,
++      .timing_adjust = 0,
++      .dma_sync = 1,
++      .ltiming_adjust = 0,
++      .max_dma_support = 32,
++};
++
+ static const struct mtk_i2c_compatible mt8173_compat = {
+       .regs = mt_i2c_regs_v1,
+       .pmic_i2c = 0,
+@@ -503,6 +516,7 @@ static const struct of_device_id mtk_i2c
+       { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
+       { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
+       { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
++      { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
+       { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
+       { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
+       { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
diff --git a/target/linux/mediatek/patches-6.6/852-v6.3-i2c-mt65xx-Use-devm_platform_get_and_ioremap_resourc.patch b/target/linux/mediatek/patches-6.6/852-v6.3-i2c-mt65xx-Use-devm_platform_get_and_ioremap_resourc.patch
new file mode 100644 (file)
index 0000000..18c66cd
--- /dev/null
@@ -0,0 +1,42 @@
+From 98204ccafd45a8a6109ff2d60e2c179b95d92578 Mon Sep 17 00:00:00 2001
+From: ye xingchen <ye.xingchen@zte.com.cn>
+Date: Thu, 19 Jan 2023 17:19:58 +0800
+Subject: [PATCH 13/16] i2c: mt65xx: Use
+ devm_platform_get_and_ioremap_resource()
+
+Convert platform_get_resource(), devm_ioremap_resource() to a single
+call to devm_platform_get_and_ioremap_resource(), as this is exactly
+what this function does.
+
+Signed-off-by: ye xingchen <ye.xingchen@zte.com.cn>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1366,20 +1366,17 @@ static int mtk_i2c_probe(struct platform
+ {
+       int ret = 0;
+       struct mtk_i2c *i2c;
+-      struct resource *res;
+       int i, irq, speed_clk;
+       i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+       if (!i2c)
+               return -ENOMEM;
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      i2c->base = devm_ioremap_resource(&pdev->dev, res);
++      i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+       if (IS_ERR(i2c->base))
+               return PTR_ERR(i2c->base);
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+-      i2c->pdmabase = devm_ioremap_resource(&pdev->dev, res);
++      i2c->pdmabase = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
+       if (IS_ERR(i2c->pdmabase))
+               return PTR_ERR(i2c->pdmabase);
diff --git a/target/linux/mediatek/patches-6.6/853-v6.3-i2c-mt65xx-drop-of_match_ptr-for-ID-table.patch b/target/linux/mediatek/patches-6.6/853-v6.3-i2c-mt65xx-drop-of_match_ptr-for-ID-table.patch
new file mode 100644 (file)
index 0000000..d000d53
--- /dev/null
@@ -0,0 +1,33 @@
+From 8106fa2e0ae6082833fe1df97829c46c0183eaea Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Sat, 11 Mar 2023 12:16:54 +0100
+Subject: [PATCH 14/16] i2c: mt65xx: drop of_match_ptr for ID table
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The driver can match only via the DT table so the table should be always
+used and the of_match_ptr does not have any sense (this also allows ACPI
+matching via PRP0001, even though it might not be relevant here).
+
+  drivers/i2c/busses/i2c-mt65xx.c:514:34: error: â€˜mtk_i2c_of_match’ defined but not used [-Werror=unused-const-variable=]
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1546,7 +1546,7 @@ static struct platform_driver mtk_i2c_dr
+       .driver = {
+               .name = I2C_DRV_NAME,
+               .pm = &mtk_i2c_pm,
+-              .of_match_table = of_match_ptr(mtk_i2c_of_match),
++              .of_match_table = mtk_i2c_of_match,
+       },
+ };
diff --git a/target/linux/mediatek/patches-6.6/854-v6.4-i2c-mediatek-add-support-for-MT7981-SoC.patch b/target/linux/mediatek/patches-6.6/854-v6.4-i2c-mediatek-add-support-for-MT7981-SoC.patch
new file mode 100644 (file)
index 0000000..e097374
--- /dev/null
@@ -0,0 +1,47 @@
+From f69f3d662ba3bf999c36d9ac1e684540c4487bc3 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 10 Apr 2023 17:19:38 +0100
+Subject: [PATCH 15/16] i2c: mediatek: add support for MT7981 SoC
+
+Add support for the I2C units found in the MediaTek MT7981 and MT7988
+SoCs. Just like other recent MediaTek I2C units that also uses v3
+register offsets (which differ from v2 only by OFFSET_SLAVE_ADDR being
+0x94 instead of 0x4).
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -431,6 +431,18 @@ static const struct mtk_i2c_compatible m
+       .max_dma_support = 33,
+ };
++static const struct mtk_i2c_compatible mt7981_compat = {
++      .regs = mt_i2c_regs_v3,
++      .pmic_i2c = 0,
++      .dcm = 0,
++      .auto_restart = 1,
++      .aux_len_reg = 1,
++      .timing_adjust = 1,
++      .dma_sync = 1,
++      .ltiming_adjust = 1,
++      .max_dma_support = 33
++};
++
+ static const struct mtk_i2c_compatible mt7986_compat = {
+       .quirks = &mt7622_i2c_quirks,
+       .regs = mt_i2c_regs_v1,
+@@ -516,6 +528,7 @@ static const struct of_device_id mtk_i2c
+       { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
+       { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
+       { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
++      { .compatible = "mediatek,mt7981-i2c", .data = &mt7981_compat },
+       { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
+       { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
+       { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
diff --git a/target/linux/mediatek/patches-6.6/855-i2c-mt65xx-allow-optional-pmic-clock.patch b/target/linux/mediatek/patches-6.6/855-i2c-mt65xx-allow-optional-pmic-clock.patch
new file mode 100644 (file)
index 0000000..69cc155
--- /dev/null
@@ -0,0 +1,45 @@
+From 3bf827929a44c17bfb1bf1000b143c02ce26a929 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 26 Aug 2023 21:56:51 +0100
+Subject: [PATCH] i2c: mt65xx: allow optional pmic clock
+
+Using the I2C host controller on the MT7981 SoC requires 4 clocks to
+be enabled. One of them, the pmic clk, is only enabled in case
+'mediatek,have-pmic' is also set which has other consequences which
+are not desired in this case.
+
+Allow defining a pmic clk even in case the 'mediatek,have-pmic' propterty
+is not present and the bus is not used to connect to a pmic, but may
+still require to enable the pmic clock.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1444,15 +1444,19 @@ static int mtk_i2c_probe(struct platform
+       if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
+               return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
++      i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get_optional(&pdev->dev, "pmic");
++      if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
++              dev_err(&pdev->dev, "cannot get pmic clock\n");
++              return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
++      }
++
+       if (i2c->have_pmic) {
+-              i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
+-              if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
++              if (!i2c->clocks[I2C_MT65XX_CLK_PMIC].clk) {
+                       dev_err(&pdev->dev, "cannot get pmic clock\n");
+-                      return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
++                      return -ENODEV;
+               }
+               speed_clk = I2C_MT65XX_CLK_PMIC;
+       } else {
+-              i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
+               speed_clk = I2C_MT65XX_CLK_MAIN;
+       }
diff --git a/target/linux/mediatek/patches-6.6/860-v6.6-01-ASoC-mediatek-mt7986-add-common-header.patch b/target/linux/mediatek/patches-6.6/860-v6.6-01-ASoC-mediatek-mt7986-add-common-header.patch
new file mode 100644 (file)
index 0000000..9607eec
--- /dev/null
@@ -0,0 +1,269 @@
+From d35469096915f2551ed1d26da1ab12ff500fc963 Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Thu, 17 Aug 2023 18:13:33 +0800
+Subject: [PATCH 1/9] ASoC: mediatek: mt7986: add common header
+
+Add header files for register definition and structure.
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230817101338.18782-2-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt7986/mt7986-afe-common.h |  49 +++++
+ sound/soc/mediatek/mt7986/mt7986-reg.h        | 196 ++++++++++++++++++
+ 2 files changed, 245 insertions(+)
+ create mode 100644 sound/soc/mediatek/mt7986/mt7986-afe-common.h
+ create mode 100644 sound/soc/mediatek/mt7986/mt7986-reg.h
+
+--- /dev/null
++++ b/sound/soc/mediatek/mt7986/mt7986-afe-common.h
+@@ -0,0 +1,49 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * mt7986-afe-common.h  --  MediaTek 7986 audio driver definitions
++ *
++ * Copyright (c) 2023 MediaTek Inc.
++ * Authors: Vic Wu <vic.wu@mediatek.com>
++ *          Maso Huang <maso.huang@mediatek.com>
++ */
++
++#ifndef _MT_7986_AFE_COMMON_H_
++#define _MT_7986_AFE_COMMON_H_
++
++#include <sound/soc.h>
++#include <linux/clk.h>
++#include <linux/list.h>
++#include <linux/regmap.h>
++#include "../common/mtk-base-afe.h"
++
++enum {
++      MT7986_MEMIF_DL1,
++      MT7986_MEMIF_VUL12,
++      MT7986_MEMIF_NUM,
++      MT7986_DAI_ETDM = MT7986_MEMIF_NUM,
++      MT7986_DAI_NUM,
++};
++
++enum {
++      MT7986_IRQ_0,
++      MT7986_IRQ_1,
++      MT7986_IRQ_2,
++      MT7986_IRQ_NUM,
++};
++
++struct mt7986_afe_private {
++      struct clk_bulk_data *clks;
++      int num_clks;
++
++      int pm_runtime_bypass_reg_ctl;
++
++      /* dai */
++      void *dai_priv[MT7986_DAI_NUM];
++};
++
++unsigned int mt7986_afe_rate_transform(struct device *dev,
++                                     unsigned int rate);
++
++/* dai register */
++int mt7986_dai_etdm_register(struct mtk_base_afe *afe);
++#endif
+--- /dev/null
++++ b/sound/soc/mediatek/mt7986/mt7986-reg.h
+@@ -0,0 +1,196 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * mt7986-reg.h  --  MediaTek 7986 audio driver reg definition
++ *
++ * Copyright (c) 2023 MediaTek Inc.
++ * Authors: Vic Wu <vic.wu@mediatek.com>
++ *          Maso Huang <maso.huang@mediatek.com>
++ */
++
++#ifndef _MT7986_REG_H_
++#define _MT7986_REG_H_
++
++#define AUDIO_TOP_CON2                  0x0008
++#define AUDIO_TOP_CON4                  0x0010
++#define AUDIO_ENGEN_CON0                0x0014
++#define AFE_IRQ_MCU_EN                  0x0100
++#define AFE_IRQ_MCU_STATUS              0x0120
++#define AFE_IRQ_MCU_CLR                 0x0128
++#define AFE_IRQ0_MCU_CFG0               0x0140
++#define AFE_IRQ0_MCU_CFG1               0x0144
++#define AFE_IRQ1_MCU_CFG0               0x0148
++#define AFE_IRQ1_MCU_CFG1               0x014c
++#define AFE_IRQ2_MCU_CFG0               0x0150
++#define AFE_IRQ2_MCU_CFG1               0x0154
++#define ETDM_IN5_CON0                   0x13f0
++#define ETDM_IN5_CON1                   0x13f4
++#define ETDM_IN5_CON2                   0x13f8
++#define ETDM_IN5_CON3                   0x13fc
++#define ETDM_IN5_CON4                   0x1400
++#define ETDM_OUT5_CON0                  0x1570
++#define ETDM_OUT5_CON4                  0x1580
++#define ETDM_OUT5_CON5                  0x1584
++#define ETDM_4_7_COWORK_CON0            0x15e0
++#define ETDM_4_7_COWORK_CON1            0x15e4
++#define AFE_CONN018_1                   0x1b44
++#define AFE_CONN018_4                   0x1b50
++#define AFE_CONN019_1                   0x1b64
++#define AFE_CONN019_4                   0x1b70
++#define AFE_CONN124_1                   0x2884
++#define AFE_CONN124_4                   0x2890
++#define AFE_CONN125_1                   0x28a4
++#define AFE_CONN125_4                   0x28b0
++#define AFE_CONN_RS_0                   0x3920
++#define AFE_CONN_RS_3                   0x392c
++#define AFE_CONN_16BIT_0                0x3960
++#define AFE_CONN_16BIT_3                0x396c
++#define AFE_CONN_24BIT_0                0x3980
++#define AFE_CONN_24BIT_3                0x398c
++#define AFE_MEMIF_CON0                  0x3d98
++#define AFE_MEMIF_RD_MON                0x3da0
++#define AFE_MEMIF_WR_MON                0x3da4
++#define AFE_DL0_BASE_MSB                0x3e40
++#define AFE_DL0_BASE                    0x3e44
++#define AFE_DL0_CUR_MSB                 0x3e48
++#define AFE_DL0_CUR                     0x3e4c
++#define AFE_DL0_END_MSB                 0x3e50
++#define AFE_DL0_END                     0x3e54
++#define AFE_DL0_RCH_MON                 0x3e58
++#define AFE_DL0_LCH_MON                 0x3e5c
++#define AFE_DL0_CON0                    0x3e60
++#define AFE_VUL0_BASE_MSB               0x4220
++#define AFE_VUL0_BASE                   0x4224
++#define AFE_VUL0_CUR_MSB                0x4228
++#define AFE_VUL0_CUR                    0x422c
++#define AFE_VUL0_END_MSB                0x4230
++#define AFE_VUL0_END                    0x4234
++#define AFE_VUL0_CON0                   0x4238
++
++#define AFE_MAX_REGISTER AFE_VUL0_CON0
++#define AFE_IRQ_STATUS_BITS             0x7
++#define AFE_IRQ_CNT_SHIFT               0
++#define AFE_IRQ_CNT_MASK              0xffffff
++
++/* AUDIO_TOP_CON2 */
++#define CLK_OUT5_PDN                    BIT(14)
++#define CLK_OUT5_PDN_MASK               BIT(14)
++#define CLK_IN5_PDN                     BIT(7)
++#define CLK_IN5_PDN_MASK                BIT(7)
++
++/* AUDIO_TOP_CON4 */
++#define PDN_APLL_TUNER2                 BIT(12)
++#define PDN_APLL_TUNER2_MASK            BIT(12)
++
++/* AUDIO_ENGEN_CON0 */
++#define AUD_APLL2_EN                    BIT(3)
++#define AUD_APLL2_EN_MASK               BIT(3)
++#define AUD_26M_EN                      BIT(0)
++#define AUD_26M_EN_MASK                 BIT(0)
++
++/* AFE_DL0_CON0 */
++#define DL0_ON_SFT                      28
++#define DL0_ON_MASK                     0x1
++#define DL0_ON_MASK_SFT                 BIT(28)
++#define DL0_MINLEN_SFT                  20
++#define DL0_MINLEN_MASK                 0xf
++#define DL0_MINLEN_MASK_SFT             (0xf << 20)
++#define DL0_MODE_SFT                    8
++#define DL0_MODE_MASK                   0x1f
++#define DL0_MODE_MASK_SFT               (0x1f << 8)
++#define DL0_PBUF_SIZE_SFT               5
++#define DL0_PBUF_SIZE_MASK              0x3
++#define DL0_PBUF_SIZE_MASK_SFT          (0x3 << 5)
++#define DL0_MONO_SFT                    4
++#define DL0_MONO_MASK                   0x1
++#define DL0_MONO_MASK_SFT               BIT(4)
++#define DL0_HALIGN_SFT                  2
++#define DL0_HALIGN_MASK                 0x1
++#define DL0_HALIGN_MASK_SFT             BIT(2)
++#define DL0_HD_MODE_SFT                 0
++#define DL0_HD_MODE_MASK                0x3
++#define DL0_HD_MODE_MASK_SFT            (0x3 << 0)
++
++/* AFE_VUL0_CON0 */
++#define VUL0_ON_SFT                     28
++#define VUL0_ON_MASK                    0x1
++#define VUL0_ON_MASK_SFT                BIT(28)
++#define VUL0_MODE_SFT                   8
++#define VUL0_MODE_MASK                  0x1f
++#define VUL0_MODE_MASK_SFT              (0x1f << 8)
++#define VUL0_MONO_SFT                   4
++#define VUL0_MONO_MASK                  0x1
++#define VUL0_MONO_MASK_SFT              BIT(4)
++#define VUL0_HALIGN_SFT                 2
++#define VUL0_HALIGN_MASK                0x1
++#define VUL0_HALIGN_MASK_SFT            BIT(2)
++#define VUL0_HD_MODE_SFT                0
++#define VUL0_HD_MODE_MASK               0x3
++#define VUL0_HD_MODE_MASK_SFT           (0x3 << 0)
++
++/* AFE_IRQ_MCU_CON */
++#define IRQ_MCU_MODE_SFT                4
++#define IRQ_MCU_MODE_MASK               0x1f
++#define IRQ_MCU_MODE_MASK_SFT           (0x1f << 4)
++#define IRQ_MCU_ON_SFT                  0
++#define IRQ_MCU_ON_MASK                 0x1
++#define IRQ_MCU_ON_MASK_SFT             BIT(0)
++#define IRQ0_MCU_CLR_SFT                0
++#define IRQ0_MCU_CLR_MASK               0x1
++#define IRQ0_MCU_CLR_MASK_SFT           BIT(0)
++#define IRQ1_MCU_CLR_SFT                1
++#define IRQ1_MCU_CLR_MASK               0x1
++#define IRQ1_MCU_CLR_MASK_SFT           BIT(1)
++#define IRQ2_MCU_CLR_SFT                2
++#define IRQ2_MCU_CLR_MASK               0x1
++#define IRQ2_MCU_CLR_MASK_SFT           BIT(2)
++
++/* ETDM_IN5_CON2 */
++#define IN_CLK_SRC(x)                   ((x) << 10)
++#define IN_CLK_SRC_SFT                  10
++#define IN_CLK_SRC_MASK                 GENMASK(12, 10)
++
++/* ETDM_IN5_CON3 */
++#define IN_SEL_FS(x)                    ((x) << 26)
++#define IN_SEL_FS_SFT                   26
++#define IN_SEL_FS_MASK                  GENMASK(30, 26)
++
++/* ETDM_IN5_CON4 */
++#define IN_RELATCH(x)                   ((x) << 20)
++#define IN_RELATCH_SFT                  20
++#define IN_RELATCH_MASK                 GENMASK(24, 20)
++#define IN_CLK_INV                      BIT(18)
++#define IN_CLK_INV_MASK                 BIT(18)
++
++/* ETDM_IN5_CON0 & ETDM_OUT5_CON0 */
++#define RELATCH_SRC_MASK                GENMASK(30, 28)
++#define ETDM_CH_NUM_MASK                GENMASK(27, 23)
++#define ETDM_WRD_LEN_MASK               GENMASK(20, 16)
++#define ETDM_BIT_LEN_MASK               GENMASK(15, 11)
++#define ETDM_FMT_MASK                   GENMASK(8, 6)
++#define ETDM_SYNC                       BIT(1)
++#define ETDM_SYNC_MASK                  BIT(1)
++#define ETDM_EN                         BIT(0)
++#define ETDM_EN_MASK                    BIT(0)
++
++/* ETDM_OUT5_CON4 */
++#define OUT_RELATCH(x)                  ((x) << 24)
++#define OUT_RELATCH_SFT                 24
++#define OUT_RELATCH_MASK                GENMASK(28, 24)
++#define OUT_CLK_SRC(x)                  ((x) << 6)
++#define OUT_CLK_SRC_SFT                 6
++#define OUT_CLK_SRC_MASK                GENMASK(8, 6)
++#define OUT_SEL_FS(x)                   (x)
++#define OUT_SEL_FS_SFT                  0
++#define OUT_SEL_FS_MASK                 GENMASK(4, 0)
++
++/* ETDM_OUT5_CON5 */
++#define ETDM_CLK_DIV                    BIT(12)
++#define ETDM_CLK_DIV_MASK               BIT(12)
++#define OUT_CLK_INV                     BIT(9)
++#define OUT_CLK_INV_MASK                BIT(9)
++
++/* ETDM_4_7_COWORK_CON0 */
++#define OUT_SEL(x)                      ((x) << 12)
++#define OUT_SEL_SFT                     12
++#define OUT_SEL_MASK                    GENMASK(15, 12)
++#endif
diff --git a/target/linux/mediatek/patches-6.6/860-v6.6-02-ASoC-mediatek-mt7986-support-etdm-in-platform-driver.patch b/target/linux/mediatek/patches-6.6/860-v6.6-02-ASoC-mediatek-mt7986-support-etdm-in-platform-driver.patch
new file mode 100644 (file)
index 0000000..f22add5
--- /dev/null
@@ -0,0 +1,430 @@
+From 948a288897015fb3ee63b3f720b396b590c17fd7 Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Thu, 17 Aug 2023 18:13:34 +0800
+Subject: [PATCH 2/9] ASoC: mediatek: mt7986: support etdm in platform driver
+
+Add mt7986 etdm dai driver support.
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230817101338.18782-3-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt7986/mt7986-dai-etdm.c | 411 ++++++++++++++++++++
+ 1 file changed, 411 insertions(+)
+ create mode 100644 sound/soc/mediatek/mt7986/mt7986-dai-etdm.c
+
+--- /dev/null
++++ b/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c
+@@ -0,0 +1,411 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * MediaTek ALSA SoC Audio DAI eTDM Control
++ *
++ * Copyright (c) 2023 MediaTek Inc.
++ * Authors: Vic Wu <vic.wu@mediatek.com>
++ *          Maso Huang <maso.huang@mediatek.com>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/bitops.h>
++#include <linux/regmap.h>
++#include <sound/pcm_params.h>
++#include "mt7986-afe-common.h"
++#include "mt7986-reg.h"
++
++#define HOPPING_CLK  0
++#define APLL_CLK     1
++#define MTK_DAI_ETDM_FORMAT_I2S   0
++#define MTK_DAI_ETDM_FORMAT_DSPA  4
++#define MTK_DAI_ETDM_FORMAT_DSPB  5
++
++enum {
++      MTK_ETDM_RATE_8K = 0,
++      MTK_ETDM_RATE_12K = 1,
++      MTK_ETDM_RATE_16K = 2,
++      MTK_ETDM_RATE_24K = 3,
++      MTK_ETDM_RATE_32K = 4,
++      MTK_ETDM_RATE_48K = 5,
++      MTK_ETDM_RATE_96K = 7,
++      MTK_ETDM_RATE_192K = 9,
++      MTK_ETDM_RATE_11K = 16,
++      MTK_ETDM_RATE_22K = 17,
++      MTK_ETDM_RATE_44K = 18,
++      MTK_ETDM_RATE_88K = 19,
++      MTK_ETDM_RATE_176K = 20,
++};
++
++struct mtk_dai_etdm_priv {
++      bool bck_inv;
++      bool lrck_inv;
++      bool slave_mode;
++      unsigned int format;
++};
++
++static unsigned int mt7986_etdm_rate_transform(struct device *dev, unsigned int rate)
++{
++      switch (rate) {
++      case 8000:
++              return MTK_ETDM_RATE_8K;
++      case 11025:
++              return MTK_ETDM_RATE_11K;
++      case 12000:
++              return MTK_ETDM_RATE_12K;
++      case 16000:
++              return MTK_ETDM_RATE_16K;
++      case 22050:
++              return MTK_ETDM_RATE_22K;
++      case 24000:
++              return MTK_ETDM_RATE_24K;
++      case 32000:
++              return MTK_ETDM_RATE_32K;
++      case 44100:
++              return MTK_ETDM_RATE_44K;
++      case 48000:
++              return MTK_ETDM_RATE_48K;
++      case 88200:
++              return MTK_ETDM_RATE_88K;
++      case 96000:
++              return MTK_ETDM_RATE_96K;
++      case 176400:
++              return MTK_ETDM_RATE_176K;
++      case 192000:
++              return MTK_ETDM_RATE_192K;
++      default:
++              dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n",
++                       __func__, rate, MTK_ETDM_RATE_48K);
++              return MTK_ETDM_RATE_48K;
++      }
++}
++
++static int get_etdm_wlen(unsigned int bitwidth)
++{
++      return bitwidth <= 16 ? 16 : 32;
++}
++
++/* dai component */
++/* interconnection */
++
++static const struct snd_kcontrol_new o124_mix[] = {
++      SOC_DAPM_SINGLE_AUTODISABLE("I032_Switch", AFE_CONN124_1, 0, 1, 0),
++};
++
++static const struct snd_kcontrol_new o125_mix[] = {
++      SOC_DAPM_SINGLE_AUTODISABLE("I033_Switch", AFE_CONN125_1, 1, 1, 0),
++};
++
++static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
++
++      /* DL */
++      SND_SOC_DAPM_MIXER("I150", SND_SOC_NOPM, 0, 0, NULL, 0),
++      SND_SOC_DAPM_MIXER("I151", SND_SOC_NOPM, 0, 0, NULL, 0),
++      /* UL */
++      SND_SOC_DAPM_MIXER("O124", SND_SOC_NOPM, 0, 0, o124_mix, ARRAY_SIZE(o124_mix)),
++      SND_SOC_DAPM_MIXER("O125", SND_SOC_NOPM, 0, 0, o125_mix, ARRAY_SIZE(o125_mix)),
++};
++
++static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
++      {"I150", NULL, "ETDM Capture"},
++      {"I151", NULL, "ETDM Capture"},
++      {"ETDM Playback", NULL, "O124"},
++      {"ETDM Playback", NULL, "O125"},
++      {"O124", "I032_Switch", "I032"},
++      {"O125", "I033_Switch", "I033"},
++};
++
++/* dai ops */
++static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream,
++                              struct snd_soc_dai *dai)
++{
++      struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
++      struct mt7986_afe_private *afe_priv = afe->platform_priv;
++      int ret;
++
++      ret = clk_bulk_prepare_enable(afe_priv->num_clks, afe_priv->clks);
++      if (ret)
++              return dev_err_probe(afe->dev, ret, "Failed to enable clocks\n");
++
++      regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_OUT5_PDN_MASK, 0);
++      regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_IN5_PDN_MASK, 0);
++
++      return 0;
++}
++
++static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream,
++                                struct snd_soc_dai *dai)
++{
++      struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
++      struct mt7986_afe_private *afe_priv = afe->platform_priv;
++
++      regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_OUT5_PDN_MASK,
++                         CLK_OUT5_PDN);
++      regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_IN5_PDN_MASK,
++                         CLK_IN5_PDN);
++
++      clk_bulk_disable_unprepare(afe_priv->num_clks, afe_priv->clks);
++}
++
++static unsigned int get_etdm_ch_fixup(unsigned int channels)
++{
++      if (channels > 16)
++              return 24;
++      else if (channels > 8)
++              return 16;
++      else if (channels > 4)
++              return 8;
++      else if (channels > 2)
++              return 4;
++      else
++              return 2;
++}
++
++static int mtk_dai_etdm_config(struct mtk_base_afe *afe,
++                             struct snd_pcm_hw_params *params,
++                             struct snd_soc_dai *dai,
++                             int stream)
++{
++      struct mt7986_afe_private *afe_priv = afe->platform_priv;
++      struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id];
++      unsigned int rate = params_rate(params);
++      unsigned int etdm_rate = mt7986_etdm_rate_transform(afe->dev, rate);
++      unsigned int afe_rate = mt7986_afe_rate_transform(afe->dev, rate);
++      unsigned int channels = params_channels(params);
++      unsigned int bit_width = params_width(params);
++      unsigned int wlen = get_etdm_wlen(bit_width);
++      unsigned int val = 0;
++      unsigned int mask = 0;
++
++      dev_dbg(afe->dev, "%s(), stream %d, rate %u, bitwidth %u\n",
++               __func__, stream, rate, bit_width);
++
++      /* CON0 */
++      mask |= ETDM_BIT_LEN_MASK;
++      val |= FIELD_PREP(ETDM_BIT_LEN_MASK, bit_width - 1);
++      mask |= ETDM_WRD_LEN_MASK;
++      val |= FIELD_PREP(ETDM_WRD_LEN_MASK, wlen - 1);
++      mask |= ETDM_FMT_MASK;
++      val |= FIELD_PREP(ETDM_FMT_MASK, etdm_data->format);
++      mask |= ETDM_CH_NUM_MASK;
++      val |= FIELD_PREP(ETDM_CH_NUM_MASK, get_etdm_ch_fixup(channels) - 1);
++      mask |= RELATCH_SRC_MASK;
++      val |= FIELD_PREP(RELATCH_SRC_MASK, APLL_CLK);
++
++      switch (stream) {
++      case SNDRV_PCM_STREAM_PLAYBACK:
++              /* set ETDM_OUT5_CON0 */
++              regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, mask, val);
++
++              /* set ETDM_OUT5_CON4 */
++              regmap_update_bits(afe->regmap, ETDM_OUT5_CON4,
++                                 OUT_RELATCH_MASK, OUT_RELATCH(afe_rate));
++              regmap_update_bits(afe->regmap, ETDM_OUT5_CON4,
++                                 OUT_CLK_SRC_MASK, OUT_CLK_SRC(APLL_CLK));
++              regmap_update_bits(afe->regmap, ETDM_OUT5_CON4,
++                                 OUT_SEL_FS_MASK, OUT_SEL_FS(etdm_rate));
++
++              /* set ETDM_OUT5_CON5 */
++              regmap_update_bits(afe->regmap, ETDM_OUT5_CON5,
++                                 ETDM_CLK_DIV_MASK, ETDM_CLK_DIV);
++              break;
++      case SNDRV_PCM_STREAM_CAPTURE:
++              /* set ETDM_IN5_CON0 */
++              regmap_update_bits(afe->regmap, ETDM_IN5_CON0, mask, val);
++              regmap_update_bits(afe->regmap, ETDM_IN5_CON0,
++                                 ETDM_SYNC_MASK, ETDM_SYNC);
++
++              /* set ETDM_IN5_CON2 */
++              regmap_update_bits(afe->regmap, ETDM_IN5_CON2,
++                                 IN_CLK_SRC_MASK, IN_CLK_SRC(APLL_CLK));
++
++              /* set ETDM_IN5_CON3 */
++              regmap_update_bits(afe->regmap, ETDM_IN5_CON3,
++                                 IN_SEL_FS_MASK, IN_SEL_FS(etdm_rate));
++
++              /* set ETDM_IN5_CON4 */
++              regmap_update_bits(afe->regmap, ETDM_IN5_CON4,
++                                 IN_RELATCH_MASK, IN_RELATCH(afe_rate));
++              break;
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
++                                struct snd_pcm_hw_params *params,
++                                struct snd_soc_dai *dai)
++{
++      struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
++
++      mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_PLAYBACK);
++      mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_CAPTURE);
++
++      return 0;
++}
++
++static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd,
++                              struct snd_soc_dai *dai)
++{
++      struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
++
++      dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id);
++      switch (cmd) {
++      case SNDRV_PCM_TRIGGER_START:
++      case SNDRV_PCM_TRIGGER_RESUME:
++              regmap_update_bits(afe->regmap, ETDM_IN5_CON0, ETDM_EN_MASK,
++                                 ETDM_EN);
++              regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, ETDM_EN_MASK,
++                                 ETDM_EN);
++              break;
++      case SNDRV_PCM_TRIGGER_STOP:
++      case SNDRV_PCM_TRIGGER_SUSPEND:
++              regmap_update_bits(afe->regmap, ETDM_IN5_CON0, ETDM_EN_MASK,
++                                 0);
++              regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, ETDM_EN_MASK,
++                                 0);
++              break;
++      default:
++              break;
++      }
++
++      return 0;
++}
++
++static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++      struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
++      struct mt7986_afe_private *afe_priv = afe->platform_priv;
++      struct mtk_dai_etdm_priv *etdm_data;
++      void *priv_data;
++
++      switch (dai->id) {
++      case MT7986_DAI_ETDM:
++              break;
++      default:
++              dev_warn(afe->dev, "%s(), id %d not support\n",
++                       __func__, dai->id);
++              return -EINVAL;
++      }
++
++      priv_data = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_etdm_priv),
++                               GFP_KERNEL);
++      if (!priv_data)
++              return -ENOMEM;
++
++      afe_priv->dai_priv[dai->id] = priv_data;
++      etdm_data = afe_priv->dai_priv[dai->id];
++
++      switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++      case SND_SOC_DAIFMT_I2S:
++              etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S;
++              break;
++      case SND_SOC_DAIFMT_DSP_A:
++              etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA;
++              break;
++      case SND_SOC_DAIFMT_DSP_B:
++              etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++      case SND_SOC_DAIFMT_NB_NF:
++              etdm_data->bck_inv = false;
++              etdm_data->lrck_inv = false;
++              break;
++      case SND_SOC_DAIFMT_NB_IF:
++              etdm_data->bck_inv = false;
++              etdm_data->lrck_inv = true;
++              break;
++      case SND_SOC_DAIFMT_IB_NF:
++              etdm_data->bck_inv = true;
++              etdm_data->lrck_inv = false;
++              break;
++      case SND_SOC_DAIFMT_IB_IF:
++              etdm_data->bck_inv = true;
++              etdm_data->lrck_inv = true;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++      case SND_SOC_DAIFMT_CBM_CFM:
++              etdm_data->slave_mode = true;
++              break;
++      case SND_SOC_DAIFMT_CBS_CFS:
++              etdm_data->slave_mode = false;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++static const struct snd_soc_dai_ops mtk_dai_etdm_ops = {
++      .startup = mtk_dai_etdm_startup,
++      .shutdown = mtk_dai_etdm_shutdown,
++      .hw_params = mtk_dai_etdm_hw_params,
++      .trigger = mtk_dai_etdm_trigger,
++      .set_fmt = mtk_dai_etdm_set_fmt,
++};
++
++/* dai driver */
++#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_48000 |\
++                      SNDRV_PCM_RATE_88200 |\
++                      SNDRV_PCM_RATE_96000 |\
++                      SNDRV_PCM_RATE_176400 |\
++                      SNDRV_PCM_RATE_192000)
++
++#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
++                        SNDRV_PCM_FMTBIT_S24_LE |\
++                        SNDRV_PCM_FMTBIT_S32_LE)
++
++static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = {
++      {
++              .name = "ETDM",
++              .id = MT7986_DAI_ETDM,
++              .capture = {
++                      .stream_name = "ETDM Capture",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MTK_ETDM_RATES,
++                      .formats = MTK_ETDM_FORMATS,
++              },
++              .playback = {
++                      .stream_name = "ETDM Playback",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MTK_ETDM_RATES,
++                      .formats = MTK_ETDM_FORMATS,
++              },
++              .ops = &mtk_dai_etdm_ops,
++              .symmetric_rate = 1,
++              .symmetric_sample_bits = 1,
++      },
++};
++
++int mt7986_dai_etdm_register(struct mtk_base_afe *afe)
++{
++      struct mtk_base_afe_dai *dai;
++
++      dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
++      if (!dai)
++              return -ENOMEM;
++
++      list_add(&dai->list, &afe->sub_dais);
++
++      dai->dai_drivers = mtk_dai_etdm_driver;
++      dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver);
++
++      dai->dapm_widgets = mtk_dai_etdm_widgets;
++      dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets);
++      dai->dapm_routes = mtk_dai_etdm_routes;
++      dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes);
++
++      return 0;
++}
diff --git a/target/linux/mediatek/patches-6.6/860-v6.6-03-ASoC-mediatek-mt7986-add-platform-driver.patch b/target/linux/mediatek/patches-6.6/860-v6.6-03-ASoC-mediatek-mt7986-add-platform-driver.patch
new file mode 100644 (file)
index 0000000..b899b96
--- /dev/null
@@ -0,0 +1,685 @@
+From fc7776dee86bc07d22820a904760a95f49a2f12e Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Thu, 17 Aug 2023 18:13:35 +0800
+Subject: [PATCH 3/9] ASoC: mediatek: mt7986: add platform driver
+
+Add mt7986 platform driver.
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230817101338.18782-4-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/Kconfig                 |  10 +
+ sound/soc/mediatek/Makefile                |   1 +
+ sound/soc/mediatek/mt7986/Makefile         |   8 +
+ sound/soc/mediatek/mt7986/mt7986-afe-pcm.c | 622 +++++++++++++++++++++
+ 4 files changed, 641 insertions(+)
+ create mode 100644 sound/soc/mediatek/mt7986/Makefile
+ create mode 100644 sound/soc/mediatek/mt7986/mt7986-afe-pcm.c
+
+--- a/sound/soc/mediatek/Kconfig
++++ b/sound/soc/mediatek/Kconfig
+@@ -54,6 +54,16 @@ config SND_SOC_MT6797_MT6351
+         Select Y if you have such device.
+         If unsure select "N".
++config SND_SOC_MT7986
++      tristate "ASoC support for Mediatek MT7986 chip"
++      depends on ARCH_MEDIATEK
++      select SND_SOC_MEDIATEK
++      help
++        This adds ASoC platform driver support for MediaTek MT7986 chip
++        that can be used with other codecs.
++        Select Y if you have such device.
++        If unsure select "N".
++
+ config SND_SOC_MT8173
+       tristate "ASoC support for Mediatek MT8173 chip"
+       depends on ARCH_MEDIATEK
+--- a/sound/soc/mediatek/Makefile
++++ b/sound/soc/mediatek/Makefile
+@@ -2,6 +2,7 @@
+ obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
+ obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
+ obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
++obj-$(CONFIG_SND_SOC_MT7986) += mt7986/
+ obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
+ obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
+ obj-$(CONFIG_SND_SOC_MT8186) += mt8186/
+--- /dev/null
++++ b/sound/soc/mediatek/mt7986/Makefile
+@@ -0,0 +1,8 @@
++# SPDX-License-Identifier: GPL-2.0
++
++# platform driver
++snd-soc-mt7986-afe-objs := \
++      mt7986-afe-pcm.o \
++      mt7986-dai-etdm.o
++
++obj-$(CONFIG_SND_SOC_MT7986) += snd-soc-mt7986-afe.o
+--- /dev/null
++++ b/sound/soc/mediatek/mt7986/mt7986-afe-pcm.c
+@@ -0,0 +1,622 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * MediaTek ALSA SoC AFE platform driver for MT7986
++ *
++ * Copyright (c) 2023 MediaTek Inc.
++ * Authors: Vic Wu <vic.wu@mediatek.com>
++ *          Maso Huang <maso.huang@mediatek.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/pm_runtime.h>
++
++#include "mt7986-afe-common.h"
++#include "mt7986-reg.h"
++#include "../common/mtk-afe-platform-driver.h"
++#include "../common/mtk-afe-fe-dai.h"
++
++enum {
++      MTK_AFE_RATE_8K = 0,
++      MTK_AFE_RATE_11K = 1,
++      MTK_AFE_RATE_12K = 2,
++      MTK_AFE_RATE_16K = 4,
++      MTK_AFE_RATE_22K = 5,
++      MTK_AFE_RATE_24K = 6,
++      MTK_AFE_RATE_32K = 8,
++      MTK_AFE_RATE_44K = 9,
++      MTK_AFE_RATE_48K = 10,
++      MTK_AFE_RATE_88K = 13,
++      MTK_AFE_RATE_96K = 14,
++      MTK_AFE_RATE_176K = 17,
++      MTK_AFE_RATE_192K = 18,
++};
++
++enum {
++      CLK_INFRA_AUD_BUS_CK = 0,
++      CLK_INFRA_AUD_26M_CK,
++      CLK_INFRA_AUD_L_CK,
++      CLK_INFRA_AUD_AUD_CK,
++      CLK_INFRA_AUD_EG2_CK,
++      CLK_NUM
++};
++
++static const char *aud_clks[CLK_NUM] = {
++      [CLK_INFRA_AUD_BUS_CK] = "aud_bus_ck",
++      [CLK_INFRA_AUD_26M_CK] = "aud_26m_ck",
++      [CLK_INFRA_AUD_L_CK] = "aud_l_ck",
++      [CLK_INFRA_AUD_AUD_CK] = "aud_aud_ck",
++      [CLK_INFRA_AUD_EG2_CK] = "aud_eg2_ck",
++};
++
++unsigned int mt7986_afe_rate_transform(struct device *dev, unsigned int rate)
++{
++      switch (rate) {
++      case 8000:
++              return MTK_AFE_RATE_8K;
++      case 11025:
++              return MTK_AFE_RATE_11K;
++      case 12000:
++              return MTK_AFE_RATE_12K;
++      case 16000:
++              return MTK_AFE_RATE_16K;
++      case 22050:
++              return MTK_AFE_RATE_22K;
++      case 24000:
++              return MTK_AFE_RATE_24K;
++      case 32000:
++              return MTK_AFE_RATE_32K;
++      case 44100:
++              return MTK_AFE_RATE_44K;
++      case 48000:
++              return MTK_AFE_RATE_48K;
++      case 88200:
++              return MTK_AFE_RATE_88K;
++      case 96000:
++              return MTK_AFE_RATE_96K;
++      case 176400:
++              return MTK_AFE_RATE_176K;
++      case 192000:
++              return MTK_AFE_RATE_192K;
++      default:
++              dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n",
++                       __func__, rate, MTK_AFE_RATE_48K);
++              return MTK_AFE_RATE_48K;
++      }
++}
++
++static const struct snd_pcm_hardware mt7986_afe_hardware = {
++      .info = SNDRV_PCM_INFO_MMAP |
++              SNDRV_PCM_INFO_INTERLEAVED |
++              SNDRV_PCM_INFO_MMAP_VALID,
++      .formats = SNDRV_PCM_FMTBIT_S16_LE |
++                 SNDRV_PCM_FMTBIT_S24_LE |
++                 SNDRV_PCM_FMTBIT_S32_LE,
++      .period_bytes_min = 256,
++      .period_bytes_max = 4 * 48 * 1024,
++      .periods_min = 2,
++      .periods_max = 256,
++      .buffer_bytes_max = 8 * 48 * 1024,
++      .fifo_size = 0,
++};
++
++static int mt7986_memif_fs(struct snd_pcm_substream *substream,
++                         unsigned int rate)
++{
++      struct snd_soc_pcm_runtime *rtd = substream->private_data;
++      struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
++      struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
++
++      return mt7986_afe_rate_transform(afe->dev, rate);
++}
++
++static int mt7986_irq_fs(struct snd_pcm_substream *substream,
++                       unsigned int rate)
++{
++      struct snd_soc_pcm_runtime *rtd = substream->private_data;
++      struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
++      struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
++
++      return mt7986_afe_rate_transform(afe->dev, rate);
++}
++
++#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000 |\
++                     SNDRV_PCM_RATE_88200 |\
++                     SNDRV_PCM_RATE_96000 |\
++                     SNDRV_PCM_RATE_176400 |\
++                     SNDRV_PCM_RATE_192000)
++
++#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
++                       SNDRV_PCM_FMTBIT_S24_LE |\
++                       SNDRV_PCM_FMTBIT_S32_LE)
++
++static struct snd_soc_dai_driver mt7986_memif_dai_driver[] = {
++      /* FE DAIs: memory intefaces to CPU */
++      {
++              .name = "DL1",
++              .id = MT7986_MEMIF_DL1,
++              .playback = {
++                      .stream_name = "DL1",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MTK_PCM_RATES,
++                      .formats = MTK_PCM_FORMATS,
++              },
++              .ops = &mtk_afe_fe_ops,
++      },
++      {
++              .name = "UL1",
++              .id = MT7986_MEMIF_VUL12,
++              .capture = {
++                      .stream_name = "UL1",
++                      .channels_min = 1,
++                      .channels_max = 2,
++                      .rates = MTK_PCM_RATES,
++                      .formats = MTK_PCM_FORMATS,
++              },
++              .ops = &mtk_afe_fe_ops,
++      },
++};
++
++static const struct snd_kcontrol_new o018_mix[] = {
++      SOC_DAPM_SINGLE_AUTODISABLE("I150_Switch", AFE_CONN018_4, 22, 1, 0),
++};
++
++static const struct snd_kcontrol_new o019_mix[] = {
++      SOC_DAPM_SINGLE_AUTODISABLE("I151_Switch", AFE_CONN019_4, 23, 1, 0),
++};
++
++static const struct snd_soc_dapm_widget mt7986_memif_widgets[] = {
++      /* DL */
++      SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0),
++      SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0),
++
++      /* UL */
++      SND_SOC_DAPM_MIXER("O018", SND_SOC_NOPM, 0, 0,
++                         o018_mix, ARRAY_SIZE(o018_mix)),
++      SND_SOC_DAPM_MIXER("O019", SND_SOC_NOPM, 0, 0,
++                         o019_mix, ARRAY_SIZE(o019_mix)),
++};
++
++static const struct snd_soc_dapm_route mt7986_memif_routes[] = {
++      {"I032", NULL, "DL1"},
++      {"I033", NULL, "DL1"},
++      {"UL1", NULL, "O018"},
++      {"UL1", NULL, "O019"},
++      {"O018", "I150_Switch", "I150"},
++      {"O019", "I151_Switch", "I151"},
++};
++
++static const struct snd_soc_component_driver mt7986_afe_pcm_dai_component = {
++      .name = "mt7986-afe-pcm-dai",
++};
++
++static const struct mtk_base_memif_data memif_data[MT7986_MEMIF_NUM] = {
++      [MT7986_MEMIF_DL1] = {
++              .name = "DL1",
++              .id = MT7986_MEMIF_DL1,
++              .reg_ofs_base = AFE_DL0_BASE,
++              .reg_ofs_cur = AFE_DL0_CUR,
++              .reg_ofs_end = AFE_DL0_END,
++              .reg_ofs_base_msb = AFE_DL0_BASE_MSB,
++              .reg_ofs_cur_msb = AFE_DL0_CUR_MSB,
++              .reg_ofs_end_msb = AFE_DL0_END_MSB,
++              .fs_reg = AFE_DL0_CON0,
++              .fs_shift =  DL0_MODE_SFT,
++              .fs_maskbit =  DL0_MODE_MASK,
++              .mono_reg = AFE_DL0_CON0,
++              .mono_shift = DL0_MONO_SFT,
++              .enable_reg = AFE_DL0_CON0,
++              .enable_shift = DL0_ON_SFT,
++              .hd_reg = AFE_DL0_CON0,
++              .hd_shift = DL0_HD_MODE_SFT,
++              .hd_align_reg = AFE_DL0_CON0,
++              .hd_align_mshift = DL0_HALIGN_SFT,
++              .pbuf_reg = AFE_DL0_CON0,
++              .pbuf_shift = DL0_PBUF_SIZE_SFT,
++              .minlen_reg = AFE_DL0_CON0,
++              .minlen_shift = DL0_MINLEN_SFT,
++      },
++      [MT7986_MEMIF_VUL12] = {
++              .name = "VUL12",
++              .id = MT7986_MEMIF_VUL12,
++              .reg_ofs_base = AFE_VUL0_BASE,
++              .reg_ofs_cur = AFE_VUL0_CUR,
++              .reg_ofs_end = AFE_VUL0_END,
++              .reg_ofs_base_msb = AFE_VUL0_BASE_MSB,
++              .reg_ofs_cur_msb = AFE_VUL0_CUR_MSB,
++              .reg_ofs_end_msb = AFE_VUL0_END_MSB,
++              .fs_reg = AFE_VUL0_CON0,
++              .fs_shift = VUL0_MODE_SFT,
++              .fs_maskbit = VUL0_MODE_MASK,
++              .mono_reg = AFE_VUL0_CON0,
++              .mono_shift = VUL0_MONO_SFT,
++              .enable_reg = AFE_VUL0_CON0,
++              .enable_shift = VUL0_ON_SFT,
++              .hd_reg = AFE_VUL0_CON0,
++              .hd_shift = VUL0_HD_MODE_SFT,
++              .hd_align_reg = AFE_VUL0_CON0,
++              .hd_align_mshift = VUL0_HALIGN_SFT,
++      },
++};
++
++static const struct mtk_base_irq_data irq_data[MT7986_IRQ_NUM] = {
++      [MT7986_IRQ_0] = {
++              .id = MT7986_IRQ_0,
++              .irq_cnt_reg = AFE_IRQ0_MCU_CFG1,
++              .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
++              .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
++              .irq_fs_reg = AFE_IRQ0_MCU_CFG0,
++              .irq_fs_shift = IRQ_MCU_MODE_SFT,
++              .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
++              .irq_en_reg = AFE_IRQ0_MCU_CFG0,
++              .irq_en_shift = IRQ_MCU_ON_SFT,
++              .irq_clr_reg = AFE_IRQ_MCU_CLR,
++              .irq_clr_shift = IRQ0_MCU_CLR_SFT,
++      },
++      [MT7986_IRQ_1] = {
++              .id = MT7986_IRQ_1,
++              .irq_cnt_reg = AFE_IRQ1_MCU_CFG1,
++              .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
++              .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
++              .irq_fs_reg = AFE_IRQ1_MCU_CFG0,
++              .irq_fs_shift = IRQ_MCU_MODE_SFT,
++              .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
++              .irq_en_reg = AFE_IRQ1_MCU_CFG0,
++              .irq_en_shift = IRQ_MCU_ON_SFT,
++              .irq_clr_reg = AFE_IRQ_MCU_CLR,
++              .irq_clr_shift = IRQ1_MCU_CLR_SFT,
++      },
++      [MT7986_IRQ_2] = {
++              .id = MT7986_IRQ_2,
++              .irq_cnt_reg = AFE_IRQ2_MCU_CFG1,
++              .irq_cnt_shift = AFE_IRQ_CNT_SHIFT,
++              .irq_cnt_maskbit = AFE_IRQ_CNT_MASK,
++              .irq_fs_reg = AFE_IRQ2_MCU_CFG0,
++              .irq_fs_shift = IRQ_MCU_MODE_SFT,
++              .irq_fs_maskbit = IRQ_MCU_MODE_MASK,
++              .irq_en_reg = AFE_IRQ2_MCU_CFG0,
++              .irq_en_shift = IRQ_MCU_ON_SFT,
++              .irq_clr_reg = AFE_IRQ_MCU_CLR,
++              .irq_clr_shift = IRQ2_MCU_CLR_SFT,
++      },
++};
++
++static bool mt7986_is_volatile_reg(struct device *dev, unsigned int reg)
++{
++      /*
++       * Those auto-gen regs are read-only, so put it as volatile because
++       * volatile registers cannot be cached, which means that they cannot
++       * be set when power is off
++       */
++
++      switch (reg) {
++      case AFE_DL0_CUR_MSB:
++      case AFE_DL0_CUR:
++      case AFE_DL0_RCH_MON:
++      case AFE_DL0_LCH_MON:
++      case AFE_VUL0_CUR_MSB:
++      case AFE_VUL0_CUR:
++      case AFE_IRQ_MCU_STATUS:
++      case AFE_MEMIF_RD_MON:
++      case AFE_MEMIF_WR_MON:
++              return true;
++      default:
++              return false;
++      };
++}
++
++static const struct regmap_config mt7986_afe_regmap_config = {
++      .reg_bits = 32,
++      .reg_stride = 4,
++      .val_bits = 32,
++      .volatile_reg = mt7986_is_volatile_reg,
++      .max_register = AFE_MAX_REGISTER,
++      .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1),
++};
++
++static int mt7986_init_clock(struct mtk_base_afe *afe)
++{
++      struct mt7986_afe_private *afe_priv = afe->platform_priv;
++      int ret, i;
++
++      afe_priv->clks = devm_kcalloc(afe->dev, CLK_NUM,
++                              sizeof(*afe_priv->clks), GFP_KERNEL);
++      if (!afe_priv->clks)
++              return -ENOMEM;
++      afe_priv->num_clks = CLK_NUM;
++
++      for (i = 0; i < afe_priv->num_clks; i++)
++              afe_priv->clks[i].id = aud_clks[i];
++
++      ret = devm_clk_bulk_get(afe->dev, afe_priv->num_clks, afe_priv->clks);
++      if (ret)
++              return dev_err_probe(afe->dev, ret, "Failed to get clocks\n");
++
++      return 0;
++}
++
++static irqreturn_t mt7986_afe_irq_handler(int irq_id, void *dev)
++{
++      struct mtk_base_afe *afe = dev;
++      struct mtk_base_afe_irq *irq;
++      u32 mcu_en, status, status_mcu;
++      int i, ret;
++      irqreturn_t irq_ret = IRQ_HANDLED;
++
++      /* get irq that is sent to MCU */
++      regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en);
++
++      ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status);
++      /* only care IRQ which is sent to MCU */
++      status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS;
++
++      if (ret || status_mcu == 0) {
++              dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, mcu_en 0x%x\n",
++                      __func__, ret, status, mcu_en);
++
++              irq_ret = IRQ_NONE;
++              goto err_irq;
++      }
++
++      for (i = 0; i < MT7986_MEMIF_NUM; i++) {
++              struct mtk_base_afe_memif *memif = &afe->memif[i];
++
++              if (!memif->substream)
++                      continue;
++
++              if (memif->irq_usage < 0)
++                      continue;
++
++              irq = &afe->irqs[memif->irq_usage];
++
++              if (status_mcu & (1 << irq->irq_data->irq_en_shift))
++                      snd_pcm_period_elapsed(memif->substream);
++      }
++
++err_irq:
++      /* clear irq */
++      regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, status_mcu);
++
++      return irq_ret;
++}
++
++static int mt7986_afe_runtime_suspend(struct device *dev)
++{
++      struct mtk_base_afe *afe = dev_get_drvdata(dev);
++      struct mt7986_afe_private *afe_priv = afe->platform_priv;
++
++      if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
++              goto skip_regmap;
++
++      /* disable clk*/
++      regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0x3fff);
++      regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK, 0);
++      regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK, 0);
++
++      /* make sure all irq status are cleared, twice intended */
++      regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CLR, 0xffff, 0xffff);
++
++skip_regmap:
++      clk_bulk_disable_unprepare(afe_priv->num_clks, afe_priv->clks);
++
++      return 0;
++}
++
++static int mt7986_afe_runtime_resume(struct device *dev)
++{
++      struct mtk_base_afe *afe = dev_get_drvdata(dev);
++      struct mt7986_afe_private *afe_priv = afe->platform_priv;
++      int ret;
++
++      ret = clk_bulk_prepare_enable(afe_priv->num_clks, afe_priv->clks);
++      if (ret)
++              return dev_err_probe(afe->dev, ret, "Failed to enable clocks\n");
++
++      if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
++              return 0;
++
++      /* enable clk*/
++      regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0);
++      regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK,
++                         AUD_APLL2_EN);
++      regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK,
++                         AUD_26M_EN);
++
++      return 0;
++}
++
++static int mt7986_afe_component_probe(struct snd_soc_component *component)
++{
++      return mtk_afe_add_sub_dai_control(component);
++}
++
++static const struct snd_soc_component_driver mt7986_afe_component = {
++      .name = AFE_PCM_NAME,
++      .probe = mt7986_afe_component_probe,
++      .pointer        = mtk_afe_pcm_pointer,
++      .pcm_construct  = mtk_afe_pcm_new,
++};
++
++static int mt7986_dai_memif_register(struct mtk_base_afe *afe)
++{
++      struct mtk_base_afe_dai *dai;
++
++      dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
++      if (!dai)
++              return -ENOMEM;
++
++      list_add(&dai->list, &afe->sub_dais);
++
++      dai->dai_drivers = mt7986_memif_dai_driver;
++      dai->num_dai_drivers = ARRAY_SIZE(mt7986_memif_dai_driver);
++
++      dai->dapm_widgets = mt7986_memif_widgets;
++      dai->num_dapm_widgets = ARRAY_SIZE(mt7986_memif_widgets);
++      dai->dapm_routes = mt7986_memif_routes;
++      dai->num_dapm_routes = ARRAY_SIZE(mt7986_memif_routes);
++
++      return 0;
++}
++
++typedef int (*dai_register_cb)(struct mtk_base_afe *);
++static const dai_register_cb dai_register_cbs[] = {
++      mt7986_dai_etdm_register,
++      mt7986_dai_memif_register,
++};
++
++static int mt7986_afe_pcm_dev_probe(struct platform_device *pdev)
++{
++      struct mtk_base_afe *afe;
++      struct mt7986_afe_private *afe_priv;
++      struct device *dev;
++      int i, irq_id, ret;
++
++      afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
++      if (!afe)
++              return -ENOMEM;
++      platform_set_drvdata(pdev, afe);
++
++      afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
++                                        GFP_KERNEL);
++      if (!afe->platform_priv)
++              return -ENOMEM;
++
++      afe_priv = afe->platform_priv;
++      afe->dev = &pdev->dev;
++      dev = afe->dev;
++
++      afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
++      if (IS_ERR(afe->base_addr))
++              return PTR_ERR(afe->base_addr);
++
++      /* initial audio related clock */
++      ret = mt7986_init_clock(afe);
++      if (ret)
++              return dev_err_probe(dev, ret, "Cannot initialize clocks\n");
++
++      ret = devm_pm_runtime_enable(dev);
++      if (ret)
++              return ret;
++
++      /* enable clock for regcache get default value from hw */
++      afe_priv->pm_runtime_bypass_reg_ctl = true;
++      pm_runtime_get_sync(&pdev->dev);
++
++      afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
++                    &mt7986_afe_regmap_config);
++
++      pm_runtime_put_sync(&pdev->dev);
++      if (IS_ERR(afe->regmap))
++              return PTR_ERR(afe->regmap);
++
++      afe_priv->pm_runtime_bypass_reg_ctl = false;
++
++      /* init memif */
++      afe->memif_size = MT7986_MEMIF_NUM;
++      afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
++                                GFP_KERNEL);
++      if (!afe->memif)
++              return -ENOMEM;
++
++      for (i = 0; i < afe->memif_size; i++) {
++              afe->memif[i].data = &memif_data[i];
++              afe->memif[i].irq_usage = -1;
++      }
++
++      mutex_init(&afe->irq_alloc_lock);
++
++      /* irq initialize */
++      afe->irqs_size = MT7986_IRQ_NUM;
++      afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
++                               GFP_KERNEL);
++      if (!afe->irqs)
++              return -ENOMEM;
++
++      for (i = 0; i < afe->irqs_size; i++)
++              afe->irqs[i].irq_data = &irq_data[i];
++
++      /* request irq */
++      irq_id = platform_get_irq(pdev, 0);
++      if (irq_id < 0) {
++              ret = irq_id;
++              return dev_err_probe(dev, ret, "No irq found\n");
++      }
++      ret = devm_request_irq(dev, irq_id, mt7986_afe_irq_handler,
++                             IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to request irq for asys-isr\n");
++
++      /* init sub_dais */
++      INIT_LIST_HEAD(&afe->sub_dais);
++
++      for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
++              ret = dai_register_cbs[i](afe);
++              if (ret)
++                      return dev_err_probe(dev, ret, "DAI register failed, i: %d\n", i);
++      }
++
++      /* init dai_driver and component_driver */
++      ret = mtk_afe_combine_sub_dai(afe);
++      if (ret)
++              return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n");
++
++      afe->mtk_afe_hardware = &mt7986_afe_hardware;
++      afe->memif_fs = mt7986_memif_fs;
++      afe->irq_fs = mt7986_irq_fs;
++
++      afe->runtime_resume = mt7986_afe_runtime_resume;
++      afe->runtime_suspend = mt7986_afe_runtime_suspend;
++
++      /* register component */
++      ret = devm_snd_soc_register_component(&pdev->dev,
++                                            &mt7986_afe_component,
++                                            NULL, 0);
++      if (ret)
++              return dev_err_probe(dev, ret, "Cannot register AFE component\n");
++
++      ret = devm_snd_soc_register_component(afe->dev,
++                                            &mt7986_afe_pcm_dai_component,
++                                            afe->dai_drivers,
++                                            afe->num_dai_drivers);
++      if (ret)
++              return dev_err_probe(dev, ret, "Cannot register PCM DAI component\n");
++
++      return 0;
++}
++
++static void mt7986_afe_pcm_dev_remove(struct platform_device *pdev)
++{
++      pm_runtime_disable(&pdev->dev);
++      if (!pm_runtime_status_suspended(&pdev->dev))
++              mt7986_afe_runtime_suspend(&pdev->dev);
++}
++
++static const struct of_device_id mt7986_afe_pcm_dt_match[] = {
++      { .compatible = "mediatek,mt7986-afe" },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, mt7986_afe_pcm_dt_match);
++
++static const struct dev_pm_ops mt7986_afe_pm_ops = {
++      SET_RUNTIME_PM_OPS(mt7986_afe_runtime_suspend,
++                         mt7986_afe_runtime_resume, NULL)
++};
++
++static struct platform_driver mt7986_afe_pcm_driver = {
++      .driver = {
++                 .name = "mt7986-audio",
++                 .of_match_table = mt7986_afe_pcm_dt_match,
++                 .pm = &mt7986_afe_pm_ops,
++      },
++      .probe = mt7986_afe_pcm_dev_probe,
++      .remove_new = mt7986_afe_pcm_dev_remove,
++};
++module_platform_driver(mt7986_afe_pcm_driver);
++
++MODULE_DESCRIPTION("MediaTek SoC AFE platform driver for ALSA MT7986");
++MODULE_AUTHOR("Vic Wu <vic.wu@mediatek.com>");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/mediatek/patches-6.6/860-v6.6-04-ASoC-mediatek-mt7986-add-machine-driver-with-wm8960.patch b/target/linux/mediatek/patches-6.6/860-v6.6-04-ASoC-mediatek-mt7986-add-machine-driver-with-wm8960.patch
new file mode 100644 (file)
index 0000000..dd354c0
--- /dev/null
@@ -0,0 +1,243 @@
+From ddf6abc1c78072f8ccad59166be95f0ca5af8ca4 Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Thu, 17 Aug 2023 18:13:36 +0800
+Subject: [PATCH 4/9] ASoC: mediatek: mt7986: add machine driver with wm8960
+
+Add support for mt7986 board with wm8960.
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230817101338.18782-5-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/Kconfig                |  10 ++
+ sound/soc/mediatek/mt7986/Makefile        |   1 +
+ sound/soc/mediatek/mt7986/mt7986-wm8960.c | 196 ++++++++++++++++++++++
+ 3 files changed, 207 insertions(+)
+ create mode 100644 sound/soc/mediatek/mt7986/mt7986-wm8960.c
+
+--- a/sound/soc/mediatek/Kconfig
++++ b/sound/soc/mediatek/Kconfig
+@@ -64,6 +64,16 @@ config SND_SOC_MT7986
+         Select Y if you have such device.
+         If unsure select "N".
++config SND_SOC_MT7986_WM8960
++      tristate "ASoc Audio driver for MT7986 with WM8960 codec"
++      depends on SND_SOC_MT7986 && I2C
++      select SND_SOC_WM8960
++      help
++        This adds support for ASoC machine driver for MediaTek MT7986
++        boards with the WM8960 codecs.
++        Select Y if you have such device.
++        If unsure select "N".
++
+ config SND_SOC_MT8173
+       tristate "ASoC support for Mediatek MT8173 chip"
+       depends on ARCH_MEDIATEK
+--- a/sound/soc/mediatek/mt7986/Makefile
++++ b/sound/soc/mediatek/mt7986/Makefile
+@@ -6,3 +6,4 @@ snd-soc-mt7986-afe-objs := \
+       mt7986-dai-etdm.o
+ obj-$(CONFIG_SND_SOC_MT7986) += snd-soc-mt7986-afe.o
++obj-$(CONFIG_SND_SOC_MT7986_WM8960) += mt7986-wm8960.o
+--- /dev/null
++++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c
+@@ -0,0 +1,196 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * mt7986-wm8960.c  --  MT7986-WM8960 ALSA SoC machine driver
++ *
++ * Copyright (c) 2023 MediaTek Inc.
++ * Authors: Vic Wu <vic.wu@mediatek.com>
++ *          Maso Huang <maso.huang@mediatek.com>
++ */
++
++#include <linux/module.h>
++#include <sound/soc.h>
++
++#include "mt7986-afe-common.h"
++
++struct mt7986_wm8960_priv {
++      struct device_node *platform_node;
++      struct device_node *codec_node;
++};
++
++static const struct snd_soc_dapm_widget mt7986_wm8960_widgets[] = {
++      SND_SOC_DAPM_HP("Headphone", NULL),
++      SND_SOC_DAPM_MIC("AMIC", NULL),
++};
++
++static const struct snd_kcontrol_new mt7986_wm8960_controls[] = {
++      SOC_DAPM_PIN_SWITCH("Headphone"),
++      SOC_DAPM_PIN_SWITCH("AMIC"),
++};
++
++SND_SOC_DAILINK_DEFS(playback,
++      DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
++      DAILINK_COMP_ARRAY(COMP_DUMMY()),
++      DAILINK_COMP_ARRAY(COMP_EMPTY()));
++
++SND_SOC_DAILINK_DEFS(capture,
++      DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
++      DAILINK_COMP_ARRAY(COMP_DUMMY()),
++      DAILINK_COMP_ARRAY(COMP_EMPTY()));
++
++SND_SOC_DAILINK_DEFS(codec,
++      DAILINK_COMP_ARRAY(COMP_CPU("ETDM")),
++      DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8960-hifi")),
++      DAILINK_COMP_ARRAY(COMP_EMPTY()));
++
++static struct snd_soc_dai_link mt7986_wm8960_dai_links[] = {
++      /* FE */
++      {
++              .name = "wm8960-playback",
++              .stream_name = "wm8960-playback",
++              .trigger = {SND_SOC_DPCM_TRIGGER_POST,
++                          SND_SOC_DPCM_TRIGGER_POST},
++              .dynamic = 1,
++              .dpcm_playback = 1,
++              SND_SOC_DAILINK_REG(playback),
++      },
++      {
++              .name = "wm8960-capture",
++              .stream_name = "wm8960-capture",
++              .trigger = {SND_SOC_DPCM_TRIGGER_POST,
++                          SND_SOC_DPCM_TRIGGER_POST},
++              .dynamic = 1,
++              .dpcm_capture = 1,
++              SND_SOC_DAILINK_REG(capture),
++      },
++      /* BE */
++      {
++              .name = "wm8960-codec",
++              .no_pcm = 1,
++              .dai_fmt = SND_SOC_DAIFMT_I2S |
++                      SND_SOC_DAIFMT_NB_NF |
++                      SND_SOC_DAIFMT_CBS_CFS |
++                      SND_SOC_DAIFMT_GATED,
++              .dpcm_playback = 1,
++              .dpcm_capture = 1,
++              SND_SOC_DAILINK_REG(codec),
++      },
++};
++
++static struct snd_soc_card mt7986_wm8960_card = {
++      .name = "mt7986-wm8960",
++      .owner = THIS_MODULE,
++      .dai_link = mt7986_wm8960_dai_links,
++      .num_links = ARRAY_SIZE(mt7986_wm8960_dai_links),
++      .controls = mt7986_wm8960_controls,
++      .num_controls = ARRAY_SIZE(mt7986_wm8960_controls),
++      .dapm_widgets = mt7986_wm8960_widgets,
++      .num_dapm_widgets = ARRAY_SIZE(mt7986_wm8960_widgets),
++};
++
++static int mt7986_wm8960_machine_probe(struct platform_device *pdev)
++{
++      struct snd_soc_card *card = &mt7986_wm8960_card;
++      struct snd_soc_dai_link *dai_link;
++      struct device_node *platform, *codec;
++      struct mt7986_wm8960_priv *priv;
++      int ret, i;
++
++      priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++
++      platform = of_get_child_by_name(pdev->dev.of_node, "platform");
++
++      if (platform) {
++              priv->platform_node = of_parse_phandle(platform, "sound-dai", 0);
++              of_node_put(platform);
++
++              if (!priv->platform_node) {
++                      dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n");
++                      return -EINVAL;
++              }
++      } else {
++              dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
++              return -EINVAL;
++      }
++
++      for_each_card_prelinks(card, i, dai_link) {
++              if (dai_link->platforms->name)
++                      continue;
++              dai_link->platforms->of_node = priv->platform_node;
++      }
++
++      card->dev = &pdev->dev;
++
++      codec = of_get_child_by_name(pdev->dev.of_node, "codec");
++
++      if (codec) {
++              priv->codec_node = of_parse_phandle(codec, "sound-dai", 0);
++              of_node_put(codec);
++
++              if (!priv->codec_node) {
++                      of_node_put(priv->platform_node);
++                      dev_err(&pdev->dev, "Failed to parse codec/sound-dai property\n");
++                      return -EINVAL;
++              }
++      } else {
++              of_node_put(priv->platform_node);
++              dev_err(&pdev->dev, "Property 'codec' missing or invalid\n");
++              return -EINVAL;
++      }
++
++      for_each_card_prelinks(card, i, dai_link) {
++              if (dai_link->codecs->name)
++                      continue;
++              dai_link->codecs->of_node = priv->codec_node;
++      }
++
++      ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
++      if (ret) {
++              dev_err(&pdev->dev, "Failed to parse audio-routing: %d\n", ret);
++              goto err_of_node_put;
++      }
++
++      ret = devm_snd_soc_register_card(&pdev->dev, card);
++      if (ret) {
++              dev_err(&pdev->dev, "%s snd_soc_register_card fail: %d\n", __func__, ret);
++              goto err_of_node_put;
++      }
++
++err_of_node_put:
++      of_node_put(priv->codec_node);
++      of_node_put(priv->platform_node);
++      return ret;
++}
++
++static void mt7986_wm8960_machine_remove(struct platform_device *pdev)
++{
++      struct snd_soc_card *card = platform_get_drvdata(pdev);
++      struct mt7986_wm8960_priv *priv = snd_soc_card_get_drvdata(card);
++
++      of_node_put(priv->codec_node);
++      of_node_put(priv->platform_node);
++}
++
++static const struct of_device_id mt7986_wm8960_machine_dt_match[] = {
++      {.compatible = "mediatek,mt7986-wm8960-sound"},
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, mt7986_wm8960_machine_dt_match);
++
++static struct platform_driver mt7986_wm8960_machine = {
++      .driver = {
++              .name = "mt7986-wm8960",
++              .of_match_table = mt7986_wm8960_machine_dt_match,
++      },
++      .probe = mt7986_wm8960_machine_probe,
++      .remove_new = mt7986_wm8960_machine_remove,
++};
++
++module_platform_driver(mt7986_wm8960_machine);
++
++/* Module information */
++MODULE_DESCRIPTION("MT7986 WM8960 ALSA SoC machine driver");
++MODULE_AUTHOR("Vic Wu <vic.wu@mediatek.com>");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("mt7986 wm8960 soc card");
diff --git a/target/linux/mediatek/patches-6.6/860-v6.6-05-ASoC-dt-bindings-mediatek-mt7986-wm8960-add-mt7986-w.patch b/target/linux/mediatek/patches-6.6/860-v6.6-05-ASoC-dt-bindings-mediatek-mt7986-wm8960-add-mt7986-w.patch
new file mode 100644 (file)
index 0000000..8cf0b54
--- /dev/null
@@ -0,0 +1,87 @@
+From 72469f950b629e57e60fbcbefed45e083619b986 Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Thu, 17 Aug 2023 18:13:37 +0800
+Subject: [PATCH 5/9] ASoC: dt-bindings: mediatek,mt7986-wm8960: add
+ mt7986-wm8960 document
+
+Add document for mt7986 board with wm8960.
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230817101338.18782-6-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ .../sound/mediatek,mt7986-wm8960.yaml         | 67 +++++++++++++++++++
+ 1 file changed, 67 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt7986-wm8960.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/sound/mediatek,mt7986-wm8960.yaml
+@@ -0,0 +1,67 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/sound/mediatek,mt7986-wm8960.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: MediaTek MT7986 sound card with WM8960 codec
++
++maintainers:
++  - Maso Huang <maso.huang@mediatek.com>
++
++allOf:
++  - $ref: sound-card-common.yaml#
++
++properties:
++  compatible:
++    const: mediatek,mt7986-wm8960-sound
++
++  platform:
++    type: object
++    additionalProperties: false
++    properties:
++      sound-dai:
++        description: The phandle of MT7986 platform.
++        maxItems: 1
++    required:
++      - sound-dai
++
++  codec:
++    type: object
++    additionalProperties: false
++    properties:
++      sound-dai:
++        description: The phandle of wm8960 codec.
++        maxItems: 1
++    required:
++      - sound-dai
++
++unevaluatedProperties: false
++
++required:
++  - compatible
++  - audio-routing
++  - platform
++  - codec
++
++examples:
++  - |
++    sound {
++        compatible = "mediatek,mt7986-wm8960-sound";
++        model = "mt7986-wm8960";
++        audio-routing =
++            "Headphone", "HP_L",
++            "Headphone", "HP_R",
++            "LINPUT1", "AMIC",
++            "RINPUT1", "AMIC";
++
++        platform {
++            sound-dai = <&afe>;
++        };
++
++        codec {
++            sound-dai = <&wm8960>;
++        };
++    };
++
++...
diff --git a/target/linux/mediatek/patches-6.6/860-v6.6-06-ASoC-dt-bindings-mediatek-mt7986-afe-add-audio-afe-d.patch b/target/linux/mediatek/patches-6.6/860-v6.6-06-ASoC-dt-bindings-mediatek-mt7986-afe-add-audio-afe-d.patch
new file mode 100644 (file)
index 0000000..236d6a2
--- /dev/null
@@ -0,0 +1,180 @@
+From d16202eb38585adbc16e32d11188dbc2127015de Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Thu, 17 Aug 2023 18:13:38 +0800
+Subject: [PATCH 6/9] ASoC: dt-bindings: mediatek,mt7986-afe: add audio afe
+ document
+
+Add mt7986 audio afe document.
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20230817101338.18782-7-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ .../bindings/sound/mediatek,mt7986-afe.yaml   | 160 ++++++++++++++++++
+ 1 file changed, 160 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt7986-afe.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/sound/mediatek,mt7986-afe.yaml
+@@ -0,0 +1,160 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/sound/mediatek,mt7986-afe.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: MediaTek AFE PCM controller for MT7986
++
++maintainers:
++  - Maso Huang <maso.huang@mediatek.com>
++
++properties:
++  compatible:
++    oneOf:
++      - const: mediatek,mt7986-afe
++      - items:
++          - enum:
++              - mediatek,mt7981-afe
++              - mediatek,mt7988-afe
++          - const: mediatek,mt7986-afe
++
++  reg:
++    maxItems: 1
++
++  interrupts:
++    maxItems: 1
++
++  clocks:
++    minItems: 5
++    items:
++      - description: audio bus clock
++      - description: audio 26M clock
++      - description: audio intbus clock
++      - description: audio hopping clock
++      - description: audio pll clock
++      - description: mux for pcm_mck
++      - description: audio i2s/pcm mck
++
++  clock-names:
++    minItems: 5
++    items:
++      - const: bus_ck
++      - const: 26m_ck
++      - const: l_ck
++      - const: aud_ck
++      - const: eg2_ck
++      - const: sel
++      - const: i2s_m
++
++required:
++  - compatible
++  - reg
++  - interrupts
++  - clocks
++  - clock-names
++
++allOf:
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: mediatek,mt7986-afe
++    then:
++      properties:
++        clocks:
++          items:
++            - description: audio bus clock
++            - description: audio 26M clock
++            - description: audio intbus clock
++            - description: audio hopping clock
++            - description: audio pll clock
++        clock-names:
++          items:
++            - const: bus_ck
++            - const: 26m_ck
++            - const: l_ck
++            - const: aud_ck
++            - const: eg2_ck
++
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: mediatek,mt7981-afe
++    then:
++      properties:
++        clocks:
++          items:
++            - description: audio bus clock
++            - description: audio 26M clock
++            - description: audio intbus clock
++            - description: audio hopping clock
++            - description: audio pll clock
++            - description: mux for pcm_mck
++        clock-names:
++          items:
++            - const: bus_ck
++            - const: 26m_ck
++            - const: l_ck
++            - const: aud_ck
++            - const: eg2_ck
++            - const: sel
++
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: mediatek,mt7988-afe
++    then:
++      properties:
++        clocks:
++          items:
++            - description: audio bus clock
++            - description: audio 26M clock
++            - description: audio intbus clock
++            - description: audio hopping clock
++            - description: audio pll clock
++            - description: mux for pcm_mck
++            - description: audio i2s/pcm mck
++        clock-names:
++          items:
++            - const: bus_ck
++            - const: 26m_ck
++            - const: l_ck
++            - const: aud_ck
++            - const: eg2_ck
++            - const: sel
++            - const: i2s_m
++
++additionalProperties: false
++
++examples:
++  - |
++    #include <dt-bindings/interrupt-controller/arm-gic.h>
++    #include <dt-bindings/interrupt-controller/irq.h>
++    #include <dt-bindings/clock/mt7986-clk.h>
++
++    afe@11210000 {
++        compatible = "mediatek,mt7986-afe";
++        reg = <0x11210000 0x9000>;
++        interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
++        clocks = <&infracfg_ao CLK_INFRA_AUD_BUS_CK>,
++                 <&infracfg_ao CLK_INFRA_AUD_26M_CK>,
++                 <&infracfg_ao CLK_INFRA_AUD_L_CK>,
++                 <&infracfg_ao CLK_INFRA_AUD_AUD_CK>,
++                 <&infracfg_ao CLK_INFRA_AUD_EG2_CK>;
++        clock-names = "bus_ck",
++                      "26m_ck",
++                      "l_ck",
++                      "aud_ck",
++                      "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>;
++    };
++
++...
diff --git a/target/linux/mediatek/patches-6.6/860-v6.7-07-ASoC-mediatek-mt7986-drop-the-remove-callback-of-mt7.patch b/target/linux/mediatek/patches-6.6/860-v6.7-07-ASoC-mediatek-mt7986-drop-the-remove-callback-of-mt7.patch
new file mode 100644 (file)
index 0000000..413db82
--- /dev/null
@@ -0,0 +1,42 @@
+From f3f0934e5c7b9c16e0cb2435be3555382e6293ad Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Tue, 24 Oct 2023 11:50:17 +0800
+Subject: [PATCH 7/9] ASoC: mediatek: mt7986: drop the remove callback of
+ mt7986_wm8960
+
+Drop the remove callback of mt7986_wm8960.
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20231024035019.11732-2-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt7986/mt7986-wm8960.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/sound/soc/mediatek/mt7986/mt7986-wm8960.c
++++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c
+@@ -163,15 +163,6 @@ err_of_node_put:
+       return ret;
+ }
+-static void mt7986_wm8960_machine_remove(struct platform_device *pdev)
+-{
+-      struct snd_soc_card *card = platform_get_drvdata(pdev);
+-      struct mt7986_wm8960_priv *priv = snd_soc_card_get_drvdata(card);
+-
+-      of_node_put(priv->codec_node);
+-      of_node_put(priv->platform_node);
+-}
+-
+ static const struct of_device_id mt7986_wm8960_machine_dt_match[] = {
+       {.compatible = "mediatek,mt7986-wm8960-sound"},
+       { /* sentinel */ }
+@@ -184,7 +175,6 @@ static struct platform_driver mt7986_wm8
+               .of_match_table = mt7986_wm8960_machine_dt_match,
+       },
+       .probe = mt7986_wm8960_machine_probe,
+-      .remove_new = mt7986_wm8960_machine_remove,
+ };
+ module_platform_driver(mt7986_wm8960_machine);
diff --git a/target/linux/mediatek/patches-6.6/860-v6.7-08-ASoC-mediatek-mt7986-remove-the-mt7986_wm8960_priv-s.patch b/target/linux/mediatek/patches-6.6/860-v6.7-08-ASoC-mediatek-mt7986-remove-the-mt7986_wm8960_priv-s.patch
new file mode 100644 (file)
index 0000000..5c596fc
--- /dev/null
@@ -0,0 +1,105 @@
+From 98b8fb2cb4fcab1903d0baf611bf0c3f822a08dc Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Tue, 24 Oct 2023 11:50:18 +0800
+Subject: [PATCH 8/9] ASoC: mediatek: mt7986: remove the mt7986_wm8960_priv
+ structure
+
+Remove the mt7986_wm8960_priv structure.
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20231024035019.11732-3-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt7986/mt7986-wm8960.c | 33 +++++++++--------------
+ 1 file changed, 12 insertions(+), 21 deletions(-)
+
+--- a/sound/soc/mediatek/mt7986/mt7986-wm8960.c
++++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c
+@@ -12,11 +12,6 @@
+ #include "mt7986-afe-common.h"
+-struct mt7986_wm8960_priv {
+-      struct device_node *platform_node;
+-      struct device_node *codec_node;
+-};
+-
+ static const struct snd_soc_dapm_widget mt7986_wm8960_widgets[] = {
+       SND_SOC_DAPM_HP("Headphone", NULL),
+       SND_SOC_DAPM_MIC("AMIC", NULL),
+@@ -92,20 +87,18 @@ static int mt7986_wm8960_machine_probe(s
+       struct snd_soc_card *card = &mt7986_wm8960_card;
+       struct snd_soc_dai_link *dai_link;
+       struct device_node *platform, *codec;
+-      struct mt7986_wm8960_priv *priv;
++      struct device_node *platform_dai_node, *codec_dai_node;
+       int ret, i;
+-      priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+-      if (!priv)
+-              return -ENOMEM;
++      card->dev = &pdev->dev;
+       platform = of_get_child_by_name(pdev->dev.of_node, "platform");
+       if (platform) {
+-              priv->platform_node = of_parse_phandle(platform, "sound-dai", 0);
++              platform_dai_node = of_parse_phandle(platform, "sound-dai", 0);
+               of_node_put(platform);
+-              if (!priv->platform_node) {
++              if (!platform_dai_node) {
+                       dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n");
+                       return -EINVAL;
+               }
+@@ -117,24 +110,22 @@ static int mt7986_wm8960_machine_probe(s
+       for_each_card_prelinks(card, i, dai_link) {
+               if (dai_link->platforms->name)
+                       continue;
+-              dai_link->platforms->of_node = priv->platform_node;
++              dai_link->platforms->of_node = platform_dai_node;
+       }
+-      card->dev = &pdev->dev;
+-
+       codec = of_get_child_by_name(pdev->dev.of_node, "codec");
+       if (codec) {
+-              priv->codec_node = of_parse_phandle(codec, "sound-dai", 0);
++              codec_dai_node = of_parse_phandle(codec, "sound-dai", 0);
+               of_node_put(codec);
+-              if (!priv->codec_node) {
+-                      of_node_put(priv->platform_node);
++              if (!codec_dai_node) {
++                      of_node_put(platform_dai_node);
+                       dev_err(&pdev->dev, "Failed to parse codec/sound-dai property\n");
+                       return -EINVAL;
+               }
+       } else {
+-              of_node_put(priv->platform_node);
++              of_node_put(platform_dai_node);
+               dev_err(&pdev->dev, "Property 'codec' missing or invalid\n");
+               return -EINVAL;
+       }
+@@ -142,7 +133,7 @@ static int mt7986_wm8960_machine_probe(s
+       for_each_card_prelinks(card, i, dai_link) {
+               if (dai_link->codecs->name)
+                       continue;
+-              dai_link->codecs->of_node = priv->codec_node;
++              dai_link->codecs->of_node = codec_dai_node;
+       }
+       ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
+@@ -158,8 +149,8 @@ static int mt7986_wm8960_machine_probe(s
+       }
+ err_of_node_put:
+-      of_node_put(priv->codec_node);
+-      of_node_put(priv->platform_node);
++      of_node_put(platform_dai_node);
++      of_node_put(codec_dai_node);
+       return ret;
+ }
diff --git a/target/linux/mediatek/patches-6.6/860-v6.7-09-ASoC-mediatek-mt7986-add-sample-rate-checker.patch b/target/linux/mediatek/patches-6.6/860-v6.7-09-ASoC-mediatek-mt7986-add-sample-rate-checker.patch
new file mode 100644 (file)
index 0000000..d4128de
--- /dev/null
@@ -0,0 +1,49 @@
+From 4e229f4264f4be7a6a554487714c0913ef59cf7f Mon Sep 17 00:00:00 2001
+From: Maso Huang <maso.huang@mediatek.com>
+Date: Tue, 24 Oct 2023 11:50:19 +0800
+Subject: [PATCH 9/9] ASoC: mediatek: mt7986: add sample rate checker
+
+mt7986 only supports 8/12/16/24/32/48/96/192 kHz
+
+Signed-off-by: Maso Huang <maso.huang@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20231024035019.11732-4-maso.huang@mediatek.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/mediatek/mt7986/mt7986-dai-etdm.c | 23 +++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c
++++ b/sound/soc/mediatek/mt7986/mt7986-dai-etdm.c
+@@ -237,12 +237,27 @@ static int mtk_dai_etdm_hw_params(struct
+                                 struct snd_pcm_hw_params *params,
+                                 struct snd_soc_dai *dai)
+ {
++      unsigned int rate = params_rate(params);
+       struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+-      mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_PLAYBACK);
+-      mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_CAPTURE);
+-
+-      return 0;
++      switch (rate) {
++      case 8000:
++      case 12000:
++      case 16000:
++      case 24000:
++      case 32000:
++      case 48000:
++      case 96000:
++      case 192000:
++              mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_PLAYBACK);
++              mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_CAPTURE);
++              return 0;
++      default:
++              dev_err(afe->dev,
++                      "Sample rate %d invalid. Supported rates: 8/12/16/24/32/48/96/192 kHz\n",
++                      rate);
++              return -EINVAL;
++      }
+ }
+ static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd,
diff --git a/target/linux/mediatek/patches-6.6/861-pending-10-ASoC-mediatek-mt7986-silence-error-in-case-of-EPROBE.patch b/target/linux/mediatek/patches-6.6/861-pending-10-ASoC-mediatek-mt7986-silence-error-in-case-of-EPROBE.patch
new file mode 100644 (file)
index 0000000..a40c249
--- /dev/null
@@ -0,0 +1,26 @@
+From e4cde335d1771863a60b6931e51357b8470e85c4 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 10 Dec 2023 22:41:39 +0000
+Subject: [PATCH] ASoC: mediatek: mt7986: silence error in case of
+ -EPROBE_DEFER
+
+If probe is defered no error should be printed. Mute it.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ sound/soc/mediatek/mt7986/mt7986-wm8960.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/mediatek/mt7986/mt7986-wm8960.c
++++ b/sound/soc/mediatek/mt7986/mt7986-wm8960.c
+@@ -144,7 +144,9 @@ static int mt7986_wm8960_machine_probe(s
+       ret = devm_snd_soc_register_card(&pdev->dev, card);
+       if (ret) {
+-              dev_err(&pdev->dev, "%s snd_soc_register_card fail: %d\n", __func__, ret);
++              if (ret != -EPROBE_DEFER)
++                      dev_err(&pdev->dev, "%s snd_soc_register_card fail: %d\n", __func__, ret);
++
+               goto err_of_node_put;
+       }
diff --git a/target/linux/mediatek/patches-6.6/862-arm64-dts-mt7986-add-afe.patch b/target/linux/mediatek/patches-6.6/862-arm64-dts-mt7986-add-afe.patch
new file mode 100644 (file)
index 0000000..b31710f
--- /dev/null
@@ -0,0 +1,40 @@
+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
+@@ -248,6 +248,28 @@
+                       status = "disabled";
+               };
++              afe: audio-controller@11210000 {
++                      compatible = "mediatek,mt7986-afe";
++                      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>;
++                      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.6/863-arm64-dts-mt7986-add-sound-wm8960.patch b/target/linux/mediatek/patches-6.6/863-arm64-dts-mt7986-add-sound-wm8960.patch
new file mode 100644 (file)
index 0000000..15e30de
--- /dev/null
@@ -0,0 +1,61 @@
+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,35 @@
+ / {
+       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";
++              reg = <0x1a>;
++      };
+ };
+ &spi0 {
+@@ -50,3 +79,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.6/864-arm64-dts-mt7986-add-sound-overlay-for-bpi-r3.patch b/target/linux/mediatek/patches-6.6/864-arm64-dts-mt7986-add-sound-overlay-for-bpi-r3.patch
new file mode 100644 (file)
index 0000000..bddcd4b
--- /dev/null
@@ -0,0 +1,75 @@
+--- /dev/null
++++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-respeaker-2mics.dtso
+@@ -0,0 +1,62 @@
++// 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__ {
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&i2c_pins>;
++                      clock-frequency = <400000>;
++                      status = "okay";
++
++                      wm8960: wm8960@1a {
++                              compatible = "wlf,wm8960";
++                              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
+@@ -12,6 +12,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) += mt8167-pumpkin.dtb
diff --git a/target/linux/mediatek/patches-6.6/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch b/target/linux/mediatek/patches-6.6/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch
new file mode 100644 (file)
index 0000000..6dede02
--- /dev/null
@@ -0,0 +1,65 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -312,7 +312,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.6/901-arm-add-cmdline-override.patch b/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch
new file mode 100644 (file)
index 0000000..bfca4b6
--- /dev/null
@@ -0,0 +1,54 @@
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1589,6 +1589,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
+@@ -1187,6 +1187,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)
++              strlcpy(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
+@@ -2240,6 +2240,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.6/910-dts-mt7622-bpi-r64-wifi-eeprom.patch b/target/linux/mediatek/patches-6.6/910-dts-mt7622-bpi-r64-wifi-eeprom.patch
new file mode 100644 (file)
index 0000000..09ce417
--- /dev/null
@@ -0,0 +1,31 @@
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -639,5 +639,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.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch b/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch
new file mode 100644 (file)
index 0000000..5d3153d
--- /dev/null
@@ -0,0 +1,103 @@
+--- 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 {
+@@ -233,6 +236,26 @@
+       assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>;
+       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
+       non-removable;
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              block {
++                      compatible = "block-device";
++                      partitions {
++                              block-partition-env {
++                                      partname = "ubootenv";
++                                      nvmem-layout {
++                                              compatible = "u-boot,env-layout";
++                                      };
++                              };
++                              emmc_rootfs: block-partition-production {
++                                      partname = "production";
++                              };
++                      };
++              };
++      };
+ };
+ &mmc1 {
+@@ -249,6 +272,26 @@
+       vqmmc-supply = <&reg_3p3v>;
+       assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>;
+       assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>;
++
++      card@0 {
++              compatible = "mmc-card";
++              reg = <0>;
++
++              block {
++                      compatible = "block-device";
++                      partitions {
++                              block-partition-env {
++                                      partname = "ubootenv";
++                                      nvmem-layout {
++                                              compatible = "u-boot,env-layout";
++                                      };
++                              };
++                              sd_rootfs: block-partition-production {
++                                      partname = "production";
++                              };
++                      };
++              };
++      };
+ };
+ &nandc {
+@@ -283,14 +326,29 @@
+                       };
+                       partition@80000 {
+-                              label = "fip";
+-                              reg = <0x80000 0x200000>;
+-                              read-only;
+-                      };
+-
+-                      ubi: partition@280000 {
+                               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-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.6/930-spi-mt65xx-enable-sel-clk.patch b/target/linux/mediatek/patches-6.6/930-spi-mt65xx-enable-sel-clk.patch
new file mode 100644 (file)
index 0000000..6e6810b
--- /dev/null
@@ -0,0 +1,18 @@
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -1225,8 +1225,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.6/940-net-ethernet-mtk_wed-rename-mtk_wed_get_memory_regio.patch b/target/linux/mediatek/patches-6.6/940-net-ethernet-mtk_wed-rename-mtk_wed_get_memory_regio.patch
new file mode 100644 (file)
index 0000000..30be535
--- /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;
+@@ -321,7 +321,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.6/941-arm64-dts-mt7986-move-cpuboot-in-a-dedicated-node.patch b/target/linux/mediatek/patches-6.6/941-arm64-dts-mt7986-move-cpuboot-in-a-dedicated-node.patch
new file mode 100644 (file)
index 0000000..3ba4853
--- /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;
+-              };
+-
+       };
+       timer {
+@@ -540,10 +534,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 {
+@@ -553,10 +548,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>;
+               };
+               wo_ccif0: syscon@151a5000 {
+@@ -573,6 +569,11 @@
+                       interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+               };
++              wo_cpuboot: syscon@15194000 {
++                      compatible = "mediatek,mt7986-wo-cpuboot", "syscon";
++                      reg = <0 0x15194000 0 0x1000>;
++              };
++
+               eth: ethernet@15100000 {
+                       compatible = "mediatek,mt7986-eth";
+                       reg = <0 0x15100000 0 0x80000>;
diff --git a/target/linux/mediatek/patches-6.6/942-net-ethernet-mtk_wed-move-cpuboot-in-a-dedicated-dts.patch b/target/linux/mediatek/patches-6.6/942-net-ethernet-mtk_wed-move-cpuboot-in-a-dedicated-dts.patch
new file mode 100644 (file)
index 0000000..b4bea20
--- /dev/null
@@ -0,0 +1,81 @@
+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
+@@ -34,12 +34,23 @@ static struct mtk_wed_wo_memory_region m
+ 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(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 *
+@@ -313,6 +324,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,
+@@ -321,6 +335,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;
+--- 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.6/943-net-ethernet-mtk_wed-move-ilm-a-dedicated-dts-node.patch b/target/linux/mediatek/patches-6.6/943-net-ethernet-mtk_wed-move-ilm-a-dedicated-dts-node.patch
new file mode 100644 (file)
index 0000000..b4ba5b0
--- /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
+@@ -316,6 +316,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;
+@@ -324,14 +357,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.6/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch b/target/linux/mediatek/patches-6.6/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch
new file mode 100644 (file)
index 0000000..c92fcd4
--- /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
+@@ -1320,6 +1320,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)
+@@ -1336,6 +1354,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.6/945-arm64-dts-mt7986-move-ilm-in-a-dedicated-node.patch b/target/linux/mediatek/patches-6.6/945-arm64-dts-mt7986-move-ilm-in-a-dedicated-node.patch
new file mode 100644 (file)
index 0000000..0ba9bd7
--- /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;
+@@ -533,11 +523,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>;
+               };
+@@ -547,11 +536,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>;
+               };
+@@ -569,6 +557,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.6/946-arm64-dts-mt7986-move-dlm-in-a-dedicated-node.patch b/target/linux/mediatek/patches-6.6/946-arm64-dts-mt7986-move-dlm-in-a-dedicated-node.patch
new file mode 100644 (file)
index 0000000..90b2bb9
--- /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;
+-              };
+       };
+       timer {
+@@ -523,10 +513,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>;
+               };
+@@ -536,10 +527,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>;
+               };
+@@ -567,6 +559,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.6/950-smartrg-i2c-led-driver.patch b/target/linux/mediatek/patches-6.6/950-smartrg-i2c-led-driver.patch
new file mode 100644 (file)
index 0000000..8b86c50
--- /dev/null
@@ -0,0 +1,34 @@
+---
+ drivers/leds/Kconfig  |   10 ++++++++++
+ drivers/leds/Makefile |    1 +
+ 2 files changed, 11 insertions(+)
+
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -874,6 +874,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
+@@ -76,6 +76,7 @@ obj-$(CONFIG_LEDS_PWM)                       += leds-pwm.o
+ obj-$(CONFIG_LEDS_REGULATOR)          += leds-regulator.o
+ obj-$(CONFIG_LEDS_S3C24XX)            += leds-s3c24xx.o
+ obj-$(CONFIG_LEDS_SC27XX_BLTC)                += leds-sc27xx-bltc.o
++obj-$(CONFIG_LEDS_SMARTRG_LED)                += leds-smartrg-system.o
+ obj-$(CONFIG_LEDS_SUNFIRE)            += leds-sunfire.o
+ obj-$(CONFIG_LEDS_SYSCON)             += leds-syscon.o
+ obj-$(CONFIG_LEDS_TCA6507)            += leds-tca6507.o
diff --git a/target/linux/mediatek/patches-6.6/961-net-ethernet-mediatek-split-tx-and-rx-fields-in-mtk_.patch b/target/linux/mediatek/patches-6.6/961-net-ethernet-mediatek-split-tx-and-rx-fields-in-mtk_.patch
new file mode 100644 (file)
index 0000000..71cb300
--- /dev/null
@@ -0,0 +1,599 @@
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 2 Nov 2023 16:47:07 +0100
+Subject: [PATCH net-next 1/2] net: ethernet: mediatek: split tx and rx fields
+ in mtk_soc_data struct
+
+Split tx and rx fields in mtk_soc_data struct. This is a preliminary
+patch to roll back to QDMA for MT7986 SoC in order to fix a hw hang
+if the device receives a corrupted packet.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 210 ++++++++++++--------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  29 +--
+ 2 files changed, 139 insertions(+), 100 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1264,7 +1264,7 @@ static int mtk_init_fq_dma(struct mtk_et
+               eth->scratch_ring = eth->sram_base;
+       else
+               eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
+-                                                     cnt * soc->txrx.txd_size,
++                                                     cnt * soc->tx.desc_size,
+                                                      &eth->phy_scratch_ring,
+                                                      GFP_KERNEL);
+       if (unlikely(!eth->scratch_ring))
+@@ -1280,16 +1280,16 @@ static int mtk_init_fq_dma(struct mtk_et
+       if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
+               return -ENOMEM;
+-      phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1);
++      phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
+       for (i = 0; i < cnt; i++) {
+               struct mtk_tx_dma_v2 *txd;
+-              txd = eth->scratch_ring + i * soc->txrx.txd_size;
++              txd = eth->scratch_ring + i * soc->tx.desc_size;
+               txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
+               if (i < cnt - 1)
+                       txd->txd2 = eth->phy_scratch_ring +
+-                                  (i + 1) * soc->txrx.txd_size;
++                                  (i + 1) * soc->tx.desc_size;
+               txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
+               txd->txd4 = 0;
+@@ -1538,7 +1538,7 @@ static int mtk_tx_map(struct sk_buff *sk
+       if (itxd == ring->last_free)
+               return -ENOMEM;
+-      itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
++      itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
+       memset(itx_buf, 0, sizeof(*itx_buf));
+       txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
+@@ -1579,7 +1579,7 @@ static int mtk_tx_map(struct sk_buff *sk
+                       memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
+                       txd_info.size = min_t(unsigned int, frag_size,
+-                                            soc->txrx.dma_max_len);
++                                            soc->tx.dma_max_len);
+                       txd_info.qid = queue;
+                       txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
+                                       !(frag_size - txd_info.size);
+@@ -1592,7 +1592,7 @@ static int mtk_tx_map(struct sk_buff *sk
+                       mtk_tx_set_dma_desc(dev, txd, &txd_info);
+                       tx_buf = mtk_desc_to_tx_buf(ring, txd,
+-                                                  soc->txrx.txd_size);
++                                                  soc->tx.desc_size);
+                       if (new_desc)
+                               memset(tx_buf, 0, sizeof(*tx_buf));
+                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+@@ -1635,7 +1635,7 @@ static int mtk_tx_map(struct sk_buff *sk
+       } else {
+               int next_idx;
+-              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->txrx.txd_size),
++              next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_size),
+                                        ring->dma_size);
+               mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
+       }
+@@ -1644,7 +1644,7 @@ static int mtk_tx_map(struct sk_buff *sk
+ err_dma:
+       do {
+-              tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
++              tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
+               /* unmap dma */
+               mtk_tx_unmap(eth, tx_buf, NULL, false);
+@@ -1669,7 +1669,7 @@ static int mtk_cal_txd_req(struct mtk_et
+               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+                       frag = &skb_shinfo(skb)->frags[i];
+                       nfrags += DIV_ROUND_UP(skb_frag_size(frag),
+-                                             eth->soc->txrx.dma_max_len);
++                                             eth->soc->tx.dma_max_len);
+               }
+       } else {
+               nfrags += skb_shinfo(skb)->nr_frags;
+@@ -1810,7 +1810,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri
+               ring = &eth->rx_ring[i];
+               idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
+-              rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
++              rxd = ring->dma + idx * eth->soc->rx.desc_size;
+               if (rxd->rxd2 & RX_DMA_DONE) {
+                       ring->calc_idx_update = true;
+                       return ring;
+@@ -1978,7 +1978,7 @@ static int mtk_xdp_submit_frame(struct m
+       }
+       htxd = txd;
+-      tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size);
++      tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_size);
+       memset(tx_buf, 0, sizeof(*tx_buf));
+       htx_buf = tx_buf;
+@@ -1997,7 +1997,7 @@ static int mtk_xdp_submit_frame(struct m
+                               goto unmap;
+                       tx_buf = mtk_desc_to_tx_buf(ring, txd,
+-                                                  soc->txrx.txd_size);
++                                                  soc->tx.desc_size);
+                       memset(tx_buf, 0, sizeof(*tx_buf));
+                       n_desc++;
+               }
+@@ -2035,7 +2035,7 @@ static int mtk_xdp_submit_frame(struct m
+       } else {
+               int idx;
+-              idx = txd_to_idx(ring, txd, soc->txrx.txd_size);
++              idx = txd_to_idx(ring, txd, soc->tx.desc_size);
+               mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
+                       MT7628_TX_CTX_IDX0);
+       }
+@@ -2046,7 +2046,7 @@ static int mtk_xdp_submit_frame(struct m
+ unmap:
+       while (htxd != txd) {
+-              tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->txrx.txd_size);
++              tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_size);
+               mtk_tx_unmap(eth, tx_buf, NULL, false);
+               htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
+@@ -2177,7 +2177,7 @@ static int mtk_poll_rx(struct napi_struc
+                       goto rx_done;
+               idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
+-              rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
++              rxd = ring->dma + idx * eth->soc->rx.desc_size;
+               data = ring->data[idx];
+               if (!mtk_rx_get_desc(eth, &trxd, rxd))
+@@ -2312,7 +2312,7 @@ static int mtk_poll_rx(struct napi_struc
+                       rxdcsum = &trxd.rxd4;
+               }
+-              if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid)
++              if (*rxdcsum & eth->soc->rx.dma_l4_valid)
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+               else
+                       skb_checksum_none_assert(skb);
+@@ -2436,7 +2436,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
+                       break;
+               tx_buf = mtk_desc_to_tx_buf(ring, desc,
+-                                          eth->soc->txrx.txd_size);
++                                          eth->soc->tx.desc_size);
+               if (!tx_buf->data)
+                       break;
+@@ -2487,7 +2487,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
+               }
+               mtk_tx_unmap(eth, tx_buf, &bq, true);
+-              desc = ring->dma + cpu * eth->soc->txrx.txd_size;
++              desc = ring->dma + cpu * eth->soc->tx.desc_size;
+               ring->last_free = desc;
+               atomic_inc(&ring->free_count);
+@@ -2577,7 +2577,7 @@ static int mtk_napi_rx(struct napi_struc
+       do {
+               int rx_done;
+-              mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask,
++              mtk_w32(eth, eth->soc->rx.irq_done_mask,
+                       reg_map->pdma.irq_status);
+               rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth);
+               rx_done_total += rx_done;
+@@ -2593,10 +2593,10 @@ static int mtk_napi_rx(struct napi_struc
+                       return budget;
+       } while (mtk_r32(eth, reg_map->pdma.irq_status) &
+-               eth->soc->txrx.rx_irq_done_mask);
++               eth->soc->rx.irq_done_mask);
+       if (napi_complete_done(napi, rx_done_total))
+-              mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
++              mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
+       return rx_done_total;
+ }
+@@ -2605,7 +2605,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+ {
+       const struct mtk_soc_data *soc = eth->soc;
+       struct mtk_tx_ring *ring = &eth->tx_ring;
+-      int i, sz = soc->txrx.txd_size;
++      int i, sz = soc->tx.desc_size;
+       struct mtk_tx_dma_v2 *txd;
+       int ring_size;
+       u32 ofs, val;
+@@ -2728,14 +2728,14 @@ static void mtk_tx_clean(struct mtk_eth
+       }
+       if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * soc->txrx.txd_size,
++                                ring->dma_size * soc->tx.desc_size,
+                                 ring->dma, ring->phys);
+               ring->dma = NULL;
+       }
+       if (ring->dma_pdma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * soc->txrx.txd_size,
++                                ring->dma_size * soc->tx.desc_size,
+                                 ring->dma_pdma, ring->phys_pdma);
+               ring->dma_pdma = NULL;
+       }
+@@ -2790,15 +2790,15 @@ static int mtk_rx_alloc(struct mtk_eth *
+       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
+           rx_flag != MTK_RX_FLAGS_NORMAL) {
+               ring->dma = dma_alloc_coherent(eth->dma_dev,
+-                                             rx_dma_size * eth->soc->txrx.rxd_size,
+-                                             &ring->phys, GFP_KERNEL);
++                              rx_dma_size * eth->soc->rx.desc_size,
++                              &ring->phys, GFP_KERNEL);
+       } else {
+               struct mtk_tx_ring *tx_ring = &eth->tx_ring;
+               ring->dma = tx_ring->dma + tx_ring_size *
+-                          eth->soc->txrx.txd_size * (ring_no + 1);
++                          eth->soc->tx.desc_size * (ring_no + 1);
+               ring->phys = tx_ring->phys + tx_ring_size *
+-                           eth->soc->txrx.txd_size * (ring_no + 1);
++                           eth->soc->tx.desc_size * (ring_no + 1);
+       }
+       if (!ring->dma)
+@@ -2809,7 +2809,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+               dma_addr_t dma_addr;
+               void *data;
+-              rxd = ring->dma + i * eth->soc->txrx.rxd_size;
++              rxd = ring->dma + i * eth->soc->rx.desc_size;
+               if (ring->page_pool) {
+                       data = mtk_page_pool_get_buff(ring->page_pool,
+                                                     &dma_addr, GFP_KERNEL);
+@@ -2900,7 +2900,7 @@ static void mtk_rx_clean(struct mtk_eth
+                       if (!ring->data[i])
+                               continue;
+-                      rxd = ring->dma + i * eth->soc->txrx.rxd_size;
++                      rxd = ring->dma + i * eth->soc->rx.desc_size;
+                       if (!rxd->rxd1)
+                               continue;
+@@ -2917,7 +2917,7 @@ static void mtk_rx_clean(struct mtk_eth
+       if (!in_sram && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+-                                ring->dma_size * eth->soc->txrx.rxd_size,
++                                ring->dma_size * eth->soc->rx.desc_size,
+                                 ring->dma, ring->phys);
+               ring->dma = NULL;
+       }
+@@ -3280,7 +3280,7 @@ static void mtk_dma_free(struct mtk_eth
+                       netdev_reset_queue(eth->netdev[i]);
+       if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
+               dma_free_coherent(eth->dma_dev,
+-                                MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
++                                MTK_QDMA_RING_SIZE * soc->tx.desc_size,
+                                 eth->scratch_ring, eth->phy_scratch_ring);
+               eth->scratch_ring = NULL;
+               eth->phy_scratch_ring = 0;
+@@ -3330,7 +3330,7 @@ static irqreturn_t mtk_handle_irq_rx(int
+       eth->rx_events++;
+       if (likely(napi_schedule_prep(&eth->rx_napi))) {
+-              mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
++              mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
+               __napi_schedule(&eth->rx_napi);
+       }
+@@ -3356,9 +3356,9 @@ static irqreturn_t mtk_handle_irq(int ir
+       const struct mtk_reg_map *reg_map = eth->soc->reg_map;
+       if (mtk_r32(eth, reg_map->pdma.irq_mask) &
+-          eth->soc->txrx.rx_irq_done_mask) {
++          eth->soc->rx.irq_done_mask) {
+               if (mtk_r32(eth, reg_map->pdma.irq_status) &
+-                  eth->soc->txrx.rx_irq_done_mask)
++                  eth->soc->rx.irq_done_mask)
+                       mtk_handle_irq_rx(irq, _eth);
+       }
+       if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) {
+@@ -3376,10 +3376,10 @@ static void mtk_poll_controller(struct n
+       struct mtk_eth *eth = mac->hw;
+       mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
+-      mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
++      mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
+       mtk_handle_irq_rx(eth->irq[2], dev);
+       mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
+-      mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
++      mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
+ }
+ #endif
+@@ -3545,7 +3545,7 @@ static int mtk_open(struct net_device *d
+               napi_enable(&eth->tx_napi);
+               napi_enable(&eth->rx_napi);
+               mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
+-              mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
++              mtk_rx_irq_enable(eth, soc->rx.irq_done_mask);
+               refcount_set(&eth->dma_refcnt, 1);
+       }
+       else
+@@ -3628,7 +3628,7 @@ static int mtk_stop(struct net_device *d
+       mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
+       mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
+-      mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
++      mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
+       napi_disable(&eth->tx_napi);
+       napi_disable(&eth->rx_napi);
+@@ -4107,9 +4107,9 @@ static int mtk_hw_init(struct mtk_eth *e
+       /* FE int grouping */
+       mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
+-      mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->pdma.int_grp + 4);
++      mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->pdma.int_grp + 4);
+       mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp);
+-      mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
++      mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->qdma.int_grp + 4);
+       mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
+       if (mtk_is_netsys_v3_or_greater(eth)) {
+@@ -5270,11 +5270,15 @@ static const struct mtk_soc_data mt2701_
+       .required_clks = MT7623_CLKS_BITMAP,
+       .required_pctl = true,
+       .version = 1,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma),
+-              .rxd_size = sizeof(struct mtk_rx_dma),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN,
++              .dma_len_offset = 16,
++      },
++      .rx = {
++              .desc_size = sizeof(struct mtk_rx_dma),
++              .irq_done_mask = MTK_RX_DONE_INT,
++              .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+       },
+@@ -5290,11 +5294,15 @@ static const struct mtk_soc_data mt7621_
+       .offload_version = 1,
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma),
+-              .rxd_size = sizeof(struct mtk_rx_dma),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN,
++              .dma_len_offset = 16,
++      },
++      .rx = {
++              .desc_size = sizeof(struct mtk_rx_dma),
++              .irq_done_mask = MTK_RX_DONE_INT,
++              .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+       },
+@@ -5312,11 +5320,15 @@ static const struct mtk_soc_data mt7622_
+       .hash_offset = 2,
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma),
+-              .rxd_size = sizeof(struct mtk_rx_dma),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN,
++              .dma_len_offset = 16,
++      },
++      .rx = {
++              .desc_size = sizeof(struct mtk_rx_dma),
++              .irq_done_mask = MTK_RX_DONE_INT,
++              .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+       },
+@@ -5333,11 +5345,15 @@ static const struct mtk_soc_data mt7623_
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .disable_pll_modes = true,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma),
+-              .rxd_size = sizeof(struct mtk_rx_dma),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN,
++              .dma_len_offset = 16,
++      },
++      .rx = {
++              .desc_size = sizeof(struct mtk_rx_dma),
++              .irq_done_mask = MTK_RX_DONE_INT,
++              .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+       },
+@@ -5352,11 +5368,15 @@ static const struct mtk_soc_data mt7629_
+       .required_pctl = false,
+       .has_accounting = true,
+       .version = 1,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma),
+-              .rxd_size = sizeof(struct mtk_rx_dma),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN,
++              .dma_len_offset = 16,
++      },
++      .rx = {
++              .desc_size = sizeof(struct mtk_rx_dma),
++              .irq_done_mask = MTK_RX_DONE_INT,
++              .dma_l4_valid = RX_DMA_L4_VALID,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+       },
+@@ -5374,11 +5394,15 @@ static const struct mtk_soc_data mt7981_
+       .hash_offset = 4,
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma_v2),
+-              .rxd_size = sizeof(struct mtk_rx_dma_v2),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
++              .dma_len_offset = 8,
++      },
++      .rx = {
++              .desc_size = sizeof(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,
+       },
+@@ -5396,11 +5420,15 @@ static const struct mtk_soc_data mt7986_
+       .hash_offset = 4,
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma_v2),
+-              .rxd_size = sizeof(struct mtk_rx_dma_v2),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
++              .dma_len_offset = 8,
++      },
++      .rx = {
++              .desc_size = sizeof(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,
+       },
+@@ -5418,11 +5446,15 @@ static const struct mtk_soc_data mt7988_
+       .hash_offset = 4,
+       .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma_v2),
+-              .rxd_size = sizeof(struct mtk_rx_dma_v2),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma_v2),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
++              .dma_len_offset = 8,
++      },
++      .rx = {
++              .desc_size = sizeof(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,
+       },
+@@ -5435,11 +5467,15 @@ static const struct mtk_soc_data rt5350_
+       .required_clks = MT7628_CLKS_BITMAP,
+       .required_pctl = false,
+       .version = 1,
+-      .txrx = {
+-              .txd_size = sizeof(struct mtk_tx_dma),
+-              .rxd_size = sizeof(struct mtk_rx_dma),
+-              .rx_irq_done_mask = MTK_RX_DONE_INT,
+-              .rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA,
++      .tx = {
++              .desc_size = sizeof(struct mtk_tx_dma),
++              .dma_max_len = MTK_TX_DMA_BUF_LEN,
++              .dma_len_offset = 16,
++      },
++      .rx = {
++              .desc_size = sizeof(struct mtk_rx_dma),
++              .irq_done_mask = MTK_RX_DONE_INT,
++              .dma_l4_valid = RX_DMA_L4_VALID_PDMA,
+               .dma_max_len = MTK_TX_DMA_BUF_LEN,
+               .dma_len_offset = 16,
+       },
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -327,8 +327,8 @@
+ /* QDMA descriptor txd3 */
+ #define TX_DMA_OWNER_CPU      BIT(31)
+ #define TX_DMA_LS0            BIT(30)
+-#define TX_DMA_PLEN0(x)               (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
+-#define TX_DMA_PLEN1(x)               ((x) & eth->soc->txrx.dma_max_len)
++#define TX_DMA_PLEN0(x)               (((x) & eth->soc->tx.dma_max_len) << eth->soc->tx.dma_len_offset)
++#define TX_DMA_PLEN1(x)               ((x) & eth->soc->tx.dma_max_len)
+ #define TX_DMA_SWC            BIT(14)
+ #define TX_DMA_PQID           GENMASK(3, 0)
+ #define TX_DMA_ADDR64_MASK    GENMASK(3, 0)
+@@ -348,8 +348,8 @@
+ /* QDMA descriptor rxd2 */
+ #define RX_DMA_DONE           BIT(31)
+ #define RX_DMA_LSO            BIT(30)
+-#define RX_DMA_PREP_PLEN0(x)  (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
+-#define RX_DMA_GET_PLEN0(x)   (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
++#define RX_DMA_PREP_PLEN0(x)  (((x) & eth->soc->rx.dma_max_len) << eth->soc->rx.dma_len_offset)
++#define RX_DMA_GET_PLEN0(x)   (((x) >> eth->soc->rx.dma_len_offset) & eth->soc->rx.dma_max_len)
+ #define RX_DMA_VTAG           BIT(15)
+ #define RX_DMA_ADDR64_MASK    GENMASK(3, 0)
+ #if IS_ENABLED(CONFIG_64BIT)
+@@ -1209,10 +1209,9 @@ struct mtk_reg_map {
+  * @foe_entry_size            Foe table entry size.
+  * @has_accounting            Bool indicating support for accounting of
+  *                            offloaded flows.
+- * @txd_size                  Tx DMA descriptor size.
+- * @rxd_size                  Rx DMA descriptor size.
+- * @rx_irq_done_mask          Rx irq done register mask.
+- * @rx_dma_l4_valid           Rx DMA valid register mask.
++ * @desc_size                 Tx/Rx DMA descriptor size.
++ * @irq_done_mask             Rx irq done register mask.
++ * @dma_l4_valid              Rx DMA valid register mask.
+  * @dma_max_len                       Max DMA tx/rx buffer length.
+  * @dma_len_offset            Tx/Rx DMA length field offset.
+  */
+@@ -1230,13 +1229,17 @@ struct mtk_soc_data {
+       bool            has_accounting;
+       bool            disable_pll_modes;
+       struct {
+-              u32     txd_size;
+-              u32     rxd_size;
+-              u32     rx_irq_done_mask;
+-              u32     rx_dma_l4_valid;
++              u32     desc_size;
+               u32     dma_max_len;
+               u32     dma_len_offset;
+-      } txrx;
++      } tx;
++      struct {
++              u32     desc_size;
++              u32     irq_done_mask;
++              u32     dma_l4_valid;
++              u32     dma_max_len;
++              u32     dma_len_offset;
++      } rx;
+ };
+ #define MTK_DMA_MONITOR_TIMEOUT               msecs_to_jiffies(1000)
diff --git a/target/linux/mediatek/patches-6.6/962-net-ethernet-mediatek-use-QDMA-instead-of-ADMAv2-on-.patch b/target/linux/mediatek/patches-6.6/962-net-ethernet-mediatek-use-QDMA-instead-of-ADMAv2-on-.patch
new file mode 100644 (file)
index 0000000..8b7d5c0
--- /dev/null
@@ -0,0 +1,123 @@
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 10 Oct 2023 21:06:43 +0200
+Subject: [PATCH net-next 2/2] net: ethernet: mediatek: use QDMA instead of
+ ADMAv2 on MT7981 and MT7986
+
+ADMA is plagued by RX hangs which can't easily detected and happen upon
+receival of a corrupted package.
+Use QDMA just like on netsys v1 which is also still present and usable, and
+doesn't suffer from that problem.
+
+Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 46 ++++++++++-----------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -110,16 +110,16 @@ static const struct mtk_reg_map mt7986_r
+       .tx_irq_mask            = 0x461c,
+       .tx_irq_status          = 0x4618,
+       .pdma = {
+-              .rx_ptr         = 0x6100,
+-              .rx_cnt_cfg     = 0x6104,
+-              .pcrx_ptr       = 0x6108,
+-              .glo_cfg        = 0x6204,
+-              .rst_idx        = 0x6208,
+-              .delay_irq      = 0x620c,
+-              .irq_status     = 0x6220,
+-              .irq_mask       = 0x6228,
+-              .adma_rx_dbg0   = 0x6238,
+-              .int_grp        = 0x6250,
++              .rx_ptr         = 0x4100,
++              .rx_cnt_cfg     = 0x4104,
++              .pcrx_ptr       = 0x4108,
++              .glo_cfg        = 0x4204,
++              .rst_idx        = 0x4208,
++              .delay_irq      = 0x420c,
++              .irq_status     = 0x4220,
++              .irq_mask       = 0x4228,
++              .adma_rx_dbg0   = 0x4238,
++              .int_grp        = 0x4250,
+       },
+       .qdma = {
+               .qtx_cfg        = 0x4400,
+@@ -1232,7 +1232,7 @@ static bool mtk_rx_get_desc(struct mtk_e
+       rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
+       rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
+       rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
+-      if (mtk_is_netsys_v2_or_greater(eth)) {
++      if (mtk_is_netsys_v3_or_greater(eth)) {
+               rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
+               rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
+       }
+@@ -2184,7 +2184,7 @@ static int mtk_poll_rx(struct napi_struc
+                       break;
+               /* find out which mac the packet come from. values start at 1 */
+-              if (mtk_is_netsys_v2_or_greater(eth)) {
++              if (mtk_is_netsys_v3_or_greater(eth)) {
+                       u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
+                       switch (val) {
+@@ -2296,7 +2296,7 @@ static int mtk_poll_rx(struct napi_struc
+               skb->dev = netdev;
+               bytes += skb->len;
+-              if (mtk_is_netsys_v2_or_greater(eth)) {
++              if (mtk_is_netsys_v3_or_greater(eth)) {
+                       reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
+                       hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
+                       if (hash != MTK_RXD5_FOE_ENTRY)
+@@ -2846,7 +2846,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+               rxd->rxd3 = 0;
+               rxd->rxd4 = 0;
+-              if (mtk_is_netsys_v2_or_greater(eth)) {
++              if (mtk_is_netsys_v3_or_greater(eth)) {
+                       rxd->rxd5 = 0;
+                       rxd->rxd6 = 0;
+                       rxd->rxd7 = 0;
+@@ -4053,7 +4053,7 @@ static int mtk_hw_init(struct mtk_eth *e
+       else
+               mtk_hw_reset(eth);
+-      if (mtk_is_netsys_v2_or_greater(eth)) {
++      if (mtk_is_netsys_v3_or_greater(eth)) {
+               /* Set FE to PDMAv2 if necessary */
+               val = mtk_r32(eth, MTK_FE_GLO_MISC);
+               mtk_w32(eth,  val | BIT(4), MTK_FE_GLO_MISC);
+@@ -5400,11 +5400,11 @@ static const struct mtk_soc_data mt7981_
+               .dma_len_offset = 8,
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma_v2),
+-              .irq_done_mask = MTK_RX_DONE_INT_V2,
++              .desc_size = sizeof(struct mtk_rx_dma),
++              .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID_V2,
+-              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+-              .dma_len_offset = 8,
++              .dma_max_len = MTK_TX_DMA_BUF_LEN,
++              .dma_len_offset = 16,
+       },
+ };
+@@ -5426,11 +5426,11 @@ static const struct mtk_soc_data mt7986_
+               .dma_len_offset = 8,
+       },
+       .rx = {
+-              .desc_size = sizeof(struct mtk_rx_dma_v2),
+-              .irq_done_mask = MTK_RX_DONE_INT_V2,
++              .desc_size = sizeof(struct mtk_rx_dma),
++              .irq_done_mask = MTK_RX_DONE_INT,
+               .dma_l4_valid = RX_DMA_L4_VALID_V2,
+-              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+-              .dma_len_offset = 8,
++              .dma_max_len = MTK_TX_DMA_BUF_LEN,
++              .dma_len_offset = 16,
+       },
+ };
diff --git a/target/linux/mediatek/patches-6.6/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch b/target/linux/mediatek/patches-6.6/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch
new file mode 100644 (file)
index 0000000..11b52d0
--- /dev/null
@@ -0,0 +1,49 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 18 Jan 2024 12:51:32 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: fix WED + wifi reset
+
+The WLAN + WED reset sequence relies on being able to receive interrupts from
+the card, in order to synchronize individual steps with the firmware.
+When WED is stopped, leave interrupts running and rely on the driver turning
+off unwanted ones.
+WED DMA also needs to be disabled before resetting.
+
+Fixes: f78cd9c783e0 ("net: ethernet: mtk_wed: update mtk_wed_stop")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -1071,13 +1071,13 @@ mtk_wed_dma_disable(struct mtk_wed_devic
+ static void
+ mtk_wed_stop(struct mtk_wed_device *dev)
+ {
++      mtk_wed_dma_disable(dev);
+       mtk_wed_set_ext_int(dev, false);
+       wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
+       wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
+       wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
+       wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
+-      wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
+       if (!mtk_wed_get_rx_capa(dev))
+               return;
+@@ -1090,7 +1090,6 @@ static void
+ mtk_wed_deinit(struct mtk_wed_device *dev)
+ {
+       mtk_wed_stop(dev);
+-      mtk_wed_dma_disable(dev);
+       wed_clr(dev, MTK_WED_CTRL,
+               MTK_WED_CTRL_WDMA_INT_AGENT_EN |
+@@ -2621,9 +2620,6 @@ mtk_wed_irq_get(struct mtk_wed_device *d
+ static void
+ mtk_wed_irq_set_mask(struct mtk_wed_device *dev, u32 mask)
+ {
+-      if (!dev->running)
+-              return;
+-
+       mtk_wed_set_ext_int(dev, !!mask);
+       wed_w32(dev, MTK_WED_INT_MASK, mask);
+ }