[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, ®, &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, ®, &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, ®, &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