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, ®map, ®, &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, ®map, ®, &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, ®map, ®, &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