From f4c30c77189ca21cd9f22a6474d6b6039b7daa65 Mon Sep 17 00:00:00 2001 From: Raphael <68374617+raphaelscholle@users.noreply.github.com> Date: Sat, 31 Aug 2024 13:53:23 +0200 Subject: [PATCH] Update rk630phy.c --- drivers/net/phy/rk630phy.c | 58 ++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/drivers/net/phy/rk630phy.c b/drivers/net/phy/rk630phy.c index 23ab0b1f9d111..471baeca43a81 100644 --- a/drivers/net/phy/rk630phy.c +++ b/drivers/net/phy/rk630phy.c @@ -53,6 +53,7 @@ #define REG_PAGE6_CP_CURRENT 0x17 #define REG_PAGE6_ADC_OP_BIAS 0x18 #define REG_PAGE6_RX_DECTOR 0x19 +#define REG_PAGE6_TX_MOS_DRV 0x1B #define REG_PAGE6_AFE_PDCW 0x1c /* PAGE 8 */ @@ -86,7 +87,7 @@ static void rk630_phy_t22_get_tx_level_from_efuse(struct phy_device *phydev) unsigned int tx_level_10M = T22_TX_LEVEL_10M; unsigned char *efuse_buf; struct nvmem_cell *cell; - int len; + size_t len; cell = nvmem_cell_get(&phydev->mdio.dev, "txlevel"); if (IS_ERR(cell)) { @@ -159,14 +160,33 @@ static void rk630_phy_ieee_set(struct phy_device *phydev, bool enable) phy_write(phydev, REG_PAGE_SEL, 0x0000); } -static void rk630_phy_set_uaps(struct phy_device *phydev) +static void rk630_phy_set_aps(struct phy_device *phydev, bool enable) +{ + u32 value; + + /* Switch to page 1 */ + phy_write(phydev, REG_PAGE_SEL, 0x0100); + value = phy_read(phydev, REG_PAGE1_APS_CTRL); + if (enable) + value |= BIT(15); + else + value &= ~BIT(15); + phy_write(phydev, REG_PAGE1_APS_CTRL, value); + /* Switch to page 0 */ + phy_write(phydev, REG_PAGE_SEL, 0x0000); +} + +static void rk630_phy_set_uaps(struct phy_device *phydev, bool enable) { u32 value; /* Switch to page 1 */ phy_write(phydev, REG_PAGE_SEL, 0x0100); value = phy_read(phydev, REG_PAGE1_UAPS_CONFIGURE); - value |= BIT(15); + if (enable) + value |= BIT(15); + else + value &= ~BIT(15); phy_write(phydev, REG_PAGE1_UAPS_CONFIGURE, value); /* Switch to page 0 */ phy_write(phydev, REG_PAGE_SEL, 0x0000); @@ -207,6 +227,8 @@ static void rk630_phy_t22_config_init(struct phy_device *phydev) /* Switch to page 1 */ phy_write(phydev, REG_PAGE_SEL, 0x0100); + /* Enable offset clock */ + phy_write(phydev, 0x10, 0xfbfe); /* Disable APS */ phy_write(phydev, REG_PAGE1_APS_CTRL, 0x4824); /* Switch to page 2 */ @@ -216,7 +238,7 @@ static void rk630_phy_t22_config_init(struct phy_device *phydev) /* Switch to page 6 */ phy_write(phydev, REG_PAGE_SEL, 0x0600); /* PHYAFE ADC optimization */ - phy_write(phydev, REG_PAGE6_ADC_ANONTROL, 0x5540); + phy_write(phydev, REG_PAGE6_ADC_ANONTROL, 0x555e); /* PHYAFE Gain optimization */ phy_write(phydev, REG_PAGE6_GAIN_ANONTROL, 0x0400); /* PHYAFE EQ optimization */ @@ -236,11 +258,15 @@ static void rk630_phy_t22_config_init(struct phy_device *phydev) phy_write(phydev, REG_PAGE6_RX_DECTOR, 0x0408); /* PHYAFE PDCW optimization */ phy_write(phydev, REG_PAGE6_AFE_PDCW, 0x8880); + /* Add PHY Tx mos drive, reduce power noise/jitter */ + phy_write(phydev, REG_PAGE6_TX_MOS_DRV, 0x888e); /* Switch to page 8 */ phy_write(phydev, REG_PAGE_SEL, 0x0800); /* Disable auto-cal */ phy_write(phydev, REG_PAGE8_AUTO_CAL, 0x0844); + /* Reatart offset calibration */ + phy_write(phydev, 0x13, 0xc096); /* Switch to page 0 */ phy_write(phydev, REG_PAGE_SEL, 0x0000); @@ -261,10 +287,12 @@ static int rk630_phy_config_init(struct phy_device *phydev) * Ultra Auto-Power Saving Mode (UAPS) is designed to * save power when cable is not plugged into PHY. */ - rk630_phy_set_uaps(phydev); + rk630_phy_set_uaps(phydev, true); break; case PHY_ADDR_T22: rk630_phy_t22_config_init(phydev); + rk630_phy_set_aps(phydev, true); + rk630_phy_set_uaps(phydev, true); break; default: phydev_err(phydev, "Unsupported address for current phy: %d\n", @@ -277,6 +305,23 @@ static int rk630_phy_config_init(struct phy_device *phydev) return 0; } +static void rk630_link_change_notify(struct phy_device *phydev) +{ + unsigned int val; + + if (phydev->state == PHY_RUNNING || phydev->state == PHY_NOLINK) { + /* Switch to page 6 */ + phy_write(phydev, REG_PAGE_SEL, 0x0600); + val = phy_read(phydev, REG_PAGE6_AFE_TX_CTRL); + val &= ~GENMASK(14, 13); + if (phydev->speed == SPEED_10 && phydev->link) + val |= BIT(13); + phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, val); + /* Switch to page 0 */ + phy_write(phydev, REG_PAGE_SEL, 0x0000); + } +} + static irqreturn_t rk630_wol_irq_thread(int irq, void *dev_id) { struct rk630_phy_priv *priv = (struct rk630_phy_priv *)dev_id; @@ -362,6 +407,7 @@ static struct phy_driver rk630_phy_driver[] = { .name = "RK630 PHY", .features = PHY_BASIC_FEATURES, .flags = 0, + .link_change_notify = rk630_link_change_notify, .probe = rk630_phy_probe, .remove = rk630_phy_remove, .soft_reset = genphy_soft_reset, @@ -378,7 +424,7 @@ static struct mdio_device_id __maybe_unused rk630_phy_tbl[] = { { } }; -MODULE_DEVICE_TABLE(mdio, rockchip_phy_tbl); +MODULE_DEVICE_TABLE(mdio, rk630_phy_tbl); module_phy_driver(rk630_phy_driver);