xref: /rk3399_rockchip-uboot/drivers/pinctrl/pinctrl_stm32.c (revision 90aa625c9a9e1fb7a2f001fd8e50099bacaf92b8)
194d53084SVikas Manocha #include <common.h>
294d53084SVikas Manocha #include <dm.h>
394d53084SVikas Manocha #include <dm/pinctrl.h>
477417102SVikas Manocha #include <asm/arch/gpio.h>
577417102SVikas Manocha #include <asm/gpio.h>
677417102SVikas Manocha #include <asm/io.h>
794d53084SVikas Manocha 
894d53084SVikas Manocha DECLARE_GLOBAL_DATA_PTR;
994d53084SVikas Manocha 
1058fb3c8dSVikas Manocha #define MAX_PINS_ONE_IP			70
1177417102SVikas Manocha #define MODE_BITS_MASK			3
1277417102SVikas Manocha #define OSPEED_MASK			3
1377417102SVikas Manocha #define PUPD_MASK			3
1477417102SVikas Manocha #define OTYPE_MSK			1
1577417102SVikas Manocha #define AFR_MASK			0xF
1677417102SVikas Manocha 
stm32_gpio_config(struct gpio_desc * desc,const struct stm32_gpio_ctl * ctl)1777417102SVikas Manocha static int stm32_gpio_config(struct gpio_desc *desc,
1877417102SVikas Manocha 			     const struct stm32_gpio_ctl *ctl)
1977417102SVikas Manocha {
2077417102SVikas Manocha 	struct stm32_gpio_priv *priv = dev_get_priv(desc->dev);
2177417102SVikas Manocha 	struct stm32_gpio_regs *regs = priv->regs;
2277417102SVikas Manocha 	u32 index;
2377417102SVikas Manocha 
2477417102SVikas Manocha 	if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 ||
2577417102SVikas Manocha 	    ctl->pupd > 2 || ctl->speed > 3)
2677417102SVikas Manocha 		return -EINVAL;
2777417102SVikas Manocha 
2877417102SVikas Manocha 	index = (desc->offset & 0x07) * 4;
2977417102SVikas Manocha 	clrsetbits_le32(&regs->afr[desc->offset >> 3], AFR_MASK << index,
3077417102SVikas Manocha 			ctl->af << index);
3177417102SVikas Manocha 
3277417102SVikas Manocha 	index = desc->offset * 2;
3377417102SVikas Manocha 	clrsetbits_le32(&regs->moder, MODE_BITS_MASK << index,
3477417102SVikas Manocha 			ctl->mode << index);
3577417102SVikas Manocha 	clrsetbits_le32(&regs->ospeedr, OSPEED_MASK << index,
3677417102SVikas Manocha 			ctl->speed << index);
3777417102SVikas Manocha 	clrsetbits_le32(&regs->pupdr, PUPD_MASK << index, ctl->pupd << index);
3877417102SVikas Manocha 
3977417102SVikas Manocha 	index = desc->offset;
4077417102SVikas Manocha 	clrsetbits_le32(&regs->otyper, OTYPE_MSK << index, ctl->otype << index);
4177417102SVikas Manocha 
4277417102SVikas Manocha 	return 0;
4377417102SVikas Manocha }
prep_gpio_dsc(struct stm32_gpio_dsc * gpio_dsc,u32 port_pin)4494d53084SVikas Manocha static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin)
4594d53084SVikas Manocha {
4694d53084SVikas Manocha 	gpio_dsc->port = (port_pin & 0xF000) >> 12;
4794d53084SVikas Manocha 	gpio_dsc->pin = (port_pin & 0x0F00) >> 8;
4894d53084SVikas Manocha 	debug("%s: GPIO:port= %d, pin= %d\n", __func__, gpio_dsc->port,
4994d53084SVikas Manocha 	      gpio_dsc->pin);
5094d53084SVikas Manocha 
5194d53084SVikas Manocha 	return 0;
5294d53084SVikas Manocha }
5394d53084SVikas Manocha 
prep_gpio_ctl(struct stm32_gpio_ctl * gpio_ctl,u32 gpio_fn,int node)5494d53084SVikas Manocha static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node)
5594d53084SVikas Manocha {
5694d53084SVikas Manocha 	gpio_fn &= 0x00FF;
5777417102SVikas Manocha 	gpio_ctl->af = 0;
5894d53084SVikas Manocha 
5994d53084SVikas Manocha 	switch (gpio_fn) {
6094d53084SVikas Manocha 	case 0:
6194d53084SVikas Manocha 		gpio_ctl->mode = STM32_GPIO_MODE_IN;
6294d53084SVikas Manocha 		break;
6394d53084SVikas Manocha 	case 1 ... 16:
6494d53084SVikas Manocha 		gpio_ctl->mode = STM32_GPIO_MODE_AF;
6594d53084SVikas Manocha 		gpio_ctl->af = gpio_fn - 1;
6694d53084SVikas Manocha 		break;
6794d53084SVikas Manocha 	case 17:
6894d53084SVikas Manocha 		gpio_ctl->mode = STM32_GPIO_MODE_AN;
6994d53084SVikas Manocha 		break;
7094d53084SVikas Manocha 	default:
7194d53084SVikas Manocha 		gpio_ctl->mode = STM32_GPIO_MODE_OUT;
7294d53084SVikas Manocha 		break;
7394d53084SVikas Manocha 	}
7494d53084SVikas Manocha 
7594d53084SVikas Manocha 	gpio_ctl->speed = fdtdec_get_int(gd->fdt_blob, node, "slew-rate", 0);
7694d53084SVikas Manocha 
7794d53084SVikas Manocha 	if (fdtdec_get_bool(gd->fdt_blob, node, "drive-open-drain"))
7894d53084SVikas Manocha 		gpio_ctl->otype = STM32_GPIO_OTYPE_OD;
7994d53084SVikas Manocha 	else
8094d53084SVikas Manocha 		gpio_ctl->otype = STM32_GPIO_OTYPE_PP;
8194d53084SVikas Manocha 
8294d53084SVikas Manocha 	if (fdtdec_get_bool(gd->fdt_blob, node, "bias-pull-up"))
8394d53084SVikas Manocha 		gpio_ctl->pupd = STM32_GPIO_PUPD_UP;
8494d53084SVikas Manocha 	else if (fdtdec_get_bool(gd->fdt_blob, node, "bias-pull-down"))
8594d53084SVikas Manocha 		gpio_ctl->pupd = STM32_GPIO_PUPD_DOWN;
8694d53084SVikas Manocha 	else
8794d53084SVikas Manocha 		gpio_ctl->pupd = STM32_GPIO_PUPD_NO;
8894d53084SVikas Manocha 
8994d53084SVikas Manocha 	debug("%s: gpio fn= %d, slew-rate= %x, op type= %x, pull-upd is = %x\n",
9094d53084SVikas Manocha 	      __func__,  gpio_fn, gpio_ctl->speed, gpio_ctl->otype,
9194d53084SVikas Manocha 	     gpio_ctl->pupd);
9294d53084SVikas Manocha 
9394d53084SVikas Manocha 	return 0;
9494d53084SVikas Manocha }
9594d53084SVikas Manocha 
stm32_pinctrl_config(int offset)96ad0376e0SChristophe Kerello static int stm32_pinctrl_config(int offset)
9794d53084SVikas Manocha {
9858fb3c8dSVikas Manocha 	u32 pin_mux[MAX_PINS_ONE_IP];
9994d53084SVikas Manocha 	int rv, len;
10094d53084SVikas Manocha 
10194d53084SVikas Manocha 	/*
10294d53084SVikas Manocha 	 * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for
10394d53084SVikas Manocha 	 * usart1) of pin controller phandle "pinctrl-0"
10494d53084SVikas Manocha 	 * */
105ad0376e0SChristophe Kerello 	fdt_for_each_subnode(offset, gd->fdt_blob, offset) {
10694d53084SVikas Manocha 		struct stm32_gpio_dsc gpio_dsc;
10794d53084SVikas Manocha 		struct stm32_gpio_ctl gpio_ctl;
10894d53084SVikas Manocha 		int i;
10994d53084SVikas Manocha 
110ad0376e0SChristophe Kerello 		len = fdtdec_get_int_array_count(gd->fdt_blob, offset,
11194d53084SVikas Manocha 						 "pinmux", pin_mux,
11294d53084SVikas Manocha 						 ARRAY_SIZE(pin_mux));
113ad0376e0SChristophe Kerello 		debug("%s: no of pinmux entries= %d\n", __func__, len);
11494d53084SVikas Manocha 		if (len < 0)
11594d53084SVikas Manocha 			return -EINVAL;
11694d53084SVikas Manocha 		for (i = 0; i < len; i++) {
117280057bdSVikas Manocha 			struct gpio_desc desc;
11894d53084SVikas Manocha 			debug("%s: pinmux = %x\n", __func__, *(pin_mux + i));
11994d53084SVikas Manocha 			prep_gpio_dsc(&gpio_dsc, *(pin_mux + i));
120ad0376e0SChristophe Kerello 			prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), offset);
121280057bdSVikas Manocha 			rv = uclass_get_device_by_seq(UCLASS_GPIO,
122280057bdSVikas Manocha 						      gpio_dsc.port, &desc.dev);
123280057bdSVikas Manocha 			if (rv)
124280057bdSVikas Manocha 				return rv;
125280057bdSVikas Manocha 			desc.offset = gpio_dsc.pin;
126280057bdSVikas Manocha 			rv = stm32_gpio_config(&desc, &gpio_ctl);
12794d53084SVikas Manocha 			debug("%s: rv = %d\n\n", __func__, rv);
12894d53084SVikas Manocha 			if (rv)
12994d53084SVikas Manocha 				return rv;
13094d53084SVikas Manocha 		}
13194d53084SVikas Manocha 	}
13294d53084SVikas Manocha 
13394d53084SVikas Manocha 	return 0;
13494d53084SVikas Manocha }
13594d53084SVikas Manocha 
136bb44b968SChristophe Kerello #if CONFIG_IS_ENABLED(PINCTRL_FULL)
stm32_pinctrl_set_state(struct udevice * dev,struct udevice * config)137bb44b968SChristophe Kerello static int stm32_pinctrl_set_state(struct udevice *dev, struct udevice *config)
138bb44b968SChristophe Kerello {
139bb44b968SChristophe Kerello 	return stm32_pinctrl_config(dev_of_offset(config));
140bb44b968SChristophe Kerello }
141bb44b968SChristophe Kerello #else /* PINCTRL_FULL */
stm32_pinctrl_set_state_simple(struct udevice * dev,struct udevice * periph)142ad0376e0SChristophe Kerello static int stm32_pinctrl_set_state_simple(struct udevice *dev,
143ad0376e0SChristophe Kerello 					  struct udevice *periph)
144ad0376e0SChristophe Kerello {
145ad0376e0SChristophe Kerello 	const void *fdt = gd->fdt_blob;
146ad0376e0SChristophe Kerello 	const fdt32_t *list;
147ad0376e0SChristophe Kerello 	uint32_t phandle;
148ad0376e0SChristophe Kerello 	int config_node;
149ad0376e0SChristophe Kerello 	int size, i, ret;
150ad0376e0SChristophe Kerello 
151ad0376e0SChristophe Kerello 	list = fdt_getprop(fdt, dev_of_offset(periph), "pinctrl-0", &size);
152ad0376e0SChristophe Kerello 	if (!list)
153ad0376e0SChristophe Kerello 		return -EINVAL;
154ad0376e0SChristophe Kerello 
155ad0376e0SChristophe Kerello 	debug("%s: periph->name = %s\n", __func__, periph->name);
156ad0376e0SChristophe Kerello 
157ad0376e0SChristophe Kerello 	size /= sizeof(*list);
158ad0376e0SChristophe Kerello 	for (i = 0; i < size; i++) {
159ad0376e0SChristophe Kerello 		phandle = fdt32_to_cpu(*list++);
160ad0376e0SChristophe Kerello 
161ad0376e0SChristophe Kerello 		config_node = fdt_node_offset_by_phandle(fdt, phandle);
162ad0376e0SChristophe Kerello 		if (config_node < 0) {
163*90aa625cSMasahiro Yamada 			pr_err("prop pinctrl-0 index %d invalid phandle\n", i);
164ad0376e0SChristophe Kerello 			return -EINVAL;
165ad0376e0SChristophe Kerello 		}
166ad0376e0SChristophe Kerello 
167ad0376e0SChristophe Kerello 		ret = stm32_pinctrl_config(config_node);
168ad0376e0SChristophe Kerello 		if (ret)
169ad0376e0SChristophe Kerello 			return ret;
170ad0376e0SChristophe Kerello 	}
171ad0376e0SChristophe Kerello 
172ad0376e0SChristophe Kerello 	return 0;
173ad0376e0SChristophe Kerello }
174bb44b968SChristophe Kerello #endif /* PINCTRL_FULL */
175ad0376e0SChristophe Kerello 
17694d53084SVikas Manocha static struct pinctrl_ops stm32_pinctrl_ops = {
177bb44b968SChristophe Kerello #if CONFIG_IS_ENABLED(PINCTRL_FULL)
178bb44b968SChristophe Kerello 	.set_state		= stm32_pinctrl_set_state,
179bb44b968SChristophe Kerello #else /* PINCTRL_FULL */
18094d53084SVikas Manocha 	.set_state_simple	= stm32_pinctrl_set_state_simple,
181bb44b968SChristophe Kerello #endif /* PINCTRL_FULL */
18294d53084SVikas Manocha };
18394d53084SVikas Manocha 
18494d53084SVikas Manocha static const struct udevice_id stm32_pinctrl_ids[] = {
18594d53084SVikas Manocha 	{ .compatible = "st,stm32f746-pinctrl" },
18694d53084SVikas Manocha 	{ }
18794d53084SVikas Manocha };
18894d53084SVikas Manocha 
18994d53084SVikas Manocha U_BOOT_DRIVER(pinctrl_stm32) = {
19094d53084SVikas Manocha 	.name		= "pinctrl_stm32",
19194d53084SVikas Manocha 	.id		= UCLASS_PINCTRL,
19294d53084SVikas Manocha 	.of_match	= stm32_pinctrl_ids,
19394d53084SVikas Manocha 	.ops		= &stm32_pinctrl_ops,
19494d53084SVikas Manocha 	.bind		= dm_scan_fdt_dev,
19594d53084SVikas Manocha };
196