From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 06 Nov 2023 03:04:41 +0000 Subject: [PATCH] rk3568 rt init --- kernel/drivers/net/phy/rk630phy.c | 71 +++++++++++++++++++++++++++++++---- 1 files changed, 63 insertions(+), 8 deletions(-) diff --git a/kernel/drivers/net/phy/rk630phy.c b/kernel/drivers/net/phy/rk630phy.c index f0128a5..327301d 100644 --- a/kernel/drivers/net/phy/rk630phy.c +++ b/kernel/drivers/net/phy/rk630phy.c @@ -16,6 +16,7 @@ #include <linux/mfd/core.h> #include <linux/mii.h> #include <linux/netdevice.h> +#include <linux/nvmem-consumer.h> #include <linux/of_irq.h> #include <linux/phy.h> #include <linux/platform_device.h> @@ -24,6 +25,8 @@ #define RK630_PHY_ID 0x00441400 /* PAGE 0 */ +#define REG_MMD_ACCESS_CONTROL 0x0d +#define REG_MMD_ACCESS_DATA_ADDRESS 0x0e #define REG_INTERRUPT_STATUS 0X10 #define REG_INTERRUPT_MASK 0X11 #define REG_GLOBAL_CONFIGURATION 0X13 @@ -50,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 */ @@ -61,15 +65,51 @@ * Addr: 1 --- RK630@S40 * 2 --- RV1106@T22 */ -#define PHY_ADDR_S40 1 -#define PHY_ADDR_T22 2 +#define PHY_ADDR_S40 1 +#define PHY_ADDR_T22 2 + +#define T22_TX_LEVEL_100M 0x2d +#define T22_TX_LEVEL_10M 0x32 struct rk630_phy_priv { struct phy_device *phydev; bool ieee; int wol_irq; struct wake_lock wol_wake_lock; + int tx_level_100M; + int tx_level_10M; }; + +static void rk630_phy_t22_get_tx_level_from_efuse(struct phy_device *phydev) +{ + struct rk630_phy_priv *priv = phydev->priv; + unsigned int tx_level_100M = T22_TX_LEVEL_100M; + unsigned int tx_level_10M = T22_TX_LEVEL_10M; + unsigned char *efuse_buf; + struct nvmem_cell *cell; + size_t len; + + cell = nvmem_cell_get(&phydev->mdio.dev, "txlevel"); + if (IS_ERR(cell)) { + phydev_err(phydev, "failed to get txlevel cell: %ld, use default\n", + PTR_ERR(cell)); + } else { + efuse_buf = nvmem_cell_read(cell, &len); + nvmem_cell_put(cell); + if (!IS_ERR(efuse_buf)) { + if (len == 2 && efuse_buf[0] > 0 && efuse_buf[1] > 0) { + tx_level_100M = efuse_buf[1]; + tx_level_10M = efuse_buf[0]; + } + kfree(efuse_buf); + } else { + phydev_err(phydev, "failed to get efuse buf, use default\n"); + } + } + + priv->tx_level_100M = tx_level_100M; + priv->tx_level_10M = tx_level_10M; +} static void rk630_phy_wol_enable(struct phy_device *phydev) { @@ -164,6 +204,8 @@ static void rk630_phy_t22_config_init(struct phy_device *phydev) { + struct rk630_phy_priv *priv = phydev->priv; + /* Switch to page 1 */ phy_write(phydev, REG_PAGE_SEL, 0x0100); /* Disable APS */ @@ -180,8 +222,13 @@ phy_write(phydev, REG_PAGE6_GAIN_ANONTROL, 0x0400); /* PHYAFE EQ optimization */ phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, 0x1088); + + if (priv->tx_level_100M <= 0 || priv->tx_level_10M <= 0) + rk630_phy_t22_get_tx_level_from_efuse(phydev); + /* PHYAFE TX optimization */ - phy_write(phydev, REG_PAGE6_AFE_DRIVER2, 0x3030); + phy_write(phydev, REG_PAGE6_AFE_DRIVER2, + (priv->tx_level_100M << 8) | priv->tx_level_10M); /* PHYAFE CP current optimization */ phy_write(phydev, REG_PAGE6_CP_CURRENT, 0x0575); /* ADC OP BIAS optimization */ @@ -190,6 +237,8 @@ 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); @@ -198,6 +247,12 @@ /* Switch to page 0 */ phy_write(phydev, REG_PAGE_SEL, 0x0000); + + /* Disable eee mode advertised */ + phy_write(phydev, REG_MMD_ACCESS_CONTROL, 0x0007); + phy_write(phydev, REG_MMD_ACCESS_DATA_ADDRESS, 0x003c); + phy_write(phydev, REG_MMD_ACCESS_CONTROL, 0x4007); + phy_write(phydev, REG_MMD_ACCESS_DATA_ADDRESS, 0x0000); } static int rk630_phy_config_init(struct phy_device *phydev) @@ -205,6 +260,11 @@ switch (phydev->mdio.addr) { case PHY_ADDR_S40: rk630_phy_s40_config_init(phydev); + /* + * Ultra Auto-Power Saving Mode (UAPS) is designed to + * save power when cable is not plugged into PHY. + */ + rk630_phy_set_uaps(phydev); break; case PHY_ADDR_T22: rk630_phy_t22_config_init(phydev); @@ -216,11 +276,6 @@ } rk630_phy_ieee_set(phydev, true); - /* - * Ultra Auto-Power Saving Mode (UAPS) is designed to - * save power when cable is not plugged into PHY. - */ - rk630_phy_set_uaps(phydev); return 0; } -- Gitblit v1.6.2