vhost-user: allow slave to send fds via slave channel
[qemu/ar7.git] / hw / arm / omap1.c
blobe54c1f8f995163d950ee6f4260cbebb28425efe8
1 /*
2 * TI OMAP processors emulation.
4 * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
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.
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.
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/>.
20 #include "qemu/osdep.h"
21 #include "qemu/error-report.h"
22 #include "qapi/error.h"
23 #include "qemu-common.h"
24 #include "cpu.h"
25 #include "hw/boards.h"
26 #include "hw/hw.h"
27 #include "hw/arm/arm.h"
28 #include "hw/arm/omap.h"
29 #include "sysemu/sysemu.h"
30 #include "hw/arm/soc_dma.h"
31 #include "sysemu/block-backend.h"
32 #include "sysemu/blockdev.h"
33 #include "sysemu/qtest.h"
34 #include "qemu/range.h"
35 #include "hw/sysbus.h"
36 #include "qemu/cutils.h"
37 #include "qemu/bcd.h"
39 /* Should signal the TCMI/GPMC */
40 uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
42 uint8_t ret;
44 OMAP_8B_REG(addr);
45 cpu_physical_memory_read(addr, &ret, 1);
46 return ret;
49 void omap_badwidth_write8(void *opaque, hwaddr addr,
50 uint32_t value)
52 uint8_t val8 = value;
54 OMAP_8B_REG(addr);
55 cpu_physical_memory_write(addr, &val8, 1);
58 uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
60 uint16_t ret;
62 OMAP_16B_REG(addr);
63 cpu_physical_memory_read(addr, &ret, 2);
64 return ret;
67 void omap_badwidth_write16(void *opaque, hwaddr addr,
68 uint32_t value)
70 uint16_t val16 = value;
72 OMAP_16B_REG(addr);
73 cpu_physical_memory_write(addr, &val16, 2);
76 uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
78 uint32_t ret;
80 OMAP_32B_REG(addr);
81 cpu_physical_memory_read(addr, &ret, 4);
82 return ret;
85 void omap_badwidth_write32(void *opaque, hwaddr addr,
86 uint32_t value)
88 OMAP_32B_REG(addr);
89 cpu_physical_memory_write(addr, &value, 4);
92 /* MPU OS timers */
93 struct omap_mpu_timer_s {
94 MemoryRegion iomem;
95 qemu_irq irq;
96 omap_clk clk;
97 uint32_t val;
98 int64_t time;
99 QEMUTimer *timer;
100 QEMUBH *tick;
101 int64_t rate;
102 int it_ena;
104 int enable;
105 int ptv;
106 int ar;
107 int st;
108 uint32_t reset_val;
111 static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
113 uint64_t distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
115 if (timer->st && timer->enable && timer->rate)
116 return timer->val - muldiv64(distance >> (timer->ptv + 1),
117 timer->rate, NANOSECONDS_PER_SECOND);
118 else
119 return timer->val;
122 static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
124 timer->val = omap_timer_read(timer);
125 timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
128 static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
130 int64_t expires;
132 if (timer->enable && timer->st && timer->rate) {
133 timer->val = timer->reset_val; /* Should skip this on clk enable */
134 expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
135 NANOSECONDS_PER_SECOND, timer->rate);
137 /* If timer expiry would be sooner than in about 1 ms and
138 * auto-reload isn't set, then fire immediately. This is a hack
139 * to make systems like PalmOS run in acceptable time. PalmOS
140 * sets the interval to a very low value and polls the status bit
141 * in a busy loop when it wants to sleep just a couple of CPU
142 * ticks. */
143 if (expires > (NANOSECONDS_PER_SECOND >> 10) || timer->ar) {
144 timer_mod(timer->timer, timer->time + expires);
145 } else {
146 qemu_bh_schedule(timer->tick);
148 } else
149 timer_del(timer->timer);
152 static void omap_timer_fire(void *opaque)
154 struct omap_mpu_timer_s *timer = opaque;
156 if (!timer->ar) {
157 timer->val = 0;
158 timer->st = 0;
161 if (timer->it_ena)
162 /* Edge-triggered irq */
163 qemu_irq_pulse(timer->irq);
166 static void omap_timer_tick(void *opaque)
168 struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
170 omap_timer_sync(timer);
171 omap_timer_fire(timer);
172 omap_timer_update(timer);
175 static void omap_timer_clk_update(void *opaque, int line, int on)
177 struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
179 omap_timer_sync(timer);
180 timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
181 omap_timer_update(timer);
184 static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
186 omap_clk_adduser(timer->clk,
187 qemu_allocate_irq(omap_timer_clk_update, timer, 0));
188 timer->rate = omap_clk_getrate(timer->clk);
191 static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
192 unsigned size)
194 struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
196 if (size != 4) {
197 return omap_badwidth_read32(opaque, addr);
200 switch (addr) {
201 case 0x00: /* CNTL_TIMER */
202 return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
204 case 0x04: /* LOAD_TIM */
205 break;
207 case 0x08: /* READ_TIM */
208 return omap_timer_read(s);
211 OMAP_BAD_REG(addr);
212 return 0;
215 static void omap_mpu_timer_write(void *opaque, hwaddr addr,
216 uint64_t value, unsigned size)
218 struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
220 if (size != 4) {
221 omap_badwidth_write32(opaque, addr, value);
222 return;
225 switch (addr) {
226 case 0x00: /* CNTL_TIMER */
227 omap_timer_sync(s);
228 s->enable = (value >> 5) & 1;
229 s->ptv = (value >> 2) & 7;
230 s->ar = (value >> 1) & 1;
231 s->st = value & 1;
232 omap_timer_update(s);
233 return;
235 case 0x04: /* LOAD_TIM */
236 s->reset_val = value;
237 return;
239 case 0x08: /* READ_TIM */
240 OMAP_RO_REG(addr);
241 break;
243 default:
244 OMAP_BAD_REG(addr);
248 static const MemoryRegionOps omap_mpu_timer_ops = {
249 .read = omap_mpu_timer_read,
250 .write = omap_mpu_timer_write,
251 .endianness = DEVICE_LITTLE_ENDIAN,
254 static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
256 timer_del(s->timer);
257 s->enable = 0;
258 s->reset_val = 31337;
259 s->val = 0;
260 s->ptv = 0;
261 s->ar = 0;
262 s->st = 0;
263 s->it_ena = 1;
266 static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
267 hwaddr base,
268 qemu_irq irq, omap_clk clk)
270 struct omap_mpu_timer_s *s = g_new0(struct omap_mpu_timer_s, 1);
272 s->irq = irq;
273 s->clk = clk;
274 s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, s);
275 s->tick = qemu_bh_new(omap_timer_fire, s);
276 omap_mpu_timer_reset(s);
277 omap_timer_clk_setup(s);
279 memory_region_init_io(&s->iomem, NULL, &omap_mpu_timer_ops, s,
280 "omap-mpu-timer", 0x100);
282 memory_region_add_subregion(system_memory, base, &s->iomem);
284 return s;
287 /* Watchdog timer */
288 struct omap_watchdog_timer_s {
289 struct omap_mpu_timer_s timer;
290 MemoryRegion iomem;
291 uint8_t last_wr;
292 int mode;
293 int free;
294 int reset;
297 static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
298 unsigned size)
300 struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
302 if (size != 2) {
303 return omap_badwidth_read16(opaque, addr);
306 switch (addr) {
307 case 0x00: /* CNTL_TIMER */
308 return (s->timer.ptv << 9) | (s->timer.ar << 8) |
309 (s->timer.st << 7) | (s->free << 1);
311 case 0x04: /* READ_TIMER */
312 return omap_timer_read(&s->timer);
314 case 0x08: /* TIMER_MODE */
315 return s->mode << 15;
318 OMAP_BAD_REG(addr);
319 return 0;
322 static void omap_wd_timer_write(void *opaque, hwaddr addr,
323 uint64_t value, unsigned size)
325 struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
327 if (size != 2) {
328 omap_badwidth_write16(opaque, addr, value);
329 return;
332 switch (addr) {
333 case 0x00: /* CNTL_TIMER */
334 omap_timer_sync(&s->timer);
335 s->timer.ptv = (value >> 9) & 7;
336 s->timer.ar = (value >> 8) & 1;
337 s->timer.st = (value >> 7) & 1;
338 s->free = (value >> 1) & 1;
339 omap_timer_update(&s->timer);
340 break;
342 case 0x04: /* LOAD_TIMER */
343 s->timer.reset_val = value & 0xffff;
344 break;
346 case 0x08: /* TIMER_MODE */
347 if (!s->mode && ((value >> 15) & 1))
348 omap_clk_get(s->timer.clk);
349 s->mode |= (value >> 15) & 1;
350 if (s->last_wr == 0xf5) {
351 if ((value & 0xff) == 0xa0) {
352 if (s->mode) {
353 s->mode = 0;
354 omap_clk_put(s->timer.clk);
356 } else {
357 /* XXX: on T|E hardware somehow this has no effect,
358 * on Zire 71 it works as specified. */
359 s->reset = 1;
360 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
363 s->last_wr = value & 0xff;
364 break;
366 default:
367 OMAP_BAD_REG(addr);
371 static const MemoryRegionOps omap_wd_timer_ops = {
372 .read = omap_wd_timer_read,
373 .write = omap_wd_timer_write,
374 .endianness = DEVICE_NATIVE_ENDIAN,
377 static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
379 timer_del(s->timer.timer);
380 if (!s->mode)
381 omap_clk_get(s->timer.clk);
382 s->mode = 1;
383 s->free = 1;
384 s->reset = 0;
385 s->timer.enable = 1;
386 s->timer.it_ena = 1;
387 s->timer.reset_val = 0xffff;
388 s->timer.val = 0;
389 s->timer.st = 0;
390 s->timer.ptv = 0;
391 s->timer.ar = 0;
392 omap_timer_update(&s->timer);
395 static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
396 hwaddr base,
397 qemu_irq irq, omap_clk clk)
399 struct omap_watchdog_timer_s *s = g_new0(struct omap_watchdog_timer_s, 1);
401 s->timer.irq = irq;
402 s->timer.clk = clk;
403 s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
404 omap_wd_timer_reset(s);
405 omap_timer_clk_setup(&s->timer);
407 memory_region_init_io(&s->iomem, NULL, &omap_wd_timer_ops, s,
408 "omap-wd-timer", 0x100);
409 memory_region_add_subregion(memory, base, &s->iomem);
411 return s;
414 /* 32-kHz timer */
415 struct omap_32khz_timer_s {
416 struct omap_mpu_timer_s timer;
417 MemoryRegion iomem;
420 static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
421 unsigned size)
423 struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
424 int offset = addr & OMAP_MPUI_REG_MASK;
426 if (size != 4) {
427 return omap_badwidth_read32(opaque, addr);
430 switch (offset) {
431 case 0x00: /* TVR */
432 return s->timer.reset_val;
434 case 0x04: /* TCR */
435 return omap_timer_read(&s->timer);
437 case 0x08: /* CR */
438 return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
440 default:
441 break;
443 OMAP_BAD_REG(addr);
444 return 0;
447 static void omap_os_timer_write(void *opaque, hwaddr addr,
448 uint64_t value, unsigned size)
450 struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
451 int offset = addr & OMAP_MPUI_REG_MASK;
453 if (size != 4) {
454 omap_badwidth_write32(opaque, addr, value);
455 return;
458 switch (offset) {
459 case 0x00: /* TVR */
460 s->timer.reset_val = value & 0x00ffffff;
461 break;
463 case 0x04: /* TCR */
464 OMAP_RO_REG(addr);
465 break;
467 case 0x08: /* CR */
468 s->timer.ar = (value >> 3) & 1;
469 s->timer.it_ena = (value >> 2) & 1;
470 if (s->timer.st != (value & 1) || (value & 2)) {
471 omap_timer_sync(&s->timer);
472 s->timer.enable = value & 1;
473 s->timer.st = value & 1;
474 omap_timer_update(&s->timer);
476 break;
478 default:
479 OMAP_BAD_REG(addr);
483 static const MemoryRegionOps omap_os_timer_ops = {
484 .read = omap_os_timer_read,
485 .write = omap_os_timer_write,
486 .endianness = DEVICE_NATIVE_ENDIAN,
489 static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
491 timer_del(s->timer.timer);
492 s->timer.enable = 0;
493 s->timer.it_ena = 0;
494 s->timer.reset_val = 0x00ffffff;
495 s->timer.val = 0;
496 s->timer.st = 0;
497 s->timer.ptv = 0;
498 s->timer.ar = 1;
501 static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
502 hwaddr base,
503 qemu_irq irq, omap_clk clk)
505 struct omap_32khz_timer_s *s = g_new0(struct omap_32khz_timer_s, 1);
507 s->timer.irq = irq;
508 s->timer.clk = clk;
509 s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
510 omap_os_timer_reset(s);
511 omap_timer_clk_setup(&s->timer);
513 memory_region_init_io(&s->iomem, NULL, &omap_os_timer_ops, s,
514 "omap-os-timer", 0x800);
515 memory_region_add_subregion(memory, base, &s->iomem);
517 return s;
520 /* Ultra Low-Power Device Module */
521 static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
522 unsigned size)
524 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
525 uint16_t ret;
527 if (size != 2) {
528 return omap_badwidth_read16(opaque, addr);
531 switch (addr) {
532 case 0x14: /* IT_STATUS */
533 ret = s->ulpd_pm_regs[addr >> 2];
534 s->ulpd_pm_regs[addr >> 2] = 0;
535 qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
536 return ret;
538 case 0x18: /* Reserved */
539 case 0x1c: /* Reserved */
540 case 0x20: /* Reserved */
541 case 0x28: /* Reserved */
542 case 0x2c: /* Reserved */
543 OMAP_BAD_REG(addr);
544 /* fall through */
545 case 0x00: /* COUNTER_32_LSB */
546 case 0x04: /* COUNTER_32_MSB */
547 case 0x08: /* COUNTER_HIGH_FREQ_LSB */
548 case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
549 case 0x10: /* GAUGING_CTRL */
550 case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
551 case 0x30: /* CLOCK_CTRL */
552 case 0x34: /* SOFT_REQ */
553 case 0x38: /* COUNTER_32_FIQ */
554 case 0x3c: /* DPLL_CTRL */
555 case 0x40: /* STATUS_REQ */
556 /* XXX: check clk::usecount state for every clock */
557 case 0x48: /* LOCL_TIME */
558 case 0x4c: /* APLL_CTRL */
559 case 0x50: /* POWER_CTRL */
560 return s->ulpd_pm_regs[addr >> 2];
563 OMAP_BAD_REG(addr);
564 return 0;
567 static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
568 uint16_t diff, uint16_t value)
570 if (diff & (1 << 4)) /* USB_MCLK_EN */
571 omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
572 if (diff & (1 << 5)) /* DIS_USB_PVCI_CLK */
573 omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
576 static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
577 uint16_t diff, uint16_t value)
579 if (diff & (1 << 0)) /* SOFT_DPLL_REQ */
580 omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
581 if (diff & (1 << 1)) /* SOFT_COM_REQ */
582 omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
583 if (diff & (1 << 2)) /* SOFT_SDW_REQ */
584 omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
585 if (diff & (1 << 3)) /* SOFT_USB_REQ */
586 omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
589 static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
590 uint64_t value, unsigned size)
592 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
593 int64_t now, ticks;
594 int div, mult;
595 static const int bypass_div[4] = { 1, 2, 4, 4 };
596 uint16_t diff;
598 if (size != 2) {
599 omap_badwidth_write16(opaque, addr, value);
600 return;
603 switch (addr) {
604 case 0x00: /* COUNTER_32_LSB */
605 case 0x04: /* COUNTER_32_MSB */
606 case 0x08: /* COUNTER_HIGH_FREQ_LSB */
607 case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
608 case 0x14: /* IT_STATUS */
609 case 0x40: /* STATUS_REQ */
610 OMAP_RO_REG(addr);
611 break;
613 case 0x10: /* GAUGING_CTRL */
614 /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
615 if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
616 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
618 if (value & 1)
619 s->ulpd_gauge_start = now;
620 else {
621 now -= s->ulpd_gauge_start;
623 /* 32-kHz ticks */
624 ticks = muldiv64(now, 32768, NANOSECONDS_PER_SECOND);
625 s->ulpd_pm_regs[0x00 >> 2] = (ticks >> 0) & 0xffff;
626 s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
627 if (ticks >> 32) /* OVERFLOW_32K */
628 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
630 /* High frequency ticks */
631 ticks = muldiv64(now, 12000000, NANOSECONDS_PER_SECOND);
632 s->ulpd_pm_regs[0x08 >> 2] = (ticks >> 0) & 0xffff;
633 s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
634 if (ticks >> 32) /* OVERFLOW_HI_FREQ */
635 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
637 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */
638 qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
641 s->ulpd_pm_regs[addr >> 2] = value;
642 break;
644 case 0x18: /* Reserved */
645 case 0x1c: /* Reserved */
646 case 0x20: /* Reserved */
647 case 0x28: /* Reserved */
648 case 0x2c: /* Reserved */
649 OMAP_BAD_REG(addr);
650 /* fall through */
651 case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
652 case 0x38: /* COUNTER_32_FIQ */
653 case 0x48: /* LOCL_TIME */
654 case 0x50: /* POWER_CTRL */
655 s->ulpd_pm_regs[addr >> 2] = value;
656 break;
658 case 0x30: /* CLOCK_CTRL */
659 diff = s->ulpd_pm_regs[addr >> 2] ^ value;
660 s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
661 omap_ulpd_clk_update(s, diff, value);
662 break;
664 case 0x34: /* SOFT_REQ */
665 diff = s->ulpd_pm_regs[addr >> 2] ^ value;
666 s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
667 omap_ulpd_req_update(s, diff, value);
668 break;
670 case 0x3c: /* DPLL_CTRL */
671 /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
672 * omitted altogether, probably a typo. */
673 /* This register has identical semantics with DPLL(1:3) control
674 * registers, see omap_dpll_write() */
675 diff = s->ulpd_pm_regs[addr >> 2] & value;
676 s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
677 if (diff & (0x3ff << 2)) {
678 if (value & (1 << 4)) { /* PLL_ENABLE */
679 div = ((value >> 5) & 3) + 1; /* PLL_DIV */
680 mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */
681 } else {
682 div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */
683 mult = 1;
685 omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
688 /* Enter the desired mode. */
689 s->ulpd_pm_regs[addr >> 2] =
690 (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
691 ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
693 /* Act as if the lock is restored. */
694 s->ulpd_pm_regs[addr >> 2] |= 2;
695 break;
697 case 0x4c: /* APLL_CTRL */
698 diff = s->ulpd_pm_regs[addr >> 2] & value;
699 s->ulpd_pm_regs[addr >> 2] = value & 0xf;
700 if (diff & (1 << 0)) /* APLL_NDPLL_SWITCH */
701 omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
702 (value & (1 << 0)) ? "apll" : "dpll4"));
703 break;
705 default:
706 OMAP_BAD_REG(addr);
710 static const MemoryRegionOps omap_ulpd_pm_ops = {
711 .read = omap_ulpd_pm_read,
712 .write = omap_ulpd_pm_write,
713 .endianness = DEVICE_NATIVE_ENDIAN,
716 static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
718 mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
719 mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
720 mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
721 mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
722 mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
723 mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
724 mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
725 mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
726 mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
727 mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
728 mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
729 omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
730 mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
731 omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
732 mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
733 mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
734 mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
735 mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
736 mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
737 mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
738 mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
739 omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
740 omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
743 static void omap_ulpd_pm_init(MemoryRegion *system_memory,
744 hwaddr base,
745 struct omap_mpu_state_s *mpu)
747 memory_region_init_io(&mpu->ulpd_pm_iomem, NULL, &omap_ulpd_pm_ops, mpu,
748 "omap-ulpd-pm", 0x800);
749 memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
750 omap_ulpd_pm_reset(mpu);
753 /* OMAP Pin Configuration */
754 static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
755 unsigned size)
757 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
759 if (size != 4) {
760 return omap_badwidth_read32(opaque, addr);
763 switch (addr) {
764 case 0x00: /* FUNC_MUX_CTRL_0 */
765 case 0x04: /* FUNC_MUX_CTRL_1 */
766 case 0x08: /* FUNC_MUX_CTRL_2 */
767 return s->func_mux_ctrl[addr >> 2];
769 case 0x0c: /* COMP_MODE_CTRL_0 */
770 return s->comp_mode_ctrl[0];
772 case 0x10: /* FUNC_MUX_CTRL_3 */
773 case 0x14: /* FUNC_MUX_CTRL_4 */
774 case 0x18: /* FUNC_MUX_CTRL_5 */
775 case 0x1c: /* FUNC_MUX_CTRL_6 */
776 case 0x20: /* FUNC_MUX_CTRL_7 */
777 case 0x24: /* FUNC_MUX_CTRL_8 */
778 case 0x28: /* FUNC_MUX_CTRL_9 */
779 case 0x2c: /* FUNC_MUX_CTRL_A */
780 case 0x30: /* FUNC_MUX_CTRL_B */
781 case 0x34: /* FUNC_MUX_CTRL_C */
782 case 0x38: /* FUNC_MUX_CTRL_D */
783 return s->func_mux_ctrl[(addr >> 2) - 1];
785 case 0x40: /* PULL_DWN_CTRL_0 */
786 case 0x44: /* PULL_DWN_CTRL_1 */
787 case 0x48: /* PULL_DWN_CTRL_2 */
788 case 0x4c: /* PULL_DWN_CTRL_3 */
789 return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
791 case 0x50: /* GATE_INH_CTRL_0 */
792 return s->gate_inh_ctrl[0];
794 case 0x60: /* VOLTAGE_CTRL_0 */
795 return s->voltage_ctrl[0];
797 case 0x70: /* TEST_DBG_CTRL_0 */
798 return s->test_dbg_ctrl[0];
800 case 0x80: /* MOD_CONF_CTRL_0 */
801 return s->mod_conf_ctrl[0];
804 OMAP_BAD_REG(addr);
805 return 0;
808 static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
809 uint32_t diff, uint32_t value)
811 if (s->compat1509) {
812 if (diff & (1 << 9)) /* BLUETOOTH */
813 omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
814 (~value >> 9) & 1);
815 if (diff & (1 << 7)) /* USB.CLKO */
816 omap_clk_onoff(omap_findclk(s, "usb.clko"),
817 (value >> 7) & 1);
821 static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
822 uint32_t diff, uint32_t value)
824 if (s->compat1509) {
825 if (diff & (1U << 31)) {
826 /* MCBSP3_CLK_HIZ_DI */
827 omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"), (value >> 31) & 1);
829 if (diff & (1 << 1)) {
830 /* CLK32K */
831 omap_clk_onoff(omap_findclk(s, "clk32k_out"), (~value >> 1) & 1);
836 static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
837 uint32_t diff, uint32_t value)
839 if (diff & (1U << 31)) {
840 /* CONF_MOD_UART3_CLK_MODE_R */
841 omap_clk_reparent(omap_findclk(s, "uart3_ck"),
842 omap_findclk(s, ((value >> 31) & 1) ?
843 "ck_48m" : "armper_ck"));
845 if (diff & (1 << 30)) /* CONF_MOD_UART2_CLK_MODE_R */
846 omap_clk_reparent(omap_findclk(s, "uart2_ck"),
847 omap_findclk(s, ((value >> 30) & 1) ?
848 "ck_48m" : "armper_ck"));
849 if (diff & (1 << 29)) /* CONF_MOD_UART1_CLK_MODE_R */
850 omap_clk_reparent(omap_findclk(s, "uart1_ck"),
851 omap_findclk(s, ((value >> 29) & 1) ?
852 "ck_48m" : "armper_ck"));
853 if (diff & (1 << 23)) /* CONF_MOD_MMC_SD_CLK_REQ_R */
854 omap_clk_reparent(omap_findclk(s, "mmc_ck"),
855 omap_findclk(s, ((value >> 23) & 1) ?
856 "ck_48m" : "armper_ck"));
857 if (diff & (1 << 12)) /* CONF_MOD_COM_MCLK_12_48_S */
858 omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
859 omap_findclk(s, ((value >> 12) & 1) ?
860 "ck_48m" : "armper_ck"));
861 if (diff & (1 << 9)) /* CONF_MOD_USB_HOST_HHC_UHO */
862 omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
865 static void omap_pin_cfg_write(void *opaque, hwaddr addr,
866 uint64_t value, unsigned size)
868 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
869 uint32_t diff;
871 if (size != 4) {
872 omap_badwidth_write32(opaque, addr, value);
873 return;
876 switch (addr) {
877 case 0x00: /* FUNC_MUX_CTRL_0 */
878 diff = s->func_mux_ctrl[addr >> 2] ^ value;
879 s->func_mux_ctrl[addr >> 2] = value;
880 omap_pin_funcmux0_update(s, diff, value);
881 return;
883 case 0x04: /* FUNC_MUX_CTRL_1 */
884 diff = s->func_mux_ctrl[addr >> 2] ^ value;
885 s->func_mux_ctrl[addr >> 2] = value;
886 omap_pin_funcmux1_update(s, diff, value);
887 return;
889 case 0x08: /* FUNC_MUX_CTRL_2 */
890 s->func_mux_ctrl[addr >> 2] = value;
891 return;
893 case 0x0c: /* COMP_MODE_CTRL_0 */
894 s->comp_mode_ctrl[0] = value;
895 s->compat1509 = (value != 0x0000eaef);
896 omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
897 omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
898 return;
900 case 0x10: /* FUNC_MUX_CTRL_3 */
901 case 0x14: /* FUNC_MUX_CTRL_4 */
902 case 0x18: /* FUNC_MUX_CTRL_5 */
903 case 0x1c: /* FUNC_MUX_CTRL_6 */
904 case 0x20: /* FUNC_MUX_CTRL_7 */
905 case 0x24: /* FUNC_MUX_CTRL_8 */
906 case 0x28: /* FUNC_MUX_CTRL_9 */
907 case 0x2c: /* FUNC_MUX_CTRL_A */
908 case 0x30: /* FUNC_MUX_CTRL_B */
909 case 0x34: /* FUNC_MUX_CTRL_C */
910 case 0x38: /* FUNC_MUX_CTRL_D */
911 s->func_mux_ctrl[(addr >> 2) - 1] = value;
912 return;
914 case 0x40: /* PULL_DWN_CTRL_0 */
915 case 0x44: /* PULL_DWN_CTRL_1 */
916 case 0x48: /* PULL_DWN_CTRL_2 */
917 case 0x4c: /* PULL_DWN_CTRL_3 */
918 s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
919 return;
921 case 0x50: /* GATE_INH_CTRL_0 */
922 s->gate_inh_ctrl[0] = value;
923 return;
925 case 0x60: /* VOLTAGE_CTRL_0 */
926 s->voltage_ctrl[0] = value;
927 return;
929 case 0x70: /* TEST_DBG_CTRL_0 */
930 s->test_dbg_ctrl[0] = value;
931 return;
933 case 0x80: /* MOD_CONF_CTRL_0 */
934 diff = s->mod_conf_ctrl[0] ^ value;
935 s->mod_conf_ctrl[0] = value;
936 omap_pin_modconf1_update(s, diff, value);
937 return;
939 default:
940 OMAP_BAD_REG(addr);
944 static const MemoryRegionOps omap_pin_cfg_ops = {
945 .read = omap_pin_cfg_read,
946 .write = omap_pin_cfg_write,
947 .endianness = DEVICE_NATIVE_ENDIAN,
950 static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
952 /* Start in Compatibility Mode. */
953 mpu->compat1509 = 1;
954 omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
955 omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
956 omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
957 memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
958 memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
959 memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
960 memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
961 memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
962 memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
963 memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
966 static void omap_pin_cfg_init(MemoryRegion *system_memory,
967 hwaddr base,
968 struct omap_mpu_state_s *mpu)
970 memory_region_init_io(&mpu->pin_cfg_iomem, NULL, &omap_pin_cfg_ops, mpu,
971 "omap-pin-cfg", 0x800);
972 memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
973 omap_pin_cfg_reset(mpu);
976 /* Device Identification, Die Identification */
977 static uint64_t omap_id_read(void *opaque, hwaddr addr,
978 unsigned size)
980 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
982 if (size != 4) {
983 return omap_badwidth_read32(opaque, addr);
986 switch (addr) {
987 case 0xfffe1800: /* DIE_ID_LSB */
988 return 0xc9581f0e;
989 case 0xfffe1804: /* DIE_ID_MSB */
990 return 0xa8858bfa;
992 case 0xfffe2000: /* PRODUCT_ID_LSB */
993 return 0x00aaaafc;
994 case 0xfffe2004: /* PRODUCT_ID_MSB */
995 return 0xcafeb574;
997 case 0xfffed400: /* JTAG_ID_LSB */
998 switch (s->mpu_model) {
999 case omap310:
1000 return 0x03310315;
1001 case omap1510:
1002 return 0x03310115;
1003 default:
1004 hw_error("%s: bad mpu model\n", __func__);
1006 break;
1008 case 0xfffed404: /* JTAG_ID_MSB */
1009 switch (s->mpu_model) {
1010 case omap310:
1011 return 0xfb57402f;
1012 case omap1510:
1013 return 0xfb47002f;
1014 default:
1015 hw_error("%s: bad mpu model\n", __func__);
1017 break;
1020 OMAP_BAD_REG(addr);
1021 return 0;
1024 static void omap_id_write(void *opaque, hwaddr addr,
1025 uint64_t value, unsigned size)
1027 if (size != 4) {
1028 omap_badwidth_write32(opaque, addr, value);
1029 return;
1032 OMAP_BAD_REG(addr);
1035 static const MemoryRegionOps omap_id_ops = {
1036 .read = omap_id_read,
1037 .write = omap_id_write,
1038 .endianness = DEVICE_NATIVE_ENDIAN,
1041 static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
1043 memory_region_init_io(&mpu->id_iomem, NULL, &omap_id_ops, mpu,
1044 "omap-id", 0x100000000ULL);
1045 memory_region_init_alias(&mpu->id_iomem_e18, NULL, "omap-id-e18", &mpu->id_iomem,
1046 0xfffe1800, 0x800);
1047 memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
1048 memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-ed4", &mpu->id_iomem,
1049 0xfffed400, 0x100);
1050 memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
1051 if (!cpu_is_omap15xx(mpu)) {
1052 memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-e20",
1053 &mpu->id_iomem, 0xfffe2000, 0x800);
1054 memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
1058 /* MPUI Control (Dummy) */
1059 static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
1060 unsigned size)
1062 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1064 if (size != 4) {
1065 return omap_badwidth_read32(opaque, addr);
1068 switch (addr) {
1069 case 0x00: /* CTRL */
1070 return s->mpui_ctrl;
1071 case 0x04: /* DEBUG_ADDR */
1072 return 0x01ffffff;
1073 case 0x08: /* DEBUG_DATA */
1074 return 0xffffffff;
1075 case 0x0c: /* DEBUG_FLAG */
1076 return 0x00000800;
1077 case 0x10: /* STATUS */
1078 return 0x00000000;
1080 /* Not in OMAP310 */
1081 case 0x14: /* DSP_STATUS */
1082 case 0x18: /* DSP_BOOT_CONFIG */
1083 return 0x00000000;
1084 case 0x1c: /* DSP_MPUI_CONFIG */
1085 return 0x0000ffff;
1088 OMAP_BAD_REG(addr);
1089 return 0;
1092 static void omap_mpui_write(void *opaque, hwaddr addr,
1093 uint64_t value, unsigned size)
1095 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1097 if (size != 4) {
1098 omap_badwidth_write32(opaque, addr, value);
1099 return;
1102 switch (addr) {
1103 case 0x00: /* CTRL */
1104 s->mpui_ctrl = value & 0x007fffff;
1105 break;
1107 case 0x04: /* DEBUG_ADDR */
1108 case 0x08: /* DEBUG_DATA */
1109 case 0x0c: /* DEBUG_FLAG */
1110 case 0x10: /* STATUS */
1111 /* Not in OMAP310 */
1112 case 0x14: /* DSP_STATUS */
1113 OMAP_RO_REG(addr);
1114 break;
1115 case 0x18: /* DSP_BOOT_CONFIG */
1116 case 0x1c: /* DSP_MPUI_CONFIG */
1117 break;
1119 default:
1120 OMAP_BAD_REG(addr);
1124 static const MemoryRegionOps omap_mpui_ops = {
1125 .read = omap_mpui_read,
1126 .write = omap_mpui_write,
1127 .endianness = DEVICE_NATIVE_ENDIAN,
1130 static void omap_mpui_reset(struct omap_mpu_state_s *s)
1132 s->mpui_ctrl = 0x0003ff1b;
1135 static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
1136 struct omap_mpu_state_s *mpu)
1138 memory_region_init_io(&mpu->mpui_iomem, NULL, &omap_mpui_ops, mpu,
1139 "omap-mpui", 0x100);
1140 memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
1142 omap_mpui_reset(mpu);
1145 /* TIPB Bridges */
1146 struct omap_tipb_bridge_s {
1147 qemu_irq abort;
1148 MemoryRegion iomem;
1150 int width_intr;
1151 uint16_t control;
1152 uint16_t alloc;
1153 uint16_t buffer;
1154 uint16_t enh_control;
1157 static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
1158 unsigned size)
1160 struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1162 if (size < 2) {
1163 return omap_badwidth_read16(opaque, addr);
1166 switch (addr) {
1167 case 0x00: /* TIPB_CNTL */
1168 return s->control;
1169 case 0x04: /* TIPB_BUS_ALLOC */
1170 return s->alloc;
1171 case 0x08: /* MPU_TIPB_CNTL */
1172 return s->buffer;
1173 case 0x0c: /* ENHANCED_TIPB_CNTL */
1174 return s->enh_control;
1175 case 0x10: /* ADDRESS_DBG */
1176 case 0x14: /* DATA_DEBUG_LOW */
1177 case 0x18: /* DATA_DEBUG_HIGH */
1178 return 0xffff;
1179 case 0x1c: /* DEBUG_CNTR_SIG */
1180 return 0x00f8;
1183 OMAP_BAD_REG(addr);
1184 return 0;
1187 static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
1188 uint64_t value, unsigned size)
1190 struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1192 if (size < 2) {
1193 omap_badwidth_write16(opaque, addr, value);
1194 return;
1197 switch (addr) {
1198 case 0x00: /* TIPB_CNTL */
1199 s->control = value & 0xffff;
1200 break;
1202 case 0x04: /* TIPB_BUS_ALLOC */
1203 s->alloc = value & 0x003f;
1204 break;
1206 case 0x08: /* MPU_TIPB_CNTL */
1207 s->buffer = value & 0x0003;
1208 break;
1210 case 0x0c: /* ENHANCED_TIPB_CNTL */
1211 s->width_intr = !(value & 2);
1212 s->enh_control = value & 0x000f;
1213 break;
1215 case 0x10: /* ADDRESS_DBG */
1216 case 0x14: /* DATA_DEBUG_LOW */
1217 case 0x18: /* DATA_DEBUG_HIGH */
1218 case 0x1c: /* DEBUG_CNTR_SIG */
1219 OMAP_RO_REG(addr);
1220 break;
1222 default:
1223 OMAP_BAD_REG(addr);
1227 static const MemoryRegionOps omap_tipb_bridge_ops = {
1228 .read = omap_tipb_bridge_read,
1229 .write = omap_tipb_bridge_write,
1230 .endianness = DEVICE_NATIVE_ENDIAN,
1233 static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1235 s->control = 0xffff;
1236 s->alloc = 0x0009;
1237 s->buffer = 0x0000;
1238 s->enh_control = 0x000f;
1241 static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
1242 MemoryRegion *memory, hwaddr base,
1243 qemu_irq abort_irq, omap_clk clk)
1245 struct omap_tipb_bridge_s *s = g_new0(struct omap_tipb_bridge_s, 1);
1247 s->abort = abort_irq;
1248 omap_tipb_bridge_reset(s);
1250 memory_region_init_io(&s->iomem, NULL, &omap_tipb_bridge_ops, s,
1251 "omap-tipb-bridge", 0x100);
1252 memory_region_add_subregion(memory, base, &s->iomem);
1254 return s;
1257 /* Dummy Traffic Controller's Memory Interface */
1258 static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
1259 unsigned size)
1261 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1262 uint32_t ret;
1264 if (size != 4) {
1265 return omap_badwidth_read32(opaque, addr);
1268 switch (addr) {
1269 case 0x00: /* IMIF_PRIO */
1270 case 0x04: /* EMIFS_PRIO */
1271 case 0x08: /* EMIFF_PRIO */
1272 case 0x0c: /* EMIFS_CONFIG */
1273 case 0x10: /* EMIFS_CS0_CONFIG */
1274 case 0x14: /* EMIFS_CS1_CONFIG */
1275 case 0x18: /* EMIFS_CS2_CONFIG */
1276 case 0x1c: /* EMIFS_CS3_CONFIG */
1277 case 0x24: /* EMIFF_MRS */
1278 case 0x28: /* TIMEOUT1 */
1279 case 0x2c: /* TIMEOUT2 */
1280 case 0x30: /* TIMEOUT3 */
1281 case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
1282 case 0x40: /* EMIFS_CFG_DYN_WAIT */
1283 return s->tcmi_regs[addr >> 2];
1285 case 0x20: /* EMIFF_SDRAM_CONFIG */
1286 ret = s->tcmi_regs[addr >> 2];
1287 s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1288 /* XXX: We can try using the VGA_DIRTY flag for this */
1289 return ret;
1292 OMAP_BAD_REG(addr);
1293 return 0;
1296 static void omap_tcmi_write(void *opaque, hwaddr addr,
1297 uint64_t value, unsigned size)
1299 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1301 if (size != 4) {
1302 omap_badwidth_write32(opaque, addr, value);
1303 return;
1306 switch (addr) {
1307 case 0x00: /* IMIF_PRIO */
1308 case 0x04: /* EMIFS_PRIO */
1309 case 0x08: /* EMIFF_PRIO */
1310 case 0x10: /* EMIFS_CS0_CONFIG */
1311 case 0x14: /* EMIFS_CS1_CONFIG */
1312 case 0x18: /* EMIFS_CS2_CONFIG */
1313 case 0x1c: /* EMIFS_CS3_CONFIG */
1314 case 0x20: /* EMIFF_SDRAM_CONFIG */
1315 case 0x24: /* EMIFF_MRS */
1316 case 0x28: /* TIMEOUT1 */
1317 case 0x2c: /* TIMEOUT2 */
1318 case 0x30: /* TIMEOUT3 */
1319 case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
1320 case 0x40: /* EMIFS_CFG_DYN_WAIT */
1321 s->tcmi_regs[addr >> 2] = value;
1322 break;
1323 case 0x0c: /* EMIFS_CONFIG */
1324 s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
1325 break;
1327 default:
1328 OMAP_BAD_REG(addr);
1332 static const MemoryRegionOps omap_tcmi_ops = {
1333 .read = omap_tcmi_read,
1334 .write = omap_tcmi_write,
1335 .endianness = DEVICE_NATIVE_ENDIAN,
1338 static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1340 mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1341 mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1342 mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1343 mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1344 mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1345 mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1346 mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1347 mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1348 mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1349 mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1350 mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1351 mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1352 mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1353 mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1354 mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1357 static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
1358 struct omap_mpu_state_s *mpu)
1360 memory_region_init_io(&mpu->tcmi_iomem, NULL, &omap_tcmi_ops, mpu,
1361 "omap-tcmi", 0x100);
1362 memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
1363 omap_tcmi_reset(mpu);
1366 /* Digital phase-locked loops control */
1367 struct dpll_ctl_s {
1368 MemoryRegion iomem;
1369 uint16_t mode;
1370 omap_clk dpll;
1373 static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
1374 unsigned size)
1376 struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1378 if (size != 2) {
1379 return omap_badwidth_read16(opaque, addr);
1382 if (addr == 0x00) /* CTL_REG */
1383 return s->mode;
1385 OMAP_BAD_REG(addr);
1386 return 0;
1389 static void omap_dpll_write(void *opaque, hwaddr addr,
1390 uint64_t value, unsigned size)
1392 struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1393 uint16_t diff;
1394 static const int bypass_div[4] = { 1, 2, 4, 4 };
1395 int div, mult;
1397 if (size != 2) {
1398 omap_badwidth_write16(opaque, addr, value);
1399 return;
1402 if (addr == 0x00) { /* CTL_REG */
1403 /* See omap_ulpd_pm_write() too */
1404 diff = s->mode & value;
1405 s->mode = value & 0x2fff;
1406 if (diff & (0x3ff << 2)) {
1407 if (value & (1 << 4)) { /* PLL_ENABLE */
1408 div = ((value >> 5) & 3) + 1; /* PLL_DIV */
1409 mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */
1410 } else {
1411 div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */
1412 mult = 1;
1414 omap_clk_setrate(s->dpll, div, mult);
1417 /* Enter the desired mode. */
1418 s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1420 /* Act as if the lock is restored. */
1421 s->mode |= 2;
1422 } else {
1423 OMAP_BAD_REG(addr);
1427 static const MemoryRegionOps omap_dpll_ops = {
1428 .read = omap_dpll_read,
1429 .write = omap_dpll_write,
1430 .endianness = DEVICE_NATIVE_ENDIAN,
1433 static void omap_dpll_reset(struct dpll_ctl_s *s)
1435 s->mode = 0x2002;
1436 omap_clk_setrate(s->dpll, 1, 1);
1439 static struct dpll_ctl_s *omap_dpll_init(MemoryRegion *memory,
1440 hwaddr base, omap_clk clk)
1442 struct dpll_ctl_s *s = g_malloc0(sizeof(*s));
1443 memory_region_init_io(&s->iomem, NULL, &omap_dpll_ops, s, "omap-dpll", 0x100);
1445 s->dpll = clk;
1446 omap_dpll_reset(s);
1448 memory_region_add_subregion(memory, base, &s->iomem);
1449 return s;
1452 /* MPU Clock/Reset/Power Mode Control */
1453 static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
1454 unsigned size)
1456 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1458 if (size != 2) {
1459 return omap_badwidth_read16(opaque, addr);
1462 switch (addr) {
1463 case 0x00: /* ARM_CKCTL */
1464 return s->clkm.arm_ckctl;
1466 case 0x04: /* ARM_IDLECT1 */
1467 return s->clkm.arm_idlect1;
1469 case 0x08: /* ARM_IDLECT2 */
1470 return s->clkm.arm_idlect2;
1472 case 0x0c: /* ARM_EWUPCT */
1473 return s->clkm.arm_ewupct;
1475 case 0x10: /* ARM_RSTCT1 */
1476 return s->clkm.arm_rstct1;
1478 case 0x14: /* ARM_RSTCT2 */
1479 return s->clkm.arm_rstct2;
1481 case 0x18: /* ARM_SYSST */
1482 return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1484 case 0x1c: /* ARM_CKOUT1 */
1485 return s->clkm.arm_ckout1;
1487 case 0x20: /* ARM_CKOUT2 */
1488 break;
1491 OMAP_BAD_REG(addr);
1492 return 0;
1495 static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1496 uint16_t diff, uint16_t value)
1498 omap_clk clk;
1500 if (diff & (1 << 14)) { /* ARM_INTHCK_SEL */
1501 if (value & (1 << 14))
1502 /* Reserved */;
1503 else {
1504 clk = omap_findclk(s, "arminth_ck");
1505 omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1508 if (diff & (1 << 12)) { /* ARM_TIMXO */
1509 clk = omap_findclk(s, "armtim_ck");
1510 if (value & (1 << 12))
1511 omap_clk_reparent(clk, omap_findclk(s, "clkin"));
1512 else
1513 omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1515 /* XXX: en_dspck */
1516 if (diff & (3 << 10)) { /* DSPMMUDIV */
1517 clk = omap_findclk(s, "dspmmu_ck");
1518 omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
1520 if (diff & (3 << 8)) { /* TCDIV */
1521 clk = omap_findclk(s, "tc_ck");
1522 omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
1524 if (diff & (3 << 6)) { /* DSPDIV */
1525 clk = omap_findclk(s, "dsp_ck");
1526 omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
1528 if (diff & (3 << 4)) { /* ARMDIV */
1529 clk = omap_findclk(s, "arm_ck");
1530 omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
1532 if (diff & (3 << 2)) { /* LCDDIV */
1533 clk = omap_findclk(s, "lcd_ck");
1534 omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
1536 if (diff & (3 << 0)) { /* PERDIV */
1537 clk = omap_findclk(s, "armper_ck");
1538 omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
1542 static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1543 uint16_t diff, uint16_t value)
1545 omap_clk clk;
1547 if (value & (1 << 11)) { /* SETARM_IDLE */
1548 cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
1550 if (!(value & (1 << 10))) { /* WKUP_MODE */
1551 /* XXX: disable wakeup from IRQ */
1552 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
1555 #define SET_CANIDLE(clock, bit) \
1556 if (diff & (1 << bit)) { \
1557 clk = omap_findclk(s, clock); \
1558 omap_clk_canidle(clk, (value >> bit) & 1); \
1560 SET_CANIDLE("mpuwd_ck", 0) /* IDLWDT_ARM */
1561 SET_CANIDLE("armxor_ck", 1) /* IDLXORP_ARM */
1562 SET_CANIDLE("mpuper_ck", 2) /* IDLPER_ARM */
1563 SET_CANIDLE("lcd_ck", 3) /* IDLLCD_ARM */
1564 SET_CANIDLE("lb_ck", 4) /* IDLLB_ARM */
1565 SET_CANIDLE("hsab_ck", 5) /* IDLHSAB_ARM */
1566 SET_CANIDLE("tipb_ck", 6) /* IDLIF_ARM */
1567 SET_CANIDLE("dma_ck", 6) /* IDLIF_ARM */
1568 SET_CANIDLE("tc_ck", 6) /* IDLIF_ARM */
1569 SET_CANIDLE("dpll1", 7) /* IDLDPLL_ARM */
1570 SET_CANIDLE("dpll2", 7) /* IDLDPLL_ARM */
1571 SET_CANIDLE("dpll3", 7) /* IDLDPLL_ARM */
1572 SET_CANIDLE("mpui_ck", 8) /* IDLAPI_ARM */
1573 SET_CANIDLE("armtim_ck", 9) /* IDLTIM_ARM */
1576 static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1577 uint16_t diff, uint16_t value)
1579 omap_clk clk;
1581 #define SET_ONOFF(clock, bit) \
1582 if (diff & (1 << bit)) { \
1583 clk = omap_findclk(s, clock); \
1584 omap_clk_onoff(clk, (value >> bit) & 1); \
1586 SET_ONOFF("mpuwd_ck", 0) /* EN_WDTCK */
1587 SET_ONOFF("armxor_ck", 1) /* EN_XORPCK */
1588 SET_ONOFF("mpuper_ck", 2) /* EN_PERCK */
1589 SET_ONOFF("lcd_ck", 3) /* EN_LCDCK */
1590 SET_ONOFF("lb_ck", 4) /* EN_LBCK */
1591 SET_ONOFF("hsab_ck", 5) /* EN_HSABCK */
1592 SET_ONOFF("mpui_ck", 6) /* EN_APICK */
1593 SET_ONOFF("armtim_ck", 7) /* EN_TIMCK */
1594 SET_CANIDLE("dma_ck", 8) /* DMACK_REQ */
1595 SET_ONOFF("arm_gpio_ck", 9) /* EN_GPIOCK */
1596 SET_ONOFF("lbfree_ck", 10) /* EN_LBFREECK */
1599 static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1600 uint16_t diff, uint16_t value)
1602 omap_clk clk;
1604 if (diff & (3 << 4)) { /* TCLKOUT */
1605 clk = omap_findclk(s, "tclk_out");
1606 switch ((value >> 4) & 3) {
1607 case 1:
1608 omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
1609 omap_clk_onoff(clk, 1);
1610 break;
1611 case 2:
1612 omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1613 omap_clk_onoff(clk, 1);
1614 break;
1615 default:
1616 omap_clk_onoff(clk, 0);
1619 if (diff & (3 << 2)) { /* DCLKOUT */
1620 clk = omap_findclk(s, "dclk_out");
1621 switch ((value >> 2) & 3) {
1622 case 0:
1623 omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
1624 break;
1625 case 1:
1626 omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
1627 break;
1628 case 2:
1629 omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
1630 break;
1631 case 3:
1632 omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1633 break;
1636 if (diff & (3 << 0)) { /* ACLKOUT */
1637 clk = omap_findclk(s, "aclk_out");
1638 switch ((value >> 0) & 3) {
1639 case 1:
1640 omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1641 omap_clk_onoff(clk, 1);
1642 break;
1643 case 2:
1644 omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
1645 omap_clk_onoff(clk, 1);
1646 break;
1647 case 3:
1648 omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1649 omap_clk_onoff(clk, 1);
1650 break;
1651 default:
1652 omap_clk_onoff(clk, 0);
1657 static void omap_clkm_write(void *opaque, hwaddr addr,
1658 uint64_t value, unsigned size)
1660 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1661 uint16_t diff;
1662 omap_clk clk;
1663 static const char *clkschemename[8] = {
1664 "fully synchronous", "fully asynchronous", "synchronous scalable",
1665 "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
1668 if (size != 2) {
1669 omap_badwidth_write16(opaque, addr, value);
1670 return;
1673 switch (addr) {
1674 case 0x00: /* ARM_CKCTL */
1675 diff = s->clkm.arm_ckctl ^ value;
1676 s->clkm.arm_ckctl = value & 0x7fff;
1677 omap_clkm_ckctl_update(s, diff, value);
1678 return;
1680 case 0x04: /* ARM_IDLECT1 */
1681 diff = s->clkm.arm_idlect1 ^ value;
1682 s->clkm.arm_idlect1 = value & 0x0fff;
1683 omap_clkm_idlect1_update(s, diff, value);
1684 return;
1686 case 0x08: /* ARM_IDLECT2 */
1687 diff = s->clkm.arm_idlect2 ^ value;
1688 s->clkm.arm_idlect2 = value & 0x07ff;
1689 omap_clkm_idlect2_update(s, diff, value);
1690 return;
1692 case 0x0c: /* ARM_EWUPCT */
1693 s->clkm.arm_ewupct = value & 0x003f;
1694 return;
1696 case 0x10: /* ARM_RSTCT1 */
1697 diff = s->clkm.arm_rstct1 ^ value;
1698 s->clkm.arm_rstct1 = value & 0x0007;
1699 if (value & 9) {
1700 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
1701 s->clkm.cold_start = 0xa;
1703 if (diff & ~value & 4) { /* DSP_RST */
1704 omap_mpui_reset(s);
1705 omap_tipb_bridge_reset(s->private_tipb);
1706 omap_tipb_bridge_reset(s->public_tipb);
1708 if (diff & 2) { /* DSP_EN */
1709 clk = omap_findclk(s, "dsp_ck");
1710 omap_clk_canidle(clk, (~value >> 1) & 1);
1712 return;
1714 case 0x14: /* ARM_RSTCT2 */
1715 s->clkm.arm_rstct2 = value & 0x0001;
1716 return;
1718 case 0x18: /* ARM_SYSST */
1719 if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
1720 s->clkm.clocking_scheme = (value >> 11) & 7;
1721 printf("%s: clocking scheme set to %s\n", __func__,
1722 clkschemename[s->clkm.clocking_scheme]);
1724 s->clkm.cold_start &= value & 0x3f;
1725 return;
1727 case 0x1c: /* ARM_CKOUT1 */
1728 diff = s->clkm.arm_ckout1 ^ value;
1729 s->clkm.arm_ckout1 = value & 0x003f;
1730 omap_clkm_ckout1_update(s, diff, value);
1731 return;
1733 case 0x20: /* ARM_CKOUT2 */
1734 default:
1735 OMAP_BAD_REG(addr);
1739 static const MemoryRegionOps omap_clkm_ops = {
1740 .read = omap_clkm_read,
1741 .write = omap_clkm_write,
1742 .endianness = DEVICE_NATIVE_ENDIAN,
1745 static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
1746 unsigned size)
1748 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1749 CPUState *cpu = CPU(s->cpu);
1751 if (size != 2) {
1752 return omap_badwidth_read16(opaque, addr);
1755 switch (addr) {
1756 case 0x04: /* DSP_IDLECT1 */
1757 return s->clkm.dsp_idlect1;
1759 case 0x08: /* DSP_IDLECT2 */
1760 return s->clkm.dsp_idlect2;
1762 case 0x14: /* DSP_RSTCT2 */
1763 return s->clkm.dsp_rstct2;
1765 case 0x18: /* DSP_SYSST */
1766 cpu = CPU(s->cpu);
1767 return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
1768 (cpu->halted << 6); /* Quite useless... */
1771 OMAP_BAD_REG(addr);
1772 return 0;
1775 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
1776 uint16_t diff, uint16_t value)
1778 omap_clk clk;
1780 SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */
1783 static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
1784 uint16_t diff, uint16_t value)
1786 omap_clk clk;
1788 SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */
1791 static void omap_clkdsp_write(void *opaque, hwaddr addr,
1792 uint64_t value, unsigned size)
1794 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1795 uint16_t diff;
1797 if (size != 2) {
1798 omap_badwidth_write16(opaque, addr, value);
1799 return;
1802 switch (addr) {
1803 case 0x04: /* DSP_IDLECT1 */
1804 diff = s->clkm.dsp_idlect1 ^ value;
1805 s->clkm.dsp_idlect1 = value & 0x01f7;
1806 omap_clkdsp_idlect1_update(s, diff, value);
1807 break;
1809 case 0x08: /* DSP_IDLECT2 */
1810 s->clkm.dsp_idlect2 = value & 0x0037;
1811 diff = s->clkm.dsp_idlect1 ^ value;
1812 omap_clkdsp_idlect2_update(s, diff, value);
1813 break;
1815 case 0x14: /* DSP_RSTCT2 */
1816 s->clkm.dsp_rstct2 = value & 0x0001;
1817 break;
1819 case 0x18: /* DSP_SYSST */
1820 s->clkm.cold_start &= value & 0x3f;
1821 break;
1823 default:
1824 OMAP_BAD_REG(addr);
1828 static const MemoryRegionOps omap_clkdsp_ops = {
1829 .read = omap_clkdsp_read,
1830 .write = omap_clkdsp_write,
1831 .endianness = DEVICE_NATIVE_ENDIAN,
1834 static void omap_clkm_reset(struct omap_mpu_state_s *s)
1836 if (s->wdt && s->wdt->reset)
1837 s->clkm.cold_start = 0x6;
1838 s->clkm.clocking_scheme = 0;
1839 omap_clkm_ckctl_update(s, ~0, 0x3000);
1840 s->clkm.arm_ckctl = 0x3000;
1841 omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
1842 s->clkm.arm_idlect1 = 0x0400;
1843 omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
1844 s->clkm.arm_idlect2 = 0x0100;
1845 s->clkm.arm_ewupct = 0x003f;
1846 s->clkm.arm_rstct1 = 0x0000;
1847 s->clkm.arm_rstct2 = 0x0000;
1848 s->clkm.arm_ckout1 = 0x0015;
1849 s->clkm.dpll1_mode = 0x2002;
1850 omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
1851 s->clkm.dsp_idlect1 = 0x0040;
1852 omap_clkdsp_idlect2_update(s, ~0, 0x0000);
1853 s->clkm.dsp_idlect2 = 0x0000;
1854 s->clkm.dsp_rstct2 = 0x0000;
1857 static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
1858 hwaddr dsp_base, struct omap_mpu_state_s *s)
1860 memory_region_init_io(&s->clkm_iomem, NULL, &omap_clkm_ops, s,
1861 "omap-clkm", 0x100);
1862 memory_region_init_io(&s->clkdsp_iomem, NULL, &omap_clkdsp_ops, s,
1863 "omap-clkdsp", 0x1000);
1865 s->clkm.arm_idlect1 = 0x03ff;
1866 s->clkm.arm_idlect2 = 0x0100;
1867 s->clkm.dsp_idlect1 = 0x0002;
1868 omap_clkm_reset(s);
1869 s->clkm.cold_start = 0x3a;
1871 memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
1872 memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
1875 /* MPU I/O */
1876 struct omap_mpuio_s {
1877 qemu_irq irq;
1878 qemu_irq kbd_irq;
1879 qemu_irq *in;
1880 qemu_irq handler[16];
1881 qemu_irq wakeup;
1882 MemoryRegion iomem;
1884 uint16_t inputs;
1885 uint16_t outputs;
1886 uint16_t dir;
1887 uint16_t edge;
1888 uint16_t mask;
1889 uint16_t ints;
1891 uint16_t debounce;
1892 uint16_t latch;
1893 uint8_t event;
1895 uint8_t buttons[5];
1896 uint8_t row_latch;
1897 uint8_t cols;
1898 int kbd_mask;
1899 int clk;
1902 static void omap_mpuio_set(void *opaque, int line, int level)
1904 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1905 uint16_t prev = s->inputs;
1907 if (level)
1908 s->inputs |= 1 << line;
1909 else
1910 s->inputs &= ~(1 << line);
1912 if (((1 << line) & s->dir & ~s->mask) && s->clk) {
1913 if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
1914 s->ints |= 1 << line;
1915 qemu_irq_raise(s->irq);
1916 /* TODO: wakeup */
1918 if ((s->event & (1 << 0)) && /* SET_GPIO_EVENT_MODE */
1919 (s->event >> 1) == line) /* PIN_SELECT */
1920 s->latch = s->inputs;
1924 static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
1926 int i;
1927 uint8_t *row, rows = 0, cols = ~s->cols;
1929 for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1930 if (*row & cols)
1931 rows |= i;
1933 qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1934 s->row_latch = ~rows;
1937 static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
1938 unsigned size)
1940 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1941 int offset = addr & OMAP_MPUI_REG_MASK;
1942 uint16_t ret;
1944 if (size != 2) {
1945 return omap_badwidth_read16(opaque, addr);
1948 switch (offset) {
1949 case 0x00: /* INPUT_LATCH */
1950 return s->inputs;
1952 case 0x04: /* OUTPUT_REG */
1953 return s->outputs;
1955 case 0x08: /* IO_CNTL */
1956 return s->dir;
1958 case 0x10: /* KBR_LATCH */
1959 return s->row_latch;
1961 case 0x14: /* KBC_REG */
1962 return s->cols;
1964 case 0x18: /* GPIO_EVENT_MODE_REG */
1965 return s->event;
1967 case 0x1c: /* GPIO_INT_EDGE_REG */
1968 return s->edge;
1970 case 0x20: /* KBD_INT */
1971 return (~s->row_latch & 0x1f) && !s->kbd_mask;
1973 case 0x24: /* GPIO_INT */
1974 ret = s->ints;
1975 s->ints &= s->mask;
1976 if (ret)
1977 qemu_irq_lower(s->irq);
1978 return ret;
1980 case 0x28: /* KBD_MASKIT */
1981 return s->kbd_mask;
1983 case 0x2c: /* GPIO_MASKIT */
1984 return s->mask;
1986 case 0x30: /* GPIO_DEBOUNCING_REG */
1987 return s->debounce;
1989 case 0x34: /* GPIO_LATCH_REG */
1990 return s->latch;
1993 OMAP_BAD_REG(addr);
1994 return 0;
1997 static void omap_mpuio_write(void *opaque, hwaddr addr,
1998 uint64_t value, unsigned size)
2000 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2001 int offset = addr & OMAP_MPUI_REG_MASK;
2002 uint16_t diff;
2003 int ln;
2005 if (size != 2) {
2006 omap_badwidth_write16(opaque, addr, value);
2007 return;
2010 switch (offset) {
2011 case 0x04: /* OUTPUT_REG */
2012 diff = (s->outputs ^ value) & ~s->dir;
2013 s->outputs = value;
2014 while ((ln = ctz32(diff)) != 32) {
2015 if (s->handler[ln])
2016 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2017 diff &= ~(1 << ln);
2019 break;
2021 case 0x08: /* IO_CNTL */
2022 diff = s->outputs & (s->dir ^ value);
2023 s->dir = value;
2025 value = s->outputs & ~s->dir;
2026 while ((ln = ctz32(diff)) != 32) {
2027 if (s->handler[ln])
2028 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2029 diff &= ~(1 << ln);
2031 break;
2033 case 0x14: /* KBC_REG */
2034 s->cols = value;
2035 omap_mpuio_kbd_update(s);
2036 break;
2038 case 0x18: /* GPIO_EVENT_MODE_REG */
2039 s->event = value & 0x1f;
2040 break;
2042 case 0x1c: /* GPIO_INT_EDGE_REG */
2043 s->edge = value;
2044 break;
2046 case 0x28: /* KBD_MASKIT */
2047 s->kbd_mask = value & 1;
2048 omap_mpuio_kbd_update(s);
2049 break;
2051 case 0x2c: /* GPIO_MASKIT */
2052 s->mask = value;
2053 break;
2055 case 0x30: /* GPIO_DEBOUNCING_REG */
2056 s->debounce = value & 0x1ff;
2057 break;
2059 case 0x00: /* INPUT_LATCH */
2060 case 0x10: /* KBR_LATCH */
2061 case 0x20: /* KBD_INT */
2062 case 0x24: /* GPIO_INT */
2063 case 0x34: /* GPIO_LATCH_REG */
2064 OMAP_RO_REG(addr);
2065 return;
2067 default:
2068 OMAP_BAD_REG(addr);
2069 return;
2073 static const MemoryRegionOps omap_mpuio_ops = {
2074 .read = omap_mpuio_read,
2075 .write = omap_mpuio_write,
2076 .endianness = DEVICE_NATIVE_ENDIAN,
2079 static void omap_mpuio_reset(struct omap_mpuio_s *s)
2081 s->inputs = 0;
2082 s->outputs = 0;
2083 s->dir = ~0;
2084 s->event = 0;
2085 s->edge = 0;
2086 s->kbd_mask = 0;
2087 s->mask = 0;
2088 s->debounce = 0;
2089 s->latch = 0;
2090 s->ints = 0;
2091 s->row_latch = 0x1f;
2092 s->clk = 1;
2095 static void omap_mpuio_onoff(void *opaque, int line, int on)
2097 struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2099 s->clk = on;
2100 if (on)
2101 omap_mpuio_kbd_update(s);
2104 static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
2105 hwaddr base,
2106 qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2107 omap_clk clk)
2109 struct omap_mpuio_s *s = g_new0(struct omap_mpuio_s, 1);
2111 s->irq = gpio_int;
2112 s->kbd_irq = kbd_int;
2113 s->wakeup = wakeup;
2114 s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2115 omap_mpuio_reset(s);
2117 memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s,
2118 "omap-mpuio", 0x800);
2119 memory_region_add_subregion(memory, base, &s->iomem);
2121 omap_clk_adduser(clk, qemu_allocate_irq(omap_mpuio_onoff, s, 0));
2123 return s;
2126 qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2128 return s->in;
2131 void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2133 if (line >= 16 || line < 0)
2134 hw_error("%s: No GPIO line %i\n", __func__, line);
2135 s->handler[line] = handler;
2138 void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2140 if (row >= 5 || row < 0)
2141 hw_error("%s: No key %i-%i\n", __func__, col, row);
2143 if (down)
2144 s->buttons[row] |= 1 << col;
2145 else
2146 s->buttons[row] &= ~(1 << col);
2148 omap_mpuio_kbd_update(s);
2151 /* MicroWire Interface */
2152 struct omap_uwire_s {
2153 MemoryRegion iomem;
2154 qemu_irq txirq;
2155 qemu_irq rxirq;
2156 qemu_irq txdrq;
2158 uint16_t txbuf;
2159 uint16_t rxbuf;
2160 uint16_t control;
2161 uint16_t setup[5];
2163 uWireSlave *chip[4];
2166 static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2168 int chipselect = (s->control >> 10) & 3; /* INDEX */
2169 uWireSlave *slave = s->chip[chipselect];
2171 if ((s->control >> 5) & 0x1f) { /* NB_BITS_WR */
2172 if (s->control & (1 << 12)) /* CS_CMD */
2173 if (slave && slave->send)
2174 slave->send(slave->opaque,
2175 s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
2176 s->control &= ~(1 << 14); /* CSRB */
2177 /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2178 * a DRQ. When is the level IRQ supposed to be reset? */
2181 if ((s->control >> 0) & 0x1f) { /* NB_BITS_RD */
2182 if (s->control & (1 << 12)) /* CS_CMD */
2183 if (slave && slave->receive)
2184 s->rxbuf = slave->receive(slave->opaque);
2185 s->control |= 1 << 15; /* RDRB */
2186 /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2187 * a DRQ. When is the level IRQ supposed to be reset? */
2191 static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
2192 unsigned size)
2194 struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2195 int offset = addr & OMAP_MPUI_REG_MASK;
2197 if (size != 2) {
2198 return omap_badwidth_read16(opaque, addr);
2201 switch (offset) {
2202 case 0x00: /* RDR */
2203 s->control &= ~(1 << 15); /* RDRB */
2204 return s->rxbuf;
2206 case 0x04: /* CSR */
2207 return s->control;
2209 case 0x08: /* SR1 */
2210 return s->setup[0];
2211 case 0x0c: /* SR2 */
2212 return s->setup[1];
2213 case 0x10: /* SR3 */
2214 return s->setup[2];
2215 case 0x14: /* SR4 */
2216 return s->setup[3];
2217 case 0x18: /* SR5 */
2218 return s->setup[4];
2221 OMAP_BAD_REG(addr);
2222 return 0;
2225 static void omap_uwire_write(void *opaque, hwaddr addr,
2226 uint64_t value, unsigned size)
2228 struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2229 int offset = addr & OMAP_MPUI_REG_MASK;
2231 if (size != 2) {
2232 omap_badwidth_write16(opaque, addr, value);
2233 return;
2236 switch (offset) {
2237 case 0x00: /* TDR */
2238 s->txbuf = value; /* TD */
2239 if ((s->setup[4] & (1 << 2)) && /* AUTO_TX_EN */
2240 ((s->setup[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */
2241 (s->control & (1 << 12)))) { /* CS_CMD */
2242 s->control |= 1 << 14; /* CSRB */
2243 omap_uwire_transfer_start(s);
2245 break;
2247 case 0x04: /* CSR */
2248 s->control = value & 0x1fff;
2249 if (value & (1 << 13)) /* START */
2250 omap_uwire_transfer_start(s);
2251 break;
2253 case 0x08: /* SR1 */
2254 s->setup[0] = value & 0x003f;
2255 break;
2257 case 0x0c: /* SR2 */
2258 s->setup[1] = value & 0x0fc0;
2259 break;
2261 case 0x10: /* SR3 */
2262 s->setup[2] = value & 0x0003;
2263 break;
2265 case 0x14: /* SR4 */
2266 s->setup[3] = value & 0x0001;
2267 break;
2269 case 0x18: /* SR5 */
2270 s->setup[4] = value & 0x000f;
2271 break;
2273 default:
2274 OMAP_BAD_REG(addr);
2275 return;
2279 static const MemoryRegionOps omap_uwire_ops = {
2280 .read = omap_uwire_read,
2281 .write = omap_uwire_write,
2282 .endianness = DEVICE_NATIVE_ENDIAN,
2285 static void omap_uwire_reset(struct omap_uwire_s *s)
2287 s->control = 0;
2288 s->setup[0] = 0;
2289 s->setup[1] = 0;
2290 s->setup[2] = 0;
2291 s->setup[3] = 0;
2292 s->setup[4] = 0;
2295 static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
2296 hwaddr base,
2297 qemu_irq txirq, qemu_irq rxirq,
2298 qemu_irq dma,
2299 omap_clk clk)
2301 struct omap_uwire_s *s = g_new0(struct omap_uwire_s, 1);
2303 s->txirq = txirq;
2304 s->rxirq = rxirq;
2305 s->txdrq = dma;
2306 omap_uwire_reset(s);
2308 memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800);
2309 memory_region_add_subregion(system_memory, base, &s->iomem);
2311 return s;
2314 void omap_uwire_attach(struct omap_uwire_s *s,
2315 uWireSlave *slave, int chipselect)
2317 if (chipselect < 0 || chipselect > 3) {
2318 error_report("%s: Bad chipselect %i", __func__, chipselect);
2319 exit(-1);
2322 s->chip[chipselect] = slave;
2325 /* Pseudonoise Pulse-Width Light Modulator */
2326 struct omap_pwl_s {
2327 MemoryRegion iomem;
2328 uint8_t output;
2329 uint8_t level;
2330 uint8_t enable;
2331 int clk;
2334 static void omap_pwl_update(struct omap_pwl_s *s)
2336 int output = (s->clk && s->enable) ? s->level : 0;
2338 if (output != s->output) {
2339 s->output = output;
2340 printf("%s: Backlight now at %i/256\n", __func__, output);
2344 static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
2345 unsigned size)
2347 struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2348 int offset = addr & OMAP_MPUI_REG_MASK;
2350 if (size != 1) {
2351 return omap_badwidth_read8(opaque, addr);
2354 switch (offset) {
2355 case 0x00: /* PWL_LEVEL */
2356 return s->level;
2357 case 0x04: /* PWL_CTRL */
2358 return s->enable;
2360 OMAP_BAD_REG(addr);
2361 return 0;
2364 static void omap_pwl_write(void *opaque, hwaddr addr,
2365 uint64_t value, unsigned size)
2367 struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2368 int offset = addr & OMAP_MPUI_REG_MASK;
2370 if (size != 1) {
2371 omap_badwidth_write8(opaque, addr, value);
2372 return;
2375 switch (offset) {
2376 case 0x00: /* PWL_LEVEL */
2377 s->level = value;
2378 omap_pwl_update(s);
2379 break;
2380 case 0x04: /* PWL_CTRL */
2381 s->enable = value & 1;
2382 omap_pwl_update(s);
2383 break;
2384 default:
2385 OMAP_BAD_REG(addr);
2386 return;
2390 static const MemoryRegionOps omap_pwl_ops = {
2391 .read = omap_pwl_read,
2392 .write = omap_pwl_write,
2393 .endianness = DEVICE_NATIVE_ENDIAN,
2396 static void omap_pwl_reset(struct omap_pwl_s *s)
2398 s->output = 0;
2399 s->level = 0;
2400 s->enable = 0;
2401 s->clk = 1;
2402 omap_pwl_update(s);
2405 static void omap_pwl_clk_update(void *opaque, int line, int on)
2407 struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2409 s->clk = on;
2410 omap_pwl_update(s);
2413 static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
2414 hwaddr base,
2415 omap_clk clk)
2417 struct omap_pwl_s *s = g_malloc0(sizeof(*s));
2419 omap_pwl_reset(s);
2421 memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s,
2422 "omap-pwl", 0x800);
2423 memory_region_add_subregion(system_memory, base, &s->iomem);
2425 omap_clk_adduser(clk, qemu_allocate_irq(omap_pwl_clk_update, s, 0));
2426 return s;
2429 /* Pulse-Width Tone module */
2430 struct omap_pwt_s {
2431 MemoryRegion iomem;
2432 uint8_t frc;
2433 uint8_t vrc;
2434 uint8_t gcr;
2435 omap_clk clk;
2438 static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
2439 unsigned size)
2441 struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
2442 int offset = addr & OMAP_MPUI_REG_MASK;
2444 if (size != 1) {
2445 return omap_badwidth_read8(opaque, addr);
2448 switch (offset) {
2449 case 0x00: /* FRC */
2450 return s->frc;
2451 case 0x04: /* VCR */
2452 return s->vrc;
2453 case 0x08: /* GCR */
2454 return s->gcr;
2456 OMAP_BAD_REG(addr);
2457 return 0;
2460 static void omap_pwt_write(void *opaque, hwaddr addr,
2461 uint64_t value, unsigned size)
2463 struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
2464 int offset = addr & OMAP_MPUI_REG_MASK;
2466 if (size != 1) {
2467 omap_badwidth_write8(opaque, addr, value);
2468 return;
2471 switch (offset) {
2472 case 0x00: /* FRC */
2473 s->frc = value & 0x3f;
2474 break;
2475 case 0x04: /* VRC */
2476 if ((value ^ s->vrc) & 1) {
2477 if (value & 1)
2478 printf("%s: %iHz buzz on\n", __func__, (int)
2479 /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
2480 ((omap_clk_getrate(s->clk) >> 3) /
2481 /* Pre-multiplexer divider */
2482 ((s->gcr & 2) ? 1 : 154) /
2483 /* Octave multiplexer */
2484 (2 << (value & 3)) *
2485 /* 101/107 divider */
2486 ((value & (1 << 2)) ? 101 : 107) *
2487 /* 49/55 divider */
2488 ((value & (1 << 3)) ? 49 : 55) *
2489 /* 50/63 divider */
2490 ((value & (1 << 4)) ? 50 : 63) *
2491 /* 80/127 divider */
2492 ((value & (1 << 5)) ? 80 : 127) /
2493 (107 * 55 * 63 * 127)));
2494 else
2495 printf("%s: silence!\n", __func__);
2497 s->vrc = value & 0x7f;
2498 break;
2499 case 0x08: /* GCR */
2500 s->gcr = value & 3;
2501 break;
2502 default:
2503 OMAP_BAD_REG(addr);
2504 return;
2508 static const MemoryRegionOps omap_pwt_ops = {
2509 .read =omap_pwt_read,
2510 .write = omap_pwt_write,
2511 .endianness = DEVICE_NATIVE_ENDIAN,
2514 static void omap_pwt_reset(struct omap_pwt_s *s)
2516 s->frc = 0;
2517 s->vrc = 0;
2518 s->gcr = 0;
2521 static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
2522 hwaddr base,
2523 omap_clk clk)
2525 struct omap_pwt_s *s = g_malloc0(sizeof(*s));
2526 s->clk = clk;
2527 omap_pwt_reset(s);
2529 memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s,
2530 "omap-pwt", 0x800);
2531 memory_region_add_subregion(system_memory, base, &s->iomem);
2532 return s;
2535 /* Real-time Clock module */
2536 struct omap_rtc_s {
2537 MemoryRegion iomem;
2538 qemu_irq irq;
2539 qemu_irq alarm;
2540 QEMUTimer *clk;
2542 uint8_t interrupts;
2543 uint8_t status;
2544 int16_t comp_reg;
2545 int running;
2546 int pm_am;
2547 int auto_comp;
2548 int round;
2549 struct tm alarm_tm;
2550 time_t alarm_ti;
2552 struct tm current_tm;
2553 time_t ti;
2554 uint64_t tick;
2557 static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2559 /* s->alarm is level-triggered */
2560 qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2563 static void omap_rtc_alarm_update(struct omap_rtc_s *s)
2565 s->alarm_ti = mktimegm(&s->alarm_tm);
2566 if (s->alarm_ti == -1)
2567 printf("%s: conversion failed\n", __func__);
2570 static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
2571 unsigned size)
2573 struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2574 int offset = addr & OMAP_MPUI_REG_MASK;
2575 uint8_t i;
2577 if (size != 1) {
2578 return omap_badwidth_read8(opaque, addr);
2581 switch (offset) {
2582 case 0x00: /* SECONDS_REG */
2583 return to_bcd(s->current_tm.tm_sec);
2585 case 0x04: /* MINUTES_REG */
2586 return to_bcd(s->current_tm.tm_min);
2588 case 0x08: /* HOURS_REG */
2589 if (s->pm_am)
2590 return ((s->current_tm.tm_hour > 11) << 7) |
2591 to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
2592 else
2593 return to_bcd(s->current_tm.tm_hour);
2595 case 0x0c: /* DAYS_REG */
2596 return to_bcd(s->current_tm.tm_mday);
2598 case 0x10: /* MONTHS_REG */
2599 return to_bcd(s->current_tm.tm_mon + 1);
2601 case 0x14: /* YEARS_REG */
2602 return to_bcd(s->current_tm.tm_year % 100);
2604 case 0x18: /* WEEK_REG */
2605 return s->current_tm.tm_wday;
2607 case 0x20: /* ALARM_SECONDS_REG */
2608 return to_bcd(s->alarm_tm.tm_sec);
2610 case 0x24: /* ALARM_MINUTES_REG */
2611 return to_bcd(s->alarm_tm.tm_min);
2613 case 0x28: /* ALARM_HOURS_REG */
2614 if (s->pm_am)
2615 return ((s->alarm_tm.tm_hour > 11) << 7) |
2616 to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
2617 else
2618 return to_bcd(s->alarm_tm.tm_hour);
2620 case 0x2c: /* ALARM_DAYS_REG */
2621 return to_bcd(s->alarm_tm.tm_mday);
2623 case 0x30: /* ALARM_MONTHS_REG */
2624 return to_bcd(s->alarm_tm.tm_mon + 1);
2626 case 0x34: /* ALARM_YEARS_REG */
2627 return to_bcd(s->alarm_tm.tm_year % 100);
2629 case 0x40: /* RTC_CTRL_REG */
2630 return (s->pm_am << 3) | (s->auto_comp << 2) |
2631 (s->round << 1) | s->running;
2633 case 0x44: /* RTC_STATUS_REG */
2634 i = s->status;
2635 s->status &= ~0x3d;
2636 return i;
2638 case 0x48: /* RTC_INTERRUPTS_REG */
2639 return s->interrupts;
2641 case 0x4c: /* RTC_COMP_LSB_REG */
2642 return ((uint16_t) s->comp_reg) & 0xff;
2644 case 0x50: /* RTC_COMP_MSB_REG */
2645 return ((uint16_t) s->comp_reg) >> 8;
2648 OMAP_BAD_REG(addr);
2649 return 0;
2652 static void omap_rtc_write(void *opaque, hwaddr addr,
2653 uint64_t value, unsigned size)
2655 struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2656 int offset = addr & OMAP_MPUI_REG_MASK;
2657 struct tm new_tm;
2658 time_t ti[2];
2660 if (size != 1) {
2661 omap_badwidth_write8(opaque, addr, value);
2662 return;
2665 switch (offset) {
2666 case 0x00: /* SECONDS_REG */
2667 #ifdef ALMDEBUG
2668 printf("RTC SEC_REG <-- %02x\n", value);
2669 #endif
2670 s->ti -= s->current_tm.tm_sec;
2671 s->ti += from_bcd(value);
2672 return;
2674 case 0x04: /* MINUTES_REG */
2675 #ifdef ALMDEBUG
2676 printf("RTC MIN_REG <-- %02x\n", value);
2677 #endif
2678 s->ti -= s->current_tm.tm_min * 60;
2679 s->ti += from_bcd(value) * 60;
2680 return;
2682 case 0x08: /* HOURS_REG */
2683 #ifdef ALMDEBUG
2684 printf("RTC HRS_REG <-- %02x\n", value);
2685 #endif
2686 s->ti -= s->current_tm.tm_hour * 3600;
2687 if (s->pm_am) {
2688 s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
2689 s->ti += ((value >> 7) & 1) * 43200;
2690 } else
2691 s->ti += from_bcd(value & 0x3f) * 3600;
2692 return;
2694 case 0x0c: /* DAYS_REG */
2695 #ifdef ALMDEBUG
2696 printf("RTC DAY_REG <-- %02x\n", value);
2697 #endif
2698 s->ti -= s->current_tm.tm_mday * 86400;
2699 s->ti += from_bcd(value) * 86400;
2700 return;
2702 case 0x10: /* MONTHS_REG */
2703 #ifdef ALMDEBUG
2704 printf("RTC MTH_REG <-- %02x\n", value);
2705 #endif
2706 memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2707 new_tm.tm_mon = from_bcd(value);
2708 ti[0] = mktimegm(&s->current_tm);
2709 ti[1] = mktimegm(&new_tm);
2711 if (ti[0] != -1 && ti[1] != -1) {
2712 s->ti -= ti[0];
2713 s->ti += ti[1];
2714 } else {
2715 /* A less accurate version */
2716 s->ti -= s->current_tm.tm_mon * 2592000;
2717 s->ti += from_bcd(value) * 2592000;
2719 return;
2721 case 0x14: /* YEARS_REG */
2722 #ifdef ALMDEBUG
2723 printf("RTC YRS_REG <-- %02x\n", value);
2724 #endif
2725 memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2726 new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
2727 ti[0] = mktimegm(&s->current_tm);
2728 ti[1] = mktimegm(&new_tm);
2730 if (ti[0] != -1 && ti[1] != -1) {
2731 s->ti -= ti[0];
2732 s->ti += ti[1];
2733 } else {
2734 /* A less accurate version */
2735 s->ti -= (time_t)(s->current_tm.tm_year % 100) * 31536000;
2736 s->ti += (time_t)from_bcd(value) * 31536000;
2738 return;
2740 case 0x18: /* WEEK_REG */
2741 return; /* Ignored */
2743 case 0x20: /* ALARM_SECONDS_REG */
2744 #ifdef ALMDEBUG
2745 printf("ALM SEC_REG <-- %02x\n", value);
2746 #endif
2747 s->alarm_tm.tm_sec = from_bcd(value);
2748 omap_rtc_alarm_update(s);
2749 return;
2751 case 0x24: /* ALARM_MINUTES_REG */
2752 #ifdef ALMDEBUG
2753 printf("ALM MIN_REG <-- %02x\n", value);
2754 #endif
2755 s->alarm_tm.tm_min = from_bcd(value);
2756 omap_rtc_alarm_update(s);
2757 return;
2759 case 0x28: /* ALARM_HOURS_REG */
2760 #ifdef ALMDEBUG
2761 printf("ALM HRS_REG <-- %02x\n", value);
2762 #endif
2763 if (s->pm_am)
2764 s->alarm_tm.tm_hour =
2765 ((from_bcd(value & 0x3f)) % 12) +
2766 ((value >> 7) & 1) * 12;
2767 else
2768 s->alarm_tm.tm_hour = from_bcd(value);
2769 omap_rtc_alarm_update(s);
2770 return;
2772 case 0x2c: /* ALARM_DAYS_REG */
2773 #ifdef ALMDEBUG
2774 printf("ALM DAY_REG <-- %02x\n", value);
2775 #endif
2776 s->alarm_tm.tm_mday = from_bcd(value);
2777 omap_rtc_alarm_update(s);
2778 return;
2780 case 0x30: /* ALARM_MONTHS_REG */
2781 #ifdef ALMDEBUG
2782 printf("ALM MON_REG <-- %02x\n", value);
2783 #endif
2784 s->alarm_tm.tm_mon = from_bcd(value);
2785 omap_rtc_alarm_update(s);
2786 return;
2788 case 0x34: /* ALARM_YEARS_REG */
2789 #ifdef ALMDEBUG
2790 printf("ALM YRS_REG <-- %02x\n", value);
2791 #endif
2792 s->alarm_tm.tm_year = from_bcd(value);
2793 omap_rtc_alarm_update(s);
2794 return;
2796 case 0x40: /* RTC_CTRL_REG */
2797 #ifdef ALMDEBUG
2798 printf("RTC CONTROL <-- %02x\n", value);
2799 #endif
2800 s->pm_am = (value >> 3) & 1;
2801 s->auto_comp = (value >> 2) & 1;
2802 s->round = (value >> 1) & 1;
2803 s->running = value & 1;
2804 s->status &= 0xfd;
2805 s->status |= s->running << 1;
2806 return;
2808 case 0x44: /* RTC_STATUS_REG */
2809 #ifdef ALMDEBUG
2810 printf("RTC STATUSL <-- %02x\n", value);
2811 #endif
2812 s->status &= ~((value & 0xc0) ^ 0x80);
2813 omap_rtc_interrupts_update(s);
2814 return;
2816 case 0x48: /* RTC_INTERRUPTS_REG */
2817 #ifdef ALMDEBUG
2818 printf("RTC INTRS <-- %02x\n", value);
2819 #endif
2820 s->interrupts = value;
2821 return;
2823 case 0x4c: /* RTC_COMP_LSB_REG */
2824 #ifdef ALMDEBUG
2825 printf("RTC COMPLSB <-- %02x\n", value);
2826 #endif
2827 s->comp_reg &= 0xff00;
2828 s->comp_reg |= 0x00ff & value;
2829 return;
2831 case 0x50: /* RTC_COMP_MSB_REG */
2832 #ifdef ALMDEBUG
2833 printf("RTC COMPMSB <-- %02x\n", value);
2834 #endif
2835 s->comp_reg &= 0x00ff;
2836 s->comp_reg |= 0xff00 & (value << 8);
2837 return;
2839 default:
2840 OMAP_BAD_REG(addr);
2841 return;
2845 static const MemoryRegionOps omap_rtc_ops = {
2846 .read = omap_rtc_read,
2847 .write = omap_rtc_write,
2848 .endianness = DEVICE_NATIVE_ENDIAN,
2851 static void omap_rtc_tick(void *opaque)
2853 struct omap_rtc_s *s = opaque;
2855 if (s->round) {
2856 /* Round to nearest full minute. */
2857 if (s->current_tm.tm_sec < 30)
2858 s->ti -= s->current_tm.tm_sec;
2859 else
2860 s->ti += 60 - s->current_tm.tm_sec;
2862 s->round = 0;
2865 localtime_r(&s->ti, &s->current_tm);
2867 if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2868 s->status |= 0x40;
2869 omap_rtc_interrupts_update(s);
2872 if (s->interrupts & 0x04)
2873 switch (s->interrupts & 3) {
2874 case 0:
2875 s->status |= 0x04;
2876 qemu_irq_pulse(s->irq);
2877 break;
2878 case 1:
2879 if (s->current_tm.tm_sec)
2880 break;
2881 s->status |= 0x08;
2882 qemu_irq_pulse(s->irq);
2883 break;
2884 case 2:
2885 if (s->current_tm.tm_sec || s->current_tm.tm_min)
2886 break;
2887 s->status |= 0x10;
2888 qemu_irq_pulse(s->irq);
2889 break;
2890 case 3:
2891 if (s->current_tm.tm_sec ||
2892 s->current_tm.tm_min || s->current_tm.tm_hour)
2893 break;
2894 s->status |= 0x20;
2895 qemu_irq_pulse(s->irq);
2896 break;
2899 /* Move on */
2900 if (s->running)
2901 s->ti ++;
2902 s->tick += 1000;
2905 * Every full hour add a rough approximation of the compensation
2906 * register to the 32kHz Timer (which drives the RTC) value.
2908 if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
2909 s->tick += s->comp_reg * 1000 / 32768;
2911 timer_mod(s->clk, s->tick);
2914 static void omap_rtc_reset(struct omap_rtc_s *s)
2916 struct tm tm;
2918 s->interrupts = 0;
2919 s->comp_reg = 0;
2920 s->running = 0;
2921 s->pm_am = 0;
2922 s->auto_comp = 0;
2923 s->round = 0;
2924 s->tick = qemu_clock_get_ms(rtc_clock);
2925 memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
2926 s->alarm_tm.tm_mday = 0x01;
2927 s->status = 1 << 7;
2928 qemu_get_timedate(&tm, 0);
2929 s->ti = mktimegm(&tm);
2931 omap_rtc_alarm_update(s);
2932 omap_rtc_tick(s);
2935 static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
2936 hwaddr base,
2937 qemu_irq timerirq, qemu_irq alarmirq,
2938 omap_clk clk)
2940 struct omap_rtc_s *s = g_new0(struct omap_rtc_s, 1);
2942 s->irq = timerirq;
2943 s->alarm = alarmirq;
2944 s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);
2946 omap_rtc_reset(s);
2948 memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,
2949 "omap-rtc", 0x800);
2950 memory_region_add_subregion(system_memory, base, &s->iomem);
2952 return s;
2955 /* Multi-channel Buffered Serial Port interfaces */
2956 struct omap_mcbsp_s {
2957 MemoryRegion iomem;
2958 qemu_irq txirq;
2959 qemu_irq rxirq;
2960 qemu_irq txdrq;
2961 qemu_irq rxdrq;
2963 uint16_t spcr[2];
2964 uint16_t rcr[2];
2965 uint16_t xcr[2];
2966 uint16_t srgr[2];
2967 uint16_t mcr[2];
2968 uint16_t pcr;
2969 uint16_t rcer[8];
2970 uint16_t xcer[8];
2971 int tx_rate;
2972 int rx_rate;
2973 int tx_req;
2974 int rx_req;
2976 I2SCodec *codec;
2977 QEMUTimer *source_timer;
2978 QEMUTimer *sink_timer;
2981 static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2983 int irq;
2985 switch ((s->spcr[0] >> 4) & 3) { /* RINTM */
2986 case 0:
2987 irq = (s->spcr[0] >> 1) & 1; /* RRDY */
2988 break;
2989 case 3:
2990 irq = (s->spcr[0] >> 3) & 1; /* RSYNCERR */
2991 break;
2992 default:
2993 irq = 0;
2994 break;
2997 if (irq)
2998 qemu_irq_pulse(s->rxirq);
3000 switch ((s->spcr[1] >> 4) & 3) { /* XINTM */
3001 case 0:
3002 irq = (s->spcr[1] >> 1) & 1; /* XRDY */
3003 break;
3004 case 3:
3005 irq = (s->spcr[1] >> 3) & 1; /* XSYNCERR */
3006 break;
3007 default:
3008 irq = 0;
3009 break;
3012 if (irq)
3013 qemu_irq_pulse(s->txirq);
3016 static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
3018 if ((s->spcr[0] >> 1) & 1) /* RRDY */
3019 s->spcr[0] |= 1 << 2; /* RFULL */
3020 s->spcr[0] |= 1 << 1; /* RRDY */
3021 qemu_irq_raise(s->rxdrq);
3022 omap_mcbsp_intr_update(s);
3025 static void omap_mcbsp_source_tick(void *opaque)
3027 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3028 static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3030 if (!s->rx_rate)
3031 return;
3032 if (s->rx_req)
3033 printf("%s: Rx FIFO overrun\n", __func__);
3035 s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
3037 omap_mcbsp_rx_newdata(s);
3038 timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
3039 NANOSECONDS_PER_SECOND);
3042 static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3044 if (!s->codec || !s->codec->rts)
3045 omap_mcbsp_source_tick(s);
3046 else if (s->codec->in.len) {
3047 s->rx_req = s->codec->in.len;
3048 omap_mcbsp_rx_newdata(s);
3052 static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3054 timer_del(s->source_timer);
3057 static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3059 s->spcr[0] &= ~(1 << 1); /* RRDY */
3060 qemu_irq_lower(s->rxdrq);
3061 omap_mcbsp_intr_update(s);
3064 static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3066 s->spcr[1] |= 1 << 1; /* XRDY */
3067 qemu_irq_raise(s->txdrq);
3068 omap_mcbsp_intr_update(s);
3071 static void omap_mcbsp_sink_tick(void *opaque)
3073 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3074 static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3076 if (!s->tx_rate)
3077 return;
3078 if (s->tx_req)
3079 printf("%s: Tx FIFO underrun\n", __func__);
3081 s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
3083 omap_mcbsp_tx_newdata(s);
3084 timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
3085 NANOSECONDS_PER_SECOND);
3088 static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3090 if (!s->codec || !s->codec->cts)
3091 omap_mcbsp_sink_tick(s);
3092 else if (s->codec->out.size) {
3093 s->tx_req = s->codec->out.size;
3094 omap_mcbsp_tx_newdata(s);
3098 static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3100 s->spcr[1] &= ~(1 << 1); /* XRDY */
3101 qemu_irq_lower(s->txdrq);
3102 omap_mcbsp_intr_update(s);
3103 if (s->codec && s->codec->cts)
3104 s->codec->tx_swallow(s->codec->opaque);
3107 static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3109 s->tx_req = 0;
3110 omap_mcbsp_tx_done(s);
3111 timer_del(s->sink_timer);
3114 static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3116 int prev_rx_rate, prev_tx_rate;
3117 int rx_rate = 0, tx_rate = 0;
3118 int cpu_rate = 1500000; /* XXX */
3120 /* TODO: check CLKSTP bit */
3121 if (s->spcr[1] & (1 << 6)) { /* GRST */
3122 if (s->spcr[0] & (1 << 0)) { /* RRST */
3123 if ((s->srgr[1] & (1 << 13)) && /* CLKSM */
3124 (s->pcr & (1 << 8))) { /* CLKRM */
3125 if (~s->pcr & (1 << 7)) /* SCLKME */
3126 rx_rate = cpu_rate /
3127 ((s->srgr[0] & 0xff) + 1); /* CLKGDV */
3128 } else
3129 if (s->codec)
3130 rx_rate = s->codec->rx_rate;
3133 if (s->spcr[1] & (1 << 0)) { /* XRST */
3134 if ((s->srgr[1] & (1 << 13)) && /* CLKSM */
3135 (s->pcr & (1 << 9))) { /* CLKXM */
3136 if (~s->pcr & (1 << 7)) /* SCLKME */
3137 tx_rate = cpu_rate /
3138 ((s->srgr[0] & 0xff) + 1); /* CLKGDV */
3139 } else
3140 if (s->codec)
3141 tx_rate = s->codec->tx_rate;
3144 prev_tx_rate = s->tx_rate;
3145 prev_rx_rate = s->rx_rate;
3146 s->tx_rate = tx_rate;
3147 s->rx_rate = rx_rate;
3149 if (s->codec)
3150 s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3152 if (!prev_tx_rate && tx_rate)
3153 omap_mcbsp_tx_start(s);
3154 else if (s->tx_rate && !tx_rate)
3155 omap_mcbsp_tx_stop(s);
3157 if (!prev_rx_rate && rx_rate)
3158 omap_mcbsp_rx_start(s);
3159 else if (prev_tx_rate && !tx_rate)
3160 omap_mcbsp_rx_stop(s);
3163 static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
3164 unsigned size)
3166 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3167 int offset = addr & OMAP_MPUI_REG_MASK;
3168 uint16_t ret;
3170 if (size != 2) {
3171 return omap_badwidth_read16(opaque, addr);
3174 switch (offset) {
3175 case 0x00: /* DRR2 */
3176 if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */
3177 return 0x0000;
3178 /* Fall through. */
3179 case 0x02: /* DRR1 */
3180 if (s->rx_req < 2) {
3181 printf("%s: Rx FIFO underrun\n", __func__);
3182 omap_mcbsp_rx_done(s);
3183 } else {
3184 s->tx_req -= 2;
3185 if (s->codec && s->codec->in.len >= 2) {
3186 ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3187 ret |= s->codec->in.fifo[s->codec->in.start ++];
3188 s->codec->in.len -= 2;
3189 } else
3190 ret = 0x0000;
3191 if (!s->tx_req)
3192 omap_mcbsp_rx_done(s);
3193 return ret;
3195 return 0x0000;
3197 case 0x04: /* DXR2 */
3198 case 0x06: /* DXR1 */
3199 return 0x0000;
3201 case 0x08: /* SPCR2 */
3202 return s->spcr[1];
3203 case 0x0a: /* SPCR1 */
3204 return s->spcr[0];
3205 case 0x0c: /* RCR2 */
3206 return s->rcr[1];
3207 case 0x0e: /* RCR1 */
3208 return s->rcr[0];
3209 case 0x10: /* XCR2 */
3210 return s->xcr[1];
3211 case 0x12: /* XCR1 */
3212 return s->xcr[0];
3213 case 0x14: /* SRGR2 */
3214 return s->srgr[1];
3215 case 0x16: /* SRGR1 */
3216 return s->srgr[0];
3217 case 0x18: /* MCR2 */
3218 return s->mcr[1];
3219 case 0x1a: /* MCR1 */
3220 return s->mcr[0];
3221 case 0x1c: /* RCERA */
3222 return s->rcer[0];
3223 case 0x1e: /* RCERB */
3224 return s->rcer[1];
3225 case 0x20: /* XCERA */
3226 return s->xcer[0];
3227 case 0x22: /* XCERB */
3228 return s->xcer[1];
3229 case 0x24: /* PCR0 */
3230 return s->pcr;
3231 case 0x26: /* RCERC */
3232 return s->rcer[2];
3233 case 0x28: /* RCERD */
3234 return s->rcer[3];
3235 case 0x2a: /* XCERC */
3236 return s->xcer[2];
3237 case 0x2c: /* XCERD */
3238 return s->xcer[3];
3239 case 0x2e: /* RCERE */
3240 return s->rcer[4];
3241 case 0x30: /* RCERF */
3242 return s->rcer[5];
3243 case 0x32: /* XCERE */
3244 return s->xcer[4];
3245 case 0x34: /* XCERF */
3246 return s->xcer[5];
3247 case 0x36: /* RCERG */
3248 return s->rcer[6];
3249 case 0x38: /* RCERH */
3250 return s->rcer[7];
3251 case 0x3a: /* XCERG */
3252 return s->xcer[6];
3253 case 0x3c: /* XCERH */
3254 return s->xcer[7];
3257 OMAP_BAD_REG(addr);
3258 return 0;
3261 static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
3262 uint32_t value)
3264 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3265 int offset = addr & OMAP_MPUI_REG_MASK;
3267 switch (offset) {
3268 case 0x00: /* DRR2 */
3269 case 0x02: /* DRR1 */
3270 OMAP_RO_REG(addr);
3271 return;
3273 case 0x04: /* DXR2 */
3274 if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */
3275 return;
3276 /* Fall through. */
3277 case 0x06: /* DXR1 */
3278 if (s->tx_req > 1) {
3279 s->tx_req -= 2;
3280 if (s->codec && s->codec->cts) {
3281 s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
3282 s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
3284 if (s->tx_req < 2)
3285 omap_mcbsp_tx_done(s);
3286 } else
3287 printf("%s: Tx FIFO overrun\n", __func__);
3288 return;
3290 case 0x08: /* SPCR2 */
3291 s->spcr[1] &= 0x0002;
3292 s->spcr[1] |= 0x03f9 & value;
3293 s->spcr[1] |= 0x0004 & (value << 2); /* XEMPTY := XRST */
3294 if (~value & 1) /* XRST */
3295 s->spcr[1] &= ~6;
3296 omap_mcbsp_req_update(s);
3297 return;
3298 case 0x0a: /* SPCR1 */
3299 s->spcr[0] &= 0x0006;
3300 s->spcr[0] |= 0xf8f9 & value;
3301 if (value & (1 << 15)) /* DLB */
3302 printf("%s: Digital Loopback mode enable attempt\n", __func__);
3303 if (~value & 1) { /* RRST */
3304 s->spcr[0] &= ~6;
3305 s->rx_req = 0;
3306 omap_mcbsp_rx_done(s);
3308 omap_mcbsp_req_update(s);
3309 return;
3311 case 0x0c: /* RCR2 */
3312 s->rcr[1] = value & 0xffff;
3313 return;
3314 case 0x0e: /* RCR1 */
3315 s->rcr[0] = value & 0x7fe0;
3316 return;
3317 case 0x10: /* XCR2 */
3318 s->xcr[1] = value & 0xffff;
3319 return;
3320 case 0x12: /* XCR1 */
3321 s->xcr[0] = value & 0x7fe0;
3322 return;
3323 case 0x14: /* SRGR2 */
3324 s->srgr[1] = value & 0xffff;
3325 omap_mcbsp_req_update(s);
3326 return;
3327 case 0x16: /* SRGR1 */
3328 s->srgr[0] = value & 0xffff;
3329 omap_mcbsp_req_update(s);
3330 return;
3331 case 0x18: /* MCR2 */
3332 s->mcr[1] = value & 0x03e3;
3333 if (value & 3) /* XMCM */
3334 printf("%s: Tx channel selection mode enable attempt\n", __func__);
3335 return;
3336 case 0x1a: /* MCR1 */
3337 s->mcr[0] = value & 0x03e1;
3338 if (value & 1) /* RMCM */
3339 printf("%s: Rx channel selection mode enable attempt\n", __func__);
3340 return;
3341 case 0x1c: /* RCERA */
3342 s->rcer[0] = value & 0xffff;
3343 return;
3344 case 0x1e: /* RCERB */
3345 s->rcer[1] = value & 0xffff;
3346 return;
3347 case 0x20: /* XCERA */
3348 s->xcer[0] = value & 0xffff;
3349 return;
3350 case 0x22: /* XCERB */
3351 s->xcer[1] = value & 0xffff;
3352 return;
3353 case 0x24: /* PCR0 */
3354 s->pcr = value & 0x7faf;
3355 return;
3356 case 0x26: /* RCERC */
3357 s->rcer[2] = value & 0xffff;
3358 return;
3359 case 0x28: /* RCERD */
3360 s->rcer[3] = value & 0xffff;
3361 return;
3362 case 0x2a: /* XCERC */
3363 s->xcer[2] = value & 0xffff;
3364 return;
3365 case 0x2c: /* XCERD */
3366 s->xcer[3] = value & 0xffff;
3367 return;
3368 case 0x2e: /* RCERE */
3369 s->rcer[4] = value & 0xffff;
3370 return;
3371 case 0x30: /* RCERF */
3372 s->rcer[5] = value & 0xffff;
3373 return;
3374 case 0x32: /* XCERE */
3375 s->xcer[4] = value & 0xffff;
3376 return;
3377 case 0x34: /* XCERF */
3378 s->xcer[5] = value & 0xffff;
3379 return;
3380 case 0x36: /* RCERG */
3381 s->rcer[6] = value & 0xffff;
3382 return;
3383 case 0x38: /* RCERH */
3384 s->rcer[7] = value & 0xffff;
3385 return;
3386 case 0x3a: /* XCERG */
3387 s->xcer[6] = value & 0xffff;
3388 return;
3389 case 0x3c: /* XCERH */
3390 s->xcer[7] = value & 0xffff;
3391 return;
3394 OMAP_BAD_REG(addr);
3397 static void omap_mcbsp_writew(void *opaque, hwaddr addr,
3398 uint32_t value)
3400 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3401 int offset = addr & OMAP_MPUI_REG_MASK;
3403 if (offset == 0x04) { /* DXR */
3404 if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */
3405 return;
3406 if (s->tx_req > 3) {
3407 s->tx_req -= 4;
3408 if (s->codec && s->codec->cts) {
3409 s->codec->out.fifo[s->codec->out.len ++] =
3410 (value >> 24) & 0xff;
3411 s->codec->out.fifo[s->codec->out.len ++] =
3412 (value >> 16) & 0xff;
3413 s->codec->out.fifo[s->codec->out.len ++] =
3414 (value >> 8) & 0xff;
3415 s->codec->out.fifo[s->codec->out.len ++] =
3416 (value >> 0) & 0xff;
3418 if (s->tx_req < 4)
3419 omap_mcbsp_tx_done(s);
3420 } else
3421 printf("%s: Tx FIFO overrun\n", __func__);
3422 return;
3425 omap_badwidth_write16(opaque, addr, value);
3428 static void omap_mcbsp_write(void *opaque, hwaddr addr,
3429 uint64_t value, unsigned size)
3431 switch (size) {
3432 case 2:
3433 omap_mcbsp_writeh(opaque, addr, value);
3434 break;
3435 case 4:
3436 omap_mcbsp_writew(opaque, addr, value);
3437 break;
3438 default:
3439 omap_badwidth_write16(opaque, addr, value);
3443 static const MemoryRegionOps omap_mcbsp_ops = {
3444 .read = omap_mcbsp_read,
3445 .write = omap_mcbsp_write,
3446 .endianness = DEVICE_NATIVE_ENDIAN,
3449 static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
3451 memset(&s->spcr, 0, sizeof(s->spcr));
3452 memset(&s->rcr, 0, sizeof(s->rcr));
3453 memset(&s->xcr, 0, sizeof(s->xcr));
3454 s->srgr[0] = 0x0001;
3455 s->srgr[1] = 0x2000;
3456 memset(&s->mcr, 0, sizeof(s->mcr));
3457 memset(&s->pcr, 0, sizeof(s->pcr));
3458 memset(&s->rcer, 0, sizeof(s->rcer));
3459 memset(&s->xcer, 0, sizeof(s->xcer));
3460 s->tx_req = 0;
3461 s->rx_req = 0;
3462 s->tx_rate = 0;
3463 s->rx_rate = 0;
3464 timer_del(s->source_timer);
3465 timer_del(s->sink_timer);
3468 static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
3469 hwaddr base,
3470 qemu_irq txirq, qemu_irq rxirq,
3471 qemu_irq *dma, omap_clk clk)
3473 struct omap_mcbsp_s *s = g_new0(struct omap_mcbsp_s, 1);
3475 s->txirq = txirq;
3476 s->rxirq = rxirq;
3477 s->txdrq = dma[0];
3478 s->rxdrq = dma[1];
3479 s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);
3480 s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);
3481 omap_mcbsp_reset(s);
3483 memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
3484 memory_region_add_subregion(system_memory, base, &s->iomem);
3486 return s;
3489 static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3491 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3493 if (s->rx_rate) {
3494 s->rx_req = s->codec->in.len;
3495 omap_mcbsp_rx_newdata(s);
3499 static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3501 struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3503 if (s->tx_rate) {
3504 s->tx_req = s->codec->out.size;
3505 omap_mcbsp_tx_newdata(s);
3509 void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
3511 s->codec = slave;
3512 slave->rx_swallow = qemu_allocate_irq(omap_mcbsp_i2s_swallow, s, 0);
3513 slave->tx_start = qemu_allocate_irq(omap_mcbsp_i2s_start, s, 0);
3516 /* LED Pulse Generators */
3517 struct omap_lpg_s {
3518 MemoryRegion iomem;
3519 QEMUTimer *tm;
3521 uint8_t control;
3522 uint8_t power;
3523 int64_t on;
3524 int64_t period;
3525 int clk;
3526 int cycle;
3529 static void omap_lpg_tick(void *opaque)
3531 struct omap_lpg_s *s = opaque;
3533 if (s->cycle)
3534 timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on);
3535 else
3536 timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
3538 s->cycle = !s->cycle;
3539 printf("%s: LED is %s\n", __func__, s->cycle ? "on" : "off");
3542 static void omap_lpg_update(struct omap_lpg_s *s)
3544 int64_t on, period = 1, ticks = 1000;
3545 static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
3547 if (~s->control & (1 << 6)) /* LPGRES */
3548 on = 0;
3549 else if (s->control & (1 << 7)) /* PERM_ON */
3550 on = period;
3551 else {
3552 period = muldiv64(ticks, per[s->control & 7], /* PERCTRL */
3553 256 / 32);
3554 on = (s->clk && s->power) ? muldiv64(ticks,
3555 per[(s->control >> 3) & 7], 256) : 0; /* ONCTRL */
3558 timer_del(s->tm);
3559 if (on == period && s->on < s->period)
3560 printf("%s: LED is on\n", __func__);
3561 else if (on == 0 && s->on)
3562 printf("%s: LED is off\n", __func__);
3563 else if (on && (on != s->on || period != s->period)) {
3564 s->cycle = 0;
3565 s->on = on;
3566 s->period = period;
3567 omap_lpg_tick(s);
3568 return;
3571 s->on = on;
3572 s->period = period;
3575 static void omap_lpg_reset(struct omap_lpg_s *s)
3577 s->control = 0x00;
3578 s->power = 0x00;
3579 s->clk = 1;
3580 omap_lpg_update(s);
3583 static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
3584 unsigned size)
3586 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3587 int offset = addr & OMAP_MPUI_REG_MASK;
3589 if (size != 1) {
3590 return omap_badwidth_read8(opaque, addr);
3593 switch (offset) {
3594 case 0x00: /* LCR */
3595 return s->control;
3597 case 0x04: /* PMR */
3598 return s->power;
3601 OMAP_BAD_REG(addr);
3602 return 0;
3605 static void omap_lpg_write(void *opaque, hwaddr addr,
3606 uint64_t value, unsigned size)
3608 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3609 int offset = addr & OMAP_MPUI_REG_MASK;
3611 if (size != 1) {
3612 omap_badwidth_write8(opaque, addr, value);
3613 return;
3616 switch (offset) {
3617 case 0x00: /* LCR */
3618 if (~value & (1 << 6)) /* LPGRES */
3619 omap_lpg_reset(s);
3620 s->control = value & 0xff;
3621 omap_lpg_update(s);
3622 return;
3624 case 0x04: /* PMR */
3625 s->power = value & 0x01;
3626 omap_lpg_update(s);
3627 return;
3629 default:
3630 OMAP_BAD_REG(addr);
3631 return;
3635 static const MemoryRegionOps omap_lpg_ops = {
3636 .read = omap_lpg_read,
3637 .write = omap_lpg_write,
3638 .endianness = DEVICE_NATIVE_ENDIAN,
3641 static void omap_lpg_clk_update(void *opaque, int line, int on)
3643 struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3645 s->clk = on;
3646 omap_lpg_update(s);
3649 static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
3650 hwaddr base, omap_clk clk)
3652 struct omap_lpg_s *s = g_new0(struct omap_lpg_s, 1);
3654 s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s);
3656 omap_lpg_reset(s);
3658 memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800);
3659 memory_region_add_subregion(system_memory, base, &s->iomem);
3661 omap_clk_adduser(clk, qemu_allocate_irq(omap_lpg_clk_update, s, 0));
3663 return s;
3666 /* MPUI Peripheral Bridge configuration */
3667 static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr,
3668 unsigned size)
3670 if (size != 2) {
3671 return omap_badwidth_read16(opaque, addr);
3674 if (addr == OMAP_MPUI_BASE) /* CMR */
3675 return 0xfe4d;
3677 OMAP_BAD_REG(addr);
3678 return 0;
3681 static void omap_mpui_io_write(void *opaque, hwaddr addr,
3682 uint64_t value, unsigned size)
3684 /* FIXME: infinite loop */
3685 omap_badwidth_write16(opaque, addr, value);
3688 static const MemoryRegionOps omap_mpui_io_ops = {
3689 .read = omap_mpui_io_read,
3690 .write = omap_mpui_io_write,
3691 .endianness = DEVICE_NATIVE_ENDIAN,
3694 static void omap_setup_mpui_io(MemoryRegion *system_memory,
3695 struct omap_mpu_state_s *mpu)
3697 memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu,
3698 "omap-mpui-io", 0x7fff);
3699 memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
3700 &mpu->mpui_io_iomem);
3703 /* General chip reset */
3704 static void omap1_mpu_reset(void *opaque)
3706 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3708 omap_dma_reset(mpu->dma);
3709 omap_mpu_timer_reset(mpu->timer[0]);
3710 omap_mpu_timer_reset(mpu->timer[1]);
3711 omap_mpu_timer_reset(mpu->timer[2]);
3712 omap_wd_timer_reset(mpu->wdt);
3713 omap_os_timer_reset(mpu->os_timer);
3714 omap_lcdc_reset(mpu->lcd);
3715 omap_ulpd_pm_reset(mpu);
3716 omap_pin_cfg_reset(mpu);
3717 omap_mpui_reset(mpu);
3718 omap_tipb_bridge_reset(mpu->private_tipb);
3719 omap_tipb_bridge_reset(mpu->public_tipb);
3720 omap_dpll_reset(mpu->dpll[0]);
3721 omap_dpll_reset(mpu->dpll[1]);
3722 omap_dpll_reset(mpu->dpll[2]);
3723 omap_uart_reset(mpu->uart[0]);
3724 omap_uart_reset(mpu->uart[1]);
3725 omap_uart_reset(mpu->uart[2]);
3726 omap_mmc_reset(mpu->mmc);
3727 omap_mpuio_reset(mpu->mpuio);
3728 omap_uwire_reset(mpu->microwire);
3729 omap_pwl_reset(mpu->pwl);
3730 omap_pwt_reset(mpu->pwt);
3731 omap_rtc_reset(mpu->rtc);
3732 omap_mcbsp_reset(mpu->mcbsp1);
3733 omap_mcbsp_reset(mpu->mcbsp2);
3734 omap_mcbsp_reset(mpu->mcbsp3);
3735 omap_lpg_reset(mpu->led[0]);
3736 omap_lpg_reset(mpu->led[1]);
3737 omap_clkm_reset(mpu);
3738 cpu_reset(CPU(mpu->cpu));
3741 static const struct omap_map_s {
3742 hwaddr phys_dsp;
3743 hwaddr phys_mpu;
3744 uint32_t size;
3745 const char *name;
3746 } omap15xx_dsp_mm[] = {
3747 /* Strobe 0 */
3748 { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" }, /* CS0 */
3749 { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" }, /* CS1 */
3750 { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" }, /* CS3 */
3751 { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" }, /* CS4 */
3752 { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" }, /* CS5 */
3753 { 0xe1013000, 0xfffb3000, 0x800, "uWire" }, /* CS6 */
3754 { 0xe1013800, 0xfffb3800, 0x800, "I^2C" }, /* CS7 */
3755 { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" }, /* CS8 */
3756 { 0xe1014800, 0xfffb4800, 0x800, "RTC" }, /* CS9 */
3757 { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" }, /* CS10 */
3758 { 0xe1015800, 0xfffb5800, 0x800, "PWL" }, /* CS11 */
3759 { 0xe1016000, 0xfffb6000, 0x800, "PWT" }, /* CS12 */
3760 { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" }, /* CS14 */
3761 { 0xe1017800, 0xfffb7800, 0x800, "MMC" }, /* CS15 */
3762 { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" }, /* CS18 */
3763 { 0xe1019800, 0xfffb9800, 0x800, "UART3" }, /* CS19 */
3764 { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" }, /* CS25 */
3765 /* Strobe 1 */
3766 { 0xe101e000, 0xfffce000, 0x800, "GPIOs" }, /* CS28 */
3768 { 0 }
3771 static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
3772 const struct omap_map_s *map)
3774 MemoryRegion *io;
3776 for (; map->phys_dsp; map ++) {
3777 io = g_new(MemoryRegion, 1);
3778 memory_region_init_alias(io, NULL, map->name,
3779 system_memory, map->phys_mpu, map->size);
3780 memory_region_add_subregion(system_memory, map->phys_dsp, io);
3784 void omap_mpu_wakeup(void *opaque, int irq, int req)
3786 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3787 CPUState *cpu = CPU(mpu->cpu);
3789 if (cpu->halted) {
3790 cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
3794 static const struct dma_irq_map omap1_dma_irq_map[] = {
3795 { 0, OMAP_INT_DMA_CH0_6 },
3796 { 0, OMAP_INT_DMA_CH1_7 },
3797 { 0, OMAP_INT_DMA_CH2_8 },
3798 { 0, OMAP_INT_DMA_CH3 },
3799 { 0, OMAP_INT_DMA_CH4 },
3800 { 0, OMAP_INT_DMA_CH5 },
3801 { 1, OMAP_INT_1610_DMA_CH6 },
3802 { 1, OMAP_INT_1610_DMA_CH7 },
3803 { 1, OMAP_INT_1610_DMA_CH8 },
3804 { 1, OMAP_INT_1610_DMA_CH9 },
3805 { 1, OMAP_INT_1610_DMA_CH10 },
3806 { 1, OMAP_INT_1610_DMA_CH11 },
3807 { 1, OMAP_INT_1610_DMA_CH12 },
3808 { 1, OMAP_INT_1610_DMA_CH13 },
3809 { 1, OMAP_INT_1610_DMA_CH14 },
3810 { 1, OMAP_INT_1610_DMA_CH15 }
3813 /* DMA ports for OMAP1 */
3814 static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
3815 hwaddr addr)
3817 return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
3820 static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
3821 hwaddr addr)
3823 return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
3824 addr);
3827 static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
3828 hwaddr addr)
3830 return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
3833 static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
3834 hwaddr addr)
3836 return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
3839 static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3840 hwaddr addr)
3842 return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
3845 static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
3846 hwaddr addr)
3848 return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
3851 struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
3852 unsigned long sdram_size,
3853 const char *cpu_type)
3855 int i;
3856 struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
3857 qemu_irq dma_irqs[6];
3858 DriveInfo *dinfo;
3859 SysBusDevice *busdev;
3861 /* Core */
3862 s->mpu_model = omap310;
3863 s->cpu = ARM_CPU(cpu_create(cpu_type));
3864 s->sdram_size = sdram_size;
3865 s->sram_size = OMAP15XX_SRAM_SIZE;
3867 s->wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0);
3869 /* Clocks */
3870 omap_clk_init(s);
3872 /* Memory-mapped stuff */
3873 memory_region_allocate_system_memory(&s->emiff_ram, NULL, "omap1.dram",
3874 s->sdram_size);
3875 memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
3876 memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
3877 &error_fatal);
3878 memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
3880 omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
3882 s->ih[0] = qdev_create(NULL, "omap-intc");
3883 qdev_prop_set_uint32(s->ih[0], "size", 0x100);
3884 qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
3885 qdev_init_nofail(s->ih[0]);
3886 busdev = SYS_BUS_DEVICE(s->ih[0]);
3887 sysbus_connect_irq(busdev, 0,
3888 qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
3889 sysbus_connect_irq(busdev, 1,
3890 qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
3891 sysbus_mmio_map(busdev, 0, 0xfffecb00);
3892 s->ih[1] = qdev_create(NULL, "omap-intc");
3893 qdev_prop_set_uint32(s->ih[1], "size", 0x800);
3894 qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
3895 qdev_init_nofail(s->ih[1]);
3896 busdev = SYS_BUS_DEVICE(s->ih[1]);
3897 sysbus_connect_irq(busdev, 0,
3898 qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
3899 /* The second interrupt controller's FIQ output is not wired up */
3900 sysbus_mmio_map(busdev, 0, 0xfffe0000);
3902 for (i = 0; i < 6; i++) {
3903 dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
3904 omap1_dma_irq_map[i].intr);
3906 s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory,
3907 qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
3908 s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
3910 s->port[emiff ].addr_valid = omap_validate_emiff_addr;
3911 s->port[emifs ].addr_valid = omap_validate_emifs_addr;
3912 s->port[imif ].addr_valid = omap_validate_imif_addr;
3913 s->port[tipb ].addr_valid = omap_validate_tipb_addr;
3914 s->port[local ].addr_valid = omap_validate_local_addr;
3915 s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
3917 /* Register SDRAM and SRAM DMA ports for fast transfers. */
3918 soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram),
3919 OMAP_EMIFF_BASE, s->sdram_size);
3920 soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
3921 OMAP_IMIF_BASE, s->sram_size);
3923 s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
3924 qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
3925 omap_findclk(s, "mputim_ck"));
3926 s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
3927 qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
3928 omap_findclk(s, "mputim_ck"));
3929 s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
3930 qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
3931 omap_findclk(s, "mputim_ck"));
3933 s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
3934 qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
3935 omap_findclk(s, "armwdt_ck"));
3937 s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
3938 qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
3939 omap_findclk(s, "clk32-kHz"));
3941 s->lcd = omap_lcdc_init(system_memory, 0xfffec000,
3942 qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
3943 omap_dma_get_lcdch(s->dma),
3944 omap_findclk(s, "lcd_ck"));
3946 omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
3947 omap_pin_cfg_init(system_memory, 0xfffe1000, s);
3948 omap_id_init(system_memory, s);
3950 omap_mpui_init(system_memory, 0xfffec900, s);
3952 s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
3953 qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
3954 omap_findclk(s, "tipb_ck"));
3955 s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
3956 qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
3957 omap_findclk(s, "tipb_ck"));
3959 omap_tcmi_init(system_memory, 0xfffecc00, s);
3961 s->uart[0] = omap_uart_init(0xfffb0000,
3962 qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
3963 omap_findclk(s, "uart1_ck"),
3964 omap_findclk(s, "uart1_ck"),
3965 s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
3966 "uart1",
3967 serial_hd(0));
3968 s->uart[1] = omap_uart_init(0xfffb0800,
3969 qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
3970 omap_findclk(s, "uart2_ck"),
3971 omap_findclk(s, "uart2_ck"),
3972 s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
3973 "uart2",
3974 serial_hd(0) ? serial_hd(1) : NULL);
3975 s->uart[2] = omap_uart_init(0xfffb9800,
3976 qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
3977 omap_findclk(s, "uart3_ck"),
3978 omap_findclk(s, "uart3_ck"),
3979 s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
3980 "uart3",
3981 serial_hd(0) && serial_hd(1) ? serial_hd(2) : NULL);
3983 s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
3984 omap_findclk(s, "dpll1"));
3985 s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000,
3986 omap_findclk(s, "dpll2"));
3987 s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100,
3988 omap_findclk(s, "dpll3"));
3990 dinfo = drive_get(IF_SD, 0, 0);
3991 if (!dinfo && !qtest_enabled()) {
3992 warn_report("missing SecureDigital device");
3994 s->mmc = omap_mmc_init(0xfffb7800, system_memory,
3995 dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
3996 qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
3997 &s->drq[OMAP_DMA_MMC_TX],
3998 omap_findclk(s, "mmc_ck"));
4000 s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
4001 qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD),
4002 qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO),
4003 s->wakeup, omap_findclk(s, "clk32-kHz"));
4005 s->gpio = qdev_create(NULL, "omap-gpio");
4006 qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
4007 qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
4008 qdev_init_nofail(s->gpio);
4009 sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio), 0,
4010 qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
4011 sysbus_mmio_map(SYS_BUS_DEVICE(s->gpio), 0, 0xfffce000);
4013 s->microwire = omap_uwire_init(system_memory, 0xfffb3000,
4014 qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX),
4015 qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX),
4016 s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4018 s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
4019 omap_findclk(s, "armxor_ck"));
4020 s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
4021 omap_findclk(s, "armxor_ck"));
4023 s->i2c[0] = qdev_create(NULL, "omap_i2c");
4024 qdev_prop_set_uint8(s->i2c[0], "revision", 0x11);
4025 qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "mpuper_ck"));
4026 qdev_init_nofail(s->i2c[0]);
4027 busdev = SYS_BUS_DEVICE(s->i2c[0]);
4028 sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C));
4029 sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]);
4030 sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]);
4031 sysbus_mmio_map(busdev, 0, 0xfffb3800);
4033 s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
4034 qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
4035 qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
4036 omap_findclk(s, "clk32-kHz"));
4038 s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
4039 qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
4040 qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
4041 &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4042 s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
4043 qdev_get_gpio_in(s->ih[0],
4044 OMAP_INT_310_McBSP2_TX),
4045 qdev_get_gpio_in(s->ih[0],
4046 OMAP_INT_310_McBSP2_RX),
4047 &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4048 s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
4049 qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
4050 qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
4051 &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4053 s->led[0] = omap_lpg_init(system_memory,
4054 0xfffbd000, omap_findclk(s, "clk32-kHz"));
4055 s->led[1] = omap_lpg_init(system_memory,
4056 0xfffbd800, omap_findclk(s, "clk32-kHz"));
4058 /* Register mappings not currenlty implemented:
4059 * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310)
4060 * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310)
4061 * USB W2FC fffb4000 - fffb47ff
4062 * Camera Interface fffb6800 - fffb6fff
4063 * USB Host fffba000 - fffba7ff
4064 * FAC fffba800 - fffbafff
4065 * HDQ/1-Wire fffbc000 - fffbc7ff
4066 * TIPB switches fffbc800 - fffbcfff
4067 * Mailbox fffcf000 - fffcf7ff
4068 * Local bus IF fffec100 - fffec1ff
4069 * Local bus MMU fffec200 - fffec2ff
4070 * DSP MMU fffed200 - fffed2ff
4073 omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
4074 omap_setup_mpui_io(system_memory, s);
4076 qemu_register_reset(omap1_mpu_reset, s);
4078 return s;