diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 4ae328699e..bca60c4042 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -45,18 +45,18 @@ static const struct mtk_drive_desc mtk_drive[] = {
 
 static const char *mtk_pinctrl_dummy_name = "_dummy";
 
-static void mtk_w32(struct udevice *dev, u32 reg, u32 val)
+static void mtk_w32(struct udevice *dev, u8 i, u32 reg, u32 val)
 {
 	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
 
-	__raw_writel(val, priv->base + reg);
+	__raw_writel(val, priv->base[i] + reg);
 }
 
-static u32 mtk_r32(struct udevice *dev, u32 reg)
+static u32 mtk_r32(struct udevice *dev, u8 i, u32 reg)
 {
 	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
 
-	return __raw_readl(priv->base + reg);
+	return __raw_readl(priv->base[i] + reg);
 }
 
 static inline int get_count_order(unsigned int count)
@@ -69,22 +69,29 @@ static inline int get_count_order(unsigned int count)
 	return order;
 }
 
-void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set)
+void mtk_rmw(struct udevice *dev, u8 i, u32 reg, u32 mask, u32 set)
+{
+	return mtk_i_rmw(dev, 0, reg, mask, set);
+}
+
+void mtk_i_rmw(struct udevice *dev, u8 i, u32 reg, u32 mask, u32 set)
 {
 	u32 val;
 
-	val = mtk_r32(dev, reg);
+	val = mtk_r32(dev, i, reg);
 	val &= ~mask;
 	val |= set;
-	mtk_w32(dev, reg, val);
+	mtk_w32(dev, i, reg, val);
 }
 
 static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
 				   const struct mtk_pin_reg_calc *rc,
 				   struct mtk_pin_field *pfd)
 {
+	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
 	const struct mtk_pin_field_calc *c, *e;
 	u32 bits;
+	u32 base_calc = priv->soc->base_calc;
 
 	c = rc->range;
 	e = c + rc->nranges;
@@ -111,6 +118,11 @@ static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
 	pfd->bitpos = bits % c->sz_reg;
 	pfd->mask = (1 << c->x_bits) - 1;
 
+	if (base_calc)
+		pfd->index = c->i_base;
+	else
+		pfd->index = 0;
+
 	/* pfd->next is used for indicating that bit wrapping-around happens
 	 * which requires the manipulation for bit 0 starting in the next
 	 * register to form the complete field read/write.
@@ -150,10 +162,10 @@ static void mtk_hw_write_cross_field(struct udevice *dev,
 
 	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
 
-	mtk_rmw(dev, pf->offset, pf->mask << pf->bitpos,
+	mtk_i_rmw(dev, pf->index, pf->offset, pf->mask << pf->bitpos,
 		(value & pf->mask) << pf->bitpos);
 
-	mtk_rmw(dev, pf->offset + pf->next, BIT(nbits_h) - 1,
+	mtk_i_rmw(dev, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
 		(value & pf->mask) >> nbits_l);
 }
 
@@ -164,8 +176,8 @@ static void mtk_hw_read_cross_field(struct udevice *dev,
 
 	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
 
-	l  = (mtk_r32(dev, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
-	h  = (mtk_r32(dev, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
+	l  = (mtk_r32(dev, pf->index, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
+	h  = (mtk_r32(dev, pf->index, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
 
 	*value = (h << nbits_l) | l;
 }
@@ -181,7 +193,7 @@ static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
 		return err;
 
 	if (!pf.next)
-		mtk_rmw(dev, pf.offset, pf.mask << pf.bitpos,
+		mtk_i_rmw(dev, pf.index, pf.offset, pf.mask << pf.bitpos,
 			(value & pf.mask) << pf.bitpos);
 	else
 		mtk_hw_write_cross_field(dev, &pf, value);
@@ -200,7 +212,7 @@ static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
 		return err;
 
 	if (!pf.next)
-		*value = (mtk_r32(dev, pf.offset) >> pf.bitpos) & pf.mask;
+		*value = (mtk_r32(dev, pf.index, pf.offset) >> pf.bitpos) & pf.mask;
 	else
 		mtk_hw_read_cross_field(dev, &pf, value);
 
@@ -236,7 +248,6 @@ static int mtk_get_pin_muxing(struct udevice *dev, unsigned int selector,
 			      char *buf, int size)
 {
 	int val, err;
-
 	err = mtk_hw_get_value(dev, selector, PINCTRL_PIN_REG_MODE, &val);
 	if (err)
 		return err;
@@ -722,13 +733,23 @@ int mtk_pinctrl_common_probe(struct udevice *dev,
 {
 	struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
 	int ret = 0;
-
-	priv->base = dev_read_addr_ptr(dev);
-	if (!priv->base)
-		return -EINVAL;
+	u32 i = 0;
+	fdt_addr_t addr;
+	u32 base_calc = soc->base_calc;
+	u32 nbase_names = soc->nbase_names;
 
 	priv->soc = soc;
 
+	if (!base_calc)
+		nbase_names = 1;
+
+	for (i = 0; i < nbase_names; i++) {
+		addr = devfdt_get_addr_index(dev, i);
+		if (addr == FDT_ADDR_T_NONE)
+			return -EINVAL;
+		priv->base[i] = (void __iomem *)addr;
+	}
+
 #if CONFIG_IS_ENABLED(DM_GPIO) || \
     (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO))
 	ret = mtk_gpiochip_register(dev);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 735fb6fef8..91a8c0581f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -8,6 +8,8 @@
 
 #define MTK_PINCTRL_V0 0x0
 #define MTK_PINCTRL_V1 0x1
+#define BASE_CALC_NONE 0
+#define MAX_BASE_CALC 10
 
 #define MTK_RANGE(_a)		{ .range = (_a), .nranges = ARRAY_SIZE(_a), }
 #define MTK_PIN(_number, _name, _drv_n) {				\
@@ -24,10 +26,11 @@
 		id##_funcs,						\
 	}
 
-#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
-			_x_bits, _sz_reg, _fixed) {			\
+#define PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs,	\
+			    _s_bit, _x_bits, _sz_reg, _fixed) {		\
 		.s_pin = _s_pin,					\
 		.e_pin = _e_pin,					\
+		.i_base = _i_base,					\
 		.s_addr = _s_addr,					\
 		.x_addrs = _x_addrs,					\
 		.s_bit = _s_bit,					\
@@ -36,6 +39,11 @@
 		.fixed = _fixed,					\
 	}
 
+#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+			_x_bits, _sz_reg, _fixed)			\
+	 PIN_FIELD_BASE_CALC(_s_pin, _e_pin, BASE_CALC_NONE, _s_addr,	\
+			    _x_addrs, _s_bit, _x_bits, _sz_reg, _fixed)
+
 /* List these attributes which could be modified for the pin */
 enum {
 	PINCTRL_PIN_REG_MODE,
@@ -70,6 +78,7 @@ enum {
 /**
  * struct mtk_pin_field - the structure that holds the information of the field
  *			  used to describe the attribute for the pin
+ * @index:		the index pointing to the entry in base address list
  * @offset:		the register offset relative to the base address
  * @mask:		the mask used to filter out the field from the register
  * @bitpos:		the start bit relative to the register
@@ -77,6 +86,7 @@ enum {
 			next register
  */
 struct mtk_pin_field {
+	u8  index;
 	u32 offset;
 	u32 mask;
 	u8 bitpos;
@@ -88,6 +98,7 @@ struct mtk_pin_field {
  *			       the guide used to look up the relevant field
  * @s_pin:		the start pin within the range
  * @e_pin:		the end pin within the range
+ * @i_base:		the index pointing to the entry in base address list
  * @s_addr:		the start address for the range
  * @x_addrs:		the address distance between two consecutive registers
  *			within the range
@@ -101,6 +112,7 @@ struct mtk_pin_field {
 struct mtk_pin_field_calc {
 	u16 s_pin;
 	u16 e_pin;
+	u8  i_base;
 	u32 s_addr;
 	u8 x_addrs;
 	u8 s_bit;
@@ -171,7 +183,10 @@ struct mtk_pinctrl_soc {
 	const struct mtk_function_desc *funcs;
 	int nfuncs;
 	int gpio_mode;
+	const char * const *base_names;
+	unsigned int nbase_names;
 	int rev;
+	int base_calc;
 };
 
 /**
@@ -181,7 +196,7 @@ struct mtk_pinctrl_soc {
  * @soc: SoC specific data
  */
 struct mtk_pinctrl_priv {
-	void __iomem *base;
+	void __iomem *base[MAX_BASE_CALC];
 	struct mtk_pinctrl_soc *soc;
 };
 
@@ -189,6 +204,7 @@ extern const struct pinctrl_ops mtk_pinctrl_ops;
 
 /* A common read-modify-write helper for MediaTek chips */
 void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set);
+void mtk_i_rmw(struct udevice *dev, u8 i, u32 reg, u32 mask, u32 set);
 int mtk_pinctrl_common_probe(struct udevice *dev,
 			     struct mtk_pinctrl_soc *soc);
 
