From ffbb4c027a42eac5f29b8f5c22c1e55b1a9c60b0 Mon Sep 17 00:00:00 2001 From: Xu Xuehui Date: Wed, 24 Jul 2024 16:50:10 +0800 Subject: [PATCH] net: phy: motorcomm: YT8011AN VDDIO voltage init from DTS motorcomm 8011AN PHY is not capable of automatically detecting the VDDIO voltage; therefore, it necessitates initialization configurations that correspond to actual VDDIO voltage levels. vddio property designates the PHY's IO voltage. If the vddio property is not specified in the DTS, the default 3V3 IO hardware initialization settings will be applied. Signed-off-by: Xu Xuehui Change-Id: Iea056f30d8ad47e5970101b4543cfda6f5c843a9 --- drivers/net/phy/motorcomm.c | 139 ++++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c index 983c6b52d103..8039c4b99b71 100644 --- a/drivers/net/phy/motorcomm.c +++ b/drivers/net/phy/motorcomm.c @@ -19,19 +19,16 @@ #define PHY_ID_YT8531S 0x4f51e91a #define PHY_ID_YT8531 0x4f51e91b -/** - * YT8011 IO VOLTAGE LEVELS - * YT8011_RGMII_DVDDIO_3V3 -> VDDIO 3V3 - * YT8011_RGMII_DVDDIO_2V5 -> VDDIO 2V5 - * YT8011_RGMII_DVDDIO_1V8 -> VDDIO 1V8 - */ -#define YT8011_RGMII_DVDDIO_3V3 -/* #define YT8011_RGMII_DVDDIO_2V5 */ -/* #define YT8011_RGMII_DVDDIO_1V8 */ +enum { + YT8011_RGMII_DVDDIO_1V8 = 1, + YT8011_RGMII_DVDDIO_2V5, + YT8011_RGMII_DVDDIO_3V3 +}; struct yt8011_priv { u8 polling_mode; u8 chip_mode; + u8 vddio; }; #define YT8011_SPEED_MODE 0xc000 @@ -313,6 +310,55 @@ static int yt8011_config_aneg(struct phy_device *phydev) return 0; } +static int yt8011_config_vddio(struct phy_device *phydev) +{ + struct yt8011_priv *priv = phydev->priv; + + if (!(priv->chip_mode)) { /* rgmii config */ + switch (priv->vddio) { + case YT8011_RGMII_DVDDIO_2V5: + dev_info(&phydev->mdio.dev, "config PHY vddio 2v5\n"); + ytphy_write_ext(phydev, 0x9000, 0x8000); + ytphy_write_ext(phydev, 0x0062, 0x0000); + ytphy_write_ext(phydev, 0x9000, 0x0000); + ytphy_write_ext(phydev, 0x9031, 0xb200); + ytphy_write_ext(phydev, 0x9111, 0x5); + ytphy_write_ext(phydev, 0x9114, 0x3939); + ytphy_write_ext(phydev, 0x9112, 0xf); + ytphy_write_ext(phydev, 0x9110, 0x0); + ytphy_write_ext(phydev, 0x9113, 0x10); + ytphy_write_ext(phydev, 0x903d, 0x2); + break; + case YT8011_RGMII_DVDDIO_1V8: + dev_info(&phydev->mdio.dev, "config PHY for 1v8\n"); + ytphy_write_ext(phydev, 0x9000, 0x8000); + ytphy_write_ext(phydev, 0x0062, 0x0000); + ytphy_write_ext(phydev, 0x9000, 0x0000); + ytphy_write_ext(phydev, 0x9031, 0xb200); + ytphy_write_ext(phydev, 0x9116, 0x6); + ytphy_write_ext(phydev, 0x9119, 0x3939); + ytphy_write_ext(phydev, 0x9117, 0xf); + ytphy_write_ext(phydev, 0x9115, 0x0); + ytphy_write_ext(phydev, 0x9118, 0x20); + ytphy_write_ext(phydev, 0x903d, 0x3); + break; + case YT8011_RGMII_DVDDIO_3V3: + default: + dev_info(&phydev->mdio.dev, "config PHY for 3v3\n"); + ytphy_write_ext(phydev, 0x9000, 0x8000); + ytphy_write_ext(phydev, 0x0062, 0x0000); + ytphy_write_ext(phydev, 0x9000, 0x0000); + ytphy_write_ext(phydev, 0x9031, 0xb200); + ytphy_write_ext(phydev, 0x903b, 0x0040); + ytphy_write_ext(phydev, 0x903e, 0x3b3b); + ytphy_write_ext(phydev, 0x903c, 0xf); + ytphy_write_ext(phydev, 0x903d, 0x1000); + ytphy_write_ext(phydev, 0x9038, 0x0000); + break; + } + } + return 0; +} static int yt8011_aneg_done(struct phy_device *phydev) { int link_utp = 0; @@ -504,9 +550,31 @@ static int yt8512_led_init(struct phy_device *phydev) static int yt8011_config_init(struct phy_device *phydev) { struct yt8011_priv *priv = phydev->priv; + struct device_node *np = phydev->mdio.dev.of_node; + const char *vddio_conf; phydev->autoneg = AUTONEG_DISABLE; + if (!np) { + dev_err(&phydev->mdio.dev, "Device Tree node is missing\n"); + priv->vddio = YT8011_RGMII_DVDDIO_3V3; + } else { + if (of_property_read_string(np, "motorcomm,vddio", &vddio_conf)) { + dev_err(&phydev->mdio.dev, "Missing 'motorcomm,vddio' property in DTS, using 3v3 default\n"); + priv->vddio = YT8011_RGMII_DVDDIO_3V3; + } else { + if (!strcasecmp(vddio_conf, "1v8")) { + priv->vddio = YT8011_RGMII_DVDDIO_1V8; + } else if (!strcasecmp(vddio_conf, "2v5")) { + priv->vddio = YT8011_RGMII_DVDDIO_2V5; + } else if (!strcasecmp(vddio_conf, "3v3")) { + priv->vddio = YT8011_RGMII_DVDDIO_3V3; + } else { + dev_err(&phydev->mdio.dev, "Invalid 'motorcomm,vddio' value, using 3v3 default\n"); + priv->vddio = YT8011_RGMII_DVDDIO_3V3; + } + } + } /* UTP */ ytphy_write_ext(phydev, 0x9000, 0x0); @@ -520,53 +588,18 @@ static int yt8011_config_init(struct phy_device *phydev) ytphy_write_ext(phydev, 0x2015, 0x1012); ytphy_write_ext(phydev, 0x2005, 0x810); ytphy_write_ext(phydev, 0x2013, 0xff06); - ytphy_write_ext(phydev, 0x1000, 0x0028); - ytphy_write_ext(phydev, 0x1002, 0x3800); - ytphy_write_ext(phydev, 0x1090, 0x1012); - ytphy_write_ext(phydev, 0x1091, 0x1013); - ytphy_write_ext(phydev, 0x1100, 0x2020); - ytphy_write_mmd(phydev, 0x7, 0x1f42, 0x0016); + ytphy_write_ext(phydev, 0x1053, 0xf); + ytphy_write_ext(phydev, 0x105e, 0xa46c); ytphy_write_ext(phydev, 0x1088, 0x002b); - ytphy_write_ext(phydev, 0x1088, 0x022b); - ytphy_write_ext(phydev, 0x1088, 0x020b); + ytphy_write_ext(phydev, 0x1088, 0x002b); + ytphy_write_ext(phydev, 0x1088, 0xb); ytphy_write_ext(phydev, 0x3008, 0x143); ytphy_write_ext(phydev, 0x3009, 0x1918); - - if (!(priv->chip_mode)) { /* rgmii config */ -#if defined(YT8011_RGMII_DVDDIO_3V3) - ytphy_write_ext(phydev, 0x9000, 0x8000); - ytphy_write_ext(phydev, 0x0062, 0x0000); - ytphy_write_ext(phydev, 0x9000, 0x0000); - ytphy_write_ext(phydev, 0x9031, 0xb200); - ytphy_write_ext(phydev, 0x903b, 0x0040); - ytphy_write_ext(phydev, 0x903e, 0x3b3b); - ytphy_write_ext(phydev, 0x903c, 0xf); - ytphy_write_ext(phydev, 0x903d, 0x1000); - ytphy_write_ext(phydev, 0x9038, 0x0000); -#elif defined(YT8011_RGMII_DVDDIO_2V5) - ytphy_write_ext(phydev, 0x9000, 0x8000); - ytphy_write_ext(phydev, 0x0062, 0x0000); - ytphy_write_ext(phydev, 0x9000, 0x0000); - ytphy_write_ext(phydev, 0x9031, 0xb200); - ytphy_write_ext(phydev, 0x9111, 0x5); - ytphy_write_ext(phydev, 0x9114, 0x3939); - ytphy_write_ext(phydev, 0x9112, 0xf); - ytphy_write_ext(phydev, 0x9110, 0x0); - ytphy_write_ext(phydev, 0x9113, 0x10); - ytphy_write_ext(phydev, 0x903d, 0x2); -#elif defined(YT8011_RGMII_DVDDIO_1V8) - ytphy_write_ext(phydev, 0x9000, 0x8000); - ytphy_write_ext(phydev, 0x0062, 0x0000); - ytphy_write_ext(phydev, 0x9000, 0x0000); - ytphy_write_ext(phydev, 0x9031, 0xb200); - ytphy_write_ext(phydev, 0x9116, 0x6); - ytphy_write_ext(phydev, 0x9119, 0x3939); - ytphy_write_ext(phydev, 0x9117, 0xf); - ytphy_write_ext(phydev, 0x9115, 0x0); - ytphy_write_ext(phydev, 0x9118, 0x20); - ytphy_write_ext(phydev, 0x903d, 0x3); -#endif - } + ytphy_write_ext(phydev, 0x9095, 0x1a1a); + ytphy_write_ext(phydev, 0x9096, 0x1a10); + ytphy_write_ext(phydev, 0x9097, 0x101a); + ytphy_write_ext(phydev, 0x9098, 0x01ff); + yt8011_config_vddio(phydev); ytphy_soft_reset(phydev);