xref: /openbmc/u-boot/drivers/pinctrl/pinctrl_pic32.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1  // SPDX-License-Identifier: GPL-2.0+
2  /*
3   * Pinctrl driver for Microchip PIC32 SoCs
4   * Copyright (c) 2015 Microchip Technology Inc.
5   * Written by Purna Chandra Mandal <purna.mandal@microchip.com>
6   */
7  #include <common.h>
8  #include <dm.h>
9  #include <errno.h>
10  #include <asm/io.h>
11  #include <dm/pinctrl.h>
12  #include <mach/pic32.h>
13  
14  DECLARE_GLOBAL_DATA_PTR;
15  
16  /* PIC32 has 10 peripheral ports with 16 pins each.
17   * Ports are marked PORTA-PORTK or PORT0-PORT9.
18   */
19  enum {
20  	PIC32_PORT_A = 0,
21  	PIC32_PORT_B = 1,
22  	PIC32_PORT_C = 2,
23  	PIC32_PORT_D = 3,
24  	PIC32_PORT_E = 4,
25  	PIC32_PORT_F = 5,
26  	PIC32_PORT_G = 6,
27  	PIC32_PORT_H = 7,
28  	PIC32_PORT_J = 8, /* no PORT_I */
29  	PIC32_PORT_K = 9,
30  	PIC32_PINS_PER_PORT = 16,
31  };
32  
33  #define PIN_CONFIG_PIC32_DIGITAL	(PIN_CONFIG_END + 1)
34  #define PIN_CONFIG_PIC32_ANALOG		(PIN_CONFIG_END + 2)
35  
36  /* pin configuration descriptor */
37  struct pic32_pin_config {
38  	u16 port;	/* port number */
39  	u16 pin;	/* pin number in the port */
40  	u32 config;	/* one of PIN_CONFIG_* */
41  };
42  #define PIN_CONFIG(_prt, _pin, _cfg) \
43  	{.port = (_prt), .pin = (_pin), .config = (_cfg), }
44  
45  /* In PIC32 muxing is performed at pin-level through two
46   * different set of registers - one set for input functions,
47   * and other for output functions.
48   * Pin configuration is handled through port register.
49   */
50  /* Port control registers */
51  struct pic32_reg_port {
52  	struct pic32_reg_atomic ansel;
53  	struct pic32_reg_atomic tris;
54  	struct pic32_reg_atomic port;
55  	struct pic32_reg_atomic lat;
56  	struct pic32_reg_atomic odc;
57  	struct pic32_reg_atomic cnpu;
58  	struct pic32_reg_atomic cnpd;
59  	struct pic32_reg_atomic cncon;
60  	struct pic32_reg_atomic unused[8];
61  };
62  
63  /* Input function mux registers */
64  struct pic32_reg_in_mux {
65  	u32 unused0;
66  	u32 int1[4];
67  	u32 unused1;
68  	u32 t2ck[8];
69  	u32 ic1[9];
70  	u32 unused2;
71  	u32 ocfar;
72  	u32 unused3;
73  	u32 u1rx;
74  	u32 u1cts;
75  	u32 u2rx;
76  	u32 u2cts;
77  	u32 u3rx;
78  	u32 u3cts;
79  	u32 u4rx;
80  	u32 u4cts;
81  	u32 u5rx;
82  	u32 u5cts;
83  	u32 u6rx;
84  	u32 u6cts;
85  	u32 unused4;
86  	u32 sdi1;
87  	u32 ss1;
88  	u32 unused5;
89  	u32 sdi2;
90  	u32 ss2;
91  	u32 unused6;
92  	u32 sdi3;
93  	u32 ss3;
94  	u32 unused7;
95  	u32 sdi4;
96  	u32 ss4;
97  	u32 unused8;
98  	u32 sdi5;
99  	u32 ss5;
100  	u32 unused9;
101  	u32 sdi6;
102  	u32 ss6;
103  	u32 c1rx;
104  	u32 c2rx;
105  	u32 refclki1;
106  	u32 refclki2;
107  	u32 refclki3;
108  	u32 refclki4;
109  };
110  
111  /* output mux register offset */
112  #define PPS_OUT(__port, __pin) \
113  	(((__port) * PIC32_PINS_PER_PORT + (__pin)) << 2)
114  
115  
116  struct pic32_pinctrl_priv {
117  	struct pic32_reg_in_mux *mux_in; /* mux input function */
118  	struct pic32_reg_port *pinconf; /* pin configuration*/
119  	void __iomem *mux_out;	/* mux output function */
120  };
121  
122  enum {
123  	PERIPH_ID_UART1,
124  	PERIPH_ID_UART2,
125  	PERIPH_ID_ETH,
126  	PERIPH_ID_USB,
127  	PERIPH_ID_SDHCI,
128  	PERIPH_ID_I2C1,
129  	PERIPH_ID_I2C2,
130  	PERIPH_ID_SPI1,
131  	PERIPH_ID_SPI2,
132  	PERIPH_ID_SQI,
133  };
134  
pic32_pinconfig_one(struct pic32_pinctrl_priv * priv,u32 port_nr,u32 pin,u32 param)135  static int pic32_pinconfig_one(struct pic32_pinctrl_priv *priv,
136  			       u32 port_nr, u32 pin, u32 param)
137  {
138  	struct pic32_reg_port *port;
139  
140  	port = &priv->pinconf[port_nr];
141  	switch (param) {
142  	case PIN_CONFIG_PIC32_DIGITAL:
143  		writel(BIT(pin), &port->ansel.clr);
144  		break;
145  	case PIN_CONFIG_PIC32_ANALOG:
146  		writel(BIT(pin), &port->ansel.set);
147  		break;
148  	case PIN_CONFIG_INPUT_ENABLE:
149  		writel(BIT(pin), &port->tris.set);
150  		break;
151  	case PIN_CONFIG_OUTPUT:
152  		writel(BIT(pin), &port->tris.clr);
153  		break;
154  	case PIN_CONFIG_BIAS_PULL_UP:
155  		writel(BIT(pin), &port->cnpu.set);
156  		break;
157  	case PIN_CONFIG_BIAS_PULL_DOWN:
158  		writel(BIT(pin), &port->cnpd.set);
159  		break;
160  	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
161  		writel(BIT(pin), &port->odc.set);
162  		break;
163  	default:
164  		break;
165  	}
166  
167  	return 0;
168  }
169  
pic32_pinconfig_set(struct pic32_pinctrl_priv * priv,const struct pic32_pin_config * list,int count)170  static int pic32_pinconfig_set(struct pic32_pinctrl_priv *priv,
171  			       const struct pic32_pin_config *list, int count)
172  {
173  	int i;
174  
175  	for (i = 0 ; i < count; i++)
176  		pic32_pinconfig_one(priv, list[i].port,
177  				    list[i].pin, list[i].config);
178  
179  	return 0;
180  }
181  
pic32_eth_pin_config(struct udevice * dev)182  static void pic32_eth_pin_config(struct udevice *dev)
183  {
184  	struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
185  	const struct pic32_pin_config configs[] = {
186  		/* EMDC - D11 */
187  		PIN_CONFIG(PIC32_PORT_D, 11, PIN_CONFIG_PIC32_DIGITAL),
188  		PIN_CONFIG(PIC32_PORT_D, 11, PIN_CONFIG_OUTPUT),
189  		/* ETXEN */
190  		PIN_CONFIG(PIC32_PORT_D, 6, PIN_CONFIG_PIC32_DIGITAL),
191  		PIN_CONFIG(PIC32_PORT_D, 6, PIN_CONFIG_OUTPUT),
192  		/* ECRSDV */
193  		PIN_CONFIG(PIC32_PORT_H, 13, PIN_CONFIG_PIC32_DIGITAL),
194  		PIN_CONFIG(PIC32_PORT_H, 13, PIN_CONFIG_INPUT_ENABLE),
195  		/* ERXD0 */
196  		PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_PIC32_DIGITAL),
197  		PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_INPUT_ENABLE),
198  		PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_BIAS_PULL_DOWN),
199  		/* ERXD1 */
200  		PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_PIC32_DIGITAL),
201  		PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_INPUT_ENABLE),
202  		PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_BIAS_PULL_DOWN),
203  		/* EREFCLK */
204  		PIN_CONFIG(PIC32_PORT_J, 11, PIN_CONFIG_PIC32_DIGITAL),
205  		PIN_CONFIG(PIC32_PORT_J, 11, PIN_CONFIG_INPUT_ENABLE),
206  		/* ETXD1 */
207  		PIN_CONFIG(PIC32_PORT_J, 9, PIN_CONFIG_PIC32_DIGITAL),
208  		PIN_CONFIG(PIC32_PORT_J, 9, PIN_CONFIG_OUTPUT),
209  		/* ETXD0 */
210  		PIN_CONFIG(PIC32_PORT_J, 8, PIN_CONFIG_PIC32_DIGITAL),
211  		PIN_CONFIG(PIC32_PORT_J, 8, PIN_CONFIG_OUTPUT),
212  		/* EMDIO */
213  		PIN_CONFIG(PIC32_PORT_J, 1, PIN_CONFIG_PIC32_DIGITAL),
214  		PIN_CONFIG(PIC32_PORT_J, 1, PIN_CONFIG_INPUT_ENABLE),
215  		/* ERXERR */
216  		PIN_CONFIG(PIC32_PORT_F, 3, PIN_CONFIG_PIC32_DIGITAL),
217  		PIN_CONFIG(PIC32_PORT_F, 3, PIN_CONFIG_INPUT_ENABLE),
218  	};
219  
220  	pic32_pinconfig_set(priv, configs, ARRAY_SIZE(configs));
221  }
222  
pic32_pinctrl_request(struct udevice * dev,int func,int flags)223  static int pic32_pinctrl_request(struct udevice *dev, int func, int flags)
224  {
225  	struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
226  
227  	switch (func) {
228  	case PERIPH_ID_UART2:
229  		/* PPS for U2 RX/TX */
230  		writel(0x02, priv->mux_out + PPS_OUT(PIC32_PORT_G, 9));
231  		writel(0x05, &priv->mux_in->u2rx); /* B0 */
232  		/* set digital mode */
233  		pic32_pinconfig_one(priv, PIC32_PORT_G, 9,
234  				    PIN_CONFIG_PIC32_DIGITAL);
235  		pic32_pinconfig_one(priv, PIC32_PORT_B, 0,
236  				    PIN_CONFIG_PIC32_DIGITAL);
237  		break;
238  	case PERIPH_ID_ETH:
239  		pic32_eth_pin_config(dev);
240  		break;
241  	default:
242  		debug("%s: unknown-unhandled case\n", __func__);
243  		break;
244  	}
245  
246  	return 0;
247  }
248  
pic32_pinctrl_get_periph_id(struct udevice * dev,struct udevice * periph)249  static int pic32_pinctrl_get_periph_id(struct udevice *dev,
250  				       struct udevice *periph)
251  {
252  	int ret;
253  	u32 cell[2];
254  
255  	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
256  				   "interrupts", cell, ARRAY_SIZE(cell));
257  	if (ret < 0)
258  		return -EINVAL;
259  
260  	/* interrupt number */
261  	switch (cell[0]) {
262  	case 112 ... 114:
263  		return PERIPH_ID_UART1;
264  	case 145 ... 147:
265  		return PERIPH_ID_UART2;
266  	case 109 ... 111:
267  		return PERIPH_ID_SPI1;
268  	case 142 ... 144:
269  		return PERIPH_ID_SPI2;
270  	case 115 ... 117:
271  		return PERIPH_ID_I2C1;
272  	case 148 ... 150:
273  		return PERIPH_ID_I2C2;
274  	case 132 ... 133:
275  		return PERIPH_ID_USB;
276  	case 169:
277  		return PERIPH_ID_SQI;
278  	case 191:
279  		return PERIPH_ID_SDHCI;
280  	case 153:
281  		return PERIPH_ID_ETH;
282  	default:
283  		break;
284  	}
285  
286  	return -ENOENT;
287  }
288  
pic32_pinctrl_set_state_simple(struct udevice * dev,struct udevice * periph)289  static int pic32_pinctrl_set_state_simple(struct udevice *dev,
290  					  struct udevice *periph)
291  {
292  	int func;
293  
294  	debug("%s: periph %s\n", __func__, periph->name);
295  	func = pic32_pinctrl_get_periph_id(dev, periph);
296  	if (func < 0)
297  		return func;
298  	return pic32_pinctrl_request(dev, func, 0);
299  }
300  
301  static struct pinctrl_ops pic32_pinctrl_ops = {
302  	.set_state_simple	= pic32_pinctrl_set_state_simple,
303  	.request		= pic32_pinctrl_request,
304  	.get_periph_id		= pic32_pinctrl_get_periph_id,
305  };
306  
pic32_pinctrl_probe(struct udevice * dev)307  static int pic32_pinctrl_probe(struct udevice *dev)
308  {
309  	struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
310  	struct fdt_resource res;
311  	void *fdt = (void *)gd->fdt_blob;
312  	int node = dev_of_offset(dev);
313  	int ret;
314  
315  	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
316  				     "ppsin", &res);
317  	if (ret < 0) {
318  		printf("pinctrl: resource \"ppsin\" not found\n");
319  		return ret;
320  	}
321  	priv->mux_in = ioremap(res.start, fdt_resource_size(&res));
322  
323  	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
324  				     "ppsout", &res);
325  	if (ret < 0) {
326  		printf("pinctrl: resource \"ppsout\" not found\n");
327  		return ret;
328  	}
329  	priv->mux_out = ioremap(res.start, fdt_resource_size(&res));
330  
331  	ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
332  				     "port", &res);
333  	if (ret < 0) {
334  		printf("pinctrl: resource \"port\" not found\n");
335  		return ret;
336  	}
337  	priv->pinconf = ioremap(res.start, fdt_resource_size(&res));
338  
339  	return 0;
340  }
341  
342  static const struct udevice_id pic32_pinctrl_ids[] = {
343  	{ .compatible = "microchip,pic32mzda-pinctrl" },
344  	{ }
345  };
346  
347  U_BOOT_DRIVER(pinctrl_pic32) = {
348  	.name		= "pinctrl_pic32",
349  	.id		= UCLASS_PINCTRL,
350  	.of_match	= pic32_pinctrl_ids,
351  	.ops		= &pic32_pinctrl_ops,
352  	.probe		= pic32_pinctrl_probe,
353  	.bind		= dm_scan_fdt_dev,
354  	.priv_auto_alloc_size = sizeof(struct pic32_pinctrl_priv),
355  };
356