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