[PATCH v4 10/25] pinctrl: rockchip: Add pinctrl route types

Jagan Teki jagan at edgeble.ai
Wed Dec 14 18:50:56 CET 2022


Some pins in rockchip are routed via Top GRF and PMU GRF
instead of direct regmap.

Add support to handle all these routing paths so that the
SoC pinctrl drivers will use them accordingly.

Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
Signed-off-by: Jagan Teki <jagan at edgeble.ai>
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>
---
Changes for v4:
- none
Changes for v3:
- collect Kever r-b
Changes for v2:
- none

 drivers/pinctrl/rockchip/pinctrl-px30.c       | 11 +---
 drivers/pinctrl/rockchip/pinctrl-rk3128.c     | 11 +---
 drivers/pinctrl/rockchip/pinctrl-rk322x.c     | 11 +---
 drivers/pinctrl/rockchip/pinctrl-rk3288.c     | 11 +---
 drivers/pinctrl/rockchip/pinctrl-rk3308.c     | 11 +---
 drivers/pinctrl/rockchip/pinctrl-rk3328.c     | 11 +---
 drivers/pinctrl/rockchip/pinctrl-rk3399.c     | 11 +---
 .../pinctrl/rockchip/pinctrl-rockchip-core.c  | 45 ++++++++++++--
 drivers/pinctrl/rockchip/pinctrl-rockchip.h   | 58 ++++++++++++++++++-
 9 files changed, 102 insertions(+), 78 deletions(-)

diff --git a/drivers/pinctrl/rockchip/pinctrl-px30.c b/drivers/pinctrl/rockchip/pinctrl-px30.c
index 9de29c0b8b..2c35491b24 100644
--- a/drivers/pinctrl/rockchip/pinctrl-px30.c
+++ b/drivers/pinctrl/rockchip/pinctrl-px30.c
@@ -80,7 +80,7 @@ static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, route_reg, route_val;
+	u32 data;
 
 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 				? priv->regmap_pmu : priv->regmap_base;
@@ -90,15 +90,6 @@ static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	reg = bank->iomux[iomux_num].offset;
 	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
 
-	if (bank->route_mask & BIT(pin)) {
-		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
-					   &route_val)) {
-			ret = regmap_write(regmap, route_reg, route_val);
-			if (ret)
-				return ret;
-		}
-	}
-
 	data = (mask << (bit + 16));
 	data |= (mux & mask) << bit;
 	ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c
index e6dc1af86e..355c45eb7f 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c
@@ -106,7 +106,7 @@ static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, route_reg, route_val;
+	u32 data;
 
 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 				? priv->regmap_pmu : priv->regmap_base;
@@ -119,15 +119,6 @@ static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	if (bank->recalced_mask & BIT(pin))
 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
 
-	if (bank->route_mask & BIT(pin)) {
-		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
-					   &route_val)) {
-			ret = regmap_write(regmap, route_reg, route_val);
-			if (ret)
-				return ret;
-		}
-	}
-
 	data = (mask << (bit + 16));
 	data |= (mux & mask) << bit;
 	ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c
index 7c58f40d93..351406da2d 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c
@@ -150,7 +150,7 @@ static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, route_reg, route_val;
+	u32 data;
 
 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 				? priv->regmap_pmu : priv->regmap_base;
@@ -160,15 +160,6 @@ static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	reg = bank->iomux[iomux_num].offset;
 	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
 
-	if (bank->route_mask & BIT(pin)) {
-		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
-					   &route_val)) {
-			ret = regmap_write(regmap, route_reg, route_val);
-			if (ret)
-				return ret;
-		}
-	}
-
 	data = (mask << (bit + 16));
 	data |= (mux & mask) << bit;
 	ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c
index 5894f47f53..a976b7aeeb 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c
@@ -37,7 +37,7 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, route_reg, route_val;
+	u32 data;
 
 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 				? priv->regmap_pmu : priv->regmap_base;
@@ -47,15 +47,6 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	reg = bank->iomux[iomux_num].offset;
 	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
 
