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