1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2021 Rockchip Electronics Co., Ltd
4 */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <dm/pinctrl.h>
9 #include <regmap.h>
10 #include <syscon.h>
11
12 #include "pinctrl-rockchip.h"
13
rk3588_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)14 static int rk3588_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
15 {
16 struct rockchip_pinctrl_priv *priv = bank->priv;
17 struct regmap *regmap;
18 int iomux_num = (pin / 8);
19 int reg, ret, mask;
20 u8 bit;
21 u32 data;
22
23 debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
24
25 regmap = priv->regmap_base;
26 reg = bank->iomux[iomux_num].offset;
27 if ((pin % 8) >= 4)
28 reg += 0x4;
29 bit = (pin % 4) * 4;
30 mask = 0xf;
31
32 if (bank->bank_num == 0) {
33 if ((pin >= RK_PB4) && (pin <= RK_PD7)) {
34 if (mux < 8) {
35 u32 reg0 = 0;
36
37 reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */
38 data = (mask << (bit + 16));
39 data |= (mux & mask) << bit;
40 ret = regmap_write(regmap, reg0, data);
41
42 reg0 = reg + 0x8000; /* BUS_IOC_BASE */
43 data = (mask << (bit + 16));
44 regmap = priv->regmap_base;
45 regmap_write(regmap, reg0, data);
46 } else {
47 u32 reg0 = 0;
48
49 reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */
50 data = (mask << (bit + 16));
51 data |= 8 << bit;
52 ret = regmap_write(regmap, reg0, data);
53
54 reg0 = reg + 0x8000; /* BUS_IOC_BASE */
55 data = (mask << (bit + 16));
56 data |= mux << bit;
57 regmap = priv->regmap_base;
58 regmap_write(regmap, reg0, data);
59 }
60 } else {
61 data = (mask << (bit + 16));
62 data |= (mux & mask) << bit;
63 ret = regmap_write(regmap, reg, data);
64 }
65 return ret;
66 } else if (bank->bank_num > 0) {
67 reg += 0x8000; /* BUS_IOC_BASE */
68 }
69
70 data = (mask << (bit + 16));
71 data |= (mux & mask) << bit;
72
73 return regmap_write(regmap, reg, data);
74 }
75
76 #define rk3588_DRV_PMU_OFFSET 0x70
77 #define rk3588_DRV_GRF_OFFSET 0x200
78 #define rk3588_DRV_BITS_PER_PIN 8
79 #define rk3588_DRV_PINS_PER_REG 2
80 #define rk3588_DRV_BANK_STRIDE 0x40
81
82 #define RK3588_PMU1_IOC_REG 0x0000
83 #define RK3588_PMU2_IOC_REG 0x4000
84 #define RK3588_BUS_IOC_REG 0x8000
85 #define RK3588_VCCIO1_4_IOC_REG 0x9000
86 #define RK3588_VCCIO3_5_IOC_REG 0xA000
87 #define RK3588_VCCIO2_IOC_REG 0xB000
88 #define RK3588_VCCIO6_IOC_REG 0xC000
89 #define RK3588_EMMC_IOC_REG 0xD000
90
91 static const u32 rk3588_ds_regs[][2] = {
92 { RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0010 },
93 { RK_GPIO0_A4, RK3588_PMU1_IOC_REG + 0x0014 },
94 { RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0018 },
95 { RK_GPIO0_B4, RK3588_PMU2_IOC_REG + 0x0014 },
96 { RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0018 },
97 { RK_GPIO0_C4, RK3588_PMU2_IOC_REG + 0x001C },
98 { RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0020 },
99 { RK_GPIO0_D4, RK3588_PMU2_IOC_REG + 0x0024 },
100 { RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0020 },
101 { RK_GPIO1_A4, RK3588_VCCIO1_4_IOC_REG + 0x0024 },
102 { RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0028 },
103 { RK_GPIO1_B4, RK3588_VCCIO1_4_IOC_REG + 0x002C },
104 { RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0030 },
105 { RK_GPIO1_C4, RK3588_VCCIO1_4_IOC_REG + 0x0034 },
106 { RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x0038 },
107 { RK_GPIO1_D4, RK3588_VCCIO1_4_IOC_REG + 0x003C },
108 { RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0040 },
109 { RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0044 },
110 { RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0048 },
111 { RK_GPIO2_B4, RK3588_VCCIO3_5_IOC_REG + 0x004C },
112 { RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0050 },
113 { RK_GPIO2_C4, RK3588_VCCIO3_5_IOC_REG + 0x0054 },
114 { RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x0058 },
115 { RK_GPIO2_D4, RK3588_EMMC_IOC_REG + 0x005C },
116 { RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0060 },
117 { RK_GPIO3_A4, RK3588_VCCIO3_5_IOC_REG + 0x0064 },
118 { RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0068 },
119 { RK_GPIO3_B4, RK3588_VCCIO3_5_IOC_REG + 0x006C },
120 { RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0070 },
121 { RK_GPIO3_C4, RK3588_VCCIO3_5_IOC_REG + 0x0074 },
122 { RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x0078 },
123 { RK_GPIO3_D4, RK3588_VCCIO3_5_IOC_REG + 0x007C },
124 { RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0080 },
125 { RK_GPIO4_A4, RK3588_VCCIO6_IOC_REG + 0x0084 },
126 { RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0088 },
127 { RK_GPIO4_B4, RK3588_VCCIO6_IOC_REG + 0x008C },
128 { RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0090 },
129 { RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0090 },
130 { RK_GPIO4_C4, RK3588_VCCIO3_5_IOC_REG + 0x0094 },
131 { RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x0098 },
132 };
133
134 static const u32 rk3588_p_regs[][2] = {
135 { RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0020 },
136 { RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0024 },
137 { RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0028 },
138 { RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x002C },
139 { RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0030 },
140 { RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0110 },
141 { RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0114 },
142 { RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0118 },
143 { RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x011C },
144 { RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0120 },
145 { RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0120 },
146 { RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0124 },
147 { RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0128 },
148 { RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x012C },
149 { RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0130 },
150 { RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0134 },
151 { RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0138 },
152 { RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x013C },
153 { RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0140 },
154 { RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0144 },
155 { RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0148 },
156 { RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0148 },
157 { RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x014C },
158 };
159
160 static const u32 rk3588_smt_regs[][2] = {
161 { RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0030 },
162 { RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0034 },
163 { RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0040 },
164 { RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0044 },
165 { RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0048 },
166 { RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0210 },
167 { RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0214 },
168 { RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0218 },
169 { RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x021C },
170 { RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0220 },
171 { RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0220 },
172 { RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0224 },
173 { RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0228 },
174 { RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x022C },
175 { RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0230 },
176 { RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0234 },
177 { RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0238 },
178 { RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x023C },
179 { RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0240 },
180 { RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0244 },
181 { RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0248 },
182 { RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0248 },
183 { RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x024C },
184 };
185
186 #define RK3588_PULL_BITS_PER_PIN 2
187 #define RK3588_PULL_PINS_PER_REG 8
188
rk3588_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)189 static void rk3588_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
190 int pin_num, struct regmap **regmap,
191 int *reg, u8 *bit)
192 {
193 struct rockchip_pinctrl_priv *info = bank->priv;
194 u8 bank_num = bank->bank_num;
195 u32 pin = bank_num * 32 + pin_num;
196 int i;
197
198 for (i = ARRAY_SIZE(rk3588_p_regs) - 1; i >= 0; i--) {
199 if (pin >= rk3588_p_regs[i][0]) {
200 *reg = rk3588_p_regs[i][1];
201 break;
202 }
203 BUG_ON(i == 0);
204 }
205
206 *regmap = info->regmap_base;
207 *reg += ((pin - rk3588_p_regs[i][0]) / RK3588_PULL_PINS_PER_REG) * 4;
208 *bit = pin_num % RK3588_PULL_PINS_PER_REG;
209 *bit *= RK3588_PULL_BITS_PER_PIN;
210 }
211
212 #define RK3588_DRV_BITS_PER_PIN 4
213 #define RK3588_DRV_PINS_PER_REG 4
214
rk3588_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)215 static void rk3588_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
216 int pin_num, struct regmap **regmap,
217 int *reg, u8 *bit)
218 {
219 struct rockchip_pinctrl_priv *info = bank->priv;
220 u8 bank_num = bank->bank_num;
221 u32 pin = bank_num * 32 + pin_num;
222 int i;
223
224 for (i = ARRAY_SIZE(rk3588_ds_regs) - 1; i >= 0; i--) {
225 if (pin >= rk3588_ds_regs[i][0]) {
226 *reg = rk3588_ds_regs[i][1];
227 break;
228 }
229 BUG_ON(i == 0);
230 }
231
232 *regmap = info->regmap_base;
233 *reg += ((pin - rk3588_ds_regs[i][0]) / RK3588_DRV_PINS_PER_REG) * 4;
234 *bit = pin_num % RK3588_DRV_PINS_PER_REG;
235 *bit *= RK3588_DRV_BITS_PER_PIN;
236 }
237
238 #define RK3588_SMT_BITS_PER_PIN 1
239 #define RK3588_SMT_PINS_PER_REG 8
240
rk3588_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)241 static int rk3588_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
242 int pin_num, struct regmap **regmap,
243 int *reg, u8 *bit)
244 {
245 struct rockchip_pinctrl_priv *info = bank->priv;
246 u8 bank_num = bank->bank_num;
247 u32 pin = bank_num * 32 + pin_num;
248 int i;
249
250 for (i = ARRAY_SIZE(rk3588_smt_regs) - 1; i >= 0; i--) {
251 if (pin >= rk3588_smt_regs[i][0]) {
252 *reg = rk3588_smt_regs[i][1];
253 break;
254 }
255 BUG_ON(i == 0);
256 }
257
258 *regmap = info->regmap_base;
259 *reg += ((pin - rk3588_smt_regs[i][0]) / RK3588_SMT_PINS_PER_REG) * 4;
260 *bit = pin_num % RK3588_SMT_PINS_PER_REG;
261 *bit *= RK3588_SMT_BITS_PER_PIN;
262
263 return 0;
264 }
265
rk3588_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)266 static int rk3588_set_pull(struct rockchip_pin_bank *bank,
267 int pin_num, int pull)
268 {
269 struct regmap *regmap;
270 int reg;
271 u32 data;
272 u8 bit;
273
274 rk3588_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit);
275
276 /* enable the write to the equivalent lower bits */
277 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
278 data |= (pull << bit);
279
280 return regmap_write(regmap, reg, data);
281 }
282
rk3588_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)283 static int rk3588_set_drive(struct rockchip_pin_bank *bank,
284 int pin_num, int strength)
285 {
286 struct regmap *regmap;
287 int reg;
288 u32 data;
289 u8 bit;
290
291 rk3588_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit);
292
293 /* enable the write to the equivalent lower bits */
294 data = ((1 << rk3588_DRV_BITS_PER_PIN) - 1) << (bit + 16);
295 data |= (strength << bit);
296
297 return regmap_write(regmap, reg, data);
298 }
299
rk3588_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)300 static int rk3588_set_schmitt(struct rockchip_pin_bank *bank,
301 int pin_num, int enable)
302 {
303 struct regmap *regmap;
304 int reg;
305 u32 data;
306 u8 bit;
307
308 rk3588_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit);
309
310 /* enable the write to the equivalent lower bits */
311 data = ((1 << RK3588_SMT_BITS_PER_PIN) - 1) << (bit + 16);
312 data |= (enable << bit);
313
314 return regmap_write(regmap, reg, data);
315 }
316
317 static struct rockchip_pin_bank rk3588_pin_banks[] = {
318 RK3588_PIN_BANK_FLAGS(0, 32, "gpio0",
319 IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
320 RK3588_PIN_BANK_FLAGS(1, 32, "gpio1",
321 IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
322 RK3588_PIN_BANK_FLAGS(2, 32, "gpio2",
323 IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
324 RK3588_PIN_BANK_FLAGS(3, 32, "gpio3",
325 IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
326 RK3588_PIN_BANK_FLAGS(4, 32, "gpio4",
327 IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
328 };
329
330 static const struct rockchip_pin_ctrl rk3588_pin_ctrl = {
331 .pin_banks = rk3588_pin_banks,
332 .nr_banks = ARRAY_SIZE(rk3588_pin_banks),
333 .nr_pins = 160,
334 .set_mux = rk3588_set_mux,
335 .set_pull = rk3588_set_pull,
336 .set_drive = rk3588_set_drive,
337 .set_schmitt = rk3588_set_schmitt,
338 };
339
340 static const struct udevice_id rk3588_pinctrl_ids[] = {
341 {
342 .compatible = "rockchip,rk3588-pinctrl",
343 .data = (ulong)&rk3588_pin_ctrl
344 },
345 { }
346 };
347
348 U_BOOT_DRIVER(pinctrl_rk3588) = {
349 .name = "rockchip_rk3588_pinctrl",
350 .id = UCLASS_PINCTRL,
351 .of_match = rk3588_pinctrl_ids,
352 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
353 .ops = &rockchip_pinctrl_ops,
354 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
355 .bind = dm_scan_fdt_dev,
356 #endif
357 .probe = rockchip_pinctrl_probe,
358 };
359