xref: /linux/drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c (revision d2c9a99135da931377240942d44f3dea104cedb8)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/bitfield.h>
4 #include <linux/module.h>
5 #include <linux/mfd/syscon.h>
6 #include <linux/of.h>
7 #include <linux/platform_device.h>
8 #include <linux/regmap.h>
9 #include <linux/seq_file.h>
10 
11 #include <linux/pinctrl/pinconf-generic.h>
12 #include <linux/pinctrl/pinconf.h>
13 #include <linux/pinctrl/pinctrl.h>
14 #include <linux/pinctrl/pinmux.h>
15 
16 #include "../core.h"
17 #include "../pinctrl-utils.h"
18 #include "../pinconf.h"
19 #include "../pinmux.h"
20 
21 #define MPFS_PINCTRL_PAD_MUX_MASK GENMASK(3, 0)
22 
23 #define MPFS_PINCTRL_IOCFG_MASK GENMASK(14, 0)
24 #define MPFS_PINCTRL_IBUFMD_MASK GENMASK(2, 0)
25 #define MPFS_PINCTRL_DRV_MASK GENMASK(6, 3)
26 #define MPFS_PINCTRL_CLAMP BIT(7)
27 #define MPFS_PINCTRL_ENHYST BIT(8)
28 #define MPFS_PINCTRL_LOCKDN BIT(9)
29 #define MPFS_PINCTRL_WPD BIT(10)
30 #define MPFS_PINCTRL_WPU BIT(11)
31 #define MPFS_PINCTRL_PULL_MASK GENMASK(11, 10)
32 #define MPFS_PINCTRL_LP_PERSIST_EN BIT(12)
33 #define MPFS_PINCTRL_LP_BYPASS_EN BIT(13)
34 
35 #define MPFS_PINCTRL_MSSIO_BANK2_CFG_CR 0x1c4
36 #define MPFS_PINCTRL_MSSIO_BANK4_CFG_CR 0x1c8
37 #define MPFS_PINCTRL_BANK_VOLTAGE_MASK GENMASK(19, 16)
38 
39 #define MPFS_PINCTRL_IOCFG01_REG 0x234
40 
41 #define MPFS_PINCTRL_INTER_BANK_GAP 0x4
42 
43 #define MPFS_PINCTRL_BANK2_START 14
44 
45 #define MPFS_PINCTRL_LOCKDOWN (PIN_CONFIG_END + 1)
46 #define MPFS_PINCTRL_CLAMP_DIODE (PIN_CONFIG_END + 2)
47 #define MPFS_PINCTRL_IBUFMD (PIN_CONFIG_END + 3)
48 
49 struct mpfs_pinctrl_mux_config {
50 	u8 pin;
51 	u8 function;
52 };
53 
54 struct mpfs_pinctrl {
55 	struct pinctrl_dev *pctrl;
56 	struct device *dev;
57 	struct regmap *regmap;
58 	struct regmap *sysreg_regmap;
59 	struct mutex mutex;
60 	struct pinctrl_desc desc;
61 };
62 
63 struct mpfs_pinctrl_drive_strength {
64 	u8 ma;
65 	u8 val;
66 };
67 
68 struct mpfs_pinctrl_bank_voltage {
69 	u32 uv;
70 	u8 val;
71 };
72 
73 static struct mpfs_pinctrl_drive_strength mpfs_pinctrl_drive_strengths[8] = {
74 	{ .ma = 2, .val = 2 },
75 	{ .ma = 4, .val = 3 },
76 	{ .ma = 6, .val = 4 },
77 	{ .ma = 8, .val = 5 },
78 	{ .ma = 10, .val = 6 },
79 	{ .ma = 12, .val = 7 },
80 	{ .ma = 16, .val = 10 },
81 	{ .ma = 20, .val = 12 },
82 };
83 static struct mpfs_pinctrl_bank_voltage mpfs_pinctrl_bank_voltages[8] = {
84 	{ .uv = 1200000, .val = 0 },
85 	{ .uv = 1500000, .val = 2 },
86 	{ .uv = 1800000, .val = 4 },
87 	{ .uv = 2500000, .val = 6 },
88 	{ .uv = 3300000, .val = 8 },
89 	{ .uv = 0, .val = 0x3f }, // pin unused
90 };
91 
mpfs_pinctrl_get_drive_strength_ma(u32 drive_strength)92 static int mpfs_pinctrl_get_drive_strength_ma(u32 drive_strength)
93 {
94 	size_t num = ARRAY_SIZE(mpfs_pinctrl_drive_strengths);
95 
96 	for (int i = 0; i < num; i++)
97 		if (drive_strength == mpfs_pinctrl_drive_strengths[i].val)
98 			return mpfs_pinctrl_drive_strengths[i].ma;
99 
100 	return -EINVAL;
101 }
102 
mpfs_pinctrl_get_drive_strength_val(u32 drive_strength_ma)103 static int mpfs_pinctrl_get_drive_strength_val(u32 drive_strength_ma)
104 {
105 	size_t num = ARRAY_SIZE(mpfs_pinctrl_drive_strengths);
106 
107 	if (!drive_strength_ma)
108 		return -EINVAL;
109 
110 	for (int i = 0; i < num; i++)
111 		if (drive_strength_ma <= mpfs_pinctrl_drive_strengths[i].ma)
112 			return mpfs_pinctrl_drive_strengths[i].val;
113 
114 	return mpfs_pinctrl_drive_strengths[num - 1].val;
115 }
116 
mpfs_pinctrl_get_bank_voltage_uv(u32 bank_voltage)117 static int mpfs_pinctrl_get_bank_voltage_uv(u32 bank_voltage)
118 {
119 	size_t num = ARRAY_SIZE(mpfs_pinctrl_bank_voltages);
120 
121 	for (int i = 0; i < num; i++)
122 		if (bank_voltage == mpfs_pinctrl_bank_voltages[i].val)
123 			return mpfs_pinctrl_bank_voltages[i].uv;
124 
125 	return -EINVAL;
126 }
127 
mpfs_pinctrl_get_bank_voltage_val(u32 bank_voltage_uv)128 static int mpfs_pinctrl_get_bank_voltage_val(u32 bank_voltage_uv)
129 {
130 	size_t num = ARRAY_SIZE(mpfs_pinctrl_bank_voltages);
131 
132 	for (int i = 0; i < num; i++)
133 		if (bank_voltage_uv <= mpfs_pinctrl_bank_voltages[i].uv)
134 			return mpfs_pinctrl_bank_voltages[i].val;
135 
136 	return -EINVAL;
137 }
138 
mpfs_pinctrl_pin_to_bank_voltage(struct mpfs_pinctrl * pctrl,unsigned int pin)139 static u32 mpfs_pinctrl_pin_to_bank_voltage(struct mpfs_pinctrl *pctrl, unsigned int pin)
140 {
141 	u32 bank_voltage, val;
142 
143 	if (pin < MPFS_PINCTRL_BANK2_START)
144 		regmap_read(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK4_CFG_CR, &val);
145 	else
146 		regmap_read(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK2_CFG_CR, &val);
147 
148 	bank_voltage = FIELD_GET(MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
149 
150 	return mpfs_pinctrl_get_bank_voltage_uv(bank_voltage);
151 }
152 
mpfs_pinctrl_set_bank_voltage(struct mpfs_pinctrl * pctrl,unsigned int pin,u32 bank_voltage)153 static void mpfs_pinctrl_set_bank_voltage(struct mpfs_pinctrl *pctrl, unsigned int pin,
154 					  u32 bank_voltage)
155 {
156 	u32 val = FIELD_PREP(MPFS_PINCTRL_BANK_VOLTAGE_MASK, bank_voltage);
157 
158 	if (pin < MPFS_PINCTRL_BANK2_START)
159 		regmap_assign_bits(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK4_CFG_CR,
160 				   MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
161 	else
162 		regmap_assign_bits(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK2_CFG_CR,
163 				   MPFS_PINCTRL_BANK_VOLTAGE_MASK, val);
164 }
165 
166 static char *mpfs_pinctrl_function_names[] = {
167 	"sd",
168 	"emmc",
169 	"qspi",
170 	"spi",
171 	"usb",
172 	"uart",
173 	"i2c",
174 	"can",
175 	"mdio",
176 	"misc",
177 	"reserved",
178 	"gpio",
179 	"fabric test",
180 	"tied-low",
181 	"tied-high",
182 	"tristate"
183 };
184 
mpfs_pinctrl_function_map(const char * function)185 static int mpfs_pinctrl_function_map(const char *function)
186 {
187 	size_t num = ARRAY_SIZE(mpfs_pinctrl_function_names);
188 
189 	for (int i = 0; i < num; i++)
190 		if (!strcmp(function, mpfs_pinctrl_function_names[i]))
191 			return i;
192 
193 	return -EINVAL;
194 }
195 
196 static const struct pinconf_generic_params mpfs_pinctrl_custom_bindings[] = {
197 	{ "microchip,clamp-diode", MPFS_PINCTRL_CLAMP_DIODE, 1 },
198 	{ "microchip,ibufmd", MPFS_PINCTRL_IBUFMD, 0x0 },
199 };
200 
mpfs_pinctrl_pin_to_iomux_offset(unsigned int pin)201 static int mpfs_pinctrl_pin_to_iomux_offset(unsigned int pin)
202 {
203 	int offset;
204 
205 	switch (pin) {
206 	case 0 ... 7:
207 		offset = pin * 4;
208 		break;
209 	case 8 ... 13:
210 		offset = (pin - 8) * 4;
211 		break;
212 	case 14 ... 21:
213 		offset = (pin - 14) * 4;
214 		break;
215 	case 22 ... 29:
216 		offset = (pin - 22) * 4;
217 		break;
218 	case 30 ... 37:
219 		offset = (pin - 30) * 4;
220 		break;
221 	default:
222 		offset = -EINVAL;
223 	}
224 
225 	return offset;
226 }
227 
mpfs_pinctrl_pin_to_iomux_reg(unsigned int pin)228 static int mpfs_pinctrl_pin_to_iomux_reg(unsigned int pin)
229 {
230 	int reg;
231 
232 	switch (pin) {
233 	case 0 ... 7:
234 		reg = 0x204;
235 		break;
236 	case 8 ... 13:
237 		reg = 0x208;
238 		break;
239 	case 14 ... 21:
240 		reg = 0x20c;
241 		break;
242 	case 22 ... 29:
243 		reg = 0x210;
244 		break;
245 	case 30 ... 37:
246 		reg = 0x214;
247 		break;
248 	default:
249 		reg = -EINVAL;
250 	}
251 
252 	return reg;
253 }
254 
mpfs_pinctrl_pin_to_iocfg_reg(unsigned int pin)255 static int mpfs_pinctrl_pin_to_iocfg_reg(unsigned int pin)
256 {
257 	u32 reg = MPFS_PINCTRL_IOCFG01_REG;
258 
259 	if (pin >= MPFS_PINCTRL_BANK2_START)
260 		reg += MPFS_PINCTRL_INTER_BANK_GAP;
261 
262 	// 2 pins per 32-bit register
263 	reg += (pin / 2) * 0x4;
264 
265 	return reg;
266 }
267 
mpfs_pinctrl_pin_to_iocfg_offset(unsigned int pin)268 static int mpfs_pinctrl_pin_to_iocfg_offset(unsigned int pin)
269 {
270 	return 16 * (pin % 2);
271 }
272 
mpfs_pinctrl_dbg_show(struct pinctrl_dev * pctrl_dev,struct seq_file * seq,unsigned int pin)273 static void mpfs_pinctrl_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq,
274 				  unsigned int pin)
275 {
276 	struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
277 	u32 func;
278 	int reg, offset;
279 
280 	reg = mpfs_pinctrl_pin_to_iomux_reg(pin);
281 	offset = mpfs_pinctrl_pin_to_iomux_offset(pin);
282 
283 	seq_printf(seq, "reg: %x, offset: %u ", reg, offset);
284 	seq_printf(seq, "pin: %u ", pin);
285 
286 	if (reg < 0 || offset < 0)
287 		return;
288 
289 	regmap_read(pctrl->regmap, reg, &func);
290 	func = (func >> offset) & MPFS_PINCTRL_PAD_MUX_MASK;
291 	seq_printf(seq, "func: %s (%x)\n", mpfs_pinctrl_function_names[func], func);
292 }
293 
294 static const struct pinctrl_ops mpfs_pinctrl_ops = {
295 	.get_groups_count = pinctrl_generic_get_group_count,
296 	.get_group_name	= pinctrl_generic_get_group_name,
297 	.get_group_pins	= pinctrl_generic_get_group_pins,
298 	.pin_dbg_show = mpfs_pinctrl_dbg_show,
299 	.dt_node_to_map = pinctrl_generic_pins_function_dt_node_to_map,
300 	.dt_free_map = pinctrl_utils_free_map,
301 };
302 
mpfs_pinctrl_set_pin_func(struct mpfs_pinctrl * pctrl,u8 pin,u8 function)303 static int mpfs_pinctrl_set_pin_func(struct mpfs_pinctrl *pctrl, u8 pin, u8 function)
304 {
305 	struct device *dev = pctrl->dev;
306 	int reg, offset;
307 	u32 func, mask;
308 
309 	reg = mpfs_pinctrl_pin_to_iomux_reg(pin);
310 	offset = mpfs_pinctrl_pin_to_iomux_offset(pin);
311 
312 	func = function << offset;
313 	mask = MPFS_PINCTRL_PAD_MUX_MASK << offset;
314 
315 	dev_dbg(dev, "Setting pin %u. reg: %x offset %u func %x\n", pin, reg, offset, func);
316 
317 	if (reg < 0 || offset < 0)
318 		return -EINVAL;
319 
320 	regmap_update_bits(pctrl->regmap, reg, mask, func);
321 
322 	return 0;
323 }
324 
mpfs_pinctrl_set_mux(struct pinctrl_dev * pctrl_dev,unsigned int fsel,unsigned int gsel)325 static int mpfs_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev, unsigned int fsel,
326 				unsigned int gsel)
327 {
328 	struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
329 	const struct group_desc *group;
330 	const char **functions;
331 
332 	group = pinctrl_generic_get_group(pctrl_dev, gsel);
333 	if (!group)
334 		return -EINVAL;
335 
336 	functions = group->data;
337 
338 	for (int i = 0; i < group->grp.npins; i++) {
339 		int function;
340 
341 		function = mpfs_pinctrl_function_map(functions[i]);
342 		if (function < 0) {
343 			dev_err(pctrl->dev, "invalid function %s\n", functions[i]);
344 			return function;
345 		}
346 
347 		mpfs_pinctrl_set_pin_func(pctrl, group->grp.pins[i], function);
348 	}
349 
350 	return 0;
351 }
352 
353 static const struct pinmux_ops mpfs_pinctrl_pinmux_ops = {
354 	.get_functions_count	= pinmux_generic_get_function_count,
355 	.get_function_name	= pinmux_generic_get_function_name,
356 	.get_function_groups	= pinmux_generic_get_function_groups,
357 	.set_mux		= mpfs_pinctrl_set_mux,
358 };
359 
mpfs_pinctrl_pinconf_get(struct pinctrl_dev * pctrl_dev,unsigned int pin,unsigned long * config)360 static int mpfs_pinctrl_pinconf_get(struct pinctrl_dev *pctrl_dev, unsigned int pin,
361 				    unsigned long *config)
362 {
363 	struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
364 	int param = pinconf_to_config_param(*config);
365 	int reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
366 	int val;
367 	u32 arg;
368 	u8 str;
369 
370 	regmap_read(pctrl->regmap, reg, &val);
371 
372 	val = val >> mpfs_pinctrl_pin_to_iocfg_offset(pin);
373 	val = val & MPFS_PINCTRL_IOCFG_MASK;
374 
375 	switch (param) {
376 	case PIN_CONFIG_BIAS_BUS_HOLD:
377 		if (!(val & MPFS_PINCTRL_WPD))
378 			return -EINVAL;
379 
380 		if (!(val & MPFS_PINCTRL_WPU))
381 			return -EINVAL;
382 
383 		arg = 1;
384 		break;
385 	case PIN_CONFIG_BIAS_PULL_DOWN:
386 		if (!(val & MPFS_PINCTRL_WPD))
387 			return -EINVAL;
388 
389 		if (val & MPFS_PINCTRL_WPU)
390 			return -EINVAL;
391 
392 		arg = 1;
393 		break;
394 	case PIN_CONFIG_BIAS_PULL_UP:
395 		if (!(val & MPFS_PINCTRL_WPU))
396 			return -EINVAL;
397 
398 		if (val & MPFS_PINCTRL_WPD)
399 			return -EINVAL;
400 
401 		arg = 1;
402 		break;
403 	case PIN_CONFIG_BIAS_DISABLE:
404 		if (val & MPFS_PINCTRL_PULL_MASK)
405 			return -EINVAL;
406 
407 		arg = 1;
408 		break;
409 	case PIN_CONFIG_DRIVE_STRENGTH:
410 		str = FIELD_GET(MPFS_PINCTRL_DRV_MASK, val);
411 		if (!str)
412 			return -EINVAL;
413 
414 		arg = mpfs_pinctrl_get_drive_strength_ma(str);
415 		break;
416 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
417 		if (!FIELD_GET(MPFS_PINCTRL_ENHYST, val))
418 			return -EINVAL;
419 
420 		arg = 1;
421 		break;
422 	case PIN_CONFIG_PERSIST_STATE:
423 		if (!FIELD_GET(MPFS_PINCTRL_LP_PERSIST_EN, val))
424 			return -EINVAL;
425 
426 		arg = 1;
427 		break;
428 	case PIN_CONFIG_MODE_LOW_POWER:
429 		if (!FIELD_GET(MPFS_PINCTRL_LP_BYPASS_EN, val))
430 			return -EINVAL;
431 
432 		arg = 1;
433 		break;
434 	case PIN_CONFIG_POWER_SOURCE:
435 		arg = mpfs_pinctrl_pin_to_bank_voltage(pctrl, pin);
436 		break;
437 	case MPFS_PINCTRL_CLAMP_DIODE:
438 		if (!FIELD_GET(MPFS_PINCTRL_CLAMP, val))
439 			return -EINVAL;
440 
441 		arg = 1;
442 		break;
443 	case MPFS_PINCTRL_LOCKDOWN:
444 		/*
445 		 * Lockdown is a read-only configuration, it'll get set if the
446 		 * tamper unit triggers global lockdown and lockdown has been
447 		 * set in the MSS Configurator for the bank a pin belongs to.
448 		 */
449 		if (!FIELD_GET(MPFS_PINCTRL_LOCKDN, val))
450 			return -EINVAL;
451 
452 		arg = 1;
453 		break;
454 	case MPFS_PINCTRL_IBUFMD:
455 		arg = FIELD_GET(MPFS_PINCTRL_IBUFMD_MASK, val);
456 		break;
457 	default:
458 		return -ENOTSUPP;
459 	}
460 
461 	*config = pinconf_to_config_packed(param, arg);
462 
463 	return 0;
464 }
465 
mpfs_pinctrl_pinconf_generate_config(struct mpfs_pinctrl * pctrl,unsigned int pin,unsigned long * configs,unsigned int num_configs,u32 * value,u32 * bank_voltage)466 static int mpfs_pinctrl_pinconf_generate_config(struct mpfs_pinctrl *pctrl, unsigned int pin,
467 						unsigned long *configs, unsigned int num_configs,
468 						u32 *value, u32 *bank_voltage)
469 {
470 	u32 val = 0;
471 
472 	for (int i = 0; i < num_configs; i++) {
473 		int param, tmp;
474 		u32 arg;
475 
476 		param = pinconf_to_config_param(configs[i]);
477 		arg = pinconf_to_config_argument(configs[i]);
478 
479 		switch (param) {
480 		case PIN_CONFIG_BIAS_BUS_HOLD:
481 			val |= MPFS_PINCTRL_PULL_MASK;
482 			break;
483 		case PIN_CONFIG_BIAS_PULL_DOWN:
484 			val &= ~MPFS_PINCTRL_PULL_MASK;
485 			val |= MPFS_PINCTRL_WPD;
486 			break;
487 		case PIN_CONFIG_BIAS_PULL_UP:
488 			val &= ~MPFS_PINCTRL_PULL_MASK;
489 			val |= MPFS_PINCTRL_WPU;
490 			break;
491 		case PIN_CONFIG_BIAS_DISABLE:
492 			val &= ~MPFS_PINCTRL_PULL_MASK;
493 			break;
494 		case PIN_CONFIG_DRIVE_STRENGTH:
495 			tmp = mpfs_pinctrl_get_drive_strength_val(arg);
496 			if (tmp < 0)
497 				return tmp;
498 
499 			val |= FIELD_PREP(MPFS_PINCTRL_DRV_MASK, tmp);
500 			break;
501 		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
502 			if (!arg)
503 				break;
504 			val |= MPFS_PINCTRL_ENHYST;
505 			break;
506 		case PIN_CONFIG_PERSIST_STATE:
507 			val |= MPFS_PINCTRL_LP_PERSIST_EN;
508 			break;
509 		case PIN_CONFIG_MODE_LOW_POWER:
510 			if (arg)
511 				val |= MPFS_PINCTRL_LP_BYPASS_EN;
512 			break;
513 		case PIN_CONFIG_POWER_SOURCE:
514 			tmp = mpfs_pinctrl_get_bank_voltage_val(arg);
515 			if (tmp < 0)
516 				return tmp;
517 
518 			*bank_voltage = tmp;
519 			break;
520 		case MPFS_PINCTRL_CLAMP_DIODE:
521 			val |= MPFS_PINCTRL_CLAMP;
522 			break;
523 		case MPFS_PINCTRL_IBUFMD:
524 			val |= FIELD_PREP(MPFS_PINCTRL_IBUFMD_MASK, arg);
525 			break;
526 		default:
527 			dev_err(pctrl->dev, "config %u not supported\n", param);
528 			return -ENOTSUPP;
529 		}
530 	}
531 
532 	*value = val;
533 	return 0;
534 }
535 
mpfs_pinctrl_pin_set_config(struct mpfs_pinctrl * pctrl,unsigned int pin,u32 config)536 static int mpfs_pinctrl_pin_set_config(struct mpfs_pinctrl *pctrl, unsigned int pin, u32 config)
537 {
538 	int reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
539 	int offset = mpfs_pinctrl_pin_to_iocfg_offset(pin);
540 	u32 val, mask;
541 
542 	mask = MPFS_PINCTRL_IOCFG_MASK << offset;
543 	val = config << offset;
544 
545 	regmap_update_bits(pctrl->regmap, reg, mask, val);
546 
547 	return 0;
548 }
549 
mpfs_pinctrl_pinconf_set(struct pinctrl_dev * pctrl_dev,unsigned int pin,unsigned long * configs,unsigned int num_configs)550 static int mpfs_pinctrl_pinconf_set(struct pinctrl_dev *pctrl_dev, unsigned int pin,
551 				    unsigned long *configs, unsigned int num_configs)
552 {
553 	struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
554 	u32 val, bank_voltage = 0;
555 	int ret;
556 
557 	ret = mpfs_pinctrl_pinconf_generate_config(pctrl, pin, configs, num_configs, &val,
558 						   &bank_voltage);
559 	if (ret)
560 		return ret;
561 
562 	ret = mpfs_pinctrl_pin_set_config(pctrl, pin, val);
563 	if (ret)
564 		return ret;
565 
566 	if (bank_voltage)
567 		mpfs_pinctrl_set_bank_voltage(pctrl, pin, bank_voltage);
568 
569 	return 0;
570 }
571 
mpfs_pinctrl_pinconf_group_set(struct pinctrl_dev * pctrl_dev,unsigned int gsel,unsigned long * configs,unsigned int num_configs)572 static int mpfs_pinctrl_pinconf_group_set(struct pinctrl_dev *pctrl_dev, unsigned int gsel,
573 					  unsigned long *configs, unsigned int num_configs)
574 {
575 	struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
576 	const struct group_desc *group;
577 	unsigned int pin;
578 	u32 val, bank_voltage = 0;
579 	int ret;
580 
581 	group = pinctrl_generic_get_group(pctrl_dev, gsel);
582 	if (!group)
583 		return -EINVAL;
584 
585 	/*
586 	 * Assume that the first pin in a group is representative, as the mss
587 	 * configurator doesn't allow splitting a function between two banks.
588 	 */
589 	pin = group->grp.pins[0];
590 
591 	ret = mpfs_pinctrl_pinconf_generate_config(pctrl, pin, configs, num_configs, &val,
592 						   &bank_voltage);
593 	if (ret)
594 		return ret;
595 
596 	for (int i = 0; i < group->grp.npins; i++)
597 		mpfs_pinctrl_pin_set_config(pctrl, group->grp.pins[i], val);
598 
599 	if (bank_voltage)
600 		mpfs_pinctrl_set_bank_voltage(pctrl, group->grp.pins[0], bank_voltage);
601 
602 	return 0;
603 }
604 
mpfs_pinctrl_pinconf_dbg_show(struct pinctrl_dev * pctrl_dev,struct seq_file * seq,unsigned int pin)605 static void mpfs_pinctrl_pinconf_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq,
606 					  unsigned int pin)
607 {
608 	struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
609 	u32 val;
610 	int reg, offset;
611 
612 	reg = mpfs_pinctrl_pin_to_iocfg_reg(pin);
613 	offset = mpfs_pinctrl_pin_to_iocfg_offset(pin);
614 
615 	seq_printf(seq, "pin: %u ", pin);
616 	seq_printf(seq, "reg: %x offset: %u ", reg, offset);
617 
618 	if (reg < 0 || offset < 0)
619 		return;
620 
621 	regmap_read(pctrl->regmap, reg, &val);
622 	val = (val & (MPFS_PINCTRL_IOCFG_MASK << offset)) >> offset;
623 	seq_printf(seq, "val: %x\n", val);
624 }
625 
626 static const struct pinconf_ops mpfs_pinctrl_pinconf_ops = {
627 	.pin_config_get			= mpfs_pinctrl_pinconf_get,
628 	.pin_config_set			= mpfs_pinctrl_pinconf_set,
629 	.pin_config_group_set		= mpfs_pinctrl_pinconf_group_set,
630 	.pin_config_dbg_show		= mpfs_pinctrl_pinconf_dbg_show,
631 	.is_generic			= true,
632 };
633 
634 static const struct pinctrl_pin_desc mpfs_pinctrl_pins[] = {
635 	PINCTRL_PIN(0,  "bank 4 0"),
636 	PINCTRL_PIN(1,  "bank 4 1"),
637 	PINCTRL_PIN(2,  "bank 4 2"),
638 	PINCTRL_PIN(3,  "bank 4 3"),
639 	PINCTRL_PIN(4,  "bank 4 4"),
640 	PINCTRL_PIN(5,  "bank 4 5"),
641 	PINCTRL_PIN(6,  "bank 4 6"),
642 	PINCTRL_PIN(7,  "bank 4 7"),
643 	PINCTRL_PIN(8,  "bank 4 8"),
644 	PINCTRL_PIN(9,  "bank 4 9"),
645 	PINCTRL_PIN(10, "bank 4 10"),
646 	PINCTRL_PIN(11, "bank 4 11"),
647 	PINCTRL_PIN(12, "bank 4 12"),
648 	PINCTRL_PIN(13, "bank 4 13"),
649 
650 	PINCTRL_PIN(14, "bank 2 0"),
651 	PINCTRL_PIN(15, "bank 2 1"),
652 	PINCTRL_PIN(16, "bank 2 2"),
653 	PINCTRL_PIN(17, "bank 2 3"),
654 	PINCTRL_PIN(18, "bank 2 4"),
655 	PINCTRL_PIN(19, "bank 2 5"),
656 	PINCTRL_PIN(20, "bank 2 6"),
657 	PINCTRL_PIN(21, "bank 2 7"),
658 	PINCTRL_PIN(22, "bank 2 8"),
659 	PINCTRL_PIN(23, "bank 2 9"),
660 	PINCTRL_PIN(24, "bank 2 10"),
661 	PINCTRL_PIN(25, "bank 2 11"),
662 	PINCTRL_PIN(26, "bank 2 12"),
663 	PINCTRL_PIN(27, "bank 2 13"),
664 	PINCTRL_PIN(28, "bank 2 14"),
665 	PINCTRL_PIN(29, "bank 2 15"),
666 	PINCTRL_PIN(30, "bank 2 16"),
667 	PINCTRL_PIN(31, "bank 2 17"),
668 	PINCTRL_PIN(32, "bank 2 18"),
669 	PINCTRL_PIN(33, "bank 2 19"),
670 	PINCTRL_PIN(34, "bank 2 20"),
671 	PINCTRL_PIN(35, "bank 2 21"),
672 	PINCTRL_PIN(36, "bank 2 22"),
673 	PINCTRL_PIN(37, "bank 2 23"),
674 };
675 
mpfs_pinctrl_probe(struct platform_device * pdev)676 static int mpfs_pinctrl_probe(struct platform_device *pdev)
677 {
678 	struct device *dev = &pdev->dev;
679 	struct mpfs_pinctrl *pctrl;
680 	int ret;
681 
682 	pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
683 	if (!pctrl)
684 		return -ENOMEM;
685 
686 	pctrl->regmap = device_node_to_regmap(pdev->dev.parent->of_node);
687 	if (IS_ERR(pctrl->regmap))
688 		return dev_err_probe(dev, PTR_ERR(pctrl->regmap), "Failed to find syscon regmap\n");
689 
690 	pctrl->sysreg_regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-sysreg-scb");
691 	if (IS_ERR(pctrl->sysreg_regmap))
692 		return PTR_ERR(pctrl->sysreg_regmap);
693 
694 	pctrl->desc.name = dev_name(dev);
695 	pctrl->desc.pins = mpfs_pinctrl_pins;
696 	pctrl->desc.npins = ARRAY_SIZE(mpfs_pinctrl_pins);
697 	pctrl->desc.pctlops = &mpfs_pinctrl_ops;
698 	pctrl->desc.pmxops = &mpfs_pinctrl_pinmux_ops;
699 	pctrl->desc.confops = &mpfs_pinctrl_pinconf_ops;
700 	pctrl->desc.owner = THIS_MODULE;
701 	pctrl->desc.num_custom_params = ARRAY_SIZE(mpfs_pinctrl_custom_bindings);
702 	pctrl->desc.custom_params = mpfs_pinctrl_custom_bindings;
703 
704 	pctrl->dev = dev;
705 
706 	ret = devm_mutex_init(dev, &pctrl->mutex);
707 	if (ret)
708 		return ret;
709 
710 	platform_set_drvdata(pdev, pctrl);
711 
712 	pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl);
713 	if (IS_ERR(pctrl->pctrl))
714 		return PTR_ERR(pctrl->pctrl);
715 
716 	return 0;
717 }
718 
719 static const struct of_device_id mpfs_pinctrl_of_match[] = {
720 	{ .compatible = "microchip,mpfs-pinctrl-mssio" },
721 	{ }
722 };
723 MODULE_DEVICE_TABLE(of, mpfs_pinctrl_of_match);
724 
725 static struct platform_driver mpfs_pinctrl_driver = {
726 	.driver = {
727 		.name = "mpfs-pinctrl",
728 		.of_match_table = mpfs_pinctrl_of_match,
729 	},
730 	.probe = mpfs_pinctrl_probe,
731 };
732 module_platform_driver(mpfs_pinctrl_driver);
733 
734 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
735 MODULE_DESCRIPTION("Polarfire SoC mssio pinctrl driver");
736 MODULE_LICENSE("GPL");
737