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;
}