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 rv1108_mux_recalced_data[] = { 15 { 16 .num = 1, 17 .pin = 0, 18 .reg = 0x418, 19 .bit = 0, 20 .mask = 0x3 21 }, { 22 .num = 1, 23 .pin = 1, 24 .reg = 0x418, 25 .bit = 2, 26 .mask = 0x3 27 }, { 28 .num = 1, 29 .pin = 2, 30 .reg = 0x418, 31 .bit = 4, 32 .mask = 0x3 33 }, { 34 .num = 1, 35 .pin = 3, 36 .reg = 0x418, 37 .bit = 6, 38 .mask = 0x3 39 }, { 40 .num = 1, 41 .pin = 4, 42 .reg = 0x418, 43 .bit = 8, 44 .mask = 0x3 45 }, { 46 .num = 1, 47 .pin = 5, 48 .reg = 0x418, 49 .bit = 10, 50 .mask = 0x3 51 }, { 52 .num = 1, 53 .pin = 6, 54 .reg = 0x418, 55 .bit = 12, 56 .mask = 0x3 57 }, { 58 .num = 1, 59 .pin = 7, 60 .reg = 0x418, 61 .bit = 14, 62 .mask = 0x3 63 }, { 64 .num = 1, 65 .pin = 8, 66 .reg = 0x41c, 67 .bit = 0, 68 .mask = 0x3 69 }, { 70 .num = 1, 71 .pin = 9, 72 .reg = 0x41c, 73 .bit = 2, 74 .mask = 0x3 75 }, 76 }; 77 78 static int rv1108_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) 79 { 80 struct rockchip_pinctrl_priv *priv = bank->priv; 81 int iomux_num = (pin / 8); 82 struct regmap *regmap; 83 int reg, ret, mask, mux_type; 84 u8 bit; 85 u32 data; 86 87 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) 88 ? priv->regmap_pmu : priv->regmap_base; 89 90 /* get basic quadrupel of mux registers and the correct reg inside */ 91 mux_type = bank->iomux[iomux_num].type; 92 reg = bank->iomux[iomux_num].offset; 93 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); 94 95 if (bank->recalced_mask & BIT(pin)) 96 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); 97 98 data = (mask << (bit + 16)); 99 data |= (mux & mask) << bit; 100 ret = regmap_write(regmap, reg, data); 101 102 return ret; 103 } 104 105 #define RV1108_PULL_PMU_OFFSET 0x10 106 #define RV1108_PULL_OFFSET 0x110 107 108 static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, 109 int pin_num, struct regmap **regmap, 110 int *reg, u8 *bit) 111 { 112 struct rockchip_pinctrl_priv *priv = bank->priv; 113 114 /* The first 24 pins of the first bank are located in PMU */ 115 if (bank->bank_num == 0) { 116 *regmap = priv->regmap_pmu; 117 *reg = RV1108_PULL_PMU_OFFSET; 118 } else { 119 *reg = RV1108_PULL_OFFSET; 120 *regmap = priv->regmap_base; 121 /* correct the offset, as we're starting with the 2nd bank */ 122 *reg -= 0x10; 123 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE; 124 } 125 126 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4); 127 *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG); 128 *bit *= ROCKCHIP_PULL_BITS_PER_PIN; 129 } 130 131 static int rv1108_set_pull(struct rockchip_pin_bank *bank, 132 int pin_num, int pull) 133 { 134 struct regmap *regmap; 135 int reg, ret; 136 u8 bit, type; 137 u32 data; 138 139 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) 140 return -ENOTSUPP; 141 142 rv1108_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); 143 type = bank->pull_type[pin_num / 8]; 144 ret = rockchip_translate_pull_value(type, pull); 145 if (ret < 0) { 146 debug("unsupported pull setting %d\n", pull); 147 return ret; 148 } 149 150 /* enable the write to the equivalent lower bits */ 151 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); 152 153 data |= (ret << bit); 154 ret = regmap_write(regmap, reg, data); 155 156 return ret; 157 } 158 159 #define RV1108_DRV_PMU_OFFSET 0x20 160 #define RV1108_DRV_GRF_OFFSET 0x210 161 162 static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, 163 int pin_num, struct regmap **regmap, 164 int *reg, u8 *bit) 165 { 166 struct rockchip_pinctrl_priv *priv = bank->priv; 167 168 /* The first 24 pins of the first bank are located in PMU */ 169 if (bank->bank_num == 0) { 170 *regmap = priv->regmap_pmu; 171 *reg = RV1108_DRV_PMU_OFFSET; 172 } else { 173 *regmap = priv->regmap_base; 174 *reg = RV1108_DRV_GRF_OFFSET; 175 176 /* correct the offset, as we're starting with the 2nd bank */ 177 *reg -= 0x10; 178 *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE; 179 } 180 181 *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); 182 *bit = pin_num % ROCKCHIP_DRV_PINS_PER_REG; 183 *bit *= ROCKCHIP_DRV_BITS_PER_PIN; 184 } 185 186 static int rv1108_set_drive(struct rockchip_pin_bank *bank, 187 int pin_num, int strength) 188 { 189 struct regmap *regmap; 190 int reg, ret; 191 u32 data; 192 u8 bit; 193 int type = bank->drv[pin_num / 8].drv_type; 194 195 rv1108_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); 196 ret = rockchip_translate_drive_value(type, strength); 197 if (ret < 0) { 198 debug("unsupported driver strength %d\n", strength); 199 return ret; 200 } 201 202 /* enable the write to the equivalent lower bits */ 203 data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); 204 205 data |= (ret << bit); 206 ret = regmap_write(regmap, reg, data); 207 return ret; 208 } 209 210 #define RV1108_SCHMITT_PMU_OFFSET 0x30 211 #define RV1108_SCHMITT_GRF_OFFSET 0x388 212 #define RV1108_SCHMITT_BANK_STRIDE 8 213 #define RV1108_SCHMITT_PINS_PER_GRF_REG 16 214 #define RV1108_SCHMITT_PINS_PER_PMU_REG 8 215 216 static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, 217 int pin_num, 218 struct regmap **regmap, 219 int *reg, u8 *bit) 220 { 221 struct rockchip_pinctrl_priv *priv = bank->priv; 222 int pins_per_reg; 223 224 if (bank->bank_num == 0) { 225 *regmap = priv->regmap_pmu; 226 *reg = RV1108_SCHMITT_PMU_OFFSET; 227 pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG; 228 } else { 229 *regmap = priv->regmap_base; 230 *reg = RV1108_SCHMITT_GRF_OFFSET; 231 pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG; 232 *reg += (bank->bank_num - 1) * RV1108_SCHMITT_BANK_STRIDE; 233 } 234 *reg += ((pin_num / pins_per_reg) * 4); 235 *bit = pin_num % pins_per_reg; 236 237 return 0; 238 } 239 240 static int rv1108_set_schmitt(struct rockchip_pin_bank *bank, 241 int pin_num, int enable) 242 { 243 struct regmap *regmap; 244 int reg; 245 u8 bit; 246 u32 data; 247 248 rv1108_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); 249 /* enable the write to the equivalent lower bits */ 250 data = BIT(bit + 16) | (enable << bit); 251 252 return regmap_write(regmap, reg, data); 253 } 254 255 static struct rockchip_pin_bank rv1108_pin_banks[] = { 256 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, 257 IOMUX_SOURCE_PMU, 258 IOMUX_SOURCE_PMU, 259 IOMUX_SOURCE_PMU), 260 PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), 261 PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), 262 PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), 263 }; 264 265 static struct rockchip_pin_ctrl rv1108_pin_ctrl = { 266 .pin_banks = rv1108_pin_banks, 267 .nr_banks = ARRAY_SIZE(rv1108_pin_banks), 268 .grf_mux_offset = 0x10, 269 .pmu_mux_offset = 0x0, 270 .iomux_recalced = rv1108_mux_recalced_data, 271 .niomux_recalced = ARRAY_SIZE(rv1108_mux_recalced_data), 272 .set_mux = rv1108_set_mux, 273 .set_pull = rv1108_set_pull, 274 .set_drive = rv1108_set_drive, 275 .set_schmitt = rv1108_set_schmitt, 276 }; 277 278 static const struct udevice_id rv1108_pinctrl_ids[] = { 279 { 280 .compatible = "rockchip,rv1108-pinctrl", 281 .data = (ulong)&rv1108_pin_ctrl 282 }, 283 { } 284 }; 285 286 U_BOOT_DRIVER(pinctrl_rv1108) = { 287 .name = "pinctrl_rv1108", 288 .id = UCLASS_PINCTRL, 289 .of_match = rv1108_pinctrl_ids, 290 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv), 291 .ops = &rockchip_pinctrl_ops, 292 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 293 .bind = dm_scan_fdt_dev, 294 #endif 295 .probe = rockchip_pinctrl_probe, 296 }; 297