From: Daniel Golle Date: Fri, 1 Mar 2024 01:56:57 +0000 (+0000) Subject: mediatek: copy patches-6.1 to patches-6.6 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=95d3d353f84c01d20c32d0811b2159da72a11a10;p=openwrt%2Fstaging%2F981213.git mediatek: copy patches-6.1 to patches-6.6 Copy patches from patches-6.1 to patches-6.6. No changes. Signed-off-by: Daniel Golle --- 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 index 0000000000..17c5c6098a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/000-v6.2-kbuild-Allow-DTB-overlays-to-built-from-.dtso-named-.patch @@ -0,0 +1,44 @@ +From 363547d2191cbc32ca954ba75d72908712398ff2 Mon Sep 17 00:00:00 2001 +From: Andrew Davis +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 +Reviewed-by: Geert Uytterhoeven +Tested-by: Geert Uytterhoeven +Reviewed-by: Frank Rowand +Tested-by: Frank Rowand +Link: https://lore.kernel.org/r/20221024173434.32518-2-afd@ti.com +Signed-off-by: Rob Herring +--- + 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 index 0000000000..970e0f92bb --- /dev/null +++ b/target/linux/mediatek/patches-6.6/001-v6.2-arm64-dts-mediatek-mt7986-add-support-for-RX-Wireles.patch @@ -0,0 +1,106 @@ +From 2c4daed9580164522859fa100128be408cc69be2 Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +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 +Signed-off-by: Sujuan Chen +Signed-off-by: Lorenzo Bianconi +Signed-off-by: David S. Miller +--- + 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 = ; ++ 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 = ; ++ 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 = ; ++ }; ++ ++ wo_ccif1: syscon@151ad000 { ++ compatible = "mediatek,mt7986-wo-ccif", "syscon"; ++ reg = <0 0x151ad000 0 0x1000>; ++ interrupt-parent = <&gic>; ++ interrupts = ; + }; + + 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 index 0000000000..b5091687a3 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/002-v6.2-arm64-dts-mt7986-harmonize-device-node-order.patch @@ -0,0 +1,166 @@ +From 438e53828c08cf0e8a65b61cf6ce1e4b6620551a Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221106085034.12582-2-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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"; +-}; +- + ð { + 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 index 0000000000..5706531a46 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/003-v6.2-arm64-dts-mt7986-add-crypto-related-device-nodes.patch @@ -0,0 +1,68 @@ +From ffb05357b47f06b2b4d1e14ba89169e28feb727b Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Sam Shih +Signed-off-by: Frank Wunderlich +Link: https://lore.kernel.org/r/20221106085034.12582-5-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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"; ++}; ++ + ð { + 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 = , ++ , ++ , ++ ; ++ 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"; ++}; ++ + ð { + 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 index 0000000000..0e5b77a11b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/004-v6.2-arm64-dts-mt7986-add-i2c-node.patch @@ -0,0 +1,37 @@ +From b49b7dc404ded1d89cbc568d875009a5c1ed4ef6 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Link: https://lore.kernel.org/r/20221106085034.12582-7-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 = ; ++ 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 index 0000000000..8201b47df6 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/005-v6.2-arm64-dts-mediatek-mt7986-Add-SoC-compatible.patch @@ -0,0 +1,61 @@ +From 2cd6022800d6da7822e169f3e6f7f790c1431445 Mon Sep 17 00:00:00 2001 +From: Matthias Brugger +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 +Link: https://lore.kernel.org/r/20221114121653.14739-1-matthias.bgg@kernel.org +Signed-off-by: Matthias Brugger +--- + 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 + + / { ++ 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 index 0000000000..3e5e3d880a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/006-v6.2-arm64-dts-mt7986-add-spi-related-device-nodes.patch @@ -0,0 +1,157 @@ +From f4029538f063a845dc9aae46cce4cf386e6253a5 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221118190126.100895-7-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 = ; ++ 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 = ; ++ 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 index 0000000000..53567c66a0 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/007-v6.3-arm64-dts-mt7986-add-usb-related-device-nodes.patch @@ -0,0 +1,127 @@ +From 9e8e24ab716098e617195ce29b88e84608bf2108 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: Chunfeng Yun +Link: https://lore.kernel.org/r/20230106152845.88717-3-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 = ; ++ 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 index 0000000000..9c0a48149d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/008-v6.3-arm64-dts-mt7986-add-mmc-related-device-nodes.patch @@ -0,0 +1,160 @@ +From c1744e9e75a6a8abc7c893f349bcbf725b9c0d74 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Frank Wunderlich +Link: https://lore.kernel.org/r/20230106152845.88717-4-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 ++ + #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 = <®_3p3v>; ++ vqmmc-supply = <®_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 = ; /* pull-up 10K */ ++ }; ++ conf-clk { ++ pins = "EMMC_CK"; ++ drive-strength = <6>; ++ bias-pull-down = ; /* pull-down 50K */ ++ }; ++ conf-ds { ++ pins = "EMMC_DSL"; ++ bias-pull-down = ; /* pull-down 50K */ ++ }; ++ conf-rst { ++ pins = "EMMC_RSTB"; ++ drive-strength = <4>; ++ bias-pull-up = ; /* 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 = ; /* pull-up 10K */ ++ }; ++ conf-clk { ++ pins = "EMMC_CK"; ++ drive-strength = <6>; ++ bias-pull-down = ; /* pull-down 50K */ ++ }; ++ conf-ds { ++ pins = "EMMC_DSL"; ++ bias-pull-down = ; /* pull-down 50K */ ++ }; ++ conf-rst { ++ pins = "EMMC_RSTB"; ++ drive-strength = <4>; ++ bias-pull-up = ; /* 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 = ; ++ 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 index 0000000000..adc6394857 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/009-v6.3-arm64-dts-mt7986-add-pcie-related-device-nodes.patch @@ -0,0 +1,118 @@ +From 87a42ef1d6cf602e4aa40555b4404cad6149a90f Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Sam Shih +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230106152845.88717-5-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 + #include + #include ++#include + + / { + 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 = ; ++ 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 index 0000000000..38f159c74e --- /dev/null +++ b/target/linux/mediatek/patches-6.6/010-v6.3-arm64-dts-mt7986-add-Bananapi-R3.patch @@ -0,0 +1,689 @@ +From a751f7412e0098801673b80bc7a4738ae7d710ce Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Link: https://lore.kernel.org/r/20230106152845.88717-6-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 ++ */ ++ ++/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 ++ * Frank Wunderlich ++ */ ++ ++/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 ++ * Frank Wunderlich ++ */ ++ ++/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 ++ */ ++ ++/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 ++ * Frank Wunderlich ++ * Daniel Golle ++ */ ++ ++/dts-v1/; ++#include ++#include ++#include ++#include ++ ++#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 = ; ++ gpios = <&pio 9 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wps-key { ++ label = "wps"; ++ linux,code = ; ++ 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 = ; ++ function = LED_FUNCTION_POWER; ++ gpios = <&pio 69 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ blue_led: led-1 { ++ color = ; ++ 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"; ++}; ++ ++ð { ++ 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 = <®_3p3v>; ++ vqmmc-supply = <®_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 = ; /* pull-up 10K */ ++ }; ++ conf-clk { ++ pins = "EMMC_CK"; ++ drive-strength = <6>; ++ bias-pull-down = ; /* pull-down 50K */ ++ }; ++ conf-ds { ++ pins = "EMMC_DSL"; ++ bias-pull-down = ; /* pull-down 50K */ ++ }; ++ conf-rst { ++ pins = "EMMC_RSTB"; ++ drive-strength = <4>; ++ bias-pull-up = ; /* 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 = ; /* pull-up 10K */ ++ }; ++ conf-clk { ++ pins = "EMMC_CK"; ++ drive-strength = <6>; ++ bias-pull-down = ; /* pull-down 50K */ ++ }; ++ conf-ds { ++ pins = "EMMC_DSL"; ++ bias-pull-down = ; /* pull-down 50K */ ++ }; ++ conf-rst { ++ pins = "EMMC_RSTB"; ++ drive-strength = <4>; ++ bias-pull-up = ; /* 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 index 0000000000..79038334c4 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/011-v6.5-arm64-mediatek-Propagate-chassis-type-where-possible.patch @@ -0,0 +1,323 @@ +From 4c2d5411f4b101f7aa0fd74f80109e3afd6dc967 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Link: https://lore.kernel.org/r/20230517101108.205654-1-angelogioacchino.delregno@collabora.com +Signed-off-by: Matthias Brugger +--- + 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 index 0000000000..e8c47945d6 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/012-v6.5-arm64-dts-mt7986-add-PWM.patch @@ -0,0 +1,38 @@ +From 3b92c547e3d4a35c6214b3e7fa1103d0749d83b1 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Frank Wunderlich +Link: https://lore.kernel.org/r/20230421132047.42166-5-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 = ; ++ 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 index 0000000000..ce908e3d31 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/013-v6.5-arm64-dts-mt7986-add-PWM-to-BPI-R3.patch @@ -0,0 +1,43 @@ +From 35e482bb599df010b4869017ff576dbb7a4d4c2e Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Link: https://lore.kernel.org/r/20230421132047.42166-6-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + .../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 index 0000000000..c7b38484f4 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/014-v6.5-arm64-dts-mt7986-set-Wifi-Leds-low-active-for-BPI-R3.patch @@ -0,0 +1,27 @@ +From ccdda5714446db8690505371442f7807f5d7c6fc Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230205174833.107050-1-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 index 0000000000..0b84f1463a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/015-v6.5-arm64-dts-mt7986-use-size-of-reserved-partition-for-.patch @@ -0,0 +1,46 @@ +From 1423b4b780adcf3994e63a5988a62d5d1d509bb1 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Daniel Golle +Link: https://lore.kernel.org/r/20230528113343.7649-1-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + .../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 index 0000000000..0d12079d7c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/016-v6.5-arm64-dts-mt7986-add-thermal-and-efuse.patch @@ -0,0 +1,80 @@ +From 40a5a767d698ef7a71f8be851ea18b0a7a8b47bd Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230530201235.22330-3-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 = ; ++ 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 index 0000000000..3fe3e885eb --- /dev/null +++ b/target/linux/mediatek/patches-6.6/017-v6.5-arm64-dts-mt7986-add-thermal-zones.patch @@ -0,0 +1,51 @@ +From bb78d0cf5117517f1ed296ae71048945d9107675 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230530201235.22330-4-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + 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 index 0000000000..ca7d872a1b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/018-v6.5-arm64-dts-mt7986-add-pwm-fan-and-cooling-maps-to-BPI.patch @@ -0,0 +1,64 @@ +From 5d90603b09e5814ffc38c47e79ccf9bc564f9296 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230530201235.22330-5-linux@fw-web.de +Signed-off-by: Matthias Brugger +--- + .../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 index 0000000000..9cc6cad0af --- /dev/null +++ b/target/linux/mediatek/patches-6.6/019-v6.5-arm64-dts-mt7986-increase-bl2-partition-on-NAND-of-B.patch @@ -0,0 +1,41 @@ +From 6dd3b939370094eb79529683be84500f3c757404 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Link: https://lore.kernel.org/r/ZH9UGF99RgzrHZ88@makrotopia.org +Signed-off-by: Matthias Brugger +--- + .../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 index 0000000000..8cba3b2059 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/020-v6.7-arm64-dts-mt7986-define-3W-max-power-to-both-SFP-on-.patch @@ -0,0 +1,34 @@ +From f8ed4088ed9c61ae92193da6130d04c37e7b19f2 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +--- + 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 index 0000000000..20d4468cf0 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/021-v6.7-arm64-dts-mt7986-change-cooling-trips.patch @@ -0,0 +1,59 @@ +From aa3d6df9803c267725dc72286bb91602b7579882 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Signed-off-by: Frank Wunderlich +--- + 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 index 0000000000..7166ab6a14 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/022-v6.7-arm64-dts-mt7986-change-thermal-trips-on-BPI-R3.patch @@ -0,0 +1,38 @@ +From 6ddf23526955b8dbedfeaa57e691261fd73f9d4e Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Signed-off-by: Frank Wunderlich +--- + .../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 index 0000000000..bb87c20a91 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch @@ -0,0 +1,216 @@ +From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001 +From: OpenWrt community +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 + #include + #include ++#ifdef CONFIG_FIT_PARTITION ++#include ++#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 index 0000000000..d5bd9a316b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/100-dts-update-mt7622-rfb1.patch @@ -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 +- * Sean Wang ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Ryder Lee + * + * 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 = ; +- gpios = <&pio 0 0>; ++ gpios = <&pio 0 GPIO_ACTIVE_LOW>; + }; + + key-wps { + label = "wps"; + linux,code = ; +- 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 index 0000000000..b1770371b0 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/101-dts-update-mt7629-rfb.patch @@ -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 index 0000000000..04df7b927b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/103-mt7623-enable-arch-timer.patch @@ -0,0 +1,20 @@ +From d6a596012150960f0f3a214d31bbac4b607dbd1e Mon Sep 17 00:00:00 2001 +From: Chuanhong Guo +Date: Fri, 29 Apr 2022 10:40:56 +0800 +Subject: [PATCH] arm: mediatek: select arch timer for mt7623 + +Signed-off-by: Chuanhong Guo +--- + 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 index 0000000000..0d9c91f44d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/104-mt7622-add-snor-irq.patch @@ -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 = ; + 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 index 0000000000..93da722e72 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/105-dts-mt7622-enable-pstore.patch @@ -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 index 0000000000..fc6a8f35bc --- /dev/null +++ b/target/linux/mediatek/patches-6.6/106-dts-mt7622-disable_btif.patch @@ -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 index 0000000000..8dc53d2985 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/110-dts-fix-bpi2-console.patch @@ -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 index 0000000000..f77f10cb95 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/111-dts-fix-bpi64-console.patch @@ -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 index 0000000000..b012a48d75 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/112-dts-fix-bpi64-lan-names.patch @@ -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 index 0000000000..1cca6f3534 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/113-dts-fix-bpi64-leds-and-buttons.patch @@ -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 = ; ++ label = "reset"; ++ linux,code = ; + 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 = ; + gpios = <&pio 89 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + +- led-1 { +- label = "bpi-r64:pio:red"; +- color = ; +- gpios = <&pio 88 GPIO_ACTIVE_HIGH>; ++ led_system_blue: led-1 { ++ label = "bpi-r64:pio:blue"; ++ color = ; ++ 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 index 0000000000..0d324084b1 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/114-dts-bpi64-disable-rtc.patch @@ -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 index 0000000000..5fc55314ce --- /dev/null +++ b/target/linux/mediatek/patches-6.6/115-v6.5-arm64-dts-mt7622-declare-SPI-NAND-present-on-BPI-R64.patch @@ -0,0 +1,70 @@ +From d278f43f25beedfd0cb784d1dd0a9e7e8c8f123f Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Link: https://lore.kernel.org/r/ZEA96dmaXqTpk8u8@makrotopia.org +Signed-off-by: Matthias Brugger +--- + .../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 index 0000000000..ff5521c44e --- /dev/null +++ b/target/linux/mediatek/patches-6.6/121-hack-spi-nand-1b-bbm.patch @@ -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 index 0000000000..82654e683c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/130-dts-mt7629-add-snand-support.patch @@ -0,0 +1,94 @@ +From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001 +From: Xiangsheng Hou +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 +--- + 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 = ; ++ 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 = ; ++ 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 index 0000000000..d6e0ab1d41 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/131-dts-mt7622-add-snand-support.patch @@ -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 index 0000000000..117d5abde6 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/140-dts-fix-wmac-support-for-mt7622-rfb1.patch @@ -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 index 0000000000..0860a22c37 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/150-dts-mt7623-eip97-inside-secure-support.patch @@ -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 = , + , + , +- , +- ; ++ ; ++ interrupt-names = "ring0", "ring1", "ring2", "ring3"; + clocks = <ðsys 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 index 0000000000..091cffc3c0 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/160-dts-mt7623-bpi-r2-earlycon.patch @@ -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 index 0000000000..d1bafc1526 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/161-dts-mt7623-bpi-r2-mmc-device-order.patch @@ -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 index 0000000000..f6745add5b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/162-dts-mt7623-bpi-r2-led-aliases.patch @@ -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 index 0000000000..b1dd75a414 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/163-dts-mt7623-bpi-r2-ethernet-alias.patch @@ -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 index 0000000000..2675aa2589 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/164-dts-mt7623-bpi-r2-rootdisk-for-fitblk.patch @@ -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 = <®_3p3v>; + vqmmc-supply = <®_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 = <®_3p3v>; + vqmmc-supply = <®_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 index 0000000000..0a971c1f45 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/180-v6.5-arm64-dts-mt7622-handle-interrupts-from-MT7531-switc.patch @@ -0,0 +1,32 @@ +From 983f37ee08acb60435744f1b1e2afea2d2a09c48 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Link: https://lore.kernel.org/r/ZEA-DV_OsmFg5egL@makrotopia.org +Signed-off-by: Matthias Brugger +--- + 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 index 0000000000..1e04d23a0e --- /dev/null +++ b/target/linux/mediatek/patches-6.6/190-arm64-dts-mediatek-mt7622-fix-GICv2-range.patch @@ -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 +X-Patchwork-Id: 12827872 +Return-Path: + +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from 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 ; + 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 ) + id 1njRDu-0006aF-4F; Tue, 26 Apr 2022 21:51:46 +0200 +Date: Tue, 26 Apr 2022 20:51:36 +0100 +From: Daniel Golle +To: devicetree@vger.kernel.org, linux-mediatek@lists.infradead.org, + linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org +Cc: Rob Herring , + Krzysztof Kozlowski , + Matthias Brugger +Subject: [PATCH] arm64: dts: mediatek: mt7622: fix GICv2 range +Message-ID: +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: +List-Unsubscribe: + , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: + , + +Sender: "linux-arm-kernel" +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 +--- + 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 index 0000000000..1cfb53d620 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/193-dts-mt7623-thermal_zone_fix.patch @@ -0,0 +1,48 @@ +From 824d56e753a588fcfd650db1822e34a02a48bb77 Mon Sep 17 00:00:00 2001 +From: Bruno Umuarama +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 +--- + 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 index 0000000000..161c1e7516 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/194-dts-mt7968a-add-ramoops.patch @@ -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 index 0000000000..336920bafe --- /dev/null +++ b/target/linux/mediatek/patches-6.6/195-dts-mt7986a-bpi-r3-leds-port-names-and-wifi-eeprom.patch @@ -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 index 0000000000..38510c0fc7 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/196-dts-mt7986a-bpi-r3-use-all-ubi-nand-layout.patch @@ -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 index 0000000000..6347533aa8 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/200-phy-phy-mtk-tphy-Add-hifsys-support.patch @@ -0,0 +1,66 @@ +From 28f9a5e2a3f5441ab5594669ed82da11e32277a9 Mon Sep 17 00:00:00 2001 +From: Kristian Evensen +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 + #include + #include ++#include ++#include + + #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 index 0000000000..3e16a533e1 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/210-v6.2-pinctrl-mt7986-allow-configuring-uart-rx-tx-and-rts-.patch @@ -0,0 +1,88 @@ +From f76e8bc416bebb0f7b9f57b1247eae945421c0b9 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Sam Shih +Link: https://lore.kernel.org/r/20221008164807.113590-1-linux@fw-web.de +Signed-off-by: Linus Walleij +--- + 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 index 0000000000..47ded1aeb5 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/211-v6.2-pinctrl-mediatek-add-pull_type-attribute-for-mediate.patch @@ -0,0 +1,100 @@ +From 822d774abbcc66b811e28c68b59b40b964ba5b46 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221106080114.7426-7-linux@fw-web.de +Signed-off-by: Linus Walleij +--- + 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 index 0000000000..46dfa24b7b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/215-v6.3-pinctrl-add-mt7981-pinctrl-driver.patch @@ -0,0 +1,1094 @@ +From 6c83b2d94fcca735cf7d8aa7a55a4957eb404a9d Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Reviewed-by: Rob Herring +Link: https://lore.kernel.org/r/ef5112946d16cacc67e65e439ba7b52a9950c1bb.1674693008.git.daniel@makrotopia.org +Signed-off-by: Linus Walleij +--- + 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 ++ */ ++ ++#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 index 0000000000..995e0dc7ed --- /dev/null +++ b/target/linux/mediatek/patches-6.6/216-v6.3-pinctrl-mediatek-add-missing-options-to-PINCTRL_MT79.patch @@ -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?= +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 +Acked-by: Daniel Golle +Link: https://lore.kernel.org/r/20230218065108.8958-1-arinc.unal@arinc9.com +Signed-off-by: Linus Walleij +--- + 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 index 0000000000..db2561695b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/217-v6.5-pinctrl-mediatek-fix-pull_type-data-for-MT7981.patch @@ -0,0 +1,76 @@ +From 8f6f16fe1553ce63edfb98a39ef9d4754a0c39bf Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Link: https://lore.kernel.org/r/7bcc8ead25dbfabc7f5a85d066224a926fbb4941.1692327317.git.daniel@makrotopia.org +Signed-off-by: Linus Walleij +--- + 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 index 0000000000..d2f055836b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/218-pinctrl-mediatek-mt7981-add-additional-uart-groups.patch @@ -0,0 +1,65 @@ +From 11db447f257231e08065989100311df57b7f1f1c Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +--- + 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 index 0000000000..7992a02677 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/219-v6.6-pinctrl-mediatek-assign-functions-to-configure-pin-b.patch @@ -0,0 +1,41 @@ +From 0d8387fba9f151220e48dc3dcdc2335539708f13 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Link: https://lore.kernel.org/r/47f72372354312a839b9337e09476aadcc206e8b.1692327317.git.daniel@makrotopia.org +Signed-off-by: Linus Walleij +--- + 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 index 0000000000..af5715e1f5 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/220-v6.3-clk-mediatek-clk-gate-Propagate-struct-device-with-m.patch @@ -0,0 +1,536 @@ +From fe5c8d03f3de89ae058e365b783f8c1314f47490 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Reviewed-by: Chen-Yu Tsai +Reviewed-by: Markus Schneider-Pargmann +Tested-by: Miles Chen +Link: https://lore.kernel.org/r/20230120092053.182923-4-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd + +[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 index 0000000000..223155c59b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/221-v6.3-clk-mediatek-cpumux-Propagate-struct-device-where-po.patch @@ -0,0 +1,140 @@ +From b888303c7d23d7bd0c8667cfc657669e5d153fea Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Reviewed-by: Chen-Yu Tsai +Reviewed-by: Markus Schneider-Pargmann +Tested-by: Miles Chen +Link: https://lore.kernel.org/r/20230120092053.182923-5-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd +--- + 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 index 0000000000..eca1b614cd --- /dev/null +++ b/target/linux/mediatek/patches-6.6/222-v6.3-clk-mediatek-clk-mtk-Propagate-struct-device-for-com.patch @@ -0,0 +1,181 @@ +From f23375db001ec0fe9f565be75eff43adde15407e Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Tested-by: Miles Chen +Link: https://lore.kernel.org/r/20230120092053.182923-6-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd + +[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 index 0000000000..a50422da58 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/223-v6.3-clk-mediatek-clk-mux-Propagate-struct-device-for-mtk.patch @@ -0,0 +1,103 @@ +From 5d911479e4c732729bfa798e4a9e3e5aec3e30a7 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Tested-by: Miles Chen +Link: https://lore.kernel.org/r/20230120092053.182923-7-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd + +[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 index 0000000000..de2e6976c3 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/224-v6.3-clk-mediatek-clk-mtk-Add-dummy-clock-ops.patch @@ -0,0 +1,74 @@ +From b8eb1081d267708ba976525a1fe2162901b34f3a Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Reviewed-by: Miles Chen +Reviewed-by: Chen-Yu Tsai +Tested-by: Miles Chen +Link: https://lore.kernel.org/r/20230120092053.182923-8-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd +--- + 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 index 0000000000..becfcd0ed8 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/225-v6.3-clk-mediatek-Switch-to-mtk_clk_simple_probe-where-po.patch @@ -0,0 +1,790 @@ +From c26e28015b74af73e0b299f6ad3ff22931e600b4 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Reviewed-by: Miles Chen +Tested-by: Miles Chen +Link: https://lore.kernel.org/r/20230120092053.182923-12-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd + +[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, ð_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 = ð_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 = ð_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 index 0000000000..ad02df10b6 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/226-v6.3-clk-mediatek-clk-mtk-Extend-mtk_clk_simple_probe.patch @@ -0,0 +1,189 @@ +From 7b6183108c8ccf0dc295f39cdf78bd8078455636 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Reviewed-by: Miles Chen +Reviewed-by: Chen-Yu Tsai +Tested-by: Miles Chen +Link: https://lore.kernel.org/r/20230120092053.182923-13-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd +--- + 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 + #include + #include ++#include + #include + #include + #include + + #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 index 0000000000..bf9a172926 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/227-v6.3-clk-mediatek-clk-mt7986-topckgen-Properly-keep-some-.patch @@ -0,0 +1,97 @@ +From 3511004225ce917a4aa6e6ac61481ac60f08f401 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Reviewed-by: Chen-Yu Tsai +Reviewed-by: Miles Chen +Link: https://lore.kernel.org/r/20230120092053.182923-23-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd +--- + 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 index 0000000000..d77b859f00 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/228-v6.3-clk-mediatek-clk-mt7986-topckgen-Migrate-to-mtk_clk_.patch @@ -0,0 +1,88 @@ +From 9ce3b4e4719d4eec38b2c8da939c073835573d1d Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Reviewed-by: Miles Chen +Reviewed-by: Chen-Yu Tsai +Link: https://lore.kernel.org/r/20230120092053.182923-24-angelogioacchino.delregno@collabora.com +Tested-by: Mingming Su +Signed-off-by: Stephen Boyd +--- + 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 index 0000000000..a47dd4b053 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/229-v6.4-clk-mediatek-mt7986-apmixed-Use-PLL_AO-flag-to-set-c.patch @@ -0,0 +1,38 @@ +From 06abdc84080729dc2c54946e1712c5ee1589ca1c Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Reviewed-by: Chen-Yu Tsai +Tested-by: Daniel Golle +Link: https://lore.kernel.org/r/20230306140543.1813621-33-angelogioacchino.delregno@collabora.com +Signed-off-by: Stephen Boyd +--- + 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 index 0000000000..ae76940e1d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/230-v6.4-dt-bindings-clock-mediatek-add-mt7981-clock-IDs.patch @@ -0,0 +1,237 @@ +From a6473d0f9f07b1196f3a67099826f50a2a4e84e8 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Jianhui Zhao +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/e353d32b5a4481766519a037afe1ed44e31ece1a.1674703830.git.daniel@makrotopia.org +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Stephen Boyd +--- + .../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 ++ * Author: Jianhui Zhao ++ * Author: Daniel Golle ++ */ ++ ++#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 index 0000000000..f9dd94a78a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/231-v6.4-clk-mediatek-add-MT7981-clock-support.patch @@ -0,0 +1,932 @@ +From 8efeeb9c8b4ecf4fb4a74be9403aba951403bbaa Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/8136eb5b2049177bc2f6d3e0f2aefecc342d626f.1674703830.git.daniel@makrotopia.org +Reviewed-by: AngeloGioacchino Del Regno +[sboyd@kernel.org: Add module license] +Signed-off-by: Stephen Boyd +--- + 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 ++ * Author: Wenzhen Yu ++ * Author: Jianhui Zhao ++ * Author: Daniel Golle ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk-gate.h" ++#include "clk-mtk.h" ++#include "clk-mux.h" ++#include "clk-pll.h" ++ ++#include ++#include ++ ++#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 ++ * Author: Wenzhen Yu ++ * Author: Jianhui Zhao ++ * Author: Daniel Golle ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk-mtk.h" ++#include "clk-gate.h" ++ ++#include ++ ++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 = ð_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 = ð_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 ++ * Author: Wenzhen Yu ++ * Author: Jianhui Zhao ++ * Author: Daniel Golle ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk-mtk.h" ++#include "clk-gate.h" ++#include "clk-mux.h" ++ ++#include ++#include ++ ++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 ++ * Author: Wenzhen Yu ++ * Author: Jianhui Zhao ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk-mtk.h" ++#include "clk-gate.h" ++#include "clk-mux.h" ++ ++#include ++#include ++ ++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 index 0000000000..8820d57f01 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/232-clk-mediatek-mt7981-topckgen-flag-SGM_REG_SEL-as-cri.patch @@ -0,0 +1,30 @@ +From fc157139e6b7f8dfb6430ac7191ba754027705e8 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +--- + 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 index 0000000000..a365f0860b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/240-pinctrl-mediatek-add-support-for-MT7988-SoC.patch @@ -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 index 0000000000..ad4ecdf83f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/241-v6.3-dt-bindings-clock-Add-compatibles-for-MT7981.patch @@ -0,0 +1,75 @@ +From cc4d9e0c77494fcf6bccbc57e23db0007cf681b7 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/cc85ee470c781ff4013f6c21c92c0a21574b12b2.1674703830.git.daniel@makrotopia.org +Signed-off-by: Stephen Boyd +--- + .../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 index 0000000000..48d3d4e90c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/242-v6.4-dt-bindings-arm-mediatek-sgmiisys-Convert-to-DT-sche.patch @@ -0,0 +1,107 @@ +From d4f08a703565abf47baa5a77d05365cf4598d55c Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Daniel Golle +Signed-off-by: Jakub Kicinski +--- + .../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 ++ ++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 index 0000000000..62a64b9dd0 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/243-v6.4-dt-bindings-net-pcs-mediatek-sgmiisys-add-MT7981-SoC.patch @@ -0,0 +1,37 @@ +From 4f7eb19c4f44078100659f6ba073b0cc7191bc91 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Daniel Golle +Signed-off-by: Jakub Kicinski +--- + .../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 index 0000000000..946db82235 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/244-v6.8-dt-bindings-arm-mediatek-move-ethsys-controller-conv.patch @@ -0,0 +1,113 @@ +From 94b0f301f6ee92f79a2fe2c655dfdbdfe2aec536 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +Reviewed-by: Rob Herring +Link: https://lore.kernel.org/r/20231119212416.2682-1-zajec5@gmail.com +Signed-off-by: Stephen Boyd +--- + .../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 ++ ++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 index 0000000000..47f05e93c6 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/245-v6.8-dt-bindings-reset-mediatek-add-MT7988-ethwarp-reset-.patch @@ -0,0 +1,35 @@ +From 5cfa3beb7761cb84be77225902e018d9d3f9b973 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Reviewed-by: AngeloGioacchino Del Regno +Acked-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/0c14bbacf471683af67ffa7572bfa1d5c45a0b5d.1702849494.git.daniel@makrotopia.org +Signed-off-by: Stephen Boyd +--- + 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 ++ * Author: Daniel Golle ++ */ ++ ++#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 index 0000000000..cf5cae6341 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/246-v6.8-dt-bindings-clock-mediatek-add-MT7988-clock-IDs.patch @@ -0,0 +1,302 @@ +From 8187e001de156e99ef95366ffd10d627ed090826 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Daniel Golle +Acked-by: Krzysztof Kozlowski +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/27f99db432e9ccc804cc5b6501d7d17d72cae879.1702849494.git.daniel@makrotopia.org +Signed-off-by: Stephen Boyd +--- + .../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 ++ * Author: Xiufeng Li ++ */ ++ ++#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 index 0000000000..79088b461b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/247-v6.8-dt-bindings-clock-mediatek-add-clock-controllers-of-.patch @@ -0,0 +1,260 @@ +From afd36e9d91b0a840983b829a9e95407d8151f7e7 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/07e76a544ce4392bcb88e34d5480e99bb7994618.1702849494.git.daniel@makrotopia.org +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Stephen Boyd +--- + .../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 ++ ++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 . ++ ++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 ++ 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 ++ ++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 index 0000000000..ca37fc793a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/248-v6.8-clk-mediatek-add-pcw_chg_bit-control-for-PLLs-of-MT7.patch @@ -0,0 +1,50 @@ +From d9bf944beaaad1890ad3fcb755c61e1c7e4c5630 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Daniel Golle +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/3b9c65ddb08c8bedf790aacf29871af026b6f0b7.1702849494.git.daniel@makrotopia.org +Signed-off-by: Stephen Boyd +--- + 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 index 0000000000..61664b934c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/249-v6.8-clk-mediatek-add-drivers-for-MT7988-SoC.patch @@ -0,0 +1,1026 @@ +From 4b4719437d85f0173d344f2c76fa1a5b7f7d184b Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Daniel Golle +Reviewed-by: AngeloGioacchino Del Regno +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 +--- + 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 ++ * Author: Xiufeng Li ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk-mtk.h" ++#include "clk-gate.h" ++#include "clk-mux.h" ++#include "clk-pll.h" ++#include ++ ++#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 ++ * Author: Xiufeng Li ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk-mtk.h" ++#include "clk-gate.h" ++#include "reset.h" ++#include ++#include ++ ++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 = ðdma_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 = ðwarp_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 = ðwarp_rst_desc, ++}; ++ ++static const struct of_device_id of_match_clk_mt7988_eth[] = { ++ { .compatible = "mediatek,mt7988-ethsys", .data = ðdma_desc }, ++ { .compatible = "mediatek,mt7988-sgmiisys0", .data = &sgmii0_desc }, ++ { .compatible = "mediatek,mt7988-sgmiisys1", .data = &sgmii1_desc }, ++ { .compatible = "mediatek,mt7988-ethwarp", .data = ðwarp_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 ++ * Author: Xiufeng Li ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk-mtk.h" ++#include "clk-gate.h" ++#include "clk-mux.h" ++#include ++ ++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 ++ * Author: Xiufeng Li ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk-mtk.h" ++#include "clk-gate.h" ++#include "clk-mux.h" ++#include ++ ++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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk-mtk.h" ++#include "clk-gate.h" ++#include ++ ++/* 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 index 0000000000..cecf095e92 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/250-clk-mediatek-add-infracfg-reset-controller-for-mt798.patch @@ -0,0 +1,57 @@ +From 26ced94177b150710d94cf365002a09cc48950e9 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +--- + 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 ++#include ++ ++#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 index 0000000000..d353074e84 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/250-dt-bindings-reset-mediatek-add-MT7988-reset-IDs.patch @@ -0,0 +1,25 @@ +From 3c810da3206f2e52c92f9f15a87f05db4bbba734 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +--- + 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 index 0000000000..cb49ce1d25 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/251-v6.8-watchdog-mediatek-mt7988-add-wdt-support.patch @@ -0,0 +1,125 @@ +From 137c9e08e5e542d58aa606b0bb4f0990117309a0 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/c0cf5f701801cce60470853fa15f1d9dced78c4f.1700504385.git.daniel@makrotopia.org +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +--- + 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 index 0000000000..c4760b9eff --- /dev/null +++ b/target/linux/mediatek/patches-6.6/252-clk-mediatek-mt7988-infracfg-fix-clocks-for-2nd-PCIe.patch @@ -0,0 +1,31 @@ +From c202f510bbaa34ab5d65a69a61e0e72761374b17 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Daniel Golle +--- + 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 index 0000000000..5e3afd856f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/320-v6.2-mmc-mediatek-add-support-for-MT7986-SoC.patch @@ -0,0 +1,47 @@ +From 24e961b93d292d0dd6380213d22a071a99ea787d Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221025132953.81286-7-linux@fw-web.de +Signed-off-by: Ulf Hansson +--- + 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 index 0000000000..db2802bd0f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/321-v6.2-mmc-mtk-sd-add-Inline-Crypto-Engine-clock-control.patch @@ -0,0 +1,57 @@ +From 7b438d0377fbd520b475a68bdd9de1692393f22d Mon Sep 17 00:00:00 2001 +From: Mengqi Zhang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221106033924.9854-2-mengqi.zhang@mediatek.com +Signed-off-by: Ulf Hansson +--- + 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 index 0000000000..921d249f8c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/322-v6.2-mmc-mtk-sd-fix-two-spelling-mistakes-in-comment.patch @@ -0,0 +1,36 @@ +From 4b323f02b6e8df1b04292635ef829e7f723bf50e Mon Sep 17 00:00:00 2001 +From: Yu Zhe +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221110072819.11530-1-yuzhe@nfschina.com +Signed-off-by: Ulf Hansson +--- + 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 index 0000000000..8e2151e16b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/323-v6.2-mmc-Avoid-open-coding-by-using-mmc_op_tuning.patch @@ -0,0 +1,39 @@ +From b98e7e8daf0ebab9dcc36812378a71e1be0b5089 Mon Sep 17 00:00:00 2001 +From: ChanWoo Lee +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 +Reviewed-by: Adrian Hunter +Link: https://lore.kernel.org/r/20221124080031.14690-1-cw9316.lee@samsung.com +Signed-off-by: Ulf Hansson +--- + 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 index 0000000000..55a308e46c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch @@ -0,0 +1,34 @@ +--- a/drivers/mtd/nand/spi/core.c ++++ b/drivers/mtd/nand/spi/core.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + 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 index 0000000000..3e956701cd --- /dev/null +++ b/target/linux/mediatek/patches-6.6/331-mt7622-rfb1-enable-bmt.patch @@ -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 index 0000000000..ec66363dc9 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch @@ -0,0 +1,122 @@ +From 5f49a5c9b16330e0df8f639310e4715dcad71947 Mon Sep 17 00:00:00 2001 +From: Davide Fioravanti +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 +--- + 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, + ¯onix_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 ++ */ ++ ++#include ++#include ++#include ++ ++#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 index 0000000000..49cd62d0ae --- /dev/null +++ b/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch @@ -0,0 +1,41 @@ +From 4983a1517e7ddbc6f53fc07607e4ebeb51412843 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +--- + 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 index 0000000000..1fcb1e64c7 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch @@ -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 index 0000000000..25ca9485e4 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/400-crypto-add-eip97-inside-secure-support.patch @@ -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 index 0000000000..186c66f687 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/401-crypto-fix-eip97-cache-incoherent.patch @@ -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 index 0000000000..615a1a1d71 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/405-v6.2-mt7986-trng-add-rng-support.patch @@ -0,0 +1,43 @@ +From f1da27b7c4191f78ed81d3dabf64c769f896296c Mon Sep 17 00:00:00 2001 +From: "Mingming.Su" +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 +Signed-off-by: Frank Wunderlich +Signed-off-by: Herbert Xu +--- + 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 index 0000000000..5b94c9216d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/410-bt-mtk-serial-fix.patch @@ -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 index 0000000000..8c2c80d6bf --- /dev/null +++ b/target/linux/mediatek/patches-6.6/431-drivers-spi-mt65xx-Move-chip_config-to-driver-s-priv.patch @@ -0,0 +1,130 @@ +From bfd3acc428085742d754a6d328d1a93ebf9451df Mon Sep 17 00:00:00 2001 +From: "SkyLake.Huang" +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 +--- + 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 + #include + #include +-#include + #include + #include + #include +@@ -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 +- */ +- +-#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 index 0000000000..b2c9df4386 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch @@ -0,0 +1,236 @@ +From 2ade0172154e50c8a2bfd8634c6eff943cffea29 Mon Sep 17 00:00:00 2001 +From: "SkyLake.Huang" +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 +--- + 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 index 0000000000..e87d63db69 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/433-drivers-spi-mem-Add-spi-calibration-hook.patch @@ -0,0 +1,41 @@ +From 06640a5da2973318c06e516da16a5b579622e7c5 Mon Sep 17 00:00:00 2001 +From: "SkyLake.Huang" +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 +--- + 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 index 0000000000..ee3dc27860 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/434-drivers-spi-mt65xx-Add-controller-s-calibration-para.patch @@ -0,0 +1,43 @@ +From d278c7a0bf730318a7ccf8d0a8b434c813e23fd0 Mon Sep 17 00:00:00 2001 +From: "SkyLake.Huang" +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 +--- + 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 index 0000000000..3991d8925a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch @@ -0,0 +1,81 @@ +From 7670ec4a14891a1a182b98a9c403ffbf6b49e4b1 Mon Sep 17 00:00:00 2001 +From: "SkyLake.Huang" +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 +--- + 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 index 0000000000..1f747d1f4f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/436-drivers-mtd-spi-nor-Add-calibration-support-for-spi-.patch @@ -0,0 +1,57 @@ +From f3fe3b15eca7908eaac57f9b8387a5dbc45ec5b2 Mon Sep 17 00:00:00 2001 +From: "SkyLake.Huang" +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 +--- + 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 index 0000000000..487990ab77 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/500-gsw-rtl8367s-mt7622-support.patch @@ -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 index 0000000000..983fde707f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/601-PCI-mediatek-Assert-PERST-for-100ms-for-power-and-cl.patch @@ -0,0 +1,34 @@ +From: qizhong cheng +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 +Signed-off-by: Lorenzo Pieralisi +Acked-by: Pali Rohár +--- + +--- 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 index 0000000000..bf479ab53b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/602-arm64-dts-mediatek-add-mt7622-pcie-slot-node.patch @@ -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 index 0000000000..2a49b2275c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/610-pcie-mediatek-fix-clearing-interrupt-status.patch @@ -0,0 +1,23 @@ +From: Felix Fietkau +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 +--- + +--- 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 index 0000000000..32b4237d82 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/611-pcie-mediatek-gen3-PERST-for-100ms.patch @@ -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 index 0000000000..a597f70caa --- /dev/null +++ b/target/linux/mediatek/patches-6.6/615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch @@ -0,0 +1,167 @@ +From 50cefacc6c001eea1d9b1c78ba27304566f304f1 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Fri, 2 Jun 2023 13:06:26 +0800 +Subject: [PATCH] phy: mediatek: xsphy: support type switch by pericfg + +Patch from Sam Shih 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 +--- + 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 + #include + #include ++#include + #include + #include + #include + #include ++#include + + #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 index 0000000000..76ee2fc89a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch @@ -0,0 +1,82 @@ +From: Felix Fietkau +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 +--- + +--- 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 + #include + #include ++#include + #include + #include + #include +@@ -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 index 0000000000..f9a5fdbd0d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/721-dts-mt7622-mediatek-fix-300mhz.patch @@ -0,0 +1,27 @@ +From: Jip de Beer +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 +Signed-off-by: Fritz D. Ansel +--- +--- 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 index 0000000000..52069496ca --- /dev/null +++ b/target/linux/mediatek/patches-6.6/722-remove-300Hz-to-prevent-freeze.patch @@ -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 index 0000000000..0bbf9ac773 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/730-v6.5-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch @@ -0,0 +1,1204 @@ +From 98c485eaf509bc0e2a85f9b58d17cd501f274c4e Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + 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 ++M: Qingfang Deng ++M: SkyLake Huang ++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 + 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++MODULE_AUTHOR("SkyLake Huang "); ++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 index 0000000000..286ce96a7d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/731-v6.5-net-phy-mediatek-ge-soc-support-PHY-LEDs.patch @@ -0,0 +1,524 @@ +From c66937b0f8dbb4c6c043663c702b1053fb47fab2 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/dc324d48c00cd7350f3a506eaa785324cae97372.1691977904.git.daniel@makrotopia.org +Signed-off-by: Jakub Kicinski +--- + 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 ++#include ++#include + #include + #include + #include + #include + #include + #include ++#include + + #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, ®); ++ 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 index 0000000000..76d8b0ef00 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch @@ -0,0 +1,63 @@ +From a969b663c866129ed9eb217785a6574fbe826f1d Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +--- + 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 index 0000000000..b4c07a4b1f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch @@ -0,0 +1,39 @@ +From 128dc09b0af36772062142ce9e85b19c84ac789a Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +--- + 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 index 0000000000..5daa62b6b7 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/734-v6.8-net-phy-mediatek-ge-soc-sync-driver-with-MediaTek-SD.patch @@ -0,0 +1,270 @@ +From f2195279c234c0f618946424b8236026126bc595 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Daniel Golle +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 , + Qingfang Deng , + SkyLake Huang , + Andrew Lunn , + Heiner Kallweit , + Russell King , + David S. Miller , + Eric Dumazet , + Jakub Kicinski , + Paolo Abeni , + Matthias Brugger , + AngeloGioacchino Del Regno , + 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 +--- + 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 index 0000000000..0c73d520b4 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/804-v6.2-pwm-add-mt7986-support.patch @@ -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 index 0000000000..f130fdbc56 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/826-v6.2-pinctrl-mediatek-extend-pinctrl-moore-to-support-new.patch @@ -0,0 +1,129 @@ +From fae82621ac33e2a4a96220c56e90d1ec6237d394 Mon Sep 17 00:00:00 2001 +From: Sam Shih +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 +Signed-off-by: Frank Wunderlich +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221106080114.7426-6-linux@fw-web.de +Signed-off-by: Linus Walleij +--- + 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 + #include + #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 index 0000000000..694b73a2b1 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.3-01-thermal-drivers-mtk_thermal-Fix-kernel-doc-function-.patch @@ -0,0 +1,37 @@ +From f167da186acf90847e1a6d3716e253825a6218ec Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +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 +Cc: "Rafael J. Wysocki" +Cc: Daniel Lezcano +Cc: Amit Kucheria +Cc: Zhang Rui +Cc: Matthias Brugger +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 +--- + 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 index 0000000000..aaed9d7e90 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.3-02-thermal-drivers-mtk_thermal-Use-devm_platform_get_an.patch @@ -0,0 +1,37 @@ +From 255509232417ee71fd606cb957d44cf6544f0c43 Mon Sep 17 00:00:00 2001 +From: ye xingchen +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 +Link: https://lore.kernel.org/r/202301181637472073620@zte.com.cn +Signed-off-by: Daniel Lezcano +--- + 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 index 0000000000..215b0fd7de --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.3-03-thermal-drivers-mtk-Use-function-pointer-for-raw_to_.patch @@ -0,0 +1,60 @@ +From ca86dbd309ba03bef38ae91f037e2030bb671ab7 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: Daniel Golle +Reviewed-by: Matthias Brugger +Link: https://lore.kernel.org/r/69c17529e8418da3eec703dde31e1b01e5b0f7e8.1674055882.git.daniel@makrotopia.org +Signed-off-by: Daniel Lezcano +--- + 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 index 0000000000..ef2006775a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.3-04-thermal-drivers-mtk-Add-support-for-MT7986-and-MT798.patch @@ -0,0 +1,236 @@ +From aec1d89dccc7cba04fdb3e52dfda328f3302ba17 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/2d341fc45266217249586eb4bd3be3ac4ca83a12.1674055882.git.daniel@makrotopia.org +Signed-off-by: Daniel Lezcano +--- + 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 index 0000000000..e102a338cd --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.3-05-thermal-drivers-mediatek-Relocate-driver-to-mediatek.patch @@ -0,0 +1,2602 @@ +From 5e3aac197a74914ccec2732a89c29d960730d28f Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230209105628.50294-2-bchihi@baylibre.com +Signed-off-by: Daniel Lezcano +Signed-off-by: Rafael J. Wysocki +--- + 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 +- * Sascha Hauer +- * Dawei Chien +- * Louis Yu +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#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 "); +-MODULE_AUTHOR("Louis Yu "); +-MODULE_AUTHOR("Dawei Chien "); +-MODULE_AUTHOR("Sascha Hauer "); +-MODULE_AUTHOR("Hanyi Wu "); +-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 ++ * Sascha Hauer ++ * Dawei Chien ++ * Louis Yu ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++MODULE_AUTHOR("Louis Yu "); ++MODULE_AUTHOR("Dawei Chien "); ++MODULE_AUTHOR("Sascha Hauer "); ++MODULE_AUTHOR("Hanyi Wu "); ++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 index 0000000000..2ae3734e40 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.3-06-thermal-drivers-mediatek-Add-the-Low-Voltage-Thermal.patch @@ -0,0 +1,1298 @@ +From 325fadf27b21f7d79843c3cc282b7f3e6620ad3d Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +Reviewed-by: AngeloGioacchino Del Regno + +On MT8195 Tomato Chromebook: + +Tested-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230209105628.50294-5-bchihi@baylibre.com +Signed-off-by: Daniel Lezcano +Signed-off-by: Rafael J. Wysocki +--- + 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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++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 index 0000000000..b6a5f64090 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-07-dt-bindings-thermal-mediatek-Add-LVTS-thermal-contro.patch @@ -0,0 +1,186 @@ +From 498e2f7a6e69dcbca24715de2b4b97569fdfeff4 Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +Reviewed-by: Rob Herring +Link: https://lore.kernel.org/r/20230209105628.50294-3-bchihi@baylibre.com +Signed-off-by: Daniel Lezcano +Signed-off-by: Rafael J. Wysocki +--- + .../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 ++ ++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 ++ #include ++ #include ++ #include ++ ++ soc { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ lvts_mcu: thermal-sensor@11278000 { ++ compatible = "mediatek,mt8195-lvts-mcu"; ++ reg = <0 0x11278000 0 0x1000>; ++ interrupts = ; ++ 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 ++ */ ++ ++#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 index 0000000000..efb0d8b64f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-08-dt-bindings-thermal-mediatek-Add-AP-domain-to-LVTS-t.patch @@ -0,0 +1,35 @@ +From 05aaa7fdb0736262e224369b9b9f1410320fc71b Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +Acked-by: Rob Herring +Reviewed-by: AngeloGioacchino Del Regno +Tested-by: Chen-Yu Tsai +Signed-off-by: Daniel Lezcano +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 index 0000000000..c68969321e --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-09-thermal-core-Add-a-thermal-zone-devdata-accessor.patch @@ -0,0 +1,65 @@ +From a6ff3c0021468721b96e84892a8cae24bde8d65f Mon Sep 17 00:00:00 2001 +From: Daniel Lezcano +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 +Acked-by: Rafael J. Wysocki +Acked-by: Mark Brown +Signed-off-by: Rafael J. Wysocki +--- + 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 index 0000000000..66d3c9e302 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-10-thermal-core-Add-thermal_zone_device-structure-type-.patch @@ -0,0 +1,55 @@ +From 072e35c98806100182c0a7263cf4cba09ce43463 Mon Sep 17 00:00:00 2001 +From: Daniel Lezcano +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 +Signed-off-by: Rafael J. Wysocki +--- + 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 index 0000000000..57bc910d3e --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-11-thermal-core-Use-the-thermal-zone-devdata-accessor-i.patch @@ -0,0 +1,74 @@ +From 7d78bab533eb9aa0e5240e25a204e8f416723ed6 Mon Sep 17 00:00:00 2001 +From: Daniel Lezcano +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 +Reviewed-by: Niklas Söderlund #R-Car +Acked-by: Mark Brown +Reviewed-by: AngeloGioacchino Del Regno #MediaTek auxadc and lvts +Reviewed-by: Balsam CHIHI #Mediatek lvts +Reviewed-by: Adam Ward #da9062 +Reviewed-by: Baolin Wang #spread +Acked-by: Jernej Skrabec #sun8i_thermal +Acked-by: Rafael J. Wysocki +Acked-by: Florian Fainelli #Broadcom +Reviewed-by: Dhruva Gole # K3 bandgap +Acked-by: Linus Walleij +Acked-by: Heiko Stuebner #rockchip +Reviewed-by: Kunihiko Hayashi #uniphier +Signed-off-by: Rafael J. Wysocki +--- + 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 index 0000000000..647b3b0eca --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-12-thermal-hwmon-Use-the-right-device-for-devm_thermal_.patch @@ -0,0 +1,201 @@ +From cc9c60e9cfeeac45d63361fa8c085c43c4bdfe3a Mon Sep 17 00:00:00 2001 +From: Daniel Lezcano +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 +Acked-by: Martin Blumenstingl #amlogic_thermal +Acked-by: Jernej Skrabec #sun8i_thermal +Reviewed-by: AngeloGioacchino Del Regno #MediaTek auxadc +Signed-off-by: Rafael J. Wysocki +--- + 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 index 0000000000..9dedc2cb68 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-13-thermal-Don-t-use-device-internal-thermal-zone-struc.patch @@ -0,0 +1,79 @@ +From 5a72b8e4bac753e4dc74dc0a1335d120f63df97a Mon Sep 17 00:00:00 2001 +From: Daniel Lezcano +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 +Cc: Guenter Roeck +Signed-off-by: Daniel Lezcano +Reviewed-by: Balsam CHIHI #Mediatek LVTS +Reviewed-by: AngeloGioacchino Del Regno #MediaTek LVTS +Signed-off-by: Rafael J. Wysocki +--- + 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 index 0000000000..8cec9aba97 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-14-thermal-Use-thermal_zone_device_type-accessor.patch @@ -0,0 +1,62 @@ +From 66b3a292d3fc749e8ec7ac5278a17e8a5757ecbc Mon Sep 17 00:00:00 2001 +From: Daniel Lezcano +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 +Reviewed-by: Ido Schimmel #mlxsw +Reviewed-by: AngeloGioacchino Del Regno #MediaTek LVTS +Signed-off-by: Rafael J. Wysocki +--- + 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 index 0000000000..68f41fdd16 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-15-thermal-drivers-mediatek-Control-buffer-enablement-t.patch @@ -0,0 +1,81 @@ +From f6658c1c4ae98477d6be00495226c0617354fe76 Mon Sep 17 00:00:00 2001 +From: Markus Schneider-Pargmann +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 +Signed-off-by: Fabien Parent +Signed-off-by: Amjad Ouled-Ameur +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-2-55a1ae14af74@baylibre.com +Signed-off-by: Daniel Lezcano +--- + 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 index 0000000000..285c6f6a7b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-16-thermal-drivers-mediatek-Add-support-for-MT8365-SoC.patch @@ -0,0 +1,123 @@ +From c4eff784465f88218dc5eb51320320464db83d3f Mon Sep 17 00:00:00 2001 +From: Fabien Parent +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 +Signed-off-by: Amjad Ouled-Ameur +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-3-55a1ae14af74@baylibre.com +Signed-off-by: Daniel Lezcano +--- + 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 index 0000000000..5c99aa80c1 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-17-thermal-drivers-mediatek-Add-delay-after-thermal-ban.patch @@ -0,0 +1,50 @@ +From 4eead70db74922bc61e9d0b4591524369a335751 Mon Sep 17 00:00:00 2001 +From: Amjad Ouled-Ameur +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 +Signed-off-by: Hsin-Yi Wang +Signed-off-by: Amjad Ouled-Ameur +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20221018-up-i350-thermal-bringup-v9-5-55a1ae14af74@baylibre.com +Signed-off-by: Daniel Lezcano +--- + 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 index 0000000000..734f5c1e77 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-18-thermal-drivers-mediatek-lvts_thermal-Fix-sensor-1-i.patch @@ -0,0 +1,46 @@ +From ad9dc9e92367803a4f9576aea0dab110d03fc510 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +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 +Signed-off-by: Daniel Lezcano +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 index 0000000000..d09c2055a3 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-19-thermal-drivers-mediatek-lvts_thermal-Add-AP-domain-.patch @@ -0,0 +1,149 @@ +From 9aad43ad3285fc21158fb416830a6156a9a31fa5 Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +Tested-by: Chen-Yu Tsai +Signed-off-by: Daniel Lezcano +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 index 0000000000..a48ea3742b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-20-Revert-thermal-drivers-mediatek-Add-delay-after-ther.patch @@ -0,0 +1,53 @@ +From 7105a86760bd9e4d107075cefc75016b693a5542 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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" +Signed-off-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..aae87af5d1 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-21-thermal-drivers-mediatek-Add-temperature-constraints.patch @@ -0,0 +1,78 @@ +From 681b652c9dfc4037d4a55b2733e091a4e1a5de18 Mon Sep 17 00:00:00 2001 +From: AngeloGioacchino Del Regno +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 +Signed-off-by: Daniel Lezcano +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 index 0000000000..782684aacc --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-22-thermal-drivers-mediatek-Use-devm_of_iomap-to-avoid-.patch @@ -0,0 +1,53 @@ +From 458fa1d508de3f17e49d974a0158d9aeff273a58 Mon Sep 17 00:00:00 2001 +From: Kang Chen +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 +Reviewed-by: Dongliang Mu +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..d7896dbd60 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-23-thermal-drivers-mediatek-Change-clk_prepare_enable-t.patch @@ -0,0 +1,100 @@ +From 227d1856924ec00a4f5bdf5afcf77bc7f3f04e86 Mon Sep 17 00:00:00 2001 +From: Kang Chen +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 +Reviewed-by: Dongliang Mu +Signed-off-by: Daniel Lezcano +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 index 0000000000..fd18a5365c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-24-thermal-drivers-mediatek-Use-of_address_to_resource.patch @@ -0,0 +1,36 @@ +From 655fe2533ac05323a07c19ba079bf2064e7741af Mon Sep 17 00:00:00 2001 +From: Rob Herring +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 +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..c3ff17d517 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-25-Revert-thermal-drivers-mediatek-Use-devm_of_iomap-to.patch @@ -0,0 +1,57 @@ +From 2c380d07215e6fce3ac66cc5af059bc2c2a69f7a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ricardo=20Ca=C3=B1uelo?= +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 +Suggested-by: AngeloGioacchino Del Regno +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..c4456529c1 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-26-thermal-drivers-mediatek-lvts_thermal-Register-therm.patch @@ -0,0 +1,37 @@ +From 496f4b08981d8a788ad5a2073fa1c65a2af1862b Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +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 +Signed-off-by: Daniel Lezcano +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 + #include + ++#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 index 0000000000..22e7a954ed --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-27-thermal-drivers-mediatek-lvts_thermal-Remove-redunda.patch @@ -0,0 +1,28 @@ +From 885b9768ce2a66ed5d250822aed53d5114c895da Mon Sep 17 00:00:00 2001 +From: Yangtao Li +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 +Signed-off-by: Daniel Lezcano +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 index 0000000000..bc67727423 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-29-thermal-drivers-mediatek-lvts_thermal-Handle-IRQ-on-.patch @@ -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?= + +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 +Reviewed-by: AngeloGioacchino Del Regno +Tested-by: Chen-Yu Tsai +Signed-off-by: Nícolas F. R. A. Prado +Reviewed-by: Alexandre Mergnat +Signed-off-by: Daniel Lezcano +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 index 0000000000..51d119c05b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-30-thermal-drivers-mediatek-lvts_thermal-Honor-sensors-.patch @@ -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?= + +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 +Tested-by: Chen-Yu Tsai +Signed-off-by: Nícolas F. R. A. Prado +Reviewed-by: Alexandre Mergnat +Signed-off-by: Daniel Lezcano +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 index 0000000000..bfbadee350 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-31-thermal-drivers-mediatek-lvts_thermal-Use-offset-thr.patch @@ -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?= + +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 +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..1c35d0ad19 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-32-thermal-drivers-mediatek-lvts_thermal-Disable-undesi.patch @@ -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?= + +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 +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Alexandre Mergnat +Signed-off-by: Daniel Lezcano +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 index 0000000000..60942fdb89 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-33-thermal-drivers-mediatek-lvts_thermal-Don-t-leave-th.patch @@ -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?= + +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 +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..e99aa0cdfd --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-34-thermal-drivers-mediatek-lvts_thermal-Manage-thresho.patch @@ -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?= + +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 +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..9ce3eeb74b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-35-thermal-drivers-mediatek-lvts-Fix-parameter-check-in.patch @@ -0,0 +1,29 @@ +From 5af4904adc8b840987000724977c13c706d3b7d8 Mon Sep 17 00:00:00 2001 +From: Minjie Du +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 +Signed-off-by: Daniel Lezcano +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 index 0000000000..4841054917 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-36-thermal-drivers-mediatek-Clean-up-redundant-dev_err_.patch @@ -0,0 +1,33 @@ +From 6186be80317d1dbda34d35c06c084a083938f2d3 Mon Sep 17 00:00:00 2001 +From: Chen Jiahao +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 +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..c88bf984fa --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.4-37-thermal-drivers-mediatek-lvts_thermal-Make-readings-.patch @@ -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?= + +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 +Tested-by: Chen-Yu Tsai +Signed-off-by: Nícolas F. R. A. Prado +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..994461cdb1 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.6-38-thermal-drivers-mediatek-auxadc_thermal-Removed-call.patch @@ -0,0 +1,30 @@ +From c864ff9de3b225b43bb8e08dedb223632323e059 Mon Sep 17 00:00:00 2001 +From: Andrei Coardos +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 +Reviewed-by: Alexandru Ardelean +Signed-off-by: Daniel Lezcano +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 index 0000000000..b3bfa37458 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-39-thermal-lvts-Convert-to-platform-remove-callback-ret.patch @@ -0,0 +1,58 @@ +From 6cf96078969ec00b873db99bae4e47001290685e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +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 +Acked-by: Daniel Lezcano +Signed-off-by: Rafael J. Wysocki +--- + 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 index 0000000000..16a32f564b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-40-thermal-drivers-mediatek-lvts_thermal-Make-coeff-con.patch @@ -0,0 +1,198 @@ +From 26cc18a3d6d9eac21c4f4b4bb96147b2c6617c86 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Reviewed-by: AngeloGioacchino Del Regno +Tested-by: Daniel Golle +Signed-off-by: Daniel Lezcano +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 index 0000000000..1c2146f43f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-41-dt-bindings-thermal-mediatek-Add-LVTS-thermal-sensor.patch @@ -0,0 +1,35 @@ +From be2cc09bd5b46f13629d4fcdeac7ad1b18bb1a0b Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Reviewed-by: AngeloGioacchino Del Regno +Acked-by: Conor Dooley +Signed-off-by: Daniel Lezcano +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 index 0000000000..97c803a820 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-42-thermal-drivers-mediatek-lvts_thermal-Add-mt7988-sup.patch @@ -0,0 +1,91 @@ +From 9924e9b91b43aaa1610a1d59c4caa43785948cf6 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Tested-by: Daniel Golle +Signed-off-by: Daniel Lezcano +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 index 0000000000..5b212a2a37 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-43-thermal-drivers-mediatek-lvts_thermal-Fix-error-chec.patch @@ -0,0 +1,30 @@ +From fb1bbb5b63e4e3c788a978724749ced57d208054 Mon Sep 17 00:00:00 2001 +From: Minjie Du +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 +Reviewed-by: Alexandre Mergnat +Reviewed-by: Chen-Yu Tsai +Signed-off-by: Daniel Lezcano +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 index 0000000000..88f383c4ae --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-44-thermal-drivers-mediatek-Fix-probe-for-THERMAL_V2.patch @@ -0,0 +1,33 @@ +From e6f43063f2fe9f08b34797bc6d223f7d63b01910 Mon Sep 17 00:00:00 2001 +From: Markus Schneider-Pargmann +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 +Closes: https://lore.kernel.org/lkml/B0B3775B-B8D1-4284-814F-4F41EC22F532@public-files.de/ +Reported-by: Daniel Lezcano +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 +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..7b4b124b56 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-45-thermal-drivers-mediatek-lvts_thermal-Add-suspend-an.patch @@ -0,0 +1,83 @@ +From a1d874ef3376295ee8ed89b3b5315f4c840ff00b Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +[bero@baylibre.com: suspend/resume in noirq phase] +Co-developed-by: Bernhard Rosenkränzer +Signed-off-by: Bernhard Rosenkränzer +Reviewed-by: Matthias Brugger +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..c278168610 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-46-dt-bindings-thermal-mediatek-Add-LVTS-thermal-contro.patch @@ -0,0 +1,49 @@ +From 0bb4937b58ab712f158588376dbac97f8e9df68e Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +Reviewed-by: AngeloGioacchino Del Regno +Acked-by: Krzysztof Kozlowski +Signed-off-by: Bernhard Rosenkränzer +Reviewed-by: Matthias Brugger +Reviewed-by: Alexandre Mergnat +Signed-off-by: Daniel Lezcano +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 index 0000000000..6d68a6cd57 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-47-thermal-drivers-mediatek-lvts_thermal-Add-mt8192-sup.patch @@ -0,0 +1,151 @@ +From 7d8b3864b38d881cf105328ff8569f47446811ad Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +Signed-off-by: Nícolas F. R. A. Prado +Signed-off-by: Balsam CHIHI +Reviewed-by: Nícolas F. R. A. Prado +[bero@baylibre.com: cosmetic changes, rebase] +Signed-off-by: Bernhard Rosenkränzer +Reviewed-by: Matthias Brugger +Reviewed-by: Alexandre Mergnat +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Daniel Lezcano +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 index 0000000000..c20c0b5f2e --- /dev/null +++ b/target/linux/mediatek/patches-6.6/830-v6.7-48-thermal-drivers-mediatek-lvts_thermal-Update-calibra.patch @@ -0,0 +1,70 @@ +From 5d126a3c87cf7964b28bacf3826eea4266265bce Mon Sep 17 00:00:00 2001 +From: Balsam CHIHI +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 +Reviewed-by: Nícolas F. R. A. Prado +[bero@baylibre.com: Fix issues pointed out by Nícolas F. R. A. Prado ] +Signed-off-by: Bernhard Rosenkränzer +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Alexandre Mergnat +Signed-off-by: Daniel Lezcano +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 index 0000000000..fc173646e0 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/831-thermal-drivers-mediatek-Fix-control-buffer-enablement-on-MT7896.patch @@ -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 +X-Patchwork-Id: 13376356 +From: Frank Wunderlich +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: +Cc: Daniel Lezcano , + "Rafael J. Wysocki" , linux-pm@vger.kernel.org, + Amit Kucheria , Daniel Golle , + stable@vger.kernel.org, linux-kernel@vger.kernel.org, + Matthias Brugger , Zhang Rui , + linux-arm-kernel@lists.infradead.org, + AngeloGioacchino Del Regno +Sender: "Linux-mediatek" + +From: Frank Wunderlich + +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 +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Markus Schneider-Pargmann +--- + 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 index 0000000000..4c398c59f9 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/851-v6.2-i2c-mediatek-add-mt7986-support.patch @@ -0,0 +1,44 @@ +From 11f9a0f4e51887ad7b4a2898a368fcd0c2984e89 Mon Sep 17 00:00:00 2001 +From: Frank Wunderlich +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 +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Wolfram Sang +--- + 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 index 0000000000..18c66cdac5 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/852-v6.3-i2c-mt65xx-Use-devm_platform_get_and_ioremap_resourc.patch @@ -0,0 +1,42 @@ +From 98204ccafd45a8a6109ff2d60e2c179b95d92578 Mon Sep 17 00:00:00 2001 +From: ye xingchen +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 +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Wolfram Sang +--- + 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 index 0000000000..d000d53522 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/853-v6.3-i2c-mt65xx-drop-of_match_ptr-for-ID-table.patch @@ -0,0 +1,33 @@ +From 8106fa2e0ae6082833fe1df97829c46c0183eaea Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +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 +Reviewed-by: Guenter Roeck +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Wolfram Sang +--- + 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 index 0000000000..e0973741e2 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/854-v6.4-i2c-mediatek-add-support-for-MT7981-SoC.patch @@ -0,0 +1,47 @@ +From f69f3d662ba3bf999c36d9ac1e684540c4487bc3 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Alexandre Mergnat +Signed-off-by: Wolfram Sang +--- + 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 index 0000000000..69cc155d8d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/855-i2c-mt65xx-allow-optional-pmic-clock.patch @@ -0,0 +1,45 @@ +From 3bf827929a44c17bfb1bf1000b143c02ce26a929 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +--- + 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 index 0000000000..9607eec821 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.6-01-ASoC-mediatek-mt7986-add-common-header.patch @@ -0,0 +1,269 @@ +From d35469096915f2551ed1d26da1ab12ff500fc963 Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230817101338.18782-2-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + 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 ++ * Maso Huang ++ */ ++ ++#ifndef _MT_7986_AFE_COMMON_H_ ++#define _MT_7986_AFE_COMMON_H_ ++ ++#include ++#include ++#include ++#include ++#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 ++ * Maso Huang ++ */ ++ ++#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 index 0000000000..f22add580f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.6-02-ASoC-mediatek-mt7986-support-etdm-in-platform-driver.patch @@ -0,0 +1,430 @@ +From 948a288897015fb3ee63b3f720b396b590c17fd7 Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230817101338.18782-3-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + 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 ++ * Maso Huang ++ */ ++ ++#include ++#include ++#include ++#include ++#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 index 0000000000..b899b963d2 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.6-03-ASoC-mediatek-mt7986-add-platform-driver.patch @@ -0,0 +1,685 @@ +From fc7776dee86bc07d22820a904760a95f49a2f12e Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230817101338.18782-4-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + 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 ++ * Maso Huang ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++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 index 0000000000..dd354c04e3 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.6-04-ASoC-mediatek-mt7986-add-machine-driver-with-wm8960.patch @@ -0,0 +1,243 @@ +From ddf6abc1c78072f8ccad59166be95f0ca5af8ca4 Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230817101338.18782-5-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + 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 ++ * Maso Huang ++ */ ++ ++#include ++#include ++ ++#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 "); ++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 index 0000000000..8cf0b5464a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.6-05-ASoC-dt-bindings-mediatek-mt7986-wm8960-add-mt7986-w.patch @@ -0,0 +1,87 @@ +From 72469f950b629e57e60fbcbefed45e083619b986 Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230817101338.18782-6-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + .../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 ++ ++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 index 0000000000..236d6a217c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.6-06-ASoC-dt-bindings-mediatek-mt7986-afe-add-audio-afe-d.patch @@ -0,0 +1,180 @@ +From d16202eb38585adbc16e32d11188dbc2127015de Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20230817101338.18782-7-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + .../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 ++ ++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 ++ #include ++ #include ++ ++ afe@11210000 { ++ compatible = "mediatek,mt7986-afe"; ++ reg = <0x11210000 0x9000>; ++ interrupts = ; ++ 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 index 0000000000..413db8233f --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.7-07-ASoC-mediatek-mt7986-drop-the-remove-callback-of-mt7.patch @@ -0,0 +1,42 @@ +From f3f0934e5c7b9c16e0cb2435be3555382e6293ad Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20231024035019.11732-2-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + 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 index 0000000000..5c596fc49c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.7-08-ASoC-mediatek-mt7986-remove-the-mt7986_wm8960_priv-s.patch @@ -0,0 +1,105 @@ +From 98b8fb2cb4fcab1903d0baf611bf0c3f822a08dc Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20231024035019.11732-3-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + 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 index 0000000000..d4128deabc --- /dev/null +++ b/target/linux/mediatek/patches-6.6/860-v6.7-09-ASoC-mediatek-mt7986-add-sample-rate-checker.patch @@ -0,0 +1,49 @@ +From 4e229f4264f4be7a6a554487714c0913ef59cf7f Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 +Reviewed-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20231024035019.11732-4-maso.huang@mediatek.com +Signed-off-by: Mark Brown +--- + 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 index 0000000000..a40c249257 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/861-pending-10-ASoC-mediatek-mt7986-silence-error-in-case-of-EPROBE.patch @@ -0,0 +1,26 @@ +From e4cde335d1771863a60b6931e51357b8470e85c4 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +--- + 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 index 0000000000..b31710fe69 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/862-arm64-dts-mt7986-add-afe.patch @@ -0,0 +1,40 @@ +From 1c09b694a1e9378931085e77d834a4d9786a5356 Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 = ; ++ 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 index 0000000000..15e30dec56 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/863-arm64-dts-mt7986-add-sound-wm8960.patch @@ -0,0 +1,61 @@ +From 1c09b694a1e9378931085e77d834a4d9786a5356 Mon Sep 17 00:00:00 2001 +From: Maso Huang +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 index 0000000000..bddcd4bb0c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/864-arm64-dts-mt7986-add-sound-overlay-for-bpi-r3.patch @@ -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 ++ */ ++ ++/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 index 0000000000..6dede02003 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/900-dts-mt7622-bpi-r64-aliases-for-dtoverlay.patch @@ -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 ++ ++/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 ++ ++/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 index 0000000000..bfca4b6389 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch @@ -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 index 0000000000..09ce417c35 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/910-dts-mt7622-bpi-r64-wifi-eeprom.patch @@ -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 index 0000000000..5d3153ded4 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch @@ -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 = <®_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 index 0000000000..6e6810b42a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/930-spi-mt65xx-enable-sel-clk.patch @@ -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 index 0000000000..30be53518a --- /dev/null +++ b/target/linux/mediatek/patches-6.6/940-net-ethernet-mtk_wed-rename-mtk_wed_get_memory_regio.patch @@ -0,0 +1,37 @@ +From 3cf212c4ce6cd72c09bc47f35f539ba0afd4d106 Mon Sep 17 00:00:00 2001 +Message-Id: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +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 +--- + 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 index 0000000000..3ba485346c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/941-arm64-dts-mt7986-move-cpuboot-in-a-dedicated-node.patch @@ -0,0 +1,66 @@ +From 247e566e3459481f1fa98733534bfed767e18b42 Mon Sep 17 00:00:00 2001 +Message-Id: <247e566e3459481f1fa98733534bfed767e18b42.1678620342.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +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 +--- + 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 = ; + 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 = ; + 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 = ; + }; + ++ 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 index 0000000000..b4bea2087b --- /dev/null +++ b/target/linux/mediatek/patches-6.6/942-net-ethernet-mtk_wed-move-cpuboot-in-a-dedicated-dts.patch @@ -0,0 +1,81 @@ +From f292d1bf83ec160bef2532b58aa08f5b71041923 Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org> +References: <3cf212c4ce6cd72c09bc47f35f539ba0afd4d106.1678716918.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +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 +--- + 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 index 0000000000..b4ba5b0d2d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/943-net-ethernet-mtk_wed-move-ilm-a-dedicated-dts-node.patch @@ -0,0 +1,86 @@ +From f3565e6c2276411275e707a5442d3f69cc111273 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Lorenzo Bianconi +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 +--- + 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 index 0000000000..c92fcd43ce --- /dev/null +++ b/target/linux/mediatek/patches-6.6/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch @@ -0,0 +1,57 @@ +From b74ba226be2c45091b93bd49192bdd6d2178729e Mon Sep 17 00:00:00 2001 +Message-Id: +In-Reply-To: +References: +From: Lorenzo Bianconi +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 +--- + 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 index 0000000000..0ba9bd7cf0 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/945-arm64-dts-mt7986-move-ilm-in-a-dedicated-node.patch @@ -0,0 +1,83 @@ +From 01561065af5bf1d2a4244896d897e3a1eafbcd46 Mon Sep 17 00:00:00 2001 +Message-Id: <01561065af5bf1d2a4244896d897e3a1eafbcd46.1678717704.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +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 +--- + 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 = ; +- 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 = ; +- 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 = ; + }; + ++ 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 index 0000000000..90b2bb91a2 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/946-arm64-dts-mt7986-move-dlm-in-a-dedicated-node.patch @@ -0,0 +1,81 @@ +From 9f76be683a8ec498563c294bc1cc279468058302 Mon Sep 17 00:00:00 2001 +Message-Id: <9f76be683a8ec498563c294bc1cc279468058302.1678719283.git.lorenzo@kernel.org> +From: Lorenzo Bianconi +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 +--- + 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 = ; +- 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 = ; +- 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 index 0000000000..8b86c50429 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/950-smartrg-i2c-led-driver.patch @@ -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 index 0000000000..71cb3006ab --- /dev/null +++ b/target/linux/mediatek/patches-6.6/961-net-ethernet-mediatek-split-tx-and-rx-fields-in-mtk_.patch @@ -0,0 +1,599 @@ +From: Lorenzo Bianconi +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 +--- + 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, + ð->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 = ð->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 = ð->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 = ð->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(ð->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(ð->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(ð->tx_napi); + napi_enable(ð->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(ð->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(ð->tx_napi); + napi_disable(ð->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 index 0000000000..8b7d5c0a1c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/962-net-ethernet-mediatek-use-QDMA-instead-of-ADMAv2-on-.patch @@ -0,0 +1,123 @@ +From: Daniel Golle +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 +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Daniel Golle +--- + 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 index 0000000000..11b52d07ab --- /dev/null +++ b/target/linux/mediatek/patches-6.6/963-net-ethernet-mtk_eth_soc-fix-WED-wifi-reset.patch @@ -0,0 +1,49 @@ +From: Felix Fietkau +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 +--- + +--- 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); + }