blob: bb56ae9fb343a59d2517f85819a36155e432e214 [file] [log] [blame]
David Wu8fb32682019-07-11 10:37:14 +02001// 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_route_data px30_mux_route_data[] = {
15 {
16 /* cif-d2m0 */
17 .bank_num = 2,
18 .pin = 0,
19 .func = 1,
20 .route_offset = 0x184,
21 .route_val = BIT(16 + 7),
22 }, {
23 /* cif-d2m1 */
24 .bank_num = 3,
25 .pin = 3,
26 .func = 3,
27 .route_offset = 0x184,
28 .route_val = BIT(16 + 7) | BIT(7),
29 }, {
30 /* pdm-m0 */
31 .bank_num = 3,
32 .pin = 22,
33 .func = 2,
34 .route_offset = 0x184,
35 .route_val = BIT(16 + 8),
36 }, {
37 /* pdm-m1 */
38 .bank_num = 2,
39 .pin = 22,
40 .func = 1,
41 .route_offset = 0x184,
42 .route_val = BIT(16 + 8) | BIT(8),
43 }, {
44 /* uart2-rxm0 */
45 .bank_num = 1,
46 .pin = 27,
47 .func = 2,
48 .route_offset = 0x184,
49 .route_val = BIT(16 + 10),
50 }, {
51 /* uart2-rxm1 */
52 .bank_num = 2,
53 .pin = 14,
54 .func = 2,
55 .route_offset = 0x184,
56 .route_val = BIT(16 + 10) | BIT(10),
57 }, {
58 /* uart3-rxm0 */
59 .bank_num = 0,
60 .pin = 17,
61 .func = 2,
62 .route_offset = 0x184,
63 .route_val = BIT(16 + 9),
64 }, {
65 /* uart3-rxm1 */
66 .bank_num = 1,
67 .pin = 15,
68 .func = 2,
69 .route_offset = 0x184,
70 .route_val = BIT(16 + 9) | BIT(9),
71 },
72};
73
74static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
75{
76 struct rockchip_pinctrl_priv *priv = bank->priv;
77 int iomux_num = (pin / 8);
78 struct regmap *regmap;
79 int reg, ret, mask, mux_type;
80 u8 bit;
81 u32 data, route_reg, route_val;
82
83 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
84 ? priv->regmap_pmu : priv->regmap_base;
85
86 /* get basic quadrupel of mux registers and the correct reg inside */
87 mux_type = bank->iomux[iomux_num].type;
88 reg = bank->iomux[iomux_num].offset;
89 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
90
91 if (bank->route_mask & BIT(pin)) {
92 if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
93 &route_val)) {
94 ret = regmap_write(regmap, route_reg, route_val);
95 if (ret)
96 return ret;
97 }
98 }
99
100 data = (mask << (bit + 16));
101 data |= (mux & mask) << bit;
102 ret = regmap_write(regmap, reg, data);
103
104 return ret;
105}
106
107#define PX30_PULL_PMU_OFFSET 0x10
108#define PX30_PULL_GRF_OFFSET 0x60
109#define PX30_PULL_BITS_PER_PIN 2
110#define PX30_PULL_PINS_PER_REG 8
111#define PX30_PULL_BANK_STRIDE 16
112
113static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
114 int pin_num, struct regmap **regmap,
115 int *reg, u8 *bit)
116{
117 struct rockchip_pinctrl_priv *priv = bank->priv;
118
119 /* The first 32 pins of the first bank are located in PMU */
120 if (bank->bank_num == 0) {
121 *regmap = priv->regmap_pmu;
122 *reg = PX30_PULL_PMU_OFFSET;
123 } else {
124 *regmap = priv->regmap_base;
125 *reg = PX30_PULL_GRF_OFFSET;
126
127 /* correct the offset, as we're starting with the 2nd bank */
128 *reg -= 0x10;
129 *reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
130 }
131
132 *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
133 *bit = (pin_num % PX30_PULL_PINS_PER_REG);
134 *bit *= PX30_PULL_BITS_PER_PIN;
135}
136
137static int px30_set_pull(struct rockchip_pin_bank *bank,
138 int pin_num, int pull)
139{
140 struct regmap *regmap;
141 int reg, ret;
142 u8 bit, type;
143 u32 data;
144
145 if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
146 return -ENOTSUPP;
147
148 px30_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
149 type = bank->pull_type[pin_num / 8];
150 ret = rockchip_translate_pull_value(type, pull);
151 if (ret < 0) {
152 debug("unsupported pull setting %d\n", pull);
153 return ret;
154 }
155
156 /* enable the write to the equivalent lower bits */
157 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
158 data |= (ret << bit);
159 ret = regmap_write(regmap, reg, data);
160
161 return ret;
162}
163
164#define PX30_DRV_PMU_OFFSET 0x20
165#define PX30_DRV_GRF_OFFSET 0xf0
166#define PX30_DRV_BITS_PER_PIN 2
167#define PX30_DRV_PINS_PER_REG 8
168#define PX30_DRV_BANK_STRIDE 16
169
170static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
171 int pin_num, struct regmap **regmap,
172 int *reg, u8 *bit)
173{
174 struct rockchip_pinctrl_priv *priv = bank->priv;
175
176 /* The first 32 pins of the first bank are located in PMU */
177 if (bank->bank_num == 0) {
178 *regmap = priv->regmap_pmu;
179 *reg = PX30_DRV_PMU_OFFSET;
180 } else {
181 *regmap = priv->regmap_base;
182 *reg = PX30_DRV_GRF_OFFSET;
183
184 /* correct the offset, as we're starting with the 2nd bank */
185 *reg -= 0x10;
186 *reg += bank->bank_num * PX30_DRV_BANK_STRIDE;
187 }
188
189 *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
190 *bit = (pin_num % PX30_DRV_PINS_PER_REG);
191 *bit *= PX30_DRV_BITS_PER_PIN;
192}
193
194static int px30_set_drive(struct rockchip_pin_bank *bank,
195 int pin_num, int strength)
196{
197 struct regmap *regmap;
198 int reg, ret;
199 u32 data, rmask_bits, temp;
200 u8 bit;
201 int drv_type = bank->drv[pin_num / 8].drv_type;
202
203 px30_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
204 ret = rockchip_translate_drive_value(drv_type, strength);
205 if (ret < 0) {
206 debug("unsupported driver strength %d\n", strength);
207 return ret;
208 }
209
210 switch (drv_type) {
211 case DRV_TYPE_IO_1V8_3V0_AUTO:
212 case DRV_TYPE_IO_3V3_ONLY:
213 rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
214 switch (bit) {
215 case 0 ... 12:
216 /* regular case, nothing to do */
217 break;
218 case 15:
219 /*
220 * drive-strength offset is special, as it is spread
221 * over 2 registers, the bit data[15] contains bit 0
222 * of the value while temp[1:0] contains bits 2 and 1
223 */
224 data = (ret & 0x1) << 15;
225 temp = (ret >> 0x1) & 0x3;
226
227 data |= BIT(31);
228 ret = regmap_write(regmap, reg, data);
229 if (ret)
230 return ret;
231
232 temp |= (0x3 << 16);
233 reg += 0x4;
234 ret = regmap_write(regmap, reg, temp);
235
236 return ret;
237 case 18 ... 21:
238 /* setting fully enclosed in the second register */
239 reg += 4;
240 bit -= 16;
241 break;
242 default:
243 debug("unsupported bit: %d for pinctrl drive type: %d\n",
244 bit, drv_type);
245 return -EINVAL;
246 }
247 break;
248 case DRV_TYPE_IO_DEFAULT:
249 case DRV_TYPE_IO_1V8_OR_3V0:
250 case DRV_TYPE_IO_1V8_ONLY:
251 rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
252 break;
253 default:
254 debug("unsupported pinctrl drive type: %d\n",
255 drv_type);
256 return -EINVAL;
257 }
258
259 /* enable the write to the equivalent lower bits */
260 data = ((1 << rmask_bits) - 1) << (bit + 16);
261 data |= (ret << bit);
262 ret = regmap_write(regmap, reg, data);
263
264 return ret;
265}
266
267#define PX30_SCHMITT_PMU_OFFSET 0x38
268#define PX30_SCHMITT_GRF_OFFSET 0xc0
269#define PX30_SCHMITT_PINS_PER_PMU_REG 16
270#define PX30_SCHMITT_BANK_STRIDE 16
271#define PX30_SCHMITT_PINS_PER_GRF_REG 8
272
273static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
274 int pin_num,
275 struct regmap **regmap,
276 int *reg, u8 *bit)
277{
278 struct rockchip_pinctrl_priv *priv = bank->priv;
279 int pins_per_reg;
280
281 if (bank->bank_num == 0) {
282 *regmap = priv->regmap_pmu;
283 *reg = PX30_SCHMITT_PMU_OFFSET;
284 pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG;
285 } else {
286 *regmap = priv->regmap_base;
287 *reg = PX30_SCHMITT_GRF_OFFSET;
288 pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG;
289 *reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE;
290 }
291 *reg += ((pin_num / pins_per_reg) * 4);
292 *bit = pin_num % pins_per_reg;
293
294 return 0;
295}
296
297static int px30_set_schmitt(struct rockchip_pin_bank *bank,
298 int pin_num, int enable)
299{
300 struct regmap *regmap;
301 int reg;
302 u8 bit;
303 u32 data;
304
305 px30_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
306 /* enable the write to the equivalent lower bits */
307 data = BIT(bit + 16) | (enable << bit);
308
309 return regmap_write(regmap, reg, data);
310}
311
312static struct rockchip_pin_bank px30_pin_banks[] = {
313 PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
314 IOMUX_SOURCE_PMU,
315 IOMUX_SOURCE_PMU,
316 IOMUX_SOURCE_PMU
317 ),
318 PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
319 IOMUX_WIDTH_4BIT,
320 IOMUX_WIDTH_4BIT,
321 IOMUX_WIDTH_4BIT
322 ),
323 PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
324 IOMUX_WIDTH_4BIT,
325 IOMUX_WIDTH_4BIT,
326 IOMUX_WIDTH_4BIT
327 ),
328 PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
329 IOMUX_WIDTH_4BIT,
330 IOMUX_WIDTH_4BIT,
331 IOMUX_WIDTH_4BIT
332 ),
333};
334
335static struct rockchip_pin_ctrl px30_pin_ctrl = {
336 .pin_banks = px30_pin_banks,
337 .nr_banks = ARRAY_SIZE(px30_pin_banks),
338 .grf_mux_offset = 0x0,
339 .pmu_mux_offset = 0x0,
340 .grf_drv_offset = 0xf0,
341 .pmu_drv_offset = 0x20,
342 .iomux_routes = px30_mux_route_data,
343 .niomux_routes = ARRAY_SIZE(px30_mux_route_data),
344 .set_mux = px30_set_mux,
345 .set_pull = px30_set_pull,
346 .set_drive = px30_set_drive,
347 .set_schmitt = px30_set_schmitt,
348};
349
350static const struct udevice_id px30_pinctrl_ids[] = {
351 {
352 .compatible = "rockchip,px30-pinctrl",
353 .data = (ulong)&px30_pin_ctrl
354 },
355 { }
356};
357
358U_BOOT_DRIVER(pinctrl_px30) = {
359 .name = "rockchip_px30_pinctrl",
360 .id = UCLASS_PINCTRL,
361 .of_match = px30_pinctrl_ids,
362 .priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
363 .ops = &rockchip_pinctrl_ops,
364#if !CONFIG_IS_ENABLED(OF_PLATDATA)
365 .bind = dm_scan_fdt_dev,
366#endif
367 .probe = rockchip_pinctrl_probe,
368};