mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-21 22:47:56 +00:00
mediatek: backport pending Ethernet PHY driver patches
Use pending patchset for 2.5GE PHY driver, unifying LED handling accross all MediaTek Ethernet PHYs. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
963be1423f
commit
1069514978
@ -1490,6 +1490,23 @@
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <15>;
|
||||
phy-mode = "internal";
|
||||
|
||||
leds {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
i2p5gbe_led0: i2p5gbe-led0@0 {
|
||||
reg = <0>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2p5gbe_led1: i2p5gbe-led1@1 {
|
||||
reg = <1>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,321 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#define MT7988_2P5GE_PMB "mediatek/mt7988/i2p5ge-phy-pmb.bin"
|
||||
|
||||
#define MD32_EN BIT(0)
|
||||
#define PMEM_PRIORITY BIT(8)
|
||||
#define DMEM_PRIORITY BIT(16)
|
||||
|
||||
#define BASE100T_STATUS_EXTEND 0x10
|
||||
#define BASE1000T_STATUS_EXTEND 0x11
|
||||
#define EXTEND_CTRL_AND_STATUS 0x16
|
||||
|
||||
#define PHY_AUX_CTRL_STATUS 0x1d
|
||||
#define PHY_AUX_DPX_MASK GENMASK(5, 5)
|
||||
#define PHY_AUX_SPEED_MASK GENMASK(4, 2)
|
||||
|
||||
/* Registers on MDIO_MMD_VEND1 */
|
||||
#define MTK_PHY_LINK_STATUS_MISC 0xa2
|
||||
#define MTK_PHY_FDX_ENABLE BIT(5)
|
||||
|
||||
#define MTK_PHY_LPI_PCS_DSP_CTRL 0x121
|
||||
#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8)
|
||||
|
||||
/* Registers on MDIO_MMD_VEND2 */
|
||||
#define MTK_PHY_LED0_ON_CTRL 0x24
|
||||
#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
|
||||
#define MTK_PHY_LED0_ON_LINK100 BIT(1)
|
||||
#define MTK_PHY_LED0_ON_LINK10 BIT(2)
|
||||
#define MTK_PHY_LED0_ON_LINK2500 BIT(7)
|
||||
#define MTK_PHY_LED0_POLARITY BIT(14)
|
||||
|
||||
#define MTK_PHY_LED1_ON_CTRL 0x26
|
||||
#define MTK_PHY_LED1_ON_FDX BIT(4)
|
||||
#define MTK_PHY_LED1_ON_HDX BIT(5)
|
||||
#define MTK_PHY_LED1_POLARITY BIT(14)
|
||||
|
||||
#define MTK_EXT_PAGE_ACCESS 0x1f
|
||||
#define MTK_PHY_PAGE_STANDARD 0x0000
|
||||
#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
|
||||
|
||||
struct mtk_i2p5ge_phy_priv {
|
||||
bool fw_loaded;
|
||||
};
|
||||
|
||||
enum {
|
||||
PHY_AUX_SPD_10 = 0,
|
||||
PHY_AUX_SPD_100,
|
||||
PHY_AUX_SPD_1000,
|
||||
PHY_AUX_SPD_2500,
|
||||
};
|
||||
|
||||
static int mtk_2p5ge_phy_read_page(struct phy_device *phydev)
|
||||
{
|
||||
return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
|
||||
}
|
||||
|
||||
static int mtk_2p5ge_phy_write_page(struct phy_device *phydev, int page)
|
||||
{
|
||||
return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
|
||||
}
|
||||
|
||||
static int mt7988_2p5ge_phy_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct mtk_i2p5ge_phy_priv *phy_priv;
|
||||
|
||||
phy_priv = devm_kzalloc(&phydev->mdio.dev,
|
||||
sizeof(struct mtk_i2p5ge_phy_priv), GFP_KERNEL);
|
||||
if (!phy_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
phydev->priv = phy_priv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7988_2p5ge_phy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret, i;
|
||||
const struct firmware *fw;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct device_node *np;
|
||||
void __iomem *pmb_addr;
|
||||
void __iomem *md32_en_cfg_base;
|
||||
struct mtk_i2p5ge_phy_priv *phy_priv = phydev->priv;
|
||||
u16 reg;
|
||||
struct pinctrl *pinctrl;
|
||||
|
||||
if (!phy_priv->fw_loaded) {
|
||||
np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw");
|
||||
if (!np)
|
||||
return -ENOENT;
|
||||
pmb_addr = of_iomap(np, 0);
|
||||
if (!pmb_addr)
|
||||
return -ENOMEM;
|
||||
md32_en_cfg_base = of_iomap(np, 1);
|
||||
if (!md32_en_cfg_base)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = request_firmware(&fw, MT7988_2P5GE_PMB, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to load firmware: %s, ret: %d\n",
|
||||
MT7988_2P5GE_PMB, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg = readw(md32_en_cfg_base);
|
||||
if (reg & MD32_EN) {
|
||||
phy_set_bits(phydev, 0, BIT(15));
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
phy_set_bits(phydev, 0, BIT(11));
|
||||
|
||||
/* 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);
|
||||
|
||||
for (i = 0; i < fw->size - 1; i += 4)
|
||||
writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
|
||||
release_firmware(fw);
|
||||
|
||||
writew(reg & ~MD32_EN, md32_en_cfg_base);
|
||||
writew(reg | MD32_EN, md32_en_cfg_base);
|
||||
phy_set_bits(phydev, 0, BIT(15));
|
||||
dev_info(dev, "Firmware loading/trigger ok.\n");
|
||||
|
||||
phy_priv->fw_loaded = true;
|
||||
}
|
||||
|
||||
/* Setup LED */
|
||||
|
||||
/* Set polarity of led0 to active-high for BPI-R4 */
|
||||
phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
|
||||
MTK_PHY_LED0_POLARITY);
|
||||
|
||||
phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
|
||||
MTK_PHY_LED0_ON_LINK10 |
|
||||
MTK_PHY_LED0_ON_LINK100 |
|
||||
MTK_PHY_LED0_ON_LINK1000 |
|
||||
MTK_PHY_LED0_ON_LINK2500);
|
||||
phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
|
||||
MTK_PHY_LED1_ON_FDX | MTK_PHY_LED1_ON_HDX);
|
||||
|
||||
pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
|
||||
if (IS_ERR(pinctrl)) {
|
||||
dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
|
||||
return PTR_ERR(pinctrl);
|
||||
}
|
||||
|
||||
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL,
|
||||
MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0);
|
||||
|
||||
/* Enable 16-bit next page exchange bit if 1000-BT isn't advertizing */
|
||||
phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
|
||||
__phy_write(phydev, 0x11, 0xfbfa);
|
||||
__phy_write(phydev, 0x12, 0xc3);
|
||||
__phy_write(phydev, 0x10, 0x87f8);
|
||||
phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7988_2p5ge_phy_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
bool changed = false;
|
||||
u32 adv;
|
||||
int ret;
|
||||
|
||||
if (phydev->autoneg == AUTONEG_DISABLE) {
|
||||
/* Configure half duplex with genphy_setup_forced,
|
||||
* because genphy_c45_pma_setup_forced does not support.
|
||||
*/
|
||||
return phydev->duplex != DUPLEX_FULL
|
||||
? genphy_setup_forced(phydev)
|
||||
: genphy_c45_pma_setup_forced(phydev);
|
||||
}
|
||||
|
||||
ret = genphy_c45_an_config_aneg(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
changed = true;
|
||||
|
||||
adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
|
||||
ret = phy_modify_changed(phydev, MII_CTRL1000,
|
||||
ADVERTISE_1000FULL | ADVERTISE_1000HALF,
|
||||
adv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
changed = true;
|
||||
|
||||
return genphy_c45_check_and_restart_aneg(phydev, changed);
|
||||
}
|
||||
|
||||
static int mt7988_2p5ge_phy_get_features(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = genphy_read_abilities(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* We don't support HDX at MAC layer on mt7988.
|
||||
* So mask phy's HDX capabilities, too.
|
||||
*/
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7988_2p5ge_phy_read_status(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = genphy_update_link(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
phydev->speed = SPEED_UNKNOWN;
|
||||
phydev->duplex = DUPLEX_UNKNOWN;
|
||||
phydev->pause = 0;
|
||||
phydev->asym_pause = 0;
|
||||
|
||||
if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
|
||||
ret = genphy_c45_read_lpa(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Read the link partner's 1G advertisement */
|
||||
ret = phy_read(phydev, MII_STAT1000);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
|
||||
} else if (phydev->autoneg == AUTONEG_DISABLE) {
|
||||
linkmode_zero(phydev->lp_advertising);
|
||||
}
|
||||
|
||||
ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
|
||||
case PHY_AUX_SPD_10:
|
||||
phydev->speed = SPEED_10;
|
||||
break;
|
||||
case PHY_AUX_SPD_100:
|
||||
phydev->speed = SPEED_100;
|
||||
break;
|
||||
case PHY_AUX_SPD_1000:
|
||||
phydev->speed = SPEED_1000;
|
||||
break;
|
||||
case PHY_AUX_SPD_2500:
|
||||
phydev->speed = SPEED_2500;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
phydev->duplex = (ret & MTK_PHY_FDX_ENABLE) ? DUPLEX_FULL : DUPLEX_HALF;
|
||||
/* FIXME: The current firmware always enables rate adaptation mode. */
|
||||
phydev->rate_matching = RATE_MATCH_PAUSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7988_2p5ge_phy_get_rate_matching(struct phy_device *phydev,
|
||||
phy_interface_t iface)
|
||||
{
|
||||
return RATE_MATCH_PAUSE;
|
||||
}
|
||||
|
||||
static struct phy_driver mtk_gephy_driver[] = {
|
||||
{
|
||||
PHY_ID_MATCH_MODEL(0x00339c11),
|
||||
.name = "MediaTek MT798x 2.5GbE PHY",
|
||||
.probe = mt7988_2p5ge_phy_probe,
|
||||
.config_init = mt7988_2p5ge_phy_config_init,
|
||||
.config_aneg = mt7988_2p5ge_phy_config_aneg,
|
||||
.get_features = mt7988_2p5ge_phy_get_features,
|
||||
.read_status = mt7988_2p5ge_phy_read_status,
|
||||
.get_rate_matching = mt7988_2p5ge_phy_get_rate_matching,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
.read_page = mtk_2p5ge_phy_read_page,
|
||||
.write_page = mtk_2p5ge_phy_write_page,
|
||||
},
|
||||
};
|
||||
|
||||
module_phy_driver(mtk_gephy_driver);
|
||||
|
||||
static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
|
||||
{ PHY_ID_MATCH_VENDOR(0x00339c00) },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
|
||||
MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
|
||||
MODULE_FIRMWARE(MT7988_2P5GE_PMB);
|
@ -240,7 +240,7 @@ CONFIG_MAXLINEAR_GPHY=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEDIATEK_2P5G_PHY=y
|
||||
CONFIG_MEDIATEK_2P5GE_PHY=y
|
||||
CONFIG_MEDIATEK_GE_PHY=y
|
||||
CONFIG_MEDIATEK_GE_SOC_PHY=y
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,62 @@
|
||||
From 12054d38fc55adbfa2b40299ad8af3449d882ee2 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:06 +0800
|
||||
Subject: [PATCH 02/13] 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 <skylake.huang@mediatek.com>
|
||||
---
|
||||
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
|
@ -0,0 +1,742 @@
|
||||
From 434e41555c45ec10b19320024163bb009da168bc Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:07 +0800
|
||||
Subject: [PATCH 03/13] 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 <skylake.huang@mediatek.com>
|
||||
---
|
||||
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 ++++++++
|
||||
6 files changed, 368 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 <linux/phy.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
+#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 <linux/phy.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+#include <linux/netdevice.h>
|
||||
+
|
||||
+#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 <SkyLake.Huang@mediatek.com>");
|
||||
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
|
||||
+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 <SkyLake.Huang@mediatek.com>
|
||||
+ * 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_ */
|
@ -0,0 +1,70 @@
|
||||
From 2783929879854d5750ba82e2e203663313362abb Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:08 +0800
|
||||
Subject: [PATCH 04/13] 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 <skylake.huang@mediatek.com>
|
||||
---
|
||||
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)
|
@ -0,0 +1,141 @@
|
||||
From 58c1270423ab48464cdc31ef71ffe7f5b2441961 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:09 +0800
|
||||
Subject: [PATCH 05/13] 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 <skylake.huang@mediatek.com>
|
||||
---
|
||||
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 <linux/module.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
+#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);
|
@ -0,0 +1,146 @@
|
||||
From 9403f1d54598ae56386a8bf47a5b6b34c884e4f5 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:10 +0800
|
||||
Subject: [PATCH 06/13] 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 <skylake.huang@mediatek.com>
|
||||
---
|
||||
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,
|
||||
},
|
||||
};
|
||||
|
@ -0,0 +1,54 @@
|
||||
From 51ee83602dbb84716180d9b6e43f6bebb0c2d7bd Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:11 +0800
|
||||
Subject: [PATCH 07/13] 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 <skylake.huang@mediatek.com>
|
||||
---
|
||||
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) },
|
||||
{ }
|
||||
};
|
||||
|
@ -0,0 +1,182 @@
|
||||
From e73df692396b0d6bdcb2317299fa1e8e547f3446 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:12 +0800
|
||||
Subject: [PATCH 08/13] 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 <skylake.huang@mediatek.com>
|
||||
---
|
||||
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;
|
||||
}
|
@ -0,0 +1,614 @@
|
||||
From 60228de48d8bfde62b4db5945314e6a62079f091 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:13 +0800
|
||||
Subject: [PATCH 09/13] 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 <skylake.huang@mediatek.com>
|
||||
---
|
||||
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);
|
||||
|
@ -0,0 +1,209 @@
|
||||
From 3c05195fc2c232cd853fc8cebf55310c4605111d Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:14 +0800
|
||||
Subject: [PATCH 10/13] net: phy: mediatek: Extend 1G TX/RX link pulse time
|
||||
|
||||
We observe that some 10G devices' (mostly Marvell's chips inside) 1G
|
||||
training time violates specification, which may last 2230ms and affect
|
||||
later TX/RX link pulse time. This will invalidate MediaTek series
|
||||
gigabit Ethernet PHYs' hardware auto downshift mechanism.
|
||||
|
||||
Without this patch, if someone is trying to use "4-wire" cable to
|
||||
connect above devices, MediaTek' gigabit Ethernet PHYs may fail
|
||||
to downshift to 100Mbps. (If partner 10G devices' downshift mechanism
|
||||
stops at 1G)
|
||||
|
||||
This patch extends our 1G TX/RX link pulse time so that we can still
|
||||
link up with those 10G devices.
|
||||
|
||||
Tested device:
|
||||
- Netgear GS110EMX's 10G port (Marvell 88X3340P)
|
||||
- QNAP QSW-M408-4C
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/net/phy/mediatek/mtk-ge-soc.c | 2 +
|
||||
drivers/net/phy/mediatek/mtk-ge.c | 5 +-
|
||||
drivers/net/phy/mediatek/mtk-phy-lib.c | 92 ++++++++++++++++++++++++++
|
||||
drivers/net/phy/mediatek/mtk.h | 21 ++++++
|
||||
4 files changed, 116 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
@@ -1396,6 +1396,7 @@ static struct phy_driver mtk_socphy_driv
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
|
||||
.name = "MediaTek MT7981 PHY",
|
||||
.config_init = mt798x_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
.config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
.probe = mt7981_phy_probe,
|
||||
@@ -1413,6 +1414,7 @@ static struct phy_driver mtk_socphy_driv
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
|
||||
.name = "MediaTek MT7988 PHY",
|
||||
.config_init = mt798x_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
.config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
.probe = mt7988_phy_probe,
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge.c
|
||||
@@ -9,10 +9,6 @@
|
||||
#define MTK_GPHY_ID_MT7530 0x03a29412
|
||||
#define MTK_GPHY_ID_MT7531 0x03a29441
|
||||
|
||||
-#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
|
||||
@@ -251,6 +247,7 @@ static struct phy_driver mtk_gephy_drive
|
||||
.name = "MediaTek MT7531 PHY",
|
||||
.probe = mt7531_phy_probe,
|
||||
.config_init = mt7531_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
/* Interrupts are handled by the switch, not the PHY
|
||||
* itself.
|
||||
*/
|
||||
--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
|
||||
@@ -109,6 +109,98 @@ int mtk_phy_write_page(struct phy_device
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mtk_phy_write_page);
|
||||
|
||||
+/* This function deals with the case that 1G AN starts but isn't completed. We
|
||||
+ * set AN_NEW_LP_CNT_LIMIT with different values time after time to let our
|
||||
+ * 1G->100Mbps hardware automatic downshift to fit more partner devices.
|
||||
+ */
|
||||
+static int extend_an_new_lp_cnt_limit(struct phy_device *phydev)
|
||||
+{
|
||||
+ int mmd_read_ret;
|
||||
+ u32 reg_val;
|
||||
+ int timeout;
|
||||
+
|
||||
+ /* According to table 28-9 & Figure 28-18 in IEEE 802.3,
|
||||
+ * link_fail_inhibit_timer of 10/100/1000 Mbps devices ranges from 750
|
||||
+ * to "1000ms". Once MTK_PHY_FINAL_SPEED_1000 is set, it means that we
|
||||
+ * enter "FLP LINK GOOD CHECK" state, link_fail_inhibit_timer starts and
|
||||
+ * this PHY's 1G training starts. If 1G training never starts, we do
|
||||
+ * nothing but leave.
|
||||
+ */
|
||||
+ timeout = read_poll_timeout(mmd_read_ret = phy_read_mmd, reg_val,
|
||||
+ (mmd_read_ret < 0) ||
|
||||
+ reg_val & MTK_PHY_FINAL_SPEED_1000,
|
||||
+ 10000, 1000000, false, phydev,
|
||||
+ MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
|
||||
+ if (mmd_read_ret < 0)
|
||||
+ return mmd_read_ret;
|
||||
+
|
||||
+ if (!timeout) {
|
||||
+ /* Once we found MTK_PHY_FINAL_SPEED_1000 is set, no matter 1G
|
||||
+ * AN is completed or not, we'll set AN_NEW_LP_CNT_LIMIT again
|
||||
+ * and again.
|
||||
+ */
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK, 0xf));
|
||||
+ mdelay(1500);
|
||||
+
|
||||
+ timeout = read_poll_timeout(mtk_tr_read, reg_val,
|
||||
+ (reg_val & AN_STATE_MASK) !=
|
||||
+ (AN_STATE_TX_DISABLE <<
|
||||
+ AN_STATE_SHIFT),
|
||||
+ 10000, 1000000, false, phydev,
|
||||
+ 0x0, 0xf, 0x2);
|
||||
+ if (!timeout) {
|
||||
+ mdelay(625);
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
|
||||
+ AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ 0x8));
|
||||
+ mdelay(500);
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
|
||||
+ AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ 0xf));
|
||||
+ } else {
|
||||
+ return -ETIMEDOUT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int mtk_gphy_cl22_read_status(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = genphy_read_status(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete) {
|
||||
+ ret = phy_read_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
|
||||
+ MTK_PHY_AUX_CTRL_AND_STATUS);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Once LP_DETECTED is set, it means that"ability_match" in
|
||||
+ * IEEE 802.3 Figure 28-18 is set. This happens after we plug in
|
||||
+ * cable. Also, LP_DETECTED will be cleared after AN complete.
|
||||
+ */
|
||||
+ if (!FIELD_GET(MTK_PHY_LP_DETECTED_MASK, ret))
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = phy_read(phydev, MII_CTRL1000);
|
||||
+ if (ret & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) {
|
||||
+ ret = extend_an_new_lp_cnt_limit(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(mtk_gphy_cl22_read_status);
|
||||
+
|
||||
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
|
||||
@@ -10,8 +10,28 @@
|
||||
|
||||
#define MTK_EXT_PAGE_ACCESS 0x1f
|
||||
#define MTK_PHY_PAGE_STANDARD 0x0000
|
||||
+#define MTK_PHY_PAGE_EXTENDED_1 0x0001
|
||||
+#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
|
||||
+/* suprv_media_select_RefClk */
|
||||
+#define MTK_PHY_LP_DETECTED_MASK GENMASK(7, 6)
|
||||
+#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
|
||||
+
|
||||
#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
|
||||
|
||||
+/* Registers on Token Ring debug nodes */
|
||||
+/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x2 */
|
||||
+#define AN_STATE_MASK GENMASK(22, 19)
|
||||
+#define AN_STATE_SHIFT 19
|
||||
+#define AN_STATE_TX_DISABLE 1
|
||||
+
|
||||
+/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
|
||||
+#define AN_NEW_LP_CNT_LIMIT_MASK GENMASK(23, 20)
|
||||
+#define AUTO_NP_10XEN BIT(6)
|
||||
+
|
||||
+/* Registers on MDIO_MMD_VEND1 */
|
||||
+#define MTK_PHY_LINK_STATUS_MISC (0xa2)
|
||||
+#define MTK_PHY_FINAL_SPEED_1000 BIT(3)
|
||||
+
|
||||
/* Registers on MDIO_MMD_VEND2 */
|
||||
#define MTK_PHY_LED0_ON_CTRL 0x24
|
||||
#define MTK_PHY_LED1_ON_CTRL 0x26
|
||||
@@ -78,6 +98,7 @@ void __mtk_tr_clr_bits(struct phy_device
|
||||
int mtk_phy_read_page(struct phy_device *phydev);
|
||||
int mtk_phy_write_page(struct phy_device *phydev, int page);
|
||||
|
||||
+int mtk_gphy_cl22_read_status(struct phy_device *phydev);
|
||||
int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
|
||||
unsigned long rules,
|
||||
unsigned long supported_triggers);
|
@ -0,0 +1,477 @@
|
||||
From 69ca89165e39e6b6f4c79e6b4c03559e0fac7051 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
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(+)
|
||||
create mode 100644 drivers/net/phy/mediatek/mtk-2p5ge.c
|
||||
|
||||
--- a/drivers/net/phy/mediatek/Kconfig
|
||||
+++ b/drivers/net/phy/mediatek/Kconfig
|
||||
@@ -25,3 +25,14 @@ config MEDIATEK_GE_SOC_PHY
|
||||
the MT7981 and MT7988 SoCs. These PHYs need calibration data
|
||||
present in the SoCs efuse and will dynamically calibrate VCM
|
||||
(common-mode voltage) during startup.
|
||||
+
|
||||
+config MEDIATEK_2P5GE_PHY
|
||||
+ tristate "MediaTek 2.5Gb Ethernet PHYs"
|
||||
+ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
|
||||
+ select MTK_NET_PHYLIB
|
||||
+ help
|
||||
+ Supports MediaTek SoC built-in 2.5Gb Ethernet PHYs.
|
||||
+
|
||||
+ This will load necessary firmware and add appropriate time delay.
|
||||
+ Accelerate this procedure through internal pbus instead of MDIO
|
||||
+ bus. Certain link-up issues will also be fixed here.
|
||||
--- a/drivers/net/phy/mediatek/Makefile
|
||||
+++ b/drivers/net/phy/mediatek/Makefile
|
||||
@@ -2,3 +2,4 @@
|
||||
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
|
||||
+obj-$(CONFIG_MEDIATEK_2P5GE_PHY) += mtk-2p5ge.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/mediatek/mtk-2p5ge.c
|
||||
@@ -0,0 +1,432 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/firmware.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/pinctrl/consumer.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/pm_domain.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+
|
||||
+#include "mtk.h"
|
||||
+
|
||||
+#define MTK_2P5GPHY_ID_MT7988 (0x00339c11)
|
||||
+
|
||||
+#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 BIT(0)
|
||||
+
|
||||
+#define BASE100T_STATUS_EXTEND (0x10)
|
||||
+#define BASE1000T_STATUS_EXTEND (0x11)
|
||||
+#define EXTEND_CTRL_AND_STATUS (0x16)
|
||||
+
|
||||
+#define PHY_AUX_CTRL_STATUS (0x1d)
|
||||
+#define PHY_AUX_DPX_MASK GENMASK(5, 5)
|
||||
+#define PHY_AUX_SPEED_MASK GENMASK(4, 2)
|
||||
+
|
||||
+#define MTK_PHY_LPI_PCS_DSP_CTRL (0x121)
|
||||
+#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8)
|
||||
+
|
||||
+/* 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 {
|
||||
+ PHY_AUX_SPD_10 = 0,
|
||||
+ PHY_AUX_SPD_100,
|
||||
+ PHY_AUX_SPD_1000,
|
||||
+ PHY_AUX_SPD_2500,
|
||||
+};
|
||||
+
|
||||
+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;
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ const struct firmware *fw;
|
||||
+ int ret, i;
|
||||
+ u16 reg;
|
||||
+
|
||||
+ if (priv->fw_loaded)
|
||||
+ return 0;
|
||||
+
|
||||
+ pmb_addr = ioremap(MT7988_2P5GE_PMB_FW_BASE, MT7988_2P5GE_PMB_FW_LEN);
|
||||
+ 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) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto free_pmb;
|
||||
+ }
|
||||
+
|
||||
+ ret = request_firmware(&fw, MT7988_2P5GE_PMB_FW, dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to load firmware: %s, ret: %d\n",
|
||||
+ MT7988_2P5GE_PMB_FW, ret);
|
||||
+ goto free;
|
||||
+ }
|
||||
+
|
||||
+ if (fw->size != MT7988_2P5GE_PMB_FW_SIZE) {
|
||||
+ dev_err(dev, "Firmware size 0x%zx != 0x%x\n",
|
||||
+ fw->size, MT7988_2P5GE_PMB_FW_SIZE);
|
||||
+ ret = -EINVAL;
|
||||
+ goto release_fw;
|
||||
+ }
|
||||
+
|
||||
+ reg = readw(md32_en_cfg_base);
|
||||
+ if (reg & MD32_EN) {
|
||||
+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
|
||||
+ usleep_range(10000, 11000);
|
||||
+ }
|
||||
+ 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);
|
||||
+
|
||||
+ 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);
|
||||
+ 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);
|
||||
+free_pmb:
|
||||
+ iounmap(pmb_addr);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct pinctrl *pinctrl;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Check if PHY interface type is compatible */
|
||||
+ if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ret = mt798x_2p5ge_phy_load_fw(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Setup LED */
|
||||
+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
|
||||
+ MTK_PHY_LED_ON_POLARITY | MTK_PHY_LED_ON_LINK10 |
|
||||
+ MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK1000 |
|
||||
+ MTK_PHY_LED_ON_LINK2500);
|
||||
+ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
|
||||
+ MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX);
|
||||
+
|
||||
+ /* Switch pinctrl after setting polarity to avoid bogus blinking */
|
||||
+ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
|
||||
+ if (IS_ERR(pinctrl))
|
||||
+ dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
|
||||
+
|
||||
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL,
|
||||
+ MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0);
|
||||
+
|
||||
+ /* Enable 16-bit next page exchange bit if 1000-BT isn't advertising */
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AUTO_NP_10XEN,
|
||||
+ FIELD_PREP(AUTO_NP_10XEN, 0x1));
|
||||
+
|
||||
+ /* Enable HW auto downshift */
|
||||
+ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
|
||||
+ MTK_PHY_AUX_CTRL_AND_STATUS,
|
||||
+ 0, MTK_PHY_ENABLE_DOWNSHIFT);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mt798x_2p5ge_phy_config_aneg(struct phy_device *phydev)
|
||||
+{
|
||||
+ bool changed = false;
|
||||
+ 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;
|
||||
+ if (ret > 0)
|
||||
+ changed = true;
|
||||
+
|
||||
+ /* Clause 45 doesn't define 1000BaseT support. Use Clause 22 instead in
|
||||
+ * our design.
|
||||
+ */
|
||||
+ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
|
||||
+ ret = phy_modify_changed(phydev, MII_CTRL1000, ADVERTISE_1000FULL, adv);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ if (ret > 0)
|
||||
+ changed = true;
|
||||
+
|
||||
+ return genphy_c45_check_and_restart_aneg(phydev, changed);
|
||||
+}
|
||||
+
|
||||
+static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = genphy_c45_pma_read_abilities(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* This phy can't handle collision, and neither can (XFI)MAC it's
|
||||
+ * connected to. Although it can do HDX handshake, it doesn't support
|
||||
+ * CSMA/CD that HDX requires.
|
||||
+ */
|
||||
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
|
||||
+ phydev->supported);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mt798x_2p5ge_phy_read_status(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* When MDIO_STAT1_LSTATUS is raised genphy_c45_read_link(), this phy
|
||||
+ * actually hasn't finished AN. So use CL22's link update function
|
||||
+ * instead.
|
||||
+ */
|
||||
+ ret = genphy_update_link(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ phydev->speed = SPEED_UNKNOWN;
|
||||
+ phydev->duplex = DUPLEX_UNKNOWN;
|
||||
+ phydev->pause = 0;
|
||||
+ phydev->asym_pause = 0;
|
||||
+
|
||||
+ /* We'll read link speed through vendor specific registers down below.
|
||||
+ * So remove phy_resolve_aneg_linkmode (AN on) & genphy_c45_read_pma
|
||||
+ * (AN off).
|
||||
+ */
|
||||
+ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
|
||||
+ ret = genphy_c45_read_lpa(phydev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Clause 45 doesn't define 1000BaseT support. Read the link
|
||||
+ * partner's 1G advertisement via Clause 22.
|
||||
+ */
|
||||
+ ret = phy_read(phydev, MII_STAT1000);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
|
||||
+ } else if (phydev->autoneg == AUTONEG_DISABLE) {
|
||||
+ linkmode_zero(phydev->lp_advertising);
|
||||
+ }
|
||||
+
|
||||
+ if (phydev->link) {
|
||||
+ ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
|
||||
+ case PHY_AUX_SPD_10:
|
||||
+ phydev->speed = SPEED_10;
|
||||
+ break;
|
||||
+ case PHY_AUX_SPD_100:
|
||||
+ phydev->speed = SPEED_100;
|
||||
+ break;
|
||||
+ case PHY_AUX_SPD_1000:
|
||||
+ phydev->speed = SPEED_1000;
|
||||
+ break;
|
||||
+ case PHY_AUX_SPD_2500:
|
||||
+ phydev->speed = SPEED_2500;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ phydev->duplex = DUPLEX_FULL;
|
||||
+ /* FIXME:
|
||||
+ * The current firmware always enables rate adaptation mode.
|
||||
+ */
|
||||
+ phydev->rate_matching = RATE_MATCH_PAUSE;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mt798x_2p5ge_phy_get_rate_matching(struct phy_device *phydev,
|
||||
+ phy_interface_t iface)
|
||||
+{
|
||||
+ 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;
|
||||
+
|
||||
+ priv = devm_kzalloc(&phydev->mdio.dev,
|
||||
+ sizeof(struct mtk_i2p5ge_phy_priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ switch (phydev->drv->phy_id) {
|
||||
+ case MTK_2P5GPHY_ID_MT7988:
|
||||
+ /* The original hardware only sets MDIO_DEVS_PMAPMD */
|
||||
+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PCS |
|
||||
+ MDIO_DEVS_AN |
|
||||
+ MDIO_DEVS_VEND1 |
|
||||
+ MDIO_DEVS_VEND2;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ priv->fw_loaded = false;
|
||||
+ phydev->priv = priv;
|
||||
+
|
||||
+ mtk_phy_leds_state_init(phydev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct phy_driver mtk_2p5gephy_driver[] = {
|
||||
+ {
|
||||
+ PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7988),
|
||||
+ .name = "MediaTek MT7988 2.5GbE PHY",
|
||||
+ .probe = mt798x_2p5ge_phy_probe,
|
||||
+ .config_init = mt798x_2p5ge_phy_config_init,
|
||||
+ .config_aneg = mt798x_2p5ge_phy_config_aneg,
|
||||
+ .get_features = mt798x_2p5ge_phy_get_features,
|
||||
+ .read_status = mt798x_2p5ge_phy_read_status,
|
||||
+ .get_rate_matching = mt798x_2p5ge_phy_get_rate_matching,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .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,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_phy_driver(mtk_2p5gephy_driver);
|
||||
+
|
||||
+static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
|
||||
+ { PHY_ID_MATCH_VENDOR(0x00339c00) },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
|
||||
+MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
|
||||
+MODULE_FIRMWARE(MT7988_2P5GE_PMB_FW);
|
@ -0,0 +1,130 @@
|
||||
From 07e90eb1819319a0c34b0cf3a57a4a3878e96e4d Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:16 +0800
|
||||
Subject: [PATCH 12/13] net: phy: mediatek: Fix alignment in callback
|
||||
functions' hook
|
||||
|
||||
Align declarations in mtk_gephy_driver(mtk-ge.c) and
|
||||
mtk_socphy_driver(mtk-ge-soc.c). At first, some of them are
|
||||
".foo<tab>= method_foo", and others are ".bar<space>= method_bar".
|
||||
Use space instead for all of them here in case line is longer than
|
||||
80 chars.
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/net/phy/mediatek/mtk-ge-soc.c | 40 +++++++++++++--------------
|
||||
drivers/net/phy/mediatek/mtk-ge.c | 34 +++++++++++------------
|
||||
2 files changed, 37 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
@@ -1394,17 +1394,17 @@ static int mt7981_phy_probe(struct phy_d
|
||||
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,
|
||||
- .read_status = mtk_gphy_cl22_read_status,
|
||||
- .config_intr = genphy_no_config_intr,
|
||||
+ .name = "MediaTek MT7981 PHY",
|
||||
+ .config_init = mt798x_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
+ .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_phy_read_page,
|
||||
- .write_page = mtk_phy_write_page,
|
||||
- .led_blink_set = mt798x_phy_led_blink_set,
|
||||
+ .probe = mt7981_phy_probe,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ .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,
|
||||
.led_hw_control_set = mt798x_phy_led_hw_control_set,
|
||||
@@ -1412,17 +1412,17 @@ static struct phy_driver mtk_socphy_driv
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
|
||||
- .name = "MediaTek MT7988 PHY",
|
||||
- .config_init = mt798x_phy_config_init,
|
||||
- .read_status = mtk_gphy_cl22_read_status,
|
||||
- .config_intr = genphy_no_config_intr,
|
||||
+ .name = "MediaTek MT7988 PHY",
|
||||
+ .config_init = mt798x_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
+ .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_phy_read_page,
|
||||
- .write_page = mtk_phy_write_page,
|
||||
- .led_blink_set = mt798x_phy_led_blink_set,
|
||||
+ .probe = mt7988_phy_probe,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ .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,
|
||||
.led_hw_control_set = mt798x_phy_led_hw_control_set,
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge.c
|
||||
@@ -230,34 +230,34 @@ static int mt753x_phy_led_hw_control_set
|
||||
static struct phy_driver mtk_gephy_driver[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
|
||||
- .name = "MediaTek MT7530 PHY",
|
||||
- .config_init = mt7530_phy_config_init,
|
||||
+ .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,
|
||||
+ .config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
- .read_page = mtk_phy_read_page,
|
||||
- .write_page = mtk_phy_write_page,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ .read_page = mtk_phy_read_page,
|
||||
+ .write_page = mtk_phy_write_page,
|
||||
},
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
|
||||
- .name = "MediaTek MT7531 PHY",
|
||||
- .probe = mt7531_phy_probe,
|
||||
- .config_init = mt7531_phy_config_init,
|
||||
- .read_status = mtk_gphy_cl22_read_status,
|
||||
+ .name = "MediaTek MT7531 PHY",
|
||||
+ .probe = mt7531_phy_probe,
|
||||
+ .config_init = mt7531_phy_config_init,
|
||||
+ .read_status = mtk_gphy_cl22_read_status,
|
||||
/* Interrupts are handled by the switch, not the PHY
|
||||
* itself.
|
||||
*/
|
||||
- .config_intr = genphy_no_config_intr,
|
||||
+ .config_intr = genphy_no_config_intr,
|
||||
.handle_interrupt = genphy_handle_interrupt_no_ack,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
- .read_page = mtk_phy_read_page,
|
||||
- .write_page = mtk_phy_write_page,
|
||||
- .led_blink_set = mt753x_phy_led_blink_set,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .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,
|
@ -0,0 +1,65 @@
|
||||
From e59883b637ae317c2ac275b542e8a50670d76e7c Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Mon, 1 Jul 2024 18:54:17 +0800
|
||||
Subject: [PATCH 13/13] net: phy: mediatek: Remove unnecessary outer parens of
|
||||
"supported_triggers" var
|
||||
|
||||
This patch removes unnecessary outer parens of "supported_triggers" vars
|
||||
in mtk-ge.c & mtk-ge-soc.c to improve readability.
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/net/phy/mediatek/mtk-ge-soc.c | 16 ++++++++--------
|
||||
drivers/net/phy/mediatek/mtk-ge.c | 16 ++++++++--------
|
||||
2 files changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
|
||||
@@ -1224,14 +1224,14 @@ static int mt798x_phy_led_brightness_set
|
||||
}
|
||||
|
||||
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));
|
||||
+ 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)
|
||||
--- a/drivers/net/phy/mediatek/mtk-ge.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-ge.c
|
||||
@@ -189,14 +189,14 @@ static int mt753x_phy_led_brightness_set
|
||||
}
|
||||
|
||||
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));
|
||||
+ 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)
|
@ -1,39 +0,0 @@
|
||||
From 128dc09b0af36772062142ce9e85b19c84ac789a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 28 Feb 2023 17:53:37 +0000
|
||||
Subject: [PATCH] net: phy: add driver for MediaTek 2.5G PHY
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/Kconfig | 7 ++
|
||||
drivers/net/phy/Makefile | 1 +
|
||||
drivers/net/phy/mediatek-2p5ge.c | 220 +++++++++++++++++++++++++++++++
|
||||
3 files changed, 226 insertions(+)
|
||||
create mode 100644 drivers/net/phy/mediatek-2p5ge.c
|
||||
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -330,6 +330,13 @@ config MEDIATEK_GE_SOC_PHY
|
||||
present in the SoCs efuse and will dynamically calibrate VCM
|
||||
(common-mode voltage) during startup.
|
||||
|
||||
+config MEDIATEK_2P5G_PHY
|
||||
+ tristate "MediaTek 2.5G Ethernet PHY"
|
||||
+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
+ default NET_MEDIATEK_SOC
|
||||
+ help
|
||||
+ Supports the MediaTek 2.5G Ethernet PHY.
|
||||
+
|
||||
config MICREL_PHY
|
||||
tristate "Micrel PHYs"
|
||||
depends on PTP_1588_CLOCK_OPTIONAL
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -82,6 +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_2P5G_PHY) += mediatek-2p5ge.o
|
||||
obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
|
||||
obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
|
||||
obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
|
Loading…
Reference in New Issue
Block a user