int emac_sgmii_init_fsm9900(struct emac_adapter *adpt) { struct emac_phy *phy = &adpt->phy; unsigned int i; emac_reg_write_all(phy->base, physical_coding_sublayer_programming, ARRAY_SIZE(physical_coding_sublayer_programming)); emac_reg_write_all(phy->base, sysclk_refclk_setting, ARRAY_SIZE(sysclk_refclk_setting)); emac_reg_write_all(phy->base, pll_setting, ARRAY_SIZE(pll_setting)); emac_reg_write_all(phy->base, cdr_setting, ARRAY_SIZE(cdr_setting)); emac_reg_write_all(phy->base, tx_rx_setting, ARRAY_SIZE(tx_rx_setting)); /* Power up the Ser/Des engine */ writel(SERDES_START, phy->base + EMAC_SGMII_PHY_SERDES_START); for (i = 0; i < SERDES_START_WAIT_TIMES; i++) { if (readl(phy->base + EMAC_QSERDES_COM_RESET_SM) & READY) break; usleep_range(100, 200); } if (i == SERDES_START_WAIT_TIMES) { netdev_err(adpt->netdev, "error: ser/des failed to start\n"); return -EIO; } /* Mask out all the SGMII Interrupt */ writel(0, phy->base + EMAC_SGMII_PHY_INTERRUPT_MASK); return 0; }
static int emac_sgmii_v1_init(struct emac_adapter *adpt) { int i; struct emac_phy *phy = &adpt->phy; struct emac_sgmii *sgmii = phy->private; emac_sgmii_init_link(adpt, phy->autoneg_advertised, phy->autoneg, !phy->disable_fc_autoneg); emac_reg_write_all( sgmii->base, (const struct emac_reg_write *) &physical_coding_sublayer_programming[phy->board_id]); /* Ensure Rx/Tx lanes power configuration is written to hw before * configuring the SerDes engine's clocks */ wmb(); emac_reg_write_all(sgmii->base, sysclk_refclk_setting); emac_reg_write_all( sgmii->base, (const struct emac_reg_write *)&pll_setting[phy->board_id]); emac_reg_write_all(sgmii->base, cdr_setting); emac_reg_write_all(sgmii->base, tx_rx_setting); /* Ensure SerDes engine configuration is written to hw before powering * it up */ wmb(); writel_relaxed(SERDES_START, sgmii->base + EMAC_SGMII_PHY_SERDES_START); /* Ensure Rx/Tx SerDes engine power-up command is written to HW */ wmb(); for (i = 0; i < SERDES_START_WAIT_TIMES; i++) { if (readl_relaxed(sgmii->base + EMAC_QSERDES_COM_RESET_SM) & QSERDES_READY) break; usleep_range(100, 200); } if (i == SERDES_START_WAIT_TIMES) { emac_err(adpt, "serdes failed to start\n"); return -EIO; } /* Mask out all the SGMII Interrupt */ writel_relaxed(0, sgmii->base + EMAC_SGMII_PHY_INTERRUPT_MASK); /* Ensure SGMII interrupts are masked out before clearing them */ wmb(); emac_hw_clear_sgmii_intr_status(adpt, SGMII_PHY_INTERRUPT_ERR); return 0; }
int emac_sgmii_init_qdf2400(struct emac_adapter *adpt) { struct emac_sgmii *phy = &adpt->phy; void __iomem *phy_regs = phy->base; void __iomem *laned = phy->digital; unsigned int i; u32 lnstatus; /* PCS lane-x init */ emac_reg_write_all(phy->base, physical_coding_sublayer_programming, ARRAY_SIZE(physical_coding_sublayer_programming)); /* SGMII lane-x init */ emac_reg_write_all(phy->digital, sgmii_laned, ARRAY_SIZE(sgmii_laned)); /* Power up PCS and start reset lane state machine */ writel(0, phy_regs + EMAC_SGMII_PHY_RESET_CTRL); writel(1, laned + SGMII_LN_RSM_START); /* Wait for c_ready assertion */ for (i = 0; i < SERDES_START_WAIT_TIMES; i++) { lnstatus = readl(phy_regs + SGMII_PHY_LN_LANE_STATUS); if (lnstatus & BIT(1)) break; usleep_range(100, 200); } if (i == SERDES_START_WAIT_TIMES) { netdev_err(adpt->netdev, "SGMII failed to start\n"); return -EIO; } /* Disable digital and SERDES loopback */ writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN0); writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN2); writel(0, phy_regs + SGMII_PHY_LN_CDR_CTRL1); /* Mask out all the SGMII Interrupt */ writel(0, phy_regs + EMAC_SGMII_PHY_INTERRUPT_MASK); return 0; }