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

Reply via email to