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