• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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