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 <linux/bitops.h> 13 14#include "pinctrl-rockchip.h" 15 16static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { 17 { 18 .num = 1, 19 .pin = 14, 20 .reg = 0x28, 21 .bit = 12, 22 .mask = 0xf 23 }, { 24 .num = 1, 25 .pin = 15, 26 .reg = 0x2c, 27 .bit = 0, 28 .mask = 0x3 29 }, { 30 .num = 1, 31 .pin = 18, 32 .reg = 0x30, 33 .bit = 4, 34 .mask = 0xf 35 }, { 36 .num = 1, 37 .pin = 19, 38 .reg = 0x30, 39 .bit = 8, 40 .mask = 0xf 41 }, { 42 .num = 1, 43 .pin = 20, 44 .reg = 0x30, 45 .bit = 12, 46 .mask = 0xf 47 }, { 48 .num = 1, 49 .pin = 21, 50 .reg = 0x34, 51 .bit = 0, 52 .mask = 0xf 53 }, { 54 .num = 1, 55 .pin = 22, 56 .reg = 0x34, 57 .bit = 4, 58 .mask = 0xf 59 }, { 60 .num = 1, 61 .pin = 23, 62 .reg = 0x34, 63 .bit = 8, 64 .mask = 0xf 65 }, { 66 .num = 3, 67 .pin = 12, 68 .reg = 0x68, 69 .bit = 8, 70 .mask = 0xf 71 }, { 72 .num = 3, 73 .pin = 13, 74 .reg = 0x68, 75 .bit = 12, 76 .mask = 0xf 77 }, { 78 .num = 2, 79 .pin = 2, 80 .reg = 0x608, 81 .bit = 0, 82 .mask = 0x7 83 }, { 84 .num = 2, 85 .pin = 3, 86 .reg = 0x608, 87 .bit = 4, 88 .mask = 0x7 89 }, { 90 .num = 2, 91 .pin = 16, 92 .reg = 0x610, 93 .bit = 8, 94 .mask = 0x7 95 }, { 96 .num = 3, 97 .pin = 10, 98 .reg = 0x610, 99 .bit = 0, 100 .mask = 0x7 101 }, { 102 .num = 3, 103 .pin = 11, 104 .reg = 0x610, 105 .bit = 4, 106 .mask = 0x7 107 }, 108}; 109 110static struct rockchip_mux_route_data rk3308_mux_route_data[] = { 111 { 112 /* rtc_clk */ 113 .bank_num = 0, 114 .pin = 19, 115 .func = 1, 116 .route_offset = 0x314, 117 .route_val = BIT(16 + 0) | BIT(0), 118 }, { 119 /* uart2_rxm0 */ 120 .bank_num = 1, 121 .pin = 22, 122 .func = 2, 123 .route_offset = 0x314, 124 .route_val = BIT(16 + 2) | BIT(16 + 3), 125 }, { 126 /* uart2_rxm1 */ 127 .bank_num = 4, 128 .pin = 26, 129 .func = 2, 130 .route_offset = 0x314, 131 .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2), 132 }, { 133 /* i2c3_sdam0 */ 134 .bank_num = 0, 135 .pin = 15, 136 .func = 2, 137 .route_offset = 0x608, 138 .route_val = BIT(16 + 8) | BIT(16 + 9), 139 }, { 140 /* i2c3_sdam1 */ 141 .bank_num = 3, 142 .pin = 12, 143 .func = 2, 144 .route_offset = 0x608, 145 .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8), 146 }, { 147 /* i2c3_sdam2 */ 148 .bank_num = 2, 149 .pin = 0, 150 .func = 3, 151 .route_offset = 0x608, 152 .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9), 153 }, { 154 /* i2s-8ch-1-sclktxm0 */ 155 .bank_num = 1, 156 .pin = 3, 157 .func = 2, 158 .route_offset = 0x308, 159 .route_val = BIT(16 + 3), 160 }, { 161 /* i2s-8ch-1-sclkrxm0 */ 162 .bank_num = 1, 163 .pin = 4, 164 .func = 2, 165 .route_offset = 0x308, 166 .route_val = BIT(16 + 3), 167 }, { 168 /* i2s-8ch-1-sclktxm1 */ 169 .bank_num = 1, 170 .pin = 13, 171 .func = 2, 172 .route_offset = 0x308, 173 .route_val = BIT(16 + 3) | BIT(3), 174 }, { 175 /* i2s-8ch-1-sclkrxm1 */ 176 .bank_num = 1, 177 .pin = 14, 178 .func = 2, 179 .route_offset = 0x308, 180 .route_val = BIT(16 + 3) | BIT(3), 181 }, { 182 /* pdm-clkm0 */ 183 .bank_num = 1, 184 .pin = 4, 185 .func = 3, 186 .route_offset = 0x308, 187 .route_val = BIT(16 + 12) | BIT(16 + 13), 188 }, { 189 /* pdm-clkm1 */ 190 .bank_num = 1, 191 .pin = 14, 192 .func = 4, 193 .route_offset = 0x308, 194 .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12), 195 }, { 196 /* pdm-clkm2 */ 197 .bank_num = 2, 198 .pin = 6, 199 .func = 2, 200 .route_offset = 0x308, 201 .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13), 202 }, { 203 /* pdm-clkm-m2 */ 204 .bank_num = 2, 205 .pin = 4, 206 .func = 3, 207 .route_offset = 0x600, 208 .route_val = BIT(16 + 2) | BIT(2), 209 }, { 210 /* spi1_miso */ 211 .bank_num = 3, 212 .pin = 10, 213 .func = 3, 214 .route_offset = 0x314, 215 .route_val = BIT(16 + 9), 216 }, { 217 /* spi1_miso_m1 */ 218 .bank_num = 2, 219 .pin = 4, 220 .func = 2, 221 .route_offset = 0x314, 222 .route_val = BIT(16 + 9) | BIT(9), 223 }, { 224 /* mac_rxd0_m0 */ 225 .bank_num = 1, 226 .pin = 20, 227 .func = 3, 228 .route_offset = 0x314, 229 .route_val = BIT(16 + 14), 230 }, { 231 /* mac_rxd0_m1 */ 232 .bank_num = 4, 233 .pin = 2, 234 .func = 2, 235 .route_offset = 0x314, 236 .route_val = BIT(16 + 14) | BIT(14), 237 }, { 238 /* uart3_rx */ 239 .bank_num = 3, 240 .pin = 12, 241 .func = 4, 242 .route_offset = 0x314, 243 .route_val = BIT(16 + 15), 244 }, { 245 /* uart3_rx_m1 */ 246 .bank_num = 0, 247 .pin = 17, 248 .func = 3, 249 .route_offset = 0x314, 250 .route_val = BIT(16 + 15) | BIT(15), 251 }, 252}; 253 254static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 255{ 256 struct rockchip_pinctrl_priv *priv = bank->priv; 257 int iomux_num = (pin / 8); 258 struct regmap *regmap; 259 int reg, ret, mask, mux_type; 260 u8 bit; 261 u32 data; 262 263 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 264 ? priv->regmap_pmu : priv->regmap_base; 265 266 /* get basic quadrupel of mux registers and the correct reg inside */ 267 mux_type = bank->iomux[iomux_num].type; 268 reg = bank->iomux[iomux_num].offset; 269 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); 270 271 if (bank->recalced_mask & BIT(pin)) 272 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 273 274 data = (mask << (bit + 16)); 275 data |= (mux & mask) << bit; 276 ret = regmap_write(regmap, reg, data); 277 278 return ret; 279} 280 281#define RK3308_PULL_OFFSET 0xa0 282 283static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 284 int pin_num, struct regmap **regmap, 285 int *reg, u8 *bit) 286{ 287 struct rockchip_pinctrl_priv *priv = bank->priv; 288 289 *regmap = priv->regmap_base; 290 *reg = RK3308_PULL_OFFSET; 291 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE; 292 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 293 294 *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG); 295 *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 296} 297 298static int rk3308_set_pull(struct rockchip_pin_bank *bank, 299 int pin_num, int pull) 300{ 301 struct regmap *regmap; 302 int reg, ret; 303 u8 bit, type; 304 u32 data; 305 306 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 307 return -ENOTSUPP; 308 309 rk3308_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 310 type = bank->pull_type[pin_num / 8]; 311 ret = rockchip_translate_pull_value(type, pull); 312 if (ret < 0) { 313 debug("unsupported pull setting %d\n", pull); 314 return ret; 315 } 316 317 /* enable the write to the equivalent lower bits */ 318 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); 319 data |= (ret << bit); 320 321 ret = regmap_write(regmap, reg, data); 322 323 return ret; 324} 325 326#define RK3308_DRV_GRF_OFFSET 0x100 327 328static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 329 int pin_num, struct regmap **regmap, 330 int *reg, u8 *bit) 331{ 332 struct rockchip_pinctrl_priv *priv = bank->priv; 333 334 *regmap = priv->regmap_base; 335 *reg = RK3308_DRV_GRF_OFFSET; 336 *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE; 337 *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); 338 339 *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG); 340 *bit *= ROCKCHIP_DRV_BITS_PER_PIN; 341} 342 343static int rk3308_set_drive(struct rockchip_pin_bank *bank, 344 int pin_num, int strength) 345{ 346 struct regmap *regmap; 347 int reg, ret; 348 u32 data; 349 u8 bit; 350 int type = bank->drv[pin_num / 8].drv_type; 351 352 rk3308_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 353 ret = rockchip_translate_drive_value(type, strength); 354 if (ret < 0) { 355 debug("unsupported driver strength %d\n", strength); 356 return ret; 357 } 358 359 /* enable the write to the equivalent lower bits */ 360 data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); 361 data |= (ret << bit); 362 ret = regmap_write(regmap, reg, data); 363 return ret; 364} 365 366#define RK3308_SCHMITT_PINS_PER_REG 8 367#define RK3308_SCHMITT_BANK_STRIDE 16 368#define RK3308_SCHMITT_GRF_OFFSET 0x1a0 369 370static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 371 int pin_num, 372 struct regmap **regmap, 373 int *reg, u8 *bit) 374{ 375 struct rockchip_pinctrl_priv *priv = bank->priv; 376 377 *regmap = priv->regmap_base; 378 *reg = RK3308_SCHMITT_GRF_OFFSET; 379 380 *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; 381 *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); 382 *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; 383 384 return 0; 385} 386 387static int rk3308_set_schmitt(struct rockchip_pin_bank *bank, 388 int pin_num, int enable) 389{ 390 struct regmap *regmap; 391 int reg; 392 u8 bit; 393 u32 data; 394 395 rk3308_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 396 /* enable the write to the equivalent lower bits */ 397 data = BIT(bit + 16) | (enable << bit); 398 399 return regmap_write(regmap, reg, data); 400} 401 402static struct rockchip_pin_bank rk3308_pin_banks[] = { 403 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT, 404 IOMUX_8WIDTH_2BIT, 405 IOMUX_8WIDTH_2BIT, 406 IOMUX_8WIDTH_2BIT), 407 PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT, 408 IOMUX_8WIDTH_2BIT, 409 IOMUX_8WIDTH_2BIT, 410 IOMUX_8WIDTH_2BIT), 411 PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT, 412 IOMUX_8WIDTH_2BIT, 413 IOMUX_8WIDTH_2BIT, 414 IOMUX_8WIDTH_2BIT), 415 PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT, 416 IOMUX_8WIDTH_2BIT, 417 IOMUX_8WIDTH_2BIT, 418 IOMUX_8WIDTH_2BIT), 419 PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT, 420 IOMUX_8WIDTH_2BIT, 421 IOMUX_8WIDTH_2BIT, 422 IOMUX_8WIDTH_2BIT), 423}; 424 425static struct rockchip_pin_ctrl rk3308_pin_ctrl = { 426 .pin_banks = rk3308_pin_banks, 427 .nr_banks = ARRAY_SIZE(rk3308_pin_banks), 428 .grf_mux_offset = 0x0, 429 .iomux_recalced = rk3308_mux_recalced_data, 430 .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data), 431 .iomux_routes = rk3308_mux_route_data, 432 .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data), 433 .set_mux = rk3308_set_mux, 434 .set_drive = rk3308_set_drive, 435 .set_pull = rk3308_set_pull, 436 .set_schmitt = rk3308_set_schmitt, 437}; 438 439static const struct udevice_id rk3308_pinctrl_ids[] = { 440 { 441 .compatible = "rockchip,rk3308-pinctrl", 442 .data = (ulong)&rk3308_pin_ctrl 443 }, 444 { } 445}; 446 447U_BOOT_DRIVER(pinctrl_rk3308) = { 448 .name = "rockchip_rk3308_pinctrl", 449 .id = UCLASS_PINCTRL, 450 .of_match = rk3308_pinctrl_ids, 451 .priv_auto = sizeof(struct rockchip_pinctrl_priv), 452 .ops = &rockchip_pinctrl_ops, 453#if CONFIG_IS_ENABLED(OF_REAL) 454 .bind = dm_scan_fdt_dev, 455#endif 456 .probe = rockchip_pinctrl_probe, 457}; 458