]> Git Repo - J-u-boot.git/blob - drivers/pinctrl/rockchip/pinctrl-rk3399.c
Merge patch series "Add AM64x Support to PRUSS and PRU_RPROC driver"
[J-u-boot.git] / drivers / pinctrl / rockchip / pinctrl-rk3399.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
4  */
5
6 #include <dm.h>
7 #include <log.h>
8 #include <dm/pinctrl.h>
9 #include <regmap.h>
10 #include <syscon.h>
11 #include <linux/bitops.h>
12
13 #include "pinctrl-rockchip.h"
14
15 static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
16         {
17                 /* uart2dbga_rx */
18                 .bank_num = 4,
19                 .pin = 8,
20                 .func = 2,
21                 .route_offset = 0xe21c,
22                 .route_val = BIT(16 + 10) | BIT(16 + 11),
23         }, {
24                 /* uart2dbgb_rx */
25                 .bank_num = 4,
26                 .pin = 16,
27                 .func = 2,
28                 .route_offset = 0xe21c,
29                 .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
30         }, {
31                 /* uart2dbgc_rx */
32                 .bank_num = 4,
33                 .pin = 19,
34                 .func = 1,
35                 .route_offset = 0xe21c,
36                 .route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
37         }, {
38                 /* pcie_clkreqn */
39                 .bank_num = 2,
40                 .pin = 26,
41                 .func = 2,
42                 .route_offset = 0xe21c,
43                 .route_val = BIT(16 + 14),
44         }, {
45                 /* pcie_clkreqnb */
46                 .bank_num = 4,
47                 .pin = 24,
48                 .func = 1,
49                 .route_offset = 0xe21c,
50                 .route_val = BIT(16 + 14) | BIT(14),
51         },
52 };
53
54 static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
55 {
56         struct rockchip_pinctrl_priv *priv = bank->priv;
57         int iomux_num = (pin / 8);
58         struct regmap *regmap;
59         int reg, ret, mask, mux_type;
60         u8 bit;
61         u32 data;
62
63         regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
64                                 ? priv->regmap_pmu : priv->regmap_base;
65
66         /* get basic quadrupel of mux registers and the correct reg inside */
67         mux_type = bank->iomux[iomux_num].type;
68         reg = bank->iomux[iomux_num].offset;
69         reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
70
71         data = (mask << (bit + 16));
72         data |= (mux & mask) << bit;
73         ret = regmap_write(regmap, reg, data);
74
75         return ret;
76 }
77
78 #define RK3399_PULL_GRF_OFFSET          0xe040
79 #define RK3399_PULL_PMU_OFFSET          0x40
80
81 static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
82                                          int pin_num, struct regmap **regmap,
83                                          int *reg, u8 *bit)
84 {
85         struct rockchip_pinctrl_priv *priv = bank->priv;
86
87         /* The bank0:16 and bank1:32 pins are located in PMU */
88         if (bank->bank_num == 0 || bank->bank_num == 1) {
89                 *regmap = priv->regmap_pmu;
90                 *reg = RK3399_PULL_PMU_OFFSET;
91
92                 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
93         } else {
94                 *regmap = priv->regmap_base;
95                 *reg = RK3399_PULL_GRF_OFFSET;
96
97                 /* correct the offset, as we're starting with the 3rd bank */
98                 *reg -= 0x20;
99                 *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
100         }
101
102         *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
103
104         *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
105         *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
106 }
107
108 static int rk3399_set_pull(struct rockchip_pin_bank *bank,
109                            int pin_num, int pull)
110 {
111         struct regmap *regmap;
112         int reg, ret;
113         u8 bit, type;
114         u32 data;
115
116         if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
117                 return -ENOTSUPP;
118
119         rk3399_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
120         type = bank->pull_type[pin_num / 8];
121         ret = rockchip_translate_pull_value(type, pull);
122         if (ret < 0) {
123                 debug("unsupported pull setting %d\n", pull);
124                 return ret;
125         }
126
127         /* enable the write to the equivalent lower bits */
128         data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
129         data |= (ret << bit);
130         ret = regmap_write(regmap, reg, data);
131
132         return ret;
133 }
134
135 static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
136                                         int pin_num, struct regmap **regmap,
137                                         int *reg, u8 *bit)
138 {
139         struct rockchip_pinctrl_priv *priv = bank->priv;
140         int drv_num = (pin_num / 8);
141
142         /*  The bank0:16 and bank1:32 pins are located in PMU */
143         if (bank->bank_num == 0 || bank->bank_num == 1)
144                 *regmap = priv->regmap_pmu;
145         else
146                 *regmap = priv->regmap_base;
147
148         *reg = bank->drv[drv_num].offset;
149         if (bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO ||
150             bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY)
151                 *bit = (pin_num % 8) * 3;
152         else
153                 *bit = (pin_num % 8) * 2;
154 }
155
156 static int rk3399_set_drive(struct rockchip_pin_bank *bank,
157                             int pin_num, int strength)
158 {
159         struct regmap *regmap;
160         int reg, ret;
161         u32 data, rmask_bits, temp;
162         u8 bit;
163         int drv_type = bank->drv[pin_num / 8].drv_type;
164
165         rk3399_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
166         ret = rockchip_translate_drive_value(drv_type, strength);
167         if (ret < 0) {
168                 debug("unsupported driver strength %d\n", strength);
169                 return ret;
170         }
171
172         switch (drv_type) {
173         case DRV_TYPE_IO_1V8_3V0_AUTO:
174         case DRV_TYPE_IO_3V3_ONLY:
175                 rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
176                 switch (bit) {
177                 case 0 ... 12:
178                         /* regular case, nothing to do */
179                         break;
180                 case 15:
181                         /*
182                          * drive-strength offset is special, as it is spread
183                          * over 2 registers, the bit data[15] contains bit 0
184                          * of the value while temp[1:0] contains bits 2 and 1
185                          */
186                         data = (ret & 0x1) << 15;
187                         temp = (ret >> 0x1) & 0x3;
188
189                         data |= BIT(31);
190                         ret = regmap_write(regmap, reg, data);
191                         if (ret)
192                                 return ret;
193
194                         temp |= (0x3 << 16);
195                         reg += 0x4;
196                         ret = regmap_write(regmap, reg, temp);
197
198                         return ret;
199                 case 18 ... 21:
200                         /* setting fully enclosed in the second register */
201                         reg += 4;
202                         bit -= 16;
203                         break;
204                 default:
205                         debug("unsupported bit: %d for pinctrl drive type: %d\n",
206                               bit, drv_type);
207                         return -EINVAL;
208                 }
209                 break;
210         case DRV_TYPE_IO_DEFAULT:
211         case DRV_TYPE_IO_1V8_OR_3V0:
212         case DRV_TYPE_IO_1V8_ONLY:
213                 rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
214                 break;
215         default:
216                 debug("unsupported pinctrl drive type: %d\n",
217                       drv_type);
218                 return -EINVAL;
219         }
220
221         /* enable the write to the equivalent lower bits */
222         data = ((1 << rmask_bits) - 1) << (bit + 16);
223         data |= (ret << bit);
224         ret = regmap_write(regmap, reg, data);
225
226         return ret;
227 }
228
229 static struct rockchip_pin_bank rk3399_pin_banks[] = {
230         PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0",
231                                                          IOMUX_SOURCE_PMU,
232                                                          IOMUX_SOURCE_PMU,
233                                                          IOMUX_SOURCE_PMU,
234                                                          IOMUX_SOURCE_PMU,
235                                                          DRV_TYPE_IO_1V8_ONLY,
236                                                          DRV_TYPE_IO_1V8_ONLY,
237                                                          DRV_TYPE_IO_DEFAULT,
238                                                          DRV_TYPE_IO_DEFAULT,
239                                                          0x80,
240                                                          0x88,
241                                                          -1,
242                                                          -1,
243                                                          PULL_TYPE_IO_1V8_ONLY,
244                                                          PULL_TYPE_IO_1V8_ONLY,
245                                                          PULL_TYPE_IO_DEFAULT,
246                                                          PULL_TYPE_IO_DEFAULT
247                                                         ),
248         PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
249                                         IOMUX_SOURCE_PMU,
250                                         IOMUX_SOURCE_PMU,
251                                         IOMUX_SOURCE_PMU,
252                                         DRV_TYPE_IO_1V8_OR_3V0,
253                                         DRV_TYPE_IO_1V8_OR_3V0,
254                                         DRV_TYPE_IO_1V8_OR_3V0,
255                                         DRV_TYPE_IO_1V8_OR_3V0,
256                                         0xa0,
257                                         0xa8,
258                                         0xb0,
259                                         0xb8
260                                         ),
261         PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
262                                       DRV_TYPE_IO_1V8_OR_3V0,
263                                       DRV_TYPE_IO_1V8_ONLY,
264                                       DRV_TYPE_IO_1V8_ONLY,
265                                       PULL_TYPE_IO_DEFAULT,
266                                       PULL_TYPE_IO_DEFAULT,
267                                       PULL_TYPE_IO_1V8_ONLY,
268                                       PULL_TYPE_IO_1V8_ONLY
269                                       ),
270         PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
271                            DRV_TYPE_IO_3V3_ONLY,
272                            DRV_TYPE_IO_3V3_ONLY,
273                            DRV_TYPE_IO_1V8_OR_3V0
274                            ),
275         PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0,
276                            DRV_TYPE_IO_1V8_3V0_AUTO,
277                            DRV_TYPE_IO_1V8_OR_3V0,
278                            DRV_TYPE_IO_1V8_OR_3V0
279                            ),
280 };
281
282 static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
283         .pin_banks              = rk3399_pin_banks,
284         .nr_banks               = ARRAY_SIZE(rk3399_pin_banks),
285         .grf_mux_offset         = 0xe000,
286         .pmu_mux_offset         = 0x0,
287         .grf_drv_offset         = 0xe100,
288         .pmu_drv_offset         = 0x80,
289         .iomux_routes           = rk3399_mux_route_data,
290         .niomux_routes          = ARRAY_SIZE(rk3399_mux_route_data),
291         .set_mux                = rk3399_set_mux,
292         .set_pull               = rk3399_set_pull,
293         .set_drive              = rk3399_set_drive,
294 };
295
296 static const struct udevice_id rk3399_pinctrl_ids[] = {
297         {
298                 .compatible = "rockchip,rk3399-pinctrl",
299                 .data = (ulong)&rk3399_pin_ctrl
300         },
301         { }
302 };
303
304 U_BOOT_DRIVER(pinctrl_rk3399) = {
305         .name           = "rockchip_rk3399_pinctrl",
306         .id             = UCLASS_PINCTRL,
307         .of_match       = rk3399_pinctrl_ids,
308         .priv_auto      = sizeof(struct rockchip_pinctrl_priv),
309         .ops            = &rockchip_pinctrl_ops,
310 #if CONFIG_IS_ENABLED(OF_REAL)
311         .bind           = dm_scan_fdt_dev,
312 #endif
313         .probe          = rockchip_pinctrl_probe,
314 };
This page took 0.04561 seconds and 4 git commands to generate.