1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2020 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_route_data rk1808_mux_route_data[] = { 15 { 16 /* i2c2m0_sda */ 17 .bank_num = 3, 18 .pin = 12, 19 .func = 2, 20 .route_offset = 0x190, 21 .route_val = BIT(16 + 3), 22 }, { 23 /* i2c2m1_sda */ 24 .bank_num = 1, 25 .pin = 13, 26 .func = 2, 27 .route_offset = 0x190, 28 .route_val = BIT(16 + 3) | BIT(3), 29 }, { 30 /* uart2_rxm0 */ 31 .bank_num = 4, 32 .pin = 3, 33 .func = 2, 34 .route_offset = 0x190, 35 .route_val = BIT(16 + 14) | BIT(16 + 15), 36 }, { 37 /* uart2_rxm1 */ 38 .bank_num = 2, 39 .pin = 25, 40 .func = 2, 41 .route_offset = 0x190, 42 .route_val = BIT(16 + 14) | BIT(14) | BIT(16 + 15), 43 }, { 44 /* uart2_rxm2 */ 45 .bank_num = 3, 46 .pin = 4, 47 .func = 2, 48 .route_offset = 0x190, 49 .route_val = BIT(16 + 14) | BIT(16 + 15) | BIT(15), 50 }, 51 }; 52 53 static int rk1808_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 54 { 55 struct rockchip_pinctrl_priv *priv = bank->priv; 56 int iomux_num = (pin / 8); 57 struct regmap *regmap; 58 int reg, ret, mask, mux_type; 59 u8 bit; 60 u32 data; 61 62 debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); 63 64 if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 65 regmap = priv->regmap_pmu; 66 else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU) 67 regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base; 68 else 69 regmap = priv->regmap_base; 70 71 /* get basic quadrupel of mux registers and the correct reg inside */ 72 mux_type = bank->iomux[iomux_num].type; 73 reg = bank->iomux[iomux_num].offset; 74 if (mux_type & IOMUX_WIDTH_4BIT) { 75 if ((pin % 8) >= 4) 76 reg += 0x4; 77 bit = (pin % 4) * 4; 78 mask = 0xf; 79 } else { 80 bit = (pin % 8) * 2; 81 mask = 0x3; 82 } 83 84 if (bank->recalced_mask & BIT(pin)) 85 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 86 87 data = (mask << (bit + 16)); 88 data |= (mux & mask) << bit; 89 ret = regmap_write(regmap, reg, data); 90 91 return ret; 92 } 93 94 #define RK1808_PULL_PMU_OFFSET 0x10 95 #define RK1808_PULL_GRF_OFFSET 0x80 96 #define RK1808_PULL_PINS_PER_REG 8 97 #define RK1808_PULL_BITS_PER_PIN 2 98 #define RK1808_PULL_BANK_STRIDE 16 99 100 static void rk1808_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 101 int pin_num, 102 struct regmap **regmap, 103 int *reg, u8 *bit) 104 { 105 struct rockchip_pinctrl_priv *priv = bank->priv; 106 107 if (bank->bank_num == 0) { 108 *regmap = priv->regmap_pmu; 109 *reg = RK1808_PULL_PMU_OFFSET; 110 } else { 111 *reg = RK1808_PULL_GRF_OFFSET; 112 *regmap = priv->regmap_base; 113 } 114 115 *reg += ((pin_num / RK1808_PULL_PINS_PER_REG) * 4); 116 *bit = (pin_num % RK1808_PULL_PINS_PER_REG); 117 *bit *= RK1808_PULL_BITS_PER_PIN; 118 } 119 120 #define RK1808_DRV_PMU_OFFSET 0x20 121 #define RK1808_DRV_GRF_OFFSET 0x140 122 #define RK1808_DRV_BITS_PER_PIN 2 123 #define RK1808_DRV_PINS_PER_REG 8 124 #define RK1808_DRV_BANK_STRIDE 16 125 126 static void rk1808_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 127 int pin_num, 128 struct regmap **regmap, 129 int *reg, u8 *bit) 130 { 131 struct rockchip_pinctrl_priv *priv = bank->priv; 132 133 if (bank->bank_num == 0) { 134 *regmap = priv->regmap_pmu; 135 *reg = RK1808_DRV_PMU_OFFSET; 136 } else { 137 *regmap = priv->regmap_base; 138 *reg = RK1808_DRV_GRF_OFFSET; 139 } 140 141 *reg += ((pin_num / RK1808_DRV_PINS_PER_REG) * 4); 142 *bit = pin_num % RK1808_DRV_PINS_PER_REG; 143 *bit *= RK1808_DRV_BITS_PER_PIN; 144 } 145 146 #define RK1808_SCHMITT_PMU_OFFSET 0x0040 147 #define RK1808_SCHMITT_GRF_OFFSET 0x0100 148 #define RK1808_SCHMITT_BANK_STRIDE 16 149 #define RK1808_SCHMITT_PINS_PER_REG 8 150 151 static int rk1808_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 152 int pin_num, 153 struct regmap **regmap, 154 int *reg, u8 *bit) 155 { 156 struct rockchip_pinctrl_priv *priv = bank->priv; 157 158 if (bank->bank_num == 0) { 159 *regmap = priv->regmap_pmu; 160 *reg = RK1808_SCHMITT_PMU_OFFSET; 161 } else { 162 *regmap = priv->regmap_base; 163 *reg = RK1808_SCHMITT_GRF_OFFSET; 164 *reg += (bank->bank_num - 1) * RK1808_SCHMITT_BANK_STRIDE; 165 } 166 *reg += ((pin_num / RK1808_SCHMITT_PINS_PER_REG) * 4); 167 *bit = pin_num % RK1808_SCHMITT_PINS_PER_REG; 168 169 return 0; 170 } 171 172 static int rk1808_set_pull(struct rockchip_pin_bank *bank, 173 int pin_num, int pull) 174 { 175 struct regmap *regmap; 176 int reg, ret; 177 u8 bit, type; 178 u32 data; 179 180 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 181 return -ENOTSUPP; 182 183 rk1808_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 184 type = bank->pull_type[pin_num / 8]; 185 ret = rockchip_translate_pull_value(type, pull); 186 if (ret < 0) { 187 debug("unsupported pull setting %d\n", pull); 188 return ret; 189 } 190 191 /* enable the write to the equivalent lower bits */ 192 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); 193 194 data |= (ret << bit); 195 ret = regmap_write(regmap, reg, data); 196 197 return ret; 198 } 199 200 static int rk1808_set_drive(struct rockchip_pin_bank *bank, 201 int pin_num, int strength) 202 { 203 struct regmap *regmap; 204 int reg; 205 u32 data; 206 u8 bit; 207 208 rk1808_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 209 210 /* enable the write to the equivalent lower bits */ 211 data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); 212 data |= (strength << bit); 213 214 return regmap_write(regmap, reg, data); 215 } 216 217 static int rk1808_set_schmitt(struct rockchip_pin_bank *bank, 218 int pin_num, int enable) 219 { 220 struct regmap *regmap; 221 int reg; 222 u8 bit; 223 u32 data; 224 225 rk1808_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 226 /* enable the write to the equivalent lower bits */ 227 data = BIT(bit + 16) | (enable << bit); 228 229 return regmap_write(regmap, reg, data); 230 } 231 232 static struct rockchip_pin_bank rk1808_pin_banks[] = { 233 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 234 IOMUX_SOURCE_PMU, 235 IOMUX_SOURCE_PMU, 236 IOMUX_SOURCE_PMU, 237 IOMUX_SOURCE_PMU), 238 PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 239 IOMUX_WIDTH_4BIT, 240 IOMUX_WIDTH_4BIT, 241 IOMUX_WIDTH_4BIT, 242 IOMUX_WIDTH_4BIT), 243 PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 244 IOMUX_WIDTH_4BIT, 245 IOMUX_WIDTH_4BIT, 246 IOMUX_WIDTH_4BIT, 247 IOMUX_WIDTH_4BIT), 248 PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 249 IOMUX_WIDTH_4BIT, 250 IOMUX_WIDTH_4BIT, 251 IOMUX_WIDTH_4BIT, 252 IOMUX_WIDTH_4BIT), 253 PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", 254 IOMUX_WIDTH_4BIT, 255 IOMUX_WIDTH_4BIT, 256 IOMUX_WIDTH_4BIT, 257 IOMUX_WIDTH_4BIT), 258 }; 259 260 static const struct rockchip_pin_ctrl rk1808_pin_ctrl = { 261 .pin_banks = rk1808_pin_banks, 262 .nr_banks = ARRAY_SIZE(rk1808_pin_banks), 263 .nr_pins = 160, 264 .iomux_routes = rk1808_mux_route_data, 265 .niomux_routes = ARRAY_SIZE(rk1808_mux_route_data), 266 .grf_mux_offset = 0x0, 267 .pmu_mux_offset = 0x0, 268 .set_mux = rk1808_set_mux, 269 .set_pull = rk1808_set_pull, 270 .set_drive = rk1808_set_drive, 271 .set_schmitt = rk1808_set_schmitt, 272 }; 273 274 static const struct udevice_id rk1808_pinctrl_ids[] = { 275 { 276 .compatible = "rockchip,rk1808-pinctrl", 277 .data = (ulong)&rk1808_pin_ctrl 278 }, 279 { } 280 }; 281 282 U_BOOT_DRIVER(pinctrl_rk1808) = { 283 .name = "rockchip_rk1808_pinctrl", 284 .id = UCLASS_PINCTRL, 285 .of_match = rk1808_pinctrl_ids, 286 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 287 .ops = &rockchip_pinctrl_ops, 288 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 289 .bind = dm_scan_fdt_dev, 290 #endif 291 .probe = rockchip_pinctrl_probe, 292 }; 293