]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
pinctrl: rockchip: Add pinctrl route types
authorJagan Teki <jagan@edgeble.ai>
Wed, 14 Dec 2022 17:50:56 +0000 (23:20 +0530)
committerKever Yang <kever.yang@rock-chips.com>
Mon, 16 Jan 2023 10:01:11 +0000 (18:01 +0800)
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@rock-chips.com>
Signed-off-by: Jagan Teki <jagan@edgeble.ai>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
drivers/pinctrl/rockchip/pinctrl-px30.c
drivers/pinctrl/rockchip/pinctrl-rk3128.c
drivers/pinctrl/rockchip/pinctrl-rk322x.c
drivers/pinctrl/rockchip/pinctrl-rk3288.c
drivers/pinctrl/rockchip/pinctrl-rk3308.c
drivers/pinctrl/rockchip/pinctrl-rk3328.c
drivers/pinctrl/rockchip/pinctrl-rk3399.c
drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
drivers/pinctrl/rockchip/pinctrl-rockchip.h

index 9de29c0b8b4332eafccb997c957252561454cf41..2c35491b24d86152a9992f08078278b15f2de8a7 100644 (file)
@@ -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);
index e6dc1af86e960524f27cfae00fc4b6cc2d057326..355c45eb7f8ccab930eb1186bebc8fba0d491fda 100644 (file)
@@ -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);
index 7c58f40d93db86755934093e0bf59b93d62833f8..351406da2d451af5a0c25320d16daa402fdb2c2d 100644 (file)
@@ -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);
index 5894f47f534b1c314fe04165482f623982e826b0..a976b7aeeb27f7bfe255b6c038f0b4adc4959ba2 100644 (file)
@@ -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);
index 83186f40f6f089d2bfb04b771f0af56cc2417d28..f9ac6347eaf15fbf839d9940794a14f43bd5c08c 100644 (file)
@@ -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);
index 1c3c5986a50458252ab0b5287400503c1f736d24..65a750076773b361abc833f29a98ca564265271c 100644 (file)
@@ -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);
index caa92200c6eb9c36d5474b0585479663e70dbc24..ae785573baf578cdd81b1c36df37fd4598f7a38c 100644 (file)
@@ -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);
index 630513ba3a22d00fec8d5f12c209b7d159674cce..d9d61fdb726a9754b842f66ad27f53f5fbfd2ff1 100644 (file)
@@ -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;
index d969c200826c046e708bde1f8cfe4c8c5f78f3e7..8dfaba5c74d2a3ef7d47b5c8f2f5af70f80279af 100644 (file)
@@ -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);