1122394Sharti// SPDX-License-Identifier: GPL-2.0+
2122394Sharti/*
3122394Sharti * (C) Copyright 2021 Rockchip Electronics Co., Ltd
4122394Sharti */
5122394Sharti
6122394Sharti#include <common.h>
7310903Sngie#include <dm.h>
8133211Sharti#include <dm/pinctrl.h>
9133211Sharti#include <regmap.h>
10133211Sharti#include <syscon.h>
11133211Sharti
12133211Sharti#include "pinctrl-rockchip.h"
13122394Sharti#include <dt-bindings/pinctrl/rockchip.h>
14122394Sharti
15122394Shartistatic int rk3588_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
16310903Sngie{
17133211Sharti	struct rockchip_pinctrl_priv *priv = bank->priv;
18133211Sharti	struct regmap *regmap;
19133211Sharti	int iomux_num = (pin / 8);
20133211Sharti	int reg, ret, mask;
21133211Sharti	u8 bit;
22133211Sharti	u32 data;
23133211Sharti
24133211Sharti	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
25133211Sharti
26133211Sharti	regmap = priv->regmap_base;
27133211Sharti	reg = bank->iomux[iomux_num].offset;
28122394Sharti	if ((pin % 8) >= 4)
29156066Sharti		reg += 0x4;
30122394Sharti	bit = (pin % 4) * 4;
31122394Sharti	mask = 0xf;
32122394Sharti
33122394Sharti	if (bank->bank_num == 0) {
34122394Sharti		if (pin >= RK_PB4 && pin <= RK_PD7) {
35122394Sharti			if (mux < 8) {
36122394Sharti				reg += 0x4000 - 0xC; /* PMU2_IOC_BASE */
37122394Sharti				data = (mask << (bit + 16));
38122394Sharti				data |= (mux & mask) << bit;
39122394Sharti				ret = regmap_write(regmap, reg, data);
40122394Sharti			} else {
41122394Sharti				u32 reg0 = 0;
42122394Sharti
43122394Sharti				reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */
44133211Sharti				data = (mask << (bit + 16));
45122394Sharti				data |= 8 << bit;
46122394Sharti				ret = regmap_write(regmap, reg0, data);
47122394Sharti
48122394Sharti				reg0 = reg + 0x8000; /* BUS_IOC_BASE */
49133211Sharti				data = (mask << (bit + 16));
50122394Sharti				data |= mux << bit;
51122394Sharti				regmap = priv->regmap_base;
52122394Sharti				regmap_write(regmap, reg0, data);
53122394Sharti			}
54122394Sharti		} else {
55122394Sharti			data = (mask << (bit + 16));
56122394Sharti			data |= (mux & mask) << bit;
57122394Sharti			ret = regmap_write(regmap, reg, data);
58122394Sharti		}
59122394Sharti		return ret;
60122394Sharti	} else if (bank->bank_num > 0) {
61122394Sharti		reg += 0x8000; /* BUS_IOC_BASE */
62122394Sharti	}
63122394Sharti
64122394Sharti	data = (mask << (bit + 16));
65122394Sharti	data |= (mux & mask) << bit;
66122394Sharti
67122394Sharti	return regmap_write(regmap, reg, data);
68122394Sharti}
69122394Sharti
70122394Sharti#define RK3588_PMU1_IOC_REG		(0x0000)
71122394Sharti#define RK3588_PMU2_IOC_REG		(0x4000)
72122394Sharti#define RK3588_BUS_IOC_REG		(0x8000)
73122394Sharti#define RK3588_VCCIO1_4_IOC_REG		(0x9000)
74122394Sharti#define RK3588_VCCIO3_5_IOC_REG		(0xA000)
75122394Sharti#define RK3588_VCCIO2_IOC_REG		(0xB000)
76122394Sharti#define RK3588_VCCIO6_IOC_REG		(0xC000)
77122394Sharti#define RK3588_EMMC_IOC_REG		(0xD000)
78122394Sharti
79122394Shartistatic const u32 rk3588_ds_regs[][2] = {
80312089Sngie	{RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0010},
81122394Sharti	{RK_GPIO0_A4, RK3588_PMU1_IOC_REG + 0x0014},
82122394Sharti	{RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0018},
83122394Sharti	{RK_GPIO0_B4, RK3588_PMU2_IOC_REG + 0x0014},
84122394Sharti	{RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0018},
85122394Sharti	{RK_GPIO0_C4, RK3588_PMU2_IOC_REG + 0x001C},
86122394Sharti	{RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0020},
87122394Sharti	{RK_GPIO0_D4, RK3588_PMU2_IOC_REG + 0x0024},
88122394Sharti	{RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0020},
89122394Sharti	{RK_GPIO1_A4, RK3588_VCCIO1_4_IOC_REG + 0x0024},
90122394Sharti	{RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0028},
91122394Sharti	{RK_GPIO1_B4, RK3588_VCCIO1_4_IOC_REG + 0x002C},
92122394Sharti	{RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0030},
93122394Sharti	{RK_GPIO1_C4, RK3588_VCCIO1_4_IOC_REG + 0x0034},
94122394Sharti	{RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x0038},
95122394Sharti	{RK_GPIO1_D4, RK3588_VCCIO1_4_IOC_REG + 0x003C},
96122394Sharti	{RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0040},
97122394Sharti	{RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0044},
98312089Sngie	{RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0048},
99122394Sharti	{RK_GPIO2_B4, RK3588_VCCIO3_5_IOC_REG + 0x004C},
100122394Sharti	{RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0050},
101122394Sharti	{RK_GPIO2_C4, RK3588_VCCIO3_5_IOC_REG + 0x0054},
102122394Sharti	{RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x0058},
103122394Sharti	{RK_GPIO2_D4, RK3588_EMMC_IOC_REG + 0x005C},
104122394Sharti	{RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0060},
105122394Sharti	{RK_GPIO3_A4, RK3588_VCCIO3_5_IOC_REG + 0x0064},
106122394Sharti	{RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0068},
107122394Sharti	{RK_GPIO3_B4, RK3588_VCCIO3_5_IOC_REG + 0x006C},
108122394Sharti	{RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0070},
109122394Sharti	{RK_GPIO3_C4, RK3588_VCCIO3_5_IOC_REG + 0x0074},
110122394Sharti	{RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x0078},
111122394Sharti	{RK_GPIO3_D4, RK3588_VCCIO3_5_IOC_REG + 0x007C},
112122394Sharti	{RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0080},
113122394Sharti	{RK_GPIO4_A4, RK3588_VCCIO6_IOC_REG + 0x0084},
114122394Sharti	{RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0088},
115122394Sharti	{RK_GPIO4_B4, RK3588_VCCIO6_IOC_REG + 0x008C},
116122394Sharti	{RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0090},
117122394Sharti	{RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0090},
118122394Sharti	{RK_GPIO4_C4, RK3588_VCCIO3_5_IOC_REG + 0x0094},
119312089Sngie	{RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x0098},
120122394Sharti	{RK_GPIO4_D4, RK3588_VCCIO2_IOC_REG + 0x009C},
121122394Sharti};
122122394Sharti
123122394Shartistatic const u32 rk3588_p_regs[][2] = {
124122394Sharti	{RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0020},
125122394Sharti	{RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0024},
126122394Sharti	{RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0028},
127122394Sharti	{RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x002C},
128122394Sharti	{RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0030},
129122394Sharti	{RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0110},
130122394Sharti	{RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0114},
131128237Sharti	{RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0118},
132128237Sharti	{RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x011C},
133128237Sharti	{RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0120},
134122394Sharti	{RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0120},
135122394Sharti	{RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0124},
136122394Sharti	{RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0128},
137122394Sharti	{RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x012C},
138146525Sharti	{RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0130},
139146525Sharti	{RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0134},
140146525Sharti	{RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0138},
141146525Sharti	{RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x013C},
142133211Sharti	{RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0140},
143122394Sharti	{RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0144},
144122394Sharti	{RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0148},
145146525Sharti	{RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0148},
146122394Sharti	{RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x014C},
147122394Sharti};
148146525Sharti
149122394Shartistatic const u32 rk3588_smt_regs[][2] = {
150122394Sharti	{RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0030},
151122394Sharti	{RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0034},
152122394Sharti	{RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0040},
153122394Sharti	{RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0044},
154122394Sharti	{RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0048},
155122394Sharti	{RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0210},
156122394Sharti	{RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0214},
157122394Sharti	{RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0218},
158122394Sharti	{RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x021C},
159122394Sharti	{RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0220},
160122394Sharti	{RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0220},
161122394Sharti	{RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0224},
162122394Sharti	{RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0228},
163122394Sharti	{RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x022C},
164122394Sharti	{RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0230},
165122394Sharti	{RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0234},
166122394Sharti	{RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0238},
167122394Sharti	{RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x023C},
168122394Sharti	{RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0240},
169122394Sharti	{RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0244},
170122394Sharti	{RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0248},
171122394Sharti	{RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0248},
172122394Sharti	{RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x024C},
173122394Sharti};
174122394Sharti
175122394Sharti#define RK3588_PULL_BITS_PER_PIN		2
176122394Sharti#define RK3588_PULL_PINS_PER_REG		8
177122394Sharti
178122394Shartistatic void rk3588_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
179122394Sharti					 int pin_num, struct regmap **regmap,
180122394Sharti					 int *reg, u8 *bit)
181122394Sharti{
182122394Sharti	struct rockchip_pinctrl_priv *info = bank->priv;
183122394Sharti	u8 bank_num = bank->bank_num;
184122394Sharti	u32 pin = bank_num * 32 + pin_num;
185122394Sharti	int i;
186122394Sharti
187122394Sharti	for (i = ARRAY_SIZE(rk3588_p_regs) - 1; i >= 0; i--) {
188122394Sharti		if (pin >= rk3588_p_regs[i][0]) {
189122394Sharti			*reg = rk3588_p_regs[i][1];
190122394Sharti			break;
191122394Sharti		}
192122394Sharti	}
193122394Sharti
194122394Sharti	assert(i >= 0);
195122394Sharti
196122394Sharti	*regmap = info->regmap_base;
197122394Sharti	*bit = pin_num % RK3588_PULL_PINS_PER_REG;
198122394Sharti	*bit *= RK3588_PULL_BITS_PER_PIN;
199122394Sharti}
200122394Sharti
201122394Sharti#define RK3588_DRV_BITS_PER_PIN		4
202122394Sharti#define RK3588_DRV_PINS_PER_REG		4
203122394Sharti
204122394Shartistatic void rk3588_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
205122394Sharti					int pin_num, struct regmap **regmap,
206122394Sharti					int *reg, u8 *bit)
207122394Sharti{
208122394Sharti	struct rockchip_pinctrl_priv *info = bank->priv;
209122394Sharti	u8 bank_num = bank->bank_num;
210122394Sharti	u32 pin = bank_num * 32 + pin_num;
211122394Sharti	int i;
212122394Sharti
213122394Sharti	for (i = ARRAY_SIZE(rk3588_ds_regs) - 1; i >= 0; i--) {
214122394Sharti		if (pin >= rk3588_ds_regs[i][0]) {
215122394Sharti			*reg = rk3588_ds_regs[i][1];
216122394Sharti			break;
217122394Sharti		}
218122394Sharti	}
219122394Sharti
220122394Sharti	assert(i >= 0);
221122394Sharti
222122394Sharti	*regmap = info->regmap_base;
223122394Sharti	*bit = pin_num % RK3588_DRV_PINS_PER_REG;
224122394Sharti	*bit *= RK3588_DRV_BITS_PER_PIN;
225122394Sharti}
226122394Sharti
227122394Sharti#define RK3588_SMT_BITS_PER_PIN		1
228122394Sharti#define RK3588_SMT_PINS_PER_REG		8
229122394Sharti
230122394Shartistatic int rk3588_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
231122394Sharti					   int pin_num, struct regmap **regmap,
232122394Sharti					   int *reg, u8 *bit)
233122394Sharti{
234122394Sharti	struct rockchip_pinctrl_priv *info = bank->priv;
235122394Sharti	u8 bank_num = bank->bank_num;
236122394Sharti	u32 pin = bank_num * 32 + pin_num;
237122394Sharti	int i;
238122394Sharti
239122394Sharti	for (i = ARRAY_SIZE(rk3588_smt_regs) - 1; i >= 0; i--) {
240122394Sharti		if (pin >= rk3588_smt_regs[i][0]) {
241122394Sharti			*reg = rk3588_smt_regs[i][1];
242122394Sharti			break;
243122394Sharti		}
244122394Sharti	}
245122394Sharti
246122394Sharti	assert(i >= 0);
247122394Sharti
248122394Sharti	*regmap = info->regmap_base;
249122394Sharti	*bit = pin_num % RK3588_SMT_PINS_PER_REG;
250122394Sharti	*bit *= RK3588_SMT_BITS_PER_PIN;
251122394Sharti
252122394Sharti	return 0;
253122394Sharti}
254122394Sharti
255122394Shartistatic int rk3588_set_pull(struct rockchip_pin_bank *bank,
256122394Sharti			   int pin_num, int pull)
257122394Sharti{
258122394Sharti	struct regmap *regmap;
259122394Sharti	int reg, translated_pull;
260122394Sharti	u8 bit, type;
261122394Sharti	u32 data;
262122394Sharti
263122394Sharti	rk3588_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
264122394Sharti	type = bank->pull_type[pin_num / 8];
265122394Sharti	translated_pull = rockchip_translate_pull_value(type, pull);
266122394Sharti	if (translated_pull < 0) {
267122394Sharti		debug("unsupported pull setting %d\n", pull);
268122394Sharti		return -EINVAL;
269122394Sharti	}
270122394Sharti
271122394Sharti	/* enable the write to the equivalent lower bits */
272122394Sharti	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
273122394Sharti	data |= (translated_pull << bit);
274122394Sharti
275122394Sharti	return regmap_write(regmap, reg, data);
276122394Sharti}
277122394Sharti
278122394Shartistatic int rk3588_set_drive(struct rockchip_pin_bank *bank,
279122394Sharti			    int pin_num, int strength)
280122394Sharti{
281122394Sharti	struct regmap *regmap;
282122394Sharti	int reg;
283151970Sharti	u32 data;
284151970Sharti	u8 bit;
285151970Sharti
286151970Sharti	rk3588_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
287151970Sharti
288151970Sharti	/* enable the write to the equivalent lower bits */
289151970Sharti	data = ((1 << RK3588_DRV_BITS_PER_PIN) - 1) << (bit + 16);
290151970Sharti	data |= (strength << bit);
291151970Sharti
292221373Sru	return regmap_write(regmap, reg, data);
293151970Sharti}
294151970Sharti
295151970Shartistatic int rk3588_set_schmitt(struct rockchip_pin_bank *bank,
296151970Sharti			      int pin_num, int enable)
297151970Sharti{
298122394Sharti	struct regmap *regmap;
299122394Sharti	int reg;
300122394Sharti	u32 data;
301122394Sharti	u8 bit;
302122394Sharti
303122394Sharti	rk3588_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
304122394Sharti
305122394Sharti	/* enable the write to the equivalent lower bits */
306122394Sharti	data = ((1 << RK3588_SMT_BITS_PER_PIN) - 1) << (bit + 16);
307122394Sharti	data |= (enable << bit);
308122394Sharti
309122394Sharti	return regmap_write(regmap, reg, data);
310122394Sharti}
311122394Sharti
312122394Shartistatic struct rockchip_pin_bank rk3588_pin_banks[] = {
313122394Sharti	RK3588_PIN_BANK_FLAGS(0, 32, "gpio0",
314122394Sharti			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
315122394Sharti	RK3588_PIN_BANK_FLAGS(1, 32, "gpio1",
316122394Sharti			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
317122394Sharti	RK3588_PIN_BANK_FLAGS(2, 32, "gpio2",
318122394Sharti			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
319122394Sharti	RK3588_PIN_BANK_FLAGS(3, 32, "gpio3",
320122394Sharti			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
321122394Sharti	RK3588_PIN_BANK_FLAGS(4, 32, "gpio4",
322122394Sharti			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
323122394Sharti};
324122394Sharti
325122394Shartistatic const struct rockchip_pin_ctrl rk3588_pin_ctrl = {
326122394Sharti	.pin_banks		= rk3588_pin_banks,
327122394Sharti	.nr_banks		= ARRAY_SIZE(rk3588_pin_banks),
328122394Sharti	.nr_pins		= 160,
329122394Sharti	.set_mux		= rk3588_set_mux,
330122394Sharti	.set_pull		= rk3588_set_pull,
331122394Sharti	.set_drive		= rk3588_set_drive,
332122394Sharti	.set_schmitt		= rk3588_set_schmitt,
333122394Sharti};
334122394Sharti
335122394Shartistatic const struct udevice_id rk3588_pinctrl_ids[] = {
336122394Sharti	{
337122394Sharti		.compatible = "rockchip,rk3588-pinctrl",
338122394Sharti		.data = (ulong)&rk3588_pin_ctrl
339122394Sharti	},
340122394Sharti	{ }
341122394Sharti};
342122394Sharti
343122394ShartiU_BOOT_DRIVER(pinctrl_rk3588) = {
344122394Sharti	.name		= "rockchip_rk3588_pinctrl",
345122394Sharti	.id		= UCLASS_PINCTRL,
346122394Sharti	.of_match	= rk3588_pinctrl_ids,
347122394Sharti	.priv_auto	= sizeof(struct rockchip_pinctrl_priv),
348122394Sharti	.ops		= &rockchip_pinctrl_ops,
349122394Sharti#if CONFIG_IS_ENABLED(OF_REAL)
350122394Sharti	.bind		= dm_scan_fdt_dev,
351122394Sharti#endif
352122394Sharti	.probe		= rockchip_pinctrl_probe,
353122394Sharti};
354122394Sharti