diff options
Diffstat (limited to 'package/boot/uboot-mediatek/patches/001-eth-mtk-add-mt7531-switch.patch')
-rw-r--r-- | package/boot/uboot-mediatek/patches/001-eth-mtk-add-mt7531-switch.patch | 1074 |
1 files changed, 1074 insertions, 0 deletions
diff --git a/package/boot/uboot-mediatek/patches/001-eth-mtk-add-mt7531-switch.patch b/package/boot/uboot-mediatek/patches/001-eth-mtk-add-mt7531-switch.patch new file mode 100644 index 0000000000..ced1ca9a15 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/001-eth-mtk-add-mt7531-switch.patch @@ -0,0 +1,1074 @@ +From patchwork Tue Feb 18 08:49:37 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Landen Chao <landen.chao@mediatek.com> +X-Patchwork-Id: 1239956 +X-Patchwork-Delegate: trini@ti.com +Return-Path: <u-boot-bounces@lists.denx.de> +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) + smtp.mailfrom=lists.denx.de + (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; + helo=phobos.denx.de; + envelope-from=u-boot-bounces@lists.denx.de; + receiver=<UNKNOWN>) +Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) + header.from=mediatek.com +Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; + unprotected) header.d=mediatek.com header.i=@mediatek.com + header.a=rsa-sha256 header.s=dk header.b=NQKfnebM; + dkim-atps=neutral +Received: from phobos.denx.de (phobos.denx.de + [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange X25519 server-signature RSA-PSS (4096 bits)) + (No client certificate requested) + by ozlabs.org (Postfix) with ESMTPS id 48MJX54ymTz9sRf + for <incoming@patchwork.ozlabs.org>; + Tue, 18 Feb 2020 22:28:53 +1100 (AEDT) +Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) + by phobos.denx.de (Postfix) with ESMTP id A68D8810D8; + Tue, 18 Feb 2020 12:28:47 +0100 (CET) +Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) + header.from=mediatek.com +Authentication-Results: phobos.denx.de; + spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de +Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; + unprotected) header.d=mediatek.com header.i=@mediatek.com + header.b="NQKfnebM"; dkim-atps=neutral +Received: by phobos.denx.de (Postfix, from userid 109) + id 767F881217; Tue, 18 Feb 2020 09:50:00 +0100 (CET) +X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de +X-Spam-Level: +X-Spam-Status: No, score=0.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, + DKIM_VALID,DKIM_VALID_AU,MIME_BASE64_TEXT,RDNS_NONE,SPF_HELO_NONE, + UNPARSEABLE_RELAY,URIBL_BLOCKED autolearn=no autolearn_force=no + version=3.4.2 +Received: from mailgw01.mediatek.com (unknown [210.61.82.183]) + by phobos.denx.de (Postfix) with ESMTP id 40ADE811FB + for <u-boot@lists.denx.de>; Tue, 18 Feb 2020 09:49:46 +0100 (CET) +Authentication-Results: phobos.denx.de; + dmarc=pass (p=none dis=none) header.from=mediatek.com +Authentication-Results: phobos.denx.de; + spf=pass smtp.mailfrom=landen.chao@mediatek.com +X-UUID: ddaa8deb3c7d4a24ba5cbcb30775fbfd-20200218 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=mediatek.com; s=dk; + h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; + bh=qvWp4DdC1p5SZD1XJPV3kwdXTU9lBi4hbWNZQoO2oLI=; + b=NQKfnebM0mIfPJuncOxa6aNY+g5wFOnlozbm/o8ViKaVNbkd8YSB0ISWOerj8lALM7E7sSP797r514G3R4EAQPPvuAm5B2wi2VuYKssTxHkvYJvCrALXp4wmQtGF+gJytfdWuHx6Np0wfbjTsLqw+JUtcDi/0jAa8TQ5y9UHr9Q=; +X-UUID: ddaa8deb3c7d4a24ba5cbcb30775fbfd-20200218 +Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by + mailgw01.mediatek.com (envelope-from <landen.chao@mediatek.com>) + (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) + with ESMTP id 827129897; Tue, 18 Feb 2020 16:49:43 +0800 +Received: from MTKCAS06.mediatek.inc (172.21.101.30) by + mtkmbs05n1.mediatek.inc (172.21.101.15) with Microsoft SMTP Server + (TLS) id 15.0.1395.4; Tue, 18 Feb 2020 16:48:45 +0800 +Received: from mtksdccf07.mediatek.inc (172.21.84.99) by MTKCAS06.mediatek.inc + (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via + Frontend Transport; Tue, 18 Feb 2020 16:47:41 +0800 +From: Landen Chao <landen.chao@mediatek.com> +To: Ryder Lee <ryder.lee@mediatek.com>, Weijie Gao <weijie.gao@mediatek.com>, + GSS_MTK_Uboot_upstream <GSS_MTK_Uboot_upstream@mediatek.com>, + Joe Hershberger <joe.hershberger@ni.com>, <u-boot@lists.denx.de> +CC: <frank-w@public-files.de>, <steven.liu@mediatek.com>, + <landen.chao@mediatek.com>, <mark-mc.lee@mediatek.com> +Subject: [U-Boot 1/1] eth: mtk-eth: add mt7531 switch support in mediatek eth + driver +Date: Tue, 18 Feb 2020 16:49:37 +0800 +Message-ID: <f10c8e2e72fda3ac9d8d240b128f28c52cf06f3f.1582015221.git.landen.chao@mediatek.com> +X-Mailer: git-send-email 2.18.0 +In-Reply-To: <cover.1582015221.git.landen.chao@mediatek.com> +References: <cover.1582015221.git.landen.chao@mediatek.com> +MIME-Version: 1.0 +X-MTK: N +X-Mailman-Approved-At: Tue, 18 Feb 2020 12:28:45 +0100 +X-BeenThere: u-boot@lists.denx.de +X-Mailman-Version: 2.1.30rc1 +Precedence: list +List-Id: U-Boot discussion <u-boot.lists.denx.de> +List-Unsubscribe: <https://lists.denx.de/options/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=unsubscribe> +List-Archive: <https://lists.denx.de/pipermail/u-boot/> +List-Post: <mailto:u-boot@lists.denx.de> +List-Help: <mailto:u-boot-request@lists.denx.de?subject=help> +List-Subscribe: <https://lists.denx.de/listinfo/u-boot>, + <mailto:u-boot-request@lists.denx.de?subject=subscribe> +Errors-To: u-boot-bounces@lists.denx.de +Sender: "U-Boot" <u-boot-bounces@lists.denx.de> +X-Virus-Scanned: clamav-milter 0.102.1 at phobos.denx.de +X-Virus-Status: Clean + +mt7531 is a 7-ports switch with 5 embedded giga phys, and uses the same +MAC design of mt7530. The cpu port6 supports SGMII only. The cpu port5 +supports RGMII or SGMII in different model. + +mt7531 is connected to mt7622 via both RGMII and SGMII interfaces. +In this patch, mt7531 cpu port5 or port6 is configured to maximum +capability to align CPU MAC setting. + +The dts has been committed in the commit 6efa450565cdc ("arm: dts: +mediatek: add ethernet and sgmii dts node for mt7622") + +Signed-off-by: Landen Chao <landen.chao@mediatek.com> +Tested-by: Frank Wunderlich <frank-w@public-files.de> +--- + drivers/net/mtk_eth.c | 580 +++++++++++++++++++++++++++++++++--------- + drivers/net/mtk_eth.h | 124 ++++++++- + 2 files changed, 577 insertions(+), 127 deletions(-) + +diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c +index edfa5d1ce8..f7d34a2e6b 100644 +--- a/drivers/net/mtk_eth.c ++++ b/drivers/net/mtk_eth.c +@@ -30,10 +30,12 @@ + #define RX_TOTAL_BUF_SIZE (NUM_RX_DESC * PKTSIZE_ALIGN) + #define TOTAL_PKT_BUF_SIZE (TX_TOTAL_BUF_SIZE + RX_TOTAL_BUF_SIZE) + +-#define MT7530_NUM_PHYS 5 +-#define MT7530_DFL_SMI_ADDR 31 ++#define MT753X_NUM_PHYS 5 ++#define MT753X_NUM_PORTS 7 ++#define MT753X_DFL_SMI_ADDR 31 ++#define MT753X_SMI_ADDR_MASK 0x1f + +-#define MT7530_PHY_ADDR(base, addr) \ ++#define MT753X_PHY_ADDR(base, addr) \ + (((base) + (addr)) & 0x1f) + + #define GDMA_FWD_TO_CPU \ +@@ -131,7 +133,8 @@ struct pdma_txdesc { + + enum mtk_switch { + SW_NONE, +- SW_MT7530 ++ SW_MT7530, ++ SW_MT7531 + }; + + enum mtk_soc { +@@ -173,8 +176,8 @@ struct mtk_eth_priv { + + enum mtk_switch sw; + int (*switch_init)(struct mtk_eth_priv *priv); +- u32 mt7530_smi_addr; +- u32 mt7530_phy_base; ++ u32 mt753x_smi_addr; ++ u32 mt753x_phy_base; + + struct gpio_desc rst_gpio; + int mcm; +@@ -349,6 +352,174 @@ static int mtk_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad, + return priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, val); + } + ++/* ++ * MT7530 Internal Register Address Bits ++ * ------------------------------------------------------------------- ++ * | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 | ++ * |----------------------------------------|---------------|--------| ++ * | Page Address | Reg Address | Unused | ++ * ------------------------------------------------------------------- ++ */ ++ ++static int mt753x_reg_read(struct mtk_eth_priv *priv, u32 reg, u32 *data) ++{ ++ int ret, low_word, high_word; ++ ++ /* Write page address */ ++ ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6); ++ if (ret) ++ return ret; ++ ++ /* Read low word */ ++ low_word = mtk_mii_read(priv, priv->mt753x_smi_addr, (reg >> 2) & 0xf); ++ if (low_word < 0) ++ return low_word; ++ ++ /* Read high word */ ++ high_word = mtk_mii_read(priv, priv->mt753x_smi_addr, 0x10); ++ if (high_word < 0) ++ return high_word; ++ ++ if (data) ++ *data = ((u32)high_word << 16) | (low_word & 0xffff); ++ ++ return 0; ++} ++ ++static int mt753x_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 data) ++{ ++ int ret; ++ ++ /* Write page address */ ++ ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6); ++ if (ret) ++ return ret; ++ ++ /* Write low word */ ++ ret = mtk_mii_write(priv, priv->mt753x_smi_addr, (reg >> 2) & 0xf, ++ data & 0xffff); ++ if (ret) ++ return ret; ++ ++ /* Write high word */ ++ return mtk_mii_write(priv, priv->mt753x_smi_addr, 0x10, data >> 16); ++} ++ ++static void mt753x_reg_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, ++ u32 set) ++{ ++ u32 val; ++ ++ mt753x_reg_read(priv, reg, &val); ++ val &= ~clr; ++ val |= set; ++ mt753x_reg_write(priv, reg, val); ++} ++ ++/* Indirect MDIO clause 22/45 access */ ++static int mt7531_mii_rw(struct mtk_eth_priv *priv, int phy, int reg, u16 data, ++ u32 cmd, u32 st) ++{ ++ ulong timeout; ++ u32 val, timeout_ms; ++ int ret = 0; ++ ++ val = (st << MDIO_ST_S) | ++ ((cmd << MDIO_CMD_S) & MDIO_CMD_M) | ++ ((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) | ++ ((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M); ++ ++ if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR) ++ val |= data & MDIO_RW_DATA_M; ++ ++ mt753x_reg_write(priv, MT7531_PHY_IAC, val | PHY_ACS_ST); ++ ++ timeout_ms = 100; ++ timeout = get_timer(0); ++ while (1) { ++ mt753x_reg_read(priv, MT7531_PHY_IAC, &val); ++ ++ if ((val & PHY_ACS_ST) == 0) ++ break; ++ ++ if (get_timer(timeout) > timeout_ms) ++ return -ETIMEDOUT; ++ } ++ ++ if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) { ++ mt753x_reg_read(priv, MT7531_PHY_IAC, &val); ++ ret = val & MDIO_RW_DATA_M; ++ } ++ ++ return ret; ++} ++ ++static int mt7531_mii_ind_read(struct mtk_eth_priv *priv, u8 phy, u8 reg) ++{ ++ u8 phy_addr; ++ ++ if (phy >= MT753X_NUM_PHYS) ++ return -EINVAL; ++ ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, phy); ++ ++ return mt7531_mii_rw(priv, phy_addr, reg, 0, MDIO_CMD_READ, ++ MDIO_ST_C22); ++} ++ ++static int mt7531_mii_ind_write(struct mtk_eth_priv *priv, u8 phy, u8 reg, ++ u16 val) ++{ ++ u8 phy_addr; ++ ++ if (phy >= MT753X_NUM_PHYS) ++ return -EINVAL; ++ ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, phy); ++ ++ return mt7531_mii_rw(priv, phy_addr, reg, val, MDIO_CMD_WRITE, ++ MDIO_ST_C22); ++} ++ ++int mt7531_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg) ++{ ++ u8 phy_addr; ++ int ret; ++ ++ if (addr >= MT753X_NUM_PHYS) ++ return -EINVAL; ++ ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, addr); ++ ++ ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR, ++ MDIO_ST_C45); ++ if (ret) ++ return ret; ++ ++ return mt7531_mii_rw(priv, phy_addr, devad, 0, MDIO_CMD_READ_C45, ++ MDIO_ST_C45); ++} ++ ++static int mt7531_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad, ++ u16 reg, u16 val) ++{ ++ u8 phy_addr; ++ int ret; ++ ++ if (addr >= MT753X_NUM_PHYS) ++ return 0; ++ ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, addr); ++ ++ ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR, ++ MDIO_ST_C45); ++ if (ret) ++ return ret; ++ ++ return mt7531_mii_rw(priv, phy_addr, devad, val, MDIO_CMD_WRITE, ++ MDIO_ST_C45); ++} ++ + static int mtk_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) + { + struct mtk_eth_priv *priv = bus->priv; +@@ -387,6 +558,12 @@ static int mtk_mdio_register(struct udevice *dev) + priv->mmd_read = mtk_mmd_ind_read; + priv->mmd_write = mtk_mmd_ind_write; + break; ++ case SW_MT7531: ++ priv->mii_read = mt7531_mii_ind_read; ++ priv->mii_write = mt7531_mii_ind_write; ++ priv->mmd_read = mt7531_mmd_ind_read; ++ priv->mmd_write = mt7531_mmd_ind_write; ++ break; + default: + priv->mii_read = mtk_mii_read; + priv->mii_write = mtk_mii_write; +@@ -410,75 +587,18 @@ static int mtk_mdio_register(struct udevice *dev) + return 0; + } + +-/* +- * MT7530 Internal Register Address Bits +- * ------------------------------------------------------------------- +- * | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 | +- * |----------------------------------------|---------------|--------| +- * | Page Address | Reg Address | Unused | +- * ------------------------------------------------------------------- +- */ +- +-static int mt7530_reg_read(struct mtk_eth_priv *priv, u32 reg, u32 *data) ++static int mt753x_core_reg_read(struct mtk_eth_priv *priv, u32 reg) + { +- int ret, low_word, high_word; ++ u8 phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, 0); + +- /* Write page address */ +- ret = mtk_mii_write(priv, priv->mt7530_smi_addr, 0x1f, reg >> 6); +- if (ret) +- return ret; +- +- /* Read low word */ +- low_word = mtk_mii_read(priv, priv->mt7530_smi_addr, (reg >> 2) & 0xf); +- if (low_word < 0) +- return low_word; +- +- /* Read high word */ +- high_word = mtk_mii_read(priv, priv->mt7530_smi_addr, 0x10); +- if (high_word < 0) +- return high_word; +- +- if (data) +- *data = ((u32)high_word << 16) | (low_word & 0xffff); +- +- return 0; ++ return priv->mmd_read(priv, phy_addr, 0x1f, reg); + } + +-static int mt7530_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 data) ++static void mt753x_core_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 val) + { +- int ret; +- +- /* Write page address */ +- ret = mtk_mii_write(priv, priv->mt7530_smi_addr, 0x1f, reg >> 6); +- if (ret) +- return ret; ++ u8 phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, 0); + +- /* Write low word */ +- ret = mtk_mii_write(priv, priv->mt7530_smi_addr, (reg >> 2) & 0xf, +- data & 0xffff); +- if (ret) +- return ret; +- +- /* Write high word */ +- return mtk_mii_write(priv, priv->mt7530_smi_addr, 0x10, data >> 16); +-} +- +-static void mt7530_reg_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, +- u32 set) +-{ +- u32 val; +- +- mt7530_reg_read(priv, reg, &val); +- val &= ~clr; +- val |= set; +- mt7530_reg_write(priv, reg, val); +-} +- +-static void mt7530_core_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 val) +-{ +- u8 phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, 0); +- +- mtk_mmd_ind_write(priv, phy_addr, 0x1f, reg, val); ++ priv->mmd_write(priv, phy_addr, 0x1f, reg, val); + } + + static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode) +@@ -496,46 +616,46 @@ static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode) + } + + /* Disable MT7530 core clock */ +- mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, 0); ++ mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, 0); + + /* Disable MT7530 PLL */ +- mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1, ++ mt753x_core_reg_write(priv, CORE_GSWPLL_GRP1, + (2 << RG_GSWPLL_POSDIV_200M_S) | + (32 << RG_GSWPLL_FBKDIV_200M_S)); + + /* For MT7530 core clock = 500Mhz */ +- mt7530_core_reg_write(priv, CORE_GSWPLL_GRP2, ++ mt753x_core_reg_write(priv, CORE_GSWPLL_GRP2, + (1 << RG_GSWPLL_POSDIV_500M_S) | + (25 << RG_GSWPLL_FBKDIV_500M_S)); + + /* Enable MT7530 PLL */ +- mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1, ++ mt753x_core_reg_write(priv, CORE_GSWPLL_GRP1, + (2 << RG_GSWPLL_POSDIV_200M_S) | + (32 << RG_GSWPLL_FBKDIV_200M_S) | + RG_GSWPLL_EN_PRE); + + udelay(20); + +- mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); ++ mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN); + + /* Setup the MT7530 TRGMII Tx Clock */ +- mt7530_core_reg_write(priv, CORE_PLL_GROUP5, ncpo1); +- mt7530_core_reg_write(priv, CORE_PLL_GROUP6, 0); +- mt7530_core_reg_write(priv, CORE_PLL_GROUP10, ssc_delta); +- mt7530_core_reg_write(priv, CORE_PLL_GROUP11, ssc_delta); +- mt7530_core_reg_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN | ++ mt753x_core_reg_write(priv, CORE_PLL_GROUP5, ncpo1); ++ mt753x_core_reg_write(priv, CORE_PLL_GROUP6, 0); ++ mt753x_core_reg_write(priv, CORE_PLL_GROUP10, ssc_delta); ++ mt753x_core_reg_write(priv, CORE_PLL_GROUP11, ssc_delta); ++ mt753x_core_reg_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN | + RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN); + +- mt7530_core_reg_write(priv, CORE_PLL_GROUP2, ++ mt753x_core_reg_write(priv, CORE_PLL_GROUP2, + RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN | + (1 << RG_SYSPLL_POSDIV_S)); + +- mt7530_core_reg_write(priv, CORE_PLL_GROUP7, ++ mt753x_core_reg_write(priv, CORE_PLL_GROUP7, + RG_LCDDS_PCW_NCPO_CHG | (3 << RG_LCCDS_C_S) | + RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); + + /* Enable MT7530 core clock */ +- mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, ++ mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, + REG_GSWCK_EN | REG_TRGMIICK_EN); + + return 0; +@@ -551,46 +671,33 @@ static int mt7530_setup(struct mtk_eth_priv *priv) + mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG, + ETHSYS_TRGMII_CLK_SEL362_5, 0); + +- /* Global reset switch */ +- if (priv->mcm) { +- reset_assert(&priv->rst_mcm); +- udelay(1000); +- reset_deassert(&priv->rst_mcm); +- mdelay(1000); +- } else if (dm_gpio_is_valid(&priv->rst_gpio)) { +- dm_gpio_set_value(&priv->rst_gpio, 0); +- udelay(1000); +- dm_gpio_set_value(&priv->rst_gpio, 1); +- mdelay(1000); +- } +- + /* Modify HWTRAP first to allow direct access to internal PHYs */ +- mt7530_reg_read(priv, HWTRAP_REG, &val); ++ mt753x_reg_read(priv, HWTRAP_REG, &val); + val |= CHG_TRAP; + val &= ~C_MDIO_BPS; +- mt7530_reg_write(priv, MHWTRAP_REG, val); ++ mt753x_reg_write(priv, MHWTRAP_REG, val); + + /* Calculate the phy base address */ + val = ((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3; +- priv->mt7530_phy_base = (val | 0x7) + 1; ++ priv->mt753x_phy_base = (val | 0x7) + 1; + + /* Turn off PHYs */ +- for (i = 0; i < MT7530_NUM_PHYS; i++) { +- phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, i); ++ for (i = 0; i < MT753X_NUM_PHYS; i++) { ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i); + phy_val = priv->mii_read(priv, phy_addr, MII_BMCR); + phy_val |= BMCR_PDOWN; + priv->mii_write(priv, phy_addr, MII_BMCR, phy_val); + } + + /* Force MAC link down before reset */ +- mt7530_reg_write(priv, PCMR_REG(5), FORCE_MODE); +- mt7530_reg_write(priv, PCMR_REG(6), FORCE_MODE); ++ mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE); ++ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE); + + /* MT7530 reset */ +- mt7530_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST); ++ mt753x_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST); + udelay(100); + +- val = (1 << IPG_CFG_S) | ++ val = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + MAC_MODE | FORCE_MODE | + MAC_TX_EN | MAC_RX_EN | + BKOFF_EN | BACKPR_EN | +@@ -598,53 +705,280 @@ static int mt7530_setup(struct mtk_eth_priv *priv) + FORCE_DPX | FORCE_LINK; + + /* MT7530 Port6: Forced 1000M/FD, FC disabled */ +- mt7530_reg_write(priv, PCMR_REG(6), val); ++ mt753x_reg_write(priv, PMCR_REG(6), val); + + /* MT7530 Port5: Forced link down */ +- mt7530_reg_write(priv, PCMR_REG(5), FORCE_MODE); ++ mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE); + + /* MT7530 Port6: Set to RGMII */ +- mt7530_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII); ++ mt753x_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII); + + /* Hardware Trap: Enable Port6, Disable Port5 */ +- mt7530_reg_read(priv, HWTRAP_REG, &val); ++ mt753x_reg_read(priv, HWTRAP_REG, &val); + val |= CHG_TRAP | LOOPDET_DIS | P5_INTF_DIS | + (P5_INTF_SEL_GMAC5 << P5_INTF_SEL_S) | + (P5_INTF_MODE_RGMII << P5_INTF_MODE_S); + val &= ~(C_MDIO_BPS | P6_INTF_DIS); +- mt7530_reg_write(priv, MHWTRAP_REG, val); ++ mt753x_reg_write(priv, MHWTRAP_REG, val); + + /* Setup switch core pll */ + mt7530_pad_clk_setup(priv, priv->phy_interface); + + /* Lower Tx Driving for TRGMII path */ + for (i = 0 ; i < NUM_TRGMII_CTRL ; i++) +- mt7530_reg_write(priv, MT7530_TRGMII_TD_ODT(i), ++ mt753x_reg_write(priv, MT7530_TRGMII_TD_ODT(i), + (8 << TD_DM_DRVP_S) | (8 << TD_DM_DRVN_S)); + + for (i = 0 ; i < NUM_TRGMII_CTRL; i++) +- mt7530_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16); ++ mt753x_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16); ++ ++ /* Turn on PHYs */ ++ for (i = 0; i < MT753X_NUM_PHYS; i++) { ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i); ++ phy_val = priv->mii_read(priv, phy_addr, MII_BMCR); ++ phy_val &= ~BMCR_PDOWN; ++ priv->mii_write(priv, phy_addr, MII_BMCR, phy_val); ++ } ++ ++ return 0; ++} ++ ++static void mt7531_core_pll_setup(struct mtk_eth_priv *priv, int mcm) ++{ ++ /* Step 1 : Disable MT7531 COREPLL */ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_EN, EN_COREPLL, 0); ++ ++ /* Step 2: switch to XTAL output */ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_EN, SW_CLKSW, SW_CLKSW); ++ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_EN, 0); ++ ++ /* Step 3: disable PLLGP and enable program PLLGP */ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_EN, SW_PLLGP, SW_PLLGP); ++ ++ /* Step 4: program COREPLL output frequency to 500MHz */ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_POSDIV_M, ++ 2 << RG_COREPLL_POSDIV_S); ++ udelay(25); ++ ++ /* Currently, support XTAL 25Mhz only */ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_M, ++ 0x140000 << RG_COREPLL_SDM_PCW_S); ++ ++ /* Set feedback divide ratio update signal to high */ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_CHG, ++ RG_COREPLL_SDM_PCW_CHG); ++ ++ /* Wait for at least 16 XTAL clocks */ ++ udelay(10); ++ ++ /* Step 5: set feedback divide ratio update signal to low */ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_CHG, 0); ++ ++ /* add enable 325M clock for SGMII */ ++ mt753x_reg_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000); ++ ++ /* add enable 250SSC clock for RGMII */ ++ mt753x_reg_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000); ++ ++ /*Step 6: Enable MT7531 PLL */ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_EN, RG_COREPLL_EN); ++ ++ mt753x_reg_rmw(priv, MT7531_PLLGP_EN, EN_COREPLL, EN_COREPLL); ++ ++ udelay(25); ++} ++ ++static int mt7531_port_sgmii_init(struct mtk_eth_priv *priv, ++ u32 port) ++{ ++ if (port != 5 && port != 6) { ++ printf("mt7531: port %d is not a SGMII port\n", port); ++ return -EINVAL; ++ } ++ ++ /* Set SGMII GEN2 speed(2.5G) */ ++ mt753x_reg_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port), ++ SGMSYS_SPEED_2500, SGMSYS_SPEED_2500); ++ ++ /* Disable SGMII AN */ ++ mt753x_reg_rmw(priv, MT7531_PCS_CONTROL_1(port), ++ SGMII_AN_ENABLE, 0); ++ ++ /* SGMII force mode setting */ ++ mt753x_reg_write(priv, MT7531_SGMII_MODE(port), SGMII_FORCE_MODE); ++ ++ /* Release PHYA power down state */ ++ mt753x_reg_rmw(priv, MT7531_QPHY_PWR_STATE_CTRL(port), ++ SGMII_PHYA_PWD, 0); ++ ++ return 0; ++} ++ ++static int mt7531_port_rgmii_init(struct mtk_eth_priv *priv, u32 port) ++{ ++ u32 val; ++ ++ if (port != 5) { ++ printf("error: RGMII mode is not available for port %d\n", ++ port); ++ return -EINVAL; ++ } ++ ++ mt753x_reg_read(priv, MT7531_CLKGEN_CTRL, &val); ++ val |= GP_CLK_EN; ++ val &= ~GP_MODE_M; ++ val |= GP_MODE_RGMII << GP_MODE_S; ++ val |= TXCLK_NO_REVERSE; ++ val |= RXCLK_NO_DELAY; ++ val &= ~CLK_SKEW_IN_M; ++ val |= CLK_SKEW_IN_NO_CHANGE << CLK_SKEW_IN_S; ++ val &= ~CLK_SKEW_OUT_M; ++ val |= CLK_SKEW_OUT_NO_CHANGE << CLK_SKEW_OUT_S; ++ mt753x_reg_write(priv, MT7531_CLKGEN_CTRL, val); ++ ++ return 0; ++} ++ ++static void mt7531_phy_setting(struct mtk_eth_priv *priv) ++{ ++ int i; ++ u32 val; ++ ++ for (i = 0; i < MT753X_NUM_PHYS; i++) { ++ /* Enable HW auto downshift */ ++ priv->mii_write(priv, i, 0x1f, 0x1); ++ val = priv->mii_read(priv, i, PHY_EXT_REG_14); ++ val |= PHY_EN_DOWN_SHFIT; ++ priv->mii_write(priv, i, PHY_EXT_REG_14, val); ++ ++ /* PHY link down power saving enable */ ++ val = priv->mii_read(priv, i, PHY_EXT_REG_17); ++ val |= PHY_LINKDOWN_POWER_SAVING_EN; ++ priv->mii_write(priv, i, PHY_EXT_REG_17, val); ++ ++ val = priv->mmd_read(priv, i, 0x1e, PHY_DEV1E_REG_0C6); ++ val &= ~PHY_POWER_SAVING_M; ++ val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S; ++ priv->mmd_write(priv, i, 0x1e, PHY_DEV1E_REG_0C6, val); ++ } ++} ++ ++static int mt7531_setup(struct mtk_eth_priv *priv) ++{ ++ u16 phy_addr, phy_val; ++ u32 val; ++ u32 pmcr; ++ u32 port5_sgmii; ++ int i; ++ ++ priv->mt753x_phy_base = (priv->mt753x_smi_addr + 1) & ++ MT753X_SMI_ADDR_MASK; ++ ++ /* Turn off PHYs */ ++ for (i = 0; i < MT753X_NUM_PHYS; i++) { ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i); ++ phy_val = priv->mii_read(priv, phy_addr, MII_BMCR); ++ phy_val |= BMCR_PDOWN; ++ priv->mii_write(priv, phy_addr, MII_BMCR, phy_val); ++ } ++ ++ /* Force MAC link down before reset */ ++ mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK); ++ mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK); ++ ++ /* Switch soft reset */ ++ mt753x_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST); ++ udelay(100); ++ ++ /* Enable MDC input Schmitt Trigger */ ++ mt753x_reg_rmw(priv, MT7531_SMT0_IOLB, SMT_IOLB_5_SMI_MDC_EN, ++ SMT_IOLB_5_SMI_MDC_EN); ++ ++ mt7531_core_pll_setup(priv, priv->mcm); ++ ++ mt753x_reg_read(priv, MT7531_TOP_SIG_SR, &val); ++ port5_sgmii = !!(val & PAD_DUAL_SGMII_EN); ++ ++ /* port5 support either RGMII or SGMII, port6 only support SGMII. */ ++ switch (priv->phy_interface) { ++ case PHY_INTERFACE_MODE_RGMII: ++ if (!port5_sgmii) ++ mt7531_port_rgmii_init(priv, 5); ++ break; ++ case PHY_INTERFACE_MODE_SGMII: ++ mt7531_port_sgmii_init(priv, 6); ++ if (port5_sgmii) ++ mt7531_port_sgmii_init(priv, 5); ++ break; ++ default: ++ break; ++ } ++ ++ pmcr = MT7531_FORCE_MODE | ++ (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | ++ MAC_MODE | MAC_TX_EN | MAC_RX_EN | ++ BKOFF_EN | BACKPR_EN | ++ FORCE_RX_FC | FORCE_TX_FC | ++ (SPEED_1000M << FORCE_SPD_S) | FORCE_DPX | ++ FORCE_LINK; ++ ++ mt753x_reg_write(priv, PMCR_REG(5), pmcr); ++ mt753x_reg_write(priv, PMCR_REG(6), pmcr); + + /* Turn on PHYs */ +- for (i = 0; i < MT7530_NUM_PHYS; i++) { +- phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, i); ++ for (i = 0; i < MT753X_NUM_PHYS; i++) { ++ phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i); + phy_val = priv->mii_read(priv, phy_addr, MII_BMCR); + phy_val &= ~BMCR_PDOWN; + priv->mii_write(priv, phy_addr, MII_BMCR, phy_val); + } + ++ mt7531_phy_setting(priv); ++ ++ /* Enable Internal PHYs */ ++ val = mt753x_core_reg_read(priv, CORE_PLL_GROUP4); ++ val |= MT7531_BYPASS_MODE; ++ val &= ~MT7531_POWER_ON_OFF; ++ mt753x_core_reg_write(priv, CORE_PLL_GROUP4, val); ++ ++ return 0; ++} ++ ++int mt753x_switch_init(struct mtk_eth_priv *priv) ++{ ++ int ret; ++ int i; ++ ++ /* Global reset switch */ ++ if (priv->mcm) { ++ reset_assert(&priv->rst_mcm); ++ udelay(1000); ++ reset_deassert(&priv->rst_mcm); ++ mdelay(1000); ++ } else if (dm_gpio_is_valid(&priv->rst_gpio)) { ++ dm_gpio_set_value(&priv->rst_gpio, 0); ++ udelay(1000); ++ dm_gpio_set_value(&priv->rst_gpio, 1); ++ mdelay(1000); ++ } ++ ++ ret = priv->switch_init(priv); ++ if (ret) ++ return ret; ++ + /* Set port isolation */ +- for (i = 0; i < 8; i++) { ++ for (i = 0; i < MT753X_NUM_PORTS; i++) { + /* Set port matrix mode */ + if (i != 6) +- mt7530_reg_write(priv, PCR_REG(i), ++ mt753x_reg_write(priv, PCR_REG(i), + (0x40 << PORT_MATRIX_S)); + else +- mt7530_reg_write(priv, PCR_REG(i), ++ mt753x_reg_write(priv, PCR_REG(i), + (0x3f << PORT_MATRIX_S)); + + /* Set port mode to user port */ +- mt7530_reg_write(priv, PVC_REG(i), ++ mt753x_reg_write(priv, PVC_REG(i), + (0x8100 << STAG_VPID_S) | + (VLAN_ATTR_USER << VLAN_ATTR_S)); + } +@@ -658,7 +992,7 @@ static void mtk_phy_link_adjust(struct mtk_eth_priv *priv) + u8 flowctrl; + u32 mcr; + +- mcr = (1 << IPG_CFG_S) | ++ mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) | + MAC_MODE | FORCE_MODE | + MAC_TX_EN | MAC_RX_EN | +@@ -803,7 +1137,7 @@ static void mtk_mac_init(struct mtk_eth_priv *priv) + ge_mode << SYSCFG0_GE_MODE_S(priv->gmac_id)); + + if (priv->force_mode) { +- mcr = (1 << IPG_CFG_S) | ++ mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) | + (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) | + MAC_MODE | FORCE_MODE | + MAC_TX_EN | MAC_RX_EN | +@@ -1050,7 +1384,7 @@ static int mtk_eth_probe(struct udevice *dev) + return mtk_phy_probe(dev); + + /* Initialize switch */ +- return priv->switch_init(priv); ++ return mt753x_switch_init(priv); + } + + static int mtk_eth_remove(struct udevice *dev) +@@ -1159,7 +1493,11 @@ static int mtk_eth_ofdata_to_platdata(struct udevice *dev) + if (!strcmp(str, "mt7530")) { + priv->sw = SW_MT7530; + priv->switch_init = mt7530_setup; +- priv->mt7530_smi_addr = MT7530_DFL_SMI_ADDR; ++ priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR; ++ } else if (!strcmp(str, "mt7531")) { ++ priv->sw = SW_MT7531; ++ priv->switch_init = mt7531_setup; ++ priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR; + } else { + printf("error: unsupported switch\n"); + return -EINVAL; +diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h +index 9bb037d440..f2940c9996 100644 +--- a/drivers/net/mtk_eth.h ++++ b/drivers/net/mtk_eth.h +@@ -34,7 +34,9 @@ + + /* SGMII subsystem config registers */ + #define SGMSYS_PCS_CONTROL_1 0x0 ++#define SGMII_LINK_STATUS BIT(18) + #define SGMII_AN_ENABLE BIT(12) ++#define SGMII_AN_RESTART BIT(9) + + #define SGMSYS_SGMII_MODE 0x20 + #define SGMII_FORCE_MODE 0x31120019 +@@ -139,6 +141,11 @@ + #define FORCE_DPX BIT(1) + #define FORCE_LINK BIT(0) + ++/* Values of IPG_CFG */ ++#define IPG_96BIT 0 ++#define IPG_96BIT_WITH_SHORT_IPG 1 ++#define IPG_64BIT 2 ++ + /* MAC_RX_PKT_LEN: Max RX packet length */ + #define MAC_RX_PKT_LEN_1518 0 + #define MAC_RX_PKT_LEN_1536 1 +@@ -178,17 +185,73 @@ + #define VLAN_ATTR_TRANSLATION 2 + #define VLAN_ATTR_TRANSPARENT 3 + +-#define PCMR_REG(p) (0x3000 + (p) * 0x100) +-/* XXX: all fields are defined under GMAC_PORT_MCR */ +- ++#define PMCR_REG(p) (0x3000 + (p) * 0x100) ++/* XXX: all fields of MT7530 are defined under GMAC_PORT_MCR ++ * MT7531 specific fields are defined below ++ */ ++#define FORCE_MODE_EEE1G BIT(25) ++#define FORCE_MODE_EEE100 BIT(26) ++#define FORCE_MODE_TX_FC BIT(27) ++#define FORCE_MODE_RX_FC BIT(28) ++#define FORCE_MODE_DPX BIT(29) ++#define FORCE_MODE_SPD BIT(30) ++#define FORCE_MODE_LNK BIT(31) ++#define MT7531_FORCE_MODE FORCE_MODE_EEE1G | FORCE_MODE_EEE100 |\ ++ FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \ ++ FORCE_MODE_DPX | FORCE_MODE_SPD | \ ++ FORCE_MODE_LNK ++ ++/* MT7531 SGMII Registers */ ++#define MT7531_SGMII_REG_BASE 0x5000 ++#define MT7531_SGMII_REG_PORT_BASE 0x1000 ++#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \ ++ (p) * MT7531_SGMII_REG_PORT_BASE + (r)) ++#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(((p) - 5), 0x00) ++#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(((p) - 5), 0x20) ++#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(((p) - 5), 0xe8) ++#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(((p) - 5), 0x128) ++/* XXX: all fields of MT7531 SGMII are defined under SGMSYS */ ++ ++/* MT753x System Control Register */ + #define SYS_CTRL_REG 0x7000 + #define SW_PHY_RST BIT(2) + #define SW_SYS_RST BIT(1) + #define SW_REG_RST BIT(0) + +-#define NUM_TRGMII_CTRL 5 ++/* MT7531 */ ++#define MT7531_PHY_IAC 0x701c ++/* XXX: all fields are defined under GMAC_PIAC_REG */ ++ ++#define MT7531_CLKGEN_CTRL 0x7500 ++#define CLK_SKEW_OUT_S 8 ++#define CLK_SKEW_OUT_M 0x300 ++#define CLK_SKEW_IN_S 6 ++#define CLK_SKEW_IN_M 0xc0 ++#define RXCLK_NO_DELAY BIT(5) ++#define TXCLK_NO_REVERSE BIT(4) ++#define GP_MODE_S 1 ++#define GP_MODE_M 0x06 ++#define GP_CLK_EN BIT(0) ++ ++/* Values of GP_MODE */ ++#define GP_MODE_RGMII 0 ++#define GP_MODE_MII 1 ++#define GP_MODE_REV_MII 2 ++ ++/* Values of CLK_SKEW_IN */ ++#define CLK_SKEW_IN_NO_CHANGE 0 ++#define CLK_SKEW_IN_DELAY_100PPS 1 ++#define CLK_SKEW_IN_DELAY_200PPS 2 ++#define CLK_SKEW_IN_REVERSE 3 ++ ++/* Values of CLK_SKEW_OUT */ ++#define CLK_SKEW_OUT_NO_CHANGE 0 ++#define CLK_SKEW_OUT_DELAY_100PPS 1 ++#define CLK_SKEW_OUT_DELAY_200PPS 2 ++#define CLK_SKEW_OUT_REVERSE 3 + + #define HWTRAP_REG 0x7800 ++/* MT7530 Modified Hardware Trap Status Registers */ + #define MHWTRAP_REG 0x7804 + #define CHG_TRAP BIT(16) + #define LOOPDET_DIS BIT(14) +@@ -222,6 +285,8 @@ + #define P6_INTF_MODE_RGMII 0 + #define P6_INTF_MODE_TRGMII 1 + ++#define NUM_TRGMII_CTRL 5 ++ + #define MT7530_TRGMII_RD(n) (0x7a10 + (n) * 8) + #define RD_TAP_S 0 + #define RD_TAP_M 0x7f +@@ -229,8 +294,34 @@ + #define MT7530_TRGMII_TD_ODT(n) (0x7a54 + (n) * 8) + /* XXX: all fields are defined under GMAC_TRGMII_TD_ODT */ + +-/* MT7530 GPHY MDIO Indirect Access Registers */ ++/* TOP Signals Status Register */ ++#define MT7531_TOP_SIG_SR 0x780c ++#define PAD_MCM_SMI_EN BIT(0) ++#define PAD_DUAL_SGMII_EN BIT(1) ++ ++/* MT7531 PLLGP Registers */ ++#define MT7531_PLLGP_EN 0x7820 ++#define EN_COREPLL BIT(2) ++#define SW_CLKSW BIT(1) ++#define SW_PLLGP BIT(0) ++ ++#define MT7531_PLLGP_CR0 0x78a8 ++#define RG_COREPLL_EN BIT(22) ++#define RG_COREPLL_POSDIV_S 23 ++#define RG_COREPLL_POSDIV_M 0x3800000 ++#define RG_COREPLL_SDM_PCW_S 1 ++#define RG_COREPLL_SDM_PCW_M 0x3ffffe ++#define RG_COREPLL_SDM_PCW_CHG BIT(0) ++ ++/* MT7531 RGMII and SGMII PLL clock */ ++#define MT7531_ANA_PLLGP_CR2 0x78b0 ++#define MT7531_ANA_PLLGP_CR5 0x78bc ++ ++/* MT7531 GPIO GROUP IOLB SMT0 Control */ ++#define MT7531_SMT0_IOLB 0x7f04 ++#define SMT_IOLB_5_SMI_MDC_EN BIT(5) + ++/* MT7530 GPHY MDIO Indirect Access Registers */ + #define MII_MMD_ACC_CTL_REG 0x0d + #define MMD_CMD_S 14 + #define MMD_CMD_M 0xc000 +@@ -246,7 +337,6 @@ + #define MII_MMD_ADDR_DATA_REG 0x0e + + /* MT7530 GPHY MDIO MMD Registers */ +- + #define CORE_PLL_GROUP2 0x401 + #define RG_SYSPLL_EN_NORMAL BIT(15) + #define RG_SYSPLL_VODEN BIT(14) +@@ -254,6 +344,8 @@ + #define RG_SYSPLL_POSDIV_M 0x60 + + #define CORE_PLL_GROUP4 0x403 ++#define MT7531_BYPASS_MODE BIT(4) ++#define MT7531_POWER_ON_OFF BIT(5) + #define RG_SYSPLL_DDSFBK_EN BIT(12) + #define RG_SYSPLL_BIAS_EN BIT(11) + #define RG_SYSPLL_BIAS_LPF_EN BIT(10) +@@ -298,4 +390,24 @@ + #define REG_GSWCK_EN BIT(0) + #define REG_TRGMIICK_EN BIT(1) + ++/* Extend PHY Control Register 3 */ ++#define PHY_EXT_REG_14 0x14 ++ ++/* Fields of PHY_EXT_REG_14 */ ++#define PHY_EN_DOWN_SHFIT BIT(4) ++ ++/* Extend PHY Control Register 4 */ ++#define PHY_EXT_REG_17 0x17 ++ ++/* Fields of PHY_EXT_REG_17 */ ++#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4) ++ ++/* PHY RXADC Control Register 7 */ ++#define PHY_DEV1E_REG_0C6 0x0c6 ++ ++/* Fields of PHY_DEV1E_REG_0C6 */ ++#define PHY_POWER_SAVING_S 8 ++#define PHY_POWER_SAVING_M 0x300 ++#define PHY_POWER_SAVING_TX 0x0 ++ + #endif /* _MTK_ETH_H_ */ |