-	if (bank->route_mask & BIT(pin)) {
-		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
-					   &route_val)) {
-			ret = regmap_write(regmap, route_reg, route_val);
-			if (ret)
-				return ret;
-		}
-	}
-
 	/* bank0 is special, there are no higher 16 bit writing bits. */
 	if (bank->bank_num == 0) {
 		regmap_read(regmap, reg, &data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3308.c b/drivers/pinctrl/rockchip/pinctrl-rk3308.c
index 83186f40f6..f9ac6347ea 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3308.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3308.c
@@ -258,7 +258,7 @@ static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, route_reg, route_val;
+	u32 data;
 
 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 				? priv->regmap_pmu : priv->regmap_base;
@@ -271,15 +271,6 @@ static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	if (bank->recalced_mask & BIT(pin))
 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
 
-	if (bank->route_mask & BIT(pin)) {
-		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
-					   &route_val)) {
-			ret = regmap_write(regmap, route_reg, route_val);
-			if (ret)
-				return ret;
-		}
-	}
-
 	data = (mask << (bit + 16));
 	data |= (mux & mask) << bit;
 	ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c
index 1c3c5986a5..65a7500767 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c
@@ -130,7 +130,7 @@ static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, route_reg, route_val;
+	u32 data;
 
 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 				? priv->regmap_pmu : priv->regmap_base;
@@ -143,15 +143,6 @@ static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	if (bank->recalced_mask & BIT(pin))
 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
 
-	if (bank->route_mask & BIT(pin)) {
-		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
-					   &route_val)) {
-			ret = regmap_write(regmap, route_reg, route_val);
-			if (ret)
-				return ret;
-		}
-	}
-
 	data = (mask << (bit + 16));
 	data |= (mux & mask) << bit;
 	ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3399.c b/drivers/pinctrl/rockchip/pinctrl-rk3399.c
index caa92200c6..ae785573ba 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3399.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3399.c
@@ -59,7 +59,7 @@ static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, route_reg, route_val;
+	u32 data;
 
 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 				? priv->regmap_pmu : priv->regmap_base;
@@ -69,15 +69,6 @@ static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	reg = bank->iomux[iomux_num].offset;
 	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
 
-	if (bank->route_mask & BIT(pin)) {
-		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
-					   &route_val)) {
-			ret = regmap_write(regmap, route_reg, route_val);
-			if (ret)
-				return ret;
-		}
-	}
-
 	data = (mask << (bit + 16));
 	data |= (mux & mask) << bit;
 	ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
index 630513ba3a..d9d61fdb72 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
@@ -62,8 +62,9 @@ void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
 	*bit = data->bit;
 }
 
-bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
-			    int mux, u32 *reg, u32 *value)
+static enum rockchip_pin_route_type
+rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
+		       int mux, u32 *reg, u32 *value)
 {
 	struct rockchip_pinctrl_priv *priv = bank->priv;
 	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
@@ -78,12 +79,12 @@ bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
 	}
 
 	if (i >= ctrl->niomux_routes)
-		return false;
+		return ROUTE_TYPE_INVALID;
 
 	*reg = data->route_offset;
 	*value = data->route_val;
 
-	return true;
+	return data->route_type;
 }
 
 int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask)
@@ -214,8 +215,40 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 		return -ENOTSUPP;
 
 	ret = ctrl->set_mux(bank, pin, mux);
+	if (ret)
+		return ret;
 
-	return ret;
+	if (bank->route_mask & BIT(pin)) {
+		struct regmap *regmap;
+		u32 route_reg = 0, route_val = 0;
+
+		ret = rockchip_get_mux_route(bank, pin, mux,
+					     &route_reg, &route_val);
+		switch (ret) {
+		case ROUTE_TYPE_DEFAULT:
+			if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+				regmap = priv->regmap_pmu;
+			else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
+				regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base;
+			else
+				regmap = priv->regmap_base;
+
+			regmap_write(regmap, route_reg, route_val);
+			break;
+		case ROUTE_TYPE_TOPGRF:
+			regmap_write(priv->regmap_base, route_reg, route_val);
+			break;
+		case ROUTE_TYPE_PMUGRF:
+			regmap_write(priv->regmap_pmu, route_reg, route_val);
+			break;
+		case ROUTE_TYPE_INVALID:
+			fallthrough;
+		default:
+			break;
+		}
+	}
+
+	return 0;
 }
 
 static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
@@ -545,7 +578,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
 			inc = (iom->type & (IOMUX_WIDTH_4BIT |
 					    IOMUX_WIDTH_3BIT |
 					    IOMUX_8WIDTH_2BIT)) ? 8 : 4;
-			if (iom->type & IOMUX_SOURCE_PMU)
+			if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
 				pmu_offs += inc;
 			else
 				grf_offs += inc;
diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip.h b/drivers/pinctrl/rockchip/pinctrl-rockchip.h
index d969c20082..8dfaba5c74 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rockchip.h
+++ b/drivers/pinctrl/rockchip/pinctrl-rockchip.h
@@ -9,6 +9,9 @@
 #include <linux/bitops.h>
 #include <linux/types.h>
 
+#define RK_GENMASK_VAL(h, l, v) \
+	(GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l))))
+
 /**
  * Encode variants of iomux registers into a type variable
  */
@@ -18,6 +21,7 @@
 #define IOMUX_UNROUTED		BIT(3)
 #define IOMUX_WIDTH_3BIT	BIT(4)
 #define IOMUX_8WIDTH_2BIT	BIT(5)
+#define IOMUX_L_SOURCE_PMU	BIT(6)
 
 /**
  * Defined some common pins constants
@@ -62,6 +66,22 @@ enum rockchip_pin_pull_type {
 	PULL_TYPE_MAX
 };
 
+/**
+ * Rockchip pinctrl route type
+ *
+ * DEFAULT	: Same regmap as pin iomux
+ * TOPGRF	: Mux route setting in topgrf
+ * PMUGRF	: Mux route setting in pmugrf
+ * INVALID	: Nnot need to set mux route
+ */
+enum rockchip_pin_route_type {
+	ROUTE_TYPE_DEFAULT	= 0,
+	ROUTE_TYPE_TOPGRF	= 1,
+	ROUTE_TYPE_PMUGRF	= 2,
+
+	ROUTE_TYPE_INVALID	= -1,
+};
+
 /**
  * @drv_type: drive strength variant using rockchip_perpin_drv_type
  * @offset: if initialized to -1 it will be autocalculated, by specifying
@@ -126,6 +146,21 @@ struct rockchip_pin_bank {
 		},							\
 	}
 
+#define PIN_BANK_IOMUX_FLAGS_OFFSET(id, pins, label, iom0, iom1, iom2,	\
+				    iom3, offset0, offset1, offset2,	\
+				    offset3)				\
+	{								\
+		.bank_num	= id,					\
+		.nr_pins	= pins,					\
+		.name		= label,				\
+		.iomux		= {					\
+			{ .type = iom0, .offset = offset0 },		\
+			{ .type = iom1, .offset = offset1 },		\
+			{ .type = iom2, .offset = offset2 },		\
+			{ .type = iom3, .offset = offset3 },		\
+		},							\
+	}
+
 #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
 	{								\
 		.bank_num	= id,					\
@@ -220,6 +255,25 @@ struct rockchip_pin_bank {
 		.pull_type[3] = pull3,					\
 	}
 
+#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG)		\
+	{								\
+		.bank_num	= ID,					\
+		.pin		= PIN,					\
+		.func		= FUNC,					\
+		.route_offset	= REG,					\
+		.route_val	= VAL,					\
+		.route_type	= FLAG,					\
+	}
+
+#define MR_DEFAULT(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_DEFAULT)
+
+#define MR_TOPGRF(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_TOPGRF)
+
+#define MR_PMUGRF(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_PMUGRF)
+
 /**
  * struct rockchip_mux_recalced_data: recalculate a pin iomux data.
  * @num: bank number.
@@ -241,6 +295,7 @@ struct rockchip_mux_recalced_data {
  * @bank_num: bank number.
  * @pin: index at register or used to calc index.
  * @func: the min pin.
+ * @route_type: the register type.
  * @route_offset: the max pin.
  * @route_val: the register offset.
  */
@@ -248,6 +303,7 @@ struct rockchip_mux_route_data {
 	u8 bank_num;
 	u8 pin;
 	u8 func;
+	enum rockchip_pin_route_type route_type : 8;
 	u32 route_offset;
 	u32 route_val;
 };
@@ -289,8 +345,6 @@ extern const struct pinctrl_ops rockchip_pinctrl_ops;
 int rockchip_pinctrl_probe(struct udevice *dev);
 void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
 			       int *reg, u8 *bit, int *mask);
-bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
-			    int mux, u32 *reg, u32 *value);
 int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask);
 int rockchip_translate_drive_value(int type, int strength);
 int rockchip_translate_pull_value(int type, int pull);
-- 
2.25.1



More information about the U-Boot mailing list