xref: /rk3399_rockchip-uboot/drivers/pinctrl/rockchip/pinctrl-rv1126b.c (revision b653b9e8c171365ce437eb92a7c649c314d97973)
1*b653b9e8SYe Zhang // SPDX-License-Identifier: GPL-2.0+
2*b653b9e8SYe Zhang /*
3*b653b9e8SYe Zhang  * (C) Copyright 2025 Rockchip Electronics Co., Ltd
4*b653b9e8SYe Zhang  */
5*b653b9e8SYe Zhang 
6*b653b9e8SYe Zhang #include <common.h>
7*b653b9e8SYe Zhang #include <dm.h>
8*b653b9e8SYe Zhang #include <dm/pinctrl.h>
9*b653b9e8SYe Zhang #include <regmap.h>
10*b653b9e8SYe Zhang #include <syscon.h>
11*b653b9e8SYe Zhang 
12*b653b9e8SYe Zhang #include "pinctrl-rockchip.h"
13*b653b9e8SYe Zhang 
rv1126b_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)14*b653b9e8SYe Zhang static int rv1126b_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
15*b653b9e8SYe Zhang {
16*b653b9e8SYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
17*b653b9e8SYe Zhang 	int iomux_num = (pin / 8);
18*b653b9e8SYe Zhang 	struct regmap *regmap;
19*b653b9e8SYe Zhang 	int reg, ret, mask;
20*b653b9e8SYe Zhang 	u8 bit;
21*b653b9e8SYe Zhang 	u32 data;
22*b653b9e8SYe Zhang 
23*b653b9e8SYe Zhang 	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
24*b653b9e8SYe Zhang 
25*b653b9e8SYe Zhang 	regmap = priv->regmap_base;
26*b653b9e8SYe Zhang 	reg = bank->iomux[iomux_num].offset;
27*b653b9e8SYe Zhang 	if ((pin % 8) >= 4)
28*b653b9e8SYe Zhang 		reg += 0x4;
29*b653b9e8SYe Zhang 	bit = (pin % 4) * 4;
30*b653b9e8SYe Zhang 	mask = 0xf;
31*b653b9e8SYe Zhang 
32*b653b9e8SYe Zhang 	if (bank->recalced_mask & BIT(pin))
33*b653b9e8SYe Zhang 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
34*b653b9e8SYe Zhang 	data = (mask << (bit + 16));
35*b653b9e8SYe Zhang 	data |= (mux & mask) << bit;
36*b653b9e8SYe Zhang 
37*b653b9e8SYe Zhang 	debug("iomux write reg = %x data = %x\n", reg, data);
38*b653b9e8SYe Zhang 
39*b653b9e8SYe Zhang 	ret = regmap_write(regmap, reg, data);
40*b653b9e8SYe Zhang 
41*b653b9e8SYe Zhang 	return ret;
42*b653b9e8SYe Zhang }
43*b653b9e8SYe Zhang 
44*b653b9e8SYe Zhang #define RV1126B_DRV_BITS_PER_PIN		8
45*b653b9e8SYe Zhang #define RV1126B_DRV_PINS_PER_REG		2
46*b653b9e8SYe Zhang #define RV1126B_DRV_GPIO0_A_OFFSET		0x100
47*b653b9e8SYe Zhang #define RV1126B_DRV_GPIO0_C_OFFSET		0x8120
48*b653b9e8SYe Zhang #define RV1126B_DRV_GPIO_OFFSET(GPION)		(0x8100 + GPION * 0x8040)
49*b653b9e8SYe Zhang 
rv1126b_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)50*b653b9e8SYe Zhang static int rv1126b_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
51*b653b9e8SYe Zhang 				       int pin_num, struct regmap **regmap,
52*b653b9e8SYe Zhang 				       int *reg, u8 *bit)
53*b653b9e8SYe Zhang {
54*b653b9e8SYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
55*b653b9e8SYe Zhang 
56*b653b9e8SYe Zhang 	*regmap = priv->regmap_base;
57*b653b9e8SYe Zhang 	switch (bank->bank_num) {
58*b653b9e8SYe Zhang 	case 0:
59*b653b9e8SYe Zhang 		if (pin_num < 16)
60*b653b9e8SYe Zhang 			*reg = RV1126B_DRV_GPIO0_A_OFFSET;
61*b653b9e8SYe Zhang 		else
62*b653b9e8SYe Zhang 			*reg = RV1126B_DRV_GPIO0_C_OFFSET - 0x20;
63*b653b9e8SYe Zhang 		break;
64*b653b9e8SYe Zhang 
65*b653b9e8SYe Zhang 	case 1:
66*b653b9e8SYe Zhang 	case 2:
67*b653b9e8SYe Zhang 	case 3:
68*b653b9e8SYe Zhang 	case 4:
69*b653b9e8SYe Zhang 	case 5:
70*b653b9e8SYe Zhang 	case 6:
71*b653b9e8SYe Zhang 	case 7:
72*b653b9e8SYe Zhang 		*reg = RV1126B_DRV_GPIO_OFFSET(bank->bank_num);
73*b653b9e8SYe Zhang 		break;
74*b653b9e8SYe Zhang 
75*b653b9e8SYe Zhang 	default:
76*b653b9e8SYe Zhang 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
77*b653b9e8SYe Zhang 
78*b653b9e8SYe Zhang 		return -EINVAL;
79*b653b9e8SYe Zhang 	}
80*b653b9e8SYe Zhang 
81*b653b9e8SYe Zhang 	*reg += ((pin_num / RV1126B_DRV_PINS_PER_REG) * 4);
82*b653b9e8SYe Zhang 	*bit = pin_num % RV1126B_DRV_PINS_PER_REG;
83*b653b9e8SYe Zhang 	*bit *= RV1126B_DRV_BITS_PER_PIN;
84*b653b9e8SYe Zhang 
85*b653b9e8SYe Zhang 	return 0;
86*b653b9e8SYe Zhang }
87*b653b9e8SYe Zhang 
rv1126b_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)88*b653b9e8SYe Zhang static int rv1126b_set_drive(struct rockchip_pin_bank *bank,
89*b653b9e8SYe Zhang 			    int pin_num, int strength)
90*b653b9e8SYe Zhang {
91*b653b9e8SYe Zhang 	struct regmap *regmap;
92*b653b9e8SYe Zhang 	int reg, ret;
93*b653b9e8SYe Zhang 	u32 data;
94*b653b9e8SYe Zhang 	u8 bit;
95*b653b9e8SYe Zhang 	int rmask_bits = RV1126B_DRV_BITS_PER_PIN;
96*b653b9e8SYe Zhang 
97*b653b9e8SYe Zhang 	ret = rv1126b_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
98*b653b9e8SYe Zhang 	if (ret)
99*b653b9e8SYe Zhang 		return ret;
100*b653b9e8SYe Zhang 
101*b653b9e8SYe Zhang 	/* enable the write to the equivalent lower bits */
102*b653b9e8SYe Zhang 	data = ((1 << rmask_bits) - 1) << (bit + 16);
103*b653b9e8SYe Zhang 	ret = (1 << (strength + 1)) - 1;
104*b653b9e8SYe Zhang 	data |= (ret << bit);
105*b653b9e8SYe Zhang 	ret = regmap_write(regmap, reg, data);
106*b653b9e8SYe Zhang 
107*b653b9e8SYe Zhang 	return ret;
108*b653b9e8SYe Zhang }
109*b653b9e8SYe Zhang 
110*b653b9e8SYe Zhang #define RV1126B_PULL_BITS_PER_PIN		2
111*b653b9e8SYe Zhang #define RV1126B_PULL_PINS_PER_REG		8
112*b653b9e8SYe Zhang #define RV1126B_PULL_GPIO0_A_OFFSET		0x300
113*b653b9e8SYe Zhang #define RV1126B_PULL_GPIO0_C_OFFSET		0x8308
114*b653b9e8SYe Zhang #define RV1126B_PULL_GPIO_OFFSET(GPION)		(0x8300 + GPION * 0x8010)
115*b653b9e8SYe Zhang 
rv1126b_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)116*b653b9e8SYe Zhang static int rv1126b_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
117*b653b9e8SYe Zhang 					int pin_num, struct regmap **regmap,
118*b653b9e8SYe Zhang 					int *reg, u8 *bit)
119*b653b9e8SYe Zhang {
120*b653b9e8SYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
121*b653b9e8SYe Zhang 
122*b653b9e8SYe Zhang 	*regmap = priv->regmap_base;
123*b653b9e8SYe Zhang 	switch (bank->bank_num) {
124*b653b9e8SYe Zhang 	case 0:
125*b653b9e8SYe Zhang 		if (pin_num < 16)
126*b653b9e8SYe Zhang 			*reg = RV1126B_PULL_GPIO0_A_OFFSET;
127*b653b9e8SYe Zhang 		else
128*b653b9e8SYe Zhang 			*reg = RV1126B_PULL_GPIO0_C_OFFSET - 0x8;
129*b653b9e8SYe Zhang 		break;
130*b653b9e8SYe Zhang 
131*b653b9e8SYe Zhang 	case 1:
132*b653b9e8SYe Zhang 	case 2:
133*b653b9e8SYe Zhang 	case 3:
134*b653b9e8SYe Zhang 	case 4:
135*b653b9e8SYe Zhang 	case 5:
136*b653b9e8SYe Zhang 	case 6:
137*b653b9e8SYe Zhang 	case 7:
138*b653b9e8SYe Zhang 		*reg = RV1126B_PULL_GPIO_OFFSET(bank->bank_num);
139*b653b9e8SYe Zhang 		break;
140*b653b9e8SYe Zhang 
141*b653b9e8SYe Zhang 	default:
142*b653b9e8SYe Zhang 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
143*b653b9e8SYe Zhang 
144*b653b9e8SYe Zhang 		return -EINVAL;
145*b653b9e8SYe Zhang 	}
146*b653b9e8SYe Zhang 
147*b653b9e8SYe Zhang 	*reg += ((pin_num / RV1126B_PULL_PINS_PER_REG) * 4);
148*b653b9e8SYe Zhang 	*bit = pin_num % RV1126B_PULL_PINS_PER_REG;
149*b653b9e8SYe Zhang 	*bit *= RV1126B_PULL_BITS_PER_PIN;
150*b653b9e8SYe Zhang 
151*b653b9e8SYe Zhang 	return 0;
152*b653b9e8SYe Zhang }
153*b653b9e8SYe Zhang 
rv1126b_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)154*b653b9e8SYe Zhang static int rv1126b_set_pull(struct rockchip_pin_bank *bank,
155*b653b9e8SYe Zhang 			   int pin_num, int pull)
156*b653b9e8SYe Zhang {
157*b653b9e8SYe Zhang 	struct regmap *regmap;
158*b653b9e8SYe Zhang 	int reg, ret;
159*b653b9e8SYe Zhang 	u8 bit, type;
160*b653b9e8SYe Zhang 	u32 data;
161*b653b9e8SYe Zhang 
162*b653b9e8SYe Zhang 	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
163*b653b9e8SYe Zhang 		return -ENOTSUPP;
164*b653b9e8SYe Zhang 
165*b653b9e8SYe Zhang 	ret = rv1126b_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
166*b653b9e8SYe Zhang 	if (ret)
167*b653b9e8SYe Zhang 		return ret;
168*b653b9e8SYe Zhang 	type = bank->pull_type[pin_num / 8];
169*b653b9e8SYe Zhang 
170*b653b9e8SYe Zhang 	ret = rockchip_translate_pull_value(type, pull);
171*b653b9e8SYe Zhang 	if (ret < 0) {
172*b653b9e8SYe Zhang 		debug("unsupported pull setting %d\n", pull);
173*b653b9e8SYe Zhang 
174*b653b9e8SYe Zhang 		return ret;
175*b653b9e8SYe Zhang 	}
176*b653b9e8SYe Zhang 
177*b653b9e8SYe Zhang 	/* enable the write to the equivalent lower bits */
178*b653b9e8SYe Zhang 	data = ((1 << RV1126B_PULL_BITS_PER_PIN) - 1) << (bit + 16);
179*b653b9e8SYe Zhang 	data |= (ret << bit);
180*b653b9e8SYe Zhang 	ret = regmap_write(regmap, reg, data);
181*b653b9e8SYe Zhang 
182*b653b9e8SYe Zhang 	return ret;
183*b653b9e8SYe Zhang }
184*b653b9e8SYe Zhang 
185*b653b9e8SYe Zhang #define RV1126B_SMT_BITS_PER_PIN		1
186*b653b9e8SYe Zhang #define RV1126B_SMT_PINS_PER_REG		8
187*b653b9e8SYe Zhang #define RV1126B_SMT_GPIO0_A_OFFSET		0x500
188*b653b9e8SYe Zhang #define RV1126B_SMT_GPIO0_C_OFFSET		0x8508
189*b653b9e8SYe Zhang #define RV1126B_SMT_GPIO_OFFSET(GPION)		(0x8500 + GPION * 0x8010)
190*b653b9e8SYe Zhang 
rv1126b_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)191*b653b9e8SYe Zhang static int rv1126b_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
192*b653b9e8SYe Zhang 					   int pin_num,
193*b653b9e8SYe Zhang 					   struct regmap **regmap,
194*b653b9e8SYe Zhang 					   int *reg, u8 *bit)
195*b653b9e8SYe Zhang {
196*b653b9e8SYe Zhang 	struct rockchip_pinctrl_priv *priv = bank->priv;
197*b653b9e8SYe Zhang 
198*b653b9e8SYe Zhang 	*regmap = priv->regmap_base;
199*b653b9e8SYe Zhang 	switch (bank->bank_num) {
200*b653b9e8SYe Zhang 	case 0:
201*b653b9e8SYe Zhang 		if (pin_num < 16)
202*b653b9e8SYe Zhang 			*reg = RV1126B_SMT_GPIO0_A_OFFSET;
203*b653b9e8SYe Zhang 		else
204*b653b9e8SYe Zhang 			*reg = RV1126B_SMT_GPIO0_C_OFFSET - 0x8;
205*b653b9e8SYe Zhang 		break;
206*b653b9e8SYe Zhang 
207*b653b9e8SYe Zhang 	case 1:
208*b653b9e8SYe Zhang 	case 2:
209*b653b9e8SYe Zhang 	case 3:
210*b653b9e8SYe Zhang 	case 4:
211*b653b9e8SYe Zhang 	case 5:
212*b653b9e8SYe Zhang 	case 6:
213*b653b9e8SYe Zhang 	case 7:
214*b653b9e8SYe Zhang 		*reg = RV1126B_SMT_GPIO_OFFSET(bank->bank_num);
215*b653b9e8SYe Zhang 		break;
216*b653b9e8SYe Zhang 
217*b653b9e8SYe Zhang 	default:
218*b653b9e8SYe Zhang 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
219*b653b9e8SYe Zhang 		return -EINVAL;
220*b653b9e8SYe Zhang 	}
221*b653b9e8SYe Zhang 
222*b653b9e8SYe Zhang 	*reg += ((pin_num / RV1126B_SMT_PINS_PER_REG) * 4);
223*b653b9e8SYe Zhang 	*bit = pin_num % RV1126B_SMT_PINS_PER_REG;
224*b653b9e8SYe Zhang 	*bit *= RV1126B_SMT_BITS_PER_PIN;
225*b653b9e8SYe Zhang 
226*b653b9e8SYe Zhang 	return 0;
227*b653b9e8SYe Zhang }
228*b653b9e8SYe Zhang 
rv1126b_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)229*b653b9e8SYe Zhang static int rv1126b_set_schmitt(struct rockchip_pin_bank *bank,
230*b653b9e8SYe Zhang 			      int pin_num, int enable)
231*b653b9e8SYe Zhang {
232*b653b9e8SYe Zhang 	struct regmap *regmap;
233*b653b9e8SYe Zhang 	int reg, ret;
234*b653b9e8SYe Zhang 	u32 data;
235*b653b9e8SYe Zhang 	u8 bit;
236*b653b9e8SYe Zhang 
237*b653b9e8SYe Zhang 	ret = rv1126b_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
238*b653b9e8SYe Zhang 	if (ret)
239*b653b9e8SYe Zhang 		return ret;
240*b653b9e8SYe Zhang 
241*b653b9e8SYe Zhang 	/* enable the write to the equivalent lower bits */
242*b653b9e8SYe Zhang 	data = ((1 << RV1126B_SMT_BITS_PER_PIN) - 1) << (bit + 16);
243*b653b9e8SYe Zhang 	data |= (enable << bit);
244*b653b9e8SYe Zhang 	ret = regmap_write(regmap, reg, data);
245*b653b9e8SYe Zhang 
246*b653b9e8SYe Zhang 	return ret;
247*b653b9e8SYe Zhang }
248*b653b9e8SYe Zhang 
249*b653b9e8SYe Zhang static struct rockchip_pin_bank rv1126b_pin_banks[] = {
250*b653b9e8SYe Zhang 	PIN_BANK_IOMUX_4_OFFSET(0, 32, "gpio0",
251*b653b9e8SYe Zhang 				      0x0, 0x8, 0x8010, 0x8018),
252*b653b9e8SYe Zhang 	PIN_BANK_IOMUX_4_OFFSET(1, 32, "gpio1",
253*b653b9e8SYe Zhang 				      0x10020, 0x10028, 0x10030, 0x10038),
254*b653b9e8SYe Zhang 	PIN_BANK_IOMUX_4_OFFSET(2, 32, "gpio2",
255*b653b9e8SYe Zhang 				      0x18040, 0x18048, 0x18050, 0x18058),
256*b653b9e8SYe Zhang 	PIN_BANK_IOMUX_4_OFFSET(3, 32, "gpio3",
257*b653b9e8SYe Zhang 				      0x20060, 0x20068, 0x20070, 0x20078),
258*b653b9e8SYe Zhang 	PIN_BANK_IOMUX_4_OFFSET(4, 32, "gpio4",
259*b653b9e8SYe Zhang 				      0x28080, 0x28088, 0x28090, 0x28098),
260*b653b9e8SYe Zhang 	PIN_BANK_IOMUX_4_OFFSET(5, 32, "gpio5",
261*b653b9e8SYe Zhang 				      0x300a0, 0x300a8, 0x300b0, 0x300b8),
262*b653b9e8SYe Zhang 	PIN_BANK_IOMUX_4_OFFSET(6, 32, "gpio6",
263*b653b9e8SYe Zhang 				      0x380c0, 0x380c8, 0x380d0, 0x380d8),
264*b653b9e8SYe Zhang 	PIN_BANK_IOMUX_4_OFFSET(7, 32, "gpio7",
265*b653b9e8SYe Zhang 				      0x400e0, 0x400e8, 0x400f0, 0x400f8),
266*b653b9e8SYe Zhang };
267*b653b9e8SYe Zhang static struct rockchip_pin_ctrl rv1126b_pin_ctrl __maybe_unused = {
268*b653b9e8SYe Zhang 	.pin_banks		= rv1126b_pin_banks,
269*b653b9e8SYe Zhang 	.nr_banks		= ARRAY_SIZE(rv1126b_pin_banks),
270*b653b9e8SYe Zhang 	.nr_pins		= 256,
271*b653b9e8SYe Zhang 	.set_mux		= rv1126b_set_mux,
272*b653b9e8SYe Zhang 	.set_pull		= rv1126b_set_pull,
273*b653b9e8SYe Zhang 	.set_drive		= rv1126b_set_drive,
274*b653b9e8SYe Zhang 	.set_schmitt		= rv1126b_set_schmitt,
275*b653b9e8SYe Zhang };
276*b653b9e8SYe Zhang 
277*b653b9e8SYe Zhang static const struct udevice_id rv1126b_pinctrl_ids[] = {
278*b653b9e8SYe Zhang 	{
279*b653b9e8SYe Zhang 		.compatible = "rockchip,rv1126b-pinctrl",
280*b653b9e8SYe Zhang 		.data = (ulong)&rv1126b_pin_ctrl
281*b653b9e8SYe Zhang 	},
282*b653b9e8SYe Zhang 	{ }
283*b653b9e8SYe Zhang };
284*b653b9e8SYe Zhang 
285*b653b9e8SYe Zhang U_BOOT_DRIVER(pinctrl_rv1126b) = {
286*b653b9e8SYe Zhang 	.name		= "rockchip_rv1126b_pinctrl",
287*b653b9e8SYe Zhang 	.id		= UCLASS_PINCTRL,
288*b653b9e8SYe Zhang 	.of_match	= rv1126b_pinctrl_ids,
289*b653b9e8SYe Zhang 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
290*b653b9e8SYe Zhang 	.ops		= &rockchip_pinctrl_ops,
291*b653b9e8SYe Zhang #if !CONFIG_IS_ENABLED(OF_PLATDATA)
292*b653b9e8SYe Zhang 	.bind		= dm_scan_fdt_dev,
293*b653b9e8SYe Zhang #endif
294*b653b9e8SYe Zhang 	.probe		= rockchip_pinctrl_probe,
295*b653b9e8SYe Zhang };
296