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