pinctrl: rockchip: add support for the rk3368
authorHeiko Stübner <heiko@sntech.de>
Fri, 12 Jun 2015 21:51:01 +0000 (23:51 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 17 Jun 2015 08:21:02 +0000 (10:21 +0200)
The rk3368 is the first ARM64 soc from Rockchip, but seems to share most
peripherals with the ARM32 soc, including the pinctrl functionality.
The only notable difference is - as with every Rockchip soc - that the
offsets in the General Register Files moved around and a split of the pmu
section of the rk3288 into pmu and pmugrf (pmu general register files)
sections. The pinctrl driver of course only needs the pmugrf registers
for controlling the pin settings.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
drivers/pinctrl/pinctrl-rockchip.c

index 388b213249fd745b44395e13d492e1a00d015e7b..391ef4be8d509006446120fb83e73712e7384628 100644 (file)
@@ -21,14 +21,15 @@ defined as gpio sub-nodes of the pinmux controller.
 Required properties for iomux controller:
   - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
                       "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
-                      "rockchip,rk3288-pinctrl"
+                      "rockchip,rk3288-pinctrl", "rockchip,rk3368-pinctrl"
   - rockchip,grf: phandle referencing a syscon providing the
         "general register files"
 
 Optional properties for iomux controller:
   - rockchip,pmu: phandle referencing a syscon providing the pmu registers
         as some SoCs carry parts of the iomux controller registers there.
-        Required for at least rk3188 and rk3288.
+        Required for at least rk3188 and rk3288. On the rk3368 this should
+        point to the PMUGRF syscon.
 
 Deprecated properties for iomux controller:
   - reg: first element is the general register space of the iomux controller
index 429a6eec8c47022fb86a16fb5311e75139b1fde8..9affcd7257764dafeb4632721951dd0ff2fe3b23 100644 (file)
@@ -63,6 +63,7 @@ enum rockchip_pinctrl_type {
        RK3066B,
        RK3188,
        RK3288,
+       RK3368,
 };
 
 /**
@@ -613,6 +614,68 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
        }
 }
 
+#define RK3368_PULL_GRF_OFFSET         0x100
+#define RK3368_PULL_PMU_OFFSET         0x10
+
+static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+                                   int pin_num, struct regmap **regmap,
+                                   int *reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+
+       /* The first 32 pins of the first bank are located in PMU */
+       if (bank->bank_num == 0) {
+               *regmap = info->regmap_pmu;
+               *reg = RK3368_PULL_PMU_OFFSET;
+
+               *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+               *bit = pin_num % RK3188_PULL_PINS_PER_REG;
+               *bit *= RK3188_PULL_BITS_PER_PIN;
+       } else {
+               *regmap = info->regmap_base;
+               *reg = RK3368_PULL_GRF_OFFSET;
+
+               /* correct the offset, as we're starting with the 2nd bank */
+               *reg -= 0x10;
+               *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
+               *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+
+               *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+               *bit *= RK3188_PULL_BITS_PER_PIN;
+       }
+}
+
+#define RK3368_DRV_PMU_OFFSET          0x20
+#define RK3368_DRV_GRF_OFFSET          0x200
+
+static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+                                   int pin_num, struct regmap **regmap,
+                                   int *reg, u8 *bit)
+{
+       struct rockchip_pinctrl *info = bank->drvdata;
+
+       /* The first 32 pins of the first bank are located in PMU */
+       if (bank->bank_num == 0) {
+               *regmap = info->regmap_pmu;
+               *reg = RK3368_DRV_PMU_OFFSET;
+
+               *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
+               *bit = pin_num % RK3288_DRV_PINS_PER_REG;
+               *bit *= RK3288_DRV_BITS_PER_PIN;
+       } else {
+               *regmap = info->regmap_base;
+               *reg = RK3368_DRV_GRF_OFFSET;
+
+               /* correct the offset, as we're starting with the 2nd bank */
+               *reg -= 0x10;
+               *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
+               *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
+
+               *bit = (pin_num % RK3288_DRV_PINS_PER_REG);
+               *bit *= RK3288_DRV_BITS_PER_PIN;
+       }
+}
+
 static int rockchip_perpin_drv_list[] = { 2, 4, 8, 12 };
 
 static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
@@ -703,6 +766,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
                                : PIN_CONFIG_BIAS_DISABLE;
        case RK3188:
        case RK3288:
+       case RK3368:
                data >>= bit;
                data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
 
@@ -758,6 +822,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
                break;
        case RK3188:
        case RK3288:
+       case RK3368:
                spin_lock_irqsave(&bank->slock, flags);
 
                /* enable the write to the equivalent lower bits */
@@ -935,6 +1000,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
                return pull ? false : true;
        case RK3188:
        case RK3288:
+       case RK3368:
                return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
        }
 
@@ -2068,6 +2134,29 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
                .drv_calc_reg           = rk3288_calc_drv_reg_and_bit,
 };
 
+static struct rockchip_pin_bank rk3368_pin_banks[] = {
+       PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
+                                            IOMUX_SOURCE_PMU,
+                                            IOMUX_SOURCE_PMU,
+                                            IOMUX_SOURCE_PMU
+                           ),
+       PIN_BANK(1, 32, "gpio1"),
+       PIN_BANK(2, 32, "gpio2"),
+       PIN_BANK(3, 32, "gpio3"),
+};
+
+static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
+               .pin_banks              = rk3368_pin_banks,
+               .nr_banks               = ARRAY_SIZE(rk3368_pin_banks),
+               .label                  = "RK3368-GPIO",
+               .type                   = RK3368,
+               .grf_mux_offset         = 0x0,
+               .pmu_mux_offset         = 0x0,
+               .pull_calc_reg          = rk3368_calc_pull_reg_and_bit,
+               .drv_calc_reg           = rk3368_calc_drv_reg_and_bit,
+};
+
+
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
        { .compatible = "rockchip,rk2928-pinctrl",
                .data = (void *)&rk2928_pin_ctrl },
@@ -2079,6 +2168,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
                .data = (void *)&rk3188_pin_ctrl },
        { .compatible = "rockchip,rk3288-pinctrl",
                .data = (void *)&rk3288_pin_ctrl },
+       { .compatible = "rockchip,rk3368-pinctrl",
+               .data = (void *)&rk3368_pin_ctrl },
        {},
 };
 MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);