1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2022 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
rv1106_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)14 static int rv1106_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
15 {
16 struct rockchip_pinctrl_priv *priv = bank->priv;
17 int iomux_num = (pin / 8);
18 struct regmap *regmap;
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 if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
26 regmap = priv->regmap_pmu;
27 else
28 regmap = priv->regmap_base;
29
30 reg = bank->iomux[iomux_num].offset;
31 if ((pin % 8) >= 4)
32 reg += 0x4;
33 bit = (pin % 4) * 4;
34 mask = 0xf;
35
36 data = (mask << (bit + 16));
37 data |= (mux & mask) << bit;
38
39 debug("iomux write reg = %x data = %x\n", reg, data);
40
41 ret = regmap_write(regmap, reg, data);
42
43 return ret;
44 }
45
46 #define RV1106_DRV_BITS_PER_PIN 8
47 #define RV1106_DRV_PINS_PER_REG 2
48 #define RV1106_DRV_GPIO0_OFFSET 0x10
49 #define RV1106_DRV_GPIO1_OFFSET 0x80
50 #define RV1106_DRV_GPIO2_OFFSET 0x100C0
51 #define RV1106_DRV_GPIO3_OFFSET 0x20100
52 #define RV1106_DRV_GPIO4_OFFSET 0x30020
53
rv1106_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)54 static void rv1106_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
55 int pin_num, struct regmap **regmap,
56 int *reg, u8 *bit)
57 {
58 struct rockchip_pinctrl_priv *priv = bank->priv;
59
60 /* GPIO0_IOC is located in PMU */
61 switch (bank->bank_num) {
62 case 0:
63 *regmap = priv->regmap_pmu;
64 *reg = RV1106_DRV_GPIO0_OFFSET;
65 break;
66
67 case 1:
68 *regmap = priv->regmap_base;
69 *reg = RV1106_DRV_GPIO1_OFFSET;
70 break;
71
72 case 2:
73 *regmap = priv->regmap_base;
74 *reg = RV1106_DRV_GPIO2_OFFSET;
75 break;
76
77 case 3:
78 *regmap = priv->regmap_base;
79 *reg = RV1106_DRV_GPIO3_OFFSET;
80 break;
81
82 case 4:
83 *regmap = priv->regmap_base;
84 *reg = RV1106_DRV_GPIO4_OFFSET;
85 break;
86
87 default:
88 *regmap = priv->regmap_base;
89 *reg = 0;
90 dev_err(priv->dev, "unsupported bank_num %d\n", bank->bank_num);
91 break;
92 }
93
94 *reg += ((pin_num / RV1106_DRV_PINS_PER_REG) * 4);
95 *bit = pin_num % RV1106_DRV_PINS_PER_REG;
96 *bit *= RV1106_DRV_BITS_PER_PIN;
97 }
98
rv1106_set_drive(struct rockchip_pin_bank * bank,int pin_num,int strength)99 static int rv1106_set_drive(struct rockchip_pin_bank *bank,
100 int pin_num, int strength)
101 {
102 struct regmap *regmap;
103 int reg, ret;
104 u32 data;
105 u8 bit;
106 int drv = (1 << (strength + 1)) - 1;
107
108 rv1106_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit);
109
110 /* enable the write to the equivalent lower bits */
111 data = ((1 << RV1106_DRV_BITS_PER_PIN) - 1) << (bit + 16);
112 data |= (drv << bit);
113 ret = regmap_write(regmap, reg, data);
114
115 return ret;
116 }
117
118 #define RV1106_PULL_BITS_PER_PIN 2
119 #define RV1106_PULL_PINS_PER_REG 8
120 #define RV1106_PULL_GPIO0_OFFSET 0x38
121 #define RV1106_PULL_GPIO1_OFFSET 0x1C0
122 #define RV1106_PULL_GPIO2_OFFSET 0x101D0
123 #define RV1106_PULL_GPIO3_OFFSET 0x201E0
124 #define RV1106_PULL_GPIO4_OFFSET 0x30070
125
rv1106_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)126 static void rv1106_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
127 int pin_num, struct regmap **regmap,
128 int *reg, u8 *bit)
129 {
130 struct rockchip_pinctrl_priv *priv = bank->priv;
131
132 /* GPIO0_IOC is located in PMU */
133 switch (bank->bank_num) {
134 case 0:
135 *regmap = priv->regmap_pmu;
136 *reg = RV1106_PULL_GPIO0_OFFSET;
137 break;
138
139 case 1:
140 *regmap = priv->regmap_base;
141 *reg = RV1106_PULL_GPIO1_OFFSET;
142 break;
143
144 case 2:
145 *regmap = priv->regmap_base;
146 *reg = RV1106_PULL_GPIO2_OFFSET;
147 break;
148
149 case 3:
150 *regmap = priv->regmap_base;
151 *reg = RV1106_PULL_GPIO3_OFFSET;
152 break;
153
154 case 4:
155 *regmap = priv->regmap_base;
156 *reg = RV1106_PULL_GPIO4_OFFSET;
157 break;
158
159 default:
160 *regmap = priv->regmap_base;
161 *reg = 0;
162 dev_err(priv->dev, "unsupported bank_num %d\n", bank->bank_num);
163 break;
164 }
165
166 *reg += ((pin_num / RV1106_PULL_PINS_PER_REG) * 4);
167 *bit = pin_num % RV1106_PULL_PINS_PER_REG;
168 *bit *= RV1106_PULL_BITS_PER_PIN;
169 }
170
rv1106_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)171 static int rv1106_set_pull(struct rockchip_pin_bank *bank,
172 int pin_num, int pull)
173 {
174 struct regmap *regmap;
175 int reg, ret;
176 u8 bit, type;
177 u32 data;
178
179 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
180 return -ENOTSUPP;
181
182 rv1106_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit);
183 type = bank->pull_type[pin_num / 8];
184 ret = rockchip_translate_pull_value(type, pull);
185 if (ret < 0) {
186 debug("unsupported pull setting %d\n", pull);
187 return ret;
188 }
189
190 /* enable the write to the equivalent lower bits */
191 data = ((1 << RV1106_PULL_BITS_PER_PIN) - 1) << (bit + 16);
192
193 data |= (ret << bit);
194 ret = regmap_write(regmap, reg, data);
195
196 return ret;
197 }
198
199 #define RV1106_SMT_BITS_PER_PIN 1
200 #define RV1106_SMT_PINS_PER_REG 8
201 #define RV1106_SMT_GPIO0_OFFSET 0x40
202 #define RV1106_SMT_GPIO1_OFFSET 0x280
203 #define RV1106_SMT_GPIO2_OFFSET 0x10290
204 #define RV1106_SMT_GPIO3_OFFSET 0x202A0
205 #define RV1106_SMT_GPIO4_OFFSET 0x300A0
206
rv1106_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)207 static int rv1106_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
208 int pin_num,
209 struct regmap **regmap,
210 int *reg, u8 *bit)
211 {
212 struct rockchip_pinctrl_priv *priv = bank->priv;
213
214 /* GPIO0_IOC is located in PMU */
215 switch (bank->bank_num) {
216 case 0:
217 *regmap = priv->regmap_pmu;
218 *reg = RV1106_SMT_GPIO0_OFFSET;
219 break;
220
221 case 1:
222 *regmap = priv->regmap_base;
223 *reg = RV1106_SMT_GPIO1_OFFSET;
224 break;
225
226 case 2:
227 *regmap = priv->regmap_base;
228 *reg = RV1106_SMT_GPIO2_OFFSET;
229 break;
230
231 case 3:
232 *regmap = priv->regmap_base;
233 *reg = RV1106_SMT_GPIO3_OFFSET;
234 break;
235
236 case 4:
237 *regmap = priv->regmap_base;
238 *reg = RV1106_SMT_GPIO4_OFFSET;
239 break;
240
241 default:
242 *regmap = priv->regmap_base;
243 *reg = 0;
244 dev_err(priv->dev, "unsupported bank_num %d\n", bank->bank_num);
245 break;
246 }
247
248 *reg += ((pin_num / RV1106_SMT_PINS_PER_REG) * 4);
249 *bit = pin_num % RV1106_SMT_PINS_PER_REG;
250 *bit *= RV1106_SMT_BITS_PER_PIN;
251
252 return 0;
253 }
254
rv1106_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)255 static int rv1106_set_schmitt(struct rockchip_pin_bank *bank,
256 int pin_num, int enable)
257 {
258 struct regmap *regmap;
259 int reg, ret;
260 u32 data;
261 u8 bit;
262
263 rv1106_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit);
264
265 /* enable the write to the equivalent lower bits */
266 data = ((1 << RV1106_SMT_BITS_PER_PIN) - 1) << (bit + 16);
267 data |= (enable << bit);
268 ret = regmap_write(regmap, reg, data);
269
270 return ret;
271 }
272
273 static struct rockchip_pin_bank rv1106_pin_banks[] = {
274 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0",
275 IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
276 IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
277 IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
278 IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU),
279 PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1",
280 IOMUX_WIDTH_4BIT,
281 IOMUX_WIDTH_4BIT,
282 IOMUX_WIDTH_4BIT,
283 IOMUX_WIDTH_4BIT,
284 0, 0x08, 0x10, 0x18),
285 PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2",
286 IOMUX_WIDTH_4BIT,
287 IOMUX_WIDTH_4BIT,
288 IOMUX_WIDTH_4BIT,
289 IOMUX_WIDTH_4BIT,
290 0x10020, 0x10028, 0, 0),
291 PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3",
292 IOMUX_WIDTH_4BIT,
293 IOMUX_WIDTH_4BIT,
294 IOMUX_WIDTH_4BIT,
295 IOMUX_WIDTH_4BIT,
296 0x20040, 0x20048, 0x20050, 0x20058),
297 PIN_BANK_IOMUX_FLAGS_OFFSET(4, 24, "gpio4",
298 IOMUX_WIDTH_4BIT,
299 IOMUX_WIDTH_4BIT,
300 IOMUX_WIDTH_4BIT,
301 0,
302 0x30000, 0x30008, 0x30010, 0),
303 };
304
305 static const struct rockchip_pin_ctrl rv1106_pin_ctrl = {
306 .pin_banks = rv1106_pin_banks,
307 .nr_banks = ARRAY_SIZE(rv1106_pin_banks),
308 .nr_pins = 152,
309 .grf_mux_offset = 0x0,
310 .pmu_mux_offset = 0x0,
311 .set_mux = rv1106_set_mux,
312 .set_pull = rv1106_set_pull,
313 .set_drive = rv1106_set_drive,
314 .set_schmitt = rv1106_set_schmitt,
315 };
316
317 static const struct udevice_id rv1106_pinctrl_ids[] = {
318 {
319 .compatible = "rockchip,rv1106-pinctrl",
320 .data = (ulong)&rv1106_pin_ctrl
321 },
322 { }
323 };
324
325 U_BOOT_DRIVER(pinctrl_rv1106) = {
326 .name = "rockchip_rv1106_pinctrl",
327 .id = UCLASS_PINCTRL,
328 .of_match = rv1106_pinctrl_ids,
329 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
330 .ops = &rockchip_pinctrl_ops,
331 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
332 .bind = dm_scan_fdt_dev,
333 #endif
334 .probe = rockchip_pinctrl_probe,
335 };
336