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, &reg);
+	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

Reply via email to