Index: if_dwqe_fdt.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/if_dwqe_fdt.c,v retrieving revision 1.5 diff -u -p -r1.5 if_dwqe_fdt.c --- if_dwqe_fdt.c 26 Mar 2023 21:44:46 -0000 1.5 +++ if_dwqe_fdt.c 3 Apr 2023 23:45:05 -0000 @@ -63,7 +63,7 @@ int dwqe_fdt_match(struct device *, void *, void *); void dwqe_fdt_attach(struct device *, struct device *, void *); -void dwqe_setup_rockchip(struct dwqe_softc *); +int dwqe_setup_rockchip(struct dwqe_softc *); void dwqe_mii_statchg_rk3568(struct device *); void dwqe_mii_statchg_rk3588(struct device *); @@ -137,8 +137,12 @@ dwqe_fdt_attach(struct device *parent, s delay(5000); /* Do hardware specific initializations. */ - if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-gmac")) - dwqe_setup_rockchip(sc); + if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-gmac")) { + if (dwqe_setup_rockchip(sc) == -1) { + /* dwqe_setup_rockchip prints the error and \n */ + return; + } + } /* Power up PHY. */ phy_supply = OF_getpropint(faa->fa_node, "phy-supply", 0); @@ -266,41 +270,70 @@ dwqe_reset_phy(struct dwqe_softc *sc, ui #define RK3568_GRF_GMACx_CON1(x) (0x0384 + (x) * 0x8) #define RK3568_GMAC_PHY_INTF_SEL_RGMII ((0x7 << 4) << 16 | (0x1 << 4)) #define RK3568_GMAC_PHY_INTF_SEL_RMII ((0x7 << 4) << 16 | (0x4 << 4)) -#define RK3568_GMAC_TXCLK_DLY_ENA ((1 << 0) << 16 | (1 << 0)) -#define RK3568_GMAC_RXCLK_DLY_ENA ((1 << 1) << 16 | (1 << 1)) +#define RK3568_GMAC_TXCLK_DLY_SET(_v) ((1 << 0) << 16 | ((_v) << 0)) +#define RK3568_GMAC_RXCLK_DLY_SET(_v) ((1 << 1) << 16 | ((_v) << 1)) void dwqe_mii_statchg_rk3568_task(void *); -void +int dwqe_setup_rockchip(struct dwqe_softc *sc) { + char phy_mode[32]; struct regmap *rm; uint32_t grf; int tx_delay, rx_delay; + uint32_t iface; grf = OF_getpropint(sc->sc_node, "rockchip,grf", 0); rm = regmap_byphandle(grf); - if (rm == NULL) - return; + if (rm == NULL) { + printf(": can't find rockchip,grf\n"); + return (-1); + } + + if (OF_getprop(sc->sc_node, "phy-mode", + phy_mode, sizeof(phy_mode)) <= 0) { + printf(": no phy-mode\n"); + return (-1); + } 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,rk3568-gmac")) { - /* Program clock delay lines. */ - regmap_write_4(rm, RK3568_GRF_GMACx_CON0(sc->sc_gmac_id), - RK3568_GMAC_CLK_TX_DL_CFG(tx_delay) | - RK3568_GMAC_CLK_RX_DL_CFG(rx_delay)); - - /* Use RGMII interface and enable clock delay. */ - regmap_write_4(rm, RK3568_GRF_GMACx_CON1(sc->sc_gmac_id), - RK3568_GMAC_PHY_INTF_SEL_RGMII | - RK3568_GMAC_TXCLK_DLY_ENA | - RK3568_GMAC_RXCLK_DLY_ENA); - - task_set(&sc->sc_statchg_task, - dwqe_mii_statchg_rk3568_task, sc); + if (strcmp(phy_mode, "rgmii") == 0) { + iface = RK3568_GMAC_PHY_INTF_SEL_RGMII; + } else if (strcmp(phy_mode, "rgmii-id") == 0) { + iface = RK3568_GMAC_PHY_INTF_SEL_RGMII; + /* id is "internal delay" */ + tx_delay = rx_delay = 0; + } else if (strcmp(phy_mode, "rgmii-rxid") == 0) { + iface = RK3568_GMAC_PHY_INTF_SEL_RGMII; + rx_delay = 0; + } else if (strcmp(phy_mode, "rgmii-txid") == 0) { + iface = RK3568_GMAC_PHY_INTF_SEL_RGMII; + tx_delay = 0; + } else if (strcmp(phy_mode, "rmii") == 0) { + iface = RK3568_GMAC_PHY_INTF_SEL_RMII; + tx_delay = rx_delay = 0; + } else { + printf(": unknown phy-mode %s\n", phy_mode); + return (-1); } + + /* Program clock delay lines. */ + regmap_write_4(rm, RK3568_GRF_GMACx_CON0(sc->sc_gmac_id), + RK3568_GMAC_CLK_TX_DL_CFG(tx_delay) | + RK3568_GMAC_CLK_RX_DL_CFG(rx_delay)); + + /* Set interface and enable/disable clock delay. */ + regmap_write_4(rm, RK3568_GRF_GMACx_CON1(sc->sc_gmac_id), iface | + RK3568_GMAC_TXCLK_DLY_SET(tx_delay > 0 ? 1 : 0) | + RK3568_GMAC_RXCLK_DLY_SET(rx_delay > 0 ? 1 : 0)); + + task_set(&sc->sc_statchg_task, + dwqe_mii_statchg_rk3568_task, sc); + + return (0); } void