Module Name: src Committed By: jmcneill Date: Sat Mar 2 12:24:44 UTC 2019
Modified Files: src/sys/arch/arm/amlogic: meson_dwmac.c Log Message: Setup RGMII mode for Meson DWMAC To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/amlogic/meson_dwmac.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/amlogic/meson_dwmac.c diff -u src/sys/arch/arm/amlogic/meson_dwmac.c:1.3 src/sys/arch/arm/amlogic/meson_dwmac.c:1.4 --- src/sys/arch/arm/amlogic/meson_dwmac.c:1.3 Mon Feb 25 19:30:17 2019 +++ src/sys/arch/arm/amlogic/meson_dwmac.c Sat Mar 2 12:24:44 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: meson_dwmac.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $ */ +/* $NetBSD: meson_dwmac.c,v 1.4 2019/03/02 12:24:44 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: meson_dwmac.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: meson_dwmac.c,v 1.4 2019/03/02 12:24:44 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -48,8 +48,12 @@ __KERNEL_RCSID(0, "$NetBSD: meson_dwmac. #include <dev/fdt/fdtvar.h> -#define GMAC_TX_RATE_MII 25000000 -#define GMAC_TX_RATE_RGMII 125000000 +#define PRG_ETHERNET_ADDR0 0x00 +#define CLKGEN_ENABLE __BIT(12) +#define PHY_CLK_ENABLE __BIT(10) +#define MP2_CLK_OUT_DIV __BITS(9,7) +#define TX_CLK_DELAY __BITS(6,5) +#define PHY_INTERFACE_SEL __BIT(0) static const char * compatible[] = { "amlogic,meson8b-dwmac", @@ -87,6 +91,29 @@ meson_dwmac_reset(const int phandle) return 0; } +static void +meson_dwmac_set_mode_rgmii(int phandle, bus_space_tag_t bst, + bus_space_handle_t bsh, struct clk *clkin) +{ + u_int tx_delay; + uint32_t val; + + const u_int div = clk_get_rate(clkin) / 250000000; + + if (of_getprop_uint32(phandle, "amlogic,tx-delay-ns", &tx_delay) != 0) + tx_delay = 2; + + val = bus_space_read_4(bst, bsh, PRG_ETHERNET_ADDR0); + val |= PHY_INTERFACE_SEL; + val &= ~TX_CLK_DELAY; + val |= __SHIFTIN((tx_delay >> 1), TX_CLK_DELAY); + val &= ~MP2_CLK_OUT_DIV; + val |= __SHIFTIN(div, MP2_CLK_OUT_DIV); + val |= PHY_CLK_ENABLE; + val |= CLKGEN_ENABLE; + bus_space_write_4(bst, bsh, PRG_ETHERNET_ADDR0, val); +} + static int meson_dwmac_intr(void *arg) { @@ -109,21 +136,24 @@ meson_dwmac_attach(device_t parent, devi struct dwc_gmac_softc * const sc = device_private(self); struct fdt_attach_args * const faa = aux; const int phandle = faa->faa_phandle; + bus_space_handle_t prgeth_bsh; struct fdtbus_reset *rst_gmac; - struct clk *clk_gmac; + struct clk *clk_gmac, *clk_in[2]; const char *phy_mode; char intrstr[128]; - bus_addr_t addr; - bus_size_t size; + bus_addr_t addr[2]; + bus_size_t size[2]; - if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + if (fdtbus_get_reg(phandle, 0, &addr[0], &size[0]) != 0 || + fdtbus_get_reg(phandle, 1, &addr[1], &size[1]) != 0) { aprint_error(": couldn't get registers\n"); return; } sc->sc_dev = self; sc->sc_bst = faa->faa_bst; - if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { + if (bus_space_map(sc->sc_bst, addr[0], size[0], 0, &sc->sc_bsh) != 0 || + bus_space_map(sc->sc_bst, addr[1], size[1], 0, &prgeth_bsh) != 0) { aprint_error(": couldn't map registers\n"); return; } @@ -135,7 +165,9 @@ meson_dwmac_attach(device_t parent, devi } clk_gmac = fdtbus_clock_get(phandle, "stmmaceth"); - if (clk_gmac == NULL) { + clk_in[0] = fdtbus_clock_get(phandle, "clkin0"); + clk_in[1] = fdtbus_clock_get(phandle, "clkin1"); + if (clk_gmac == NULL || clk_in[0] == NULL || clk_in[1] == NULL) { aprint_error(": couldn't get clocks\n"); return; } @@ -147,22 +179,13 @@ meson_dwmac_attach(device_t parent, devi aprint_error(": missing 'phy-mode' property\n"); return; } -#if notyet - if (strcmp(phy_mode, "mii") == 0) { - if (clk_set_rate(clk_gmac_tx, GMAC_TX_RATE_MII) != 0) { - aprint_error(": failed to set TX clock rate (MII)\n"); - return; - } - } else if (strcmp(phy_mode, "rgmii") == 0) { - if (clk_set_rate(clk_gmac_tx, GMAC_TX_RATE_RGMII) != 0) { - aprint_error(": failed to set TX clock rate (RGMII)\n"); - return; - } + + if (strcmp(phy_mode, "rgmii") == 0) { + meson_dwmac_set_mode_rgmii(phandle, sc->sc_bst, prgeth_bsh, clk_in[0]); } else { aprint_error(": unsupported phy-mode '%s'\n", phy_mode); return; } -#endif if (clk_enable(clk_gmac) != 0) { aprint_error(": couldn't enable clock\n");