blob: abd57e54a5b359e1933f18f42d440c87800002a3 [file] [log] [blame]
David Wufd2fdf72019-12-03 19:26:50 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2019 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
14static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
15 {
16 .num = 1,
17 .pin = 14,
18 .reg = 0x28,
19 .bit = 12,
20 .mask = 0xf
21 }, {
22 .num = 1,
23 .pin = 15,
24 .reg = 0x2c,
25 .bit = 0,
26 .mask = 0x3
27 }, {
28 .num = 1,
29 .pin = 18,
30 .reg = 0x30,
31 .bit = 4,
32 .mask = 0xf
33 }, {
34 .num = 1,
35 .pin = 19,
36 .reg = 0x30,
37 .bit = 8,
38 .mask = 0xf
39 }, {
40 .num = 1,
41 .pin = 20,
42 .reg = 0x30,
43 .bit = 12,
44 .mask = 0xf
45 }, {
46 .num = 1,
47 .pin = 21,
48 .reg = 0x34,
49 .bit = 0,
50 .mask = 0xf
51 }, {
52 .num = 1,
53 .pin = 22,
54 .reg = 0x34,
55 .bit = 4,
56 .mask = 0xf
57 }, {
58 .num = 1,
59 .pin = 23,
60 .reg = 0x34,
61 .bit = 8,
62 .mask = 0xf
63 }, {
64 .num = 3,
65 .pin = 12,
66 .reg = 0x68,
67 .bit = 8,
68 .mask = 0xf
69 }, {
70 .num = 3,
71 .pin = 13,
72 .reg = 0x68,
73 .bit = 12,
74 .mask = 0xf
75 }, {
76 .num = 2,
77 .pin = 2,
78 .reg = 0x608,
79 .bit = 0,
80 .mask = 0x7
81 }, {
82 .num = 2,
83 .pin = 3,
84 .reg = 0x608,
85 .bit = 4,
86 .mask = 0x7
87 }, {
88 .num = 2,
89 .pin = 16,
90 .reg = 0x610,
91 .bit = 8,
92 .mask = 0x7
93 }, {
94 .num = 3,
95 .pin = 10,
96 .reg = 0x610,
97 .bit = 0,
98 .mask = 0x7
99 }, {
100 .num = 3,
101 .pin = 11,
102 .reg = 0x610,
103 .bit = 4,
104 .mask = 0x7
105 },
106};
107
108static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
109 {
110 /* rtc_clk */
111 .bank_num = 0,
112 .pin = 19,
113 .func = 1,
114 .route_offset = 0x314,
115 .route_val = BIT(16 + 0) | BIT(0),
116 }, {
117 /* uart2_rxm0 */
118 .bank_num = 1,
119 .pin = 22,
120 .func = 2,
121 .route_offset = 0x314,
122 .route_val = BIT(16 + 2) | BIT(16 + 3),
123 }, {
124 /* uart2_rxm1 */
125 .bank_num = 4,
126 .pin = 26,
127 .func = 2,
128 .route_offset = 0x314,
129 .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
130 }, {
131 /* i2c3_sdam0 */
132 .bank_num = 0,
133 .pin = 15,
134 .func = 2,
135 .route_offset = 0x608,
136 .route_val = BIT(16 + 8) | BIT(16 + 9),
137 }, {
138 /* i2c3_sdam1 */
139 .bank_num = 3,
140 .pin = 12,
141 .func = 2,
142 .route_offset = 0x608,
143 .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8),
144 }, {
145 /* i2c3_sdam2 */
146 .bank_num = 2,
147 .pin = 0,
148 .func = 3,
149 .route_offset = 0x608,
150 .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9),
151 }, {
152 /* i2s-8ch-1-sclktxm0 */
153 .bank_num = 1,
154 .pin = 3,
155 .func = 2,
156 .route_offset = 0x308,
157 .route_val = BIT(16 + 3),
158 }, {
159 /* i2s-8ch-1-sclkrxm0 */
160 .bank_num = 1,
161 .pin = 4,
162 .func = 2,
163 .route_offset = 0x308,
164 .route_val = BIT(16 + 3),
165 }, {
166 /* i2s-8ch-1-sclktxm1 */
167 .bank_num = 1,
168 .pin = 13,
169 .func = 2,
170 .route_offset = 0x308,
171 .route_val = BIT(16 + 3) | BIT(3),
172 }, {
173 /* i2s-8ch-1-sclkrxm1 */
174 .bank_num = 1,
175 .pin = 14,
176 .func = 2,
177 .route_offset = 0x308,
178 .route_val = BIT(16 + 3) | BIT(3),
179 }, {
180 /* pdm-clkm0 */
181 .bank_num = 1,
182 .pin = 4,
183 .func = 3,
184 .route_offset = 0x308,
185 .route_val = BIT(16 + 12) | BIT(16 + 13),
186 }, {
187 /* pdm-clkm1 */
188 .bank_num = 1,
189 .pin = 14,
190 .func = 4,
191 .route_offset = 0x308,
192 .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
193 }, {
194 /* pdm-clkm2 */
195 .bank_num = 2,
196 .pin = 6,
197 .func = 2,
198 .route_offset = 0x308,
199 .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
200 }, {
201 /* pdm-clkm-m2 */
202 .bank_num = 2,
203 .pin = 4,
204 .func = 3,
205 .route_offset = 0x600,
206 .route_val = BIT(16 + 2) | BIT(2),
207 }, {
208 /* spi1_miso */
209 .bank_num = 3,
210 .pin = 10,
211 .func = 3,
212 .route_offset = 0x314,
213 .route_val = BIT(16 + 9),
214 }, {
215 /* spi1_miso_m1 */
216 .bank_num = 2,
217 .pin = 4,
218 .func = 2,
219 .route_offset = 0x314,
220 .route_val = BIT(16 + 9) | BIT(9),
221 }, {
222 /* mac_rxd0_m0 */
223 .bank_num = 1,
224 .pin = 20,
225 .func = 3,
226 .route_offset = 0x314,
227 .route_val = BIT(16 + 14),
228 }, {
229 /* mac_rxd0_m1 */
230 .bank_num = 4,
231 .pin = 2,
232 .func = 2,
233 .route_offset = 0x314,
234 .route_val = BIT(16 + 14) | BIT(14),
235 }, {
236 /* uart3_rx */
237 .bank_num = 3,
238 .pin = 12,
239 .func = 4,
240 .route_offset = 0x314,
241 .route_val = BIT(16 + 15),
242 }, {
243 /* uart3_rx_m1 */
244 .bank_num = 0,
245 .pin = 17,
246 .func = 3,
247 .route_offset = 0x314,
248 .route_val = BIT(16 + 15) | BIT(15),
249 },
250};
251
252static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
253{
254 struct rockchip_pinctrl_priv *priv = bank->priv;
255 int iomux_num = (pin / 8);
256 struct regmap *regmap;
257 int reg, ret, mask, mux_type;
258 u8 bit;
259 u32 data, route_reg, route_val;
260
261 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
262 ? priv->regmap_pmu : priv->regmap_base;
263
264 /* get basic quadrupel of mux registers and the correct reg inside */
265 mux_type = bank->iomux[iomux_num].type;
266 reg = bank->iomux[iomux_num].offset;
267 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
268
269 if (bank->recalced_mask & BIT(pin))
270 rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
271
272 if (bank->route_mask & BIT(pin)) {
273 if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
274 &route_val)) {
275 ret = regmap_write(regmap, route_reg, route_val);
276 if (ret)
277 return ret;
278 }
279 }
280
281 data = (mask << (bit + 16));
282 data |= (mux & mask) << bit;
283 ret = regmap_write(regmap, reg, data);
284
285 return ret;
286}
287
288#define RK3308_PULL_OFFSET 0xa0
289
290static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
291 int pin_num, struct regmap **regmap,
292 int *reg, u8 *bit)
293{
294 struct rockchip_pinctrl_priv *priv = bank->priv;
295
296 *regmap = priv->regmap_base;
297 *reg = RK3308_PULL_OFFSET;
298 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
299 *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
300
301 *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
302 *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
303}
304
305static int rk3308_set_pull(struct rockchip_pin_bank *bank,
306 int pin_num, int pull)
307{
308 struct regmap *regmap;
309 int reg, ret;
310 u8 bit, type;
311 u32 data;
312
313 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
314 return -ENOTSUPP;
315
316 rk3308_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
317 type = bank->pull_type[pin_num / 8];
318 ret = rockchip_translate_pull_value(type, pull);
319 if (ret < 0) {
320 debug("unsupported pull setting %d\n", pull);
321 return ret;
322 }
323
324 /* enable the write to the equivalent lower bits */
325 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
326 data |= (ret << bit);
327
328 ret = regmap_write(regmap, reg, data);
329
330 return ret;
331}
332
333#define RK3308_DRV_GRF_OFFSET 0x100
334
335static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
336 int pin_num, struct regmap **regmap,
337 int *reg, u8 *bit)
338{
339 struct rockchip_pinctrl_priv *priv = bank->priv;
340
341 *regmap = priv->regmap_base;
342 *reg = RK3308_DRV_GRF_OFFSET;
343 *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
344 *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
345
346 *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
347 *bit *= ROCKCHIP_DRV_BITS_PER_PIN;
348}
349
350static int rk3308_set_drive(struct rockchip_pin_bank *bank,
351 int pin_num, int strength)
352{
353 struct regmap *regmap;
354 int reg, ret;
355 u32 data;
356 u8 bit;
357 int type = bank->drv[pin_num / 8].drv_type;
358
359 rk3308_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
360 ret = rockchip_translate_drive_value(type, strength);
361 if (ret < 0) {
362 debug("unsupported driver strength %d\n", strength);
363 return ret;
364 }
365
366 /* enable the write to the equivalent lower bits */
367 data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
368 data |= (ret << bit);
369 ret = regmap_write(regmap, reg, data);
370 return ret;
371}
372
373#define RK3308_SCHMITT_PINS_PER_REG 8
374#define RK3308_SCHMITT_BANK_STRIDE 16
375#define RK3308_SCHMITT_GRF_OFFSET 0x1a0
376
377static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
378 int pin_num,
379 struct regmap **regmap,
380 int *reg, u8 *bit)
381{
382 struct rockchip_pinctrl_priv *priv = bank->priv;
383
384 *regmap = priv->regmap_base;
385 *reg = RK3308_SCHMITT_GRF_OFFSET;
386
387 *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE;
388 *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4);
389 *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG;
390
391 return 0;
392}
393
394static int rk3308_set_schmitt(struct rockchip_pin_bank *bank,
395 int pin_num, int enable)
396{
397 struct regmap *regmap;
398 int reg;
399 u8 bit;
400 u32 data;
401
402 rk3308_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
403 /* enable the write to the equivalent lower bits */
404 data = BIT(bit + 16) | (enable << bit);
405
406 return regmap_write(regmap, reg, data);
407}
408
409static struct rockchip_pin_bank rk3308_pin_banks[] = {
410 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT,
411 IOMUX_8WIDTH_2BIT,
412 IOMUX_8WIDTH_2BIT,
413 IOMUX_8WIDTH_2BIT),
414 PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT,
415 IOMUX_8WIDTH_2BIT,
416 IOMUX_8WIDTH_2BIT,
417 IOMUX_8WIDTH_2BIT),
418 PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT,
419 IOMUX_8WIDTH_2BIT,
420 IOMUX_8WIDTH_2BIT,
421 IOMUX_8WIDTH_2BIT),
422 PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT,
423 IOMUX_8WIDTH_2BIT,
424 IOMUX_8WIDTH_2BIT,
425 IOMUX_8WIDTH_2BIT),
426 PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT,
427 IOMUX_8WIDTH_2BIT,
428 IOMUX_8WIDTH_2BIT,
429 IOMUX_8WIDTH_2BIT),
430};
431
432static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
433 .pin_banks = rk3308_pin_banks,
434 .nr_banks = ARRAY_SIZE(rk3308_pin_banks),
435 .grf_mux_offset = 0x0,
436 .iomux_recalced = rk3308_mux_recalced_data,
437 .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data),
438 .iomux_routes = rk3308_mux_route_data,
439 .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data),
440 .set_mux = rk3308_set_mux,
441 .set_drive = rk3308_set_drive,
442 .set_pull = rk3308_set_pull,
443 .set_schmitt = rk3308_set_schmitt,
444};
445
446static const struct udevice_id rk3308_pinctrl_ids[] = {
447 {
448 .compatible = "rockchip,rk3308-pinctrl",
449 .data = (ulong)&rk3308_pin_ctrl
450 },
451 { }
452};
453
454U_BOOT_DRIVER(pinctrl_rk3308) = {
455 .name = "rockchip_rk3308_pinctrl",
456 .id = UCLASS_PINCTRL,
457 .of_match = rk3308_pinctrl_ids,
458 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
459 .ops = &rockchip_pinctrl_ops,
460#if !CONFIG_IS_ENABLED(OF_PLATDATA)
461 .bind = dm_scan_fdt_dev,
462#endif
463 .probe = rockchip_pinctrl_probe,
464};