net: phy: Cleanup the Edge-Rate feature in Microsemi PHYs.
Edge-Rate cleanup include the following: - Updated device tree bindings documentation for edge-rate - The edge-rate is now specified as a "slowdown", meaning that it is now being specified as positive values instead of negative (both documentation and implementation wise). - Only explicitly documented values for "vsc8531,vddmac" and "vsc8531,edge-slowdown" are accepted by the device driver. - Deleted include/dt-bindings/net/mscc-phy-vsc8531.h as it was not needed. - Read/validate devicetree settings in probe instead of init Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com> Signed-off-by: Raju Lakkaraju <raju.lakkaraju@microsemi.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
cf53b1da73
commit
4f58e6dceb
@@ -12,7 +12,6 @@
|
||||
#include <linux/mii.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/of.h>
|
||||
#include <dt-bindings/net/mscc-phy-vsc8531.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
enum rgmii_rx_clock_delay {
|
||||
@@ -69,23 +68,29 @@ enum rgmii_rx_clock_delay {
|
||||
#define PHY_ID_VSC8531 0x00070570
|
||||
#define PHY_ID_VSC8541 0x00070770
|
||||
|
||||
struct edge_rate_table {
|
||||
u16 vddmac;
|
||||
int slowdown[MSCC_SLOWDOWN_MAX];
|
||||
};
|
||||
|
||||
struct edge_rate_table edge_table[MSCC_VDDMAC_MAX] = {
|
||||
{3300, { 0, -2, -4, -7, -10, -17, -29, -53} },
|
||||
{2500, { 0, -3, -6, -10, -14, -23, -37, -63} },
|
||||
{1800, { 0, -5, -9, -16, -23, -35, -52, -76} },
|
||||
{1500, { 0, -6, -14, -21, -29, -42, -58, -77} },
|
||||
};
|
||||
#define MSCC_VDDMAC_1500 1500
|
||||
#define MSCC_VDDMAC_1800 1800
|
||||
#define MSCC_VDDMAC_2500 2500
|
||||
#define MSCC_VDDMAC_3300 3300
|
||||
|
||||
struct vsc8531_private {
|
||||
u8 edge_slowdown;
|
||||
u16 vddmac;
|
||||
int rate_magic;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF_MDIO
|
||||
struct vsc8531_edge_rate_table {
|
||||
u16 vddmac;
|
||||
u8 slowdown[8];
|
||||
};
|
||||
|
||||
static const struct vsc8531_edge_rate_table edge_table[] = {
|
||||
{MSCC_VDDMAC_3300, { 0, 2, 4, 7, 10, 17, 29, 53} },
|
||||
{MSCC_VDDMAC_2500, { 0, 3, 6, 10, 14, 23, 37, 63} },
|
||||
{MSCC_VDDMAC_1800, { 0, 5, 9, 16, 23, 35, 52, 76} },
|
||||
{MSCC_VDDMAC_1500, { 0, 6, 14, 21, 29, 42, 58, 77} },
|
||||
};
|
||||
#endif /* CONFIG_OF_MDIO */
|
||||
|
||||
static int vsc85xx_phy_page_set(struct phy_device *phydev, u8 page)
|
||||
{
|
||||
int rc;
|
||||
@@ -205,29 +210,43 @@ out_unlock:
|
||||
mutex_unlock(&phydev->lock);
|
||||
}
|
||||
|
||||
static u8 edge_rate_magic_get(u16 vddmac,
|
||||
int slowdown)
|
||||
#ifdef CONFIG_OF_MDIO
|
||||
static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
|
||||
{
|
||||
int rc = (MSCC_SLOWDOWN_MAX - 1);
|
||||
u8 vdd;
|
||||
u8 sd;
|
||||
u16 vdd;
|
||||
int rc, i, j;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct device_node *of_node = dev->of_node;
|
||||
u8 sd_array_size = ARRAY_SIZE(edge_table[0].slowdown);
|
||||
|
||||
for (vdd = 0; vdd < MSCC_VDDMAC_MAX; vdd++) {
|
||||
if (edge_table[vdd].vddmac == vddmac) {
|
||||
for (sd = 0; sd < MSCC_SLOWDOWN_MAX; sd++) {
|
||||
if (edge_table[vdd].slowdown[sd] <= slowdown) {
|
||||
rc = (MSCC_SLOWDOWN_MAX - sd - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!of_node)
|
||||
return -ENODEV;
|
||||
|
||||
return rc;
|
||||
rc = of_property_read_u16(of_node, "vsc8531,vddmac", &vdd);
|
||||
if (rc != 0)
|
||||
vdd = MSCC_VDDMAC_3300;
|
||||
|
||||
rc = of_property_read_u8(of_node, "vsc8531,edge-slowdown", &sd);
|
||||
if (rc != 0)
|
||||
sd = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(edge_table); i++)
|
||||
if (edge_table[i].vddmac == vdd)
|
||||
for (j = 0; j < sd_array_size; j++)
|
||||
if (edge_table[i].slowdown[j] == sd)
|
||||
return (sd_array_size - j - 1);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
#else
|
||||
static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_OF_MDIO */
|
||||
|
||||
static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev,
|
||||
u8 edge_rate)
|
||||
static int vsc85xx_edge_rate_cntl_set(struct phy_device *phydev, u8 edge_rate)
|
||||
{
|
||||
int rc;
|
||||
u16 reg_val;
|
||||
@@ -308,45 +327,10 @@ out_unlock:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_MDIO
|
||||
static int vsc8531_of_init(struct phy_device *phydev)
|
||||
{
|
||||
int rc;
|
||||
struct vsc8531_private *vsc8531 = phydev->priv;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct device_node *of_node = dev->of_node;
|
||||
|
||||
if (!of_node)
|
||||
return -ENODEV;
|
||||
|
||||
rc = of_property_read_u16(of_node, "vsc8531,vddmac",
|
||||
&vsc8531->vddmac);
|
||||
if (rc == -EINVAL)
|
||||
vsc8531->vddmac = MSCC_VDDMAC_3300;
|
||||
rc = of_property_read_u8(of_node, "vsc8531,edge-slowdown",
|
||||
&vsc8531->edge_slowdown);
|
||||
if (rc == -EINVAL)
|
||||
vsc8531->edge_slowdown = 0;
|
||||
|
||||
rc = 0;
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static int vsc8531_of_init(struct phy_device *phydev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_OF_MDIO */
|
||||
|
||||
static int vsc85xx_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int rc;
|
||||
struct vsc8531_private *vsc8531 = phydev->priv;
|
||||
u8 edge_rate;
|
||||
|
||||
rc = vsc8531_of_init(phydev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = vsc85xx_default_config(phydev);
|
||||
if (rc)
|
||||
@@ -356,9 +340,7 @@ static int vsc85xx_config_init(struct phy_device *phydev)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
edge_rate = edge_rate_magic_get(vsc8531->vddmac,
|
||||
-(int)vsc8531->edge_slowdown);
|
||||
rc = vsc85xx_edge_rate_cntl_set(phydev, edge_rate);
|
||||
rc = vsc85xx_edge_rate_cntl_set(phydev, vsc8531->rate_magic);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -396,14 +378,21 @@ static int vsc85xx_config_intr(struct phy_device *phydev)
|
||||
|
||||
static int vsc85xx_probe(struct phy_device *phydev)
|
||||
{
|
||||
int rate_magic;
|
||||
struct vsc8531_private *vsc8531;
|
||||
|
||||
rate_magic = vsc85xx_edge_rate_magic_get(phydev);
|
||||
if (rate_magic < 0)
|
||||
return rate_magic;
|
||||
|
||||
vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
|
||||
if (!vsc8531)
|
||||
return -ENOMEM;
|
||||
|
||||
phydev->priv = vsc8531;
|
||||
|
||||
vsc8531->rate_magic = rate_magic;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -424,9 +413,9 @@ static struct phy_driver vsc85xx_driver[] = {
|
||||
.config_intr = &vsc85xx_config_intr,
|
||||
.suspend = &genphy_suspend,
|
||||
.resume = &genphy_resume,
|
||||
.probe = &vsc85xx_probe,
|
||||
.set_wol = &vsc85xx_wol_set,
|
||||
.get_wol = &vsc85xx_wol_get,
|
||||
.probe = &vsc85xx_probe,
|
||||
.set_wol = &vsc85xx_wol_set,
|
||||
.get_wol = &vsc85xx_wol_get,
|
||||
},
|
||||
{
|
||||
.phy_id = PHY_ID_VSC8541,
|
||||
@@ -443,9 +432,9 @@ static struct phy_driver vsc85xx_driver[] = {
|
||||
.config_intr = &vsc85xx_config_intr,
|
||||
.suspend = &genphy_suspend,
|
||||
.resume = &genphy_resume,
|
||||
.probe = &vsc85xx_probe,
|
||||
.set_wol = &vsc85xx_wol_set,
|
||||
.get_wol = &vsc85xx_wol_get,
|
||||
.probe = &vsc85xx_probe,
|
||||
.set_wol = &vsc85xx_wol_set,
|
||||
.get_wol = &vsc85xx_wol_get,
|
||||
}
|
||||
|
||||
};
|
||||
|
Reference in New Issue
Block a user