• 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 #include <common.h>
7 #include <dm.h>
8 #include <dm/pinctrl.h>
9 #include <regmap.h>
10 #include <syscon.h>
11 
12 #include "pinctrl-rockchip.h"
13 
14 static struct rockchip_mux_route_data px30_mux_route_data[] = {
15 	{
16 		/* cif-d2m0 */
17 		.bank_num = 2,
18 		.pin = 0,
19 		.func = 1,
20 		.route_offset = 0x184,
21 		.route_val = BIT(16 + 7),
22 	}, {
23 		/* cif-d2m1 */
24 		.bank_num = 3,
25 		.pin = 3,
26 		.func = 3,
27 		.route_offset = 0x184,
28 		.route_val = BIT(16 + 7) | BIT(7),
29 	}, {
30 		/* pdm-m0 */
31 		.bank_num = 3,
32 		.pin = 22,
33 		.func = 2,
34 		.route_offset = 0x184,
35 		.route_val = BIT(16 + 8),
36 	}, {
37 		/* pdm-m1 */
38 		.bank_num = 2,
39 		.pin = 22,
40 		.func = 1,
41 		.route_offset = 0x184,
42 		.route_val = BIT(16 + 8) | BIT(8),
43 	}, {
44 		/* uart2-rxm0 */
45 		.bank_num = 1,
46 		.pin = 27,
47 		.func = 2,
48 		.route_offset = 0x184,
49 		.route_val = BIT(16 + 10),
50 	}, {
51 		/* uart2-rxm1 */
52 		.bank_num = 2,
53 		.pin = 14,
54 		.func = 2,
55 		.route_offset = 0x184,
56 		.route_val = BIT(16 + 10) | BIT(10),
57 	}, {
58 		/* uart3-rxm0 */
59 		.bank_num = 0,
60 		.pin = 17,
61 		.func = 2,
62 		.route_offset = 0x184,
63 		.route_val = BIT(16 + 9),
64 	}, {
65 		/* uart3-rxm1 */
66 		.bank_num = 1,
67 		.pin = 15,
68 		.func = 2,
69 		.route_offset = 0x184,
70 		.route_val = BIT(16 + 9) | BIT(9),
71 	},
72 };
73 
px30_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)74 static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
75 {
76 	struct rockchip_pinctrl_priv *priv = bank->priv;
77 	int iomux_num = (pin / 8);
78 	struct regmap *regmap;
79 	int reg, ret, mask, mux_type;
80 	u8 bit;
81 	u32 data, route_reg, route_val;
82 
83 	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
84 				? priv->regmap_pmu : priv->regmap_base;
85 
86 	/* get basic quadrupel of mux registers and the correct reg inside */
87 	mux_type = bank->iomux[iomux_num].type;
88 	reg = bank->iomux[iomux_num].offset;
89 	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
90 
91 	if (bank->route_mask & BIT(pin)) {
92 		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
93 					   &route_val)) {
94 			ret = regmap_write(regmap, route_reg, route_val);
95 			if (ret)
96 				return ret;
97 		}
98 	}
99 
100 	data = (mask << (bit + 16));
101 	data |= (mux & mask) << bit;
102 	ret = regmap_write(regmap, reg, data);
103 
104 	return ret;
105 }
106 
107 #define PX30_PULL_PMU_OFFSET		0x10
108 #define PX30_PULL_GRF_OFFSET		0x60
109 #define PX30_PULL_BITS_PER_PIN		2
110 #define PX30_PULL_PINS_PER_REG		8
111 #define PX30_PULL_BANK_STRIDE		16
112 
px30_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)113 static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
114 				       int pin_num, struct regmap **regmap,
115 				       int *reg, u8 *bit)
116 {
117 	struct rockchip_pinctrl_priv *priv = bank->priv;
118 
119 	/* The first 32 pins of the first bank are located in PMU */
120 	if (bank->bank_num == 0) {
121 		*regmap = priv->regmap_pmu;
122 		*reg = PX30_PULL_PMU_OFFSET;
123 	} else {
124 		*regmap = priv->regmap_base;
125 		*reg = PX30_PULL_GRF_OFFSET;
126 
127 		/* correct the offset, as we're starting with the 2nd bank */
128 		*reg -= 0x10;
129 		*reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
130 	}
131 
132 	*reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
133 	*bit = (pin_num % PX30_PULL_PINS_PER_REG);
134 	*bit *= PX30_PULL_BITS_PER_PIN;
135 }
136 
px30_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)137 static int px30_set_pull(struct rockchip_pin_bank *bank,
138 			 int pin_num, int pull)
139 {
140 	struct regmap *regmap;
141 	int reg, ret;
142 	u8 bit, type;
143 	u32 data;
144 
145 	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
146 		return -ENOTSUPP;
147 
148 	px30_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
149 	type = bank->pull_type[pin_num / 8];
150 	ret = rockchip_translate_pull_value(type, pull);
151 	if (ret < 0) {
152 		debug("unsupported pull setting %d\n", pull);
153 		return ret;
154 	}
155 
156 	/* enable the write to the equivalent lower bits */
157 	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
158 	data |= (ret << bit);
159 	ret = regmap_write(regmap, reg, data);
160 
161 	return ret;
162 }
163 
164 #define PX30_DRV_PMU_OFFSET		0x20
165 #define PX30_DRV_GRF_OFFSET		0xf0
166 #define PX30_DRV_BITS_PER_PIN		2
167 #define PX30_DRV_PINS_PER_REG		8
168 #define PX30_DRV_BANK_STRIDE		16
169 
px30_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)170 static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
171 				      int pin_num, struct regmap **regmap,
172 				      int *reg, u8 *bit)
173 {
174 	struct rockchip_pinctrl_priv *priv = bank->priv;
175 
176 	/* The first 32 pins of the first bank are located in PMU */
177 	if (bank->bank_num == 0) {
178 		*regmap = priv->regmap_pmu;
179 		*reg = PX30_DRV_PMU_OFFSET;
180 	} else {
181 		*regmap = priv->regmap_base;
182 		*reg = PX30_DRV_GRF_OFFSET;
183 
184 		/* correct the offset, as we're starting with the 2nd bank */
185 		*reg -= 0x10;
186 		*reg += bank->bank_num * PX30_DRV_BANK_STRIDE;
187 	}
188 
189 	*reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
190 	*bit = (pin_num % PX30_DRV_PINS_PER_REG);
191 	*bit *= PX30_DRV_BITS_PER_PIN;
192 }
193 
px30_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)194 static int px30_set_drive(struct rockchip_pin_bank *bank,
195 			  int pin_num, int strength)
196 {
197 	struct regmap *regmap;
198 	int reg, ret;
199 	u32 data, rmask_bits, temp;
200 	u8 bit;
201 	int drv_type = bank->drv[pin_num / 8].drv_type;
202 
203 	px30_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
204 	ret = rockchip_translate_drive_value(drv_type, strength);
205 	if (ret < 0) {
206 		debug("unsupported driver strength %d\n", strength);
207 		return ret;
208 	}
209 
210 	switch (drv_type) {
211 	case DRV_TYPE_IO_1V8_3V0_AUTO:
212 	case DRV_TYPE_IO_3V3_ONLY:
213 		rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
214 		switch (bit) {
215 		case 0 ... 12:
216 			/* regular case, nothing to do */
217 			break;
218 		case 15:
219 			/*
220 			 * drive-strength offset is special, as it is spread
221 			 * over 2 registers, the bit data[15] contains bit 0
222 			 * of the value while temp[1:0] contains bits 2 and 1
223 			 */
224 			data = (ret & 0x1) << 15;
225 			temp = (ret >> 0x1) & 0x3;
226 
227 			data |= BIT(31);
228 			ret = regmap_write(regmap, reg, data);
229 			if (ret)
230 				return ret;
231 
232 			temp |= (0x3 << 16);
233 			reg += 0x4;
234 			ret = regmap_write(regmap, reg, temp);
235 
236 			return ret;
237 		case 18 ... 21:
238 			/* setting fully enclosed in the second register */
239 			reg += 4;
240 			bit -= 16;
241 			break;
242 		default:
243 			debug("unsupported bit: %d for pinctrl drive type: %d\n",
244 			      bit, drv_type);
245 			return -EINVAL;
246 		}
247 		break;
248 	case DRV_TYPE_IO_DEFAULT:
249 	case DRV_TYPE_IO_1V8_OR_3V0:
250 	case DRV_TYPE_IO_1V8_ONLY:
251 		rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
252 		break;
253 	default:
254 		debug("unsupported pinctrl drive type: %d\n",
255 		      drv_type);
256 		return -EINVAL;
257 	}
258 
259 	/* enable the write to the equivalent lower bits */
260 	data = ((1 << rmask_bits) - 1) << (bit + 16);
261 	data |= (ret << bit);
262 	ret = regmap_write(regmap, reg, data);
263 
264 	return ret;
265 }
266 
267 #define PX30_SCHMITT_PMU_OFFSET			0x38
268 #define PX30_SCHMITT_GRF_OFFSET			0xc0
269 #define PX30_SCHMITT_PINS_PER_PMU_REG		16
270 #define PX30_SCHMITT_BANK_STRIDE		16
271 #define PX30_SCHMITT_PINS_PER_GRF_REG		8
272 
px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)273 static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
274 					 int pin_num,
275 					 struct regmap **regmap,
276 					 int *reg, u8 *bit)
277 {
278 	struct rockchip_pinctrl_priv *priv = bank->priv;
279 	int pins_per_reg;
280 
281 	if (bank->bank_num == 0) {
282 		*regmap = priv->regmap_pmu;
283 		*reg = PX30_SCHMITT_PMU_OFFSET;
284 		pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG;
285 	} else {
286 		*regmap = priv->regmap_base;
287 		*reg = PX30_SCHMITT_GRF_OFFSET;
288 		pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG;
289 		*reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE;
290 	}
291 	*reg += ((pin_num / pins_per_reg) * 4);
292 	*bit = pin_num % pins_per_reg;
293 
294 	return 0;
295 }
296 
px30_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)297 static int px30_set_schmitt(struct rockchip_pin_bank *bank,
298 			    int pin_num, int enable)
299 {
300 	struct regmap *regmap;
301 	int reg;
302 	u8 bit;
303 	u32 data;
304 
305 	px30_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
306 	/* enable the write to the equivalent lower bits */
307 	data = BIT(bit + 16) | (enable << bit);
308 
309 	return regmap_write(regmap, reg, data);
310 }
311 
312 static struct rockchip_pin_bank px30_pin_banks[] = {
313 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
314 					     IOMUX_SOURCE_PMU,
315 					     IOMUX_SOURCE_PMU,
316 					     IOMUX_SOURCE_PMU
317 			    ),
318 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
319 					     IOMUX_WIDTH_4BIT,
320 					     IOMUX_WIDTH_4BIT,
321 					     IOMUX_WIDTH_4BIT
322 			    ),
323 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
324 					     IOMUX_WIDTH_4BIT,
325 					     IOMUX_WIDTH_4BIT,
326 					     IOMUX_WIDTH_4BIT
327 			    ),
328 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
329 					     IOMUX_WIDTH_4BIT,
330 					     IOMUX_WIDTH_4BIT,
331 					     IOMUX_WIDTH_4BIT
332 			    ),
333 };
334 
335 static struct rockchip_pin_ctrl px30_pin_ctrl = {
336 	.pin_banks		= px30_pin_banks,
337 	.nr_banks		= ARRAY_SIZE(px30_pin_banks),
338 	.grf_mux_offset		= 0x0,
339 	.pmu_mux_offset		= 0x0,
340 	.grf_drv_offset		= 0xf0,
341 	.pmu_drv_offset		= 0x20,
342 	.iomux_routes		= px30_mux_route_data,
343 	.niomux_routes		= ARRAY_SIZE(px30_mux_route_data),
344 	.set_mux		= px30_set_mux,
345 	.set_pull		= px30_set_pull,
346 	.set_drive		= px30_set_drive,
347 	.set_schmitt		= px30_set_schmitt,
348 };
349 
350 static const struct udevice_id px30_pinctrl_ids[] = {
351 	{
352 		.compatible = "rockchip,px30-pinctrl",
353 		.data = (ulong)&px30_pin_ctrl
354 	},
355 	{ }
356 };
357 
358 U_BOOT_DRIVER(pinctrl_px30) = {
359 	.name		= "rockchip_px30_pinctrl",
360 	.id		= UCLASS_PINCTRL,
361 	.of_match	= px30_pinctrl_ids,
362 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
363 	.ops		= &rockchip_pinctrl_ops,
364 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
365 	.bind		= dm_scan_fdt_dev,
366 #endif
367 	.probe		= rockchip_pinctrl_probe,
368 };
369