Module Name: src Committed By: hkenken Date: Fri Oct 18 12:53:09 UTC 2019
Modified Files: src/sys/arch/arm/imx/fdt: if_enet_imx.c imx6_platform.c src/sys/dev/mii: atphy.c Log Message: Modified atphy(4) * Support CLK_25M clock out. * Support internal delay for RGMII interface. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/imx/fdt/if_enet_imx.c cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/imx/fdt/imx6_platform.c cvs rdiff -u -r1.23 -r1.24 src/sys/dev/mii/atphy.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/imx/fdt/if_enet_imx.c diff -u src/sys/arch/arm/imx/fdt/if_enet_imx.c:1.3 src/sys/arch/arm/imx/fdt/if_enet_imx.c:1.4 --- src/sys/arch/arm/imx/fdt/if_enet_imx.c:1.3 Mon Aug 19 03:45:51 2019 +++ src/sys/arch/arm/imx/fdt/if_enet_imx.c Fri Oct 18 12:53:08 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_enet_imx.c,v 1.3 2019/08/19 03:45:51 hkenken Exp $ */ +/* $NetBSD: if_enet_imx.c,v 1.4 2019/10/18 12:53:08 hkenken Exp $ */ /*- * Copyright (c) 2019 Genetec Corporation. All rights reserved. * Written by Hashimoto Kenichi for Genetec Corporation. @@ -25,7 +25,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_enet_imx.c,v 1.3 2019/08/19 03:45:51 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_enet_imx.c,v 1.4 2019/10/18 12:53:08 hkenken Exp $"); #include "opt_fdt.h" @@ -71,6 +71,7 @@ enet_attach(device_t parent, device_t se struct enet_fdt_softc * const efsc = device_private(self); struct enet_softc *sc = &efsc->sc_enet; struct fdt_attach_args * const faa = aux; + prop_dictionary_t prop = device_properties(self); const int phandle = faa->faa_phandle; bus_space_tag_t bst = faa->faa_bst; bus_space_handle_t bsh; @@ -103,15 +104,35 @@ enet_attach(device_t parent, device_t se aprint_naive("\n"); aprint_normal(": Gigabit Ethernet Controller\n"); - enet_phy_reset(efsc, phandle); - sc->sc_dev = self; sc->sc_iot = bst; sc->sc_ioh = bsh; sc->sc_dmat = faa->faa_dmat; sc->sc_imxtype = 6; /* i.MX6 */ - sc->sc_rgmii = 1; + sc->sc_unit = 0; + + const char *phy_mode = fdtbus_get_string(phandle, "phy-mode"); + if (phy_mode == NULL) { + aprint_error(": missing 'phy-mode' property\n"); + goto failure; + } + + if (strcmp(phy_mode, "rgmii-txid") == 0) { + prop_dictionary_set_bool(prop, "tx_internal_delay", true); + sc->sc_rgmii = 1; + } else if (strcmp(phy_mode, "rgmii-rxid") == 0) { + prop_dictionary_set_bool(prop, "rx_internal_delay", true); + sc->sc_rgmii = 1; + } else if (strcmp(phy_mode, "rgmii-id") == 0) { + prop_dictionary_set_bool(prop, "tx_internal_delay", true); + prop_dictionary_set_bool(prop, "rx_internal_delay", true); + sc->sc_rgmii = 1; + } else if (strcmp(phy_mode, "rgmii") == 0) { + sc->sc_rgmii = 1; + } else { + sc->sc_rgmii = 0; + } char intrstr[128]; if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { @@ -128,7 +149,9 @@ enet_attach(device_t parent, device_t se aprint_normal_dev(self, "interrupting on %s\n", intrstr); enet_init_clocks(sc); - sc->sc_pllclock = clk_get_rate(sc->sc_clk_enet); + sc->sc_pllclock = clk_get_rate(sc->sc_clk_enet_ref); + + enet_phy_reset(efsc, phandle); if (enet_attach_common(self) != 0) goto failure; Index: src/sys/arch/arm/imx/fdt/imx6_platform.c diff -u src/sys/arch/arm/imx/fdt/imx6_platform.c:1.6 src/sys/arch/arm/imx/fdt/imx6_platform.c:1.7 --- src/sys/arch/arm/imx/fdt/imx6_platform.c:1.6 Mon Aug 19 10:44:35 2019 +++ src/sys/arch/arm/imx/fdt/imx6_platform.c Fri Oct 18 12:53:08 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: imx6_platform.c,v 1.6 2019/08/19 10:44:35 hkenken Exp $ */ +/* $NetBSD: imx6_platform.c,v 1.7 2019/10/18 12:53:08 hkenken Exp $ */ /*- * Copyright (c) 2019 Genetec Corporation. All rights reserved. * Written by Hashimoto Kenichi for Genetec Corporation. @@ -25,7 +25,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.6 2019/08/19 10:44:35 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.7 2019/10/18 12:53:08 hkenken Exp $"); #include "arml2cc.h" #include "opt_console.h" @@ -116,6 +116,20 @@ imx_platform_early_putchar(char c) static void imx_platform_device_register(device_t self, void *aux) { + prop_dictionary_t prop = device_properties(self); + + if (device_is_a(self, "atphy")) { + const char * compat[] = { + "fsl,imx6dl-sabresd", + "fsl,imx6q-sabresd", + "fsl,imx6qp-sabresd", + "solidrun,hummingboard2/q", + "solidrun,hummingboard2/dl", + NULL + }; + if (of_match_compatible(OF_finddevice("/"), compat)) + prop_dictionary_set_uint32(prop, "clk_25m", 125000000); + } } static u_int Index: src/sys/dev/mii/atphy.c diff -u src/sys/dev/mii/atphy.c:1.23 src/sys/dev/mii/atphy.c:1.24 --- src/sys/dev/mii/atphy.c:1.23 Mon Sep 2 12:48:52 2019 +++ src/sys/dev/mii/atphy.c Fri Oct 18 12:53:08 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: atphy.c,v 1.23 2019/09/02 12:48:52 msaitoh Exp $ */ +/* $NetBSD: atphy.c,v 1.24 2019/10/18 12:53:08 hkenken Exp $ */ /* $OpenBSD: atphy.c,v 1.1 2008/09/25 20:47:16 brad Exp $ */ /*- @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: atphy.c,v 1.23 2019/09/02 12:48:52 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: atphy.c,v 1.24 2019/10/18 12:53:08 hkenken Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -74,6 +74,11 @@ __KERNEL_RCSID(0, "$NetBSD: atphy.c,v 1. #define ATPHY_SSR_100MBS 0x4000 #define ATPHY_SSR_1000MBS 0x8000 +#define ATPHY_DEBUG_PORT_ADDR 0x1d +#define ATPHY_DEBUG_PORT_DATA 0x1e +#define ATPHY_RGMII_RX_CLK_DLY __BIT(15) +#define ATPHY_RGMII_TX_CLK_DLY __BIT(8) + static int atphy_match(device_t, cfdata_t, void *); static void atphy_attach(device_t, device_t, void *); @@ -83,7 +88,14 @@ static void atphy_status(struct mii_soft static int atphy_mii_phy_auto(struct mii_softc *); static bool atphy_is_gige(const struct mii_phydesc *); -CFATTACH_DECL_NEW(atphy, sizeof(struct mii_softc), +struct atphy_softc { + struct mii_softc mii_sc; + int mii_clk_25m; + bool rgmii_tx_internal_delay; + bool rgmii_rx_internal_delay; +}; + +CFATTACH_DECL_NEW(atphy, sizeof(struct atphy_softc), atphy_match, atphy_attach, mii_phy_detach, mii_phy_activate); const struct mii_phy_funcs atphy_funcs = { @@ -99,6 +111,35 @@ static const struct mii_phydesc atphys[] MII_PHY_END, }; +static void +atphy_clk_25m(struct atphy_softc *asc) +{ + struct mii_softc *sc = &asc->mii_sc; + struct { + uint32_t hz; + uint16_t data; + } select_clk[] = { + { 25000000, 0x0 }, + { 50000000, 0x1 }, + { 62500000, 0x2 }, + { 125000000, 0x3 } + }; + uint16_t data = 0; + uint16_t reg = 0; + + for (int i = 0; i < __arraycount(select_clk); i++) { + if (asc->mii_clk_25m <= select_clk[i].hz) + data = select_clk[i].data; + } + + PHY_WRITE(sc, 0x0d, 0x0007); + PHY_WRITE(sc, 0x0e, 0x8016); + PHY_WRITE(sc, 0x0d, 0x4007); + PHY_READ(sc, 0x0e, ®); + PHY_WRITE(sc, 0x0e, reg | __SHIFTIN(data, __BITS(4, 3))); +} + + static bool atphy_is_gige(const struct mii_phydesc *mpd) { @@ -127,7 +168,10 @@ atphy_match(device_t parent, cfdata_t ma void atphy_attach(device_t parent, device_t self, void *aux) { - struct mii_softc *sc = device_private(self); + struct atphy_softc *asc = device_private(self); + prop_dictionary_t parent_prop = device_properties(parent); + prop_dictionary_t prop = device_properties(self); + struct mii_softc *sc = &asc->mii_sc; struct mii_attach_args *ma = aux; struct mii_data *mii = ma->mii_data; const struct mii_phydesc *mpd; @@ -153,6 +197,13 @@ atphy_attach(device_t parent, device_t s sc->mii_flags |= MIIF_NOLOOP; + prop_dictionary_get_bool(parent_prop, "tx_internal_delay", &asc->rgmii_tx_internal_delay); + prop_dictionary_get_bool(parent_prop, "rx_internal_delay", &asc->rgmii_rx_internal_delay); + + prop_dictionary_get_uint32(prop, "clk_25m", &asc->mii_clk_25m); + if (asc->mii_clk_25m != 0) + atphy_clk_25m(asc); + PHY_RESET(sc); PHY_READ(sc, MII_BMSR, &bmsr); @@ -355,6 +406,7 @@ atphy_status(struct mii_softc *sc) static void atphy_reset(struct mii_softc *sc) { + struct atphy_softc *asc = (struct atphy_softc *)sc; uint16_t reg; int i; @@ -386,6 +438,15 @@ atphy_reset(struct mii_softc *sc) if ((reg & BMCR_RESET) == 0) break; } + + if (asc->rgmii_tx_internal_delay) { + PHY_WRITE(sc, ATPHY_DEBUG_PORT_ADDR, 0x05); + PHY_WRITE(sc, ATPHY_DEBUG_PORT_DATA, ATPHY_RGMII_TX_CLK_DLY); + } + if (asc->rgmii_rx_internal_delay) { + PHY_WRITE(sc, ATPHY_DEBUG_PORT_ADDR, 0x00); + PHY_WRITE(sc, ATPHY_DEBUG_PORT_DATA, ATPHY_RGMII_RX_CLK_DLY); + } } static int