最近有需求进行phy芯片更改,因此对phy芯片进行了一部分研究配置做个记录,其实主要还是得参考github上的开源kernel,有些人找不到我就告诉你一个路径,其实随便哪家的kernel应该某些驱动都差不多。GitHub - rockchip-toybrick/kernel

boot:

/* RTL8211F PHY Status Register */
#define MIIM_RTL8211F_PHY_STATUS       0x1a
#define MIIM_RTL8211F_AUTONEG_ENABLE   0x1000
#define MIIM_RTL8211F_PHYSTAT_SPEED    0x0030
#define MIIM_RTL8211F_PHYSTAT_GBIT     0x0020
#define MIIM_RTL8211F_PHYSTAT_100      0x0010
#define MIIM_RTL8211F_PHYSTAT_DUPLEX   0x0008
#define MIIM_RTL8211F_PHYSTAT_SPDDONE  0x0800
#define MIIM_RTL8211F_PHYSTAT_LINK     0x0004

#define MIIM_RTL8211F_PAGE_SELECT      0x1f
#define MIIM_RTL8211F_TX_DELAY        0x100
#define MIIM_RTL8211F_LCR        0x10

static int rtl8211f_config(struct phy_device *phydev)
{
    u16 reg;

    phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);

    if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
        /* enable TXDLY */
        phy_write(phydev, MDIO_DEVAD_NONE,
              MIIM_RTL8211F_PAGE_SELECT, 0xd08);
        reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x11);
        reg |= MIIM_RTL8211F_TX_DELAY;
        phy_write(phydev, MDIO_DEVAD_NONE, 0x11, reg);
        /* restore to default page 0 */
        phy_write(phydev, MDIO_DEVAD_NONE,
              MIIM_RTL8211F_PAGE_SELECT, 0x0);
    }

    /* Set green LED for Link, yellow LED for Active */
    phy_write(phydev, MDIO_DEVAD_NONE,
          MIIM_RTL8211F_PAGE_SELECT, 0xd04);
    phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f);
    phy_write(phydev, MDIO_DEVAD_NONE,
          MIIM_RTL8211F_PAGE_SELECT, 0x0);

    genphy_config_aneg(phydev);

    return 0;
}

static int rtl8211f_parse_status(struct phy_device *phydev)
{
    unsigned int speed;
    unsigned int mii_reg;
    int i = 0;

    phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0xa43);
    mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PHY_STATUS);

    phydev->link = 1;
    while (!(mii_reg & MIIM_RTL8211F_PHYSTAT_LINK)) {
        if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
            puts(" TIMEOUT !\n");
            phydev->link = 0;
            break;
        }

        if ((i++ % 1000) == 0)
            putc('.');
        udelay(1000);
        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
                   MIIM_RTL8211F_PHY_STATUS);
    }

    if (mii_reg & MIIM_RTL8211F_PHYSTAT_DUPLEX)
        phydev->duplex = DUPLEX_FULL;
    else
        phydev->duplex = DUPLEX_HALF;

    speed = (mii_reg & MIIM_RTL8211F_PHYSTAT_SPEED);

    switch (speed) {
    case MIIM_RTL8211F_PHYSTAT_GBIT:
        phydev->speed = SPEED_1000;
        break;
    case MIIM_RTL8211F_PHYSTAT_100:
        phydev->speed = SPEED_100;
        break;
    default:
        phydev->speed = SPEED_10;
    }

    return 0;
}

static int rtl8211f_startup(struct phy_device *phydev)
{
    /* Read the Status (2x to make sure link is right) */
    genphy_update_link(phydev);
    rtl8211f_parse_status(phydev);

    return 0;
}

/* Support for RTL8211F PHY */
static struct phy_driver RTL8211F_driver = {
    .name = "RealTek RTL8211F",
    .uid = 0x1cc916,
    .mask = 0xffffff,
    .features = PHY_GBIT_FEATURES,
    .config = &rtl8211f_config,
    .startup = &rtl8211f_startup,
    .shutdown = &genphy_shutdown,
};

更改phy芯片主要涉及mdio地址问题,电压电容问题,目前已解决,后续还根据芯片手册进行了一些微调就没有再补充了,主要是网口灯闪烁有点毛病,也不知道是我们那硬件工程师的问题还是哪的问题没管了凑合用。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