dm: core: Access device ofnode through functions
[platform/kernel/u-boot.git] / drivers / gpio / mpc8xxx_gpio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2016
4  * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5  *
6  * based on arch/powerpc/include/asm/mpc85xx_gpio.h, which is
7  *
8  * Copyright 2010 eXMeritus, A Boeing Company
9  * Copyright 2020 NXP
10  */
11
12 #include <common.h>
13 #include <dm.h>
14 #include <mapmem.h>
15 #include <asm/gpio.h>
16 #include <asm/io.h>
17 #include <dm/of_access.h>
18
19 struct ccsr_gpio {
20         u32     gpdir;
21         u32     gpodr;
22         u32     gpdat;
23         u32     gpier;
24         u32     gpimr;
25         u32     gpicr;
26         u32     gpibe;
27 };
28
29 struct mpc8xxx_gpio_data {
30         /* The bank's register base in memory */
31         struct ccsr_gpio __iomem *base;
32         /* The address of the registers; used to identify the bank */
33         ulong addr;
34         /* The GPIO count of the bank */
35         uint gpio_count;
36         /* The GPDAT register cannot be used to determine the value of output
37          * pins on MPC8572/MPC8536, so we shadow it and use the shadowed value
38          * for output pins
39          */
40         u32 dat_shadow;
41         ulong type;
42         bool  little_endian;
43 };
44
45 enum {
46         MPC8XXX_GPIO_TYPE,
47         MPC5121_GPIO_TYPE,
48 };
49
50 inline u32 gpio_mask(uint gpio)
51 {
52         return (1U << (31 - (gpio)));
53 }
54
55 static inline u32 mpc8xxx_gpio_get_val(struct udevice *dev, u32 mask)
56 {
57         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
58
59         if (data->little_endian)
60                 return in_le32(&data->base->gpdat) & mask;
61         else
62                 return in_be32(&data->base->gpdat) & mask;
63 }
64
65 static inline u32 mpc8xxx_gpio_get_dir(struct udevice *dev, u32 mask)
66 {
67         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
68
69         if (data->little_endian)
70                 return in_le32(&data->base->gpdir) & mask;
71         else
72                 return in_be32(&data->base->gpdir) & mask;
73 }
74
75 static inline int mpc8xxx_gpio_open_drain_val(struct udevice *dev, u32 mask)
76 {
77         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
78
79         if (data->little_endian)
80                 return in_le32(&data->base->gpodr) & mask;
81         else
82                 return in_be32(&data->base->gpodr) & mask;
83 }
84
85 static inline void mpc8xxx_gpio_open_drain_on(struct udevice *dev, u32
86                                               gpios)
87 {
88         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
89         /* GPODR register 1 -> open drain on */
90         if (data->little_endian)
91                 setbits_le32(&data->base->gpodr, gpios);
92         else
93                 setbits_be32(&data->base->gpodr, gpios);
94 }
95
96 static inline void mpc8xxx_gpio_open_drain_off(struct udevice *dev,
97                                                u32 gpios)
98 {
99         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
100         /* GPODR register 0 -> open drain off (actively driven) */
101         if (data->little_endian)
102                 clrbits_le32(&data->base->gpodr, gpios);
103         else
104                 clrbits_be32(&data->base->gpodr, gpios);
105 }
106
107 static int mpc8xxx_gpio_direction_input(struct udevice *dev, uint gpio)
108 {
109         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
110         u32 mask = gpio_mask(gpio);
111
112         /* GPDIR register 0 -> input */
113         if (data->little_endian)
114                 clrbits_le32(&data->base->gpdir, mask);
115         else
116                 clrbits_be32(&data->base->gpdir, mask);
117
118         return 0;
119 }
120
121 static int mpc8xxx_gpio_set_value(struct udevice *dev, uint gpio, int value)
122 {
123         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
124         struct ccsr_gpio *base = data->base;
125         u32 mask = gpio_mask(gpio);
126         u32 gpdir;
127
128         if (value) {
129                 data->dat_shadow |= mask;
130         } else {
131                 data->dat_shadow &= ~mask;
132         }
133
134         if (data->little_endian)
135                 gpdir = in_le32(&base->gpdir);
136         else
137                 gpdir = in_be32(&base->gpdir);
138
139         gpdir |= gpio_mask(gpio);
140
141         if (data->little_endian) {
142                 out_le32(&base->gpdat, gpdir & data->dat_shadow);
143                 out_le32(&base->gpdir, gpdir);
144         } else {
145                 out_be32(&base->gpdat, gpdir & data->dat_shadow);
146                 out_be32(&base->gpdir, gpdir);
147         }
148
149         return 0;
150 }
151
152 static int mpc8xxx_gpio_direction_output(struct udevice *dev, uint gpio,
153                                          int value)
154 {
155         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
156
157         /* GPIO 28..31 are input only on MPC5121 */
158         if (data->type == MPC5121_GPIO_TYPE && gpio >= 28)
159                 return -EINVAL;
160
161         return mpc8xxx_gpio_set_value(dev, gpio, value);
162 }
163
164 static int mpc8xxx_gpio_get_value(struct udevice *dev, uint gpio)
165 {
166         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
167
168         if (!!mpc8xxx_gpio_get_dir(dev, gpio_mask(gpio))) {
169                 /* Output -> use shadowed value */
170                 return !!(data->dat_shadow & gpio_mask(gpio));
171         }
172
173         /* Input -> read value from GPDAT register */
174         return !!mpc8xxx_gpio_get_val(dev, gpio_mask(gpio));
175 }
176
177 static int mpc8xxx_gpio_get_function(struct udevice *dev, uint gpio)
178 {
179         int dir;
180
181         dir = !!mpc8xxx_gpio_get_dir(dev, gpio_mask(gpio));
182         return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
183 }
184
185 #if CONFIG_IS_ENABLED(OF_CONTROL)
186 static int mpc8xxx_gpio_of_to_plat(struct udevice *dev)
187 {
188         struct mpc8xxx_gpio_plat *plat = dev_get_plat(dev);
189         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
190         fdt_addr_t addr;
191         u32 i;
192         u32 reg[4];
193
194         if (ofnode_read_bool(dev_ofnode(dev), "little-endian"))
195                 data->little_endian = true;
196
197         if (data->little_endian)
198                 dev_read_u32_array(dev, "reg", reg, 4);
199         else
200                 dev_read_u32_array(dev, "reg", reg, 2);
201
202         if (data->little_endian) {
203                 for (i = 0; i < 2; i++)
204                         reg[i] = be32_to_cpu(reg[i]);
205         }
206
207         addr = dev_translate_address(dev, reg);
208
209         plat->addr = addr;
210
211         if (data->little_endian)
212                 plat->size = reg[3];
213         else
214                 plat->size = reg[1];
215
216         plat->ngpios = dev_read_u32_default(dev, "ngpios", 32);
217
218         return 0;
219 }
220 #endif
221
222 static int mpc8xxx_gpio_plat_to_priv(struct udevice *dev)
223 {
224         struct mpc8xxx_gpio_data *priv = dev_get_priv(dev);
225         struct mpc8xxx_gpio_plat *plat = dev_get_plat(dev);
226         unsigned long size = plat->size;
227         ulong driver_data = dev_get_driver_data(dev);
228
229         if (size == 0)
230                 size = 0x100;
231
232         priv->addr = plat->addr;
233         priv->base = map_sysmem(plat->addr, size);
234
235         if (!priv->base)
236                 return -ENOMEM;
237
238         priv->gpio_count = plat->ngpios;
239         priv->dat_shadow = 0;
240
241         priv->type = driver_data;
242
243         return 0;
244 }
245
246 static int mpc8xxx_gpio_probe(struct udevice *dev)
247 {
248         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
249         struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
250         char name[32], *str;
251
252         mpc8xxx_gpio_plat_to_priv(dev);
253
254         snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
255         str = strdup(name);
256
257         if (!str)
258                 return -ENOMEM;
259
260         if (ofnode_device_is_compatible(dev_ofnode(dev), "fsl,qoriq-gpio")) {
261                 unsigned long gpibe = data->addr + sizeof(struct ccsr_gpio)
262                         - sizeof(u32);
263
264                 out_be32((unsigned int *)gpibe, 0xffffffff);
265         }
266
267         uc_priv->bank_name = str;
268         uc_priv->gpio_count = data->gpio_count;
269
270         return 0;
271 }
272
273 static const struct dm_gpio_ops gpio_mpc8xxx_ops = {
274         .direction_input        = mpc8xxx_gpio_direction_input,
275         .direction_output       = mpc8xxx_gpio_direction_output,
276         .get_value              = mpc8xxx_gpio_get_value,
277         .set_value              = mpc8xxx_gpio_set_value,
278         .get_function           = mpc8xxx_gpio_get_function,
279 };
280
281 static const struct udevice_id mpc8xxx_gpio_ids[] = {
282         { .compatible = "fsl,pq3-gpio", .data = MPC8XXX_GPIO_TYPE },
283         { .compatible = "fsl,mpc8308-gpio", .data = MPC8XXX_GPIO_TYPE },
284         { .compatible = "fsl,mpc8349-gpio", .data = MPC8XXX_GPIO_TYPE },
285         { .compatible = "fsl,mpc8572-gpio", .data = MPC8XXX_GPIO_TYPE},
286         { .compatible = "fsl,mpc8610-gpio", .data = MPC8XXX_GPIO_TYPE},
287         { .compatible = "fsl,mpc5121-gpio", .data = MPC5121_GPIO_TYPE, },
288         { .compatible = "fsl,qoriq-gpio", .data = MPC8XXX_GPIO_TYPE },
289         { /* sentinel */ }
290 };
291
292 U_BOOT_DRIVER(gpio_mpc8xxx) = {
293         .name   = "gpio_mpc8xxx",
294         .id     = UCLASS_GPIO,
295         .ops    = &gpio_mpc8xxx_ops,
296 #if CONFIG_IS_ENABLED(OF_CONTROL)
297         .of_to_plat = mpc8xxx_gpio_of_to_plat,
298         .plat_auto      = sizeof(struct mpc8xxx_gpio_plat),
299         .of_match = mpc8xxx_gpio_ids,
300 #endif
301         .probe  = mpc8xxx_gpio_probe,
302         .priv_auto      = sizeof(struct mpc8xxx_gpio_data),
303 };