xref: /rk3399_rockchip-uboot/drivers/pinctrl/pinctrl_stm32.c (revision 58fb3c8d89872f82a03c03625dcf5cc61b733bab)
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 
10*58fb3c8dSVikas 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 
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 }
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 
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 
9694d53084SVikas Manocha static int stm32_pinctrl_set_state_simple(struct udevice *dev,
9794d53084SVikas Manocha 					  struct udevice *periph)
9894d53084SVikas Manocha {
99*58fb3c8dSVikas Manocha 	u32 pin_mux[MAX_PINS_ONE_IP];
10094d53084SVikas Manocha 	struct fdtdec_phandle_args args;
10194d53084SVikas Manocha 	int rv, len;
10294d53084SVikas Manocha 
10394d53084SVikas Manocha 	/* Get node pinctrl-0 */
10494d53084SVikas Manocha 	rv = fdtdec_parse_phandle_with_args(gd->fdt_blob, periph->of_offset,
10594d53084SVikas Manocha 					   "pinctrl-0", 0, 0, 0, &args);
10694d53084SVikas Manocha 	if (rv)
10794d53084SVikas Manocha 		return rv;
10894d53084SVikas Manocha 	/*
10994d53084SVikas Manocha 	 * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for
11094d53084SVikas Manocha 	 * usart1) of pin controller phandle "pinctrl-0"
11194d53084SVikas Manocha 	 * */
11294d53084SVikas Manocha 	fdt_for_each_subnode(args.node, gd->fdt_blob, args.node) {
11394d53084SVikas Manocha 		struct stm32_gpio_dsc gpio_dsc;
11494d53084SVikas Manocha 		struct stm32_gpio_ctl gpio_ctl;
11594d53084SVikas Manocha 		int i;
11694d53084SVikas Manocha 
11794d53084SVikas Manocha 		len = fdtdec_get_int_array_count(gd->fdt_blob, args.node,
11894d53084SVikas Manocha 						 "pinmux", pin_mux,
11994d53084SVikas Manocha 						 ARRAY_SIZE(pin_mux));
12094d53084SVikas Manocha 		debug("%s: periph->name = %s, no of pinmux entries= %d\n",
12194d53084SVikas Manocha 		      __func__, periph->name, len);
12294d53084SVikas Manocha 		if (len < 0)
12394d53084SVikas Manocha 			return -EINVAL;
12494d53084SVikas Manocha 		for (i = 0; i < len; i++) {
125280057bdSVikas Manocha 			struct gpio_desc desc;
12694d53084SVikas Manocha 			debug("%s: pinmux = %x\n", __func__, *(pin_mux + i));
12794d53084SVikas Manocha 			prep_gpio_dsc(&gpio_dsc, *(pin_mux + i));
12894d53084SVikas Manocha 			prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), args.node);
129280057bdSVikas Manocha 			rv = uclass_get_device_by_seq(UCLASS_GPIO,
130280057bdSVikas Manocha 						      gpio_dsc.port, &desc.dev);
131280057bdSVikas Manocha 			if (rv)
132280057bdSVikas Manocha 				return rv;
133280057bdSVikas Manocha 			desc.offset = gpio_dsc.pin;
134280057bdSVikas Manocha 			rv = stm32_gpio_config(&desc, &gpio_ctl);
13594d53084SVikas Manocha 			debug("%s: rv = %d\n\n", __func__, rv);
13694d53084SVikas Manocha 			if (rv)
13794d53084SVikas Manocha 				return rv;
13894d53084SVikas Manocha 		}
13994d53084SVikas Manocha 	}
14094d53084SVikas Manocha 
14194d53084SVikas Manocha 	return 0;
14294d53084SVikas Manocha }
14394d53084SVikas Manocha 
14494d53084SVikas Manocha static struct pinctrl_ops stm32_pinctrl_ops = {
14594d53084SVikas Manocha 	.set_state_simple	= stm32_pinctrl_set_state_simple,
14694d53084SVikas Manocha };
14794d53084SVikas Manocha 
14894d53084SVikas Manocha static const struct udevice_id stm32_pinctrl_ids[] = {
14994d53084SVikas Manocha 	{ .compatible = "st,stm32f746-pinctrl" },
15094d53084SVikas Manocha 	{ }
15194d53084SVikas Manocha };
15294d53084SVikas Manocha 
15394d53084SVikas Manocha U_BOOT_DRIVER(pinctrl_stm32) = {
15494d53084SVikas Manocha 	.name		= "pinctrl_stm32",
15594d53084SVikas Manocha 	.id		= UCLASS_PINCTRL,
15694d53084SVikas Manocha 	.of_match	= stm32_pinctrl_ids,
15794d53084SVikas Manocha 	.ops		= &stm32_pinctrl_ops,
15894d53084SVikas Manocha 	.bind		= dm_scan_fdt_dev,
15994d53084SVikas Manocha };
160