1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2019 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 #include <fdtdec.h> 12 13 #include "pinctrl-rockchip.h" 14 15 #define MAX_ROCKCHIP_PINS_ENTRIES 30 16 #define MAX_ROCKCHIP_GPIO_PER_BANK 32 17 #define RK_FUNC_GPIO 0 18 19 static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin) 20 { 21 struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 22 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 23 24 if (bank >= ctrl->nr_banks) { 25 debug("pin conf bank %d >= nbanks %d\n", bank, ctrl->nr_banks); 26 return -EINVAL; 27 } 28 29 if (pin >= MAX_ROCKCHIP_GPIO_PER_BANK) { 30 debug("pin conf pin %d >= %d\n", pin, 31 MAX_ROCKCHIP_GPIO_PER_BANK); 32 return -EINVAL; 33 } 34 35 return 0; 36 } 37 38 void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, 39 int *reg, u8 *bit, int *mask) 40 { 41 struct rockchip_pinctrl_priv *priv = bank->priv; 42 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 43 struct rockchip_mux_recalced_data *data; 44 int i; 45 46 for (i = 0; i < ctrl->niomux_recalced; i++) { 47 data = &ctrl->iomux_recalced[i]; 48 if (data->num == bank->bank_num && 49 data->pin == pin) 50 break; 51 } 52 53 if (i >= ctrl->niomux_recalced) 54 return; 55 56 *reg = data->reg; 57 *mask = data->mask; 58 *bit = data->bit; 59 } 60 61 bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, 62 int mux, u32 *reg, u32 *value) 63 { 64 struct rockchip_pinctrl_priv *priv = bank->priv; 65 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 66 struct rockchip_mux_route_data *data; 67 int i; 68 69 for (i = 0; i < ctrl->niomux_routes; i++) { 70 data = &ctrl->iomux_routes[i]; 71 if (data->bank_num == bank->bank_num && 72 data->pin == pin && data->func == mux) 73 break; 74 } 75 76 if (i >= ctrl->niomux_routes) 77 return false; 78 79 *reg = data->route_offset; 80 *value = data->route_val; 81 82 return true; 83 } 84 85 int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask) 86 { 87 int offset = 0; 88 89 if (mux_type & IOMUX_WIDTH_4BIT) { 90 if ((pin % 8) >= 4) 91 offset = 0x4; 92 *bit = (pin % 4) * 4; 93 *mask = 0xf; 94 } else if (mux_type & IOMUX_WIDTH_3BIT) { 95 /* 96 * pin0 ~ pin4 are at first register, and 97 * pin5 ~ pin7 are at second register. 98 */ 99 if ((pin % 8) >= 5) 100 offset = 0x4; 101 *bit = (pin % 8 % 5) * 3; 102 *mask = 0x7; 103 } else { 104 *bit = (pin % 8) * 2; 105 *mask = 0x3; 106 } 107 108 return offset; 109 } 110 111 static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) 112 { 113 struct rockchip_pinctrl_priv *priv = bank->priv; 114 int iomux_num = (pin / 8); 115 struct regmap *regmap; 116 unsigned int val; 117 int reg, ret, mask, mux_type; 118 u8 bit; 119 120 if (iomux_num > 3) 121 return -EINVAL; 122 123 if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 124 debug("pin %d is unrouted\n", pin); 125 return 0; 126 } 127 128 if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 129 return RK_FUNC_GPIO; 130 131 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 132 ? priv->regmap_pmu : priv->regmap_base; 133 134 /* get basic quadrupel of mux registers and the correct reg inside */ 135 mux_type = bank->iomux[iomux_num].type; 136 reg = bank->iomux[iomux_num].offset; 137 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); 138 139 if (bank->recalced_mask & BIT(pin)) 140 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 141 142 ret = regmap_read(regmap, reg, &val); 143 if (ret) 144 return ret; 145 146 return ((val >> bit) & mask); 147 } 148 149 static int rockchip_pinctrl_get_gpio_mux(struct udevice *dev, int banknum, 150 int index) 151 { struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 152 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 153 154 return rockchip_get_mux(&ctrl->pin_banks[banknum], index); 155 } 156 157 static int rockchip_verify_mux(struct rockchip_pin_bank *bank, 158 int pin, int mux) 159 { 160 int iomux_num = (pin / 8); 161 162 if (iomux_num > 3) 163 return -EINVAL; 164 165 if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { 166 debug("pin %d is unrouted\n", pin); 167 return -ENOTSUPP; 168 } 169 170 if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { 171 if (mux != IOMUX_GPIO_ONLY) { 172 debug("pin %d only supports a gpio mux\n", pin); 173 return -ENOTSUPP; 174 } 175 } 176 177 return 0; 178 } 179 180 /* 181 * Set a new mux function for a pin. 182 * 183 * The register is divided into the upper and lower 16 bit. When changing 184 * a value, the previous register value is not read and changed. Instead 185 * it seems the changed bits are marked in the upper 16 bit, while the 186 * changed value gets set in the same offset in the lower 16 bit. 187 * All pin settings seem to be 2 bit wide in both the upper and lower 188 * parts. 189 * @bank: pin bank to change 190 * @pin: pin to change 191 * @mux: new mux function to set 192 */ 193 static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 194 { 195 struct rockchip_pinctrl_priv *priv = bank->priv; 196 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 197 int iomux_num = (pin / 8); 198 int ret; 199 200 ret = rockchip_verify_mux(bank, pin, mux); 201 if (ret < 0) 202 return ret == -ENOTSUPP ? 0 : ret; 203 204 if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) 205 return 0; 206 207 debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 208 209 if (!ctrl->set_mux) 210 return -ENOTSUPP; 211 212 ret = ctrl->set_mux(bank, pin, mux); 213 214 return ret; 215 } 216 217 static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { 218 { 2, 4, 8, 12, -1, -1, -1, -1 }, 219 { 3, 6, 9, 12, -1, -1, -1, -1 }, 220 { 5, 10, 15, 20, -1, -1, -1, -1 }, 221 { 4, 6, 8, 10, 12, 14, 16, 18 }, 222 { 4, 7, 10, 13, 16, 19, 22, 26 } 223 }; 224 225 int rockchip_translate_drive_value(int type, int strength) 226 { 227 int i, ret; 228 229 ret = -EINVAL; 230 for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[type]); i++) { 231 if (rockchip_perpin_drv_list[type][i] == strength) { 232 ret = i; 233 break; 234 } else if (rockchip_perpin_drv_list[type][i] < 0) { 235 ret = rockchip_perpin_drv_list[type][i]; 236 break; 237 } 238 } 239 240 return ret; 241 } 242 243 static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, 244 int pin_num, int strength) 245 { 246 struct rockchip_pinctrl_priv *priv = bank->priv; 247 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 248 249 debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num, 250 pin_num, strength); 251 252 if (!ctrl->set_drive) 253 return -ENOTSUPP; 254 255 return ctrl->set_drive(bank, pin_num, strength); 256 } 257 258 static int rockchip_pull_list[PULL_TYPE_MAX][4] = { 259 { 260 PIN_CONFIG_BIAS_DISABLE, 261 PIN_CONFIG_BIAS_PULL_UP, 262 PIN_CONFIG_BIAS_PULL_DOWN, 263 PIN_CONFIG_BIAS_BUS_HOLD 264 }, 265 { 266 PIN_CONFIG_BIAS_DISABLE, 267 PIN_CONFIG_BIAS_PULL_DOWN, 268 PIN_CONFIG_BIAS_DISABLE, 269 PIN_CONFIG_BIAS_PULL_UP 270 }, 271 }; 272 273 int rockchip_translate_pull_value(int type, int pull) 274 { 275 int i, ret; 276 277 ret = -EINVAL; 278 for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[type]); 279 i++) { 280 if (rockchip_pull_list[type][i] == pull) { 281 ret = i; 282 break; 283 } 284 } 285 286 return ret; 287 } 288 289 static int rockchip_set_pull(struct rockchip_pin_bank *bank, 290 int pin_num, int pull) 291 { 292 struct rockchip_pinctrl_priv *priv = bank->priv; 293 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 294 295 debug("setting pull of GPIO%d-%d to %d\n", bank->bank_num, 296 pin_num, pull); 297 298 if (!ctrl->set_pull) 299 return -ENOTSUPP; 300 301 return ctrl->set_pull(bank, pin_num, pull); 302 } 303 304 static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, 305 int pin_num, int enable) 306 { 307 struct rockchip_pinctrl_priv *priv = bank->priv; 308 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 309 struct regmap *regmap; 310 int reg, ret; 311 u8 bit; 312 u32 data; 313 314 debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num, 315 pin_num, enable); 316 317 ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); 318 if (ret) 319 return ret; 320 321 /* enable the write to the equivalent lower bits */ 322 data = BIT(bit + 16) | (enable << bit); 323 324 return regmap_write(regmap, reg, data); 325 } 326 327 /* set the pin config settings for a specified pin */ 328 static int rockchip_pinconf_set(struct rockchip_pin_bank *bank, 329 u32 pin, u32 param, u32 arg) 330 { 331 struct rockchip_pinctrl_priv *priv = bank->priv; 332 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 333 int rc; 334 335 switch (param) { 336 case PIN_CONFIG_BIAS_DISABLE: 337 case PIN_CONFIG_BIAS_PULL_UP: 338 case PIN_CONFIG_BIAS_PULL_DOWN: 339 case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: 340 case PIN_CONFIG_BIAS_BUS_HOLD: 341 rc = rockchip_set_pull(bank, pin, param); 342 if (rc) 343 return rc; 344 break; 345 346 case PIN_CONFIG_DRIVE_STRENGTH: 347 rc = rockchip_set_drive_perpin(bank, pin, arg); 348 if (rc < 0) 349 return rc; 350 break; 351 352 case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 353 if (!ctrl->schmitt_calc_reg) 354 return -ENOTSUPP; 355 356 rc = rockchip_set_schmitt(bank, pin, arg); 357 if (rc < 0) 358 return rc; 359 break; 360 361 default: 362 break; 363 } 364 365 return 0; 366 } 367 368 static const struct pinconf_param rockchip_conf_params[] = { 369 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, 370 { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, 371 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, 372 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, 373 { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 }, 374 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, 375 { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, 376 { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, 377 }; 378 379 static int rockchip_pinconf_prop_name_to_param(const char *property, 380 u32 *default_value) 381 { 382 const struct pinconf_param *p, *end; 383 384 p = rockchip_conf_params; 385 end = p + sizeof(rockchip_conf_params) / sizeof(struct pinconf_param); 386 387 /* See if this pctldev supports this parameter */ 388 for (; p < end; p++) { 389 if (!strcmp(property, p->property)) { 390 *default_value = p->default_value; 391 return p->param; 392 } 393 } 394 395 *default_value = 0; 396 return -EPERM; 397 } 398 399 static int rockchip_pinctrl_set_state(struct udevice *dev, 400 struct udevice *config) 401 { 402 struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 403 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 404 u32 cells[MAX_ROCKCHIP_PINS_ENTRIES * 4]; 405 u32 bank, pin, mux, conf, arg, default_val; 406 int ret, count, i; 407 const char *prop_name; 408 const void *value; 409 int prop_len, param; 410 const u32 *data; 411 ofnode node; 412 #ifdef CONFIG_OF_LIVE 413 const struct device_node *np; 414 struct property *pp; 415 #else 416 int property_offset, pcfg_node; 417 const void *blob = gd->fdt_blob; 418 #endif 419 data = dev_read_prop(config, "rockchip,pins", &count); 420 if (count < 0) { 421 debug("%s: bad array size %d\n", __func__, count); 422 return -EINVAL; 423 } 424 425 count /= sizeof(u32); 426 if (count > MAX_ROCKCHIP_PINS_ENTRIES * 4) { 427 debug("%s: unsupported pins array count %d\n", 428 __func__, count); 429 return -EINVAL; 430 } 431 432 for (i = 0; i < count; i++) 433 cells[i] = fdt32_to_cpu(data[i]); 434 435 for (i = 0; i < (count >> 2); i++) { 436 bank = cells[4 * i + 0]; 437 pin = cells[4 * i + 1]; 438 mux = cells[4 * i + 2]; 439 conf = cells[4 * i + 3]; 440 441 ret = rockchip_verify_config(dev, bank, pin); 442 if (ret) 443 return ret; 444 445 ret = rockchip_set_mux(&ctrl->pin_banks[bank], pin, mux); 446 if (ret) 447 return ret; 448 449 node = ofnode_get_by_phandle(conf); 450 if (!ofnode_valid(node)) 451 return -ENODEV; 452 #ifdef CONFIG_OF_LIVE 453 np = ofnode_to_np(node); 454 for (pp = np->properties; pp; pp = pp->next) { 455 prop_name = pp->name; 456 prop_len = pp->length; 457 value = pp->value; 458 #else 459 pcfg_node = ofnode_to_offset(node); 460 fdt_for_each_property_offset(property_offset, blob, pcfg_node) { 461 value = fdt_getprop_by_offset(blob, property_offset, 462 &prop_name, &prop_len); 463 if (!value) 464 return -ENOENT; 465 #endif 466 param = rockchip_pinconf_prop_name_to_param(prop_name, 467 &default_val); 468 if (param < 0) 469 break; 470 471 if (prop_len >= sizeof(fdt32_t)) 472 arg = fdt32_to_cpu(*(fdt32_t *)value); 473 else 474 arg = default_val; 475 476 ret = rockchip_pinconf_set(&ctrl->pin_banks[bank], pin, 477 param, arg); 478 if (ret) { 479 debug("%s: rockchip_pinconf_set fail: %d\n", 480 __func__, ret); 481 return ret; 482 } 483 } 484 } 485 486 return 0; 487 } 488 489 static int rockchip_pinctrl_get_pins_count(struct udevice *dev) 490 { 491 struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 492 struct rockchip_pin_ctrl *ctrl = priv->ctrl; 493 494 return ctrl->nr_pins; 495 } 496 497 const struct pinctrl_ops rockchip_pinctrl_ops = { 498 .get_pins_count = rockchip_pinctrl_get_pins_count, 499 .set_state = rockchip_pinctrl_set_state, 500 .get_gpio_mux = rockchip_pinctrl_get_gpio_mux, 501 }; 502 503 /* retrieve the soc specific data */ 504 static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *dev) 505 { 506 struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 507 struct rockchip_pin_ctrl *ctrl = 508 (struct rockchip_pin_ctrl *)dev_get_driver_data(dev); 509 struct rockchip_pin_bank *bank; 510 int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; 511 512 grf_offs = ctrl->grf_mux_offset; 513 pmu_offs = ctrl->pmu_mux_offset; 514 drv_pmu_offs = ctrl->pmu_drv_offset; 515 drv_grf_offs = ctrl->grf_drv_offset; 516 bank = ctrl->pin_banks; 517 518 for (i = 0; i < ctrl->nr_banks; ++i, ++bank) { 519 int bank_pins = 0; 520 521 bank->priv = priv; 522 bank->pin_base = ctrl->nr_pins; 523 ctrl->nr_pins += bank->nr_pins; 524 525 /* calculate iomux and drv offsets */ 526 for (j = 0; j < 4; j++) { 527 struct rockchip_iomux *iom = &bank->iomux[j]; 528 struct rockchip_drv *drv = &bank->drv[j]; 529 int inc; 530 531 if (bank_pins >= bank->nr_pins) 532 break; 533 534 /* preset iomux offset value, set new start value */ 535 if (iom->offset >= 0) { 536 if (iom->type & IOMUX_SOURCE_PMU) 537 pmu_offs = iom->offset; 538 else 539 grf_offs = iom->offset; 540 } else { /* set current iomux offset */ 541 iom->offset = (iom->type & IOMUX_SOURCE_PMU) ? 542 pmu_offs : grf_offs; 543 } 544 545 /* preset drv offset value, set new start value */ 546 if (drv->offset >= 0) { 547 if (iom->type & IOMUX_SOURCE_PMU) 548 drv_pmu_offs = drv->offset; 549 else 550 drv_grf_offs = drv->offset; 551 } else { /* set current drv offset */ 552 drv->offset = (iom->type & IOMUX_SOURCE_PMU) ? 553 drv_pmu_offs : drv_grf_offs; 554 } 555 556 debug("bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n", 557 i, j, iom->offset, drv->offset); 558 559 /* 560 * Increase offset according to iomux width. 561 * 4bit iomux'es are spread over two registers. 562 */ 563 inc = (iom->type & (IOMUX_WIDTH_4BIT | 564 IOMUX_WIDTH_3BIT)) ? 8 : 4; 565 if (iom->type & IOMUX_SOURCE_PMU) 566 pmu_offs += inc; 567 else 568 grf_offs += inc; 569 570 /* 571 * Increase offset according to drv width. 572 * 3bit drive-strenth'es are spread over two registers. 573 */ 574 if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || 575 (drv->drv_type == DRV_TYPE_IO_3V3_ONLY)) 576 inc = 8; 577 else 578 inc = 4; 579 580 if (iom->type & IOMUX_SOURCE_PMU) 581 drv_pmu_offs += inc; 582 else 583 drv_grf_offs += inc; 584 585 bank_pins += 8; 586 } 587 588 /* calculate the per-bank recalced_mask */ 589 for (j = 0; j < ctrl->niomux_recalced; j++) { 590 int pin = 0; 591 592 if (ctrl->iomux_recalced[j].num == bank->bank_num) { 593 pin = ctrl->iomux_recalced[j].pin; 594 bank->recalced_mask |= BIT(pin); 595 } 596 } 597 598 /* calculate the per-bank route_mask */ 599 for (j = 0; j < ctrl->niomux_routes; j++) { 600 int pin = 0; 601 602 if (ctrl->iomux_routes[j].bank_num == bank->bank_num) { 603 pin = ctrl->iomux_routes[j].pin; 604 bank->route_mask |= BIT(pin); 605 } 606 } 607 } 608 609 return ctrl; 610 } 611 612 int rockchip_pinctrl_probe(struct udevice *dev) 613 { 614 struct rockchip_pinctrl_priv *priv = dev_get_priv(dev); 615 struct rockchip_pin_ctrl *ctrl; 616 struct udevice *syscon; 617 struct regmap *regmap; 618 int ret = 0; 619 620 /* get rockchip grf syscon phandle */ 621 ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,grf", 622 &syscon); 623 if (ret) { 624 debug("unable to find rockchip,grf syscon device (%d)\n", ret); 625 return ret; 626 } 627 628 /* get grf-reg base address */ 629 regmap = syscon_get_regmap(syscon); 630 if (!regmap) { 631 debug("unable to find rockchip grf regmap\n"); 632 return -ENODEV; 633 } 634 priv->regmap_base = regmap; 635 636 /* option: get pmu-reg base address */ 637 ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pmu", 638 &syscon); 639 if (!ret) { 640 /* get pmugrf-reg base address */ 641 regmap = syscon_get_regmap(syscon); 642 if (!regmap) { 643 debug("unable to find rockchip pmu regmap\n"); 644 return -ENODEV; 645 } 646 priv->regmap_pmu = regmap; 647 } 648 649 ctrl = rockchip_pinctrl_get_soc_data(dev); 650 if (!ctrl) { 651 debug("driver data not available\n"); 652 return -EINVAL; 653 } 654 655 priv->ctrl = ctrl; 656 return 0; 657 } 658