Apparently when hooking up an Ethernet PHY using an RGMII interface
some signals need a to have a small clock delay applied to them.  The
delays can be applied at various points: by the PHY, by the lengt of
the traces on the board or by the MAC.  Linux has an explanation her:

  
https://github.com/torvalds/linux/blob/master/Documentation/driver-api/phy/phy.rst

which includes the description of the kernel interface to handle this.
Part of this interface is exported into the device tree and ACPI
properies to allow software configuration of the appropriate delays to
happen.  Unfortunately that means we have to deal with this as well.

Below is a diff that adds support for the BCM54210E PHY that is used
on the Raspberry Pi4.  The idea is to pass acombination of the
MIIF_RXID and MIIF_TXID flags to indicate the combination of delays
that is desired:

"rgmii"       -> 0
"rgmii-rxid" -> MIIF_RXID
"rgmii-txid" -> MIIF_TXID
"rgmii-id"   -> MIIF_RXID | MIIF_TXID

The diff also replaces some magic numbers with proper defines since I
added those in this diff.  I can split that out.

ok?


Index: dev/mii/brgphy.c
===================================================================
RCS file: /cvs/src/sys/dev/mii/brgphy.c,v
retrieving revision 1.105
diff -u -p -r1.105 brgphy.c
--- dev/mii/brgphy.c    19 Jul 2015 06:28:12 -0000      1.105
+++ dev/mii/brgphy.c    11 Apr 2020 19:48:59 -0000
@@ -92,6 +92,7 @@ void  brgphy_crc_bug(struct mii_softc *);
 void   brgphy_disable_early_dac(struct mii_softc *sc);
 void   brgphy_jumbo_settings(struct mii_softc *);
 void   brgphy_eth_wirespeed(struct mii_softc *);
+void   brgphy_bcm54xx_clock_delay(struct mii_softc *);
 
 const struct mii_phy_funcs brgphy_copper_funcs = {            
        brgphy_service, brgphy_copper_status, brgphy_reset,          
@@ -180,6 +181,8 @@ static const struct mii_phydesc brgphys[
          MII_STR_xxBROADCOM3_BCM57765 },
        { MII_OUI_xxBROADCOM3,          MII_MODEL_xxBROADCOM3_BCM57780,
          MII_STR_xxBROADCOM3_BCM57780 },
+       { MII_OUI_xxBROADCOM4,          MII_MODEL_xxBROADCOM4_BCM54210E,
+         MII_STR_xxBROADCOM4_BCM54210E },
        { MII_OUI_BROADCOM2,            MII_MODEL_BROADCOM2_BCM5906,
          MII_STR_BROADCOM2_BCM5906 },
 
@@ -789,6 +792,12 @@ brgphy_reset(struct mii_softc *sc)
                        break;
                }
                break;
+       case MII_OUI_xxBROADCOM4:
+               switch (sc->mii_model) {
+               case MII_MODEL_xxBROADCOM4_BCM54210E:
+                       brgphy_bcm54xx_clock_delay(sc);
+                       break;
+               }
        }
 
        /* Handle any bge (NetXtreme/NetLink) workarounds. */
