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(®s->afr[desc->offset >> 3], AFR_MASK << index, 3077417102SVikas Manocha ctl->af << index); 3177417102SVikas Manocha 3277417102SVikas Manocha index = desc->offset * 2; 3377417102SVikas Manocha clrsetbits_le32(®s->moder, MODE_BITS_MASK << index, 3477417102SVikas Manocha ctl->mode << index); 3577417102SVikas Manocha clrsetbits_le32(®s->ospeedr, OSPEED_MASK << index, 3677417102SVikas Manocha ctl->speed << index); 3777417102SVikas Manocha clrsetbits_le32(®s->pupdr, PUPD_MASK << index, ctl->pupd << index); 3877417102SVikas Manocha 3977417102SVikas Manocha index = desc->offset; 4077417102SVikas Manocha clrsetbits_le32(®s->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