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 12 #include "pinctrl-rockchip.h" 13 14 static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { 15 { 16 /* gpio2_b7_sel */ 17 .num = 2, 18 .pin = 15, 19 .reg = 0x28, 20 .bit = 0, 21 .mask = 0x7 22 }, { 23 /* gpio2_c7_sel */ 24 .num = 2, 25 .pin = 23, 26 .reg = 0x30, 27 .bit = 14, 28 .mask = 0x3 29 }, { 30 /* gpio3_b1_sel */ 31 .num = 3, 32 .pin = 9, 33 .reg = 0x44, 34 .bit = 2, 35 .mask = 0x3 36 }, { 37 /* gpio3_b2_sel */ 38 .num = 3, 39 .pin = 10, 40 .reg = 0x44, 41 .bit = 4, 42 .mask = 0x3 43 }, { 44 /* gpio3_b3_sel */ 45 .num = 3, 46 .pin = 11, 47 .reg = 0x44, 48 .bit = 6, 49 .mask = 0x3 50 }, { 51 /* gpio3_b4_sel */ 52 .num = 3, 53 .pin = 12, 54 .reg = 0x44, 55 .bit = 8, 56 .mask = 0x3 57 }, { 58 /* gpio3_b5_sel */ 59 .num = 3, 60 .pin = 13, 61 .reg = 0x44, 62 .bit = 10, 63 .mask = 0x3 64 }, { 65 /* gpio3_b6_sel */ 66 .num = 3, 67 .pin = 14, 68 .reg = 0x44, 69 .bit = 12, 70 .mask = 0x3 71 }, { 72 /* gpio3_b7_sel */ 73 .num = 3, 74 .pin = 15, 75 .reg = 0x44, 76 .bit = 14, 77 .mask = 0x3 78 }, 79 }; 80 81 static struct rockchip_mux_route_data rk3328_mux_route_data[] = { 82 { 83 /* uart2dbg_rxm0 */ 84 .bank_num = 1, 85 .pin = 1, 86 .func = 2, 87 .route_offset = 0x50, 88 .route_val = BIT(16) | BIT(16 + 1), 89 }, { 90 /* uart2dbg_rxm1 */ 91 .bank_num = 2, 92 .pin = 1, 93 .func = 1, 94 .route_offset = 0x50, 95 .route_val = BIT(16) | BIT(16 + 1) | BIT(0), 96 }, { 97 /* gmac-m1_rxd0 */ 98 .bank_num = 1, 99 .pin = 11, 100 .func = 2, 101 .route_offset = 0x50, 102 .route_val = BIT(16 + 2) | BIT(2), 103 }, { 104 /* gmac-m1-optimized_rxd3 */ 105 .bank_num = 1, 106 .pin = 14, 107 .func = 2, 108 .route_offset = 0x50, 109 .route_val = BIT(16 + 10) | BIT(10), 110 }, { 111 /* pdm_sdi0m0 */ 112 .bank_num = 2, 113 .pin = 19, 114 .func = 2, 115 .route_offset = 0x50, 116 .route_val = BIT(16 + 3), 117 }, { 118 /* pdm_sdi0m1 */ 119 .bank_num = 1, 120 .pin = 23, 121 .func = 3, 122 .route_offset = 0x50, 123 .route_val = BIT(16 + 3) | BIT(3), 124 }, { 125 /* spi_rxdm2 */ 126 .bank_num = 3, 127 .pin = 2, 128 .func = 4, 129 .route_offset = 0x50, 130 .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5), 131 }, { 132 /* i2s2_sdim0 */ 133 .bank_num = 1, 134 .pin = 24, 135 .func = 1, 136 .route_offset = 0x50, 137 .route_val = BIT(16 + 6), 138 }, { 139 /* i2s2_sdim1 */ 140 .bank_num = 3, 141 .pin = 2, 142 .func = 6, 143 .route_offset = 0x50, 144 .route_val = BIT(16 + 6) | BIT(6), 145 }, { 146 /* card_iom1 */ 147 .bank_num = 2, 148 .pin = 22, 149 .func = 3, 150 .route_offset = 0x50, 151 .route_val = BIT(16 + 7) | BIT(7), 152 }, { 153 /* tsp_d5m1 */ 154 .bank_num = 2, 155 .pin = 16, 156 .func = 3, 157 .route_offset = 0x50, 158 .route_val = BIT(16 + 8) | BIT(8), 159 }, { 160 /* cif_data5m1 */ 161 .bank_num = 2, 162 .pin = 16, 163 .func = 4, 164 .route_offset = 0x50, 165 .route_val = BIT(16 + 9) | BIT(9), 166 }, 167 }; 168 169 static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 170 { 171 struct rockchip_pinctrl_priv *priv = bank->priv; 172 int iomux_num = (pin / 8); 173 struct regmap *regmap; 174 int reg, ret, mask, mux_type; 175 u8 bit; 176 u32 data; 177 178 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 179 ? priv->regmap_pmu : priv->regmap_base; 180 181 /* get basic quadrupel of mux registers and the correct reg inside */ 182 mux_type = bank->iomux[iomux_num].type; 183 reg = bank->iomux[iomux_num].offset; 184 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); 185 186 if (bank->recalced_mask & BIT(pin)) 187 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 188 189 data = (mask << (bit + 16)); 190 data |= (mux & mask) << bit; 191 ret = regmap_write(regmap, reg, data); 192 193 return ret; 194 } 195 196 #define RK3328_PULL_OFFSET 0x100 197 198 static void rk3328_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 199 int pin_num, struct regmap **regmap, 200 int *reg, u8 *bit) 201 { 202 struct rockchip_pinctrl_priv *priv = bank->priv; 203 204 *regmap = priv->regmap_base; 205 *reg = RK3328_PULL_OFFSET; 206 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE; 207 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 208 209 *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG); 210 *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 211 } 212 213 static int rk3328_set_pull(struct rockchip_pin_bank *bank, 214 int pin_num, int pull) 215 { 216 struct regmap *regmap; 217 int reg, ret; 218 u8 bit, type; 219 u32 data; 220 221 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 222 return -ENOTSUPP; 223 224 rk3328_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 225 type = bank->pull_type[pin_num / 8]; 226 ret = rockchip_translate_pull_value(type, pull); 227 if (ret < 0) { 228 debug("unsupported pull setting %d\n", pull); 229 return ret; 230 } 231 232 /* enable the write to the equivalent lower bits */ 233 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); 234 data |= (ret << bit); 235 ret = regmap_write(regmap, reg, data); 236 237 return ret; 238 } 239 240 #define RK3328_DRV_GRF_OFFSET 0x200 241 242 static void rk3328_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 243 int pin_num, struct regmap **regmap, 244 int *reg, u8 *bit) 245 { 246 struct rockchip_pinctrl_priv *priv = bank->priv; 247 248 *regmap = priv->regmap_base; 249 *reg = RK3328_DRV_GRF_OFFSET; 250 *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE; 251 *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); 252 253 *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG); 254 *bit *= ROCKCHIP_DRV_BITS_PER_PIN; 255 } 256 257 static int rk3328_set_drive(struct rockchip_pin_bank *bank, 258 int pin_num, int strength) 259 { 260 struct regmap *regmap; 261 int reg, ret; 262 u32 data; 263 u8 bit; 264 int type = bank->drv[pin_num / 8].drv_type; 265 266 rk3328_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 267 ret = rockchip_translate_drive_value(type, strength); 268 if (ret < 0) { 269 debug("unsupported driver strength %d\n", strength); 270 return ret; 271 } 272 273 /* enable the write to the equivalent lower bits */ 274 data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); 275 data |= (ret << bit); 276 ret = regmap_write(regmap, reg, data); 277 278 return ret; 279 } 280 281 #define RK3328_SCHMITT_BITS_PER_PIN 1 282 #define RK3328_SCHMITT_PINS_PER_REG 16 283 #define RK3328_SCHMITT_BANK_STRIDE 8 284 #define RK3328_SCHMITT_GRF_OFFSET 0x380 285 286 static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 287 int pin_num, 288 struct regmap **regmap, 289 int *reg, u8 *bit) 290 { 291 struct rockchip_pinctrl_priv *priv = bank->priv; 292 293 *regmap = priv->regmap_base; 294 *reg = RK3328_SCHMITT_GRF_OFFSET; 295 296 *reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE; 297 *reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4); 298 *bit = pin_num % RK3328_SCHMITT_PINS_PER_REG; 299 300 return 0; 301 } 302 303 static int rk3328_set_schmitt(struct rockchip_pin_bank *bank, 304 int pin_num, int enable) 305 { 306 struct regmap *regmap; 307 int reg; 308 u8 bit; 309 u32 data; 310 311 rk3328_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 312 /* enable the write to the equivalent lower bits */ 313 data = BIT(bit + 16) | (enable << bit); 314 315 return regmap_write(regmap, reg, data); 316 } 317 318 static struct rockchip_pin_bank rk3328_pin_banks[] = { 319 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), 320 PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 321 PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 322 IOMUX_8WIDTH_2BIT, 323 IOMUX_WIDTH_3BIT, 324 0), 325 PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 326 IOMUX_WIDTH_3BIT, 327 IOMUX_WIDTH_3BIT, 328 0, 329 0), 330 }; 331 332 static struct rockchip_pin_ctrl rk3328_pin_ctrl = { 333 .pin_banks = rk3328_pin_banks, 334 .nr_banks = ARRAY_SIZE(rk3328_pin_banks), 335 .nr_pins = 128, 336 .grf_mux_offset = 0x0, 337 .iomux_recalced = rk3328_mux_recalced_data, 338 .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data), 339 .iomux_routes = rk3328_mux_route_data, 340 .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data), 341 .set_mux = rk3328_set_mux, 342 .set_pull = rk3328_set_pull, 343 .set_drive = rk3328_set_drive, 344 .set_schmitt = rk3328_set_schmitt, 345 }; 346 347 static const struct udevice_id rk3328_pinctrl_ids[] = { 348 { 349 .compatible = "rockchip,rk3328-pinctrl", 350 .data = (ulong)&rk3328_pin_ctrl 351 }, 352 { } 353 }; 354 355 U_BOOT_DRIVER(pinctrl_rk3328) = { 356 .name = "rockchip_rk3328_pinctrl", 357 .id = UCLASS_PINCTRL, 358 .of_match = rk3328_pinctrl_ids, 359 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 360 .ops = &rockchip_pinctrl_ops, 361 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 362 .bind = dm_scan_fdt_dev, 363 #endif 364 .probe = rockchip_pinctrl_probe, 365 }; 366