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