]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
net: phy: marvell: Support reg config via "marvell, reg-init" DT property
authorStefan Roese <sr@denx.de>
Thu, 31 Mar 2022 09:43:06 +0000 (11:43 +0200)
committerTom Rini <trini@konsulko.com>
Mon, 8 Aug 2022 14:50:20 +0000 (10:50 -0400)
This patch adds support for the "marvell,reg-init" DT property, which
is used to describe board specific Marvell PHY register configurations
in the board dts file. This DT property is supported in the Linux Kernel
since a longer time. Adding it to U-Boot now, enables the boards which
describe the register settings in their DT files here as well.

I've included calling this marvell_of_reg_init() to all foo_config()
functions in this patch as well. If CONFIG_DM_ETH is not set, there is
no ofnode, or no "marvell,reg-init" property, the PHY initialization is
unchanged.

The function marvell_of_reg_init() is a port of the Linux version.
Please note that I explicitly did not add error checking and handling
to the U-Boot version, as this is basically not done for phy_read/write
in this Marvell PHY code.

This will be used by the upcoming ethernet support on the MIPS
Octeon EBB 7304 board.

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Ramon Fried <rfried.dev@gmail.com>
Cc: Joe Hershberger <joe.hershberger@ni.com>
Cc: Aaron Williams <awilliams@marvell.com>
Cc: Chandrakala Chavva <cchavva@marvell.com>
Cc: Marek BehĂșn <marek.behun@nic.cz>
Reviewed-by: Marek BehĂșn <marek.behun@nic.cz>
drivers/net/phy/marvell.c

index a62c695c5c846a410dd1ea5bae95b89e02404e12..1dcb79db242907f59614c05242cc28d002088355 100644 (file)
 #define MIIM_88E151x_MODE_SGMII                1
 #define MIIM_88E151x_RESET_OFFS                15
 
+#if IS_ENABLED(CONFIG_DM_ETH)
+static int marvell_read_page(struct phy_device *phydev)
+{
+       return phy_read(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE);
+}
+
+static int marvell_write_page(struct phy_device *phydev, int page)
+{
+       return phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, page);
+}
+
+/* Set and/or override some configuration registers based on the
+ * marvell,reg-init property stored in the of_node for the phydev.
+ *
+ * marvell,reg-init = <reg-page reg mask value>,...;
+ *
+ * There may be one or more sets of <reg-page reg mask value>:
+ *
+ * reg-page: which register bank to use.
+ * reg: the register.
+ * mask: if non-zero, ANDed with existing register value.
+ * value: ORed with the masked value and written to the regiser.
+ *
+ */
+static int marvell_of_reg_init(struct phy_device *phydev)
+{
+       const __be32 *prop;
+       int len, i, saved_page, current_page, ret = 0;
+
+       if (!ofnode_valid(phydev->node))
+               return 0;
+
+       prop = ofnode_get_property(phydev->node, "marvell,reg-init", &len);
+       if (!prop)
+               return 0;
+
+       saved_page = marvell_read_page(phydev);
+       if (saved_page < 0)
+               goto err;
+       current_page = saved_page;
+
+       len /= sizeof(*prop);
+       for (i = 0; i < len - 3; i += 4) {
+               u16 page = be32_to_cpup(prop + i);
+               u16 reg = be32_to_cpup(prop + i + 1);
+               u16 mask = be32_to_cpup(prop + i + 2);
+               u16 val_bits = be32_to_cpup(prop + i + 3);
+               int val;
+
+               if (page != current_page) {
+                       current_page = page;
+                       ret = marvell_write_page(phydev, page);
+                       if (ret < 0)
+                               goto err;
+               }
+
+               val = 0;
+               if (mask) {
+                       val = phy_read(phydev, MDIO_DEVAD_NONE, reg);
+                       if (val < 0) {
+                               ret = val;
+                               goto err;
+                       }
+                       val &= mask;
+               }
+               val |= val_bits;
+
+               ret = phy_write(phydev, MDIO_DEVAD_NONE, reg, val);
+               if (ret < 0)
+                       goto err;
+       }
+
+err:
+       return marvell_write_page(phydev, saved_page);
+}
+#else
+static int marvell_of_reg_init(struct phy_device *phydev)
+{
+       return 0;
+}
+#endif /* CONFIG_DM_ETH */
+
 static int m88e1xxx_phy_extread(struct phy_device *phydev, int addr,
                                int devaddr, int regnum)
 {
@@ -143,6 +225,8 @@ static int m88e1011s_config(struct phy_device *phydev)
 
        phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
 
+       marvell_of_reg_init(phydev);
+
        genphy_config_aneg(phydev);
 
        return 0;
@@ -298,6 +382,8 @@ static int m88e1111s_config(struct phy_device *phydev)
        /* soft reset */
        phy_reset(phydev);
 
+       marvell_of_reg_init(phydev);
+
        genphy_config_aneg(phydev);
        genphy_restart_aneg(phydev);
 
@@ -397,6 +483,8 @@ static int m88e151x_config(struct phy_device *phydev)
        /* soft reset */
        phy_reset(phydev);
 
+       marvell_of_reg_init(phydev);
+
        genphy_config_aneg(phydev);
        genphy_restart_aneg(phydev);
 
@@ -417,6 +505,8 @@ static int m88e1118_config(struct phy_device *phydev)
        /* Change Page Number */
        phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
 
+       marvell_of_reg_init(phydev);
+
        return genphy_config_aneg(phydev);
 }
 
@@ -439,6 +529,8 @@ static int m88e1121_config(struct phy_device *phydev)
 {
        int pg;
 
+       marvell_of_reg_init(phydev);
+
        /* Configure the PHY */
        genphy_config_aneg(phydev);
 
@@ -479,6 +571,8 @@ static int m88e1145_config(struct phy_device *phydev)
                        MIIM_M88E1145_RGMII_TX_DELAY;
        phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR, reg);
 
+       marvell_of_reg_init(phydev);
+
        genphy_config_aneg(phydev);
 
        /* soft reset */
@@ -511,6 +605,8 @@ static int m88e1149_config(struct phy_device *phydev)
        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x0);
        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
 
+       marvell_of_reg_init(phydev);
+
        genphy_config_aneg(phydev);
 
        phy_reset(phydev);
@@ -544,6 +640,8 @@ static int m88e1310_config(struct phy_device *phydev)
        /* Ensure to return to page 0 */
        phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0000);
 
+       marvell_of_reg_init(phydev);
+
        return genphy_config_aneg(phydev);
 }
 
@@ -578,6 +676,8 @@ static int m88e1680_config(struct phy_device *phydev)
        phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
        phy_write(phydev, MDIO_DEVAD_NONE,  0, 0x9140);
 
+       marvell_of_reg_init(phydev);
+
        res = genphy_config_aneg(phydev);
        if (res < 0)
                return res;