2 * TI OMAP processors GPIO emulation.
4 * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
5 * Copyright (C) 2007-2009 Nokia Corporation
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 or
10 * (at your option) version 3 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, see <http://www.gnu.org/licenses/>.
23 /* General-Purpose I/O */
38 static void omap_gpio_set(void *opaque, int line, int level)
40 struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
41 uint16_t prev = s->inputs;
44 s->inputs |= 1 << line;
46 s->inputs &= ~(1 << line);
48 if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
49 (1 << line) & s->dir & ~s->mask) {
51 qemu_irq_raise(s->irq);
55 static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
57 struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
58 int offset = addr & OMAP_MPUI_REG_MASK;
61 case 0x00: /* DATA_INPUT */
62 return s->inputs & s->pins;
64 case 0x04: /* DATA_OUTPUT */
67 case 0x08: /* DIRECTION_CONTROL */
70 case 0x0c: /* INTERRUPT_CONTROL */
73 case 0x10: /* INTERRUPT_MASK */
76 case 0x14: /* INTERRUPT_STATUS */
79 case 0x18: /* PIN_CONTROL (not in OMAP310) */
88 static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
91 struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
92 int offset = addr & OMAP_MPUI_REG_MASK;
97 case 0x00: /* DATA_INPUT */
101 case 0x04: /* DATA_OUTPUT */
102 diff = (s->outputs ^ value) & ~s->dir;
104 while ((ln = ffs(diff))) {
107 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
112 case 0x08: /* DIRECTION_CONTROL */
113 diff = s->outputs & (s->dir ^ value);
116 value = s->outputs & ~s->dir;
117 while ((ln = ffs(diff))) {
120 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
125 case 0x0c: /* INTERRUPT_CONTROL */
129 case 0x10: /* INTERRUPT_MASK */
133 case 0x14: /* INTERRUPT_STATUS */
136 qemu_irq_lower(s->irq);
139 case 0x18: /* PIN_CONTROL (not in OMAP310 TRM) */
150 /* *Some* sources say the memory region is 32-bit. */
151 static CPUReadMemoryFunc * const omap_gpio_readfn[] = {
152 omap_badwidth_read16,
154 omap_badwidth_read16,
157 static CPUWriteMemoryFunc * const omap_gpio_writefn[] = {
158 omap_badwidth_write16,
160 omap_badwidth_write16,
163 void omap_gpio_reset(struct omap_gpio_s *s)
174 struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
175 qemu_irq irq, omap_clk clk)
178 struct omap_gpio_s *s = (struct omap_gpio_s *)
179 qemu_mallocz(sizeof(struct omap_gpio_s));
182 s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
185 iomemtype = cpu_register_io_memory(omap_gpio_readfn,
186 omap_gpio_writefn, s, DEVICE_NATIVE_ENDIAN);
187 cpu_register_physical_memory(base, 0x1000, iomemtype);
192 qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
197 void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
199 if (line >= 16 || line < 0)
200 hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
201 s->handler[line] = handler;
204 /* General-Purpose Interface of OMAP2 */
205 struct omap2_gpio_s {
209 qemu_irq handler[32];
224 static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s,
227 qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
230 static void omap2_gpio_module_wake(struct omap2_gpio_s *s, int line)
232 if (!(s->config[0] & (1 << 2))) /* ENAWAKEUP */
234 if (!(s->config[0] & (3 << 3))) /* Force Idle */
236 if (!(s->wumask & (1 << line)))
239 qemu_irq_raise(s->wkup);
242 static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
249 while ((ln = ffs(diff))) {
251 qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
256 static void omap2_gpio_module_level_update(struct omap2_gpio_s *s, int line)
258 s->ints[line] |= s->dir &
259 ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
260 omap2_gpio_module_int_update(s, line);
263 static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
265 s->ints[0] |= 1 << line;
266 omap2_gpio_module_int_update(s, 0);
267 s->ints[1] |= 1 << line;
268 omap2_gpio_module_int_update(s, 1);
269 omap2_gpio_module_wake(s, line);
272 static void omap2_gpio_module_set(void *opaque, int line, int level)
274 struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
277 if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
278 omap2_gpio_module_int(s, line);
279 s->inputs |= 1 << line;
281 if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
282 omap2_gpio_module_int(s, line);
283 s->inputs &= ~(1 << line);
287 static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
305 static uint32_t omap2_gpio_module_read(void *opaque, target_phys_addr_t addr)
307 struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
310 case 0x00: /* GPIO_REVISION */
313 case 0x10: /* GPIO_SYSCONFIG */
316 case 0x14: /* GPIO_SYSSTATUS */
319 case 0x18: /* GPIO_IRQSTATUS1 */
322 case 0x1c: /* GPIO_IRQENABLE1 */
323 case 0x60: /* GPIO_CLEARIRQENABLE1 */
324 case 0x64: /* GPIO_SETIRQENABLE1 */
327 case 0x20: /* GPIO_WAKEUPENABLE */
328 case 0x80: /* GPIO_CLEARWKUENA */
329 case 0x84: /* GPIO_SETWKUENA */
332 case 0x28: /* GPIO_IRQSTATUS2 */
335 case 0x2c: /* GPIO_IRQENABLE2 */
336 case 0x70: /* GPIO_CLEARIRQENABLE2 */
337 case 0x74: /* GPIO_SETIREQNEABLE2 */
340 case 0x30: /* GPIO_CTRL */
343 case 0x34: /* GPIO_OE */
346 case 0x38: /* GPIO_DATAIN */
349 case 0x3c: /* GPIO_DATAOUT */
350 case 0x90: /* GPIO_CLEARDATAOUT */
351 case 0x94: /* GPIO_SETDATAOUT */
354 case 0x40: /* GPIO_LEVELDETECT0 */
357 case 0x44: /* GPIO_LEVELDETECT1 */
360 case 0x48: /* GPIO_RISINGDETECT */
363 case 0x4c: /* GPIO_FALLINGDETECT */
366 case 0x50: /* GPIO_DEBOUNCENABLE */
369 case 0x54: /* GPIO_DEBOUNCINGTIME */
377 static void omap2_gpio_module_write(void *opaque, target_phys_addr_t addr,
380 struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
385 case 0x00: /* GPIO_REVISION */
386 case 0x14: /* GPIO_SYSSTATUS */
387 case 0x38: /* GPIO_DATAIN */
391 case 0x10: /* GPIO_SYSCONFIG */
392 if (((value >> 3) & 3) == 3)
393 fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
395 omap2_gpio_module_reset(s);
396 s->config[0] = value & 0x1d;
399 case 0x18: /* GPIO_IRQSTATUS1 */
400 if (s->ints[0] & value) {
401 s->ints[0] &= ~value;
402 omap2_gpio_module_level_update(s, 0);
406 case 0x1c: /* GPIO_IRQENABLE1 */
408 omap2_gpio_module_int_update(s, 0);
411 case 0x20: /* GPIO_WAKEUPENABLE */
415 case 0x28: /* GPIO_IRQSTATUS2 */
416 if (s->ints[1] & value) {
417 s->ints[1] &= ~value;
418 omap2_gpio_module_level_update(s, 1);
422 case 0x2c: /* GPIO_IRQENABLE2 */
424 omap2_gpio_module_int_update(s, 1);
427 case 0x30: /* GPIO_CTRL */
428 s->config[1] = value & 7;
431 case 0x34: /* GPIO_OE */
432 diff = s->outputs & (s->dir ^ value);
435 value = s->outputs & ~s->dir;
436 while ((ln = ffs(diff))) {
437 diff &= ~(1 <<-- ln);
438 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
441 omap2_gpio_module_level_update(s, 0);
442 omap2_gpio_module_level_update(s, 1);
445 case 0x3c: /* GPIO_DATAOUT */
446 omap2_gpio_module_out_update(s, s->outputs ^ value);
449 case 0x40: /* GPIO_LEVELDETECT0 */
451 omap2_gpio_module_level_update(s, 0);
452 omap2_gpio_module_level_update(s, 1);
455 case 0x44: /* GPIO_LEVELDETECT1 */
457 omap2_gpio_module_level_update(s, 0);
458 omap2_gpio_module_level_update(s, 1);
461 case 0x48: /* GPIO_RISINGDETECT */
465 case 0x4c: /* GPIO_FALLINGDETECT */
469 case 0x50: /* GPIO_DEBOUNCENABLE */
473 case 0x54: /* GPIO_DEBOUNCINGTIME */
477 case 0x60: /* GPIO_CLEARIRQENABLE1 */
478 s->mask[0] &= ~value;
479 omap2_gpio_module_int_update(s, 0);
482 case 0x64: /* GPIO_SETIRQENABLE1 */
484 omap2_gpio_module_int_update(s, 0);
487 case 0x70: /* GPIO_CLEARIRQENABLE2 */
488 s->mask[1] &= ~value;
489 omap2_gpio_module_int_update(s, 1);
492 case 0x74: /* GPIO_SETIREQNEABLE2 */
494 omap2_gpio_module_int_update(s, 1);
497 case 0x80: /* GPIO_CLEARWKUENA */
501 case 0x84: /* GPIO_SETWKUENA */
505 case 0x90: /* GPIO_CLEARDATAOUT */
506 omap2_gpio_module_out_update(s, s->outputs & value);
509 case 0x94: /* GPIO_SETDATAOUT */
510 omap2_gpio_module_out_update(s, ~s->outputs & value);
519 static uint32_t omap2_gpio_module_readp(void *opaque, target_phys_addr_t addr)
521 return omap2_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
524 static void omap2_gpio_module_writep(void *opaque, target_phys_addr_t addr,
528 uint32_t mask = 0xffff;
531 case 0x00: /* GPIO_REVISION */
532 case 0x14: /* GPIO_SYSSTATUS */
533 case 0x38: /* GPIO_DATAIN */
537 case 0x10: /* GPIO_SYSCONFIG */
538 case 0x1c: /* GPIO_IRQENABLE1 */
539 case 0x20: /* GPIO_WAKEUPENABLE */
540 case 0x2c: /* GPIO_IRQENABLE2 */
541 case 0x30: /* GPIO_CTRL */
542 case 0x34: /* GPIO_OE */
543 case 0x3c: /* GPIO_DATAOUT */
544 case 0x40: /* GPIO_LEVELDETECT0 */
545 case 0x44: /* GPIO_LEVELDETECT1 */
546 case 0x48: /* GPIO_RISINGDETECT */
547 case 0x4c: /* GPIO_FALLINGDETECT */
548 case 0x50: /* GPIO_DEBOUNCENABLE */
549 case 0x54: /* GPIO_DEBOUNCINGTIME */
550 cur = omap2_gpio_module_read(opaque, addr & ~3) &
551 ~(mask << ((addr & 3) << 3));
554 case 0x18: /* GPIO_IRQSTATUS1 */
555 case 0x28: /* GPIO_IRQSTATUS2 */
556 case 0x60: /* GPIO_CLEARIRQENABLE1 */
557 case 0x64: /* GPIO_SETIRQENABLE1 */
558 case 0x70: /* GPIO_CLEARIRQENABLE2 */
559 case 0x74: /* GPIO_SETIREQNEABLE2 */
560 case 0x80: /* GPIO_CLEARWKUENA */
561 case 0x84: /* GPIO_SETWKUENA */
562 case 0x90: /* GPIO_CLEARDATAOUT */
563 case 0x94: /* GPIO_SETDATAOUT */
564 value <<= (addr & 3) << 3;
565 omap2_gpio_module_write(opaque, addr, cur | value);
574 static CPUReadMemoryFunc * const omap2_gpio_module_readfn[] = {
575 omap2_gpio_module_readp,
576 omap2_gpio_module_readp,
577 omap2_gpio_module_read,
580 static CPUWriteMemoryFunc * const omap2_gpio_module_writefn[] = {
581 omap2_gpio_module_writep,
582 omap2_gpio_module_writep,
583 omap2_gpio_module_write,
586 static void omap2_gpio_module_init(struct omap2_gpio_s *s,
587 struct omap_target_agent_s *ta, int region,
588 qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
589 omap_clk fclk, omap_clk iclk)
596 s->in = qemu_allocate_irqs(omap2_gpio_module_set, s, 32);
598 iomemtype = l4_register_io_memory(omap2_gpio_module_readfn,
599 omap2_gpio_module_writefn, s);
600 omap_l4_attach(ta, region, iomemtype);
604 struct omap2_gpio_s module[5];
611 void omap_gpif_reset(struct omap_gpif_s *s)
615 for (i = 0; i < s->modules; i ++)
616 omap2_gpio_module_reset(s->module + i);
622 static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
624 struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
627 case 0x00: /* IPGENERICOCPSPL_REVISION */
630 case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */
633 case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */
636 case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */
639 case 0x40: /* IPGENERICOCPSPL_GPO */
642 case 0x50: /* IPGENERICOCPSPL_GPI */
650 static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
653 struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
656 case 0x00: /* IPGENERICOCPSPL_REVISION */
657 case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */
658 case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */
659 case 0x50: /* IPGENERICOCPSPL_GPI */
663 case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */
664 if (value & (1 << 1)) /* SOFTRESET */
666 s->autoidle = value & 1;
669 case 0x40: /* IPGENERICOCPSPL_GPO */
679 static CPUReadMemoryFunc * const omap_gpif_top_readfn[] = {
685 static CPUWriteMemoryFunc * const omap_gpif_top_writefn[] = {
691 struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
692 qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
695 struct omap_gpif_s *s = (struct omap_gpif_s *)
696 qemu_mallocz(sizeof(struct omap_gpif_s));
697 int region[4] = { 0, 2, 4, 5 };
699 s->modules = modules;
700 for (i = 0; i < modules; i ++)
701 omap2_gpio_module_init(s->module + i, ta, region[i],
702 irq[i], NULL, NULL, fclk[i], iclk);
706 iomemtype = l4_register_io_memory(omap_gpif_top_readfn,
707 omap_gpif_top_writefn, s);
708 omap_l4_attach(ta, 1, iomemtype);
713 qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
715 if (start >= s->modules * 32 || start < 0)
716 hw_error("%s: No GPIO line %i\n", __FUNCTION__, start);
717 return s->module[start >> 5].in + (start & 31);
720 void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
722 if (line >= s->modules * 32 || line < 0)
723 hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
724 s->module[line >> 5].handler[line & 31] = handler;