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
;