summaryrefslogtreecommitdiff
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2020-10-05 13:05:46 -0400
committerTom Rini <[email protected]>2020-10-05 14:10:59 -0400
commitb7e7831e5d5be047f421ddc1f308afc22764a893 (patch)
tree7d5f27c82b260278ed0b3ea96bce592b0505b898 /drivers/net/phy
parent050acee119b3757fee3bd128f55d720fdd9bb890 (diff)
parentcaebff09efe8c061b4d99b82262c67fb2db9bbcf (diff)
Merge branch 'next'
Bring in the assorted changes that have been staged in the 'next' branch prior to release. Signed-off-by: Tom Rini <[email protected]>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/mscc.c129
-rw-r--r--drivers/net/phy/phy.c4
2 files changed, 107 insertions, 26 deletions
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
index 709979f48c9..d1a643cf5a0 100644
--- a/drivers/net/phy/mscc.c
+++ b/drivers/net/phy/mscc.c
@@ -157,6 +157,14 @@
#define INT_MEM_DATA_M GENMASK(7, 0)
#define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x))
+/* Extended page GPIO register 13G */
+#define MSCC_CLKOUT_CNTL 13
+#define CLKOUT_ENABLE BIT(15)
+#define CLKOUT_FREQ_MASK GENMASK(14, 13)
+#define CLKOUT_FREQ_25M (0x0 << 13)
+#define CLKOUT_FREQ_50M (0x1 << 13)
+#define CLKOUT_FREQ_125M (0x2 << 13)
+
/* Extended page GPIO register 18G */
#define MSCC_PHY_PROC_CMD 18
#define PROC_CMD_NCOMPLETED BIT(15)
@@ -1168,6 +1176,9 @@ static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
rx_clk_out = RX_CLK_OUT_NORMAL;
break;
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII:
/* Set Reg23.12:11=2 */
mac_if = MAC_IF_SELECTION_RGMII;
@@ -1210,13 +1221,84 @@ static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
return 0;
}
+static int vsc8531_vsc8541_clkout_config(struct phy_device *phydev)
+{
+ struct ofnode_phandle_args phandle_args;
+ u32 clkout_rate = 0;
+ u16 reg_val;
+ int retval;
+
+ retval = dev_read_phandle_with_args(phydev->dev, "phy-handle", NULL,
+ 0, 0, &phandle_args);
+ if (!retval)
+ clkout_rate = ofnode_read_u32_default(phandle_args.node,
+ "vsc8531,clk-out-frequency", 0);
+
+ switch (clkout_rate) {
+ case 0:
+ reg_val = 0;
+ break;
+ case 25000000:
+ reg_val = CLKOUT_FREQ_25M | CLKOUT_ENABLE;
+ break;
+ case 50000000:
+ reg_val = CLKOUT_FREQ_50M | CLKOUT_ENABLE;
+ break;
+ case 125000000:
+ reg_val = CLKOUT_FREQ_125M | CLKOUT_ENABLE;
+ break;
+ default:
+ printf("PHY 8530/31 invalid clkout rate %u\n",
+ clkout_rate);
+ return -EINVAL;
+ }
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_CLKOUT_CNTL, reg_val);
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return 0;
+}
+
+static int vsc8531_vsc8541_clk_skew_config(struct phy_device *phydev)
+{
+ enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_200_PS;
+ enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_200_PS;
+ u16 reg_val;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+ rx_clk_skew = VSC_PHY_RGMII_DELAY_2000_PS;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+ tx_clk_skew = VSC_PHY_RGMII_DELAY_2000_PS;
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXT2);
+ reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
+
+ /* Reg20E2 - Update RGMII RX_Clk Skews. */
+ reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
+ RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
+ /* Reg20E2 - Update RGMII TX_Clk Skews. */
+ reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
+ RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return 0;
+}
+
static int vsc8531_config(struct phy_device *phydev)
{
int retval = -EINVAL;
u16 reg_val;
u16 rmii_clk_out;
- enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
- enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
/* For VSC8530/31 and VSC8540/41 the init scripts are the same */
@@ -1226,6 +1308,9 @@ static int vsc8531_config(struct phy_device *phydev)
switch (phydev->interface) {
case PHY_INTERFACE_MODE_RMII:
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_ID:
retval = vsc8531_vsc8541_mac_config(phydev);
if (retval != 0)
return retval;
@@ -1242,19 +1327,12 @@ static int vsc8531_config(struct phy_device *phydev)
/* Default RMII Clk Output to 0=OFF/1=ON */
rmii_clk_out = 0;
+ retval = vsc8531_vsc8541_clk_skew_config(phydev);
+ if (retval != 0)
+ return retval;
+
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_EXT2);
- reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
-
- /* Reg20E2 - Update RGMII RX_Clk Skews. */
- reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
- RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
- /* Reg20E2 - Update RGMII TX_Clk Skews. */
- reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
- RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
-
- phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
-
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
/* Reg27E2 - Update Clk Slew Rate. */
reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
@@ -1267,6 +1345,11 @@ static int vsc8531_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
+ /* Configure the clk output */
+ retval = vsc8531_vsc8541_clkout_config(phydev);
+ if (retval != 0)
+ return retval;
+
return genphy_config_aneg(phydev);
}
@@ -1275,8 +1358,6 @@ static int vsc8541_config(struct phy_device *phydev)
int retval = -EINVAL;
u16 reg_val;
u16 rmii_clk_out;
- enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
- enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
/* For VSC8530/31 and VSC8540/41 the init scripts are the same */
@@ -1304,17 +1385,12 @@ static int vsc8541_config(struct phy_device *phydev)
/* Default RMII Clk Output to 0=OFF/1=ON */
rmii_clk_out = 0;
+ retval = vsc8531_vsc8541_clk_skew_config(phydev);
+ if (retval != 0)
+ return retval;
+
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_EXT2);
- reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
- /* Reg20E2 - Update RGMII RX_Clk Skews. */
- reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
- RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
- /* Reg20E2 - Update RGMII TX_Clk Skews. */
- reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
- RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
- phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
-
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
/* Reg27E2 - Update Clk Slew Rate. */
reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
@@ -1327,6 +1403,11 @@ static int vsc8541_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
+ /* Configure the clk output */
+ retval = vsc8531_vsc8541_clkout_config(phydev);
+ if (retval != 0)
+ return retval;
+
return genphy_config_aneg(phydev);
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 67789897c25..9587e6b9fae 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -664,7 +664,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
dev = malloc(sizeof(*dev));
if (!dev) {
printf("Failed to allocate PHY device for %s:%d\n",
- bus->name, addr);
+ bus ? bus->name : "(null bus)", addr);
return NULL;
}
@@ -692,7 +692,7 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
return NULL;
}
- if (addr >= 0 && addr < PHY_MAX_ADDR)
+ if (addr >= 0 && addr < PHY_MAX_ADDR && phy_id != PHY_FIXED_ID)
bus->phymap[addr] = dev;
return dev;