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