Before MII reads/writes, make sure it's not busy like the docs say to. --- sys/dev/fdt/if_dwge.c | 64 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-)
diff --git a/sys/dev/fdt/if_dwge.c b/sys/dev/fdt/if_dwge.c index 94705b1c1cf..68eaae44f96 100644 --- a/sys/dev/fdt/if_dwge.c +++ b/sys/dev/fdt/if_dwge.c @@ -378,6 +378,7 @@ dwge_match(struct device *parent, void *cfdata, void *aux) return (OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-gmac") || OF_is_compatible(faa->fa_node, "amlogic,meson-axg-dwmac") || OF_is_compatible(faa->fa_node, "amlogic,meson-g12a-dwmac") || + OF_is_compatible(faa->fa_node, "rockchip,rk3128-gmac") || OF_is_compatible(faa->fa_node, "rockchip,rk3288-gmac") || OF_is_compatible(faa->fa_node, "rockchip,rk3308-mac") || OF_is_compatible(faa->fa_node, "rockchip,rk3328-gmac") || @@ -423,7 +424,8 @@ dwge_attach(struct device *parent, struct device *self, void *aux) clock_set_assigned(faa->fa_node); clock_enable(faa->fa_node, "stmmaceth"); reset_deassert(faa->fa_node, "stmmaceth"); - if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-gmac") || + if (OF_is_compatible(faa->fa_node, "rockchip,rk3128-gmac") || + OF_is_compatible(faa->fa_node, "rockchip,rk3288-gmac") || OF_is_compatible(faa->fa_node, "rockchip,rk3308-mac") || OF_is_compatible(faa->fa_node, "rockchip,rk3328-gmac") || OF_is_compatible(faa->fa_node, "rockchip,rk3399-gmac")) { @@ -530,7 +532,8 @@ dwge_attach(struct device *parent, struct device *self, void *aux) /* Do hardware specific initializations. */ if (OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-gmac")) dwge_setup_allwinner(sc); - if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-gmac") || + if (OF_is_compatible(faa->fa_node, "rockchip,rk3128-gmac") || + OF_is_compatible(faa->fa_node, "rockchip,rk3288-gmac") || OF_is_compatible(faa->fa_node, "rockchip,rk3308-mac") || OF_is_compatible(faa->fa_node, "rockchip,rk3328-gmac") || OF_is_compatible(faa->fa_node, "rockchip,rk3399-gmac")) @@ -862,6 +865,17 @@ dwge_mii_readreg(struct device *self, int phy, int reg) struct dwge_softc *sc = (void *)self; int n; + for (n = 0; n < 1000; n++) { + if ((dwge_read(sc, GMAC_GMII_ADDR) & GMAC_GMII_ADDR_GB) == 0) + break; + if (n == 999) { + printf("%s: mii_read timeout: GW busy\n", + sc->sc_dev.dv_xname); + return 0; + } + delay(10); + } + dwge_write(sc, GMAC_GMII_ADDR, sc->sc_clk << GMAC_GMII_ADDR_CR_SHIFT | phy << GMAC_GMII_ADDR_PA_SHIFT | @@ -883,6 +897,17 @@ dwge_mii_writereg(struct device *self, int phy, int reg, int val) struct dwge_softc *sc = (void *)self; int n; + for (n = 0; n < 1000; n++) { + if ((dwge_read(sc, GMAC_GMII_ADDR) & GMAC_GMII_ADDR_GB) == 0) + break; + if (n == 999) { + printf("%s: mii_write timeout: GW busy\n", + sc->sc_dev.dv_xname); + return; + } + delay(10); + } + dwge_write(sc, GMAC_GMII_DATA, val); dwge_write(sc, GMAC_GMII_ADDR, sc->sc_clk << GMAC_GMII_ADDR_CR_SHIFT | @@ -1583,9 +1608,32 @@ dwge_setup_allwinner(struct dwge_softc *sc) } /* - * Rockchip RK3288/RK3399. + * Rockchip RK3128/RK3288/RK3399. */ +/* RK3128 registers */ +#define RK3128_GRF_MAC_CON0 0x0168 +#define RK3128_GMAC_TXCLK_DLY_ENABLE (1 << 14 << 16 | 1 << 14) +#define RK3128_GMAC_TXCLK_DLY_DISABLE (1 << 14 << 16) +#define RK3128_GMAC_RXCLK_DLY_ENABLE (1 << 15 << 16 | 1 << 15) +#define RK3128_GMAC_RXCLK_DLY_DISABLE (1 << 15 << 16) +#define RK3128_GMAC_CLK_RX_DL_CFG(val) (0x7f << 7 << 16 | (val) << 7) +#define RK3128_GMAC_CLK_TX_DL_CFG(val) (0x7f << 0 << 16 | (val) << 0) + +#define RK3128_GRF_MAC_CON1 0x016c +#define RK3128_GMAC_PHY_INTF_SEL_RGMII \ + ((1 << 6 | 1 << 7 | 1 << 8) << 16 | 1 << 6) +#define RK3128_GMAC_PHY_INTF_SEL_RMII \ + ((1 << 6 | 1 << 7 | 1 << 8) << 16 | 1 << 8) +#define RK3128_GMAC_FLOW_CTRL (1 << 9 << 16 | 1 << 9) +#define RK3128_GMAC_FLOW_CTRL_CLR (1 << 9 << 16) +#define RK3128_GMAC_SPEED_10M (1 << 10 << 16) +#define RK3128_GMAC_SPEED_100M (1 << 10 << 16 | 1 << 10) +#define RK3128_GMAC_RMII_CLK_25M (1 << 11 << 16 | 1 << 11) +#define RK3128_GMAC_RMII_CLK_2_5M (1 << 11 << 16) +#define RK3128_GMAC_RMII_MODE (1 << 14 << 16 | 1 << 14) +#define RK3128_GMAC_RMII_MODE_CLR (1 << 14 << 16) + /* RK3308 registers */ #define RK3308_GRF_MAC_CON0 0x04a0 #define RK3308_MAC_SPEED_100M ((0x1 << 0) << 16 | (0x1 << 0)) @@ -1657,7 +1705,15 @@ dwge_setup_rockchip(struct dwge_softc *sc) tx_delay = OF_getpropint(sc->sc_node, "tx_delay", 0x30); rx_delay = OF_getpropint(sc->sc_node, "rx_delay", 0x10); - if (OF_is_compatible(sc->sc_node, "rockchip,rk3288-gmac")) { + if (OF_is_compatible(sc->sc_node, "rockchip,rk3128-gmac")) { + /* Use RMII interface. */ + regmap_write_4(rm, RK3128_GRF_MAC_CON1, + RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_SPEED_100M); + + sc->sc_clk_sel = RK3128_GRF_MAC_CON1; + sc->sc_clk_sel_2_5 = RK3128_GMAC_RMII_CLK_2_5M; + sc->sc_clk_sel_25 = RK3128_GMAC_RMII_CLK_25M; + } else if (OF_is_compatible(sc->sc_node, "rockchip,rk3288-gmac")) { /* Use RGMII interface. */ regmap_write_4(rm, RK3288_GRF_SOC_CON1, RK3288_GMAC_PHY_INTF_SEL_RGMII | RK3288_RMII_MODE_MII); -- 2.47.1