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