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