colibri_imx6: fix video stdout in default environment
[oweals/u-boot.git] / drivers / gpio / stm32_gpio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
4  * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
5  */
6
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <fdtdec.h>
11 #include <log.h>
12 #include <asm/arch/gpio.h>
13 #include <asm/arch/stm32.h>
14 #include <asm/gpio.h>
15 #include <asm/io.h>
16 #include <dm/device_compat.h>
17 #include <linux/bitops.h>
18 #include <linux/errno.h>
19 #include <linux/io.h>
20
21 #define MODE_BITS(gpio_pin)             (gpio_pin * 2)
22 #define MODE_BITS_MASK                  3
23 #define BSRR_BIT(gpio_pin, value)       BIT(gpio_pin + (value ? 0 : 16))
24
25 /*
26  * convert gpio offset to gpio index taking into account gpio holes
27  * into gpio bank
28  */
29 int stm32_offset_to_index(struct udevice *dev, unsigned int offset)
30 {
31         struct stm32_gpio_priv *priv = dev_get_priv(dev);
32         unsigned int idx = 0;
33         int i;
34
35         for (i = 0; i < STM32_GPIOS_PER_BANK; i++) {
36                 if (priv->gpio_range & BIT(i)) {
37                         if (idx == offset)
38                                 return idx;
39                         idx++;
40                 }
41         }
42         /* shouldn't happen */
43         return -EINVAL;
44 }
45
46 static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset)
47 {
48         struct stm32_gpio_priv *priv = dev_get_priv(dev);
49         struct stm32_gpio_regs *regs = priv->regs;
50         int bits_index;
51         int mask;
52         int idx;
53
54         idx = stm32_offset_to_index(dev, offset);
55         if (idx < 0)
56                 return idx;
57
58         bits_index = MODE_BITS(idx);
59         mask = MODE_BITS_MASK << bits_index;
60
61         clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_IN << bits_index);
62
63         return 0;
64 }
65
66 static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset,
67                                        int value)
68 {
69         struct stm32_gpio_priv *priv = dev_get_priv(dev);
70         struct stm32_gpio_regs *regs = priv->regs;
71         int bits_index;
72         int mask;
73         int idx;
74
75         idx = stm32_offset_to_index(dev, offset);
76         if (idx < 0)
77                 return idx;
78
79         bits_index = MODE_BITS(idx);
80         mask = MODE_BITS_MASK << bits_index;
81
82         clrsetbits_le32(&regs->moder, mask, STM32_GPIO_MODE_OUT << bits_index);
83
84         writel(BSRR_BIT(idx, value), &regs->bsrr);
85
86         return 0;
87 }
88
89 static int stm32_gpio_get_value(struct udevice *dev, unsigned offset)
90 {
91         struct stm32_gpio_priv *priv = dev_get_priv(dev);
92         struct stm32_gpio_regs *regs = priv->regs;
93         int idx;
94
95         idx = stm32_offset_to_index(dev, offset);
96         if (idx < 0)
97                 return idx;
98
99         return readl(&regs->idr) & BIT(idx) ? 1 : 0;
100 }
101
102 static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value)
103 {
104         struct stm32_gpio_priv *priv = dev_get_priv(dev);
105         struct stm32_gpio_regs *regs = priv->regs;
106         int idx;
107
108         idx = stm32_offset_to_index(dev, offset);
109         if (idx < 0)
110                 return idx;
111
112         writel(BSRR_BIT(idx, value), &regs->bsrr);
113
114         return 0;
115 }
116
117 static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset)
118 {
119         struct stm32_gpio_priv *priv = dev_get_priv(dev);
120         struct stm32_gpio_regs *regs = priv->regs;
121         int bits_index;
122         int mask;
123         int idx;
124         u32 mode;
125
126         idx = stm32_offset_to_index(dev, offset);
127         if (idx < 0)
128                 return idx;
129
130         bits_index = MODE_BITS(idx);
131         mask = MODE_BITS_MASK << bits_index;
132
133         mode = (readl(&regs->moder) & mask) >> bits_index;
134         if (mode == STM32_GPIO_MODE_OUT)
135                 return GPIOF_OUTPUT;
136         if (mode == STM32_GPIO_MODE_IN)
137                 return GPIOF_INPUT;
138         if (mode == STM32_GPIO_MODE_AN)
139                 return GPIOF_UNUSED;
140
141         return GPIOF_FUNC;
142 }
143
144 static const struct dm_gpio_ops gpio_stm32_ops = {
145         .direction_input        = stm32_gpio_direction_input,
146         .direction_output       = stm32_gpio_direction_output,
147         .get_value              = stm32_gpio_get_value,
148         .set_value              = stm32_gpio_set_value,
149         .get_function           = stm32_gpio_get_function,
150 };
151
152 static int gpio_stm32_probe(struct udevice *dev)
153 {
154         struct stm32_gpio_priv *priv = dev_get_priv(dev);
155         struct clk clk;
156         fdt_addr_t addr;
157         int ret;
158
159         addr = dev_read_addr(dev);
160         if (addr == FDT_ADDR_T_NONE)
161                 return -EINVAL;
162
163         priv->regs = (struct stm32_gpio_regs *)addr;
164
165         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
166         struct ofnode_phandle_args args;
167         const char *name;
168         int i;
169
170         name = dev_read_string(dev, "st,bank-name");
171         if (!name)
172                 return -EINVAL;
173         uc_priv->bank_name = name;
174
175         i = 0;
176         ret = dev_read_phandle_with_args(dev, "gpio-ranges",
177                                          NULL, 3, i, &args);
178
179         if (ret == -ENOENT) {
180                 uc_priv->gpio_count = STM32_GPIOS_PER_BANK;
181                 priv->gpio_range = GENMASK(STM32_GPIOS_PER_BANK - 1, 0);
182         }
183
184         while (ret != -ENOENT) {
185                 priv->gpio_range |= GENMASK(args.args[2] + args.args[0] - 1,
186                                     args.args[0]);
187
188                 uc_priv->gpio_count += args.args[2];
189
190                 ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3,
191                                                  ++i, &args);
192         }
193
194         dev_dbg(dev, "addr = 0x%p bank_name = %s gpio_count = %d gpio_range = 0x%x\n",
195                 (u32 *)priv->regs, uc_priv->bank_name, uc_priv->gpio_count,
196                 priv->gpio_range);
197
198         ret = clk_get_by_index(dev, 0, &clk);
199         if (ret < 0)
200                 return ret;
201
202         ret = clk_enable(&clk);
203
204         if (ret) {
205                 dev_err(dev, "failed to enable clock\n");
206                 return ret;
207         }
208         debug("clock enabled for device %s\n", dev->name);
209
210         return 0;
211 }
212
213 U_BOOT_DRIVER(gpio_stm32) = {
214         .name   = "gpio_stm32",
215         .id     = UCLASS_GPIO,
216         .probe  = gpio_stm32_probe,
217         .ops    = &gpio_stm32_ops,
218         .flags  = DM_UC_FLAG_SEQ_ALIAS,
219         .priv_auto_alloc_size   = sizeof(struct stm32_gpio_priv),
220 };