Merge tag 'ti-v2020.07-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-ti
[oweals/u-boot.git] / drivers / pinctrl / rockchip / pinctrl-rk3308.c
1 // 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 <log.h>
9 #include <dm/pinctrl.h>
10 #include <regmap.h>
11 #include <syscon.h>
12 #include <linux/bitops.h>
13
14 #include "pinctrl-rockchip.h"
15
16 static 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
110 static 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
254 static 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
292 static 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
307 static 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
337 static 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
352 static 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
379 static 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
396 static 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
411 static 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
434 static 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
448 static const struct udevice_id rk3308_pinctrl_ids[] = {
449         {
450                 .compatible = "rockchip,rk3308-pinctrl",
451                 .data = (ulong)&rk3308_pin_ctrl
452         },
453         { }
454 };
455
456 U_BOOT_DRIVER(pinctrl_rk3308) = {
457         .name           = "rockchip_rk3308_pinctrl",
458         .id             = UCLASS_PINCTRL,
459         .of_match       = rk3308_pinctrl_ids,
460         .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
461         .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 };