@@ -1187,11 +1196,38 @@ brgphy_jumbo_settings(struct mii_softc *
 void
 brgphy_eth_wirespeed(struct mii_softc *sc)
 {
-       u_int32_t val;
+       uint16_t val;
 
        /* Enable Ethernet@Wirespeed */
-       PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7007);
-       val = PHY_READ(sc, BRGPHY_MII_AUXCTL);
-       PHY_WRITE(sc, BRGPHY_MII_AUXCTL,
-               (val | (1 << 15) | (1 << 4)));
+       PHY_WRITE(sc, BRGPHY_MII_AUXCTL, BRGPHY_AUXCTL_SHADOW_MISC |
+           BRGPHY_AUXCTL_SHADOW_MISC << BRGPHY_AUXCTL_MISC_READ_SHIFT);
+       val = PHY_READ(sc, BRGPHY_MII_AUXCTL) & BRGPHY_AUXCTL_MISC_DATA_MASK;
+       val |= BRGPHY_AUXCTL_MISC_WIRESPEED_EN;
+       PHY_WRITE(sc, BRGPHY_MII_AUXCTL, BRGPHY_AUXCTL_MISC_WRITE_EN |
+           BRGPHY_AUXCTL_SHADOW_MISC | val);
+}
+
+void
+brgphy_bcm54xx_clock_delay(struct mii_softc *sc)
+{
+       uint16_t val;
+
+       PHY_WRITE(sc, BRGPHY_MII_AUXCTL, BRGPHY_AUXCTL_SHADOW_MISC |
+           BRGPHY_AUXCTL_SHADOW_MISC << BRGPHY_AUXCTL_MISC_READ_SHIFT);
+       val = PHY_READ(sc, BRGPHY_MII_AUXCTL) & BRGPHY_AUXCTL_MISC_DATA_MASK;
+       if (sc->mii_flags & MIIF_RXID)
+               val |= BRGPHY_AUXCTL_MISC_RGMII_SKEW_EN;
+       else
+               val &= ~BRGPHY_AUXCTL_MISC_RGMII_SKEW_EN;
+       PHY_WRITE(sc, BRGPHY_MII_AUXCTL, BRGPHY_AUXCTL_MISC_WRITE_EN |
+           BRGPHY_AUXCTL_SHADOW_MISC | val);
+
+       PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C, BRGPHY_SHADOW_1C_CLK_CTRL);
+       val = PHY_READ(sc, BRGPHY_MII_SHADOW_1C) & BRGPHY_SHADOW_1C_DATA_MASK;
+       if (sc->mii_flags & MIIF_TXID)
+               val |= BRGPHY_SHADOW_1C_GTXCLK_EN;
+       else
+               val &= ~BRGPHY_SHADOW_1C_GTXCLK_EN;
+       PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C, BRGPHY_SHADOW_1C_WRITE_EN |
+           BRGPHY_SHADOW_1C_CLK_CTRL | val);
 }
Index: dev/mii/brgphyreg.h
===================================================================
RCS file: /cvs/src/sys/dev/mii/brgphyreg.h,v
retrieving revision 1.17
diff -u -p -r1.17 brgphyreg.h
--- dev/mii/brgphyreg.h 19 Jul 2015 06:28:12 -0000      1.17
+++ dev/mii/brgphyreg.h 11 Apr 2020 19:48:59 -0000
@@ -195,6 +195,17 @@
 /* Begin: PHY register values for the 5706 PHY         */
 /*******************************************************/
 
+/*
+ * Aux control shadow register, bits 0-2 select function (0x00 to
+ * 0x07).
+ */
+#define BRGPHY_AUXCTL_SHADOW_MISC      0x07
+#define BRGPHY_AUXCTL_MISC_DATA_MASK   0x7ff8
+#define BRGPHY_AUXCTL_MISC_READ_SHIFT  12
+#define BRGPHY_AUXCTL_MISC_WRITE_EN    0x8000
+#define BRGPHY_AUXCTL_MISC_RGMII_SKEW_EN 0x0200
+#define BRGPHY_AUXCTL_MISC_WIRESPEED_EN        0x0010
+
 /* 
  * Shadow register 0x1C, bit 15 is write enable,
  * bits 14-10 select function (0x00 to 0x1F).
@@ -202,6 +213,11 @@
 #define BRGPHY_MII_SHADOW_1C           0x1C
 #define BRGPHY_SHADOW_1C_WRITE_EN      0x8000
 #define BRGPHY_SHADOW_1C_SELECT_MASK   0x7C00
+#define BRGPHY_SHADOW_1C_DATA_MASK     0x03FF
+
+/* Shadow 0x1C Clock Alignment Control Register (select value 0x03) */
+#define BRGPHY_SHADOW_1C_CLK_CTRL      (0x03 << 10)
+#define BRGPHY_SHADOW_1C_GTXCLK_EN     0x0200
 
 /* Shadow 0x1C Mode Control Register (select value 0x1F) */
 #define BRGPHY_SHADOW_1C_MODE_CTRL     (0x1F << 10)
