1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2024 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 rockchip_set_rmio(struct rockchip_pin_bank *bank, int pin, int *mux) 15 { 16 struct rockchip_pinctrl_priv *priv = bank->priv; 17 struct regmap *regmap; 18 int reg, function; 19 u32 data; 20 int ret = 0; 21 u32 iomux_max = (1 << 4) - 1; 22 23 if (*mux > iomux_max) 24 function = *mux - iomux_max; 25 else 26 return 0; 27 28 regmap = priv->regmap_rmio; 29 if (bank->bank_num == 0) { 30 if (pin < 24) 31 reg = 0x80 + 0x4 * pin; 32 else 33 ret = -EINVAL; 34 } else if (bank->bank_num == 1) { 35 if (pin >= 9 && pin <= 11) 36 reg = 0xbc + 0x4 * pin; 37 else if (pin >= 18 && pin <= 19) 38 reg = 0xa4 + 0x4 * pin; 39 else if (pin >= 25 && pin <= 27) 40 reg = 0x90 + 0x4 * pin; 41 else 42 ret = -EINVAL; 43 } else { 44 ret = -EINVAL; 45 } 46 if (ret) { 47 pr_err("rmio unsupported bank_num %d function %d\n", 48 bank->bank_num, function); 49 50 return -EINVAL; 51 } 52 53 data = 0x7f0000 | function; 54 *mux = 7; 55 ret = regmap_write(regmap, reg, data); 56 if (ret) 57 return ret; 58 59 return 0; 60 } 61 62 static int rk3506_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 63 { 64 struct rockchip_pinctrl_priv *priv = bank->priv; 65 int iomux_num = (pin / 8); 66 struct regmap *regmap; 67 int reg, ret, mask; 68 u8 bit; 69 u32 data; 70 71 debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 72 73 ret = rockchip_set_rmio(bank, pin, &mux); 74 if (ret) 75 return ret; 76 77 if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 78 regmap = priv->regmap_pmu; 79 else 80 regmap = priv->regmap_base; 81 82 if (bank->bank_num == 1) 83 regmap = priv->regmap_ioc1; 84 else if (bank->bank_num == 4) 85 return 0; 86 87 reg = bank->iomux[iomux_num].offset; 88 if ((pin % 8) >= 4) 89 reg += 0x4; 90 bit = (pin % 4) * 4; 91 mask = 0xf; 92 93 if (bank->recalced_mask & BIT(pin)) 94 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 95 data = (mask << (bit + 16)); 96 data |= (mux & mask) << bit; 97 98 debug("iomux write reg = %x data = %x\n", reg, data); 99 100 ret = regmap_write(regmap, reg, data); 101 102 return ret; 103 } 104 105 #define RK3506_DRV_BITS_PER_PIN 8 106 #define RK3506_DRV_PINS_PER_REG 2 107 #define RK3506_DRV_GPIO0_A_OFFSET 0x100 108 #define RK3506_DRV_GPIO0_D_OFFSET 0x830 109 #define RK3506_DRV_GPIO1_OFFSET 0x140 110 #define RK3506_DRV_GPIO2_OFFSET 0x180 111 #define RK3506_DRV_GPIO3_OFFSET 0x1c0 112 #define RK3506_DRV_GPIO4_OFFSET 0x840 113 114 static int rk3506_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 115 int pin_num, struct regmap **regmap, 116 int *reg, u8 *bit) 117 { 118 struct rockchip_pinctrl_priv *priv = bank->priv; 119 int ret = 0; 120 121 switch (bank->bank_num) { 122 case 0: 123 *regmap = priv->regmap_pmu; 124 if (pin_num > 24) { 125 ret = -EINVAL; 126 } else if (pin_num < 24) { 127 *reg = RK3506_DRV_GPIO0_A_OFFSET; 128 } else { 129 *reg = RK3506_DRV_GPIO0_D_OFFSET; 130 *bit = 3; 131 132 return 0; 133 } 134 break; 135 136 case 1: 137 *regmap = priv->regmap_ioc1; 138 if (pin_num < 28) 139 *reg = RK3506_DRV_GPIO1_OFFSET; 140 else 141 ret = -EINVAL; 142 break; 143 144 case 2: 145 *regmap = priv->regmap_base; 146 if (pin_num < 17) 147 *reg = RK3506_DRV_GPIO2_OFFSET; 148 else 149 ret = -EINVAL; 150 break; 151 152 case 3: 153 *regmap = priv->regmap_base; 154 if (pin_num < 15) 155 *reg = RK3506_DRV_GPIO3_OFFSET; 156 else 157 ret = -EINVAL; 158 break; 159 160 case 4: 161 *regmap = priv->regmap_base; 162 if (pin_num < 8 || pin_num > 11) { 163 ret = -EINVAL; 164 } else { 165 *reg = RK3506_DRV_GPIO4_OFFSET; 166 *bit = 10; 167 168 return 0; 169 } 170 break; 171 172 default: 173 ret = -EINVAL; 174 break; 175 } 176 177 if (ret) { 178 debug("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num); 179 180 return ret; 181 } 182 183 *reg += ((pin_num / RK3506_DRV_PINS_PER_REG) * 4); 184 *bit = pin_num % RK3506_DRV_PINS_PER_REG; 185 *bit *= RK3506_DRV_BITS_PER_PIN; 186 187 return 0; 188 } 189 190 static int rk3506_set_drive(struct rockchip_pin_bank *bank, 191 int pin_num, int strength) 192 { 193 struct regmap *regmap; 194 int reg, ret, i; 195 u32 data; 196 u8 bit; 197 int rmask_bits = RK3506_DRV_BITS_PER_PIN; 198 199 ret = rk3506_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 200 if (ret) 201 return ret; 202 203 for (i = 0, ret = 1; i < strength; i++) 204 ret = (ret << 1) | 1; 205 206 if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) { 207 rmask_bits = 2; 208 ret = strength; 209 } 210 211 /* enable the write to the equivalent lower bits */ 212 data = ((1 << rmask_bits) - 1) << (bit + 16); 213 data |= (ret << bit); 214 ret = regmap_write(regmap, reg, data); 215 216 return ret; 217 } 218 219 #define RK3506_PULL_BITS_PER_PIN 2 220 #define RK3506_PULL_PINS_PER_REG 8 221 #define RK3506_PULL_GPIO0_A_OFFSET 0x200 222 #define RK3506_PULL_GPIO0_D_OFFSET 0x830 223 #define RK3506_PULL_GPIO1_OFFSET 0x210 224 #define RK3506_PULL_GPIO2_OFFSET 0x220 225 #define RK3506_PULL_GPIO3_OFFSET 0x230 226 #define RK3506_PULL_GPIO4_OFFSET 0x840 227 228 static int rk3506_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 229 int pin_num, struct regmap **regmap, 230 int *reg, u8 *bit) 231 { 232 struct rockchip_pinctrl_priv *priv = bank->priv; 233 int ret = 0; 234 235 switch (bank->bank_num) { 236 case 0: 237 *regmap = priv->regmap_pmu; 238 if (pin_num > 24) { 239 ret = -EINVAL; 240 } else if (pin_num < 24) { 241 *reg = RK3506_PULL_GPIO0_A_OFFSET; 242 } else { 243 *reg = RK3506_PULL_GPIO0_D_OFFSET; 244 *bit = 5; 245 246 return 0; 247 } 248 break; 249 250 case 1: 251 *regmap = priv->regmap_ioc1; 252 if (pin_num < 28) 253 *reg = RK3506_PULL_GPIO1_OFFSET; 254 else 255 ret = -EINVAL; 256 break; 257 258 case 2: 259 *regmap = priv->regmap_base; 260 if (pin_num < 17) 261 *reg = RK3506_PULL_GPIO2_OFFSET; 262 else 263 ret = -EINVAL; 264 break; 265 266 case 3: 267 *regmap = priv->regmap_base; 268 if (pin_num < 15) 269 *reg = RK3506_PULL_GPIO3_OFFSET; 270 else 271 ret = -EINVAL; 272 break; 273 274 case 4: 275 *regmap = priv->regmap_base; 276 if (pin_num < 8 || pin_num > 11) { 277 ret = -EINVAL; 278 } else { 279 *reg = RK3506_PULL_GPIO4_OFFSET; 280 *bit = 13; 281 282 return 0; 283 } 284 break; 285 286 default: 287 ret = -EINVAL; 288 break; 289 } 290 291 if (ret) { 292 debug("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num); 293 294 return ret; 295 } 296 297 *reg += ((pin_num / RK3506_PULL_PINS_PER_REG) * 4); 298 *bit = pin_num % RK3506_PULL_PINS_PER_REG; 299 *bit *= RK3506_PULL_BITS_PER_PIN; 300 301 return 0; 302 } 303 304 static int rk3506_set_pull(struct rockchip_pin_bank *bank, 305 int pin_num, int pull) 306 { 307 struct regmap *regmap; 308 int reg, ret; 309 u8 bit, type; 310 u32 data; 311 312 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 313 return -ENOTSUPP; 314 315 ret = rk3506_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 316 if (ret) 317 return ret; 318 type = bank->pull_type[pin_num / 8]; 319 320 if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) 321 type = 1; 322 323 ret = rockchip_translate_pull_value(type, pull); 324 if (ret < 0) { 325 debug("unsupported pull setting %d\n", pull); 326 327 return ret; 328 } 329 330 /* enable the write to the equivalent lower bits */ 331 data = ((1 << RK3506_PULL_BITS_PER_PIN) - 1) << (bit + 16); 332 333 data |= (ret << bit); 334 ret = regmap_write(regmap, reg, data); 335 336 return ret; 337 } 338 339 #define RK3506_SMT_BITS_PER_PIN 1 340 #define RK3506_SMT_PINS_PER_REG 8 341 #define RK3506_SMT_GPIO0_A_OFFSET 0x400 342 #define RK3506_SMT_GPIO0_D_OFFSET 0x830 343 #define RK3506_SMT_GPIO1_OFFSET 0x410 344 #define RK3506_SMT_GPIO2_OFFSET 0x420 345 #define RK3506_SMT_GPIO3_OFFSET 0x430 346 #define RK3506_SMT_GPIO4_OFFSET 0x840 347 348 static int rk3506_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 349 int pin_num, 350 struct regmap **regmap, 351 int *reg, u8 *bit) 352 { 353 struct rockchip_pinctrl_priv *priv = bank->priv; 354 int ret = 0; 355 356 switch (bank->bank_num) { 357 case 0: 358 *regmap = priv->regmap_pmu; 359 if (pin_num > 24) { 360 ret = -EINVAL; 361 } else if (pin_num < 24) { 362 *reg = RK3506_SMT_GPIO0_A_OFFSET; 363 } else { 364 *reg = RK3506_SMT_GPIO0_D_OFFSET; 365 *bit = 9; 366 367 return 0; 368 } 369 break; 370 371 case 1: 372 *regmap = priv->regmap_ioc1; 373 if (pin_num < 28) 374 *reg = RK3506_SMT_GPIO1_OFFSET; 375 else 376 ret = -EINVAL; 377 break; 378 379 case 2: 380 *regmap = priv->regmap_base; 381 if (pin_num < 17) 382 *reg = RK3506_SMT_GPIO2_OFFSET; 383 else 384 ret = -EINVAL; 385 break; 386 387 case 3: 388 *regmap = priv->regmap_base; 389 if (pin_num < 15) 390 *reg = RK3506_SMT_GPIO3_OFFSET; 391 else 392 ret = -EINVAL; 393 break; 394 395 case 4: 396 *regmap = priv->regmap_base; 397 if (pin_num < 8 || pin_num > 11) { 398 ret = -EINVAL; 399 } else { 400 *reg = RK3506_SMT_GPIO4_OFFSET; 401 *bit = 8; 402 403 return 0; 404 } 405 break; 406 407 default: 408 ret = -EINVAL; 409 break; 410 } 411 412 if (ret) { 413 dev_err(priv->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num); 414 415 return ret; 416 } 417 418 *reg += ((pin_num / RK3506_SMT_PINS_PER_REG) * 4); 419 *bit = pin_num % RK3506_SMT_PINS_PER_REG; 420 *bit *= RK3506_SMT_BITS_PER_PIN; 421 422 return 0; 423 } 424 425 static int rk3506_set_schmitt(struct rockchip_pin_bank *bank, 426 int pin_num, int enable) 427 { 428 struct regmap *regmap; 429 int reg, ret; 430 u32 data; 431 u8 bit; 432 433 ret = rk3506_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 434 if (ret) 435 return ret; 436 437 /* enable the write to the equivalent lower bits */ 438 data = ((1 << RK3506_SMT_BITS_PER_PIN) - 1) << (bit + 16); 439 data |= (enable << bit); 440 441 if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) { 442 data = 0x3 << (bit + 16); 443 data |= ((enable ? 0x3 : 0) << bit); 444 } 445 ret = regmap_write(regmap, reg, data); 446 447 return ret; 448 } 449 450 static struct rockchip_mux_recalced_data rk3506_mux_recalced_data[] = { 451 { 452 .num = 0, 453 .pin = 24, 454 .reg = 0x830, 455 .bit = 0, 456 .mask = 0x3 457 }, 458 }; 459 460 static struct rockchip_pin_bank rk3506_pin_banks[] = { 461 PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0", 462 IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, 463 IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, 464 IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, 465 IOMUX_8WIDTH_2BIT | IOMUX_SOURCE_PMU, 466 0x0, 0x8, 0x10, 0x830), 467 PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", 468 IOMUX_WIDTH_4BIT, 469 IOMUX_WIDTH_4BIT, 470 IOMUX_WIDTH_4BIT, 471 IOMUX_WIDTH_4BIT, 472 0x20, 0x28, 0x30, 0x38), 473 PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2", 474 IOMUX_WIDTH_4BIT, 475 IOMUX_WIDTH_4BIT, 476 IOMUX_WIDTH_4BIT, 477 IOMUX_WIDTH_4BIT, 478 0x40, 0x48, 0x50, 0x58), 479 PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3", 480 IOMUX_WIDTH_4BIT, 481 IOMUX_WIDTH_4BIT, 482 IOMUX_WIDTH_4BIT, 483 IOMUX_WIDTH_4BIT, 484 0x60, 0x68, 0x70, 0x78), 485 PIN_BANK_IOMUX_FLAGS_OFFSET(4, 32, "gpio4", 486 IOMUX_WIDTH_4BIT, 487 IOMUX_WIDTH_4BIT, 488 IOMUX_WIDTH_4BIT, 489 IOMUX_WIDTH_4BIT, 490 0x80, 0x88, 0x90, 0x98), 491 }; 492 493 static const struct rockchip_pin_ctrl rk3506_pin_ctrl = { 494 .pin_banks = rk3506_pin_banks, 495 .nr_banks = ARRAY_SIZE(rk3506_pin_banks), 496 .nr_pins = 160, 497 .iomux_recalced = rk3506_mux_recalced_data, 498 .niomux_recalced = ARRAY_SIZE(rk3506_mux_recalced_data), 499 .set_mux = rk3506_set_mux, 500 .set_pull = rk3506_set_pull, 501 .set_drive = rk3506_set_drive, 502 .set_schmitt = rk3506_set_schmitt, 503 }; 504 505 static const struct udevice_id rk3506_pinctrl_ids[] = { 506 { 507 .compatible = "rockchip,rk3506-pinctrl", 508 .data = (ulong)&rk3506_pin_ctrl 509 }, 510 { } 511 }; 512 513 U_BOOT_DRIVER(pinctrl_rk3506) = { 514 .name = "rockchip_rk3506_pinctrl", 515 .id = UCLASS_PINCTRL, 516 .of_match = rk3506_pinctrl_ids, 517 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 518 .ops = &rockchip_pinctrl_ops, 519 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 520 .bind = dm_scan_fdt_dev, 521 #endif 522 .probe = rockchip_pinctrl_probe, 523 }; 524