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;