1122394Sharti// SPDX-License-Identifier: GPL-2.0+ 2122394Sharti/* 3122394Sharti * (C) Copyright 2021 Rockchip Electronics Co., Ltd 4122394Sharti */ 5122394Sharti 6122394Sharti#include <common.h> 7310903Sngie#include <dm.h> 8133211Sharti#include <dm/pinctrl.h> 9133211Sharti#include <regmap.h> 10133211Sharti#include <syscon.h> 11133211Sharti 12133211Sharti#include "pinctrl-rockchip.h" 13122394Sharti#include <dt-bindings/pinctrl/rockchip.h> 14122394Sharti 15122394Shartistatic int rk3588_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 16310903Sngie{ 17133211Sharti struct rockchip_pinctrl_priv *priv = bank->priv; 18133211Sharti struct regmap *regmap; 19133211Sharti int iomux_num = (pin / 8); 20133211Sharti int reg, ret, mask; 21133211Sharti u8 bit; 22133211Sharti u32 data; 23133211Sharti 24133211Sharti debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 25133211Sharti 26133211Sharti regmap = priv->regmap_base; 27133211Sharti reg = bank->iomux[iomux_num].offset; 28122394Sharti if ((pin % 8) >= 4) 29156066Sharti reg += 0x4; 30122394Sharti bit = (pin % 4) * 4; 31122394Sharti mask = 0xf; 32122394Sharti 33122394Sharti if (bank->bank_num == 0) { 34122394Sharti if (pin >= RK_PB4 && pin <= RK_PD7) { 35122394Sharti if (mux < 8) { 36122394Sharti reg += 0x4000 - 0xC; /* PMU2_IOC_BASE */ 37122394Sharti data = (mask << (bit + 16)); 38122394Sharti data |= (mux & mask) << bit; 39122394Sharti ret = regmap_write(regmap, reg, data); 40122394Sharti } else { 41122394Sharti u32 reg0 = 0; 42122394Sharti 43122394Sharti reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */ 44133211Sharti data = (mask << (bit + 16)); 45122394Sharti data |= 8 << bit; 46122394Sharti ret = regmap_write(regmap, reg0, data); 47122394Sharti 48122394Sharti reg0 = reg + 0x8000; /* BUS_IOC_BASE */ 49133211Sharti data = (mask << (bit + 16)); 50122394Sharti data |= mux << bit; 51122394Sharti regmap = priv->regmap_base; 52122394Sharti regmap_write(regmap, reg0, data); 53122394Sharti } 54122394Sharti } else { 55122394Sharti data = (mask << (bit + 16)); 56122394Sharti data |= (mux & mask) << bit; 57122394Sharti ret = regmap_write(regmap, reg, data); 58122394Sharti } 59122394Sharti return ret; 60122394Sharti } else if (bank->bank_num > 0) { 61122394Sharti reg += 0x8000; /* BUS_IOC_BASE */ 62122394Sharti } 63122394Sharti 64122394Sharti data = (mask << (bit + 16)); 65122394Sharti data |= (mux & mask) << bit; 66122394Sharti 67122394Sharti return regmap_write(regmap, reg, data); 68122394Sharti} 69122394Sharti 70122394Sharti#define RK3588_PMU1_IOC_REG (0x0000) 71122394Sharti#define RK3588_PMU2_IOC_REG (0x4000) 72122394Sharti#define RK3588_BUS_IOC_REG (0x8000) 73122394Sharti#define RK3588_VCCIO1_4_IOC_REG (0x9000) 74122394Sharti#define RK3588_VCCIO3_5_IOC_REG (0xA000) 75122394Sharti#define RK3588_VCCIO2_IOC_REG (0xB000) 76122394Sharti#define RK3588_VCCIO6_IOC_REG (0xC000) 77122394Sharti#define RK3588_EMMC_IOC_REG (0xD000) 78122394Sharti 79122394Shartistatic const u32 rk3588_ds_regs[][2] = { 80312089Sngie {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0010}, 81122394Sharti {RK_GPIO0_A4, RK3588_PMU1_IOC_REG + 0x0014}, 82122394Sharti {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0018}, 83122394Sharti {RK_GPIO0_B4, RK3588_PMU2_IOC_REG + 0x0014}, 84122394Sharti {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0018}, 85122394Sharti {RK_GPIO0_C4, RK3588_PMU2_IOC_REG + 0x001C}, 86122394Sharti {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0020}, 87122394Sharti {RK_GPIO0_D4, RK3588_PMU2_IOC_REG + 0x0024}, 88122394Sharti {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0020}, 89122394Sharti {RK_GPIO1_A4, RK3588_VCCIO1_4_IOC_REG + 0x0024}, 90122394Sharti {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0028}, 91122394Sharti {RK_GPIO1_B4, RK3588_VCCIO1_4_IOC_REG + 0x002C}, 92122394Sharti {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0030}, 93122394Sharti {RK_GPIO1_C4, RK3588_VCCIO1_4_IOC_REG + 0x0034}, 94122394Sharti {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x0038}, 95122394Sharti {RK_GPIO1_D4, RK3588_VCCIO1_4_IOC_REG + 0x003C}, 96122394Sharti {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0040}, 97122394Sharti {RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0044}, 98312089Sngie {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0048}, 99122394Sharti {RK_GPIO2_B4, RK3588_VCCIO3_5_IOC_REG + 0x004C}, 100122394Sharti {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0050}, 101122394Sharti {RK_GPIO2_C4, RK3588_VCCIO3_5_IOC_REG + 0x0054}, 102122394Sharti {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x0058}, 103122394Sharti {RK_GPIO2_D4, RK3588_EMMC_IOC_REG + 0x005C}, 104122394Sharti {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0060}, 105122394Sharti {RK_GPIO3_A4, RK3588_VCCIO3_5_IOC_REG + 0x0064}, 106122394Sharti {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0068}, 107122394Sharti {RK_GPIO3_B4, RK3588_VCCIO3_5_IOC_REG + 0x006C}, 108122394Sharti {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0070}, 109122394Sharti {RK_GPIO3_C4, RK3588_VCCIO3_5_IOC_REG + 0x0074}, 110122394Sharti {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x0078}, 111122394Sharti {RK_GPIO3_D4, RK3588_VCCIO3_5_IOC_REG + 0x007C}, 112122394Sharti {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0080}, 113122394Sharti {RK_GPIO4_A4, RK3588_VCCIO6_IOC_REG + 0x0084}, 114122394Sharti {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0088}, 115122394Sharti {RK_GPIO4_B4, RK3588_VCCIO6_IOC_REG + 0x008C}, 116122394Sharti {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0090}, 117122394Sharti {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0090}, 118122394Sharti {RK_GPIO4_C4, RK3588_VCCIO3_5_IOC_REG + 0x0094}, 119312089Sngie {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x0098}, 120122394Sharti {RK_GPIO4_D4, RK3588_VCCIO2_IOC_REG + 0x009C}, 121122394Sharti}; 122122394Sharti 123122394Shartistatic const u32 rk3588_p_regs[][2] = { 124122394Sharti {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0020}, 125122394Sharti {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0024}, 126122394Sharti {RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0028}, 127122394Sharti {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x002C}, 128122394Sharti {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0030}, 129122394Sharti {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0110}, 130122394Sharti {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0114}, 131128237Sharti {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0118}, 132128237Sharti {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x011C}, 133128237Sharti {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0120}, 134122394Sharti {RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0120}, 135122394Sharti {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0124}, 136122394Sharti {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0128}, 137122394Sharti {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x012C}, 138146525Sharti {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0130}, 139146525Sharti {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0134}, 140146525Sharti {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0138}, 141146525Sharti {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x013C}, 142133211Sharti {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0140}, 143122394Sharti {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0144}, 144122394Sharti {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0148}, 145146525Sharti {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0148}, 146122394Sharti {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x014C}, 147122394Sharti}; 148146525Sharti 149122394Shartistatic const u32 rk3588_smt_regs[][2] = { 150122394Sharti {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0030}, 151122394Sharti {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0034}, 152122394Sharti {RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0040}, 153122394Sharti {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0044}, 154122394Sharti {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0048}, 155122394Sharti {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0210}, 156122394Sharti {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0214}, 157122394Sharti {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0218}, 158122394Sharti {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x021C}, 159122394Sharti {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0220}, 160122394Sharti {RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0220}, 161122394Sharti {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0224}, 162122394Sharti {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0228}, 163122394Sharti {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x022C}, 164122394Sharti {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0230}, 165122394Sharti {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0234}, 166122394Sharti {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0238}, 167122394Sharti {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x023C}, 168122394Sharti {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0240}, 169122394Sharti {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0244}, 170122394Sharti {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0248}, 171122394Sharti {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0248}, 172122394Sharti {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x024C}, 173122394Sharti}; 174122394Sharti 175122394Sharti#define RK3588_PULL_BITS_PER_PIN 2 176122394Sharti#define RK3588_PULL_PINS_PER_REG 8 177122394Sharti 178122394Shartistatic void rk3588_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 179122394Sharti int pin_num, struct regmap **regmap, 180122394Sharti int *reg, u8 *bit) 181122394Sharti{ 182122394Sharti struct rockchip_pinctrl_priv *info = bank->priv; 183122394Sharti u8 bank_num = bank->bank_num; 184122394Sharti u32 pin = bank_num * 32 + pin_num; 185122394Sharti int i; 186122394Sharti 187122394Sharti for (i = ARRAY_SIZE(rk3588_p_regs) - 1; i >= 0; i--) { 188122394Sharti if (pin >= rk3588_p_regs[i][0]) { 189122394Sharti *reg = rk3588_p_regs[i][1]; 190122394Sharti break; 191122394Sharti } 192122394Sharti } 193122394Sharti 194122394Sharti assert(i >= 0); 195122394Sharti 196122394Sharti *regmap = info->regmap_base; 197122394Sharti *bit = pin_num % RK3588_PULL_PINS_PER_REG; 198122394Sharti *bit *= RK3588_PULL_BITS_PER_PIN; 199122394Sharti} 200122394Sharti 201122394Sharti#define RK3588_DRV_BITS_PER_PIN 4 202122394Sharti#define RK3588_DRV_PINS_PER_REG 4 203122394Sharti 204122394Shartistatic void rk3588_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 205122394Sharti int pin_num, struct regmap **regmap, 206122394Sharti int *reg, u8 *bit) 207122394Sharti{ 208122394Sharti struct rockchip_pinctrl_priv *info = bank->priv; 209122394Sharti u8 bank_num = bank->bank_num; 210122394Sharti u32 pin = bank_num * 32 + pin_num; 211122394Sharti int i; 212122394Sharti 213122394Sharti for (i = ARRAY_SIZE(rk3588_ds_regs) - 1; i >= 0; i--) { 214122394Sharti if (pin >= rk3588_ds_regs[i][0]) { 215122394Sharti *reg = rk3588_ds_regs[i][1]; 216122394Sharti break; 217122394Sharti } 218122394Sharti } 219122394Sharti 220122394Sharti assert(i >= 0); 221122394Sharti 222122394Sharti *regmap = info->regmap_base; 223122394Sharti *bit = pin_num % RK3588_DRV_PINS_PER_REG; 224122394Sharti *bit *= RK3588_DRV_BITS_PER_PIN; 225122394Sharti} 226122394Sharti 227122394Sharti#define RK3588_SMT_BITS_PER_PIN 1 228122394Sharti#define RK3588_SMT_PINS_PER_REG 8 229122394Sharti 230122394Shartistatic int rk3588_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 231122394Sharti int pin_num, struct regmap **regmap, 232122394Sharti int *reg, u8 *bit) 233122394Sharti{ 234122394Sharti struct rockchip_pinctrl_priv *info = bank->priv; 235122394Sharti u8 bank_num = bank->bank_num; 236122394Sharti u32 pin = bank_num * 32 + pin_num; 237122394Sharti int i; 238122394Sharti 239122394Sharti for (i = ARRAY_SIZE(rk3588_smt_regs) - 1; i >= 0; i--) { 240122394Sharti if (pin >= rk3588_smt_regs[i][0]) { 241122394Sharti *reg = rk3588_smt_regs[i][1]; 242122394Sharti break; 243122394Sharti } 244122394Sharti } 245122394Sharti 246122394Sharti assert(i >= 0); 247122394Sharti 248122394Sharti *regmap = info->regmap_base; 249122394Sharti *bit = pin_num % RK3588_SMT_PINS_PER_REG; 250122394Sharti *bit *= RK3588_SMT_BITS_PER_PIN; 251122394Sharti 252122394Sharti return 0; 253122394Sharti} 254122394Sharti 255122394Shartistatic int rk3588_set_pull(struct rockchip_pin_bank *bank, 256122394Sharti int pin_num, int pull) 257122394Sharti{ 258122394Sharti struct regmap *regmap; 259122394Sharti int reg, translated_pull; 260122394Sharti u8 bit, type; 261122394Sharti u32 data; 262122394Sharti 263122394Sharti rk3588_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 264122394Sharti type = bank->pull_type[pin_num / 8]; 265122394Sharti translated_pull = rockchip_translate_pull_value(type, pull); 266122394Sharti if (translated_pull < 0) { 267122394Sharti debug("unsupported pull setting %d\n", pull); 268122394Sharti return -EINVAL; 269122394Sharti } 270122394Sharti 271122394Sharti /* enable the write to the equivalent lower bits */ 272122394Sharti data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); 273122394Sharti data |= (translated_pull << bit); 274122394Sharti 275122394Sharti return regmap_write(regmap, reg, data); 276122394Sharti} 277122394Sharti 278122394Shartistatic int rk3588_set_drive(struct rockchip_pin_bank *bank, 279122394Sharti int pin_num, int strength) 280122394Sharti{ 281122394Sharti struct regmap *regmap; 282122394Sharti int reg; 283151970Sharti u32 data; 284151970Sharti u8 bit; 285151970Sharti 286151970Sharti rk3588_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 287151970Sharti 288151970Sharti /* enable the write to the equivalent lower bits */ 289151970Sharti data = ((1 << RK3588_DRV_BITS_PER_PIN) - 1) << (bit + 16); 290151970Sharti data |= (strength << bit); 291151970Sharti 292221373Sru return regmap_write(regmap, reg, data); 293151970Sharti} 294151970Sharti 295151970Shartistatic int rk3588_set_schmitt(struct rockchip_pin_bank *bank, 296151970Sharti int pin_num, int enable) 297151970Sharti{ 298122394Sharti struct regmap *regmap; 299122394Sharti int reg; 300122394Sharti u32 data; 301122394Sharti u8 bit; 302122394Sharti 303122394Sharti rk3588_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 304122394Sharti 305122394Sharti /* enable the write to the equivalent lower bits */ 306122394Sharti data = ((1 << RK3588_SMT_BITS_PER_PIN) - 1) << (bit + 16); 307122394Sharti data |= (enable << bit); 308122394Sharti 309122394Sharti return regmap_write(regmap, reg, data); 310122394Sharti} 311122394Sharti 312122394Shartistatic struct rockchip_pin_bank rk3588_pin_banks[] = { 313122394Sharti RK3588_PIN_BANK_FLAGS(0, 32, "gpio0", 314122394Sharti IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 315122394Sharti RK3588_PIN_BANK_FLAGS(1, 32, "gpio1", 316122394Sharti IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 317122394Sharti RK3588_PIN_BANK_FLAGS(2, 32, "gpio2", 318122394Sharti IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 319122394Sharti RK3588_PIN_BANK_FLAGS(3, 32, "gpio3", 320122394Sharti IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 321122394Sharti RK3588_PIN_BANK_FLAGS(4, 32, "gpio4", 322122394Sharti IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), 323122394Sharti}; 324122394Sharti 325122394Shartistatic const struct rockchip_pin_ctrl rk3588_pin_ctrl = { 326122394Sharti .pin_banks = rk3588_pin_banks, 327122394Sharti .nr_banks = ARRAY_SIZE(rk3588_pin_banks), 328122394Sharti .nr_pins = 160, 329122394Sharti .set_mux = rk3588_set_mux, 330122394Sharti .set_pull = rk3588_set_pull, 331122394Sharti .set_drive = rk3588_set_drive, 332122394Sharti .set_schmitt = rk3588_set_schmitt, 333122394Sharti}; 334122394Sharti 335122394Shartistatic const struct udevice_id rk3588_pinctrl_ids[] = { 336122394Sharti { 337122394Sharti .compatible = "rockchip,rk3588-pinctrl", 338122394Sharti .data = (ulong)&rk3588_pin_ctrl 339122394Sharti }, 340122394Sharti { } 341122394Sharti}; 342122394Sharti 343122394ShartiU_BOOT_DRIVER(pinctrl_rk3588) = { 344122394Sharti .name = "rockchip_rk3588_pinctrl", 345122394Sharti .id = UCLASS_PINCTRL, 346122394Sharti .of_match = rk3588_pinctrl_ids, 347122394Sharti .priv_auto = sizeof(struct rockchip_pinctrl_priv), 348122394Sharti .ops = &rockchip_pinctrl_ops, 349122394Sharti#if CONFIG_IS_ENABLED(OF_REAL) 350122394Sharti .bind = dm_scan_fdt_dev, 351122394Sharti#endif 352122394Sharti .probe = rockchip_pinctrl_probe, 353122394Sharti}; 354122394Sharti