88e1512和88e1510是一个系列的phy,采用marvell的通用phy驱动,驱动源码路径:\u-boot\drivers\net\phy\marvell.c

如上图所示,ETH2的工作模式为RGMII TO SGMII,SGMII与交换芯片bcm5396相连。设备树配置为RGMII模式,如下:

&gem0 {
	status = "okay";
	phy-mode = "rgmii-id";
	phy-handle = <&ethernet_phy0>;

	ethernet_phy0: ethernet-phy@0 {
		reg = <0>;
		device_type = "ethernet-phy";
	};
};

查看芯片手册Page 18 – Register 20,配置工作模式为RGMII (System mode) to SGMII (Media mode)。

   读写88e1512寄存器,先将要操作的Page number写入Register 22,再配置相应的寄存器。

   88e1512驱动配置步骤:

  • 配置工作模式为100,RGMII (System mode) to SGMII (Media mode)。
  • 所有寄存器配置完成后,将Page Address配置为1,PHY切换至Fiber Page,否则MAC获取的是PHY的Copper Page的link状态,无法获取到Fiber Page的link状态。
  • 关闭自协商,强制link为千兆全双工
    static int m88e1518_config(struct phy_device *phydev)
    {
    	u16 reg;
    	int temp_addr;
    
    	/*
    	 * As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
    	 * /88E1514 Rev A0, Errata Section 3.1
    	 */
    
    	/* EEE initialization */
    	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x00ff);
    	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B);
    	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144);
    	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28);
    	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146);
    	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233);
    	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D);
    	phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C);
    	phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159);
    	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
    
    	/* SGMII-to-Copper mode initialization */
    	if (phydev->interface == PHY_INTERFACE_MODE_SGMII ||
    		phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
    		/* Select page 18 */
    		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 18);
    		
    		/* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
    		if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
    			m88e1518_phy_writebits(phydev, MIIM_88E151x_GENERAL_CTRL,
    				       0, 3, MIIM_88E151x_MODE_SGMII);
    		} 
    else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
    		/* In reg 20, write MODE[2:0] = 0x4 (RGMII to SGMII) */
    			m88e1518_phy_writebits(phydev, MIIM_88E151x_GENERAL_CTRL,
    				       0, 3, MII_88E151x_MODE_RGMII_TO_SGMII);
    		}
    
    		/* PHY reset is necessary after changing MODE[2:0] */
    		m88e1518_phy_writebits(phydev, MIIM_88E151x_GENERAL_CTRL,
    				       MIIM_88E151x_RESET_OFFS, 1, 1);
    
    		/* Reset page selection */
    		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0);
    
    		udelay(100);
    	}
    
    	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
    		reg = phy_read(phydev, MDIO_DEVAD_NONE,
    			       MIIM_88E1111_PHY_EXT_SR);
    
    		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
    		reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK;
    		reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
    
    		phy_write(phydev, MDIO_DEVAD_NONE,
    			  MIIM_88E1111_PHY_EXT_SR, reg);
    	}
    
    	if (phy_interface_is_rgmii(phydev)) {
    		phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, 2);
    
    		reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR);
    		reg &= ~MIIM_88E151x_RGMII_RXTX_DELAY;
    		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
    			reg |= MIIM_88E151x_RGMII_RXTX_DELAY;
    		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
    			reg |= MIIM_88E151x_RGMII_RX_DELAY;
    		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
    			reg |= MIIM_88E151x_RGMII_TX_DELAY;
    		phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR, reg);
    
    		phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, 0);
    	}
    
    		phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, MII_MARVELL_FIBER_PAGE);
    		
    		phydev->autoneg = AUTONEG_DISABLE;
    		phydev->speed = SPEED_1000;
    		phydev->duplex = DUPLEX_FULL;
    
    		puts("phy_interface_is_rgmii out!!!!!!!!\n");
    
    	/* soft reset */
    	phy_reset(phydev);
    
    	genphy_config_aneg(phydev);
    	//genphy_restart_aneg(phydev);
    
    	return 0;
    }

Logo

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

更多推荐