]> git.proxmox.com Git - mirror_qemu.git/blob - hw/gpio/imx_gpio.c
Include hw/hw.h exactly where needed
[mirror_qemu.git] / hw / gpio / imx_gpio.c
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)