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