xref: /qemu/hw/arm/omap1.c (revision 67cc32eb)
1 /*
2  * TI OMAP processors emulation.
3  *
4  * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 or
9  * (at your option) version 3 of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "hw/boards.h"
21 #include "hw/hw.h"
22 #include "hw/arm/arm.h"
23 #include "hw/arm/omap.h"
24 #include "sysemu/sysemu.h"
25 #include "hw/arm/soc_dma.h"
26 #include "sysemu/block-backend.h"
27 #include "sysemu/blockdev.h"
28 #include "qemu/range.h"
29 #include "hw/sysbus.h"
30 
31 /* Should signal the TCMI/GPMC */
32 uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
33 {
34     uint8_t ret;
35 
36     OMAP_8B_REG(addr);
37     cpu_physical_memory_read(addr, &ret, 1);
38     return ret;
39 }
40 
41 void omap_badwidth_write8(void *opaque, hwaddr addr,
42                 uint32_t value)
43 {
44     uint8_t val8 = value;
45 
46     OMAP_8B_REG(addr);
47     cpu_physical_memory_write(addr, &val8, 1);
48 }
49 
50 uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
51 {
52     uint16_t ret;
53 
54     OMAP_16B_REG(addr);
55     cpu_physical_memory_read(addr, &ret, 2);
56     return ret;
57 }
58 
59 void omap_badwidth_write16(void *opaque, hwaddr addr,
60                 uint32_t value)
61 {
62     uint16_t val16 = value;
63 
64     OMAP_16B_REG(addr);
65     cpu_physical_memory_write(addr, &val16, 2);
66 }
67 
68 uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
69 {
70     uint32_t ret;
71 
72     OMAP_32B_REG(addr);
73     cpu_physical_memory_read(addr, &ret, 4);
74     return ret;
75 }
76 
77 void omap_badwidth_write32(void *opaque, hwaddr addr,
78                 uint32_t value)
79 {
80     OMAP_32B_REG(addr);
81     cpu_physical_memory_write(addr, &value, 4);
82 }
83 
84 /* MPU OS timers */
85 struct omap_mpu_timer_s {
86     MemoryRegion iomem;
87     qemu_irq irq;
88     omap_clk clk;
89     uint32_t val;
90     int64_t time;
91     QEMUTimer *timer;
92     QEMUBH *tick;
93     int64_t rate;
94     int it_ena;
95 
96     int enable;
97     int ptv;
98     int ar;
99     int st;
100     uint32_t reset_val;
101 };
102 
103 static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
104 {
105     uint64_t distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
106 
107     if (timer->st && timer->enable && timer->rate)
108         return timer->val - muldiv64(distance >> (timer->ptv + 1),
109                                      timer->rate, get_ticks_per_sec());
110     else
111         return timer->val;
112 }
113 
114 static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
115 {
116     timer->val = omap_timer_read(timer);
117     timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
118 }
119 
120 static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
121 {
122     int64_t expires;
123 
124     if (timer->enable && timer->st && timer->rate) {
125         timer->val = timer->reset_val;	/* Should skip this on clk enable */
126         expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
127                            get_ticks_per_sec(), timer->rate);
128 
129         /* If timer expiry would be sooner than in about 1 ms and
130          * auto-reload isn't set, then fire immediately.  This is a hack
131          * to make systems like PalmOS run in acceptable time.  PalmOS
132          * sets the interval to a very low value and polls the status bit
133          * in a busy loop when it wants to sleep just a couple of CPU
134          * ticks.  */
135         if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
136             timer_mod(timer->timer, timer->time + expires);
137         else
138             qemu_bh_schedule(timer->tick);
139     } else
140         timer_del(timer->timer);
141 }
142 
143 static void omap_timer_fire(void *opaque)
144 {
145     struct omap_mpu_timer_s *timer = opaque;
146 
147     if (!timer->ar) {
148         timer->val = 0;
149         timer->st = 0;
150     }
151 
152     if (timer->it_ena)
153         /* Edge-triggered irq */
154         qemu_irq_pulse(timer->irq);
155 }
156 
157 static void omap_timer_tick(void *opaque)
158 {
159     struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
160 
161     omap_timer_sync(timer);
162     omap_timer_fire(timer);
163     omap_timer_update(timer);
164 }
165 
166 static void omap_timer_clk_update(void *opaque, int line, int on)
167 {
168     struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
169 
170     omap_timer_sync(timer);
171     timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
172     omap_timer_update(timer);
173 }
174 
175 static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
176 {
177     omap_clk_adduser(timer->clk,
178                     qemu_allocate_irq(omap_timer_clk_update, timer, 0));
179     timer->rate = omap_clk_getrate(timer->clk);
180 }
181 
182 static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
183                                     unsigned size)
184 {
185     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
186 
187     if (size != 4) {
188         return omap_badwidth_read32(opaque, addr);
189     }
190 
191     switch (addr) {
192     case 0x00:	/* CNTL_TIMER */
193         return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
194 
195     case 0x04:	/* LOAD_TIM */
196         break;
197 
198     case 0x08:	/* READ_TIM */
199         return omap_timer_read(s);
200     }
201 
202     OMAP_BAD_REG(addr);
203     return 0;
204 }
205 
206 static void omap_mpu_timer_write(void *opaque, hwaddr addr,
207                                  uint64_t value, unsigned size)
208 {
209     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
210 
211     if (size != 4) {
212         omap_badwidth_write32(opaque, addr, value);
213         return;
214     }
215 
216     switch (addr) {
217     case 0x00:	/* CNTL_TIMER */
218         omap_timer_sync(s);
219         s->enable = (value >> 5) & 1;
220         s->ptv = (value >> 2) & 7;
221         s->ar = (value >> 1) & 1;
222         s->st = value & 1;
223         omap_timer_update(s);
224         return;
225 
226     case 0x04:	/* LOAD_TIM */
227         s->reset_val = value;
228         return;
229 
230     case 0x08:	/* READ_TIM */
231         OMAP_RO_REG(addr);
232         break;
233 
234     default:
235         OMAP_BAD_REG(addr);
236     }
237 }
238 
239 static const MemoryRegionOps omap_mpu_timer_ops = {
240     .read = omap_mpu_timer_read,
241     .write = omap_mpu_timer_write,
242     .endianness = DEVICE_LITTLE_ENDIAN,
243 };
244 
245 static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
246 {
247     timer_del(s->timer);
248     s->enable = 0;
249     s->reset_val = 31337;
250     s->val = 0;
251     s->ptv = 0;
252     s->ar = 0;
253     s->st = 0;
254     s->it_ena = 1;
255 }
256 
257 static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
258                 hwaddr base,
259                 qemu_irq irq, omap_clk clk)
260 {
261     struct omap_mpu_timer_s *s = g_new0(struct omap_mpu_timer_s, 1);
262 
263     s->irq = irq;
264     s->clk = clk;
265     s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, s);
266     s->tick = qemu_bh_new(omap_timer_fire, s);
267     omap_mpu_timer_reset(s);
268     omap_timer_clk_setup(s);
269 
270     memory_region_init_io(&s->iomem, NULL, &omap_mpu_timer_ops, s,
271                           "omap-mpu-timer", 0x100);
272 
273     memory_region_add_subregion(system_memory, base, &s->iomem);
274 
275     return s;
276 }
277 
278 /* Watchdog timer */
279 struct omap_watchdog_timer_s {
280     struct omap_mpu_timer_s timer;
281     MemoryRegion iomem;
282     uint8_t last_wr;
283     int mode;
284     int free;
285     int reset;
286 };
287 
288 static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
289                                    unsigned size)
290 {
291     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
292 
293     if (size != 2) {
294         return omap_badwidth_read16(opaque, addr);
295     }
296 
297     switch (addr) {
298     case 0x00:	/* CNTL_TIMER */
299         return (s->timer.ptv << 9) | (s->timer.ar << 8) |
300                 (s->timer.st << 7) | (s->free << 1);
301 
302     case 0x04:	/* READ_TIMER */
303         return omap_timer_read(&s->timer);
304 
305     case 0x08:	/* TIMER_MODE */
306         return s->mode << 15;
307     }
308 
309     OMAP_BAD_REG(addr);
310     return 0;
311 }
312 
313 static void omap_wd_timer_write(void *opaque, hwaddr addr,
314                                 uint64_t value, unsigned size)
315 {
316     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
317 
318     if (size != 2) {
319         omap_badwidth_write16(opaque, addr, value);
320         return;
321     }
322 
323     switch (addr) {
324     case 0x00:	/* CNTL_TIMER */
325         omap_timer_sync(&s->timer);
326         s->timer.ptv = (value >> 9) & 7;
327         s->timer.ar = (value >> 8) & 1;
328         s->timer.st = (value >> 7) & 1;
329         s->free = (value >> 1) & 1;
330         omap_timer_update(&s->timer);
331         break;
332 
333     case 0x04:	/* LOAD_TIMER */
334         s->timer.reset_val = value & 0xffff;
335         break;
336 
337     case 0x08:	/* TIMER_MODE */
338         if (!s->mode && ((value >> 15) & 1))
339             omap_clk_get(s->timer.clk);
340         s->mode |= (value >> 15) & 1;
341         if (s->last_wr == 0xf5) {
342             if ((value & 0xff) == 0xa0) {
343                 if (s->mode) {
344                     s->mode = 0;
345                     omap_clk_put(s->timer.clk);
346                 }
347             } else {
348                 /* XXX: on T|E hardware somehow this has no effect,
349                  * on Zire 71 it works as specified.  */
350                 s->reset = 1;
351                 qemu_system_reset_request();
352             }
353         }
354         s->last_wr = value & 0xff;
355         break;
356 
357     default:
358         OMAP_BAD_REG(addr);
359     }
360 }
361 
362 static const MemoryRegionOps omap_wd_timer_ops = {
363     .read = omap_wd_timer_read,
364     .write = omap_wd_timer_write,
365     .endianness = DEVICE_NATIVE_ENDIAN,
366 };
367 
368 static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
369 {
370     timer_del(s->timer.timer);
371     if (!s->mode)
372         omap_clk_get(s->timer.clk);
373     s->mode = 1;
374     s->free = 1;
375     s->reset = 0;
376     s->timer.enable = 1;
377     s->timer.it_ena = 1;
378     s->timer.reset_val = 0xffff;
379     s->timer.val = 0;
380     s->timer.st = 0;
381     s->timer.ptv = 0;
382     s->timer.ar = 0;
383     omap_timer_update(&s->timer);
384 }
385 
386 static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
387                 hwaddr base,
388                 qemu_irq irq, omap_clk clk)
389 {
390     struct omap_watchdog_timer_s *s = g_new0(struct omap_watchdog_timer_s, 1);
391 
392     s->timer.irq = irq;
393     s->timer.clk = clk;
394     s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
395     omap_wd_timer_reset(s);
396     omap_timer_clk_setup(&s->timer);
397 
398     memory_region_init_io(&s->iomem, NULL, &omap_wd_timer_ops, s,
399                           "omap-wd-timer", 0x100);
400     memory_region_add_subregion(memory, base, &s->iomem);
401 
402     return s;
403 }
404 
405 /* 32-kHz timer */
406 struct omap_32khz_timer_s {
407     struct omap_mpu_timer_s timer;
408     MemoryRegion iomem;
409 };
410 
411 static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
412                                    unsigned size)
413 {
414     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
415     int offset = addr & OMAP_MPUI_REG_MASK;
416 
417     if (size != 4) {
418         return omap_badwidth_read32(opaque, addr);
419     }
420 
421     switch (offset) {
422     case 0x00:	/* TVR */
423         return s->timer.reset_val;
424 
425     case 0x04:	/* TCR */
426         return omap_timer_read(&s->timer);
427 
428     case 0x08:	/* CR */
429         return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
430 
431     default:
432         break;
433     }
434     OMAP_BAD_REG(addr);
435     return 0;
436 }
437 
438 static void omap_os_timer_write(void *opaque, hwaddr addr,
439                                 uint64_t value, unsigned size)
440 {
441     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
442     int offset = addr & OMAP_MPUI_REG_MASK;
443 
444     if (size != 4) {
445         omap_badwidth_write32(opaque, addr, value);
446         return;
447     }
448 
449     switch (offset) {
450     case 0x00:	/* TVR */
451         s->timer.reset_val = value & 0x00ffffff;
452         break;
453 
454     case 0x04:	/* TCR */
455         OMAP_RO_REG(addr);
456         break;
457 
458     case 0x08:	/* CR */
459         s->timer.ar = (value >> 3) & 1;
460         s->timer.it_ena = (value >> 2) & 1;
461         if (s->timer.st != (value & 1) || (value & 2)) {
462             omap_timer_sync(&s->timer);
463             s->timer.enable = value & 1;
464             s->timer.st = value & 1;
465             omap_timer_update(&s->timer);
466         }
467         break;
468 
469     default:
470         OMAP_BAD_REG(addr);
471     }
472 }
473 
474 static const MemoryRegionOps omap_os_timer_ops = {
475     .read = omap_os_timer_read,
476     .write = omap_os_timer_write,
477     .endianness = DEVICE_NATIVE_ENDIAN,
478 };
479 
480 static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
481 {
482     timer_del(s->timer.timer);
483     s->timer.enable = 0;
484     s->timer.it_ena = 0;
485     s->timer.reset_val = 0x00ffffff;
486     s->timer.val = 0;
487     s->timer.st = 0;
488     s->timer.ptv = 0;
489     s->timer.ar = 1;
490 }
491 
492 static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
493                 hwaddr base,
494                 qemu_irq irq, omap_clk clk)
495 {
496     struct omap_32khz_timer_s *s = g_new0(struct omap_32khz_timer_s, 1);
497 
498     s->timer.irq = irq;
499     s->timer.clk = clk;
500     s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
501     omap_os_timer_reset(s);
502     omap_timer_clk_setup(&s->timer);
503 
504     memory_region_init_io(&s->iomem, NULL, &omap_os_timer_ops, s,
505                           "omap-os-timer", 0x800);
506     memory_region_add_subregion(memory, base, &s->iomem);
507 
508     return s;
509 }
510 
511 /* Ultra Low-Power Device Module */
512 static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
513                                   unsigned size)
514 {
515     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
516     uint16_t ret;
517 
518     if (size != 2) {
519         return omap_badwidth_read16(opaque, addr);
520     }
521 
522     switch (addr) {
523     case 0x14:	/* IT_STATUS */
524         ret = s->ulpd_pm_regs[addr >> 2];
525         s->ulpd_pm_regs[addr >> 2] = 0;
526         qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
527         return ret;
528 
529     case 0x18:	/* Reserved */
530     case 0x1c:	/* Reserved */
531     case 0x20:	/* Reserved */
532     case 0x28:	/* Reserved */
533     case 0x2c:	/* Reserved */
534         OMAP_BAD_REG(addr);
535         /* fall through */
536     case 0x00:	/* COUNTER_32_LSB */
537     case 0x04:	/* COUNTER_32_MSB */
538     case 0x08:	/* COUNTER_HIGH_FREQ_LSB */
539     case 0x0c:	/* COUNTER_HIGH_FREQ_MSB */
540     case 0x10:	/* GAUGING_CTRL */
541     case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */
542     case 0x30:	/* CLOCK_CTRL */
543     case 0x34:	/* SOFT_REQ */
544     case 0x38:	/* COUNTER_32_FIQ */
545     case 0x3c:	/* DPLL_CTRL */
546     case 0x40:	/* STATUS_REQ */
547         /* XXX: check clk::usecount state for every clock */
548     case 0x48:	/* LOCL_TIME */
549     case 0x4c:	/* APLL_CTRL */
550     case 0x50:	/* POWER_CTRL */
551         return s->ulpd_pm_regs[addr >> 2];
552     }
553 
554     OMAP_BAD_REG(addr);
555     return 0;
556 }
557 
558 static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
559                 uint16_t diff, uint16_t value)
560 {
561     if (diff & (1 << 4))				/* USB_MCLK_EN */
562         omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
563     if (diff & (1 << 5))				/* DIS_USB_PVCI_CLK */
564         omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
565 }
566 
567 static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
568                 uint16_t diff, uint16_t value)
569 {
570     if (diff & (1 << 0))				/* SOFT_DPLL_REQ */
571         omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
572     if (diff & (1 << 1))				/* SOFT_COM_REQ */
573         omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
574     if (diff & (1 << 2))				/* SOFT_SDW_REQ */
575         omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
576     if (diff & (1 << 3))				/* SOFT_USB_REQ */
577         omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
578 }
579 
580 static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
581                                uint64_t value, unsigned size)
582 {
583     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
584     int64_t now, ticks;
585     int div, mult;
586     static const int bypass_div[4] = { 1, 2, 4, 4 };
587     uint16_t diff;
588 
589     if (size != 2) {
590         omap_badwidth_write16(opaque, addr, value);
591         return;
592     }
593 
594     switch (addr) {
595     case 0x00:	/* COUNTER_32_LSB */
596     case 0x04:	/* COUNTER_32_MSB */
597     case 0x08:	/* COUNTER_HIGH_FREQ_LSB */
598     case 0x0c:	/* COUNTER_HIGH_FREQ_MSB */
599     case 0x14:	/* IT_STATUS */
600     case 0x40:	/* STATUS_REQ */
601         OMAP_RO_REG(addr);
602         break;
603 
604     case 0x10:	/* GAUGING_CTRL */
605         /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
606         if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
607             now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
608 
609             if (value & 1)
610                 s->ulpd_gauge_start = now;
611             else {
612                 now -= s->ulpd_gauge_start;
613 
614                 /* 32-kHz ticks */
615                 ticks = muldiv64(now, 32768, get_ticks_per_sec());
616                 s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
617                 s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
618                 if (ticks >> 32)	/* OVERFLOW_32K */
619                     s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
620 
621                 /* High frequency ticks */
622                 ticks = muldiv64(now, 12000000, get_ticks_per_sec());
623                 s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
624                 s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
625                 if (ticks >> 32)	/* OVERFLOW_HI_FREQ */
626                     s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
627 
628                 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;	/* IT_GAUGING */
629                 qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
630             }
631         }
632         s->ulpd_pm_regs[addr >> 2] = value;
633         break;
634 
635     case 0x18:	/* Reserved */
636     case 0x1c:	/* Reserved */
637     case 0x20:	/* Reserved */
638     case 0x28:	/* Reserved */
639     case 0x2c:	/* Reserved */
640         OMAP_BAD_REG(addr);
641         /* fall through */
642     case 0x24:	/* SETUP_ANALOG_CELL3_ULPD1 */
643     case 0x38:	/* COUNTER_32_FIQ */
644     case 0x48:	/* LOCL_TIME */
645     case 0x50:	/* POWER_CTRL */
646         s->ulpd_pm_regs[addr >> 2] = value;
647         break;
648 
649     case 0x30:	/* CLOCK_CTRL */
650         diff = s->ulpd_pm_regs[addr >> 2] ^ value;
651         s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
652         omap_ulpd_clk_update(s, diff, value);
653         break;
654 
655     case 0x34:	/* SOFT_REQ */
656         diff = s->ulpd_pm_regs[addr >> 2] ^ value;
657         s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
658         omap_ulpd_req_update(s, diff, value);
659         break;
660 
661     case 0x3c:	/* DPLL_CTRL */
662         /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
663          * omitted altogether, probably a typo.  */
664         /* This register has identical semantics with DPLL(1:3) control
665          * registers, see omap_dpll_write() */
666         diff = s->ulpd_pm_regs[addr >> 2] & value;
667         s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
668         if (diff & (0x3ff << 2)) {
669             if (value & (1 << 4)) {			/* PLL_ENABLE */
670                 div = ((value >> 5) & 3) + 1;		/* PLL_DIV */
671                 mult = MIN((value >> 7) & 0x1f, 1);	/* PLL_MULT */
672             } else {
673                 div = bypass_div[((value >> 2) & 3)];	/* BYPASS_DIV */
674                 mult = 1;
675             }
676             omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
677         }
678 
679         /* Enter the desired mode.  */
680         s->ulpd_pm_regs[addr >> 2] =
681                 (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
682                 ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
683 
684         /* Act as if the lock is restored.  */
685         s->ulpd_pm_regs[addr >> 2] |= 2;
686         break;
687 
688     case 0x4c:	/* APLL_CTRL */
689         diff = s->ulpd_pm_regs[addr >> 2] & value;
690         s->ulpd_pm_regs[addr >> 2] = value & 0xf;
691         if (diff & (1 << 0))				/* APLL_NDPLL_SWITCH */
692             omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
693                                     (value & (1 << 0)) ? "apll" : "dpll4"));
694         break;
695 
696     default:
697         OMAP_BAD_REG(addr);
698     }
699 }
700 
701 static const MemoryRegionOps omap_ulpd_pm_ops = {
702     .read = omap_ulpd_pm_read,
703     .write = omap_ulpd_pm_write,
704     .endianness = DEVICE_NATIVE_ENDIAN,
705 };
706 
707 static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
708 {
709     mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
710     mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
711     mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
712     mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
713     mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
714     mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
715     mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
716     mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
717     mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
718     mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
719     mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
720     omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
721     mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
722     omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
723     mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
724     mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
725     mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
726     mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
727     mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
728     mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
729     mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
730     omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
731     omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
732 }
733 
734 static void omap_ulpd_pm_init(MemoryRegion *system_memory,
735                 hwaddr base,
736                 struct omap_mpu_state_s *mpu)
737 {
738     memory_region_init_io(&mpu->ulpd_pm_iomem, NULL, &omap_ulpd_pm_ops, mpu,
739                           "omap-ulpd-pm", 0x800);
740     memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
741     omap_ulpd_pm_reset(mpu);
742 }
743 
744 /* OMAP Pin Configuration */
745 static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
746                                   unsigned size)
747 {
748     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
749 
750     if (size != 4) {
751         return omap_badwidth_read32(opaque, addr);
752     }
753 
754     switch (addr) {
755     case 0x00:	/* FUNC_MUX_CTRL_0 */
756     case 0x04:	/* FUNC_MUX_CTRL_1 */
757     case 0x08:	/* FUNC_MUX_CTRL_2 */
758         return s->func_mux_ctrl[addr >> 2];
759 
760     case 0x0c:	/* COMP_MODE_CTRL_0 */
761         return s->comp_mode_ctrl[0];
762 
763     case 0x10:	/* FUNC_MUX_CTRL_3 */
764     case 0x14:	/* FUNC_MUX_CTRL_4 */
765     case 0x18:	/* FUNC_MUX_CTRL_5 */
766     case 0x1c:	/* FUNC_MUX_CTRL_6 */
767     case 0x20:	/* FUNC_MUX_CTRL_7 */
768     case 0x24:	/* FUNC_MUX_CTRL_8 */
769     case 0x28:	/* FUNC_MUX_CTRL_9 */
770     case 0x2c:	/* FUNC_MUX_CTRL_A */
771     case 0x30:	/* FUNC_MUX_CTRL_B */
772     case 0x34:	/* FUNC_MUX_CTRL_C */
773     case 0x38:	/* FUNC_MUX_CTRL_D */
774         return s->func_mux_ctrl[(addr >> 2) - 1];
775 
776     case 0x40:	/* PULL_DWN_CTRL_0 */
777     case 0x44:	/* PULL_DWN_CTRL_1 */
778     case 0x48:	/* PULL_DWN_CTRL_2 */
779     case 0x4c:	/* PULL_DWN_CTRL_3 */
780         return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
781 
782     case 0x50:	/* GATE_INH_CTRL_0 */
783         return s->gate_inh_ctrl[0];
784 
785     case 0x60:	/* VOLTAGE_CTRL_0 */
786         return s->voltage_ctrl[0];
787 
788     case 0x70:	/* TEST_DBG_CTRL_0 */
789         return s->test_dbg_ctrl[0];
790 
791     case 0x80:	/* MOD_CONF_CTRL_0 */
792         return s->mod_conf_ctrl[0];
793     }
794 
795     OMAP_BAD_REG(addr);
796     return 0;
797 }
798 
799 static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
800                 uint32_t diff, uint32_t value)
801 {
802     if (s->compat1509) {
803         if (diff & (1 << 9))			/* BLUETOOTH */
804             omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
805                             (~value >> 9) & 1);
806         if (diff & (1 << 7))			/* USB.CLKO */
807             omap_clk_onoff(omap_findclk(s, "usb.clko"),
808                             (value >> 7) & 1);
809     }
810 }
811 
812 static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
813                 uint32_t diff, uint32_t value)
814 {
815     if (s->compat1509) {
816         if (diff & (1U << 31)) {
817             /* MCBSP3_CLK_HIZ_DI */
818             omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"), (value >> 31) & 1);
819         }
820         if (diff & (1 << 1)) {
821             /* CLK32K */
822             omap_clk_onoff(omap_findclk(s, "clk32k_out"), (~value >> 1) & 1);
823         }
824     }
825 }
826 
827 static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
828                 uint32_t diff, uint32_t value)
829 {
830     if (diff & (1U << 31)) {
831         /* CONF_MOD_UART3_CLK_MODE_R */
832         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
833                           omap_findclk(s, ((value >> 31) & 1) ?
834                                        "ck_48m" : "armper_ck"));
835     }
836     if (diff & (1 << 30))			/* CONF_MOD_UART2_CLK_MODE_R */
837          omap_clk_reparent(omap_findclk(s, "uart2_ck"),
838                          omap_findclk(s, ((value >> 30) & 1) ?
839                                  "ck_48m" : "armper_ck"));
840     if (diff & (1 << 29))			/* CONF_MOD_UART1_CLK_MODE_R */
841          omap_clk_reparent(omap_findclk(s, "uart1_ck"),
842                          omap_findclk(s, ((value >> 29) & 1) ?
843                                  "ck_48m" : "armper_ck"));
844     if (diff & (1 << 23))			/* CONF_MOD_MMC_SD_CLK_REQ_R */
845          omap_clk_reparent(omap_findclk(s, "mmc_ck"),
846                          omap_findclk(s, ((value >> 23) & 1) ?
847                                  "ck_48m" : "armper_ck"));
848     if (diff & (1 << 12))			/* CONF_MOD_COM_MCLK_12_48_S */
849          omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
850                          omap_findclk(s, ((value >> 12) & 1) ?
851                                  "ck_48m" : "armper_ck"));
852     if (diff & (1 << 9))			/* CONF_MOD_USB_HOST_HHC_UHO */
853          omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
854 }
855 
856 static void omap_pin_cfg_write(void *opaque, hwaddr addr,
857                                uint64_t value, unsigned size)
858 {
859     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
860     uint32_t diff;
861 
862     if (size != 4) {
863         omap_badwidth_write32(opaque, addr, value);
864         return;
865     }
866 
867     switch (addr) {
868     case 0x00:	/* FUNC_MUX_CTRL_0 */
869         diff = s->func_mux_ctrl[addr >> 2] ^ value;
870         s->func_mux_ctrl[addr >> 2] = value;
871         omap_pin_funcmux0_update(s, diff, value);
872         return;
873 
874     case 0x04:	/* FUNC_MUX_CTRL_1 */
875         diff = s->func_mux_ctrl[addr >> 2] ^ value;
876         s->func_mux_ctrl[addr >> 2] = value;
877         omap_pin_funcmux1_update(s, diff, value);
878         return;
879 
880     case 0x08:	/* FUNC_MUX_CTRL_2 */
881         s->func_mux_ctrl[addr >> 2] = value;
882         return;
883 
884     case 0x0c:	/* COMP_MODE_CTRL_0 */
885         s->comp_mode_ctrl[0] = value;
886         s->compat1509 = (value != 0x0000eaef);
887         omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
888         omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
889         return;
890 
891     case 0x10:	/* FUNC_MUX_CTRL_3 */
892     case 0x14:	/* FUNC_MUX_CTRL_4 */
893     case 0x18:	/* FUNC_MUX_CTRL_5 */
894     case 0x1c:	/* FUNC_MUX_CTRL_6 */
895     case 0x20:	/* FUNC_MUX_CTRL_7 */
896     case 0x24:	/* FUNC_MUX_CTRL_8 */
897     case 0x28:	/* FUNC_MUX_CTRL_9 */
898     case 0x2c:	/* FUNC_MUX_CTRL_A */
899     case 0x30:	/* FUNC_MUX_CTRL_B */
900     case 0x34:	/* FUNC_MUX_CTRL_C */
901     case 0x38:	/* FUNC_MUX_CTRL_D */
902         s->func_mux_ctrl[(addr >> 2) - 1] = value;
903         return;
904 
905     case 0x40:	/* PULL_DWN_CTRL_0 */
906     case 0x44:	/* PULL_DWN_CTRL_1 */
907     case 0x48:	/* PULL_DWN_CTRL_2 */
908     case 0x4c:	/* PULL_DWN_CTRL_3 */
909         s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
910         return;
911 
912     case 0x50:	/* GATE_INH_CTRL_0 */
913         s->gate_inh_ctrl[0] = value;
914         return;
915 
916     case 0x60:	/* VOLTAGE_CTRL_0 */
917         s->voltage_ctrl[0] = value;
918         return;
919 
920     case 0x70:	/* TEST_DBG_CTRL_0 */
921         s->test_dbg_ctrl[0] = value;
922         return;
923 
924     case 0x80:	/* MOD_CONF_CTRL_0 */
925         diff = s->mod_conf_ctrl[0] ^ value;
926         s->mod_conf_ctrl[0] = value;
927         omap_pin_modconf1_update(s, diff, value);
928         return;
929 
930     default:
931         OMAP_BAD_REG(addr);
932     }
933 }
934 
935 static const MemoryRegionOps omap_pin_cfg_ops = {
936     .read = omap_pin_cfg_read,
937     .write = omap_pin_cfg_write,
938     .endianness = DEVICE_NATIVE_ENDIAN,
939 };
940 
941 static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
942 {
943     /* Start in Compatibility Mode.  */
944     mpu->compat1509 = 1;
945     omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
946     omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
947     omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
948     memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
949     memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
950     memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
951     memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
952     memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
953     memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
954     memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
955 }
956 
957 static void omap_pin_cfg_init(MemoryRegion *system_memory,
958                 hwaddr base,
959                 struct omap_mpu_state_s *mpu)
960 {
961     memory_region_init_io(&mpu->pin_cfg_iomem, NULL, &omap_pin_cfg_ops, mpu,
962                           "omap-pin-cfg", 0x800);
963     memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
964     omap_pin_cfg_reset(mpu);
965 }
966 
967 /* Device Identification, Die Identification */
968 static uint64_t omap_id_read(void *opaque, hwaddr addr,
969                              unsigned size)
970 {
971     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
972 
973     if (size != 4) {
974         return omap_badwidth_read32(opaque, addr);
975     }
976 
977     switch (addr) {
978     case 0xfffe1800:	/* DIE_ID_LSB */
979         return 0xc9581f0e;
980     case 0xfffe1804:	/* DIE_ID_MSB */
981         return 0xa8858bfa;
982 
983     case 0xfffe2000:	/* PRODUCT_ID_LSB */
984         return 0x00aaaafc;
985     case 0xfffe2004:	/* PRODUCT_ID_MSB */
986         return 0xcafeb574;
987 
988     case 0xfffed400:	/* JTAG_ID_LSB */
989         switch (s->mpu_model) {
990         case omap310:
991             return 0x03310315;
992         case omap1510:
993             return 0x03310115;
994         default:
995             hw_error("%s: bad mpu model\n", __FUNCTION__);
996         }
997         break;
998 
999     case 0xfffed404:	/* JTAG_ID_MSB */
1000         switch (s->mpu_model) {
1001         case omap310:
1002             return 0xfb57402f;
1003         case omap1510:
1004             return 0xfb47002f;
1005         default:
1006             hw_error("%s: bad mpu model\n", __FUNCTION__);
1007         }
1008         break;
1009     }
1010 
1011     OMAP_BAD_REG(addr);
1012     return 0;
1013 }
1014 
1015 static void omap_id_write(void *opaque, hwaddr addr,
1016                           uint64_t value, unsigned size)
1017 {
1018     if (size != 4) {
1019         omap_badwidth_write32(opaque, addr, value);
1020         return;
1021     }
1022 
1023     OMAP_BAD_REG(addr);
1024 }
1025 
1026 static const MemoryRegionOps omap_id_ops = {
1027     .read = omap_id_read,
1028     .write = omap_id_write,
1029     .endianness = DEVICE_NATIVE_ENDIAN,
1030 };
1031 
1032 static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
1033 {
1034     memory_region_init_io(&mpu->id_iomem, NULL, &omap_id_ops, mpu,
1035                           "omap-id", 0x100000000ULL);
1036     memory_region_init_alias(&mpu->id_iomem_e18, NULL, "omap-id-e18", &mpu->id_iomem,
1037                              0xfffe1800, 0x800);
1038     memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
1039     memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-ed4", &mpu->id_iomem,
1040                              0xfffed400, 0x100);
1041     memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
1042     if (!cpu_is_omap15xx(mpu)) {
1043         memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-e20",
1044                                  &mpu->id_iomem, 0xfffe2000, 0x800);
1045         memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
1046     }
1047 }
1048 
1049 /* MPUI Control (Dummy) */
1050 static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
1051                                unsigned size)
1052 {
1053     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1054 
1055     if (size != 4) {
1056         return omap_badwidth_read32(opaque, addr);
1057     }
1058 
1059     switch (addr) {
1060     case 0x00:	/* CTRL */
1061         return s->mpui_ctrl;
1062     case 0x04:	/* DEBUG_ADDR */
1063         return 0x01ffffff;
1064     case 0x08:	/* DEBUG_DATA */
1065         return 0xffffffff;
1066     case 0x0c:	/* DEBUG_FLAG */
1067         return 0x00000800;
1068     case 0x10:	/* STATUS */
1069         return 0x00000000;
1070 
1071     /* Not in OMAP310 */
1072     case 0x14:	/* DSP_STATUS */
1073     case 0x18:	/* DSP_BOOT_CONFIG */
1074         return 0x00000000;
1075     case 0x1c:	/* DSP_MPUI_CONFIG */
1076         return 0x0000ffff;
1077     }
1078 
1079     OMAP_BAD_REG(addr);
1080     return 0;
1081 }
1082 
1083 static void omap_mpui_write(void *opaque, hwaddr addr,
1084                             uint64_t value, unsigned size)
1085 {
1086     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1087 
1088     if (size != 4) {
1089         omap_badwidth_write32(opaque, addr, value);
1090         return;
1091     }
1092 
1093     switch (addr) {
1094     case 0x00:	/* CTRL */
1095         s->mpui_ctrl = value & 0x007fffff;
1096         break;
1097 
1098     case 0x04:	/* DEBUG_ADDR */
1099     case 0x08:	/* DEBUG_DATA */
1100     case 0x0c:	/* DEBUG_FLAG */
1101     case 0x10:	/* STATUS */
1102     /* Not in OMAP310 */
1103     case 0x14:	/* DSP_STATUS */
1104         OMAP_RO_REG(addr);
1105         break;
1106     case 0x18:	/* DSP_BOOT_CONFIG */
1107     case 0x1c:	/* DSP_MPUI_CONFIG */
1108         break;
1109 
1110     default:
1111         OMAP_BAD_REG(addr);
1112     }
1113 }
1114 
1115 static const MemoryRegionOps omap_mpui_ops = {
1116     .read = omap_mpui_read,
1117     .write = omap_mpui_write,
1118     .endianness = DEVICE_NATIVE_ENDIAN,
1119 };
1120 
1121 static void omap_mpui_reset(struct omap_mpu_state_s *s)
1122 {
1123     s->mpui_ctrl = 0x0003ff1b;
1124 }
1125 
1126 static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
1127                 struct omap_mpu_state_s *mpu)
1128 {
1129     memory_region_init_io(&mpu->mpui_iomem, NULL, &omap_mpui_ops, mpu,
1130                           "omap-mpui", 0x100);
1131     memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
1132 
1133     omap_mpui_reset(mpu);
1134 }
1135 
1136 /* TIPB Bridges */
1137 struct omap_tipb_bridge_s {
1138     qemu_irq abort;
1139     MemoryRegion iomem;
1140 
1141     int width_intr;
1142     uint16_t control;
1143     uint16_t alloc;
1144     uint16_t buffer;
1145     uint16_t enh_control;
1146 };
1147 
1148 static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
1149                                       unsigned size)
1150 {
1151     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1152 
1153     if (size < 2) {
1154         return omap_badwidth_read16(opaque, addr);
1155     }
1156 
1157     switch (addr) {
1158     case 0x00:	/* TIPB_CNTL */
1159         return s->control;
1160     case 0x04:	/* TIPB_BUS_ALLOC */
1161         return s->alloc;
1162     case 0x08:	/* MPU_TIPB_CNTL */
1163         return s->buffer;
1164     case 0x0c:	/* ENHANCED_TIPB_CNTL */
1165         return s->enh_control;
1166     case 0x10:	/* ADDRESS_DBG */
1167     case 0x14:	/* DATA_DEBUG_LOW */
1168     case 0x18:	/* DATA_DEBUG_HIGH */
1169         return 0xffff;
1170     case 0x1c:	/* DEBUG_CNTR_SIG */
1171         return 0x00f8;
1172     }
1173 
1174     OMAP_BAD_REG(addr);
1175     return 0;
1176 }
1177 
1178 static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
1179                                    uint64_t value, unsigned size)
1180 {
1181     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1182 
1183     if (size < 2) {
1184         omap_badwidth_write16(opaque, addr, value);
1185         return;
1186     }
1187 
1188     switch (addr) {
1189     case 0x00:	/* TIPB_CNTL */
1190         s->control = value & 0xffff;
1191         break;
1192 
1193     case 0x04:	/* TIPB_BUS_ALLOC */
1194         s->alloc = value & 0x003f;
1195         break;
1196 
1197     case 0x08:	/* MPU_TIPB_CNTL */
1198         s->buffer = value & 0x0003;
1199         break;
1200 
1201     case 0x0c:	/* ENHANCED_TIPB_CNTL */
1202         s->width_intr = !(value & 2);
1203         s->enh_control = value & 0x000f;
1204         break;
1205 
1206     case 0x10:	/* ADDRESS_DBG */
1207     case 0x14:	/* DATA_DEBUG_LOW */
1208     case 0x18:	/* DATA_DEBUG_HIGH */
1209     case 0x1c:	/* DEBUG_CNTR_SIG */
1210         OMAP_RO_REG(addr);
1211         break;
1212 
1213     default:
1214         OMAP_BAD_REG(addr);
1215     }
1216 }
1217 
1218 static const MemoryRegionOps omap_tipb_bridge_ops = {
1219     .read = omap_tipb_bridge_read,
1220     .write = omap_tipb_bridge_write,
1221     .endianness = DEVICE_NATIVE_ENDIAN,
1222 };
1223 
1224 static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1225 {
1226     s->control = 0xffff;
1227     s->alloc = 0x0009;
1228     s->buffer = 0x0000;
1229     s->enh_control = 0x000f;
1230 }
1231 
1232 static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
1233     MemoryRegion *memory, hwaddr base,
1234     qemu_irq abort_irq, omap_clk clk)
1235 {
1236     struct omap_tipb_bridge_s *s = g_new0(struct omap_tipb_bridge_s, 1);
1237 
1238     s->abort = abort_irq;
1239     omap_tipb_bridge_reset(s);
1240 
1241     memory_region_init_io(&s->iomem, NULL, &omap_tipb_bridge_ops, s,
1242                           "omap-tipb-bridge", 0x100);
1243     memory_region_add_subregion(memory, base, &s->iomem);
1244 
1245     return s;
1246 }
1247 
1248 /* Dummy Traffic Controller's Memory Interface */
1249 static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
1250                                unsigned size)
1251 {
1252     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1253     uint32_t ret;
1254 
1255     if (size != 4) {
1256         return omap_badwidth_read32(opaque, addr);
1257     }
1258 
1259     switch (addr) {
1260     case 0x00:	/* IMIF_PRIO */
1261     case 0x04:	/* EMIFS_PRIO */
1262     case 0x08:	/* EMIFF_PRIO */
1263     case 0x0c:	/* EMIFS_CONFIG */
1264     case 0x10:	/* EMIFS_CS0_CONFIG */
1265     case 0x14:	/* EMIFS_CS1_CONFIG */
1266     case 0x18:	/* EMIFS_CS2_CONFIG */
1267     case 0x1c:	/* EMIFS_CS3_CONFIG */
1268     case 0x24:	/* EMIFF_MRS */
1269     case 0x28:	/* TIMEOUT1 */
1270     case 0x2c:	/* TIMEOUT2 */
1271     case 0x30:	/* TIMEOUT3 */
1272     case 0x3c:	/* EMIFF_SDRAM_CONFIG_2 */
1273     case 0x40:	/* EMIFS_CFG_DYN_WAIT */
1274         return s->tcmi_regs[addr >> 2];
1275 
1276     case 0x20:	/* EMIFF_SDRAM_CONFIG */
1277         ret = s->tcmi_regs[addr >> 2];
1278         s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1279         /* XXX: We can try using the VGA_DIRTY flag for this */
1280         return ret;
1281     }
1282 
1283     OMAP_BAD_REG(addr);
1284     return 0;
1285 }
1286 
1287 static void omap_tcmi_write(void *opaque, hwaddr addr,
1288                             uint64_t value, unsigned size)
1289 {
1290     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1291 
1292     if (size != 4) {
1293         omap_badwidth_write32(opaque, addr, value);
1294         return;
1295     }
1296 
1297     switch (addr) {
1298     case 0x00:	/* IMIF_PRIO */
1299     case 0x04:	/* EMIFS_PRIO */
1300     case 0x08:	/* EMIFF_PRIO */
1301     case 0x10:	/* EMIFS_CS0_CONFIG */
1302     case 0x14:	/* EMIFS_CS1_CONFIG */
1303     case 0x18:	/* EMIFS_CS2_CONFIG */
1304     case 0x1c:	/* EMIFS_CS3_CONFIG */
1305     case 0x20:	/* EMIFF_SDRAM_CONFIG */
1306     case 0x24:	/* EMIFF_MRS */
1307     case 0x28:	/* TIMEOUT1 */
1308     case 0x2c:	/* TIMEOUT2 */
1309     case 0x30:	/* TIMEOUT3 */
1310     case 0x3c:	/* EMIFF_SDRAM_CONFIG_2 */
1311     case 0x40:	/* EMIFS_CFG_DYN_WAIT */
1312         s->tcmi_regs[addr >> 2] = value;
1313         break;
1314     case 0x0c:	/* EMIFS_CONFIG */
1315         s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
1316         break;
1317 
1318     default:
1319         OMAP_BAD_REG(addr);
1320     }
1321 }
1322 
1323 static const MemoryRegionOps omap_tcmi_ops = {
1324     .read = omap_tcmi_read,
1325     .write = omap_tcmi_write,
1326     .endianness = DEVICE_NATIVE_ENDIAN,
1327 };
1328 
1329 static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1330 {
1331     mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1332     mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1333     mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1334     mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1335     mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1336     mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1337     mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1338     mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1339     mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1340     mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1341     mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1342     mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1343     mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1344     mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1345     mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1346 }
1347 
1348 static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
1349                 struct omap_mpu_state_s *mpu)
1350 {
1351     memory_region_init_io(&mpu->tcmi_iomem, NULL, &omap_tcmi_ops, mpu,
1352                           "omap-tcmi", 0x100);
1353     memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
1354     omap_tcmi_reset(mpu);
1355 }
1356 
1357 /* Digital phase-locked loops control */
1358 struct dpll_ctl_s {
1359     MemoryRegion iomem;
1360     uint16_t mode;
1361     omap_clk dpll;
1362 };
1363 
1364 static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
1365                                unsigned size)
1366 {
1367     struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1368 
1369     if (size != 2) {
1370         return omap_badwidth_read16(opaque, addr);
1371     }
1372 
1373     if (addr == 0x00)	/* CTL_REG */
1374         return s->mode;
1375 
1376     OMAP_BAD_REG(addr);
1377     return 0;
1378 }
1379 
1380 static void omap_dpll_write(void *opaque, hwaddr addr,
1381                             uint64_t value, unsigned size)
1382 {
1383     struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1384     uint16_t diff;
1385     static const int bypass_div[4] = { 1, 2, 4, 4 };
1386     int div, mult;
1387 
1388     if (size != 2) {
1389         omap_badwidth_write16(opaque, addr, value);
1390         return;
1391     }
1392 
1393     if (addr == 0x00) {	/* CTL_REG */
1394         /* See omap_ulpd_pm_write() too */
1395         diff = s->mode & value;
1396         s->mode = value & 0x2fff;
1397         if (diff & (0x3ff << 2)) {
1398             if (value & (1 << 4)) {			/* PLL_ENABLE */
1399                 div = ((value >> 5) & 3) + 1;		/* PLL_DIV */
1400                 mult = MIN((value >> 7) & 0x1f, 1);	/* PLL_MULT */
1401             } else {
1402                 div = bypass_div[((value >> 2) & 3)];	/* BYPASS_DIV */
1403                 mult = 1;
1404             }
1405             omap_clk_setrate(s->dpll, div, mult);
1406         }
1407 
1408         /* Enter the desired mode.  */
1409         s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1410 
1411         /* Act as if the lock is restored.  */
1412         s->mode |= 2;
1413     } else {
1414         OMAP_BAD_REG(addr);
1415     }
1416 }
1417 
1418 static const MemoryRegionOps omap_dpll_ops = {
1419     .read = omap_dpll_read,
1420     .write = omap_dpll_write,
1421     .endianness = DEVICE_NATIVE_ENDIAN,
1422 };
1423 
1424 static void omap_dpll_reset(struct dpll_ctl_s *s)
1425 {
1426     s->mode = 0x2002;
1427     omap_clk_setrate(s->dpll, 1, 1);
1428 }
1429 
1430 static struct dpll_ctl_s  *omap_dpll_init(MemoryRegion *memory,
1431                            hwaddr base, omap_clk clk)
1432 {
1433     struct dpll_ctl_s *s = g_malloc0(sizeof(*s));
1434     memory_region_init_io(&s->iomem, NULL, &omap_dpll_ops, s, "omap-dpll", 0x100);
1435 
1436     s->dpll = clk;
1437     omap_dpll_reset(s);
1438 
1439     memory_region_add_subregion(memory, base, &s->iomem);
1440     return s;
1441 }
1442 
1443 /* MPU Clock/Reset/Power Mode Control */
1444 static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
1445                                unsigned size)
1446 {
1447     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1448 
1449     if (size != 2) {
1450         return omap_badwidth_read16(opaque, addr);
1451     }
1452 
1453     switch (addr) {
1454     case 0x00:	/* ARM_CKCTL */
1455         return s->clkm.arm_ckctl;
1456 
1457     case 0x04:	/* ARM_IDLECT1 */
1458         return s->clkm.arm_idlect1;
1459 
1460     case 0x08:	/* ARM_IDLECT2 */
1461         return s->clkm.arm_idlect2;
1462 
1463     case 0x0c:	/* ARM_EWUPCT */
1464         return s->clkm.arm_ewupct;
1465 
1466     case 0x10:	/* ARM_RSTCT1 */
1467         return s->clkm.arm_rstct1;
1468 
1469     case 0x14:	/* ARM_RSTCT2 */
1470         return s->clkm.arm_rstct2;
1471 
1472     case 0x18:	/* ARM_SYSST */
1473         return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1474 
1475     case 0x1c:	/* ARM_CKOUT1 */
1476         return s->clkm.arm_ckout1;
1477 
1478     case 0x20:	/* ARM_CKOUT2 */
1479         break;
1480     }
1481 
1482     OMAP_BAD_REG(addr);
1483     return 0;
1484 }
1485 
1486 static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1487                 uint16_t diff, uint16_t value)
1488 {
1489     omap_clk clk;
1490 
1491     if (diff & (1 << 14)) {				/* ARM_INTHCK_SEL */
1492         if (value & (1 << 14))
1493             /* Reserved */;
1494         else {
1495             clk = omap_findclk(s, "arminth_ck");
1496             omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1497         }
1498     }
1499     if (diff & (1 << 12)) {				/* ARM_TIMXO */
1500         clk = omap_findclk(s, "armtim_ck");
1501         if (value & (1 << 12))
1502             omap_clk_reparent(clk, omap_findclk(s, "clkin"));
1503         else
1504             omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1505     }
1506     /* XXX: en_dspck */
1507     if (diff & (3 << 10)) {				/* DSPMMUDIV */
1508         clk = omap_findclk(s, "dspmmu_ck");
1509         omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
1510     }
1511     if (diff & (3 << 8)) {				/* TCDIV */
1512         clk = omap_findclk(s, "tc_ck");
1513         omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
1514     }
1515     if (diff & (3 << 6)) {				/* DSPDIV */
1516         clk = omap_findclk(s, "dsp_ck");
1517         omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
1518     }
1519     if (diff & (3 << 4)) {				/* ARMDIV */
1520         clk = omap_findclk(s, "arm_ck");
1521         omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
1522     }
1523     if (diff & (3 << 2)) {				/* LCDDIV */
1524         clk = omap_findclk(s, "lcd_ck");
1525         omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
1526     }
1527     if (diff & (3 << 0)) {				/* PERDIV */
1528         clk = omap_findclk(s, "armper_ck");
1529         omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
1530     }
1531 }
1532 
1533 static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1534                 uint16_t diff, uint16_t value)
1535 {
1536     omap_clk clk;
1537 
1538     if (value & (1 << 11)) {                            /* SETARM_IDLE */
1539         cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
1540     }
1541     if (!(value & (1 << 10)))				/* WKUP_MODE */
1542         qemu_system_shutdown_request();	/* XXX: disable wakeup from IRQ */
1543 
1544 #define SET_CANIDLE(clock, bit)				\
1545     if (diff & (1 << bit)) {				\
1546         clk = omap_findclk(s, clock);			\
1547         omap_clk_canidle(clk, (value >> bit) & 1);	\
1548     }
1549     SET_CANIDLE("mpuwd_ck", 0)				/* IDLWDT_ARM */
1550     SET_CANIDLE("armxor_ck", 1)				/* IDLXORP_ARM */
1551     SET_CANIDLE("mpuper_ck", 2)				/* IDLPER_ARM */
1552     SET_CANIDLE("lcd_ck", 3)				/* IDLLCD_ARM */
1553     SET_CANIDLE("lb_ck", 4)				/* IDLLB_ARM */
1554     SET_CANIDLE("hsab_ck", 5)				/* IDLHSAB_ARM */
1555     SET_CANIDLE("tipb_ck", 6)				/* IDLIF_ARM */
1556     SET_CANIDLE("dma_ck", 6)				/* IDLIF_ARM */
1557     SET_CANIDLE("tc_ck", 6)				/* IDLIF_ARM */
1558     SET_CANIDLE("dpll1", 7)				/* IDLDPLL_ARM */
1559     SET_CANIDLE("dpll2", 7)				/* IDLDPLL_ARM */
1560     SET_CANIDLE("dpll3", 7)				/* IDLDPLL_ARM */
1561     SET_CANIDLE("mpui_ck", 8)				/* IDLAPI_ARM */
1562     SET_CANIDLE("armtim_ck", 9)				/* IDLTIM_ARM */
1563 }
1564 
1565 static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1566                 uint16_t diff, uint16_t value)
1567 {
1568     omap_clk clk;
1569 
1570 #define SET_ONOFF(clock, bit)				\
1571     if (diff & (1 << bit)) {				\
1572         clk = omap_findclk(s, clock);			\
1573         omap_clk_onoff(clk, (value >> bit) & 1);	\
1574     }
1575     SET_ONOFF("mpuwd_ck", 0)				/* EN_WDTCK */
1576     SET_ONOFF("armxor_ck", 1)				/* EN_XORPCK */
1577     SET_ONOFF("mpuper_ck", 2)				/* EN_PERCK */
1578     SET_ONOFF("lcd_ck", 3)				/* EN_LCDCK */
1579     SET_ONOFF("lb_ck", 4)				/* EN_LBCK */
1580     SET_ONOFF("hsab_ck", 5)				/* EN_HSABCK */
1581     SET_ONOFF("mpui_ck", 6)				/* EN_APICK */
1582     SET_ONOFF("armtim_ck", 7)				/* EN_TIMCK */
1583     SET_CANIDLE("dma_ck", 8)				/* DMACK_REQ */
1584     SET_ONOFF("arm_gpio_ck", 9)				/* EN_GPIOCK */
1585     SET_ONOFF("lbfree_ck", 10)				/* EN_LBFREECK */
1586 }
1587 
1588 static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1589                 uint16_t diff, uint16_t value)
1590 {
1591     omap_clk clk;
1592 
1593     if (diff & (3 << 4)) {				/* TCLKOUT */
1594         clk = omap_findclk(s, "tclk_out");
1595         switch ((value >> 4) & 3) {
1596         case 1:
1597             omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
1598             omap_clk_onoff(clk, 1);
1599             break;
1600         case 2:
1601             omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1602             omap_clk_onoff(clk, 1);
1603             break;
1604         default:
1605             omap_clk_onoff(clk, 0);
1606         }
1607     }
1608     if (diff & (3 << 2)) {				/* DCLKOUT */
1609         clk = omap_findclk(s, "dclk_out");
1610         switch ((value >> 2) & 3) {
1611         case 0:
1612             omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
1613             break;
1614         case 1:
1615             omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
1616             break;
1617         case 2:
1618             omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
1619             break;
1620         case 3:
1621             omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1622             break;
1623         }
1624     }
1625     if (diff & (3 << 0)) {				/* ACLKOUT */
1626         clk = omap_findclk(s, "aclk_out");
1627         switch ((value >> 0) & 3) {
1628         case 1:
1629             omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1630             omap_clk_onoff(clk, 1);
1631             break;
1632         case 2:
1633             omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
1634             omap_clk_onoff(clk, 1);
1635             break;
1636         case 3:
1637             omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1638             omap_clk_onoff(clk, 1);
1639             break;
1640         default:
1641             omap_clk_onoff(clk, 0);
1642         }
1643     }
1644 }
1645 
1646 static void omap_clkm_write(void *opaque, hwaddr addr,
1647                             uint64_t value, unsigned size)
1648 {
1649     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1650     uint16_t diff;
1651     omap_clk clk;
1652     static const char *clkschemename[8] = {
1653         "fully synchronous", "fully asynchronous", "synchronous scalable",
1654         "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
1655     };
1656 
1657     if (size != 2) {
1658         omap_badwidth_write16(opaque, addr, value);
1659         return;
1660     }
1661 
1662     switch (addr) {
1663     case 0x00:	/* ARM_CKCTL */
1664         diff = s->clkm.arm_ckctl ^ value;
1665         s->clkm.arm_ckctl = value & 0x7fff;
1666         omap_clkm_ckctl_update(s, diff, value);
1667         return;
1668 
1669     case 0x04:	/* ARM_IDLECT1 */
1670         diff = s->clkm.arm_idlect1 ^ value;
1671         s->clkm.arm_idlect1 = value & 0x0fff;
1672         omap_clkm_idlect1_update(s, diff, value);
1673         return;
1674 
1675     case 0x08:	/* ARM_IDLECT2 */
1676         diff = s->clkm.arm_idlect2 ^ value;
1677         s->clkm.arm_idlect2 = value & 0x07ff;
1678         omap_clkm_idlect2_update(s, diff, value);
1679         return;
1680 
1681     case 0x0c:	/* ARM_EWUPCT */
1682         s->clkm.arm_ewupct = value & 0x003f;
1683         return;
1684 
1685     case 0x10:	/* ARM_RSTCT1 */
1686         diff = s->clkm.arm_rstct1 ^ value;
1687         s->clkm.arm_rstct1 = value & 0x0007;
1688         if (value & 9) {
1689             qemu_system_reset_request();
1690             s->clkm.cold_start = 0xa;
1691         }
1692         if (diff & ~value & 4) {				/* DSP_RST */
1693             omap_mpui_reset(s);
1694             omap_tipb_bridge_reset(s->private_tipb);
1695             omap_tipb_bridge_reset(s->public_tipb);
1696         }
1697         if (diff & 2) {						/* DSP_EN */
1698             clk = omap_findclk(s, "dsp_ck");
1699             omap_clk_canidle(clk, (~value >> 1) & 1);
1700         }
1701         return;
1702 
1703     case 0x14:	/* ARM_RSTCT2 */
1704         s->clkm.arm_rstct2 = value & 0x0001;
1705         return;
1706 
1707     case 0x18:	/* ARM_SYSST */
1708         if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
1709             s->clkm.clocking_scheme = (value >> 11) & 7;
1710             printf("%s: clocking scheme set to %s\n", __FUNCTION__,
1711                             clkschemename[s->clkm.clocking_scheme]);
1712         }
1713         s->clkm.cold_start &= value & 0x3f;
1714         return;
1715 
1716     case 0x1c:	/* ARM_CKOUT1 */
1717         diff = s->clkm.arm_ckout1 ^ value;
1718         s->clkm.arm_ckout1 = value & 0x003f;
1719         omap_clkm_ckout1_update(s, diff, value);
1720         return;
1721 
1722     case 0x20:	/* ARM_CKOUT2 */
1723     default:
1724         OMAP_BAD_REG(addr);
1725     }
1726 }
1727 
1728 static const MemoryRegionOps omap_clkm_ops = {
1729     .read = omap_clkm_read,
1730     .write = omap_clkm_write,
1731     .endianness = DEVICE_NATIVE_ENDIAN,
1732 };
1733 
1734 static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
1735                                  unsigned size)
1736 {
1737     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1738     CPUState *cpu = CPU(s->cpu);
1739 
1740     if (size != 2) {
1741         return omap_badwidth_read16(opaque, addr);
1742     }
1743 
1744     switch (addr) {
1745     case 0x04:	/* DSP_IDLECT1 */
1746         return s->clkm.dsp_idlect1;
1747 
1748     case 0x08:	/* DSP_IDLECT2 */
1749         return s->clkm.dsp_idlect2;
1750 
1751     case 0x14:	/* DSP_RSTCT2 */
1752         return s->clkm.dsp_rstct2;
1753 
1754     case 0x18:	/* DSP_SYSST */
1755         cpu = CPU(s->cpu);
1756         return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
1757                 (cpu->halted << 6);      /* Quite useless... */
1758     }
1759 
1760     OMAP_BAD_REG(addr);
1761     return 0;
1762 }
1763 
1764 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
1765                 uint16_t diff, uint16_t value)
1766 {
1767     omap_clk clk;
1768 
1769     SET_CANIDLE("dspxor_ck", 1);			/* IDLXORP_DSP */
1770 }
1771 
1772 static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
1773                 uint16_t diff, uint16_t value)
1774 {
1775     omap_clk clk;
1776 
1777     SET_ONOFF("dspxor_ck", 1);				/* EN_XORPCK */
1778 }
1779 
1780 static void omap_clkdsp_write(void *opaque, hwaddr addr,
1781                               uint64_t value, unsigned size)
1782 {
1783     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1784     uint16_t diff;
1785 
1786     if (size != 2) {
1787         omap_badwidth_write16(opaque, addr, value);
1788         return;
1789     }
1790 
1791     switch (addr) {
1792     case 0x04:	/* DSP_IDLECT1 */
1793         diff = s->clkm.dsp_idlect1 ^ value;
1794         s->clkm.dsp_idlect1 = value & 0x01f7;
1795         omap_clkdsp_idlect1_update(s, diff, value);
1796         break;
1797 
1798     case 0x08:	/* DSP_IDLECT2 */
1799         s->clkm.dsp_idlect2 = value & 0x0037;
1800         diff = s->clkm.dsp_idlect1 ^ value;
1801         omap_clkdsp_idlect2_update(s, diff, value);
1802         break;
1803 
1804     case 0x14:	/* DSP_RSTCT2 */
1805         s->clkm.dsp_rstct2 = value & 0x0001;
1806         break;
1807 
1808     case 0x18:	/* DSP_SYSST */
1809         s->clkm.cold_start &= value & 0x3f;
1810         break;
1811 
1812     default:
1813         OMAP_BAD_REG(addr);
1814     }
1815 }
1816 
1817 static const MemoryRegionOps omap_clkdsp_ops = {
1818     .read = omap_clkdsp_read,
1819     .write = omap_clkdsp_write,
1820     .endianness = DEVICE_NATIVE_ENDIAN,
1821 };
1822 
1823 static void omap_clkm_reset(struct omap_mpu_state_s *s)
1824 {
1825     if (s->wdt && s->wdt->reset)
1826         s->clkm.cold_start = 0x6;
1827     s->clkm.clocking_scheme = 0;
1828     omap_clkm_ckctl_update(s, ~0, 0x3000);
1829     s->clkm.arm_ckctl = 0x3000;
1830     omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
1831     s->clkm.arm_idlect1 = 0x0400;
1832     omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
1833     s->clkm.arm_idlect2 = 0x0100;
1834     s->clkm.arm_ewupct = 0x003f;
1835     s->clkm.arm_rstct1 = 0x0000;
1836     s->clkm.arm_rstct2 = 0x0000;
1837     s->clkm.arm_ckout1 = 0x0015;
1838     s->clkm.dpll1_mode = 0x2002;
1839     omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
1840     s->clkm.dsp_idlect1 = 0x0040;
1841     omap_clkdsp_idlect2_update(s, ~0, 0x0000);
1842     s->clkm.dsp_idlect2 = 0x0000;
1843     s->clkm.dsp_rstct2 = 0x0000;
1844 }
1845 
1846 static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
1847                 hwaddr dsp_base, struct omap_mpu_state_s *s)
1848 {
1849     memory_region_init_io(&s->clkm_iomem, NULL, &omap_clkm_ops, s,
1850                           "omap-clkm", 0x100);
1851     memory_region_init_io(&s->clkdsp_iomem, NULL, &omap_clkdsp_ops, s,
1852                           "omap-clkdsp", 0x1000);
1853 
1854     s->clkm.arm_idlect1 = 0x03ff;
1855     s->clkm.arm_idlect2 = 0x0100;
1856     s->clkm.dsp_idlect1 = 0x0002;
1857     omap_clkm_reset(s);
1858     s->clkm.cold_start = 0x3a;
1859 
1860     memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
1861     memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
1862 }
1863 
1864 /* MPU I/O */
1865 struct omap_mpuio_s {
1866     qemu_irq irq;
1867     qemu_irq kbd_irq;
1868     qemu_irq *in;
1869     qemu_irq handler[16];
1870     qemu_irq wakeup;
1871     MemoryRegion iomem;
1872 
1873     uint16_t inputs;
1874     uint16_t outputs;
1875     uint16_t dir;
1876     uint16_t edge;
1877     uint16_t mask;
1878     uint16_t ints;
1879 
1880     uint16_t debounce;
1881     uint16_t latch;
1882     uint8_t event;
1883 
1884     uint8_t buttons[5];
1885     uint8_t row_latch;
1886     uint8_t cols;
1887     int kbd_mask;
1888     int clk;
1889 };
1890 
1891 static void omap_mpuio_set(void *opaque, int line, int level)
1892 {
1893     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1894     uint16_t prev = s->inputs;
1895 
1896     if (level)
1897         s->inputs |= 1 << line;
1898     else
1899         s->inputs &= ~(1 << line);
1900 
1901     if (((1 << line) & s->dir & ~s->mask) && s->clk) {
1902         if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
1903             s->ints |= 1 << line;
1904             qemu_irq_raise(s->irq);
1905             /* TODO: wakeup */
1906         }
1907         if ((s->event & (1 << 0)) &&		/* SET_GPIO_EVENT_MODE */
1908                 (s->event >> 1) == line)	/* PIN_SELECT */
1909             s->latch = s->inputs;
1910     }
1911 }
1912 
1913 static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
1914 {
1915     int i;
1916     uint8_t *row, rows = 0, cols = ~s->cols;
1917 
1918     for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1919         if (*row & cols)
1920             rows |= i;
1921 
1922     qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1923     s->row_latch = ~rows;
1924 }
1925 
1926 static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
1927                                 unsigned size)
1928 {
1929     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1930     int offset = addr & OMAP_MPUI_REG_MASK;
1931     uint16_t ret;
1932 
1933     if (size != 2) {
1934         return omap_badwidth_read16(opaque, addr);
1935     }
1936 
1937     switch (offset) {
1938     case 0x00:	/* INPUT_LATCH */
1939         return s->inputs;
1940 
1941     case 0x04:	/* OUTPUT_REG */
1942         return s->outputs;
1943 
1944     case 0x08:	/* IO_CNTL */
1945         return s->dir;
1946 
1947     case 0x10:	/* KBR_LATCH */
1948         return s->row_latch;
1949 
1950     case 0x14:	/* KBC_REG */
1951         return s->cols;
1952 
1953     case 0x18:	/* GPIO_EVENT_MODE_REG */
1954         return s->event;
1955 
1956     case 0x1c:	/* GPIO_INT_EDGE_REG */
1957         return s->edge;
1958 
1959     case 0x20:	/* KBD_INT */
1960         return (~s->row_latch & 0x1f) && !s->kbd_mask;
1961 
1962     case 0x24:	/* GPIO_INT */
1963         ret = s->ints;
1964         s->ints &= s->mask;
1965         if (ret)
1966             qemu_irq_lower(s->irq);
1967         return ret;
1968 
1969     case 0x28:	/* KBD_MASKIT */
1970         return s->kbd_mask;
1971 
1972     case 0x2c:	/* GPIO_MASKIT */
1973         return s->mask;
1974 
1975     case 0x30:	/* GPIO_DEBOUNCING_REG */
1976         return s->debounce;
1977 
1978     case 0x34:	/* GPIO_LATCH_REG */
1979         return s->latch;
1980     }
1981 
1982     OMAP_BAD_REG(addr);
1983     return 0;
1984 }
1985 
1986 static void omap_mpuio_write(void *opaque, hwaddr addr,
1987                              uint64_t value, unsigned size)
1988 {
1989     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1990     int offset = addr & OMAP_MPUI_REG_MASK;
1991     uint16_t diff;
1992     int ln;
1993 
1994     if (size != 2) {
1995         omap_badwidth_write16(opaque, addr, value);
1996         return;
1997     }
1998 
1999     switch (offset) {
2000     case 0x04:	/* OUTPUT_REG */
2001         diff = (s->outputs ^ value) & ~s->dir;
2002         s->outputs = value;
2003         while ((ln = ctz32(diff)) != 32) {
2004             if (s->handler[ln])
2005                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2006             diff &= ~(1 << ln);
2007         }
2008         break;
2009 
2010     case 0x08:	/* IO_CNTL */
2011         diff = s->outputs & (s->dir ^ value);
2012         s->dir = value;
2013 
2014         value = s->outputs & ~s->dir;
2015         while ((ln = ctz32(diff)) != 32) {
2016             if (s->handler[ln])
2017                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2018             diff &= ~(1 << ln);
2019         }
2020         break;
2021 
2022     case 0x14:	/* KBC_REG */
2023         s->cols = value;
2024         omap_mpuio_kbd_update(s);
2025         break;
2026 
2027     case 0x18:	/* GPIO_EVENT_MODE_REG */
2028         s->event = value & 0x1f;
2029         break;
2030 
2031     case 0x1c:	/* GPIO_INT_EDGE_REG */
2032         s->edge = value;
2033         break;
2034 
2035     case 0x28:	/* KBD_MASKIT */
2036         s->kbd_mask = value & 1;
2037         omap_mpuio_kbd_update(s);
2038         break;
2039 
2040     case 0x2c:	/* GPIO_MASKIT */
2041         s->mask = value;
2042         break;
2043 
2044     case 0x30:	/* GPIO_DEBOUNCING_REG */
2045         s->debounce = value & 0x1ff;
2046         break;
2047 
2048     case 0x00:	/* INPUT_LATCH */
2049     case 0x10:	/* KBR_LATCH */
2050     case 0x20:	/* KBD_INT */
2051     case 0x24:	/* GPIO_INT */
2052     case 0x34:	/* GPIO_LATCH_REG */
2053         OMAP_RO_REG(addr);
2054         return;
2055 
2056     default:
2057         OMAP_BAD_REG(addr);
2058         return;
2059     }
2060 }
2061 
2062 static const MemoryRegionOps omap_mpuio_ops  = {
2063     .read = omap_mpuio_read,
2064     .write = omap_mpuio_write,
2065     .endianness = DEVICE_NATIVE_ENDIAN,
2066 };
2067 
2068 static void omap_mpuio_reset(struct omap_mpuio_s *s)
2069 {
2070     s->inputs = 0;
2071     s->outputs = 0;
2072     s->dir = ~0;
2073     s->event = 0;
2074     s->edge = 0;
2075     s->kbd_mask = 0;
2076     s->mask = 0;
2077     s->debounce = 0;
2078     s->latch = 0;
2079     s->ints = 0;
2080     s->row_latch = 0x1f;
2081     s->clk = 1;
2082 }
2083 
2084 static void omap_mpuio_onoff(void *opaque, int line, int on)
2085 {
2086     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2087 
2088     s->clk = on;
2089     if (on)
2090         omap_mpuio_kbd_update(s);
2091 }
2092 
2093 static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
2094                 hwaddr base,
2095                 qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2096                 omap_clk clk)
2097 {
2098     struct omap_mpuio_s *s = g_new0(struct omap_mpuio_s, 1);
2099 
2100     s->irq = gpio_int;
2101     s->kbd_irq = kbd_int;
2102     s->wakeup = wakeup;
2103     s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2104     omap_mpuio_reset(s);
2105 
2106     memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s,
2107                           "omap-mpuio", 0x800);
2108     memory_region_add_subregion(memory, base, &s->iomem);
2109 
2110     omap_clk_adduser(clk, qemu_allocate_irq(omap_mpuio_onoff, s, 0));
2111 
2112     return s;
2113 }
2114 
2115 qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2116 {
2117     return s->in;
2118 }
2119 
2120 void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2121 {
2122     if (line >= 16 || line < 0)
2123         hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
2124     s->handler[line] = handler;
2125 }
2126 
2127 void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2128 {
2129     if (row >= 5 || row < 0)
2130         hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
2131 
2132     if (down)
2133         s->buttons[row] |= 1 << col;
2134     else
2135         s->buttons[row] &= ~(1 << col);
2136 
2137     omap_mpuio_kbd_update(s);
2138 }
2139 
2140 /* MicroWire Interface */
2141 struct omap_uwire_s {
2142     MemoryRegion iomem;
2143     qemu_irq txirq;
2144     qemu_irq rxirq;
2145     qemu_irq txdrq;
2146 
2147     uint16_t txbuf;
2148     uint16_t rxbuf;
2149     uint16_t control;
2150     uint16_t setup[5];
2151 
2152     uWireSlave *chip[4];
2153 };
2154 
2155 static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2156 {
2157     int chipselect = (s->control >> 10) & 3;		/* INDEX */
2158     uWireSlave *slave = s->chip[chipselect];
2159 
2160     if ((s->control >> 5) & 0x1f) {			/* NB_BITS_WR */
2161         if (s->control & (1 << 12))			/* CS_CMD */
2162             if (slave && slave->send)
2163                 slave->send(slave->opaque,
2164                                 s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
2165         s->control &= ~(1 << 14);			/* CSRB */
2166         /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2167          * a DRQ.  When is the level IRQ supposed to be reset?  */
2168     }
2169 
2170     if ((s->control >> 0) & 0x1f) {			/* NB_BITS_RD */
2171         if (s->control & (1 << 12))			/* CS_CMD */
2172             if (slave && slave->receive)
2173                 s->rxbuf = slave->receive(slave->opaque);
2174         s->control |= 1 << 15;				/* RDRB */
2175         /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2176          * a DRQ.  When is the level IRQ supposed to be reset?  */
2177     }
2178 }
2179 
2180 static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
2181                                 unsigned size)
2182 {
2183     struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2184     int offset = addr & OMAP_MPUI_REG_MASK;
2185 
2186     if (size != 2) {
2187         return omap_badwidth_read16(opaque, addr);
2188     }
2189 
2190     switch (offset) {
2191     case 0x00:	/* RDR */
2192         s->control &= ~(1 << 15);			/* RDRB */
2193         return s->rxbuf;
2194 
2195     case 0x04:	/* CSR */
2196         return s->control;
2197 
2198     case 0x08:	/* SR1 */
2199         return s->setup[0];
2200     case 0x0c:	/* SR2 */
2201         return s->setup[1];
2202     case 0x10:	/* SR3 */
2203         return s->setup[2];
2204     case 0x14:	/* SR4 */
2205         return s->setup[3];
2206     case 0x18:	/* SR5 */
2207         return s->setup[4];
2208     }
2209 
2210     OMAP_BAD_REG(addr);
2211     return 0;
2212 }
2213 
2214 static void omap_uwire_write(void *opaque, hwaddr addr,
2215                              uint64_t value, unsigned size)
2216 {
2217     struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2218     int offset = addr & OMAP_MPUI_REG_MASK;
2219 
2220     if (size != 2) {
2221         omap_badwidth_write16(opaque, addr, value);
2222         return;
2223     }
2224 
2225     switch (offset) {
2226     case 0x00:	/* TDR */
2227         s->txbuf = value;				/* TD */
2228         if ((s->setup[4] & (1 << 2)) &&			/* AUTO_TX_EN */
2229                         ((s->setup[4] & (1 << 3)) ||	/* CS_TOGGLE_TX_EN */
2230                          (s->control & (1 << 12)))) {	/* CS_CMD */
2231             s->control |= 1 << 14;			/* CSRB */
2232             omap_uwire_transfer_start(s);
2233         }
2234         break;
2235 
2236     case 0x04:	/* CSR */
2237         s->control = value & 0x1fff;
2238         if (value & (1 << 13))				/* START */
2239             omap_uwire_transfer_start(s);
2240         break;
2241 
2242     case 0x08:	/* SR1 */
2243         s->setup[0] = value & 0x003f;
2244         break;
2245 
2246     case 0x0c:	/* SR2 */
2247         s->setup[1] = value & 0x0fc0;
2248         break;
2249 
2250     case 0x10:	/* SR3 */
2251         s->setup[2] = value & 0x0003;
2252         break;
2253 
2254     case 0x14:	/* SR4 */
2255         s->setup[3] = value & 0x0001;
2256         break;
2257 
2258     case 0x18:	/* SR5 */
2259         s->setup[4] = value & 0x000f;
2260         break;
2261 
2262     default:
2263         OMAP_BAD_REG(addr);
2264         return;
2265     }
2266 }
2267 
2268 static const MemoryRegionOps omap_uwire_ops = {
2269     .read = omap_uwire_read,
2270     .write = omap_uwire_write,
2271     .endianness = DEVICE_NATIVE_ENDIAN,
2272 };
2273 
2274 static void omap_uwire_reset(struct omap_uwire_s *s)
2275 {
2276     s->control = 0;
2277     s->setup[0] = 0;
2278     s->setup[1] = 0;
2279     s->setup[2] = 0;
2280     s->setup[3] = 0;
2281     s->setup[4] = 0;
2282 }
2283 
2284 static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
2285                                             hwaddr base,
2286                                             qemu_irq txirq, qemu_irq rxirq,
2287                                             qemu_irq dma,
2288                                             omap_clk clk)
2289 {
2290     struct omap_uwire_s *s = g_new0(struct omap_uwire_s, 1);
2291 
2292     s->txirq = txirq;
2293     s->rxirq = rxirq;
2294     s->txdrq = dma;
2295     omap_uwire_reset(s);
2296 
2297     memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800);
2298     memory_region_add_subregion(system_memory, base, &s->iomem);
2299 
2300     return s;
2301 }
2302 
2303 void omap_uwire_attach(struct omap_uwire_s *s,
2304                 uWireSlave *slave, int chipselect)
2305 {
2306     if (chipselect < 0 || chipselect > 3) {
2307         fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
2308         exit(-1);
2309     }
2310 
2311     s->chip[chipselect] = slave;
2312 }
2313 
2314 /* Pseudonoise Pulse-Width Light Modulator */
2315 struct omap_pwl_s {
2316     MemoryRegion iomem;
2317     uint8_t output;
2318     uint8_t level;
2319     uint8_t enable;
2320     int clk;
2321 };
2322 
2323 static void omap_pwl_update(struct omap_pwl_s *s)
2324 {
2325     int output = (s->clk && s->enable) ? s->level : 0;
2326 
2327     if (output != s->output) {
2328         s->output = output;
2329         printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
2330     }
2331 }
2332 
2333 static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
2334                               unsigned size)
2335 {
2336     struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2337     int offset = addr & OMAP_MPUI_REG_MASK;
2338 
2339     if (size != 1) {
2340         return omap_badwidth_read8(opaque, addr);
2341     }
2342 
2343     switch (offset) {
2344     case 0x00:	/* PWL_LEVEL */
2345         return s->level;
2346     case 0x04:	/* PWL_CTRL */
2347         return s->enable;
2348     }
2349     OMAP_BAD_REG(addr);
2350     return 0;
2351 }
2352 
2353 static void omap_pwl_write(void *opaque, hwaddr addr,
2354                            uint64_t value, unsigned size)
2355 {
2356     struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2357     int offset = addr & OMAP_MPUI_REG_MASK;
2358 
2359     if (size != 1) {
2360         omap_badwidth_write8(opaque, addr, value);
2361         return;
2362     }
2363 
2364     switch (offset) {
2365     case 0x00:	/* PWL_LEVEL */
2366         s->level = value;
2367         omap_pwl_update(s);
2368         break;
2369     case 0x04:	/* PWL_CTRL */
2370         s->enable = value & 1;
2371         omap_pwl_update(s);
2372         break;
2373     default:
2374         OMAP_BAD_REG(addr);
2375         return;
2376     }
2377 }
2378 
2379 static const MemoryRegionOps omap_pwl_ops = {
2380     .read = omap_pwl_read,
2381     .write = omap_pwl_write,
2382     .endianness = DEVICE_NATIVE_ENDIAN,
2383 };
2384 
2385 static void omap_pwl_reset(struct omap_pwl_s *s)
2386 {
2387     s->output = 0;
2388     s->level = 0;
2389     s->enable = 0;
2390     s->clk = 1;
2391     omap_pwl_update(s);
2392 }
2393 
2394 static void omap_pwl_clk_update(void *opaque, int line, int on)
2395 {
2396     struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2397 
2398     s->clk = on;
2399     omap_pwl_update(s);
2400 }
2401 
2402 static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
2403                                         hwaddr base,
2404                                         omap_clk clk)
2405 {
2406     struct omap_pwl_s *s = g_malloc0(sizeof(*s));
2407 
2408     omap_pwl_reset(s);
2409 
2410     memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s,
2411                           "omap-pwl", 0x800);
2412     memory_region_add_subregion(system_memory, base, &s->iomem);
2413 
2414     omap_clk_adduser(clk, qemu_allocate_irq(omap_pwl_clk_update, s, 0));
2415     return s;
2416 }
2417 
2418 /* Pulse-Width Tone module */
2419 struct omap_pwt_s {
2420     MemoryRegion iomem;
2421     uint8_t frc;
2422     uint8_t vrc;
2423     uint8_t gcr;
2424     omap_clk clk;
2425 };
2426 
2427 static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
2428                               unsigned size)
2429 {
2430     struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
2431     int offset = addr & OMAP_MPUI_REG_MASK;
2432 
2433     if (size != 1) {
2434         return omap_badwidth_read8(opaque, addr);
2435     }
2436 
2437     switch (offset) {
2438     case 0x00:	/* FRC */
2439         return s->frc;
2440     case 0x04:	/* VCR */
2441         return s->vrc;
2442     case 0x08:	/* GCR */
2443         return s->gcr;
2444     }
2445     OMAP_BAD_REG(addr);
2446     return 0;
2447 }
2448 
2449 static void omap_pwt_write(void *opaque, hwaddr addr,
2450                            uint64_t value, unsigned size)
2451 {
2452     struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
2453     int offset = addr & OMAP_MPUI_REG_MASK;
2454 
2455     if (size != 1) {
2456         omap_badwidth_write8(opaque, addr, value);
2457         return;
2458     }
2459 
2460     switch (offset) {
2461     case 0x00:	/* FRC */
2462         s->frc = value & 0x3f;
2463         break;
2464     case 0x04:	/* VRC */
2465         if ((value ^ s->vrc) & 1) {
2466             if (value & 1)
2467                 printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
2468                                 /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
2469                                 ((omap_clk_getrate(s->clk) >> 3) /
2470                                  /* Pre-multiplexer divider */
2471                                  ((s->gcr & 2) ? 1 : 154) /
2472                                  /* Octave multiplexer */
2473                                  (2 << (value & 3)) *
2474                                  /* 101/107 divider */
2475                                  ((value & (1 << 2)) ? 101 : 107) *
2476                                  /*  49/55 divider */
2477                                  ((value & (1 << 3)) ?  49 : 55) *
2478                                  /*  50/63 divider */
2479                                  ((value & (1 << 4)) ?  50 : 63) *
2480                                  /*  80/127 divider */
2481                                  ((value & (1 << 5)) ?  80 : 127) /
2482                                  (107 * 55 * 63 * 127)));
2483             else
2484                 printf("%s: silence!\n", __FUNCTION__);
2485         }
2486         s->vrc = value & 0x7f;
2487         break;
2488     case 0x08:	/* GCR */
2489         s->gcr = value & 3;
2490         break;
2491     default:
2492         OMAP_BAD_REG(addr);
2493         return;
2494     }
2495 }
2496 
2497 static const MemoryRegionOps omap_pwt_ops = {
2498     .read =omap_pwt_read,
2499     .write = omap_pwt_write,
2500     .endianness = DEVICE_NATIVE_ENDIAN,
2501 };
2502 
2503 static void omap_pwt_reset(struct omap_pwt_s *s)
2504 {
2505     s->frc = 0;
2506     s->vrc = 0;
2507     s->gcr = 0;
2508 }
2509 
2510 static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
2511                                         hwaddr base,
2512                                         omap_clk clk)
2513 {
2514     struct omap_pwt_s *s = g_malloc0(sizeof(*s));
2515     s->clk = clk;
2516     omap_pwt_reset(s);
2517 
2518     memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s,
2519                           "omap-pwt", 0x800);
2520     memory_region_add_subregion(system_memory, base, &s->iomem);
2521     return s;
2522 }
2523 
2524 /* Real-time Clock module */
2525 struct omap_rtc_s {
2526     MemoryRegion iomem;
2527     qemu_irq irq;
2528     qemu_irq alarm;
2529     QEMUTimer *clk;
2530 
2531     uint8_t interrupts;
2532     uint8_t status;
2533     int16_t comp_reg;
2534     int running;
2535     int pm_am;
2536     int auto_comp;
2537     int round;
2538     struct tm alarm_tm;
2539     time_t alarm_ti;
2540 
2541     struct tm current_tm;
2542     time_t ti;
2543     uint64_t tick;
2544 };
2545 
2546 static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2547 {
2548     /* s->alarm is level-triggered */
2549     qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2550 }
2551 
2552 static void omap_rtc_alarm_update(struct omap_rtc_s *s)
2553 {
2554     s->alarm_ti = mktimegm(&s->alarm_tm);
2555     if (s->alarm_ti == -1)
2556         printf("%s: conversion failed\n", __FUNCTION__);
2557 }
2558 
2559 static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
2560                               unsigned size)
2561 {
2562     struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2563     int offset = addr & OMAP_MPUI_REG_MASK;
2564     uint8_t i;
2565 
2566     if (size != 1) {
2567         return omap_badwidth_read8(opaque, addr);
2568     }
2569 
2570     switch (offset) {
2571     case 0x00:	/* SECONDS_REG */
2572         return to_bcd(s->current_tm.tm_sec);
2573 
2574     case 0x04:	/* MINUTES_REG */
2575         return to_bcd(s->current_tm.tm_min);
2576 
2577     case 0x08:	/* HOURS_REG */
2578         if (s->pm_am)
2579             return ((s->current_tm.tm_hour > 11) << 7) |
2580                     to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
2581         else
2582             return to_bcd(s->current_tm.tm_hour);
2583 
2584     case 0x0c:	/* DAYS_REG */
2585         return to_bcd(s->current_tm.tm_mday);
2586 
2587     case 0x10:	/* MONTHS_REG */
2588         return to_bcd(s->current_tm.tm_mon + 1);
2589 
2590     case 0x14:	/* YEARS_REG */
2591         return to_bcd(s->current_tm.tm_year % 100);
2592 
2593     case 0x18:	/* WEEK_REG */
2594         return s->current_tm.tm_wday;
2595 
2596     case 0x20:	/* ALARM_SECONDS_REG */
2597         return to_bcd(s->alarm_tm.tm_sec);
2598 
2599     case 0x24:	/* ALARM_MINUTES_REG */
2600         return to_bcd(s->alarm_tm.tm_min);
2601 
2602     case 0x28:	/* ALARM_HOURS_REG */
2603         if (s->pm_am)
2604             return ((s->alarm_tm.tm_hour > 11) << 7) |
2605                     to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
2606         else
2607             return to_bcd(s->alarm_tm.tm_hour);
2608 
2609     case 0x2c:	/* ALARM_DAYS_REG */
2610         return to_bcd(s->alarm_tm.tm_mday);
2611 
2612     case 0x30:	/* ALARM_MONTHS_REG */
2613         return to_bcd(s->alarm_tm.tm_mon + 1);
2614 
2615     case 0x34:	/* ALARM_YEARS_REG */
2616         return to_bcd(s->alarm_tm.tm_year % 100);
2617 
2618     case 0x40:	/* RTC_CTRL_REG */
2619         return (s->pm_am << 3) | (s->auto_comp << 2) |
2620                 (s->round << 1) | s->running;
2621 
2622     case 0x44:	/* RTC_STATUS_REG */
2623         i = s->status;
2624         s->status &= ~0x3d;
2625         return i;
2626 
2627     case 0x48:	/* RTC_INTERRUPTS_REG */
2628         return s->interrupts;
2629 
2630     case 0x4c:	/* RTC_COMP_LSB_REG */
2631         return ((uint16_t) s->comp_reg) & 0xff;
2632 
2633     case 0x50:	/* RTC_COMP_MSB_REG */
2634         return ((uint16_t) s->comp_reg) >> 8;
2635     }
2636 
2637     OMAP_BAD_REG(addr);
2638     return 0;
2639 }
2640 
2641 static void omap_rtc_write(void *opaque, hwaddr addr,
2642                            uint64_t value, unsigned size)
2643 {
2644     struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2645     int offset = addr & OMAP_MPUI_REG_MASK;
2646     struct tm new_tm;
2647     time_t ti[2];
2648 
2649     if (size != 1) {
2650         omap_badwidth_write8(opaque, addr, value);
2651         return;
2652     }
2653 
2654     switch (offset) {
2655     case 0x00:	/* SECONDS_REG */
2656 #ifdef ALMDEBUG
2657         printf("RTC SEC_REG <-- %02x\n", value);
2658 #endif
2659         s->ti -= s->current_tm.tm_sec;
2660         s->ti += from_bcd(value);
2661         return;
2662 
2663     case 0x04:	/* MINUTES_REG */
2664 #ifdef ALMDEBUG
2665         printf("RTC MIN_REG <-- %02x\n", value);
2666 #endif
2667         s->ti -= s->current_tm.tm_min * 60;
2668         s->ti += from_bcd(value) * 60;
2669         return;
2670 
2671     case 0x08:	/* HOURS_REG */
2672 #ifdef ALMDEBUG
2673         printf("RTC HRS_REG <-- %02x\n", value);
2674 #endif
2675         s->ti -= s->current_tm.tm_hour * 3600;
2676         if (s->pm_am) {
2677             s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
2678             s->ti += ((value >> 7) & 1) * 43200;
2679         } else
2680             s->ti += from_bcd(value & 0x3f) * 3600;
2681         return;
2682 
2683     case 0x0c:	/* DAYS_REG */
2684 #ifdef ALMDEBUG
2685         printf("RTC DAY_REG <-- %02x\n", value);
2686 #endif
2687         s->ti -= s->current_tm.tm_mday * 86400;
2688         s->ti += from_bcd(value) * 86400;
2689         return;
2690 
2691     case 0x10:	/* MONTHS_REG */
2692 #ifdef ALMDEBUG
2693         printf("RTC MTH_REG <-- %02x\n", value);
2694 #endif
2695         memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2696         new_tm.tm_mon = from_bcd(value);
2697         ti[0] = mktimegm(&s->current_tm);
2698         ti[1] = mktimegm(&new_tm);
2699 
2700         if (ti[0] != -1 && ti[1] != -1) {
2701             s->ti -= ti[0];
2702             s->ti += ti[1];
2703         } else {
2704             /* A less accurate version */
2705             s->ti -= s->current_tm.tm_mon * 2592000;
2706             s->ti += from_bcd(value) * 2592000;
2707         }
2708         return;
2709 
2710     case 0x14:	/* YEARS_REG */
2711 #ifdef ALMDEBUG
2712         printf("RTC YRS_REG <-- %02x\n", value);
2713 #endif
2714         memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2715         new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
2716         ti[0] = mktimegm(&s->current_tm);
2717         ti[1] = mktimegm(&new_tm);
2718 
2719         if (ti[0] != -1 && ti[1] != -1) {
2720             s->ti -= ti[0];
2721             s->ti += ti[1];
2722         } else {
2723             /* A less accurate version */
2724             s->ti -= (time_t)(s->current_tm.tm_year % 100) * 31536000;
2725             s->ti += (time_t)from_bcd(value) * 31536000;
2726         }
2727         return;
2728 
2729     case 0x18:	/* WEEK_REG */
2730         return;	/* Ignored */
2731 
2732     case 0x20:	/* ALARM_SECONDS_REG */
2733 #ifdef ALMDEBUG
2734         printf("ALM SEC_REG <-- %02x\n", value);
2735 #endif
2736         s->alarm_tm.tm_sec = from_bcd(value);
2737         omap_rtc_alarm_update(s);
2738         return;
2739 
2740     case 0x24:	/* ALARM_MINUTES_REG */
2741 #ifdef ALMDEBUG
2742         printf("ALM MIN_REG <-- %02x\n", value);
2743 #endif
2744         s->alarm_tm.tm_min = from_bcd(value);
2745         omap_rtc_alarm_update(s);
2746         return;
2747 
2748     case 0x28:	/* ALARM_HOURS_REG */
2749 #ifdef ALMDEBUG
2750         printf("ALM HRS_REG <-- %02x\n", value);
2751 #endif
2752         if (s->pm_am)
2753             s->alarm_tm.tm_hour =
2754                     ((from_bcd(value & 0x3f)) % 12) +
2755                     ((value >> 7) & 1) * 12;
2756         else
2757             s->alarm_tm.tm_hour = from_bcd(value);
2758         omap_rtc_alarm_update(s);
2759         return;
2760 
2761     case 0x2c:	/* ALARM_DAYS_REG */
2762 #ifdef ALMDEBUG
2763         printf("ALM DAY_REG <-- %02x\n", value);
2764 #endif
2765         s->alarm_tm.tm_mday = from_bcd(value);
2766         omap_rtc_alarm_update(s);
2767         return;
2768 
2769     case 0x30:	/* ALARM_MONTHS_REG */
2770 #ifdef ALMDEBUG
2771         printf("ALM MON_REG <-- %02x\n", value);
2772 #endif
2773         s->alarm_tm.tm_mon = from_bcd(value);
2774         omap_rtc_alarm_update(s);
2775         return;
2776 
2777     case 0x34:	/* ALARM_YEARS_REG */
2778 #ifdef ALMDEBUG
2779         printf("ALM YRS_REG <-- %02x\n", value);
2780 #endif
2781         s->alarm_tm.tm_year = from_bcd(value);
2782         omap_rtc_alarm_update(s);
2783         return;
2784 
2785     case 0x40:	/* RTC_CTRL_REG */
2786 #ifdef ALMDEBUG
2787         printf("RTC CONTROL <-- %02x\n", value);
2788 #endif
2789         s->pm_am = (value >> 3) & 1;
2790         s->auto_comp = (value >> 2) & 1;
2791         s->round = (value >> 1) & 1;
2792         s->running = value & 1;
2793         s->status &= 0xfd;
2794         s->status |= s->running << 1;
2795         return;
2796 
2797     case 0x44:	/* RTC_STATUS_REG */
2798 #ifdef ALMDEBUG
2799         printf("RTC STATUSL <-- %02x\n", value);
2800 #endif
2801         s->status &= ~((value & 0xc0) ^ 0x80);
2802         omap_rtc_interrupts_update(s);
2803         return;
2804 
2805     case 0x48:	/* RTC_INTERRUPTS_REG */
2806 #ifdef ALMDEBUG
2807         printf("RTC INTRS <-- %02x\n", value);
2808 #endif
2809         s->interrupts = value;
2810         return;
2811 
2812     case 0x4c:	/* RTC_COMP_LSB_REG */
2813 #ifdef ALMDEBUG
2814         printf("RTC COMPLSB <-- %02x\n", value);
2815 #endif
2816         s->comp_reg &= 0xff00;
2817         s->comp_reg |= 0x00ff & value;
2818         return;
2819 
2820     case 0x50:	/* RTC_COMP_MSB_REG */
2821 #ifdef ALMDEBUG
2822         printf("RTC COMPMSB <-- %02x\n", value);
2823 #endif
2824         s->comp_reg &= 0x00ff;
2825         s->comp_reg |= 0xff00 & (value << 8);
2826         return;
2827 
2828     default:
2829         OMAP_BAD_REG(addr);
2830         return;
2831     }
2832 }
2833 
2834 static const MemoryRegionOps omap_rtc_ops = {
2835     .read = omap_rtc_read,
2836     .write = omap_rtc_write,
2837     .endianness = DEVICE_NATIVE_ENDIAN,
2838 };
2839 
2840 static void omap_rtc_tick(void *opaque)
2841 {
2842     struct omap_rtc_s *s = opaque;
2843 
2844     if (s->round) {
2845         /* Round to nearest full minute.  */
2846         if (s->current_tm.tm_sec < 30)
2847             s->ti -= s->current_tm.tm_sec;
2848         else
2849             s->ti += 60 - s->current_tm.tm_sec;
2850 
2851         s->round = 0;
2852     }
2853 
2854     localtime_r(&s->ti, &s->current_tm);
2855 
2856     if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2857         s->status |= 0x40;
2858         omap_rtc_interrupts_update(s);
2859     }
2860 
2861     if (s->interrupts & 0x04)
2862         switch (s->interrupts & 3) {
2863         case 0:
2864             s->status |= 0x04;
2865             qemu_irq_pulse(s->irq);
2866             break;
2867         case 1:
2868             if (s->current_tm.tm_sec)
2869                 break;
2870             s->status |= 0x08;
2871             qemu_irq_pulse(s->irq);
2872             break;
2873         case 2:
2874             if (s->current_tm.tm_sec || s->current_tm.tm_min)
2875                 break;
2876             s->status |= 0x10;
2877             qemu_irq_pulse(s->irq);
2878             break;
2879         case 3:
2880             if (s->current_tm.tm_sec ||
2881                             s->current_tm.tm_min || s->current_tm.tm_hour)
2882                 break;
2883             s->status |= 0x20;
2884             qemu_irq_pulse(s->irq);
2885             break;
2886         }
2887 
2888     /* Move on */
2889     if (s->running)
2890         s->ti ++;
2891     s->tick += 1000;
2892 
2893     /*
2894      * Every full hour add a rough approximation of the compensation
2895      * register to the 32kHz Timer (which drives the RTC) value.
2896      */
2897     if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
2898         s->tick += s->comp_reg * 1000 / 32768;
2899 
2900     timer_mod(s->clk, s->tick);
2901 }
2902 
2903 static void omap_rtc_reset(struct omap_rtc_s *s)
2904 {
2905     struct tm tm;
2906 
2907     s->interrupts = 0;
2908     s->comp_reg = 0;
2909     s->running = 0;
2910     s->pm_am = 0;
2911     s->auto_comp = 0;
2912     s->round = 0;
2913     s->tick = qemu_clock_get_ms(rtc_clock);
2914     memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
2915     s->alarm_tm.tm_mday = 0x01;
2916     s->status = 1 << 7;
2917     qemu_get_timedate(&tm, 0);
2918     s->ti = mktimegm(&tm);
2919 
2920     omap_rtc_alarm_update(s);
2921     omap_rtc_tick(s);
2922 }
2923 
2924 static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
2925                                         hwaddr base,
2926                                         qemu_irq timerirq, qemu_irq alarmirq,
2927                                         omap_clk clk)
2928 {
2929     struct omap_rtc_s *s = g_new0(struct omap_rtc_s, 1);
2930 
2931     s->irq = timerirq;
2932     s->alarm = alarmirq;
2933     s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);
2934 
2935     omap_rtc_reset(s);
2936 
2937     memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,
2938                           "omap-rtc", 0x800);
2939     memory_region_add_subregion(system_memory, base, &s->iomem);
2940 
2941     return s;
2942 }
2943 
2944 /* Multi-channel Buffered Serial Port interfaces */
2945 struct omap_mcbsp_s {
2946     MemoryRegion iomem;
2947     qemu_irq txirq;
2948     qemu_irq rxirq;
2949     qemu_irq txdrq;
2950     qemu_irq rxdrq;
2951 
2952     uint16_t spcr[2];
2953     uint16_t rcr[2];
2954     uint16_t xcr[2];
2955     uint16_t srgr[2];
2956     uint16_t mcr[2];
2957     uint16_t pcr;
2958     uint16_t rcer[8];
2959     uint16_t xcer[8];
2960     int tx_rate;
2961     int rx_rate;
2962     int tx_req;
2963     int rx_req;
2964 
2965     I2SCodec *codec;
2966     QEMUTimer *source_timer;
2967     QEMUTimer *sink_timer;
2968 };
2969 
2970 static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2971 {
2972     int irq;
2973 
2974     switch ((s->spcr[0] >> 4) & 3) {			/* RINTM */
2975     case 0:
2976         irq = (s->spcr[0] >> 1) & 1;			/* RRDY */
2977         break;
2978     case 3:
2979         irq = (s->spcr[0] >> 3) & 1;			/* RSYNCERR */
2980         break;
2981     default:
2982         irq = 0;
2983         break;
2984     }
2985 
2986     if (irq)
2987         qemu_irq_pulse(s->rxirq);
2988 
2989     switch ((s->spcr[1] >> 4) & 3) {			/* XINTM */
2990     case 0:
2991         irq = (s->spcr[1] >> 1) & 1;			/* XRDY */
2992         break;
2993     case 3:
2994         irq = (s->spcr[1] >> 3) & 1;			/* XSYNCERR */
2995         break;
2996     default:
2997         irq = 0;
2998         break;
2999     }
3000 
3001     if (irq)
3002         qemu_irq_pulse(s->txirq);
3003 }
3004 
3005 static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
3006 {
3007     if ((s->spcr[0] >> 1) & 1)				/* RRDY */
3008         s->spcr[0] |= 1 << 2;				/* RFULL */
3009     s->spcr[0] |= 1 << 1;				/* RRDY */
3010     qemu_irq_raise(s->rxdrq);
3011     omap_mcbsp_intr_update(s);
3012 }
3013 
3014 static void omap_mcbsp_source_tick(void *opaque)
3015 {
3016     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3017     static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3018 
3019     if (!s->rx_rate)
3020         return;
3021     if (s->rx_req)
3022         printf("%s: Rx FIFO overrun\n", __FUNCTION__);
3023 
3024     s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
3025 
3026     omap_mcbsp_rx_newdata(s);
3027     timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
3028                    get_ticks_per_sec());
3029 }
3030 
3031 static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3032 {
3033     if (!s->codec || !s->codec->rts)
3034         omap_mcbsp_source_tick(s);
3035     else if (s->codec->in.len) {
3036         s->rx_req = s->codec->in.len;
3037         omap_mcbsp_rx_newdata(s);
3038     }
3039 }
3040 
3041 static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3042 {
3043     timer_del(s->source_timer);
3044 }
3045 
3046 static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3047 {
3048     s->spcr[0] &= ~(1 << 1);				/* RRDY */
3049     qemu_irq_lower(s->rxdrq);
3050     omap_mcbsp_intr_update(s);
3051 }
3052 
3053 static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3054 {
3055     s->spcr[1] |= 1 << 1;				/* XRDY */
3056     qemu_irq_raise(s->txdrq);
3057     omap_mcbsp_intr_update(s);
3058 }
3059 
3060 static void omap_mcbsp_sink_tick(void *opaque)
3061 {
3062     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3063     static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3064 
3065     if (!s->tx_rate)
3066         return;
3067     if (s->tx_req)
3068         printf("%s: Tx FIFO underrun\n", __FUNCTION__);
3069 
3070     s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
3071 
3072     omap_mcbsp_tx_newdata(s);
3073     timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
3074                    get_ticks_per_sec());
3075 }
3076 
3077 static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3078 {
3079     if (!s->codec || !s->codec->cts)
3080         omap_mcbsp_sink_tick(s);
3081     else if (s->codec->out.size) {
3082         s->tx_req = s->codec->out.size;
3083         omap_mcbsp_tx_newdata(s);
3084     }
3085 }
3086 
3087 static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3088 {
3089     s->spcr[1] &= ~(1 << 1);				/* XRDY */
3090     qemu_irq_lower(s->txdrq);
3091     omap_mcbsp_intr_update(s);
3092     if (s->codec && s->codec->cts)
3093         s->codec->tx_swallow(s->codec->opaque);
3094 }
3095 
3096 static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3097 {
3098     s->tx_req = 0;
3099     omap_mcbsp_tx_done(s);
3100     timer_del(s->sink_timer);
3101 }
3102 
3103 static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3104 {
3105     int prev_rx_rate, prev_tx_rate;
3106     int rx_rate = 0, tx_rate = 0;
3107     int cpu_rate = 1500000;	/* XXX */
3108 
3109     /* TODO: check CLKSTP bit */
3110     if (s->spcr[1] & (1 << 6)) {			/* GRST */
3111         if (s->spcr[0] & (1 << 0)) {			/* RRST */
3112             if ((s->srgr[1] & (1 << 13)) &&		/* CLKSM */
3113                             (s->pcr & (1 << 8))) {	/* CLKRM */
3114                 if (~s->pcr & (1 << 7))			/* SCLKME */
3115                     rx_rate = cpu_rate /
3116                             ((s->srgr[0] & 0xff) + 1);	/* CLKGDV */
3117             } else
3118                 if (s->codec)
3119                     rx_rate = s->codec->rx_rate;
3120         }
3121 
3122         if (s->spcr[1] & (1 << 0)) {			/* XRST */
3123             if ((s->srgr[1] & (1 << 13)) &&		/* CLKSM */
3124                             (s->pcr & (1 << 9))) {	/* CLKXM */
3125                 if (~s->pcr & (1 << 7))			/* SCLKME */
3126                     tx_rate = cpu_rate /
3127                             ((s->srgr[0] & 0xff) + 1);	/* CLKGDV */
3128             } else
3129                 if (s->codec)
3130                     tx_rate = s->codec->tx_rate;
3131         }
3132     }
3133     prev_tx_rate = s->tx_rate;
3134     prev_rx_rate = s->rx_rate;
3135     s->tx_rate = tx_rate;
3136     s->rx_rate = rx_rate;
3137 
3138     if (s->codec)
3139         s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3140 
3141     if (!prev_tx_rate && tx_rate)
3142         omap_mcbsp_tx_start(s);
3143     else if (s->tx_rate && !tx_rate)
3144         omap_mcbsp_tx_stop(s);
3145 
3146     if (!prev_rx_rate && rx_rate)
3147         omap_mcbsp_rx_start(s);
3148     else if (prev_tx_rate && !tx_rate)
3149         omap_mcbsp_rx_stop(s);
3150 }
3151 
3152 static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
3153                                 unsigned size)
3154 {
3155     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3156     int offset = addr & OMAP_MPUI_REG_MASK;
3157     uint16_t ret;
3158 
3159     if (size != 2) {
3160         return omap_badwidth_read16(opaque, addr);
3161     }
3162 
3163     switch (offset) {
3164     case 0x00:	/* DRR2 */
3165         if (((s->rcr[0] >> 5) & 7) < 3)			/* RWDLEN1 */
3166             return 0x0000;
3167         /* Fall through.  */
3168     case 0x02:	/* DRR1 */
3169         if (s->rx_req < 2) {
3170             printf("%s: Rx FIFO underrun\n", __FUNCTION__);
3171             omap_mcbsp_rx_done(s);
3172         } else {
3173             s->tx_req -= 2;
3174             if (s->codec && s->codec->in.len >= 2) {
3175                 ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3176                 ret |= s->codec->in.fifo[s->codec->in.start ++];
3177                 s->codec->in.len -= 2;
3178             } else
3179                 ret = 0x0000;
3180             if (!s->tx_req)
3181                 omap_mcbsp_rx_done(s);
3182             return ret;
3183         }
3184         return 0x0000;
3185 
3186     case 0x04:	/* DXR2 */
3187     case 0x06:	/* DXR1 */
3188         return 0x0000;
3189 
3190     case 0x08:	/* SPCR2 */
3191         return s->spcr[1];
3192     case 0x0a:	/* SPCR1 */
3193         return s->spcr[0];
3194     case 0x0c:	/* RCR2 */
3195         return s->rcr[1];
3196     case 0x0e:	/* RCR1 */
3197         return s->rcr[0];
3198     case 0x10:	/* XCR2 */
3199         return s->xcr[1];
3200     case 0x12:	/* XCR1 */
3201         return s->xcr[0];
3202     case 0x14:	/* SRGR2 */
3203         return s->srgr[1];
3204     case 0x16:	/* SRGR1 */
3205         return s->srgr[0];
3206     case 0x18:	/* MCR2 */
3207         return s->mcr[1];
3208     case 0x1a:	/* MCR1 */
3209         return s->mcr[0];
3210     case 0x1c:	/* RCERA */
3211         return s->rcer[0];
3212     case 0x1e:	/* RCERB */
3213         return s->rcer[1];
3214     case 0x20:	/* XCERA */
3215         return s->xcer[0];
3216     case 0x22:	/* XCERB */
3217         return s->xcer[1];
3218     case 0x24:	/* PCR0 */
3219         return s->pcr;
3220     case 0x26:	/* RCERC */
3221         return s->rcer[2];
3222     case 0x28:	/* RCERD */
3223         return s->rcer[3];
3224     case 0x2a:	/* XCERC */
3225         return s->xcer[2];
3226     case 0x2c:	/* XCERD */
3227         return s->xcer[3];
3228     case 0x2e:	/* RCERE */
3229         return s->rcer[4];
3230     case 0x30:	/* RCERF */
3231         return s->rcer[5];
3232     case 0x32:	/* XCERE */
3233         return s->xcer[4];
3234     case 0x34:	/* XCERF */
3235         return s->xcer[5];
3236     case 0x36:	/* RCERG */
3237         return s->rcer[6];
3238     case 0x38:	/* RCERH */
3239         return s->rcer[7];
3240     case 0x3a:	/* XCERG */
3241         return s->xcer[6];
3242     case 0x3c:	/* XCERH */
3243         return s->xcer[7];
3244     }
3245 
3246     OMAP_BAD_REG(addr);
3247     return 0;
3248 }
3249 
3250 static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
3251                 uint32_t value)
3252 {
3253     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3254     int offset = addr & OMAP_MPUI_REG_MASK;
3255 
3256     switch (offset) {
3257     case 0x00:	/* DRR2 */
3258     case 0x02:	/* DRR1 */
3259         OMAP_RO_REG(addr);
3260         return;
3261 
3262     case 0x04:	/* DXR2 */
3263         if (((s->xcr[0] >> 5) & 7) < 3)			/* XWDLEN1 */
3264             return;
3265         /* Fall through.  */
3266     case 0x06:	/* DXR1 */
3267         if (s->tx_req > 1) {
3268             s->tx_req -= 2;
3269             if (s->codec && s->codec->cts) {
3270                 s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
3271                 s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
3272             }
3273             if (s->tx_req < 2)
3274                 omap_mcbsp_tx_done(s);
3275         } else
3276             printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3277         return;
3278 
3279     case 0x08:	/* SPCR2 */
3280         s->spcr[1] &= 0x0002;
3281         s->spcr[1] |= 0x03f9 & value;
3282         s->spcr[1] |= 0x0004 & (value << 2);		/* XEMPTY := XRST */
3283         if (~value & 1)					/* XRST */
3284             s->spcr[1] &= ~6;
3285         omap_mcbsp_req_update(s);
3286         return;
3287     case 0x0a:	/* SPCR1 */
3288         s->spcr[0] &= 0x0006;
3289         s->spcr[0] |= 0xf8f9 & value;
3290         if (value & (1 << 15))				/* DLB */
3291             printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
3292         if (~value & 1) {				/* RRST */
3293             s->spcr[0] &= ~6;
3294             s->rx_req = 0;
3295             omap_mcbsp_rx_done(s);
3296         }
3297         omap_mcbsp_req_update(s);
3298         return;
3299 
3300     case 0x0c:	/* RCR2 */
3301         s->rcr[1] = value & 0xffff;
3302         return;
3303     case 0x0e:	/* RCR1 */
3304         s->rcr[0] = value & 0x7fe0;
3305         return;
3306     case 0x10:	/* XCR2 */
3307         s->xcr[1] = value & 0xffff;
3308         return;
3309     case 0x12:	/* XCR1 */
3310         s->xcr[0] = value & 0x7fe0;
3311         return;
3312     case 0x14:	/* SRGR2 */
3313         s->srgr[1] = value & 0xffff;
3314         omap_mcbsp_req_update(s);
3315         return;
3316     case 0x16:	/* SRGR1 */
3317         s->srgr[0] = value & 0xffff;
3318         omap_mcbsp_req_update(s);
3319         return;
3320     case 0x18:	/* MCR2 */
3321         s->mcr[1] = value & 0x03e3;
3322         if (value & 3)					/* XMCM */
3323             printf("%s: Tx channel selection mode enable attempt\n",
3324                             __FUNCTION__);
3325         return;
3326     case 0x1a:	/* MCR1 */
3327         s->mcr[0] = value & 0x03e1;
3328         if (value & 1)					/* RMCM */
3329             printf("%s: Rx channel selection mode enable attempt\n",
3330                             __FUNCTION__);
3331         return;
3332     case 0x1c:	/* RCERA */
3333         s->rcer[0] = value & 0xffff;
3334         return;
3335     case 0x1e:	/* RCERB */
3336         s->rcer[1] = value & 0xffff;
3337         return;
3338     case 0x20:	/* XCERA */
3339         s->xcer[0] = value & 0xffff;
3340         return;
3341     case 0x22:	/* XCERB */
3342         s->xcer[1] = value & 0xffff;
3343         return;
3344     case 0x24:	/* PCR0 */
3345         s->pcr = value & 0x7faf;
3346         return;
3347     case 0x26:	/* RCERC */
3348         s->rcer[2] = value & 0xffff;
3349         return;
3350     case 0x28:	/* RCERD */
3351         s->rcer[3] = value & 0xffff;
3352         return;
3353     case 0x2a:	/* XCERC */
3354         s->xcer[2] = value & 0xffff;
3355         return;
3356     case 0x2c:	/* XCERD */
3357         s->xcer[3] = value & 0xffff;
3358         return;
3359     case 0x2e:	/* RCERE */
3360         s->rcer[4] = value & 0xffff;
3361         return;
3362     case 0x30:	/* RCERF */
3363         s->rcer[5] = value & 0xffff;
3364         return;
3365     case 0x32:	/* XCERE */
3366         s->xcer[4] = value & 0xffff;
3367         return;
3368     case 0x34:	/* XCERF */
3369         s->xcer[5] = value & 0xffff;
3370         return;
3371     case 0x36:	/* RCERG */
3372         s->rcer[6] = value & 0xffff;
3373         return;
3374     case 0x38:	/* RCERH */
3375         s->rcer[7] = value & 0xffff;
3376         return;
3377     case 0x3a:	/* XCERG */
3378         s->xcer[6] = value & 0xffff;
3379         return;
3380     case 0x3c:	/* XCERH */
3381         s->xcer[7] = value & 0xffff;
3382         return;
3383     }
3384 
3385     OMAP_BAD_REG(addr);
3386 }
3387 
3388 static void omap_mcbsp_writew(void *opaque, hwaddr addr,
3389                 uint32_t value)
3390 {
3391     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3392     int offset = addr & OMAP_MPUI_REG_MASK;
3393 
3394     if (offset == 0x04) {				/* DXR */
3395         if (((s->xcr[0] >> 5) & 7) < 3)			/* XWDLEN1 */
3396             return;
3397         if (s->tx_req > 3) {
3398             s->tx_req -= 4;
3399             if (s->codec && s->codec->cts) {
3400                 s->codec->out.fifo[s->codec->out.len ++] =
3401                         (value >> 24) & 0xff;
3402                 s->codec->out.fifo[s->codec->out.len ++] =
3403                         (value >> 16) & 0xff;
3404                 s->codec->out.fifo[s->codec->out.len ++] =
3405                         (value >> 8) & 0xff;
3406                 s->codec->out.fifo[s->codec->out.len ++] =
3407                         (value >> 0) & 0xff;
3408             }
3409             if (s->tx_req < 4)
3410                 omap_mcbsp_tx_done(s);
3411         } else
3412             printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3413         return;
3414     }
3415 
3416     omap_badwidth_write16(opaque, addr, value);
3417 }
3418 
3419 static void omap_mcbsp_write(void *opaque, hwaddr addr,
3420                              uint64_t value, unsigned size)
3421 {
3422     switch (size) {
3423     case 2:
3424         omap_mcbsp_writeh(opaque, addr, value);
3425         break;
3426     case 4:
3427         omap_mcbsp_writew(opaque, addr, value);
3428         break;
3429     default:
3430         omap_badwidth_write16(opaque, addr, value);
3431     }
3432 }
3433 
3434 static const MemoryRegionOps omap_mcbsp_ops = {
3435     .read = omap_mcbsp_read,
3436     .write = omap_mcbsp_write,
3437     .endianness = DEVICE_NATIVE_ENDIAN,
3438 };
3439 
3440 static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
3441 {
3442     memset(&s->spcr, 0, sizeof(s->spcr));
3443     memset(&s->rcr, 0, sizeof(s->rcr));
3444     memset(&s->xcr, 0, sizeof(s->xcr));
3445     s->srgr[0] = 0x0001;
3446     s->srgr[1] = 0x2000;
3447     memset(&s->mcr, 0, sizeof(s->mcr));
3448     memset(&s->pcr, 0, sizeof(s->pcr));
3449     memset(&s->rcer, 0, sizeof(s->rcer));
3450     memset(&s->xcer, 0, sizeof(s->xcer));
3451     s->tx_req = 0;
3452     s->rx_req = 0;
3453     s->tx_rate = 0;
3454     s->rx_rate = 0;
3455     timer_del(s->source_timer);
3456     timer_del(s->sink_timer);
3457 }
3458 
3459 static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
3460                                             hwaddr base,
3461                                             qemu_irq txirq, qemu_irq rxirq,
3462                                             qemu_irq *dma, omap_clk clk)
3463 {
3464     struct omap_mcbsp_s *s = g_new0(struct omap_mcbsp_s, 1);
3465 
3466     s->txirq = txirq;
3467     s->rxirq = rxirq;
3468     s->txdrq = dma[0];
3469     s->rxdrq = dma[1];
3470     s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);
3471     s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);
3472     omap_mcbsp_reset(s);
3473 
3474     memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
3475     memory_region_add_subregion(system_memory, base, &s->iomem);
3476 
3477     return s;
3478 }
3479 
3480 static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3481 {
3482     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3483 
3484     if (s->rx_rate) {
3485         s->rx_req = s->codec->in.len;
3486         omap_mcbsp_rx_newdata(s);
3487     }
3488 }
3489 
3490 static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3491 {
3492     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3493 
3494     if (s->tx_rate) {
3495         s->tx_req = s->codec->out.size;
3496         omap_mcbsp_tx_newdata(s);
3497     }
3498 }
3499 
3500 void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
3501 {
3502     s->codec = slave;
3503     slave->rx_swallow = qemu_allocate_irq(omap_mcbsp_i2s_swallow, s, 0);
3504     slave->tx_start = qemu_allocate_irq(omap_mcbsp_i2s_start, s, 0);
3505 }
3506 
3507 /* LED Pulse Generators */
3508 struct omap_lpg_s {
3509     MemoryRegion iomem;
3510     QEMUTimer *tm;
3511 
3512     uint8_t control;
3513     uint8_t power;
3514     int64_t on;
3515     int64_t period;
3516     int clk;
3517     int cycle;
3518 };
3519 
3520 static void omap_lpg_tick(void *opaque)
3521 {
3522     struct omap_lpg_s *s = opaque;
3523 
3524     if (s->cycle)
3525         timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on);
3526     else
3527         timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
3528 
3529     s->cycle = !s->cycle;
3530     printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
3531 }
3532 
3533 static void omap_lpg_update(struct omap_lpg_s *s)
3534 {
3535     int64_t on, period = 1, ticks = 1000;
3536     static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
3537 
3538     if (~s->control & (1 << 6))					/* LPGRES */
3539         on = 0;
3540     else if (s->control & (1 << 7))				/* PERM_ON */
3541         on = period;
3542     else {
3543         period = muldiv64(ticks, per[s->control & 7],		/* PERCTRL */
3544                         256 / 32);
3545         on = (s->clk && s->power) ? muldiv64(ticks,
3546                         per[(s->control >> 3) & 7], 256) : 0;	/* ONCTRL */
3547     }
3548 
3549     timer_del(s->tm);
3550     if (on == period && s->on < s->period)
3551         printf("%s: LED is on\n", __FUNCTION__);
3552     else if (on == 0 && s->on)
3553         printf("%s: LED is off\n", __FUNCTION__);
3554     else if (on && (on != s->on || period != s->period)) {
3555         s->cycle = 0;
3556         s->on = on;
3557         s->period = period;
3558         omap_lpg_tick(s);
3559         return;
3560     }
3561 
3562     s->on = on;
3563     s->period = period;
3564 }
3565 
3566 static void omap_lpg_reset(struct omap_lpg_s *s)
3567 {
3568     s->control = 0x00;
3569     s->power = 0x00;
3570     s->clk = 1;
3571     omap_lpg_update(s);
3572 }
3573 
3574 static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
3575                               unsigned size)
3576 {
3577     struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3578     int offset = addr & OMAP_MPUI_REG_MASK;
3579 
3580     if (size != 1) {
3581         return omap_badwidth_read8(opaque, addr);
3582     }
3583 
3584     switch (offset) {
3585     case 0x00:	/* LCR */
3586         return s->control;
3587 
3588     case 0x04:	/* PMR */
3589         return s->power;
3590     }
3591 
3592     OMAP_BAD_REG(addr);
3593     return 0;
3594 }
3595 
3596 static void omap_lpg_write(void *opaque, hwaddr addr,
3597                            uint64_t value, unsigned size)
3598 {
3599     struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3600     int offset = addr & OMAP_MPUI_REG_MASK;
3601 
3602     if (size != 1) {
3603         omap_badwidth_write8(opaque, addr, value);
3604         return;
3605     }
3606 
3607     switch (offset) {
3608     case 0x00:	/* LCR */
3609         if (~value & (1 << 6))					/* LPGRES */
3610             omap_lpg_reset(s);
3611         s->control = value & 0xff;
3612         omap_lpg_update(s);
3613         return;
3614 
3615     case 0x04:	/* PMR */
3616         s->power = value & 0x01;
3617         omap_lpg_update(s);
3618         return;
3619 
3620     default:
3621         OMAP_BAD_REG(addr);
3622         return;
3623     }
3624 }
3625 
3626 static const MemoryRegionOps omap_lpg_ops = {
3627     .read = omap_lpg_read,
3628     .write = omap_lpg_write,
3629     .endianness = DEVICE_NATIVE_ENDIAN,
3630 };
3631 
3632 static void omap_lpg_clk_update(void *opaque, int line, int on)
3633 {
3634     struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3635 
3636     s->clk = on;
3637     omap_lpg_update(s);
3638 }
3639 
3640 static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
3641                                         hwaddr base, omap_clk clk)
3642 {
3643     struct omap_lpg_s *s = g_new0(struct omap_lpg_s, 1);
3644 
3645     s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s);
3646 
3647     omap_lpg_reset(s);
3648 
3649     memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800);
3650     memory_region_add_subregion(system_memory, base, &s->iomem);
3651 
3652     omap_clk_adduser(clk, qemu_allocate_irq(omap_lpg_clk_update, s, 0));
3653 
3654     return s;
3655 }
3656 
3657 /* MPUI Peripheral Bridge configuration */
3658 static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr,
3659                                   unsigned size)
3660 {
3661     if (size != 2) {
3662         return omap_badwidth_read16(opaque, addr);
3663     }
3664 
3665     if (addr == OMAP_MPUI_BASE)	/* CMR */
3666         return 0xfe4d;
3667 
3668     OMAP_BAD_REG(addr);
3669     return 0;
3670 }
3671 
3672 static void omap_mpui_io_write(void *opaque, hwaddr addr,
3673                                uint64_t value, unsigned size)
3674 {
3675     /* FIXME: infinite loop */
3676     omap_badwidth_write16(opaque, addr, value);
3677 }
3678 
3679 static const MemoryRegionOps omap_mpui_io_ops = {
3680     .read = omap_mpui_io_read,
3681     .write = omap_mpui_io_write,
3682     .endianness = DEVICE_NATIVE_ENDIAN,
3683 };
3684 
3685 static void omap_setup_mpui_io(MemoryRegion *system_memory,
3686                                struct omap_mpu_state_s *mpu)
3687 {
3688     memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu,
3689                           "omap-mpui-io", 0x7fff);
3690     memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
3691                                 &mpu->mpui_io_iomem);
3692 }
3693 
3694 /* General chip reset */
3695 static void omap1_mpu_reset(void *opaque)
3696 {
3697     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3698 
3699     omap_dma_reset(mpu->dma);
3700     omap_mpu_timer_reset(mpu->timer[0]);
3701     omap_mpu_timer_reset(mpu->timer[1]);
3702     omap_mpu_timer_reset(mpu->timer[2]);
3703     omap_wd_timer_reset(mpu->wdt);
3704     omap_os_timer_reset(mpu->os_timer);
3705     omap_lcdc_reset(mpu->lcd);
3706     omap_ulpd_pm_reset(mpu);
3707     omap_pin_cfg_reset(mpu);
3708     omap_mpui_reset(mpu);
3709     omap_tipb_bridge_reset(mpu->private_tipb);
3710     omap_tipb_bridge_reset(mpu->public_tipb);
3711     omap_dpll_reset(mpu->dpll[0]);
3712     omap_dpll_reset(mpu->dpll[1]);
3713     omap_dpll_reset(mpu->dpll[2]);
3714     omap_uart_reset(mpu->uart[0]);
3715     omap_uart_reset(mpu->uart[1]);
3716     omap_uart_reset(mpu->uart[2]);
3717     omap_mmc_reset(mpu->mmc);
3718     omap_mpuio_reset(mpu->mpuio);
3719     omap_uwire_reset(mpu->microwire);
3720     omap_pwl_reset(mpu->pwl);
3721     omap_pwt_reset(mpu->pwt);
3722     omap_rtc_reset(mpu->rtc);
3723     omap_mcbsp_reset(mpu->mcbsp1);
3724     omap_mcbsp_reset(mpu->mcbsp2);
3725     omap_mcbsp_reset(mpu->mcbsp3);
3726     omap_lpg_reset(mpu->led[0]);
3727     omap_lpg_reset(mpu->led[1]);
3728     omap_clkm_reset(mpu);
3729     cpu_reset(CPU(mpu->cpu));
3730 }
3731 
3732 static const struct omap_map_s {
3733     hwaddr phys_dsp;
3734     hwaddr phys_mpu;
3735     uint32_t size;
3736     const char *name;
3737 } omap15xx_dsp_mm[] = {
3738     /* Strobe 0 */
3739     { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },		/* CS0 */
3740     { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },		/* CS1 */
3741     { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },		/* CS3 */
3742     { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },	/* CS4 */
3743     { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },	/* CS5 */
3744     { 0xe1013000, 0xfffb3000, 0x800, "uWire" },			/* CS6 */
3745     { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },			/* CS7 */
3746     { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },		/* CS8 */
3747     { 0xe1014800, 0xfffb4800, 0x800, "RTC" },			/* CS9 */
3748     { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },			/* CS10 */
3749     { 0xe1015800, 0xfffb5800, 0x800, "PWL" },			/* CS11 */
3750     { 0xe1016000, 0xfffb6000, 0x800, "PWT" },			/* CS12 */
3751     { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },		/* CS14 */
3752     { 0xe1017800, 0xfffb7800, 0x800, "MMC" },			/* CS15 */
3753     { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },		/* CS18 */
3754     { 0xe1019800, 0xfffb9800, 0x800, "UART3" },			/* CS19 */
3755     { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },		/* CS25 */
3756     /* Strobe 1 */
3757     { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },			/* CS28 */
3758 
3759     { 0 }
3760 };
3761 
3762 static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
3763                                    const struct omap_map_s *map)
3764 {
3765     MemoryRegion *io;
3766 
3767     for (; map->phys_dsp; map ++) {
3768         io = g_new(MemoryRegion, 1);
3769         memory_region_init_alias(io, NULL, map->name,
3770                                  system_memory, map->phys_mpu, map->size);
3771         memory_region_add_subregion(system_memory, map->phys_dsp, io);
3772     }
3773 }
3774 
3775 void omap_mpu_wakeup(void *opaque, int irq, int req)
3776 {
3777     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3778     CPUState *cpu = CPU(mpu->cpu);
3779 
3780     if (cpu->halted) {
3781         cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
3782     }
3783 }
3784 
3785 static const struct dma_irq_map omap1_dma_irq_map[] = {
3786     { 0, OMAP_INT_DMA_CH0_6 },
3787     { 0, OMAP_INT_DMA_CH1_7 },
3788     { 0, OMAP_INT_DMA_CH2_8 },
3789     { 0, OMAP_INT_DMA_CH3 },
3790     { 0, OMAP_INT_DMA_CH4 },
3791     { 0, OMAP_INT_DMA_CH5 },
3792     { 1, OMAP_INT_1610_DMA_CH6 },
3793     { 1, OMAP_INT_1610_DMA_CH7 },
3794     { 1, OMAP_INT_1610_DMA_CH8 },
3795     { 1, OMAP_INT_1610_DMA_CH9 },
3796     { 1, OMAP_INT_1610_DMA_CH10 },
3797     { 1, OMAP_INT_1610_DMA_CH11 },
3798     { 1, OMAP_INT_1610_DMA_CH12 },
3799     { 1, OMAP_INT_1610_DMA_CH13 },
3800     { 1, OMAP_INT_1610_DMA_CH14 },
3801     { 1, OMAP_INT_1610_DMA_CH15 }
3802 };
3803 
3804 /* DMA ports for OMAP1 */
3805 static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
3806                 hwaddr addr)
3807 {
3808     return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
3809 }
3810 
3811 static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
3812                 hwaddr addr)
3813 {
3814     return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
3815                              addr);
3816 }
3817 
3818 static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
3819                 hwaddr addr)
3820 {
3821     return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
3822 }
3823 
3824 static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
3825                 hwaddr addr)
3826 {
3827     return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
3828 }
3829 
3830 static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3831                 hwaddr addr)
3832 {
3833     return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
3834 }
3835 
3836 static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
3837                 hwaddr addr)
3838 {
3839     return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
3840 }
3841 
3842 struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
3843                 unsigned long sdram_size,
3844                 const char *core)
3845 {
3846     int i;
3847     struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
3848     qemu_irq dma_irqs[6];
3849     DriveInfo *dinfo;
3850     SysBusDevice *busdev;
3851 
3852     if (!core)
3853         core = "ti925t";
3854 
3855     /* Core */
3856     s->mpu_model = omap310;
3857     s->cpu = cpu_arm_init(core);
3858     if (s->cpu == NULL) {
3859         fprintf(stderr, "Unable to find CPU definition\n");
3860         exit(1);
3861     }
3862     s->sdram_size = sdram_size;
3863     s->sram_size = OMAP15XX_SRAM_SIZE;
3864 
3865     s->wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0);
3866 
3867     /* Clocks */
3868     omap_clk_init(s);
3869 
3870     /* Memory-mapped stuff */
3871     memory_region_allocate_system_memory(&s->emiff_ram, NULL, "omap1.dram",
3872                                          s->sdram_size);
3873     memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
3874     memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
3875                            &error_abort);
3876     vmstate_register_ram_global(&s->imif_ram);
3877     memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
3878 
3879     omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
3880 
3881     s->ih[0] = qdev_create(NULL, "omap-intc");
3882     qdev_prop_set_uint32(s->ih[0], "size", 0x100);
3883     qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
3884     qdev_init_nofail(s->ih[0]);
3885     busdev = SYS_BUS_DEVICE(s->ih[0]);
3886     sysbus_connect_irq(busdev, 0,
3887                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
3888     sysbus_connect_irq(busdev, 1,
3889                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
3890     sysbus_mmio_map(busdev, 0, 0xfffecb00);
3891     s->ih[1] = qdev_create(NULL, "omap-intc");
3892     qdev_prop_set_uint32(s->ih[1], "size", 0x800);
3893     qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
3894     qdev_init_nofail(s->ih[1]);
3895     busdev = SYS_BUS_DEVICE(s->ih[1]);
3896     sysbus_connect_irq(busdev, 0,
3897                        qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
3898     /* The second interrupt controller's FIQ output is not wired up */
3899     sysbus_mmio_map(busdev, 0, 0xfffe0000);
3900 
3901     for (i = 0; i < 6; i++) {
3902         dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
3903                                        omap1_dma_irq_map[i].intr);
3904     }
3905     s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory,
3906                            qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
3907                            s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
3908 
3909     s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
3910     s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
3911     s->port[imif     ].addr_valid = omap_validate_imif_addr;
3912     s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
3913     s->port[local    ].addr_valid = omap_validate_local_addr;
3914     s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
3915 
3916     /* Register SDRAM and SRAM DMA ports for fast transfers.  */
3917     soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram),
3918                          OMAP_EMIFF_BASE, s->sdram_size);
3919     soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
3920                          OMAP_IMIF_BASE, s->sram_size);
3921 
3922     s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
3923                     qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
3924                     omap_findclk(s, "mputim_ck"));
3925     s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
3926                     qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
3927                     omap_findclk(s, "mputim_ck"));
3928     s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
3929                     qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
3930                     omap_findclk(s, "mputim_ck"));
3931 
3932     s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
3933                     qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
3934                     omap_findclk(s, "armwdt_ck"));
3935 
3936     s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
3937                     qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
3938                     omap_findclk(s, "clk32-kHz"));
3939 
3940     s->lcd = omap_lcdc_init(system_memory, 0xfffec000,
3941                             qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
3942                             omap_dma_get_lcdch(s->dma),
3943                             omap_findclk(s, "lcd_ck"));
3944 
3945     omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
3946     omap_pin_cfg_init(system_memory, 0xfffe1000, s);
3947     omap_id_init(system_memory, s);
3948 
3949     omap_mpui_init(system_memory, 0xfffec900, s);
3950 
3951     s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
3952                     qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
3953                     omap_findclk(s, "tipb_ck"));
3954     s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
3955                     qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
3956                     omap_findclk(s, "tipb_ck"));
3957 
3958     omap_tcmi_init(system_memory, 0xfffecc00, s);
3959 
3960     s->uart[0] = omap_uart_init(0xfffb0000,
3961                                 qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
3962                     omap_findclk(s, "uart1_ck"),
3963                     omap_findclk(s, "uart1_ck"),
3964                     s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
3965                     "uart1",
3966                     serial_hds[0]);
3967     s->uart[1] = omap_uart_init(0xfffb0800,
3968                                 qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
3969                     omap_findclk(s, "uart2_ck"),
3970                     omap_findclk(s, "uart2_ck"),
3971                     s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
3972                     "uart2",
3973                     serial_hds[0] ? serial_hds[1] : NULL);
3974     s->uart[2] = omap_uart_init(0xfffb9800,
3975                                 qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
3976                     omap_findclk(s, "uart3_ck"),
3977                     omap_findclk(s, "uart3_ck"),
3978                     s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
3979                     "uart3",
3980                     serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
3981 
3982     s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
3983                                 omap_findclk(s, "dpll1"));
3984     s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000,
3985                                 omap_findclk(s, "dpll2"));
3986     s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100,
3987                                 omap_findclk(s, "dpll3"));
3988 
3989     dinfo = drive_get(IF_SD, 0, 0);
3990     if (!dinfo) {
3991         fprintf(stderr, "qemu: missing SecureDigital device\n");
3992         exit(1);
3993     }
3994     s->mmc = omap_mmc_init(0xfffb7800, system_memory,
3995                            blk_by_legacy_dinfo(dinfo),
3996                            qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
3997                            &s->drq[OMAP_DMA_MMC_TX],
3998                     omap_findclk(s, "mmc_ck"));
3999 
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"));
4004 
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);
4012 
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"));
4017 
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"));
4022 
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);
4032 
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"));
4037 
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"));
4052 
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"));
4057 
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
4071      */
4072 
4073     omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
4074     omap_setup_mpui_io(system_memory, s);
4075 
4076     qemu_register_reset(omap1_mpu_reset, s);
4077 
4078     return s;
4079 }
4080