Commit 91c724cf authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller
Browse files

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: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d037b4d
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -524,7 +524,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)

	for (port = 0; port < num_phys_ports; port++) {
		struct ocelot_port *ocelot_port;
		void __iomem *port_regs;
		struct regmap *target;

		ocelot_port = devm_kzalloc(ocelot->dev,
					   sizeof(struct ocelot_port),
@@ -541,17 +541,18 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
		res.start += switch_base;
		res.end += switch_base;

		port_regs = devm_ioremap_resource(ocelot->dev, &res);
		if (IS_ERR(port_regs)) {
		target = ocelot_regmap_init(ocelot, &res);
		if (IS_ERR(target)) {
			dev_err(ocelot->dev,
				"failed to map registers for port %d\n", port);
				"Failed to map memory space for port %d\n",
				port);
			kfree(port_phy_modes);
			return PTR_ERR(port_regs);
			return PTR_ERR(target);
		}

		ocelot_port->phy_mode = port_phy_modes[port];
		ocelot_port->ocelot = ocelot;
		ocelot_port->regs = port_regs;
		ocelot_port->target = target;
		ocelot->ports[port] = ocelot_port;
	}

+45 −2
Original line number Diff line number Diff line
@@ -329,7 +329,49 @@ static const u32 vsc9959_gcb_regmap[] = {
	REG(GCB_SOFT_RST,			0x000004),
};

static const u32 *vsc9959_regmap[] = {
static const u32 vsc9959_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_RESERVED(PCS1G_CFG),
	REG_RESERVED(PCS1G_MODE_CFG),
	REG_RESERVED(PCS1G_SD_CFG),
	REG_RESERVED(PCS1G_ANEG_CFG),
	REG_RESERVED(PCS1G_ANEG_NP_CFG),
	REG_RESERVED(PCS1G_LB_CFG),
	REG_RESERVED(PCS1G_DBG_CFG),
	REG_RESERVED(PCS1G_CDET_CFG),
	REG_RESERVED(PCS1G_ANEG_STATUS),
	REG_RESERVED(PCS1G_ANEG_NP_STATUS),
	REG_RESERVED(PCS1G_LINK_STATUS),
	REG_RESERVED(PCS1G_LINK_DOWN_CNT),
	REG_RESERVED(PCS1G_STICKY),
	REG_RESERVED(PCS1G_DEBUG_STATUS),
	REG_RESERVED(PCS1G_LPI_CFG),
	REG_RESERVED(PCS1G_LPI_WAKE_ERROR_CNT),
	REG_RESERVED(PCS1G_LPI_STATUS),
	REG_RESERVED(PCS1G_TSTPAT_MODE_CFG),
	REG_RESERVED(PCS1G_TSTPAT_STATUS),
	REG_RESERVED(DEV_PCS_FX100_CFG),
	REG_RESERVED(DEV_PCS_FX100_STATUS),
};

static const u32 *vsc9959_regmap[TARGET_MAX] = {
	[ANA]	= vsc9959_ana_regmap,
	[QS]	= vsc9959_qs_regmap,
	[QSYS]	= vsc9959_qsys_regmap,
@@ -338,10 +380,11 @@ static const u32 *vsc9959_regmap[] = {
	[S2]	= vsc9959_s2_regmap,
	[PTP]	= vsc9959_ptp_regmap,
	[GCB]	= vsc9959_gcb_regmap,
	[DEV_GMII] = vsc9959_dev_gmii_regmap,
};

/* Addresses are relative to the PCI device's base address */
static const struct resource vsc9959_target_io_res[] = {
static const struct resource vsc9959_target_io_res[TARGET_MAX] = {
	[ANA] = {
		.start	= 0x0280000,
		.end	= 0x028ffff,
+1 −2
Original line number Diff line number Diff line
@@ -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,
+14 −2
Original line number Diff line number Diff line
@@ -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);

+2 −3
Original line number Diff line number Diff line
@@ -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;
Loading