1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2025 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 rv1126b_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 if (bank->recalced_mask & BIT(pin)) 33 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 34 data = (mask << (bit + 16)); 35 data |= (mux & mask) << bit; 36 37 debug("iomux write reg = %x data = %x\n", reg, data); 38 39 ret = regmap_write(regmap, reg, data); 40 41 return ret; 42 } 43 44 #define RV1126B_DRV_BITS_PER_PIN 8 45 #define RV1126B_DRV_PINS_PER_REG 2 46 #define RV1126B_DRV_GPIO0_A_OFFSET 0x100 47 #define RV1126B_DRV_GPIO0_C_OFFSET 0x8120 48 #define RV1126B_DRV_GPIO_OFFSET(GPION) (0x8100 + GPION * 0x8040) 49 50 static int rv1126b_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 if (pin_num < 16) 60 *reg = RV1126B_DRV_GPIO0_A_OFFSET; 61 else 62 *reg = RV1126B_DRV_GPIO0_C_OFFSET - 0x20; 63 break; 64 65 case 1: 66 case 2: 67 case 3: 68 case 4: 69 case 5: 70 case 6: 71 case 7: 72 *reg = RV1126B_DRV_GPIO_OFFSET(bank->bank_num); 73 break; 74 75 default: 76 dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); 77 78 return -EINVAL; 79 } 80 81 *reg += ((pin_num / RV1126B_DRV_PINS_PER_REG) * 4); 82 *bit = pin_num % RV1126B_DRV_PINS_PER_REG; 83 *bit *= RV1126B_DRV_BITS_PER_PIN; 84 85 return 0; 86 } 87 88 static int rv1126b_set_drive(struct rockchip_pin_bank *bank, 89 int pin_num, int strength) 90 { 91 struct regmap *regmap; 92 int reg, ret; 93 u32 data; 94 u8 bit; 95 int rmask_bits = RV1126B_DRV_BITS_PER_PIN; 96 97 ret = rv1126b_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 98 if (ret) 99 return ret; 100 101 /* enable the write to the equivalent lower bits */ 102 data = ((1 << rmask_bits) - 1) << (bit + 16); 103 ret = (1 << (strength + 1)) - 1; 104 data |= (ret << bit); 105 ret = regmap_write(regmap, reg, data); 106 107 return ret; 108 } 109 110 #define RV1126B_PULL_BITS_PER_PIN 2 111 #define RV1126B_PULL_PINS_PER_REG 8 112 #define RV1126B_PULL_GPIO0_A_OFFSET 0x300 113 #define RV1126B_PULL_GPIO0_C_OFFSET 0x8308 114 #define RV1126B_PULL_GPIO_OFFSET(GPION) (0x8300 + GPION * 0x8010) 115 116 static int rv1126b_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 if (pin_num < 16) 126 *reg = RV1126B_PULL_GPIO0_A_OFFSET; 127 else 128 *reg = RV1126B_PULL_GPIO0_C_OFFSET - 0x8; 129 break; 130 131 case 1: 132 case 2: 133 case 3: 134 case 4: 135 case 5: 136 case 6: 137 case 7: 138 *reg = RV1126B_PULL_GPIO_OFFSET(bank->bank_num); 139 break; 140 141 default: 142 dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); 143 144 return -EINVAL; 145 } 146 147 *reg += ((pin_num / RV1126B_PULL_PINS_PER_REG) * 4); 148 *bit = pin_num % RV1126B_PULL_PINS_PER_REG; 149 *bit *= RV1126B_PULL_BITS_PER_PIN; 150 151 return 0; 152 } 153 154 static int rv1126b_set_pull(struct rockchip_pin_bank *bank, 155 int pin_num, int pull) 156 { 157 struct regmap *regmap; 158 int reg, ret; 159 u8 bit, type; 160 u32 data; 161 162 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 163 return -ENOTSUPP; 164 165 ret = rv1126b_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 166 if (ret) 167 return ret; 168 type = bank->pull_type[pin_num / 8]; 169 170 ret = rockchip_translate_pull_value(type, pull); 171 if (ret < 0) { 172 debug("unsupported pull setting %d\n", pull); 173 174 return ret; 175 } 176 177 /* enable the write to the equivalent lower bits */ 178 data = ((1 << RV1126B_PULL_BITS_PER_PIN) - 1) << (bit + 16); 179 data |= (ret << bit); 180 ret = regmap_write(regmap, reg, data); 181 182 return ret; 183 } 184 185 #define RV1126B_SMT_BITS_PER_PIN 1 186 #define RV1126B_SMT_PINS_PER_REG 8 187 #define RV1126B_SMT_GPIO0_A_OFFSET 0x500 188 #define RV1126B_SMT_GPIO0_C_OFFSET 0x8508 189 #define RV1126B_SMT_GPIO_OFFSET(GPION) (0x8500 + GPION * 0x8010) 190 191 static int rv1126b_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 if (pin_num < 16) 202 *reg = RV1126B_SMT_GPIO0_A_OFFSET; 203 else 204 *reg = RV1126B_SMT_GPIO0_C_OFFSET - 0x8; 205 break; 206 207 case 1: 208 case 2: 209 case 3: 210 case 4: 211 case 5: 212 case 6: 213 case 7: 214 *reg = RV1126B_SMT_GPIO_OFFSET(bank->bank_num); 215 break; 216 217 default: 218 dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); 219 return -EINVAL; 220 } 221 222 *reg += ((pin_num / RV1126B_SMT_PINS_PER_REG) * 4); 223 *bit = pin_num % RV1126B_SMT_PINS_PER_REG; 224 *bit *= RV1126B_SMT_BITS_PER_PIN; 225 226 return 0; 227 } 228 229 static int rv1126b_set_schmitt(struct rockchip_pin_bank *bank, 230 int pin_num, int enable) 231 { 232 struct regmap *regmap; 233 int reg, ret; 234 u32 data; 235 u8 bit; 236 237 ret = rv1126b_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 238 if (ret) 239 return ret; 240 241 /* enable the write to the equivalent lower bits */ 242 data = ((1 << RV1126B_SMT_BITS_PER_PIN) - 1) << (bit + 16); 243 data |= (enable << bit); 244 ret = regmap_write(regmap, reg, data); 245 246 return ret; 247 } 248 249 static struct rockchip_pin_bank rv1126b_pin_banks[] = { 250 PIN_BANK_IOMUX_4_OFFSET(0, 32, "gpio0", 251 0x0, 0x8, 0x8010, 0x8018), 252 PIN_BANK_IOMUX_4_OFFSET(1, 32, "gpio1", 253 0x10020, 0x10028, 0x10030, 0x10038), 254 PIN_BANK_IOMUX_4_OFFSET(2, 32, "gpio2", 255 0x18040, 0x18048, 0x18050, 0x18058), 256 PIN_BANK_IOMUX_4_OFFSET(3, 32, "gpio3", 257 0x20060, 0x20068, 0x20070, 0x20078), 258 PIN_BANK_IOMUX_4_OFFSET(4, 32, "gpio4", 259 0x28080, 0x28088, 0x28090, 0x28098), 260 PIN_BANK_IOMUX_4_OFFSET(5, 32, "gpio5", 261 0x300a0, 0x300a8, 0x300b0, 0x300b8), 262 PIN_BANK_IOMUX_4_OFFSET(6, 32, "gpio6", 263 0x380c0, 0x380c8, 0x380d0, 0x380d8), 264 PIN_BANK_IOMUX_4_OFFSET(7, 32, "gpio7", 265 0x400e0, 0x400e8, 0x400f0, 0x400f8), 266 }; 267 static struct rockchip_pin_ctrl rv1126b_pin_ctrl __maybe_unused = { 268 .pin_banks = rv1126b_pin_banks, 269 .nr_banks = ARRAY_SIZE(rv1126b_pin_banks), 270 .nr_pins = 256, 271 .set_mux = rv1126b_set_mux, 272 .set_pull = rv1126b_set_pull, 273 .set_drive = rv1126b_set_drive, 274 .set_schmitt = rv1126b_set_schmitt, 275 }; 276 277 static const struct udevice_id rv1126b_pinctrl_ids[] = { 278 { 279 .compatible = "rockchip,rv1126b-pinctrl", 280 .data = (ulong)&rv1126b_pin_ctrl 281 }, 282 { } 283 }; 284 285 U_BOOT_DRIVER(pinctrl_rv1126b) = { 286 .name = "rockchip_rv1126b_pinctrl", 287 .id = UCLASS_PINCTRL, 288 .of_match = rv1126b_pinctrl_ids, 289 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 290 .ops = &rockchip_pinctrl_ops, 291 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 292 .bind = dm_scan_fdt_dev, 293 #endif 294 .probe = rockchip_pinctrl_probe, 295 }; 296