diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 628afb47b579..71aa11b209e8 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -1122,7 +1122,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 		res.start += felix->switch_base;
 		res.end += felix->switch_base;
 
-		target = ocelot_regmap_init(ocelot, &res);
+		target = felix->info->init_regmap(ocelot, &res,
+						  &ocelot->offsets[i]);
 		if (IS_ERR(target)) {
 			dev_err(ocelot->dev,
 				"Failed to map device memory space\n");
@@ -1159,7 +1160,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 		res.start += felix->switch_base;
 		res.end += felix->switch_base;
 
-		target = ocelot_regmap_init(ocelot, &res);
+		target = felix->info->init_regmap(ocelot, &res,
+						  &ocelot_port->offset);
 		if (IS_ERR(target)) {
 			dev_err(ocelot->dev,
 				"Failed to map memory space for port %d\n",
diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
index 4d96cad815d5..03ae576e018a 100644
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -47,6 +47,8 @@ struct felix_info {
 				 enum tc_setup_type type, void *type_data);
 	void	(*port_sched_speed_set)(struct ocelot *ocelot, int port,
 					u32 speed);
+	struct regmap *(*init_regmap)(struct ocelot *ocelot,
+				      struct resource *res, u32 *offset);
 };
 
 extern const struct dsa_switch_ops felix_switch_ops;
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 5ff623ee76a6..87178345116b 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -1362,6 +1362,7 @@ static const struct felix_info felix_info_vsc9959 = {
 	.prevalidate_phy_mode	= vsc9959_prevalidate_phy_mode,
 	.port_setup_tc		= vsc9959_port_setup_tc,
 	.port_sched_speed_set	= vsc9959_sched_speed_set,
+	.init_regmap		= ocelot_regmap_init,
 };
 
 static irqreturn_t felix_irq_handler(int irq, void *data)
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index 84f93a874d50..d88a9729222c 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -1181,6 +1181,7 @@ static const struct felix_info seville_info_vsc9953 = {
 	.mdio_bus_free		= vsc9953_mdio_bus_free,
 	.phylink_validate	= vsc9953_phylink_validate,
 	.prevalidate_phy_mode	= vsc9953_prevalidate_phy_mode,
+	.init_regmap		= ocelot_regmap_init,
 };
 
 static int seville_probe(struct platform_device *pdev)
diff --git a/drivers/net/ethernet/mscc/ocelot_io.c b/drivers/net/ethernet/mscc/ocelot_io.c
index ea4e83410fe4..8f314639faff 100644
--- a/drivers/net/ethernet/mscc/ocelot_io.c
+++ b/drivers/net/ethernet/mscc/ocelot_io.c
@@ -18,7 +18,8 @@ u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset)
 	WARN_ON(!target);
 
 	regmap_read(ocelot->targets[target],
-		    ocelot->map[target][reg & REG_MASK] + offset, &val);
+		    ocelot->offsets[target] +
+			    ocelot->map[target][reg & REG_MASK] + offset, &val);
 	return val;
 }
 EXPORT_SYMBOL(__ocelot_read_ix);
@@ -30,7 +31,8 @@ void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset)
 	WARN_ON(!target);
 
 	regmap_write(ocelot->targets[target],
-		     ocelot->map[target][reg & REG_MASK] + offset, val);
+		     ocelot->offsets[target] +
+			     ocelot->map[target][reg & REG_MASK] + offset, val);
 }
 EXPORT_SYMBOL(__ocelot_write_ix);
 
@@ -42,7 +44,8 @@ void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
 	WARN_ON(!target);
 
 	regmap_update_bits(ocelot->targets[target],
-			   ocelot->map[target][reg & REG_MASK] + offset,
+			   ocelot->offsets[target] +
+				   ocelot->map[target][reg & REG_MASK] + offset,
 			   mask, val);
 }
 EXPORT_SYMBOL(__ocelot_rmw_ix);
@@ -55,7 +58,8 @@ u32 ocelot_port_readl(struct ocelot_port *port, u32 reg)
 
 	WARN_ON(!target);
 
-	regmap_read(port->target, ocelot->map[target][reg & REG_MASK], &val);
+	regmap_read(port->target,
+		    port->offset + ocelot->map[target][reg & REG_MASK], &val);
 	return val;
 }
 EXPORT_SYMBOL(ocelot_port_readl);
@@ -67,7 +71,8 @@ void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
 
 	WARN_ON(!target);
 
-	regmap_write(port->target, ocelot->map[target][reg & REG_MASK], val);
+	regmap_write(port->target,
+		     port->offset + ocelot->map[target][reg & REG_MASK], val);
 }
 EXPORT_SYMBOL(ocelot_port_writel);
 
@@ -85,7 +90,8 @@ u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target,
 	u32 val;
 
 	regmap_read(ocelot->targets[target],
-		    ocelot->map[target][reg] + offset, &val);
+		    ocelot->offsets[target] + ocelot->map[target][reg] + offset,
+		    &val);
 	return val;
 }
 
@@ -93,7 +99,9 @@ void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target,
 			      u32 val, u32 reg, u32 offset)
 {
 	regmap_write(ocelot->targets[target],
-		     ocelot->map[target][reg] + offset, val);
+		     ocelot->offsets[target] + ocelot->map[target][reg] +
+			     offset,
+		     val);
 }
 
 int ocelot_regfields_init(struct ocelot *ocelot,
@@ -136,10 +144,13 @@ static struct regmap_config ocelot_regmap_config = {
 	.reg_stride	= 4,
 };
 
-struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res)
+struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res,
+				  u32 *offset)
 {
 	void __iomem *regs;
 
+	*offset = 0;
+
 	regs = devm_ioremap_resource(ocelot->dev, res);
 	if (IS_ERR(regs))
 		return ERR_CAST(regs);
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 425ff29d9389..ad45c1af4be9 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -591,6 +591,7 @@ struct ocelot_port {
 	struct ocelot			*ocelot;
 
 	struct regmap			*target;
+	u32				offset;
 
 	bool				vlan_aware;
 	/* VLAN that untagged frames are classified to, on ingress */
@@ -621,6 +622,7 @@ struct ocelot {
 	const struct ocelot_ops		*ops;
 	struct regmap			*targets[TARGET_MAX];
 	struct regmap_field		*regfields[REGFIELD_MAX];
+	u32				offsets[TARGET_MAX];
 	const u32 *const		*map;
 	const struct ocelot_stat_layout	*stats_layout;
 	unsigned int			num_stats;
@@ -780,7 +782,8 @@ static inline void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp)
 /* Hardware initialization */
 int ocelot_regfields_init(struct ocelot *ocelot,
 			  const struct reg_field *const regfields);
-struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res);
+struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res,
+				  u32 *offset);
 int ocelot_init(struct ocelot *ocelot);
 void ocelot_deinit(struct ocelot *ocelot);
 void ocelot_init_port(struct ocelot *ocelot, int port);
