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 <log.h>
9#include <dm/pinctrl.h>
10#include <regmap.h>
11#include <syscon.h>
12#include <linux/bitops.h>
13
14#include "pinctrl-rockchip.h"
15
16static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
17	{
18		/* uart2dbga_rx */
19		.bank_num = 4,
20		.pin = 8,
21		.func = 2,
22		.route_offset = 0xe21c,
23		.route_val = BIT(16 + 10) | BIT(16 + 11),
24	}, {
25		/* uart2dbgb_rx */
26		.bank_num = 4,
27		.pin = 16,
28		.func = 2,
29		.route_offset = 0xe21c,
30		.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
31	}, {
32		/* uart2dbgc_rx */
33		.bank_num = 4,
34		.pin = 19,
35		.func = 1,
36		.route_offset = 0xe21c,
37		.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
38	}, {
39		/* pcie_clkreqn */
40		.bank_num = 2,
41		.pin = 26,
42		.func = 2,
43		.route_offset = 0xe21c,
44		.route_val = BIT(16 + 14),
45	}, {
46		/* pcie_clkreqnb */
47		.bank_num = 4,
48		.pin = 24,
49		.func = 1,
50		.route_offset = 0xe21c,
51		.route_val = BIT(16 + 14) | BIT(14),
52	},
53};
54
55static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
56{
57	struct rockchip_pinctrl_priv *priv = bank->priv;
58	int iomux_num = (pin / 8);
59	struct regmap *regmap;
60	int reg, ret, mask, mux_type;
61	u8 bit;
62	u32 data;
63
64	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
65				? priv->regmap_pmu : priv->regmap_base;
66
67	/* get basic quadrupel of mux registers and the correct reg inside */
68	mux_type = bank->iomux[iomux_num].type;
69	reg = bank->iomux[iomux_num].offset;
70	reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
71
72	data = (mask << (bit + 16));
73	data |= (mux & mask) << bit;
74	ret = regmap_write(regmap, reg, data);
75
76	return ret;
77}
78
79#define RK3399_PULL_GRF_OFFSET		0xe040
80#define RK3399_PULL_PMU_OFFSET		0x40
81
82static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
83					 int pin_num, struct regmap **regmap,
84					 int *reg, u8 *bit)
85{
86	struct rockchip_pinctrl_priv *priv = bank->priv;
87
88	/* The bank0:16 and bank1:32 pins are located in PMU */
89	if (bank->bank_num == 0 || bank->bank_num == 1) {
90		*regmap = priv->regmap_pmu;
91		*reg = RK3399_PULL_PMU_OFFSET;
92
93		*reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
94	} else {
95		*regmap = priv->regmap_base;
96		*reg = RK3399_PULL_GRF_OFFSET;
97
98		/* correct the offset, as we're starting with the 3rd bank */
99		*reg -= 0x20;
100		*reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
101	}
102
103	*reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
104
105	*bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
106	*bit *= ROCKCHIP_PULL_BITS_PER_PIN;
107}
108
109static int rk3399_set_pull(struct rockchip_pin_bank *bank,
110			   int pin_num, int pull)
111{
112	struct regmap *regmap;
113	int reg, ret;
114	u8 bit, type;
115	u32 data;
116
117	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
118		return -ENOTSUPP;
119
120	rk3399_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
121	type = bank->pull_type[pin_num / 8];
122	ret = rockchip_translate_pull_value(type, pull);
123	if (ret < 0) {
124		debug("unsupported pull setting %d\n", pull);
125		return ret;
126	}
127
128	/* enable the write to the equivalent lower bits */
129	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
130	data |= (ret << bit);
131	ret = regmap_write(regmap, reg, data);
132
133	return ret;
134}
135
136static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
137					int pin_num, struct regmap **regmap,
138					int *reg, u8 *bit)
139{
140	struct rockchip_pinctrl_priv *priv = bank->priv;
141	int drv_num = (pin_num / 8);
142
143	/*  The bank0:16 and bank1:32 pins are located in PMU */
144	if (bank->bank_num == 0 || bank->bank_num == 1)
145		*regmap = priv->regmap_pmu;
146	else
147		*regmap = priv->regmap_base;
148
149	*reg = bank->drv[drv_num].offset;
150	if (bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO ||
151	    bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY)
152		*bit = (pin_num % 8) * 3;
153	else
154		*bit = (pin_num % 8) * 2;
155}
156
157static int rk3399_set_drive(struct rockchip_pin_bank *bank,
158			    int pin_num, int strength)
159{
160	struct regmap *regmap;
161	int reg, ret;
162	u32 data, rmask_bits, temp;
163	u8 bit;
164	int drv_type = bank->drv[pin_num / 8].drv_type;
165
166	rk3399_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
167	ret = rockchip_translate_drive_value(drv_type, strength);
168	if (ret < 0) {
169		debug("unsupported driver strength %d\n", strength);
170		return ret;
171	}
172
173	switch (drv_type) {
174	case DRV_TYPE_IO_1V8_3V0_AUTO:
175	case DRV_TYPE_IO_3V3_ONLY:
176		rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
177		switch (bit) {
178		case 0 ... 12:
179			/* regular case, nothing to do */
180			break;
181		case 15:
182			/*
183			 * drive-strength offset is special, as it is spread
184			 * over 2 registers, the bit data[15] contains bit 0
185			 * of the value while temp[1:0] contains bits 2 and 1
186			 */
187			data = (ret & 0x1) << 15;
188			temp = (ret >> 0x1) & 0x3;
189
190			data |= BIT(31);
191			ret = regmap_write(regmap, reg, data);
192			if (ret)
193				return ret;
194
195			temp |= (0x3 << 16);
196			reg += 0x4;
197			ret = regmap_write(regmap, reg, temp);
198
199			return ret;
200		case 18 ... 21:
201			/* setting fully enclosed in the second register */
202			reg += 4;
203			bit -= 16;
204			break;
205		default:
206			debug("unsupported bit: %d for pinctrl drive type: %d\n",
207			      bit, drv_type);
208			return -EINVAL;
209		}
210		break;
211	case DRV_TYPE_IO_DEFAULT:
212	case DRV_TYPE_IO_1V8_OR_3V0:
213	case DRV_TYPE_IO_1V8_ONLY:
214		rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
215		break;
216	default:
217		debug("unsupported pinctrl drive type: %d\n",
218		      drv_type);
219		return -EINVAL;
220	}
221
222	/* enable the write to the equivalent lower bits */
223	data = ((1 << rmask_bits) - 1) << (bit + 16);
224	data |= (ret << bit);
225	ret = regmap_write(regmap, reg, data);
226
227	return ret;
228}
229
230static struct rockchip_pin_bank rk3399_pin_banks[] = {
231	PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0",
232							 IOMUX_SOURCE_PMU,
233							 IOMUX_SOURCE_PMU,
234							 IOMUX_SOURCE_PMU,
235							 IOMUX_SOURCE_PMU,
236							 DRV_TYPE_IO_1V8_ONLY,
237							 DRV_TYPE_IO_1V8_ONLY,
238							 DRV_TYPE_IO_DEFAULT,
239							 DRV_TYPE_IO_DEFAULT,
240							 0x80,
241							 0x88,
242							 -1,
243							 -1,
244							 PULL_TYPE_IO_1V8_ONLY,
245							 PULL_TYPE_IO_1V8_ONLY,
246							 PULL_TYPE_IO_DEFAULT,
247							 PULL_TYPE_IO_DEFAULT
248							),
249	PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
250					IOMUX_SOURCE_PMU,
251					IOMUX_SOURCE_PMU,
252					IOMUX_SOURCE_PMU,
253					DRV_TYPE_IO_1V8_OR_3V0,
254					DRV_TYPE_IO_1V8_OR_3V0,
255					DRV_TYPE_IO_1V8_OR_3V0,
256					DRV_TYPE_IO_1V8_OR_3V0,
257					0xa0,
258					0xa8,
259					0xb0,
260					0xb8
261					),
262	PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
263				      DRV_TYPE_IO_1V8_OR_3V0,
264				      DRV_TYPE_IO_1V8_ONLY,
265				      DRV_TYPE_IO_1V8_ONLY,
266				      PULL_TYPE_IO_DEFAULT,
267				      PULL_TYPE_IO_DEFAULT,
268				      PULL_TYPE_IO_1V8_ONLY,
269				      PULL_TYPE_IO_1V8_ONLY
270				      ),
271	PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
272			   DRV_TYPE_IO_3V3_ONLY,
273			   DRV_TYPE_IO_3V3_ONLY,
274			   DRV_TYPE_IO_1V8_OR_3V0
275			   ),
276	PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0,
277			   DRV_TYPE_IO_1V8_3V0_AUTO,
278			   DRV_TYPE_IO_1V8_OR_3V0,
279			   DRV_TYPE_IO_1V8_OR_3V0
280			   ),
281};
282
283static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
284	.pin_banks		= rk3399_pin_banks,
285	.nr_banks		= ARRAY_SIZE(rk3399_pin_banks),
286	.grf_mux_offset		= 0xe000,
287	.pmu_mux_offset		= 0x0,
288	.grf_drv_offset		= 0xe100,
289	.pmu_drv_offset		= 0x80,
290	.iomux_routes		= rk3399_mux_route_data,
291	.niomux_routes		= ARRAY_SIZE(rk3399_mux_route_data),
292	.set_mux		= rk3399_set_mux,
293	.set_pull		= rk3399_set_pull,
294	.set_drive		= rk3399_set_drive,
295};
296
297static const struct udevice_id rk3399_pinctrl_ids[] = {
298	{
299		.compatible = "rockchip,rk3399-pinctrl",
300		.data = (ulong)&rk3399_pin_ctrl
301	},
302	{ }
303};
304
305U_BOOT_DRIVER(pinctrl_rk3399) = {
306	.name		= "rockchip_rk3399_pinctrl",
307	.id		= UCLASS_PINCTRL,
308	.of_match	= rk3399_pinctrl_ids,
309	.priv_auto	= sizeof(struct rockchip_pinctrl_priv),
310	.ops		= &rockchip_pinctrl_ops,
311#if CONFIG_IS_ENABLED(OF_REAL)
312	.bind		= dm_scan_fdt_dev,
313#endif
314	.probe		= rockchip_pinctrl_probe,
315};
316