<div dir="ltr">This patch is to add support for sgmii/serdes calibration from within the OpenWRT environment. This is needed on boards that do not use u-boot or do not have a pre-init process that runs calibration.<br><br>Signed-off-by: Chris R Blake <<a href="mailto:chrisrblake93@gmail.com">chrisrblake93@gmail.com</a>><br><br>---<br><br>--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h 2015-08-05 12:58:15.580496899 +0200<br>+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h 2015-08-05 13:52:32.590857293 +0200<br>@@ -360,6 +360,7 @@<br> #define QCA955X_PLL_CLK_CTRL_REG 0x08<br> #define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28<br> #define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48<br>+#define QCA955X_PLL_ETH_SGMII_SERDES_REG 0x4c<br><br> #define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0<br> #define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f<br>@@ -392,6 +393,10 @@<br> #define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)<br> #define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)<br><br>+#define QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT BIT(2)<br>+#define QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK BIT(1)<br>+#define QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL BIT(0)<br>+<br> #define QCA956X_PLL_CPU_CONFIG_REG 0x00<br> #define QCA956X_PLL_CPU_CONFIG1_REG 0x04<br> #define QCA956X_PLL_DDR_CONFIG_REG 0x08<br>@@ -1104,5 +1109,11 @@<br> #define QCA955X_ETH_CFG_RDV_DELAY BIT(16)<br> #define QCA955X_ETH_CFG_RDV_DELAY_MASK 0x3<br> #define QCA955X_ETH_CFG_RDV_DELAY_SHIFT 16<br>+<br>+#define QCA955X_GMAC_REG_SGMII_SERDES 0x0018<br>+#define QCA955X_SGMII_SERDES_RES_CALIBRATION BIT(23)<br>+#define QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK 0xf<br>+#define QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT 23<br>+#define QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS BIT(15)<br><br> #endif /* __ASM_MACH_AR71XX_REGS_H */<br>--- a/arch/mips/ath79/dev-eth.c 2015-08-05 14:17:25.757504251 +0200<br>+++ b/arch/mips/ath79/dev-eth.c 2015-08-05 14:09:54.716333554 +0200<br>@@ -849,6 +849,37 @@ void __init ath79_setup_qca955x_eth_rx_d<br>  iounmap(base);<br> }<br><br>+void __init ath79_setup_qca955x_eth_serdes_cal(unsigned int sgmii_value)<br>+{<br>+ void __iomem *ethbase, *pllbase;<br>+ u32 t;<br>+<br>+ ethbase = ioremap_nocache(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE);<br>+ pllbase = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);<br>+<br>+ /* To Check the locking of the SGMII PLL */<br>+ t = __raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES);<br>+ t &= ~(QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK <<<br>+       QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT);<br>+ t |= (sgmii_value & QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK) <<<br>+     QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT;<br>+ __raw_writel(t, ethbase + QCA955X_GMAC_REG_SGMII_SERDES);<br>+<br>+ __raw_writel(QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT |<br>+     QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK |<br>+     QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL,<br>+     pllbase + QCA955X_PLL_ETH_SGMII_SERDES_REG);<br>+<br>+ ath79_device_reset_clear(QCA955X_RESET_SGMII_ANALOG);<br>+ ath79_device_reset_clear(QCA955X_RESET_SGMII);<br>+<br>+ while (!(__raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES) &<br>+ QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS));<br>+<br>+ iounmap(ethbase);<br>+ iounmap(pllbase);<br>+}<br>+<br> static int ath79_eth_instance __initdata;<br> void __init ath79_register_eth(unsigned int id)<br> {<br>--- a/arch/mips/ath79/dev-eth.h 2015-08-05 14:17:25.757504251 +0200<br>+++ b/arch/mips/ath79/dev-eth.h 2015-08-05 13:58:20.292866210 +0200<br>@@ -50,5 +50,6 @@ void ath79_setup_ar934x_eth_cfg(u32 mask<br> void ath79_setup_ar934x_eth_rx_delay(unsigned int rxd, unsigned int rxdv);<br> void ath79_setup_qca955x_eth_cfg(u32 mask);<br> void ath79_setup_qca955x_eth_rx_delay(unsigned int rxd, unsigned int rxdv);<br>+void ath79_setup_qca955x_eth_serdes_cal(unsigned int sgmii_value);<br><br> #endif /* _ATH79_DEV_ETH_H */</div>