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