1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
4 */
5
6#include <common.h>
7#include <clk.h>
8#include <dm.h>
9#include <dm/pinctrl.h>
10#include <dt-bindings/pinctrl/k210-pinctrl.h>
11#include <mapmem.h>
12#include <regmap.h>
13#include <syscon.h>
14#include <asm/io.h>
15#include <linux/err.h>
16#include <linux/bitfield.h>
17#include <linux/bitops.h>
18
19/*
20 * The K210 only implements 8 drive levels, even though there is register space
21 * for 16
22 */
23#define K210_PC_DRIVE_MASK GENMASK(11, 8)
24#define K210_PC_DRIVE_SHIFT 8
25#define K210_PC_DRIVE_0 (0 << K210_PC_DRIVE_SHIFT)
26#define K210_PC_DRIVE_1 (1 << K210_PC_DRIVE_SHIFT)
27#define K210_PC_DRIVE_2 (2 << K210_PC_DRIVE_SHIFT)
28#define K210_PC_DRIVE_3 (3 << K210_PC_DRIVE_SHIFT)
29#define K210_PC_DRIVE_4 (4 << K210_PC_DRIVE_SHIFT)
30#define K210_PC_DRIVE_5 (5 << K210_PC_DRIVE_SHIFT)
31#define K210_PC_DRIVE_6 (6 << K210_PC_DRIVE_SHIFT)
32#define K210_PC_DRIVE_7 (7 << K210_PC_DRIVE_SHIFT)
33#define K210_PC_DRIVE_MAX 7
34
35#define K210_PC_MODE_MASK GENMASK(23, 12)
36/*
37 * output enabled == PC_OE & (PC_OE_INV ^ FUNCTION_OE) where FUNCTION_OE is a
38 * physical signal from the function
39 */
40#define K210_PC_OE       BIT(12) /* Output Enable */
41#define K210_PC_OE_INV   BIT(13) /* INVert function-controlled Output Enable */
42#define K210_PC_DO_OE    BIT(14) /* set Data Out to the Output Enable signal */
43#define K210_PC_DO_INV   BIT(15) /* INVert final Data Output */
44#define K210_PC_PU       BIT(16) /* Pull Up */
45#define K210_PC_PD       BIT(17) /* Pull Down */
46/* Strong pull up not implemented on K210 */
47#define K210_PC_SL       BIT(19) /* reduce SLew rate to prevent overshoot */
48/* Same semantics as OE above */
49#define K210_PC_IE       BIT(20) /* Input Enable */
50#define K210_PC_IE_INV   BIT(21) /* INVert function-controlled Input Enable */
51#define K210_PC_DI_INV   BIT(22) /* INVert Data Input */
52#define K210_PC_ST       BIT(23) /* Schmitt Trigger */
53#define K210_PC_DI       BIT(31) /* raw Data Input */
54#define K210_PC_BIAS_MASK (K210_PC_PU & K210_PC_PD)
55
56#define K210_PC_MODE_IN   (K210_PC_IE | K210_PC_ST)
57#define K210_PC_MODE_OUT  (K210_PC_DRIVE_7 | K210_PC_OE)
58#define K210_PC_MODE_I2C  (K210_PC_MODE_IN | K210_PC_SL | K210_PC_OE | \
59			   K210_PC_PU)
60#define K210_PC_MODE_SCCB (K210_PC_MODE_I2C | K210_PC_OE_INV | K210_PC_IE_INV)
61#define K210_PC_MODE_SPI  (K210_PC_MODE_IN | K210_PC_IE_INV | \
62			   K210_PC_MODE_OUT | K210_PC_OE_INV)
63#define K210_PC_MODE_GPIO (K210_PC_MODE_IN | K210_PC_MODE_OUT)
64
65#define K210_PG_FUNC GENMASK(7, 0)
66#define K210_PG_DO BIT(8)
67#define K210_PG_PIN GENMASK(22, 16)
68
69#define PIN_CONFIG_OUTPUT_INVERT (PIN_CONFIG_END + 1)
70#define PIN_CONFIG_INPUT_INVERT (PIN_CONFIG_END + 2)
71
72struct k210_fpioa {
73	u32 pins[48];
74	u32 tie_en[8];
75	u32 tie_val[8];
76};
77
78struct k210_pc_priv {
79	struct clk clk;
80	struct k210_fpioa __iomem *fpioa; /* FPIOA register */
81	struct regmap *sysctl; /* Sysctl regmap */
82	u32 power_offset; /* Power bank register offset */
83};
84
85#ifdef CONFIG_CMD_PINMUX
86static const char k210_pc_pin_names[][6] = {
87#define PIN(i) \
88	[i] = "IO_" #i
89	PIN(0),
90	PIN(1),
91	PIN(2),
92	PIN(3),
93	PIN(4),
94	PIN(5),
95	PIN(6),
96	PIN(7),
97	PIN(8),
98	PIN(9),
99	PIN(10),
100	PIN(11),
101	PIN(12),
102	PIN(13),
103	PIN(14),
104	PIN(15),
105	PIN(16),
106	PIN(17),
107	PIN(18),
108	PIN(19),
109	PIN(20),
110	PIN(21),
111	PIN(22),
112	PIN(23),
113	PIN(24),
114	PIN(25),
115	PIN(26),
116	PIN(27),
117	PIN(28),
118	PIN(29),
119	PIN(30),
120	PIN(31),
121	PIN(32),
122	PIN(33),
123	PIN(34),
124	PIN(35),
125	PIN(36),
126	PIN(37),
127	PIN(38),
128	PIN(39),
129	PIN(40),
130	PIN(41),
131	PIN(42),
132	PIN(43),
133	PIN(44),
134	PIN(45),
135	PIN(46),
136	PIN(47),
137#undef PIN
138};
139
140static int k210_pc_get_pins_count(struct udevice *dev)
141{
142	return ARRAY_SIZE(k210_pc_pin_names);
143};
144
145static const char *k210_pc_get_pin_name(struct udevice *dev, unsigned selector)
146{
147	return k210_pc_pin_names[selector];
148}
149#endif /* CONFIG_CMD_PINMUX */
150
151/* These are just power domains */
152static const char k210_pc_group_names[][3] = {
153	[0] = "A0",
154	[1] = "A1",
155	[2] = "A2",
156	[3] = "B3",
157	[4] = "B4",
158	[5] = "B5",
159	[6] = "C6",
160	[7] = "C7",
161};
162
163static int k210_pc_get_groups_count(struct udevice *dev)
164{
165	return ARRAY_SIZE(k210_pc_group_names);
166}
167
168static const char *k210_pc_get_group_name(struct udevice *dev,
169					  unsigned selector)
170{
171	return k210_pc_group_names[selector];
172}
173
174enum k210_pc_mode_id {
175	K210_PC_DEFAULT_DISABLED,
176	K210_PC_DEFAULT_IN,
177	K210_PC_DEFAULT_IN_TIE,
178	K210_PC_DEFAULT_OUT,
179	K210_PC_DEFAULT_I2C,
180	K210_PC_DEFAULT_SCCB,
181	K210_PC_DEFAULT_SPI,
182	K210_PC_DEFAULT_GPIO,
183	K210_PC_DEFAULT_INT13,
184};
185
186static const u32 k210_pc_mode_id_to_mode[] = {
187#define DEFAULT(mode) \
188	[K210_PC_DEFAULT_##mode] = K210_PC_MODE_##mode
189	[K210_PC_DEFAULT_DISABLED] = 0,
190	DEFAULT(IN),
191	[K210_PC_DEFAULT_IN_TIE] = K210_PC_MODE_IN,
192	DEFAULT(OUT),
193	DEFAULT(I2C),
194	DEFAULT(SCCB),
195	DEFAULT(SPI),
196	DEFAULT(GPIO),
197	[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
198#undef DEFAULT
199};
200
201/* This saves around 2K vs having a pointer+mode */
202struct k210_pcf_info {
203#ifdef CONFIG_CMD_PINMUX
204	char name[15];
205#endif
206	u8 mode_id;
207};
208
209static const struct k210_pcf_info k210_pcf_infos[] = {
210#ifdef CONFIG_CMD_PINMUX
211#define FUNC(id, mode) \
212	[K210_PCF_##id] = { \
213		.name = #id, \
214		.mode_id = K210_PC_DEFAULT_##mode \
215	}
216#else
217#define FUNC(id, mode) \
218	[K210_PCF_##id] = { \
219		.mode_id = K210_PC_DEFAULT_##mode \
220	}
221#endif
222	FUNC(JTAG_TCLK,      IN),
223	FUNC(JTAG_TDI,       IN),
224	FUNC(JTAG_TMS,       IN),
225	FUNC(JTAG_TDO,       OUT),
226	FUNC(SPI0_D0,        SPI),
227	FUNC(SPI0_D1,        SPI),
228	FUNC(SPI0_D2,        SPI),
229	FUNC(SPI0_D3,        SPI),
230	FUNC(SPI0_D4,        SPI),
231	FUNC(SPI0_D5,        SPI),
232	FUNC(SPI0_D6,        SPI),
233	FUNC(SPI0_D7,        SPI),
234	FUNC(SPI0_SS0,       OUT),
235	FUNC(SPI0_SS1,       OUT),
236	FUNC(SPI0_SS2,       OUT),
237	FUNC(SPI0_SS3,       OUT),
238	FUNC(SPI0_ARB,       IN_TIE),
239	FUNC(SPI0_SCLK,      OUT),
240	FUNC(UARTHS_RX,      IN),
241	FUNC(UARTHS_TX,      OUT),
242	FUNC(RESV6,          IN),
243	FUNC(RESV7,          IN),
244	FUNC(CLK_SPI1,       OUT),
245	FUNC(CLK_I2C1,       OUT),
246	FUNC(GPIOHS0,        GPIO),
247	FUNC(GPIOHS1,        GPIO),
248	FUNC(GPIOHS2,        GPIO),
249	FUNC(GPIOHS3,        GPIO),
250	FUNC(GPIOHS4,        GPIO),
251	FUNC(GPIOHS5,        GPIO),
252	FUNC(GPIOHS6,        GPIO),
253	FUNC(GPIOHS7,        GPIO),
254	FUNC(GPIOHS8,        GPIO),
255	FUNC(GPIOHS9,        GPIO),
256	FUNC(GPIOHS10,       GPIO),
257	FUNC(GPIOHS11,       GPIO),
258	FUNC(GPIOHS12,       GPIO),
259	FUNC(GPIOHS13,       GPIO),
260	FUNC(GPIOHS14,       GPIO),
261	FUNC(GPIOHS15,       GPIO),
262	FUNC(GPIOHS16,       GPIO),
263	FUNC(GPIOHS17,       GPIO),
264	FUNC(GPIOHS18,       GPIO),
265	FUNC(GPIOHS19,       GPIO),
266	FUNC(GPIOHS20,       GPIO),
267	FUNC(GPIOHS21,       GPIO),
268	FUNC(GPIOHS22,       GPIO),
269	FUNC(GPIOHS23,       GPIO),
270	FUNC(GPIOHS24,       GPIO),
271	FUNC(GPIOHS25,       GPIO),
272	FUNC(GPIOHS26,       GPIO),
273	FUNC(GPIOHS27,       GPIO),
274	FUNC(GPIOHS28,       GPIO),
275	FUNC(GPIOHS29,       GPIO),
276	FUNC(GPIOHS30,       GPIO),
277	FUNC(GPIOHS31,       GPIO),
278	FUNC(GPIO0,          GPIO),
279	FUNC(GPIO1,          GPIO),
280	FUNC(GPIO2,          GPIO),
281	FUNC(GPIO3,          GPIO),
282	FUNC(GPIO4,          GPIO),
283	FUNC(GPIO5,          GPIO),
284	FUNC(GPIO6,          GPIO),
285	FUNC(GPIO7,          GPIO),
286	FUNC(UART1_RX,       IN),
287	FUNC(UART1_TX,       OUT),
288	FUNC(UART2_RX,       IN),
289	FUNC(UART2_TX,       OUT),
290	FUNC(UART3_RX,       IN),
291	FUNC(UART3_TX,       OUT),
292	FUNC(SPI1_D0,        SPI),
293	FUNC(SPI1_D1,        SPI),
294	FUNC(SPI1_D2,        SPI),
295	FUNC(SPI1_D3,        SPI),
296	FUNC(SPI1_D4,        SPI),
297	FUNC(SPI1_D5,        SPI),
298	FUNC(SPI1_D6,        SPI),
299	FUNC(SPI1_D7,        SPI),
300	FUNC(SPI1_SS0,       OUT),
301	FUNC(SPI1_SS1,       OUT),
302	FUNC(SPI1_SS2,       OUT),
303	FUNC(SPI1_SS3,       OUT),
304	FUNC(SPI1_ARB,       IN_TIE),
305	FUNC(SPI1_SCLK,      OUT),
306	FUNC(SPI2_D0,        SPI),
307	FUNC(SPI2_SS,        IN),
308	FUNC(SPI2_SCLK,      IN),
309	FUNC(I2S0_MCLK,      OUT),
310	FUNC(I2S0_SCLK,      OUT),
311	FUNC(I2S0_WS,        OUT),
312	FUNC(I2S0_IN_D0,     IN),
313	FUNC(I2S0_IN_D1,     IN),
314	FUNC(I2S0_IN_D2,     IN),
315	FUNC(I2S0_IN_D3,     IN),
316	FUNC(I2S0_OUT_D0,    OUT),
317	FUNC(I2S0_OUT_D1,    OUT),
318	FUNC(I2S0_OUT_D2,    OUT),
319	FUNC(I2S0_OUT_D3,    OUT),
320	FUNC(I2S1_MCLK,      OUT),
321	FUNC(I2S1_SCLK,      OUT),
322	FUNC(I2S1_WS,        OUT),
323	FUNC(I2S1_IN_D0,     IN),
324	FUNC(I2S1_IN_D1,     IN),
325	FUNC(I2S1_IN_D2,     IN),
326	FUNC(I2S1_IN_D3,     IN),
327	FUNC(I2S1_OUT_D0,    OUT),
328	FUNC(I2S1_OUT_D1,    OUT),
329	FUNC(I2S1_OUT_D2,    OUT),
330	FUNC(I2S1_OUT_D3,    OUT),
331	FUNC(I2S2_MCLK,      OUT),
332	FUNC(I2S2_SCLK,      OUT),
333	FUNC(I2S2_WS,        OUT),
334	FUNC(I2S2_IN_D0,     IN),
335	FUNC(I2S2_IN_D1,     IN),
336	FUNC(I2S2_IN_D2,     IN),
337	FUNC(I2S2_IN_D3,     IN),
338	FUNC(I2S2_OUT_D0,    OUT),
339	FUNC(I2S2_OUT_D1,    OUT),
340	FUNC(I2S2_OUT_D2,    OUT),
341	FUNC(I2S2_OUT_D3,    OUT),
342	FUNC(RESV0,          DISABLED),
343	FUNC(RESV1,          DISABLED),
344	FUNC(RESV2,          DISABLED),
345	FUNC(RESV3,          DISABLED),
346	FUNC(RESV4,          DISABLED),
347	FUNC(RESV5,          DISABLED),
348	FUNC(I2C0_SCLK,      I2C),
349	FUNC(I2C0_SDA,       I2C),
350	FUNC(I2C1_SCLK,      I2C),
351	FUNC(I2C1_SDA,       I2C),
352	FUNC(I2C2_SCLK,      I2C),
353	FUNC(I2C2_SDA,       I2C),
354	FUNC(DVP_XCLK,       OUT),
355	FUNC(DVP_RST,        OUT),
356	FUNC(DVP_PWDN,       OUT),
357	FUNC(DVP_VSYNC,      IN),
358	FUNC(DVP_HSYNC,      IN),
359	FUNC(DVP_PCLK,       IN),
360	FUNC(DVP_D0,         IN),
361	FUNC(DVP_D1,         IN),
362	FUNC(DVP_D2,         IN),
363	FUNC(DVP_D3,         IN),
364	FUNC(DVP_D4,         IN),
365	FUNC(DVP_D5,         IN),
366	FUNC(DVP_D6,         IN),
367	FUNC(DVP_D7,         IN),
368	FUNC(SCCB_SCLK,      SCCB),
369	FUNC(SCCB_SDA,       SCCB),
370	FUNC(UART1_CTS,      IN),
371	FUNC(UART1_DSR,      IN),
372	FUNC(UART1_DCD,      IN),
373	FUNC(UART1_RI,       IN),
374	FUNC(UART1_SIR_IN,   IN),
375	FUNC(UART1_DTR,      OUT),
376	FUNC(UART1_RTS,      OUT),
377	FUNC(UART1_OUT2,     OUT),
378	FUNC(UART1_OUT1,     OUT),
379	FUNC(UART1_SIR_OUT,  OUT),
380	FUNC(UART1_BAUD,     OUT),
381	FUNC(UART1_RE,       OUT),
382	FUNC(UART1_DE,       OUT),
383	FUNC(UART1_RS485_EN, OUT),
384	FUNC(UART2_CTS,      IN),
385	FUNC(UART2_DSR,      IN),
386	FUNC(UART2_DCD,      IN),
387	FUNC(UART2_RI,       IN),
388	FUNC(UART2_SIR_IN,   IN),
389	FUNC(UART2_DTR,      OUT),
390	FUNC(UART2_RTS,      OUT),
391	FUNC(UART2_OUT2,     OUT),
392	FUNC(UART2_OUT1,     OUT),
393	FUNC(UART2_SIR_OUT,  OUT),
394	FUNC(UART2_BAUD,     OUT),
395	FUNC(UART2_RE,       OUT),
396	FUNC(UART2_DE,       OUT),
397	FUNC(UART2_RS485_EN, OUT),
398	FUNC(UART3_CTS,      IN),
399	FUNC(UART3_DSR,      IN),
400	FUNC(UART3_DCD,      IN),
401	FUNC(UART3_RI,       IN),
402	FUNC(UART3_SIR_IN,   IN),
403	FUNC(UART3_DTR,      OUT),
404	FUNC(UART3_RTS,      OUT),
405	FUNC(UART3_OUT2,     OUT),
406	FUNC(UART3_OUT1,     OUT),
407	FUNC(UART3_SIR_OUT,  OUT),
408	FUNC(UART3_BAUD,     OUT),
409	FUNC(UART3_RE,       OUT),
410	FUNC(UART3_DE,       OUT),
411	FUNC(UART3_RS485_EN, OUT),
412	FUNC(TIMER0_TOGGLE1, OUT),
413	FUNC(TIMER0_TOGGLE2, OUT),
414	FUNC(TIMER0_TOGGLE3, OUT),
415	FUNC(TIMER0_TOGGLE4, OUT),
416	FUNC(TIMER1_TOGGLE1, OUT),
417	FUNC(TIMER1_TOGGLE2, OUT),
418	FUNC(TIMER1_TOGGLE3, OUT),
419	FUNC(TIMER1_TOGGLE4, OUT),
420	FUNC(TIMER2_TOGGLE1, OUT),
421	FUNC(TIMER2_TOGGLE2, OUT),
422	FUNC(TIMER2_TOGGLE3, OUT),
423	FUNC(TIMER2_TOGGLE4, OUT),
424	FUNC(CLK_SPI2,       OUT),
425	FUNC(CLK_I2C2,       OUT),
426	FUNC(INTERNAL0,      OUT),
427	FUNC(INTERNAL1,      OUT),
428	FUNC(INTERNAL2,      OUT),
429	FUNC(INTERNAL3,      OUT),
430	FUNC(INTERNAL4,      OUT),
431	FUNC(INTERNAL5,      OUT),
432	FUNC(INTERNAL6,      OUT),
433	FUNC(INTERNAL7,      OUT),
434	FUNC(INTERNAL8,      OUT),
435	FUNC(INTERNAL9,      IN),
436	FUNC(INTERNAL10,     IN),
437	FUNC(INTERNAL11,     IN),
438	FUNC(INTERNAL12,     IN),
439	FUNC(INTERNAL13,     INT13),
440	FUNC(INTERNAL14,     I2C),
441	FUNC(INTERNAL15,     IN),
442	FUNC(INTERNAL16,     IN),
443	FUNC(INTERNAL17,     IN),
444	FUNC(CONSTANT,       DISABLED),
445	FUNC(INTERNAL18,     IN),
446	FUNC(DEBUG0,         OUT),
447	FUNC(DEBUG1,         OUT),
448	FUNC(DEBUG2,         OUT),
449	FUNC(DEBUG3,         OUT),
450	FUNC(DEBUG4,         OUT),
451	FUNC(DEBUG5,         OUT),
452	FUNC(DEBUG6,         OUT),
453	FUNC(DEBUG7,         OUT),
454	FUNC(DEBUG8,         OUT),
455	FUNC(DEBUG9,         OUT),
456	FUNC(DEBUG10,        OUT),
457	FUNC(DEBUG11,        OUT),
458	FUNC(DEBUG12,        OUT),
459	FUNC(DEBUG13,        OUT),
460	FUNC(DEBUG14,        OUT),
461	FUNC(DEBUG15,        OUT),
462	FUNC(DEBUG16,        OUT),
463	FUNC(DEBUG17,        OUT),
464	FUNC(DEBUG18,        OUT),
465	FUNC(DEBUG19,        OUT),
466	FUNC(DEBUG20,        OUT),
467	FUNC(DEBUG21,        OUT),
468	FUNC(DEBUG22,        OUT),
469	FUNC(DEBUG23,        OUT),
470	FUNC(DEBUG24,        OUT),
471	FUNC(DEBUG25,        OUT),
472	FUNC(DEBUG26,        OUT),
473	FUNC(DEBUG27,        OUT),
474	FUNC(DEBUG28,        OUT),
475	FUNC(DEBUG29,        OUT),
476	FUNC(DEBUG30,        OUT),
477	FUNC(DEBUG31,        OUT),
478#undef FUNC
479};
480
481static int k210_pc_pinmux_set(struct udevice *dev, u32 pinmux_group)
482{
483	unsigned pin = FIELD_GET(K210_PG_PIN, pinmux_group);
484	bool do_oe = FIELD_GET(K210_PG_DO, pinmux_group);
485	unsigned func = FIELD_GET(K210_PG_FUNC, pinmux_group);
486	struct k210_pc_priv *priv = dev_get_priv(dev);
487	const struct k210_pcf_info *info = &k210_pcf_infos[func];
488	u32 mode = k210_pc_mode_id_to_mode[info->mode_id];
489	u32 val = func | mode | (do_oe ? K210_PC_DO_OE : 0);
490
491	debug("%s(%.8x): IO_%.2u = %3u | %.8x\n", __func__, pinmux_group, pin,
492	      func, mode);
493
494	writel(val, &priv->fpioa->pins[pin]);
495	return pin;
496}
497
498/* Max drive strength in uA */
499static const int k210_pc_drive_strength[] = {
500	[0] = 11200,
501	[1] = 16800,
502	[2] = 22300,
503	[3] = 27800,
504	[4] = 33300,
505	[5] = 38700,
506	[6] = 44100,
507	[7] = 49500,
508};
509
510static int k210_pc_get_drive(unsigned max_strength_ua)
511{
512	int i;
513
514	for (i = K210_PC_DRIVE_MAX; i >= 0; i--)
515		if (k210_pc_drive_strength[i] < max_strength_ua)
516			return i;
517
518	return -EINVAL;
519}
520
521static int k210_pc_pinconf_set(struct udevice *dev, unsigned pin_selector,
522			       unsigned param, unsigned argument)
523{
524	struct k210_pc_priv *priv = dev_get_priv(dev);
525	u32 val = readl(&priv->fpioa->pins[pin_selector]);
526
527	switch (param) {
528	case PIN_CONFIG_BIAS_DISABLE:
529		val &= ~K210_PC_BIAS_MASK;
530		break;
531	case PIN_CONFIG_BIAS_PULL_DOWN:
532		if (argument)
533			val |= K210_PC_PD;
534		else
535			return -EINVAL;
536		break;
537	case PIN_CONFIG_BIAS_PULL_UP:
538		if (argument)
539			val |= K210_PC_PU;
540		else
541			return -EINVAL;
542		break;
543	case PIN_CONFIG_DRIVE_STRENGTH:
544		argument *= 1000;
545	case PIN_CONFIG_DRIVE_STRENGTH_UA: {
546		int drive = k210_pc_get_drive(argument);
547
548		if (IS_ERR_VALUE(drive))
549			return drive;
550		val &= ~K210_PC_DRIVE_MASK;
551		val |= FIELD_PREP(K210_PC_DRIVE_MASK, drive);
552		break;
553	}
554	case PIN_CONFIG_INPUT_ENABLE:
555		if (argument)
556			val |= K210_PC_IE;
557		else
558			val &= ~K210_PC_IE;
559		break;
560	case PIN_CONFIG_INPUT_SCHMITT:
561		argument = 1;
562	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
563		if (argument)
564			val |= K210_PC_ST;
565		else
566			val &= ~K210_PC_ST;
567		break;
568	case PIN_CONFIG_OUTPUT:
569		k210_pc_pinmux_set(dev,
570				   K210_FPIOA(pin_selector, K210_PCF_CONSTANT));
571		val = readl(&priv->fpioa->pins[pin_selector]);
572		val |= K210_PC_MODE_OUT;
573
574		if (!argument)
575			val |= K210_PC_DO_INV;
576		break;
577	case PIN_CONFIG_OUTPUT_ENABLE:
578		if (argument)
579			val |= K210_PC_OE;
580		else
581			val &= ~K210_PC_OE;
582		break;
583	case PIN_CONFIG_SLEW_RATE:
584		if (argument)
585			val |= K210_PC_SL;
586		else
587			val &= ~K210_PC_SL;
588		break;
589	case PIN_CONFIG_OUTPUT_INVERT:
590		if (argument)
591			val |= K210_PC_DO_INV;
592		else
593			val &= ~K210_PC_DO_INV;
594		break;
595	case PIN_CONFIG_INPUT_INVERT:
596		if (argument)
597			val |= K210_PC_DI_INV;
598		else
599			val &= ~K210_PC_DI_INV;
600		break;
601	default:
602		return -EINVAL;
603	}
604
605	writel(val, &priv->fpioa->pins[pin_selector]);
606	return 0;
607}
608
609static int k210_pc_pinconf_group_set(struct udevice *dev,
610				     unsigned group_selector, unsigned param,
611				     unsigned argument)
612{
613	struct k210_pc_priv *priv = dev_get_priv(dev);
614
615	if (param == PIN_CONFIG_POWER_SOURCE) {
616		u32 bit = BIT(group_selector);
617
618		regmap_update_bits(priv->sysctl, priv->power_offset, bit,
619				   argument ? bit : 0);
620	} else {
621		return -EINVAL;
622	}
623
624	return 0;
625}
626
627#ifdef CONFIG_CMD_PINMUX
628static int k210_pc_get_pin_muxing(struct udevice *dev, unsigned int selector,
629				  char *buf, int size)
630{
631	struct k210_pc_priv *priv = dev_get_priv(dev);
632	u32 val = readl(&priv->fpioa->pins[selector]);
633	const struct k210_pcf_info *info = &k210_pcf_infos[val & K210_PCF_MASK];
634
635	strncpy(buf, info->name, min((size_t)size, sizeof(info->name)));
636	return 0;
637}
638#endif
639
640static const struct pinconf_param k210_pc_pinconf_params[] = {
641	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
642	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
643	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
644	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, U32_MAX },
645	{ "drive-strength-ua", PIN_CONFIG_DRIVE_STRENGTH_UA, U32_MAX },
646	{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
647	{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
648	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
649	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
650	{ "power-source", PIN_CONFIG_POWER_SOURCE, K210_PC_POWER_1V8 },
651	{ "output-low", PIN_CONFIG_OUTPUT, 0 },
652	{ "output-high", PIN_CONFIG_OUTPUT, 1 },
653	{ "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
654	{ "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 },
655	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 1 },
656	{ "output-polarity-invert", PIN_CONFIG_OUTPUT_INVERT, 1},
657	{ "input-polarity-invert", PIN_CONFIG_INPUT_INVERT, 1},
658};
659
660static const struct pinctrl_ops k210_pc_pinctrl_ops = {
661#ifdef CONFIG_CMD_PINMUX
662	.get_pins_count = k210_pc_get_pins_count,
663	.get_pin_name = k210_pc_get_pin_name,
664#endif
665	.get_groups_count = k210_pc_get_groups_count,
666	.get_group_name = k210_pc_get_group_name,
667	.pinmux_property_set = k210_pc_pinmux_set,
668	.pinconf_num_params = ARRAY_SIZE(k210_pc_pinconf_params),
669	.pinconf_params = k210_pc_pinconf_params,
670	.pinconf_set = k210_pc_pinconf_set,
671	.pinconf_group_set = k210_pc_pinconf_group_set,
672	.set_state = pinctrl_generic_set_state,
673#ifdef CONFIG_CMD_PINMUX
674	.get_pin_muxing = k210_pc_get_pin_muxing,
675#endif
676};
677
678static int k210_pc_probe(struct udevice *dev)
679{
680	int ret, i, j;
681	struct k210_pc_priv *priv = dev_get_priv(dev);
682	struct ofnode_phandle_args args;
683
684	priv->fpioa = dev_read_addr_ptr(dev);
685	if (!priv->fpioa)
686		return -EINVAL;
687
688	ret = clk_get_by_index(dev, 0, &priv->clk);
689	if (ret)
690		return ret;
691
692	ret = clk_enable(&priv->clk);
693	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
694		return ret;
695
696	ret = dev_read_phandle_with_args(dev, "canaan,k210-sysctl-power",
697					NULL, 1, 0, &args);
698        if (ret)
699		return ret;
700
701	if (args.args_count != 1)
702		return -EINVAL;
703
704	priv->sysctl = syscon_node_to_regmap(args.node);
705	if (IS_ERR(priv->sysctl))
706		return PTR_ERR(priv->sysctl);
707
708	priv->power_offset = args.args[0];
709
710	debug("%s: fpioa = %p sysctl = %p power offset = %x\n", __func__,
711	      priv->fpioa, (void *)priv->sysctl->ranges[0].start,
712	      priv->power_offset);
713
714	/* Init input ties */
715	for (i = 0; i < ARRAY_SIZE(priv->fpioa->tie_en); i++) {
716		u32 val = 0;
717
718		for (j = 0; j < 32; j++)
719			if (k210_pcf_infos[i * 32 + j].mode_id ==
720			    K210_PC_DEFAULT_IN_TIE)
721				val |= BIT(j);
722		writel(val, &priv->fpioa->tie_en[i]);
723		writel(val, &priv->fpioa->tie_val[i]);
724	}
725
726	return 0;
727}
728
729static const struct udevice_id k210_pc_ids[] = {
730	{ .compatible = "canaan,k210-fpioa" },
731	{ }
732};
733
734U_BOOT_DRIVER(pinctrl_k210) = {
735	.name = "pinctrl_k210",
736	.id = UCLASS_PINCTRL,
737	.of_match = k210_pc_ids,
738	.probe = k210_pc_probe,
739	.priv_auto	= sizeof(struct k210_pc_priv),
740	.ops = &k210_pc_pinctrl_ops,
741};
742