Skip to content

Commit 6d6714b

Browse files
ziyao233kuba-moo
authored andcommitted
net: stmmac: thead: Enable TX clock before MAC initialization
The clk_tx_i clock must be supplied to the MAC for successful initialization. On TH1520 SoC, the clock is provided by an internal divider configured through GMAC_PLLCLK_DIV register when using RGMII interface. However, currently we don't setup the divider before initialization of the MAC, resulting in DMA reset failures if the bootloader/firmware doesn't enable the divider, [ 7.839601] thead-dwmac ffe7060000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0 [ 7.938338] thead-dwmac ffe7060000.ethernet eth0: PHY [stmmac-0:02] driver [RTL8211F Gigabit Ethernet] (irq=POLL) [ 8.160746] thead-dwmac ffe7060000.ethernet eth0: Failed to reset the dma [ 8.170118] thead-dwmac ffe7060000.ethernet eth0: stmmac_hw_setup: DMA engine initialization failed [ 8.179384] thead-dwmac ffe7060000.ethernet eth0: __stmmac_open: Hw setup failed Let's simply write GMAC_PLLCLK_DIV_EN to GMAC_PLLCLK_DIV to enable the divider before MAC initialization. Note that for reconfiguring the divisor, the divider must be disabled first and re-enabled later to make sure the new divisor take effect. The exact clock rate doesn't affect MAC's initialization according to my test. It's set to the speed required by RGMII when the linkspeed is 1Gbps and could be reclocked later after link is up if necessary. Fixes: 33a1a01 ("net: stmmac: Add glue layer for T-HEAD TH1520 SoC") Signed-off-by: Yao Zi <[email protected]> Reviewed-by: Drew Fustini <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 75a9a46 commit 6d6714b

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ static int thead_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i,
152152
static int thead_dwmac_enable_clk(struct plat_stmmacenet_data *plat)
153153
{
154154
struct thead_dwmac *dwmac = plat->bsp_priv;
155-
u32 reg;
155+
u32 reg, div;
156156

157157
switch (plat->mac_interface) {
158158
case PHY_INTERFACE_MODE_MII:
@@ -164,6 +164,13 @@ static int thead_dwmac_enable_clk(struct plat_stmmacenet_data *plat)
164164
case PHY_INTERFACE_MODE_RGMII_RXID:
165165
case PHY_INTERFACE_MODE_RGMII_TXID:
166166
/* use pll */
167+
div = clk_get_rate(plat->stmmac_clk) / rgmii_clock(SPEED_1000);
168+
reg = FIELD_PREP(GMAC_PLLCLK_DIV_EN, 1) |
169+
FIELD_PREP(GMAC_PLLCLK_DIV_NUM, div);
170+
171+
writel(0, dwmac->apb_base + GMAC_PLLCLK_DIV);
172+
writel(reg, dwmac->apb_base + GMAC_PLLCLK_DIV);
173+
167174
writel(GMAC_GTXCLK_SEL_PLL, dwmac->apb_base + GMAC_GTXCLK_SEL);
168175
reg = GMAC_TX_CLK_EN | GMAC_TX_CLK_N_EN | GMAC_TX_CLK_OUT_EN |
169176
GMAC_RX_CLK_EN | GMAC_RX_CLK_N_EN;

0 commit comments

Comments
 (0)