xref: /rk3399_rockchip-uboot/drivers/pinctrl/rockchip/pinctrl-rk3506.c (revision 3fd22dcdf025129433b12c22bcf0b8fc3c469b5a)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2024 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 
rockchip_set_rmio(struct rockchip_pin_bank * bank,int pin,int * mux)14 static int rockchip_set_rmio(struct rockchip_pin_bank *bank, int pin, int *mux)
15 {
16 	struct rockchip_pinctrl_priv *priv = bank->priv;
17 	struct regmap *regmap;
18 	int reg, function;
19 	u32 data;
20 	int ret = 0;
21 	u32 iomux_max = (1 << 4) - 1;
22 
23 	if (*mux > iomux_max)
24 		function = *mux - iomux_max;
25 	else
26 		return 0;
27 
28 	regmap = priv->regmap_rmio;
29 	if (bank->bank_num == 0) {
30 		if (pin < 24)
31 			reg = 0x80 + 0x4 * pin;
32 		else
33 			ret = -EINVAL;
34 	} else if (bank->bank_num == 1) {
35 		if (pin >= 9 && pin <= 11)
36 			reg = 0xbc + 0x4 * pin;
37 		else if (pin >= 18 && pin <= 19)
38 			reg = 0xa4 + 0x4 * pin;
39 		else if (pin >= 25 && pin <= 27)
40 			reg = 0x90 + 0x4 * pin;
41 		else
42 			ret = -EINVAL;
43 	} else {
44 		ret = -EINVAL;
45 	}
46 	if (ret) {
47 		pr_err("rmio unsupported bank_num %d function %d\n",
48 			bank->bank_num, function);
49 
50 		return -EINVAL;
51 	}
52 
53 	data = 0x7f0000 | function;
54 	*mux = 7;
55 	ret = regmap_write(regmap, reg, data);
56 	if (ret)
57 		return ret;
58 
59 	return 0;
60 }
61 
rk3506_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)62 static int rk3506_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
63 {
64 	struct rockchip_pinctrl_priv *priv = bank->priv;
65 	int iomux_num = (pin / 8);
66 	struct regmap *regmap;
67 	int reg, ret, mask;
68 	u8 bit;
69 	u32 data;
70 
71 	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
72 
73 	ret = rockchip_set_rmio(bank, pin, &mux);
74 	if (ret)
75 		return ret;
76 
77 	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
78 		regmap = priv->regmap_pmu;
79 	else
80 		regmap = priv->regmap_base;
81 
82 	if (bank->bank_num == 1)
83 		regmap = priv->regmap_ioc1;
84 	else if (bank->bank_num == 4)
85 		return 0;
86 
87 	reg = bank->iomux[iomux_num].offset;
88 	if ((pin % 8) >= 4)
89 		reg += 0x4;
90 	bit = (pin % 4) * 4;
91 	mask = 0xf;
92 
93 	if (bank->recalced_mask & BIT(pin))
94 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
95 	data = (mask << (bit + 16));
96 	data |= (mux & mask) << bit;
97 
98 	debug("iomux write reg = %x data = %x\n", reg, data);
99 
100 	ret = regmap_write(regmap, reg, data);
101 
102 	return ret;
103 }
104 
105 #define RK3506_DRV_BITS_PER_PIN		8
106 #define RK3506_DRV_PINS_PER_REG		2
107 #define RK3506_DRV_GPIO0_A_OFFSET	0x100
108 #define RK3506_DRV_GPIO0_D_OFFSET	0x830
109 #define RK3506_DRV_GPIO1_OFFSET		0x140
110 #define RK3506_DRV_GPIO2_OFFSET		0x180
111 #define RK3506_DRV_GPIO3_OFFSET		0x1c0
112 #define RK3506_DRV_GPIO4_OFFSET		0x840
113 
rk3506_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)114 static int rk3506_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
115 					int pin_num, struct regmap **regmap,
116 					int *reg, u8 *bit)
117 {
118 	struct rockchip_pinctrl_priv *priv = bank->priv;
119 	int ret = 0;
120 
121 	switch (bank->bank_num) {
122 	case 0:
123 		*regmap = priv->regmap_pmu;
124 		if (pin_num > 24) {
125 			ret = -EINVAL;
126 		} else if (pin_num < 24) {
127 			*reg = RK3506_DRV_GPIO0_A_OFFSET;
128 		} else {
129 			*reg = RK3506_DRV_GPIO0_D_OFFSET;
130 			*bit = 3;
131 
132 			return 0;
133 		}
134 		break;
135 
136 	case 1:
137 		*regmap = priv->regmap_ioc1;
138 		if (pin_num < 28)
139 			*reg = RK3506_DRV_GPIO1_OFFSET;
140 		else
141 			ret = -EINVAL;
142 		break;
143 
144 	case 2:
145 		*regmap = priv->regmap_base;
146 		if (pin_num < 17)
147 			*reg = RK3506_DRV_GPIO2_OFFSET;
148 		else
149 			ret = -EINVAL;
150 		break;
151 
152 	case 3:
153 		*regmap = priv->regmap_base;
154 		if (pin_num < 15)
155 			*reg = RK3506_DRV_GPIO3_OFFSET;
156 		else
157 			ret = -EINVAL;
158 		break;
159 
160 	case 4:
161 		*regmap = priv->regmap_base;
162 		if (pin_num < 8 || pin_num > 11) {
163 			ret = -EINVAL;
164 		} else {
165 			*reg = RK3506_DRV_GPIO4_OFFSET;
166 			*bit = 10;
167 
168 			return 0;
169 		}
170 		break;
171 
172 	default:
173 		ret = -EINVAL;
174 		break;
175 	}
176 
177 	if (ret) {
178 		debug("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
179 
180 		return ret;
181 	}
182 
183 	*reg += ((pin_num / RK3506_DRV_PINS_PER_REG) * 4);
184 	*bit = pin_num % RK3506_DRV_PINS_PER_REG;
185 	*bit *= RK3506_DRV_BITS_PER_PIN;
186 
187 	return 0;
188 }
189 
rk3506_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)190 static int rk3506_set_drive(struct rockchip_pin_bank *bank,
191 			    int pin_num, int strength)
192 {
193 	struct regmap *regmap;
194 	int reg, ret, i;
195 	u32 data;
196 	u8 bit;
197 	int rmask_bits = RK3506_DRV_BITS_PER_PIN;
198 
199 	ret = rk3506_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
200 	if (ret)
201 		return ret;
202 
203 	for (i = 0, ret = 1; i < strength; i++)
204 		ret = (ret << 1) | 1;
205 
206 	if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) {
207 		rmask_bits = 2;
208 		ret = strength;
209 	}
210 
211 	/* enable the write to the equivalent lower bits */
212 	data = ((1 << rmask_bits) - 1) << (bit + 16);
213 	data |= (ret << bit);
214 	ret = regmap_write(regmap, reg, data);
215 
216 	return ret;
217 }
218 
219 #define RK3506_PULL_BITS_PER_PIN	2
220 #define RK3506_PULL_PINS_PER_REG	8
221 #define RK3506_PULL_GPIO0_A_OFFSET	0x200
222 #define RK3506_PULL_GPIO0_D_OFFSET	0x830
223 #define RK3506_PULL_GPIO1_OFFSET	0x210
224 #define RK3506_PULL_GPIO2_OFFSET	0x220
225 #define RK3506_PULL_GPIO3_OFFSET	0x230
226 #define RK3506_PULL_GPIO4_OFFSET	0x840
227 
rk3506_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)228 static int rk3506_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
229 					 int pin_num, struct regmap **regmap,
230 					 int *reg, u8 *bit)
231 {
232 	struct rockchip_pinctrl_priv *priv = bank->priv;
233 	int ret = 0;
234 
235 	switch (bank->bank_num) {
236 	case 0:
237 		*regmap = priv->regmap_pmu;
238 		if (pin_num > 24) {
239 			ret = -EINVAL;
240 		} else if (pin_num < 24) {
241 			*reg = RK3506_PULL_GPIO0_A_OFFSET;
242 		} else {
243 			*reg = RK3506_PULL_GPIO0_D_OFFSET;
244 			*bit = 5;
245 
246 			return 0;
247 		}
248 		break;
249 
250 	case 1:
251 		*regmap = priv->regmap_ioc1;
252 		if (pin_num < 28)
253 			*reg = RK3506_PULL_GPIO1_OFFSET;
254 		else
255 			ret = -EINVAL;
256 		break;
257 
258 	case 2:
259 		*regmap = priv->regmap_base;
260 		if (pin_num < 17)
261 			*reg = RK3506_PULL_GPIO2_OFFSET;
262 		else
263 			ret = -EINVAL;
264 		break;
265 
266 	case 3:
267 		*regmap = priv->regmap_base;
268 		if (pin_num < 15)
269 			*reg = RK3506_PULL_GPIO3_OFFSET;
270 		else
271 			ret = -EINVAL;
272 		break;
273 
274 	case 4:
275 		*regmap = priv->regmap_base;
276 		if (pin_num < 8 || pin_num > 11) {
277 			ret = -EINVAL;
278 		} else {
279 			*reg = RK3506_PULL_GPIO4_OFFSET;
280 			*bit = 13;
281 
282 			return 0;
283 		}
284 		break;
285 
286 	default:
287 		ret = -EINVAL;
288 		break;
289 	}
290 
291 	if (ret) {
292 		debug("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
293 
294 		return ret;
295 	}
296 
297 	*reg += ((pin_num / RK3506_PULL_PINS_PER_REG) * 4);
298 	*bit = pin_num % RK3506_PULL_PINS_PER_REG;
299 	*bit *= RK3506_PULL_BITS_PER_PIN;
300 
301 	return 0;
302 }
303 
rk3506_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)304 static int rk3506_set_pull(struct rockchip_pin_bank *bank,
305 			   int pin_num, int pull)
306 {
307 	struct regmap *regmap;
308 	int reg, ret;
309 	u8 bit, type;
310 	u32 data;
311 
312 	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
313 		return -ENOTSUPP;
314 
315 	ret = rk3506_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
316 	if (ret)
317 		return ret;
318 	type = bank->pull_type[pin_num / 8];
319 
320 	if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4)
321 		type = 1;
322 
323 	ret = rockchip_translate_pull_value(type, pull);
324 	if (ret < 0) {
325 		debug("unsupported pull setting %d\n", pull);
326 
327 		return ret;
328 	}
329 
330 	/* enable the write to the equivalent lower bits */
331 	data = ((1 << RK3506_PULL_BITS_PER_PIN) - 1) << (bit + 16);
332 
333 	data |= (ret << bit);
334 	ret = regmap_write(regmap, reg, data);
335 
336 	return ret;
337 }
338 
339 #define RK3506_SMT_BITS_PER_PIN		1
340 #define RK3506_SMT_PINS_PER_REG		8
341 #define RK3506_SMT_GPIO0_A_OFFSET	0x400
342 #define RK3506_SMT_GPIO0_D_OFFSET	0x830
343 #define RK3506_SMT_GPIO1_OFFSET		0x410
344 #define RK3506_SMT_GPIO2_OFFSET		0x420
345 #define RK3506_SMT_GPIO3_OFFSET		0x430
346 #define RK3506_SMT_GPIO4_OFFSET		0x840
347 
rk3506_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)348 static int rk3506_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
349 					   int pin_num,
350 					   struct regmap **regmap,
351 					   int *reg, u8 *bit)
352 {
353 	struct rockchip_pinctrl_priv *priv = bank->priv;
354 	int ret = 0;
355 
356 	switch (bank->bank_num) {
357 	case 0:
358 		*regmap = priv->regmap_pmu;
359 		if (pin_num > 24) {
360 			ret = -EINVAL;
361 		} else if (pin_num < 24) {
362 			*reg = RK3506_SMT_GPIO0_A_OFFSET;
363 		} else {
364 			*reg = RK3506_SMT_GPIO0_D_OFFSET;
365 			*bit = 9;
366 
367 			return 0;
368 		}
369 		break;
370 
371 	case 1:
372 		*regmap = priv->regmap_ioc1;
373 		if (pin_num < 28)
374 			*reg = RK3506_SMT_GPIO1_OFFSET;
375 		else
376 			ret = -EINVAL;
377 		break;
378 
379 	case 2:
380 		*regmap = priv->regmap_base;
381 		if (pin_num < 17)
382 			*reg = RK3506_SMT_GPIO2_OFFSET;
383 		else
384 			ret = -EINVAL;
385 		break;
386 
387 	case 3:
388 		*regmap = priv->regmap_base;
389 		if (pin_num < 15)
390 			*reg = RK3506_SMT_GPIO3_OFFSET;
391 		else
392 			ret = -EINVAL;
393 		break;
394 
395 	case 4:
396 		*regmap = priv->regmap_base;
397 		if (pin_num < 8 || pin_num > 11) {
398 			ret = -EINVAL;
399 		} else {
400 			*reg = RK3506_SMT_GPIO4_OFFSET;
401 			*bit = 8;
402 
403 			return 0;
404 		}
405 		break;
406 
407 	default:
408 		ret = -EINVAL;
409 		break;
410 	}
411 
412 	if (ret) {
413 		dev_err(priv->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
414 
415 		return ret;
416 	}
417 
418 	*reg += ((pin_num / RK3506_SMT_PINS_PER_REG) * 4);
419 	*bit = pin_num % RK3506_SMT_PINS_PER_REG;
420 	*bit *= RK3506_SMT_BITS_PER_PIN;
421 
422 	return 0;
423 }
424 
rk3506_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)425 static int rk3506_set_schmitt(struct rockchip_pin_bank *bank,
426 			      int pin_num, int enable)
427 {
428 	struct regmap *regmap;
429 	int reg, ret;
430 	u32 data;
431 	u8 bit;
432 
433 	ret = rk3506_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
434 	if (ret)
435 		return ret;
436 
437 	/* enable the write to the equivalent lower bits */
438 	data = ((1 << RK3506_SMT_BITS_PER_PIN) - 1) << (bit + 16);
439 	data |= (enable << bit);
440 
441 	if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) {
442 		data = 0x3 << (bit + 16);
443 		data |= ((enable ? 0x3 : 0) << bit);
444 	}
445 	ret = regmap_write(regmap, reg, data);
446 
447 	return ret;
448 }
449 
450 static struct rockchip_mux_recalced_data rk3506_mux_recalced_data[] = {
451 	{
452 		.num = 0,
453 		.pin = 24,
454 		.reg = 0x830,
455 		.bit = 0,
456 		.mask = 0x3
457 	},
458 };
459 
460 static struct rockchip_pin_bank rk3506_pin_banks[] = {
461 	PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0",
462 				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
463 				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
464 				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
465 				    IOMUX_8WIDTH_2BIT | IOMUX_SOURCE_PMU,
466 				    0x0, 0x8, 0x10, 0x830),
467 	PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1",
468 				    IOMUX_WIDTH_4BIT,
469 				    IOMUX_WIDTH_4BIT,
470 				    IOMUX_WIDTH_4BIT,
471 				    IOMUX_WIDTH_4BIT,
472 				    0x20, 0x28, 0x30, 0x38),
473 	PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2",
474 				    IOMUX_WIDTH_4BIT,
475 				    IOMUX_WIDTH_4BIT,
476 				    IOMUX_WIDTH_4BIT,
477 				    IOMUX_WIDTH_4BIT,
478 				    0x40, 0x48, 0x50, 0x58),
479 	PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3",
480 				    IOMUX_WIDTH_4BIT,
481 				    IOMUX_WIDTH_4BIT,
482 				    IOMUX_WIDTH_4BIT,
483 				    IOMUX_WIDTH_4BIT,
484 				    0x60, 0x68, 0x70, 0x78),
485 	PIN_BANK_IOMUX_FLAGS_OFFSET(4, 32, "gpio4",
486 				    IOMUX_WIDTH_4BIT,
487 				    IOMUX_WIDTH_4BIT,
488 				    IOMUX_WIDTH_4BIT,
489 				    IOMUX_WIDTH_4BIT,
490 				    0x80, 0x88, 0x90, 0x98),
491 };
492 
493 static const struct rockchip_pin_ctrl rk3506_pin_ctrl = {
494 	.pin_banks		= rk3506_pin_banks,
495 	.nr_banks		= ARRAY_SIZE(rk3506_pin_banks),
496 	.nr_pins		= 160,
497 	.iomux_recalced		= rk3506_mux_recalced_data,
498 	.niomux_recalced	= ARRAY_SIZE(rk3506_mux_recalced_data),
499 	.set_mux		= rk3506_set_mux,
500 	.set_pull		= rk3506_set_pull,
501 	.set_drive		= rk3506_set_drive,
502 	.set_schmitt		= rk3506_set_schmitt,
503 };
504 
505 static const struct udevice_id rk3506_pinctrl_ids[] = {
506 	{
507 		.compatible = "rockchip,rk3506-pinctrl",
508 		.data = (ulong)&rk3506_pin_ctrl
509 	},
510 	{ }
511 };
512 
513 U_BOOT_DRIVER(pinctrl_rk3506) = {
514 	.name		= "rockchip_rk3506_pinctrl",
515 	.id		= UCLASS_PINCTRL,
516 	.of_match	= rk3506_pinctrl_ids,
517 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
518 	.ops		= &rockchip_pinctrl_ops,
519 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
520 	.bind		= dm_scan_fdt_dev,
521 #endif
522 	.probe		= rockchip_pinctrl_probe,
523 };
524