Home | History | Annotate | Download | only in pinctrl
      1 #include <common.h>
      2 #include <dm.h>
      3 #include <dm/pinctrl.h>
      4 #include <asm/arch/gpio.h>
      5 #include <asm/gpio.h>
      6 #include <asm/io.h>
      7 
      8 DECLARE_GLOBAL_DATA_PTR;
      9 
     10 #define MAX_PINS_ONE_IP			70
     11 #define MODE_BITS_MASK			3
     12 #define OSPEED_MASK			3
     13 #define PUPD_MASK			3
     14 #define OTYPE_MSK			1
     15 #define AFR_MASK			0xF
     16 
     17 static int stm32_gpio_config(struct gpio_desc *desc,
     18 			     const struct stm32_gpio_ctl *ctl)
     19 {
     20 	struct stm32_gpio_priv *priv = dev_get_priv(desc->dev);
     21 	struct stm32_gpio_regs *regs = priv->regs;
     22 	u32 index;
     23 
     24 	if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 ||
     25 	    ctl->pupd > 2 || ctl->speed > 3)
     26 		return -EINVAL;
     27 
     28 	index = (desc->offset & 0x07) * 4;
     29 	clrsetbits_le32(&regs->afr[desc->offset >> 3], AFR_MASK << index,
     30 			ctl->af << index);
     31 
     32 	index = desc->offset * 2;
     33 	clrsetbits_le32(&regs->moder, MODE_BITS_MASK << index,
     34 			ctl->mode << index);
     35 	clrsetbits_le32(&regs->ospeedr, OSPEED_MASK << index,
     36 			ctl->speed << index);
     37 	clrsetbits_le32(&regs->pupdr, PUPD_MASK << index, ctl->pupd << index);
     38 
     39 	index = desc->offset;
     40 	clrsetbits_le32(&regs->otyper, OTYPE_MSK << index, ctl->otype << index);
     41 
     42 	return 0;
     43 }
     44 
     45 static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin)
     46 {
     47 	gpio_dsc->port = (port_pin & 0x1F000) >> 12;
     48 	gpio_dsc->pin = (port_pin & 0x0F00) >> 8;
     49 	debug("%s: GPIO:port= %d, pin= %d\n", __func__, gpio_dsc->port,
     50 	      gpio_dsc->pin);
     51 
     52 	return 0;
     53 }
     54 
     55 static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node)
     56 {
     57 	gpio_fn &= 0x00FF;
     58 	gpio_ctl->af = 0;
     59 
     60 	switch (gpio_fn) {
     61 	case 0:
     62 		gpio_ctl->mode = STM32_GPIO_MODE_IN;
     63 		break;
     64 	case 1 ... 16:
     65 		gpio_ctl->mode = STM32_GPIO_MODE_AF;
     66 		gpio_ctl->af = gpio_fn - 1;
     67 		break;
     68 	case 17:
     69 		gpio_ctl->mode = STM32_GPIO_MODE_AN;
     70 		break;
     71 	default:
     72 		gpio_ctl->mode = STM32_GPIO_MODE_OUT;
     73 		break;
     74 	}
     75 
     76 	gpio_ctl->speed = fdtdec_get_int(gd->fdt_blob, node, "slew-rate", 0);
     77 
     78 	if (fdtdec_get_bool(gd->fdt_blob, node, "drive-open-drain"))
     79 		gpio_ctl->otype = STM32_GPIO_OTYPE_OD;
     80 	else
     81 		gpio_ctl->otype = STM32_GPIO_OTYPE_PP;
     82 
     83 	if (fdtdec_get_bool(gd->fdt_blob, node, "bias-pull-up"))
     84 		gpio_ctl->pupd = STM32_GPIO_PUPD_UP;
     85 	else if (fdtdec_get_bool(gd->fdt_blob, node, "bias-pull-down"))
     86 		gpio_ctl->pupd = STM32_GPIO_PUPD_DOWN;
     87 	else
     88 		gpio_ctl->pupd = STM32_GPIO_PUPD_NO;
     89 
     90 	debug("%s: gpio fn= %d, slew-rate= %x, op type= %x, pull-upd is = %x\n",
     91 	      __func__,  gpio_fn, gpio_ctl->speed, gpio_ctl->otype,
     92 	     gpio_ctl->pupd);
     93 
     94 	return 0;
     95 }
     96 
     97 static int stm32_pinctrl_config(int offset)
     98 {
     99 	u32 pin_mux[MAX_PINS_ONE_IP];
    100 	int rv, len;
    101 
    102 	/*
    103 	 * check for "pinmux" property in each subnode (e.g. pins1 and pins2 for
    104 	 * usart1) of pin controller phandle "pinctrl-0"
    105 	 * */
    106 	fdt_for_each_subnode(offset, gd->fdt_blob, offset) {
    107 		struct stm32_gpio_dsc gpio_dsc;
    108 		struct stm32_gpio_ctl gpio_ctl;
    109 		int i;
    110 
    111 		len = fdtdec_get_int_array_count(gd->fdt_blob, offset,
    112 						 "pinmux", pin_mux,
    113 						 ARRAY_SIZE(pin_mux));
    114 		debug("%s: no of pinmux entries= %d\n", __func__, len);
    115 		if (len < 0)
    116 			return -EINVAL;
    117 		for (i = 0; i < len; i++) {
    118 			struct gpio_desc desc;
    119 
    120 			debug("%s: pinmux = %x\n", __func__, *(pin_mux + i));
    121 			prep_gpio_dsc(&gpio_dsc, *(pin_mux + i));
    122 			prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), offset);
    123 			rv = uclass_get_device_by_seq(UCLASS_GPIO,
    124 						      gpio_dsc.port,
    125 						      &desc.dev);
    126 			if (rv)
    127 				return rv;
    128 			desc.offset = gpio_dsc.pin;
    129 			rv = stm32_gpio_config(&desc, &gpio_ctl);
    130 			debug("%s: rv = %d\n\n", __func__, rv);
    131 			if (rv)
    132 				return rv;
    133 		}
    134 	}
    135 
    136 	return 0;
    137 }
    138 
    139 #if CONFIG_IS_ENABLED(PINCTRL_FULL)
    140 static int stm32_pinctrl_set_state(struct udevice *dev, struct udevice *config)
    141 {
    142 	return stm32_pinctrl_config(dev_of_offset(config));
    143 }
    144 #else /* PINCTRL_FULL */
    145 static int stm32_pinctrl_set_state_simple(struct udevice *dev,
    146 					  struct udevice *periph)
    147 {
    148 	const void *fdt = gd->fdt_blob;
    149 	const fdt32_t *list;
    150 	uint32_t phandle;
    151 	int config_node;
    152 	int size, i, ret;
    153 
    154 	list = fdt_getprop(fdt, dev_of_offset(periph), "pinctrl-0", &size);
    155 	if (!list)
    156 		return -EINVAL;
    157 
    158 	debug("%s: periph->name = %s\n", __func__, periph->name);
    159 
    160 	size /= sizeof(*list);
    161 	for (i = 0; i < size; i++) {
    162 		phandle = fdt32_to_cpu(*list++);
    163 
    164 		config_node = fdt_node_offset_by_phandle(fdt, phandle);
    165 		if (config_node < 0) {
    166 			pr_err("prop pinctrl-0 index %d invalid phandle\n", i);
    167 			return -EINVAL;
    168 		}
    169 
    170 		ret = stm32_pinctrl_config(config_node);
    171 		if (ret)
    172 			return ret;
    173 	}
    174 
    175 	return 0;
    176 }
    177 #endif /* PINCTRL_FULL */
    178 
    179 static struct pinctrl_ops stm32_pinctrl_ops = {
    180 #if CONFIG_IS_ENABLED(PINCTRL_FULL)
    181 	.set_state		= stm32_pinctrl_set_state,
    182 #else /* PINCTRL_FULL */
    183 	.set_state_simple	= stm32_pinctrl_set_state_simple,
    184 #endif /* PINCTRL_FULL */
    185 };
    186 
    187 static const struct udevice_id stm32_pinctrl_ids[] = {
    188 	{ .compatible = "st,stm32f429-pinctrl" },
    189 	{ .compatible = "st,stm32f469-pinctrl" },
    190 	{ .compatible = "st,stm32f746-pinctrl" },
    191 	{ .compatible = "st,stm32h743-pinctrl" },
    192 	{ .compatible = "st,stm32mp157-pinctrl" },
    193 	{ .compatible = "st,stm32mp157-z-pinctrl" },
    194 	{ }
    195 };
    196 
    197 U_BOOT_DRIVER(pinctrl_stm32) = {
    198 	.name		= "pinctrl_stm32",
    199 	.id		= UCLASS_PINCTRL,
    200 	.of_match	= stm32_pinctrl_ids,
    201 	.ops		= &stm32_pinctrl_ops,
    202 	.bind		= dm_scan_fdt_dev,
    203 };
    204