@@ -383,6 +383,81 @@ static void qca955x_set_speed_xmii(int speed)
iounmap(base);
}
+static void qca955x_reset_sgmii(void)
+{
+ void __iomem *base;
+ int count = 0;
+ u32 status;
+ u32 t;
+
+ base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE);
+
+ t = QCA955X_MR_AN_CONTROL_AN_ENABLE |
+ QCA955X_MR_AN_CONTROL_PHY_RESET;
+ __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL);
+ udelay(10);
+
+ t = QCA955X_MR_AN_CONTROL_AN_ENABLE;
+ __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL);
+
+ t = 0;
+ __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET);
+
+ t = QCA955X_SGMII_RESET_HW_RX_125M;
+ __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET);
+
+ t = QCA955X_SGMII_RESET_HW_RX_125M |
+ QCA955X_SGMII_RESET_RX_125M;
+ __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET);
+
+ t = QCA955X_SGMII_RESET_HW_RX_125M |
+ QCA955X_SGMII_RESET_TX_125M |
+ QCA955X_SGMII_RESET_RX_125M;
+ __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET);
+
+ t = QCA955X_SGMII_RESET_HW_RX_125M |
+ QCA955X_SGMII_RESET_TX_125M |
+ QCA955X_SGMII_RESET_RX_125M |
+ QCA955X_SGMII_RESET_RX_CLK;
+ __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET);
+
+ t = QCA955X_SGMII_RESET_HW_RX_125M |
+ QCA955X_SGMII_RESET_TX_125M |
+ QCA955X_SGMII_RESET_RX_125M |
+ QCA955X_SGMII_RESET_RX_CLK |
+ QCA955X_SGMII_RESET_TX_CLK;
+ __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET);
+
+ t = __raw_readl(base + QCA955X_GMAC_REG_MR_AN_CONTROL);
+ t &= ~QCA955X_MR_AN_CONTROL_PHY_RESET;
+ __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL);
+ udelay(100);
+
+ status = __raw_readl(base + QCA955X_GMAC_REG_SGMII_DEBUG);
+ status &= 0xff;
+ while (status != 0xf && status != 0x10) {
+ t = __raw_readl(base + QCA955X_GMAC_REG_MR_AN_CONTROL);
+ t |= QCA955X_MR_AN_CONTROL_PHY_RESET;
+ __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL);
+
+ udelay(100);
+
+ t = __raw_readl(base + QCA955X_GMAC_REG_MR_AN_CONTROL);
+ t &= ~QCA955X_MR_AN_CONTROL_PHY_RESET;
+ __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL);
+
+ if (count++ >= 20)
+ break;
+
+ mdelay(10);
+
+ status = __raw_readl(base + QCA955X_GMAC_REG_SGMII_DEBUG);
+ status &= 0xff;
+ }
+
+ iounmap(base);
+}
+
static void qca955x_set_speed_sgmii(int speed)
{
void __iomem *base;
@@ -391,6 +466,8 @@ static void qca955x_set_speed_sgmii(int speed)
base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
__raw_writel(val, base + QCA955X_PLL_ETH_SGMII_CONTROL_REG);
iounmap(base);
+
+ qca955x_reset_sgmii();
}
static void qca956x_set_speed_sgmii(int speed)