xref: /rk3399_rockchip-uboot/drivers/pinctrl/rockchip/pinctrl-rk3576.c (revision f11557654b890b08c3f8f18d042f36a4ac17447f)
1*f1155765SSteven Liu // SPDX-License-Identifier: GPL-2.0+
2*f1155765SSteven Liu /*
3*f1155765SSteven Liu  * (C) Copyright 2024 Rockchip Electronics Co., Ltd
4*f1155765SSteven Liu  */
5*f1155765SSteven Liu 
6*f1155765SSteven Liu #include <common.h>
7*f1155765SSteven Liu #include <dm.h>
8*f1155765SSteven Liu #include <dm/pinctrl.h>
9*f1155765SSteven Liu #include <regmap.h>
10*f1155765SSteven Liu #include <syscon.h>
11*f1155765SSteven Liu 
12*f1155765SSteven Liu #include "pinctrl-rockchip.h"
13*f1155765SSteven Liu 
rk3576_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)14*f1155765SSteven Liu static int rk3576_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
15*f1155765SSteven Liu {
16*f1155765SSteven Liu 	struct rockchip_pinctrl_priv *priv = bank->priv;
17*f1155765SSteven Liu 	int iomux_num = (pin / 8);
18*f1155765SSteven Liu 	struct regmap *regmap;
19*f1155765SSteven Liu 	int reg, ret, mask;
20*f1155765SSteven Liu 	u8 bit;
21*f1155765SSteven Liu 	u32 data;
22*f1155765SSteven Liu 
23*f1155765SSteven Liu 	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
24*f1155765SSteven Liu 
25*f1155765SSteven Liu 	regmap = priv->regmap_base;
26*f1155765SSteven Liu 	reg = bank->iomux[iomux_num].offset;
27*f1155765SSteven Liu 	if ((pin % 8) >= 4)
28*f1155765SSteven Liu 		reg += 0x4;
29*f1155765SSteven Liu 	bit = (pin % 4) * 4;
30*f1155765SSteven Liu 	mask = 0xf;
31*f1155765SSteven Liu 
32*f1155765SSteven Liu 	data = (mask << (bit + 16));
33*f1155765SSteven Liu 	data |= (mux & mask) << bit;
34*f1155765SSteven Liu 
35*f1155765SSteven Liu 	if ((bank->bank_num == 0) && (pin >= RK_PB4) && (pin <= RK_PB7))
36*f1155765SSteven Liu 		reg += 0x1FF4; /* GPIO0_IOC_GPIO0B_IOMUX_SEL_H */
37*f1155765SSteven Liu 
38*f1155765SSteven Liu 	debug("iomux write reg = %x data = %x\n", reg, data);
39*f1155765SSteven Liu 
40*f1155765SSteven Liu 	ret = regmap_write(regmap, reg, data);
41*f1155765SSteven Liu 
42*f1155765SSteven Liu 	return ret;
43*f1155765SSteven Liu }
44*f1155765SSteven Liu 
45*f1155765SSteven Liu #define RK3576_DRV_BITS_PER_PIN		4
46*f1155765SSteven Liu #define RK3576_DRV_PINS_PER_REG		4
47*f1155765SSteven Liu #define RK3576_DRV_GPIO0_AL_OFFSET	0x10
48*f1155765SSteven Liu #define RK3576_DRV_GPIO0_BH_OFFSET	0x2014
49*f1155765SSteven Liu #define RK3576_DRV_GPIO1_OFFSET		0x6020
50*f1155765SSteven Liu #define RK3576_DRV_GPIO2_OFFSET		0x6040
51*f1155765SSteven Liu #define RK3576_DRV_GPIO3_OFFSET		0x6060
52*f1155765SSteven Liu #define RK3576_DRV_GPIO4_AL_OFFSET	0x6080
53*f1155765SSteven Liu #define RK3576_DRV_GPIO4_CL_OFFSET	0xA090
54*f1155765SSteven Liu #define RK3576_DRV_GPIO4_DL_OFFSET	0xB098
55*f1155765SSteven Liu 
rk3576_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)56*f1155765SSteven Liu static void rk3576_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
57*f1155765SSteven Liu 					int pin_num, struct regmap **regmap,
58*f1155765SSteven Liu 					int *reg, u8 *bit)
59*f1155765SSteven Liu {
60*f1155765SSteven Liu 	struct rockchip_pinctrl_priv *priv = bank->priv;
61*f1155765SSteven Liu 
62*f1155765SSteven Liu 	*regmap = priv->regmap_base;
63*f1155765SSteven Liu 	if (bank->bank_num == 0 && pin_num < 12)
64*f1155765SSteven Liu 		*reg = RK3576_DRV_GPIO0_AL_OFFSET;
65*f1155765SSteven Liu 	else if (bank->bank_num == 0)
66*f1155765SSteven Liu 		*reg = RK3576_DRV_GPIO0_BH_OFFSET - 0xc;
67*f1155765SSteven Liu 	else if (bank->bank_num == 1)
68*f1155765SSteven Liu 		*reg = RK3576_DRV_GPIO1_OFFSET;
69*f1155765SSteven Liu 	else if (bank->bank_num == 2)
70*f1155765SSteven Liu 		*reg = RK3576_DRV_GPIO2_OFFSET;
71*f1155765SSteven Liu 	else if (bank->bank_num == 3)
72*f1155765SSteven Liu 		*reg = RK3576_DRV_GPIO3_OFFSET;
73*f1155765SSteven Liu 	else if (bank->bank_num == 4 && pin_num < 16)
74*f1155765SSteven Liu 		*reg = RK3576_DRV_GPIO4_AL_OFFSET;
75*f1155765SSteven Liu 	else if (bank->bank_num == 4 && pin_num < 24)
76*f1155765SSteven Liu 		*reg = RK3576_DRV_GPIO4_CL_OFFSET - 0x10;
77*f1155765SSteven Liu 	else if (bank->bank_num == 4)
78*f1155765SSteven Liu 		*reg = RK3576_DRV_GPIO4_DL_OFFSET - 0x18;
79*f1155765SSteven Liu 	else {
80*f1155765SSteven Liu 		*reg = 0;
81*f1155765SSteven Liu 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
82*f1155765SSteven Liu 	}
83*f1155765SSteven Liu 
84*f1155765SSteven Liu 	*reg += ((pin_num / RK3576_DRV_PINS_PER_REG) * 4);
85*f1155765SSteven Liu 	*bit = pin_num % RK3576_DRV_PINS_PER_REG;
86*f1155765SSteven Liu 	*bit *= RK3576_DRV_BITS_PER_PIN;
87*f1155765SSteven Liu }
88*f1155765SSteven Liu 
rk3576_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)89*f1155765SSteven Liu static int rk3576_set_drive(struct rockchip_pin_bank *bank,
90*f1155765SSteven Liu 			    int pin_num, int strength)
91*f1155765SSteven Liu {
92*f1155765SSteven Liu 	struct regmap *regmap;
93*f1155765SSteven Liu 	int reg, ret;
94*f1155765SSteven Liu 	u32 data;
95*f1155765SSteven Liu 	u8 bit;
96*f1155765SSteven Liu 	int drv = ((strength & BIT(2)) >> 2) | ((strength & BIT(0)) << 2) | (strength & BIT(1));
97*f1155765SSteven Liu 
98*f1155765SSteven Liu 	rk3576_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
99*f1155765SSteven Liu 
100*f1155765SSteven Liu 	/* enable the write to the equivalent lower bits */
101*f1155765SSteven Liu 	data = ((1 << RK3576_DRV_BITS_PER_PIN) - 1) << (bit + 16);
102*f1155765SSteven Liu 	data |= (drv << bit);
103*f1155765SSteven Liu 	ret = regmap_write(regmap, reg, data);
104*f1155765SSteven Liu 
105*f1155765SSteven Liu 	return ret;
106*f1155765SSteven Liu }
107*f1155765SSteven Liu 
108*f1155765SSteven Liu #define RK3576_PULL_BITS_PER_PIN	2
109*f1155765SSteven Liu #define RK3576_PULL_PINS_PER_REG	8
110*f1155765SSteven Liu #define RK3576_PULL_GPIO0_AL_OFFSET	0x20
111*f1155765SSteven Liu #define RK3576_PULL_GPIO0_BH_OFFSET	0x2028
112*f1155765SSteven Liu #define RK3576_PULL_GPIO1_OFFSET	0x6110
113*f1155765SSteven Liu #define RK3576_PULL_GPIO2_OFFSET	0x6120
114*f1155765SSteven Liu #define RK3576_PULL_GPIO3_OFFSET	0x6130
115*f1155765SSteven Liu #define RK3576_PULL_GPIO4_AL_OFFSET	0x6140
116*f1155765SSteven Liu #define RK3576_PULL_GPIO4_CL_OFFSET	0xA148
117*f1155765SSteven Liu #define RK3576_PULL_GPIO4_DL_OFFSET	0xB14C
118*f1155765SSteven Liu 
rk3576_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)119*f1155765SSteven Liu static void rk3576_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
120*f1155765SSteven Liu 					 int pin_num, struct regmap **regmap,
121*f1155765SSteven Liu 					 int *reg, u8 *bit)
122*f1155765SSteven Liu {
123*f1155765SSteven Liu 	struct rockchip_pinctrl_priv *priv = bank->priv;
124*f1155765SSteven Liu 
125*f1155765SSteven Liu 	*regmap = priv->regmap_base;
126*f1155765SSteven Liu 	if (bank->bank_num == 0 && pin_num < 12)
127*f1155765SSteven Liu 		*reg = RK3576_PULL_GPIO0_AL_OFFSET;
128*f1155765SSteven Liu 	else if (bank->bank_num == 0)
129*f1155765SSteven Liu 		*reg = RK3576_PULL_GPIO0_BH_OFFSET - 0x4;
130*f1155765SSteven Liu 	else if (bank->bank_num == 1)
131*f1155765SSteven Liu 		*reg = RK3576_PULL_GPIO1_OFFSET;
132*f1155765SSteven Liu 	else if (bank->bank_num == 2)
133*f1155765SSteven Liu 		*reg = RK3576_PULL_GPIO2_OFFSET;
134*f1155765SSteven Liu 	else if (bank->bank_num == 3)
135*f1155765SSteven Liu 		*reg = RK3576_PULL_GPIO3_OFFSET;
136*f1155765SSteven Liu 	else if (bank->bank_num == 4 && pin_num < 16)
137*f1155765SSteven Liu 		*reg = RK3576_PULL_GPIO4_AL_OFFSET;
138*f1155765SSteven Liu 	else if (bank->bank_num == 4 && pin_num < 24)
139*f1155765SSteven Liu 		*reg = RK3576_PULL_GPIO4_CL_OFFSET - 0x8;
140*f1155765SSteven Liu 	else if (bank->bank_num == 4)
141*f1155765SSteven Liu 		*reg = RK3576_PULL_GPIO4_DL_OFFSET - 0xc;
142*f1155765SSteven Liu 	else {
143*f1155765SSteven Liu 		*reg = 0;
144*f1155765SSteven Liu 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
145*f1155765SSteven Liu 	}
146*f1155765SSteven Liu 
147*f1155765SSteven Liu 	*reg += ((pin_num / RK3576_PULL_PINS_PER_REG) * 4);
148*f1155765SSteven Liu 	*bit = pin_num % RK3576_PULL_PINS_PER_REG;
149*f1155765SSteven Liu 	*bit *= RK3576_PULL_BITS_PER_PIN;
150*f1155765SSteven Liu }
151*f1155765SSteven Liu 
rk3576_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)152*f1155765SSteven Liu static int rk3576_set_pull(struct rockchip_pin_bank *bank,
153*f1155765SSteven Liu 			   int pin_num, int pull)
154*f1155765SSteven Liu {
155*f1155765SSteven Liu 	struct regmap *regmap;
156*f1155765SSteven Liu 	int reg, ret;
157*f1155765SSteven Liu 	u8 bit, type;
158*f1155765SSteven Liu 	u32 data;
159*f1155765SSteven Liu 
160*f1155765SSteven Liu 	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
161*f1155765SSteven Liu 		return -ENOTSUPP;
162*f1155765SSteven Liu 
163*f1155765SSteven Liu 	rk3576_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
164*f1155765SSteven Liu 	type = bank->pull_type[pin_num / 8];
165*f1155765SSteven Liu 	ret = rockchip_translate_pull_value(type, pull);
166*f1155765SSteven Liu 	if (ret < 0) {
167*f1155765SSteven Liu 		debug("unsupported pull setting %d\n", pull);
168*f1155765SSteven Liu 		return ret;
169*f1155765SSteven Liu 	}
170*f1155765SSteven Liu 
171*f1155765SSteven Liu 	/* enable the write to the equivalent lower bits */
172*f1155765SSteven Liu 	data = ((1 << RK3576_PULL_BITS_PER_PIN) - 1) << (bit + 16);
173*f1155765SSteven Liu 
174*f1155765SSteven Liu 	data |= (ret << bit);
175*f1155765SSteven Liu 	ret = regmap_write(regmap, reg, data);
176*f1155765SSteven Liu 
177*f1155765SSteven Liu 	return ret;
178*f1155765SSteven Liu }
179*f1155765SSteven Liu 
180*f1155765SSteven Liu #define RK3576_SMT_BITS_PER_PIN		1
181*f1155765SSteven Liu #define RK3576_SMT_PINS_PER_REG		8
182*f1155765SSteven Liu #define RK3576_SMT_GPIO0_AL_OFFSET	0x30
183*f1155765SSteven Liu #define RK3576_SMT_GPIO0_BH_OFFSET	0x2040
184*f1155765SSteven Liu #define RK3576_SMT_GPIO1_OFFSET		0x6210
185*f1155765SSteven Liu #define RK3576_SMT_GPIO2_OFFSET		0x6220
186*f1155765SSteven Liu #define RK3576_SMT_GPIO3_OFFSET		0x6230
187*f1155765SSteven Liu #define RK3576_SMT_GPIO4_AL_OFFSET	0x6240
188*f1155765SSteven Liu #define RK3576_SMT_GPIO4_CL_OFFSET	0xA248
189*f1155765SSteven Liu #define RK3576_SMT_GPIO4_DL_OFFSET	0xB24C
190*f1155765SSteven Liu 
rk3576_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)191*f1155765SSteven Liu static int rk3576_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
192*f1155765SSteven Liu 					   int pin_num,
193*f1155765SSteven Liu 					   struct regmap **regmap,
194*f1155765SSteven Liu 					   int *reg, u8 *bit)
195*f1155765SSteven Liu {
196*f1155765SSteven Liu 	struct rockchip_pinctrl_priv *priv = bank->priv;
197*f1155765SSteven Liu 
198*f1155765SSteven Liu 	*regmap = priv->regmap_base;
199*f1155765SSteven Liu 	if (bank->bank_num == 0 && pin_num < 12)
200*f1155765SSteven Liu 		*reg = RK3576_SMT_GPIO0_AL_OFFSET;
201*f1155765SSteven Liu 	else if (bank->bank_num == 0)
202*f1155765SSteven Liu 		*reg = RK3576_SMT_GPIO0_BH_OFFSET - 0x4;
203*f1155765SSteven Liu 	else if (bank->bank_num == 1)
204*f1155765SSteven Liu 		*reg = RK3576_SMT_GPIO1_OFFSET;
205*f1155765SSteven Liu 	else if (bank->bank_num == 2)
206*f1155765SSteven Liu 		*reg = RK3576_SMT_GPIO2_OFFSET;
207*f1155765SSteven Liu 	else if (bank->bank_num == 3)
208*f1155765SSteven Liu 		*reg = RK3576_SMT_GPIO3_OFFSET;
209*f1155765SSteven Liu 	else if (bank->bank_num == 4 && pin_num < 16)
210*f1155765SSteven Liu 		*reg = RK3576_SMT_GPIO4_AL_OFFSET;
211*f1155765SSteven Liu 	else if (bank->bank_num == 4 && pin_num < 24)
212*f1155765SSteven Liu 		*reg = RK3576_SMT_GPIO4_CL_OFFSET - 0x8;
213*f1155765SSteven Liu 	else if (bank->bank_num == 4)
214*f1155765SSteven Liu 		*reg = RK3576_SMT_GPIO4_DL_OFFSET - 0xc;
215*f1155765SSteven Liu 	else {
216*f1155765SSteven Liu 		*reg = 0;
217*f1155765SSteven Liu 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
218*f1155765SSteven Liu 	}
219*f1155765SSteven Liu 
220*f1155765SSteven Liu 	*reg += ((pin_num / RK3576_SMT_PINS_PER_REG) * 4);
221*f1155765SSteven Liu 	*bit = pin_num % RK3576_SMT_PINS_PER_REG;
222*f1155765SSteven Liu 	*bit *= RK3576_SMT_BITS_PER_PIN;
223*f1155765SSteven Liu 
224*f1155765SSteven Liu 	return 0;
225*f1155765SSteven Liu }
226*f1155765SSteven Liu 
rk3576_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)227*f1155765SSteven Liu static int rk3576_set_schmitt(struct rockchip_pin_bank *bank,
228*f1155765SSteven Liu 			      int pin_num, int enable)
229*f1155765SSteven Liu {
230*f1155765SSteven Liu 	struct regmap *regmap;
231*f1155765SSteven Liu 	int reg, ret;
232*f1155765SSteven Liu 	u32 data;
233*f1155765SSteven Liu 	u8 bit;
234*f1155765SSteven Liu 
235*f1155765SSteven Liu 	rk3576_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
236*f1155765SSteven Liu 
237*f1155765SSteven Liu 	/* enable the write to the equivalent lower bits */
238*f1155765SSteven Liu 	data = ((1 << RK3576_SMT_BITS_PER_PIN) - 1) << (bit + 16);
239*f1155765SSteven Liu 	data |= (enable << bit);
240*f1155765SSteven Liu 	ret = regmap_write(regmap, reg, data);
241*f1155765SSteven Liu 
242*f1155765SSteven Liu 	return ret;
243*f1155765SSteven Liu }
244*f1155765SSteven Liu 
245*f1155765SSteven Liu #define RK3576_PIN_BANK(ID, LABEL, OFFSET0, OFFSET1, OFFSET2, OFFSET3)		\
246*f1155765SSteven Liu 	PIN_BANK_IOMUX_FLAGS_OFFSET_PULL_FLAGS(ID, 32, LABEL,			\
247*f1155765SSteven Liu 					       IOMUX_WIDTH_4BIT,		\
248*f1155765SSteven Liu 					       IOMUX_WIDTH_4BIT,		\
249*f1155765SSteven Liu 					       IOMUX_WIDTH_4BIT,		\
250*f1155765SSteven Liu 					       IOMUX_WIDTH_4BIT,		\
251*f1155765SSteven Liu 					       OFFSET0, OFFSET1,		\
252*f1155765SSteven Liu 					       OFFSET2, OFFSET3,		\
253*f1155765SSteven Liu 					       PULL_TYPE_IO_1, PULL_TYPE_IO_1,	\
254*f1155765SSteven Liu 					       PULL_TYPE_IO_1, PULL_TYPE_IO_1)
255*f1155765SSteven Liu 
256*f1155765SSteven Liu static struct rockchip_pin_bank rk3576_pin_banks[] = {
257*f1155765SSteven Liu 	RK3576_PIN_BANK(0, "gpio0", 0, 0x8, 0x2004, 0x200C),
258*f1155765SSteven Liu 	RK3576_PIN_BANK(1, "gpio1", 0x4020, 0x4028, 0x4030, 0x4038),
259*f1155765SSteven Liu 	RK3576_PIN_BANK(2, "gpio2", 0x4040, 0x4048, 0x4050, 0x4058),
260*f1155765SSteven Liu 	RK3576_PIN_BANK(3, "gpio3", 0x4060, 0x4068, 0x4070, 0x4078),
261*f1155765SSteven Liu 	RK3576_PIN_BANK(4, "gpio4", 0x4080, 0x4088, 0xA390, 0xB398),
262*f1155765SSteven Liu };
263*f1155765SSteven Liu 
264*f1155765SSteven Liu static const struct rockchip_pin_ctrl rk3576_pin_ctrl = {
265*f1155765SSteven Liu 	.pin_banks		= rk3576_pin_banks,
266*f1155765SSteven Liu 	.nr_banks		= ARRAY_SIZE(rk3576_pin_banks),
267*f1155765SSteven Liu 	.nr_pins		= 160,
268*f1155765SSteven Liu 	.grf_mux_offset		= 0x0,
269*f1155765SSteven Liu 	.set_mux		= rk3576_set_mux,
270*f1155765SSteven Liu 	.set_pull		= rk3576_set_pull,
271*f1155765SSteven Liu 	.set_drive		= rk3576_set_drive,
272*f1155765SSteven Liu 	.set_schmitt		= rk3576_set_schmitt,
273*f1155765SSteven Liu };
274*f1155765SSteven Liu 
275*f1155765SSteven Liu static const struct udevice_id rk3576_pinctrl_ids[] = {
276*f1155765SSteven Liu 	{
277*f1155765SSteven Liu 		.compatible = "rockchip,rk3576-pinctrl",
278*f1155765SSteven Liu 		.data = (ulong)&rk3576_pin_ctrl
279*f1155765SSteven Liu 	},
280*f1155765SSteven Liu 	{ }
281*f1155765SSteven Liu };
282*f1155765SSteven Liu 
283*f1155765SSteven Liu U_BOOT_DRIVER(pinctrl_rk3576) = {
284*f1155765SSteven Liu 	.name		= "rockchip_rk3576_pinctrl",
285*f1155765SSteven Liu 	.id		= UCLASS_PINCTRL,
286*f1155765SSteven Liu 	.of_match	= rk3576_pinctrl_ids,
287*f1155765SSteven Liu 	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
288*f1155765SSteven Liu 	.ops		= &rockchip_pinctrl_ops,
289*f1155765SSteven Liu #if !CONFIG_IS_ENABLED(OF_PLATDATA)
290*f1155765SSteven Liu 	.bind		= dm_scan_fdt_dev,
291*f1155765SSteven Liu #endif
292*f1155765SSteven Liu 	.probe		= rockchip_pinctrl_probe,
293*f1155765SSteven Liu };
294