From: Daniel Golle Date: Sat, 17 May 2025 13:05:17 +0000 (+0100) Subject: kernel/mediatek: 6.12: drop patches which are now part of generic X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72994b5e5a72afe06f7416cf600a248f5da09f7e;p=thirdparty%2Fopenwrt.git kernel/mediatek: 6.12: drop patches which are now part of generic Drop patches which have been moved into target/linux/generic by commit f4144d61d2 ("generic: 6.12: backport MediaTek Ethernet PHY changes"). Signed-off-by: Daniel Golle --- diff --git a/target/linux/mediatek/patches-6.12/700-net-phy-mediatek-Add-2.5Gphy-firmware-dt-bindings-an.patch b/target/linux/mediatek/patches-6.12/700-net-phy-mediatek-Add-2.5Gphy-firmware-dt-bindings-an.patch new file mode 100644 index 00000000000..8c0ded2b37d --- /dev/null +++ b/target/linux/mediatek/patches-6.12/700-net-phy-mediatek-Add-2.5Gphy-firmware-dt-bindings-an.patch @@ -0,0 +1,71 @@ +From 955a80b20fad77dd73ec17ab64d7eb8014cb59c7 Mon Sep 17 00:00:00 2001 +From: Sky Huang +Date: Wed, 19 Feb 2025 16:39:08 +0800 +Subject: [PATCH 19/20] net: phy: mediatek: Add 2.5Gphy firmware dt-bindings + and dts node + +Add 2.5Gphy firmware dt-bindings and dts node since mtk-2p5ge +driver requires firmware to run. Also, update MAINTAINERS for +MediaTek's built-in 2.5Gphy dt-bindings and change MAINTAINER's name. + +Signed-off-by: Sky Huang +--- + .../bindings/net/mediatek,2p5gphy-fw.yaml | 37 +++++++++++++++++++ + MAINTAINERS | 3 +- + 2 files changed, 39 insertions(+), 1 deletion(-) + create mode 100644 Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml +@@ -0,0 +1,37 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/net/mediatek,2p5gphy-fw.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: MediaTek Built-in 2.5G Ethernet PHY ++ ++maintainers: ++ - Sky Huang ++ ++description: | ++ MediaTek Built-in 2.5G Ethernet PHY needs to load firmware so it can ++ run correctly. ++ ++properties: ++ compatible: ++ const: "mediatek,2p5gphy-fw" ++ ++ reg: ++ items: ++ - description: pmb firmware load address ++ - description: firmware trigger register ++ ++required: ++ - compatible ++ - reg ++ ++additionalProperties: false ++ ++examples: ++ - | ++ phyfw: phy-firmware@f000000 { ++ compatible = "mediatek,2p5gphy-fw"; ++ reg = <0 0x0f100000 0 0x20000>, ++ <0 0x0f0f0018 0 0x20>; ++ }; +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -14426,9 +14426,10 @@ F: include/linux/pcs/pcs-mtk-usxgmii.h + MEDIATEK ETHERNET PHY DRIVERS + M: Daniel Golle + M: Qingfang Deng +-M: SkyLake Huang ++M: Sky Huang + L: netdev@vger.kernel.org + S: Maintained ++F: Documentation/devicetree/bindings/net/mediatek,2p5gphy-fw.yaml + F: drivers/net/phy/mediatek/mtk-ge-soc.c + F: drivers/net/phy/mediatek/mtk-phy-lib.c + F: drivers/net/phy/mediatek/mtk-ge.c diff --git a/target/linux/mediatek/patches-6.12/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch b/target/linux/mediatek/patches-6.12/701-net-phy-mediatek-add-driver-for-built-in-2.5G-ethern.patch similarity index 65% rename from target/linux/mediatek/patches-6.12/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch rename to target/linux/mediatek/patches-6.12/701-net-phy-mediatek-add-driver-for-built-in-2.5G-ethern.patch index 2548e789f06..0bb8ba00a3d 100644 --- a/target/linux/mediatek/patches-6.12/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch +++ b/target/linux/mediatek/patches-6.12/701-net-phy-mediatek-add-driver-for-built-in-2.5G-ethern.patch @@ -1,24 +1,36 @@ -From 69ca89165e39e6b6f4c79e6b4c03559e0fac7051 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Mon, 1 Jul 2024 18:54:15 +0800 -Subject: [PATCH 11/13] net: phy: add driver for built-in 2.5G ethernet PHY on - MT7988 +From 4eb44972db02c2b704f0ef5c891f29f25440a063 Mon Sep 17 00:00:00 2001 +From: Sky Huang +Date: Wed, 19 Feb 2025 16:39:10 +0800 +Subject: [PATCH 20/20] net: phy: mediatek: add driver for built-in 2.5G + ethernet PHY on MT7988 Add support for internal 2.5Gphy on MT7988. This driver will load -necessary firmware, add appropriate time delay and figure out LED. -Also, certain control registers will be set to fix link-up issues. +necessary firmware and add appropriate time delay to make sure +that firmware works stably. Also, certain control registers will +be set to fix link-up issues. -Signed-off-by: SkyLake.Huang +Signed-off-by: Sky Huang --- + MAINTAINERS | 1 + drivers/net/phy/mediatek/Kconfig | 11 + drivers/net/phy/mediatek/Makefile | 1 + - drivers/net/phy/mediatek/mtk-2p5ge.c | 432 +++++++++++++++++++++++++++ - 4 files changed, 445 insertions(+) + drivers/net/phy/mediatek/mtk-2p5ge.c | 342 +++++++++++++++++++++++++++ + 4 files changed, 355 insertions(+) create mode 100644 drivers/net/phy/mediatek/mtk-2p5ge.c +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -14430,6 +14430,7 @@ M: Sky Huang +obj-$(CONFIG_MEDIATEK_2P5GE_PHY) += mtk-2p5ge.o --- /dev/null +++ b/drivers/net/phy/mediatek/mtk-2p5ge.c -@@ -0,0 +1,436 @@ +@@ -0,0 +1,342 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include @@ -59,16 +71,9 @@ Signed-off-by: SkyLake.Huang + +#define MTK_2P5GPHY_ID_MT7988 (0x00339c11) + -+#define MTK_PHY_PAGE_EXTENDED_1 0x0001 -+#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14 -+#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4) -+ +#define MT7988_2P5GE_PMB_FW "mediatek/mt7988/i2p5ge-phy-pmb.bin" +#define MT7988_2P5GE_PMB_FW_SIZE (0x20000) -+#define MT7988_2P5GE_PMB_FW_BASE (0x0f100000) -+#define MT7988_2P5GE_PMB_FW_LEN (0x20000) -+#define MT7988_2P5GE_MD32_EN_CFG_BASE (0x0f0f0018) -+#define MT7988_2P5GE_MD32_EN_CFG_LEN (0x20) ++#define MD32_EN_CFG (0x18) +#define MD32_EN BIT(0) + +#define BASE100T_STATUS_EXTEND (0x10) @@ -79,16 +84,18 @@ Signed-off-by: SkyLake.Huang +#define PHY_AUX_DPX_MASK GENMASK(5, 5) +#define PHY_AUX_SPEED_MASK GENMASK(4, 2) + ++/* Registers on MDIO_MMD_VEND1 */ +#define MTK_PHY_LPI_PCS_DSP_CTRL (0x121) +#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8) + ++#define MTK_PHY_HOST_CMD1 0x800e ++#define MTK_PHY_HOST_CMD2 0x800f +/* Registers on Token Ring debug nodes */ +/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */ +#define AUTO_NP_10XEN BIT(6) + +struct mtk_i2p5ge_phy_priv { + bool fw_loaded; -+ unsigned long led_state; +}; + +enum { @@ -101,21 +108,22 @@ Signed-off-by: SkyLake.Huang +static int mt798x_2p5ge_phy_load_fw(struct phy_device *phydev) +{ + struct mtk_i2p5ge_phy_priv *priv = phydev->priv; -+ void __iomem *md32_en_cfg_base, *pmb_addr; ++ void __iomem *mcu_csr_base, *pmb_addr; + struct device *dev = &phydev->mdio.dev; + const struct firmware *fw; ++ struct device_node *np; + int ret, i; -+ u16 reg; ++ u32 reg; + -+ if (priv->fw_loaded) -+ return 0; ++ np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw"); ++ if (!np) ++ return -ENOENT; + -+ pmb_addr = ioremap(MT7988_2P5GE_PMB_FW_BASE, MT7988_2P5GE_PMB_FW_LEN); ++ pmb_addr = of_iomap(np, 0); + if (!pmb_addr) + return -ENOMEM; -+ md32_en_cfg_base = ioremap(MT7988_2P5GE_MD32_EN_CFG_BASE, -+ MT7988_2P5GE_MD32_EN_CFG_LEN); -+ if (!md32_en_cfg_base) { ++ mcu_csr_base = of_iomap(np, 1); ++ if (!mcu_csr_base) { + ret = -ENOMEM; + goto free_pmb; + } @@ -134,7 +142,7 @@ Signed-off-by: SkyLake.Huang + goto release_fw; + } + -+ reg = readw(md32_en_cfg_base); ++ reg = readw(mcu_csr_base + MD32_EN_CFG); + if (reg & MD32_EN) { + phy_set_bits(phydev, MII_BMCR, BMCR_RESET); + usleep_range(10000, 11000); @@ -142,32 +150,33 @@ Signed-off-by: SkyLake.Huang + phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN); + + /* Write magic number to safely stall MCU */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800e, 0x1100); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800f, 0x00df); ++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_HOST_CMD1, 0x1100); ++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_HOST_CMD2, 0x00df); + + for (i = 0; i < MT7988_2P5GE_PMB_FW_SIZE - 1; i += 4) + writel(*((uint32_t *)(fw->data + i)), pmb_addr + i); -+ dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n", -+ be16_to_cpu(*((__be16 *)(fw->data + -+ MT7988_2P5GE_PMB_FW_SIZE - 8))), -+ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 6), -+ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 5), -+ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 2), -+ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 1)); -+ -+ writew(reg & ~MD32_EN, md32_en_cfg_base); -+ writew(reg | MD32_EN, md32_en_cfg_base); ++ ++ if (!priv->fw_loaded) ++ dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n", ++ be16_to_cpu(*((__be16 *)(fw->data + ++ MT7988_2P5GE_PMB_FW_SIZE - 8))), ++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 6), ++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 5), ++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 2), ++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 1)); ++ ++ writew(reg & ~MD32_EN, mcu_csr_base + MD32_EN_CFG); ++ writew(reg | MD32_EN, mcu_csr_base + MD32_EN_CFG); + phy_set_bits(phydev, MII_BMCR, BMCR_RESET); + /* We need a delay here to stabilize initialization of MCU */ + usleep_range(7000, 8000); -+ dev_info(dev, "Firmware loading/trigger ok.\n"); + + priv->fw_loaded = true; + +release_fw: + release_firmware(fw); +free: -+ iounmap(md32_en_cfg_base); ++ iounmap(mcu_csr_base); +free_pmb: + iounmap(pmb_addr); + @@ -197,7 +206,7 @@ Signed-off-by: SkyLake.Huang + + /* Switch pinctrl after setting polarity to avoid bogus blinking */ + pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led"); -+ if (IS_ERR(pinctrl)) ++ if (IS_ERR(pinctrl) && PTR_ERR(pinctrl) != -ENODEV) + dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n"); + + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL, @@ -221,14 +230,6 @@ Signed-off-by: SkyLake.Huang + u32 adv; + int ret; + -+ /* In fact, if we disable autoneg, we can't link up correctly: -+ * 2.5G/1G: Need AN to exchange master/slave information. -+ * 100M/10M: Without AN, link starts at half duplex (According to -+ * IEEE 802.3-2018), which this phy doesn't support. -+ */ -+ if (phydev->autoneg == AUTONEG_DISABLE) -+ return -EOPNOTSUPP; -+ + ret = genphy_c45_an_config_aneg(phydev); + if (ret < 0) + return ret; @@ -245,7 +246,7 @@ Signed-off-by: SkyLake.Huang + if (ret > 0) + changed = true; + -+ return genphy_c45_check_and_restart_aneg(phydev, changed); ++ return __genphy_config_aneg(phydev, changed); +} + +static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev) @@ -339,82 +340,6 @@ Signed-off-by: SkyLake.Huang + return RATE_MATCH_PAUSE; +} + -+static const unsigned long supported_triggers = -+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -+ BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX); -+ -+static int mt798x_2p5ge_phy_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct mtk_i2p5ge_phy_priv *priv = phydev->priv; -+ bool blinking = false; -+ int err = 0; -+ -+ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking); -+ if (err < 0) -+ return err; -+ -+ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, -+ blinking); -+ if (err) -+ return err; -+ -+ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state, -+ MTK_2P5GPHY_LED_ON_MASK, false); -+} -+ -+static int mt798x_2p5ge_phy_led_brightness_set(struct phy_device *phydev, -+ u8 index, -+ enum led_brightness value) -+{ -+ struct mtk_i2p5ge_phy_priv *priv = phydev->priv; -+ int err; -+ -+ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false); -+ if (err) -+ return err; -+ -+ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state, -+ MTK_2P5GPHY_LED_ON_MASK, -+ (value != LED_OFF)); -+} -+ -+static int mt798x_2p5ge_phy_led_hw_is_supported(struct phy_device *phydev, -+ u8 index, unsigned long rules) -+{ -+ return mtk_phy_led_hw_is_supported(phydev, index, rules, -+ supported_triggers); -+} -+ -+static int mt798x_2p5ge_phy_led_hw_control_get(struct phy_device *phydev, -+ u8 index, unsigned long *rules) -+{ -+ struct mtk_i2p5ge_phy_priv *priv = phydev->priv; -+ -+ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state, -+ MTK_2P5GPHY_LED_ON_SET, -+ MTK_2P5GPHY_LED_RX_BLINK_SET, -+ MTK_2P5GPHY_LED_TX_BLINK_SET); -+}; -+ -+static int mt798x_2p5ge_phy_led_hw_control_set(struct phy_device *phydev, -+ u8 index, unsigned long rules) -+{ -+ struct mtk_i2p5ge_phy_priv *priv = phydev->priv; -+ -+ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state, -+ MTK_2P5GPHY_LED_ON_SET, -+ MTK_2P5GPHY_LED_RX_BLINK_SET, -+ MTK_2P5GPHY_LED_TX_BLINK_SET); -+}; -+ +static int mt798x_2p5ge_phy_probe(struct phy_device *phydev) +{ + struct mtk_i2p5ge_phy_priv *priv; @@ -439,8 +364,6 @@ Signed-off-by: SkyLake.Huang + priv->fw_loaded = false; + phydev->priv = priv; + -+ mtk_phy_leds_state_init(phydev); -+ + return 0; +} + @@ -458,11 +381,6 @@ Signed-off-by: SkyLake.Huang + .resume = genphy_resume, + .read_page = mtk_phy_read_page, + .write_page = mtk_phy_write_page, -+ .led_blink_set = mt798x_2p5ge_phy_led_blink_set, -+ .led_brightness_set = mt798x_2p5ge_phy_led_brightness_set, -+ .led_hw_is_supported = mt798x_2p5ge_phy_led_hw_is_supported, -+ .led_hw_control_get = mt798x_2p5ge_phy_led_hw_control_get, -+ .led_hw_control_set = mt798x_2p5ge_phy_led_hw_control_set, + }, +}; + diff --git a/target/linux/mediatek/patches-6.12/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch b/target/linux/mediatek/patches-6.12/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch index 917a458d308..d85e505d45e 100644 --- a/target/linux/mediatek/patches-6.12/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch +++ b/target/linux/mediatek/patches-6.12/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch @@ -61,7 +61,7 @@ Signed-off-by: Felix Fietkau struct mtk_pcie_port; /** -@@ -1060,6 +1066,27 @@ static int mtk_pcie_setup(struct mtk_pci +@@ -1052,6 +1058,27 @@ static int mtk_pcie_setup(struct mtk_pci struct mtk_pcie_port *port, *tmp; int err, slot; diff --git a/target/linux/mediatek/patches-6.12/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch b/target/linux/mediatek/patches-6.12/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch index b29b0d52edd..d1ac132ac5b 100644 --- a/target/linux/mediatek/patches-6.12/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch +++ b/target/linux/mediatek/patches-6.12/732-net-phy-mxl-gpy-don-t-use-SGMII-AN-if-using-phylink.patch @@ -14,7 +14,7 @@ Signed-off-by: Daniel Golle --- a/drivers/net/phy/mxl-gpy.c +++ b/drivers/net/phy/mxl-gpy.c -@@ -372,8 +372,11 @@ static bool gpy_2500basex_chk(struct phy +@@ -380,8 +380,11 @@ static bool gpy_2500basex_chk(struct phy phydev->speed = SPEED_2500; phydev->interface = PHY_INTERFACE_MODE_2500BASEX; @@ -28,7 +28,7 @@ Signed-off-by: Daniel Golle return true; } -@@ -424,6 +427,14 @@ static int gpy_config_aneg(struct phy_de +@@ -432,6 +435,14 @@ static int gpy_config_aneg(struct phy_de u32 adv; int ret; @@ -43,7 +43,7 @@ Signed-off-by: Daniel Golle if (phydev->autoneg == AUTONEG_DISABLE) { /* Configure half duplex with genphy_setup_forced, * because genphy_c45_pma_setup_forced does not support. -@@ -546,6 +557,8 @@ static int gpy_update_interface(struct p +@@ -554,6 +565,8 @@ static int gpy_update_interface(struct p switch (phydev->speed) { case SPEED_2500: phydev->interface = PHY_INTERFACE_MODE_2500BASEX; @@ -52,7 +52,7 @@ Signed-off-by: Daniel Golle ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL, VSPEC1_SGMII_CTRL_ANEN, 0); if (ret < 0) { -@@ -559,7 +572,7 @@ static int gpy_update_interface(struct p +@@ -567,7 +580,7 @@ static int gpy_update_interface(struct p case SPEED_100: case SPEED_10: phydev->interface = PHY_INTERFACE_MODE_SGMII; diff --git a/target/linux/mediatek/patches-6.12/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch b/target/linux/mediatek/patches-6.12/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch deleted file mode 100644 index cf8e5cd38a9..00000000000 --- a/target/linux/mediatek/patches-6.12/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch +++ /dev/null @@ -1,3514 +0,0 @@ -From 656f5fdeb6ee6fa95c28cab3b535e2e09ef59c57 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:05 +0800 -Subject: [PATCH 1/9] net: phy: mediatek: Re-organize MediaTek ethernet phy - drivers - -Re-organize MediaTek ethernet phy driver files and get ready to integrate -some common functions (and add new 2.5G phy driver). -mtk-ge.c: MT7530 Gphy on MT7621 & MT7531 Gphy -mtk-ge-soc.c: Built-in Gphy on MT7981 & Built-in switch Gphy on MT7988 -(mtk-2p5ge.c: Planned for built-in 2.5G phy on MT7988 - --> in another patchset) - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/Kconfig | 17 +------------- - drivers/net/phy/Makefile | 3 +-- - drivers/net/phy/mediatek/Kconfig | 22 +++++++++++++++++++ - drivers/net/phy/mediatek/Makefile | 3 +++ - .../mtk-ge-soc.c} | 0 - .../phy/{mediatek-ge.c => mediatek/mtk-ge.c} | 0 - 6 files changed, 27 insertions(+), 18 deletions(-) - create mode 100644 drivers/net/phy/mediatek/Kconfig - create mode 100644 drivers/net/phy/mediatek/Makefile - rename drivers/net/phy/{mediatek-ge-soc.c => mediatek/mtk-ge-soc.c} (100%) - rename drivers/net/phy/{mediatek-ge.c => mediatek/mtk-ge.c} (100%) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -313,22 +313,7 @@ config MAXLINEAR_GPHY - Support for the Maxlinear GPY115, GPY211, GPY212, GPY215, - GPY241, GPY245 PHYs. - --config MEDIATEK_GE_PHY -- tristate "MediaTek Gigabit Ethernet PHYs" -- help -- Supports the MediaTek Gigabit Ethernet PHYs. -- --config MEDIATEK_GE_SOC_PHY -- tristate "MediaTek SoC Ethernet PHYs" -- depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST -- depends on 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. -+source "drivers/net/phy/mediatek/Kconfig" - - config MICREL_PHY - tristate "Micrel PHYs" ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -82,8 +82,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o - obj-$(CONFIG_MARVELL_88Q2XXX_PHY) += marvell-88q2xxx.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-y += mediatek/ - 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/Kconfig -@@ -0,0 +1,22 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+config MEDIATEK_GE_PHY -+ tristate "MediaTek Gigabit Ethernet PHYs" -+ help -+ Supports the MediaTek non-built-in Gigabit Ethernet PHYs. -+ -+ Non-built-in Gigabit Ethernet PHYs include mt7530/mt7531. -+ You may find mt7530 inside mt7621. This driver shares some -+ common operations with MediaTek SoC built-in 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. ---- /dev/null -+++ b/drivers/net/phy/mediatek/Makefile -@@ -0,0 +1,3 @@ -+# SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o -+obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o ---- a/drivers/net/phy/mediatek-ge-soc.c -+++ /dev/null -@@ -1,1555 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0+ --#include --#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_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_LINK (MTK_PHY_LED_ON_LINK10 |\ -- MTK_PHY_LED_ON_LINK100 |\ -- MTK_PHY_LED_ON_LINK1000) --#define MTK_PHY_LED_ON_LINKDOWN BIT(3) --#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */ --#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */ --#define MTK_PHY_LED_ON_FORCE_ON BIT(6) --#define MTK_PHY_LED_ON_POLARITY BIT(14) --#define MTK_PHY_LED_ON_ENABLE BIT(15) -- --#define MTK_PHY_LED0_BLINK_CTRL 0x25 --#define MTK_PHY_LED1_BLINK_CTRL 0x27 --#define MTK_PHY_LED_BLINK_1000TX BIT(0) --#define MTK_PHY_LED_BLINK_1000RX BIT(1) --#define MTK_PHY_LED_BLINK_100TX BIT(2) --#define MTK_PHY_LED_BLINK_100RX BIT(3) --#define MTK_PHY_LED_BLINK_10TX BIT(4) --#define MTK_PHY_LED_BLINK_10RX BIT(5) --#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\ -- MTK_PHY_LED_BLINK_100RX |\ -- MTK_PHY_LED_BLINK_1000RX) --#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\ -- MTK_PHY_LED_BLINK_100TX |\ -- MTK_PHY_LED_BLINK_1000TX) --#define MTK_PHY_LED_BLINK_COLLISION BIT(6) --#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7) --#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) --#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9) -- --#define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1) -- --#define MTK_PHY_RG_BG_RASEL 0x115 --#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0) -- --/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */ --#define RG_GPIO_MISC_TPBANK0 0x6f0 --#define RG_GPIO_MISC_TPBANK0_BOOTMODE GENMASK(11, 8) -- --/* These macro privides efuse parsing for internal phy. */ --#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0)) --#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0)) --#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 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 --}; -- --#define MTK_PHY_LED_STATE_FORCE_ON 0 --#define MTK_PHY_LED_STATE_FORCE_BLINK 1 --#define MTK_PHY_LED_STATE_NETDEV 2 -- --struct mtk_socphy_priv { -- unsigned long led_state; --}; -- --struct mtk_socphy_shared { -- u32 boottrap; -- struct mtk_socphy_priv priv[4]; --}; -- --static int mtk_socphy_read_page(struct phy_device *phydev) --{ -- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); --} -- --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 = -1; -- -- 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); -- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ -- __phy_write(phydev, 0x11, 0xc71); -- __phy_write(phydev, 0x12, 0xc); -- __phy_write(phydev, 0x10, 0x8fae); -- -- /* EnabRandUpdTrig = 1 */ -- __phy_write(phydev, 0x11, 0x2f00); -- __phy_write(phydev, 0x12, 0xe); -- __phy_write(phydev, 0x10, 0x8fb0); -- -- /* NormMseLoThresh = 85 */ -- __phy_write(phydev, 0x11, 0x55a0); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x83aa); -- -- /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ -- __phy_write(phydev, 0x11, 0x240); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x9680); -- -- /* TrFreeze = 0 (mt7988 default) */ -- __phy_write(phydev, 0x11, 0x0); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x9686); -- -- /* SSTrKp100 = 5 */ -- /* SSTrKf100 = 6 */ -- /* SSTrKp1000Mas = 5 */ -- /* SSTrKf1000Mas = 6 */ -- /* SSTrKp1000Slv = 5 */ -- /* SSTrKf1000Slv = 6 */ -- __phy_write(phydev, 0x11, 0xbaef); -- __phy_write(phydev, 0x12, 0x2e); -- __phy_write(phydev, 0x10, 0x968c); -- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); --} -- --static void mt7981_phy_finetune(struct phy_device *phydev) --{ -- u16 val[8] = { 0x01ce, 0x01c1, -- 0x020f, 0x0202, -- 0x03d0, 0x03c0, -- 0x0013, 0x0005 }; -- int i, k; -- -- /* 100M eye finetune: -- * Keep middle level of TX MLT3 shapper as default. -- * Only change TX MLT3 overshoot level here. -- */ -- for (k = 0, i = 1; i < 12; i++) { -- if (i % 3 == 0) -- continue; -- phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); -- } -- -- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* ResetSyncOffset = 6 */ -- __phy_write(phydev, 0x11, 0x600); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x8fc0); -- -- /* VgaDecRate = 1 */ -- __phy_write(phydev, 0x11, 0x4c2a); -- __phy_write(phydev, 0x12, 0x3e); -- __phy_write(phydev, 0x10, 0x8fa4); -- -- /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, -- * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 -- */ -- __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 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); -- -- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* ResetSyncOffset = 5 */ -- __phy_write(phydev, 0x11, 0x500); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x8fc0); -- -- /* VgaDecRate is 1 at default on mt7988 */ -- -- /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, -- * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 -- */ -- __phy_write(phydev, 0x11, 0xb90a); -- __phy_write(phydev, 0x12, 0x6f); -- __phy_write(phydev, 0x10, 0x8f82); -- -- /* RemAckCntLimitCtrl = 1 */ -- __phy_write(phydev, 0x11, 0xfbba); -- __phy_write(phydev, 0x12, 0xc3); -- __phy_write(phydev, 0x10, 0x87f8); -- -- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -- -- /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ -- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, -- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, -- BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); -- -- /* rg_tr_lpf_cnt_val = 1023 */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff); --} -- --static void mt798x_phy_eee(struct phy_device *phydev) --{ -- 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)); -- -- /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */ -- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, -- MTK_PHY_LPI_TXPCS_LOC_RCV); -- -- /* This also fixes some IoT issues, such as CH340 */ -- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, -- MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, -- FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | -- 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 = 2 */ -- __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 = 0 */ -- __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 mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index, -- bool on) --{ -- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- bool changed; -- -- if (on) -- changed = !test_and_set_bit(bit_on, &priv->led_state); -- else -- changed = !!test_and_clear_bit(bit_on, &priv->led_state); -- -- changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV + -- (index ? 16 : 0), &priv->led_state); -- if (changed) -- return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -- MTK_PHY_LED_ON_MASK, -- on ? MTK_PHY_LED_ON_FORCE_ON : 0); -- else -- return 0; --} -- --static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, -- bool blinking) --{ -- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- bool changed; -- -- if (blinking) -- changed = !test_and_set_bit(bit_blink, &priv->led_state); -- else -- changed = !!test_and_clear_bit(bit_blink, &priv->led_state); -- -- changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV + -- (index ? 16 : 0), &priv->led_state); -- if (changed) -- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL, -- blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0); -- else -- return 0; --} -- --static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index, -- unsigned long *delay_on, -- unsigned long *delay_off) --{ -- bool blinking = false; -- int err = 0; -- -- if (index > 1) -- return -EINVAL; -- -- if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { -- blinking = true; -- *delay_on = 50; -- *delay_off = 50; -- } -- -- err = mt798x_phy_hw_led_blink_set(phydev, index, blinking); -- if (err) -- return err; -- -- return mt798x_phy_hw_led_on_set(phydev, index, false); --} -- --static int mt798x_phy_led_brightness_set(struct phy_device *phydev, -- u8 index, enum led_brightness value) --{ -- int err; -- -- err = mt798x_phy_hw_led_blink_set(phydev, index, false); -- if (err) -- return err; -- -- return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF)); --} -- --static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -- BIT(TRIGGER_NETDEV_HALF_DUPLEX) | -- BIT(TRIGGER_NETDEV_LINK) | -- BIT(TRIGGER_NETDEV_LINK_10) | -- BIT(TRIGGER_NETDEV_LINK_100) | -- BIT(TRIGGER_NETDEV_LINK_1000) | -- BIT(TRIGGER_NETDEV_RX) | -- BIT(TRIGGER_NETDEV_TX)); -- --static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, -- unsigned long rules) --{ -- if (index > 1) -- return -EINVAL; -- -- /* All combinations of the supported triggers are allowed */ -- if (rules & ~supported_triggers) -- return -EOPNOTSUPP; -- -- return 0; --}; -- --static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index, -- unsigned long *rules) --{ -- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); -- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- int on, blink; -- -- if (index > 1) -- return -EINVAL; -- -- on = phy_read_mmd(phydev, MDIO_MMD_VEND2, -- index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL); -- -- if (on < 0) -- return -EIO; -- -- blink = phy_read_mmd(phydev, MDIO_MMD_VEND2, -- index ? MTK_PHY_LED1_BLINK_CTRL : -- MTK_PHY_LED0_BLINK_CTRL); -- if (blink < 0) -- return -EIO; -- -- if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | -- MTK_PHY_LED_ON_LINKDOWN)) || -- (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX))) -- set_bit(bit_netdev, &priv->led_state); -- else -- clear_bit(bit_netdev, &priv->led_state); -- -- if (on & MTK_PHY_LED_ON_FORCE_ON) -- set_bit(bit_on, &priv->led_state); -- else -- clear_bit(bit_on, &priv->led_state); -- -- if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK) -- set_bit(bit_blink, &priv->led_state); -- else -- clear_bit(bit_blink, &priv->led_state); -- -- if (!rules) -- return 0; -- -- if (on & MTK_PHY_LED_ON_LINK) -- *rules |= BIT(TRIGGER_NETDEV_LINK); -- -- if (on & MTK_PHY_LED_ON_LINK10) -- *rules |= BIT(TRIGGER_NETDEV_LINK_10); -- -- if (on & MTK_PHY_LED_ON_LINK100) -- *rules |= BIT(TRIGGER_NETDEV_LINK_100); -- -- if (on & MTK_PHY_LED_ON_LINK1000) -- *rules |= BIT(TRIGGER_NETDEV_LINK_1000); -- -- if (on & MTK_PHY_LED_ON_FDX) -- *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX); -- -- if (on & MTK_PHY_LED_ON_HDX) -- *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX); -- -- if (blink & MTK_PHY_LED_BLINK_RX) -- *rules |= BIT(TRIGGER_NETDEV_RX); -- -- if (blink & MTK_PHY_LED_BLINK_TX) -- *rules |= BIT(TRIGGER_NETDEV_TX); -- -- return 0; --}; -- --static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index, -- unsigned long rules) --{ -- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- u16 on = 0, blink = 0; -- int ret; -- -- if (index > 1) -- return -EINVAL; -- -- if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) -- on |= MTK_PHY_LED_ON_FDX; -- -- if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) -- on |= MTK_PHY_LED_ON_HDX; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK10; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK100; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK1000; -- -- if (rules & BIT(TRIGGER_NETDEV_RX)) { -- blink |= (on & MTK_PHY_LED_ON_LINK) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) : -- MTK_PHY_LED_BLINK_RX; -- } -- -- if (rules & BIT(TRIGGER_NETDEV_TX)) { -- blink |= (on & MTK_PHY_LED_ON_LINK) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) : -- MTK_PHY_LED_BLINK_TX; -- } -- -- if (blink || on) -- set_bit(bit_netdev, &priv->led_state); -- else -- clear_bit(bit_netdev, &priv->led_state); -- -- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_ON_CTRL : -- MTK_PHY_LED0_ON_CTRL, -- MTK_PHY_LED_ON_FDX | -- MTK_PHY_LED_ON_HDX | -- MTK_PHY_LED_ON_LINK, -- on); -- -- if (ret) -- return ret; -- -- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_BLINK_CTRL : -- MTK_PHY_LED0_BLINK_CTRL, blink); --}; -- --static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num) --{ -- struct mtk_socphy_shared *priv = phydev->shared->priv; -- u32 polarities; -- -- if (led_num == 0) -- polarities = ~(priv->boottrap); -- else -- polarities = MTK_PHY_LED1_DEFAULT_POLARITIES; -- -- if (polarities & BIT(phydev->mdio.addr)) -- return true; -- -- return false; --} -- --static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev) --{ -- struct pinctrl *pinctrl; -- int index; -- -- /* Setup LED polarity according to bootstrap use of LED pins */ -- for (index = 0; index < 2; ++index) -- phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -- MTK_PHY_LED_ON_POLARITY, -- mt7988_phy_led_get_polarity(phydev, index) ? -- MTK_PHY_LED_ON_POLARITY : 0); -- -- /* Only now setup pinctrl to avoid bogus blinking */ -- pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); -- if (IS_ERR(pinctrl)) -- dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n"); -- -- return 0; --} -- --static int mt7988_phy_probe_shared(struct phy_device *phydev) --{ -- struct device_node *np = dev_of_node(&phydev->mdio.bus->dev); -- struct mtk_socphy_shared *shared = phydev->shared->priv; -- struct regmap *regmap; -- u32 reg; -- int ret; -- -- /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B, -- * LED_C and LED_D respectively. At the same time those pins are used to -- * bootstrap configuration of the reference clock source (LED_A), -- * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D). -- * In practise this is done using a LED and a resistor pulling the pin -- * either to GND or to VIO. -- * The detected value at boot time is accessible at run-time using the -- * TPBANK0 register located in the gpio base of the pinctrl, in order -- * to read it here it needs to be referenced by a phandle called -- * 'mediatek,pio' in the MDIO bus hosting the PHY. -- * The 4 bits in TPBANK0 are kept as package shared data and are used to -- * set LED polarity for each of the LED0. -- */ -- regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio"); -- if (IS_ERR(regmap)) -- return PTR_ERR(regmap); -- -- ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, ®); -- if (ret) -- return ret; -- -- shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg); -- -- return 0; --} -- --static void mt798x_phy_leds_state_init(struct phy_device *phydev) --{ -- int i; -- -- for (i = 0; i < 2; ++i) -- mt798x_phy_led_hw_control_get(phydev, i, NULL); --} -- --static int mt7988_phy_probe(struct phy_device *phydev) --{ -- struct mtk_socphy_shared *shared; -- struct mtk_socphy_priv *priv; -- int err; -- -- if (phydev->mdio.addr > 3) -- return -EINVAL; -- -- err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0, -- sizeof(struct mtk_socphy_shared)); -- if (err) -- return err; -- -- if (phy_package_probe_once(phydev)) { -- err = mt7988_phy_probe_shared(phydev); -- if (err) -- return err; -- } -- -- shared = phydev->shared->priv; -- priv = &shared->priv[phydev->mdio.addr]; -- -- phydev->priv = priv; -- -- mt798x_phy_leds_state_init(phydev); -- -- err = mt7988_phy_fix_leds_polarities(phydev); -- if (err) -- return err; -- -- /* Disable TX power saving at probing to: -- * 1. Meet common mode compliance test criteria -- * 2. Make sure that TX-VCM calibration works fine -- */ -- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, -- MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); -- -- return mt798x_phy_calibration(phydev); --} -- --static int mt7981_phy_probe(struct phy_device *phydev) --{ -- struct mtk_socphy_priv *priv; -- -- priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv), -- GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- phydev->priv = priv; -- -- mt798x_phy_leds_state_init(phydev); -- -- return mt798x_phy_calibration(phydev); --} -- --static struct phy_driver mtk_socphy_driver[] = { -- { -- PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), -- .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, -- .led_blink_set = mt798x_phy_led_blink_set, -- .led_brightness_set = mt798x_phy_led_brightness_set, -- .led_hw_is_supported = mt798x_phy_led_hw_is_supported, -- .led_hw_control_set = mt798x_phy_led_hw_control_set, -- .led_hw_control_get = mt798x_phy_led_hw_control_get, -- }, -- { -- PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988), -- .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, -- .led_blink_set = mt798x_phy_led_blink_set, -- .led_brightness_set = mt798x_phy_led_brightness_set, -- .led_hw_is_supported = mt798x_phy_led_hw_is_supported, -- .led_hw_control_set = mt798x_phy_led_hw_control_set, -- .led_hw_control_get = mt798x_phy_led_hw_control_get, -- }, --}; -- --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 -+++ /dev/null -@@ -1,148 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0+ --#include --#include --#include --#include -- --#define MTK_EXT_PAGE_ACCESS 0x1f --#define MTK_PHY_PAGE_STANDARD 0x0000 --#define MTK_PHY_PAGE_EXTENDED 0x0001 --#define MTK_PHY_PAGE_EXTENDED_2 0x0002 --#define MTK_PHY_PAGE_EXTENDED_3 0x0003 --#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 --#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 -- --static int mtk_gephy_read_page(struct phy_device *phydev) --{ -- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); --} -- --static int mtk_gephy_write_page(struct phy_device *phydev, int page) --{ -- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); --} -- --static void mtk_gephy_config_init(struct phy_device *phydev) --{ -- /* Disable EEE */ -- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); -- -- /* Enable HW auto downshift */ -- phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4)); -- -- /* Increase SlvDPSready time */ -- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- __phy_write(phydev, 0x10, 0xafae); -- __phy_write(phydev, 0x12, 0x2f); -- __phy_write(phydev, 0x10, 0x8fae); -- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -- -- /* Adjust 100_mse_threshold */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff); -- -- /* Disable mcc */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300); --} -- --static int mt7530_phy_config_init(struct phy_device *phydev) --{ -- mtk_gephy_config_init(phydev); -- -- /* Increase post_update_timer */ -- phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b); -- -- return 0; --} -- --static int mt7530_led_config_of(struct phy_device *phydev) --{ -- struct device_node *np = phydev->mdio.dev.of_node; -- const __be32 *paddr; -- int len; -- int i; -- -- paddr = of_get_property(np, "mediatek,led-config", &len); -- if (!paddr) -- return 0; -- -- if (len < (2 * sizeof(*paddr))) -- return -EINVAL; -- -- len /= sizeof(*paddr); -- -- phydev_warn(phydev, "Configure LED registers (num=%d)\n", len); -- for (i = 0; i < len - 1; i += 2) { -- u32 reg; -- u32 val; -- -- reg = be32_to_cpup(paddr + i); -- val = be32_to_cpup(paddr + i + 1); -- -- phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val); -- } -- -- return 0; --} -- --static int mt7531_phy_config_init(struct phy_device *phydev) --{ -- mtk_gephy_config_init(phydev); -- -- /* PHY link down power saving enable */ -- phy_set_bits(phydev, 0x17, BIT(4)); -- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300); -- -- /* Set TX Pair delay selection */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404); -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404); -- -- /* LED Config*/ -- mt7530_led_config_of(phydev); -- -- return 0; --} -- --static struct phy_driver mtk_gephy_driver[] = { -- { -- PHY_ID_MATCH_EXACT(0x03a29412), -- .name = "MediaTek MT7530 PHY", -- .config_init = mt7530_phy_config_init, -- /* Interrupts are handled by the switch, not the PHY -- * itself. -- */ -- .config_intr = genphy_no_config_intr, -- .handle_interrupt = genphy_handle_interrupt_no_ack, -- .suspend = genphy_suspend, -- .resume = genphy_resume, -- .read_page = mtk_gephy_read_page, -- .write_page = mtk_gephy_write_page, -- }, -- { -- PHY_ID_MATCH_EXACT(0x03a29441), -- .name = "MediaTek MT7531 PHY", -- .config_init = mt7531_phy_config_init, -- /* Interrupts are handled by the switch, not the PHY -- * itself. -- */ -- .config_intr = genphy_no_config_intr, -- .handle_interrupt = genphy_handle_interrupt_no_ack, -- .suspend = genphy_suspend, -- .resume = genphy_resume, -- .read_page = mtk_gephy_read_page, -- .write_page = mtk_gephy_write_page, -- }, --}; -- --module_phy_driver(mtk_gephy_driver); -- --static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = { -- { PHY_ID_MATCH_EXACT(0x03a29441) }, -- { PHY_ID_MATCH_EXACT(0x03a29412) }, -- { } --}; -- --MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver"); --MODULE_AUTHOR("DENG, Qingfang "); --MODULE_LICENSE("GPL"); -- --MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl); ---- /dev/null -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -0,0 +1,1555 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+#include -+#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_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_LINK (MTK_PHY_LED_ON_LINK10 |\ -+ MTK_PHY_LED_ON_LINK100 |\ -+ MTK_PHY_LED_ON_LINK1000) -+#define MTK_PHY_LED_ON_LINKDOWN BIT(3) -+#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */ -+#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */ -+#define MTK_PHY_LED_ON_FORCE_ON BIT(6) -+#define MTK_PHY_LED_ON_POLARITY BIT(14) -+#define MTK_PHY_LED_ON_ENABLE BIT(15) -+ -+#define MTK_PHY_LED0_BLINK_CTRL 0x25 -+#define MTK_PHY_LED1_BLINK_CTRL 0x27 -+#define MTK_PHY_LED_BLINK_1000TX BIT(0) -+#define MTK_PHY_LED_BLINK_1000RX BIT(1) -+#define MTK_PHY_LED_BLINK_100TX BIT(2) -+#define MTK_PHY_LED_BLINK_100RX BIT(3) -+#define MTK_PHY_LED_BLINK_10TX BIT(4) -+#define MTK_PHY_LED_BLINK_10RX BIT(5) -+#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\ -+ MTK_PHY_LED_BLINK_100RX |\ -+ MTK_PHY_LED_BLINK_1000RX) -+#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\ -+ MTK_PHY_LED_BLINK_100TX |\ -+ MTK_PHY_LED_BLINK_1000TX) -+#define MTK_PHY_LED_BLINK_COLLISION BIT(6) -+#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7) -+#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) -+#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9) -+ -+#define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1) -+ -+#define MTK_PHY_RG_BG_RASEL 0x115 -+#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0) -+ -+/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */ -+#define RG_GPIO_MISC_TPBANK0 0x6f0 -+#define RG_GPIO_MISC_TPBANK0_BOOTMODE GENMASK(11, 8) -+ -+/* These macro privides efuse parsing for internal phy. */ -+#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0)) -+#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0)) -+#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 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 -+}; -+ -+#define MTK_PHY_LED_STATE_FORCE_ON 0 -+#define MTK_PHY_LED_STATE_FORCE_BLINK 1 -+#define MTK_PHY_LED_STATE_NETDEV 2 -+ -+struct mtk_socphy_priv { -+ unsigned long led_state; -+}; -+ -+struct mtk_socphy_shared { -+ u32 boottrap; -+ struct mtk_socphy_priv priv[4]; -+}; -+ -+static int mtk_socphy_read_page(struct phy_device *phydev) -+{ -+ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); -+} -+ -+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 = -1; -+ -+ 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); -+ /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ -+ __phy_write(phydev, 0x11, 0xc71); -+ __phy_write(phydev, 0x12, 0xc); -+ __phy_write(phydev, 0x10, 0x8fae); -+ -+ /* EnabRandUpdTrig = 1 */ -+ __phy_write(phydev, 0x11, 0x2f00); -+ __phy_write(phydev, 0x12, 0xe); -+ __phy_write(phydev, 0x10, 0x8fb0); -+ -+ /* NormMseLoThresh = 85 */ -+ __phy_write(phydev, 0x11, 0x55a0); -+ __phy_write(phydev, 0x12, 0x0); -+ __phy_write(phydev, 0x10, 0x83aa); -+ -+ /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ -+ __phy_write(phydev, 0x11, 0x240); -+ __phy_write(phydev, 0x12, 0x0); -+ __phy_write(phydev, 0x10, 0x9680); -+ -+ /* TrFreeze = 0 (mt7988 default) */ -+ __phy_write(phydev, 0x11, 0x0); -+ __phy_write(phydev, 0x12, 0x0); -+ __phy_write(phydev, 0x10, 0x9686); -+ -+ /* SSTrKp100 = 5 */ -+ /* SSTrKf100 = 6 */ -+ /* SSTrKp1000Mas = 5 */ -+ /* SSTrKf1000Mas = 6 */ -+ /* SSTrKp1000Slv = 5 */ -+ /* SSTrKf1000Slv = 6 */ -+ __phy_write(phydev, 0x11, 0xbaef); -+ __phy_write(phydev, 0x12, 0x2e); -+ __phy_write(phydev, 0x10, 0x968c); -+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -+} -+ -+static void mt7981_phy_finetune(struct phy_device *phydev) -+{ -+ u16 val[8] = { 0x01ce, 0x01c1, -+ 0x020f, 0x0202, -+ 0x03d0, 0x03c0, -+ 0x0013, 0x0005 }; -+ int i, k; -+ -+ /* 100M eye finetune: -+ * Keep middle level of TX MLT3 shapper as default. -+ * Only change TX MLT3 overshoot level here. -+ */ -+ for (k = 0, i = 1; i < 12; i++) { -+ if (i % 3 == 0) -+ continue; -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); -+ } -+ -+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -+ /* ResetSyncOffset = 6 */ -+ __phy_write(phydev, 0x11, 0x600); -+ __phy_write(phydev, 0x12, 0x0); -+ __phy_write(phydev, 0x10, 0x8fc0); -+ -+ /* VgaDecRate = 1 */ -+ __phy_write(phydev, 0x11, 0x4c2a); -+ __phy_write(phydev, 0x12, 0x3e); -+ __phy_write(phydev, 0x10, 0x8fa4); -+ -+ /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, -+ * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 -+ */ -+ __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 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); -+ -+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -+ /* ResetSyncOffset = 5 */ -+ __phy_write(phydev, 0x11, 0x500); -+ __phy_write(phydev, 0x12, 0x0); -+ __phy_write(phydev, 0x10, 0x8fc0); -+ -+ /* VgaDecRate is 1 at default on mt7988 */ -+ -+ /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, -+ * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 -+ */ -+ __phy_write(phydev, 0x11, 0xb90a); -+ __phy_write(phydev, 0x12, 0x6f); -+ __phy_write(phydev, 0x10, 0x8f82); -+ -+ /* RemAckCntLimitCtrl = 1 */ -+ __phy_write(phydev, 0x11, 0xfbba); -+ __phy_write(phydev, 0x12, 0xc3); -+ __phy_write(phydev, 0x10, 0x87f8); -+ -+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -+ -+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, -+ MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, -+ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); -+ -+ /* rg_tr_lpf_cnt_val = 1023 */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff); -+} -+ -+static void mt798x_phy_eee(struct phy_device *phydev) -+{ -+ 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)); -+ -+ /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */ -+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, -+ MTK_PHY_LPI_TXPCS_LOC_RCV); -+ -+ /* This also fixes some IoT issues, such as CH340 */ -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, -+ MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, -+ FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | -+ 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 = 2 */ -+ __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 = 0 */ -+ __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 mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index, -+ bool on) -+{ -+ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -+ struct mtk_socphy_priv *priv = phydev->priv; -+ bool changed; -+ -+ if (on) -+ changed = !test_and_set_bit(bit_on, &priv->led_state); -+ else -+ changed = !!test_and_clear_bit(bit_on, &priv->led_state); -+ -+ changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV + -+ (index ? 16 : 0), &priv->led_state); -+ if (changed) -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -+ MTK_PHY_LED_ON_MASK, -+ on ? MTK_PHY_LED_ON_FORCE_ON : 0); -+ else -+ return 0; -+} -+ -+static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, -+ bool blinking) -+{ -+ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); -+ struct mtk_socphy_priv *priv = phydev->priv; -+ bool changed; -+ -+ if (blinking) -+ changed = !test_and_set_bit(bit_blink, &priv->led_state); -+ else -+ changed = !!test_and_clear_bit(bit_blink, &priv->led_state); -+ -+ changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV + -+ (index ? 16 : 0), &priv->led_state); -+ if (changed) -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL, -+ blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0); -+ else -+ return 0; -+} -+ -+static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ bool blinking = false; -+ int err = 0; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { -+ blinking = true; -+ *delay_on = 50; -+ *delay_off = 50; -+ } -+ -+ err = mt798x_phy_hw_led_blink_set(phydev, index, blinking); -+ if (err) -+ return err; -+ -+ return mt798x_phy_hw_led_on_set(phydev, index, false); -+} -+ -+static int mt798x_phy_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ int err; -+ -+ err = mt798x_phy_hw_led_blink_set(phydev, index, false); -+ if (err) -+ return err; -+ -+ return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF)); -+} -+ -+static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) | -+ BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)); -+ -+static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ if (index > 1) -+ return -EINVAL; -+ -+ /* All combinations of the supported triggers are allowed */ -+ if (rules & ~supported_triggers) -+ return -EOPNOTSUPP; -+ -+ return 0; -+}; -+ -+static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); -+ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -+ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -+ struct mtk_socphy_priv *priv = phydev->priv; -+ int on, blink; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ on = phy_read_mmd(phydev, MDIO_MMD_VEND2, -+ index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL); -+ -+ if (on < 0) -+ return -EIO; -+ -+ blink = phy_read_mmd(phydev, MDIO_MMD_VEND2, -+ index ? MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL); -+ if (blink < 0) -+ return -EIO; -+ -+ if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | -+ MTK_PHY_LED_ON_LINKDOWN)) || -+ (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX))) -+ set_bit(bit_netdev, &priv->led_state); -+ else -+ clear_bit(bit_netdev, &priv->led_state); -+ -+ if (on & MTK_PHY_LED_ON_FORCE_ON) -+ set_bit(bit_on, &priv->led_state); -+ else -+ clear_bit(bit_on, &priv->led_state); -+ -+ if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK) -+ set_bit(bit_blink, &priv->led_state); -+ else -+ clear_bit(bit_blink, &priv->led_state); -+ -+ if (!rules) -+ return 0; -+ -+ if (on & MTK_PHY_LED_ON_LINK) -+ *rules |= BIT(TRIGGER_NETDEV_LINK); -+ -+ if (on & MTK_PHY_LED_ON_LINK10) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_10); -+ -+ if (on & MTK_PHY_LED_ON_LINK100) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_100); -+ -+ if (on & MTK_PHY_LED_ON_LINK1000) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_1000); -+ -+ if (on & MTK_PHY_LED_ON_FDX) -+ *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX); -+ -+ if (on & MTK_PHY_LED_ON_HDX) -+ *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX); -+ -+ if (blink & MTK_PHY_LED_BLINK_RX) -+ *rules |= BIT(TRIGGER_NETDEV_RX); -+ -+ if (blink & MTK_PHY_LED_BLINK_TX) -+ *rules |= BIT(TRIGGER_NETDEV_TX); -+ -+ return 0; -+}; -+ -+static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -+ struct mtk_socphy_priv *priv = phydev->priv; -+ u16 on = 0, blink = 0; -+ int ret; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) -+ on |= MTK_PHY_LED_ON_FDX; -+ -+ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) -+ on |= MTK_PHY_LED_ON_HDX; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK10; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK100; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK1000; -+ -+ if (rules & BIT(TRIGGER_NETDEV_RX)) { -+ blink |= (on & MTK_PHY_LED_ON_LINK) ? -+ (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) : -+ MTK_PHY_LED_BLINK_RX; -+ } -+ -+ if (rules & BIT(TRIGGER_NETDEV_TX)) { -+ blink |= (on & MTK_PHY_LED_ON_LINK) ? -+ (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) : -+ MTK_PHY_LED_BLINK_TX; -+ } -+ -+ if (blink || on) -+ set_bit(bit_netdev, &priv->led_state); -+ else -+ clear_bit(bit_netdev, &priv->led_state); -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_ON_CTRL : -+ MTK_PHY_LED0_ON_CTRL, -+ MTK_PHY_LED_ON_FDX | -+ MTK_PHY_LED_ON_HDX | -+ MTK_PHY_LED_ON_LINK, -+ on); -+ -+ if (ret) -+ return ret; -+ -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL, blink); -+}; -+ -+static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num) -+{ -+ struct mtk_socphy_shared *priv = phydev->shared->priv; -+ u32 polarities; -+ -+ if (led_num == 0) -+ polarities = ~(priv->boottrap); -+ else -+ polarities = MTK_PHY_LED1_DEFAULT_POLARITIES; -+ -+ if (polarities & BIT(phydev->mdio.addr)) -+ return true; -+ -+ return false; -+} -+ -+static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev) -+{ -+ struct pinctrl *pinctrl; -+ int index; -+ -+ /* Setup LED polarity according to bootstrap use of LED pins */ -+ for (index = 0; index < 2; ++index) -+ phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -+ MTK_PHY_LED_ON_POLARITY, -+ mt7988_phy_led_get_polarity(phydev, index) ? -+ MTK_PHY_LED_ON_POLARITY : 0); -+ -+ /* Only now setup pinctrl to avoid bogus blinking */ -+ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); -+ if (IS_ERR(pinctrl)) -+ dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n"); -+ -+ return 0; -+} -+ -+static int mt7988_phy_probe_shared(struct phy_device *phydev) -+{ -+ struct device_node *np = dev_of_node(&phydev->mdio.bus->dev); -+ struct mtk_socphy_shared *shared = phydev->shared->priv; -+ struct regmap *regmap; -+ u32 reg; -+ int ret; -+ -+ /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B, -+ * LED_C and LED_D respectively. At the same time those pins are used to -+ * bootstrap configuration of the reference clock source (LED_A), -+ * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D). -+ * In practise this is done using a LED and a resistor pulling the pin -+ * either to GND or to VIO. -+ * The detected value at boot time is accessible at run-time using the -+ * TPBANK0 register located in the gpio base of the pinctrl, in order -+ * to read it here it needs to be referenced by a phandle called -+ * 'mediatek,pio' in the MDIO bus hosting the PHY. -+ * The 4 bits in TPBANK0 are kept as package shared data and are used to -+ * set LED polarity for each of the LED0. -+ */ -+ regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio"); -+ if (IS_ERR(regmap)) -+ return PTR_ERR(regmap); -+ -+ ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, ®); -+ if (ret) -+ return ret; -+ -+ shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg); -+ -+ return 0; -+} -+ -+static void mt798x_phy_leds_state_init(struct phy_device *phydev) -+{ -+ int i; -+ -+ for (i = 0; i < 2; ++i) -+ mt798x_phy_led_hw_control_get(phydev, i, NULL); -+} -+ -+static int mt7988_phy_probe(struct phy_device *phydev) -+{ -+ struct mtk_socphy_shared *shared; -+ struct mtk_socphy_priv *priv; -+ int err; -+ -+ if (phydev->mdio.addr > 3) -+ return -EINVAL; -+ -+ err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0, -+ sizeof(struct mtk_socphy_shared)); -+ if (err) -+ return err; -+ -+ if (phy_package_probe_once(phydev)) { -+ err = mt7988_phy_probe_shared(phydev); -+ if (err) -+ return err; -+ } -+ -+ shared = phydev->shared->priv; -+ priv = &shared->priv[phydev->mdio.addr]; -+ -+ phydev->priv = priv; -+ -+ mt798x_phy_leds_state_init(phydev); -+ -+ err = mt7988_phy_fix_leds_polarities(phydev); -+ if (err) -+ return err; -+ -+ /* Disable TX power saving at probing to: -+ * 1. Meet common mode compliance test criteria -+ * 2. Make sure that TX-VCM calibration works fine -+ */ -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, -+ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); -+ -+ return mt798x_phy_calibration(phydev); -+} -+ -+static int mt7981_phy_probe(struct phy_device *phydev) -+{ -+ struct mtk_socphy_priv *priv; -+ -+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv), -+ GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ phydev->priv = priv; -+ -+ mt798x_phy_leds_state_init(phydev); -+ -+ return mt798x_phy_calibration(phydev); -+} -+ -+static struct phy_driver mtk_socphy_driver[] = { -+ { -+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), -+ .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, -+ .led_blink_set = mt798x_phy_led_blink_set, -+ .led_brightness_set = mt798x_phy_led_brightness_set, -+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported, -+ .led_hw_control_set = mt798x_phy_led_hw_control_set, -+ .led_hw_control_get = mt798x_phy_led_hw_control_get, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988), -+ .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, -+ .led_blink_set = mt798x_phy_led_blink_set, -+ .led_brightness_set = mt798x_phy_led_brightness_set, -+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported, -+ .led_hw_control_set = mt798x_phy_led_hw_control_set, -+ .led_hw_control_get = mt798x_phy_led_hw_control_get, -+ }, -+}; -+ -+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); ---- /dev/null -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -0,0 +1,148 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+#include -+#include -+#include -+#include -+ -+#define MTK_EXT_PAGE_ACCESS 0x1f -+#define MTK_PHY_PAGE_STANDARD 0x0000 -+#define MTK_PHY_PAGE_EXTENDED 0x0001 -+#define MTK_PHY_PAGE_EXTENDED_2 0x0002 -+#define MTK_PHY_PAGE_EXTENDED_3 0x0003 -+#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 -+#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 -+ -+static int mtk_gephy_read_page(struct phy_device *phydev) -+{ -+ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); -+} -+ -+static int mtk_gephy_write_page(struct phy_device *phydev, int page) -+{ -+ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); -+} -+ -+static void mtk_gephy_config_init(struct phy_device *phydev) -+{ -+ /* Disable EEE */ -+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); -+ -+ /* Enable HW auto downshift */ -+ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4)); -+ -+ /* Increase SlvDPSready time */ -+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -+ __phy_write(phydev, 0x10, 0xafae); -+ __phy_write(phydev, 0x12, 0x2f); -+ __phy_write(phydev, 0x10, 0x8fae); -+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -+ -+ /* Adjust 100_mse_threshold */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff); -+ -+ /* Disable mcc */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300); -+} -+ -+static int mt7530_phy_config_init(struct phy_device *phydev) -+{ -+ mtk_gephy_config_init(phydev); -+ -+ /* Increase post_update_timer */ -+ phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b); -+ -+ return 0; -+} -+ -+static int mt7530_led_config_of(struct phy_device *phydev) -+{ -+ struct device_node *np = phydev->mdio.dev.of_node; -+ const __be32 *paddr; -+ int len; -+ int i; -+ -+ paddr = of_get_property(np, "mediatek,led-config", &len); -+ if (!paddr) -+ return 0; -+ -+ if (len < (2 * sizeof(*paddr))) -+ return -EINVAL; -+ -+ len /= sizeof(*paddr); -+ -+ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len); -+ for (i = 0; i < len - 1; i += 2) { -+ u32 reg; -+ u32 val; -+ -+ reg = be32_to_cpup(paddr + i); -+ val = be32_to_cpup(paddr + i + 1); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val); -+ } -+ -+ return 0; -+} -+ -+static int mt7531_phy_config_init(struct phy_device *phydev) -+{ -+ mtk_gephy_config_init(phydev); -+ -+ /* PHY link down power saving enable */ -+ phy_set_bits(phydev, 0x17, BIT(4)); -+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300); -+ -+ /* Set TX Pair delay selection */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404); -+ -+ /* LED Config*/ -+ mt7530_led_config_of(phydev); -+ -+ return 0; -+} -+ -+static struct phy_driver mtk_gephy_driver[] = { -+ { -+ PHY_ID_MATCH_EXACT(0x03a29412), -+ .name = "MediaTek MT7530 PHY", -+ .config_init = mt7530_phy_config_init, -+ /* Interrupts are handled by the switch, not the PHY -+ * itself. -+ */ -+ .config_intr = genphy_no_config_intr, -+ .handle_interrupt = genphy_handle_interrupt_no_ack, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_page = mtk_gephy_read_page, -+ .write_page = mtk_gephy_write_page, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(0x03a29441), -+ .name = "MediaTek MT7531 PHY", -+ .config_init = mt7531_phy_config_init, -+ /* Interrupts are handled by the switch, not the PHY -+ * itself. -+ */ -+ .config_intr = genphy_no_config_intr, -+ .handle_interrupt = genphy_handle_interrupt_no_ack, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_page = mtk_gephy_read_page, -+ .write_page = mtk_gephy_write_page, -+ }, -+}; -+ -+module_phy_driver(mtk_gephy_driver); -+ -+static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = { -+ { PHY_ID_MATCH_EXACT(0x03a29441) }, -+ { PHY_ID_MATCH_EXACT(0x03a29412) }, -+ { } -+}; -+ -+MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver"); -+MODULE_AUTHOR("DENG, Qingfang "); -+MODULE_LICENSE("GPL"); -+ -+MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl); diff --git a/target/linux/mediatek/patches-6.12/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch b/target/linux/mediatek/patches-6.12/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch deleted file mode 100644 index ed68e97dbbe..00000000000 --- a/target/linux/mediatek/patches-6.12/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 61bcabdb69418215ea05bdc48cb88459d757f505 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:06 +0800 -Subject: [PATCH 2/9] net: phy: mediatek: Fix spelling errors and rearrange - variables - -This patch fixes spelling errors which comes from mediatek-ge-soc.c and -rearrange variables with reverse Xmas tree order. - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 19 ++++++++++--------- - 1 file changed, 10 insertions(+), 9 deletions(-) - ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -408,16 +408,17 @@ static int tx_offset_cal_efuse(struct ph - - 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 }; -+ const int vals_9461[16] = { 7, 1, 4, 7, -+ 7, 1, 4, 7, -+ 7, 1, 4, 7, -+ 7, 1, 4, 7 }; -+ int bias[16] = {}; -+ int i; -+ - switch (phydev->drv->phy_id) { - case MTK_GPHY_ID_MT7981: - /* We add some calibration to efuse values -@@ -1069,10 +1070,10 @@ static int start_cal(struct phy_device * - - static int mt798x_phy_calibration(struct phy_device *phydev) - { -+ struct nvmem_cell *cell; - int ret = 0; -- u32 *buf; - size_t len; -- struct nvmem_cell *cell; -+ u32 *buf; - - cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data"); - if (IS_ERR(cell)) { -@@ -1415,7 +1416,7 @@ static int mt7988_phy_probe_shared(struc - * 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 -+ * In practice 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 diff --git a/target/linux/mediatek/patches-6.12/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch b/target/linux/mediatek/patches-6.12/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch deleted file mode 100644 index 61bde761f0e..00000000000 --- a/target/linux/mediatek/patches-6.12/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch +++ /dev/null @@ -1,742 +0,0 @@ -From 16bbd4ecb67ec1899ad8aa1eb1219a6d576cbaaf Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:07 +0800 -Subject: [PATCH 3/9] net: phy: mediatek: Move LED helper functions into mtk - phy lib - -This patch creates mtk-phy-lib.c & mtk-phy.h and integrates mtk-ge-soc.c's -LED helper functions so that we can use those helper functions in other -MTK's ethernet phy driver. - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/mediatek/Kconfig | 5 + - drivers/net/phy/mediatek/Makefile | 1 + - drivers/net/phy/mediatek/mtk-ge-soc.c | 262 +++---------------------- - drivers/net/phy/mediatek/mtk-phy-lib.c | 251 +++++++++++++++++++++++ - drivers/net/phy/mediatek/mtk.h | 82 ++++++++ - 5 files changed, 366 insertions(+), 235 deletions(-) - create mode 100644 drivers/net/phy/mediatek/mtk-phy-lib.c - create mode 100644 drivers/net/phy/mediatek/mtk.h - ---- a/drivers/net/phy/mediatek/Kconfig -+++ b/drivers/net/phy/mediatek/Kconfig -@@ -1,6 +1,10 @@ - # SPDX-License-Identifier: GPL-2.0-only -+config MTK_NET_PHYLIB -+ tristate -+ - config MEDIATEK_GE_PHY - tristate "MediaTek Gigabit Ethernet PHYs" -+ select MTK_NET_PHYLIB - help - Supports the MediaTek non-built-in Gigabit Ethernet PHYs. - -@@ -13,6 +17,7 @@ config MEDIATEK_GE_SOC_PHY - tristate "MediaTek SoC Ethernet PHYs" - depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST - select NVMEM_MTK_EFUSE -+ select MTK_NET_PHYLIB - help - Supports MediaTek SoC built-in Gigabit Ethernet PHYs. - ---- a/drivers/net/phy/mediatek/Makefile -+++ b/drivers/net/phy/mediatek/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o - obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o - obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -8,6 +8,8 @@ - #include - #include - -+#include "mtk.h" -+ - #define MTK_GPHY_ID_MT7981 0x03a29461 - #define MTK_GPHY_ID_MT7988 0x03a29481 - -@@ -210,41 +212,6 @@ - #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_LINK (MTK_PHY_LED_ON_LINK10 |\ -- MTK_PHY_LED_ON_LINK100 |\ -- MTK_PHY_LED_ON_LINK1000) --#define MTK_PHY_LED_ON_LINKDOWN BIT(3) --#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */ --#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */ --#define MTK_PHY_LED_ON_FORCE_ON BIT(6) --#define MTK_PHY_LED_ON_POLARITY BIT(14) --#define MTK_PHY_LED_ON_ENABLE BIT(15) -- --#define MTK_PHY_LED0_BLINK_CTRL 0x25 --#define MTK_PHY_LED1_BLINK_CTRL 0x27 --#define MTK_PHY_LED_BLINK_1000TX BIT(0) --#define MTK_PHY_LED_BLINK_1000RX BIT(1) --#define MTK_PHY_LED_BLINK_100TX BIT(2) --#define MTK_PHY_LED_BLINK_100RX BIT(3) --#define MTK_PHY_LED_BLINK_10TX BIT(4) --#define MTK_PHY_LED_BLINK_10RX BIT(5) --#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\ -- MTK_PHY_LED_BLINK_100RX |\ -- MTK_PHY_LED_BLINK_1000RX) --#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\ -- MTK_PHY_LED_BLINK_100TX |\ -- MTK_PHY_LED_BLINK_1000TX) --#define MTK_PHY_LED_BLINK_COLLISION BIT(6) --#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7) --#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) --#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9) -- - #define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1) - - #define MTK_PHY_RG_BG_RASEL 0x115 -@@ -299,10 +266,6 @@ enum CAL_MODE { - SW_M - }; - --#define MTK_PHY_LED_STATE_FORCE_ON 0 --#define MTK_PHY_LED_STATE_FORCE_BLINK 1 --#define MTK_PHY_LED_STATE_NETDEV 2 -- - struct mtk_socphy_priv { - unsigned long led_state; - }; -@@ -1131,84 +1094,39 @@ static int mt798x_phy_config_init(struct - return mt798x_phy_calibration(phydev); - } - --static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index, -- bool on) --{ -- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- bool changed; -- -- if (on) -- changed = !test_and_set_bit(bit_on, &priv->led_state); -- else -- changed = !!test_and_clear_bit(bit_on, &priv->led_state); -- -- changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV + -- (index ? 16 : 0), &priv->led_state); -- if (changed) -- return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -- MTK_PHY_LED_ON_MASK, -- on ? MTK_PHY_LED_ON_FORCE_ON : 0); -- else -- return 0; --} -- --static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, -- bool blinking) --{ -- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); -- struct mtk_socphy_priv *priv = phydev->priv; -- bool changed; -- -- if (blinking) -- changed = !test_and_set_bit(bit_blink, &priv->led_state); -- else -- changed = !!test_and_clear_bit(bit_blink, &priv->led_state); -- -- changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV + -- (index ? 16 : 0), &priv->led_state); -- if (changed) -- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL, -- blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0); -- else -- return 0; --} -- - static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index, - unsigned long *delay_on, - unsigned long *delay_off) - { -+ struct mtk_socphy_priv *priv = phydev->priv; - bool blinking = false; - int err = 0; - -- if (index > 1) -- return -EINVAL; -- -- if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { -- blinking = true; -- *delay_on = 50; -- *delay_off = 50; -- } -+ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking); -+ if (err < 0) -+ return err; - -- err = mt798x_phy_hw_led_blink_set(phydev, index, blinking); -+ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, -+ blinking); - if (err) - return err; - -- return mt798x_phy_hw_led_on_set(phydev, index, false); -+ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state, -+ MTK_GPHY_LED_ON_MASK, false); - } - - static int mt798x_phy_led_brightness_set(struct phy_device *phydev, - u8 index, enum led_brightness value) - { -+ struct mtk_socphy_priv *priv = phydev->priv; - int err; - -- err = mt798x_phy_hw_led_blink_set(phydev, index, false); -+ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false); - if (err) - return err; - -- return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF)); -+ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state, -+ MTK_GPHY_LED_ON_MASK, (value != LED_OFF)); - } - - static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -@@ -1223,148 +1141,30 @@ static const unsigned long supported_tri - static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules) - { -- if (index > 1) -- return -EINVAL; -- -- /* All combinations of the supported triggers are allowed */ -- if (rules & ~supported_triggers) -- return -EOPNOTSUPP; -- -- return 0; --}; -+ return mtk_phy_led_hw_is_supported(phydev, index, rules, -+ supported_triggers); -+} - - static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index, - unsigned long *rules) - { -- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); -- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); - struct mtk_socphy_priv *priv = phydev->priv; -- int on, blink; -- -- if (index > 1) -- return -EINVAL; -- -- on = phy_read_mmd(phydev, MDIO_MMD_VEND2, -- index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL); -- -- if (on < 0) -- return -EIO; -- -- blink = phy_read_mmd(phydev, MDIO_MMD_VEND2, -- index ? MTK_PHY_LED1_BLINK_CTRL : -- MTK_PHY_LED0_BLINK_CTRL); -- if (blink < 0) -- return -EIO; -- -- if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | -- MTK_PHY_LED_ON_LINKDOWN)) || -- (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX))) -- set_bit(bit_netdev, &priv->led_state); -- else -- clear_bit(bit_netdev, &priv->led_state); -- -- if (on & MTK_PHY_LED_ON_FORCE_ON) -- set_bit(bit_on, &priv->led_state); -- else -- clear_bit(bit_on, &priv->led_state); -- -- if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK) -- set_bit(bit_blink, &priv->led_state); -- else -- clear_bit(bit_blink, &priv->led_state); -- -- if (!rules) -- return 0; -- -- if (on & MTK_PHY_LED_ON_LINK) -- *rules |= BIT(TRIGGER_NETDEV_LINK); - -- if (on & MTK_PHY_LED_ON_LINK10) -- *rules |= BIT(TRIGGER_NETDEV_LINK_10); -- -- if (on & MTK_PHY_LED_ON_LINK100) -- *rules |= BIT(TRIGGER_NETDEV_LINK_100); -- -- if (on & MTK_PHY_LED_ON_LINK1000) -- *rules |= BIT(TRIGGER_NETDEV_LINK_1000); -- -- if (on & MTK_PHY_LED_ON_FDX) -- *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX); -- -- if (on & MTK_PHY_LED_ON_HDX) -- *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX); -- -- if (blink & MTK_PHY_LED_BLINK_RX) -- *rules |= BIT(TRIGGER_NETDEV_RX); -- -- if (blink & MTK_PHY_LED_BLINK_TX) -- *rules |= BIT(TRIGGER_NETDEV_TX); -- -- return 0; -+ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state, -+ MTK_GPHY_LED_ON_SET, -+ MTK_GPHY_LED_RX_BLINK_SET, -+ MTK_GPHY_LED_TX_BLINK_SET); - }; - - static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index, - unsigned long rules) - { -- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); - struct mtk_socphy_priv *priv = phydev->priv; -- u16 on = 0, blink = 0; -- int ret; - -- if (index > 1) -- return -EINVAL; -- -- if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) -- on |= MTK_PHY_LED_ON_FDX; -- -- if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) -- on |= MTK_PHY_LED_ON_HDX; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK10; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK100; -- -- if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) -- on |= MTK_PHY_LED_ON_LINK1000; -- -- if (rules & BIT(TRIGGER_NETDEV_RX)) { -- blink |= (on & MTK_PHY_LED_ON_LINK) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) : -- MTK_PHY_LED_BLINK_RX; -- } -- -- if (rules & BIT(TRIGGER_NETDEV_TX)) { -- blink |= (on & MTK_PHY_LED_ON_LINK) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) : -- MTK_PHY_LED_BLINK_TX; -- } -- -- if (blink || on) -- set_bit(bit_netdev, &priv->led_state); -- else -- clear_bit(bit_netdev, &priv->led_state); -- -- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_ON_CTRL : -- MTK_PHY_LED0_ON_CTRL, -- MTK_PHY_LED_ON_FDX | -- MTK_PHY_LED_ON_HDX | -- MTK_PHY_LED_ON_LINK, -- on); -- -- if (ret) -- return ret; -- -- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -- MTK_PHY_LED1_BLINK_CTRL : -- MTK_PHY_LED0_BLINK_CTRL, blink); -+ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state, -+ MTK_GPHY_LED_ON_SET, -+ MTK_GPHY_LED_RX_BLINK_SET, -+ MTK_GPHY_LED_TX_BLINK_SET); - }; - - static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num) -@@ -1438,14 +1238,6 @@ static int mt7988_phy_probe_shared(struc - return 0; - } - --static void mt798x_phy_leds_state_init(struct phy_device *phydev) --{ -- int i; -- -- for (i = 0; i < 2; ++i) -- mt798x_phy_led_hw_control_get(phydev, i, NULL); --} -- - static int mt7988_phy_probe(struct phy_device *phydev) - { - struct mtk_socphy_shared *shared; -@@ -1471,7 +1263,7 @@ static int mt7988_phy_probe(struct phy_d - - phydev->priv = priv; - -- mt798x_phy_leds_state_init(phydev); -+ mtk_phy_leds_state_init(phydev); - - err = mt7988_phy_fix_leds_polarities(phydev); - if (err) -@@ -1498,7 +1290,7 @@ static int mt7981_phy_probe(struct phy_d - - phydev->priv = priv; - -- mt798x_phy_leds_state_init(phydev); -+ mtk_phy_leds_state_init(phydev); - - return mt798x_phy_calibration(phydev); - } ---- /dev/null -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -0,0 +1,251 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+#include -+ -+#include -+ -+#include "mtk.h" -+ -+int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules, -+ unsigned long supported_triggers) -+{ -+ if (index > 1) -+ return -EINVAL; -+ -+ /* All combinations of the supported triggers are allowed */ -+ if (rules & ~supported_triggers) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_is_supported); -+ -+int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules, unsigned long *led_state, -+ u16 on_set, u16 rx_blink_set, u16 tx_blink_set) -+{ -+ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + -+ (index ? 16 : 0); -+ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -+ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -+ int on, blink; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ on = phy_read_mmd(phydev, MDIO_MMD_VEND2, -+ index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL); -+ -+ if (on < 0) -+ return -EIO; -+ -+ blink = phy_read_mmd(phydev, MDIO_MMD_VEND2, -+ index ? MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL); -+ if (blink < 0) -+ return -EIO; -+ -+ if ((on & (on_set | MTK_PHY_LED_ON_FDX | -+ MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) || -+ (blink & (rx_blink_set | tx_blink_set))) -+ set_bit(bit_netdev, led_state); -+ else -+ clear_bit(bit_netdev, led_state); -+ -+ if (on & MTK_PHY_LED_ON_FORCE_ON) -+ set_bit(bit_on, led_state); -+ else -+ clear_bit(bit_on, led_state); -+ -+ if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK) -+ set_bit(bit_blink, led_state); -+ else -+ clear_bit(bit_blink, led_state); -+ -+ if (!rules) -+ return 0; -+ -+ if (on & on_set) -+ *rules |= BIT(TRIGGER_NETDEV_LINK); -+ -+ if (on & MTK_PHY_LED_ON_LINK10) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_10); -+ -+ if (on & MTK_PHY_LED_ON_LINK100) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_100); -+ -+ if (on & MTK_PHY_LED_ON_LINK1000) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_1000); -+ -+ if (on & MTK_PHY_LED_ON_LINK2500) -+ *rules |= BIT(TRIGGER_NETDEV_LINK_2500); -+ -+ if (on & MTK_PHY_LED_ON_FDX) -+ *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX); -+ -+ if (on & MTK_PHY_LED_ON_HDX) -+ *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX); -+ -+ if (blink & rx_blink_set) -+ *rules |= BIT(TRIGGER_NETDEV_RX); -+ -+ if (blink & tx_blink_set) -+ *rules |= BIT(TRIGGER_NETDEV_TX); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_get); -+ -+int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index, -+ unsigned long rules, unsigned long *led_state, -+ u16 on_set, u16 rx_blink_set, u16 tx_blink_set) -+{ -+ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); -+ u16 on = 0, blink = 0; -+ int ret; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) -+ on |= MTK_PHY_LED_ON_FDX; -+ -+ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) -+ on |= MTK_PHY_LED_ON_HDX; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK10; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK100; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK1000; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= MTK_PHY_LED_ON_LINK2500; -+ -+ if (rules & BIT(TRIGGER_NETDEV_RX)) { -+ blink |= (on & on_set) ? -+ (((on & MTK_PHY_LED_ON_LINK10) ? -+ MTK_PHY_LED_BLINK_10RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK100) ? -+ MTK_PHY_LED_BLINK_100RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK1000) ? -+ MTK_PHY_LED_BLINK_1000RX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK2500) ? -+ MTK_PHY_LED_BLINK_2500RX : 0)) : -+ rx_blink_set; -+ } -+ -+ if (rules & BIT(TRIGGER_NETDEV_TX)) { -+ blink |= (on & on_set) ? -+ (((on & MTK_PHY_LED_ON_LINK10) ? -+ MTK_PHY_LED_BLINK_10TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK100) ? -+ MTK_PHY_LED_BLINK_100TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK1000) ? -+ MTK_PHY_LED_BLINK_1000TX : 0) | -+ ((on & MTK_PHY_LED_ON_LINK2500) ? -+ MTK_PHY_LED_BLINK_2500TX : 0)) : -+ tx_blink_set; -+ } -+ -+ if (blink || on) -+ set_bit(bit_netdev, led_state); -+ else -+ clear_bit(bit_netdev, led_state); -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, -+ MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | on_set, -+ on); -+ -+ if (ret) -+ return ret; -+ -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL, blink); -+} -+EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_set); -+ -+int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on, -+ unsigned long *delay_off, bool *blinking) -+{ -+ if (index > 1) -+ return -EINVAL; -+ -+ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { -+ *blinking = true; -+ *delay_on = 50; -+ *delay_off = 50; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_led_num_dly_cfg); -+ -+int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index, -+ unsigned long *led_state, u16 led_on_mask, bool on) -+{ -+ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); -+ bool changed; -+ -+ if (on) -+ changed = !test_and_set_bit(bit_on, led_state); -+ else -+ changed = !!test_and_clear_bit(bit_on, led_state); -+ -+ changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV + -+ (index ? 16 : 0), led_state); -+ if (changed) -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_ON_CTRL : -+ MTK_PHY_LED0_ON_CTRL, -+ led_on_mask, -+ on ? MTK_PHY_LED_ON_FORCE_ON : 0); -+ else -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_hw_led_on_set); -+ -+int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *led_state, bool blinking) -+{ -+ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + -+ (index ? 16 : 0); -+ bool changed; -+ -+ if (blinking) -+ changed = !test_and_set_bit(bit_blink, led_state); -+ else -+ changed = !!test_and_clear_bit(bit_blink, led_state); -+ -+ changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV + -+ (index ? 16 : 0), led_state); -+ if (changed) -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? -+ MTK_PHY_LED1_BLINK_CTRL : -+ MTK_PHY_LED0_BLINK_CTRL, -+ blinking ? -+ MTK_PHY_LED_BLINK_FORCE_BLINK : 0); -+ else -+ return 0; -+} -+EXPORT_SYMBOL_GPL(mtk_phy_hw_led_blink_set); -+ -+void mtk_phy_leds_state_init(struct phy_device *phydev) -+{ -+ int i; -+ -+ for (i = 0; i < 2; ++i) -+ phydev->drv->led_hw_control_get(phydev, i, NULL); -+} -+EXPORT_SYMBOL_GPL(mtk_phy_leds_state_init); -+ -+MODULE_DESCRIPTION("MediaTek Ethernet PHY driver common"); -+MODULE_AUTHOR("Sky Huang "); -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -0,0 +1,82 @@ -+/* SPDX-License-Identifier: GPL-2.0 -+ * -+ * Common definition for Mediatek Ethernet PHYs -+ * Author: SkyLake Huang -+ * Copyright (c) 2024 MediaTek Inc. -+ */ -+ -+#ifndef _MTK_EPHY_H_ -+#define _MTK_EPHY_H_ -+ -+#define MTK_EXT_PAGE_ACCESS 0x1f -+ -+/* Registers on MDIO_MMD_VEND2 */ -+#define MTK_PHY_LED0_ON_CTRL 0x24 -+#define MTK_PHY_LED1_ON_CTRL 0x26 -+#define MTK_GPHY_LED_ON_MASK GENMASK(6, 0) -+#define MTK_2P5GPHY_LED_ON_MASK GENMASK(7, 0) -+#define MTK_PHY_LED_ON_LINK1000 BIT(0) -+#define MTK_PHY_LED_ON_LINK100 BIT(1) -+#define MTK_PHY_LED_ON_LINK10 BIT(2) -+#define MTK_PHY_LED_ON_LINKDOWN BIT(3) -+#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */ -+#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */ -+#define MTK_PHY_LED_ON_FORCE_ON BIT(6) -+#define MTK_PHY_LED_ON_LINK2500 BIT(7) -+#define MTK_PHY_LED_ON_POLARITY BIT(14) -+#define MTK_PHY_LED_ON_ENABLE BIT(15) -+ -+#define MTK_PHY_LED0_BLINK_CTRL 0x25 -+#define MTK_PHY_LED1_BLINK_CTRL 0x27 -+#define MTK_PHY_LED_BLINK_1000TX BIT(0) -+#define MTK_PHY_LED_BLINK_1000RX BIT(1) -+#define MTK_PHY_LED_BLINK_100TX BIT(2) -+#define MTK_PHY_LED_BLINK_100RX BIT(3) -+#define MTK_PHY_LED_BLINK_10TX BIT(4) -+#define MTK_PHY_LED_BLINK_10RX BIT(5) -+#define MTK_PHY_LED_BLINK_COLLISION BIT(6) -+#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7) -+#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) -+#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9) -+#define MTK_PHY_LED_BLINK_2500TX BIT(10) -+#define MTK_PHY_LED_BLINK_2500RX BIT(11) -+ -+#define MTK_GPHY_LED_ON_SET (MTK_PHY_LED_ON_LINK1000 | \ -+ MTK_PHY_LED_ON_LINK100 | \ -+ MTK_PHY_LED_ON_LINK10) -+#define MTK_GPHY_LED_RX_BLINK_SET (MTK_PHY_LED_BLINK_1000RX | \ -+ MTK_PHY_LED_BLINK_100RX | \ -+ MTK_PHY_LED_BLINK_10RX) -+#define MTK_GPHY_LED_TX_BLINK_SET (MTK_PHY_LED_BLINK_1000RX | \ -+ MTK_PHY_LED_BLINK_100RX | \ -+ MTK_PHY_LED_BLINK_10RX) -+ -+#define MTK_2P5GPHY_LED_ON_SET (MTK_PHY_LED_ON_LINK2500 | \ -+ MTK_GPHY_LED_ON_SET) -+#define MTK_2P5GPHY_LED_RX_BLINK_SET (MTK_PHY_LED_BLINK_2500RX | \ -+ MTK_GPHY_LED_RX_BLINK_SET) -+#define MTK_2P5GPHY_LED_TX_BLINK_SET (MTK_PHY_LED_BLINK_2500RX | \ -+ MTK_GPHY_LED_TX_BLINK_SET) -+ -+#define MTK_PHY_LED_STATE_FORCE_ON 0 -+#define MTK_PHY_LED_STATE_FORCE_BLINK 1 -+#define MTK_PHY_LED_STATE_NETDEV 2 -+ -+int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules, -+ unsigned long supported_triggers); -+int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index, -+ unsigned long rules, unsigned long *led_state, -+ u16 on_set, u16 rx_blink_set, u16 tx_blink_set); -+int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules, unsigned long *led_state, -+ u16 on_set, u16 rx_blink_set, u16 tx_blink_set); -+int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on, -+ unsigned long *delay_off, bool *blinking); -+int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index, -+ unsigned long *led_state, u16 led_on_mask, bool on); -+int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *led_state, bool blinking); -+void mtk_phy_leds_state_init(struct phy_device *phydev); -+ -+#endif /* _MTK_EPHY_H_ */ diff --git a/target/linux/mediatek/patches-6.12/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch b/target/linux/mediatek/patches-6.12/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch deleted file mode 100644 index 78413d28ead..00000000000 --- a/target/linux/mediatek/patches-6.12/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch +++ /dev/null @@ -1,70 +0,0 @@ -From 2b118202583eb05a1799d435d2dce974dc3f5b16 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:08 +0800 -Subject: [PATCH 4/9] net: phy: mediatek: Improve readability of - mtk-phy-lib.c's mtk_phy_led_hw_ctrl_set() - -This patch removes parens around TRIGGER_NETDEV_RX/TRIGGER_NETDEV_TX in -mtk_phy_led_hw_ctrl_set(), which improves readability. - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/mediatek/mtk-phy-lib.c | 44 ++++++++++++++------------ - 1 file changed, 24 insertions(+), 20 deletions(-) - ---- a/drivers/net/phy/mediatek/mtk-phy-lib.c -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -127,29 +127,33 @@ int mtk_phy_led_hw_ctrl_set(struct phy_d - on |= MTK_PHY_LED_ON_LINK2500; - - if (rules & BIT(TRIGGER_NETDEV_RX)) { -- blink |= (on & on_set) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? -- MTK_PHY_LED_BLINK_10RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? -- MTK_PHY_LED_BLINK_100RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? -- MTK_PHY_LED_BLINK_1000RX : 0) | -- ((on & MTK_PHY_LED_ON_LINK2500) ? -- MTK_PHY_LED_BLINK_2500RX : 0)) : -- rx_blink_set; -+ if (on & on_set) { -+ if (on & MTK_PHY_LED_ON_LINK10) -+ blink |= MTK_PHY_LED_BLINK_10RX; -+ if (on & MTK_PHY_LED_ON_LINK100) -+ blink |= MTK_PHY_LED_BLINK_100RX; -+ if (on & MTK_PHY_LED_ON_LINK1000) -+ blink |= MTK_PHY_LED_BLINK_1000RX; -+ if (on & MTK_PHY_LED_ON_LINK2500) -+ blink |= MTK_PHY_LED_BLINK_2500RX; -+ } else { -+ blink |= rx_blink_set; -+ } - } - - if (rules & BIT(TRIGGER_NETDEV_TX)) { -- blink |= (on & on_set) ? -- (((on & MTK_PHY_LED_ON_LINK10) ? -- MTK_PHY_LED_BLINK_10TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK100) ? -- MTK_PHY_LED_BLINK_100TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK1000) ? -- MTK_PHY_LED_BLINK_1000TX : 0) | -- ((on & MTK_PHY_LED_ON_LINK2500) ? -- MTK_PHY_LED_BLINK_2500TX : 0)) : -- tx_blink_set; -+ if (on & on_set) { -+ if (on & MTK_PHY_LED_ON_LINK10) -+ blink |= MTK_PHY_LED_BLINK_10TX; -+ if (on & MTK_PHY_LED_ON_LINK100) -+ blink |= MTK_PHY_LED_BLINK_100TX; -+ if (on & MTK_PHY_LED_ON_LINK1000) -+ blink |= MTK_PHY_LED_BLINK_1000TX; -+ if (on & MTK_PHY_LED_ON_LINK2500) -+ blink |= MTK_PHY_LED_BLINK_2500TX; -+ } else { -+ blink |= tx_blink_set; -+ } - } - - if (blink || on) diff --git a/target/linux/mediatek/patches-6.12/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch b/target/linux/mediatek/patches-6.12/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch deleted file mode 100644 index 9dd9f7d99da..00000000000 --- a/target/linux/mediatek/patches-6.12/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 59e7082cb8c8e89bceb44cc60df156d818c8da96 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:09 +0800 -Subject: [PATCH 5/9] net: phy: mediatek: Integrate read/write page helper - functions - -This patch integrates read/write page helper functions as MTK phy lib. -They are basically the same in mtk-ge.c & mtk-ge-soc.c. - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 18 ++++-------------- - drivers/net/phy/mediatek/mtk-ge.c | 20 ++++++-------------- - drivers/net/phy/mediatek/mtk-phy-lib.c | 12 ++++++++++++ - drivers/net/phy/mediatek/mtk.h | 3 +++ - 4 files changed, 25 insertions(+), 28 deletions(-) - ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -275,16 +275,6 @@ struct mtk_socphy_shared { - struct mtk_socphy_priv priv[4]; - }; - --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. -@@ -1305,8 +1295,8 @@ static struct phy_driver mtk_socphy_driv - .probe = mt7981_phy_probe, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .read_page = mtk_socphy_read_page, -- .write_page = mtk_socphy_write_page, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, - .led_blink_set = mt798x_phy_led_blink_set, - .led_brightness_set = mt798x_phy_led_brightness_set, - .led_hw_is_supported = mt798x_phy_led_hw_is_supported, -@@ -1322,8 +1312,8 @@ static struct phy_driver mtk_socphy_driv - .probe = mt7988_phy_probe, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .read_page = mtk_socphy_read_page, -- .write_page = mtk_socphy_write_page, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, - .led_blink_set = mt798x_phy_led_blink_set, - .led_brightness_set = mt798x_phy_led_brightness_set, - .led_hw_is_supported = mt798x_phy_led_hw_is_supported, ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -4,6 +4,8 @@ - #include - #include - -+#include "mtk.h" -+ - #define MTK_EXT_PAGE_ACCESS 0x1f - #define MTK_PHY_PAGE_STANDARD 0x0000 - #define MTK_PHY_PAGE_EXTENDED 0x0001 -@@ -12,16 +14,6 @@ - #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 - #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 - --static int mtk_gephy_read_page(struct phy_device *phydev) --{ -- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); --} -- --static int mtk_gephy_write_page(struct phy_device *phydev, int page) --{ -- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); --} -- - static void mtk_gephy_config_init(struct phy_device *phydev) - { - /* Disable EEE */ -@@ -114,8 +106,8 @@ static struct phy_driver mtk_gephy_drive - .handle_interrupt = genphy_handle_interrupt_no_ack, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .read_page = mtk_gephy_read_page, -- .write_page = mtk_gephy_write_page, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, - }, - { - PHY_ID_MATCH_EXACT(0x03a29441), -@@ -128,8 +120,8 @@ static struct phy_driver mtk_gephy_drive - .handle_interrupt = genphy_handle_interrupt_no_ack, - .suspend = genphy_suspend, - .resume = genphy_resume, -- .read_page = mtk_gephy_read_page, -- .write_page = mtk_gephy_write_page, -+ .read_page = mtk_phy_read_page, -+ .write_page = mtk_phy_write_page, - }, - }; - ---- a/drivers/net/phy/mediatek/mtk-phy-lib.c -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -6,6 +6,18 @@ - - #include "mtk.h" - -+int mtk_phy_read_page(struct phy_device *phydev) -+{ -+ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); -+} -+EXPORT_SYMBOL_GPL(mtk_phy_read_page); -+ -+int mtk_phy_write_page(struct phy_device *phydev, int page) -+{ -+ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); -+} -+EXPORT_SYMBOL_GPL(mtk_phy_write_page); -+ - int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules, - unsigned long supported_triggers) ---- a/drivers/net/phy/mediatek/mtk.h -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -62,6 +62,9 @@ - #define MTK_PHY_LED_STATE_FORCE_BLINK 1 - #define MTK_PHY_LED_STATE_NETDEV 2 - -+int mtk_phy_read_page(struct phy_device *phydev); -+int mtk_phy_write_page(struct phy_device *phydev, int page); -+ - int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules, - unsigned long supported_triggers); diff --git a/target/linux/mediatek/patches-6.12/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch b/target/linux/mediatek/patches-6.12/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch deleted file mode 100644 index 9f6dac9431b..00000000000 --- a/target/linux/mediatek/patches-6.12/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 5b605457b93d0979ab623ef2aa6eb456c46e511c Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:10 +0800 -Subject: [PATCH 6/9] net: phy: mediatek: Hook LED helper functions in mtk-ge.c - -We have mtk-phy-lib.c now so that we can use LED helper functions in -mtk-ge.c(mt7531 part). It also means that mt7531/mt7981/mt7988's -Giga ethernet phys share almost the same HW LED controller design. -Also, add probe function for mt7531 so that it can initialize LED state. - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/mediatek/mtk-ge.c | 100 ++++++++++++++++++++++++++++++ - 1 file changed, 100 insertions(+) - ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -14,6 +14,10 @@ - #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 - #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 - -+struct mtk_gephy_priv { -+ unsigned long led_state; -+}; -+ - static void mtk_gephy_config_init(struct phy_device *phydev) - { - /* Disable EEE */ -@@ -94,6 +98,96 @@ static int mt7531_phy_config_init(struct - return 0; - } - -+static int mt7531_phy_probe(struct phy_device *phydev) -+{ -+ struct mtk_gephy_priv *priv; -+ -+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_gephy_priv), -+ GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ phydev->priv = priv; -+ -+ mtk_phy_leds_state_init(phydev); -+ -+ return 0; -+} -+ -+static int mt753x_phy_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct mtk_gephy_priv *priv = phydev->priv; -+ bool blinking = false; -+ int err = 0; -+ -+ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking); -+ if (err < 0) -+ return err; -+ -+ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, -+ blinking); -+ if (err) -+ return err; -+ -+ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state, -+ MTK_GPHY_LED_ON_MASK, false); -+} -+ -+static int mt753x_phy_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ struct mtk_gephy_priv *priv = phydev->priv; -+ int err; -+ -+ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false); -+ if (err) -+ return err; -+ -+ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state, -+ MTK_GPHY_LED_ON_MASK, (value != LED_OFF)); -+} -+ -+static const unsigned long supported_triggers = -+ BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) | -+ BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX); -+ -+static int mt753x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ return mtk_phy_led_hw_is_supported(phydev, index, rules, -+ supported_triggers); -+} -+ -+static int mt753x_phy_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ struct mtk_gephy_priv *priv = phydev->priv; -+ -+ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state, -+ MTK_GPHY_LED_ON_SET, -+ MTK_GPHY_LED_RX_BLINK_SET, -+ MTK_GPHY_LED_TX_BLINK_SET); -+}; -+ -+static int mt753x_phy_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ struct mtk_gephy_priv *priv = phydev->priv; -+ -+ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state, -+ MTK_GPHY_LED_ON_SET, -+ MTK_GPHY_LED_RX_BLINK_SET, -+ MTK_GPHY_LED_TX_BLINK_SET); -+}; -+ - static struct phy_driver mtk_gephy_driver[] = { - { - PHY_ID_MATCH_EXACT(0x03a29412), -@@ -112,6 +206,7 @@ static struct phy_driver mtk_gephy_drive - { - PHY_ID_MATCH_EXACT(0x03a29441), - .name = "MediaTek MT7531 PHY", -+ .probe = mt7531_phy_probe, - .config_init = mt7531_phy_config_init, - /* Interrupts are handled by the switch, not the PHY - * itself. -@@ -122,6 +217,11 @@ static struct phy_driver mtk_gephy_drive - .resume = genphy_resume, - .read_page = mtk_phy_read_page, - .write_page = mtk_phy_write_page, -+ .led_blink_set = mt753x_phy_led_blink_set, -+ .led_brightness_set = mt753x_phy_led_brightness_set, -+ .led_hw_is_supported = mt753x_phy_led_hw_is_supported, -+ .led_hw_control_set = mt753x_phy_led_hw_control_set, -+ .led_hw_control_get = mt753x_phy_led_hw_control_get, - }, - }; - diff --git a/target/linux/mediatek/patches-6.12/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch b/target/linux/mediatek/patches-6.12/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch deleted file mode 100644 index 7ea81612e3c..00000000000 --- a/target/linux/mediatek/patches-6.12/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch +++ /dev/null @@ -1,54 +0,0 @@ -From c5ff7bece642dbba601be89e70f78ff037ca084f Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:11 +0800 -Subject: [PATCH 7/9] net: phy: mediatek: add MT7530 & MT7531's PHY ID macros - -This patch adds MT7530 & MT7531's PHY ID macros in mtk-ge.c so that -it follows the same rule of mtk-ge-soc.c. - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/mediatek/mtk-ge.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -6,6 +6,9 @@ - - #include "mtk.h" - -+#define MTK_GPHY_ID_MT7530 0x03a29412 -+#define MTK_GPHY_ID_MT7531 0x03a29441 -+ - #define MTK_EXT_PAGE_ACCESS 0x1f - #define MTK_PHY_PAGE_STANDARD 0x0000 - #define MTK_PHY_PAGE_EXTENDED 0x0001 -@@ -190,7 +193,7 @@ static int mt753x_phy_led_hw_control_set - - static struct phy_driver mtk_gephy_driver[] = { - { -- PHY_ID_MATCH_EXACT(0x03a29412), -+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530), - .name = "MediaTek MT7530 PHY", - .config_init = mt7530_phy_config_init, - /* Interrupts are handled by the switch, not the PHY -@@ -204,7 +207,7 @@ static struct phy_driver mtk_gephy_drive - .write_page = mtk_phy_write_page, - }, - { -- PHY_ID_MATCH_EXACT(0x03a29441), -+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531), - .name = "MediaTek MT7531 PHY", - .probe = mt7531_phy_probe, - .config_init = mt7531_phy_config_init, -@@ -228,8 +231,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_EXACT(0x03a29441) }, -- { PHY_ID_MATCH_EXACT(0x03a29412) }, -+ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530) }, -+ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531) }, - { } - }; - diff --git a/target/linux/mediatek/patches-6.12/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch b/target/linux/mediatek/patches-6.12/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch deleted file mode 100644 index 8cb2b549e5b..00000000000 --- a/target/linux/mediatek/patches-6.12/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch +++ /dev/null @@ -1,182 +0,0 @@ -From dbe70a9353b5095a90af61a051486484765ada6f Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:12 +0800 -Subject: [PATCH 8/9] net: phy: mediatek: Change mtk-ge-soc.c line wrapping - -This patch shrinks mtk-ge-soc.c line wrapping to 80 characters. - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 67 +++++++++++++++++---------- - 1 file changed, 42 insertions(+), 25 deletions(-) - ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -295,7 +295,8 @@ static int cal_cycle(struct phy_device * - 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); -+ ANALOG_INTERNAL_OPERATION_MAX_US, -+ false); - if (ret) { - phydev_err(phydev, "Calibration cycle timeout\n"); - return ret; -@@ -304,7 +305,7 @@ static int cal_cycle(struct phy_device * - 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; -+ MTK_PHY_AD_CAL_COMP_OUT_SHIFT; - phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret); - - return ret; -@@ -394,38 +395,46 @@ static int tx_amp_fill_result(struct phy - } - - 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); -+ 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); -+ 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); -+ 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); -+ 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); -+ 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); -+ 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); -+ 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); -+ 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]); - -@@ -616,7 +625,8 @@ static int tx_vcm_cal_sw(struct phy_devi - 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. -+ * lower index. If this calibration is valid, apply lower index's -+ * result. - */ - ret = upper_ret - lower_ret; - if (ret == 1) { -@@ -645,7 +655,8 @@ static int tx_vcm_cal_sw(struct phy_devi - } 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", -+ phydev_warn(phydev, -+ "TX-VCM SW cal result at high margin 0x%x\n", - upper_idx); - } else { - ret = -EINVAL; -@@ -749,7 +760,8 @@ static void mt7981_phy_finetune(struct p - - /* 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, -+ 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 */ -@@ -818,7 +830,8 @@ static void mt7988_phy_finetune(struct p - - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, -- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, -+ MTK_PHY_TR_OPEN_LOOP_EN_MASK | -+ MTK_PHY_LPF_X_AVERAGE_MASK, - BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); - - /* rg_tr_lpf_cnt_val = 1023 */ -@@ -930,7 +943,8 @@ static void mt798x_phy_eee(struct phy_de - 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, -+ __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, -@@ -940,7 +954,8 @@ static void mt798x_phy_eee(struct phy_de - 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)); -+ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, -+ 0xff)); - } - - static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item, -@@ -1119,14 +1134,15 @@ static int mt798x_phy_led_brightness_set - MTK_GPHY_LED_ON_MASK, (value != LED_OFF)); - } - --static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -- BIT(TRIGGER_NETDEV_HALF_DUPLEX) | -- BIT(TRIGGER_NETDEV_LINK) | -- BIT(TRIGGER_NETDEV_LINK_10) | -- BIT(TRIGGER_NETDEV_LINK_100) | -- BIT(TRIGGER_NETDEV_LINK_1000) | -- BIT(TRIGGER_NETDEV_RX) | -- BIT(TRIGGER_NETDEV_TX)); -+static const unsigned long supported_triggers = -+ (BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -+ BIT(TRIGGER_NETDEV_HALF_DUPLEX) | -+ BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)); - - static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, - unsigned long rules) -@@ -1189,7 +1205,8 @@ static int mt7988_phy_fix_leds_polaritie - /* Only now setup pinctrl to avoid bogus blinking */ - pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); - if (IS_ERR(pinctrl)) -- dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n"); -+ dev_err(&phydev->mdio.bus->dev, -+ "Failed to setup PHY LED pinctrl\n"); - - return 0; - } diff --git a/target/linux/mediatek/patches-6.12/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch b/target/linux/mediatek/patches-6.12/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch deleted file mode 100644 index 62c063462b9..00000000000 --- a/target/linux/mediatek/patches-6.12/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch +++ /dev/null @@ -1,614 +0,0 @@ -From ca024bc7267a8c0439325d352f9b8818ba0f2cf0 Mon Sep 17 00:00:00 2001 -From: "SkyLake.Huang" -Date: Fri, 4 Oct 2024 18:24:13 +0800 -Subject: [PATCH 9/9] net: phy: mediatek: Add token ring access helper - functions in mtk-phy-lib - -This patch adds TR(token ring) manipulations and adds correct -macro names for those magic numbers. TR is a way to access -proprietary registers on page 52b5. Use these helper functions -so we can see which fields we're going to modify/set/clear. - -This patch doesn't really change registers' settings but just -enhances readability and maintainability. - -Signed-off-by: SkyLake.Huang ---- - drivers/net/phy/mediatek/mtk-ge-soc.c | 297 ++++++++++++++++--------- - drivers/net/phy/mediatek/mtk-ge.c | 82 +++++-- - drivers/net/phy/mediatek/mtk-phy-lib.c | 91 ++++++++ - drivers/net/phy/mediatek/mtk.h | 13 ++ - 4 files changed, 358 insertions(+), 125 deletions(-) - ---- a/drivers/net/phy/mediatek/mtk-ge-soc.c -+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c -@@ -24,7 +24,108 @@ - #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 -+ -+/* Registers on Token Ring debug nodes */ -+/* ch_addr = 0x0, node_addr = 0x7, data_addr = 0x15 */ -+/* NormMseLoThresh */ -+#define NORMAL_MSE_LO_THRESH_MASK GENMASK(15, 8) -+ -+/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */ -+/* RemAckCntLimitCtrl */ -+#define REMOTE_ACK_COUNT_LIMIT_CTRL_MASK GENMASK(2, 1) -+ -+/* ch_addr = 0x1, node_addr = 0xd, data_addr = 0x20 */ -+/* VcoSlicerThreshBitsHigh */ -+#define VCO_SLICER_THRESH_HIGH_MASK GENMASK(23, 0) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x0 */ -+/* DfeTailEnableVgaThresh1000 */ -+#define DFE_TAIL_EANBLE_VGA_TRHESH_1000 GENMASK(5, 1) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x1 */ -+/* MrvlTrFix100Kp */ -+#define MRVL_TR_FIX_100KP_MASK GENMASK(22, 20) -+/* MrvlTrFix100Kf */ -+#define MRVL_TR_FIX_100KF_MASK GENMASK(19, 17) -+/* MrvlTrFix1000Kp */ -+#define MRVL_TR_FIX_1000KP_MASK GENMASK(16, 14) -+/* MrvlTrFix1000Kf */ -+#define MRVL_TR_FIX_1000KF_MASK GENMASK(13, 11) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x12 */ -+/* VgaDecRate */ -+#define VGA_DECIMATION_RATE_MASK GENMASK(8, 5) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */ -+/* SlvDSPreadyTime */ -+#define SLAVE_DSP_READY_TIME_MASK GENMASK(22, 15) -+/* MasDSPreadyTime */ -+#define MASTER_DSP_READY_TIME_MASK GENMASK(14, 7) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x18 */ -+/* EnabRandUpdTrig */ -+#define ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER BIT(8) -+ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x20 */ -+/* ResetSyncOffset */ -+#define RESET_SYNC_OFFSET_MASK GENMASK(11, 8) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x0 */ -+/* FfeUpdGainForceVal */ -+#define FFE_UPDATE_GAIN_FORCE_VAL_MASK GENMASK(9, 7) -+/* FfeUpdGainForce */ -+#define FFE_UPDATE_GAIN_FORCE BIT(6) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x3 */ -+/* TrFreeze */ -+#define TR_FREEZE_MASK GENMASK(11, 0) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x6 */ -+/* SS: Steady-state, KP: Proportional Gain */ -+/* SSTrKp100 */ -+#define SS_TR_KP100_MASK GENMASK(21, 19) -+/* SSTrKf100 */ -+#define SS_TR_KF100_MASK GENMASK(18, 16) -+/* SSTrKp1000Mas */ -+#define SS_TR_KP1000_MASTER_MASK GENMASK(15, 13) -+/* SSTrKf1000Mas */ -+#define SS_TR_KF1000_MASTER_MASK GENMASK(12, 10) -+/* SSTrKp1000Slv */ -+#define SS_TR_KP1000_SLAVE_MASK GENMASK(9, 7) -+/* SSTrKf1000Slv */ -+#define SS_TR_KF1000_SLAVE_MASK GENMASK(6, 4) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x8 */ -+/* clear this bit if wanna select from AFE */ -+/* Regsigdet_sel_1000 */ -+#define EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE BIT(4) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xd */ -+/* RegEEE_st2TrKf1000 */ -+#define EEE1000_STAGE2_TR_KF_MASK GENMASK(13, 11) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xf */ -+/* RegEEE_slv_waketr_timer_tar */ -+#define SLAVE_WAKETR_TIMER_MASK GENMASK(20, 11) -+/* RegEEE_slv_remtx_timer_tar */ -+#define SLAVE_REMTX_TIMER_MASK GENMASK(10, 1) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x10 */ -+/* RegEEE_slv_wake_int_timer_tar */ -+#define SLAVE_WAKEINT_TIMER_MASK GENMASK(10, 1) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x14 */ -+/* RegEEE_trfreeze_timer2 */ -+#define TR_FREEZE_TIMER2_MASK GENMASK(9, 0) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x1c */ -+/* RegEEE100Stg1_tar */ -+#define EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK GENMASK(8, 0) -+ -+/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x25 */ -+/* REGEEE_wake_slv_tr_wait_dfesigdet_en */ -+#define WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN BIT(11) -+ - - #define ANALOG_INTERNAL_OPERATION_MAX_US 20 - #define TXRESERVE_MIN 0 -@@ -679,40 +780,36 @@ restore: - static void mt798x_phy_common_finetune(struct phy_device *phydev) - { - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ -- __phy_write(phydev, 0x11, 0xc71); -- __phy_write(phydev, 0x12, 0xc); -- __phy_write(phydev, 0x10, 0x8fae); -- -- /* EnabRandUpdTrig = 1 */ -- __phy_write(phydev, 0x11, 0x2f00); -- __phy_write(phydev, 0x12, 0xe); -- __phy_write(phydev, 0x10, 0x8fb0); -- -- /* NormMseLoThresh = 85 */ -- __phy_write(phydev, 0x11, 0x55a0); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x83aa); -- -- /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ -- __phy_write(phydev, 0x11, 0x240); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x9680); -- -- /* TrFreeze = 0 (mt7988 default) */ -- __phy_write(phydev, 0x11, 0x0); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x9686); -- -- /* SSTrKp100 = 5 */ -- /* SSTrKf100 = 6 */ -- /* SSTrKp1000Mas = 5 */ -- /* SSTrKf1000Mas = 6 */ -- /* SSTrKp1000Slv = 5 */ -- /* SSTrKf1000Slv = 6 */ -- __phy_write(phydev, 0x11, 0xbaef); -- __phy_write(phydev, 0x12, 0x2e); -- __phy_write(phydev, 0x10, 0x968c); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x17, -+ SLAVE_DSP_READY_TIME_MASK | MASTER_DSP_READY_TIME_MASK, -+ FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x18) | -+ FIELD_PREP(MASTER_DSP_READY_TIME_MASK, 0x18)); -+ -+ __mtk_tr_set_bits(phydev, 0x1, 0xf, 0x18, -+ ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER); -+ -+ __mtk_tr_modify(phydev, 0x0, 0x7, 0x15, -+ NORMAL_MSE_LO_THRESH_MASK, -+ FIELD_PREP(NORMAL_MSE_LO_THRESH_MASK, 0x55)); -+ -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x0, -+ FFE_UPDATE_GAIN_FORCE_VAL_MASK, -+ FIELD_PREP(FFE_UPDATE_GAIN_FORCE_VAL_MASK, 0x4) | -+ FFE_UPDATE_GAIN_FORCE); -+ -+ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x3, TR_FREEZE_MASK); -+ -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x6, -+ SS_TR_KP100_MASK | SS_TR_KF100_MASK | -+ SS_TR_KP1000_MASTER_MASK | SS_TR_KF1000_MASTER_MASK | -+ SS_TR_KP1000_SLAVE_MASK | SS_TR_KF1000_SLAVE_MASK, -+ FIELD_PREP(SS_TR_KP100_MASK, 0x5) | -+ FIELD_PREP(SS_TR_KF100_MASK, 0x6) | -+ FIELD_PREP(SS_TR_KP1000_MASTER_MASK, 0x5) | -+ FIELD_PREP(SS_TR_KF1000_MASTER_MASK, 0x6) | -+ FIELD_PREP(SS_TR_KP1000_SLAVE_MASK, 0x5) | -+ FIELD_PREP(SS_TR_KF1000_SLAVE_MASK, 0x6)); -+ - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - } - -@@ -735,27 +832,29 @@ static void mt7981_phy_finetune(struct p - } - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* ResetSyncOffset = 6 */ -- __phy_write(phydev, 0x11, 0x600); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x8fc0); -- -- /* VgaDecRate = 1 */ -- __phy_write(phydev, 0x11, 0x4c2a); -- __phy_write(phydev, 0x12, 0x3e); -- __phy_write(phydev, 0x10, 0x8fa4); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x20, -+ RESET_SYNC_OFFSET_MASK, -+ FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x6)); -+ -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x12, -+ VGA_DECIMATION_RATE_MASK, -+ FIELD_PREP(VGA_DECIMATION_RATE_MASK, 0x1)); - - /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, - * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 - */ -- __phy_write(phydev, 0x11, 0xd10a); -- __phy_write(phydev, 0x12, 0x34); -- __phy_write(phydev, 0x10, 0x8f82); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x1, -+ MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK | -+ MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK, -+ FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x3) | -+ FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x2) | -+ FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x3) | -+ FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x2)); - - /* VcoSlicerThreshBitsHigh */ -- __phy_write(phydev, 0x11, 0x5555); -- __phy_write(phydev, 0x12, 0x55); -- __phy_write(phydev, 0x10, 0x8ec0); -+ __mtk_tr_modify(phydev, 0x1, 0xd, 0x20, -+ VCO_SLICER_THRESH_HIGH_MASK, -+ FIELD_PREP(VCO_SLICER_THRESH_HIGH_MASK, 0x555555)); - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */ -@@ -807,25 +906,23 @@ static void mt7988_phy_finetune(struct p - phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- /* ResetSyncOffset = 5 */ -- __phy_write(phydev, 0x11, 0x500); -- __phy_write(phydev, 0x12, 0x0); -- __phy_write(phydev, 0x10, 0x8fc0); -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x20, -+ RESET_SYNC_OFFSET_MASK, -+ FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x5)); - - /* VgaDecRate is 1 at default on mt7988 */ - -- /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, -- * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 -- */ -- __phy_write(phydev, 0x11, 0xb90a); -- __phy_write(phydev, 0x12, 0x6f); -- __phy_write(phydev, 0x10, 0x8f82); -- -- /* RemAckCntLimitCtrl = 1 */ -- __phy_write(phydev, 0x11, 0xfbba); -- __phy_write(phydev, 0x12, 0xc3); -- __phy_write(phydev, 0x10, 0x87f8); -- -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x1, -+ MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK | -+ MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK, -+ FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x6) | -+ FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x7) | -+ FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x6) | -+ FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x7)); -+ -+ __mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, -+ REMOTE_ACK_COUNT_LIMIT_CTRL_MASK, -+ FIELD_PREP(REMOTE_ACK_COUNT_LIMIT_CTRL_MASK, 0x1)); - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ -@@ -901,45 +998,37 @@ static void mt798x_phy_eee(struct phy_de - 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 = 2 */ -- __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 = 0 */ -- __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); -+ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x8, -+ EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE); -+ -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0xd, -+ EEE1000_STAGE2_TR_KF_MASK, -+ FIELD_PREP(EEE1000_STAGE2_TR_KF_MASK, 0x2)); -+ -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0xf, -+ SLAVE_WAKETR_TIMER_MASK | SLAVE_REMTX_TIMER_MASK, -+ FIELD_PREP(SLAVE_WAKETR_TIMER_MASK, 0x6) | -+ FIELD_PREP(SLAVE_REMTX_TIMER_MASK, 0x14)); -+ -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x10, -+ SLAVE_WAKEINT_TIMER_MASK, -+ FIELD_PREP(SLAVE_WAKEINT_TIMER_MASK, 0x8)); -+ -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x14, -+ TR_FREEZE_TIMER2_MASK, -+ FIELD_PREP(TR_FREEZE_TIMER2_MASK, 0x24a)); -+ -+ __mtk_tr_modify(phydev, 0x2, 0xd, 0x1c, -+ EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK, -+ FIELD_PREP(EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK, -+ 0x10)); -+ -+ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x25, -+ WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN); -+ -+ __mtk_tr_modify(phydev, 0x1, 0xf, 0x0, -+ DFE_TAIL_EANBLE_VGA_TRHESH_1000, -+ FIELD_PREP(DFE_TAIL_EANBLE_VGA_TRHESH_1000, 0x1b)); - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3); ---- a/drivers/net/phy/mediatek/mtk-ge.c -+++ b/drivers/net/phy/mediatek/mtk-ge.c -@@ -9,13 +9,35 @@ - #define MTK_GPHY_ID_MT7530 0x03a29412 - #define MTK_GPHY_ID_MT7531 0x03a29441 - --#define MTK_EXT_PAGE_ACCESS 0x1f --#define MTK_PHY_PAGE_STANDARD 0x0000 --#define MTK_PHY_PAGE_EXTENDED 0x0001 --#define MTK_PHY_PAGE_EXTENDED_2 0x0002 --#define MTK_PHY_PAGE_EXTENDED_3 0x0003 --#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 --#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 -+#define MTK_PHY_PAGE_EXTENDED_1 0x0001 -+#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14 -+#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4) -+ -+#define MTK_PHY_PAGE_EXTENDED_2 0x0002 -+#define MTK_PHY_PAGE_EXTENDED_3 0x0003 -+#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11 0x11 -+ -+#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 -+ -+/* Registers on Token Ring debug nodes */ -+/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */ -+#define SLAVE_DSP_READY_TIME_MASK GENMASK(22, 15) -+ -+/* Registers on MDIO_MMD_VEND1 */ -+#define MTK_PHY_GBE_MODE_TX_DELAY_SEL 0x13 -+#define MTK_PHY_TEST_MODE_TX_DELAY_SEL 0x14 -+#define MTK_TX_DELAY_PAIR_B_MASK GENMASK(10, 8) -+#define MTK_TX_DELAY_PAIR_D_MASK GENMASK(2, 0) -+ -+#define MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL 0xa6 -+#define MTK_MCC_NEARECHO_OFFSET_MASK GENMASK(15, 8) -+ -+#define MTK_PHY_RXADC_CTRL_RG7 0xc6 -+#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8) -+ -+#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123 0x123 -+#define MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK GENMASK(15, 8) -+#define MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK GENMASK(7, 0) - - struct mtk_gephy_priv { - unsigned long led_state; -@@ -27,20 +49,29 @@ static void mtk_gephy_config_init(struct - phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0); - - /* Enable HW auto downshift */ -- phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4)); -+ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1, -+ MTK_PHY_AUX_CTRL_AND_STATUS, -+ 0, MTK_PHY_ENABLE_DOWNSHIFT); - - /* Increase SlvDPSready time */ -- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -- __phy_write(phydev, 0x10, 0xafae); -- __phy_write(phydev, 0x12, 0x2f); -- __phy_write(phydev, 0x10, 0x8fae); -- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -+ mtk_tr_modify(phydev, 0x1, 0xf, 0x17, SLAVE_DSP_READY_TIME_MASK, -+ FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x5e)); - - /* Adjust 100_mse_threshold */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff); -- -- /* Disable mcc */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300); -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, -+ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123, -+ MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK | -+ MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK, -+ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK, -+ 0xff) | -+ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK, -+ 0xff)); -+ -+ /* If echo time is narrower than 0x3, it will be regarded as noise */ -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, -+ MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL, -+ MTK_MCC_NEARECHO_OFFSET_MASK, -+ FIELD_PREP(MTK_MCC_NEARECHO_OFFSET_MASK, 0x3)); - } - - static int mt7530_phy_config_init(struct phy_device *phydev) -@@ -48,7 +79,8 @@ static int mt7530_phy_config_init(struct - mtk_gephy_config_init(phydev); - - /* Increase post_update_timer */ -- phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b); -+ phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, -+ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11, 0x4b); - - return 0; - } -@@ -89,11 +121,19 @@ static int mt7531_phy_config_init(struct - - /* PHY link down power saving enable */ - phy_set_bits(phydev, 0x17, BIT(4)); -- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300); -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, -+ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, -+ FIELD_PREP(MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3)); - - /* Set TX Pair delay selection */ -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404); -- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404); -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_GBE_MODE_TX_DELAY_SEL, -+ MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK, -+ FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) | -+ FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4)); -+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TEST_MODE_TX_DELAY_SEL, -+ MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK, -+ FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) | -+ FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4)); - - /* LED Config*/ - mt7530_led_config_of(phydev); ---- a/drivers/net/phy/mediatek/mtk-phy-lib.c -+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c -@@ -6,6 +6,97 @@ - - #include "mtk.h" - -+/* Difference between functions with mtk_tr* and __mtk_tr* prefixes is -+ * mtk_tr* functions: wrapped by page switching operations -+ * __mtk_tr* functions: no page switching operations -+ */ -+ -+static void __mtk_tr_access(struct phy_device *phydev, bool read, u8 ch_addr, -+ u8 node_addr, u8 data_addr) -+{ -+ u16 tr_cmd = BIT(15); /* bit 14 & 0 are reserved */ -+ -+ if (read) -+ tr_cmd |= BIT(13); -+ -+ tr_cmd |= (((ch_addr & 0x3) << 11) | -+ ((node_addr & 0xf) << 7) | -+ ((data_addr & 0x3f) << 1)); -+ dev_dbg(&phydev->mdio.dev, "tr_cmd: 0x%x\n", tr_cmd); -+ __phy_write(phydev, 0x10, tr_cmd); -+} -+ -+static void __mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u16 *tr_high, u16 *tr_low) -+{ -+ __mtk_tr_access(phydev, true, ch_addr, node_addr, data_addr); -+ *tr_low = __phy_read(phydev, 0x11); -+ *tr_high = __phy_read(phydev, 0x12); -+ dev_dbg(&phydev->mdio.dev, "tr_high read: 0x%x, tr_low read: 0x%x\n", -+ *tr_high, *tr_low); -+} -+ -+u32 mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr) -+{ -+ u16 tr_high; -+ u16 tr_low; -+ -+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -+ __mtk_tr_read(phydev, ch_addr, node_addr, data_addr, &tr_high, &tr_low); -+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -+ -+ return (tr_high << 16) | tr_low; -+} -+EXPORT_SYMBOL_GPL(mtk_tr_read); -+ -+static void __mtk_tr_write(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 tr_data) -+{ -+ __phy_write(phydev, 0x11, tr_data & 0xffff); -+ __phy_write(phydev, 0x12, tr_data >> 16); -+ dev_dbg(&phydev->mdio.dev, "tr_high write: 0x%x, tr_low write: 0x%x\n", -+ tr_data >> 16, tr_data & 0xffff); -+ __mtk_tr_access(phydev, false, ch_addr, node_addr, data_addr); -+} -+ -+void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 mask, u32 set) -+{ -+ u32 tr_data; -+ u16 tr_high; -+ u16 tr_low; -+ -+ __mtk_tr_read(phydev, ch_addr, node_addr, data_addr, &tr_high, &tr_low); -+ tr_data = (tr_high << 16) | tr_low; -+ tr_data = (tr_data & ~mask) | set; -+ __mtk_tr_write(phydev, ch_addr, node_addr, data_addr, tr_data); -+} -+EXPORT_SYMBOL_GPL(__mtk_tr_modify); -+ -+void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 mask, u32 set) -+{ -+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); -+ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, mask, set); -+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -+} -+EXPORT_SYMBOL_GPL(mtk_tr_modify); -+ -+void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 set) -+{ -+ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, 0, set); -+} -+EXPORT_SYMBOL_GPL(__mtk_tr_set_bits); -+ -+void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 clr) -+{ -+ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, clr, 0); -+} -+EXPORT_SYMBOL_GPL(__mtk_tr_clr_bits); -+ - int mtk_phy_read_page(struct phy_device *phydev) - { - return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); ---- a/drivers/net/phy/mediatek/mtk.h -+++ b/drivers/net/phy/mediatek/mtk.h -@@ -9,6 +9,8 @@ - #define _MTK_EPHY_H_ - - #define MTK_EXT_PAGE_ACCESS 0x1f -+#define MTK_PHY_PAGE_STANDARD 0x0000 -+#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 - - /* Registers on MDIO_MMD_VEND2 */ - #define MTK_PHY_LED0_ON_CTRL 0x24 -@@ -62,6 +64,17 @@ - #define MTK_PHY_LED_STATE_FORCE_BLINK 1 - #define MTK_PHY_LED_STATE_NETDEV 2 - -+u32 mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr); -+void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 mask, u32 set); -+void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 mask, u32 set); -+void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 set); -+void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr, -+ u8 data_addr, u32 clr); -+ - int mtk_phy_read_page(struct phy_device *phydev); - int mtk_phy_write_page(struct phy_device *phydev, int page); - diff --git a/target/linux/mediatek/patches-6.12/734-net-phy-add-Airoha-EN8801SC-PHY.patch b/target/linux/mediatek/patches-6.12/734-net-phy-add-Airoha-EN8801SC-PHY.patch index 90c030fb89c..079351b7a22 100644 --- a/target/linux/mediatek/patches-6.12/734-net-phy-add-Airoha-EN8801SC-PHY.patch +++ b/target/linux/mediatek/patches-6.12/734-net-phy-add-Airoha-EN8801SC-PHY.patch @@ -14,7 +14,7 @@ Signed-off-by: Robert Marko --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig -@@ -142,6 +142,11 @@ endif # RTL8366_SMI +@@ -153,6 +153,11 @@ endif # RTL8366_SMI comment "MII PHY device drivers" @@ -28,11 +28,11 @@ Signed-off-by: Robert Marko help --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile -@@ -49,6 +49,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) +@@ -50,6 +50,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) obj-$(CONFIG_ADIN_PHY) += adin.o obj-$(CONFIG_ADIN1100_PHY) += adin1100.o +obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o obj-$(CONFIG_AMD_PHY) += amd.o - obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ + obj-$(CONFIG_AMCC_QT2025_PHY) += qt2025.o