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 <xxh@rock-chips.com>
Change-Id: Iea056f30d8ad47e5970101b4543cfda6f5c843a9
This commit is contained in:
Xu Xuehui
2024-07-24 16:50:10 +08:00
committed by Tao Huang
parent 2351410fd8
commit ffbb4c027a

View File

@@ -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);