[PATCH v2 12/28] pinctrl: rockchip: Add pinctrl route types

Kever Yang kever.yang at rock-chips.com
Wed Sep 28 14:19:27 CEST 2022


On 2022/8/18 22:52, Jagan Teki wrote:
> 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>

Thanks,
- Kever
> ---
> 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);


More information about the U-Boot mailing list