Zeroing ITR shouldn't ack irq zero.
[qemu] / hw / omap.c
1 /*
2  * TI OMAP processors emulation.
3  *
4  * Copyright (C) 2006-2007 Andrzej Zaborowski  <balrog@zabor.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19  * MA 02111-1307 USA
20  */
21 #include "vl.h"
22 #include "arm_pic.h"
23
24 /* Should signal the TCMI */
25 uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
26 {
27     uint8_t ret;
28
29     OMAP_8B_REG(addr);
30     cpu_physical_memory_read(addr, (void *) &ret, 1);
31     return ret;
32 }
33
34 void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
35                 uint32_t value)
36 {
37     uint8_t val8 = value;
38
39     OMAP_8B_REG(addr);
40     cpu_physical_memory_write(addr, (void *) &val8, 1);
41 }
42
43 uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
44 {
45     uint16_t ret;
46
47     OMAP_16B_REG(addr);
48     cpu_physical_memory_read(addr, (void *) &ret, 2);
49     return ret;
50 }
51
52 void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
53                 uint32_t value)
54 {
55     uint16_t val16 = value;
56
57     OMAP_16B_REG(addr);
58     cpu_physical_memory_write(addr, (void *) &val16, 2);
59 }
60
61 uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
62 {
63     uint32_t ret;
64
65     OMAP_32B_REG(addr);
66     cpu_physical_memory_read(addr, (void *) &ret, 4);
67     return ret;
68 }
69
70 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
71                 uint32_t value)
72 {
73     OMAP_32B_REG(addr);
74     cpu_physical_memory_write(addr, (void *) &value, 4);
75 }
76
77 /* Interrupt Handlers */
78 struct omap_intr_handler_s {
79     qemu_irq *pins;
80     qemu_irq *parent_pic;
81     target_phys_addr_t base;
82
83     /* state */
84     uint32_t irqs;
85     uint32_t mask;
86     uint32_t sens_edge;
87     uint32_t fiq;
88     int priority[32];
89     uint32_t new_irq_agr;
90     uint32_t new_fiq_agr;
91     int sir_irq;
92     int sir_fiq;
93     int stats[32];
94 };
95
96 static void omap_inth_update(struct omap_intr_handler_s *s)
97 {
98     uint32_t irq = s->irqs & ~s->mask & ~s->fiq;
99     uint32_t fiq = s->irqs & ~s->mask & s->fiq;
100
101     if (s->new_irq_agr || !irq) {
102        qemu_set_irq(s->parent_pic[ARM_PIC_CPU_IRQ], irq);
103        if (irq)
104            s->new_irq_agr = 0;
105     }
106
107     if (s->new_fiq_agr || !irq) {
108         qemu_set_irq(s->parent_pic[ARM_PIC_CPU_FIQ], fiq);
109         if (fiq)
110             s->new_fiq_agr = 0;
111     }
112 }
113
114 static void omap_inth_sir_update(struct omap_intr_handler_s *s)
115 {
116     int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f;
117     uint32_t level = s->irqs & ~s->mask;
118
119     intr_irq = 0;
120     intr_fiq = 0;
121     p_irq = -1;
122     p_fiq = -1;
123     /* Find the interrupt line with the highest dynamic priority */
124     for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, level >>= f) {
125         p = s->priority[i];
126         if (s->fiq & (1 << i)) {
127             if (p > p_fiq) {
128                 p_fiq = p;
129                 intr_fiq = i;
130             }
131         } else {
132             if (p > p_irq) {
133                 p_irq = p;
134                 intr_irq = i;
135             }
136         }
137
138         f = ffs(level >> 1);
139     }
140
141     s->sir_irq = intr_irq;
142     s->sir_fiq = intr_fiq;
143 }
144
145 #define INT_FALLING_EDGE        0
146 #define INT_LOW_LEVEL           1
147
148 static void omap_set_intr(void *opaque, int irq, int req)
149 {
150     struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
151     uint32_t rise;
152
153     if (req) {
154         rise = ~ih->irqs & (1 << irq);
155         ih->irqs |= rise;
156         ih->stats[irq] += !!rise;
157     } else {
158         rise = ih->sens_edge & ih->irqs & (1 << irq);
159         ih->irqs &= ~rise;
160     }
161
162     if (rise & ~ih->mask) {
163         omap_inth_sir_update(ih);
164
165         omap_inth_update(ih);
166     }
167 }
168
169 static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
170 {
171     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
172     int i, offset = addr - s->base;
173
174     switch (offset) {
175     case 0x00:  /* ITR */
176         return s->irqs;
177
178     case 0x04:  /* MIR */
179         return s->mask;
180
181     case 0x10:  /* SIR_IRQ_CODE */
182         i = s->sir_irq;
183         if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
184             s->irqs &= ~(1 << i);
185             omap_inth_sir_update(s);
186             omap_inth_update(s);
187         }
188         return i;
189
190     case 0x14:  /* SIR_FIQ_CODE */
191         i = s->sir_fiq;
192         if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
193             s->irqs &= ~(1 << i);
194             omap_inth_sir_update(s);
195             omap_inth_update(s);
196         }
197         return i;
198
199     case 0x18:  /* CONTROL_REG */
200         return 0;
201
202     case 0x1c:  /* ILR0 */
203     case 0x20:  /* ILR1 */
204     case 0x24:  /* ILR2 */
205     case 0x28:  /* ILR3 */
206     case 0x2c:  /* ILR4 */
207     case 0x30:  /* ILR5 */
208     case 0x34:  /* ILR6 */
209     case 0x38:  /* ILR7 */
210     case 0x3c:  /* ILR8 */
211     case 0x40:  /* ILR9 */
212     case 0x44:  /* ILR10 */
213     case 0x48:  /* ILR11 */
214     case 0x4c:  /* ILR12 */
215     case 0x50:  /* ILR13 */
216     case 0x54:  /* ILR14 */
217     case 0x58:  /* ILR15 */
218     case 0x5c:  /* ILR16 */
219     case 0x60:  /* ILR17 */
220     case 0x64:  /* ILR18 */
221     case 0x68:  /* ILR19 */
222     case 0x6c:  /* ILR20 */
223     case 0x70:  /* ILR21 */
224     case 0x74:  /* ILR22 */
225     case 0x78:  /* ILR23 */
226     case 0x7c:  /* ILR24 */
227     case 0x80:  /* ILR25 */
228     case 0x84:  /* ILR26 */
229     case 0x88:  /* ILR27 */
230     case 0x8c:  /* ILR28 */
231     case 0x90:  /* ILR29 */
232     case 0x94:  /* ILR30 */
233     case 0x98:  /* ILR31 */
234         i = (offset - 0x1c) >> 2;
235         return (s->priority[i] << 2) |
236                 (((s->sens_edge >> i) & 1) << 1) |
237                 ((s->fiq >> i) & 1);
238
239     case 0x9c:  /* ISR */
240         return 0x00000000;
241
242     default:
243         OMAP_BAD_REG(addr);
244         break;
245     }
246     return 0;
247 }
248
249 static void omap_inth_write(void *opaque, target_phys_addr_t addr,
250                 uint32_t value)
251 {
252     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
253     int i, offset = addr - s->base;
254
255     switch (offset) {
256     case 0x00:  /* ITR */
257         s->irqs &= value | 1;
258         omap_inth_sir_update(s);
259         omap_inth_update(s);
260         return;
261
262     case 0x04:  /* MIR */
263         s->mask = value;
264         omap_inth_sir_update(s);
265         omap_inth_update(s);
266         return;
267
268     case 0x10:  /* SIR_IRQ_CODE */
269     case 0x14:  /* SIR_FIQ_CODE */
270         OMAP_RO_REG(addr);
271         break;
272
273     case 0x18:  /* CONTROL_REG */
274         if (value & 2)
275             s->new_fiq_agr = ~0;
276         if (value & 1)
277             s->new_irq_agr = ~0;
278         omap_inth_update(s);
279         return;
280
281     case 0x1c:  /* ILR0 */
282     case 0x20:  /* ILR1 */
283     case 0x24:  /* ILR2 */
284     case 0x28:  /* ILR3 */
285     case 0x2c:  /* ILR4 */
286     case 0x30:  /* ILR5 */
287     case 0x34:  /* ILR6 */
288     case 0x38:  /* ILR7 */
289     case 0x3c:  /* ILR8 */
290     case 0x40:  /* ILR9 */
291     case 0x44:  /* ILR10 */
292     case 0x48:  /* ILR11 */
293     case 0x4c:  /* ILR12 */
294     case 0x50:  /* ILR13 */
295     case 0x54:  /* ILR14 */
296     case 0x58:  /* ILR15 */
297     case 0x5c:  /* ILR16 */
298     case 0x60:  /* ILR17 */
299     case 0x64:  /* ILR18 */
300     case 0x68:  /* ILR19 */
301     case 0x6c:  /* ILR20 */
302     case 0x70:  /* ILR21 */
303     case 0x74:  /* ILR22 */
304     case 0x78:  /* ILR23 */
305     case 0x7c:  /* ILR24 */
306     case 0x80:  /* ILR25 */
307     case 0x84:  /* ILR26 */
308     case 0x88:  /* ILR27 */
309     case 0x8c:  /* ILR28 */
310     case 0x90:  /* ILR29 */
311     case 0x94:  /* ILR30 */
312     case 0x98:  /* ILR31 */
313         i = (offset - 0x1c) >> 2;
314         s->priority[i] = (value >> 2) & 0x1f;
315         s->sens_edge &= ~(1 << i);
316         s->sens_edge |= ((value >> 1) & 1) << i;
317         s->fiq &= ~(1 << i);
318         s->fiq |= (value & 1) << i;
319         return;
320
321     case 0x9c:  /* ISR */
322         for (i = 0; i < 32; i ++)
323             if (value & (1 << i)) {
324                 omap_set_intr(s, i, 1);
325                 return;
326             }
327         return;
328
329     default:
330         OMAP_BAD_REG(addr);
331     }
332 }
333
334 static CPUReadMemoryFunc *omap_inth_readfn[] = {
335     omap_badwidth_read32,
336     omap_badwidth_read32,
337     omap_inth_read,
338 };
339
340 static CPUWriteMemoryFunc *omap_inth_writefn[] = {
341     omap_inth_write,
342     omap_inth_write,
343     omap_inth_write,
344 };
345
346 static void omap_inth_reset(struct omap_intr_handler_s *s)
347 {
348     s->irqs = 0x00000000;
349     s->mask = 0xffffffff;
350     s->sens_edge = 0x00000000;
351     s->fiq = 0x00000000;
352     memset(s->priority, 0, sizeof(s->priority));
353     s->new_irq_agr = ~0;
354     s->new_fiq_agr = ~0;
355     s->sir_irq = 0;
356     s->sir_fiq = 0;
357
358     omap_inth_update(s);
359 }
360
361 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
362                 unsigned long size, qemu_irq parent[2], omap_clk clk)
363 {
364     int iomemtype;
365     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
366             qemu_mallocz(sizeof(struct omap_intr_handler_s));
367
368     s->parent_pic = parent;
369     s->base = base;
370     s->pins = qemu_allocate_irqs(omap_set_intr, s, 32);
371     omap_inth_reset(s);
372
373     iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
374                     omap_inth_writefn, s);
375     cpu_register_physical_memory(s->base, size, iomemtype);
376
377     return s;
378 }
379
380 /* OMAP1 DMA module */
381 typedef enum {
382     constant = 0,
383     post_incremented,
384     single_index,
385     double_index,
386 } omap_dma_addressing_t;
387
388 struct omap_dma_channel_s {
389     int burst[2];
390     int pack[2];
391     enum omap_dma_port port[2];
392     target_phys_addr_t addr[2];
393     omap_dma_addressing_t mode[2];
394     int data_type;
395     int end_prog;
396     int repeat;
397     int auto_init;
398     int priority;
399     int fs;
400     int sync;
401     int running;
402     int interrupts;
403     int status;
404     int signalled;
405     int post_sync;
406     int transfer;
407     uint16_t elements;
408     uint16_t frames;
409     uint16_t frame_index;
410     uint16_t element_index;
411     uint16_t cpc;
412
413     struct omap_dma_reg_set_s {
414         target_phys_addr_t src, dest;
415         int frame;
416         int element;
417         int frame_delta[2];
418         int elem_delta[2];
419         int frames;
420         int elements;
421     } active_set;
422 };
423
424 struct omap_dma_s {
425     qemu_irq *ih;
426     QEMUTimer *tm;
427     struct omap_mpu_state_s *mpu;
428     target_phys_addr_t base;
429     omap_clk clk;
430     int64_t delay;
431     uint32_t drq;
432
433     uint16_t gcr;
434     int run_count;
435
436     int chans;
437     struct omap_dma_channel_s ch[16];
438     struct omap_dma_lcd_channel_s lcd_ch;
439 };
440
441 static void omap_dma_interrupts_update(struct omap_dma_s *s)
442 {
443     /* First three interrupts are shared between two channels each.  */
444     qemu_set_irq(s->ih[OMAP_INT_DMA_CH0_6],
445                     (s->ch[0].status | s->ch[6].status) & 0x3f);
446     qemu_set_irq(s->ih[OMAP_INT_DMA_CH1_7],
447                     (s->ch[1].status | s->ch[7].status) & 0x3f);
448     qemu_set_irq(s->ih[OMAP_INT_DMA_CH2_8],
449                     (s->ch[2].status | s->ch[8].status) & 0x3f);
450     qemu_set_irq(s->ih[OMAP_INT_DMA_CH3],
451                     (s->ch[3].status) & 0x3f);
452     qemu_set_irq(s->ih[OMAP_INT_DMA_CH4],
453                     (s->ch[4].status) & 0x3f);
454     qemu_set_irq(s->ih[OMAP_INT_DMA_CH5],
455                     (s->ch[5].status) & 0x3f);
456 }
457
458 static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
459 {
460     struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
461     int i;
462
463     /*
464      * TODO: verify address ranges and alignment
465      * TODO: port endianness
466      */
467
468     a->src = s->ch[ch].addr[0];
469     a->dest = s->ch[ch].addr[1];
470     a->frames = s->ch[ch].frames;
471     a->elements = s->ch[ch].elements;
472     a->frame = 0;
473     a->element = 0;
474
475     if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
476         printf("%s: bad DMA request\n", __FUNCTION__);
477         return;
478     }
479
480     for (i = 0; i < 2; i ++)
481         switch (s->ch[ch].mode[i]) {
482         case constant:
483             a->elem_delta[i] = 0;
484             a->frame_delta[i] = 0;
485             break;
486         case post_incremented:
487             a->elem_delta[i] = s->ch[ch].data_type;
488             a->frame_delta[i] = 0;
489             break;
490         case single_index:
491             a->elem_delta[i] = s->ch[ch].data_type +
492                 s->ch[ch].element_index - 1;
493             if (s->ch[ch].element_index > 0x7fff)
494                 a->elem_delta[i] -= 0x10000;
495             a->frame_delta[i] = 0;
496             break;
497         case double_index:
498             a->elem_delta[i] = s->ch[ch].data_type +
499                 s->ch[ch].element_index - 1;
500             if (s->ch[ch].element_index > 0x7fff)
501                 a->elem_delta[i] -= 0x10000;
502             a->frame_delta[i] = s->ch[ch].frame_index -
503                 s->ch[ch].element_index;
504             if (s->ch[ch].frame_index > 0x7fff)
505                 a->frame_delta[i] -= 0x10000;
506             break;
507         default:
508             break;
509         }
510 }
511
512 static inline void omap_dma_request_run(struct omap_dma_s *s,
513                 int channel, int request)
514 {
515 next_channel:
516     if (request > 0)
517         for (; channel < 9; channel ++)
518             if (s->ch[channel].sync == request && s->ch[channel].running)
519                 break;
520     if (channel >= 9)
521         return;
522
523     if (s->ch[channel].transfer) {
524         if (request > 0) {
525             s->ch[channel ++].post_sync = request;
526             goto next_channel;
527         }
528         s->ch[channel].status |= 0x02;  /* Synchronisation drop */
529         omap_dma_interrupts_update(s);
530         return;
531     }
532
533     if (!s->ch[channel].signalled)
534         s->run_count ++;
535     s->ch[channel].signalled = 1;
536
537     if (request > 0)
538         s->ch[channel].status |= 0x40;  /* External request */
539
540     if (s->delay && !qemu_timer_pending(s->tm))
541         qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
542
543     if (request > 0) {
544         channel ++;
545         goto next_channel;
546     }
547 }
548
549 static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel)
550 {
551     if (s->ch[channel].signalled)
552         s->run_count --;
553     s->ch[channel].signalled = 0;
554
555     if (!s->run_count)
556         qemu_del_timer(s->tm);
557 }
558
559 static void omap_dma_channel_run(struct omap_dma_s *s)
560 {
561     int ch;
562     uint16_t status;
563     uint8_t value[4];
564     struct omap_dma_port_if_s *src_p, *dest_p;
565     struct omap_dma_reg_set_s *a;
566
567     for (ch = 0; ch < 9; ch ++) {
568         a = &s->ch[ch].active_set;
569
570         src_p = &s->mpu->port[s->ch[ch].port[0]];
571         dest_p = &s->mpu->port[s->ch[ch].port[1]];
572         if (s->ch[ch].signalled && (!src_p->addr_valid(s->mpu, a->src) ||
573                     !dest_p->addr_valid(s->mpu, a->dest))) {
574 #if 0
575             /* Bus time-out */
576             if (s->ch[ch].interrupts & 0x01)
577                 s->ch[ch].status |= 0x01;
578             omap_dma_request_stop(s, ch);
579             continue;
580 #endif
581             printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch);
582         }
583
584         status = s->ch[ch].status;
585         while (status == s->ch[ch].status && s->ch[ch].signalled) {
586             /* Transfer a single element */
587             s->ch[ch].transfer = 1;
588             cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
589             cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
590             s->ch[ch].transfer = 0;
591
592             a->src += a->elem_delta[0];
593             a->dest += a->elem_delta[1];
594             a->element ++;
595
596             /* Check interrupt conditions */
597             if (a->element == a->elements) {
598                 a->element = 0;
599                 a->src += a->frame_delta[0];
600                 a->dest += a->frame_delta[1];
601                 a->frame ++;
602
603                 if (a->frame == a->frames) {
604                     if (!s->ch[ch].repeat || !s->ch[ch].auto_init)
605                         s->ch[ch].running = 0;
606
607                     if (s->ch[ch].auto_init &&
608                             (s->ch[ch].repeat ||
609                              s->ch[ch].end_prog))
610                         omap_dma_channel_load(s, ch);
611
612                     if (s->ch[ch].interrupts & 0x20)
613                         s->ch[ch].status |= 0x20;
614
615                     if (!s->ch[ch].sync)
616                         omap_dma_request_stop(s, ch);
617                 }
618
619                 if (s->ch[ch].interrupts & 0x08)
620                     s->ch[ch].status |= 0x08;
621
622                 if (s->ch[ch].sync && s->ch[ch].fs &&
623                                 !(s->drq & (1 << s->ch[ch].sync))) {
624                     s->ch[ch].status &= ~0x40;
625                     omap_dma_request_stop(s, ch);
626                 }
627             }
628
629             if (a->element == 1 && a->frame == a->frames - 1)
630                 if (s->ch[ch].interrupts & 0x10)
631                     s->ch[ch].status |= 0x10;
632
633             if (a->element == (a->elements >> 1))
634                 if (s->ch[ch].interrupts & 0x04)
635                     s->ch[ch].status |= 0x04;
636
637             if (s->ch[ch].sync && !s->ch[ch].fs &&
638                             !(s->drq & (1 << s->ch[ch].sync))) {
639                 s->ch[ch].status &= ~0x40;
640                 omap_dma_request_stop(s, ch);
641             }
642
643             /*
644              * Process requests made while the element was
645              * being transferred.
646              */
647             if (s->ch[ch].post_sync) {
648                 omap_dma_request_run(s, 0, s->ch[ch].post_sync);
649                 s->ch[ch].post_sync = 0;
650             }
651
652 #if 0
653             break;
654 #endif
655         }
656
657         s->ch[ch].cpc = a->dest & 0x0000ffff;
658     }
659
660     omap_dma_interrupts_update(s);
661     if (s->run_count && s->delay)
662         qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
663 }
664
665 static int omap_dma_ch_reg_read(struct omap_dma_s *s,
666                 int ch, int reg, uint16_t *value) {
667     switch (reg) {
668     case 0x00:  /* SYS_DMA_CSDP_CH0 */
669         *value = (s->ch[ch].burst[1] << 14) |
670                 (s->ch[ch].pack[1] << 13) |
671                 (s->ch[ch].port[1] << 9) |
672                 (s->ch[ch].burst[0] << 7) |
673                 (s->ch[ch].pack[0] << 6) |
674                 (s->ch[ch].port[0] << 2) |
675                 (s->ch[ch].data_type >> 1);
676         break;
677
678     case 0x02:  /* SYS_DMA_CCR_CH0 */
679         *value = (s->ch[ch].mode[1] << 14) |
680                 (s->ch[ch].mode[0] << 12) |
681                 (s->ch[ch].end_prog << 11) |
682                 (s->ch[ch].repeat << 9) |
683                 (s->ch[ch].auto_init << 8) |
684                 (s->ch[ch].running << 7) |
685                 (s->ch[ch].priority << 6) |
686                 (s->ch[ch].fs << 5) | s->ch[ch].sync;
687         break;
688
689     case 0x04:  /* SYS_DMA_CICR_CH0 */
690         *value = s->ch[ch].interrupts;
691         break;
692
693     case 0x06:  /* SYS_DMA_CSR_CH0 */
694         /* FIXME: shared CSR for channels sharing the interrupts */
695         *value = s->ch[ch].status;
696         s->ch[ch].status &= 0x40;
697         omap_dma_interrupts_update(s);
698         break;
699
700     case 0x08:  /* SYS_DMA_CSSA_L_CH0 */
701         *value = s->ch[ch].addr[0] & 0x0000ffff;
702         break;
703
704     case 0x0a:  /* SYS_DMA_CSSA_U_CH0 */
705         *value = s->ch[ch].addr[0] >> 16;
706         break;
707
708     case 0x0c:  /* SYS_DMA_CDSA_L_CH0 */
709         *value = s->ch[ch].addr[1] & 0x0000ffff;
710         break;
711
712     case 0x0e:  /* SYS_DMA_CDSA_U_CH0 */
713         *value = s->ch[ch].addr[1] >> 16;
714         break;
715
716     case 0x10:  /* SYS_DMA_CEN_CH0 */
717         *value = s->ch[ch].elements;
718         break;
719
720     case 0x12:  /* SYS_DMA_CFN_CH0 */
721         *value = s->ch[ch].frames;
722         break;
723
724     case 0x14:  /* SYS_DMA_CFI_CH0 */
725         *value = s->ch[ch].frame_index;
726         break;
727
728     case 0x16:  /* SYS_DMA_CEI_CH0 */
729         *value = s->ch[ch].element_index;
730         break;
731
732     case 0x18:  /* SYS_DMA_CPC_CH0 */
733         *value = s->ch[ch].cpc;
734         break;
735
736     default:
737         return 1;
738     }
739     return 0;
740 }
741
742 static int omap_dma_ch_reg_write(struct omap_dma_s *s,
743                 int ch, int reg, uint16_t value) {
744     switch (reg) {
745     case 0x00:  /* SYS_DMA_CSDP_CH0 */
746         s->ch[ch].burst[1] = (value & 0xc000) >> 14;
747         s->ch[ch].pack[1] = (value & 0x2000) >> 13;
748         s->ch[ch].port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
749         s->ch[ch].burst[0] = (value & 0x0180) >> 7;
750         s->ch[ch].pack[0] = (value & 0x0040) >> 6;
751         s->ch[ch].port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
752         s->ch[ch].data_type = (1 << (value & 3));
753         if (s->ch[ch].port[0] >= omap_dma_port_last)
754             printf("%s: invalid DMA port %i\n", __FUNCTION__,
755                             s->ch[ch].port[0]);
756         if (s->ch[ch].port[1] >= omap_dma_port_last)
757             printf("%s: invalid DMA port %i\n", __FUNCTION__,
758                             s->ch[ch].port[1]);
759         if ((value & 3) == 3)
760             printf("%s: bad data_type for DMA channel %i\n", __FUNCTION__, ch);
761         break;
762
763     case 0x02:  /* SYS_DMA_CCR_CH0 */
764         s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
765         s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
766         s->ch[ch].end_prog = (value & 0x0800) >> 11;
767         s->ch[ch].repeat = (value & 0x0200) >> 9;
768         s->ch[ch].auto_init = (value & 0x0100) >> 8;
769         s->ch[ch].priority = (value & 0x0040) >> 6;
770         s->ch[ch].fs = (value & 0x0020) >> 5;
771         s->ch[ch].sync = value & 0x001f;
772         if (value & 0x0080) {
773             if (s->ch[ch].running) {
774                 if (!s->ch[ch].signalled &&
775                                 s->ch[ch].auto_init && s->ch[ch].end_prog)
776                     omap_dma_channel_load(s, ch);
777             } else {
778                 s->ch[ch].running = 1;
779                 omap_dma_channel_load(s, ch);
780             }
781             if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync)))
782                 omap_dma_request_run(s, ch, 0);
783         } else {
784             s->ch[ch].running = 0;
785             omap_dma_request_stop(s, ch);
786         }
787         break;
788
789     case 0x04:  /* SYS_DMA_CICR_CH0 */
790         s->ch[ch].interrupts = value & 0x003f;
791         break;
792
793     case 0x06:  /* SYS_DMA_CSR_CH0 */
794         return 1;
795
796     case 0x08:  /* SYS_DMA_CSSA_L_CH0 */
797         s->ch[ch].addr[0] &= 0xffff0000;
798         s->ch[ch].addr[0] |= value;
799         break;
800
801     case 0x0a:  /* SYS_DMA_CSSA_U_CH0 */
802         s->ch[ch].addr[0] &= 0x0000ffff;
803         s->ch[ch].addr[0] |= (uint32_t) value << 16;
804         break;
805
806     case 0x0c:  /* SYS_DMA_CDSA_L_CH0 */
807         s->ch[ch].addr[1] &= 0xffff0000;
808         s->ch[ch].addr[1] |= value;
809         break;
810
811     case 0x0e:  /* SYS_DMA_CDSA_U_CH0 */
812         s->ch[ch].addr[1] &= 0x0000ffff;
813         s->ch[ch].addr[1] |= (uint32_t) value << 16;
814         break;
815
816     case 0x10:  /* SYS_DMA_CEN_CH0 */
817         s->ch[ch].elements = value & 0xffff;
818         break;
819
820     case 0x12:  /* SYS_DMA_CFN_CH0 */
821         s->ch[ch].frames = value & 0xffff;
822         break;
823
824     case 0x14:  /* SYS_DMA_CFI_CH0 */
825         s->ch[ch].frame_index = value & 0xffff;
826         break;
827
828     case 0x16:  /* SYS_DMA_CEI_CH0 */
829         s->ch[ch].element_index = value & 0xffff;
830         break;
831
832     case 0x18:  /* SYS_DMA_CPC_CH0 */
833         return 1;
834
835     default:
836         OMAP_BAD_REG((unsigned long) reg);
837     }
838     return 0;
839 }
840
841 static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
842 {
843     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
844     int i, reg, ch, offset = addr - s->base;
845     uint16_t ret;
846
847     switch (offset) {
848     case 0x000 ... 0x2fe:
849         reg = offset & 0x3f;
850         ch = (offset >> 6) & 0x0f;
851         if (omap_dma_ch_reg_read(s, ch, reg, &ret))
852             break;
853         return ret;
854
855     case 0x300: /* SYS_DMA_LCD_CTRL */
856         i = s->lcd_ch.condition;
857         s->lcd_ch.condition = 0;
858         qemu_irq_lower(s->lcd_ch.irq);
859         return ((s->lcd_ch.src == imif) << 6) | (i << 3) |
860                 (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
861
862     case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
863         return s->lcd_ch.src_f1_top & 0xffff;
864
865     case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
866         return s->lcd_ch.src_f1_top >> 16;
867
868     case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
869         return s->lcd_ch.src_f1_bottom & 0xffff;
870
871     case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
872         return s->lcd_ch.src_f1_bottom >> 16;
873
874     case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
875         return s->lcd_ch.src_f2_top & 0xffff;
876
877     case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
878         return s->lcd_ch.src_f2_top >> 16;
879
880     case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
881         return s->lcd_ch.src_f2_bottom & 0xffff;
882
883     case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
884         return s->lcd_ch.src_f2_bottom >> 16;
885
886     case 0x400: /* SYS_DMA_GCR */
887         return s->gcr;
888     }
889
890     OMAP_BAD_REG(addr);
891     return 0;
892 }
893
894 static void omap_dma_write(void *opaque, target_phys_addr_t addr,
895                 uint32_t value)
896 {
897     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
898     int reg, ch, offset = addr - s->base;
899
900     switch (offset) {
901     case 0x000 ... 0x2fe:
902         reg = offset & 0x3f;
903         ch = (offset >> 6) & 0x0f;
904         if (omap_dma_ch_reg_write(s, ch, reg, value))
905             OMAP_RO_REG(addr);
906         break;
907
908     case 0x300: /* SYS_DMA_LCD_CTRL */
909         s->lcd_ch.src = (value & 0x40) ? imif : emiff;
910         s->lcd_ch.condition = 0;
911         /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
912         s->lcd_ch.interrupts = (value >> 1) & 1;
913         s->lcd_ch.dual = value & 1;
914         break;
915
916     case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
917         s->lcd_ch.src_f1_top &= 0xffff0000;
918         s->lcd_ch.src_f1_top |= 0x0000ffff & value;
919         break;
920
921     case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
922         s->lcd_ch.src_f1_top &= 0x0000ffff;
923         s->lcd_ch.src_f1_top |= value << 16;
924         break;
925
926     case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
927         s->lcd_ch.src_f1_bottom &= 0xffff0000;
928         s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
929         break;
930
931     case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
932         s->lcd_ch.src_f1_bottom &= 0x0000ffff;
933         s->lcd_ch.src_f1_bottom |= value << 16;
934         break;
935
936     case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
937         s->lcd_ch.src_f2_top &= 0xffff0000;
938         s->lcd_ch.src_f2_top |= 0x0000ffff & value;
939         break;
940
941     case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
942         s->lcd_ch.src_f2_top &= 0x0000ffff;
943         s->lcd_ch.src_f2_top |= value << 16;
944         break;
945
946     case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
947         s->lcd_ch.src_f2_bottom &= 0xffff0000;
948         s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
949         break;
950
951     case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
952         s->lcd_ch.src_f2_bottom &= 0x0000ffff;
953         s->lcd_ch.src_f2_bottom |= value << 16;
954         break;
955
956     case 0x400: /* SYS_DMA_GCR */
957         s->gcr = value & 0x000c;
958         break;
959
960     default:
961         OMAP_BAD_REG(addr);
962     }
963 }
964
965 static CPUReadMemoryFunc *omap_dma_readfn[] = {
966     omap_badwidth_read16,
967     omap_dma_read,
968     omap_badwidth_read16,
969 };
970
971 static CPUWriteMemoryFunc *omap_dma_writefn[] = {
972     omap_badwidth_write16,
973     omap_dma_write,
974     omap_badwidth_write16,
975 };
976
977 static void omap_dma_request(void *opaque, int drq, int req)
978 {
979     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
980     /* The request pins are level triggered.  */
981     if (req) {
982         if (~s->drq & (1 << drq)) {
983             s->drq |= 1 << drq;
984             omap_dma_request_run(s, 0, drq);
985         }
986     } else
987         s->drq &= ~(1 << drq);
988 }
989
990 static void omap_dma_clk_update(void *opaque, int line, int on)
991 {
992     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
993
994     if (on) {
995         s->delay = ticks_per_sec >> 7;
996         if (s->run_count)
997             qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
998     } else {
999         s->delay = 0;
1000         qemu_del_timer(s->tm);
1001     }
1002 }
1003
1004 static void omap_dma_reset(struct omap_dma_s *s)
1005 {
1006     int i;
1007
1008     qemu_del_timer(s->tm);
1009     s->gcr = 0x0004;
1010     s->drq = 0x00000000;
1011     s->run_count = 0;
1012     s->lcd_ch.src = emiff;
1013     s->lcd_ch.condition = 0;
1014     s->lcd_ch.interrupts = 0;
1015     s->lcd_ch.dual = 0;
1016     memset(s->ch, 0, sizeof(s->ch));
1017     for (i = 0; i < s->chans; i ++)
1018         s->ch[i].interrupts = 0x0003;
1019 }
1020
1021 struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
1022                 qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk)
1023 {
1024     int iomemtype;
1025     struct omap_dma_s *s = (struct omap_dma_s *)
1026             qemu_mallocz(sizeof(struct omap_dma_s));
1027
1028     s->ih = pic;
1029     s->base = base;
1030     s->chans = 9;
1031     s->mpu = mpu;
1032     s->clk = clk;
1033     s->lcd_ch.irq = pic[OMAP_INT_DMA_LCD];
1034     s->lcd_ch.mpu = mpu;
1035     s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1036     omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1037     mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1038     omap_dma_reset(s);
1039     omap_dma_clk_update(s, 0, 1);
1040
1041     iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1042                     omap_dma_writefn, s);
1043     cpu_register_physical_memory(s->base, 0x800, iomemtype);
1044
1045     return s;
1046 }
1047
1048 /* DMA ports */
1049 static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1050                 target_phys_addr_t addr)
1051 {
1052     return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1053 }
1054
1055 static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1056                 target_phys_addr_t addr)
1057 {
1058     return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1059 }
1060
1061 static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1062                 target_phys_addr_t addr)
1063 {
1064     return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1065 }
1066
1067 static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1068                 target_phys_addr_t addr)
1069 {
1070     return addr >= 0xfffb0000 && addr < 0xffff0000;
1071 }
1072
1073 static int omap_validate_local_addr(struct omap_mpu_state_s *s,
1074                 target_phys_addr_t addr)
1075 {
1076     return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1077 }
1078
1079 static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1080                 target_phys_addr_t addr)
1081 {
1082     return addr >= 0xe1010000 && addr < 0xe1020004;
1083 }
1084
1085 /* MPU OS timers */
1086 struct omap_mpu_timer_s {
1087     qemu_irq irq;
1088     omap_clk clk;
1089     target_phys_addr_t base;
1090     uint32_t val;
1091     int64_t time;
1092     QEMUTimer *timer;
1093     int64_t rate;
1094     int it_ena;
1095
1096     int enable;
1097     int ptv;
1098     int ar;
1099     int st;
1100     uint32_t reset_val;
1101 };
1102
1103 static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1104 {
1105     uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
1106
1107     if (timer->st && timer->enable && timer->rate)
1108         return timer->val - muldiv64(distance >> (timer->ptv + 1),
1109                         timer->rate, ticks_per_sec);
1110     else
1111         return timer->val;
1112 }
1113
1114 static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1115 {
1116     timer->val = omap_timer_read(timer);
1117     timer->time = qemu_get_clock(vm_clock);
1118 }
1119
1120 static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1121 {
1122     int64_t expires;
1123
1124     if (timer->enable && timer->st && timer->rate) {
1125         timer->val = timer->reset_val;  /* Should skip this on clk enable */
1126         expires = muldiv64(timer->val << (timer->ptv + 1),
1127                         ticks_per_sec, timer->rate);
1128
1129         /* If timer expiry would be sooner than in about 1 ms and
1130          * auto-reload isn't set, then fire immediately.  This is a hack
1131          * to make systems like PalmOS run in acceptable time.  PalmOS
1132          * sets the interval to a very low value and polls the status bit
1133          * in a busy loop when it wants to sleep just a couple of CPU
1134          * ticks.  */
1135         if (expires > (ticks_per_sec >> 10) || timer->ar)
1136             qemu_mod_timer(timer->timer, timer->time + expires);
1137         else {
1138             timer->val = 0;
1139             timer->st = 0;
1140             if (timer->it_ena)
1141                 qemu_irq_raise(timer->irq);
1142         }
1143     } else
1144         qemu_del_timer(timer->timer);
1145 }
1146
1147 static void omap_timer_tick(void *opaque)
1148 {
1149     struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1150     omap_timer_sync(timer);
1151
1152     if (!timer->ar) {
1153         timer->val = 0;
1154         timer->st = 0;
1155     }
1156
1157     if (timer->it_ena)
1158         qemu_irq_raise(timer->irq);
1159     omap_timer_update(timer);
1160 }
1161
1162 static void omap_timer_clk_update(void *opaque, int line, int on)
1163 {
1164     struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1165
1166     omap_timer_sync(timer);
1167     timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1168     omap_timer_update(timer);
1169 }
1170
1171 static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
1172 {
1173     omap_clk_adduser(timer->clk,
1174                     qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
1175     timer->rate = omap_clk_getrate(timer->clk);
1176 }
1177
1178 static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
1179 {
1180     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1181     int offset = addr - s->base;
1182
1183     switch (offset) {
1184     case 0x00:  /* CNTL_TIMER */
1185         return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1186
1187     case 0x04:  /* LOAD_TIM */
1188         break;
1189
1190     case 0x08:  /* READ_TIM */
1191         return omap_timer_read(s);
1192     }
1193
1194     OMAP_BAD_REG(addr);
1195     return 0;
1196 }
1197
1198 static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1199                 uint32_t value)
1200 {
1201     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1202     int offset = addr - s->base;
1203
1204     switch (offset) {
1205     case 0x00:  /* CNTL_TIMER */
1206         omap_timer_sync(s);
1207         s->enable = (value >> 5) & 1;
1208         s->ptv = (value >> 2) & 7;
1209         s->ar = (value >> 1) & 1;
1210         s->st = value & 1;
1211         omap_timer_update(s);
1212         return;
1213
1214     case 0x04:  /* LOAD_TIM */
1215         s->reset_val = value;
1216         return;
1217
1218     case 0x08:  /* READ_TIM */
1219         OMAP_RO_REG(addr);
1220         break;
1221
1222     default:
1223         OMAP_BAD_REG(addr);
1224     }
1225 }
1226
1227 static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1228     omap_badwidth_read32,
1229     omap_badwidth_read32,
1230     omap_mpu_timer_read,
1231 };
1232
1233 static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1234     omap_badwidth_write32,
1235     omap_badwidth_write32,
1236     omap_mpu_timer_write,
1237 };
1238
1239 static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
1240 {
1241     qemu_del_timer(s->timer);
1242     s->enable = 0;
1243     s->reset_val = 31337;
1244     s->val = 0;
1245     s->ptv = 0;
1246     s->ar = 0;
1247     s->st = 0;
1248     s->it_ena = 1;
1249 }
1250
1251 struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1252                 qemu_irq irq, omap_clk clk)
1253 {
1254     int iomemtype;
1255     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1256             qemu_mallocz(sizeof(struct omap_mpu_timer_s));
1257
1258     s->irq = irq;
1259     s->clk = clk;
1260     s->base = base;
1261     s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
1262     omap_mpu_timer_reset(s);
1263     omap_timer_clk_setup(s);
1264
1265     iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
1266                     omap_mpu_timer_writefn, s);
1267     cpu_register_physical_memory(s->base, 0x100, iomemtype);
1268
1269     return s;
1270 }
1271
1272 /* Watchdog timer */
1273 struct omap_watchdog_timer_s {
1274     struct omap_mpu_timer_s timer;
1275     uint8_t last_wr;
1276     int mode;
1277     int free;
1278     int reset;
1279 };
1280
1281 static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
1282 {
1283     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1284     int offset = addr - s->timer.base;
1285
1286     switch (offset) {
1287     case 0x00:  /* CNTL_TIMER */
1288         return (s->timer.ptv << 9) | (s->timer.ar << 8) |
1289                 (s->timer.st << 7) | (s->free << 1);
1290
1291     case 0x04:  /* READ_TIMER */
1292         return omap_timer_read(&s->timer);
1293
1294     case 0x08:  /* TIMER_MODE */
1295         return s->mode << 15;
1296     }
1297
1298     OMAP_BAD_REG(addr);
1299     return 0;
1300 }
1301
1302 static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1303                 uint32_t value)
1304 {
1305     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1306     int offset = addr - s->timer.base;
1307
1308     switch (offset) {
1309     case 0x00:  /* CNTL_TIMER */
1310         omap_timer_sync(&s->timer);
1311         s->timer.ptv = (value >> 9) & 7;
1312         s->timer.ar = (value >> 8) & 1;
1313         s->timer.st = (value >> 7) & 1;
1314         s->free = (value >> 1) & 1;
1315         omap_timer_update(&s->timer);
1316         break;
1317
1318     case 0x04:  /* LOAD_TIMER */
1319         s->timer.reset_val = value & 0xffff;
1320         break;
1321
1322     case 0x08:  /* TIMER_MODE */
1323         if (!s->mode && ((value >> 15) & 1))
1324             omap_clk_get(s->timer.clk);
1325         s->mode |= (value >> 15) & 1;
1326         if (s->last_wr == 0xf5) {
1327             if ((value & 0xff) == 0xa0) {
1328                 if (s->mode) {
1329                     s->mode = 0;
1330                     omap_clk_put(s->timer.clk);
1331                 }
1332             } else {
1333                 /* XXX: on T|E hardware somehow this has no effect,
1334                  * on Zire 71 it works as specified.  */
1335                 s->reset = 1;
1336                 qemu_system_reset_request();
1337             }
1338         }
1339         s->last_wr = value & 0xff;
1340         break;
1341
1342     default:
1343         OMAP_BAD_REG(addr);
1344     }
1345 }
1346
1347 static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
1348     omap_badwidth_read16,
1349     omap_wd_timer_read,
1350     omap_badwidth_read16,
1351 };
1352
1353 static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
1354     omap_badwidth_write16,
1355     omap_wd_timer_write,
1356     omap_badwidth_write16,
1357 };
1358
1359 static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
1360 {
1361     qemu_del_timer(s->timer.timer);
1362     if (!s->mode)
1363         omap_clk_get(s->timer.clk);
1364     s->mode = 1;
1365     s->free = 1;
1366     s->reset = 0;
1367     s->timer.enable = 1;
1368     s->timer.it_ena = 1;
1369     s->timer.reset_val = 0xffff;
1370     s->timer.val = 0;
1371     s->timer.st = 0;
1372     s->timer.ptv = 0;
1373     s->timer.ar = 0;
1374     omap_timer_update(&s->timer);
1375 }
1376
1377 struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
1378                 qemu_irq irq, omap_clk clk)
1379 {
1380     int iomemtype;
1381     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
1382             qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
1383
1384     s->timer.irq = irq;
1385     s->timer.clk = clk;
1386     s->timer.base = base;
1387     s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1388     omap_wd_timer_reset(s);
1389     omap_timer_clk_setup(&s->timer);
1390
1391     iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
1392                     omap_wd_timer_writefn, s);
1393     cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
1394
1395     return s;
1396 }
1397
1398 /* 32-kHz timer */
1399 struct omap_32khz_timer_s {
1400     struct omap_mpu_timer_s timer;
1401 };
1402
1403 static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
1404 {
1405     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1406     int offset = addr & OMAP_MPUI_REG_MASK;
1407
1408     switch (offset) {
1409     case 0x00:  /* TVR */
1410         return s->timer.reset_val;
1411
1412     case 0x04:  /* TCR */
1413         return omap_timer_read(&s->timer);
1414
1415     case 0x08:  /* CR */
1416         return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
1417
1418     default:
1419         break;
1420     }
1421     OMAP_BAD_REG(addr);
1422     return 0;
1423 }
1424
1425 static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1426                 uint32_t value)
1427 {
1428     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1429     int offset = addr & OMAP_MPUI_REG_MASK;
1430
1431     switch (offset) {
1432     case 0x00:  /* TVR */
1433         s->timer.reset_val = value & 0x00ffffff;
1434         break;
1435
1436     case 0x04:  /* TCR */
1437         OMAP_RO_REG(addr);
1438         break;
1439
1440     case 0x08:  /* CR */
1441         s->timer.ar = (value >> 3) & 1;
1442         s->timer.it_ena = (value >> 2) & 1;
1443         if (s->timer.st != (value & 1) || (value & 2)) {
1444             omap_timer_sync(&s->timer);
1445             s->timer.enable = value & 1;
1446             s->timer.st = value & 1;
1447             omap_timer_update(&s->timer);
1448         }
1449         break;
1450
1451     default:
1452         OMAP_BAD_REG(addr);
1453     }
1454 }
1455
1456 static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1457     omap_badwidth_read32,
1458     omap_badwidth_read32,
1459     omap_os_timer_read,
1460 };
1461
1462 static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1463     omap_badwidth_write32,
1464     omap_badwidth_write32,
1465     omap_os_timer_write,
1466 };
1467
1468 static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1469 {
1470     qemu_del_timer(s->timer.timer);
1471     s->timer.enable = 0;
1472     s->timer.it_ena = 0;
1473     s->timer.reset_val = 0x00ffffff;
1474     s->timer.val = 0;
1475     s->timer.st = 0;
1476     s->timer.ptv = 0;
1477     s->timer.ar = 1;
1478 }
1479
1480 struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1481                 qemu_irq irq, omap_clk clk)
1482 {
1483     int iomemtype;
1484     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1485             qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1486
1487     s->timer.irq = irq;
1488     s->timer.clk = clk;
1489     s->timer.base = base;
1490     s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1491     omap_os_timer_reset(s);
1492     omap_timer_clk_setup(&s->timer);
1493
1494     iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1495                     omap_os_timer_writefn, s);
1496     cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
1497
1498     return s;
1499 }
1500
1501 /* Ultra Low-Power Device Module */
1502 static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1503 {
1504     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1505     int offset = addr - s->ulpd_pm_base;
1506     uint16_t ret;
1507
1508     switch (offset) {
1509     case 0x14:  /* IT_STATUS */
1510         ret = s->ulpd_pm_regs[offset >> 2];
1511         s->ulpd_pm_regs[offset >> 2] = 0;
1512         qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1513         return ret;
1514
1515     case 0x18:  /* Reserved */
1516     case 0x1c:  /* Reserved */
1517     case 0x20:  /* Reserved */
1518     case 0x28:  /* Reserved */
1519     case 0x2c:  /* Reserved */
1520         OMAP_BAD_REG(addr);
1521     case 0x00:  /* COUNTER_32_LSB */
1522     case 0x04:  /* COUNTER_32_MSB */
1523     case 0x08:  /* COUNTER_HIGH_FREQ_LSB */
1524     case 0x0c:  /* COUNTER_HIGH_FREQ_MSB */
1525     case 0x10:  /* GAUGING_CTRL */
1526     case 0x24:  /* SETUP_ANALOG_CELL3_ULPD1 */
1527     case 0x30:  /* CLOCK_CTRL */
1528     case 0x34:  /* SOFT_REQ */
1529     case 0x38:  /* COUNTER_32_FIQ */
1530     case 0x3c:  /* DPLL_CTRL */
1531     case 0x40:  /* STATUS_REQ */
1532         /* XXX: check clk::usecount state for every clock */
1533     case 0x48:  /* LOCL_TIME */
1534     case 0x4c:  /* APLL_CTRL */
1535     case 0x50:  /* POWER_CTRL */
1536         return s->ulpd_pm_regs[offset >> 2];
1537     }
1538
1539     OMAP_BAD_REG(addr);
1540     return 0;
1541 }
1542
1543 static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1544                 uint16_t diff, uint16_t value)
1545 {
1546     if (diff & (1 << 4))                                /* USB_MCLK_EN */
1547         omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1548     if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1549         omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1550 }
1551
1552 static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1553                 uint16_t diff, uint16_t value)
1554 {
1555     if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1556         omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1557     if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1558         omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1559     if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1560         omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1561     if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1562         omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1563 }
1564
1565 static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1566                 uint32_t value)
1567 {
1568     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1569     int offset = addr - s->ulpd_pm_base;
1570     int64_t now, ticks;
1571     int div, mult;
1572     static const int bypass_div[4] = { 1, 2, 4, 4 };
1573     uint16_t diff;
1574
1575     switch (offset) {
1576     case 0x00:  /* COUNTER_32_LSB */
1577     case 0x04:  /* COUNTER_32_MSB */
1578     case 0x08:  /* COUNTER_HIGH_FREQ_LSB */
1579     case 0x0c:  /* COUNTER_HIGH_FREQ_MSB */
1580     case 0x14:  /* IT_STATUS */
1581     case 0x40:  /* STATUS_REQ */
1582         OMAP_RO_REG(addr);
1583         break;
1584
1585     case 0x10:  /* GAUGING_CTRL */
1586         /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1587         if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
1588             now = qemu_get_clock(vm_clock);
1589
1590             if (value & 1)
1591                 s->ulpd_gauge_start = now;
1592             else {
1593                 now -= s->ulpd_gauge_start;
1594
1595                 /* 32-kHz ticks */
1596                 ticks = muldiv64(now, 32768, ticks_per_sec);
1597                 s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1598                 s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1599                 if (ticks >> 32)        /* OVERFLOW_32K */
1600                     s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1601
1602                 /* High frequency ticks */
1603                 ticks = muldiv64(now, 12000000, ticks_per_sec);
1604                 s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1605                 s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1606                 if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1607                     s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1608
1609                 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;   /* IT_GAUGING */
1610                 qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1611             }
1612         }
1613         s->ulpd_pm_regs[offset >> 2] = value;
1614         break;
1615
1616     case 0x18:  /* Reserved */
1617     case 0x1c:  /* Reserved */
1618     case 0x20:  /* Reserved */
1619     case 0x28:  /* Reserved */
1620     case 0x2c:  /* Reserved */
1621         OMAP_BAD_REG(addr);
1622     case 0x24:  /* SETUP_ANALOG_CELL3_ULPD1 */
1623     case 0x38:  /* COUNTER_32_FIQ */
1624     case 0x48:  /* LOCL_TIME */
1625     case 0x50:  /* POWER_CTRL */
1626         s->ulpd_pm_regs[offset >> 2] = value;
1627         break;
1628
1629     case 0x30:  /* CLOCK_CTRL */
1630         diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1631         s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
1632         omap_ulpd_clk_update(s, diff, value);
1633         break;
1634
1635     case 0x34:  /* SOFT_REQ */
1636         diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1637         s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
1638         omap_ulpd_req_update(s, diff, value);
1639         break;
1640
1641     case 0x3c:  /* DPLL_CTRL */
1642         /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
1643          * omitted altogether, probably a typo.  */
1644         /* This register has identical semantics with DPLL(1:3) control
1645          * registers, see omap_dpll_write() */
1646         diff = s->ulpd_pm_regs[offset >> 2] & value;
1647         s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
1648         if (diff & (0x3ff << 2)) {
1649             if (value & (1 << 4)) {                     /* PLL_ENABLE */
1650                 div = ((value >> 5) & 3) + 1;           /* PLL_DIV */
1651                 mult = MIN((value >> 7) & 0x1f, 1);     /* PLL_MULT */
1652             } else {
1653                 div = bypass_div[((value >> 2) & 3)];   /* BYPASS_DIV */
1654                 mult = 1;
1655             }
1656             omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
1657         }
1658
1659         /* Enter the desired mode.  */
1660         s->ulpd_pm_regs[offset >> 2] =
1661                 (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
1662                 ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
1663
1664         /* Act as if the lock is restored.  */
1665         s->ulpd_pm_regs[offset >> 2] |= 2;
1666         break;
1667
1668     case 0x4c:  /* APLL_CTRL */
1669         diff = s->ulpd_pm_regs[offset >> 2] & value;
1670         s->ulpd_pm_regs[offset >> 2] = value & 0xf;
1671         if (diff & (1 << 0))                            /* APLL_NDPLL_SWITCH */
1672             omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1673                                     (value & (1 << 0)) ? "apll" : "dpll4"));
1674         break;
1675
1676     default:
1677         OMAP_BAD_REG(addr);
1678     }
1679 }
1680
1681 static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1682     omap_badwidth_read16,
1683     omap_ulpd_pm_read,
1684     omap_badwidth_read16,
1685 };
1686
1687 static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1688     omap_badwidth_write16,
1689     omap_ulpd_pm_write,
1690     omap_badwidth_write16,
1691 };
1692
1693 static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
1694 {
1695     mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
1696     mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
1697     mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
1698     mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
1699     mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
1700     mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
1701     mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
1702     mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
1703     mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
1704     mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
1705     mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
1706     omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
1707     mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
1708     omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
1709     mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
1710     mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
1711     mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
1712     mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
1713     mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
1714     mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
1715     mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
1716     omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
1717     omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
1718 }
1719
1720 static void omap_ulpd_pm_init(target_phys_addr_t base,
1721                 struct omap_mpu_state_s *mpu)
1722 {
1723     int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1724                     omap_ulpd_pm_writefn, mpu);
1725
1726     mpu->ulpd_pm_base = base;
1727     cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1728     omap_ulpd_pm_reset(mpu);
1729 }
1730
1731 /* OMAP Pin Configuration */
1732 static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1733 {
1734     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1735     int offset = addr - s->pin_cfg_base;
1736
1737     switch (offset) {
1738     case 0x00:  /* FUNC_MUX_CTRL_0 */
1739     case 0x04:  /* FUNC_MUX_CTRL_1 */
1740     case 0x08:  /* FUNC_MUX_CTRL_2 */
1741         return s->func_mux_ctrl[offset >> 2];
1742
1743     case 0x0c:  /* COMP_MODE_CTRL_0 */
1744         return s->comp_mode_ctrl[0];
1745
1746     case 0x10:  /* FUNC_MUX_CTRL_3 */
1747     case 0x14:  /* FUNC_MUX_CTRL_4 */
1748     case 0x18:  /* FUNC_MUX_CTRL_5 */
1749     case 0x1c:  /* FUNC_MUX_CTRL_6 */
1750     case 0x20:  /* FUNC_MUX_CTRL_7 */
1751     case 0x24:  /* FUNC_MUX_CTRL_8 */
1752     case 0x28:  /* FUNC_MUX_CTRL_9 */
1753     case 0x2c:  /* FUNC_MUX_CTRL_A */
1754     case 0x30:  /* FUNC_MUX_CTRL_B */
1755     case 0x34:  /* FUNC_MUX_CTRL_C */
1756     case 0x38:  /* FUNC_MUX_CTRL_D */
1757         return s->func_mux_ctrl[(offset >> 2) - 1];
1758
1759     case 0x40:  /* PULL_DWN_CTRL_0 */
1760     case 0x44:  /* PULL_DWN_CTRL_1 */
1761     case 0x48:  /* PULL_DWN_CTRL_2 */
1762     case 0x4c:  /* PULL_DWN_CTRL_3 */
1763         return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1764
1765     case 0x50:  /* GATE_INH_CTRL_0 */
1766         return s->gate_inh_ctrl[0];
1767
1768     case 0x60:  /* VOLTAGE_CTRL_0 */
1769         return s->voltage_ctrl[0];
1770
1771     case 0x70:  /* TEST_DBG_CTRL_0 */
1772         return s->test_dbg_ctrl[0];
1773
1774     case 0x80:  /* MOD_CONF_CTRL_0 */
1775         return s->mod_conf_ctrl[0];
1776     }
1777
1778     OMAP_BAD_REG(addr);
1779     return 0;
1780 }
1781
1782 static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1783                 uint32_t diff, uint32_t value)
1784 {
1785     if (s->compat1509) {
1786         if (diff & (1 << 9))                    /* BLUETOOTH */
1787             omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1788                             (~value >> 9) & 1);
1789         if (diff & (1 << 7))                    /* USB.CLKO */
1790             omap_clk_onoff(omap_findclk(s, "usb.clko"),
1791                             (value >> 7) & 1);
1792     }
1793 }
1794
1795 static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1796                 uint32_t diff, uint32_t value)
1797 {
1798     if (s->compat1509) {
1799         if (diff & (1 << 31))                   /* MCBSP3_CLK_HIZ_DI */
1800             omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1801                             (value >> 31) & 1);
1802         if (diff & (1 << 1))                    /* CLK32K */
1803             omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1804                             (~value >> 1) & 1);
1805     }
1806 }
1807
1808 static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1809                 uint32_t diff, uint32_t value)
1810 {
1811     if (diff & (1 << 31))                       /* CONF_MOD_UART3_CLK_MODE_R */
1812          omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1813                          omap_findclk(s, ((value >> 31) & 1) ?
1814                                  "ck_48m" : "armper_ck"));
1815     if (diff & (1 << 30))                       /* CONF_MOD_UART2_CLK_MODE_R */
1816          omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1817                          omap_findclk(s, ((value >> 30) & 1) ?
1818                                  "ck_48m" : "armper_ck"));
1819     if (diff & (1 << 29))                       /* CONF_MOD_UART1_CLK_MODE_R */
1820          omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1821                          omap_findclk(s, ((value >> 29) & 1) ?
1822                                  "ck_48m" : "armper_ck"));
1823     if (diff & (1 << 23))                       /* CONF_MOD_MMC_SD_CLK_REQ_R */
1824          omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1825                          omap_findclk(s, ((value >> 23) & 1) ?
1826                                  "ck_48m" : "armper_ck"));
1827     if (diff & (1 << 12))                       /* CONF_MOD_COM_MCLK_12_48_S */
1828          omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1829                          omap_findclk(s, ((value >> 12) & 1) ?
1830                                  "ck_48m" : "armper_ck"));
1831     if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1832          omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1833 }
1834
1835 static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1836                 uint32_t value)
1837 {
1838     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1839     int offset = addr - s->pin_cfg_base;
1840     uint32_t diff;
1841
1842     switch (offset) {
1843     case 0x00:  /* FUNC_MUX_CTRL_0 */
1844         diff = s->func_mux_ctrl[offset >> 2] ^ value;
1845         s->func_mux_ctrl[offset >> 2] = value;
1846         omap_pin_funcmux0_update(s, diff, value);
1847         return;
1848
1849     case 0x04:  /* FUNC_MUX_CTRL_1 */
1850         diff = s->func_mux_ctrl[offset >> 2] ^ value;
1851         s->func_mux_ctrl[offset >> 2] = value;
1852         omap_pin_funcmux1_update(s, diff, value);
1853         return;
1854
1855     case 0x08:  /* FUNC_MUX_CTRL_2 */
1856         s->func_mux_ctrl[offset >> 2] = value;
1857         return;
1858
1859     case 0x0c:  /* COMP_MODE_CTRL_0 */
1860         s->comp_mode_ctrl[0] = value;
1861         s->compat1509 = (value != 0x0000eaef);
1862         omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1863         omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1864         return;
1865
1866     case 0x10:  /* FUNC_MUX_CTRL_3 */
1867     case 0x14:  /* FUNC_MUX_CTRL_4 */
1868     case 0x18:  /* FUNC_MUX_CTRL_5 */
1869     case 0x1c:  /* FUNC_MUX_CTRL_6 */
1870     case 0x20:  /* FUNC_MUX_CTRL_7 */
1871     case 0x24:  /* FUNC_MUX_CTRL_8 */
1872     case 0x28:  /* FUNC_MUX_CTRL_9 */
1873     case 0x2c:  /* FUNC_MUX_CTRL_A */
1874     case 0x30:  /* FUNC_MUX_CTRL_B */
1875     case 0x34:  /* FUNC_MUX_CTRL_C */
1876     case 0x38:  /* FUNC_MUX_CTRL_D */
1877         s->func_mux_ctrl[(offset >> 2) - 1] = value;
1878         return;
1879
1880     case 0x40:  /* PULL_DWN_CTRL_0 */
1881     case 0x44:  /* PULL_DWN_CTRL_1 */
1882     case 0x48:  /* PULL_DWN_CTRL_2 */
1883     case 0x4c:  /* PULL_DWN_CTRL_3 */
1884         s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1885         return;
1886
1887     case 0x50:  /* GATE_INH_CTRL_0 */
1888         s->gate_inh_ctrl[0] = value;
1889         return;
1890
1891     case 0x60:  /* VOLTAGE_CTRL_0 */
1892         s->voltage_ctrl[0] = value;
1893         return;
1894
1895     case 0x70:  /* TEST_DBG_CTRL_0 */
1896         s->test_dbg_ctrl[0] = value;
1897         return;
1898
1899     case 0x80:  /* MOD_CONF_CTRL_0 */
1900         diff = s->mod_conf_ctrl[0] ^ value;
1901         s->mod_conf_ctrl[0] = value;
1902         omap_pin_modconf1_update(s, diff, value);
1903         return;
1904
1905     default:
1906         OMAP_BAD_REG(addr);
1907     }
1908 }
1909
1910 static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1911     omap_badwidth_read32,
1912     omap_badwidth_read32,
1913     omap_pin_cfg_read,
1914 };
1915
1916 static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1917     omap_badwidth_write32,
1918     omap_badwidth_write32,
1919     omap_pin_cfg_write,
1920 };
1921
1922 static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1923 {
1924     /* Start in Compatibility Mode.  */
1925     mpu->compat1509 = 1;
1926     omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1927     omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1928     omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1929     memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1930     memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1931     memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1932     memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1933     memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1934     memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1935     memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1936 }
1937
1938 static void omap_pin_cfg_init(target_phys_addr_t base,
1939                 struct omap_mpu_state_s *mpu)
1940 {
1941     int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1942                     omap_pin_cfg_writefn, mpu);
1943
1944     mpu->pin_cfg_base = base;
1945     cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1946     omap_pin_cfg_reset(mpu);
1947 }
1948
1949 /* Device Identification, Die Identification */
1950 static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1951 {
1952     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1953
1954     switch (addr) {
1955     case 0xfffe1800:    /* DIE_ID_LSB */
1956         return 0xc9581f0e;
1957     case 0xfffe1804:    /* DIE_ID_MSB */
1958         return 0xa8858bfa;
1959
1960     case 0xfffe2000:    /* PRODUCT_ID_LSB */
1961         return 0x00aaaafc;
1962     case 0xfffe2004:    /* PRODUCT_ID_MSB */
1963         return 0xcafeb574;
1964
1965     case 0xfffed400:    /* JTAG_ID_LSB */
1966         switch (s->mpu_model) {
1967         case omap310:
1968             return 0x03310315;
1969         case omap1510:
1970             return 0x03310115;
1971         }
1972         break;
1973
1974     case 0xfffed404:    /* JTAG_ID_MSB */
1975         switch (s->mpu_model) {
1976         case omap310:
1977             return 0xfb57402f;
1978         case omap1510:
1979             return 0xfb47002f;
1980         }
1981         break;
1982     }
1983
1984     OMAP_BAD_REG(addr);
1985     return 0;
1986 }
1987
1988 static void omap_id_write(void *opaque, target_phys_addr_t addr,
1989                 uint32_t value)
1990 {
1991     OMAP_BAD_REG(addr);
1992 }
1993
1994 static CPUReadMemoryFunc *omap_id_readfn[] = {
1995     omap_badwidth_read32,
1996     omap_badwidth_read32,
1997     omap_id_read,
1998 };
1999
2000 static CPUWriteMemoryFunc *omap_id_writefn[] = {
2001     omap_badwidth_write32,
2002     omap_badwidth_write32,
2003     omap_id_write,
2004 };
2005
2006 static void omap_id_init(struct omap_mpu_state_s *mpu)
2007 {
2008     int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
2009                     omap_id_writefn, mpu);
2010     cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
2011     cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
2012     if (!cpu_is_omap15xx(mpu))
2013         cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
2014 }
2015
2016 /* MPUI Control (Dummy) */
2017 static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
2018 {
2019     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2020     int offset = addr - s->mpui_base;
2021
2022     switch (offset) {
2023     case 0x00:  /* CTRL */
2024         return s->mpui_ctrl;
2025     case 0x04:  /* DEBUG_ADDR */
2026         return 0x01ffffff;
2027     case 0x08:  /* DEBUG_DATA */
2028         return 0xffffffff;
2029     case 0x0c:  /* DEBUG_FLAG */
2030         return 0x00000800;
2031     case 0x10:  /* STATUS */
2032         return 0x00000000;
2033
2034     /* Not in OMAP310 */
2035     case 0x14:  /* DSP_STATUS */
2036     case 0x18:  /* DSP_BOOT_CONFIG */
2037         return 0x00000000;
2038     case 0x1c:  /* DSP_MPUI_CONFIG */
2039         return 0x0000ffff;
2040     }
2041
2042     OMAP_BAD_REG(addr);
2043     return 0;
2044 }
2045
2046 static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2047                 uint32_t value)
2048 {
2049     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2050     int offset = addr - s->mpui_base;
2051
2052     switch (offset) {
2053     case 0x00:  /* CTRL */
2054         s->mpui_ctrl = value & 0x007fffff;
2055         break;
2056
2057     case 0x04:  /* DEBUG_ADDR */
2058     case 0x08:  /* DEBUG_DATA */
2059     case 0x0c:  /* DEBUG_FLAG */
2060     case 0x10:  /* STATUS */
2061     /* Not in OMAP310 */
2062     case 0x14:  /* DSP_STATUS */
2063         OMAP_RO_REG(addr);
2064     case 0x18:  /* DSP_BOOT_CONFIG */
2065     case 0x1c:  /* DSP_MPUI_CONFIG */
2066         break;
2067
2068     default:
2069         OMAP_BAD_REG(addr);
2070     }
2071 }
2072
2073 static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2074     omap_badwidth_read32,
2075     omap_badwidth_read32,
2076     omap_mpui_read,
2077 };
2078
2079 static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2080     omap_badwidth_write32,
2081     omap_badwidth_write32,
2082     omap_mpui_write,
2083 };
2084
2085 static void omap_mpui_reset(struct omap_mpu_state_s *s)
2086 {
2087     s->mpui_ctrl = 0x0003ff1b;
2088 }
2089
2090 static void omap_mpui_init(target_phys_addr_t base,
2091                 struct omap_mpu_state_s *mpu)
2092 {
2093     int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2094                     omap_mpui_writefn, mpu);
2095
2096     mpu->mpui_base = base;
2097     cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2098
2099     omap_mpui_reset(mpu);
2100 }
2101
2102 /* TIPB Bridges */
2103 struct omap_tipb_bridge_s {
2104     target_phys_addr_t base;
2105     qemu_irq abort;
2106
2107     int width_intr;
2108     uint16_t control;
2109     uint16_t alloc;
2110     uint16_t buffer;
2111     uint16_t enh_control;
2112 };
2113
2114 static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
2115 {
2116     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2117     int offset = addr - s->base;
2118
2119     switch (offset) {
2120     case 0x00:  /* TIPB_CNTL */
2121         return s->control;
2122     case 0x04:  /* TIPB_BUS_ALLOC */
2123         return s->alloc;
2124     case 0x08:  /* MPU_TIPB_CNTL */
2125         return s->buffer;
2126     case 0x0c:  /* ENHANCED_TIPB_CNTL */
2127         return s->enh_control;
2128     case 0x10:  /* ADDRESS_DBG */
2129     case 0x14:  /* DATA_DEBUG_LOW */
2130     case 0x18:  /* DATA_DEBUG_HIGH */
2131         return 0xffff;
2132     case 0x1c:  /* DEBUG_CNTR_SIG */
2133         return 0x00f8;
2134     }
2135
2136     OMAP_BAD_REG(addr);
2137     return 0;
2138 }
2139
2140 static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
2141                 uint32_t value)
2142 {
2143     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2144     int offset = addr - s->base;
2145
2146     switch (offset) {
2147     case 0x00:  /* TIPB_CNTL */
2148         s->control = value & 0xffff;
2149         break;
2150
2151     case 0x04:  /* TIPB_BUS_ALLOC */
2152         s->alloc = value & 0x003f;
2153         break;
2154
2155     case 0x08:  /* MPU_TIPB_CNTL */
2156         s->buffer = value & 0x0003;
2157         break;
2158
2159     case 0x0c:  /* ENHANCED_TIPB_CNTL */
2160         s->width_intr = !(value & 2);
2161         s->enh_control = value & 0x000f;
2162         break;
2163
2164     case 0x10:  /* ADDRESS_DBG */
2165     case 0x14:  /* DATA_DEBUG_LOW */
2166     case 0x18:  /* DATA_DEBUG_HIGH */
2167     case 0x1c:  /* DEBUG_CNTR_SIG */
2168         OMAP_RO_REG(addr);
2169         break;
2170
2171     default:
2172         OMAP_BAD_REG(addr);
2173     }
2174 }
2175
2176 static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2177     omap_badwidth_read16,
2178     omap_tipb_bridge_read,
2179     omap_tipb_bridge_read,
2180 };
2181
2182 static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2183     omap_badwidth_write16,
2184     omap_tipb_bridge_write,
2185     omap_tipb_bridge_write,
2186 };
2187
2188 static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2189 {
2190     s->control = 0xffff;
2191     s->alloc = 0x0009;
2192     s->buffer = 0x0000;
2193     s->enh_control = 0x000f;
2194 }
2195
2196 struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2197                 qemu_irq abort_irq, omap_clk clk)
2198 {
2199     int iomemtype;
2200     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2201             qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2202
2203     s->abort = abort_irq;
2204     s->base = base;
2205     omap_tipb_bridge_reset(s);
2206
2207     iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
2208                     omap_tipb_bridge_writefn, s);
2209     cpu_register_physical_memory(s->base, 0x100, iomemtype);
2210
2211     return s;
2212 }
2213
2214 /* Dummy Traffic Controller's Memory Interface */
2215 static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2216 {
2217     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2218     int offset = addr - s->tcmi_base;
2219     uint32_t ret;
2220
2221     switch (offset) {
2222     case 0x00:  /* IMIF_PRIO */
2223     case 0x04:  /* EMIFS_PRIO */
2224     case 0x08:  /* EMIFF_PRIO */
2225     case 0x0c:  /* EMIFS_CONFIG */
2226     case 0x10:  /* EMIFS_CS0_CONFIG */
2227     case 0x14:  /* EMIFS_CS1_CONFIG */
2228     case 0x18:  /* EMIFS_CS2_CONFIG */
2229     case 0x1c:  /* EMIFS_CS3_CONFIG */
2230     case 0x24:  /* EMIFF_MRS */
2231     case 0x28:  /* TIMEOUT1 */
2232     case 0x2c:  /* TIMEOUT2 */
2233     case 0x30:  /* TIMEOUT3 */
2234     case 0x3c:  /* EMIFF_SDRAM_CONFIG_2 */
2235     case 0x40:  /* EMIFS_CFG_DYN_WAIT */
2236         return s->tcmi_regs[offset >> 2];
2237
2238     case 0x20:  /* EMIFF_SDRAM_CONFIG */
2239         ret = s->tcmi_regs[offset >> 2];
2240         s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2241         /* XXX: We can try using the VGA_DIRTY flag for this */
2242         return ret;
2243     }
2244
2245     OMAP_BAD_REG(addr);
2246     return 0;
2247 }
2248
2249 static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2250                 uint32_t value)
2251 {
2252     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2253     int offset = addr - s->tcmi_base;
2254
2255     switch (offset) {
2256     case 0x00:  /* IMIF_PRIO */
2257     case 0x04:  /* EMIFS_PRIO */
2258     case 0x08:  /* EMIFF_PRIO */
2259     case 0x10:  /* EMIFS_CS0_CONFIG */
2260     case 0x14:  /* EMIFS_CS1_CONFIG */
2261     case 0x18:  /* EMIFS_CS2_CONFIG */
2262     case 0x1c:  /* EMIFS_CS3_CONFIG */
2263     case 0x20:  /* EMIFF_SDRAM_CONFIG */
2264     case 0x24:  /* EMIFF_MRS */
2265     case 0x28:  /* TIMEOUT1 */
2266     case 0x2c:  /* TIMEOUT2 */
2267     case 0x30:  /* TIMEOUT3 */
2268     case 0x3c:  /* EMIFF_SDRAM_CONFIG_2 */
2269     case 0x40:  /* EMIFS_CFG_DYN_WAIT */
2270         s->tcmi_regs[offset >> 2] = value;
2271         break;
2272     case 0x0c:  /* EMIFS_CONFIG */
2273         s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
2274         break;
2275
2276     default:
2277         OMAP_BAD_REG(addr);
2278     }
2279 }
2280
2281 static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2282     omap_badwidth_read32,
2283     omap_badwidth_read32,
2284     omap_tcmi_read,
2285 };
2286
2287 static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2288     omap_badwidth_write32,
2289     omap_badwidth_write32,
2290     omap_tcmi_write,
2291 };
2292
2293 static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
2294 {
2295     mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
2296     mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
2297     mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
2298     mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
2299     mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
2300     mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
2301     mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
2302     mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
2303     mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
2304     mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
2305     mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
2306     mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
2307     mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
2308     mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
2309     mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
2310 }
2311
2312 static void omap_tcmi_init(target_phys_addr_t base,
2313                 struct omap_mpu_state_s *mpu)
2314 {
2315     int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2316                     omap_tcmi_writefn, mpu);
2317
2318     mpu->tcmi_base = base;
2319     cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2320     omap_tcmi_reset(mpu);
2321 }
2322
2323 /* Digital phase-locked loops control */
2324 static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2325 {
2326     struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2327     int offset = addr - s->base;
2328
2329     if (offset == 0x00) /* CTL_REG */
2330         return s->mode;
2331
2332     OMAP_BAD_REG(addr);
2333     return 0;
2334 }
2335
2336 static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2337                 uint32_t value)
2338 {
2339     struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2340     uint16_t diff;
2341     int offset = addr - s->base;
2342     static const int bypass_div[4] = { 1, 2, 4, 4 };
2343     int div, mult;
2344
2345     if (offset == 0x00) {       /* CTL_REG */
2346         /* See omap_ulpd_pm_write() too */
2347         diff = s->mode & value;
2348         s->mode = value & 0x2fff;
2349         if (diff & (0x3ff << 2)) {
2350             if (value & (1 << 4)) {                     /* PLL_ENABLE */
2351                 div = ((value >> 5) & 3) + 1;           /* PLL_DIV */
2352                 mult = MIN((value >> 7) & 0x1f, 1);     /* PLL_MULT */
2353             } else {
2354                 div = bypass_div[((value >> 2) & 3)];   /* BYPASS_DIV */
2355                 mult = 1;
2356             }
2357             omap_clk_setrate(s->dpll, div, mult);
2358         }
2359
2360         /* Enter the desired mode.  */
2361         s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
2362
2363         /* Act as if the lock is restored.  */
2364         s->mode |= 2;
2365     } else {
2366         OMAP_BAD_REG(addr);
2367     }
2368 }
2369
2370 static CPUReadMemoryFunc *omap_dpll_readfn[] = {
2371     omap_badwidth_read16,
2372     omap_dpll_read,
2373     omap_badwidth_read16,
2374 };
2375
2376 static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
2377     omap_badwidth_write16,
2378     omap_dpll_write,
2379     omap_badwidth_write16,
2380 };
2381
2382 static void omap_dpll_reset(struct dpll_ctl_s *s)
2383 {
2384     s->mode = 0x2002;
2385     omap_clk_setrate(s->dpll, 1, 1);
2386 }
2387
2388 static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
2389                 omap_clk clk)
2390 {
2391     int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
2392                     omap_dpll_writefn, s);
2393
2394     s->base = base;
2395     s->dpll = clk;
2396     omap_dpll_reset(s);
2397
2398     cpu_register_physical_memory(s->base, 0x100, iomemtype);
2399 }
2400
2401 /* UARTs */
2402 struct omap_uart_s {
2403     SerialState *serial; /* TODO */
2404 };
2405
2406 static void omap_uart_reset(struct omap_uart_s *s)
2407 {
2408 }
2409
2410 struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2411                 qemu_irq irq, omap_clk clk, CharDriverState *chr)
2412 {
2413     struct omap_uart_s *s = (struct omap_uart_s *)
2414             qemu_mallocz(sizeof(struct omap_uart_s));
2415     if (chr)
2416         s->serial = serial_mm_init(base, 2, irq, chr, 1);
2417     return s;
2418 }
2419
2420 /* MPU Clock/Reset/Power Mode Control */
2421 static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2422 {
2423     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2424     int offset = addr - s->clkm.mpu_base;
2425
2426     switch (offset) {
2427     case 0x00:  /* ARM_CKCTL */
2428         return s->clkm.arm_ckctl;
2429
2430     case 0x04:  /* ARM_IDLECT1 */
2431         return s->clkm.arm_idlect1;
2432
2433     case 0x08:  /* ARM_IDLECT2 */
2434         return s->clkm.arm_idlect2;
2435
2436     case 0x0c:  /* ARM_EWUPCT */
2437         return s->clkm.arm_ewupct;
2438
2439     case 0x10:  /* ARM_RSTCT1 */
2440         return s->clkm.arm_rstct1;
2441
2442     case 0x14:  /* ARM_RSTCT2 */
2443         return s->clkm.arm_rstct2;
2444
2445     case 0x18:  /* ARM_SYSST */
2446         return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
2447
2448     case 0x1c:  /* ARM_CKOUT1 */
2449         return s->clkm.arm_ckout1;
2450
2451     case 0x20:  /* ARM_CKOUT2 */
2452         break;
2453     }
2454
2455     OMAP_BAD_REG(addr);
2456     return 0;
2457 }
2458
2459 static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2460                 uint16_t diff, uint16_t value)
2461 {
2462     omap_clk clk;
2463
2464     if (diff & (1 << 14)) {                             /* ARM_INTHCK_SEL */
2465         if (value & (1 << 14))
2466             /* Reserved */;
2467         else {
2468             clk = omap_findclk(s, "arminth_ck");
2469             omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2470         }
2471     }
2472     if (diff & (1 << 12)) {                             /* ARM_TIMXO */
2473         clk = omap_findclk(s, "armtim_ck");
2474         if (value & (1 << 12))
2475             omap_clk_reparent(clk, omap_findclk(s, "clkin"));
2476         else
2477             omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2478     }
2479     /* XXX: en_dspck */
2480     if (diff & (3 << 10)) {                             /* DSPMMUDIV */
2481         clk = omap_findclk(s, "dspmmu_ck");
2482         omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
2483     }
2484     if (diff & (3 << 8)) {                              /* TCDIV */
2485         clk = omap_findclk(s, "tc_ck");
2486         omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2487     }
2488     if (diff & (3 << 6)) {                              /* DSPDIV */
2489         clk = omap_findclk(s, "dsp_ck");
2490         omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2491     }
2492     if (diff & (3 << 4)) {                              /* ARMDIV */
2493         clk = omap_findclk(s, "arm_ck");
2494         omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2495     }
2496     if (diff & (3 << 2)) {                              /* LCDDIV */
2497         clk = omap_findclk(s, "lcd_ck");
2498         omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2499     }
2500     if (diff & (3 << 0)) {                              /* PERDIV */
2501         clk = omap_findclk(s, "armper_ck");
2502         omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2503     }
2504 }
2505
2506 static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2507                 uint16_t diff, uint16_t value)
2508 {
2509     omap_clk clk;
2510
2511     if (value & (1 << 11))                              /* SETARM_IDLE */
2512         cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2513     if (!(value & (1 << 10)))                           /* WKUP_MODE */
2514         qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */
2515
2516 #define SET_CANIDLE(clock, bit)                         \
2517     if (diff & (1 << bit)) {                            \
2518         clk = omap_findclk(s, clock);                   \
2519         omap_clk_canidle(clk, (value >> bit) & 1);      \
2520     }
2521     SET_CANIDLE("mpuwd_ck", 0)                          /* IDLWDT_ARM */
2522     SET_CANIDLE("armxor_ck", 1)                         /* IDLXORP_ARM */
2523     SET_CANIDLE("mpuper_ck", 2)                         /* IDLPER_ARM */
2524     SET_CANIDLE("lcd_ck", 3)                            /* IDLLCD_ARM */
2525     SET_CANIDLE("lb_ck", 4)                             /* IDLLB_ARM */
2526     SET_CANIDLE("hsab_ck", 5)                           /* IDLHSAB_ARM */
2527     SET_CANIDLE("tipb_ck", 6)                           /* IDLIF_ARM */
2528     SET_CANIDLE("dma_ck", 6)                            /* IDLIF_ARM */
2529     SET_CANIDLE("tc_ck", 6)                             /* IDLIF_ARM */
2530     SET_CANIDLE("dpll1", 7)                             /* IDLDPLL_ARM */
2531     SET_CANIDLE("dpll2", 7)                             /* IDLDPLL_ARM */
2532     SET_CANIDLE("dpll3", 7)                             /* IDLDPLL_ARM */
2533     SET_CANIDLE("mpui_ck", 8)                           /* IDLAPI_ARM */
2534     SET_CANIDLE("armtim_ck", 9)                         /* IDLTIM_ARM */
2535 }
2536
2537 static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2538                 uint16_t diff, uint16_t value)
2539 {
2540     omap_clk clk;
2541
2542 #define SET_ONOFF(clock, bit)                           \
2543     if (diff & (1 << bit)) {                            \
2544         clk = omap_findclk(s, clock);                   \
2545         omap_clk_onoff(clk, (value >> bit) & 1);        \
2546     }
2547     SET_ONOFF("mpuwd_ck", 0)                            /* EN_WDTCK */
2548     SET_ONOFF("armxor_ck", 1)                           /* EN_XORPCK */
2549     SET_ONOFF("mpuper_ck", 2)                           /* EN_PERCK */
2550     SET_ONOFF("lcd_ck", 3)                              /* EN_LCDCK */
2551     SET_ONOFF("lb_ck", 4)                               /* EN_LBCK */
2552     SET_ONOFF("hsab_ck", 5)                             /* EN_HSABCK */
2553     SET_ONOFF("mpui_ck", 6)                             /* EN_APICK */
2554     SET_ONOFF("armtim_ck", 7)                           /* EN_TIMCK */
2555     SET_CANIDLE("dma_ck", 8)                            /* DMACK_REQ */
2556     SET_ONOFF("arm_gpio_ck", 9)                         /* EN_GPIOCK */
2557     SET_ONOFF("lbfree_ck", 10)                          /* EN_LBFREECK */
2558 }
2559
2560 static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2561                 uint16_t diff, uint16_t value)
2562 {
2563     omap_clk clk;
2564
2565     if (diff & (3 << 4)) {                              /* TCLKOUT */
2566         clk = omap_findclk(s, "tclk_out");
2567         switch ((value >> 4) & 3) {
2568         case 1:
2569             omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
2570             omap_clk_onoff(clk, 1);
2571             break;
2572         case 2:
2573             omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2574             omap_clk_onoff(clk, 1);
2575             break;
2576         default:
2577             omap_clk_onoff(clk, 0);
2578         }
2579     }
2580     if (diff & (3 << 2)) {                              /* DCLKOUT */
2581         clk = omap_findclk(s, "dclk_out");
2582         switch ((value >> 2) & 3) {
2583         case 0:
2584             omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
2585             break;
2586         case 1:
2587             omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
2588             break;
2589         case 2:
2590             omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
2591             break;
2592         case 3:
2593             omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2594             break;
2595         }
2596     }
2597     if (diff & (3 << 0)) {                              /* ACLKOUT */
2598         clk = omap_findclk(s, "aclk_out");
2599         switch ((value >> 0) & 3) {
2600         case 1:
2601             omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2602             omap_clk_onoff(clk, 1);
2603             break;
2604         case 2:
2605             omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
2606             omap_clk_onoff(clk, 1);
2607             break;
2608         case 3:
2609             omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2610             omap_clk_onoff(clk, 1);
2611             break;
2612         default:
2613             omap_clk_onoff(clk, 0);
2614         }
2615     }
2616 }
2617
2618 static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2619                 uint32_t value)
2620 {
2621     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2622     int offset = addr - s->clkm.mpu_base;
2623     uint16_t diff;
2624     omap_clk clk;
2625     static const char *clkschemename[8] = {
2626         "fully synchronous", "fully asynchronous", "synchronous scalable",
2627         "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2628     };
2629
2630     switch (offset) {
2631     case 0x00:  /* ARM_CKCTL */
2632         diff = s->clkm.arm_ckctl ^ value;
2633         s->clkm.arm_ckctl = value & 0x7fff;
2634         omap_clkm_ckctl_update(s, diff, value);
2635         return;
2636
2637     case 0x04:  /* ARM_IDLECT1 */
2638         diff = s->clkm.arm_idlect1 ^ value;
2639         s->clkm.arm_idlect1 = value & 0x0fff;
2640         omap_clkm_idlect1_update(s, diff, value);
2641         return;
2642
2643     case 0x08:  /* ARM_IDLECT2 */
2644         diff = s->clkm.arm_idlect2 ^ value;
2645         s->clkm.arm_idlect2 = value & 0x07ff;
2646         omap_clkm_idlect2_update(s, diff, value);
2647         return;
2648
2649     case 0x0c:  /* ARM_EWUPCT */
2650         diff = s->clkm.arm_ewupct ^ value;
2651         s->clkm.arm_ewupct = value & 0x003f;
2652         return;
2653
2654     case 0x10:  /* ARM_RSTCT1 */
2655         diff = s->clkm.arm_rstct1 ^ value;
2656         s->clkm.arm_rstct1 = value & 0x0007;
2657         if (value & 9) {
2658             qemu_system_reset_request();
2659             s->clkm.cold_start = 0xa;
2660         }
2661         if (diff & ~value & 4) {                                /* DSP_RST */
2662             omap_mpui_reset(s);
2663             omap_tipb_bridge_reset(s->private_tipb);
2664             omap_tipb_bridge_reset(s->public_tipb);
2665         }
2666         if (diff & 2) {                                         /* DSP_EN */
2667             clk = omap_findclk(s, "dsp_ck");
2668             omap_clk_canidle(clk, (~value >> 1) & 1);
2669         }
2670         return;
2671
2672     case 0x14:  /* ARM_RSTCT2 */
2673         s->clkm.arm_rstct2 = value & 0x0001;
2674         return;
2675
2676     case 0x18:  /* ARM_SYSST */
2677         if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2678             s->clkm.clocking_scheme = (value >> 11) & 7;
2679             printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2680                             clkschemename[s->clkm.clocking_scheme]);
2681         }
2682         s->clkm.cold_start &= value & 0x3f;
2683         return;
2684
2685     case 0x1c:  /* ARM_CKOUT1 */
2686         diff = s->clkm.arm_ckout1 ^ value;
2687         s->clkm.arm_ckout1 = value & 0x003f;
2688         omap_clkm_ckout1_update(s, diff, value);
2689         return;
2690
2691     case 0x20:  /* ARM_CKOUT2 */
2692     default:
2693         OMAP_BAD_REG(addr);
2694     }
2695 }
2696
2697 static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2698     omap_badwidth_read16,
2699     omap_clkm_read,
2700     omap_badwidth_read16,
2701 };
2702
2703 static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2704     omap_badwidth_write16,
2705     omap_clkm_write,
2706     omap_badwidth_write16,
2707 };
2708
2709 static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2710 {
2711     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2712     int offset = addr - s->clkm.dsp_base;
2713
2714     switch (offset) {
2715     case 0x04:  /* DSP_IDLECT1 */
2716         return s->clkm.dsp_idlect1;
2717
2718     case 0x08:  /* DSP_IDLECT2 */
2719         return s->clkm.dsp_idlect2;
2720
2721     case 0x14:  /* DSP_RSTCT2 */
2722         return s->clkm.dsp_rstct2;
2723
2724     case 0x18:  /* DSP_SYSST */
2725         return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
2726                 (s->env->halted << 6);  /* Quite useless... */
2727     }
2728
2729     OMAP_BAD_REG(addr);
2730     return 0;
2731 }
2732
2733 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2734                 uint16_t diff, uint16_t value)
2735 {
2736     omap_clk clk;
2737
2738     SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2739 }
2740
2741 static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2742                 uint16_t diff, uint16_t value)
2743 {
2744     omap_clk clk;
2745
2746     SET_ONOFF("dspxor_ck", 1);                          /* EN_XORPCK */
2747 }
2748
2749 static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2750                 uint32_t value)
2751 {
2752     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2753     int offset = addr - s->clkm.dsp_base;
2754     uint16_t diff;
2755
2756     switch (offset) {
2757     case 0x04:  /* DSP_IDLECT1 */
2758         diff = s->clkm.dsp_idlect1 ^ value;
2759         s->clkm.dsp_idlect1 = value & 0x01f7;
2760         omap_clkdsp_idlect1_update(s, diff, value);
2761         break;
2762
2763     case 0x08:  /* DSP_IDLECT2 */
2764         s->clkm.dsp_idlect2 = value & 0x0037;
2765         diff = s->clkm.dsp_idlect1 ^ value;
2766         omap_clkdsp_idlect2_update(s, diff, value);
2767         break;
2768
2769     case 0x14:  /* DSP_RSTCT2 */
2770         s->clkm.dsp_rstct2 = value & 0x0001;
2771         break;
2772
2773     case 0x18:  /* DSP_SYSST */
2774         s->clkm.cold_start &= value & 0x3f;
2775         break;
2776
2777     default:
2778         OMAP_BAD_REG(addr);
2779     }
2780 }
2781
2782 static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2783     omap_badwidth_read16,
2784     omap_clkdsp_read,
2785     omap_badwidth_read16,
2786 };
2787
2788 static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2789     omap_badwidth_write16,
2790     omap_clkdsp_write,
2791     omap_badwidth_write16,
2792 };
2793
2794 static void omap_clkm_reset(struct omap_mpu_state_s *s)
2795 {
2796     if (s->wdt && s->wdt->reset)
2797         s->clkm.cold_start = 0x6;
2798     s->clkm.clocking_scheme = 0;
2799     omap_clkm_ckctl_update(s, ~0, 0x3000);
2800     s->clkm.arm_ckctl = 0x3000;
2801     omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
2802     s->clkm.arm_idlect1 = 0x0400;
2803     omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
2804     s->clkm.arm_idlect2 = 0x0100;
2805     s->clkm.arm_ewupct = 0x003f;
2806     s->clkm.arm_rstct1 = 0x0000;
2807     s->clkm.arm_rstct2 = 0x0000;
2808     s->clkm.arm_ckout1 = 0x0015;
2809     s->clkm.dpll1_mode = 0x2002;
2810     omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2811     s->clkm.dsp_idlect1 = 0x0040;
2812     omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2813     s->clkm.dsp_idlect2 = 0x0000;
2814     s->clkm.dsp_rstct2 = 0x0000;
2815 }
2816
2817 static void omap_clkm_init(target_phys_addr_t mpu_base,
2818                 target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2819 {
2820     int iomemtype[2] = {
2821         cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2822         cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2823     };
2824
2825     s->clkm.mpu_base = mpu_base;
2826     s->clkm.dsp_base = dsp_base;
2827     s->clkm.arm_idlect1 = 0x03ff;
2828     s->clkm.arm_idlect2 = 0x0100;
2829     s->clkm.dsp_idlect1 = 0x0002;
2830     omap_clkm_reset(s);
2831     s->clkm.cold_start = 0x3a;
2832
2833     cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2834     cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2835 }
2836
2837 /* MPU I/O */
2838 struct omap_mpuio_s {
2839     target_phys_addr_t base;
2840     qemu_irq irq;
2841     qemu_irq kbd_irq;
2842     qemu_irq *in;
2843     qemu_irq handler[16];
2844     qemu_irq wakeup;
2845
2846     uint16_t inputs;
2847     uint16_t outputs;
2848     uint16_t dir;
2849     uint16_t edge;
2850     uint16_t mask;
2851     uint16_t ints;
2852
2853     uint16_t debounce;
2854     uint16_t latch;
2855     uint8_t event;
2856
2857     uint8_t buttons[5];
2858     uint8_t row_latch;
2859     uint8_t cols;
2860     int kbd_mask;
2861     int clk;
2862 };
2863
2864 static void omap_mpuio_set(void *opaque, int line, int level)
2865 {
2866     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2867     uint16_t prev = s->inputs;
2868
2869     if (level)
2870         s->inputs |= 1 << line;
2871     else
2872         s->inputs &= ~(1 << line);
2873
2874     if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2875         if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2876             s->ints |= 1 << line;
2877             qemu_irq_raise(s->irq);
2878             /* TODO: wakeup */
2879         }
2880         if ((s->event & (1 << 0)) &&            /* SET_GPIO_EVENT_MODE */
2881                 (s->event >> 1) == line)        /* PIN_SELECT */
2882             s->latch = s->inputs;
2883     }
2884 }
2885
2886 static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2887 {
2888     int i;
2889     uint8_t *row, rows = 0, cols = ~s->cols;
2890
2891     for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2892         if (*row & cols)
2893             rows |= i;
2894
2895     qemu_set_irq(s->kbd_irq, rows && ~s->kbd_mask && s->clk);
2896     s->row_latch = rows ^ 0x1f;
2897 }
2898
2899 static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2900 {
2901     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2902     int offset = addr & OMAP_MPUI_REG_MASK;
2903     uint16_t ret;
2904
2905     switch (offset) {
2906     case 0x00:  /* INPUT_LATCH */
2907         return s->inputs;
2908
2909     case 0x04:  /* OUTPUT_REG */
2910         return s->outputs;
2911
2912     case 0x08:  /* IO_CNTL */
2913         return s->dir;
2914
2915     case 0x10:  /* KBR_LATCH */
2916         return s->row_latch;
2917
2918     case 0x14:  /* KBC_REG */
2919         return s->cols;
2920
2921     case 0x18:  /* GPIO_EVENT_MODE_REG */
2922         return s->event;
2923
2924     case 0x1c:  /* GPIO_INT_EDGE_REG */
2925         return s->edge;
2926
2927     case 0x20:  /* KBD_INT */
2928         return (s->row_latch != 0x1f) && !s->kbd_mask;
2929
2930     case 0x24:  /* GPIO_INT */
2931         ret = s->ints;
2932         s->ints &= s->mask;
2933         if (ret)
2934             qemu_irq_lower(s->irq);
2935         return ret;
2936
2937     case 0x28:  /* KBD_MASKIT */
2938         return s->kbd_mask;
2939
2940     case 0x2c:  /* GPIO_MASKIT */
2941         return s->mask;
2942
2943     case 0x30:  /* GPIO_DEBOUNCING_REG */
2944         return s->debounce;
2945
2946     case 0x34:  /* GPIO_LATCH_REG */
2947         return s->latch;
2948     }
2949
2950     OMAP_BAD_REG(addr);
2951     return 0;
2952 }
2953
2954 static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2955                 uint32_t value)
2956 {
2957     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2958     int offset = addr & OMAP_MPUI_REG_MASK;
2959     uint16_t diff;
2960     int ln;
2961
2962     switch (offset) {
2963     case 0x04:  /* OUTPUT_REG */
2964         diff = (s->outputs ^ value) & ~s->dir;
2965         s->outputs = value;
2966         while ((ln = ffs(diff))) {
2967             ln --;
2968             if (s->handler[ln])
2969                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2970             diff &= ~(1 << ln);
2971         }
2972         break;
2973
2974     case 0x08:  /* IO_CNTL */
2975         diff = s->outputs & (s->dir ^ value);
2976         s->dir = value;
2977
2978         value = s->outputs & ~s->dir;
2979         while ((ln = ffs(diff))) {
2980             ln --;
2981             if (s->handler[ln])
2982                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2983             diff &= ~(1 << ln);
2984         }
2985         break;
2986
2987     case 0x14:  /* KBC_REG */
2988         s->cols = value;
2989         omap_mpuio_kbd_update(s);
2990         break;
2991
2992     case 0x18:  /* GPIO_EVENT_MODE_REG */
2993         s->event = value & 0x1f;
2994         break;
2995
2996     case 0x1c:  /* GPIO_INT_EDGE_REG */
2997         s->edge = value;
2998         break;
2999
3000     case 0x28:  /* KBD_MASKIT */
3001         s->kbd_mask = value & 1;
3002         omap_mpuio_kbd_update(s);
3003         break;
3004
3005     case 0x2c:  /* GPIO_MASKIT */
3006         s->mask = value;
3007         break;
3008
3009     case 0x30:  /* GPIO_DEBOUNCING_REG */
3010         s->debounce = value & 0x1ff;
3011         break;
3012
3013     case 0x00:  /* INPUT_LATCH */
3014     case 0x10:  /* KBR_LATCH */
3015     case 0x20:  /* KBD_INT */
3016     case 0x24:  /* GPIO_INT */
3017     case 0x34:  /* GPIO_LATCH_REG */
3018         OMAP_RO_REG(addr);
3019         return;
3020
3021     default:
3022         OMAP_BAD_REG(addr);
3023         return;
3024     }
3025 }
3026
3027 static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
3028     omap_badwidth_read16,
3029     omap_mpuio_read,
3030     omap_badwidth_read16,
3031 };
3032
3033 static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
3034     omap_badwidth_write16,
3035     omap_mpuio_write,
3036     omap_badwidth_write16,
3037 };
3038
3039 void omap_mpuio_reset(struct omap_mpuio_s *s)
3040 {
3041     s->inputs = 0;
3042     s->outputs = 0;
3043     s->dir = ~0;
3044     s->event = 0;
3045     s->edge = 0;
3046     s->kbd_mask = 0;
3047     s->mask = 0;
3048     s->debounce = 0;
3049     s->latch = 0;
3050     s->ints = 0;
3051     s->row_latch = 0x1f;
3052     s->clk = 1;
3053 }
3054
3055 static void omap_mpuio_onoff(void *opaque, int line, int on)
3056 {
3057     struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3058
3059     s->clk = on;
3060     if (on)
3061         omap_mpuio_kbd_update(s);
3062 }
3063
3064 struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
3065                 qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
3066                 omap_clk clk)
3067 {
3068     int iomemtype;
3069     struct omap_mpuio_s *s = (struct omap_mpuio_s *)
3070             qemu_mallocz(sizeof(struct omap_mpuio_s));
3071
3072     s->base = base;
3073     s->irq = gpio_int;
3074     s->kbd_irq = kbd_int;
3075     s->wakeup = wakeup;
3076     s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
3077     omap_mpuio_reset(s);
3078
3079     iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
3080                     omap_mpuio_writefn, s);
3081     cpu_register_physical_memory(s->base, 0x800, iomemtype);
3082
3083     omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
3084
3085     return s;
3086 }
3087
3088 qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
3089 {
3090     return s->in;
3091 }
3092
3093 void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
3094 {
3095     if (line >= 16 || line < 0)
3096         cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3097     s->handler[line] = handler;
3098 }
3099
3100 void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
3101 {
3102     if (row >= 5 || row < 0)
3103         cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
3104                         __FUNCTION__, col, row);
3105
3106     if (down)
3107         s->buttons[row] |= 1 << col;
3108     else
3109         s->buttons[row] &= ~(1 << col);
3110
3111     omap_mpuio_kbd_update(s);
3112 }
3113
3114 /* General-Purpose I/O */
3115 struct omap_gpio_s {
3116     target_phys_addr_t base;
3117     qemu_irq irq;
3118     qemu_irq *in;
3119     qemu_irq handler[16];
3120
3121     uint16_t inputs;
3122     uint16_t outputs;
3123     uint16_t dir;
3124     uint16_t edge;
3125     uint16_t mask;
3126     uint16_t ints;
3127     uint16_t pins;
3128 };
3129
3130 static void omap_gpio_set(void *opaque, int line, int level)
3131 {
3132     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3133     uint16_t prev = s->inputs;
3134
3135     if (level)
3136         s->inputs |= 1 << line;
3137     else
3138         s->inputs &= ~(1 << line);
3139
3140     if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
3141                     (1 << line) & s->dir & ~s->mask) {
3142         s->ints |= 1 << line;
3143         qemu_irq_raise(s->irq);
3144     }
3145 }
3146
3147 static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
3148 {
3149     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3150     int offset = addr & OMAP_MPUI_REG_MASK;
3151
3152     switch (offset) {
3153     case 0x00:  /* DATA_INPUT */
3154         return s->inputs & s->pins;
3155
3156     case 0x04:  /* DATA_OUTPUT */
3157         return s->outputs;
3158
3159     case 0x08:  /* DIRECTION_CONTROL */
3160         return s->dir;
3161
3162     case 0x0c:  /* INTERRUPT_CONTROL */
3163         return s->edge;
3164
3165     case 0x10:  /* INTERRUPT_MASK */
3166         return s->mask;
3167
3168     case 0x14:  /* INTERRUPT_STATUS */
3169         return s->ints;
3170
3171     case 0x18:  /* PIN_CONTROL (not in OMAP310) */
3172         OMAP_BAD_REG(addr);
3173         return s->pins;
3174     }
3175
3176     OMAP_BAD_REG(addr);
3177     return 0;
3178 }
3179
3180 static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
3181                 uint32_t value)
3182 {
3183     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3184     int offset = addr & OMAP_MPUI_REG_MASK;
3185     uint16_t diff;
3186     int ln;
3187
3188     switch (offset) {
3189     case 0x00:  /* DATA_INPUT */
3190         OMAP_RO_REG(addr);
3191         return;
3192
3193     case 0x04:  /* DATA_OUTPUT */
3194         diff = (s->outputs ^ value) & ~s->dir;
3195         s->outputs = value;
3196         while ((ln = ffs(diff))) {
3197             ln --;
3198             if (s->handler[ln])
3199                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3200             diff &= ~(1 << ln);
3201         }
3202         break;
3203
3204     case 0x08:  /* DIRECTION_CONTROL */
3205         diff = s->outputs & (s->dir ^ value);
3206         s->dir = value;
3207
3208         value = s->outputs & ~s->dir;
3209         while ((ln = ffs(diff))) {
3210             ln --;
3211             if (s->handler[ln])
3212                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3213             diff &= ~(1 << ln);
3214         }
3215         break;
3216
3217     case 0x0c:  /* INTERRUPT_CONTROL */
3218         s->edge = value;
3219         break;
3220
3221     case 0x10:  /* INTERRUPT_MASK */
3222         s->mask = value;
3223         break;
3224
3225     case 0x14:  /* INTERRUPT_STATUS */
3226         s->ints &= ~value;
3227         if (!s->ints)
3228             qemu_irq_lower(s->irq);
3229         break;
3230
3231     case 0x18:  /* PIN_CONTROL (not in OMAP310 TRM) */
3232         OMAP_BAD_REG(addr);
3233         s->pins = value;
3234         break;
3235
3236     default:
3237         OMAP_BAD_REG(addr);
3238         return;
3239     }
3240 }
3241
3242 /* *Some* sources say the memory region is 32-bit.  */
3243 static CPUReadMemoryFunc *omap_gpio_readfn[] = {
3244     omap_badwidth_read16,
3245     omap_gpio_read,
3246     omap_badwidth_read16,
3247 };
3248
3249 static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
3250     omap_badwidth_write16,
3251     omap_gpio_write,
3252     omap_badwidth_write16,
3253 };
3254
3255 void omap_gpio_reset(struct omap_gpio_s *s)
3256 {
3257     s->inputs = 0;
3258     s->outputs = ~0;
3259     s->dir = ~0;
3260     s->edge = ~0;
3261     s->mask = ~0;
3262     s->ints = 0;
3263     s->pins = ~0;
3264 }
3265
3266 struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
3267                 qemu_irq irq, omap_clk clk)
3268 {
3269     int iomemtype;
3270     struct omap_gpio_s *s = (struct omap_gpio_s *)
3271             qemu_mallocz(sizeof(struct omap_gpio_s));
3272
3273     s->base = base;
3274     s->irq = irq;
3275     s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
3276     omap_gpio_reset(s);
3277
3278     iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
3279                     omap_gpio_writefn, s);
3280     cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3281
3282     return s;
3283 }
3284
3285 qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
3286 {
3287     return s->in;
3288 }
3289
3290 void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3291 {
3292     if (line >= 16 || line < 0)
3293         cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3294     s->handler[line] = handler;
3295 }
3296
3297 /* MicroWire Interface */
3298 struct omap_uwire_s {
3299     target_phys_addr_t base;
3300     qemu_irq txirq;
3301     qemu_irq rxirq;
3302     qemu_irq txdrq;
3303
3304     uint16_t txbuf;
3305     uint16_t rxbuf;
3306     uint16_t control;
3307     uint16_t setup[5];
3308
3309     struct uwire_slave_s *chip[4];
3310 };
3311
3312 static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3313 {
3314     int chipselect = (s->control >> 10) & 3;            /* INDEX */
3315     struct uwire_slave_s *slave = s->chip[chipselect];
3316
3317     if ((s->control >> 5) & 0x1f) {                     /* NB_BITS_WR */
3318         if (s->control & (1 << 12))                     /* CS_CMD */
3319             if (slave && slave->send)
3320                 slave->send(slave->opaque,
3321                                 s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3322         s->control &= ~(1 << 14);                       /* CSRB */
3323         /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3324          * a DRQ.  When is the level IRQ supposed to be reset?  */
3325     }
3326
3327     if ((s->control >> 0) & 0x1f) {                     /* NB_BITS_RD */
3328         if (s->control & (1 << 12))                     /* CS_CMD */
3329             if (slave && slave->receive)
3330                 s->rxbuf = slave->receive(slave->opaque);
3331         s->control |= 1 << 15;                          /* RDRB */
3332         /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3333          * a DRQ.  When is the level IRQ supposed to be reset?  */
3334     }
3335 }
3336
3337 static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3338 {
3339     struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3340     int offset = addr & OMAP_MPUI_REG_MASK;
3341
3342     switch (offset) {
3343     case 0x00:  /* RDR */
3344         s->control &= ~(1 << 15);                       /* RDRB */
3345         return s->rxbuf;
3346
3347     case 0x04:  /* CSR */
3348         return s->control;
3349
3350     case 0x08:  /* SR1 */
3351         return s->setup[0];
3352     case 0x0c:  /* SR2 */
3353         return s->setup[1];
3354     case 0x10:  /* SR3 */
3355         return s->setup[2];
3356     case 0x14:  /* SR4 */
3357         return s->setup[3];
3358     case 0x18:  /* SR5 */
3359         return s->setup[4];
3360     }
3361
3362     OMAP_BAD_REG(addr);
3363     return 0;
3364 }
3365
3366 static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3367                 uint32_t value)
3368 {
3369     struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3370     int offset = addr & OMAP_MPUI_REG_MASK;
3371
3372     switch (offset) {
3373     case 0x00:  /* TDR */
3374         s->txbuf = value;                               /* TD */
3375         if ((s->setup[4] & (1 << 2)) &&                 /* AUTO_TX_EN */
3376                         ((s->setup[4] & (1 << 3)) ||    /* CS_TOGGLE_TX_EN */
3377                          (s->control & (1 << 12)))) {   /* CS_CMD */
3378             s->control |= 1 << 14;                      /* CSRB */
3379             omap_uwire_transfer_start(s);
3380         }
3381         break;
3382
3383     case 0x04:  /* CSR */
3384         s->control = value & 0x1fff;
3385         if (value & (1 << 13))                          /* START */
3386             omap_uwire_transfer_start(s);
3387         break;
3388
3389     case 0x08:  /* SR1 */
3390         s->setup[0] = value & 0x003f;
3391         break;
3392
3393     case 0x0c:  /* SR2 */
3394         s->setup[1] = value & 0x0fc0;
3395         break;
3396
3397     case 0x10:  /* SR3 */
3398         s->setup[2] = value & 0x0003;
3399         break;
3400
3401     case 0x14:  /* SR4 */
3402         s->setup[3] = value & 0x0001;
3403         break;
3404
3405     case 0x18:  /* SR5 */
3406         s->setup[4] = value & 0x000f;
3407         break;
3408
3409     default:
3410         OMAP_BAD_REG(addr);
3411         return;
3412     }
3413 }
3414
3415 static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3416     omap_badwidth_read16,
3417     omap_uwire_read,
3418     omap_badwidth_read16,
3419 };
3420
3421 static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3422     omap_badwidth_write16,
3423     omap_uwire_write,
3424     omap_badwidth_write16,
3425 };
3426
3427 void omap_uwire_reset(struct omap_uwire_s *s)
3428 {
3429     s->control = 0;
3430     s->setup[0] = 0;
3431     s->setup[1] = 0;
3432     s->setup[2] = 0;
3433     s->setup[3] = 0;
3434     s->setup[4] = 0;
3435 }
3436
3437 struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3438                 qemu_irq *irq, qemu_irq dma, omap_clk clk)
3439 {
3440     int iomemtype;
3441     struct omap_uwire_s *s = (struct omap_uwire_s *)
3442             qemu_mallocz(sizeof(struct omap_uwire_s));
3443
3444     s->base = base;
3445     s->txirq = irq[0];
3446     s->rxirq = irq[1];
3447     s->txdrq = dma;
3448     omap_uwire_reset(s);
3449
3450     iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3451                     omap_uwire_writefn, s);
3452     cpu_register_physical_memory(s->base, 0x800, iomemtype);
3453
3454     return s;
3455 }
3456
3457 void omap_uwire_attach(struct omap_uwire_s *s,
3458                 struct uwire_slave_s *slave, int chipselect)
3459 {
3460     if (chipselect < 0 || chipselect > 3)
3461         cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
3462                         chipselect);
3463
3464     s->chip[chipselect] = slave;
3465 }
3466
3467 /* Pseudonoise Pulse-Width Light Modulator */
3468 void omap_pwl_update(struct omap_mpu_state_s *s)
3469 {
3470     int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3471
3472     if (output != s->pwl.output) {
3473         s->pwl.output = output;
3474         printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3475     }
3476 }
3477
3478 static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3479 {
3480     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3481     int offset = addr & OMAP_MPUI_REG_MASK;
3482
3483     switch (offset) {
3484     case 0x00:  /* PWL_LEVEL */
3485         return s->pwl.level;
3486     case 0x04:  /* PWL_CTRL */
3487         return s->pwl.enable;
3488     }
3489     OMAP_BAD_REG(addr);
3490     return 0;
3491 }
3492
3493 static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3494                 uint32_t value)
3495 {
3496     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3497     int offset = addr & OMAP_MPUI_REG_MASK;
3498
3499     switch (offset) {
3500     case 0x00:  /* PWL_LEVEL */
3501         s->pwl.level = value;
3502         omap_pwl_update(s);
3503         break;
3504     case 0x04:  /* PWL_CTRL */
3505         s->pwl.enable = value & 1;
3506         omap_pwl_update(s);
3507         break;
3508     default:
3509         OMAP_BAD_REG(addr);
3510         return;
3511     }
3512 }
3513
3514 static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3515     omap_pwl_read,
3516     omap_badwidth_read8,
3517     omap_badwidth_read8,
3518 };
3519
3520 static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3521     omap_pwl_write,
3522     omap_badwidth_write8,
3523     omap_badwidth_write8,
3524 };
3525
3526 void omap_pwl_reset(struct omap_mpu_state_s *s)
3527 {
3528     s->pwl.output = 0;
3529     s->pwl.level = 0;
3530     s->pwl.enable = 0;
3531     s->pwl.clk = 1;
3532     omap_pwl_update(s);
3533 }
3534
3535 static void omap_pwl_clk_update(void *opaque, int line, int on)
3536 {
3537     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3538
3539     s->pwl.clk = on;
3540     omap_pwl_update(s);
3541 }
3542
3543 static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3544                 omap_clk clk)
3545 {
3546     int iomemtype;
3547
3548     omap_pwl_reset(s);
3549
3550     iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3551                     omap_pwl_writefn, s);
3552     cpu_register_physical_memory(base, 0x800, iomemtype);
3553
3554     omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3555 }
3556
3557 /* Pulse-Width Tone module */
3558 static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3559 {
3560     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3561     int offset = addr & OMAP_MPUI_REG_MASK;
3562
3563     switch (offset) {
3564     case 0x00:  /* FRC */
3565         return s->pwt.frc;
3566     case 0x04:  /* VCR */
3567         return s->pwt.vrc;
3568     case 0x08:  /* GCR */
3569         return s->pwt.gcr;
3570     }
3571     OMAP_BAD_REG(addr);
3572     return 0;
3573 }
3574
3575 static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3576                 uint32_t value)
3577 {
3578     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3579     int offset = addr & OMAP_MPUI_REG_MASK;
3580
3581     switch (offset) {
3582     case 0x00:  /* FRC */
3583         s->pwt.frc = value & 0x3f;
3584         break;
3585     case 0x04:  /* VRC */
3586         if ((value ^ s->pwt.vrc) & 1) {
3587             if (value & 1)
3588                 printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
3589                                 /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
3590                                 ((omap_clk_getrate(s->pwt.clk) >> 3) /
3591                                  /* Pre-multiplexer divider */
3592                                  ((s->pwt.gcr & 2) ? 1 : 154) /
3593                                  /* Octave multiplexer */
3594                                  (2 << (value & 3)) *
3595                                  /* 101/107 divider */
3596                                  ((value & (1 << 2)) ? 101 : 107) *
3597                                  /*  49/55 divider */
3598                                  ((value & (1 << 3)) ?  49 : 55) *
3599                                  /*  50/63 divider */
3600                                  ((value & (1 << 4)) ?  50 : 63) *
3601                                  /*  80/127 divider */
3602                                  ((value & (1 << 5)) ?  80 : 127) /
3603                                  (107 * 55 * 63 * 127)));
3604             else
3605                 printf("%s: silence!\n", __FUNCTION__);
3606         }
3607         s->pwt.vrc = value & 0x7f;
3608         break;
3609     case 0x08:  /* GCR */
3610         s->pwt.gcr = value & 3;
3611         break;
3612     default:
3613         OMAP_BAD_REG(addr);
3614         return;
3615     }
3616 }
3617
3618 static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3619     omap_pwt_read,
3620     omap_badwidth_read8,
3621     omap_badwidth_read8,
3622 };
3623
3624 static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3625     omap_pwt_write,
3626     omap_badwidth_write8,
3627     omap_badwidth_write8,
3628 };
3629
3630 void omap_pwt_reset(struct omap_mpu_state_s *s)
3631 {
3632     s->pwt.frc = 0;
3633     s->pwt.vrc = 0;
3634     s->pwt.gcr = 0;
3635 }
3636
3637 static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3638                 omap_clk clk)
3639 {
3640     int iomemtype;
3641
3642     s->pwt.clk = clk;
3643     omap_pwt_reset(s);
3644
3645     iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3646                     omap_pwt_writefn, s);
3647     cpu_register_physical_memory(base, 0x800, iomemtype);
3648 }
3649
3650 /* Real-time Clock module */
3651 struct omap_rtc_s {
3652     target_phys_addr_t base;
3653     qemu_irq irq;
3654     qemu_irq alarm;
3655     QEMUTimer *clk;
3656
3657     uint8_t interrupts;
3658     uint8_t status;
3659     int16_t comp_reg;
3660     int running;
3661     int pm_am;
3662     int auto_comp;
3663     int round;
3664     struct tm *(*convert)(const time_t *timep, struct tm *result);
3665     struct tm alarm_tm;
3666     time_t alarm_ti;
3667
3668     struct tm current_tm;
3669     time_t ti;
3670     uint64_t tick;
3671 };
3672
3673 static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3674 {
3675     qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3676 }
3677
3678 static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3679 {
3680     s->alarm_ti = mktime(&s->alarm_tm);
3681     if (s->alarm_ti == -1)
3682         printf("%s: conversion failed\n", __FUNCTION__);
3683 }
3684
3685 static inline uint8_t omap_rtc_bcd(int num)
3686 {
3687     return ((num / 10) << 4) | (num % 10);
3688 }
3689
3690 static inline int omap_rtc_bin(uint8_t num)
3691 {
3692     return (num & 15) + 10 * (num >> 4);
3693 }
3694
3695 static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3696 {
3697     struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3698     int offset = addr & OMAP_MPUI_REG_MASK;
3699     uint8_t i;
3700
3701     switch (offset) {
3702     case 0x00:  /* SECONDS_REG */
3703         return omap_rtc_bcd(s->current_tm.tm_sec);
3704
3705     case 0x04:  /* MINUTES_REG */
3706         return omap_rtc_bcd(s->current_tm.tm_min);
3707
3708     case 0x08:  /* HOURS_REG */
3709         if (s->pm_am)
3710             return ((s->current_tm.tm_hour > 11) << 7) |
3711                     omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3712         else
3713             return omap_rtc_bcd(s->current_tm.tm_hour);
3714
3715     case 0x0c:  /* DAYS_REG */
3716         return omap_rtc_bcd(s->current_tm.tm_mday);
3717
3718     case 0x10:  /* MONTHS_REG */
3719         return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3720
3721     case 0x14:  /* YEARS_REG */
3722         return omap_rtc_bcd(s->current_tm.tm_year % 100);
3723
3724     case 0x18:  /* WEEK_REG */
3725         return s->current_tm.tm_wday;
3726
3727     case 0x20:  /* ALARM_SECONDS_REG */
3728         return omap_rtc_bcd(s->alarm_tm.tm_sec);
3729
3730     case 0x24:  /* ALARM_MINUTES_REG */
3731         return omap_rtc_bcd(s->alarm_tm.tm_min);
3732
3733     case 0x28:  /* ALARM_HOURS_REG */
3734         if (s->pm_am)
3735             return ((s->alarm_tm.tm_hour > 11) << 7) |
3736                     omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3737         else
3738             return omap_rtc_bcd(s->alarm_tm.tm_hour);
3739
3740     case 0x2c:  /* ALARM_DAYS_REG */
3741         return omap_rtc_bcd(s->alarm_tm.tm_mday);
3742
3743     case 0x30:  /* ALARM_MONTHS_REG */
3744         return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3745
3746     case 0x34:  /* ALARM_YEARS_REG */
3747         return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3748
3749     case 0x40:  /* RTC_CTRL_REG */
3750         return (s->pm_am << 3) | (s->auto_comp << 2) |
3751                 (s->round << 1) | s->running;
3752
3753     case 0x44:  /* RTC_STATUS_REG */
3754         i = s->status;
3755         s->status &= ~0x3d;
3756         return i;
3757
3758     case 0x48:  /* RTC_INTERRUPTS_REG */
3759         return s->interrupts;
3760
3761     case 0x4c:  /* RTC_COMP_LSB_REG */
3762         return ((uint16_t) s->comp_reg) & 0xff;
3763
3764     case 0x50:  /* RTC_COMP_MSB_REG */
3765         return ((uint16_t) s->comp_reg) >> 8;
3766     }
3767
3768     OMAP_BAD_REG(addr);
3769     return 0;
3770 }
3771
3772 static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3773                 uint32_t value)
3774 {
3775     struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3776     int offset = addr & OMAP_MPUI_REG_MASK;
3777     struct tm new_tm;
3778     time_t ti[2];
3779
3780     switch (offset) {
3781     case 0x00:  /* SECONDS_REG */
3782 #if ALMDEBUG
3783         printf("RTC SEC_REG <-- %02x\n", value);
3784 #endif
3785         s->ti -= s->current_tm.tm_sec;
3786         s->ti += omap_rtc_bin(value);
3787         return;
3788
3789     case 0x04:  /* MINUTES_REG */
3790 #if ALMDEBUG
3791         printf("RTC MIN_REG <-- %02x\n", value);
3792 #endif
3793         s->ti -= s->current_tm.tm_min * 60;
3794         s->ti += omap_rtc_bin(value) * 60;
3795         return;
3796
3797     case 0x08:  /* HOURS_REG */
3798 #if ALMDEBUG
3799         printf("RTC HRS_REG <-- %02x\n", value);
3800 #endif
3801         s->ti -= s->current_tm.tm_hour * 3600;
3802         if (s->pm_am) {
3803             s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3804             s->ti += ((value >> 7) & 1) * 43200;
3805         } else
3806             s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3807         return;
3808
3809     case 0x0c:  /* DAYS_REG */
3810 #if ALMDEBUG
3811         printf("RTC DAY_REG <-- %02x\n", value);
3812 #endif
3813         s->ti -= s->current_tm.tm_mday * 86400;
3814         s->ti += omap_rtc_bin(value) * 86400;
3815         return;
3816
3817     case 0x10:  /* MONTHS_REG */
3818 #if ALMDEBUG
3819         printf("RTC MTH_REG <-- %02x\n", value);
3820 #endif
3821         memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3822         new_tm.tm_mon = omap_rtc_bin(value);
3823         ti[0] = mktime(&s->current_tm);
3824         ti[1] = mktime(&new_tm);
3825
3826         if (ti[0] != -1 && ti[1] != -1) {
3827             s->ti -= ti[0];
3828             s->ti += ti[1];
3829         } else {
3830             /* A less accurate version */
3831             s->ti -= s->current_tm.tm_mon * 2592000;
3832             s->ti += omap_rtc_bin(value) * 2592000;
3833         }
3834         return;
3835
3836     case 0x14:  /* YEARS_REG */
3837 #if ALMDEBUG
3838         printf("RTC YRS_REG <-- %02x\n", value);
3839 #endif
3840         memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3841         new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3842         ti[0] = mktime(&s->current_tm);
3843         ti[1] = mktime(&new_tm);
3844
3845         if (ti[0] != -1 && ti[1] != -1) {
3846             s->ti -= ti[0];
3847             s->ti += ti[1];
3848         } else {
3849             /* A less accurate version */
3850             s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3851             s->ti += omap_rtc_bin(value) * 31536000;
3852         }
3853         return;
3854
3855     case 0x18:  /* WEEK_REG */
3856         return; /* Ignored */
3857
3858     case 0x20:  /* ALARM_SECONDS_REG */
3859 #if ALMDEBUG
3860         printf("ALM SEC_REG <-- %02x\n", value);
3861 #endif
3862         s->alarm_tm.tm_sec = omap_rtc_bin(value);
3863         omap_rtc_alarm_update(s);
3864         return;
3865
3866     case 0x24:  /* ALARM_MINUTES_REG */
3867 #if ALMDEBUG
3868         printf("ALM MIN_REG <-- %02x\n", value);
3869 #endif
3870         s->alarm_tm.tm_min = omap_rtc_bin(value);
3871         omap_rtc_alarm_update(s);
3872         return;
3873
3874     case 0x28:  /* ALARM_HOURS_REG */
3875 #if ALMDEBUG
3876         printf("ALM HRS_REG <-- %02x\n", value);
3877 #endif
3878         if (s->pm_am)
3879             s->alarm_tm.tm_hour =
3880                     ((omap_rtc_bin(value & 0x3f)) % 12) +
3881                     ((value >> 7) & 1) * 12;
3882         else
3883             s->alarm_tm.tm_hour = omap_rtc_bin(value);
3884         omap_rtc_alarm_update(s);
3885         return;
3886
3887     case 0x2c:  /* ALARM_DAYS_REG */
3888 #if ALMDEBUG
3889         printf("ALM DAY_REG <-- %02x\n", value);
3890 #endif
3891         s->alarm_tm.tm_mday = omap_rtc_bin(value);
3892         omap_rtc_alarm_update(s);
3893         return;
3894
3895     case 0x30:  /* ALARM_MONTHS_REG */
3896 #if ALMDEBUG
3897         printf("ALM MON_REG <-- %02x\n", value);
3898 #endif
3899         s->alarm_tm.tm_mon = omap_rtc_bin(value);
3900         omap_rtc_alarm_update(s);
3901         return;
3902
3903     case 0x34:  /* ALARM_YEARS_REG */
3904 #if ALMDEBUG
3905         printf("ALM YRS_REG <-- %02x\n", value);
3906 #endif
3907         s->alarm_tm.tm_year = omap_rtc_bin(value);
3908         omap_rtc_alarm_update(s);
3909         return;
3910
3911     case 0x40:  /* RTC_CTRL_REG */
3912 #if ALMDEBUG
3913         printf("RTC CONTROL <-- %02x\n", value);
3914 #endif
3915         s->pm_am = (value >> 3) & 1;
3916         s->auto_comp = (value >> 2) & 1;
3917         s->round = (value >> 1) & 1;
3918         s->running = value & 1;
3919         s->status &= 0xfd;
3920         s->status |= s->running << 1;
3921         return;
3922
3923     case 0x44:  /* RTC_STATUS_REG */
3924 #if ALMDEBUG
3925         printf("RTC STATUSL <-- %02x\n", value);
3926 #endif
3927         s->status &= ~((value & 0xc0) ^ 0x80);
3928         omap_rtc_interrupts_update(s);
3929         return;
3930
3931     case 0x48:  /* RTC_INTERRUPTS_REG */
3932 #if ALMDEBUG
3933         printf("RTC INTRS <-- %02x\n", value);
3934 #endif
3935         s->interrupts = value;
3936         return;
3937
3938     case 0x4c:  /* RTC_COMP_LSB_REG */
3939 #if ALMDEBUG
3940         printf("RTC COMPLSB <-- %02x\n", value);
3941 #endif
3942         s->comp_reg &= 0xff00;
3943         s->comp_reg |= 0x00ff & value;
3944         return;
3945
3946     case 0x50:  /* RTC_COMP_MSB_REG */
3947 #if ALMDEBUG
3948         printf("RTC COMPMSB <-- %02x\n", value);
3949 #endif
3950         s->comp_reg &= 0x00ff;
3951         s->comp_reg |= 0xff00 & (value << 8);
3952         return;
3953
3954     default:
3955         OMAP_BAD_REG(addr);
3956         return;
3957     }
3958 }
3959
3960 static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3961     omap_rtc_read,
3962     omap_badwidth_read8,
3963     omap_badwidth_read8,
3964 };
3965
3966 static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3967     omap_rtc_write,
3968     omap_badwidth_write8,
3969     omap_badwidth_write8,
3970 };
3971
3972 static void omap_rtc_tick(void *opaque)
3973 {
3974     struct omap_rtc_s *s = opaque;
3975
3976     if (s->round) {
3977         /* Round to nearest full minute.  */
3978         if (s->current_tm.tm_sec < 30)
3979             s->ti -= s->current_tm.tm_sec;
3980         else
3981             s->ti += 60 - s->current_tm.tm_sec;
3982
3983         s->round = 0;
3984     }
3985
3986     localtime_r(&s->ti, &s->current_tm);
3987
3988     if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3989         s->status |= 0x40;
3990         omap_rtc_interrupts_update(s);
3991     }
3992
3993     if (s->interrupts & 0x04)
3994         switch (s->interrupts & 3) {
3995         case 0:
3996             s->status |= 0x04;
3997             qemu_irq_raise(s->irq);
3998             break;
3999         case 1:
4000             if (s->current_tm.tm_sec)
4001                 break;
4002             s->status |= 0x08;
4003             qemu_irq_raise(s->irq);
4004             break;
4005         case 2:
4006             if (s->current_tm.tm_sec || s->current_tm.tm_min)
4007                 break;
4008             s->status |= 0x10;
4009             qemu_irq_raise(s->irq);
4010             break;
4011         case 3:
4012             if (s->current_tm.tm_sec ||
4013                             s->current_tm.tm_min || s->current_tm.tm_hour)
4014                 break;
4015             s->status |= 0x20;
4016             qemu_irq_raise(s->irq);
4017             break;
4018         }
4019
4020     /* Move on */
4021     if (s->running)
4022         s->ti ++;
4023     s->tick += 1000;
4024
4025     /*
4026      * Every full hour add a rough approximation of the compensation
4027      * register to the 32kHz Timer (which drives the RTC) value. 
4028      */
4029     if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
4030         s->tick += s->comp_reg * 1000 / 32768;
4031
4032     qemu_mod_timer(s->clk, s->tick);
4033 }
4034
4035 void omap_rtc_reset(struct omap_rtc_s *s)
4036 {
4037     s->interrupts = 0;
4038     s->comp_reg = 0;
4039     s->running = 0;
4040     s->pm_am = 0;
4041     s->auto_comp = 0;
4042     s->round = 0;
4043     s->tick = qemu_get_clock(rt_clock);
4044     memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
4045     s->alarm_tm.tm_mday = 0x01;
4046     s->status = 1 << 7;
4047     time(&s->ti);
4048     s->ti = mktime(s->convert(&s->ti, &s->current_tm));
4049
4050     omap_rtc_alarm_update(s);
4051     omap_rtc_tick(s);
4052 }
4053
4054 struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
4055                 qemu_irq *irq, omap_clk clk)
4056 {
4057     int iomemtype;
4058     struct omap_rtc_s *s = (struct omap_rtc_s *)
4059             qemu_mallocz(sizeof(struct omap_rtc_s));
4060
4061     s->base = base;
4062     s->irq = irq[0];
4063     s->alarm = irq[1];
4064     s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
4065     s->convert = rtc_utc ? gmtime_r : localtime_r;
4066
4067     omap_rtc_reset(s);
4068
4069     iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
4070                     omap_rtc_writefn, s);
4071     cpu_register_physical_memory(s->base, 0x800, iomemtype);
4072
4073     return s;
4074 }
4075
4076 /* Multi-channel Buffered Serial Port interfaces */
4077 struct omap_mcbsp_s {
4078     target_phys_addr_t base;
4079     qemu_irq txirq;
4080     qemu_irq rxirq;
4081     qemu_irq txdrq;
4082     qemu_irq rxdrq;
4083
4084     uint16_t spcr[2];
4085     uint16_t rcr[2];
4086     uint16_t xcr[2];
4087     uint16_t srgr[2];
4088     uint16_t mcr[2];
4089     uint16_t pcr;
4090     uint16_t rcer[8];
4091     uint16_t xcer[8];
4092     int tx_rate;
4093     int rx_rate;
4094     int tx_req;
4095
4096     struct i2s_codec_s *codec;
4097 };
4098
4099 static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
4100 {
4101     int irq;
4102
4103     switch ((s->spcr[0] >> 4) & 3) {                    /* RINTM */
4104     case 0:
4105         irq = (s->spcr[0] >> 1) & 1;                    /* RRDY */
4106         break;
4107     case 3:
4108         irq = (s->spcr[0] >> 3) & 1;                    /* RSYNCERR */
4109         break;
4110     default:
4111         irq = 0;
4112         break;
4113     }
4114
4115     qemu_set_irq(s->rxirq, irq);
4116
4117     switch ((s->spcr[1] >> 4) & 3) {                    /* XINTM */
4118     case 0:
4119         irq = (s->spcr[1] >> 1) & 1;                    /* XRDY */
4120         break;
4121     case 3:
4122         irq = (s->spcr[1] >> 3) & 1;                    /* XSYNCERR */
4123         break;
4124     default:
4125         irq = 0;
4126         break;
4127     }
4128
4129     qemu_set_irq(s->txirq, irq);
4130 }
4131
4132 static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
4133 {
4134     int prev = s->tx_req;
4135
4136     s->tx_req = (s->tx_rate ||
4137                     (s->spcr[0] & (1 << 12))) &&        /* CLKSTP */
4138             (s->spcr[1] & (1 << 6)) &&                  /* GRST */
4139             (s->spcr[1] & (1 << 0));                    /* XRST */
4140
4141     if (!s->tx_req && prev) {
4142         s->spcr[1] &= ~(1 << 1);                        /* XRDY */
4143         qemu_irq_lower(s->txdrq);
4144         omap_mcbsp_intr_update(s);
4145
4146         if (s->codec)
4147             s->codec->tx_swallow(s->codec->opaque);
4148     } else if (s->codec && s->tx_req && !prev) {
4149         s->spcr[1] |= 1 << 1;                           /* XRDY */
4150         qemu_irq_raise(s->txdrq);
4151         omap_mcbsp_intr_update(s);
4152     }
4153 }
4154
4155 static void omap_mcbsp_rate_update(struct omap_mcbsp_s *s)
4156 {
4157     int rx_clk = 0, tx_clk = 0;
4158     int cpu_rate = 1500000;     /* XXX */
4159     if (!s->codec)
4160         return;
4161
4162     if (s->spcr[1] & (1 << 6)) {                        /* GRST */
4163         if (s->spcr[0] & (1 << 0))                      /* RRST */
4164             if ((s->srgr[1] & (1 << 13)) &&             /* CLKSM */
4165                             (s->pcr & (1 << 8)))        /* CLKRM */
4166                 if (~s->pcr & (1 << 7))                 /* SCLKME */
4167                     rx_clk = cpu_rate /
4168                             ((s->srgr[0] & 0xff) + 1);  /* CLKGDV */
4169         if (s->spcr[1] & (1 << 0))                      /* XRST */
4170             if ((s->srgr[1] & (1 << 13)) &&             /* CLKSM */
4171                             (s->pcr & (1 << 9)))        /* CLKXM */
4172                 if (~s->pcr & (1 << 7))                 /* SCLKME */
4173                     tx_clk = cpu_rate /
4174                             ((s->srgr[0] & 0xff) + 1);  /* CLKGDV */
4175     }
4176
4177     s->codec->set_rate(s->codec->opaque, rx_clk, tx_clk);
4178 }
4179
4180 static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
4181 {
4182     if (!(s->spcr[0] & 1)) {                            /* RRST */
4183         if (s->codec)
4184             s->codec->in.len = 0;
4185         return;
4186     }
4187
4188     if ((s->spcr[0] >> 1) & 1)                          /* RRDY */
4189         s->spcr[0] |= 1 << 2;                           /* RFULL */
4190     s->spcr[0] |= 1 << 1;                               /* RRDY */
4191     qemu_irq_raise(s->rxdrq);
4192     omap_mcbsp_intr_update(s);
4193 }
4194
4195 static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
4196 {
4197     s->spcr[0] &= ~(1 << 1);                            /* RRDY */
4198     qemu_irq_lower(s->rxdrq);
4199     omap_mcbsp_intr_update(s);
4200 }
4201
4202 static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
4203 {
4204     if (s->tx_rate)
4205         return;
4206     s->tx_rate = 1;
4207     omap_mcbsp_req_update(s);
4208 }
4209
4210 static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
4211 {
4212     s->tx_rate = 0;
4213     omap_mcbsp_req_update(s);
4214 }
4215
4216 static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
4217 {
4218     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4219     int offset = addr & OMAP_MPUI_REG_MASK;
4220     uint16_t ret;
4221
4222     switch (offset) {
4223     case 0x00:  /* DRR2 */
4224         if (((s->rcr[0] >> 5) & 7) < 3)                 /* RWDLEN1 */
4225             return 0x0000;
4226         /* Fall through.  */
4227     case 0x02:  /* DRR1 */
4228         if (!s->codec)
4229             return 0x0000;
4230         if (s->codec->in.len < 2) {
4231             printf("%s: Rx FIFO underrun\n", __FUNCTION__);
4232             omap_mcbsp_rx_stop(s);
4233         } else {
4234             s->codec->in.len -= 2;
4235             ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
4236             ret |= s->codec->in.fifo[s->codec->in.start ++];
4237             if (!s->codec->in.len)
4238                 omap_mcbsp_rx_stop(s);
4239             return ret;
4240         }
4241         return 0x0000;
4242
4243     case 0x04:  /* DXR2 */
4244     case 0x06:  /* DXR1 */
4245         return 0x0000;
4246
4247     case 0x08:  /* SPCR2 */
4248         return s->spcr[1];
4249     case 0x0a:  /* SPCR1 */
4250         return s->spcr[0];
4251     case 0x0c:  /* RCR2 */
4252         return s->rcr[1];
4253     case 0x0e:  /* RCR1 */
4254         return s->rcr[0];
4255     case 0x10:  /* XCR2 */
4256         return s->xcr[1];
4257     case 0x12:  /* XCR1 */
4258         return s->xcr[0];
4259     case 0x14:  /* SRGR2 */
4260         return s->srgr[1];
4261     case 0x16:  /* SRGR1 */
4262         return s->srgr[0];
4263     case 0x18:  /* MCR2 */
4264         return s->mcr[1];
4265     case 0x1a:  /* MCR1 */
4266         return s->mcr[0];
4267     case 0x1c:  /* RCERA */
4268         return s->rcer[0];
4269     case 0x1e:  /* RCERB */
4270         return s->rcer[1];
4271     case 0x20:  /* XCERA */
4272         return s->xcer[0];
4273     case 0x22:  /* XCERB */
4274         return s->xcer[1];
4275     case 0x24:  /* PCR0 */
4276         return s->pcr;
4277     case 0x26:  /* RCERC */
4278         return s->rcer[2];
4279     case 0x28:  /* RCERD */
4280         return s->rcer[3];
4281     case 0x2a:  /* XCERC */
4282         return s->xcer[2];
4283     case 0x2c:  /* XCERD */
4284         return s->xcer[3];
4285     case 0x2e:  /* RCERE */
4286         return s->rcer[4];
4287     case 0x30:  /* RCERF */
4288         return s->rcer[5];
4289     case 0x32:  /* XCERE */
4290         return s->xcer[4];
4291     case 0x34:  /* XCERF */
4292         return s->xcer[5];
4293     case 0x36:  /* RCERG */
4294         return s->rcer[6];
4295     case 0x38:  /* RCERH */
4296         return s->rcer[7];
4297     case 0x3a:  /* XCERG */
4298         return s->xcer[6];
4299     case 0x3c:  /* XCERH */
4300         return s->xcer[7];
4301     }
4302
4303     OMAP_BAD_REG(addr);
4304     return 0;
4305 }
4306
4307 static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr,
4308                 uint32_t value)
4309 {
4310     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4311     int offset = addr & OMAP_MPUI_REG_MASK;
4312
4313     switch (offset) {
4314     case 0x00:  /* DRR2 */
4315     case 0x02:  /* DRR1 */
4316         OMAP_RO_REG(addr);
4317         return;
4318
4319     case 0x04:  /* DXR2 */
4320         if (((s->xcr[0] >> 5) & 7) < 3)                 /* XWDLEN1 */
4321             return;
4322         /* Fall through.  */
4323     case 0x06:  /* DXR1 */
4324         if (!s->codec)
4325             return;
4326         if (s->tx_req) {
4327             if (s->codec->out.len > s->codec->out.size - 2) {
4328                 printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4329                 omap_mcbsp_tx_stop(s);
4330             } else {
4331                 s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
4332                 s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
4333                 if (s->codec->out.len >= s->codec->out.size)
4334                     omap_mcbsp_tx_stop(s);
4335             }
4336         } else
4337             printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4338         return;
4339
4340     case 0x08:  /* SPCR2 */
4341         s->spcr[1] &= 0x0002;
4342         s->spcr[1] |= 0x03f9 & value;
4343         s->spcr[1] |= 0x0004 & (value << 2);            /* XEMPTY := XRST */
4344         if (~value & 1) {                               /* XRST */
4345             s->spcr[1] &= ~6;
4346             qemu_irq_lower(s->rxdrq);
4347             if (s->codec)
4348                 s->codec->out.len = 0;
4349         }
4350         if (s->codec)
4351             omap_mcbsp_rate_update(s);
4352         omap_mcbsp_req_update(s);
4353         return;
4354     case 0x0a:  /* SPCR1 */
4355         s->spcr[0] &= 0x0006;
4356         s->spcr[0] |= 0xf8f9 & value;
4357         if (value & (1 << 15))                          /* DLB */
4358             printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
4359         if (~value & 1) {                               /* RRST */
4360             s->spcr[0] &= ~6;
4361             qemu_irq_lower(s->txdrq);
4362             if (s->codec)
4363                 s->codec->in.len = 0;
4364         }
4365         if (s->codec)
4366             omap_mcbsp_rate_update(s);
4367         omap_mcbsp_req_update(s);
4368         return;
4369
4370     case 0x0c:  /* RCR2 */
4371         s->rcr[1] = value & 0xffff;
4372         return;
4373     case 0x0e:  /* RCR1 */
4374         s->rcr[0] = value & 0x7fe0;
4375         return;
4376     case 0x10:  /* XCR2 */
4377         s->xcr[1] = value & 0xffff;
4378         return;
4379     case 0x12:  /* XCR1 */
4380         s->xcr[0] = value & 0x7fe0;
4381         return;
4382     case 0x14:  /* SRGR2 */
4383         s->srgr[1] = value & 0xffff;
4384         omap_mcbsp_rate_update(s);
4385         return;
4386     case 0x16:  /* SRGR1 */
4387         s->srgr[0] = value & 0xffff;
4388         omap_mcbsp_rate_update(s);
4389         return;
4390     case 0x18:  /* MCR2 */
4391         s->mcr[1] = value & 0x03e3;
4392         if (value & 3)                                  /* XMCM */
4393             printf("%s: Tx channel selection mode enable attempt\n",
4394                             __FUNCTION__);
4395         return;
4396     case 0x1a:  /* MCR1 */
4397         s->mcr[0] = value & 0x03e1;
4398         if (value & 1)                                  /* RMCM */
4399             printf("%s: Rx channel selection mode enable attempt\n",
4400                             __FUNCTION__);
4401         return;
4402     case 0x1c:  /* RCERA */
4403         s->rcer[0] = value & 0xffff;
4404         return;
4405     case 0x1e:  /* RCERB */
4406         s->rcer[1] = value & 0xffff;
4407         return;
4408     case 0x20:  /* XCERA */
4409         s->xcer[0] = value & 0xffff;
4410         return;
4411     case 0x22:  /* XCERB */
4412         s->xcer[1] = value & 0xffff;
4413         return;
4414     case 0x24:  /* PCR0 */
4415         s->pcr = value & 0x7faf;
4416         return;
4417     case 0x26:  /* RCERC */
4418         s->rcer[2] = value & 0xffff;
4419         return;
4420     case 0x28:  /* RCERD */
4421         s->rcer[3] = value & 0xffff;
4422         return;
4423     case 0x2a:  /* XCERC */
4424         s->xcer[2] = value & 0xffff;
4425         return;
4426     case 0x2c:  /* XCERD */
4427         s->xcer[3] = value & 0xffff;
4428         return;
4429     case 0x2e:  /* RCERE */
4430         s->rcer[4] = value & 0xffff;
4431         return;
4432     case 0x30:  /* RCERF */
4433         s->rcer[5] = value & 0xffff;
4434         return;
4435     case 0x32:  /* XCERE */
4436         s->xcer[4] = value & 0xffff;
4437         return;
4438     case 0x34:  /* XCERF */
4439         s->xcer[5] = value & 0xffff;
4440         return;
4441     case 0x36:  /* RCERG */
4442         s->rcer[6] = value & 0xffff;
4443         return;
4444     case 0x38:  /* RCERH */
4445         s->rcer[7] = value & 0xffff;
4446         return;
4447     case 0x3a:  /* XCERG */
4448         s->xcer[6] = value & 0xffff;
4449         return;
4450     case 0x3c:  /* XCERH */
4451         s->xcer[7] = value & 0xffff;
4452         return;
4453     }
4454
4455     OMAP_BAD_REG(addr);
4456 }
4457
4458 static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
4459     omap_badwidth_read16,
4460     omap_mcbsp_read,
4461     omap_badwidth_read16,
4462 };
4463
4464 static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
4465     omap_badwidth_write16,
4466     omap_mcbsp_write,
4467     omap_badwidth_write16,
4468 };
4469
4470 static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
4471 {
4472     memset(&s->spcr, 0, sizeof(s->spcr));
4473     memset(&s->rcr, 0, sizeof(s->rcr));
4474     memset(&s->xcr, 0, sizeof(s->xcr));
4475     s->srgr[0] = 0x0001;
4476     s->srgr[1] = 0x2000;
4477     memset(&s->mcr, 0, sizeof(s->mcr));
4478     memset(&s->pcr, 0, sizeof(s->pcr));
4479     memset(&s->rcer, 0, sizeof(s->rcer));
4480     memset(&s->xcer, 0, sizeof(s->xcer));
4481     s->tx_req = 0;
4482     s->tx_rate = 0;
4483     s->rx_rate = 0;
4484 }
4485
4486 struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
4487                 qemu_irq *irq, qemu_irq *dma, omap_clk clk)
4488 {
4489     int iomemtype;
4490     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
4491             qemu_mallocz(sizeof(struct omap_mcbsp_s));
4492
4493     s->base = base;
4494     s->txirq = irq[0];
4495     s->rxirq = irq[1];
4496     s->txdrq = dma[0];
4497     s->rxdrq = dma[1];
4498     omap_mcbsp_reset(s);
4499
4500     iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
4501                     omap_mcbsp_writefn, s);
4502     cpu_register_physical_memory(s->base, 0x800, iomemtype);
4503
4504     return s;
4505 }
4506
4507 void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4508 {
4509     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4510
4511     omap_mcbsp_rx_start(s);
4512 }
4513
4514 void omap_mcbsp_i2s_start(void *opaque, int line, int level)
4515 {
4516     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4517
4518     omap_mcbsp_tx_start(s);
4519 }
4520
4521 void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
4522 {
4523     s->codec = slave;
4524     slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4525     slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4526 }
4527
4528 /* General chip reset */
4529 static void omap_mpu_reset(void *opaque)
4530 {
4531     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4532
4533     omap_clkm_reset(mpu);
4534     omap_inth_reset(mpu->ih[0]);
4535     omap_inth_reset(mpu->ih[1]);
4536     omap_dma_reset(mpu->dma);
4537     omap_mpu_timer_reset(mpu->timer[0]);
4538     omap_mpu_timer_reset(mpu->timer[1]);
4539     omap_mpu_timer_reset(mpu->timer[2]);
4540     omap_wd_timer_reset(mpu->wdt);
4541     omap_os_timer_reset(mpu->os_timer);
4542     omap_lcdc_reset(mpu->lcd);
4543     omap_ulpd_pm_reset(mpu);
4544     omap_pin_cfg_reset(mpu);
4545     omap_mpui_reset(mpu);
4546     omap_tipb_bridge_reset(mpu->private_tipb);
4547     omap_tipb_bridge_reset(mpu->public_tipb);
4548     omap_dpll_reset(&mpu->dpll[0]);
4549     omap_dpll_reset(&mpu->dpll[1]);
4550     omap_dpll_reset(&mpu->dpll[2]);
4551     omap_uart_reset(mpu->uart[0]);
4552     omap_uart_reset(mpu->uart[1]);
4553     omap_uart_reset(mpu->uart[2]);
4554     omap_mmc_reset(mpu->mmc);
4555     omap_mpuio_reset(mpu->mpuio);
4556     omap_gpio_reset(mpu->gpio);
4557     omap_uwire_reset(mpu->microwire);
4558     omap_pwl_reset(mpu);
4559     omap_pwt_reset(mpu);
4560     omap_i2c_reset(mpu->i2c);
4561     omap_rtc_reset(mpu->rtc);
4562     omap_mcbsp_reset(mpu->mcbsp1);
4563     omap_mcbsp_reset(mpu->mcbsp2);
4564     omap_mcbsp_reset(mpu->mcbsp3);
4565     cpu_reset(mpu->env);
4566 }
4567
4568 static const struct omap_map_s {
4569     target_phys_addr_t phys_dsp;
4570     target_phys_addr_t phys_mpu;
4571     uint32_t size;
4572     const char *name;
4573 } omap15xx_dsp_mm[] = {
4574     /* Strobe 0 */
4575     { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },              /* CS0 */
4576     { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },             /* CS1 */
4577     { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },          /* CS3 */
4578     { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },   /* CS4 */
4579     { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
4580     { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                 /* CS6 */
4581     { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                  /* CS7 */
4582     { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },              /* CS8 */
4583     { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                   /* CS9 */
4584     { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                 /* CS10 */
4585     { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                   /* CS11 */
4586     { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                   /* CS12 */
4587     { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
4588     { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                   /* CS15 */
4589     { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },          /* CS18 */
4590     { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                 /* CS19 */
4591     { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },         /* CS25 */
4592     /* Strobe 1 */
4593     { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                 /* CS28 */
4594
4595     { 0 }
4596 };
4597
4598 static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4599 {
4600     int io;
4601
4602     for (; map->phys_dsp; map ++) {
4603         io = cpu_get_physical_page_desc(map->phys_mpu);
4604
4605         cpu_register_physical_memory(map->phys_dsp, map->size, io);
4606     }
4607 }
4608
4609 static void omap_mpu_wakeup(void *opaque, int irq, int req)
4610 {
4611     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4612
4613     if (mpu->env->halted)
4614         cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4615 }
4616
4617 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4618                 DisplayState *ds, const char *core)
4619 {
4620     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4621             qemu_mallocz(sizeof(struct omap_mpu_state_s));
4622     ram_addr_t imif_base, emiff_base;
4623
4624     /* Core */
4625     s->mpu_model = omap310;
4626     s->env = cpu_init();
4627     s->sdram_size = sdram_size;
4628     s->sram_size = OMAP15XX_SRAM_SIZE;
4629
4630     cpu_arm_set_model(s->env, core ?: "ti925t");
4631
4632     s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4633
4634     /* Clocks */
4635     omap_clk_init(s);
4636
4637     /* Memory-mapped stuff */
4638     cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4639                     (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4640     cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4641                     (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4642
4643     omap_clkm_init(0xfffece00, 0xe1008000, s);
4644
4645     s->ih[0] = omap_inth_init(0xfffecb00, 0x100,
4646                     arm_pic_init_cpu(s->env),
4647                     omap_findclk(s, "arminth_ck"));
4648     s->ih[1] = omap_inth_init(0xfffe0000, 0x800,
4649                     &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ],
4650                     omap_findclk(s, "arminth_ck"));
4651     s->irq[0] = s->ih[0]->pins;
4652     s->irq[1] = s->ih[1]->pins;
4653
4654     s->dma = omap_dma_init(0xfffed800, s->irq[0], s,
4655                     omap_findclk(s, "dma_ck"));
4656     s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4657     s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4658     s->port[imif     ].addr_valid = omap_validate_imif_addr;
4659     s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4660     s->port[local    ].addr_valid = omap_validate_local_addr;
4661     s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4662
4663     s->timer[0] = omap_mpu_timer_init(0xfffec500,
4664                     s->irq[0][OMAP_INT_TIMER1],
4665                     omap_findclk(s, "mputim_ck"));
4666     s->timer[1] = omap_mpu_timer_init(0xfffec600,
4667                     s->irq[0][OMAP_INT_TIMER2],
4668                     omap_findclk(s, "mputim_ck"));
4669     s->timer[2] = omap_mpu_timer_init(0xfffec700,
4670                     s->irq[0][OMAP_INT_TIMER3],
4671                     omap_findclk(s, "mputim_ck"));
4672
4673     s->wdt = omap_wd_timer_init(0xfffec800,
4674                     s->irq[0][OMAP_INT_WD_TIMER],
4675                     omap_findclk(s, "armwdt_ck"));
4676
4677     s->os_timer = omap_os_timer_init(0xfffb9000,
4678                     s->irq[1][OMAP_INT_OS_TIMER],
4679                     omap_findclk(s, "clk32-kHz"));
4680
4681     s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4682                     &s->dma->lcd_ch, ds, imif_base, emiff_base,
4683                     omap_findclk(s, "lcd_ck"));
4684
4685     omap_ulpd_pm_init(0xfffe0800, s);
4686     omap_pin_cfg_init(0xfffe1000, s);
4687     omap_id_init(s);
4688
4689     omap_mpui_init(0xfffec900, s);
4690
4691     s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4692                     s->irq[0][OMAP_INT_BRIDGE_PRIV],
4693                     omap_findclk(s, "tipb_ck"));
4694     s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4695                     s->irq[0][OMAP_INT_BRIDGE_PUB],
4696                     omap_findclk(s, "tipb_ck"));
4697
4698     omap_tcmi_init(0xfffecc00, s);
4699
4700     s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4701                     omap_findclk(s, "uart1_ck"),
4702                     serial_hds[0]);
4703     s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4704                     omap_findclk(s, "uart2_ck"),
4705                     serial_hds[0] ? serial_hds[1] : 0);
4706     s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4707                     omap_findclk(s, "uart3_ck"),
4708                     serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4709
4710     omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4711     omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4712     omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4713
4714     s->mmc = omap_mmc_init(0xfffb7800, s->irq[1][OMAP_INT_OQN],
4715                     &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
4716
4717     s->mpuio = omap_mpuio_init(0xfffb5000,
4718                     s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4719                     s->wakeup, omap_findclk(s, "clk32-kHz"));
4720
4721     s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4722                     omap_findclk(s, "arm_gpio_ck"));
4723
4724     s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4725                     s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4726
4727     omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4728     omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4729
4730     s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4731                     &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4732
4733     s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4734                     omap_findclk(s, "clk32-kHz"));
4735
4736     s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
4737                     &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4738     s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
4739                     &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4740     s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
4741                     &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4742
4743     /* Register mappings not currenlty implemented:
4744      * MCSI2 Comm       fffb2000 - fffb27ff (not mapped on OMAP310)
4745      * MCSI1 Bluetooth  fffb2800 - fffb2fff (not mapped on OMAP310)
4746      * USB W2FC         fffb4000 - fffb47ff
4747      * Camera Interface fffb6800 - fffb6fff
4748      * USB Host         fffba000 - fffba7ff
4749      * FAC              fffba800 - fffbafff
4750      * HDQ/1-Wire       fffbc000 - fffbc7ff
4751      * TIPB switches    fffbc800 - fffbcfff
4752      * LED1             fffbd000 - fffbd7ff
4753      * LED2             fffbd800 - fffbdfff
4754      * Mailbox          fffcf000 - fffcf7ff
4755      * Local bus IF     fffec100 - fffec1ff
4756      * Local bus MMU    fffec200 - fffec2ff
4757      * DSP MMU          fffed200 - fffed2ff
4758      */
4759
4760     omap_setup_dsp_mapping(omap15xx_dsp_mm);
4761
4762     qemu_register_reset(omap_mpu_reset, s);
4763
4764     return s;
4765 }