net: mscc: ocelot: convert port registers to regmap
At the moment, there are some minimal register differences between VSC7514 Ocelot and VSC9959 Felix. To be precise, the PCS1G registers are missing from Felix because it was integrated with an NXP PCS. But with VSC9953 Seville (not yet introduced), the register differences are more pronounced. The MAC registers are located at different offsets within the DEV_GMII target. So we need to refactor the driver to keep a regmap even for per-port registers. The callers of the ocelot_port_readl and ocelot_port_writel were kept unchanged, only the implementation is now more generic. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
5d037b4d3d
commit
91c724cfc0
@@ -105,8 +105,7 @@ void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg);
|
||||
#define ocelot_field_write(ocelot, reg, val) regmap_field_write((ocelot)->regfields[(reg)], (val))
|
||||
#define ocelot_field_read(ocelot, reg, val) regmap_field_read((ocelot)->regfields[(reg)], (val))
|
||||
|
||||
int ocelot_probe_port(struct ocelot *ocelot, u8 port,
|
||||
void __iomem *regs,
|
||||
int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target,
|
||||
struct phy_device *phy);
|
||||
|
||||
void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu,
|
||||
|
||||
@@ -49,13 +49,25 @@ EXPORT_SYMBOL(__ocelot_rmw_ix);
|
||||
|
||||
u32 ocelot_port_readl(struct ocelot_port *port, u32 reg)
|
||||
{
|
||||
return readl(port->regs + reg);
|
||||
struct ocelot *ocelot = port->ocelot;
|
||||
u16 target = reg >> TARGET_OFFSET;
|
||||
u32 val;
|
||||
|
||||
WARN_ON(!target);
|
||||
|
||||
regmap_read(port->target, ocelot->map[target][reg & REG_MASK], &val);
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL(ocelot_port_readl);
|
||||
|
||||
void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
|
||||
{
|
||||
writel(val, port->regs + reg);
|
||||
struct ocelot *ocelot = port->ocelot;
|
||||
u16 target = reg >> TARGET_OFFSET;
|
||||
|
||||
WARN_ON(!target);
|
||||
|
||||
regmap_write(port->target, ocelot->map[target][reg & REG_MASK], val);
|
||||
}
|
||||
EXPORT_SYMBOL(ocelot_port_writel);
|
||||
|
||||
|
||||
@@ -1005,8 +1005,7 @@ struct notifier_block ocelot_switchdev_blocking_nb __read_mostly = {
|
||||
.notifier_call = ocelot_switchdev_blocking_event,
|
||||
};
|
||||
|
||||
int ocelot_probe_port(struct ocelot *ocelot, u8 port,
|
||||
void __iomem *regs,
|
||||
int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target,
|
||||
struct phy_device *phy)
|
||||
{
|
||||
struct ocelot_port_private *priv;
|
||||
@@ -1024,7 +1023,7 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
|
||||
priv->chip_port = port;
|
||||
ocelot_port = &priv->port;
|
||||
ocelot_port->ocelot = ocelot;
|
||||
ocelot_port->regs = regs;
|
||||
ocelot_port->target = target;
|
||||
ocelot->ports[port] = ocelot_port;
|
||||
|
||||
dev->netdev_ops = &ocelot_port_netdev_ops;
|
||||
|
||||
@@ -263,7 +263,49 @@ static const u32 ocelot_ptp_regmap[] = {
|
||||
REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8),
|
||||
};
|
||||
|
||||
static const u32 *ocelot_regmap[] = {
|
||||
static const u32 ocelot_dev_gmii_regmap[] = {
|
||||
REG(DEV_CLOCK_CFG, 0x0),
|
||||
REG(DEV_PORT_MISC, 0x4),
|
||||
REG(DEV_EVENTS, 0x8),
|
||||
REG(DEV_EEE_CFG, 0xc),
|
||||
REG(DEV_RX_PATH_DELAY, 0x10),
|
||||
REG(DEV_TX_PATH_DELAY, 0x14),
|
||||
REG(DEV_PTP_PREDICT_CFG, 0x18),
|
||||
REG(DEV_MAC_ENA_CFG, 0x1c),
|
||||
REG(DEV_MAC_MODE_CFG, 0x20),
|
||||
REG(DEV_MAC_MAXLEN_CFG, 0x24),
|
||||
REG(DEV_MAC_TAGS_CFG, 0x28),
|
||||
REG(DEV_MAC_ADV_CHK_CFG, 0x2c),
|
||||
REG(DEV_MAC_IFG_CFG, 0x30),
|
||||
REG(DEV_MAC_HDX_CFG, 0x34),
|
||||
REG(DEV_MAC_DBG_CFG, 0x38),
|
||||
REG(DEV_MAC_FC_MAC_LOW_CFG, 0x3c),
|
||||
REG(DEV_MAC_FC_MAC_HIGH_CFG, 0x40),
|
||||
REG(DEV_MAC_STICKY, 0x44),
|
||||
REG(PCS1G_CFG, 0x48),
|
||||
REG(PCS1G_MODE_CFG, 0x4c),
|
||||
REG(PCS1G_SD_CFG, 0x50),
|
||||
REG(PCS1G_ANEG_CFG, 0x54),
|
||||
REG(PCS1G_ANEG_NP_CFG, 0x58),
|
||||
REG(PCS1G_LB_CFG, 0x5c),
|
||||
REG(PCS1G_DBG_CFG, 0x60),
|
||||
REG(PCS1G_CDET_CFG, 0x64),
|
||||
REG(PCS1G_ANEG_STATUS, 0x68),
|
||||
REG(PCS1G_ANEG_NP_STATUS, 0x6c),
|
||||
REG(PCS1G_LINK_STATUS, 0x70),
|
||||
REG(PCS1G_LINK_DOWN_CNT, 0x74),
|
||||
REG(PCS1G_STICKY, 0x78),
|
||||
REG(PCS1G_DEBUG_STATUS, 0x7c),
|
||||
REG(PCS1G_LPI_CFG, 0x80),
|
||||
REG(PCS1G_LPI_WAKE_ERROR_CNT, 0x84),
|
||||
REG(PCS1G_LPI_STATUS, 0x88),
|
||||
REG(PCS1G_TSTPAT_MODE_CFG, 0x8c),
|
||||
REG(PCS1G_TSTPAT_STATUS, 0x90),
|
||||
REG(DEV_PCS_FX100_CFG, 0x94),
|
||||
REG(DEV_PCS_FX100_STATUS, 0x98),
|
||||
};
|
||||
|
||||
static const u32 *ocelot_regmap[TARGET_MAX] = {
|
||||
[ANA] = ocelot_ana_regmap,
|
||||
[QS] = ocelot_qs_regmap,
|
||||
[QSYS] = ocelot_qsys_regmap,
|
||||
@@ -271,6 +313,7 @@ static const u32 *ocelot_regmap[] = {
|
||||
[SYS] = ocelot_sys_regmap,
|
||||
[S2] = ocelot_s2_regmap,
|
||||
[PTP] = ocelot_ptp_regmap,
|
||||
[DEV_GMII] = ocelot_dev_gmii_regmap,
|
||||
};
|
||||
|
||||
static const struct reg_field ocelot_regfields[] = {
|
||||
@@ -948,9 +991,9 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
|
||||
struct device_node *phy_node;
|
||||
phy_interface_t phy_mode;
|
||||
struct phy_device *phy;
|
||||
struct regmap *target;
|
||||
struct resource *res;
|
||||
struct phy *serdes;
|
||||
void __iomem *regs;
|
||||
char res_name[8];
|
||||
u32 port;
|
||||
|
||||
@@ -961,8 +1004,8 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
res_name);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(regs))
|
||||
target = ocelot_regmap_init(ocelot, res);
|
||||
if (IS_ERR(target))
|
||||
continue;
|
||||
|
||||
phy_node = of_parse_phandle(portnp, "phy-handle", 0);
|
||||
@@ -974,7 +1017,7 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
|
||||
if (!phy)
|
||||
continue;
|
||||
|
||||
err = ocelot_probe_port(ocelot, port, regs, phy);
|
||||
err = ocelot_probe_port(ocelot, port, target, phy);
|
||||
if (err) {
|
||||
of_node_put(portnp);
|
||||
goto out_put_ports;
|
||||
|
||||
Reference in New Issue
Block a user