static void xgbe_serdes_complete_ratechange(struct xgbe_prv_data *pdata) { unsigned int wait; u16 status; /* Release Rx and Tx ratechange */ XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, RATECHANGE, 0); /* Wait for Rx and Tx ready */ wait = XGBE_RATECHANGE_COUNT; while (wait--) { usleep_range(50, 75); status = XSIR0_IOREAD(pdata, SIR0_STATUS); if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) && XSIR_GET_BITS(status, SIR0_STATUS, TX_READY)) goto rx_reset; } netif_dbg(pdata, link, pdata->netdev, "SerDes rx/tx not ready (%#hx)\n", status); rx_reset: /* Perform Rx reset for the DFE changes */ XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 0); XRXTX_IOWRITE_BITS(pdata, RXTX_REG6, RESETB_RXD, 1); }
static int amd_xgbe_phy_gmii_mode(struct phy_device *phydev) { struct amd_xgbe_phy_priv *priv = phydev->priv; int ret; /* Disable KR training */ ret = amd_xgbe_an_disable_kr_training(phydev); if (ret < 0) return ret; /* Set PCS to KX/1G speed */ ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2); if (ret < 0) return ret; ret &= ~MDIO_PCS_CTRL2_TYPE; ret |= MDIO_PCS_CTRL2_10GBX; phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2, ret); ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1); if (ret < 0) return ret; ret &= ~MDIO_CTRL1_SPEEDSEL; ret |= MDIO_CTRL1_SPEED1G; phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, ret); ret = amd_xgbe_phy_pcs_power_cycle(phydev); if (ret < 0) return ret; /* Set SerDes to 1G speed */ amd_xgbe_phy_serdes_start_ratechange(phydev); XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, DATARATE, SPEED_1000_RATE); XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, WORDMODE, SPEED_1000_WORD); XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, PLLSEL, SPEED_1000_PLL); XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, CDR_RATE, priv->serdes_cdr_rate[XGBE_PHY_SPEED_1000]); XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, TXAMP, priv->serdes_tx_amp[XGBE_PHY_SPEED_1000]); XRXTX_IOWRITE_BITS(priv, RXTX_REG20, BLWC_ENA, priv->serdes_blwc[XGBE_PHY_SPEED_1000]); XRXTX_IOWRITE_BITS(priv, RXTX_REG114, PQ_REG, priv->serdes_pq_skew[XGBE_PHY_SPEED_1000]); amd_xgbe_phy_serdes_complete_ratechange(phydev); return 0; }
static void xgbe_gmii_mode(struct xgbe_prv_data *pdata) { unsigned int reg; /* Disable KR training */ xgbe_an_disable_kr_training(pdata); /* Set MAC to 1G speed */ pdata->hw_if.set_gmii_speed(pdata); /* Set PCS to KX/1G speed */ reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL2); reg &= ~MDIO_PCS_CTRL2_TYPE; reg |= MDIO_PCS_CTRL2_10GBX; XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL2, reg); reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1); reg &= ~MDIO_CTRL1_SPEEDSEL; reg |= MDIO_CTRL1_SPEED1G; XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, reg); xgbe_pcs_power_cycle(pdata); /* Set SerDes to 1G speed */ xgbe_serdes_start_ratechange(pdata); XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, DATARATE, XGBE_SPEED_1000_RATE); XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, WORDMODE, XGBE_SPEED_1000_WORD); XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, PLLSEL, XGBE_SPEED_1000_PLL); XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, CDR_RATE, pdata->serdes_cdr_rate[XGBE_SPEED_1000]); XSIR1_IOWRITE_BITS(pdata, SIR1_SPEED, TXAMP, pdata->serdes_tx_amp[XGBE_SPEED_1000]); XRXTX_IOWRITE_BITS(pdata, RXTX_REG20, BLWC_ENA, pdata->serdes_blwc[XGBE_SPEED_1000]); XRXTX_IOWRITE_BITS(pdata, RXTX_REG114, PQ_REG, pdata->serdes_pq_skew[XGBE_SPEED_1000]); XRXTX_IOWRITE_BITS(pdata, RXTX_REG129, RXDFE_CONFIG, pdata->serdes_dfe_tap_cfg[XGBE_SPEED_1000]); XRXTX_IOWRITE(pdata, RXTX_REG22, pdata->serdes_dfe_tap_ena[XGBE_SPEED_1000]); xgbe_serdes_complete_ratechange(pdata); netif_dbg(pdata, link, pdata->netdev, "1GbE KX mode set\n"); }