Index: dev/mii/miidevs
===================================================================
RCS file: /cvs/src/sys/dev/mii/miidevs,v
retrieving revision 1.128
diff -u -p -r1.128 miidevs
--- dev/mii/miidevs     24 Sep 2019 14:35:22 -0000      1.128
+++ dev/mii/miidevs     11 Apr 2020 19:48:59 -0000
@@ -96,6 +96,7 @@ oui xxLEVEL1                  0x1e0400        Level 1
 /* Don't know what's going on here. */
 oui xxBROADCOM2                        0x0050ef        Broadcom
 oui xxBROADCOM3                        0x00d897        Broadcom
+oui xxBROADCOM4                        0x180361        Broadcom
 oui xxDAVICOM                  0x006040        Davicom
 
 /* This is the OUI of the gigE PHY in the Realtek 8169S/8110S chips */
@@ -177,6 +178,7 @@ model BROADCOM BCM5222              0x0032  BCM5222 D
 model BROADCOM BCM5220         0x0033  BCM5220 10/100 PHY
 model BROADCOM BCM4401         0x0036  BCM4401 10/100baseTX PHY
 model BROADCOM2 BCM5906                0x0004  BCM5906 10/100baseTX PHY
+model xxBROADCOM4 BCM54210E    0x000a  BCM54210E 10/100/1000baseT PHY 
 
 /* Cicada PHYs (now owned by Vitesse) */
 model xxCICADA CS8201B         0x0021  CS8201 10/100/1000TX PHY
Index: dev/mii/miidevs.h
===================================================================
RCS file: /cvs/src/sys/dev/mii/miidevs.h,v
retrieving revision 1.131
diff -u -p -r1.131 miidevs.h
--- dev/mii/miidevs.h   24 Sep 2019 14:36:00 -0000      1.131
+++ dev/mii/miidevs.h   11 Apr 2020 19:48:59 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: miidevs.h,v 1.131 2019/09/24 14:36:00 visa Exp $      */
+/*     $OpenBSD$       */
 
 /*
  * THIS FILE AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -103,6 +103,7 @@
 /* Don't know what's going on here. */
 #define        MII_OUI_xxBROADCOM2     0x0050ef        /* Broadcom */
 #define        MII_OUI_xxBROADCOM3     0x00d897        /* Broadcom */
+#define        MII_OUI_xxBROADCOM4     0x180361        /* Broadcom */
 #define        MII_OUI_xxDAVICOM       0x006040        /* Davicom */
 
 /* This is the OUI of the gigE PHY in the Realtek 8169S/8110S chips */
@@ -242,6 +243,8 @@
 #define        MII_STR_BROADCOM_BCM4401        "BCM4401 10/100baseTX PHY"
 #define        MII_MODEL_BROADCOM2_BCM5906     0x0004
 #define        MII_STR_BROADCOM2_BCM5906       "BCM5906 10/100baseTX PHY"
+#define        MII_MODEL_xxBROADCOM4_BCM54210E 0x000a
+#define        MII_STR_xxBROADCOM4_BCM54210E   "BCM54210E 10/100/1000baseT PHY"
 
 /* Cicada PHYs (now owned by Vitesse) */
 #define        MII_MODEL_xxCICADA_CS8201B      0x0021
Index: dev/mii/miivar.h
===================================================================
RCS file: /cvs/src/sys/dev/mii/miivar.h,v
retrieving revision 1.34
diff -u -p -r1.34 miivar.h
--- dev/mii/miivar.h    12 Sep 2015 09:49:20 -0000      1.34
+++ dev/mii/miivar.h    11 Apr 2020 19:48:59 -0000
@@ -152,6 +152,8 @@ typedef struct mii_softc mii_softc_t;
 #define        MIIF_DOPAUSE    0x0100          /* advertise PAUSE capability */
 #define        MIIF_IS_HPNA    0x0200          /* is a HomePNA device */
 #define        MIIF_FORCEANEG  0x0400          /* force autonegotiation */
+#define        MIIF_RXID       0x0800          /* add Rx delay */
+#define        MIIF_TXID       0x1000          /* add Tx delay */
 
 #define        MIIF_INHERIT_MASK       
(MIIF_NOISOLATE|MIIF_NOLOOP|MIIF_AUTOTSLEEP)
 

Reply via email to