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 30 /** 31 * Defined some common pins constants 32 */ 33 #define ROCKCHIP_PULL_BITS_PER_PIN 2 34 #define ROCKCHIP_PULL_PINS_PER_REG 8 35 #define ROCKCHIP_PULL_BANK_STRIDE 16 36 #define ROCKCHIP_DRV_BITS_PER_PIN 2 37 #define ROCKCHIP_DRV_PINS_PER_REG 8 38 #define ROCKCHIP_DRV_BANK_STRIDE 16 39 #define ROCKCHIP_DRV_3BITS_PER_PIN 3 40 41 /** 42 * @type: iomux variant using IOMUX_* constants 43 * @offset: if initialized to -1 it will be autocalculated, by specifying 44 * an initial offset value the relevant source offset can be reset 45 * to a new value for autocalculating the following iomux registers. 46 */ 47 struct rockchip_iomux { 48 int type; 49 int offset; 50 }; 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 /** 65 * enum type index corresponding to rockchip_pull_list arrays index. 66 */ 67 enum rockchip_pin_pull_type { 68 PULL_TYPE_IO_DEFAULT = 0, 69 PULL_TYPE_IO_1V8_ONLY, 70 PULL_TYPE_MAX 71 }; 72 73 /** 74 * @drv_type: drive strength variant using rockchip_perpin_drv_type 75 * @offset: if initialized to -1 it will be autocalculated, by specifying 76 * an initial offset value the relevant source offset can be reset 77 * to a new value for autocalculating the following drive strength 78 * registers. if used chips own cal_drv func instead to calculate 79 * registers offset, the variant could be ignored. 80 */ 81 struct rockchip_drv { 82 enum rockchip_pin_drv_type drv_type; 83 int offset; 84 }; 85 86 /** 87 * @priv: common pinctrl private basedata 88 * @pin_base: first pin number 89 * @nr_pins: number of pins in this bank 90 * @name: name of the bank 91 * @bank_num: number of the bank, to account for holes 92 * @iomux: array describing the 4 iomux sources of the bank 93 * @drv: array describing the 4 drive strength sources of the bank 94 * @pull_type: array describing the 4 pull type sources of the bank 95 * @recalced_mask: bits describing the mux recalced pins of per bank 96 * @route_mask: bits describing the routing pins of per bank 97 */ 98 struct rockchip_pin_bank { 99 struct rockchip_pinctrl_priv *priv; 100 u32 pin_base; 101 u8 nr_pins; 102 char *name; 103 u8 bank_num; 104 struct rockchip_iomux iomux[4]; 105 struct rockchip_drv drv[4]; 106 enum rockchip_pin_pull_type pull_type[4]; 107 u32 recalced_mask; 108 u32 route_mask; 109 }; 110 111 #define PIN_BANK(id, pins, label) \ 112 { \ 113 .bank_num = id, \ 114 .nr_pins = pins, \ 115 .name = label, \ 116 .iomux = { \ 117 { .offset = -1 }, \ 118 { .offset = -1 }, \ 119 { .offset = -1 }, \ 120 { .offset = -1 }, \ 121 }, \ 122 } 123 124 #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \ 125 { \ 126 .bank_num = id, \ 127 .nr_pins = pins, \ 128 .name = label, \ 129 .iomux = { \ 130 { .type = iom0, .offset = -1 }, \ 131 { .type = iom1, .offset = -1 }, \ 132 { .type = iom2, .offset = -1 }, \ 133 { .type = iom3, .offset = -1 }, \ 134 }, \ 135 } 136 137 #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \ 138 { \ 139 .bank_num = id, \ 140 .nr_pins = pins, \ 141 .name = label, \ 142 .iomux = { \ 143 { .offset = -1 }, \ 144 { .offset = -1 }, \ 145 { .offset = -1 }, \ 146 { .offset = -1 }, \ 147 }, \ 148 .drv = { \ 149 { .drv_type = type0, .offset = -1 }, \ 150 { .drv_type = type1, .offset = -1 }, \ 151 { .drv_type = type2, .offset = -1 }, \ 152 { .drv_type = type3, .offset = -1 }, \ 153 }, \ 154 } 155 156 #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \ 157 drv2, drv3, pull0, pull1, \ 158 pull2, pull3) \ 159 { \ 160 .bank_num = id, \ 161 .nr_pins = pins, \ 162 .name = label, \ 163 .iomux = { \ 164 { .offset = -1 }, \ 165 { .offset = -1 }, \ 166 { .offset = -1 }, \ 167 { .offset = -1 }, \ 168 }, \ 169 .drv = { \ 170 { .drv_type = drv0, .offset = -1 }, \ 171 { .drv_type = drv1, .offset = -1 }, \ 172 { .drv_type = drv2, .offset = -1 }, \ 173 { .drv_type = drv3, .offset = -1 }, \ 174 }, \ 175 .pull_type[0] = pull0, \ 176 .pull_type[1] = pull1, \ 177 .pull_type[2] = pull2, \ 178 .pull_type[3] = pull3, \ 179 } 180 181 #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1, \ 182 iom2, iom3, drv0, drv1, drv2, \ 183 drv3, offset0, offset1, \ 184 offset2, offset3) \ 185 { \ 186 .bank_num = id, \ 187 .nr_pins = pins, \ 188 .name = label, \ 189 .iomux = { \ 190 { .type = iom0, .offset = -1 }, \ 191 { .type = iom1, .offset = -1 }, \ 192 { .type = iom2, .offset = -1 }, \ 193 { .type = iom3, .offset = -1 }, \ 194 }, \ 195 .drv = { \ 196 { .drv_type = drv0, .offset = offset0 }, \ 197 { .drv_type = drv1, .offset = offset1 }, \ 198 { .drv_type = drv2, .offset = offset2 }, \ 199 { .drv_type = drv3, .offset = offset3 }, \ 200 }, \ 201 } 202 203 #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins, \ 204 label, iom0, iom1, iom2, \ 205 iom3, drv0, drv1, drv2, \ 206 drv3, offset0, offset1, \ 207 offset2, offset3, pull0, \ 208 pull1, pull2, pull3) \ 209 { \ 210 .bank_num = id, \ 211 .nr_pins = pins, \ 212 .name = label, \ 213 .iomux = { \ 214 { .type = iom0, .offset = -1 }, \ 215 { .type = iom1, .offset = -1 }, \ 216 { .type = iom2, .offset = -1 }, \ 217 { .type = iom3, .offset = -1 }, \ 218 }, \ 219 .drv = { \ 220 { .drv_type = drv0, .offset = offset0 }, \ 221 { .drv_type = drv1, .offset = offset1 }, \ 222 { .drv_type = drv2, .offset = offset2 }, \ 223 { .drv_type = drv3, .offset = offset3 }, \ 224 }, \ 225 .pull_type[0] = pull0, \ 226 .pull_type[1] = pull1, \ 227 .pull_type[2] = pull2, \ 228 .pull_type[3] = pull3, \ 229 } 230 231 /** 232 * struct rockchip_mux_recalced_data: recalculate a pin iomux data. 233 * @num: bank number. 234 * @pin: pin number. 235 * @reg: register offset. 236 * @bit: index at register. 237 * @mask: mask bit 238 */ 239 struct rockchip_mux_recalced_data { 240 u8 num; 241 u8 pin; 242 u32 reg; 243 u8 bit; 244 u8 mask; 245 }; 246 247 /** 248 * struct rockchip_mux_route_data: route a pin iomux data. 249 * @bank_num: bank number. 250 * @pin: index at register or used to calc index. 251 * @func: the min pin. 252 * @route_offset: the max pin. 253 * @route_val: the register offset. 254 */ 255 struct rockchip_mux_route_data { 256 u8 bank_num; 257 u8 pin; 258 u8 func; 259 u32 route_offset; 260 u32 route_val; 261 }; 262 263 /** 264 */ 265 struct rockchip_pin_ctrl { 266 struct rockchip_pin_bank *pin_banks; 267 u32 nr_banks; 268 u32 nr_pins; 269 char *label; 270 enum rockchip_pinctrl_type type; 271 int grf_mux_offset; 272 int pmu_mux_offset; 273 int grf_drv_offset; 274 int pmu_drv_offset; 275 struct rockchip_mux_recalced_data *iomux_recalced; 276 u32 niomux_recalced; 277 struct rockchip_mux_route_data *iomux_routes; 278 u32 niomux_routes; 279 280 void (*pull_calc_reg)(struct rockchip_pin_bank *bank, 281 int pin_num, struct regmap **regmap, 282 int *reg, u8 *bit); 283 void (*drv_calc_reg)(struct rockchip_pin_bank *bank, 284 int pin_num, struct regmap **regmap, 285 int *reg, u8 *bit); 286 int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank, 287 int pin_num, struct regmap **regmap, 288 int *reg, u8 *bit); 289 }; 290 291 /** 292 */ 293 struct rockchip_pinctrl_priv { 294 struct rockchip_pin_ctrl *ctrl; 295 struct regmap *regmap_base; 296 struct regmap *regmap_pmu; 297 }; 298 299 extern const struct pinctrl_ops rockchip_pinctrl_ops; 300 int rockchip_pinctrl_probe(struct udevice *dev); 301 302 #endif /* __DRIVERS_PINCTRL_ROCKCHIP_H */ 303