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