1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * (C) Copyright 2019 Rockchip Electronics Co., Ltd 4 */ 5 6 #ifndef __DRIVERS_PINCTRL_ROCKCHIP_H 7 #define __DRIVERS_PINCTRL_ROCKCHIP_H 8 9 #include <linux/types.h> 10 11 enum rockchip_pinctrl_type { 12 RV1108, 13 RK3036, 14 RK3128, 15 RK3188, 16 RK3288, 17 RK3368, 18 RK3399, 19 }; 20 21 /** 22 * Encode variants of iomux registers into a type variable 23 */ 24 #define IOMUX_GPIO_ONLY BIT(0) 25 #define IOMUX_WIDTH_4BIT BIT(1) 26 #define IOMUX_SOURCE_PMU BIT(2) 27 #define IOMUX_UNROUTED BIT(3) 28 #define IOMUX_WIDTH_3BIT BIT(4) 29 #define IOMUX_WRITABLE_32BIT BIT(5) 30 31 /** 32 * Defined some common pins constants 33 */ 34 #define ROCKCHIP_PULL_BITS_PER_PIN 2 35 #define ROCKCHIP_PULL_PINS_PER_REG 8 36 #define ROCKCHIP_PULL_BANK_STRIDE 16 37 #define ROCKCHIP_DRV_BITS_PER_PIN 2 38 #define ROCKCHIP_DRV_PINS_PER_REG 8 39 #define ROCKCHIP_DRV_BANK_STRIDE 16 40 #define ROCKCHIP_DRV_3BITS_PER_PIN 3 41 42 /** 43 * @type: iomux variant using IOMUX_* constants 44 * @offset: if initialized to -1 it will be autocalculated, by specifying 45 * an initial offset value the relevant source offset can be reset 46 * to a new value for autocalculating the following iomux registers. 47 */ 48 struct rockchip_iomux { 49 int type; 50 int offset; 51 }; 52 53 #define DRV_TYPE_IO_MASK GENMASK(31, 16) 54 #define DRV_TYPE_WRITABLE_32BIT BIT(31) 55 56 /** 57 * enum type index corresponding to rockchip_perpin_drv_list arrays index. 58 */ 59 enum rockchip_pin_drv_type { 60 DRV_TYPE_IO_DEFAULT = 0, 61 DRV_TYPE_IO_1V8_OR_3V0, 62 DRV_TYPE_IO_1V8_ONLY, 63 DRV_TYPE_IO_1V8_3V0_AUTO, 64 DRV_TYPE_IO_3V3_ONLY, 65 DRV_TYPE_MAX 66 }; 67 68 #define PULL_TYPE_IO_MASK GENMASK(31, 16) 69 #define PULL_TYPE_WRITABLE_32BIT BIT(31) 70 71 /** 72 * enum type index corresponding to rockchip_pull_list arrays index. 73 */ 74 enum rockchip_pin_pull_type { 75 PULL_TYPE_IO_DEFAULT = 0, 76 PULL_TYPE_IO_1V8_ONLY, 77 PULL_TYPE_MAX 78 }; 79 80 /** 81 * @drv_type: drive strength variant using rockchip_perpin_drv_type 82 * @offset: if initialized to -1 it will be autocalculated, by specifying 83 * an initial offset value the relevant source offset can be reset 84 * to a new value for autocalculating the following drive strength 85 * registers. if used chips own cal_drv func instead to calculate 86 * registers offset, the variant could be ignored. 87 */ 88 struct rockchip_drv { 89 enum rockchip_pin_drv_type drv_type; 90 int offset; 91 }; 92 93 /** 94 * @priv: common pinctrl private basedata 95 * @pin_base: first pin number 96 * @nr_pins: number of pins in this bank 97 * @name: name of the bank 98 * @bank_num: number of the bank, to account for holes 99 * @iomux: array describing the 4 iomux sources of the bank 100 * @drv: array describing the 4 drive strength sources of the bank 101 * @pull_type: array describing the 4 pull type sources of the bank 102 * @recalced_mask: bits describing the mux recalced pins of per bank 103 * @route_mask: bits describing the routing pins of per bank 104 */ 105 struct rockchip_pin_bank { 106 struct rockchip_pinctrl_priv *priv; 107 u32 pin_base; 108 u8 nr_pins; 109 char *name; 110 u8 bank_num; 111 struct rockchip_iomux iomux[4]; 112 struct rockchip_drv drv[4]; 113 enum rockchip_pin_pull_type pull_type[4]; 114 u32 recalced_mask; 115 u32 route_mask; 116 }; 117 118 #define PIN_BANK(id, pins, label) \ 119 { \ 120 .bank_num = id, \ 121 .nr_pins = pins, \ 122 .name = label, \ 123 .iomux = { \ 124 { .offset = -1 }, \ 125 { .offset = -1 }, \ 126 { .offset = -1 }, \ 127 { .offset = -1 }, \ 128 }, \ 129 } 130 131 #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ 132 { \ 133 .bank_num = id, \ 134 .nr_pins = pins, \ 135 .name = label, \ 136 .iomux = { \ 137 { .type = iom0, .offset = -1 }, \ 138 { .type = iom1, .offset = -1 }, \ 139 { .type = iom2, .offset = -1 }, \ 140 { .type = iom3, .offset = -1 }, \ 141 }, \ 142 } 143 144 #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \ 145 { \ 146 .bank_num = id, \ 147 .nr_pins = pins, \ 148 .name = label, \ 149 .iomux = { \ 150 { .offset = -1 }, \ 151 { .offset = -1 }, \ 152 { .offset = -1 }, \ 153 { .offset = -1 }, \ 154 }, \ 155 .drv = { \ 156 { .drv_type = type0, .offset = -1 }, \ 157 { .drv_type = type1, .offset = -1 }, \ 158 { .drv_type = type2, .offset = -1 }, \ 159 { .drv_type = type3, .offset = -1 }, \ 160 }, \ 161 } 162 163 #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \ 164 drv2, drv3, pull0, pull1, \ 165 pull2, pull3) \ 166 { \ 167 .bank_num = id, \ 168 .nr_pins = pins, \ 169 .name = label, \ 170 .iomux = { \ 171 { .offset = -1 }, \ 172 { .offset = -1 }, \ 173 { .offset = -1 }, \ 174 { .offset = -1 }, \ 175 }, \ 176 .drv = { \ 177 { .drv_type = drv0, .offset = -1 }, \ 178 { .drv_type = drv1, .offset = -1 }, \ 179 { .drv_type = drv2, .offset = -1 }, \ 180 { .drv_type = drv3, .offset = -1 }, \ 181 }, \ 182 .pull_type[0] = pull0, \ 183 .pull_type[1] = pull1, \ 184 .pull_type[2] = pull2, \ 185 .pull_type[3] = pull3, \ 186 } 187 188 #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ 189 iom2, iom3, drv0, drv1, drv2, \ 190 drv3, offset0, offset1, \ 191 offset2, offset3) \ 192 { \ 193 .bank_num = id, \ 194 .nr_pins = pins, \ 195 .name = label, \ 196 .iomux = { \ 197 { .type = iom0, .offset = -1 }, \ 198 { .type = iom1, .offset = -1 }, \ 199 { .type = iom2, .offset = -1 }, \ 200 { .type = iom3, .offset = -1 }, \ 201 }, \ 202 .drv = { \ 203 { .drv_type = drv0, .offset = offset0 }, \ 204 { .drv_type = drv1, .offset = offset1 }, \ 205 { .drv_type = drv2, .offset = offset2 }, \ 206 { .drv_type = drv3, .offset = offset3 }, \ 207 }, \ 208 } 209 210 #define PIN_BANK_IOMUX_DRV_PULL_FLAGS(id, pins, label, iom0, iom1, \ 211 iom2, iom3, drv0, drv1, drv2, \ 212 drv3, pull0, pull1, pull2, \ 213 pull3) \ 214 { \ 215 .bank_num = id, \ 216 .nr_pins = pins, \ 217 .name = label, \ 218 .iomux = { \ 219 { .type = iom0, .offset = -1 }, \ 220 { .type = iom1, .offset = -1 }, \ 221 { .type = iom2, .offset = -1 }, \ 222 { .type = iom3, .offset = -1 }, \ 223 }, \ 224 .drv = { \ 225 { .drv_type = drv0, .offset = -1 }, \ 226 { .drv_type = drv1, .offset = -1 }, \ 227 { .drv_type = drv2, .offset = -1 }, \ 228 { .drv_type = drv3, .offset = -1 }, \ 229 }, \ 230 .pull_type[0] = pull0, \ 231 .pull_type[1] = pull1, \ 232 .pull_type[2] = pull2, \ 233 .pull_type[3] = pull3, \ 234 } 235 236 #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \ 237 label, iom0, iom1, iom2, \ 238 iom3, drv0, drv1, drv2, \ 239 drv3, offset0, offset1, \ 240 offset2, offset3, pull0, \ 241 pull1, pull2, pull3) \ 242 { \ 243 .bank_num = id, \ 244 .nr_pins = pins, \ 245 .name = label, \ 246 .iomux = { \ 247 { .type = iom0, .offset = -1 }, \ 248 { .type = iom1, .offset = -1 }, \ 249 { .type = iom2, .offset = -1 }, \ 250 { .type = iom3, .offset = -1 }, \ 251 }, \ 252 .drv = { \ 253 { .drv_type = drv0, .offset = offset0 }, \ 254 { .drv_type = drv1, .offset = offset1 }, \ 255 { .drv_type = drv2, .offset = offset2 }, \ 256 { .drv_type = drv3, .offset = offset3 }, \ 257 }, \ 258 .pull_type[0] = pull0, \ 259 .pull_type[1] = pull1, \ 260 .pull_type[2] = pull2, \ 261 .pull_type[3] = pull3, \ 262 } 263 264 /** 265 * struct rockchip_mux_recalced_data: recalculate a pin iomux data. 266 * @num: bank number. 267 * @pin: pin number. 268 * @reg: register offset. 269 * @bit: index at register. 270 * @mask: mask bit 271 */ 272 struct rockchip_mux_recalced_data { 273 u8 num; 274 u8 pin; 275 u32 reg; 276 u8 bit; 277 u8 mask; 278 }; 279 280 /** 281 * struct rockchip_mux_route_data: route a pin iomux data. 282 * @bank_num: bank number. 283 * @pin: index at register or used to calc index. 284 * @func: the min pin. 285 * @route_offset: the max pin. 286 * @route_val: the register offset. 287 */ 288 struct rockchip_mux_route_data { 289 u8 bank_num; 290 u8 pin; 291 u8 func; 292 u32 route_offset; 293 u32 route_val; 294 }; 295 296 /** 297 */ 298 struct rockchip_pin_ctrl { 299 struct rockchip_pin_bank *pin_banks; 300 u32 nr_banks; 301 u32 nr_pins; 302 char *label; 303 enum rockchip_pinctrl_type type; 304 int grf_mux_offset; 305 int pmu_mux_offset; 306 int grf_drv_offset; 307 int pmu_drv_offset; 308 struct rockchip_mux_recalced_data *iomux_recalced; 309 u32 niomux_recalced; 310 struct rockchip_mux_route_data *iomux_routes; 311 u32 niomux_routes; 312 313 void (*pull_calc_reg)(struct rockchip_pin_bank *bank, 314 int pin_num, struct regmap **regmap, 315 int *reg, u8 *bit); 316 void (*drv_calc_reg)(struct rockchip_pin_bank *bank, 317 int pin_num, struct regmap **regmap, 318 int *reg, u8 *bit); 319 int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank, 320 int pin_num, struct regmap **regmap, 321 int *reg, u8 *bit); 322 }; 323 324 /** 325 */ 326 struct rockchip_pinctrl_priv { 327 struct rockchip_pin_ctrl *ctrl; 328 struct regmap *regmap_base; 329 struct regmap *regmap_pmu; 330 }; 331 332 extern const struct pinctrl_ops rockchip_pinctrl_ops; 333 int rockchip_pinctrl_probe(struct udevice *dev); 334 335 #endif /* __DRIVERS_PINCTRL_ROCKCHIP_H */ 336