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