1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2022 Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <dm/pinctrl.h> 9 #include <regmap.h> 10 #include <syscon.h> 11 12 #include "pinctrl-rockchip.h" 13 14 static int rk3528_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 15 { 16 struct rockchip_pinctrl_priv *priv = bank->priv; 17 int iomux_num = (pin / 8); 18 struct regmap *regmap; 19 int reg, ret, mask; 20 u8 bit; 21 u32 data; 22 23 debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 24 25 regmap = priv->regmap_base; 26 reg = bank->iomux[iomux_num].offset; 27 if ((pin % 8) >= 4) 28 reg += 0x4; 29 bit = (pin % 4) * 4; 30 mask = 0xf; 31 32 data = (mask << (bit + 16)); 33 data |= (mux & mask) << bit; 34 35 debug("iomux write reg = %x data = %x\n", reg, data); 36 37 ret = regmap_write(regmap, reg, data); 38 39 return ret; 40 } 41 42 #define RK3528_DRV_BITS_PER_PIN 8 43 #define RK3528_DRV_PINS_PER_REG 2 44 #define RK3528_DRV_GPIO0_OFFSET 0x100 45 #define RK3528_DRV_GPIO1_OFFSET 0x20120 46 #define RK3528_DRV_GPIO2_OFFSET 0x30160 47 #define RK3528_DRV_GPIO3_OFFSET 0x20190 48 #define RK3528_DRV_GPIO4_OFFSET 0x101C0 49 50 static void rk3528_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 51 int pin_num, struct regmap **regmap, 52 int *reg, u8 *bit) 53 { 54 struct rockchip_pinctrl_priv *priv = bank->priv; 55 56 *regmap = priv->regmap_base; 57 switch (bank->bank_num) { 58 case 0: 59 *reg = RK3528_DRV_GPIO0_OFFSET; 60 break; 61 62 case 1: 63 *reg = RK3528_DRV_GPIO1_OFFSET; 64 break; 65 66 case 2: 67 *reg = RK3528_DRV_GPIO2_OFFSET; 68 break; 69 70 case 3: 71 *reg = RK3528_DRV_GPIO3_OFFSET; 72 break; 73 74 case 4: 75 *reg = RK3528_DRV_GPIO4_OFFSET; 76 break; 77 78 default: 79 *reg = 0; 80 dev_err(priv->dev, "unsupported bank_num %d\n", bank->bank_num); 81 break; 82 } 83 84 *reg += ((pin_num / RK3528_DRV_PINS_PER_REG) * 4); 85 *bit = pin_num % RK3528_DRV_PINS_PER_REG; 86 *bit *= RK3528_DRV_BITS_PER_PIN; 87 } 88 89 static int rk3528_set_drive(struct rockchip_pin_bank *bank, 90 int pin_num, int strength) 91 { 92 struct regmap *regmap; 93 int reg, ret; 94 u32 data; 95 u8 bit; 96 int drv = (1 << (strength + 1)) - 1; 97 98 rk3528_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 99 100 /* enable the write to the equivalent lower bits */ 101 data = ((1 << RK3528_DRV_BITS_PER_PIN) - 1) << (bit + 16); 102 data |= (drv << bit); 103 ret = regmap_write(regmap, reg, data); 104 105 return ret; 106 } 107 108 #define RK3528_PULL_BITS_PER_PIN 2 109 #define RK3528_PULL_PINS_PER_REG 8 110 #define RK3528_PULL_GPIO0_OFFSET 0x200 111 #define RK3528_PULL_GPIO1_OFFSET 0x20210 112 #define RK3528_PULL_GPIO2_OFFSET 0x30220 113 #define RK3528_PULL_GPIO3_OFFSET 0x20230 114 #define RK3528_PULL_GPIO4_OFFSET 0x10240 115 116 static void rk3528_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 117 int pin_num, struct regmap **regmap, 118 int *reg, u8 *bit) 119 { 120 struct rockchip_pinctrl_priv *priv = bank->priv; 121 122 *regmap = priv->regmap_base; 123 switch (bank->bank_num) { 124 case 0: 125 *reg = RK3528_PULL_GPIO0_OFFSET; 126 break; 127 128 case 1: 129 *reg = RK3528_PULL_GPIO1_OFFSET; 130 break; 131 132 case 2: 133 *reg = RK3528_PULL_GPIO2_OFFSET; 134 break; 135 136 case 3: 137 *reg = RK3528_PULL_GPIO3_OFFSET; 138 break; 139 140 case 4: 141 *reg = RK3528_PULL_GPIO4_OFFSET; 142 break; 143 144 default: 145 *reg = 0; 146 dev_err(priv->dev, "unsupported bank_num %d\n", bank->bank_num); 147 break; 148 } 149 150 *reg += ((pin_num / RK3528_PULL_PINS_PER_REG) * 4); 151 *bit = pin_num % RK3528_PULL_PINS_PER_REG; 152 *bit *= RK3528_PULL_BITS_PER_PIN; 153 } 154 155 static int rk3528_set_pull(struct rockchip_pin_bank *bank, 156 int pin_num, int pull) 157 { 158 struct regmap *regmap; 159 int reg, ret; 160 u8 bit, type; 161 u32 data; 162 163 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 164 return -ENOTSUPP; 165 166 rk3528_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 167 type = bank->pull_type[pin_num / 8]; 168 ret = rockchip_translate_pull_value(type, pull); 169 if (ret < 0) { 170 debug("unsupported pull setting %d\n", pull); 171 return ret; 172 } 173 174 /* enable the write to the equivalent lower bits */ 175 data = ((1 << RK3528_PULL_BITS_PER_PIN) - 1) << (bit + 16); 176 177 data |= (ret << bit); 178 ret = regmap_write(regmap, reg, data); 179 180 return ret; 181 } 182 183 #define RK3528_SMT_BITS_PER_PIN 1 184 #define RK3528_SMT_PINS_PER_REG 8 185 #define RK3528_SMT_GPIO0_OFFSET 0x400 186 #define RK3528_SMT_GPIO1_OFFSET 0x20410 187 #define RK3528_SMT_GPIO2_OFFSET 0x30420 188 #define RK3528_SMT_GPIO3_OFFSET 0x20430 189 #define RK3528_SMT_GPIO4_OFFSET 0x10440 190 191 static int rk3528_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 192 int pin_num, 193 struct regmap **regmap, 194 int *reg, u8 *bit) 195 { 196 struct rockchip_pinctrl_priv *priv = bank->priv; 197 198 *regmap = priv->regmap_base; 199 switch (bank->bank_num) { 200 case 0: 201 *reg = RK3528_SMT_GPIO0_OFFSET; 202 break; 203 204 case 1: 205 *reg = RK3528_SMT_GPIO1_OFFSET; 206 break; 207 208 case 2: 209 *reg = RK3528_SMT_GPIO2_OFFSET; 210 break; 211 212 case 3: 213 *reg = RK3528_SMT_GPIO3_OFFSET; 214 break; 215 216 case 4: 217 *reg = RK3528_SMT_GPIO4_OFFSET; 218 break; 219 220 default: 221 *reg = 0; 222 dev_err(priv->dev, "unsupported bank_num %d\n", bank->bank_num); 223 break; 224 } 225 226 *reg += ((pin_num / RK3528_SMT_PINS_PER_REG) * 4); 227 *bit = pin_num % RK3528_SMT_PINS_PER_REG; 228 *bit *= RK3528_SMT_BITS_PER_PIN; 229 return 0; 230 } 231 232 static int rk3528_set_schmitt(struct rockchip_pin_bank *bank, 233 int pin_num, int enable) 234 { 235 struct regmap *regmap; 236 int reg, ret; 237 u32 data; 238 u8 bit; 239 240 rk3528_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 241 242 /* enable the write to the equivalent lower bits */ 243 data = ((1 << RK3528_SMT_BITS_PER_PIN) - 1) << (bit + 16); 244 data |= (enable << bit); 245 ret = regmap_write(regmap, reg, data); 246 247 return ret; 248 } 249 250 static struct rockchip_pin_bank rk3528_pin_banks[] = { 251 PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0", 252 IOMUX_WIDTH_4BIT, 253 IOMUX_WIDTH_4BIT, 254 IOMUX_WIDTH_4BIT, 255 IOMUX_WIDTH_4BIT, 256 0, 0, 0, 0), 257 PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", 258 IOMUX_WIDTH_4BIT, 259 IOMUX_WIDTH_4BIT, 260 IOMUX_WIDTH_4BIT, 261 IOMUX_WIDTH_4BIT, 262 0x20020, 0x20028, 0x20030, 0x20038), 263 PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2", 264 IOMUX_WIDTH_4BIT, 265 IOMUX_WIDTH_4BIT, 266 IOMUX_WIDTH_4BIT, 267 IOMUX_WIDTH_4BIT, 268 0x30040, 0, 0, 0), 269 PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3", 270 IOMUX_WIDTH_4BIT, 271 IOMUX_WIDTH_4BIT, 272 IOMUX_WIDTH_4BIT, 273 IOMUX_WIDTH_4BIT, 274 0x20060, 0x20068, 0x20070, 0), 275 PIN_BANK_IOMUX_FLAGS_OFFSET(4, 32, "gpio4", 276 IOMUX_WIDTH_4BIT, 277 IOMUX_WIDTH_4BIT, 278 IOMUX_WIDTH_4BIT, 279 IOMUX_WIDTH_4BIT, 280 0x10080, 0x10088, 0x10090, 0x10098), 281 }; 282 283 static const struct rockchip_pin_ctrl rk3528_pin_ctrl = { 284 .pin_banks = rk3528_pin_banks, 285 .nr_banks = ARRAY_SIZE(rk3528_pin_banks), 286 .nr_pins = 160, 287 .grf_mux_offset = 0x0, 288 .set_mux = rk3528_set_mux, 289 .set_pull = rk3528_set_pull, 290 .set_drive = rk3528_set_drive, 291 .set_schmitt = rk3528_set_schmitt, 292 }; 293 294 static const struct udevice_id rk3528_pinctrl_ids[] = { 295 { 296 .compatible = "rockchip,rk3528-pinctrl", 297 .data = (ulong)&rk3528_pin_ctrl 298 }, 299 { } 300 }; 301 302 U_BOOT_DRIVER(pinctrl_rk3528) = { 303 .name = "rockchip_rk3528_pinctrl", 304 .id = UCLASS_PINCTRL, 305 .of_match = rk3528_pinctrl_ids, 306 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 307 .ops = &rockchip_pinctrl_ops, 308 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 309 .bind = dm_scan_fdt_dev, 310 #endif 311 .probe = rockchip_pinctrl_probe, 312 }; 313 314