Commit 9b9fd023 authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'read-phy-address-of-switch-from-device-tree-on-mt7530-dsa-subdriver'

Arınç ÜNAL says:

====================
Read PHY address of switch from device tree on MT7530 DSA subdriver

This patch series makes the driver read the PHY address the switch listens
on from the device tree which, in result, brings support for MT7530
switches listening on a different PHY address than 31. And the patch series
simplifies the core operations.
Signed-off-by: default avatarArınç ÜNAL <arinc.unal@arinc9.com>
====================

Link: https://lore.kernel.org/r/20240418-b4-for-netnext-mt7530-phy-addr-from-dt-and-simplify-core-ops-v3-0-3b5fb249b004@arinc9.comSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 077633af 7c5e37d7
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
static int static int
mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
{ {
struct mii_bus *bus = context; struct mt7530_priv *priv = context;
struct mii_bus *bus = priv->bus;
u16 page, r, lo, hi; u16 page, r, lo, hi;
int ret; int ret;
...@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) ...@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
lo = val & 0xffff; lo = val & 0xffff;
hi = val >> 16; hi = val >> 16;
/* MT7530 uses 31 as the pseudo port */ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
ret = bus->write(bus, 0x1f, 0x1f, page);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = bus->write(bus, 0x1f, r, lo); ret = bus->write(bus, priv->mdiodev->addr, r, lo);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = bus->write(bus, 0x1f, 0x10, hi); ret = bus->write(bus, priv->mdiodev->addr, 0x10, hi);
return ret; return ret;
} }
static int static int
mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
{ {
struct mii_bus *bus = context; struct mt7530_priv *priv = context;
struct mii_bus *bus = priv->bus;
u16 page, r, lo, hi; u16 page, r, lo, hi;
int ret; int ret;
page = (reg >> 6) & 0x3ff; page = (reg >> 6) & 0x3ff;
r = (reg >> 2) & 0xf; r = (reg >> 2) & 0xf;
/* MT7530 uses 31 as the pseudo port */ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
ret = bus->write(bus, 0x1f, 0x1f, page);
if (ret < 0) if (ret < 0)
return ret; return ret;
lo = bus->read(bus, 0x1f, r); lo = bus->read(bus, priv->mdiodev->addr, r);
hi = bus->read(bus, 0x1f, 0x10); hi = bus->read(bus, priv->mdiodev->addr, 0x10);
*val = (hi << 16) | (lo & 0xffff); *val = (hi << 16) | (lo & 0xffff);
...@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv *priv) ...@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv *priv)
mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock; mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
regmap = devm_regmap_init(priv->dev, regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
&mt7530_regmap_bus, priv->bus,
mt7531_pcs_config[i]); mt7531_pcs_config[i]);
if (IS_ERR(regmap)) { if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap); ret = PTR_ERR(regmap);
...@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev) ...@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev)
priv->bus = mdiodev->bus; priv->bus = mdiodev->bus;
priv->dev = &mdiodev->dev; priv->dev = &mdiodev->dev;
priv->mdiodev = mdiodev;
ret = mt7530_probe_common(priv); ret = mt7530_probe_common(priv);
if (ret) if (ret)
...@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev) ...@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev)
regmap_config->reg_stride = 4; regmap_config->reg_stride = 4;
regmap_config->max_register = MT7530_CREV; regmap_config->max_register = MT7530_CREV;
regmap_config->disable_locking = true; regmap_config->disable_locking = true;
priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
priv->bus, regmap_config); regmap_config);
if (IS_ERR(priv->regmap)) if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap); return PTR_ERR(priv->regmap);
......
...@@ -74,108 +74,94 @@ static const struct mt7530_mib_desc mt7530_mib[] = { ...@@ -74,108 +74,94 @@ static const struct mt7530_mib_desc mt7530_mib[] = {
MIB_DESC(1, 0xb8, "RxArlDrop"), MIB_DESC(1, 0xb8, "RxArlDrop"),
}; };
/* Since phy_device has not yet been created and static void
* phy_{read,write}_mmd_indirect is not available, we provide our own mt7530_mutex_lock(struct mt7530_priv *priv)
* core_{read,write}_mmd_indirect with core_{clear,write,set} wrappers {
* to complete this function. if (priv->bus)
*/ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
static int }
core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
static void
mt7530_mutex_unlock(struct mt7530_priv *priv)
{
if (priv->bus)
mutex_unlock(&priv->bus->mdio_lock);
}
static void
core_write(struct mt7530_priv *priv, u32 reg, u32 val)
{ {
struct mii_bus *bus = priv->bus; struct mii_bus *bus = priv->bus;
int value, ret; int ret;
mt7530_mutex_lock(priv);
/* Write the desired MMD Devad */ /* Write the desired MMD Devad */
ret = bus->write(bus, 0, MII_MMD_CTRL, devad); ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_CTRL, MDIO_MMD_VEND2);
if (ret < 0) if (ret < 0)
goto err; goto err;
/* Write the desired MMD register address */ /* Write the desired MMD register address */
ret = bus->write(bus, 0, MII_MMD_DATA, prtad); ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_DATA, reg);
if (ret < 0) if (ret < 0)
goto err; goto err;
/* Select the Function : DATA with no post increment */ /* Select the Function : DATA with no post increment */
ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
if (ret < 0) if (ret < 0)
goto err; goto err;
/* Read the content of the MMD's selected register */ /* Write the data into MMD's selected register */
value = bus->read(bus, 0, MII_MMD_DATA); ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_DATA, val);
return value;
err: err:
dev_err(&bus->dev, "failed to read mmd register\n"); if (ret < 0)
dev_err(&bus->dev, "failed to write mmd register\n");
return ret; mt7530_mutex_unlock(priv);
} }
static int static void
core_write_mmd_indirect(struct mt7530_priv *priv, int prtad, core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
int devad, u32 data)
{ {
struct mii_bus *bus = priv->bus; struct mii_bus *bus = priv->bus;
u32 val;
int ret; int ret;
mt7530_mutex_lock(priv);
/* Write the desired MMD Devad */ /* Write the desired MMD Devad */
ret = bus->write(bus, 0, MII_MMD_CTRL, devad); ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_CTRL, MDIO_MMD_VEND2);
if (ret < 0) if (ret < 0)
goto err; goto err;
/* Write the desired MMD register address */ /* Write the desired MMD register address */
ret = bus->write(bus, 0, MII_MMD_DATA, prtad); ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_DATA, reg);
if (ret < 0) if (ret < 0)
goto err; goto err;
/* Select the Function : DATA with no post increment */ /* Select the Function : DATA with no post increment */
ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
if (ret < 0) if (ret < 0)
goto err; goto err;
/* Read the content of the MMD's selected register */
val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_DATA);
val &= ~mask;
val |= set;
/* Write the data into MMD's selected register */ /* Write the data into MMD's selected register */
ret = bus->write(bus, 0, MII_MMD_DATA, data); ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MII_MMD_DATA, val);
err: err:
if (ret < 0) if (ret < 0)
dev_err(&bus->dev, dev_err(&bus->dev, "failed to write mmd register\n");
"failed to write mmd register\n");
return ret;
}
static void
mt7530_mutex_lock(struct mt7530_priv *priv)
{
if (priv->bus)
mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
}
static void
mt7530_mutex_unlock(struct mt7530_priv *priv)
{
if (priv->bus)
mutex_unlock(&priv->bus->mdio_lock);
}
static void
core_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
mt7530_mutex_lock(priv);
core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
mt7530_mutex_unlock(priv);
}
static void
core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
{
u32 val;
mt7530_mutex_lock(priv);
val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
val &= ~mask;
val |= set;
core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
mt7530_mutex_unlock(priv); mt7530_mutex_unlock(priv);
} }
...@@ -2679,16 +2665,19 @@ mt7531_setup(struct dsa_switch *ds) ...@@ -2679,16 +2665,19 @@ mt7531_setup(struct dsa_switch *ds)
* phy_[read,write]_mmd_indirect is called, we provide our own * phy_[read,write]_mmd_indirect is called, we provide our own
* mt7531_ind_mmd_phy_[read,write] to complete this function. * mt7531_ind_mmd_phy_[read,write] to complete this function.
*/ */
val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR, val = mt7531_ind_c45_phy_read(priv,
MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MDIO_MMD_VEND2, CORE_PLL_GROUP4); MDIO_MMD_VEND2, CORE_PLL_GROUP4);
val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE; val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
val &= ~MT7531_PHY_PLL_OFF; val &= ~MT7531_PHY_PLL_OFF;
mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2, mt7531_ind_c45_phy_write(priv,
CORE_PLL_GROUP4, val); MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
/* Disable EEE advertisement on the switch PHYs. */ /* Disable EEE advertisement on the switch PHYs. */
for (i = MT753X_CTRL_PHY_ADDR; for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) { i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
i++) {
mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV, mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
0); 0);
} }
......
...@@ -629,7 +629,7 @@ enum mt7531_clk_skew { ...@@ -629,7 +629,7 @@ enum mt7531_clk_skew {
#define MT7531_PHY_PLL_OFF BIT(5) #define MT7531_PHY_PLL_OFF BIT(5)
#define MT7531_PHY_PLL_BYPASS_MODE BIT(4) #define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
#define MT753X_CTRL_PHY_ADDR 0 #define MT753X_CTRL_PHY_ADDR(addr) ((addr + 1) & 0x1f)
#define CORE_PLL_GROUP5 0x404 #define CORE_PLL_GROUP5 0x404
#define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff) #define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff)
...@@ -778,6 +778,7 @@ struct mt753x_info { ...@@ -778,6 +778,7 @@ struct mt753x_info {
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN * @irq_enable: IRQ enable bits, synced to SYS_INT_EN
* @create_sgmii: Pointer to function creating SGMII PCS instance(s) * @create_sgmii: Pointer to function creating SGMII PCS instance(s)
* @active_cpu_ports: Holding the active CPU ports * @active_cpu_ports: Holding the active CPU ports
* @mdiodev: The pointer to the MDIO device structure
*/ */
struct mt7530_priv { struct mt7530_priv {
struct device *dev; struct device *dev;
...@@ -804,6 +805,7 @@ struct mt7530_priv { ...@@ -804,6 +805,7 @@ struct mt7530_priv {
u32 irq_enable; u32 irq_enable;
int (*create_sgmii)(struct mt7530_priv *priv); int (*create_sgmii)(struct mt7530_priv *priv);
u8 active_cpu_ports; u8 active_cpu_ports;
struct mdio_device *mdiodev;
}; };
struct mt7530_hw_vlan_entry { struct mt7530_hw_vlan_entry {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment