xref: /openbmc/qemu/hw/gpio/imx_gpio.c (revision d6454270)
1 /*
2  * i.MX processors GPIO emulation.
3  *
4  * Copyright (C) 2015 Jean-Christophe Dubois <jcd@tribudubois.net>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 or
9  * (at your option) version 3 of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "qemu/osdep.h"
21 #include "hw/gpio/imx_gpio.h"
22 #include "hw/irq.h"
23 #include "migration/vmstate.h"
24 #include "qemu/log.h"
25 #include "qemu/module.h"
26 
27 #ifndef DEBUG_IMX_GPIO
28 #define DEBUG_IMX_GPIO 0
29 #endif
30 
31 typedef enum IMXGPIOLevel {
32     IMX_GPIO_LEVEL_LOW = 0,
33     IMX_GPIO_LEVEL_HIGH = 1,
34 } IMXGPIOLevel;
35 
36 #define DPRINTF(fmt, args...) \
37     do { \
38         if (DEBUG_IMX_GPIO) { \
39             fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_GPIO, \
40                                              __func__, ##args); \
41         } \
42     } while (0)
43 
44 static const char *imx_gpio_reg_name(uint32_t reg)
45 {
46     switch (reg) {
47     case DR_ADDR:
48         return "DR";
49     case GDIR_ADDR:
50         return "GDIR";
51     case PSR_ADDR:
52         return "PSR";
53     case ICR1_ADDR:
54         return "ICR1";
55     case ICR2_ADDR:
56         return "ICR2";
57     case IMR_ADDR:
58         return "IMR";
59     case ISR_ADDR:
60         return "ISR";
61     case EDGE_SEL_ADDR:
62         return "EDGE_SEL";
63     default:
64         return "[?]";
65     }
66 }
67 
68 static void imx_gpio_update_int(IMXGPIOState *s)
69 {
70     if (s->has_upper_pin_irq) {
71         qemu_set_irq(s->irq[0], (s->isr & s->imr & 0x0000FFFF) ? 1 : 0);
72         qemu_set_irq(s->irq[1], (s->isr & s->imr & 0xFFFF0000) ? 1 : 0);
73     } else {
74         qemu_set_irq(s->irq[0], (s->isr & s->imr) ? 1 : 0);
75     }
76 }
77 
78 static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level)
79 {
80     /* if this signal isn't configured as an input signal, nothing to do */
81     if (!extract32(s->gdir, line, 1)) {
82         return;
83     }
84 
85     /* When set, EDGE_SEL overrides the ICR config */
86     if (extract32(s->edge_sel, line, 1)) {
87         /* we detect interrupt on rising and falling edge */
88         if (extract32(s->psr, line, 1) != level) {
89             /* level changed */
90             s->isr = deposit32(s->isr, line, 1, 1);
91         }
92     } else if (extract64(s->icr, 2*line + 1, 1)) {
93         /* interrupt is edge sensitive */
94         if (extract32(s->psr, line, 1) != level) {
95             /* level changed */
96             if (extract64(s->icr, 2*line, 1) != level) {
97                 s->isr = deposit32(s->isr, line, 1, 1);
98             }
99         }
100     } else {
101         /* interrupt is level sensitive */
102         if (extract64(s->icr, 2*line, 1) == level) {
103             s->isr = deposit32(s->isr, line, 1, 1);
104         }
105     }
106 }
107 
108 static void imx_gpio_set(void *opaque, int line, int level)
109 {
110     IMXGPIOState *s = IMX_GPIO(opaque);
111     IMXGPIOLevel imx_level = level ? IMX_GPIO_LEVEL_HIGH : IMX_GPIO_LEVEL_LOW;
112 
113     imx_gpio_set_int_line(s, line, imx_level);
114 
115     /* this is an input signal, so set PSR */
116     s->psr = deposit32(s->psr, line, 1, imx_level);
117 
118     imx_gpio_update_int(s);
119 }
120 
121 static void imx_gpio_set_all_int_lines(IMXGPIOState *s)
122 {
123     int i;
124 
125     for (i = 0; i < IMX_GPIO_PIN_COUNT; i++) {
126         IMXGPIOLevel imx_level = extract32(s->psr, i, 1);
127         imx_gpio_set_int_line(s, i, imx_level);
128     }
129 
130     imx_gpio_update_int(s);
131 }
132 
133 static inline void imx_gpio_set_all_output_lines(IMXGPIOState *s)
134 {
135     int i;
136 
137     for (i = 0; i < IMX_GPIO_PIN_COUNT; i++) {
138         /*
139          * if the line is set as output, then forward the line
140          * level to its user.
141          */
142         if (extract32(s->gdir, i, 1) && s->output[i]) {
143             qemu_set_irq(s->output[i], extract32(s->dr, i, 1));
144         }
145     }
146 }
147 
148 static uint64_t imx_gpio_read(void *opaque, hwaddr offset, unsigned size)
149 {
150     IMXGPIOState *s = IMX_GPIO(opaque);
151     uint32_t reg_value = 0;
152 
153     switch (offset) {
154     case DR_ADDR:
155         /*
156          * depending on the "line" configuration, the bit values
157          * are coming either from DR or PSR
158          */
159         reg_value = (s->dr & s->gdir) | (s->psr & ~s->gdir);
160         break;
161 
162     case GDIR_ADDR:
163         reg_value = s->gdir;
164         break;
165 
166     case PSR_ADDR:
167         reg_value = s->psr & ~s->gdir;
168         break;
169 
170     case ICR1_ADDR:
171         reg_value = extract64(s->icr, 0, 32);
172         break;
173 
174     case ICR2_ADDR:
175         reg_value = extract64(s->icr, 32, 32);
176         break;
177 
178     case IMR_ADDR:
179         reg_value = s->imr;
180         break;
181 
182     case ISR_ADDR:
183         reg_value = s->isr;
184         break;
185 
186     case EDGE_SEL_ADDR:
187         if (s->has_edge_sel) {
188             reg_value = s->edge_sel;
189         } else {
190             qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: EDGE_SEL register not "
191                           "present on this version of GPIO device\n",
192                           TYPE_IMX_GPIO, __func__);
193         }
194         break;
195 
196     default:
197         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
198                       HWADDR_PRIx "\n", TYPE_IMX_GPIO, __func__, offset);
199         break;
200     }
201 
202     DPRINTF("(%s) = 0x%" PRIx32 "\n", imx_gpio_reg_name(offset), reg_value);
203 
204     return reg_value;
205 }
206 
207 static void imx_gpio_write(void *opaque, hwaddr offset, uint64_t value,
208                            unsigned size)
209 {
210     IMXGPIOState *s = IMX_GPIO(opaque);
211 
212     DPRINTF("(%s, value = 0x%" PRIx32 ")\n", imx_gpio_reg_name(offset),
213             (uint32_t)value);
214 
215     switch (offset) {
216     case DR_ADDR:
217         s->dr = value;
218         imx_gpio_set_all_output_lines(s);
219         break;
220 
221     case GDIR_ADDR:
222         s->gdir = value;
223         imx_gpio_set_all_output_lines(s);
224         imx_gpio_set_all_int_lines(s);
225         break;
226 
227     case ICR1_ADDR:
228         s->icr = deposit64(s->icr, 0, 32, value);
229         imx_gpio_set_all_int_lines(s);
230         break;
231 
232     case ICR2_ADDR:
233         s->icr = deposit64(s->icr, 32, 32, value);
234         imx_gpio_set_all_int_lines(s);
235         break;
236 
237     case IMR_ADDR:
238         s->imr = value;
239         imx_gpio_update_int(s);
240         break;
241 
242     case ISR_ADDR:
243         s->isr &= ~value;
244         imx_gpio_set_all_int_lines(s);
245         break;
246 
247     case EDGE_SEL_ADDR:
248         if (s->has_edge_sel) {
249             s->edge_sel = value;
250             imx_gpio_set_all_int_lines(s);
251         } else {
252             qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: EDGE_SEL register not "
253                           "present on this version of GPIO device\n",
254                           TYPE_IMX_GPIO, __func__);
255         }
256         break;
257 
258     default:
259         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
260                       HWADDR_PRIx "\n", TYPE_IMX_GPIO, __func__, offset);
261         break;
262     }
263 
264     return;
265 }
266 
267 static const MemoryRegionOps imx_gpio_ops = {
268     .read = imx_gpio_read,
269     .write = imx_gpio_write,
270     .valid.min_access_size = 4,
271     .valid.max_access_size = 4,
272     .endianness = DEVICE_NATIVE_ENDIAN,
273 };
274 
275 static const VMStateDescription vmstate_imx_gpio = {
276     .name = TYPE_IMX_GPIO,
277     .version_id = 1,
278     .minimum_version_id = 1,
279     .minimum_version_id_old = 1,
280     .fields = (VMStateField[]) {
281         VMSTATE_UINT32(dr, IMXGPIOState),
282         VMSTATE_UINT32(gdir, IMXGPIOState),
283         VMSTATE_UINT32(psr, IMXGPIOState),
284         VMSTATE_UINT64(icr, IMXGPIOState),
285         VMSTATE_UINT32(imr, IMXGPIOState),
286         VMSTATE_UINT32(isr, IMXGPIOState),
287         VMSTATE_BOOL(has_edge_sel, IMXGPIOState),
288         VMSTATE_UINT32(edge_sel, IMXGPIOState),
289         VMSTATE_END_OF_LIST()
290     }
291 };
292 
293 static Property imx_gpio_properties[] = {
294     DEFINE_PROP_BOOL("has-edge-sel", IMXGPIOState, has_edge_sel, true),
295     DEFINE_PROP_BOOL("has-upper-pin-irq", IMXGPIOState, has_upper_pin_irq,
296                      false),
297     DEFINE_PROP_END_OF_LIST(),
298 };
299 
300 static void imx_gpio_reset(DeviceState *dev)
301 {
302     IMXGPIOState *s = IMX_GPIO(dev);
303 
304     s->dr       = 0;
305     s->gdir     = 0;
306     s->psr      = 0;
307     s->icr      = 0;
308     s->imr      = 0;
309     s->isr      = 0;
310     s->edge_sel = 0;
311 
312     imx_gpio_set_all_output_lines(s);
313     imx_gpio_update_int(s);
314 }
315 
316 static void imx_gpio_realize(DeviceState *dev, Error **errp)
317 {
318     IMXGPIOState *s = IMX_GPIO(dev);
319 
320     memory_region_init_io(&s->iomem, OBJECT(s), &imx_gpio_ops, s,
321                           TYPE_IMX_GPIO, IMX_GPIO_MEM_SIZE);
322 
323     qdev_init_gpio_in(DEVICE(s), imx_gpio_set, IMX_GPIO_PIN_COUNT);
324     qdev_init_gpio_out(DEVICE(s), s->output, IMX_GPIO_PIN_COUNT);
325 
326     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[0]);
327     sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[1]);
328     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
329 }
330 
331 static void imx_gpio_class_init(ObjectClass *klass, void *data)
332 {
333     DeviceClass *dc = DEVICE_CLASS(klass);
334 
335     dc->realize = imx_gpio_realize;
336     dc->reset = imx_gpio_reset;
337     dc->props = imx_gpio_properties;
338     dc->vmsd = &vmstate_imx_gpio;
339     dc->desc = "i.MX GPIO controller";
340 }
341 
342 static const TypeInfo imx_gpio_info = {
343     .name = TYPE_IMX_GPIO,
344     .parent = TYPE_SYS_BUS_DEVICE,
345     .instance_size = sizeof(IMXGPIOState),
346     .class_init = imx_gpio_class_init,
347 };
348 
349 static void imx_gpio_register_types(void)
350 {
351     type_register_static(&imx_gpio_info);
352 }
353 
354 type_init(imx_gpio_register_types)
355