From a94b34b29ab0204d3f1789e234c94b173dc20ce4 Mon Sep 17 00:00:00 2001 From: Rani Hod Date: Fri, 7 Jul 2023 18:26:32 +0300 Subject: [PATCH 01/15] apm821xx: fix autoloading of kmod-hw-crypto4xx Fixes: 55fbcad20a2d (apm821xx: make crypto4xx as a standalone module) Signed-off-by: Rani Hod --- target/linux/apm821xx/modules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/apm821xx/modules.mk b/target/linux/apm821xx/modules.mk index f8880d6712..1abb12a483 100644 --- a/target/linux/apm821xx/modules.mk +++ b/target/linux/apm821xx/modules.mk @@ -23,7 +23,7 @@ define KernelPackage/hw-crypto-4xx +kmod-crypto-ccm +kmod-crypto-gcm \ +kmod-crypto-sha1 +kmod-crypto-sha256 +kmod-crypto-sha512 FILES:=$(LINUX_DIR)/drivers/crypto/amcc/crypto4xx.ko - AUTOLOAD:=$(call AutoLoad,09,sata_dwc_460ex,1) + AUTOLOAD:=$(call AutoLoad,09,crypto4xx,1) $(call AddDepends/crypto) endef From 6b52a9b7520e6982c4876d792b10ad8771dc7f1b Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 8 Jul 2023 12:33:17 +0100 Subject: [PATCH 02/15] kernel: add two missing symbols in 6.1 Two more new symbols were discovered when building mediatek targets with CONFIG_ALL_KMODS=y. Signed-off-by: Daniel Golle --- target/linux/generic/config-6.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 index 4d7ef7b2bd..6a3ed63f56 100644 --- a/target/linux/generic/config-6.1 +++ b/target/linux/generic/config-6.1 @@ -3133,6 +3133,7 @@ CONFIG_KERNFS=y # CONFIG_KEYBOARD_MAX7359 is not set # CONFIG_KEYBOARD_MCS is not set # CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_MT6779 is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_OMAP4 is not set # CONFIG_KEYBOARD_OPENCORES is not set @@ -6297,6 +6298,7 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_MT6797 is not set # CONFIG_SND_SOC_MT8173 is not set # CONFIG_SND_SOC_MT8183 is not set +# CONFIG_SND_SOC_MT8186 is not set # CONFIG_SND_SOC_MT8192 is not set # CONFIG_SND_SOC_MT8195 is not set # CONFIG_SND_SOC_MTK_BTCVSD is not set From 0f9e8baa9ec38288c587893667ac4d103ccd7bfe Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 8 Jul 2023 14:46:18 +0100 Subject: [PATCH 03/15] kernel: leds-ws2812b: fix build with Linux >= 5.18 The return value of the .remove function pointer has changed from int to void with Linux 5.18. Use a precompiler macro to allow building the leds-ws2812b module with both, Linux 5.15 and Linux 6.1. Signed-off-by: Daniel Golle --- package/kernel/leds-ws2812b/src/leds-ws2812b.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/package/kernel/leds-ws2812b/src/leds-ws2812b.c b/package/kernel/leds-ws2812b/src/leds-ws2812b.c index b0d13f5242..0dba128c1f 100644 --- a/package/kernel/leds-ws2812b/src/leds-ws2812b.c +++ b/package/kernel/leds-ws2812b/src/leds-ws2812b.c @@ -17,6 +17,7 @@ #include #include #include +#include #define WS2812B_BYTES_PER_COLOR 3 #define WS2812B_NUM_COLORS 3 @@ -191,7 +192,11 @@ ERR_UNREG_LEDS: return ret; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,18,0) +static void ws2812b_remove(struct spi_device *spi) +#else static int ws2812b_remove(struct spi_device *spi) +#endif { struct ws2812b_priv *priv = spi_get_drvdata(spi); int cur_led; @@ -201,7 +206,9 @@ static int ws2812b_remove(struct spi_device *spi) kfree(priv->data_buf); mutex_destroy(&priv->mutex); +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0) return 0; +#endif } static const struct spi_device_id ws2812b_spi_ids[] = { From 0b80c5725fd70bfd23701cd49fa9f252f6835506 Mon Sep 17 00:00:00 2001 From: Martin Schiller Date: Fri, 7 Jul 2023 13:29:45 +0200 Subject: [PATCH 04/15] e2fsprogs: do not symlink tune2fs to findfs commit c0611b45a998 ("e2fsprogs: symlink e2fsck to fsck.ext{2, 3, 4}, and tune2fs to findfs") introduced a symlink from tune2fs to findfs. This only works when the included private libblkid library is used, but commit 5b1660a5387b ("utils/e2fsprogs: Update to 1.43.6") disabled the usage of this private lib and enabled the shared lib support. Removing this symlink makes it possible to install tune2fs and findfs package. Signed-off-by: Martin Schiller --- package/utils/e2fsprogs/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/package/utils/e2fsprogs/Makefile b/package/utils/e2fsprogs/Makefile index 42c2971529..2657077a16 100644 --- a/package/utils/e2fsprogs/Makefile +++ b/package/utils/e2fsprogs/Makefile @@ -267,7 +267,6 @@ endef define Package/tune2fs/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/tune2fs $(1)/usr/sbin/ - $(LN) tune2fs $(1)/usr/sbin/findfs endef define Package/resize2fs/install From c170fc78ba6e4477cc06b2b77e11747da862dcf0 Mon Sep 17 00:00:00 2001 From: Christian Svensson Date: Sat, 8 Jul 2023 00:23:28 +0200 Subject: [PATCH 05/15] kernel: remove CRYPTO_BLAKE2S from all >=5.15 This option was removed from upstream kernel back in 2022. See commits: 2d16803c562ecc644803d42ba98a8e0aef9c014e (>=6.0) 3dd33a09f5dc12ccb0902923c4c784eb0f8c7554 (>=5.15.61 backport) Signed-off-by: Christian Svensson --- target/linux/armsr/armv8/config-6.1 | 1 - target/linux/ath79/config-5.15 | 1 - target/linux/bcm63xx/config-5.15 | 1 - target/linux/generic/config-5.15 | 1 - target/linux/generic/config-6.1 | 1 - target/linux/lantiq/config-5.15 | 1 - target/linux/malta/config-5.15 | 1 - target/linux/malta/config-6.1 | 1 - target/linux/mediatek/mt7622/config-5.15 | 1 - target/linux/octeon/config-5.15 | 1 - target/linux/sunxi/cortexa53/config-5.15 | 1 - target/linux/uml/config-5.15 | 1 - target/linux/x86/generic/config-5.15 | 1 - target/linux/x86/geode/config-5.15 | 1 - target/linux/x86/legacy/config-5.15 | 1 - 15 files changed, 15 deletions(-) diff --git a/target/linux/armsr/armv8/config-6.1 b/target/linux/armsr/armv8/config-6.1 index f6bcce191f..5bdda2d517 100644 --- a/target/linux/armsr/armv8/config-6.1 +++ b/target/linux/armsr/armv8/config-6.1 @@ -114,7 +114,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CHACHA20=y CONFIG_CRYPTO_CHACHA20_NEON=y CONFIG_CRYPTO_CRYPTD=y diff --git a/target/linux/ath79/config-5.15 b/target/linux/ath79/config-5.15 index ce987c5539..21fd091a2e 100644 --- a/target/linux/ath79/config-5.15 +++ b/target/linux/ath79/config-5.15 @@ -34,7 +34,6 @@ CONFIG_CPU_R4K_CACHE_TLB=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_MSA=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 CONFIG_CRYPTO_RNG2=y diff --git a/target/linux/bcm63xx/config-5.15 b/target/linux/bcm63xx/config-5.15 index c946302d31..f19d45362e 100644 --- a/target/linux/bcm63xx/config-5.15 +++ b/target/linux/bcm63xx/config-5.15 @@ -57,7 +57,6 @@ CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_CPUFREQ=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CRASH_CORE=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 CONFIG_CRYPTO_RNG2=y diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index a2770f2d5f..d7e4742d63 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -1087,7 +1087,6 @@ CONFIG_CRYPTO_ALGAPI2=y # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_BLAKE2B is not set # CONFIG_CRYPTO_BLAKE2B_NEON is not set -# CONFIG_CRYPTO_BLAKE2S is not set # CONFIG_CRYPTO_BLAKE2S_ARM is not set # CONFIG_CRYPTO_BLAKE2S_X86 is not set # CONFIG_CRYPTO_BLOWFISH is not set diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 index 6a3ed63f56..8ba82f4222 100644 --- a/target/linux/generic/config-6.1 +++ b/target/linux/generic/config-6.1 @@ -1145,7 +1145,6 @@ CONFIG_CRYPTO_ALGAPI2=y # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_BLAKE2B is not set # CONFIG_CRYPTO_BLAKE2B_NEON is not set -# CONFIG_CRYPTO_BLAKE2S is not set # CONFIG_CRYPTO_BLAKE2S_ARM is not set # CONFIG_CRYPTO_BLAKE2S_X86 is not set # CONFIG_CRYPTO_BLOWFISH is not set diff --git a/target/linux/lantiq/config-5.15 b/target/linux/lantiq/config-5.15 index c37a543e1e..90d48fff04 100644 --- a/target/linux/lantiq/config-5.15 +++ b/target/linux/lantiq/config-5.15 @@ -37,7 +37,6 @@ CONFIG_CPU_R4K_CACHE_TLB=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_MSA=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 CONFIG_CRYPTO_RNG2=y diff --git a/target/linux/malta/config-5.15 b/target/linux/malta/config-5.15 index f1ef5e8dfb..bbedaf5633 100644 --- a/target/linux/malta/config-5.15 +++ b/target/linux/malta/config-5.15 @@ -57,7 +57,6 @@ CONFIG_CPU_RMAP=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CRC16=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y diff --git a/target/linux/malta/config-6.1 b/target/linux/malta/config-6.1 index 8ab648069d..9ce439ee38 100644 --- a/target/linux/malta/config-6.1 +++ b/target/linux/malta/config-6.1 @@ -58,7 +58,6 @@ CONFIG_CPU_RMAP=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CRC16=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y diff --git a/target/linux/mediatek/mt7622/config-5.15 b/target/linux/mediatek/mt7622/config-5.15 index 30a5ff948f..643eaa45b6 100644 --- a/target/linux/mediatek/mt7622/config-5.15 +++ b/target/linux/mediatek/mt7622/config-5.15 @@ -111,7 +111,6 @@ CONFIG_CRYPTO_AES_ARM64=y CONFIG_CRYPTO_AES_ARM64_CE=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y diff --git a/target/linux/octeon/config-5.15 b/target/linux/octeon/config-5.15 index 5882c7dd75..cf64ae34f9 100644 --- a/target/linux/octeon/config-5.15 +++ b/target/linux/octeon/config-5.15 @@ -44,7 +44,6 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_HUGEPAGES=y CONFIG_CRAMFS=y CONFIG_CRC16=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y diff --git a/target/linux/sunxi/cortexa53/config-5.15 b/target/linux/sunxi/cortexa53/config-5.15 index 85ace5d928..93d5b2b21c 100644 --- a/target/linux/sunxi/cortexa53/config-5.15 +++ b/target/linux/sunxi/cortexa53/config-5.15 @@ -28,7 +28,6 @@ CONFIG_CRYPTO_AES_ARM64=y CONFIG_CRYPTO_AES_ARM64_CE=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y CONFIG_CRYPTO_CRYPTD=y CONFIG_CRYPTO_GHASH_ARM64_CE=y diff --git a/target/linux/uml/config-5.15 b/target/linux/uml/config-5.15 index 549a31e1c6..ac13cda703 100644 --- a/target/linux/uml/config-5.15 +++ b/target/linux/uml/config-5.15 @@ -20,7 +20,6 @@ CONFIG_CPU_SUP_HYGON=y CONFIG_CPU_SUP_INTEL=y CONFIG_CPU_SUP_ZHAOXIN=y CONFIG_CRC16=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y diff --git a/target/linux/x86/generic/config-5.15 b/target/linux/x86/generic/config-5.15 index 5fda82dd29..29c1e43b22 100644 --- a/target/linux/x86/generic/config-5.15 +++ b/target/linux/x86/generic/config-5.15 @@ -61,7 +61,6 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # CONFIG_CPU_IDLE_GOV_HALTPOLL is not set CONFIG_CPU_IDLE_GOV_MENU=y CONFIG_CPU_RMAP=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y # CONFIG_CS89x0_ISA is not set # CONFIG_DEBUG_HOTPLUG_CPU0 is not set diff --git a/target/linux/x86/geode/config-5.15 b/target/linux/x86/geode/config-5.15 index 2ede23ea5e..0104b1e7b3 100644 --- a/target/linux/x86/geode/config-5.15 +++ b/target/linux/x86/geode/config-5.15 @@ -37,7 +37,6 @@ CONFIG_ALIX=y # CONFIG_AMD_PMC is not set CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y # CONFIG_ATA_PIIX is not set -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CS5535_CLOCK_EVENT_SRC=y CONFIG_CS5535_MFGPT=y diff --git a/target/linux/x86/legacy/config-5.15 b/target/linux/x86/legacy/config-5.15 index a75ce40ab4..d6802d6c99 100644 --- a/target/linux/x86/legacy/config-5.15 +++ b/target/linux/x86/legacy/config-5.15 @@ -45,7 +45,6 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BLK_DEV_SR=y CONFIG_CDROM=y CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y # CONFIG_CS89x0_ISA is not set CONFIG_DMA_ACPI=y From 3a2e7c30d3e6a187ba1df740cdb24c8ad84dfe48 Mon Sep 17 00:00:00 2001 From: Adam Bailey Date: Mon, 3 Jul 2023 20:16:14 -0500 Subject: [PATCH 06/15] lua: fix integer overflow in LNUM patch Safely detect integer overflow in try_addint() and try_subint(). Old code relied on undefined behavior, and recent versions of GCC on x86 optimized away the if-statements. This caused integer overflow in Lua code instead of falling back to floating-point numbers. Signed-off-by: Adam Bailey --- .../010-lua-5.1.3-lnum-full-260308.patch | 16 ++++++++-------- .../patches/010-lua-5.1.3-lnum-full-260308.patch | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package/utils/lua/patches-host/010-lua-5.1.3-lnum-full-260308.patch b/package/utils/lua/patches-host/010-lua-5.1.3-lnum-full-260308.patch index 4530edd181..fd398c28d1 100644 --- a/package/utils/lua/patches-host/010-lua-5.1.3-lnum-full-260308.patch +++ b/package/utils/lua/patches-host/010-lua-5.1.3-lnum-full-260308.patch @@ -1600,18 +1600,18 @@ + * (and doing them). + */ +int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { -+ lua_Integer v= ib+ic; /* may overflow */ -+ if (ib>0 && ic>0) { if (v < 0) return 0; /*overflow, use floats*/ } -+ else if (ib<0 && ic<0) { if (v >= 0) return 0; } -+ *r= v; ++ /* Signed int overflow is undefined behavior, so catch it without causing it. */ ++ if (ic>0) { if (ib > LUA_INTEGER_MAX - ic) return 0; /*overflow, use floats*/ } ++ else { if (ib < LUA_INTEGER_MIN - ic) return 0; } ++ *r = ib + ic; + return 1; +} + +int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { -+ lua_Integer v= ib-ic; /* may overflow */ -+ if (ib>=0 && ic<0) { if (v < 0) return 0; /*overflow, use floats*/ } -+ else if (ib<0 && ic>0) { if (v >= 0) return 0; } -+ *r= v; ++ /* Signed int overflow is undefined behavior, so catch it without causing it. */ ++ if (ic>0) { if (ib < LUA_INTEGER_MIN + ic) return 0; /*overflow, use floats*/ } ++ else { if (ib > LUA_INTEGER_MAX + ic) return 0; } ++ *r = ib - ic; + return 1; +} + diff --git a/package/utils/lua/patches/010-lua-5.1.3-lnum-full-260308.patch b/package/utils/lua/patches/010-lua-5.1.3-lnum-full-260308.patch index ac0722c707..58cc894e1c 100644 --- a/package/utils/lua/patches/010-lua-5.1.3-lnum-full-260308.patch +++ b/package/utils/lua/patches/010-lua-5.1.3-lnum-full-260308.patch @@ -1589,18 +1589,18 @@ + * (and doing them). + */ +int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { -+ lua_Integer v= ib+ic; /* may overflow */ -+ if (ib>0 && ic>0) { if (v < 0) return 0; /*overflow, use floats*/ } -+ else if (ib<0 && ic<0) { if (v >= 0) return 0; } -+ *r= v; ++ /* Signed int overflow is undefined behavior, so catch it without causing it. */ ++ if (ic>0) { if (ib > LUA_INTEGER_MAX - ic) return 0; /*overflow, use floats*/ } ++ else { if (ib < LUA_INTEGER_MIN - ic) return 0; } ++ *r = ib + ic; + return 1; +} + +int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) { -+ lua_Integer v= ib-ic; /* may overflow */ -+ if (ib>=0 && ic<0) { if (v < 0) return 0; /*overflow, use floats*/ } -+ else if (ib<0 && ic>0) { if (v >= 0) return 0; } -+ *r= v; ++ /* Signed int overflow is undefined behavior, so catch it without causing it. */ ++ if (ic>0) { if (ib < LUA_INTEGER_MIN + ic) return 0; /*overflow, use floats*/ } ++ else { if (ib > LUA_INTEGER_MAX + ic) return 0; } ++ *r = ib - ic; + return 1; +} + From 1f1e0b1144ebaa4ba8b948a12d989a0a6fc9b76f Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 8 Jul 2023 16:27:25 +0100 Subject: [PATCH 07/15] mediatek: dts: mt7988a: wire-up mediatek,pio for PHY LEDs The PHY driver needs to read a register containing the values of the bootstrap pins (which happen to be the PHY LEDs) to determine the LED polarities. Allow regmap access to first pinctrl bank by adding the 'syscon' compatible, and reference the pinctrl in the MDIO bus where the PHY driver will look for it. Signed-off-by: Daniel Golle --- .../arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts | 1 + .../files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 +- .../arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts | 1 + .../files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts index 98dbf8d691..e204dc4f16 100644 --- a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts +++ b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts @@ -156,6 +156,7 @@ mdio { #address-cells = <1>; #size-cells = <0>; + mediatek,pio = <&pio>; gsw_phy0: ethernet-phy@0 { compatible = "ethernet-phy-id03a2.9481"; diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi index 13ad39500d..17de885629 100644 --- a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +++ b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi @@ -215,7 +215,7 @@ }; pio: pinctrl@1001f000 { - compatible = "mediatek,mt7988-pinctrl"; + compatible = "mediatek,mt7988-pinctrl", "syscon"; reg = <0 0x1001f000 0 0x1000>, <0 0x11c10000 0 0x1000>, <0 0x11d00000 0 0x1000>, diff --git a/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts b/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts index 98dbf8d691..e204dc4f16 100644 --- a/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts +++ b/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts @@ -156,6 +156,7 @@ mdio { #address-cells = <1>; #size-cells = <0>; + mediatek,pio = <&pio>; gsw_phy0: ethernet-phy@0 { compatible = "ethernet-phy-id03a2.9481"; diff --git a/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi index 13ad39500d..17de885629 100644 --- a/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +++ b/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi @@ -215,7 +215,7 @@ }; pio: pinctrl@1001f000 { - compatible = "mediatek,mt7988-pinctrl"; + compatible = "mediatek,mt7988-pinctrl", "syscon"; reg = <0 0x1001f000 0 0x1000>, <0 0x11c10000 0 0x1000>, <0 0x11d00000 0 0x1000>, From 094c37708ace9040e294c5aa7be34bc9e7a8dcc1 Mon Sep 17 00:00:00 2001 From: Mathew McBride Date: Tue, 27 Jun 2023 06:37:28 +0000 Subject: [PATCH 08/15] layerscape: base-files: remove redundant RAMFS_COPY_* additions All the tools (e.g fw_setenv, ubiupdatevol) and config (fw_env.config) needed for sysupgrade are already included in /lib/upgrade/stage2 Signed-off-by: Mathew McBride --- target/linux/layerscape/base-files/lib/upgrade/platform.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/linux/layerscape/base-files/lib/upgrade/platform.sh b/target/linux/layerscape/base-files/lib/upgrade/platform.sh index 0b5d14b579..8ad9df4a13 100644 --- a/target/linux/layerscape/base-files/lib/upgrade/platform.sh +++ b/target/linux/layerscape/base-files/lib/upgrade/platform.sh @@ -3,8 +3,8 @@ # Copyright 2020 NXP # -RAMFS_COPY_BIN="/usr/sbin/fw_printenv /usr/sbin/fw_setenv /usr/sbin/ubinfo /bin/echo" -RAMFS_COPY_DATA="/etc/fw_env.config /var/lock/fw_printenv.lock" +RAMFS_COPY_BIN="" +RAMFS_COPY_DATA="" REQUIRE_IMAGE_METADATA=1 From 9fac59009657068d5a58b3d0255d4ca1507dd457 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 8 Jul 2023 17:21:27 +0100 Subject: [PATCH 09/15] mediatek: use backported Ethernet PHY driver also for 5.15 Backport in-SoC Gigabit Ethernet PHY driver instead of carrying the driver in files-5.15. Signed-off-by: Daniel Golle --- .../drivers/net/phy/mediatek-ge-soc.c | 1263 ----------------- ...er-for-MediaTek-SoC-built-in-GE-PHYs.patch | 82 -- ...er-for-MediaTek-SoC-built-in-GE-PHYs.patch | 1204 ++++++++++++++++ ...-ge-soc-initialize-MT7988-PHY-LEDs-d.patch | 213 +++ 4 files changed, 1417 insertions(+), 1345 deletions(-) delete mode 100644 target/linux/mediatek/files-5.15/drivers/net/phy/mediatek-ge-soc.c delete mode 100644 target/linux/mediatek/patches-5.15/730-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch create mode 100644 target/linux/mediatek/patches-5.15/730-v6.5-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch create mode 100644 target/linux/mediatek/patches-5.15/731-net-phy-mediatek-ge-soc-initialize-MT7988-PHY-LEDs-d.patch diff --git a/target/linux/mediatek/files-5.15/drivers/net/phy/mediatek-ge-soc.c b/target/linux/mediatek/files-5.15/drivers/net/phy/mediatek-ge-soc.c deleted file mode 100644 index e48502ac3f..0000000000 --- a/target/linux/mediatek/files-5.15/drivers/net/phy/mediatek-ge-soc.c +++ /dev/null @@ -1,1263 +0,0 @@ -// 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 - -/* Registers on MDIO_MMD_VEND2 */ -#define MTK_PHY_LED0_ON_CTRL 0x24 -#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0) -#define MTK_PHY_LED0_ON_LINK1000 BIT(0) -#define MTK_PHY_LED0_ON_LINK100 BIT(1) -#define MTK_PHY_LED0_ON_LINK10 BIT(2) -#define MTK_PHY_LED0_ON_LINKDOWN BIT(3) -#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */ -#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */ -#define MTK_PHY_LED0_FORCE_ON BIT(6) -#define MTK_PHY_LED0_POLARITY BIT(14) -#define MTK_PHY_LED0_ENABLE BIT(15) - -#define MTK_PHY_LED0_BLINK_CTRL 0x25 -#define MTK_PHY_LED0_1000TX BIT(0) -#define MTK_PHY_LED0_1000RX BIT(1) -#define MTK_PHY_LED0_100TX BIT(2) -#define MTK_PHY_LED0_100RX BIT(3) -#define MTK_PHY_LED0_10TX BIT(4) -#define MTK_PHY_LED0_10RX BIT(5) -#define MTK_PHY_LED0_COLLISION BIT(6) -#define MTK_PHY_LED0_RX_CRC_ERR BIT(7) -#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8) -#define MTK_PHY_LED0_FORCE_BLINK BIT(9) - -#define MTK_PHY_LED1_ON_CTRL 0x26 -#define MTK_PHY_LED1_ON_MASK GENMASK(6, 0) -#define MTK_PHY_LED1_ON_LINK1000 BIT(0) -#define MTK_PHY_LED1_ON_LINK100 BIT(1) -#define MTK_PHY_LED1_ON_LINK10 BIT(2) -#define MTK_PHY_LED1_ON_LINKDOWN BIT(3) -#define MTK_PHY_LED1_ON_FDX BIT(4) /* Full duplex */ -#define MTK_PHY_LED1_ON_HDX BIT(5) /* Half duplex */ -#define MTK_PHY_LED1_FORCE_ON BIT(6) -#define MTK_PHY_LED1_POLARITY BIT(14) -#define MTK_PHY_LED1_ENABLE BIT(15) - -#define MTK_PHY_LED1_BLINK_CTRL 0x27 -#define MTK_PHY_LED1_1000TX BIT(0) -#define MTK_PHY_LED1_1000RX BIT(1) -#define MTK_PHY_LED1_100TX BIT(2) -#define MTK_PHY_LED1_100RX BIT(3) -#define MTK_PHY_LED1_10TX BIT(4) -#define MTK_PHY_LED1_10RX BIT(5) -#define MTK_PHY_LED1_COLLISION BIT(6) -#define MTK_PHY_LED1_RX_CRC_ERR BIT(7) -#define MTK_PHY_LED1_RX_IDLE_ERR BIT(8) -#define MTK_PHY_LED1_FORCE_BLINK BIT(9) - -#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 -}; - -struct mtk_socphy_shared_priv { - u32 boottrap; -}; - -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 int mt7988_phy_setup_led(struct phy_device *phydev) -{ - struct mtk_socphy_shared_priv *priv = phydev->shared->priv; - int port = phydev->mdio.addr; - u32 reg = priv->boottrap; - struct pinctrl *pinctrl; - - phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL, - MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY | - MTK_PHY_LED0_ON_LINK10 | - MTK_PHY_LED0_ON_LINK100 | - MTK_PHY_LED0_ON_LINK1000); - phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL, - MTK_PHY_LED1_ENABLE | MTK_PHY_LED1_POLARITY | - MTK_PHY_LED1_ON_LINK10 | - MTK_PHY_LED1_ON_LINK100 | - MTK_PHY_LED1_ON_LINK1000); - - if ((port == GPHY_PORT0 && reg & BIT(8)) || - (port == GPHY_PORT1 && reg & BIT(9)) || - (port == GPHY_PORT2 && reg & BIT(10)) || - (port == GPHY_PORT3 && reg & BIT(11))) { - phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL, - MTK_PHY_LED0_POLARITY); - phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL, - MTK_PHY_LED1_POLARITY); - } - - phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL, - MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX | - MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX | - MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX); - phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_BLINK_CTRL, - MTK_PHY_LED1_1000TX | MTK_PHY_LED1_1000RX | - MTK_PHY_LED1_100TX | MTK_PHY_LED1_100RX | - MTK_PHY_LED1_10TX | MTK_PHY_LED1_10RX); - - pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); - if (IS_ERR(pinctrl)) { - dev_err(&phydev->mdio.bus->dev, "Failed to setup LED pins\n"); - return PTR_ERR(pinctrl); - } - - return 0; -} - -static int mt7988_phy_probe_shared(struct phy_device *phydev) -{ - struct mtk_socphy_shared_priv *priv = phydev->shared->priv; - void __iomem *boottrap; - struct device_node *np; - u32 reg; - - np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap"); - if (!np) - return -ENOENT; - - boottrap = of_iomap(np, 0); - if (!boottrap) - return -ENOMEM; - - reg = readl(boottrap); - iounmap(boottrap); - - priv->boottrap = reg; - - return 0; -} - -static int mt7981_phy_probe(struct phy_device *phydev) -{ - return mt798x_phy_calibration(phydev); -} - -static int mt7988_phy_probe(struct phy_device *phydev) -{ - int err; - - err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0, - sizeof(struct mtk_socphy_shared_priv)); - if (err) - return err; - - if (phy_package_probe_once(phydev)) { - err = mt7988_phy_probe_shared(phydev); - if (err) - return err; - } - - mt7988_phy_setup_led(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 = mt7981_phy_probe, - .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 = mt7988_phy_probe, - .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); diff --git a/target/linux/mediatek/patches-5.15/730-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch b/target/linux/mediatek/patches-5.15/730-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch deleted file mode 100644 index 43876deb66..0000000000 --- a/target/linux/mediatek/patches-5.15/730-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 60ed9eb9605656c19ca402b7bd3f47552e901601 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 13 Feb 2023 02:33:14 +0000 -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, so add support for these PHYs by introducing a -new driver for only MediaTek's ARM64 SoCs. - -Signed-off-by: Daniel Golle ---- - MAINTAINERS | 9 + - drivers/net/phy/Kconfig | 12 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/mediatek-ge-soc.c | 1263 +++++++++++++++++++++++++++++ - drivers/net/phy/mediatek-ge.c | 3 +- - 5 files changed, 1287 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/phy/mediatek-ge-soc.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -11790,6 +11790,15 @@ S: Maintained - F: drivers/net/pcs/pcs-mtk-lynxi.c - F: include/linux/pcs/pcs-mtk-lynxi.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 -@@ -293,6 +293,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" - help ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -81,6 +81,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 ---- 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-5.15/730-v6.5-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch b/target/linux/mediatek/patches-5.15/730-v6.5-net-phy-add-driver-for-MediaTek-SoC-built-in-GE-PHYs.patch new file mode 100644 index 0000000000..26ebcb6733 --- /dev/null +++ b/target/linux/mediatek/patches-5.15/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 +@@ -11790,6 +11790,15 @@ S: Maintained + F: drivers/net/pcs/pcs-mtk-lynxi.c + F: include/linux/pcs/pcs-mtk-lynxi.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 +@@ -293,6 +293,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" + help +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -81,6 +81,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-5.15/731-net-phy-mediatek-ge-soc-initialize-MT7988-PHY-LEDs-d.patch b/target/linux/mediatek/patches-5.15/731-net-phy-mediatek-ge-soc-initialize-MT7988-PHY-LEDs-d.patch new file mode 100644 index 0000000000..83d0f26bf4 --- /dev/null +++ b/target/linux/mediatek/patches-5.15/731-net-phy-mediatek-ge-soc-initialize-MT7988-PHY-LEDs-d.patch @@ -0,0 +1,213 @@ +From 5d2d78860f98eb5c03bc404eb024606878901ac8 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 13 Jun 2023 03:27:14 +0100 +Subject: [PATCH] net: phy: mediatek-ge-soc: initialize MT7988 PHY LEDs default + state + +Initialize LEDs and set sane default values. +Read boottrap register and apply LED polarities accordingly to get +uniform behavior from all LEDs on MT7988. +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 +--- + drivers/net/phy/mediatek-ge-soc.c | 144 ++++++++++++++++++++++++++++-- + 1 file changed, 136 insertions(+), 8 deletions(-) + +--- a/drivers/net/phy/mediatek-ge-soc.c ++++ b/drivers/net/phy/mediatek-ge-soc.c +@@ -1,11 +1,13 @@ + // SPDX-License-Identifier: GPL-2.0+ + #include ++#include + #include + #include + #include + #include + #include + #include ++#include + + #define MTK_GPHY_ID_MT7981 0x03a29461 + #define MTK_GPHY_ID_MT7988 0x03a29481 +@@ -208,9 +210,40 @@ + #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_FORCE_ON BIT(6) ++#define MTK_PHY_LED_POLARITY BIT(14) ++#define MTK_PHY_LED_ENABLE BIT(15) ++ ++#define MTK_PHY_LED0_BLINK_CTRL 0x25 ++#define MTK_PHY_LED1_BLINK_CTRL 0x27 ++#define MTK_PHY_LED_1000TX BIT(0) ++#define MTK_PHY_LED_1000RX BIT(1) ++#define MTK_PHY_LED_100TX BIT(2) ++#define MTK_PHY_LED_100RX BIT(3) ++#define MTK_PHY_LED_10TX BIT(4) ++#define MTK_PHY_LED_10RX BIT(5) ++#define MTK_PHY_LED_COLLISION BIT(6) ++#define MTK_PHY_LED_RX_CRC_ERR BIT(7) ++#define MTK_PHY_LED_RX_IDLE_ERR BIT(8) ++#define MTK_PHY_LED_FORCE_BLINK BIT(9) ++ + #define MTK_PHY_RG_BG_RASEL 0x115 + #define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0) + ++/* Register in boottrap syscon defining the initial state 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 +271,6 @@ enum { + PAIR_D, + }; + +-enum { +- GPHY_PORT0, +- GPHY_PORT1, +- GPHY_PORT2, +- GPHY_PORT3, +-}; +- + enum calibration_mode { + EFUSE_K, + SW_K +@@ -263,6 +289,10 @@ enum CAL_MODE { + SW_M + }; + ++struct mtk_socphy_shared { ++ u32 boottrap; ++}; ++ + static int mtk_socphy_read_page(struct phy_device *phydev) + { + return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); +@@ -1073,6 +1103,104 @@ static int mt798x_phy_config_init(struct + return mt798x_phy_calibration(phydev); + } + ++static int mt798x_phy_setup_led(struct phy_device *phydev, bool inverted) ++{ ++ struct pinctrl *pinctrl; ++ const u16 led_on_ctrl_defaults = MTK_PHY_LED_ENABLE | ++ MTK_PHY_LED_ON_LINK1000 | ++ MTK_PHY_LED_ON_LINK100 | ++ MTK_PHY_LED_ON_LINK10; ++ const u16 led_blink_defaults = MTK_PHY_LED_1000TX | ++ MTK_PHY_LED_1000RX | ++ MTK_PHY_LED_100TX | ++ MTK_PHY_LED_100RX | ++ MTK_PHY_LED_10TX | ++ MTK_PHY_LED_10RX; ++ ++ phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL, ++ led_on_ctrl_defaults ^ ++ (inverted ? MTK_PHY_LED_POLARITY : 0)); ++ ++ phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL, ++ led_on_ctrl_defaults); ++ ++ phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL, ++ led_blink_defaults); ++ ++ phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_BLINK_CTRL, ++ led_blink_defaults); ++ ++ 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\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 *priv = 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; ++ ++ priv->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg); ++ ++ return 0; ++} ++ ++static bool mt7988_phy_get_boottrap_polarity(struct phy_device *phydev) ++{ ++ struct mtk_socphy_shared *priv = phydev->shared->priv; ++ ++ if (priv->boottrap & BIT(phydev->mdio.addr)) ++ return false; ++ ++ return true; ++} ++ ++static int mt7988_phy_probe(struct phy_device *phydev) ++{ ++ int err; ++ ++ 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; ++ } ++ ++ mt798x_phy_setup_led(phydev, mt7988_phy_get_boottrap_polarity(phydev)); ++ ++ return mt798x_phy_calibration(phydev); ++} ++ + static struct phy_driver mtk_socphy_driver[] = { + { + PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), +@@ -1092,7 +1220,7 @@ 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, From f321a49fd523a8d393be8e3cd2de41d67855da91 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 8 Jul 2023 16:48:39 +0100 Subject: [PATCH 10/15] mediatek: dts: mt7988a: remove boottrap hack The PHY driver now uses regmap created from pio syscon, we no longer need the boottrap device. Signed-off-by: Daniel Golle --- .../files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 5 ----- .../files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi | 5 ----- 2 files changed, 10 deletions(-) diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi index 17de885629..94aa8251bd 100644 --- a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +++ b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7988a.dtsi @@ -303,11 +303,6 @@ }; }; - boottrap: boottrap@1001f6f0 { - compatible = "mediatek,boottrap"; - reg = <0 0x1001f6f0 0 0x4>; - }; - sgmiisys0: syscon@10060000 { compatible = "mediatek,mt7988-sgmiisys", "mediatek,mt7988-sgmiisys_0", diff --git a/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi index 17de885629..94aa8251bd 100644 --- a/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi +++ b/target/linux/mediatek/files-6.1/arch/arm64/boot/dts/mediatek/mt7988a.dtsi @@ -303,11 +303,6 @@ }; }; - boottrap: boottrap@1001f6f0 { - compatible = "mediatek,boottrap"; - reg = <0 0x1001f6f0 0 0x4>; - }; - sgmiisys0: syscon@10060000 { compatible = "mediatek,mt7988-sgmiisys", "mediatek,mt7988-sgmiisys_0", From 712fa3eff82086da8a13e7e5bc577df17892a581 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 8 Jul 2023 17:31:24 +0100 Subject: [PATCH 11/15] mediatek: replace hack for MaxLinear 2.5G PHY Replace hack with proper patch also for Linux 5.15. Signed-off-by: Daniel Golle --- ...et-phy-hack-mxl-gpy-disable-sgmii-an.patch | 166 ------------------ ...-don-t-use-SGMII-AN-if-using-phylink.patch | 63 +++++++ ...hy-add-driver-for-MediaTek-2.5G-PHY.patch} | 0 3 files changed, 63 insertions(+), 166 deletions(-) delete mode 100644 target/linux/mediatek/patches-5.15/731-net-phy-hack-mxl-gpy-disable-sgmii-an.patch create mode 100644 target/linux/mediatek/patches-5.15/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch rename target/linux/mediatek/patches-5.15/{732-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch => 733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch} (100%) diff --git a/target/linux/mediatek/patches-5.15/731-net-phy-hack-mxl-gpy-disable-sgmii-an.patch b/target/linux/mediatek/patches-5.15/731-net-phy-hack-mxl-gpy-disable-sgmii-an.patch deleted file mode 100644 index 2e39ca3c26..0000000000 --- a/target/linux/mediatek/patches-5.15/731-net-phy-hack-mxl-gpy-disable-sgmii-an.patch +++ /dev/null @@ -1,166 +0,0 @@ ---- a/drivers/net/phy/mxl-gpy.c -+++ b/drivers/net/phy/mxl-gpy.c -@@ -126,6 +126,12 @@ static int gpy_config_init(struct phy_de - if (ret < 0) - return ret; - -+ /* Disable SGMII auto-negotiation */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, -+ VSPEC1_SGMII_CTRL_ANEN, 0); -+ if (ret < 0) -+ return ret; -+ - return gpy_led_write(phydev); - } - -@@ -151,65 +157,6 @@ static int gpy_probe(struct phy_device * - return 0; - } - --static bool gpy_sgmii_need_reaneg(struct phy_device *phydev) --{ -- int fw_ver, fw_type, fw_minor; -- size_t i; -- -- fw_ver = phy_read(phydev, PHY_FWV); -- if (fw_ver < 0) -- return true; -- -- fw_type = FIELD_GET(PHY_FWV_TYPE_MASK, fw_ver); -- fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_ver); -- -- for (i = 0; i < ARRAY_SIZE(ver_need_sgmii_reaneg); i++) { -- if (fw_type != ver_need_sgmii_reaneg[i].type) -- continue; -- if (fw_minor < ver_need_sgmii_reaneg[i].minor) -- return true; -- break; -- } -- -- return false; --} -- --static bool gpy_2500basex_chk(struct phy_device *phydev) --{ -- int ret; -- -- ret = phy_read(phydev, PHY_MIISTAT); -- if (ret < 0) { -- phydev_err(phydev, "Error: MDIO register access failed: %d\n", -- ret); -- return false; -- } -- -- if (!(ret & PHY_MIISTAT_LS) || -- FIELD_GET(PHY_MIISTAT_SPD_MASK, ret) != PHY_MIISTAT_SPD_2500) -- return false; -- -- 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); -- return true; --} -- --static bool gpy_sgmii_aneg_en(struct phy_device *phydev) --{ -- int ret; -- -- ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL); -- if (ret < 0) { -- phydev_err(phydev, "Error: MMD register access failed: %d\n", -- ret); -- return true; -- } -- -- return (ret & VSPEC1_SGMII_CTRL_ANEN) ? true : false; --} -- - static int gpy_config_aneg(struct phy_device *phydev) - { - bool changed = false; -@@ -248,53 +195,11 @@ static int gpy_config_aneg(struct phy_de - phydev->interface == PHY_INTERFACE_MODE_INTERNAL) - return 0; - -- /* No need to trigger re-ANEG if link speed is 2.5G or SGMII ANEG is -- * disabled. -- */ -- if (!gpy_sgmii_need_reaneg(phydev) || gpy_2500basex_chk(phydev) || -- !gpy_sgmii_aneg_en(phydev)) -- return 0; -- -- /* There is a design constraint in GPY2xx device where SGMII AN is -- * only triggered when there is change of speed. If, PHY link -- * partner`s speed is still same even after PHY TPI is down and up -- * again, SGMII AN is not triggered and hence no new in-band message -- * from GPY to MAC side SGMII. -- * This could cause an issue during power up, when PHY is up prior to -- * MAC. At this condition, once MAC side SGMII is up, MAC side SGMII -- * wouldn`t receive new in-band message from GPY with correct link -- * status, speed and duplex info. -- * -- * 1) If PHY is already up and TPI link status is still down (such as -- * hard reboot), TPI link status is polled for 4 seconds before -- * retriggerring SGMII AN. -- * 2) If PHY is already up and TPI link status is also up (such as soft -- * reboot), polling of TPI link status is not needed and SGMII AN is -- * immediately retriggered. -- * 3) Other conditions such as PHY is down, speed change etc, skip -- * retriggering SGMII AN. Note: in case of speed change, GPY FW will -- * initiate SGMII AN. -- */ -- -- if (phydev->state != PHY_UP) -- return 0; -- -- ret = phy_read_poll_timeout(phydev, MII_BMSR, ret, ret & BMSR_LSTATUS, -- 20000, 4000000, false); -- if (ret == -ETIMEDOUT) -- return 0; -- else if (ret < 0) -- return ret; -- -- /* Trigger SGMII AN. */ -- return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, -- VSPEC1_SGMII_CTRL_ANRS, VSPEC1_SGMII_CTRL_ANRS); -+ return 0; - } - - static void gpy_update_interface(struct phy_device *phydev) - { -- int ret; -- - /* Interface mode is fixed for USXGMII and integrated PHY */ - if (phydev->interface == PHY_INTERFACE_MODE_USXGMII || - phydev->interface == PHY_INTERFACE_MODE_INTERNAL) -@@ -306,29 +211,11 @@ static void gpy_update_interface(struct - switch (phydev->speed) { - case SPEED_2500: - phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, -- VSPEC1_SGMII_CTRL_ANEN, 0); -- if (ret < 0) -- phydev_err(phydev, -- "Error: Disable of SGMII ANEG failed: %d\n", -- ret); - break; - case SPEED_1000: - case SPEED_100: - case SPEED_10: - phydev->interface = PHY_INTERFACE_MODE_SGMII; -- if (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). -- */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, -- VSPEC1_SGMII_ANEN_ANRS, -- VSPEC1_SGMII_ANEN_ANRS); -- if (ret < 0) -- phydev_err(phydev, -- "Error: Enable of SGMII ANEG failed: %d\n", -- ret); - break; - } - } diff --git a/target/linux/mediatek/patches-5.15/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch b/target/linux/mediatek/patches-5.15/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch new file mode 100644 index 0000000000..598d9d0d21 --- /dev/null +++ b/target/linux/mediatek/patches-5.15/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 +@@ -191,8 +191,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; + } + +@@ -216,6 +219,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. +@@ -306,6 +317,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) +@@ -317,7 +330,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-5.15/732-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch b/target/linux/mediatek/patches-5.15/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch similarity index 100% rename from target/linux/mediatek/patches-5.15/732-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch rename to target/linux/mediatek/patches-5.15/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch From 2b133ab19cd5d741f3191f917c607667943f5f58 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Fri, 9 Jun 2023 14:12:47 +0200 Subject: [PATCH 12/15] scripts: use sep-char for hash nodes U-Boot with enabled secure-boot will not boot images with the @-character used for hash node-names. Use the existing separation character configurable for each device. Signed-off-by: David Bauer --- scripts/mkits.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/mkits.sh b/scripts/mkits.sh index b1c6f98867..eeb01216f9 100755 --- a/scripts/mkits.sh +++ b/scripts/mkits.sh @@ -108,10 +108,10 @@ if [ -n "${DTB}" ]; then ${DTADDR:+load = <${DTADDR}>;} arch = \"${ARCH}\"; compression = \"none\"; - hash@1 { + hash${REFERENCE_CHAR}1 { algo = \"crc32\"; }; - hash@2 { + hash${REFERENCE_CHAR}2 { algo = \"${HASH}\"; }; }; @@ -128,10 +128,10 @@ if [ -n "${INITRD}" ]; then type = \"ramdisk\"; arch = \"${ARCH}\"; os = \"linux\"; - hash@1 { + hash${REFERENCE_CHAR}1 { algo = \"crc32\"; }; - hash@2 { + hash${REFERENCE_CHAR}2 { algo = \"${HASH}\"; }; }; @@ -150,10 +150,10 @@ if [ -n "${ROOTFS}" ]; then type = \"filesystem\"; arch = \"${ARCH}\"; compression = \"none\"; - hash@1 { + hash${REFERENCE_CHAR}1 { algo = \"crc32\"; }; - hash@2 { + hash${REFERENCE_CHAR}2 { algo = \"${HASH}\"; }; }; @@ -181,10 +181,10 @@ OVCONFIGS="" arch = \"${ARCH}\"; load = <${DTADDR}>; compression = \"none\"; - hash@1 { + hash${REFERENCE_CHAR}1 { algo = \"crc32\"; }; - hash@2 { + hash${REFERENCE_CHAR}2 { algo = \"${HASH}\"; }; }; @@ -216,10 +216,10 @@ DATA="/dts-v1/; compression = \"${COMPRESS}\"; load = <${LOAD_ADDR}>; entry = <${ENTRY_ADDR}>; - hash@1 { + hash${REFERENCE_CHAR}1 { algo = \"crc32\"; }; - hash@2 { + hash${REFERENCE_CHAR}2 { algo = \"$HASH\"; }; }; From 95330a5d605715179cc7e4047cbeaf66b097fc87 Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Sat, 1 Jul 2023 17:37:17 +0000 Subject: [PATCH 13/15] build: add ALT5 vendor/model/variant This allows adding another device variant. Signed-off-by: Wenli Looi --- include/image.mk | 21 ++++++++++++++++++++- scripts/json_add_image_info.py | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/image.mk b/include/image.mk index fae4d32a8b..8f0cbead10 100644 --- a/include/image.mk +++ b/include/image.mk @@ -346,6 +346,7 @@ define Device/InitProfile DEVICE_ALT2_TITLE = $$(DEVICE_ALT2_VENDOR) $$(DEVICE_ALT2_MODEL)$$(if $$(DEVICE_ALT2_VARIANT), $$(DEVICE_ALT2_VARIANT)) DEVICE_ALT3_TITLE = $$(DEVICE_ALT3_VENDOR) $$(DEVICE_ALT3_MODEL)$$(if $$(DEVICE_ALT3_VARIANT), $$(DEVICE_ALT3_VARIANT)) DEVICE_ALT4_TITLE = $$(DEVICE_ALT4_VENDOR) $$(DEVICE_ALT4_MODEL)$$(if $$(DEVICE_ALT4_VARIANT), $$(DEVICE_ALT4_VARIANT)) + DEVICE_ALT5_TITLE = $$(DEVICE_ALT5_VENDOR) $$(DEVICE_ALT5_MODEL)$$(if $$(DEVICE_ALT5_VARIANT), $$(DEVICE_ALT5_VARIANT)) DEVICE_VENDOR := DEVICE_MODEL := DEVICE_VARIANT := @@ -364,6 +365,9 @@ define Device/InitProfile DEVICE_ALT4_VENDOR := DEVICE_ALT4_MODEL := DEVICE_ALT4_VARIANT := + DEVICE_ALT5_VENDOR := + DEVICE_ALT5_MODEL := + DEVICE_ALT5_VARIANT := DEVICE_PACKAGES := DEVICE_DESCRIPTION = Build firmware images for $$(DEVICE_TITLE) endef @@ -448,7 +452,8 @@ DEFAULT_DEVICE_VARS := \ DEVICE_ALT1_VENDOR DEVICE_ALT1_MODEL DEVICE_ALT1_VARIANT \ DEVICE_ALT2_VENDOR DEVICE_ALT2_MODEL DEVICE_ALT2_VARIANT \ DEVICE_ALT3_VENDOR DEVICE_ALT3_MODEL DEVICE_ALT3_VARIANT \ - DEVICE_ALT4_VENDOR DEVICE_ALT4_MODEL DEVICE_ALT4_VARIANT + DEVICE_ALT4_VENDOR DEVICE_ALT4_MODEL DEVICE_ALT4_VARIANT \ + DEVICE_ALT5_VENDOR DEVICE_ALT5_MODEL DEVICE_ALT5_VARIANT define Device/ExportVar $(1) : $(2):=$$($(2)) @@ -537,6 +542,9 @@ define Device/Build/initramfs DEVICE_ALT4_VENDOR="$$(DEVICE_ALT4_VENDOR)" \ DEVICE_ALT4_MODEL="$$(DEVICE_ALT4_MODEL)" \ DEVICE_ALT4_VARIANT="$$(DEVICE_ALT4_VARIANT)" \ + DEVICE_ALT5_VENDOR="$$(DEVICE_ALT5_VENDOR)" \ + DEVICE_ALT5_MODEL="$$(DEVICE_ALT5_MODEL)" \ + DEVICE_ALT5_VARIANT="$$(DEVICE_ALT5_VARIANT)" \ DEVICE_TITLE="$$(DEVICE_TITLE)" \ DEVICE_PACKAGES="$$(DEVICE_PACKAGES)" \ TARGET="$(BOARD)" \ @@ -668,6 +676,9 @@ define Device/Build/image DEVICE_ALT4_VENDOR="$(DEVICE_ALT4_VENDOR)" \ DEVICE_ALT4_MODEL="$(DEVICE_ALT4_MODEL)" \ DEVICE_ALT4_VARIANT="$(DEVICE_ALT4_VARIANT)" \ + DEVICE_ALT5_VENDOR="$(DEVICE_ALT5_VENDOR)" \ + DEVICE_ALT5_MODEL="$(DEVICE_ALT5_MODEL)" \ + DEVICE_ALT5_VARIANT="$(DEVICE_ALT5_VARIANT)" \ DEVICE_TITLE="$(DEVICE_TITLE)" \ DEVICE_PACKAGES="$(DEVICE_PACKAGES)" \ TARGET="$(BOARD)" \ @@ -719,6 +730,9 @@ define Device/Build/artifact DEVICE_ALT4_VENDOR="$(DEVICE_ALT4_VENDOR)" \ DEVICE_ALT4_MODEL="$(DEVICE_ALT4_MODEL)" \ DEVICE_ALT4_VARIANT="$(DEVICE_ALT4_VARIANT)" \ + DEVICE_ALT5_VENDOR="$(DEVICE_ALT5_VENDOR)" \ + DEVICE_ALT5_MODEL="$(DEVICE_ALT5_MODEL)" \ + DEVICE_ALT5_VARIANT="$(DEVICE_ALT5_VARIANT)" \ DEVICE_TITLE="$(DEVICE_TITLE)" \ DEVICE_PACKAGES="$(DEVICE_PACKAGES)" \ TARGET="$(BOARD)" \ @@ -762,6 +776,7 @@ $(if $(strip $(DEVICE_ALT1_TITLE)),- $(DEVICE_ALT1_TITLE)) $(if $(strip $(DEVICE_ALT2_TITLE)),- $(DEVICE_ALT2_TITLE)) $(if $(strip $(DEVICE_ALT3_TITLE)),- $(DEVICE_ALT3_TITLE)) $(if $(strip $(DEVICE_ALT4_TITLE)),- $(DEVICE_ALT4_TITLE)) +$(if $(strip $(DEVICE_ALT5_TITLE)),- $(DEVICE_ALT5_TITLE)) @@ endef @@ -787,6 +802,10 @@ ifneq ($$(strip $$(DEVICE_ALT4_TITLE)),) DEVICE_DISPLAY = $$(DEVICE_ALT4_TITLE) ($$(DEVICE_TITLE)) $$(info $$(call Device/DumpInfo,$(1))) endif +ifneq ($$(strip $$(DEVICE_ALT5_TITLE)),) +DEVICE_DISPLAY = $$(DEVICE_ALT5_TITLE) ($$(DEVICE_TITLE)) +$$(info $$(call Device/DumpInfo,$(1))) +endif DEVICE_DISPLAY = $$(DEVICE_TITLE) $$(eval $$(if $$(DEVICE_TITLE),$$(info $$(call Device/DumpInfo,$(1))))) endef diff --git a/scripts/json_add_image_info.py b/scripts/json_add_image_info.py index 0c441b9334..3aeb7ba5fc 100755 --- a/scripts/json_add_image_info.py +++ b/scripts/json_add_image_info.py @@ -21,7 +21,7 @@ if not file_path.is_file(): def get_titles(): titles = [] - for prefix in ["", "ALT0_", "ALT1_", "ALT2_", "ALT3_", "ALT4_"]: + for prefix in ["", "ALT0_", "ALT1_", "ALT2_", "ALT3_", "ALT4_", "ALT5_"]: title = {} for var in ["vendor", "model", "variant"]: if getenv("DEVICE_{}{}".format(prefix, var.upper())): From 520c9917f8883766d47707cd560ffdaecc9b9dee Mon Sep 17 00:00:00 2001 From: Wenli Looi Date: Sat, 1 Jul 2023 17:46:15 +0000 Subject: [PATCH 14/15] ath79: add support for ASUS RT-AC59U / ZenWiFi CD6 ASUS RT-AC59U / RT-AC59U v2 are wi-fi routers with a large number of alternate names, including RT-AC1200GE, RT-AC1300G PLUS, RT-AC1500UHP, RT-AC57U v2/v3, RT-AC58U v2/v3, and RT-ACRH12. ASUS ZenWiFi AC Mini(CD6) is a mesh wifi system. The unit labeled CD6R is the router, and CD6N is the node. Hardware: - SoC: QCN5502 - RAM: 128 MiB - UART: 115200 baud (labeled on boards) - Wireless: - 2.4GHz: QCN5502 on-chip 4x4 802.11b/g/n currently unsupported due to missing support for QCN550x in ath9k - 5GHz: QCA9888 pcie 5GHz 2x2 802.11a/n/ac - Flash: SPI NOR - RT-AC59U / CD6N: 16 MiB - RT-AC59U v2 / CD6R: 32 MiB - Ethernet: gigabit - RT-AC59U / RT-AC59U v2: 4x LAN 1x WAN - CD6R: 3x LAN 1x WAN - CD6N: 2x LAN - USB: - RT-AC59U / RT-AC59U v2: 1 port USB 2.0 - CD6R / CD6N: none WiFi calibration data contains valid MAC addresses. The initramfs image is uncompressed because I was unable to boot a compressed initramfs from memory (gzip or lzma). Booting a compressed image from flash works fine. Installation: To install without opening the case: - Set your computer IP address to 192.168.1.10/24 - Power up with the Reset button pressed - Release the Reset button after about 5 seconds or until you see the power LED blinking slowly - Upload OpenWRT factory image via TFTP client to 192.168.1.1 Revert to stock firmware using the same TFTP method. Signed-off-by: Wenli Looi --- package/boot/uboot-envtools/files/ath79 | 4 + target/linux/ath79/dts/qcn5502_asus.dtsi | 114 ++++++++++++++++++ .../ath79/dts/qcn5502_asus_rt-ac59u-v2.dts | 19 +++ .../linux/ath79/dts/qcn5502_asus_rt-ac59u.dts | 19 +++ .../ath79/dts/qcn5502_asus_rt-ac59u.dtsi | 69 +++++++++++ .../ath79/dts/qcn5502_asus_zenwifi-cd6.dtsi | 57 +++++++++ .../ath79/dts/qcn5502_asus_zenwifi-cd6n.dts | 19 +++ .../ath79/dts/qcn5502_asus_zenwifi-cd6r.dts | 19 +++ .../generic/base-files/etc/board.d/02_network | 10 ++ target/linux/ath79/image/generic.mk | 64 ++++++++++ 10 files changed, 394 insertions(+) create mode 100644 target/linux/ath79/dts/qcn5502_asus.dtsi create mode 100644 target/linux/ath79/dts/qcn5502_asus_rt-ac59u-v2.dts create mode 100644 target/linux/ath79/dts/qcn5502_asus_rt-ac59u.dts create mode 100644 target/linux/ath79/dts/qcn5502_asus_rt-ac59u.dtsi create mode 100644 target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6.dtsi create mode 100644 target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6n.dts create mode 100644 target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6r.dts diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index e83703b035..aeeb9385d3 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -25,6 +25,10 @@ araknis,an-300-ap-i-n|\ araknis,an-500-ap-i-ac|\ araknis,an-700-ap-i-ac|\ arduino,yun|\ +asus,rt-ac59u|\ +asus,rt-ac59u-v2|\ +asus,zenwifi-cd6n|\ +asus,zenwifi-cd6r|\ buffalo,bhr-4grv2|\ devolo,magic-2-wifi|\ dlink,dir-859-a1|\ diff --git a/target/linux/ath79/dts/qcn5502_asus.dtsi b/target/linux/ath79/dts/qcn5502_asus.dtsi new file mode 100644 index 0000000000..a2b4a76e92 --- /dev/null +++ b/target/linux/ath79/dts/qcn5502_asus.dtsi @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca956x.dtsi" + +#include +#include + +/ { + aliases { + label-mac-device = ð0; + }; +}; + +ð0 { + status = "okay"; + + pll-data = <0x03000101 0x00000101 0x00001919>; + + phy-mode = "sgmii"; + phy-handle = <&phy0>; + + nvmem-cells = <&macaddr_factory_1002>; + nvmem-cell-names = "mac-address"; +}; + +&mdio0 { + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + phy-mode = "sgmii"; + qca,mib-poll-interval = <500>; + + qca,ar8327-initvals = < + 0x04 0x80080080 /* PORT0 PAD MODE CTRL */ + 0x08 0x00000000 /* PORT5 PAD MODE CTRL */ + 0x0c 0x00000000 /* PORT6 PAD MODE CTRL */ + 0x10 0x00000080 /* POWER_ON_STRAP */ + 0x7c 0x0000007e /* PORT0_STATUS */ + 0x94 0x00000200 /* PORT6_STATUS */ + >; + }; +}; + +&pcie { + status = "okay"; + + wifi@0,0 { + compatible = "qcom,ath10k"; + reg = <0 0 0 0 0>; + + nvmem-cells = <&precal_factory_5000>; + nvmem-cell-names = "pre-calibration"; + }; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + m25p,fast-read; + + mtdparts: partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "Bootloader"; + reg = <0x000000 0x040000>; + read-only; + }; + + partition@40000 { + label = "nvram"; + reg = <0x040000 0x010000>; + read-only; + }; + + partition@50000 { + label = "Factory"; + reg = <0x050000 0x010000>; + read-only; + + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + cal_factory_1000: cal@1000 { + reg = <0x1000 0x440>; + }; + + macaddr_factory_1002: macaddr@1002 { + reg = <0x1002 0x6>; + }; + + precal_factory_5000: precal@5000 { + reg = <0x5000 0x2f20>; + }; + }; + }; + }; +}; + +&wmac { + /* Does not work due to lack of QCN5502 support in ath9k. */ + status = "disabled"; + + nvmem-cells = <&cal_factory_1000>; + nvmem-cell-names = "calibration"; +}; diff --git a/target/linux/ath79/dts/qcn5502_asus_rt-ac59u-v2.dts b/target/linux/ath79/dts/qcn5502_asus_rt-ac59u-v2.dts new file mode 100644 index 0000000000..795bb299e9 --- /dev/null +++ b/target/linux/ath79/dts/qcn5502_asus_rt-ac59u-v2.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcn5502_asus_rt-ac59u.dtsi" + +#include +#include + +/ { + compatible = "asus,rt-ac59u-v2", "qca,qcn5500", "qca,qca9560"; + model = "ASUS RT-AC59U v2"; +}; + +&mtdparts { + partition@60000 { + label = "firmware"; + reg = <0x060000 0x1fa0000>; + compatible = "denx,uimage"; + }; +}; diff --git a/target/linux/ath79/dts/qcn5502_asus_rt-ac59u.dts b/target/linux/ath79/dts/qcn5502_asus_rt-ac59u.dts new file mode 100644 index 0000000000..a4ebeb3912 --- /dev/null +++ b/target/linux/ath79/dts/qcn5502_asus_rt-ac59u.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcn5502_asus_rt-ac59u.dtsi" + +#include +#include + +/ { + compatible = "asus,rt-ac59u", "qca,qcn5500", "qca,qca9560"; + model = "ASUS RT-AC59U"; +}; + +&mtdparts { + partition@60000 { + label = "firmware"; + reg = <0x060000 0xfa0000>; + compatible = "denx,uimage"; + }; +}; diff --git a/target/linux/ath79/dts/qcn5502_asus_rt-ac59u.dtsi b/target/linux/ath79/dts/qcn5502_asus_rt-ac59u.dtsi new file mode 100644 index 0000000000..ffc2b89345 --- /dev/null +++ b/target/linux/ath79/dts/qcn5502_asus_rt-ac59u.dtsi @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcn5502_asus.dtsi" + +#include +#include + +/ { + aliases { + led-boot = &led_power; + led-failsafe = &led_power; + led-running = &led_power; + led-upgrade = &led_power; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&gpio 1 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_power: power { + label = "blue:power"; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + }; + + usb { + label = "blue:usb"; + gpios = <&gpio 4 GPIO_ACTIVE_LOW>; + trigger-sources = <&hub_port0>; + linux,default-trigger = "usbport"; + }; + + wlan2g { + label = "blue:wlan2g"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy1tpt"; + }; + + wlan5g { + label = "blue:wlan5g"; + gpios = <&gpio 5 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + }; +}; + +&usb_phy0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; diff --git a/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6.dtsi b/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6.dtsi new file mode 100644 index 0000000000..1d8fe7637a --- /dev/null +++ b/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6.dtsi @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcn5502_asus.dtsi" + +#include +#include + +/ { + aliases { + led-boot = &led_blue; + led-failsafe = &led_red; + led-running = &led_blue; + led-upgrade = &led_red; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 1 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_blue: blue { + label = "blue"; + gpios = <&gpio 5 GPIO_ACTIVE_LOW>; + }; + + green { + label = "green"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + + led_red: red { + label = "red"; + gpios = <&gpio 4 GPIO_ACTIVE_LOW>; + }; + + white { + label = "white"; + gpios = <&gpio 16 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6n.dts b/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6n.dts new file mode 100644 index 0000000000..426f203357 --- /dev/null +++ b/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6n.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcn5502_asus_zenwifi-cd6.dtsi" + +#include +#include + +/ { + compatible = "asus,zenwifi-cd6n", "qca,qcn5500", "qca,qca9560"; + model = "ASUS ZenWiFi CD6N"; +}; + +&mtdparts { + partition@60000 { + label = "firmware"; + reg = <0x060000 0xfa0000>; + compatible = "denx,uimage"; + }; +}; diff --git a/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6r.dts b/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6r.dts new file mode 100644 index 0000000000..b9c2ba0288 --- /dev/null +++ b/target/linux/ath79/dts/qcn5502_asus_zenwifi-cd6r.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qcn5502_asus_zenwifi-cd6.dtsi" + +#include +#include + +/ { + compatible = "asus,zenwifi-cd6r", "qca,qcn5500", "qca,qca9560"; + model = "ASUS ZenWiFi CD6R"; +}; + +&mtdparts { + partition@60000 { + label = "firmware"; + reg = <0x060000 0x1fa0000>; + compatible = "denx,uimage"; + }; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 1b12a21d0d..ddcb69f68c 100644 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -152,6 +152,14 @@ ath79_setup_interfaces() ucidef_add_switch "switch0" \ "0@eth0" "1:lan:1" "2:lan:2" "3:lan:3" "6:lan:4" ;; + asus,zenwifi-cd6n) + ucidef_add_switch "switch0" \ + "0@eth0" "1:lan:1" "4:lan:2" + ;; + asus,zenwifi-cd6r) + ucidef_add_switch "switch0" \ + "0@eth0" "1:lan:2" "3:lan:1" "4:lan:3" "2:wan" + ;; atheros,db120) ucidef_add_switch "switch0" \ "0@eth0" "2:lan" "3:lan" "4:lan" "5:lan" "1:wan" @@ -381,6 +389,8 @@ ath79_setup_interfaces() ucidef_add_switch "switch0" \ "0@eth1" "1:lan" ;; + asus,rt-ac59u|\ + asus,rt-ac59u-v2|\ mercury,mw4530r-v1|\ tplink,archer-a7-v5|\ tplink,archer-a9-v6|\ diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index b32a09f34b..59cc3c5a2b 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -483,6 +483,70 @@ define Device/asus_rp-ac66 endef TARGET_DEVICES += asus_rp-ac66 +define Device/asus_qcn5502 + SOC := qcn5502 + DEVICE_VENDOR := ASUS + DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca9888-ct + KERNEL_INITRAMFS := kernel-bin | append-dtb | uImage none + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ + append-rootfs | pad-rootfs +endef + +define Device/asus_rt-ac59u + $(Device/asus_qcn5502) + DEVICE_MODEL := RT-AC59U + DEVICE_ALT0_VENDOR := ASUS + DEVICE_ALT0_MODEL := RT-AC1200GE + DEVICE_ALT1_VENDOR := ASUS + DEVICE_ALT1_MODEL := RT-AC1500G PLUS + DEVICE_ALT2_VENDOR := ASUS + DEVICE_ALT2_MODEL := RT-AC1500UHP + DEVICE_ALT3_VENDOR := ASUS + DEVICE_ALT3_MODEL := RT-AC57U + DEVICE_ALT3_VARIANT := v2 + DEVICE_ALT4_VENDOR := ASUS + DEVICE_ALT4_MODEL := RT-AC58U + DEVICE_ALT4_VARIANT := v2 + DEVICE_ALT5_VENDOR := ASUS + DEVICE_ALT5_MODEL := RT-ACRH12 + IMAGE_SIZE := 16000k + DEVICE_PACKAGES += kmod-usb2 kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += asus_rt-ac59u + +define Device/asus_rt-ac59u-v2 + $(Device/asus_qcn5502) + DEVICE_MODEL := RT-AC59U + DEVICE_VARIANT := v2 + DEVICE_ALT0_VENDOR := ASUS + DEVICE_ALT0_MODEL := RT-AC1300G PLUS + DEVICE_ALT0_VARIANT := v3 + DEVICE_ALT1_VENDOR := ASUS + DEVICE_ALT1_MODEL := RT-AC57U + DEVICE_ALT1_VARIANT := v3 + DEVICE_ALT2_VENDOR := ASUS + DEVICE_ALT2_MODEL := RT-AC58U + DEVICE_ALT2_VARIANT := v3 + IMAGE_SIZE := 32384k + DEVICE_PACKAGES += kmod-usb2 kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += asus_rt-ac59u-v2 + +define Device/asus_zenwifi-cd6n + $(Device/asus_qcn5502) + DEVICE_MODEL := ZenWiFi CD6N + IMAGE_SIZE := 16000k +endef +TARGET_DEVICES += asus_zenwifi-cd6n + +define Device/asus_zenwifi-cd6r + $(Device/asus_qcn5502) + DEVICE_MODEL := ZenWiFi CD6R + IMAGE_SIZE := 32384k +endef +TARGET_DEVICES += asus_zenwifi-cd6r + define Device/atheros_db120 $(Device/loader-okli-uimage) SOC := ar9344 From 98e3f82c3fb729c1d9de78fef215322528b50cb4 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 12 Jun 2023 04:06:40 +0100 Subject: [PATCH 15/15] uboot-mediatek: support classic uImage.FIT with internal images in imszb The side-effect and main motivation is to also drop the FIT structure size limit because with multiple device tree overlays it may easily grow beyond the previous 4kB limit in the future. Signed-off-by: Daniel Golle --- .../patches/200-cmd-add-imsz-and-imszb.patch | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package/boot/uboot-mediatek/patches/200-cmd-add-imsz-and-imszb.patch b/package/boot/uboot-mediatek/patches/200-cmd-add-imsz-and-imszb.patch index 7cf0778e47..fcbb6b28a0 100644 --- a/package/boot/uboot-mediatek/patches/200-cmd-add-imsz-and-imszb.patch +++ b/package/boot/uboot-mediatek/patches/200-cmd-add-imsz-and-imszb.patch @@ -70,7 +70,7 @@ { --- a/boot/image-fit.c +++ b/boot/image-fit.c -@@ -2051,6 +2051,50 @@ static const char *fit_get_image_type_pr +@@ -2051,6 +2051,49 @@ static const char *fit_get_image_type_pr return "unknown"; } @@ -89,9 +89,8 @@ + + hdrsize = fdt_totalsize(fit); + -+ /* simple FIT with internal images */ -+ if (hdrsize > 0x1000) -+ return hdrsize; ++ /* take care of simple FIT with internal images */ ++ max_size = hdrsize; + + images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); + if (images_noffset < 0) {