xref: /rk3399_rockchip-uboot/drivers/pinctrl/rockchip/pinctrl-rockchip.h (revision d3acdc96e2fd0ed34beb32b26ba57131a1e04ea3)
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