diff options
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-px30.c | 11 | ||||
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rk3128.c | 11 | ||||
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rk322x.c | 11 | ||||
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rk3288.c | 11 | ||||
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rk3308.c | 11 | ||||
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rk3328.c | 11 | ||||
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rk3399.c | 11 | ||||
-rw-r--r-- | drivers/pinctrl/rockchip/pinctrl-rockchip-core.c | 45 | ||||
-rw-r--r-- | 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 9de29c0b8b4..2c35491b24d 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 e6dc1af86e9..355c45eb7f8 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 7c58f40d93d..351406da2d4 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 5894f47f534..a976b7aeeb2 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 83186f40f6f..f9ac6347eaf 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 1c3c5986a50..65a75007677 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 caa92200c6e..ae785573baf 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 630513ba3a2..d9d61fdb726 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 d969c200826..8dfaba5c74d 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 @@ -63,6 +67,22 @@ enum rockchip_pin_pull_type { }; /** + * 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 * an initial offset value the relevant source offset can be reset @@ -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); |