packing update
[qemu] / hw / omap2.c
1 /*
2  * TI OMAP processors emulation.
3  *
4  * Copyright (C) 2007-2008 Nokia Corporation
5  * Written by Andrzej Zaborowski <andrew@openedhand.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 or
10  * (at your option) version 3 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 #include "hw.h"
22 #include "arm-misc.h"
23 #include "omap.h"
24 #include "sysemu.h"
25 #include "qemu-timer.h"
26 #include "qemu-char.h"
27 #include "flash.h"
28 #include "soc_dma.h"
29 #include "audio/audio.h"
30
31 /* GP timers */
32 struct omap_gp_timer_s {
33     qemu_irq irq;
34     qemu_irq wkup;
35     qemu_irq in;
36     qemu_irq out;
37     omap_clk clk;
38     QEMUTimer *timer;
39     QEMUTimer *match;
40     struct omap_target_agent_s *ta;
41
42     int in_val;
43     int out_val;
44     int64_t time;
45     int64_t rate;
46     int64_t ticks_per_sec;
47
48     int16_t config;
49     int status;
50     int it_ena;
51     int wu_ena;
52     int enable;
53     int inout;
54     int capt2;
55     int pt;
56     enum {
57         gpt_trigger_none, gpt_trigger_overflow, gpt_trigger_both
58     } trigger;
59     enum {
60         gpt_capture_none, gpt_capture_rising,
61         gpt_capture_falling, gpt_capture_both
62     } capture;
63     int scpwm;
64     int ce;
65     int pre;
66     int ptv;
67     int ar;
68     int st;
69     int posted;
70     uint32_t val;
71     uint32_t load_val;
72     uint32_t capture_val[2];
73     uint32_t match_val;
74     int capt_num;
75
76     uint16_t writeh;    /* LSB */
77     uint16_t readh;     /* MSB */
78 };
79
80 #define GPT_TCAR_IT     (1 << 2)
81 #define GPT_OVF_IT      (1 << 1)
82 #define GPT_MAT_IT      (1 << 0)
83
84 /*if the clock source of gptimer changes, rate must be regenerated*/
85 void omap_gp_timer_change_clk(struct omap_gp_timer_s *timer)
86 {
87     timer->rate = omap_clk_getrate(timer->clk);
88 }
89
90 static inline void omap_gp_timer_intr(struct omap_gp_timer_s *timer, int it)
91 {
92     if (timer->it_ena & it) {
93         if (!timer->status)
94             qemu_irq_raise(timer->irq);
95
96         timer->status |= it;
97         /* Or are the status bits set even when masked?
98          * i.e. is masking applied before or after the status register?  */
99     }
100
101     if (timer->wu_ena & it)
102         qemu_irq_pulse(timer->wkup);
103 }
104
105 static inline void omap_gp_timer_out(struct omap_gp_timer_s *timer, int level)
106 {
107     if (!timer->inout && timer->out_val != level) {
108         timer->out_val = level;
109         qemu_set_irq(timer->out, level);
110     }
111 }
112
113 static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer)
114 {
115     uint64_t distance, rate;
116
117     if (timer->st && timer->rate) {
118         distance = qemu_get_clock(vm_clock) - timer->time;
119         
120         /*if ticks_per_sec is bigger than 32bit we cannot use muldiv64*/
121         if (timer->ticks_per_sec > 0xffffffff) {
122             distance /= ticks_per_sec / 1000; /*distance ms*/
123             rate = timer->rate >> (timer->pre ? timer->ptv + 1 : 0);
124             distance = muldiv64(distance, rate, 1000);
125         } else
126             distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
127
128         if (distance >= 0xffffffff - timer->val)
129             return 0xffffffff;
130         else
131             return timer->val + distance;
132     } else
133         return timer->val;
134 }
135
136 static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer)
137 {
138     if (timer->st) {
139         timer->val = omap_gp_timer_read(timer);
140         timer->time = qemu_get_clock(vm_clock);
141     }
142 }
143
144 static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
145 {
146     int64_t expires, matches, rate;
147
148     if (timer->st && timer->rate) {
149         if (timer->ticks_per_sec > 0xffffffff) {
150             rate = timer->rate >> (timer->pre ? timer->ptv + 1 : 0); /*1s -> rate ticks*/
151             expires = muldiv64(0x100000000ll - timer->val, ticks_per_sec, rate);
152         } else
153             expires = muldiv64(0x100000000ll - timer->val,
154                         timer->ticks_per_sec, timer->rate);
155         qemu_mod_timer(timer->timer, timer->time + expires);
156
157         if (timer->ce && timer->match_val >= timer->val) {
158             if (timer->ticks_per_sec > 0xffffffff) {
159                 rate = timer->rate >> (timer->pre ? timer->ptv + 1 : 0); /*1s -> rate ticks*/
160                 matches = muldiv64(timer->match_val - timer->val, ticks_per_sec, rate);
161             } else
162                 matches = muldiv64(timer->match_val - timer->val,
163                             timer->ticks_per_sec, timer->rate);
164             qemu_mod_timer(timer->match, timer->time + matches);
165         } else
166             qemu_del_timer(timer->match);
167     } else {
168         qemu_del_timer(timer->timer);
169         qemu_del_timer(timer->match);
170         omap_gp_timer_out(timer, timer->scpwm);
171     }
172 }
173
174 static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer)
175 {
176     if (timer->pt)
177         /* TODO in overflow-and-match mode if the first event to
178          * occur is the match, don't toggle.  */
179         omap_gp_timer_out(timer, !timer->out_val);
180     else
181         /* TODO inverted pulse on timer->out_val == 1?  */
182         qemu_irq_pulse(timer->out);
183 }
184
185 static void omap_gp_timer_tick(void *opaque)
186 {
187     struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
188
189     if (!timer->ar) {
190         timer->st = 0;
191         timer->val = 0;
192     } else {
193         timer->val = timer->load_val;
194         timer->time = qemu_get_clock(vm_clock);
195     }
196
197     if (timer->trigger == gpt_trigger_overflow ||
198                     timer->trigger == gpt_trigger_both)
199         omap_gp_timer_trigger(timer);
200
201     omap_gp_timer_intr(timer, GPT_OVF_IT);
202     omap_gp_timer_update(timer);
203 }
204
205 static void omap_gp_timer_match(void *opaque)
206 {
207     struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
208
209     if (timer->trigger == gpt_trigger_both)
210         omap_gp_timer_trigger(timer);
211
212     omap_gp_timer_intr(timer, GPT_MAT_IT);
213 }
214
215 static void omap_gp_timer_input(void *opaque, int line, int on)
216 {
217     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
218     int trigger;
219
220     switch (s->capture) {
221     default:
222     case gpt_capture_none:
223         trigger = 0;
224         break;
225     case gpt_capture_rising:
226         trigger = !s->in_val && on;
227         break;
228     case gpt_capture_falling:
229         trigger = s->in_val && !on;
230         break;
231     case gpt_capture_both:
232         trigger = (s->in_val == !on);
233         break;
234     }
235     s->in_val = on;
236
237     if (s->inout && trigger && s->capt_num < 2) {
238         s->capture_val[s->capt_num] = omap_gp_timer_read(s);
239
240         if (s->capt2 == s->capt_num ++)
241             omap_gp_timer_intr(s, GPT_TCAR_IT);
242     }
243 }
244
245 static void omap_gp_timer_clk_update(void *opaque, int line, int on)
246 {
247     struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
248
249     omap_gp_timer_sync(timer);
250     timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
251     omap_gp_timer_update(timer);
252 }
253
254 static void omap_gp_timer_clk_setup(struct omap_gp_timer_s *timer)
255 {
256     omap_clk_adduser(timer->clk,
257                     qemu_allocate_irqs(omap_gp_timer_clk_update, timer, 1)[0]);
258     timer->rate = omap_clk_getrate(timer->clk);
259     //fprintf(stderr, "omap gptimer clk rate 0x%llx\n", timer->rate);
260 }
261
262 static void omap_gp_timer_reset(struct omap_gp_timer_s *s)
263 {
264     s->config = 0x000;
265     s->status = 0;
266     s->it_ena = 0;
267     s->wu_ena = 0;
268     s->inout = 0;
269     s->capt2 = 0;
270     s->capt_num = 0;
271     s->pt = 0;
272     s->trigger = gpt_trigger_none;
273     s->capture = gpt_capture_none;
274     s->scpwm = 0;
275     s->ce = 0;
276     s->pre = 0;
277     s->ptv = 0;
278     s->ar = 0;
279     s->st = 0;
280     s->posted = 1;
281     s->val = 0x00000000;
282     s->load_val = 0x00000000;
283     s->capture_val[0] = 0x00000000;
284     s->capture_val[1] = 0x00000000;
285     s->match_val = 0x00000000;
286     omap_gp_timer_update(s);
287 }
288
289 static uint32_t omap_gp_timer_readw(void *opaque, target_phys_addr_t addr)
290 {
291     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
292
293     switch (addr) {
294     case 0x00:  /* TIDR */
295         return 0x21;
296
297     case 0x10:  /* TIOCP_CFG */
298         return s->config;
299
300     case 0x14:  /* TISTAT */
301         /* ??? When's this bit reset? */
302         return 1;                                               /* RESETDONE */
303
304     case 0x18:  /* TISR */
305         return s->status;
306
307     case 0x1c:  /* TIER */
308         return s->it_ena;
309
310     case 0x20:  /* TWER */
311         return s->wu_ena;
312
313     case 0x24:  /* TCLR */
314         return (s->inout << 14) |
315                 (s->capt2 << 13) |
316                 (s->pt << 12) |
317                 (s->trigger << 10) |
318                 (s->capture << 8) |
319                 (s->scpwm << 7) |
320                 (s->ce << 6) |
321                 (s->pre << 5) |
322                 (s->ptv << 2) |
323                 (s->ar << 1) |
324                 (s->st << 0);
325
326     case 0x28:  /* TCRR */
327         return omap_gp_timer_read(s);
328
329     case 0x2c:  /* TLDR */
330         return s->load_val;
331
332     case 0x30:  /* TTGR */
333         return 0xffffffff;
334
335     case 0x34:  /* TWPS */
336         return 0x00000000;      /* No posted writes pending.  */
337
338     case 0x38:  /* TMAR */
339         return s->match_val;
340
341     case 0x3c:  /* TCAR1 */
342         return s->capture_val[0];
343
344     case 0x40:  /* TSICR */
345         return s->posted << 2;
346
347     case 0x44:  /* TCAR2 */
348         return s->capture_val[1];
349     }
350
351     OMAP_BAD_REG(addr);
352     return 0;
353 }
354
355 static uint32_t omap_gp_timer_readh(void *opaque, target_phys_addr_t addr)
356 {
357     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
358     uint32_t ret;
359
360     if (addr & 2)
361         return s->readh;
362     else {
363         ret = omap_gp_timer_readw(opaque, addr);
364         s->readh = ret >> 16;
365         return ret & 0xffff;
366     }
367 }
368
369 static CPUReadMemoryFunc *omap_gp_timer_readfn[] = {
370     omap_badwidth_read32,
371     omap_gp_timer_readh,
372     omap_gp_timer_readw,
373 };
374
375 static void omap_gp_timer_write(void *opaque, target_phys_addr_t addr,
376                 uint32_t value)
377 {
378     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
379
380     switch (addr) {
381     case 0x00:  /* TIDR */
382     case 0x14:  /* TISTAT */
383     case 0x34:  /* TWPS */
384     case 0x3c:  /* TCAR1 */
385     case 0x44:  /* TCAR2 */
386         OMAP_RO_REG(addr);
387         break;
388
389     case 0x10:  /* TIOCP_CFG */
390         s->config = value & 0x33d;
391         if (((value >> 3) & 3) == 3)                            /* IDLEMODE */
392             fprintf(stderr, "%s: illegal IDLEMODE value in TIOCP_CFG\n",
393                             __FUNCTION__);
394         if (value & 2)                                          /* SOFTRESET */
395             omap_gp_timer_reset(s);
396         break;
397
398     case 0x18:  /* TISR */
399         if (value & GPT_TCAR_IT)
400             s->capt_num = 0;
401         if (s->status && !(s->status &= ~value))
402             qemu_irq_lower(s->irq);
403         break;
404
405     case 0x1c:  /* TIER */
406         s->it_ena = value & 7;
407         break;
408
409     case 0x20:  /* TWER */
410         s->wu_ena = value & 7;
411         break;
412
413     case 0x24:  /* TCLR */
414         omap_gp_timer_sync(s);
415         s->inout = (value >> 14) & 1;
416         s->capt2 = (value >> 13) & 1;
417         s->pt = (value >> 12) & 1;
418         s->trigger = (value >> 10) & 3;
419         if (s->capture == gpt_capture_none &&
420                         ((value >> 8) & 3) != gpt_capture_none)
421             s->capt_num = 0;
422         s->capture = (value >> 8) & 3;
423         s->scpwm = (value >> 7) & 1;
424         s->ce = (value >> 6) & 1;
425         s->pre = (value >> 5) & 1;
426         s->ptv = (value >> 2) & 7;
427         s->ar = (value >> 1) & 1;
428         s->st = (value >> 0) & 1;
429         if (s->inout && s->trigger != gpt_trigger_none)
430             fprintf(stderr, "%s: GP timer pin must be an output "
431                             "for this trigger mode\n", __FUNCTION__);
432         if (!s->inout && s->capture != gpt_capture_none)
433             fprintf(stderr, "%s: GP timer pin must be an input "
434                             "for this capture mode\n", __FUNCTION__);
435         if (s->trigger == gpt_trigger_none)
436             omap_gp_timer_out(s, s->scpwm);
437         /* TODO: make sure this doesn't overflow 32-bits */
438         s->ticks_per_sec = ticks_per_sec << (s->pre ? s->ptv + 1 : 0);
439         omap_gp_timer_update(s);
440         break;
441
442     case 0x28:  /* TCRR */
443         s->time = qemu_get_clock(vm_clock);
444         s->val = value;
445         omap_gp_timer_update(s);
446         break;
447
448     case 0x2c:  /* TLDR */
449         s->load_val = value;
450         break;
451
452     case 0x30:  /* TTGR */
453         s->time = qemu_get_clock(vm_clock);
454         s->val = s->load_val;
455         omap_gp_timer_update(s);
456         break;
457
458     case 0x38:  /* TMAR */
459         omap_gp_timer_sync(s);
460         s->match_val = value;
461         omap_gp_timer_update(s);
462         break;
463
464     case 0x40:  /* TSICR */
465         s->posted = (value >> 2) & 1;
466         if (value & 2)  /* How much exactly are we supposed to reset? */
467             omap_gp_timer_reset(s);
468         break;
469
470     default:
471         OMAP_BAD_REG(addr);
472     }
473 }
474
475 static void omap_gp_timer_writeh(void *opaque, target_phys_addr_t addr,
476                 uint32_t value)
477 {
478     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
479
480     if (addr & 2)
481         return omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh);
482     else
483         s->writeh = (uint16_t) value;
484 }
485
486 static CPUWriteMemoryFunc *omap_gp_timer_writefn[] = {
487     omap_badwidth_write32,
488     omap_gp_timer_writeh,
489     omap_gp_timer_write,
490 };
491
492 struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
493                 qemu_irq irq, omap_clk fclk, omap_clk iclk)
494 {
495     int iomemtype;
496     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *)
497             qemu_mallocz(sizeof(struct omap_gp_timer_s));
498
499     s->ta = ta;
500     s->irq = irq;
501     s->clk = fclk;
502     s->timer = qemu_new_timer(vm_clock, omap_gp_timer_tick, s);
503     s->match = qemu_new_timer(vm_clock, omap_gp_timer_match, s);
504     s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0];
505     omap_gp_timer_reset(s);
506     omap_gp_timer_clk_setup(s);
507
508     iomemtype = l4_register_io_memory(0, omap_gp_timer_readfn,
509                     omap_gp_timer_writefn, s);
510     omap_l4_attach(ta, 0, iomemtype);
511
512     return s;
513 }
514
515 /* 32-kHz Sync Timer of the OMAP2 */
516 static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
517     return muldiv64(qemu_get_clock(vm_clock), 0x8000, ticks_per_sec);
518 }
519
520 static void omap_synctimer_reset(struct omap_synctimer_s *s)
521 {
522     s->val = omap_synctimer_read(s);
523 }
524
525 static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr)
526 {
527     struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
528     
529     switch (addr) {
530     case 0x00:  /* 32KSYNCNT_REV */
531         return 0x21;
532     case 0x10:  /* CR */
533         return omap_synctimer_read(s) - s->val;
534     }
535
536     OMAP_BAD_REG(addr);
537     return 0;
538 }
539
540 static uint32_t omap3_synctimer_readw(void *opaque, target_phys_addr_t addr)
541 {
542     struct omap_synctimer_s *s = (struct omap_synctimer_s *)opaque;
543     return (addr == 0x04) 
544         ? s->sysconfig 
545         : omap_synctimer_readw(opaque, addr);
546 }
547
548 static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr)
549 {
550     struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
551     uint32_t ret;
552
553     if (addr & 2)
554         return s->readh;
555
556     ret = omap_synctimer_readw(opaque, addr);
557     s->readh = ret >> 16;
558     return ret & 0xffff;
559 }
560
561 static uint32_t omap3_synctimer_readh(void *opaque, target_phys_addr_t addr)
562 {
563     struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
564     uint32_t ret;
565     
566     if (addr & 2)
567         return s->readh;
568     
569     ret = omap3_synctimer_readw(opaque, addr);
570     s->readh = ret >> 16;
571     return ret & 0xffff;
572 }
573
574 static CPUReadMemoryFunc *omap_synctimer_readfn[] = {
575     omap_badwidth_read32,
576     omap_synctimer_readh,
577     omap_synctimer_readw,
578 };
579
580 static CPUReadMemoryFunc *omap3_synctimer_readfn[] = {
581     omap_badwidth_read32,
582     omap3_synctimer_readh,
583     omap3_synctimer_readw,
584 };
585
586 static void omap_synctimer_write(void *opaque, target_phys_addr_t addr,
587                 uint32_t value)
588 {
589     OMAP_BAD_REG(addr);
590 }
591
592 static void omap3_synctimer_write(void *opaque, target_phys_addr_t addr,
593                 uint32_t value)
594 {
595     struct omap_synctimer_s *s = (struct omap_synctimer_s *)opaque;
596     if (addr == 0x04) /* SYSCONFIG */
597         s->sysconfig = value & 0x0c;
598     else
599         OMAP_BAD_REG(addr);
600 }
601
602 static CPUWriteMemoryFunc *omap_synctimer_writefn[] = {
603     omap_badwidth_write32,
604     omap_synctimer_write,
605     omap_synctimer_write,
606 };
607
608 static CPUWriteMemoryFunc *omap3_synctimer_writefn[] = {
609     omap_badwidth_write32,
610     omap3_synctimer_write,
611     omap3_synctimer_write,
612 };
613
614 void omap_synctimer_init(struct omap_target_agent_s *ta,
615                 struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
616 {
617     struct omap_synctimer_s *s = &mpu->synctimer;
618
619     omap_synctimer_reset(s);
620     if (cpu_class_omap3(mpu))
621         omap_l4_attach(ta, 0, l4_register_io_memory(0,
622                     omap3_synctimer_readfn, omap3_synctimer_writefn, s));
623     else
624         omap_l4_attach(ta, 0, l4_register_io_memory(0,
625                     omap_synctimer_readfn, omap_synctimer_writefn, s));
626 }
627
628 /* General-Purpose Interface of OMAP2 */
629 struct omap2_gpio_s {
630     qemu_irq irq[2];
631     qemu_irq wkup;
632     qemu_irq *in;
633     qemu_irq handler[32];
634
635     uint8_t revision;
636     uint8_t config[2];
637     uint32_t inputs;
638     uint32_t outputs;
639     uint32_t dir;
640     uint32_t level[2];
641     uint32_t edge[2];
642     uint32_t mask[2];
643     uint32_t wumask;
644     uint32_t ints[2];
645     uint32_t debounce;
646     uint8_t delay;
647 };
648
649 static inline void omap_gpio_module_int_update(struct omap2_gpio_s *s,
650                 int line)
651 {
652     qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
653 }
654
655 static void omap_gpio_module_wake(struct omap2_gpio_s *s, int line)
656 {
657     if (!(s->config[0] & (1 << 2)))                     /* ENAWAKEUP */
658         return;
659     if (!(s->config[0] & (3 << 3)))                     /* Force Idle */
660         return;
661     if (!(s->wumask & (1 << line)))
662         return;
663
664     qemu_irq_raise(s->wkup);
665 }
666
667 static inline void omap_gpio_module_out_update(struct omap2_gpio_s *s,
668                 uint32_t diff)
669 {
670     int ln;
671
672     s->outputs ^= diff;
673     diff &= ~s->dir;
674     while ((ln = ffs(diff))) {
675         ln --;
676         qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
677         diff &= ~(1 << ln);
678     }
679 }
680
681 static void omap_gpio_module_level_update(struct omap2_gpio_s *s, int line)
682 {
683     s->ints[line] |= s->dir &
684             ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
685     omap_gpio_module_int_update(s, line);
686 }
687
688 static inline void omap_gpio_module_int(struct omap2_gpio_s *s, int line)
689 {
690     s->ints[0] |= 1 << line;
691     omap_gpio_module_int_update(s, 0);
692     s->ints[1] |= 1 << line;
693     omap_gpio_module_int_update(s, 1);
694     omap_gpio_module_wake(s, line);
695 }
696
697 static void omap_gpio_module_set(void *opaque, int line, int level)
698 {
699     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
700
701     if (level) {
702         if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
703             omap_gpio_module_int(s, line);
704         s->inputs |= 1 << line;
705     } else {
706         if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
707             omap_gpio_module_int(s, line);
708         s->inputs &= ~(1 << line);
709     }
710 }
711
712 static void omap_gpio_module_reset(struct omap2_gpio_s *s)
713 {
714     s->config[0] = 0;
715     s->config[1] = 2;
716     s->ints[0] = 0;
717     s->ints[1] = 0;
718     s->mask[0] = 0;
719     s->mask[1] = 0;
720     s->wumask = 0;
721     s->dir = ~0;
722     s->level[0] = 0;
723     s->level[1] = 0;
724     s->edge[0] = 0;
725     s->edge[1] = 0;
726     s->debounce = 0;
727     s->delay = 0;
728 }
729
730 static uint32_t omap_gpio_module_read(void *opaque, target_phys_addr_t addr)
731 {
732     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
733
734     switch (addr) {
735     case 0x00:  /* GPIO_REVISION */
736         return s->revision;
737
738     case 0x10:  /* GPIO_SYSCONFIG */
739         return s->config[0];
740
741     case 0x14:  /* GPIO_SYSSTATUS */
742         return 0x01;
743
744     case 0x18:  /* GPIO_IRQSTATUS1 */
745         return s->ints[0];
746
747     case 0x1c:  /* GPIO_IRQENABLE1 */
748     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
749     case 0x64:  /* GPIO_SETIRQENABLE1 */
750         return s->mask[0];
751
752     case 0x20:  /* GPIO_WAKEUPENABLE */
753     case 0x80:  /* GPIO_CLEARWKUENA */
754     case 0x84:  /* GPIO_SETWKUENA */
755         return s->wumask;
756
757     case 0x28:  /* GPIO_IRQSTATUS2 */
758         return s->ints[1];
759
760     case 0x2c:  /* GPIO_IRQENABLE2 */
761     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
762     case 0x74:  /* GPIO_SETIREQNEABLE2 */
763         return s->mask[1];
764
765     case 0x30:  /* GPIO_CTRL */
766         return s->config[1];
767
768     case 0x34:  /* GPIO_OE */
769         return s->dir;
770
771     case 0x38:  /* GPIO_DATAIN */
772         return s->inputs;
773
774     case 0x3c:  /* GPIO_DATAOUT */
775     case 0x90:  /* GPIO_CLEARDATAOUT */
776     case 0x94:  /* GPIO_SETDATAOUT */
777         return s->outputs;
778
779     case 0x40:  /* GPIO_LEVELDETECT0 */
780         return s->level[0];
781
782     case 0x44:  /* GPIO_LEVELDETECT1 */
783         return s->level[1];
784
785     case 0x48:  /* GPIO_RISINGDETECT */
786         return s->edge[0];
787
788     case 0x4c:  /* GPIO_FALLINGDETECT */
789         return s->edge[1];
790
791     case 0x50:  /* GPIO_DEBOUNCENABLE */
792         return s->debounce;
793
794     case 0x54:  /* GPIO_DEBOUNCINGTIME */
795         return s->delay;
796     }
797
798     OMAP_BAD_REG(addr);
799     return 0;
800 }
801
802 static void omap_gpio_module_write(void *opaque, target_phys_addr_t addr,
803                 uint32_t value)
804 {
805     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
806     uint32_t diff;
807     int ln;
808
809     switch (addr) {
810     case 0x00:  /* GPIO_REVISION */
811     case 0x14:  /* GPIO_SYSSTATUS */
812     case 0x38:  /* GPIO_DATAIN */
813         OMAP_RO_REGV(addr, value);
814         break;
815
816     case 0x10:  /* GPIO_SYSCONFIG */
817         if (((value >> 3) & 3) == 3)
818             fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
819         if (value & 2)
820             omap_gpio_module_reset(s);
821         s->config[0] = value & 0x1d;
822         break;
823
824     case 0x18:  /* GPIO_IRQSTATUS1 */
825         if (s->ints[0] & value) {
826             s->ints[0] &= ~value;
827             omap_gpio_module_level_update(s, 0);
828         }
829         break;
830
831     case 0x1c:  /* GPIO_IRQENABLE1 */
832         s->mask[0] = value;
833         omap_gpio_module_int_update(s, 0);
834         break;
835
836     case 0x20:  /* GPIO_WAKEUPENABLE */
837         s->wumask = value;
838         break;
839
840     case 0x28:  /* GPIO_IRQSTATUS2 */
841         if (s->ints[1] & value) {
842             s->ints[1] &= ~value;
843             omap_gpio_module_level_update(s, 1);
844         }
845         break;
846
847     case 0x2c:  /* GPIO_IRQENABLE2 */
848         s->mask[1] = value;
849         omap_gpio_module_int_update(s, 1);
850         break;
851
852     case 0x30:  /* GPIO_CTRL */
853         s->config[1] = value & 7;
854         break;
855
856     case 0x34:  /* GPIO_OE */
857         diff = s->outputs & (s->dir ^ value);
858         s->dir = value;
859
860         value = s->outputs & ~s->dir;
861         while ((ln = ffs(diff))) {
862             diff &= ~(1 <<-- ln);
863             qemu_set_irq(s->handler[ln], (value >> ln) & 1);
864         }
865
866         omap_gpio_module_level_update(s, 0);
867         omap_gpio_module_level_update(s, 1);
868         break;
869
870     case 0x3c:  /* GPIO_DATAOUT */
871         omap_gpio_module_out_update(s, s->outputs ^ value);
872         break;
873
874     case 0x40:  /* GPIO_LEVELDETECT0 */
875         s->level[0] = value;
876         omap_gpio_module_level_update(s, 0);
877         omap_gpio_module_level_update(s, 1);
878         break;
879
880     case 0x44:  /* GPIO_LEVELDETECT1 */
881         s->level[1] = value;
882         omap_gpio_module_level_update(s, 0);
883         omap_gpio_module_level_update(s, 1);
884         break;
885
886     case 0x48:  /* GPIO_RISINGDETECT */
887         s->edge[0] = value;
888         break;
889
890     case 0x4c:  /* GPIO_FALLINGDETECT */
891         s->edge[1] = value;
892         break;
893
894     case 0x50:  /* GPIO_DEBOUNCENABLE */
895         s->debounce = value;
896         break;
897
898     case 0x54:  /* GPIO_DEBOUNCINGTIME */
899         s->delay = value;
900         break;
901
902     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
903         s->mask[0] &= ~value;
904         omap_gpio_module_int_update(s, 0);
905         break;
906
907     case 0x64:  /* GPIO_SETIRQENABLE1 */
908         s->mask[0] |= value;
909         omap_gpio_module_int_update(s, 0);
910         break;
911
912     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
913         s->mask[1] &= ~value;
914         omap_gpio_module_int_update(s, 1);
915         break;
916
917     case 0x74:  /* GPIO_SETIREQNEABLE2 */
918         s->mask[1] |= value;
919         omap_gpio_module_int_update(s, 1);
920         break;
921
922     case 0x80:  /* GPIO_CLEARWKUENA */
923         s->wumask &= ~value;
924         break;
925
926     case 0x84:  /* GPIO_SETWKUENA */
927         s->wumask |= value;
928         break;
929
930     case 0x90:  /* GPIO_CLEARDATAOUT */
931         omap_gpio_module_out_update(s, s->outputs & value);
932         break;
933
934     case 0x94:  /* GPIO_SETDATAOUT */
935         omap_gpio_module_out_update(s, ~s->outputs & value);
936         break;
937
938     default:
939         OMAP_BAD_REGV(addr, value);
940         return;
941     }
942 }
943
944 static uint32_t omap_gpio_module_readp(void *opaque, target_phys_addr_t addr)
945 {
946     return omap_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
947 }
948
949 static void omap_gpio_module_writep(void *opaque, target_phys_addr_t addr,
950                 uint32_t value)
951 {
952     uint32_t cur = 0;
953     uint32_t mask = 0xffff;
954
955     switch (addr & ~3) {
956     case 0x00:  /* GPIO_REVISION */
957     case 0x14:  /* GPIO_SYSSTATUS */
958     case 0x38:  /* GPIO_DATAIN */
959         OMAP_RO_REG(addr);
960         break;
961
962     case 0x10:  /* GPIO_SYSCONFIG */
963     case 0x1c:  /* GPIO_IRQENABLE1 */
964     case 0x20:  /* GPIO_WAKEUPENABLE */
965     case 0x2c:  /* GPIO_IRQENABLE2 */
966     case 0x30:  /* GPIO_CTRL */
967     case 0x34:  /* GPIO_OE */
968     case 0x3c:  /* GPIO_DATAOUT */
969     case 0x40:  /* GPIO_LEVELDETECT0 */
970     case 0x44:  /* GPIO_LEVELDETECT1 */
971     case 0x48:  /* GPIO_RISINGDETECT */
972     case 0x4c:  /* GPIO_FALLINGDETECT */
973     case 0x50:  /* GPIO_DEBOUNCENABLE */
974     case 0x54:  /* GPIO_DEBOUNCINGTIME */
975         cur = omap_gpio_module_read(opaque, addr & ~3) &
976                 ~(mask << ((addr & 3) << 3));
977
978         /* Fall through.  */
979     case 0x18:  /* GPIO_IRQSTATUS1 */
980     case 0x28:  /* GPIO_IRQSTATUS2 */
981     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
982     case 0x64:  /* GPIO_SETIRQENABLE1 */
983     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
984     case 0x74:  /* GPIO_SETIREQNEABLE2 */
985     case 0x80:  /* GPIO_CLEARWKUENA */
986     case 0x84:  /* GPIO_SETWKUENA */
987     case 0x90:  /* GPIO_CLEARDATAOUT */
988     case 0x94:  /* GPIO_SETDATAOUT */
989         value <<= (addr & 3) << 3;
990         omap_gpio_module_write(opaque, addr, cur | value);
991         break;
992
993     default:
994         OMAP_BAD_REG(addr);
995         return;
996     }
997 }
998
999 static CPUReadMemoryFunc *omap_gpio_module_readfn[] = {
1000     omap_gpio_module_readp,
1001     omap_gpio_module_readp,
1002     omap_gpio_module_read,
1003 };
1004
1005 static CPUWriteMemoryFunc *omap_gpio_module_writefn[] = {
1006     omap_gpio_module_writep,
1007     omap_gpio_module_writep,
1008     omap_gpio_module_write,
1009 };
1010
1011 static void omap_gpio_module_init(struct omap_mpu_state_s *mpu,
1012                 struct omap2_gpio_s *s,
1013                 struct omap_target_agent_s *ta, int region,
1014                 qemu_irq mpu_irq, qemu_irq dsp_irq, qemu_irq wkup_irq,
1015                 omap_clk fclk, omap_clk iclk)
1016 {
1017     int iomemtype;
1018
1019     s->revision = cpu_class_omap3(mpu) ? 0x25 : 0x18;
1020     s->irq[0] = mpu_irq;
1021     s->irq[1] = dsp_irq;
1022     s->wkup = wkup_irq;
1023     s->in = qemu_allocate_irqs(omap_gpio_module_set, s, 32);
1024
1025     iomemtype = l4_register_io_memory(0, omap_gpio_module_readfn,
1026                     omap_gpio_module_writefn, s);
1027     omap_l4_attach(ta, region, iomemtype);
1028 }
1029
1030 struct omap_gpif_s {
1031     struct omap2_gpio_s module[6];
1032     int modules;
1033
1034     int autoidle;
1035     int gpo;
1036 };
1037
1038 static void omap_gpif_reset(struct omap_gpif_s *s)
1039 {
1040     int i;
1041
1042     for (i = 0; i < s->modules; i ++)
1043         omap_gpio_module_reset(s->module + i);
1044
1045     s->autoidle = 0;
1046     s->gpo = 0;
1047 }
1048
1049 static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
1050 {
1051     struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
1052
1053     switch (addr) {
1054     case 0x00:  /* IPGENERICOCPSPL_REVISION */
1055         return 0x18;
1056
1057     case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
1058         return s->autoidle;
1059
1060     case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
1061         return 0x01;
1062
1063     case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
1064         return 0x00;
1065
1066     case 0x40:  /* IPGENERICOCPSPL_GPO */
1067         return s->gpo;
1068
1069     case 0x50:  /* IPGENERICOCPSPL_GPI */
1070         return 0x00;
1071     }
1072
1073     OMAP_BAD_REG(addr);
1074     return 0;
1075 }
1076
1077 static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
1078                 uint32_t value)
1079 {
1080     struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
1081
1082     switch (addr) {
1083     case 0x00:  /* IPGENERICOCPSPL_REVISION */
1084     case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
1085     case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
1086     case 0x50:  /* IPGENERICOCPSPL_GPI */
1087         OMAP_RO_REG(addr);
1088         break;
1089
1090     case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
1091         if (value & (1 << 1))                                   /* SOFTRESET */
1092             omap_gpif_reset(s);
1093         s->autoidle = value & 1;
1094         break;
1095
1096     case 0x40:  /* IPGENERICOCPSPL_GPO */
1097         s->gpo = value & 1;
1098         break;
1099
1100     default:
1101         OMAP_BAD_REG(addr);
1102         return;
1103     }
1104 }
1105
1106 static CPUReadMemoryFunc *omap_gpif_top_readfn[] = {
1107     omap_gpif_top_read,
1108     omap_gpif_top_read,
1109     omap_gpif_top_read,
1110 };
1111
1112 static CPUWriteMemoryFunc *omap_gpif_top_writefn[] = {
1113     omap_gpif_top_write,
1114     omap_gpif_top_write,
1115     omap_gpif_top_write,
1116 };
1117
1118 struct omap_gpif_s *omap2_gpio_init(struct omap_mpu_state_s *mpu,
1119                 struct omap_target_agent_s *ta,
1120                 qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
1121 {
1122     int iomemtype, i;
1123     struct omap_gpif_s *s = (struct omap_gpif_s *)
1124             qemu_mallocz(sizeof(struct omap_gpif_s));
1125     int region[4] = { 0, 2, 4, 5 };
1126
1127     s->modules = modules;
1128     for (i = 0; i < modules; i ++)
1129         omap_gpio_module_init(mpu, s->module + i, ta, region[i],
1130                         irq[i], 0, 0, fclk[i], iclk);
1131
1132     omap_gpif_reset(s);
1133
1134     iomemtype = l4_register_io_memory(0, omap_gpif_top_readfn,
1135                     omap_gpif_top_writefn, s);
1136     omap_l4_attach(ta, 1, iomemtype);
1137
1138     return s;
1139 }
1140
1141 struct omap_gpif_s *omap3_gpif_init()
1142 {
1143     struct omap_gpif_s *s = (struct omap_gpif_s *)
1144         qemu_mallocz(sizeof(struct omap_gpif_s));
1145     omap_gpif_reset(s);
1146     return s;
1147 }
1148
1149 void omap3_gpio_init(struct omap_mpu_state_s *mpu,
1150                      struct omap_gpif_s *s,struct omap_target_agent_s *ta,
1151                      qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int module_index)
1152 {
1153     s->modules++;
1154     omap_gpio_module_init(mpu, s->module + module_index, ta, 0,
1155                           irq[module_index], 0, 0, NULL,NULL);
1156 }
1157
1158 qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
1159 {
1160     if (start >= s->modules * 32 || start < 0)
1161         cpu_abort(cpu_single_env, "%s: No GPIO line %i\n",
1162                         __FUNCTION__, start);
1163     return s->module[start >> 5].in + (start & 31);
1164 }
1165
1166 void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
1167 {
1168     if (line >= s->modules * 32 || line < 0)
1169         cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
1170     s->module[line >> 5].handler[line & 31] = handler;
1171 }
1172
1173 /* Multichannel SPI */
1174 struct omap_mcspi_s {
1175     qemu_irq irq;
1176     int chnum;
1177
1178     uint32_t sysconfig;
1179     uint32_t systest;
1180     uint32_t irqst;
1181     uint32_t irqen;
1182     uint32_t wken;
1183     uint32_t control;
1184
1185     struct omap_mcspi_ch_s {
1186         qemu_irq txdrq;
1187         qemu_irq rxdrq;
1188         uint32_t (*txrx)(void *opaque, uint32_t, int);
1189         void *opaque;
1190
1191         uint32_t tx;
1192         uint32_t rx;
1193
1194         uint32_t config;
1195         uint32_t status;
1196         uint32_t control;
1197     } ch[4];
1198 };
1199
1200 static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s)
1201 {
1202     qemu_set_irq(s->irq, s->irqst & s->irqen);
1203 }
1204
1205 static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch)
1206 {
1207     qemu_set_irq(ch->txdrq,
1208                     (ch->control & 1) &&                /* EN */
1209                     (ch->config & (1 << 14)) &&         /* DMAW */
1210                     (ch->status & (1 << 1)) &&          /* TXS */
1211                     ((ch->config >> 12) & 3) != 1);     /* TRM */
1212     qemu_set_irq(ch->rxdrq,
1213                     (ch->control & 1) &&                /* EN */
1214                     (ch->config & (1 << 15)) &&         /* DMAW */
1215                     (ch->status & (1 << 0)) &&          /* RXS */
1216                     ((ch->config >> 12) & 3) != 2);     /* TRM */
1217 }
1218
1219 static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
1220 {
1221     struct omap_mcspi_ch_s *ch = s->ch + chnum;
1222
1223     if (!(ch->control & 1))                             /* EN */
1224         return;
1225     if ((ch->status & (1 << 0)) &&                      /* RXS */
1226                     ((ch->config >> 12) & 3) != 2 &&    /* TRM */
1227                     !(ch->config & (1 << 19)))          /* TURBO */
1228         goto intr_update;
1229     if ((ch->status & (1 << 1)) &&                      /* TXS */
1230                     ((ch->config >> 12) & 3) != 1)      /* TRM */
1231         goto intr_update;
1232
1233     if (!(s->control & 1) ||                            /* SINGLE */
1234                     (ch->config & (1 << 20))) {         /* FORCE */
1235         if (ch->txrx)
1236             ch->rx = ch->txrx(ch->opaque, ch->tx,       /* WL */
1237                             1 + (0x1f & (ch->config >> 7)));
1238     }
1239
1240     ch->tx = 0;
1241     ch->status |= 1 << 2;                               /* EOT */
1242     ch->status |= 1 << 1;                               /* TXS */
1243     if (((ch->config >> 12) & 3) != 2)                  /* TRM */
1244         ch->status |= 1 << 0;                           /* RXS */
1245
1246 intr_update:
1247     if ((ch->status & (1 << 0)) &&                      /* RXS */
1248                     ((ch->config >> 12) & 3) != 2 &&    /* TRM */
1249                     !(ch->config & (1 << 19)))          /* TURBO */
1250         s->irqst |= 1 << (2 + 4 * chnum);               /* RX_FULL */
1251     if ((ch->status & (1 << 1)) &&                      /* TXS */
1252                     ((ch->config >> 12) & 3) != 1)      /* TRM */
1253         s->irqst |= 1 << (0 + 4 * chnum);               /* TX_EMPTY */
1254     omap_mcspi_interrupt_update(s);
1255     omap_mcspi_dmarequest_update(ch);
1256 }
1257
1258 static void omap_mcspi_reset(struct omap_mcspi_s *s)
1259 {
1260     int ch;
1261
1262     s->sysconfig = 0;
1263     s->systest = 0;
1264     s->irqst = 0;
1265     s->irqen = 0;
1266     s->wken = 0;
1267     s->control = 4;
1268
1269     for (ch = 0; ch < 4; ch ++) {
1270         s->ch[ch].config = 0x060000;
1271         s->ch[ch].status = 2;                           /* TXS */
1272         s->ch[ch].control = 0;
1273
1274         omap_mcspi_dmarequest_update(s->ch + ch);
1275     }
1276
1277     omap_mcspi_interrupt_update(s);
1278 }
1279
1280 static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr)
1281 {
1282     struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1283     int ch = 0;
1284     uint32_t ret;
1285
1286     switch (addr) {
1287     case 0x00:  /* MCSPI_REVISION */
1288         return 0x91;
1289
1290     case 0x10:  /* MCSPI_SYSCONFIG */
1291         return s->sysconfig;
1292
1293     case 0x14:  /* MCSPI_SYSSTATUS */
1294         return 1;                                       /* RESETDONE */
1295
1296     case 0x18:  /* MCSPI_IRQSTATUS */
1297         return s->irqst;
1298
1299     case 0x1c:  /* MCSPI_IRQENABLE */
1300         return s->irqen;
1301
1302     case 0x20:  /* MCSPI_WAKEUPENABLE */
1303         return s->wken;
1304
1305     case 0x24:  /* MCSPI_SYST */
1306         return s->systest;
1307
1308     case 0x28:  /* MCSPI_MODULCTRL */
1309         return s->control;
1310
1311     case 0x68: ch ++;
1312     case 0x54: ch ++;
1313     case 0x40: ch ++;
1314     case 0x2c:  /* MCSPI_CHCONF */
1315         return s->ch[ch].config;
1316
1317     case 0x6c: ch ++;
1318     case 0x58: ch ++;
1319     case 0x44: ch ++;
1320     case 0x30:  /* MCSPI_CHSTAT */
1321         return s->ch[ch].status;
1322
1323     case 0x70: ch ++;
1324     case 0x5c: ch ++;
1325     case 0x48: ch ++;
1326     case 0x34:  /* MCSPI_CHCTRL */
1327         return s->ch[ch].control;
1328
1329     case 0x74: ch ++;
1330     case 0x60: ch ++;
1331     case 0x4c: ch ++;
1332     case 0x38:  /* MCSPI_TX */
1333         return s->ch[ch].tx;
1334
1335     case 0x78: ch ++;
1336     case 0x64: ch ++;
1337     case 0x50: ch ++;
1338     case 0x3c:  /* MCSPI_RX */
1339         s->ch[ch].status &= ~(1 << 0);                  /* RXS */
1340         ret = s->ch[ch].rx;
1341         omap_mcspi_transfer_run(s, ch);
1342         return ret;
1343     }
1344
1345     OMAP_BAD_REG(addr);
1346     return 0;
1347 }
1348
1349 static void omap_mcspi_write(void *opaque, target_phys_addr_t addr,
1350                 uint32_t value)
1351 {
1352     struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1353     int ch = 0;
1354
1355     switch (addr) {
1356     case 0x00:  /* MCSPI_REVISION */
1357     case 0x14:  /* MCSPI_SYSSTATUS */
1358     case 0x30:  /* MCSPI_CHSTAT0 */
1359     case 0x3c:  /* MCSPI_RX0 */
1360     case 0x44:  /* MCSPI_CHSTAT1 */
1361     case 0x50:  /* MCSPI_RX1 */
1362     case 0x58:  /* MCSPI_CHSTAT2 */
1363     case 0x64:  /* MCSPI_RX2 */
1364     case 0x6c:  /* MCSPI_CHSTAT3 */
1365     case 0x78:  /* MCSPI_RX3 */
1366         OMAP_RO_REG(addr);
1367         return;
1368
1369     case 0x10:  /* MCSPI_SYSCONFIG */
1370         if (value & (1 << 1))                           /* SOFTRESET */
1371             omap_mcspi_reset(s);
1372         s->sysconfig = value & 0x31d;
1373         break;
1374
1375     case 0x18:  /* MCSPI_IRQSTATUS */
1376         if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) {
1377             s->irqst &= ~value;
1378             omap_mcspi_interrupt_update(s);
1379         }
1380         break;
1381
1382     case 0x1c:  /* MCSPI_IRQENABLE */
1383         s->irqen = value & 0x1777f;
1384         omap_mcspi_interrupt_update(s);
1385         break;
1386
1387     case 0x20:  /* MCSPI_WAKEUPENABLE */
1388         s->wken = value & 1;
1389         break;
1390
1391     case 0x24:  /* MCSPI_SYST */
1392         if (s->control & (1 << 3))                      /* SYSTEM_TEST */
1393             if (value & (1 << 11)) {                    /* SSB */
1394                 s->irqst |= 0x1777f;
1395                 omap_mcspi_interrupt_update(s);
1396             }
1397         s->systest = value & 0xfff;
1398         break;
1399
1400     case 0x28:  /* MCSPI_MODULCTRL */
1401         if (value & (1 << 3))                           /* SYSTEM_TEST */
1402             if (s->systest & (1 << 11)) {               /* SSB */
1403                 s->irqst |= 0x1777f;
1404                 omap_mcspi_interrupt_update(s);
1405             }
1406         s->control = value & 0xf;
1407         break;
1408
1409     case 0x68: ch ++;
1410     case 0x54: ch ++;
1411     case 0x40: ch ++;
1412     case 0x2c:  /* MCSPI_CHCONF */
1413         if ((value ^ s->ch[ch].config) & (3 << 14))     /* DMAR | DMAW */
1414             omap_mcspi_dmarequest_update(s->ch + ch);
1415         if (((value >> 12) & 3) == 3)                   /* TRM */
1416             fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__);
1417         if (((value >> 7) & 0x1f) < 3)                  /* WL */
1418             fprintf(stderr, "%s: invalid WL value (%i)\n",
1419                             __FUNCTION__, (value >> 7) & 0x1f);
1420         s->ch[ch].config = value & 0x7fffff;
1421         break;
1422
1423     case 0x70: ch ++;
1424     case 0x5c: ch ++;
1425     case 0x48: ch ++;
1426     case 0x34:  /* MCSPI_CHCTRL */
1427         if (value & ~s->ch[ch].control & 1) {           /* EN */
1428             s->ch[ch].control |= 1;
1429             omap_mcspi_transfer_run(s, ch);
1430         } else
1431             s->ch[ch].control = value & 1;
1432         break;
1433
1434     case 0x74: ch ++;
1435     case 0x60: ch ++;
1436     case 0x4c: ch ++;
1437     case 0x38:  /* MCSPI_TX */
1438         s->ch[ch].tx = value;
1439         s->ch[ch].status &= ~(1 << 1);                  /* TXS */
1440         omap_mcspi_transfer_run(s, ch);
1441         break;
1442
1443     default:
1444         OMAP_BAD_REG(addr);
1445         return;
1446     }
1447 }
1448
1449 static CPUReadMemoryFunc *omap_mcspi_readfn[] = {
1450     omap_badwidth_read32,
1451     omap_badwidth_read32,
1452     omap_mcspi_read,
1453 };
1454
1455 static CPUWriteMemoryFunc *omap_mcspi_writefn[] = {
1456     omap_badwidth_write32,
1457     omap_badwidth_write32,
1458     omap_mcspi_write,
1459 };
1460
1461 struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
1462                 qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
1463 {
1464     int iomemtype;
1465     struct omap_mcspi_s *s = (struct omap_mcspi_s *)
1466             qemu_mallocz(sizeof(struct omap_mcspi_s));
1467     struct omap_mcspi_ch_s *ch = s->ch;
1468
1469     s->irq = irq;
1470     s->chnum = chnum;
1471     while (chnum --) {
1472         ch->txdrq = *drq ++;
1473         ch->rxdrq = *drq ++;
1474         ch ++;
1475     }
1476     omap_mcspi_reset(s);
1477
1478     iomemtype = l4_register_io_memory(0, omap_mcspi_readfn,
1479                     omap_mcspi_writefn, s);
1480     omap_l4_attach(ta, 0, iomemtype);
1481
1482     return s;
1483 }
1484
1485 void omap_mcspi_attach(struct omap_mcspi_s *s,
1486                 uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque,
1487                 int chipselect)
1488 {
1489     if (chipselect < 0 || chipselect >= s->chnum)
1490         cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n",
1491                         __FUNCTION__, chipselect);
1492
1493     s->ch[chipselect].txrx = txrx;
1494     s->ch[chipselect].opaque = opaque;
1495 }
1496
1497 /* Enhanced Audio Controller (CODEC only) */
1498 struct omap_eac_s {
1499     qemu_irq irq;
1500
1501     uint16_t sysconfig;
1502     uint8_t config[4];
1503     uint8_t control;
1504     uint8_t address;
1505     uint16_t data;
1506     uint8_t vtol;
1507     uint8_t vtsl;
1508     uint16_t mixer;
1509     uint16_t gain[4];
1510     uint8_t att;
1511     uint16_t max[7];
1512
1513     struct {
1514         qemu_irq txdrq;
1515         qemu_irq rxdrq;
1516         uint32_t (*txrx)(void *opaque, uint32_t, int);
1517         void *opaque;
1518
1519 #define EAC_BUF_LEN 1024
1520         uint32_t rxbuf[EAC_BUF_LEN];
1521         int rxoff;
1522         int rxlen;
1523         int rxavail;
1524         uint32_t txbuf[EAC_BUF_LEN];
1525         int txlen;
1526         int txavail;
1527
1528         int enable;
1529         int rate;
1530
1531         uint16_t config[4];
1532
1533         /* These need to be moved to the actual codec */
1534         QEMUSoundCard card;
1535         SWVoiceIn *in_voice;
1536         SWVoiceOut *out_voice;
1537         int hw_enable;
1538     } codec;
1539
1540     struct {
1541         uint8_t control;
1542         uint16_t config;
1543     } modem, bt;
1544 };
1545
1546 static inline void omap_eac_interrupt_update(struct omap_eac_s *s)
1547 {
1548     qemu_set_irq(s->irq, (s->codec.config[1] >> 14) & 1);       /* AURDI */
1549 }
1550
1551 static inline void omap_eac_in_dmarequest_update(struct omap_eac_s *s)
1552 {
1553     qemu_set_irq(s->codec.rxdrq, (s->codec.rxavail || s->codec.rxlen) &&
1554                     ((s->codec.config[1] >> 12) & 1));          /* DMAREN */
1555 }
1556
1557 static inline void omap_eac_out_dmarequest_update(struct omap_eac_s *s)
1558 {
1559     qemu_set_irq(s->codec.txdrq, s->codec.txlen < s->codec.txavail &&
1560                     ((s->codec.config[1] >> 11) & 1));          /* DMAWEN */
1561 }
1562
1563 static inline void omap_eac_in_refill(struct omap_eac_s *s)
1564 {
1565     int left = MIN(EAC_BUF_LEN - s->codec.rxlen, s->codec.rxavail) << 2;
1566     int start = ((s->codec.rxoff + s->codec.rxlen) & (EAC_BUF_LEN - 1)) << 2;
1567     int leftwrap = MIN(left, (EAC_BUF_LEN << 2) - start);
1568     int recv = 1;
1569     uint8_t *buf = (uint8_t *) s->codec.rxbuf + start;
1570
1571     left -= leftwrap;
1572     start = 0;
1573     while (leftwrap && (recv = AUD_read(s->codec.in_voice, buf + start,
1574                                     leftwrap)) > 0) {   /* Be defensive */
1575         start += recv;
1576         leftwrap -= recv;
1577     }
1578     if (recv <= 0)
1579         s->codec.rxavail = 0;
1580     else
1581         s->codec.rxavail -= start >> 2;
1582     s->codec.rxlen += start >> 2;
1583
1584     if (recv > 0 && left > 0) {
1585         start = 0;
1586         while (left && (recv = AUD_read(s->codec.in_voice,
1587                                         (uint8_t *) s->codec.rxbuf + start,
1588                                         left)) > 0) {   /* Be defensive */
1589             start += recv;
1590             left -= recv;
1591         }
1592         if (recv <= 0)
1593             s->codec.rxavail = 0;
1594         else
1595             s->codec.rxavail -= start >> 2;
1596         s->codec.rxlen += start >> 2;
1597     }
1598 }
1599
1600 static inline void omap_eac_out_empty(struct omap_eac_s *s)
1601 {
1602     int left = s->codec.txlen << 2;
1603     int start = 0;
1604     int sent = 1;
1605
1606     while (left && (sent = AUD_write(s->codec.out_voice,
1607                                     (uint8_t *) s->codec.txbuf + start,
1608                                     left)) > 0) {       /* Be defensive */
1609         start += sent;
1610         left -= sent;
1611     }
1612
1613     if (!sent) {
1614         s->codec.txavail = 0;
1615         omap_eac_out_dmarequest_update(s);
1616     }
1617
1618     if (start)
1619         s->codec.txlen = 0;
1620 }
1621
1622 static void omap_eac_in_cb(void *opaque, int avail_b)
1623 {
1624     struct omap_eac_s *s = (struct omap_eac_s *) opaque;
1625
1626     s->codec.rxavail = avail_b >> 2;
1627     omap_eac_in_refill(s);
1628     /* TODO: possibly discard current buffer if overrun */
1629     omap_eac_in_dmarequest_update(s);
1630 }
1631
1632 static void omap_eac_out_cb(void *opaque, int free_b)
1633 {
1634     struct omap_eac_s *s = (struct omap_eac_s *) opaque;
1635
1636     s->codec.txavail = free_b >> 2;
1637     if (s->codec.txlen)
1638         omap_eac_out_empty(s);
1639     else
1640         omap_eac_out_dmarequest_update(s);
1641 }
1642
1643 static void omap_eac_enable_update(struct omap_eac_s *s)
1644 {
1645     s->codec.enable = !(s->codec.config[1] & 1) &&              /* EACPWD */
1646             (s->codec.config[1] & 2) &&                         /* AUDEN */
1647             s->codec.hw_enable;
1648 }
1649
1650 static const int omap_eac_fsint[4] = {
1651     8000,
1652     11025,
1653     22050,
1654     44100,
1655 };
1656
1657 static const int omap_eac_fsint2[8] = {
1658     8000,
1659     11025,
1660     22050,
1661     44100,
1662     48000,
1663     0, 0, 0,
1664 };
1665
1666 static const int omap_eac_fsint3[16] = {
1667     8000,
1668     11025,
1669     16000,
1670     22050,
1671     24000,
1672     32000,
1673     44100,
1674     48000,
1675     0, 0, 0, 0, 0, 0, 0, 0,
1676 };
1677
1678 static void omap_eac_rate_update(struct omap_eac_s *s)
1679 {
1680     int fsint[3];
1681
1682     fsint[2] = (s->codec.config[3] >> 9) & 0xf;
1683     fsint[1] = (s->codec.config[2] >> 0) & 0x7;
1684     fsint[0] = (s->codec.config[0] >> 6) & 0x3;
1685     if (fsint[2] < 0xf)
1686         s->codec.rate = omap_eac_fsint3[fsint[2]];
1687     else if (fsint[1] < 0x7)
1688         s->codec.rate = omap_eac_fsint2[fsint[1]];
1689     else
1690         s->codec.rate = omap_eac_fsint[fsint[0]];
1691 }
1692
1693 static void omap_eac_volume_update(struct omap_eac_s *s)
1694 {
1695     /* TODO */
1696 }
1697
1698 static void omap_eac_format_update(struct omap_eac_s *s)
1699 {
1700     struct audsettings fmt;
1701
1702     /* The hardware buffers at most one sample */
1703     if (s->codec.rxlen)
1704         s->codec.rxlen = 1;
1705
1706     if (s->codec.in_voice) {
1707         AUD_set_active_in(s->codec.in_voice, 0);
1708         AUD_close_in(&s->codec.card, s->codec.in_voice);
1709         s->codec.in_voice = 0;
1710     }
1711     if (s->codec.out_voice) {
1712         omap_eac_out_empty(s);
1713         AUD_set_active_out(s->codec.out_voice, 0);
1714         AUD_close_out(&s->codec.card, s->codec.out_voice);
1715         s->codec.out_voice = 0;
1716         s->codec.txavail = 0;
1717     }
1718     /* Discard what couldn't be written */
1719     s->codec.txlen = 0;
1720
1721     omap_eac_enable_update(s);
1722     if (!s->codec.enable)
1723         return;
1724
1725     omap_eac_rate_update(s);
1726     fmt.endianness = ((s->codec.config[0] >> 8) & 1);           /* LI_BI */
1727     fmt.nchannels = ((s->codec.config[0] >> 10) & 1) ? 2 : 1;   /* MN_ST */
1728     fmt.freq = s->codec.rate;
1729     /* TODO: signedness possibly depends on the CODEC hardware - or
1730      * does I2S specify it?  */
1731     /* All register writes are 16 bits so we we store 16-bit samples
1732      * in the buffers regardless of AGCFR[B8_16] value.  */
1733     fmt.fmt = AUD_FMT_U16;
1734
1735     s->codec.in_voice = AUD_open_in(&s->codec.card, s->codec.in_voice,
1736                     "eac.codec.in", s, omap_eac_in_cb, &fmt);
1737     s->codec.out_voice = AUD_open_out(&s->codec.card, s->codec.out_voice,
1738                     "eac.codec.out", s, omap_eac_out_cb, &fmt);
1739
1740     omap_eac_volume_update(s);
1741
1742     AUD_set_active_in(s->codec.in_voice, 1);
1743     AUD_set_active_out(s->codec.out_voice, 1);
1744 }
1745
1746 static void omap_eac_reset(struct omap_eac_s *s)
1747 {
1748     s->sysconfig = 0;
1749     s->config[0] = 0x0c;
1750     s->config[1] = 0x09;
1751     s->config[2] = 0xab;
1752     s->config[3] = 0x03;
1753     s->control = 0x00;
1754     s->address = 0x00;
1755     s->data = 0x0000;
1756     s->vtol = 0x00;
1757     s->vtsl = 0x00;
1758     s->mixer = 0x0000;
1759     s->gain[0] = 0xe7e7;
1760     s->gain[1] = 0x6767;
1761     s->gain[2] = 0x6767;
1762     s->gain[3] = 0x6767;
1763     s->att = 0xce;
1764     s->max[0] = 0;
1765     s->max[1] = 0;
1766     s->max[2] = 0;
1767     s->max[3] = 0;
1768     s->max[4] = 0;
1769     s->max[5] = 0;
1770     s->max[6] = 0;
1771
1772     s->modem.control = 0x00;
1773     s->modem.config = 0x0000;
1774     s->bt.control = 0x00;
1775     s->bt.config = 0x0000;
1776     s->codec.config[0] = 0x0649;
1777     s->codec.config[1] = 0x0000;
1778     s->codec.config[2] = 0x0007;
1779     s->codec.config[3] = 0x1ffc;
1780     s->codec.rxoff = 0;
1781     s->codec.rxlen = 0;
1782     s->codec.txlen = 0;
1783     s->codec.rxavail = 0;
1784     s->codec.txavail = 0;
1785
1786     omap_eac_format_update(s);
1787     omap_eac_interrupt_update(s);
1788 }
1789
1790 static uint32_t omap_eac_read(void *opaque, target_phys_addr_t addr)
1791 {
1792     struct omap_eac_s *s = (struct omap_eac_s *) opaque;
1793     uint32_t ret;
1794
1795     switch (addr) {
1796     case 0x000: /* CPCFR1 */
1797         return s->config[0];
1798     case 0x004: /* CPCFR2 */
1799         return s->config[1];
1800     case 0x008: /* CPCFR3 */
1801         return s->config[2];
1802     case 0x00c: /* CPCFR4 */
1803         return s->config[3];
1804
1805     case 0x010: /* CPTCTL */
1806         return s->control | ((s->codec.rxavail + s->codec.rxlen > 0) << 7) |
1807                 ((s->codec.txlen < s->codec.txavail) << 5);
1808
1809     case 0x014: /* CPTTADR */
1810         return s->address;
1811     case 0x018: /* CPTDATL */
1812         return s->data & 0xff;
1813     case 0x01c: /* CPTDATH */
1814         return s->data >> 8;
1815     case 0x020: /* CPTVSLL */
1816         return s->vtol;
1817     case 0x024: /* CPTVSLH */
1818         return s->vtsl | (3 << 5);      /* CRDY1 | CRDY2 */
1819     case 0x040: /* MPCTR */
1820         return s->modem.control;
1821     case 0x044: /* MPMCCFR */
1822         return s->modem.config;
1823     case 0x060: /* BPCTR */
1824         return s->bt.control;
1825     case 0x064: /* BPMCCFR */
1826         return s->bt.config;
1827     case 0x080: /* AMSCFR */
1828         return s->mixer;
1829     case 0x084: /* AMVCTR */
1830         return s->gain[0];
1831     case 0x088: /* AM1VCTR */
1832         return s->gain[1];
1833     case 0x08c: /* AM2VCTR */
1834         return s->gain[2];
1835     case 0x090: /* AM3VCTR */
1836         return s->gain[3];
1837     case 0x094: /* ASTCTR */
1838         return s->att;
1839     case 0x098: /* APD1LCR */
1840         return s->max[0];
1841     case 0x09c: /* APD1RCR */
1842         return s->max[1];
1843     case 0x0a0: /* APD2LCR */
1844         return s->max[2];
1845     case 0x0a4: /* APD2RCR */
1846         return s->max[3];
1847     case 0x0a8: /* APD3LCR */
1848         return s->max[4];
1849     case 0x0ac: /* APD3RCR */
1850         return s->max[5];
1851     case 0x0b0: /* APD4R */
1852         return s->max[6];
1853     case 0x0b4: /* ADWR */
1854         /* This should be write-only?  Docs list it as read-only.  */
1855         return 0x0000;
1856     case 0x0b8: /* ADRDR */
1857         if (likely(s->codec.rxlen > 1)) {
1858             ret = s->codec.rxbuf[s->codec.rxoff ++];
1859             s->codec.rxlen --;
1860             s->codec.rxoff &= EAC_BUF_LEN - 1;
1861             return ret;
1862         } else if (s->codec.rxlen) {
1863             ret = s->codec.rxbuf[s->codec.rxoff ++];
1864             s->codec.rxlen --;
1865             s->codec.rxoff &= EAC_BUF_LEN - 1;
1866             if (s->codec.rxavail)
1867                 omap_eac_in_refill(s);
1868             omap_eac_in_dmarequest_update(s);
1869             return ret;
1870         }
1871         return 0x0000;
1872     case 0x0bc: /* AGCFR */
1873         return s->codec.config[0];
1874     case 0x0c0: /* AGCTR */
1875         return s->codec.config[1] | ((s->codec.config[1] & 2) << 14);
1876     case 0x0c4: /* AGCFR2 */
1877         return s->codec.config[2];
1878     case 0x0c8: /* AGCFR3 */
1879         return s->codec.config[3];
1880     case 0x0cc: /* MBPDMACTR */
1881     case 0x0d0: /* MPDDMARR */
1882     case 0x0d8: /* MPUDMARR */
1883     case 0x0e4: /* BPDDMARR */
1884     case 0x0ec: /* BPUDMARR */
1885         return 0x0000;
1886
1887     case 0x100: /* VERSION_NUMBER */
1888         return 0x0010;
1889
1890     case 0x104: /* SYSCONFIG */
1891         return s->sysconfig;
1892
1893     case 0x108: /* SYSSTATUS */
1894         return 1 | 0xe;                                 /* RESETDONE | stuff */
1895     }
1896
1897     OMAP_BAD_REG(addr);
1898     return 0;
1899 }
1900
1901 static void omap_eac_write(void *opaque, target_phys_addr_t addr,
1902                 uint32_t value)
1903 {
1904     struct omap_eac_s *s = (struct omap_eac_s *) opaque;
1905
1906     switch (addr) {
1907     case 0x098: /* APD1LCR */
1908     case 0x09c: /* APD1RCR */
1909     case 0x0a0: /* APD2LCR */
1910     case 0x0a4: /* APD2RCR */
1911     case 0x0a8: /* APD3LCR */
1912     case 0x0ac: /* APD3RCR */
1913     case 0x0b0: /* APD4R */
1914     case 0x0b8: /* ADRDR */
1915     case 0x0d0: /* MPDDMARR */
1916     case 0x0d8: /* MPUDMARR */
1917     case 0x0e4: /* BPDDMARR */
1918     case 0x0ec: /* BPUDMARR */
1919     case 0x100: /* VERSION_NUMBER */
1920     case 0x108: /* SYSSTATUS */
1921         OMAP_RO_REG(addr);
1922         return;
1923
1924     case 0x000: /* CPCFR1 */
1925         s->config[0] = value & 0xff;
1926         omap_eac_format_update(s);
1927         break;
1928     case 0x004: /* CPCFR2 */
1929         s->config[1] = value & 0xff;
1930         omap_eac_format_update(s);
1931         break;
1932     case 0x008: /* CPCFR3 */
1933         s->config[2] = value & 0xff;
1934         omap_eac_format_update(s);
1935         break;
1936     case 0x00c: /* CPCFR4 */
1937         s->config[3] = value & 0xff;
1938         omap_eac_format_update(s);
1939         break;
1940
1941     case 0x010: /* CPTCTL */
1942         /* Assuming TXF and TXE bits are read-only... */
1943         s->control = value & 0x5f;
1944         omap_eac_interrupt_update(s);
1945         break;
1946
1947     case 0x014: /* CPTTADR */
1948         s->address = value & 0xff;
1949         break;
1950     case 0x018: /* CPTDATL */
1951         s->data &= 0xff00;
1952         s->data |= value & 0xff;
1953         break;
1954     case 0x01c: /* CPTDATH */
1955         s->data &= 0x00ff;
1956         s->data |= value << 8;
1957         break;
1958     case 0x020: /* CPTVSLL */
1959         s->vtol = value & 0xf8;
1960         break;
1961     case 0x024: /* CPTVSLH */
1962         s->vtsl = value & 0x9f;
1963         break;
1964     case 0x040: /* MPCTR */
1965         s->modem.control = value & 0x8f;
1966         break;
1967     case 0x044: /* MPMCCFR */
1968         s->modem.config = value & 0x7fff;
1969         break;
1970     case 0x060: /* BPCTR */
1971         s->bt.control = value & 0x8f;
1972         break;
1973     case 0x064: /* BPMCCFR */
1974         s->bt.config = value & 0x7fff;
1975         break;
1976     case 0x080: /* AMSCFR */
1977         s->mixer = value & 0x0fff;
1978         break;
1979     case 0x084: /* AMVCTR */
1980         s->gain[0] = value & 0xffff;
1981         break;
1982     case 0x088: /* AM1VCTR */
1983         s->gain[1] = value & 0xff7f;
1984         break;
1985     case 0x08c: /* AM2VCTR */
1986         s->gain[2] = value & 0xff7f;
1987         break;
1988     case 0x090: /* AM3VCTR */
1989         s->gain[3] = value & 0xff7f;
1990         break;
1991     case 0x094: /* ASTCTR */
1992         s->att = value & 0xff;
1993         break;
1994
1995     case 0x0b4: /* ADWR */
1996         s->codec.txbuf[s->codec.txlen ++] = value;
1997         if (unlikely(s->codec.txlen == EAC_BUF_LEN ||
1998                                 s->codec.txlen == s->codec.txavail)) {
1999             if (s->codec.txavail)
2000                 omap_eac_out_empty(s);
2001             /* Discard what couldn't be written */
2002             s->codec.txlen = 0;
2003         }
2004         break;
2005
2006     case 0x0bc: /* AGCFR */
2007         s->codec.config[0] = value & 0x07ff;
2008         omap_eac_format_update(s);
2009         break;
2010     case 0x0c0: /* AGCTR */
2011         s->codec.config[1] = value & 0x780f;
2012         omap_eac_format_update(s);
2013         break;
2014     case 0x0c4: /* AGCFR2 */
2015         s->codec.config[2] = value & 0x003f;
2016         omap_eac_format_update(s);
2017         break;
2018     case 0x0c8: /* AGCFR3 */
2019         s->codec.config[3] = value & 0xffff;
2020         omap_eac_format_update(s);
2021         break;
2022     case 0x0cc: /* MBPDMACTR */
2023     case 0x0d4: /* MPDDMAWR */
2024     case 0x0e0: /* MPUDMAWR */
2025     case 0x0e8: /* BPDDMAWR */
2026     case 0x0f0: /* BPUDMAWR */
2027         break;
2028
2029     case 0x104: /* SYSCONFIG */
2030         if (value & (1 << 1))                           /* SOFTRESET */
2031             omap_eac_reset(s);
2032         s->sysconfig = value & 0x31d;
2033         break;
2034
2035     default:
2036         OMAP_BAD_REG(addr);
2037         return;
2038     }
2039 }
2040
2041 static CPUReadMemoryFunc *omap_eac_readfn[] = {
2042     omap_badwidth_read16,
2043     omap_eac_read,
2044     omap_badwidth_read16,
2045 };
2046
2047 static CPUWriteMemoryFunc *omap_eac_writefn[] = {
2048     omap_badwidth_write16,
2049     omap_eac_write,
2050     omap_badwidth_write16,
2051 };
2052
2053 struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
2054                 qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
2055 {
2056     int iomemtype;
2057     struct omap_eac_s *s = (struct omap_eac_s *)
2058             qemu_mallocz(sizeof(struct omap_eac_s));
2059
2060     s->irq = irq;
2061     s->codec.rxdrq = *drq ++;
2062     s->codec.txdrq = *drq ++;
2063     omap_eac_reset(s);
2064
2065 #ifdef HAS_AUDIO
2066     /* TODO: do AUD_init globally for machine */
2067     AUD_register_card(AUD_init(), "OMAP EAC", &s->codec.card);
2068
2069     iomemtype = cpu_register_io_memory(0, omap_eac_readfn,
2070                     omap_eac_writefn, s);
2071     omap_l4_attach(ta, 0, iomemtype);
2072 #endif
2073
2074     return s;
2075 }
2076
2077 /* STI/XTI (emulation interface) console - reverse engineered only */
2078 struct omap_sti_s {
2079     qemu_irq irq;
2080     CharDriverState *chr;
2081
2082     uint32_t sysconfig;
2083     uint32_t systest;
2084     uint32_t irqst;
2085     uint32_t irqen;
2086     uint32_t clkcontrol;
2087     uint32_t serial_config;
2088 };
2089
2090 #define STI_TRACE_CONSOLE_CHANNEL       239
2091 #define STI_TRACE_CONTROL_CHANNEL       253
2092
2093 static inline void omap_sti_interrupt_update(struct omap_sti_s *s)
2094 {
2095     qemu_set_irq(s->irq, s->irqst & s->irqen);
2096 }
2097
2098 static void omap_sti_reset(struct omap_sti_s *s)
2099 {
2100     s->sysconfig = 0;
2101     s->irqst = 0;
2102     s->irqen = 0;
2103     s->clkcontrol = 0;
2104     s->serial_config = 0;
2105
2106     omap_sti_interrupt_update(s);
2107 }
2108
2109 static uint32_t omap_sti_read(void *opaque, target_phys_addr_t addr)
2110 {
2111     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
2112
2113     switch (addr) {
2114     case 0x00:  /* STI_REVISION */
2115         return 0x10;
2116
2117     case 0x10:  /* STI_SYSCONFIG */
2118         return s->sysconfig;
2119
2120     case 0x14:  /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
2121         return 0x00;
2122
2123     case 0x18:  /* STI_IRQSTATUS */
2124         return s->irqst;
2125
2126     case 0x1c:  /* STI_IRQSETEN / STI_IRQCLREN */
2127         return s->irqen;
2128
2129     case 0x24:  /* STI_ER / STI_DR / XTI_TRACESELECT */
2130     case 0x28:  /* STI_RX_DR / XTI_RXDATA */
2131         /* TODO */
2132         return 0;
2133
2134     case 0x2c:  /* STI_CLK_CTRL / XTI_SCLKCRTL */
2135         return s->clkcontrol;
2136
2137     case 0x30:  /* STI_SERIAL_CFG / XTI_SCONFIG */
2138         return s->serial_config;
2139     }
2140
2141     OMAP_BAD_REG(addr);
2142     return 0;
2143 }
2144
2145 static void omap_sti_write(void *opaque, target_phys_addr_t addr,
2146                 uint32_t value)
2147 {
2148     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
2149
2150     switch (addr) {
2151     case 0x00:  /* STI_REVISION */
2152     case 0x14:  /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
2153         OMAP_RO_REG(addr);
2154         return;
2155
2156     case 0x10:  /* STI_SYSCONFIG */
2157         if (value & (1 << 1))                           /* SOFTRESET */
2158             omap_sti_reset(s);
2159         s->sysconfig = value & 0xfe;
2160         break;
2161
2162     case 0x18:  /* STI_IRQSTATUS */
2163         s->irqst &= ~value;
2164         omap_sti_interrupt_update(s);
2165         break;
2166
2167     case 0x1c:  /* STI_IRQSETEN / STI_IRQCLREN */
2168         s->irqen = value & 0xffff;
2169         omap_sti_interrupt_update(s);
2170         break;
2171
2172     case 0x2c:  /* STI_CLK_CTRL / XTI_SCLKCRTL */
2173         s->clkcontrol = value & 0xff;
2174         break;
2175
2176     case 0x30:  /* STI_SERIAL_CFG / XTI_SCONFIG */
2177         s->serial_config = value & 0xff;
2178         break;
2179
2180     case 0x24:  /* STI_ER / STI_DR / XTI_TRACESELECT */
2181     case 0x28:  /* STI_RX_DR / XTI_RXDATA */
2182         /* TODO */
2183         return;
2184
2185     default:
2186         OMAP_BAD_REG(addr);
2187         return;
2188     }
2189 }
2190
2191 static CPUReadMemoryFunc *omap_sti_readfn[] = {
2192     omap_badwidth_read32,
2193     omap_badwidth_read32,
2194     omap_sti_read,
2195 };
2196
2197 static CPUWriteMemoryFunc *omap_sti_writefn[] = {
2198     omap_badwidth_write32,
2199     omap_badwidth_write32,
2200     omap_sti_write,
2201 };
2202
2203 static uint32_t omap_sti_fifo_read(void *opaque, target_phys_addr_t addr)
2204 {
2205     OMAP_BAD_REG(addr);
2206     return 0;
2207 }
2208
2209 static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr,
2210                 uint32_t value)
2211 {
2212     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
2213     int ch = addr >> 6;
2214     uint8_t byte = value;
2215
2216     if (ch == STI_TRACE_CONTROL_CHANNEL) {
2217         /* Flush channel <i>value</i>.  */
2218         qemu_chr_write(s->chr, (const uint8_t *) "\r", 1);
2219     } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
2220         if (value == 0xc0 || value == 0xc3) {
2221             /* Open channel <i>ch</i>.  */
2222         } else if (value == 0x00)
2223             qemu_chr_write(s->chr, (const uint8_t *) "\n", 1);
2224         else
2225             qemu_chr_write(s->chr, &byte, 1);
2226     }
2227 }
2228
2229 static CPUReadMemoryFunc *omap_sti_fifo_readfn[] = {
2230     omap_sti_fifo_read,
2231     omap_badwidth_read8,
2232     omap_badwidth_read8,
2233 };
2234
2235 static CPUWriteMemoryFunc *omap_sti_fifo_writefn[] = {
2236     omap_sti_fifo_write,
2237     omap_badwidth_write8,
2238     omap_badwidth_write8,
2239 };
2240
2241 static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
2242                 target_phys_addr_t channel_base, qemu_irq irq, omap_clk clk,
2243                 CharDriverState *chr)
2244 {
2245     int iomemtype;
2246     struct omap_sti_s *s = (struct omap_sti_s *)
2247             qemu_mallocz(sizeof(struct omap_sti_s));
2248
2249     s->irq = irq;
2250     omap_sti_reset(s);
2251
2252     s->chr = chr ?: qemu_chr_open("null", "null", NULL);
2253
2254     iomemtype = l4_register_io_memory(0, omap_sti_readfn,
2255                     omap_sti_writefn, s);
2256     omap_l4_attach(ta, 0, iomemtype);
2257
2258     iomemtype = cpu_register_io_memory(0, omap_sti_fifo_readfn,
2259                     omap_sti_fifo_writefn, s);
2260     cpu_register_physical_memory(channel_base, 0x10000, iomemtype);
2261
2262     return s;
2263 }
2264
2265 /* L4 Interconnect */
2266 #ifdef L4_MUX_HACK
2267 static int omap_l4_io_entries;
2268 static int omap_cpu_io_entry;
2269 static struct omap_l4_entry {
2270         CPUReadMemoryFunc **mem_read;
2271         CPUWriteMemoryFunc **mem_write;
2272         void *opaque;
2273 } *omap_l4_io_entry;
2274 static CPUReadMemoryFunc **omap_l4_io_readb_fn;
2275 static CPUReadMemoryFunc **omap_l4_io_readh_fn;
2276 static CPUReadMemoryFunc **omap_l4_io_readw_fn;
2277 static CPUWriteMemoryFunc **omap_l4_io_writeb_fn;
2278 static CPUWriteMemoryFunc **omap_l4_io_writeh_fn;
2279 static CPUWriteMemoryFunc **omap_l4_io_writew_fn;
2280 static void **omap_l4_io_opaque;
2281
2282 int l4_register_io_memory(int io_index, CPUReadMemoryFunc **mem_read,
2283                 CPUWriteMemoryFunc **mem_write, void *opaque)
2284 {
2285     omap_l4_io_entry[omap_l4_io_entries].mem_read = mem_read;
2286     omap_l4_io_entry[omap_l4_io_entries].mem_write = mem_write;
2287     omap_l4_io_entry[omap_l4_io_entries].opaque = opaque;
2288
2289     return omap_l4_io_entries ++;
2290 }
2291
2292 static uint32_t omap_l4_io_readb(void *opaque, target_phys_addr_t addr)
2293 {
2294     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2295
2296     return omap_l4_io_readb_fn[i](omap_l4_io_opaque[i], addr);
2297 }
2298
2299 static uint32_t omap_l4_io_readh(void *opaque, target_phys_addr_t addr)
2300 {
2301     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2302
2303     return omap_l4_io_readh_fn[i](omap_l4_io_opaque[i], addr);
2304 }
2305
2306 static uint32_t omap_l4_io_readw(void *opaque, target_phys_addr_t addr)
2307 {
2308     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2309
2310     return omap_l4_io_readw_fn[i](omap_l4_io_opaque[i], addr);
2311 }
2312
2313 static void omap_l4_io_writeb(void *opaque, target_phys_addr_t addr,
2314                 uint32_t value)
2315 {
2316     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2317
2318     return omap_l4_io_writeb_fn[i](omap_l4_io_opaque[i], addr, value);
2319 }
2320
2321 static void omap_l4_io_writeh(void *opaque, target_phys_addr_t addr,
2322                 uint32_t value)
2323 {
2324     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2325
2326     return omap_l4_io_writeh_fn[i](omap_l4_io_opaque[i], addr, value);
2327 }
2328
2329 static void omap_l4_io_writew(void *opaque, target_phys_addr_t addr,
2330                 uint32_t value)
2331 {
2332     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
2333
2334     return omap_l4_io_writew_fn[i](omap_l4_io_opaque[i], addr, value);
2335 }
2336
2337 static CPUReadMemoryFunc *omap_l4_io_readfn[] = {
2338     omap_l4_io_readb,
2339     omap_l4_io_readh,
2340     omap_l4_io_readw,
2341 };
2342
2343 static CPUWriteMemoryFunc *omap_l4_io_writefn[] = {
2344     omap_l4_io_writeb,
2345     omap_l4_io_writeh,
2346     omap_l4_io_writew,
2347 };
2348 #endif
2349
2350 struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
2351 {
2352     struct omap_l4_s *bus = qemu_mallocz(
2353                     sizeof(*bus) + ta_num * sizeof(*bus->ta));
2354
2355     bus->ta_num = ta_num;
2356     bus->base = base;
2357
2358 #ifdef L4_MUX_HACK
2359     omap_l4_io_entries = 1;
2360     omap_l4_io_entry = qemu_mallocz(125 * sizeof(*omap_l4_io_entry));
2361
2362     omap_cpu_io_entry =
2363             cpu_register_io_memory(0, omap_l4_io_readfn,
2364                             omap_l4_io_writefn, bus);
2365 # define L4_PAGES       (0xb4000 / TARGET_PAGE_SIZE)
2366     omap_l4_io_readb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2367     omap_l4_io_readh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2368     omap_l4_io_readw_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2369     omap_l4_io_writeb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2370     omap_l4_io_writeh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2371     omap_l4_io_writew_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
2372     omap_l4_io_opaque = qemu_mallocz(sizeof(void *) * L4_PAGES);
2373 #endif
2374
2375     return bus;
2376 }
2377
2378 static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr)
2379 {
2380     struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
2381
2382     switch (addr) {
2383     case 0x00:  /* COMPONENT */
2384         return s->component;
2385
2386     case 0x20:  /* AGENT_CONTROL */
2387         return s->control;
2388
2389     case 0x28:  /* AGENT_STATUS */
2390         return s->status;
2391     }
2392
2393     OMAP_BAD_REG(addr);
2394     return 0;
2395 }
2396
2397 static void omap_l4ta_write(void *opaque, target_phys_addr_t addr,
2398                 uint32_t value)
2399 {
2400     struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
2401
2402     switch (addr) {
2403     case 0x00:  /* COMPONENT */
2404     case 0x28:  /* AGENT_STATUS */
2405         OMAP_RO_REG(addr);
2406         break;
2407
2408     case 0x20:  /* AGENT_CONTROL */
2409         s->control = value & 0x01000700;
2410         if (value & 1)                                  /* OCP_RESET */
2411             s->status &= ~1;                            /* REQ_TIMEOUT */
2412         break;
2413
2414     default:
2415         OMAP_BAD_REG(addr);
2416     }
2417 }
2418
2419 static CPUReadMemoryFunc *omap_l4ta_readfn[] = {
2420     omap_badwidth_read16,
2421     omap_l4ta_read,
2422     omap_badwidth_read16,
2423 };
2424
2425 static CPUWriteMemoryFunc *omap_l4ta_writefn[] = {
2426     omap_badwidth_write32,
2427     omap_badwidth_write32,
2428     omap_l4ta_write,
2429 };
2430
2431 #define L4TA(n)         (n)
2432 #define L4TAO(n)        ((n) + 39)
2433
2434 static struct omap_l4_region_s omap_l4_region[125] = {
2435     [  1] = { 0x40800,  0x800, 32          }, /* Initiator agent */
2436     [  2] = { 0x41000, 0x1000, 32          }, /* Link agent */
2437     [  0] = { 0x40000,  0x800, 32          }, /* Address and protection */
2438     [  3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
2439     [  4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
2440     [  5] = { 0x04000, 0x1000, 32 | 16     }, /* 32K Timer */
2441     [  6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
2442     [  7] = { 0x08000,  0x800, 32          }, /* PRCM Region A */
2443     [  8] = { 0x08800,  0x800, 32          }, /* PRCM Region B */
2444     [  9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
2445     [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
2446     [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
2447     [ 12] = { 0x14000, 0x1000, 32          }, /* Test/emulation (TAP) */
2448     [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
2449     [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
2450     [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
2451     [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
2452     [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
2453     [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
2454     [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
2455     [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
2456     [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
2457     [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
2458     [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
2459     [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
2460     [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
2461     [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
2462     [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
2463     [ 28] = { 0x50000,  0x400, 32 | 16 | 8 }, /* Display top */
2464     [ 29] = { 0x50400,  0x400, 32 | 16 | 8 }, /* Display control */
2465     [ 30] = { 0x50800,  0x400, 32 | 16 | 8 }, /* Display RFBI */
2466     [ 31] = { 0x50c00,  0x400, 32 | 16 | 8 }, /* Display encoder */
2467     [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
2468     [ 33] = { 0x52000,  0x400, 32 | 16 | 8 }, /* Camera top */
2469     [ 34] = { 0x52400,  0x400, 32 | 16 | 8 }, /* Camera core */
2470     [ 35] = { 0x52800,  0x400, 32 | 16 | 8 }, /* Camera DMA */
2471     [ 36] = { 0x52c00,  0x400, 32 | 16 | 8 }, /* Camera MMU */
2472     [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
2473     [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
2474     [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
2475     [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
2476     [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
2477     [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
2478     [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
2479     [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
2480     [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
2481     [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
2482     [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
2483     [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
2484     [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
2485     [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
2486     [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
2487     [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
2488     [ 53] = { 0x66000,  0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
2489     [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
2490     [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
2491     [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
2492     [ 57] = { 0x6a000, 0x1000,      16 | 8 }, /* UART1 */
2493     [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
2494     [ 59] = { 0x6c000, 0x1000,      16 | 8 }, /* UART2 */
2495     [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
2496     [ 61] = { 0x6e000, 0x1000,      16 | 8 }, /* UART3 */
2497     [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
2498     [ 63] = { 0x70000, 0x1000,      16     }, /* I2C1 */
2499     [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
2500     [ 65] = { 0x72000, 0x1000,      16     }, /* I2C2 */
2501     [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
2502     [ 67] = { 0x74000, 0x1000,      16     }, /* McBSP1 */
2503     [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
2504     [ 69] = { 0x76000, 0x1000,      16     }, /* McBSP2 */
2505     [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
2506     [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
2507     [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
2508     [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
2509     [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
2510     [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
2511     [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
2512     [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
2513     [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
2514     [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
2515     [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
2516     [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
2517     [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
2518     [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
2519     [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
2520     [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
2521     [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
2522     [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
2523     [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
2524     [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
2525     [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
2526     [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
2527     [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
2528     [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
2529     [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
2530     [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
2531     [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
2532     [ 97] = { 0x90000, 0x1000,      16     }, /* EAC */
2533     [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
2534     [ 99] = { 0x92000, 0x1000,      16     }, /* FAC */
2535     [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
2536     [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
2537     [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
2538     [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
2539     [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
2540     [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
2541     [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
2542     [107] = { 0x9c000, 0x1000,      16 | 8 }, /* MMC SDIO */
2543     [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
2544     [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
2545     [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
2546     [111] = { 0xa0000, 0x1000, 32          }, /* RNG */
2547     [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
2548     [113] = { 0xa2000, 0x1000, 32          }, /* DES3DES */
2549     [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
2550     [115] = { 0xa4000, 0x1000, 32          }, /* SHA1MD5 */
2551     [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
2552     [117] = { 0xa6000, 0x1000, 32          }, /* AES */
2553     [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
2554     [119] = { 0xa8000, 0x2000, 32          }, /* PKA */
2555     [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
2556     [121] = { 0xb0000, 0x1000, 32          }, /* MG */
2557     [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
2558     [123] = { 0xb2000, 0x1000, 32          }, /* HDQ/1-Wire */
2559     [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
2560 };
2561
2562 static struct omap_l4_agent_info_s omap_l4_agent_info[54] = {
2563     { 0,           0, 3, 2 }, /* L4IA initiatior agent */
2564     { L4TAO(1),    3, 2, 1 }, /* Control and pinout module */
2565     { L4TAO(2),    5, 2, 1 }, /* 32K timer */
2566     { L4TAO(3),    7, 3, 2 }, /* PRCM */
2567     { L4TA(1),    10, 2, 1 }, /* BCM */
2568     { L4TA(2),    12, 2, 1 }, /* Test JTAG */
2569     { L4TA(3),    14, 6, 3 }, /* Quad GPIO */
2570     { L4TA(4),    20, 4, 3 }, /* WD timer 1/2 */
2571     { L4TA(7),    24, 2, 1 }, /* GP timer 1 */
2572     { L4TA(9),    26, 2, 1 }, /* ATM11 ETB */
2573     { L4TA(10),   28, 5, 4 }, /* Display subsystem */
2574     { L4TA(11),   33, 5, 4 }, /* Camera subsystem */
2575     { L4TA(12),   38, 2, 1 }, /* sDMA */
2576     { L4TA(13),   40, 5, 4 }, /* SSI */
2577     { L4TAO(4),   45, 2, 1 }, /* USB */
2578     { L4TA(14),   47, 2, 1 }, /* Win Tracer1 */
2579     { L4TA(15),   49, 2, 1 }, /* Win Tracer2 */
2580     { L4TA(16),   51, 2, 1 }, /* Win Tracer3 */
2581     { L4TA(17),   53, 2, 1 }, /* Win Tracer4 */
2582     { L4TA(18),   55, 2, 1 }, /* XTI */
2583     { L4TA(19),   57, 2, 1 }, /* UART1 */
2584     { L4TA(20),   59, 2, 1 }, /* UART2 */
2585     { L4TA(21),   61, 2, 1 }, /* UART3 */
2586     { L4TAO(5),   63, 2, 1 }, /* I2C1 */
2587     { L4TAO(6),   65, 2, 1 }, /* I2C2 */
2588     { L4TAO(7),   67, 2, 1 }, /* McBSP1 */
2589     { L4TAO(8),   69, 2, 1 }, /* McBSP2 */
2590     { L4TA(5),    71, 2, 1 }, /* WD Timer 3 (DSP) */
2591     { L4TA(6),    73, 2, 1 }, /* WD Timer 4 (IVA) */
2592     { L4TA(8),    75, 2, 1 }, /* GP Timer 2 */
2593     { L4TA(22),   77, 2, 1 }, /* GP Timer 3 */
2594     { L4TA(23),   79, 2, 1 }, /* GP Timer 4 */
2595     { L4TA(24),   81, 2, 1 }, /* GP Timer 5 */
2596     { L4TA(25),   83, 2, 1 }, /* GP Timer 6 */
2597     { L4TA(26),   85, 2, 1 }, /* GP Timer 7 */
2598     { L4TA(27),   87, 2, 1 }, /* GP Timer 8 */
2599     { L4TA(28),   89, 2, 1 }, /* GP Timer 9 */
2600     { L4TA(29),   91, 2, 1 }, /* GP Timer 10 */
2601     { L4TA(30),   93, 2, 1 }, /* GP Timer 11 */
2602     { L4TA(31),   95, 2, 1 }, /* GP Timer 12 */
2603     { L4TA(32),   97, 2, 1 }, /* EAC */
2604     { L4TA(33),   99, 2, 1 }, /* FAC */
2605     { L4TA(34),  101, 2, 1 }, /* IPC */
2606     { L4TA(35),  103, 2, 1 }, /* SPI1 */
2607     { L4TA(36),  105, 2, 1 }, /* SPI2 */
2608     { L4TAO(9),  107, 2, 1 }, /* MMC SDIO */
2609     { L4TAO(10), 109, 2, 1 },
2610     { L4TAO(11), 111, 2, 1 }, /* RNG */
2611     { L4TAO(12), 113, 2, 1 }, /* DES3DES */
2612     { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
2613     { L4TA(37),  117, 2, 1 }, /* AES */
2614     { L4TA(38),  119, 2, 1 }, /* PKA */
2615     { -1,        121, 2, 1 },
2616     { L4TA(39),  123, 2, 1 }, /* HDQ/1-Wire */
2617 };
2618
2619 #define omap_l4ta(bus, cs)      omap_l4ta_get(bus, L4TA(cs))
2620 #define omap_l4tao(bus, cs)     omap_l4ta_get(bus, L4TAO(cs))
2621
2622 struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs)
2623 {
2624     int i, iomemtype;
2625     struct omap_target_agent_s *ta = 0;
2626     struct omap_l4_agent_info_s *info = 0;
2627
2628     for (i = 0; i < bus->ta_num; i ++)
2629         if (omap_l4_agent_info[i].ta == cs) {
2630             ta = &bus->ta[i];
2631             info = &omap_l4_agent_info[i];
2632             break;
2633         }
2634     if (!ta) {
2635         fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
2636         exit(-1);
2637     }
2638
2639     ta->bus = bus;
2640     ta->start = &omap_l4_region[info->region];
2641     ta->regions = info->regions;
2642
2643     ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2644     ta->status = 0x00000000;
2645     ta->control = 0x00000200;   /* XXX 01000200 for L4TAO */
2646
2647     iomemtype = l4_register_io_memory(0, omap_l4ta_readfn,
2648                     omap_l4ta_writefn, ta);
2649     ta->base = omap_l4_attach(ta, info->ta_region, iomemtype);
2650
2651     return ta;
2652 }
2653
2654 target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
2655                 int iotype)
2656 {
2657     target_phys_addr_t base;
2658     ssize_t size;
2659 #ifdef L4_MUX_HACK
2660     int i;
2661 #endif
2662
2663     if (region < 0 || region >= ta->regions) {
2664         fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);
2665         exit(-1);
2666     }
2667
2668     base = ta->bus->base + ta->start[region].offset;
2669     size = ta->start[region].size;
2670     if (iotype) {
2671 #ifndef L4_MUX_HACK
2672         cpu_register_physical_memory(base, size, iotype);
2673 #else
2674         cpu_register_physical_memory(base, size, omap_cpu_io_entry);
2675         i = (base - ta->bus->base) / TARGET_PAGE_SIZE;
2676         for (; size > 0; size -= TARGET_PAGE_SIZE, i ++) {
2677             omap_l4_io_readb_fn[i] = omap_l4_io_entry[iotype].mem_read[0];
2678             omap_l4_io_readh_fn[i] = omap_l4_io_entry[iotype].mem_read[1];
2679             omap_l4_io_readw_fn[i] = omap_l4_io_entry[iotype].mem_read[2];
2680             omap_l4_io_writeb_fn[i] = omap_l4_io_entry[iotype].mem_write[0];
2681             omap_l4_io_writeh_fn[i] = omap_l4_io_entry[iotype].mem_write[1];
2682             omap_l4_io_writew_fn[i] = omap_l4_io_entry[iotype].mem_write[2];
2683             omap_l4_io_opaque[i] = omap_l4_io_entry[iotype].opaque;
2684         }
2685 #endif
2686     }
2687
2688     return base;
2689 }
2690
2691 /* TEST-Chip-level TAP */
2692 static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr)
2693 {
2694     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2695
2696     switch (addr) {
2697     case 0x204: /* IDCODE_reg */
2698         switch (s->mpu_model) {
2699         case omap2420:
2700         case omap2422:
2701         case omap2423:
2702             return 0x5b5d902f;  /* ES 2.2 */
2703         case omap2430:
2704             return 0x5b68a02f;  /* ES 2.2 */
2705         case omap3430:
2706             return 0x1b7ae02f;  /* ES 2 */
2707         case omap3530:
2708             return 0x3b7ae02f;  /* ES 3.0 */
2709         default:
2710             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2711         }
2712
2713     case 0x208: /* PRODUCTION_ID_reg for OMAP2 */
2714     case 0x210: /* PRODUCTION_ID_reg for OMAP3 */
2715         switch (s->mpu_model) {
2716         case omap2420:
2717             return 0x000254f0;  /* POP ESHS2.1.1 in N91/93/95, ES2 in N800 */
2718         case omap2422:
2719             return 0x000400f0;
2720         case omap2423:
2721             return 0x000800f0;
2722         case omap2430:
2723             return 0x000000f0;
2724         case omap3430:
2725             return 0x000000f0;
2726         case omap3530:
2727             return 0x000f00f0;
2728         default:
2729             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2730         }
2731
2732     case 0x20c:
2733         switch (s->mpu_model) {
2734         case omap2420:
2735         case omap2422:
2736         case omap2423:
2737             return 0xcafeb5d9;  /* ES 2.2 */
2738         case omap2430:
2739             return 0xcafeb68a;  /* ES 2.2 */
2740         case omap3430:
2741         case omap3530:
2742             return 0xcafeb7ae;  /* ES 2 */
2743         default:
2744             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2745         }
2746
2747     case 0x218: /* DIE_ID_reg */
2748         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2749     case 0x21c: /* DIE_ID_reg */
2750         return 0x54 << 24;
2751     case 0x220: /* DIE_ID_reg */
2752         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2753     case 0x224: /* DIE_ID_reg */
2754         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2755     }
2756
2757     OMAP_BAD_REG(addr);
2758     return 0;
2759 }
2760
2761 static void omap_tap_write(void *opaque, target_phys_addr_t addr,
2762                 uint32_t value)
2763 {
2764     OMAP_BAD_REG(addr);
2765 }
2766
2767 static CPUReadMemoryFunc *omap_tap_readfn[] = {
2768     omap_badwidth_read32,
2769     omap_badwidth_read32,
2770     omap_tap_read,
2771 };
2772
2773 static CPUWriteMemoryFunc *omap_tap_writefn[] = {
2774     omap_badwidth_write32,
2775     omap_badwidth_write32,
2776     omap_tap_write,
2777 };
2778
2779 void omap_tap_init(struct omap_target_agent_s *ta,
2780                 struct omap_mpu_state_s *mpu)
2781 {
2782     omap_l4_attach(ta, 0, l4_register_io_memory(0,
2783                             omap_tap_readfn, omap_tap_writefn, mpu));
2784 }
2785
2786 /* Power, Reset, and Clock Management */
2787 struct omap_prcm_s {
2788     qemu_irq irq[3];
2789     struct omap_mpu_state_s *mpu;
2790
2791     uint32_t irqst[3];
2792     uint32_t irqen[3];
2793
2794     uint32_t sysconfig;
2795     uint32_t voltctrl;
2796     uint32_t scratch[20];
2797
2798     uint32_t clksrc[1];
2799     uint32_t clkout[1];
2800     uint32_t clkemul[1];
2801     uint32_t clkpol[1];
2802     uint32_t clksel[8];
2803     uint32_t clken[12];
2804     uint32_t clkctrl[4];
2805     uint32_t clkidle[7];
2806     uint32_t setuptime[2];
2807
2808     uint32_t wkup[3];
2809     uint32_t wken[3];
2810     uint32_t wkst[3];
2811     uint32_t rst[4];
2812     uint32_t rstctrl[1];
2813     uint32_t power[4];
2814     uint32_t rsttime_wkup;
2815
2816     uint32_t ev;
2817     uint32_t evtime[2];
2818
2819     int dpll_lock, apll_lock[2];
2820 };
2821
2822 static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
2823 {
2824     qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
2825     /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
2826 }
2827
2828 static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr)
2829 {
2830     struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
2831     uint32_t ret;
2832
2833     switch (addr) {
2834     case 0x000: /* PRCM_REVISION */
2835         return 0x10;
2836
2837     case 0x010: /* PRCM_SYSCONFIG */
2838         return s->sysconfig;
2839
2840     case 0x018: /* PRCM_IRQSTATUS_MPU */
2841         return s->irqst[0];
2842
2843     case 0x01c: /* PRCM_IRQENABLE_MPU */
2844         return s->irqen[0];
2845
2846     case 0x050: /* PRCM_VOLTCTRL */
2847         return s->voltctrl;
2848     case 0x054: /* PRCM_VOLTST */
2849         return s->voltctrl & 3;
2850
2851     case 0x060: /* PRCM_CLKSRC_CTRL */
2852         return s->clksrc[0];
2853     case 0x070: /* PRCM_CLKOUT_CTRL */
2854         return s->clkout[0];
2855     case 0x078: /* PRCM_CLKEMUL_CTRL */
2856         return s->clkemul[0];
2857     case 0x080: /* PRCM_CLKCFG_CTRL */
2858     case 0x084: /* PRCM_CLKCFG_STATUS */
2859         return 0;
2860
2861     case 0x090: /* PRCM_VOLTSETUP */
2862         return s->setuptime[0];
2863
2864     case 0x094: /* PRCM_CLKSSETUP */
2865         return s->setuptime[1];
2866
2867     case 0x098: /* PRCM_POLCTRL */
2868         return s->clkpol[0];
2869
2870     case 0x0b0: /* GENERAL_PURPOSE1 */
2871     case 0x0b4: /* GENERAL_PURPOSE2 */
2872     case 0x0b8: /* GENERAL_PURPOSE3 */
2873     case 0x0bc: /* GENERAL_PURPOSE4 */
2874     case 0x0c0: /* GENERAL_PURPOSE5 */
2875     case 0x0c4: /* GENERAL_PURPOSE6 */
2876     case 0x0c8: /* GENERAL_PURPOSE7 */
2877     case 0x0cc: /* GENERAL_PURPOSE8 */
2878     case 0x0d0: /* GENERAL_PURPOSE9 */
2879     case 0x0d4: /* GENERAL_PURPOSE10 */
2880     case 0x0d8: /* GENERAL_PURPOSE11 */
2881     case 0x0dc: /* GENERAL_PURPOSE12 */
2882     case 0x0e0: /* GENERAL_PURPOSE13 */
2883     case 0x0e4: /* GENERAL_PURPOSE14 */
2884     case 0x0e8: /* GENERAL_PURPOSE15 */
2885     case 0x0ec: /* GENERAL_PURPOSE16 */
2886     case 0x0f0: /* GENERAL_PURPOSE17 */
2887     case 0x0f4: /* GENERAL_PURPOSE18 */
2888     case 0x0f8: /* GENERAL_PURPOSE19 */
2889     case 0x0fc: /* GENERAL_PURPOSE20 */
2890         return s->scratch[(addr - 0xb0) >> 2];
2891
2892     case 0x140: /* CM_CLKSEL_MPU */
2893         return s->clksel[0];
2894     case 0x148: /* CM_CLKSTCTRL_MPU */
2895         return s->clkctrl[0];
2896
2897     case 0x158: /* RM_RSTST_MPU */
2898         return s->rst[0];
2899     case 0x1c8: /* PM_WKDEP_MPU */
2900         return s->wkup[0];
2901     case 0x1d4: /* PM_EVGENCTRL_MPU */
2902         return s->ev;
2903     case 0x1d8: /* PM_EVEGENONTIM_MPU */
2904         return s->evtime[0];
2905     case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
2906         return s->evtime[1];
2907     case 0x1e0: /* PM_PWSTCTRL_MPU */
2908         return s->power[0];
2909     case 0x1e4: /* PM_PWSTST_MPU */
2910         return 0;
2911
2912     case 0x200: /* CM_FCLKEN1_CORE */
2913         return s->clken[0];
2914     case 0x204: /* CM_FCLKEN2_CORE */
2915         return s->clken[1];
2916     case 0x210: /* CM_ICLKEN1_CORE */
2917         return s->clken[2];
2918     case 0x214: /* CM_ICLKEN2_CORE */
2919         return s->clken[3];
2920     case 0x21c: /* CM_ICLKEN4_CORE */
2921         return s->clken[4];
2922
2923     case 0x220: /* CM_IDLEST1_CORE */
2924         /* TODO: check the actual iclk status */
2925         return 0x7ffffff9;
2926     case 0x224: /* CM_IDLEST2_CORE */
2927         /* TODO: check the actual iclk status */
2928         return 0x00000007;
2929     case 0x22c: /* CM_IDLEST4_CORE */
2930         /* TODO: check the actual iclk status */
2931         return 0x0000001f;
2932
2933     case 0x230: /* CM_AUTOIDLE1_CORE */
2934         return s->clkidle[0];
2935     case 0x234: /* CM_AUTOIDLE2_CORE */
2936         return s->clkidle[1];
2937     case 0x238: /* CM_AUTOIDLE3_CORE */
2938         return s->clkidle[2];
2939     case 0x23c: /* CM_AUTOIDLE4_CORE */
2940         return s->clkidle[3];
2941
2942     case 0x240: /* CM_CLKSEL1_CORE */
2943         return s->clksel[1];
2944     case 0x244: /* CM_CLKSEL2_CORE */
2945         return s->clksel[2];
2946
2947     case 0x248: /* CM_CLKSTCTRL_CORE */
2948         return s->clkctrl[1];
2949
2950     case 0x2a0: /* PM_WKEN1_CORE */
2951         return s->wken[0];
2952     case 0x2a4: /* PM_WKEN2_CORE */
2953         return s->wken[1];
2954
2955     case 0x2b0: /* PM_WKST1_CORE */
2956         return s->wkst[0];
2957     case 0x2b4: /* PM_WKST2_CORE */
2958         return s->wkst[1];
2959     case 0x2c8: /* PM_WKDEP_CORE */
2960         return 0x1e;
2961
2962     case 0x2e0: /* PM_PWSTCTRL_CORE */
2963         return s->power[1];
2964     case 0x2e4: /* PM_PWSTST_CORE */
2965         return 0x000030 | (s->power[1] & 0xfc00);
2966
2967     case 0x300: /* CM_FCLKEN_GFX */
2968         return s->clken[5];
2969     case 0x310: /* CM_ICLKEN_GFX */
2970         return s->clken[6];
2971     case 0x320: /* CM_IDLEST_GFX */
2972         /* TODO: check the actual iclk status */
2973         return 0x00000001;
2974     case 0x340: /* CM_CLKSEL_GFX */
2975         return s->clksel[3];
2976     case 0x348: /* CM_CLKSTCTRL_GFX */
2977         return s->clkctrl[2];
2978     case 0x350: /* RM_RSTCTRL_GFX */
2979         return s->rstctrl[0];
2980     case 0x358: /* RM_RSTST_GFX */
2981         return s->rst[1];
2982     case 0x3c8: /* PM_WKDEP_GFX */
2983         return s->wkup[1];
2984
2985     case 0x3e0: /* PM_PWSTCTRL_GFX */
2986         return s->power[2];
2987     case 0x3e4: /* PM_PWSTST_GFX */
2988         return s->power[2] & 3;
2989
2990     case 0x400: /* CM_FCLKEN_WKUP */
2991         return s->clken[7];
2992     case 0x410: /* CM_ICLKEN_WKUP */
2993         return s->clken[8];
2994     case 0x420: /* CM_IDLEST_WKUP */
2995         /* TODO: check the actual iclk status */
2996         return 0x0000003f;
2997     case 0x430: /* CM_AUTOIDLE_WKUP */
2998         return s->clkidle[4];
2999     case 0x440: /* CM_CLKSEL_WKUP */
3000         return s->clksel[4];
3001     case 0x450: /* RM_RSTCTRL_WKUP */
3002         return 0;
3003     case 0x454: /* RM_RSTTIME_WKUP */
3004         return s->rsttime_wkup;
3005     case 0x458: /* RM_RSTST_WKUP */
3006         return s->rst[2];
3007     case 0x4a0: /* PM_WKEN_WKUP */
3008         return s->wken[2];
3009     case 0x4b0: /* PM_WKST_WKUP */
3010         return s->wkst[2];
3011
3012     case 0x500: /* CM_CLKEN_PLL */
3013         return s->clken[9];
3014     case 0x520: /* CM_IDLEST_CKGEN */
3015         ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8);
3016         if (!(s->clksel[6] & 3))
3017             /* Core uses 32-kHz clock */
3018             ret |= 3 << 0;
3019         else if (!s->dpll_lock)
3020             /* DPLL not locked, core uses ref_clk */
3021             ret |= 1 << 0;
3022         else
3023             /* Core uses DPLL */
3024             ret |= 2 << 0;
3025         return ret;
3026     case 0x530: /* CM_AUTOIDLE_PLL */
3027         return s->clkidle[5];
3028     case 0x540: /* CM_CLKSEL1_PLL */
3029         return s->clksel[5];
3030     case 0x544: /* CM_CLKSEL2_PLL */
3031         return s->clksel[6];
3032
3033     case 0x800: /* CM_FCLKEN_DSP */
3034         return s->clken[10];
3035     case 0x810: /* CM_ICLKEN_DSP */
3036         return s->clken[11];
3037     case 0x820: /* CM_IDLEST_DSP */
3038         /* TODO: check the actual iclk status */
3039         return 0x00000103;
3040     case 0x830: /* CM_AUTOIDLE_DSP */
3041         return s->clkidle[6];
3042     case 0x840: /* CM_CLKSEL_DSP */
3043         return s->clksel[7];
3044     case 0x848: /* CM_CLKSTCTRL_DSP */
3045         return s->clkctrl[3];
3046     case 0x850: /* RM_RSTCTRL_DSP */
3047         return 0;
3048     case 0x858: /* RM_RSTST_DSP */
3049         return s->rst[3];
3050     case 0x8c8: /* PM_WKDEP_DSP */
3051         return s->wkup[2];
3052     case 0x8e0: /* PM_PWSTCTRL_DSP */
3053         return s->power[3];
3054     case 0x8e4: /* PM_PWSTST_DSP */
3055         return 0x008030 | (s->power[3] & 0x3003);
3056
3057     case 0x8f0: /* PRCM_IRQSTATUS_DSP */
3058         return s->irqst[1];
3059     case 0x8f4: /* PRCM_IRQENABLE_DSP */
3060         return s->irqen[1];
3061
3062     case 0x8f8: /* PRCM_IRQSTATUS_IVA */
3063         return s->irqst[2];
3064     case 0x8fc: /* PRCM_IRQENABLE_IVA */
3065         return s->irqen[2];
3066     }
3067
3068     OMAP_BAD_REG(addr);
3069     return 0;
3070 }
3071
3072 static void omap_prcm_apll_update(struct omap_prcm_s *s)
3073 {
3074     int mode[2];
3075
3076     mode[0] = (s->clken[9] >> 6) & 3;
3077     s->apll_lock[0] = (mode[0] == 3);
3078     mode[1] = (s->clken[9] >> 2) & 3;
3079     s->apll_lock[1] = (mode[1] == 3);
3080     /* TODO: update clocks */
3081
3082     if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[2] == 2)
3083         fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
3084                         __FUNCTION__);
3085 }
3086
3087 static void omap_prcm_dpll_update(struct omap_prcm_s *s)
3088 {
3089     omap_clk dpll = omap_findclk(s->mpu, "dpll");
3090     omap_clk dpll_x2 = omap_findclk(s->mpu, "dpll");
3091     omap_clk core = omap_findclk(s->mpu, "core_clk");
3092     int mode = (s->clken[9] >> 0) & 3;
3093     int mult, div;
3094
3095     mult = (s->clksel[5] >> 12) & 0x3ff;
3096     div = (s->clksel[5] >> 8) & 0xf;
3097     if (mult == 0 || mult == 1)
3098         mode = 1;       /* Bypass */
3099
3100     s->dpll_lock = 0;
3101     switch (mode) {
3102     case 0:
3103         fprintf(stderr, "%s: bad EN_DPLL\n", __FUNCTION__);
3104         break;
3105     case 1:     /* Low-power bypass mode (Default) */
3106     case 2:     /* Fast-relock bypass mode */
3107         omap_clk_setrate(dpll, 1, 1);
3108         omap_clk_setrate(dpll_x2, 1, 1);
3109         break;
3110     case 3:     /* Lock mode */
3111         s->dpll_lock = 1; /* After 20 FINT cycles (ref_clk / (div + 1)).  */
3112
3113         omap_clk_setrate(dpll, div + 1, mult);
3114         omap_clk_setrate(dpll_x2, div + 1, mult * 2);
3115         break;
3116     }
3117
3118     switch ((s->clksel[6] >> 0) & 3) {
3119     case 0:
3120         omap_clk_reparent(core, omap_findclk(s->mpu, "clk32-kHz"));
3121         break;
3122     case 1:
3123         omap_clk_reparent(core, dpll);
3124         break;
3125     case 2:
3126         /* Default */
3127         omap_clk_reparent(core, dpll_x2);
3128         break;
3129     case 3:
3130         fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __FUNCTION__);
3131         break;
3132     }
3133 }
3134
3135 static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
3136                 uint32_t value)
3137 {
3138     struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
3139
3140     switch (addr) {
3141     case 0x000: /* PRCM_REVISION */
3142     case 0x054: /* PRCM_VOLTST */
3143     case 0x084: /* PRCM_CLKCFG_STATUS */
3144     case 0x1e4: /* PM_PWSTST_MPU */
3145     case 0x220: /* CM_IDLEST1_CORE */
3146     case 0x224: /* CM_IDLEST2_CORE */
3147     case 0x22c: /* CM_IDLEST4_CORE */
3148     case 0x2c8: /* PM_WKDEP_CORE */
3149     case 0x2e4: /* PM_PWSTST_CORE */
3150     case 0x320: /* CM_IDLEST_GFX */
3151     case 0x3e4: /* PM_PWSTST_GFX */
3152     case 0x420: /* CM_IDLEST_WKUP */
3153     case 0x520: /* CM_IDLEST_CKGEN */
3154     case 0x820: /* CM_IDLEST_DSP */
3155     case 0x8e4: /* PM_PWSTST_DSP */
3156         OMAP_RO_REG(addr);
3157         return;
3158
3159     case 0x010: /* PRCM_SYSCONFIG */
3160         s->sysconfig = value & 1;
3161         break;
3162
3163     case 0x018: /* PRCM_IRQSTATUS_MPU */
3164         s->irqst[0] &= ~value;
3165         omap_prcm_int_update(s, 0);
3166         break;
3167     case 0x01c: /* PRCM_IRQENABLE_MPU */
3168         s->irqen[0] = value & 0x3f;
3169         omap_prcm_int_update(s, 0);
3170         break;
3171
3172     case 0x050: /* PRCM_VOLTCTRL */
3173         s->voltctrl = value & 0xf1c3;
3174         break;
3175
3176     case 0x060: /* PRCM_CLKSRC_CTRL */
3177         s->clksrc[0] = value & 0xdb;
3178         /* TODO update clocks */
3179         break;
3180
3181     case 0x070: /* PRCM_CLKOUT_CTRL */
3182         s->clkout[0] = value & 0xbbbb;
3183         /* TODO update clocks */
3184         break;
3185
3186     case 0x078: /* PRCM_CLKEMUL_CTRL */
3187         s->clkemul[0] = value & 1;
3188         /* TODO update clocks */
3189         break;
3190
3191     case 0x080: /* PRCM_CLKCFG_CTRL */
3192         break;
3193
3194     case 0x090: /* PRCM_VOLTSETUP */
3195         s->setuptime[0] = value & 0xffff;
3196         break;
3197     case 0x094: /* PRCM_CLKSSETUP */
3198         s->setuptime[1] = value & 0xffff;
3199         break;
3200
3201     case 0x098: /* PRCM_POLCTRL */
3202         s->clkpol[0] = value & 0x701;
3203         break;
3204
3205     case 0x0b0: /* GENERAL_PURPOSE1 */
3206     case 0x0b4: /* GENERAL_PURPOSE2 */
3207     case 0x0b8: /* GENERAL_PURPOSE3 */
3208     case 0x0bc: /* GENERAL_PURPOSE4 */
3209     case 0x0c0: /* GENERAL_PURPOSE5 */
3210     case 0x0c4: /* GENERAL_PURPOSE6 */
3211     case 0x0c8: /* GENERAL_PURPOSE7 */
3212     case 0x0cc: /* GENERAL_PURPOSE8 */
3213     case 0x0d0: /* GENERAL_PURPOSE9 */
3214     case 0x0d4: /* GENERAL_PURPOSE10 */
3215     case 0x0d8: /* GENERAL_PURPOSE11 */
3216     case 0x0dc: /* GENERAL_PURPOSE12 */
3217     case 0x0e0: /* GENERAL_PURPOSE13 */
3218     case 0x0e4: /* GENERAL_PURPOSE14 */
3219     case 0x0e8: /* GENERAL_PURPOSE15 */
3220     case 0x0ec: /* GENERAL_PURPOSE16 */
3221     case 0x0f0: /* GENERAL_PURPOSE17 */
3222     case 0x0f4: /* GENERAL_PURPOSE18 */
3223     case 0x0f8: /* GENERAL_PURPOSE19 */
3224     case 0x0fc: /* GENERAL_PURPOSE20 */
3225         s->scratch[(addr - 0xb0) >> 2] = value;
3226         break;
3227
3228     case 0x140: /* CM_CLKSEL_MPU */
3229         s->clksel[0] = value & 0x1f;
3230         /* TODO update clocks */
3231         break;
3232     case 0x148: /* CM_CLKSTCTRL_MPU */
3233         s->clkctrl[0] = value & 0x1f;
3234         break;
3235
3236     case 0x158: /* RM_RSTST_MPU */
3237         s->rst[0] &= ~value;
3238         break;
3239     case 0x1c8: /* PM_WKDEP_MPU */
3240         s->wkup[0] = value & 0x15;
3241         break;
3242
3243     case 0x1d4: /* PM_EVGENCTRL_MPU */
3244         s->ev = value & 0x1f;
3245         break;
3246     case 0x1d8: /* PM_EVEGENONTIM_MPU */
3247         s->evtime[0] = value;
3248         break;
3249     case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
3250         s->evtime[1] = value;
3251         break;
3252
3253     case 0x1e0: /* PM_PWSTCTRL_MPU */
3254         s->power[0] = value & 0xc0f;
3255         break;
3256
3257     case 0x200: /* CM_FCLKEN1_CORE */
3258         s->clken[0] = value & 0xbfffffff;
3259         /* TODO update clocks */
3260         /* The EN_EAC bit only gets/puts func_96m_clk.  */
3261         break;
3262     case 0x204: /* CM_FCLKEN2_CORE */
3263         s->clken[1] = value & 0x00000007;
3264         /* TODO update clocks */
3265         break;
3266     case 0x210: /* CM_ICLKEN1_CORE */
3267         s->clken[2] = value & 0xfffffff9;
3268         /* TODO update clocks */
3269         /* The EN_EAC bit only gets/puts core_l4_iclk.  */
3270         break;
3271     case 0x214: /* CM_ICLKEN2_CORE */
3272         s->clken[3] = value & 0x00000007;
3273         /* TODO update clocks */
3274         break;
3275     case 0x21c: /* CM_ICLKEN4_CORE */
3276         s->clken[4] = value & 0x0000001f;
3277         /* TODO update clocks */
3278         break;
3279
3280     case 0x230: /* CM_AUTOIDLE1_CORE */
3281         s->clkidle[0] = value & 0xfffffff9;
3282         /* TODO update clocks */
3283         break;
3284     case 0x234: /* CM_AUTOIDLE2_CORE */
3285         s->clkidle[1] = value & 0x00000007;
3286         /* TODO update clocks */
3287         break;
3288     case 0x238: /* CM_AUTOIDLE3_CORE */
3289         s->clkidle[2] = value & 0x00000007;
3290         /* TODO update clocks */
3291         break;
3292     case 0x23c: /* CM_AUTOIDLE4_CORE */
3293         s->clkidle[3] = value & 0x0000001f;
3294         /* TODO update clocks */
3295         break;
3296
3297     case 0x240: /* CM_CLKSEL1_CORE */
3298         s->clksel[1] = value & 0x0fffbf7f;
3299         /* TODO update clocks */
3300         break;
3301
3302     case 0x244: /* CM_CLKSEL2_CORE */
3303         s->clksel[2] = value & 0x00fffffc;
3304         /* TODO update clocks */
3305         break;
3306
3307     case 0x248: /* CM_CLKSTCTRL_CORE */
3308         s->clkctrl[1] = value & 0x7;
3309         break;
3310
3311     case 0x2a0: /* PM_WKEN1_CORE */
3312         s->wken[0] = value & 0x04667ff8;
3313         break;
3314     case 0x2a4: /* PM_WKEN2_CORE */
3315         s->wken[1] = value & 0x00000005;
3316         break;
3317
3318     case 0x2b0: /* PM_WKST1_CORE */
3319         s->wkst[0] &= ~value;
3320         break;
3321     case 0x2b4: /* PM_WKST2_CORE */
3322         s->wkst[1] &= ~value;
3323         break;
3324
3325     case 0x2e0: /* PM_PWSTCTRL_CORE */
3326         s->power[1] = (value & 0x00fc3f) | (1 << 2);
3327         break;
3328
3329     case 0x300: /* CM_FCLKEN_GFX */
3330         s->clken[5] = value & 6;
3331         /* TODO update clocks */
3332         break;
3333     case 0x310: /* CM_ICLKEN_GFX */
3334         s->clken[6] = value & 1;
3335         /* TODO update clocks */
3336         break;
3337     case 0x340: /* CM_CLKSEL_GFX */
3338         s->clksel[3] = value & 7;
3339         /* TODO update clocks */
3340         break;
3341     case 0x348: /* CM_CLKSTCTRL_GFX */
3342         s->clkctrl[2] = value & 1;
3343         break;
3344     case 0x350: /* RM_RSTCTRL_GFX */
3345         s->rstctrl[0] = value & 1;
3346         /* TODO: reset */
3347         break;
3348     case 0x358: /* RM_RSTST_GFX */
3349         s->rst[1] &= ~value;
3350         break;
3351     case 0x3c8: /* PM_WKDEP_GFX */
3352         s->wkup[1] = value & 0x13;
3353         break;
3354     case 0x3e0: /* PM_PWSTCTRL_GFX */
3355         s->power[2] = (value & 0x00c0f) | (3 << 2);
3356         break;
3357
3358     case 0x400: /* CM_FCLKEN_WKUP */
3359         s->clken[7] = value & 0xd;
3360         /* TODO update clocks */
3361         break;
3362     case 0x410: /* CM_ICLKEN_WKUP */
3363         s->clken[8] = value & 0x3f;
3364         /* TODO update clocks */
3365         break;
3366     case 0x430: /* CM_AUTOIDLE_WKUP */
3367         s->clkidle[4] = value & 0x0000003f;
3368         /* TODO update clocks */
3369         break;
3370     case 0x440: /* CM_CLKSEL_WKUP */
3371         s->clksel[4] = value & 3;
3372         /* TODO update clocks */
3373         break;
3374     case 0x450: /* RM_RSTCTRL_WKUP */
3375         /* TODO: reset */
3376         if (value & 2)
3377             qemu_system_reset_request();
3378         break;
3379     case 0x454: /* RM_RSTTIME_WKUP */
3380         s->rsttime_wkup = value & 0x1fff;
3381         break;
3382     case 0x458: /* RM_RSTST_WKUP */
3383         s->rst[2] &= ~value;
3384         break;
3385     case 0x4a0: /* PM_WKEN_WKUP */
3386         s->wken[2] = value & 0x00000005;
3387         break;
3388     case 0x4b0: /* PM_WKST_WKUP */
3389         s->wkst[2] &= ~value;
3390         break;
3391
3392     case 0x500: /* CM_CLKEN_PLL */
3393         if (value & 0xffffff30)
3394             fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
3395                             "future compatiblity\n", __FUNCTION__);
3396         if ((s->clken[9] ^ value) & 0xcc) {
3397             s->clken[9] &= ~0xcc;
3398             s->clken[9] |= value & 0xcc;
3399             omap_prcm_apll_update(s);
3400         }
3401         if ((s->clken[9] ^ value) & 3) {
3402             s->clken[9] &= ~3;
3403             s->clken[9] |= value & 3;
3404             omap_prcm_dpll_update(s);
3405         }
3406         break;
3407     case 0x530: /* CM_AUTOIDLE_PLL */
3408         s->clkidle[5] = value & 0x000000cf;
3409         /* TODO update clocks */
3410         break;
3411     case 0x540: /* CM_CLKSEL1_PLL */
3412         if (value & 0xfc4000d7)
3413             fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
3414                             "future compatiblity\n", __FUNCTION__);
3415         if ((s->clksel[5] ^ value) & 0x003fff00) {
3416             s->clksel[5] = value & 0x03bfff28;
3417             omap_prcm_dpll_update(s);
3418         }
3419         /* TODO update the other clocks */
3420
3421         s->clksel[5] = value & 0x03bfff28;
3422         break;
3423     case 0x544: /* CM_CLKSEL2_PLL */
3424         if (value & ~3)
3425             fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
3426                             "future compatiblity\n", __FUNCTION__);
3427         if (s->clksel[6] != (value & 3)) {
3428             s->clksel[6] = value & 3;
3429             omap_prcm_dpll_update(s);
3430         }
3431         break;
3432
3433     case 0x800: /* CM_FCLKEN_DSP */
3434         s->clken[10] = value & 0x501;
3435         /* TODO update clocks */
3436         break;
3437     case 0x810: /* CM_ICLKEN_DSP */
3438         s->clken[11] = value & 0x2;
3439         /* TODO update clocks */
3440         break;
3441     case 0x830: /* CM_AUTOIDLE_DSP */
3442         s->clkidle[6] = value & 0x2;
3443         /* TODO update clocks */
3444         break;
3445     case 0x840: /* CM_CLKSEL_DSP */
3446         s->clksel[7] = value & 0x3fff;
3447         /* TODO update clocks */
3448         break;
3449     case 0x848: /* CM_CLKSTCTRL_DSP */
3450         s->clkctrl[3] = value & 0x101;
3451         break;
3452     case 0x850: /* RM_RSTCTRL_DSP */
3453         /* TODO: reset */
3454         break;
3455     case 0x858: /* RM_RSTST_DSP */
3456         s->rst[3] &= ~value;
3457         break;
3458     case 0x8c8: /* PM_WKDEP_DSP */
3459         s->wkup[2] = value & 0x13;
3460         break;
3461     case 0x8e0: /* PM_PWSTCTRL_DSP */
3462         s->power[3] = (value & 0x03017) | (3 << 2);
3463         break;
3464
3465     case 0x8f0: /* PRCM_IRQSTATUS_DSP */
3466         s->irqst[1] &= ~value;
3467         omap_prcm_int_update(s, 1);
3468         break;
3469     case 0x8f4: /* PRCM_IRQENABLE_DSP */
3470         s->irqen[1] = value & 0x7;
3471         omap_prcm_int_update(s, 1);
3472         break;
3473
3474     case 0x8f8: /* PRCM_IRQSTATUS_IVA */
3475         s->irqst[2] &= ~value;
3476         omap_prcm_int_update(s, 2);
3477         break;
3478     case 0x8fc: /* PRCM_IRQENABLE_IVA */
3479         s->irqen[2] = value & 0x7;
3480         omap_prcm_int_update(s, 2);
3481         break;
3482
3483     default:
3484         OMAP_BAD_REG(addr);
3485         return;
3486     }
3487 }
3488
3489 static CPUReadMemoryFunc *omap_prcm_readfn[] = {
3490     omap_badwidth_read32,
3491     omap_badwidth_read32,
3492     omap_prcm_read,
3493 };
3494
3495 static CPUWriteMemoryFunc *omap_prcm_writefn[] = {
3496     omap_badwidth_write32,
3497     omap_badwidth_write32,
3498     omap_prcm_write,
3499 };
3500
3501 static void omap_prcm_reset(struct omap_prcm_s *s)
3502 {
3503     s->sysconfig = 0;
3504     s->irqst[0] = 0;
3505     s->irqst[1] = 0;
3506     s->irqst[2] = 0;
3507     s->irqen[0] = 0;
3508     s->irqen[1] = 0;
3509     s->irqen[2] = 0;
3510     s->voltctrl = 0x1040;
3511     s->ev = 0x14;
3512     s->evtime[0] = 0;
3513     s->evtime[1] = 0;
3514     s->clkctrl[0] = 0;
3515     s->clkctrl[1] = 0;
3516     s->clkctrl[2] = 0;
3517     s->clkctrl[3] = 0;
3518     s->clken[1] = 7;
3519     s->clken[3] = 7;
3520     s->clken[4] = 0;
3521     s->clken[5] = 0;
3522     s->clken[6] = 0;
3523     s->clken[7] = 0xc;
3524     s->clken[8] = 0x3e;
3525     s->clken[9] = 0x0d;
3526     s->clken[10] = 0;
3527     s->clken[11] = 0;
3528     s->clkidle[0] = 0;
3529     s->clkidle[2] = 7;
3530     s->clkidle[3] = 0;
3531     s->clkidle[4] = 0;
3532     s->clkidle[5] = 0x0c;
3533     s->clkidle[6] = 0;
3534     s->clksel[0] = 0x01;
3535     s->clksel[1] = 0x02100121;
3536     s->clksel[2] = 0x00000000;
3537     s->clksel[3] = 0x01;
3538     s->clksel[4] = 0;
3539     s->clksel[7] = 0x0121;
3540     s->wkup[0] = 0x15;
3541     s->wkup[1] = 0x13;
3542     s->wkup[2] = 0x13;
3543     s->wken[0] = 0x04667ff8;
3544     s->wken[1] = 0x00000005;
3545     s->wken[2] = 5;
3546     s->wkst[0] = 0;
3547     s->wkst[1] = 0;
3548     s->wkst[2] = 0;
3549     s->power[0] = 0x00c;
3550     s->power[1] = 4;
3551     s->power[2] = 0x0000c;
3552     s->power[3] = 0x14;
3553     s->rstctrl[0] = 1;
3554     s->rst[3] = 1;
3555     omap_prcm_apll_update(s);
3556     omap_prcm_dpll_update(s);
3557 }
3558
3559 static void omap_prcm_coldreset(struct omap_prcm_s *s)
3560 {
3561     s->setuptime[0] = 0;
3562     s->setuptime[1] = 0;
3563     memset(&s->scratch, 0, sizeof(s->scratch));
3564     s->rst[0] = 0x01;
3565     s->rst[1] = 0x00;
3566     s->rst[2] = 0x01;
3567     s->clken[0] = 0;
3568     s->clken[2] = 0;
3569     s->clkidle[1] = 0;
3570     s->clksel[5] = 0;
3571     s->clksel[6] = 2;
3572     s->clksrc[0] = 0x43;
3573     s->clkout[0] = 0x0303;
3574     s->clkemul[0] = 0;
3575     s->clkpol[0] = 0x100;
3576     s->rsttime_wkup = 0x1002;
3577
3578     omap_prcm_reset(s);
3579 }
3580
3581 struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
3582                 qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
3583                 struct omap_mpu_state_s *mpu)
3584 {
3585     int iomemtype;
3586     struct omap_prcm_s *s = (struct omap_prcm_s *)
3587             qemu_mallocz(sizeof(struct omap_prcm_s));
3588
3589     s->irq[0] = mpu_int;
3590     s->irq[1] = dsp_int;
3591     s->irq[2] = iva_int;
3592     s->mpu = mpu;
3593     omap_prcm_coldreset(s);
3594
3595     iomemtype = l4_register_io_memory(0, omap_prcm_readfn,
3596                     omap_prcm_writefn, s);
3597     omap_l4_attach(ta, 0, iomemtype);
3598     omap_l4_attach(ta, 1, iomemtype);
3599
3600     return s;
3601 }
3602
3603 /* System and Pinout control */
3604 struct omap_sysctl_s {
3605     struct omap_mpu_state_s *mpu;
3606
3607     uint32_t sysconfig;
3608     uint32_t devconfig;
3609     uint32_t psaconfig;
3610     uint32_t padconf[0x45];
3611     uint8_t obs;
3612     uint32_t msuspendmux[5];
3613 };
3614
3615 static uint32_t omap_sysctl_read8(void *opaque, target_phys_addr_t addr)
3616 {
3617
3618     struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3619     int pad_offset, byte_offset;
3620     int value;
3621
3622     switch (addr) {
3623     case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
3624         pad_offset = (addr - 0x30) >> 2;
3625         byte_offset = (addr - 0x30) & (4 - 1);
3626
3627         value = s->padconf[pad_offset];
3628         value = (value >> (byte_offset * 8)) & 0xff;
3629
3630         return value;
3631
3632     default:
3633         break;
3634     }
3635
3636     OMAP_BAD_REG(addr);
3637     return 0;
3638 }
3639
3640 static uint32_t omap_sysctl_read(void *opaque, target_phys_addr_t addr)
3641 {
3642     struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3643
3644     switch (addr) {
3645     case 0x000: /* CONTROL_REVISION */
3646         return 0x20;
3647
3648     case 0x010: /* CONTROL_SYSCONFIG */
3649         return s->sysconfig;
3650
3651     case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
3652         return s->padconf[(addr - 0x30) >> 2];
3653
3654     case 0x270: /* CONTROL_DEBOBS */
3655         return s->obs;
3656
3657     case 0x274: /* CONTROL_DEVCONF */
3658         return s->devconfig;
3659
3660     case 0x28c: /* CONTROL_EMU_SUPPORT */
3661         return 0;
3662
3663     case 0x290: /* CONTROL_MSUSPENDMUX_0 */
3664         return s->msuspendmux[0];
3665     case 0x294: /* CONTROL_MSUSPENDMUX_1 */
3666         return s->msuspendmux[1];
3667     case 0x298: /* CONTROL_MSUSPENDMUX_2 */
3668         return s->msuspendmux[2];
3669     case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
3670         return s->msuspendmux[3];
3671     case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
3672         return s->msuspendmux[4];
3673     case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
3674         return 0;
3675
3676     case 0x2b8: /* CONTROL_PSA_CTRL */
3677         return s->psaconfig;
3678     case 0x2bc: /* CONTROL_PSA_CMD */
3679     case 0x2c0: /* CONTROL_PSA_VALUE */
3680         return 0;
3681
3682     case 0x2b0: /* CONTROL_SEC_CTRL */
3683         return 0x800000f1;
3684     case 0x2d0: /* CONTROL_SEC_EMU */
3685         return 0x80000015;
3686     case 0x2d4: /* CONTROL_SEC_TAP */
3687         return 0x8000007f;
3688     case 0x2b4: /* CONTROL_SEC_TEST */
3689     case 0x2f0: /* CONTROL_SEC_STATUS */
3690     case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
3691         /* Secure mode is not present on general-pusrpose device.  Outside
3692          * secure mode these values cannot be read or written.  */
3693         return 0;
3694
3695     case 0x2d8: /* CONTROL_OCM_RAM_PERM */
3696         return 0xff;
3697     case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
3698     case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
3699     case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
3700         /* No secure mode so no Extended Secure RAM present.  */
3701         return 0;
3702
3703     case 0x2f8: /* CONTROL_STATUS */
3704         /* Device Type => General-purpose */
3705         return 0x0300;
3706     case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
3707
3708     case 0x300: /* CONTROL_RPUB_KEY_H_0 */
3709     case 0x304: /* CONTROL_RPUB_KEY_H_1 */
3710     case 0x308: /* CONTROL_RPUB_KEY_H_2 */
3711     case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
3712         return 0xdecafbad;
3713
3714     case 0x310: /* CONTROL_RAND_KEY_0 */
3715     case 0x314: /* CONTROL_RAND_KEY_1 */
3716     case 0x318: /* CONTROL_RAND_KEY_2 */
3717     case 0x31c: /* CONTROL_RAND_KEY_3 */
3718     case 0x320: /* CONTROL_CUST_KEY_0 */
3719     case 0x324: /* CONTROL_CUST_KEY_1 */
3720     case 0x330: /* CONTROL_TEST_KEY_0 */
3721     case 0x334: /* CONTROL_TEST_KEY_1 */
3722     case 0x338: /* CONTROL_TEST_KEY_2 */
3723     case 0x33c: /* CONTROL_TEST_KEY_3 */
3724     case 0x340: /* CONTROL_TEST_KEY_4 */
3725     case 0x344: /* CONTROL_TEST_KEY_5 */
3726     case 0x348: /* CONTROL_TEST_KEY_6 */
3727     case 0x34c: /* CONTROL_TEST_KEY_7 */
3728     case 0x350: /* CONTROL_TEST_KEY_8 */
3729     case 0x354: /* CONTROL_TEST_KEY_9 */
3730         /* Can only be accessed in secure mode and when C_FieldAccEnable
3731          * bit is set in CONTROL_SEC_CTRL.
3732          * TODO: otherwise an interconnect access error is generated.  */
3733         return 0;
3734     }
3735
3736     OMAP_BAD_REG(addr);
3737     return 0;
3738 }
3739
3740 static void omap_sysctl_write8(void *opaque, target_phys_addr_t addr,
3741                 uint32_t value)
3742 {
3743     struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3744     int pad_offset, byte_offset;
3745     int prev_value;
3746
3747     switch (addr) {
3748     case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
3749         pad_offset = (addr - 0x30) >> 2;
3750         byte_offset = (addr - 0x30) & (4 - 1);
3751
3752         prev_value = s->padconf[pad_offset];
3753         prev_value &= ~(0xff << (byte_offset * 8));
3754         prev_value |= ((value & 0x1f1f1f1f) << (byte_offset * 8)) & 0x1f1f1f1f;
3755         s->padconf[pad_offset] = prev_value;
3756         break;
3757
3758     default:
3759         OMAP_BAD_REG(addr);
3760         break;
3761     }
3762 }
3763
3764 static void omap_sysctl_write(void *opaque, target_phys_addr_t addr,
3765                 uint32_t value)
3766 {
3767     struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3768
3769     switch (addr) {
3770     case 0x000: /* CONTROL_REVISION */
3771     case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
3772     case 0x2c0: /* CONTROL_PSA_VALUE */
3773     case 0x2f8: /* CONTROL_STATUS */
3774     case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
3775     case 0x300: /* CONTROL_RPUB_KEY_H_0 */
3776     case 0x304: /* CONTROL_RPUB_KEY_H_1 */
3777     case 0x308: /* CONTROL_RPUB_KEY_H_2 */
3778     case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
3779     case 0x310: /* CONTROL_RAND_KEY_0 */
3780     case 0x314: /* CONTROL_RAND_KEY_1 */
3781     case 0x318: /* CONTROL_RAND_KEY_2 */
3782     case 0x31c: /* CONTROL_RAND_KEY_3 */
3783     case 0x320: /* CONTROL_CUST_KEY_0 */
3784     case 0x324: /* CONTROL_CUST_KEY_1 */
3785     case 0x330: /* CONTROL_TEST_KEY_0 */
3786     case 0x334: /* CONTROL_TEST_KEY_1 */
3787     case 0x338: /* CONTROL_TEST_KEY_2 */
3788     case 0x33c: /* CONTROL_TEST_KEY_3 */
3789     case 0x340: /* CONTROL_TEST_KEY_4 */
3790     case 0x344: /* CONTROL_TEST_KEY_5 */
3791     case 0x348: /* CONTROL_TEST_KEY_6 */
3792     case 0x34c: /* CONTROL_TEST_KEY_7 */
3793     case 0x350: /* CONTROL_TEST_KEY_8 */
3794     case 0x354: /* CONTROL_TEST_KEY_9 */
3795         OMAP_RO_REG(addr);
3796         return;
3797
3798     case 0x010: /* CONTROL_SYSCONFIG */
3799         s->sysconfig = value & 0x1e;
3800         break;
3801
3802     case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
3803         /* XXX: should check constant bits */
3804         s->padconf[(addr - 0x30) >> 2] = value & 0x1f1f1f1f;
3805         break;
3806
3807     case 0x270: /* CONTROL_DEBOBS */
3808         s->obs = value & 0xff;
3809         break;
3810
3811     case 0x274: /* CONTROL_DEVCONF */
3812         s->devconfig = value & 0xffffc7ff;
3813         break;
3814
3815     case 0x28c: /* CONTROL_EMU_SUPPORT */
3816         break;
3817
3818     case 0x290: /* CONTROL_MSUSPENDMUX_0 */
3819         s->msuspendmux[0] = value & 0x3fffffff;
3820         break;
3821     case 0x294: /* CONTROL_MSUSPENDMUX_1 */
3822         s->msuspendmux[1] = value & 0x3fffffff;
3823         break;
3824     case 0x298: /* CONTROL_MSUSPENDMUX_2 */
3825         s->msuspendmux[2] = value & 0x3fffffff;
3826         break;
3827     case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
3828         s->msuspendmux[3] = value & 0x3fffffff;
3829         break;
3830     case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
3831         s->msuspendmux[4] = value & 0x3fffffff;
3832         break;
3833
3834     case 0x2b8: /* CONTROL_PSA_CTRL */
3835         s->psaconfig = value & 0x1c;
3836         s->psaconfig |= (value & 0x20) ? 2 : 1;
3837         break;
3838     case 0x2bc: /* CONTROL_PSA_CMD */
3839         break;
3840
3841     case 0x2b0: /* CONTROL_SEC_CTRL */
3842     case 0x2b4: /* CONTROL_SEC_TEST */
3843     case 0x2d0: /* CONTROL_SEC_EMU */
3844     case 0x2d4: /* CONTROL_SEC_TAP */
3845     case 0x2d8: /* CONTROL_OCM_RAM_PERM */
3846     case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
3847     case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
3848     case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
3849     case 0x2f0: /* CONTROL_SEC_STATUS */
3850     case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
3851         break;
3852
3853     default:
3854         OMAP_BAD_REG(addr);
3855         return;
3856     }
3857 }
3858
3859 static CPUReadMemoryFunc *omap_sysctl_readfn[] = {
3860     omap_sysctl_read8,
3861     omap_badwidth_read32,       /* TODO */
3862     omap_sysctl_read,
3863 };
3864
3865 static CPUWriteMemoryFunc *omap_sysctl_writefn[] = {
3866     omap_sysctl_write8,
3867     omap_badwidth_write32,      /* TODO */
3868     omap_sysctl_write,
3869 };
3870
3871 static void omap_sysctl_reset(struct omap_sysctl_s *s)
3872 {
3873     /* (power-on reset) */
3874     s->sysconfig = 0;
3875     s->obs = 0;
3876     s->devconfig = 0x0c000000;
3877     s->msuspendmux[0] = 0x00000000;
3878     s->msuspendmux[1] = 0x00000000;
3879     s->msuspendmux[2] = 0x00000000;
3880     s->msuspendmux[3] = 0x00000000;
3881     s->msuspendmux[4] = 0x00000000;
3882     s->psaconfig = 1;
3883
3884     s->padconf[0x00] = 0x000f0f0f;
3885     s->padconf[0x01] = 0x00000000;
3886     s->padconf[0x02] = 0x00000000;
3887     s->padconf[0x03] = 0x00000000;
3888     s->padconf[0x04] = 0x00000000;
3889     s->padconf[0x05] = 0x00000000;
3890     s->padconf[0x06] = 0x00000000;
3891     s->padconf[0x07] = 0x00000000;
3892     s->padconf[0x08] = 0x08080800;
3893     s->padconf[0x09] = 0x08080808;
3894     s->padconf[0x0a] = 0x08080808;
3895     s->padconf[0x0b] = 0x08080808;
3896     s->padconf[0x0c] = 0x08080808;
3897     s->padconf[0x0d] = 0x08080800;
3898     s->padconf[0x0e] = 0x08080808;
3899     s->padconf[0x0f] = 0x08080808;
3900     s->padconf[0x10] = 0x18181808;      /* | 0x07070700 if SBoot3 */
3901     s->padconf[0x11] = 0x18181818;      /* | 0x07070707 if SBoot3 */
3902     s->padconf[0x12] = 0x18181818;      /* | 0x07070707 if SBoot3 */
3903     s->padconf[0x13] = 0x18181818;      /* | 0x07070707 if SBoot3 */
3904     s->padconf[0x14] = 0x18181818;      /* | 0x00070707 if SBoot3 */
3905     s->padconf[0x15] = 0x18181818;
3906     s->padconf[0x16] = 0x18181818;      /* | 0x07000000 if SBoot3 */
3907     s->padconf[0x17] = 0x1f001f00;
3908     s->padconf[0x18] = 0x1f1f1f1f;
3909     s->padconf[0x19] = 0x00000000;
3910     s->padconf[0x1a] = 0x1f180000;
3911     s->padconf[0x1b] = 0x00001f1f;
3912     s->padconf[0x1c] = 0x1f001f00;
3913     s->padconf[0x1d] = 0x00000000;
3914     s->padconf[0x1e] = 0x00000000;
3915     s->padconf[0x1f] = 0x08000000;
3916     s->padconf[0x20] = 0x08080808;
3917     s->padconf[0x21] = 0x08080808;
3918     s->padconf[0x22] = 0x0f080808;
3919     s->padconf[0x23] = 0x0f0f0f0f;
3920     s->padconf[0x24] = 0x000f0f0f;
3921     s->padconf[0x25] = 0x1f1f1f0f;
3922     s->padconf[0x26] = 0x080f0f1f;
3923     s->padconf[0x27] = 0x070f1808;
3924     s->padconf[0x28] = 0x0f070707;
3925     s->padconf[0x29] = 0x000f0f1f;
3926     s->padconf[0x2a] = 0x0f0f0f1f;
3927     s->padconf[0x2b] = 0x08000000;
3928     s->padconf[0x2c] = 0x0000001f;
3929     s->padconf[0x2d] = 0x0f0f1f00;
3930     s->padconf[0x2e] = 0x1f1f0f0f;
3931     s->padconf[0x2f] = 0x0f1f1f1f;
3932     s->padconf[0x30] = 0x0f0f0f0f;
3933     s->padconf[0x31] = 0x0f1f0f1f;
3934     s->padconf[0x32] = 0x0f0f0f0f;
3935     s->padconf[0x33] = 0x0f1f0f1f;
3936     s->padconf[0x34] = 0x1f1f0f0f;
3937     s->padconf[0x35] = 0x0f0f1f1f;
3938     s->padconf[0x36] = 0x0f0f1f0f;
3939     s->padconf[0x37] = 0x0f0f0f0f;
3940     s->padconf[0x38] = 0x1f18180f;
3941     s->padconf[0x39] = 0x1f1f1f1f;
3942     s->padconf[0x3a] = 0x00001f1f;
3943     s->padconf[0x3b] = 0x00000000;
3944     s->padconf[0x3c] = 0x00000000;
3945     s->padconf[0x3d] = 0x0f0f0f0f;
3946     s->padconf[0x3e] = 0x18000f0f;
3947     s->padconf[0x3f] = 0x00070000;
3948     s->padconf[0x40] = 0x00000707;
3949     s->padconf[0x41] = 0x0f1f0700;
3950     s->padconf[0x42] = 0x1f1f070f;
3951     s->padconf[0x43] = 0x0008081f;
3952     s->padconf[0x44] = 0x00000800;
3953 }
3954
3955 struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
3956                 omap_clk iclk, struct omap_mpu_state_s *mpu)
3957 {
3958     int iomemtype;
3959     struct omap_sysctl_s *s = (struct omap_sysctl_s *)
3960             qemu_mallocz(sizeof(struct omap_sysctl_s));
3961
3962     s->mpu = mpu;
3963     omap_sysctl_reset(s);
3964
3965     iomemtype = l4_register_io_memory(0, omap_sysctl_readfn,
3966                     omap_sysctl_writefn, s);
3967     omap_l4_attach(ta, 0, iomemtype);
3968
3969     return s;
3970 }
3971
3972 /* SDRAM Controller Subsystem */
3973 struct omap_sdrc_s {
3974     uint8_t config;
3975     uint32_t cscfg;
3976     uint32_t sharing;
3977     uint32_t dlla_ctrl;
3978     uint32_t power_reg;
3979     struct {
3980         uint32_t mcfg;
3981         uint32_t mr;
3982         uint32_t emr2;
3983         uint32_t actim_ctrla;
3984         uint32_t actim_ctrlb;
3985         uint32_t rfr_ctrl;
3986         uint32_t manual;
3987     } cs[2];
3988 };
3989
3990 static void omap_sdrc_reset(struct omap_sdrc_s *s)
3991 {
3992     s->config    = 0x10;
3993     s->cscfg     = 0x4;
3994     s->sharing   = 0; // TODO: copy from system control module
3995     s->dlla_ctrl = 0;
3996     s->power_reg = 0x85;
3997     s->cs[0].mcfg        = s->cs[1].mcfg        = 0; // TODO: copy from system control module!
3998     s->cs[0].mr          = s->cs[1].mr          = 0x0024;
3999     s->cs[0].emr2        = s->cs[1].emr2        = 0;
4000     s->cs[0].actim_ctrla = s->cs[1].actim_ctrla = 0;
4001     s->cs[0].actim_ctrlb = s->cs[1].actim_ctrlb = 0;
4002     s->cs[0].rfr_ctrl    = s->cs[1].rfr_ctrl    = 0;
4003     s->cs[0].manual      = s->cs[1].manual      = 0;
4004 }
4005
4006 static uint32_t omap_sdrc_read(void *opaque, target_phys_addr_t addr)
4007 {
4008     struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
4009     int cs = 0;
4010
4011     switch (addr) {
4012     case 0x00:  /* SDRC_REVISION */
4013         return 0x20;
4014
4015     case 0x10:  /* SDRC_SYSCONFIG */
4016         return s->config;
4017
4018     case 0x14:  /* SDRC_SYSSTATUS */
4019         return 1; /* RESETDONE */
4020
4021     case 0x40:  /* SDRC_CS_CFG */
4022         return s->cscfg;
4023
4024     case 0x44:  /* SDRC_SHARING */
4025         return s->sharing;
4026             
4027     case 0x48:  /* SDRC_ERR_ADDR */
4028         return 0;
4029
4030     case 0x4c:  /* SDRC_ERR_TYPE */
4031         return 0x8;
4032             
4033     case 0x60:  /* SDRC_DLLA_SCTRL */
4034         return s->dlla_ctrl;
4035         
4036     case 0x64:  /* SDRC_DLLA_STATUS */
4037         return ~(s->dlla_ctrl & 0x4);
4038
4039     case 0x68:  /* SDRC_DLLB_CTRL */
4040     case 0x6c:  /* SDRC_DLLB_STATUS */
4041         return 0x00;
4042     
4043     case 0x70:  /* SDRC_POWER */
4044         return s->power_reg;
4045
4046     case 0xb0 ... 0xd8:
4047         cs = 1;
4048         addr -= 0x30;
4049         /* fall through */
4050     case 0x80 ... 0xa8:
4051         switch (addr & 0x3f) {
4052         case 0x00: /* SDRC_MCFG_x */
4053             return s->cs[cs].mcfg;
4054         case 0x04: /* SDRC_MR_x */
4055             return s->cs[cs].mr;
4056         case 0x08: /* SDRC_EMR1_x */
4057             return 0x00;
4058         case 0x0c: /* SDRC_EMR2_x */
4059             return s->cs[cs].emr2;
4060         case 0x10: /* SDRC_EMR3_x */
4061             return 0x00;
4062         case 0x14:
4063             if (cs)
4064                 return s->cs[1].actim_ctrla; /* SDRC_ACTIM_CTRLA_1 */
4065             return 0x00;                     /* SDRC_DCDL1_CTRL */
4066         case 0x18:
4067             if (cs)
4068                 return s->cs[1].actim_ctrlb; /* SDRC_ACTIM_CTRLB_1 */
4069             return 0x00;                     /* SDRC_DCDL2_CTRL */
4070         case 0x1c:
4071             if (!cs)
4072                 return s->cs[0].actim_ctrla; /* SDRC_ACTIM_CTRLA_0 */
4073             break;
4074         case 0x20:
4075             if (!cs)
4076                 return s->cs[0].actim_ctrlb; /* SDRC_ACTIM_CTRLB_0 */
4077             break;
4078         case 0x24: /* SDRC_RFR_CTRL_x */
4079             return s->cs[cs].rfr_ctrl;
4080         case 0x28: /* SDRC_MANUAL_x */
4081             return s->cs[cs].manual;
4082         default:
4083             break;
4084         }
4085         addr += cs * 0x30; // restore address to get correct error messages
4086         break;
4087
4088     default:
4089         break;
4090     }
4091
4092     OMAP_BAD_REG(addr);
4093     return 0;
4094 }
4095
4096 static void omap_sdrc_write(void *opaque, target_phys_addr_t addr,
4097                 uint32_t value)
4098 {
4099     struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
4100     int cs = 0;
4101
4102     switch (addr) {
4103     case 0x00:  /* SDRC_REVISION */
4104     case 0x14:  /* SDRC_SYSSTATUS */
4105     case 0x48:  /* SDRC_ERR_ADDR */
4106     case 0x64:  /* SDRC_DLLA_STATUS */
4107     case 0x6c:  /* SDRC_DLLB_STATUS */
4108         OMAP_RO_REGV(addr, value);
4109         break;
4110
4111     case 0x10:  /* SDRC_SYSCONFIG */
4112         /* ignore invalid idle mode settings */
4113         /*if ((value >> 3) != 0x2)
4114             fprintf(stderr, "%s: bad SDRAM idle mode %i for SDRC_SYSCONFIG (full value 0x%08x)\n",
4115                             __FUNCTION__, value >> 3, value);*/
4116         if (value & 2)
4117             omap_sdrc_reset(s);
4118         s->config = value & 0x18;
4119         break;
4120
4121     case 0x40:  /* SDRC_CS_CFG */
4122         s->cscfg = value & 0x30f;
4123         break;
4124
4125     case 0x44:  /* SDRC_SHARING */
4126         if (!(s->sharing & 0x40000000)) /* LOCK */
4127             s->sharing = value & 0x40007f00;
4128         break;
4129
4130     case 0x4c:  /* SDRC_ERR_TYPE */
4131         OMAP_BAD_REGV(addr, value);
4132         break;
4133
4134     case 0x60:  /* SDRC_DLLA_CTRL */
4135         s->dlla_ctrl = value & 0xffff00fe;
4136         break;
4137
4138     case 0x68:  /* SDRC_DLLB_CTRL */
4139         /* silently ignore */
4140         /*OMAP_BAD_REGV(addr, value);*/
4141         break;
4142         
4143     case 0x70:  /* SDRC_POWER_REG */
4144         s->power_reg = value & 0x04fffffd;
4145         break;
4146
4147     case 0xb0 ... 0xd8:
4148         cs = 1;
4149         addr -= 0x30;
4150         /* fall through */
4151     case 0x80 ... 0xa8:
4152         switch (addr & 0x3f) {
4153         case 0x00: /* SDRC_MCFG_x */
4154             if (!(s->cs[cs].mcfg & 0x40000000)) { /* LOCKSTATUS */
4155                 if (value & 0x00080000) /* ADDRMUXLEGACY */
4156                     s->cs[cs].mcfg = value & 0x477bffdf;
4157                 else
4158                     s->cs[cs].mcfg = value & 0x41fbffdf; // ????
4159             }
4160             break;
4161         case 0x04: /* SDRC_MR_x */
4162             s->cs[cs].mr = value & 0xfff;
4163             break;
4164         case 0x08: /* SDRC_EMR1_x */
4165             break;
4166         case 0x0c: /* SDRC_EMR2_x */
4167             s->cs[cs].emr2 = value & 0xfff;
4168             break;
4169         case 0x10: /* SDRC_EMR3_x */
4170             break;
4171         case 0x14:
4172             if (cs)
4173                 s->cs[1].actim_ctrla = value & 0xffffffdf; /* SDRC_ACTIM_CTRLA_1 */
4174             break;                                         /* SDRC_DCDL1_CTRL */
4175         case 0x18:
4176             if (cs)
4177                 s->cs[1].actim_ctrlb = value & 0x000377ff; /* SDRC_ACTIM_CTRLB_1 */
4178             break;                                         /* SDRC_DCDL2_CTRL */
4179         case 0x1c:
4180             if (!cs)
4181                 s->cs[0].actim_ctrla = value & 0xffffffdf; /* SDRC_ACTIM_CTRLA_0 */
4182             else
4183                 OMAP_BAD_REGV(addr + 0x30, value);
4184             break;
4185         case 0x20:
4186             if (!cs)
4187                 s->cs[0].actim_ctrlb = value & 0x000377ff; /* SDRC_ACTIM_CTRLB_0 */
4188             else
4189                 OMAP_BAD_REGV(addr + 0x30, value);
4190             break;
4191         case 0x24: /* SDRC_RFR_CTRL_x */
4192             s->cs[cs].rfr_ctrl = value & 0x00ffff03;
4193             break;
4194         case 0x28: /* SDRC_MANUAL_x */
4195             s->cs[cs].manual = value & 0xffff000f;
4196             break;
4197         default:
4198             OMAP_BAD_REGV(addr + cs * 0x30, value);
4199             break;
4200         }
4201         break;
4202
4203     default:
4204         OMAP_BAD_REGV(addr, value);
4205         break;
4206     }
4207 }
4208
4209 static CPUReadMemoryFunc *omap_sdrc_readfn[] = {
4210     omap_badwidth_read32,
4211     omap_badwidth_read32,
4212     omap_sdrc_read,
4213 };
4214
4215 static CPUWriteMemoryFunc *omap_sdrc_writefn[] = {
4216     omap_badwidth_write32,
4217     omap_badwidth_write32,
4218     omap_sdrc_write,
4219 };
4220
4221 struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base)
4222 {
4223     int iomemtype;
4224     struct omap_sdrc_s *s = (struct omap_sdrc_s *)
4225             qemu_mallocz(sizeof(struct omap_sdrc_s));
4226
4227     omap_sdrc_reset(s);
4228
4229     iomemtype = cpu_register_io_memory(0, omap_sdrc_readfn,
4230                     omap_sdrc_writefn, s);
4231     cpu_register_physical_memory(base, 0x1000, iomemtype);
4232
4233     return s;
4234 }
4235
4236 /* General-Purpose Memory Controller */
4237 struct omap_gpmc_s {
4238     qemu_irq irq;
4239
4240     uint8_t revision;
4241     uint8_t sysconfig;
4242     uint16_t irqst;
4243     uint16_t irqen;
4244     uint16_t timeout;
4245     uint16_t config;
4246     uint32_t prefconfig[2];
4247     int prefcontrol;
4248     int preffifo;
4249     int prefcount;
4250     struct omap_gpmc_cs_file_s {
4251         uint32_t config[7];
4252         target_phys_addr_t base;
4253         size_t size;
4254         int iomemtype;
4255         void (*base_update)(void *opaque, target_phys_addr_t new);
4256         void (*unmap)(void *opaque);
4257         void *opaque;
4258         struct nand_flash_s *nand;
4259     } cs_file[8];
4260     int ecc_cs;
4261     int ecc_ptr;
4262     uint32_t ecc_cfg;
4263     struct ecc_state_s ecc[9];
4264 };
4265
4266 static void omap_gpmc_int_update(struct omap_gpmc_s *s)
4267 {
4268     qemu_set_irq(s->irq, s->irqen & s->irqst);
4269 }
4270
4271 static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
4272 {
4273     /* TODO: check for overlapping regions and report access errors */
4274     if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
4275                     (base < 0 || base >= 0x40) ||
4276                     (base & 0x0f & ~mask)) {
4277         fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
4278                         __FUNCTION__);
4279         return;
4280     }
4281
4282     if (!f->opaque)
4283         return;
4284
4285     f->base = base << 24;
4286     f->size = (0x0fffffff & ~(mask << 24)) + 1;
4287     /* TODO: rather than setting the size of the mapping (which should be
4288      * constant), the mask should cause wrapping of the address space, so
4289      * that the same memory becomes accessible at every <i>size</i> bytes
4290      * starting from <i>base</i>.  */
4291     if (f->iomemtype)
4292         cpu_register_physical_memory(f->base, f->size, f->iomemtype);
4293
4294     if (f->base_update)
4295         f->base_update(f->opaque, f->base);
4296 }
4297
4298 static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
4299 {
4300     if (f->size) {
4301         if (f->unmap)
4302             f->unmap(f->opaque);
4303         if (f->iomemtype)
4304             cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED);
4305         f->base = 0;
4306         f->size = 0;
4307     }
4308 }
4309
4310 static void omap_gpmc_reset(struct omap_gpmc_s *s)
4311 {
4312     int i;
4313
4314     s->sysconfig = 0;
4315     s->irqst = 0;
4316     s->irqen = 0;
4317     omap_gpmc_int_update(s);
4318     s->timeout = 0;
4319     s->config = 0xa00;
4320     s->prefconfig[0] = 0x00004000;
4321     s->prefconfig[1] = 0x00000000;
4322     s->prefcontrol = 0;
4323     s->preffifo = 0;
4324     s->prefcount = 0;
4325     for (i = 0; i < 8; i ++) {
4326         if (s->cs_file[i].config[6] & (1 << 6))                 /* CSVALID */
4327             omap_gpmc_cs_unmap(s->cs_file + i);
4328         s->cs_file[i].config[0] = i ? 1 << 12 : 0;
4329         s->cs_file[i].config[1] = 0x101001;
4330         s->cs_file[i].config[2] = 0x020201;
4331         s->cs_file[i].config[3] = 0x10031003;
4332         s->cs_file[i].config[4] = 0x10f1111;
4333         s->cs_file[i].config[5] = 0;
4334         s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
4335         if (s->cs_file[i].config[6] & (1 << 6))                 /* CSVALID */
4336             omap_gpmc_cs_map(&s->cs_file[i],
4337                             s->cs_file[i].config[6] & 0x3f,     /* MASKADDR */
4338                         (s->cs_file[i].config[6] >> 8 & 0xf));  /* BASEADDR */
4339     }
4340     omap_gpmc_cs_map(s->cs_file, 0, 0xf);
4341     s->ecc_cs = 0;
4342     s->ecc_ptr = 0;
4343     s->ecc_cfg = 0x3fcff000;
4344     for (i = 0; i < 9; i ++)
4345         ecc_reset(&s->ecc[i]);
4346 }
4347
4348 static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
4349 {
4350     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
4351     int cs;
4352     struct omap_gpmc_cs_file_s *f;
4353     uint32_t x1, x2, x3, x4;
4354
4355     switch (addr) {
4356     case 0x000: /* GPMC_REVISION */
4357         return s->revision;
4358
4359     case 0x010: /* GPMC_SYSCONFIG */
4360         return s->sysconfig;
4361
4362     case 0x014: /* GPMC_SYSSTATUS */
4363         return 1;                                               /* RESETDONE */
4364
4365     case 0x018: /* GPMC_IRQSTATUS */
4366         return s->irqst;
4367
4368     case 0x01c: /* GPMC_IRQENABLE */
4369         return s->irqen;
4370
4371     case 0x040: /* GPMC_TIMEOUT_CONTROL */
4372         return s->timeout;
4373
4374     case 0x044: /* GPMC_ERR_ADDRESS */
4375     case 0x048: /* GPMC_ERR_TYPE */
4376         return 0;
4377
4378     case 0x050: /* GPMC_CONFIG */
4379         return s->config;
4380
4381     case 0x054: /* GPMC_STATUS */
4382         return 0x001;
4383
4384     case 0x060 ... 0x1d4:
4385         cs = (addr - 0x060) / 0x30;
4386         addr -= cs * 0x30;
4387         f = s->cs_file + cs;
4388         switch (addr) {
4389             case 0x60:  /* GPMC_CONFIG1 */
4390                 return f->config[0];
4391             case 0x64:  /* GPMC_CONFIG2 */
4392                 return f->config[1];
4393             case 0x68:  /* GPMC_CONFIG3 */
4394                 return f->config[2];
4395             case 0x6c:  /* GPMC_CONFIG4 */
4396                 return f->config[3];
4397             case 0x70:  /* GPMC_CONFIG5 */
4398                 return f->config[4];
4399             case 0x74:  /* GPMC_CONFIG6 */
4400                 return f->config[5];
4401             case 0x78:  /* GPMC_CONFIG7 */
4402                 return f->config[6];
4403             case 0x84:  /* GPMC_NAND_DATA */
4404                 if (((f->config[0] >> 10) & 3) == 2 /* NAND device type ? */
4405                     && f->nand) {
4406                     nand_setpins(f->nand, 0, 0, 0, 1, 0);
4407                     switch (((f->config[0] >> 12) & 3)) {
4408                         case 0: /* 8bit */
4409                             x1 = nand_getio(f->nand);
4410                             x2 = nand_getio(f->nand);
4411                             x3 = nand_getio(f->nand);
4412                             x4 = nand_getio(f->nand);
4413                             return (x4 << 24) | (x3 << 16) | (x2 << 8) | x1;
4414                         case 1: /* 16bit */
4415                             x1 = nand_getio(f->nand);
4416                             x2 = nand_getio(f->nand);
4417                             return (x2 << 16) | x1;
4418                         default:
4419                             return 0;
4420                     }
4421                 }
4422                 return 0;
4423             default:
4424                 break;
4425         }
4426         break;
4427
4428     case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */
4429         return s->prefconfig[0];
4430     case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */
4431         return s->prefconfig[1];
4432     case 0x1ec: /* GPMC_PREFETCH_CONTROL */
4433         return s->prefcontrol;
4434     case 0x1f0: /* GPMC_PREFETCH_STATUS */
4435         return (s->preffifo << 24) |
4436                 ((s->preffifo >
4437                   ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
4438                 s->prefcount;
4439
4440     case 0x1f4: /* GPMC_ECC_CONFIG */
4441         return s->ecc_cs;
4442     case 0x1f8: /* GPMC_ECC_CONTROL */
4443         return s->ecc_ptr;
4444     case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */
4445         return s->ecc_cfg;
4446     case 0x200 ... 0x220:       /* GPMC_ECC_RESULT */
4447         cs = (addr & 0x1f) >> 2;
4448         /* TODO: check correctness */
4449         return
4450                 ((s->ecc[cs].cp    &  0x07) <<  0) |
4451                 ((s->ecc[cs].cp    &  0x38) << 13) |
4452                 ((s->ecc[cs].lp[0] & 0x1ff) <<  3) |
4453                 ((s->ecc[cs].lp[1] & 0x1ff) << 19);
4454
4455     case 0x230: /* GPMC_TESTMODE_CTRL */
4456         return 0;
4457     case 0x234: /* GPMC_PSA_LSB */
4458     case 0x238: /* GPMC_PSA_MSB */
4459         return 0x00000000;
4460     }
4461
4462     OMAP_BAD_REG(addr);
4463     return 0;
4464 }
4465
4466 static uint32_t omap_gpmc_read8(void *opaque, target_phys_addr_t addr)
4467 {
4468     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
4469     int cs;
4470     struct omap_gpmc_cs_file_s *f;
4471     
4472     switch (addr) {
4473         case 0x060 ... 0x1d4:
4474             cs = (addr - 0x060) / 0x30;
4475             addr -= cs * 0x30;
4476             f = s->cs_file + cs;
4477             switch (addr) {
4478                 case 0x84 ... 0x87:     /* GPMC_NAND_DATA */
4479                     if (((f->config[0] >> 10) & 3) == 2 /* NAND device type ? */
4480                         && f->nand) {
4481                         nand_setpins(f->nand, 0, 0, 0, 1, 0);
4482                         switch (((f->config[0] >> 12) & 3)) {
4483                             case 0: /* 8bit */
4484                                 return nand_getio(f->nand);
4485                             case 1: /* 16bit */
4486                                 /* reading 8bits from a 16bit device?! */
4487                                 return nand_getio(f->nand);
4488                             default:
4489                                 return 0;
4490                         }
4491                     }
4492                     return 0;
4493                 default:
4494                     break;
4495             }
4496             break;
4497         default:
4498             break;
4499     }
4500     OMAP_BAD_REG(addr);
4501     return 0;
4502 }
4503
4504 static uint32_t omap_gpmc_read16(void *opaque, target_phys_addr_t addr)
4505 {
4506     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
4507     int cs;
4508     struct omap_gpmc_cs_file_s *f;
4509     uint32_t x1, x2;
4510     
4511     switch (addr) {
4512         case 0x060 ... 0x1d4:
4513             cs = (addr - 0x060) / 0x30;
4514             addr -= cs * 0x30;
4515             f = s->cs_file + cs;
4516             switch (addr) {
4517                 case 0x84:      /* GPMC_NAND_DATA */
4518                 case 0x86:
4519                     if (((f->config[0] >> 10) & 3) == 2 /* NAND device type ? */
4520                         && f->nand) {
4521                         nand_setpins(f->nand, 0, 0, 0, 1, 0);
4522                         switch (((f->config[0] >> 12) & 3)) {
4523                             case 0: /* 8bit */
4524                                 x1 = nand_getio(f->nand);
4525                                 x2 = nand_getio(f->nand);
4526                                 return (x2 << 8) | x1;
4527                             case 1: /* 16bit */
4528                                 return nand_getio(f->nand);
4529                             default:
4530                                 return 0;
4531                         }
4532                     }
4533                     return 0;
4534                 default:
4535                     break;
4536             }
4537             break;
4538         default:
4539             break;
4540     }
4541     OMAP_BAD_REG(addr);
4542     return 0;
4543 }
4544
4545 static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
4546                 uint32_t value)
4547 {
4548     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
4549     int cs;
4550     struct omap_gpmc_cs_file_s *f;
4551
4552     switch (addr) {
4553     case 0x000: /* GPMC_REVISION */
4554     case 0x014: /* GPMC_SYSSTATUS */
4555     case 0x054: /* GPMC_STATUS */
4556     case 0x1f0: /* GPMC_PREFETCH_STATUS */
4557     case 0x200 ... 0x220:       /* GPMC_ECC_RESULT */
4558     case 0x234: /* GPMC_PSA_LSB */
4559     case 0x238: /* GPMC_PSA_MSB */
4560         OMAP_RO_REGV(addr, value);
4561         break;
4562
4563     case 0x010: /* GPMC_SYSCONFIG */
4564         if ((value >> 3) == 0x3)
4565             fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
4566                             __FUNCTION__, value >> 3);
4567         if (value & 2)
4568             omap_gpmc_reset(s);
4569         s->sysconfig = value & 0x19;
4570         break;
4571
4572     case 0x018: /* GPMC_IRQSTATUS */
4573         s->irqen = ~value;
4574         omap_gpmc_int_update(s);
4575         break;
4576
4577     case 0x01c: /* GPMC_IRQENABLE */
4578         s->irqen = value & 0xf03;
4579         omap_gpmc_int_update(s);
4580         break;
4581
4582     case 0x040: /* GPMC_TIMEOUT_CONTROL */
4583         s->timeout = value & 0x1ff1;
4584         break;
4585
4586     case 0x044: /* GPMC_ERR_ADDRESS */
4587     case 0x048: /* GPMC_ERR_TYPE */
4588         break;
4589
4590     case 0x050: /* GPMC_CONFIG */
4591         s->config = value & 0xf13;
4592         break;
4593
4594     case 0x060 ... 0x1d4:
4595         cs = (addr - 0x060) / 0x30;
4596         addr -= cs * 0x30;
4597         f = s->cs_file + cs;
4598         switch (addr) {
4599             case 0x60:  /* GPMC_CONFIG1 */
4600                 f->config[0] = value & 0xffef3e13;
4601                 break;
4602             case 0x64:  /* GPMC_CONFIG2 */
4603                 f->config[1] = value & 0x001f1f8f;
4604                 break;
4605             case 0x68:  /* GPMC_CONFIG3 */
4606                 f->config[2] = value & 0x001f1f8f;
4607                 break;
4608             case 0x6c:  /* GPMC_CONFIG4 */
4609                 f->config[3] = value & 0x1f8f1f8f;
4610                 break;
4611             case 0x70:  /* GPMC_CONFIG5 */
4612                 f->config[4] = value & 0x0f1f1f1f;
4613                 break;
4614             case 0x74:  /* GPMC_CONFIG6 */
4615                 f->config[5] = value & 0x00000fcf;
4616                 break;
4617             case 0x78:  /* GPMC_CONFIG7 */
4618                 if ((f->config[6] ^ value) & 0xf7f) {
4619                     if (f->config[6] & (1 << 6))                /* CSVALID */
4620                         omap_gpmc_cs_unmap(f);
4621                     if (value & (1 << 6))                       /* CSVALID */
4622                         omap_gpmc_cs_map(f, value & 0x3f,       /* MASKADDR */
4623                                         (value >> 8 & 0xf));    /* BASEADDR */
4624                 }
4625                 f->config[6] = value & 0x00000f7f;
4626                 break;
4627             case 0x7c:  /* GPMC_NAND_COMMAND */
4628             case 0x80:  /* GPMC_NAND_ADDRESS */
4629             case 0x84:  /* GPMC_NAND_DATA */
4630                 if (((f->config[0] >> 10) & 3) == 2 /* NAND device type ? */
4631                     && f->nand) {
4632                     switch (addr) {
4633                         case 0x7c: nand_setpins(f->nand, 1, 0, 0, 1, 0); break; /* CLE */
4634                         case 0x80: nand_setpins(f->nand, 0, 1, 0, 1, 0); break; /* ALE */
4635                         case 0x84: nand_setpins(f->nand, 0, 0, 0, 1, 0); break;
4636                         default: break;
4637                     }
4638                     switch (((f->config[0] >> 12) & 3)) {
4639                         case 0: /* 8bit */
4640                             nand_setio(f->nand, value & 0xff);
4641                             nand_setio(f->nand, (value >> 8) & 0xff);
4642                             nand_setio(f->nand, (value >> 16) & 0xff);
4643                             nand_setio(f->nand, (value >> 24) & 0xff);
4644                             break;
4645                         case 1: /* 16bit */
4646                             nand_setio(f->nand, value & 0xffff);
4647                             nand_setio(f->nand, (value >> 16) & 0xffff);
4648                             break;
4649                         default:
4650                             break;
4651                     }
4652                 }
4653                 break;
4654             default:
4655                 goto bad_reg;
4656         }
4657         break;
4658
4659     case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */
4660         s->prefconfig[0] = value & 0x7f8f7fbf;
4661         /* TODO: update interrupts, fifos, dmas */
4662         break;
4663
4664     case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */
4665         s->prefconfig[1] = value & 0x3fff;
4666         break;
4667
4668     case 0x1ec: /* GPMC_PREFETCH_CONTROL */
4669         s->prefcontrol = value & 1;
4670         if (s->prefcontrol) {
4671             if (s->prefconfig[0] & 1)
4672                 s->preffifo = 0x40;
4673             else
4674                 s->preffifo = 0x00;
4675         }
4676         /* TODO: start */
4677         break;
4678
4679     case 0x1f4: /* GPMC_ECC_CONFIG */
4680         s->ecc_cs = 0x8f;
4681         break;
4682     case 0x1f8: /* GPMC_ECC_CONTROL */
4683         if (value & (1 << 8))
4684             for (cs = 0; cs < 9; cs ++)
4685                 ecc_reset(&s->ecc[cs]);
4686         s->ecc_ptr = value & 0xf;
4687         if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
4688             s->ecc_ptr = 0;
4689             s->ecc_cs &= ~1;
4690         }
4691         break;
4692     case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */
4693         s->ecc_cfg = value & 0x3fcff1ff;
4694         break;
4695     case 0x230: /* GPMC_TESTMODE_CTRL */
4696         if (value & 7)
4697             fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
4698         break;
4699
4700     default:
4701     bad_reg:
4702         OMAP_BAD_REGV(addr, value);
4703         return;
4704     }
4705 }
4706
4707 static void omap_gpmc_write8(void *opaque, target_phys_addr_t addr,
4708                              uint32_t value)
4709 {
4710     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
4711     int cs;
4712     struct omap_gpmc_cs_file_s *f;
4713
4714     switch (addr) {
4715         case 0x060 ... 0x1d4:
4716             cs = (addr - 0x060) / 0x30;
4717             addr -= cs * 0x30;
4718             f = s->cs_file + cs;
4719             switch (addr) {
4720                 case 0x7c ... 0x7f:     /* GPMC_NAND_COMMAND */
4721                 case 0x80 ... 0x83:     /* GPMC_NAND_ADDRESS */
4722                 case 0x84 ... 0x87:     /* GPMC_NAND_DATA */
4723                     if (((f->config[0] >> 10) & 3) == 2 /* NAND device type ? */
4724                         && f->nand) {
4725                         switch (addr) {
4726                             case 0x7c ... 0x7f:
4727                                 nand_setpins(f->nand, 1, 0, 0, 1, 0); /* CLE */
4728                                 break;
4729                             case 0x80 ... 0x83:
4730                                 nand_setpins(f->nand, 0, 1, 0, 1, 0); /* ALE */
4731                                 break;
4732                             case 0x84 ... 0x87:
4733                                 nand_setpins(f->nand, 0, 0, 0, 1, 0);
4734                                 break;
4735                             default:
4736                                 break;
4737                         }
4738                         switch (((f->config[0] >> 12) & 3)) {
4739                             case 0: /* 8bit */
4740                                 nand_setio(f->nand, value & 0xff);
4741                                 break;
4742                             case 1: /* 16bit */
4743                                 /* writing to a 16bit device with 8bit access!? */
4744                                 nand_setio(f->nand, value & 0xffff);
4745                                 break;
4746                             default:
4747                                 break;
4748                         }
4749                     }
4750                     break;
4751                 default:
4752                     goto bad_reg;
4753             }
4754             break;
4755         default:
4756         bad_reg:
4757             OMAP_BAD_REGV(addr, value);
4758             return;
4759     }
4760 }
4761
4762 static void omap_gpmc_write16(void *opaque, target_phys_addr_t addr,
4763                               uint32_t value)
4764 {
4765     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
4766     int cs;
4767     struct omap_gpmc_cs_file_s *f;
4768     
4769     switch (addr) {
4770         case 0x060 ... 0x1d4:
4771             cs = (addr - 0x060) / 0x30;
4772             addr -= cs * 0x30;
4773             f = s->cs_file + cs;
4774             switch (addr) {
4775                 case 0x7c:      /* GPMC_NAND_COMMAND */
4776                 case 0x7e:
4777                 case 0x80:      /* GPMC_NAND_ADDRESS */
4778                 case 0x82:
4779                 case 0x84:      /* GPMC_NAND_DATA */
4780                 case 0x86:
4781                     if (((f->config[0] >> 10) & 3) == 2 /* NAND device type ? */
4782                         && f->nand) {
4783                         switch (addr) {
4784                             case 0x7c:
4785                             case 0x7e: 
4786                                 nand_setpins(f->nand, 1, 0, 0, 1, 0); /* CLE */
4787                                 break;
4788                             case 0x80:
4789                             case 0x82:
4790                                 nand_setpins(f->nand, 0, 1, 0, 1, 0); /* ALE */
4791                                 break;
4792                             case 0x84:
4793                             case 0x86:
4794                                 nand_setpins(f->nand, 0, 0, 0, 1, 0);
4795                                 break;
4796                             default:
4797                                 break;
4798                         }
4799                         switch (((f->config[0] >> 12) & 3)) {
4800                             case 0: /* 8bit */
4801                                 nand_setio(f->nand, value & 0xff);
4802                                 nand_setio(f->nand, (value >> 8) & 0xff);
4803                                 break;
4804                             case 1: /* 16bit */
4805                                 nand_setio(f->nand, value & 0xffff);
4806                                 break;
4807                             default:
4808                                 break;
4809                         }
4810                     }
4811                     break;
4812                 default:
4813                     goto bad_reg;
4814             }
4815             break;
4816         default:
4817         bad_reg:
4818             OMAP_BAD_REGV(addr, value);
4819             return;
4820     }
4821 }
4822
4823 static CPUReadMemoryFunc *omap_gpmc_readfn[] = {
4824     omap_gpmc_read8,
4825     omap_gpmc_read16,
4826     omap_gpmc_read,
4827 };
4828
4829 static CPUWriteMemoryFunc *omap_gpmc_writefn[] = {
4830     omap_gpmc_write8,
4831     omap_gpmc_write16,
4832     omap_gpmc_write,
4833 };
4834
4835 struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
4836                                    target_phys_addr_t base, qemu_irq irq)
4837 {
4838     int iomemtype;
4839     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
4840             qemu_mallocz(sizeof(struct omap_gpmc_s));
4841
4842     s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
4843     omap_gpmc_reset(s);
4844
4845     iomemtype = cpu_register_io_memory(0, omap_gpmc_readfn,
4846                     omap_gpmc_writefn, s);
4847     cpu_register_physical_memory(base, 0x1000, iomemtype);
4848
4849     return s;
4850 }
4851
4852 void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
4853                 void (*base_upd)(void *opaque, target_phys_addr_t new),
4854                 void (*unmap)(void *opaque), void *opaque,
4855                 struct nand_flash_s *nand_s)
4856 {
4857     struct omap_gpmc_cs_file_s *f;
4858
4859     if (cs < 0 || cs >= 8) {
4860         fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
4861         exit(-1);
4862     }
4863     f = &s->cs_file[cs];
4864
4865     f->iomemtype = iomemtype;
4866     f->base_update = base_upd;
4867     f->unmap = unmap;
4868     f->opaque = opaque;
4869     f->nand = nand_s;
4870
4871     if (f->nand) {
4872         f->config[0] &= ~(0xf << 10);
4873         f->config[0] |= 2 << 10;     /* DEVICETYPE = NAND */
4874         if (nand_getbuswidth(f->nand) == 16)
4875             f->config[0] |= 1 << 12; /* 16-bit device */
4876     }
4877     
4878     if (f->config[6] & (1 << 6))                                /* CSVALID */
4879         omap_gpmc_cs_map(f, f->config[6] & 0x3f,                /* MASKADDR */
4880                         (f->config[6] >> 8 & 0xf));             /* BASEADDR */
4881 }
4882
4883 /* General chip reset */
4884 static void omap2_mpu_reset(void *opaque)
4885 {
4886     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4887
4888     omap_inth_reset(mpu->ih[0]);
4889     omap_dma_reset(mpu->dma);
4890     omap_prcm_reset(mpu->prcm);
4891     omap_sysctl_reset(mpu->sysc);
4892     omap_gp_timer_reset(mpu->gptimer[0]);
4893     omap_gp_timer_reset(mpu->gptimer[1]);
4894     omap_gp_timer_reset(mpu->gptimer[2]);
4895     omap_gp_timer_reset(mpu->gptimer[3]);
4896     omap_gp_timer_reset(mpu->gptimer[4]);
4897     omap_gp_timer_reset(mpu->gptimer[5]);
4898     omap_gp_timer_reset(mpu->gptimer[6]);
4899     omap_gp_timer_reset(mpu->gptimer[7]);
4900     omap_gp_timer_reset(mpu->gptimer[8]);
4901     omap_gp_timer_reset(mpu->gptimer[9]);
4902     omap_gp_timer_reset(mpu->gptimer[10]);
4903     omap_gp_timer_reset(mpu->gptimer[11]);
4904     omap_synctimer_reset(&mpu->synctimer);
4905     omap_sdrc_reset(mpu->sdrc);
4906     omap_gpmc_reset(mpu->gpmc);
4907     omap_dss_reset(mpu->dss);
4908     omap_uart_reset(mpu->uart[0]);
4909     omap_uart_reset(mpu->uart[1]);
4910     omap_uart_reset(mpu->uart[2]);
4911     omap_mmc_reset(mpu->mmc);
4912     omap_gpif_reset(mpu->gpif);
4913     omap_mcspi_reset(mpu->mcspi[0]);
4914     omap_mcspi_reset(mpu->mcspi[1]);
4915     omap_i2c_reset(mpu->i2c[0]);
4916     omap_i2c_reset(mpu->i2c[1]);
4917     cpu_reset(mpu->env);
4918 }
4919
4920 static int omap2_validate_addr(struct omap_mpu_state_s *s,
4921                 target_phys_addr_t addr)
4922 {
4923     return 1;
4924 }
4925
4926 static const struct dma_irq_map omap2_dma_irq_map[] = {
4927     { 0, OMAP_INT_24XX_SDMA_IRQ0 },
4928     { 0, OMAP_INT_24XX_SDMA_IRQ1 },
4929     { 0, OMAP_INT_24XX_SDMA_IRQ2 },
4930     { 0, OMAP_INT_24XX_SDMA_IRQ3 },
4931 };
4932
4933 struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
4934                 const char *core)
4935 {
4936     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4937             qemu_mallocz(sizeof(struct omap_mpu_state_s));
4938     ram_addr_t sram_base, q2_base;
4939     qemu_irq *cpu_irq;
4940     qemu_irq dma_irqs[4];
4941     omap_clk gpio_clks[4];
4942     int sdindex;
4943     int i;
4944
4945     /* Core */
4946     s->mpu_model = omap2420;
4947     s->env = cpu_init(core ?: "arm1136-r2");
4948     if (!s->env) {
4949         fprintf(stderr, "Unable to find CPU definition\n");
4950         exit(1);
4951     }
4952     s->sdram_size = sdram_size;
4953     s->sram_size = OMAP242X_SRAM_SIZE;
4954
4955     s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4956
4957     /* Clocks */
4958     omap_clk_init(s);
4959
4960     /* Memory-mapped stuff */
4961     cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
4962                     (q2_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4963     cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
4964                     (sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4965
4966     s->l4 = omap_l4_init(OMAP2_L4_BASE, 54);
4967
4968     /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
4969     cpu_irq = arm_pic_init_cpu(s->env);
4970     s->ih[0] = omap2_inth_init(s,
4971                     0x480fe000, 0x1000, 3, &s->irq[0],
4972                     cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4973                     omap_findclk(s, "mpu_intc_fclk"),
4974                     omap_findclk(s, "mpu_intc_iclk"));
4975
4976     s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
4977                     s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s);
4978
4979     s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
4980                     omap_findclk(s, "omapctrl_iclk"), s);
4981
4982     for (i = 0; i < 4; i ++)
4983         dma_irqs[i] =
4984                 s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr];
4985     s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
4986                     omap_findclk(s, "sdma_iclk"),
4987                     omap_findclk(s, "sdma_fclk"));
4988     s->port->addr_valid = omap2_validate_addr;
4989
4990     /* Register SDRAM and SRAM ports for fast DMA transfers.  */
4991     soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
4992     soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
4993
4994     s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
4995                     s->irq[0][OMAP_INT_24XX_UART1_IRQ],
4996                     omap_findclk(s, "uart1_fclk"),
4997                     omap_findclk(s, "uart1_iclk"),
4998                     s->drq[OMAP24XX_DMA_UART1_TX],
4999                     s->drq[OMAP24XX_DMA_UART1_RX], serial_hds[0]);
5000     s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20),
5001                     s->irq[0][OMAP_INT_24XX_UART2_IRQ],
5002                     omap_findclk(s, "uart2_fclk"),
5003                     omap_findclk(s, "uart2_iclk"),
5004                     s->drq[OMAP24XX_DMA_UART2_TX],
5005                     s->drq[OMAP24XX_DMA_UART2_RX],
5006                     serial_hds[0] ? serial_hds[1] : 0);
5007     s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21),
5008                     s->irq[0][OMAP_INT_24XX_UART3_IRQ],
5009                     omap_findclk(s, "uart3_fclk"),
5010                     omap_findclk(s, "uart3_iclk"),
5011                     s->drq[OMAP24XX_DMA_UART3_TX],
5012                     s->drq[OMAP24XX_DMA_UART3_RX],
5013                     serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
5014
5015     s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
5016                     s->irq[0][OMAP_INT_24XX_GPTIMER1],
5017                     omap_findclk(s, "wu_gpt1_clk"),
5018                     omap_findclk(s, "wu_l4_iclk"));
5019     s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
5020                     s->irq[0][OMAP_INT_24XX_GPTIMER2],
5021                     omap_findclk(s, "core_gpt2_clk"),
5022                     omap_findclk(s, "core_l4_iclk"));
5023     s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
5024                     s->irq[0][OMAP_INT_24XX_GPTIMER3],
5025                     omap_findclk(s, "core_gpt3_clk"),
5026                     omap_findclk(s, "core_l4_iclk"));
5027     s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
5028                     s->irq[0][OMAP_INT_24XX_GPTIMER4],
5029                     omap_findclk(s, "core_gpt4_clk"),
5030                     omap_findclk(s, "core_l4_iclk"));
5031     s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
5032                     s->irq[0][OMAP_INT_24XX_GPTIMER5],
5033                     omap_findclk(s, "core_gpt5_clk"),
5034                     omap_findclk(s, "core_l4_iclk"));
5035     s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
5036                     s->irq[0][OMAP_INT_24XX_GPTIMER6],
5037                     omap_findclk(s, "core_gpt6_clk"),
5038                     omap_findclk(s, "core_l4_iclk"));
5039     s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
5040                     s->irq[0][OMAP_INT_24XX_GPTIMER7],
5041                     omap_findclk(s, "core_gpt7_clk"),
5042                     omap_findclk(s, "core_l4_iclk"));
5043     s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
5044                     s->irq[0][OMAP_INT_24XX_GPTIMER8],
5045                     omap_findclk(s, "core_gpt8_clk"),
5046                     omap_findclk(s, "core_l4_iclk"));
5047     s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
5048                     s->irq[0][OMAP_INT_24XX_GPTIMER9],
5049                     omap_findclk(s, "core_gpt9_clk"),
5050                     omap_findclk(s, "core_l4_iclk"));
5051     s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
5052                     s->irq[0][OMAP_INT_24XX_GPTIMER10],
5053                     omap_findclk(s, "core_gpt10_clk"),
5054                     omap_findclk(s, "core_l4_iclk"));
5055     s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
5056                     s->irq[0][OMAP_INT_24XX_GPTIMER11],
5057                     omap_findclk(s, "core_gpt11_clk"),
5058                     omap_findclk(s, "core_l4_iclk"));
5059     s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
5060                     s->irq[0][OMAP_INT_24XX_GPTIMER12],
5061                     omap_findclk(s, "core_gpt12_clk"),
5062                     omap_findclk(s, "core_l4_iclk"));
5063
5064     omap_tap_init(omap_l4ta(s->l4, 2), s);
5065
5066     omap_synctimer_init(omap_l4tao(s->l4, 2), s,
5067                     omap_findclk(s, "clk32-kHz"),
5068                     omap_findclk(s, "core_l4_iclk"));
5069
5070     s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
5071                     s->irq[0][OMAP_INT_24XX_I2C1_IRQ],
5072                     &s->drq[OMAP24XX_DMA_I2C1_TX],
5073                     omap_findclk(s, "i2c1.fclk"),
5074                     omap_findclk(s, "i2c1.iclk"));
5075     s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
5076                     s->irq[0][OMAP_INT_24XX_I2C2_IRQ],
5077                     &s->drq[OMAP24XX_DMA_I2C2_TX],
5078                     omap_findclk(s, "i2c2.fclk"),
5079                     omap_findclk(s, "i2c2.iclk"));
5080
5081     gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
5082     gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
5083     gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
5084     gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
5085     s->gpif = omap2_gpio_init(s, omap_l4ta(s->l4, 3),
5086                     &s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
5087                     gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
5088
5089     s->sdrc = omap_sdrc_init(0x68009000);
5090     s->gpmc = omap_gpmc_init(s, 0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
5091
5092     sdindex = drive_get_index(IF_SD, 0, 0);
5093     if (sdindex == -1) {
5094         fprintf(stderr, "qemu: missing SecureDigital device\n");
5095         exit(1);
5096     }
5097     s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), drives_table[sdindex].bdrv,
5098                     s->irq[0][OMAP_INT_24XX_MMC_IRQ],
5099                     &s->drq[OMAP24XX_DMA_MMC1_TX],
5100                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
5101
5102     s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
5103                     s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ],
5104                     &s->drq[OMAP24XX_DMA_SPI1_TX0],
5105                     omap_findclk(s, "spi1_fclk"),
5106                     omap_findclk(s, "spi1_iclk"));
5107     s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
5108                     s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ],
5109                     &s->drq[OMAP24XX_DMA_SPI2_TX0],
5110                     omap_findclk(s, "spi2_fclk"),
5111                     omap_findclk(s, "spi2_iclk"));
5112
5113     s->dss = omap_dss_init(s, omap_l4ta(s->l4, 10),
5114                     /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
5115                     s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
5116                     omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
5117                     omap_findclk(s, "dss_54m_clk"),
5118                     omap_findclk(s, "dss_l3_iclk"),
5119                     omap_findclk(s, "dss_l4_iclk"));
5120
5121     omap_sti_init(omap_l4ta(s->l4, 18), 0x54000000,
5122                     s->irq[0][OMAP_INT_24XX_STI], omap_findclk(s, "emul_ck"),
5123                     serial_hds[0] && serial_hds[1] && serial_hds[2] ?
5124                     serial_hds[3] : 0);
5125
5126     s->eac = omap_eac_init(omap_l4ta(s->l4, 32),
5127                     s->irq[0][OMAP_INT_24XX_EAC_IRQ],
5128                     /* Ten consecutive lines */
5129                     &s->drq[OMAP24XX_DMA_EAC_AC_RD],
5130                     omap_findclk(s, "func_96m_clk"),
5131                     omap_findclk(s, "core_l4_iclk"));
5132
5133     /* All register mappings (includin those not currenlty implemented):
5134      * SystemControlMod 48000000 - 48000fff
5135      * SystemControlL4  48001000 - 48001fff
5136      * 32kHz Timer Mod  48004000 - 48004fff
5137      * 32kHz Timer L4   48005000 - 48005fff
5138      * PRCM ModA        48008000 - 480087ff
5139      * PRCM ModB        48008800 - 48008fff
5140      * PRCM L4          48009000 - 48009fff
5141      * TEST-BCM Mod     48012000 - 48012fff
5142      * TEST-BCM L4      48013000 - 48013fff
5143      * TEST-TAP Mod     48014000 - 48014fff
5144      * TEST-TAP L4      48015000 - 48015fff
5145      * GPIO1 Mod        48018000 - 48018fff
5146      * GPIO Top         48019000 - 48019fff
5147      * GPIO2 Mod        4801a000 - 4801afff
5148      * GPIO L4          4801b000 - 4801bfff
5149      * GPIO3 Mod        4801c000 - 4801cfff
5150      * GPIO4 Mod        4801e000 - 4801efff
5151      * WDTIMER1 Mod     48020000 - 48010fff
5152      * WDTIMER Top      48021000 - 48011fff
5153      * WDTIMER2 Mod     48022000 - 48012fff
5154      * WDTIMER L4       48023000 - 48013fff
5155      * WDTIMER3 Mod     48024000 - 48014fff
5156      * WDTIMER3 L4      48025000 - 48015fff
5157      * WDTIMER4 Mod     48026000 - 48016fff
5158      * WDTIMER4 L4      48027000 - 48017fff
5159      * GPTIMER1 Mod     48028000 - 48018fff
5160      * GPTIMER1 L4      48029000 - 48019fff
5161      * GPTIMER2 Mod     4802a000 - 4801afff
5162      * GPTIMER2 L4      4802b000 - 4801bfff
5163      * L4-Config AP     48040000 - 480407ff
5164      * L4-Config IP     48040800 - 48040fff
5165      * L4-Config LA     48041000 - 48041fff
5166      * ARM11ETB Mod     48048000 - 48049fff
5167      * ARM11ETB L4      4804a000 - 4804afff
5168      * DISPLAY Top      48050000 - 480503ff
5169      * DISPLAY DISPC    48050400 - 480507ff
5170      * DISPLAY RFBI     48050800 - 48050bff
5171      * DISPLAY VENC     48050c00 - 48050fff
5172      * DISPLAY L4       48051000 - 48051fff
5173      * CAMERA Top       48052000 - 480523ff
5174      * CAMERA core      48052400 - 480527ff
5175      * CAMERA DMA       48052800 - 48052bff
5176      * CAMERA MMU       48052c00 - 48052fff
5177      * CAMERA L4        48053000 - 48053fff
5178      * SDMA Mod         48056000 - 48056fff
5179      * SDMA L4          48057000 - 48057fff
5180      * SSI Top          48058000 - 48058fff
5181      * SSI GDD          48059000 - 48059fff
5182      * SSI Port1        4805a000 - 4805afff
5183      * SSI Port2        4805b000 - 4805bfff
5184      * SSI L4           4805c000 - 4805cfff
5185      * USB Mod          4805e000 - 480fefff
5186      * USB L4           4805f000 - 480fffff
5187      * WIN_TRACER1 Mod  48060000 - 48060fff
5188      * WIN_TRACER1 L4   48061000 - 48061fff
5189      * WIN_TRACER2 Mod  48062000 - 48062fff
5190      * WIN_TRACER2 L4   48063000 - 48063fff
5191      * WIN_TRACER3 Mod  48064000 - 48064fff
5192      * WIN_TRACER3 L4   48065000 - 48065fff
5193      * WIN_TRACER4 Top  48066000 - 480660ff
5194      * WIN_TRACER4 ETT  48066100 - 480661ff
5195      * WIN_TRACER4 WT   48066200 - 480662ff
5196      * WIN_TRACER4 L4   48067000 - 48067fff
5197      * XTI Mod          48068000 - 48068fff
5198      * XTI L4           48069000 - 48069fff
5199      * UART1 Mod        4806a000 - 4806afff
5200      * UART1 L4         4806b000 - 4806bfff
5201      * UART2 Mod        4806c000 - 4806cfff
5202      * UART2 L4         4806d000 - 4806dfff
5203      * UART3 Mod        4806e000 - 4806efff
5204      * UART3 L4         4806f000 - 4806ffff
5205      * I2C1 Mod         48070000 - 48070fff
5206      * I2C1 L4          48071000 - 48071fff
5207      * I2C2 Mod         48072000 - 48072fff
5208      * I2C2 L4          48073000 - 48073fff
5209      * McBSP1 Mod       48074000 - 48074fff
5210      * McBSP1 L4        48075000 - 48075fff
5211      * McBSP2 Mod       48076000 - 48076fff
5212      * McBSP2 L4        48077000 - 48077fff
5213      * GPTIMER3 Mod     48078000 - 48078fff
5214      * GPTIMER3 L4      48079000 - 48079fff
5215      * GPTIMER4 Mod     4807a000 - 4807afff
5216      * GPTIMER4 L4      4807b000 - 4807bfff
5217      * GPTIMER5 Mod     4807c000 - 4807cfff
5218      * GPTIMER5 L4      4807d000 - 4807dfff
5219      * GPTIMER6 Mod     4807e000 - 4807efff
5220      * GPTIMER6 L4      4807f000 - 4807ffff
5221      * GPTIMER7 Mod     48080000 - 48080fff
5222      * GPTIMER7 L4      48081000 - 48081fff
5223      * GPTIMER8 Mod     48082000 - 48082fff
5224      * GPTIMER8 L4      48083000 - 48083fff
5225      * GPTIMER9 Mod     48084000 - 48084fff
5226      * GPTIMER9 L4      48085000 - 48085fff
5227      * GPTIMER10 Mod    48086000 - 48086fff
5228      * GPTIMER10 L4     48087000 - 48087fff
5229      * GPTIMER11 Mod    48088000 - 48088fff
5230      * GPTIMER11 L4     48089000 - 48089fff
5231      * GPTIMER12 Mod    4808a000 - 4808afff
5232      * GPTIMER12 L4     4808b000 - 4808bfff
5233      * EAC Mod          48090000 - 48090fff
5234      * EAC L4           48091000 - 48091fff
5235      * FAC Mod          48092000 - 48092fff
5236      * FAC L4           48093000 - 48093fff
5237      * MAILBOX Mod      48094000 - 48094fff
5238      * MAILBOX L4       48095000 - 48095fff
5239      * SPI1 Mod         48098000 - 48098fff
5240      * SPI1 L4          48099000 - 48099fff
5241      * SPI2 Mod         4809a000 - 4809afff
5242      * SPI2 L4          4809b000 - 4809bfff
5243      * MMC/SDIO Mod     4809c000 - 4809cfff
5244      * MMC/SDIO L4      4809d000 - 4809dfff
5245      * MS_PRO Mod       4809e000 - 4809efff
5246      * MS_PRO L4        4809f000 - 4809ffff
5247      * RNG Mod          480a0000 - 480a0fff
5248      * RNG L4           480a1000 - 480a1fff
5249      * DES3DES Mod      480a2000 - 480a2fff
5250      * DES3DES L4       480a3000 - 480a3fff
5251      * SHA1MD5 Mod      480a4000 - 480a4fff
5252      * SHA1MD5 L4       480a5000 - 480a5fff
5253      * AES Mod          480a6000 - 480a6fff
5254      * AES L4           480a7000 - 480a7fff
5255      * PKA Mod          480a8000 - 480a9fff
5256      * PKA L4           480aa000 - 480aafff
5257      * MG Mod           480b0000 - 480b0fff
5258      * MG L4            480b1000 - 480b1fff
5259      * HDQ/1-wire Mod   480b2000 - 480b2fff
5260      * HDQ/1-wire L4    480b3000 - 480b3fff
5261      * MPU interrupt    480fe000 - 480fefff
5262      * STI channel base 54000000 - 5400ffff
5263      * IVA RAM          5c000000 - 5c01ffff
5264      * IVA ROM          5c020000 - 5c027fff
5265      * IMG_BUF_A        5c040000 - 5c040fff
5266      * IMG_BUF_B        5c042000 - 5c042fff
5267      * VLCDS            5c048000 - 5c0487ff
5268      * IMX_COEF         5c049000 - 5c04afff
5269      * IMX_CMD          5c051000 - 5c051fff
5270      * VLCDQ            5c053000 - 5c0533ff
5271      * VLCDH            5c054000 - 5c054fff
5272      * SEQ_CMD          5c055000 - 5c055fff
5273      * IMX_REG          5c056000 - 5c0560ff
5274      * VLCD_REG         5c056100 - 5c0561ff
5275      * SEQ_REG          5c056200 - 5c0562ff
5276      * IMG_BUF_REG      5c056300 - 5c0563ff
5277      * SEQIRQ_REG       5c056400 - 5c0564ff
5278      * OCP_REG          5c060000 - 5c060fff
5279      * SYSC_REG         5c070000 - 5c070fff
5280      * MMU_REG          5d000000 - 5d000fff
5281      * sDMA R           68000400 - 680005ff
5282      * sDMA W           68000600 - 680007ff
5283      * Display Control  68000800 - 680009ff
5284      * DSP subsystem    68000a00 - 68000bff
5285      * MPU subsystem    68000c00 - 68000dff
5286      * IVA subsystem    68001000 - 680011ff
5287      * USB              68001200 - 680013ff
5288      * Camera           68001400 - 680015ff
5289      * VLYNQ (firewall) 68001800 - 68001bff
5290      * VLYNQ            68001e00 - 68001fff
5291      * SSI              68002000 - 680021ff
5292      * L4               68002400 - 680025ff
5293      * DSP (firewall)   68002800 - 68002bff
5294      * DSP subsystem    68002e00 - 68002fff
5295      * IVA (firewall)   68003000 - 680033ff
5296      * IVA              68003600 - 680037ff
5297      * GFX              68003a00 - 68003bff
5298      * CMDWR emulation  68003c00 - 68003dff
5299      * SMS              68004000 - 680041ff
5300      * OCM              68004200 - 680043ff
5301      * GPMC             68004400 - 680045ff
5302      * RAM (firewall)   68005000 - 680053ff
5303      * RAM (err login)  68005400 - 680057ff
5304      * ROM (firewall)   68005800 - 68005bff
5305      * ROM (err login)  68005c00 - 68005fff
5306      * GPMC (firewall)  68006000 - 680063ff
5307      * GPMC (err login) 68006400 - 680067ff
5308      * SMS (err login)  68006c00 - 68006fff
5309      * SMS registers    68008000 - 68008fff
5310      * SDRC registers   68009000 - 68009fff
5311      * GPMC registers   6800a000   6800afff
5312      */
5313
5314     qemu_register_reset(omap2_mpu_reset, s);
5315
5316     return s;
5317 }