Less magic constants, by Filip Navara.
[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_read16(void *opaque, target_phys_addr_t addr)
26 {
27     OMAP_16B_REG(addr);
28     return 0;
29 }
30
31 void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
32                 uint32_t value)
33 {
34     OMAP_16B_REG(addr);
35 }
36
37 uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
38 {
39     OMAP_32B_REG(addr);
40     return 0;
41 }
42
43 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
44                 uint32_t value)
45 {
46     OMAP_32B_REG(addr);
47 }
48
49 #define likely
50 #define unlikely
51
52 /* Interrupt Handlers */
53 struct omap_intr_handler_s {
54     qemu_irq *pins;
55     qemu_irq *parent_pic;
56     target_phys_addr_t base;
57
58     /* state */
59     uint32_t irqs;
60     uint32_t mask;
61     uint32_t sens_edge;
62     uint32_t fiq;
63     int priority[32];
64     uint32_t new_irq_agr;
65     uint32_t new_fiq_agr;
66     int sir_irq;
67     int sir_fiq;
68     int stats[32];
69 };
70
71 static void omap_inth_update(struct omap_intr_handler_s *s)
72 {
73     uint32_t irq = s->irqs & ~s->mask & ~s->fiq;
74     uint32_t fiq = s->irqs & ~s->mask & s->fiq;
75
76     if (s->new_irq_agr || !irq) {
77        qemu_set_irq(s->parent_pic[ARM_PIC_CPU_IRQ], irq);
78        if (irq)
79            s->new_irq_agr = 0;
80     }
81
82     if (s->new_fiq_agr || !irq) {
83         qemu_set_irq(s->parent_pic[ARM_PIC_CPU_FIQ], fiq);
84         if (fiq)
85             s->new_fiq_agr = 0;
86     }
87 }
88
89 static void omap_inth_sir_update(struct omap_intr_handler_s *s)
90 {
91     int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f;
92     uint32_t level = s->irqs & ~s->mask;
93
94     intr_irq = 0;
95     intr_fiq = 0;
96     p_irq = -1;
97     p_fiq = -1;
98     /* Find the interrupt line with the highest dynamic priority */
99     for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, level >>= f) {
100         p = s->priority[i];
101         if (s->fiq & (1 << i)) {
102             if (p > p_fiq) {
103                 p_fiq = p;
104                 intr_fiq = i;
105             }
106         } else {
107             if (p > p_irq) {
108                 p_irq = p;
109                 intr_irq = i;
110             }
111         }
112
113         f = ffs(level >> 1);
114     }
115
116     s->sir_irq = intr_irq;
117     s->sir_fiq = intr_fiq;
118 }
119
120 #define INT_FALLING_EDGE        0
121 #define INT_LOW_LEVEL           1
122
123 static void omap_set_intr(void *opaque, int irq, int req)
124 {
125     struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
126     uint32_t rise;
127
128     if (req) {
129         rise = ~ih->irqs & (1 << irq);
130         ih->irqs |= rise;
131         ih->stats[irq] += !!rise;
132     } else {
133         rise = ih->sens_edge & ih->irqs & (1 << irq);
134         ih->irqs &= ~rise;
135     }
136
137     if (rise & ~ih->mask) {
138         omap_inth_sir_update(ih);
139
140         omap_inth_update(ih);
141     }
142 }
143
144 static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
145 {
146     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
147     int i, offset = addr - s->base;
148
149     switch (offset) {
150     case 0x00:  /* ITR */
151         return s->irqs;
152
153     case 0x04:  /* MIR */
154         return s->mask;
155
156     case 0x10:  /* SIR_IRQ_CODE */
157         i = s->sir_irq;
158         if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
159             s->irqs &= ~(1 << i);
160             omap_inth_sir_update(s);
161             omap_inth_update(s);
162         }
163         return i;
164
165     case 0x14:  /* SIR_FIQ_CODE */
166         i = s->sir_fiq;
167         if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
168             s->irqs &= ~(1 << i);
169             omap_inth_sir_update(s);
170             omap_inth_update(s);
171         }
172         return i;
173
174     case 0x18:  /* CONTROL_REG */
175         return 0;
176
177     case 0x1c:  /* ILR0 */
178     case 0x20:  /* ILR1 */
179     case 0x24:  /* ILR2 */
180     case 0x28:  /* ILR3 */
181     case 0x2c:  /* ILR4 */
182     case 0x30:  /* ILR5 */
183     case 0x34:  /* ILR6 */
184     case 0x38:  /* ILR7 */
185     case 0x3c:  /* ILR8 */
186     case 0x40:  /* ILR9 */
187     case 0x44:  /* ILR10 */
188     case 0x48:  /* ILR11 */
189     case 0x4c:  /* ILR12 */
190     case 0x50:  /* ILR13 */
191     case 0x54:  /* ILR14 */
192     case 0x58:  /* ILR15 */
193     case 0x5c:  /* ILR16 */
194     case 0x60:  /* ILR17 */
195     case 0x64:  /* ILR18 */
196     case 0x68:  /* ILR19 */
197     case 0x6c:  /* ILR20 */
198     case 0x70:  /* ILR21 */
199     case 0x74:  /* ILR22 */
200     case 0x78:  /* ILR23 */
201     case 0x7c:  /* ILR24 */
202     case 0x80:  /* ILR25 */
203     case 0x84:  /* ILR26 */
204     case 0x88:  /* ILR27 */
205     case 0x8c:  /* ILR28 */
206     case 0x90:  /* ILR29 */
207     case 0x94:  /* ILR30 */
208     case 0x98:  /* ILR31 */
209         i = (offset - 0x1c) >> 2;
210         return (s->priority[i] << 2) |
211                 (((s->sens_edge >> i) & 1) << 1) |
212                 ((s->fiq >> i) & 1);
213
214     case 0x9c:  /* ISR */
215         return 0x00000000;
216
217     default:
218         OMAP_BAD_REG(addr);
219         break;
220     }
221     return 0;
222 }
223
224 static void omap_inth_write(void *opaque, target_phys_addr_t addr,
225                 uint32_t value)
226 {
227     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
228     int i, offset = addr - s->base;
229
230     switch (offset) {
231     case 0x00:  /* ITR */
232         s->irqs &= value;
233         omap_inth_sir_update(s);
234         omap_inth_update(s);
235         return;
236
237     case 0x04:  /* MIR */
238         s->mask = value;
239         omap_inth_sir_update(s);
240         omap_inth_update(s);
241         return;
242
243     case 0x10:  /* SIR_IRQ_CODE */
244     case 0x14:  /* SIR_FIQ_CODE */
245         OMAP_RO_REG(addr);
246         break;
247
248     case 0x18:  /* CONTROL_REG */
249         if (value & 2)
250             s->new_fiq_agr = ~0;
251         if (value & 1)
252             s->new_irq_agr = ~0;
253         omap_inth_update(s);
254         return;
255
256     case 0x1c:  /* ILR0 */
257     case 0x20:  /* ILR1 */
258     case 0x24:  /* ILR2 */
259     case 0x28:  /* ILR3 */
260     case 0x2c:  /* ILR4 */
261     case 0x30:  /* ILR5 */
262     case 0x34:  /* ILR6 */
263     case 0x38:  /* ILR7 */
264     case 0x3c:  /* ILR8 */
265     case 0x40:  /* ILR9 */
266     case 0x44:  /* ILR10 */
267     case 0x48:  /* ILR11 */
268     case 0x4c:  /* ILR12 */
269     case 0x50:  /* ILR13 */
270     case 0x54:  /* ILR14 */
271     case 0x58:  /* ILR15 */
272     case 0x5c:  /* ILR16 */
273     case 0x60:  /* ILR17 */
274     case 0x64:  /* ILR18 */
275     case 0x68:  /* ILR19 */
276     case 0x6c:  /* ILR20 */
277     case 0x70:  /* ILR21 */
278     case 0x74:  /* ILR22 */
279     case 0x78:  /* ILR23 */
280     case 0x7c:  /* ILR24 */
281     case 0x80:  /* ILR25 */
282     case 0x84:  /* ILR26 */
283     case 0x88:  /* ILR27 */
284     case 0x8c:  /* ILR28 */
285     case 0x90:  /* ILR29 */
286     case 0x94:  /* ILR30 */
287     case 0x98:  /* ILR31 */
288         i = (offset - 0x1c) >> 2;
289         s->priority[i] = (value >> 2) & 0x1f;
290         s->sens_edge &= ~(1 << i);
291         s->sens_edge |= ((value >> 1) & 1) << i;
292         s->fiq &= ~(1 << i);
293         s->fiq |= (value & 1) << i;
294         return;
295
296     case 0x9c:  /* ISR */
297         for (i = 0; i < 32; i ++)
298             if (value & (1 << i)) {
299                 omap_set_intr(s, i, 1);
300                 return;
301             }
302         return;
303
304     default:
305         OMAP_BAD_REG(addr);
306     }
307 }
308
309 static CPUReadMemoryFunc *omap_inth_readfn[] = {
310     omap_badwidth_read32,
311     omap_badwidth_read32,
312     omap_inth_read,
313 };
314
315 static CPUWriteMemoryFunc *omap_inth_writefn[] = {
316     omap_inth_write,
317     omap_inth_write,
318     omap_inth_write,
319 };
320
321 static void omap_inth_reset(struct omap_intr_handler_s *s)
322 {
323     s->irqs = 0x00000000;
324     s->mask = 0xffffffff;
325     s->sens_edge = 0x00000000;
326     s->fiq = 0x00000000;
327     memset(s->priority, 0, sizeof(s->priority));
328     s->new_irq_agr = ~0;
329     s->new_fiq_agr = ~0;
330     s->sir_irq = 0;
331     s->sir_fiq = 0;
332
333     omap_inth_update(s);
334 }
335
336 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
337                 unsigned long size, qemu_irq parent[2], omap_clk clk)
338 {
339     int iomemtype;
340     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
341             qemu_mallocz(sizeof(struct omap_intr_handler_s));
342
343     s->parent_pic = parent;
344     s->base = base;
345     s->pins = qemu_allocate_irqs(omap_set_intr, s, 32);
346     omap_inth_reset(s);
347
348     iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
349                     omap_inth_writefn, s);
350     cpu_register_physical_memory(s->base, size, iomemtype);
351
352     return s;
353 }
354
355 /* OMAP1 DMA module */
356 typedef enum {
357     constant = 0,
358     post_incremented,
359     single_index,
360     double_index,
361 } omap_dma_addressing_t;
362
363 struct omap_dma_channel_s {
364     int burst[2];
365     int pack[2];
366     enum omap_dma_port port[2];
367     target_phys_addr_t addr[2];
368     omap_dma_addressing_t mode[2];
369     int data_type;
370     int end_prog;
371     int repeat;
372     int auto_init;
373     int priority;
374     int fs;
375     int sync;
376     int running;
377     int interrupts;
378     int status;
379     int signalled;
380     int post_sync;
381     int transfer;
382     uint16_t elements;
383     uint16_t frames;
384     uint16_t frame_index;
385     uint16_t element_index;
386     uint16_t cpc;
387
388     struct omap_dma_reg_set_s {
389         target_phys_addr_t src, dest;
390         int frame;
391         int element;
392         int frame_delta[2];
393         int elem_delta[2];
394         int frames;
395         int elements;
396     } active_set;
397 };
398
399 struct omap_dma_s {
400     qemu_irq *ih;
401     QEMUTimer *tm;
402     struct omap_mpu_state_s *mpu;
403     target_phys_addr_t base;
404     omap_clk clk;
405     int64_t delay;
406     uint32_t drq;
407
408     uint16_t gcr;
409     int run_count;
410
411     int chans;
412     struct omap_dma_channel_s ch[16];
413     struct omap_dma_lcd_channel_s lcd_ch;
414 };
415
416 static void omap_dma_interrupts_update(struct omap_dma_s *s)
417 {
418     /* First three interrupts are shared between two channels each.  */
419     qemu_set_irq(s->ih[OMAP_INT_DMA_CH0_6],
420                     (s->ch[0].status | s->ch[6].status) & 0x3f);
421     qemu_set_irq(s->ih[OMAP_INT_DMA_CH1_7],
422                     (s->ch[1].status | s->ch[7].status) & 0x3f);
423     qemu_set_irq(s->ih[OMAP_INT_DMA_CH2_8],
424                     (s->ch[2].status | s->ch[8].status) & 0x3f);
425     qemu_set_irq(s->ih[OMAP_INT_DMA_CH3],
426                     (s->ch[3].status) & 0x3f);
427     qemu_set_irq(s->ih[OMAP_INT_DMA_CH4],
428                     (s->ch[4].status) & 0x3f);
429     qemu_set_irq(s->ih[OMAP_INT_DMA_CH5],
430                     (s->ch[5].status) & 0x3f);
431 }
432
433 static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
434 {
435     struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
436     int i;
437
438     /*
439      * TODO: verify address ranges and alignment
440      * TODO: port endianness
441      */
442
443     a->src = s->ch[ch].addr[0];
444     a->dest = s->ch[ch].addr[1];
445     a->frames = s->ch[ch].frames;
446     a->elements = s->ch[ch].elements;
447     a->frame = 0;
448     a->element = 0;
449
450     if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
451         printf("%s: bad DMA request\n", __FUNCTION__);
452         return;
453     }
454
455     for (i = 0; i < 2; i ++)
456         switch (s->ch[ch].mode[i]) {
457         case constant:
458             a->elem_delta[i] = 0;
459             a->frame_delta[i] = 0;
460             break;
461         case post_incremented:
462             a->elem_delta[i] = s->ch[ch].data_type;
463             a->frame_delta[i] = 0;
464             break;
465         case single_index:
466             a->elem_delta[i] = s->ch[ch].data_type +
467                 s->ch[ch].element_index - 1;
468             if (s->ch[ch].element_index > 0x7fff)
469                 a->elem_delta[i] -= 0x10000;
470             a->frame_delta[i] = 0;
471             break;
472         case double_index:
473             a->elem_delta[i] = s->ch[ch].data_type +
474                 s->ch[ch].element_index - 1;
475             if (s->ch[ch].element_index > 0x7fff)
476                 a->elem_delta[i] -= 0x10000;
477             a->frame_delta[i] = s->ch[ch].frame_index -
478                 s->ch[ch].element_index;
479             if (s->ch[ch].frame_index > 0x7fff)
480                 a->frame_delta[i] -= 0x10000;
481             break;
482         default:
483             break;
484         }
485 }
486
487 static inline void omap_dma_request_run(struct omap_dma_s *s,
488                 int channel, int request)
489 {
490 next_channel:
491     if (request > 0)
492         for (; channel < 9; channel ++)
493             if (s->ch[channel].sync == request && s->ch[channel].running)
494                 break;
495     if (channel >= 9)
496         return;
497
498     if (s->ch[channel].transfer) {
499         if (request > 0) {
500             s->ch[channel ++].post_sync = request;
501             goto next_channel;
502         }
503         s->ch[channel].status |= 0x02;  /* Synchronisation drop */
504         omap_dma_interrupts_update(s);
505         return;
506     }
507
508     if (!s->ch[channel].signalled)
509         s->run_count ++;
510     s->ch[channel].signalled = 1;
511
512     if (request > 0)
513         s->ch[channel].status |= 0x40;  /* External request */
514
515     if (s->delay && !qemu_timer_pending(s->tm))
516         qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
517
518     if (request > 0) {
519         channel ++;
520         goto next_channel;
521     }
522 }
523
524 static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel)
525 {
526     if (s->ch[channel].signalled)
527         s->run_count --;
528     s->ch[channel].signalled = 0;
529
530     if (!s->run_count)
531         qemu_del_timer(s->tm);
532 }
533
534 static void omap_dma_channel_run(struct omap_dma_s *s)
535 {
536     int ch;
537     uint16_t status;
538     uint8_t value[4];
539     struct omap_dma_port_if_s *src_p, *dest_p;
540     struct omap_dma_reg_set_s *a;
541
542     for (ch = 0; ch < 9; ch ++) {
543         a = &s->ch[ch].active_set;
544
545         src_p = &s->mpu->port[s->ch[ch].port[0]];
546         dest_p = &s->mpu->port[s->ch[ch].port[1]];
547         if (s->ch[ch].signalled && (!src_p->addr_valid(s->mpu, a->src) ||
548                     !dest_p->addr_valid(s->mpu, a->dest))) {
549 #if 0
550             /* Bus time-out */
551             if (s->ch[ch].interrupts & 0x01)
552                 s->ch[ch].status |= 0x01;
553             omap_dma_request_stop(s, ch);
554             continue;
555 #endif
556             printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch);
557         }
558
559         status = s->ch[ch].status;
560         while (status == s->ch[ch].status && s->ch[ch].signalled) {
561             /* Transfer a single element */
562             s->ch[ch].transfer = 1;
563             cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
564             cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
565             s->ch[ch].transfer = 0;
566
567             a->src += a->elem_delta[0];
568             a->dest += a->elem_delta[1];
569             a->element ++;
570
571             /* Check interrupt conditions */
572             if (a->element == a->elements) {
573                 a->element = 0;
574                 a->src += a->frame_delta[0];
575                 a->dest += a->frame_delta[1];
576                 a->frame ++;
577
578                 if (a->frame == a->frames) {
579                     if (!s->ch[ch].repeat || !s->ch[ch].auto_init)
580                         s->ch[ch].running = 0;
581
582                     if (s->ch[ch].auto_init &&
583                             (s->ch[ch].repeat ||
584                              s->ch[ch].end_prog))
585                         omap_dma_channel_load(s, ch);
586
587                     if (s->ch[ch].interrupts & 0x20)
588                         s->ch[ch].status |= 0x20;
589
590                     if (!s->ch[ch].sync)
591                         omap_dma_request_stop(s, ch);
592                 }
593
594                 if (s->ch[ch].interrupts & 0x08)
595                     s->ch[ch].status |= 0x08;
596
597                 if (s->ch[ch].sync && s->ch[ch].fs &&
598                                 !(s->drq & (1 << s->ch[ch].sync))) {
599                     s->ch[ch].status &= ~0x40;
600                     omap_dma_request_stop(s, ch);
601                 }
602             }
603
604             if (a->element == 1 && a->frame == a->frames - 1)
605                 if (s->ch[ch].interrupts & 0x10)
606                     s->ch[ch].status |= 0x10;
607
608             if (a->element == (a->elements >> 1))
609                 if (s->ch[ch].interrupts & 0x04)
610                     s->ch[ch].status |= 0x04;
611
612             if (s->ch[ch].sync && !s->ch[ch].fs &&
613                             !(s->drq & (1 << s->ch[ch].sync))) {
614                 s->ch[ch].status &= ~0x40;
615                 omap_dma_request_stop(s, ch);
616             }
617
618             /*
619              * Process requests made while the element was
620              * being transferred.
621              */
622             if (s->ch[ch].post_sync) {
623                 omap_dma_request_run(s, 0, s->ch[ch].post_sync);
624                 s->ch[ch].post_sync = 0;
625             }
626
627 #if 0
628             break;
629 #endif
630         }
631
632         s->ch[ch].cpc = a->dest & 0x0000ffff;
633     }
634
635     omap_dma_interrupts_update(s);
636     if (s->run_count && s->delay)
637         qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
638 }
639
640 static int omap_dma_ch_reg_read(struct omap_dma_s *s,
641                 int ch, int reg, uint16_t *value) {
642     switch (reg) {
643     case 0x00:  /* SYS_DMA_CSDP_CH0 */
644         *value = (s->ch[ch].burst[1] << 14) |
645                 (s->ch[ch].pack[1] << 13) |
646                 (s->ch[ch].port[1] << 9) |
647                 (s->ch[ch].burst[0] << 7) |
648                 (s->ch[ch].pack[0] << 6) |
649                 (s->ch[ch].port[0] << 2) |
650                 (s->ch[ch].data_type >> 1);
651         break;
652
653     case 0x02:  /* SYS_DMA_CCR_CH0 */
654         *value = (s->ch[ch].mode[1] << 14) |
655                 (s->ch[ch].mode[0] << 12) |
656                 (s->ch[ch].end_prog << 11) |
657                 (s->ch[ch].repeat << 9) |
658                 (s->ch[ch].auto_init << 8) |
659                 (s->ch[ch].running << 7) |
660                 (s->ch[ch].priority << 6) |
661                 (s->ch[ch].fs << 5) | s->ch[ch].sync;
662         break;
663
664     case 0x04:  /* SYS_DMA_CICR_CH0 */
665         *value = s->ch[ch].interrupts;
666         break;
667
668     case 0x06:  /* SYS_DMA_CSR_CH0 */
669         /* FIXME: shared CSR for channels sharing the interrupts */
670         *value = s->ch[ch].status;
671         s->ch[ch].status &= 0x40;
672         omap_dma_interrupts_update(s);
673         break;
674
675     case 0x08:  /* SYS_DMA_CSSA_L_CH0 */
676         *value = s->ch[ch].addr[0] & 0x0000ffff;
677         break;
678
679     case 0x0a:  /* SYS_DMA_CSSA_U_CH0 */
680         *value = s->ch[ch].addr[0] >> 16;
681         break;
682
683     case 0x0c:  /* SYS_DMA_CDSA_L_CH0 */
684         *value = s->ch[ch].addr[1] & 0x0000ffff;
685         break;
686
687     case 0x0e:  /* SYS_DMA_CDSA_U_CH0 */
688         *value = s->ch[ch].addr[1] >> 16;
689         break;
690
691     case 0x10:  /* SYS_DMA_CEN_CH0 */
692         *value = s->ch[ch].elements;
693         break;
694
695     case 0x12:  /* SYS_DMA_CFN_CH0 */
696         *value = s->ch[ch].frames;
697         break;
698
699     case 0x14:  /* SYS_DMA_CFI_CH0 */
700         *value = s->ch[ch].frame_index;
701         break;
702
703     case 0x16:  /* SYS_DMA_CEI_CH0 */
704         *value = s->ch[ch].element_index;
705         break;
706
707     case 0x18:  /* SYS_DMA_CPC_CH0 */
708         *value = s->ch[ch].cpc;
709         break;
710
711     default:
712         return 1;
713     }
714     return 0;
715 }
716
717 static int omap_dma_ch_reg_write(struct omap_dma_s *s,
718                 int ch, int reg, uint16_t value) {
719     switch (reg) {
720     case 0x00:  /* SYS_DMA_CSDP_CH0 */
721         s->ch[ch].burst[1] = (value & 0xc000) >> 14;
722         s->ch[ch].pack[1] = (value & 0x2000) >> 13;
723         s->ch[ch].port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
724         s->ch[ch].burst[0] = (value & 0x0180) >> 7;
725         s->ch[ch].pack[0] = (value & 0x0040) >> 6;
726         s->ch[ch].port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
727         s->ch[ch].data_type = (1 << (value & 3));
728         if (s->ch[ch].port[0] >= omap_dma_port_last)
729             printf("%s: invalid DMA port %i\n", __FUNCTION__,
730                             s->ch[ch].port[0]);
731         if (s->ch[ch].port[1] >= omap_dma_port_last)
732             printf("%s: invalid DMA port %i\n", __FUNCTION__,
733                             s->ch[ch].port[1]);
734         if ((value & 3) == 3)
735             printf("%s: bad data_type for DMA channel %i\n", __FUNCTION__, ch);
736         break;
737
738     case 0x02:  /* SYS_DMA_CCR_CH0 */
739         s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
740         s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
741         s->ch[ch].end_prog = (value & 0x0800) >> 11;
742         s->ch[ch].repeat = (value & 0x0200) >> 9;
743         s->ch[ch].auto_init = (value & 0x0100) >> 8;
744         s->ch[ch].priority = (value & 0x0040) >> 6;
745         s->ch[ch].fs = (value & 0x0020) >> 5;
746         s->ch[ch].sync = value & 0x001f;
747         if (value & 0x0080) {
748             if (s->ch[ch].running) {
749                 if (!s->ch[ch].signalled &&
750                                 s->ch[ch].auto_init && s->ch[ch].end_prog)
751                     omap_dma_channel_load(s, ch);
752             } else {
753                 s->ch[ch].running = 1;
754                 omap_dma_channel_load(s, ch);
755             }
756             if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync)))
757                 omap_dma_request_run(s, ch, 0);
758         } else {
759             s->ch[ch].running = 0;
760             omap_dma_request_stop(s, ch);
761         }
762         break;
763
764     case 0x04:  /* SYS_DMA_CICR_CH0 */
765         s->ch[ch].interrupts = value & 0x003f;
766         break;
767
768     case 0x06:  /* SYS_DMA_CSR_CH0 */
769         return 1;
770
771     case 0x08:  /* SYS_DMA_CSSA_L_CH0 */
772         s->ch[ch].addr[0] &= 0xffff0000;
773         s->ch[ch].addr[0] |= value;
774         break;
775
776     case 0x0a:  /* SYS_DMA_CSSA_U_CH0 */
777         s->ch[ch].addr[0] &= 0x0000ffff;
778         s->ch[ch].addr[0] |= value << 16;
779         break;
780
781     case 0x0c:  /* SYS_DMA_CDSA_L_CH0 */
782         s->ch[ch].addr[1] &= 0xffff0000;
783         s->ch[ch].addr[1] |= value;
784         break;
785
786     case 0x0e:  /* SYS_DMA_CDSA_U_CH0 */
787         s->ch[ch].addr[1] &= 0x0000ffff;
788         s->ch[ch].addr[1] |= value << 16;
789         break;
790
791     case 0x10:  /* SYS_DMA_CEN_CH0 */
792         s->ch[ch].elements = value & 0xffff;
793         break;
794
795     case 0x12:  /* SYS_DMA_CFN_CH0 */
796         s->ch[ch].frames = value & 0xffff;
797         break;
798
799     case 0x14:  /* SYS_DMA_CFI_CH0 */
800         s->ch[ch].frame_index = value & 0xffff;
801         break;
802
803     case 0x16:  /* SYS_DMA_CEI_CH0 */
804         s->ch[ch].element_index = value & 0xffff;
805         break;
806
807     case 0x18:  /* SYS_DMA_CPC_CH0 */
808         return 1;
809
810     default:
811         OMAP_BAD_REG((unsigned long) reg);
812     }
813     return 0;
814 }
815
816 static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
817 {
818     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
819     int i, reg, ch, offset = addr - s->base;
820     uint16_t ret;
821
822     switch (offset) {
823     case 0x000 ... 0x2fe:
824         reg = offset & 0x3f;
825         ch = (offset >> 6) & 0x0f;
826         if (omap_dma_ch_reg_read(s, ch, reg, &ret))
827             break;
828         return ret;
829
830     case 0x300: /* SYS_DMA_LCD_CTRL */
831         i = s->lcd_ch.condition;
832         s->lcd_ch.condition = 0;
833         qemu_irq_lower(s->lcd_ch.irq);
834         return ((s->lcd_ch.src == imif) << 6) | (i << 3) |
835                 (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
836
837     case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
838         return s->lcd_ch.src_f1_top & 0xffff;
839
840     case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
841         return s->lcd_ch.src_f1_top >> 16;
842
843     case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
844         return s->lcd_ch.src_f1_bottom & 0xffff;
845
846     case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
847         return s->lcd_ch.src_f1_bottom >> 16;
848
849     case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
850         return s->lcd_ch.src_f2_top & 0xffff;
851
852     case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
853         return s->lcd_ch.src_f2_top >> 16;
854
855     case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
856         return s->lcd_ch.src_f2_bottom & 0xffff;
857
858     case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
859         return s->lcd_ch.src_f2_bottom >> 16;
860
861     case 0x400: /* SYS_DMA_GCR */
862         return s->gcr;
863     }
864
865     OMAP_BAD_REG(addr);
866     return 0;
867 }
868
869 static void omap_dma_write(void *opaque, target_phys_addr_t addr,
870                 uint32_t value)
871 {
872     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
873     int reg, ch, offset = addr - s->base;
874
875     switch (offset) {
876     case 0x000 ... 0x2fe:
877         reg = offset & 0x3f;
878         ch = (offset >> 6) & 0x0f;
879         if (omap_dma_ch_reg_write(s, ch, reg, value))
880             OMAP_RO_REG(addr);
881         break;
882
883     case 0x300: /* SYS_DMA_LCD_CTRL */
884         s->lcd_ch.src = (value & 0x40) ? imif : emiff;
885         s->lcd_ch.condition = 0;
886         /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
887         s->lcd_ch.interrupts = (value >> 1) & 1;
888         s->lcd_ch.dual = value & 1;
889         break;
890
891     case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
892         s->lcd_ch.src_f1_top &= 0xffff0000;
893         s->lcd_ch.src_f1_top |= 0x0000ffff & value;
894         break;
895
896     case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
897         s->lcd_ch.src_f1_top &= 0x0000ffff;
898         s->lcd_ch.src_f1_top |= value << 16;
899         break;
900
901     case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
902         s->lcd_ch.src_f1_bottom &= 0xffff0000;
903         s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
904         break;
905
906     case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
907         s->lcd_ch.src_f1_bottom &= 0x0000ffff;
908         s->lcd_ch.src_f1_bottom |= value << 16;
909         break;
910
911     case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
912         s->lcd_ch.src_f2_top &= 0xffff0000;
913         s->lcd_ch.src_f2_top |= 0x0000ffff & value;
914         break;
915
916     case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
917         s->lcd_ch.src_f2_top &= 0x0000ffff;
918         s->lcd_ch.src_f2_top |= value << 16;
919         break;
920
921     case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
922         s->lcd_ch.src_f2_bottom &= 0xffff0000;
923         s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
924         break;
925
926     case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
927         s->lcd_ch.src_f2_bottom &= 0x0000ffff;
928         s->lcd_ch.src_f2_bottom |= value << 16;
929         break;
930
931     case 0x400: /* SYS_DMA_GCR */
932         s->gcr = value & 0x000c;
933         break;
934
935     default:
936         OMAP_BAD_REG(addr);
937     }
938 }
939
940 static CPUReadMemoryFunc *omap_dma_readfn[] = {
941     omap_badwidth_read16,
942     omap_dma_read,
943     omap_badwidth_read16,
944 };
945
946 static CPUWriteMemoryFunc *omap_dma_writefn[] = {
947     omap_badwidth_write16,
948     omap_dma_write,
949     omap_badwidth_write16,
950 };
951
952 static void omap_dma_request(void *opaque, int drq, int req)
953 {
954     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
955     /* The request pins are level triggered.  */
956     if (req) {
957         if (~s->drq & (1 << drq)) {
958             s->drq |= 1 << drq;
959             omap_dma_request_run(s, 0, drq);
960         }
961     } else
962         s->drq &= ~(1 << drq);
963 }
964
965 static void omap_dma_clk_update(void *opaque, int line, int on)
966 {
967     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
968
969     if (on) {
970         s->delay = ticks_per_sec >> 5;
971         if (s->run_count)
972             qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
973     } else {
974         s->delay = 0;
975         qemu_del_timer(s->tm);
976     }
977 }
978
979 static void omap_dma_reset(struct omap_dma_s *s)
980 {
981     int i;
982
983     qemu_del_timer(s->tm);
984     s->gcr = 0x0004;
985     s->drq = 0x00000000;
986     s->run_count = 0;
987     s->lcd_ch.src = emiff;
988     s->lcd_ch.condition = 0;
989     s->lcd_ch.interrupts = 0;
990     s->lcd_ch.dual = 0;
991     memset(s->ch, 0, sizeof(s->ch));
992     for (i = 0; i < s->chans; i ++)
993         s->ch[i].interrupts = 0x0003;
994 }
995
996 struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
997                 qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk)
998 {
999     int iomemtype;
1000     struct omap_dma_s *s = (struct omap_dma_s *)
1001             qemu_mallocz(sizeof(struct omap_dma_s));
1002
1003     s->ih = pic;
1004     s->base = base;
1005     s->chans = 9;
1006     s->mpu = mpu;
1007     s->clk = clk;
1008     s->lcd_ch.irq = pic[OMAP_INT_DMA_LCD];
1009     s->lcd_ch.mpu = mpu;
1010     s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1011     omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1012     mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1013     omap_dma_reset(s);
1014     omap_dma_clk_update(s, 0, 1);
1015
1016     iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1017                     omap_dma_writefn, s);
1018     cpu_register_physical_memory(s->base, 0x800, iomemtype);
1019
1020     return s;
1021 }
1022
1023 /* DMA ports */
1024 int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1025                 target_phys_addr_t addr)
1026 {
1027     return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1028 }
1029
1030 int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1031                 target_phys_addr_t addr)
1032 {
1033     return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1034 }
1035
1036 int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1037                 target_phys_addr_t addr)
1038 {
1039     return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1040 }
1041
1042 int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1043                 target_phys_addr_t addr)
1044 {
1045     return addr >= 0xfffb0000 && addr < 0xffff0000;
1046 }
1047
1048 int omap_validate_local_addr(struct omap_mpu_state_s *s,
1049                 target_phys_addr_t addr)
1050 {
1051     return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1052 }
1053
1054 int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1055                 target_phys_addr_t addr)
1056 {
1057     return addr >= 0xe1010000 && addr < 0xe1020004;
1058 }
1059
1060 /* MPU OS timers */
1061 struct omap_mpu_timer_s {
1062     qemu_irq irq;
1063     omap_clk clk;
1064     target_phys_addr_t base;
1065     uint32_t val;
1066     int64_t time;
1067     QEMUTimer *timer;
1068     int64_t rate;
1069     int it_ena;
1070
1071     int enable;
1072     int ptv;
1073     int ar;
1074     int st;
1075     uint32_t reset_val;
1076 };
1077
1078 static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1079 {
1080     uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
1081
1082     if (timer->st && timer->enable && timer->rate)
1083         return timer->val - muldiv64(distance >> (timer->ptv + 1),
1084                         timer->rate, ticks_per_sec);
1085     else
1086         return timer->val;
1087 }
1088
1089 static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1090 {
1091     timer->val = omap_timer_read(timer);
1092     timer->time = qemu_get_clock(vm_clock);
1093 }
1094
1095 static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1096 {
1097     int64_t expires;
1098
1099     if (timer->enable && timer->st && timer->rate) {
1100         timer->val = timer->reset_val;  /* Should skip this on clk enable */
1101         expires = timer->time + muldiv64(timer->val << (timer->ptv + 1),
1102                         ticks_per_sec, timer->rate);
1103         qemu_mod_timer(timer->timer, expires);
1104     } else
1105         qemu_del_timer(timer->timer);
1106 }
1107
1108 static void omap_timer_tick(void *opaque)
1109 {
1110     struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1111     omap_timer_sync(timer);
1112
1113     if (!timer->ar) {
1114         timer->val = 0;
1115         timer->st = 0;
1116     }
1117
1118     if (timer->it_ena)
1119         qemu_irq_raise(timer->irq);
1120     omap_timer_update(timer);
1121 }
1122
1123 static void omap_timer_clk_update(void *opaque, int line, int on)
1124 {
1125     struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1126
1127     omap_timer_sync(timer);
1128     timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1129     omap_timer_update(timer);
1130 }
1131
1132 static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
1133 {
1134     omap_clk_adduser(timer->clk,
1135                     qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
1136     timer->rate = omap_clk_getrate(timer->clk);
1137 }
1138
1139 static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
1140 {
1141     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1142     int offset = addr - s->base;
1143
1144     switch (offset) {
1145     case 0x00:  /* CNTL_TIMER */
1146         return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1147
1148     case 0x04:  /* LOAD_TIM */
1149         break;
1150
1151     case 0x08:  /* READ_TIM */
1152         return omap_timer_read(s);
1153     }
1154
1155     OMAP_BAD_REG(addr);
1156     return 0;
1157 }
1158
1159 static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1160                 uint32_t value)
1161 {
1162     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1163     int offset = addr - s->base;
1164
1165     switch (offset) {
1166     case 0x00:  /* CNTL_TIMER */
1167         omap_timer_sync(s);
1168         s->enable = (value >> 5) & 1;
1169         s->ptv = (value >> 2) & 7;
1170         s->ar = (value >> 1) & 1;
1171         s->st = value & 1;
1172         omap_timer_update(s);
1173         return;
1174
1175     case 0x04:  /* LOAD_TIM */
1176         s->reset_val = value;
1177         return;
1178
1179     case 0x08:  /* READ_TIM */
1180         OMAP_RO_REG(addr);
1181         break;
1182
1183     default:
1184         OMAP_BAD_REG(addr);
1185     }
1186 }
1187
1188 static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1189     omap_badwidth_read32,
1190     omap_badwidth_read32,
1191     omap_mpu_timer_read,
1192 };
1193
1194 static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1195     omap_badwidth_write32,
1196     omap_badwidth_write32,
1197     omap_mpu_timer_write,
1198 };
1199
1200 static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
1201 {
1202     qemu_del_timer(s->timer);
1203     s->enable = 0;
1204     s->reset_val = 31337;
1205     s->val = 0;
1206     s->ptv = 0;
1207     s->ar = 0;
1208     s->st = 0;
1209     s->it_ena = 1;
1210 }
1211
1212 struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1213                 qemu_irq irq, omap_clk clk)
1214 {
1215     int iomemtype;
1216     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1217             qemu_mallocz(sizeof(struct omap_mpu_timer_s));
1218
1219     s->irq = irq;
1220     s->clk = clk;
1221     s->base = base;
1222     s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
1223     omap_mpu_timer_reset(s);
1224     omap_timer_clk_setup(s);
1225
1226     iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
1227                     omap_mpu_timer_writefn, s);
1228     cpu_register_physical_memory(s->base, 0x100, iomemtype);
1229
1230     return s;
1231 }
1232
1233 /* Watchdog timer */
1234 struct omap_watchdog_timer_s {
1235     struct omap_mpu_timer_s timer;
1236     uint8_t last_wr;
1237     int mode;
1238     int free;
1239     int reset;
1240 };
1241
1242 static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
1243 {
1244     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1245     int offset = addr - s->timer.base;
1246
1247     switch (offset) {
1248     case 0x00:  /* CNTL_TIMER */
1249         return (s->timer.ptv << 9) | (s->timer.ar << 8) |
1250                 (s->timer.st << 7) | (s->free << 1);
1251
1252     case 0x04:  /* READ_TIMER */
1253         return omap_timer_read(&s->timer);
1254
1255     case 0x08:  /* TIMER_MODE */
1256         return s->mode << 15;
1257     }
1258
1259     OMAP_BAD_REG(addr);
1260     return 0;
1261 }
1262
1263 static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1264                 uint32_t value)
1265 {
1266     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1267     int offset = addr - s->timer.base;
1268
1269     switch (offset) {
1270     case 0x00:  /* CNTL_TIMER */
1271         omap_timer_sync(&s->timer);
1272         s->timer.ptv = (value >> 9) & 7;
1273         s->timer.ar = (value >> 8) & 1;
1274         s->timer.st = (value >> 7) & 1;
1275         s->free = (value >> 1) & 1;
1276         omap_timer_update(&s->timer);
1277         break;
1278
1279     case 0x04:  /* LOAD_TIMER */
1280         s->timer.reset_val = value & 0xffff;
1281         break;
1282
1283     case 0x08:  /* TIMER_MODE */
1284         if (!s->mode && ((value >> 15) & 1))
1285             omap_clk_get(s->timer.clk);
1286         s->mode |= (value >> 15) & 1;
1287         if (s->last_wr == 0xf5) {
1288             if ((value & 0xff) == 0xa0) {
1289                 s->mode = 0;
1290                 omap_clk_put(s->timer.clk);
1291             } else {
1292                 /* XXX: on T|E hardware somehow this has no effect,
1293                  * on Zire 71 it works as specified.  */
1294                 s->reset = 1;
1295                 qemu_system_reset_request();
1296             }
1297         }
1298         s->last_wr = value & 0xff;
1299         break;
1300
1301     default:
1302         OMAP_BAD_REG(addr);
1303     }
1304 }
1305
1306 static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
1307     omap_badwidth_read16,
1308     omap_wd_timer_read,
1309     omap_badwidth_read16,
1310 };
1311
1312 static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
1313     omap_badwidth_write16,
1314     omap_wd_timer_write,
1315     omap_badwidth_write16,
1316 };
1317
1318 static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
1319 {
1320     qemu_del_timer(s->timer.timer);
1321     if (!s->mode)
1322         omap_clk_get(s->timer.clk);
1323     s->mode = 1;
1324     s->free = 1;
1325     s->reset = 0;
1326     s->timer.enable = 1;
1327     s->timer.it_ena = 1;
1328     s->timer.reset_val = 0xffff;
1329     s->timer.val = 0;
1330     s->timer.st = 0;
1331     s->timer.ptv = 0;
1332     s->timer.ar = 0;
1333     omap_timer_update(&s->timer);
1334 }
1335
1336 struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
1337                 qemu_irq irq, omap_clk clk)
1338 {
1339     int iomemtype;
1340     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
1341             qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
1342
1343     s->timer.irq = irq;
1344     s->timer.clk = clk;
1345     s->timer.base = base;
1346     s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1347     omap_wd_timer_reset(s);
1348     omap_timer_clk_setup(&s->timer);
1349
1350     iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
1351                     omap_wd_timer_writefn, s);
1352     cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
1353
1354     return s;
1355 }
1356
1357 /* 32-kHz timer */
1358 struct omap_32khz_timer_s {
1359     struct omap_mpu_timer_s timer;
1360 };
1361
1362 static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
1363 {
1364     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1365     int offset = addr - s->timer.base;
1366
1367     switch (offset) {
1368     case 0x00:  /* TVR */
1369         return s->timer.reset_val;
1370
1371     case 0x04:  /* TCR */
1372         return omap_timer_read(&s->timer);
1373
1374     case 0x08:  /* CR */
1375         return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
1376
1377     default:
1378         break;
1379     }
1380     OMAP_BAD_REG(addr);
1381     return 0;
1382 }
1383
1384 static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1385                 uint32_t value)
1386 {
1387     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1388     int offset = addr - s->timer.base;
1389
1390     switch (offset) {
1391     case 0x00:  /* TVR */
1392         s->timer.reset_val = value & 0x00ffffff;
1393         break;
1394
1395     case 0x04:  /* TCR */
1396         OMAP_RO_REG(addr);
1397         break;
1398
1399     case 0x08:  /* CR */
1400         s->timer.ar = (value >> 3) & 1;
1401         s->timer.it_ena = (value >> 2) & 1;
1402         if (s->timer.st != (value & 1) || (value & 2)) {
1403             omap_timer_sync(&s->timer);
1404             s->timer.enable = value & 1;
1405             s->timer.st = value & 1;
1406             omap_timer_update(&s->timer);
1407         }
1408         break;
1409
1410     default:
1411         OMAP_BAD_REG(addr);
1412     }
1413 }
1414
1415 static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1416     omap_badwidth_read32,
1417     omap_badwidth_read32,
1418     omap_os_timer_read,
1419 };
1420
1421 static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1422     omap_badwidth_write32,
1423     omap_badwidth_write32,
1424     omap_os_timer_write,
1425 };
1426
1427 static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1428 {
1429     qemu_del_timer(s->timer.timer);
1430     s->timer.enable = 0;
1431     s->timer.it_ena = 0;
1432     s->timer.reset_val = 0x00ffffff;
1433     s->timer.val = 0;
1434     s->timer.st = 0;
1435     s->timer.ptv = 0;
1436     s->timer.ar = 1;
1437 }
1438
1439 struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1440                 qemu_irq irq, omap_clk clk)
1441 {
1442     int iomemtype;
1443     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1444             qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1445
1446     s->timer.irq = irq;
1447     s->timer.clk = clk;
1448     s->timer.base = base;
1449     s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1450     omap_os_timer_reset(s);
1451     omap_timer_clk_setup(&s->timer);
1452
1453     iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1454                     omap_os_timer_writefn, s);
1455     cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
1456
1457     return s;
1458 }
1459
1460 /* Ultra Low-Power Device Module */
1461 static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1462 {
1463     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1464     int offset = addr - s->ulpd_pm_base;
1465     uint16_t ret;
1466
1467     switch (offset) {
1468     case 0x14:  /* IT_STATUS */
1469         ret = s->ulpd_pm_regs[offset >> 2];
1470         s->ulpd_pm_regs[offset >> 2] = 0;
1471         qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1472         return ret;
1473
1474     case 0x18:  /* Reserved */
1475     case 0x1c:  /* Reserved */
1476     case 0x20:  /* Reserved */
1477     case 0x28:  /* Reserved */
1478     case 0x2c:  /* Reserved */
1479         OMAP_BAD_REG(addr);
1480     case 0x00:  /* COUNTER_32_LSB */
1481     case 0x04:  /* COUNTER_32_MSB */
1482     case 0x08:  /* COUNTER_HIGH_FREQ_LSB */
1483     case 0x0c:  /* COUNTER_HIGH_FREQ_MSB */
1484     case 0x10:  /* GAUGING_CTRL */
1485     case 0x24:  /* SETUP_ANALOG_CELL3_ULPD1 */
1486     case 0x30:  /* CLOCK_CTRL */
1487     case 0x34:  /* SOFT_REQ */
1488     case 0x38:  /* COUNTER_32_FIQ */
1489     case 0x3c:  /* DPLL_CTRL */
1490     case 0x40:  /* STATUS_REQ */
1491         /* XXX: check clk::usecount state for every clock */
1492     case 0x48:  /* LOCL_TIME */
1493     case 0x4c:  /* APLL_CTRL */
1494     case 0x50:  /* POWER_CTRL */
1495         return s->ulpd_pm_regs[offset >> 2];
1496     }
1497
1498     OMAP_BAD_REG(addr);
1499     return 0;
1500 }
1501
1502 static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1503                 uint16_t diff, uint16_t value)
1504 {
1505     if (diff & (1 << 4))                                /* USB_MCLK_EN */
1506         omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1507     if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1508         omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1509 }
1510
1511 static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1512                 uint16_t diff, uint16_t value)
1513 {
1514     if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1515         omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1516     if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1517         omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1518     if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1519         omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1520     if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1521         omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1522 }
1523
1524 static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1525                 uint32_t value)
1526 {
1527     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1528     int offset = addr - s->ulpd_pm_base;
1529     int64_t now, ticks;
1530     int div, mult;
1531     static const int bypass_div[4] = { 1, 2, 4, 4 };
1532     uint16_t diff;
1533
1534     switch (offset) {
1535     case 0x00:  /* COUNTER_32_LSB */
1536     case 0x04:  /* COUNTER_32_MSB */
1537     case 0x08:  /* COUNTER_HIGH_FREQ_LSB */
1538     case 0x0c:  /* COUNTER_HIGH_FREQ_MSB */
1539     case 0x14:  /* IT_STATUS */
1540     case 0x40:  /* STATUS_REQ */
1541         OMAP_RO_REG(addr);
1542         break;
1543
1544     case 0x10:  /* GAUGING_CTRL */
1545         /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1546         if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
1547             now = qemu_get_clock(vm_clock);
1548
1549             if (value & 1)
1550                 s->ulpd_gauge_start = now;
1551             else {
1552                 now -= s->ulpd_gauge_start;
1553
1554                 /* 32-kHz ticks */
1555                 ticks = muldiv64(now, 32768, ticks_per_sec);
1556                 s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1557                 s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1558                 if (ticks >> 32)        /* OVERFLOW_32K */
1559                     s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1560
1561                 /* High frequency ticks */
1562                 ticks = muldiv64(now, 12000000, ticks_per_sec);
1563                 s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1564                 s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1565                 if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1566                     s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1567
1568                 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;   /* IT_GAUGING */
1569                 qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1570             }
1571         }
1572         s->ulpd_pm_regs[offset >> 2] = value;
1573         break;
1574
1575     case 0x18:  /* Reserved */
1576     case 0x1c:  /* Reserved */
1577     case 0x20:  /* Reserved */
1578     case 0x28:  /* Reserved */
1579     case 0x2c:  /* Reserved */
1580         OMAP_BAD_REG(addr);
1581     case 0x24:  /* SETUP_ANALOG_CELL3_ULPD1 */
1582     case 0x38:  /* COUNTER_32_FIQ */
1583     case 0x48:  /* LOCL_TIME */
1584     case 0x50:  /* POWER_CTRL */
1585         s->ulpd_pm_regs[offset >> 2] = value;
1586         break;
1587
1588     case 0x30:  /* CLOCK_CTRL */
1589         diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1590         s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
1591         omap_ulpd_clk_update(s, diff, value);
1592         break;
1593
1594     case 0x34:  /* SOFT_REQ */
1595         diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1596         s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
1597         omap_ulpd_req_update(s, diff, value);
1598         break;
1599
1600     case 0x3c:  /* DPLL_CTRL */
1601         /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
1602          * omitted altogether, probably a typo.  */
1603         /* This register has identical semantics with DPLL(1:3) control
1604          * registers, see omap_dpll_write() */
1605         diff = s->ulpd_pm_regs[offset >> 2] & value;
1606         s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
1607         if (diff & (0x3ff << 2)) {
1608             if (value & (1 << 4)) {                     /* PLL_ENABLE */
1609                 div = ((value >> 5) & 3) + 1;           /* PLL_DIV */
1610                 mult = MIN((value >> 7) & 0x1f, 1);     /* PLL_MULT */
1611             } else {
1612                 div = bypass_div[((value >> 2) & 3)];   /* BYPASS_DIV */
1613                 mult = 1;
1614             }
1615             omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
1616         }
1617
1618         /* Enter the desired mode.  */
1619         s->ulpd_pm_regs[offset >> 2] =
1620                 (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
1621                 ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
1622
1623         /* Act as if the lock is restored.  */
1624         s->ulpd_pm_regs[offset >> 2] |= 2;
1625         break;
1626
1627     case 0x4c:  /* APLL_CTRL */
1628         diff = s->ulpd_pm_regs[offset >> 2] & value;
1629         s->ulpd_pm_regs[offset >> 2] = value & 0xf;
1630         if (diff & (1 << 0))                            /* APLL_NDPLL_SWITCH */
1631             omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1632                                     (value & (1 << 0)) ? "apll" : "dpll4"));
1633         break;
1634
1635     default:
1636         OMAP_BAD_REG(addr);
1637     }
1638 }
1639
1640 static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1641     omap_badwidth_read16,
1642     omap_ulpd_pm_read,
1643     omap_badwidth_read16,
1644 };
1645
1646 static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1647     omap_badwidth_write16,
1648     omap_ulpd_pm_write,
1649     omap_badwidth_write16,
1650 };
1651
1652 static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
1653 {
1654     mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
1655     mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
1656     mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
1657     mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
1658     mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
1659     mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
1660     mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
1661     mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
1662     mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
1663     mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
1664     mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
1665     omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
1666     mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
1667     omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
1668     mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
1669     mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
1670     mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
1671     mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
1672     mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
1673     mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
1674     mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
1675     omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
1676     omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
1677 }
1678
1679 static void omap_ulpd_pm_init(target_phys_addr_t base,
1680                 struct omap_mpu_state_s *mpu)
1681 {
1682     int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1683                     omap_ulpd_pm_writefn, mpu);
1684
1685     mpu->ulpd_pm_base = base;
1686     cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1687     omap_ulpd_pm_reset(mpu);
1688 }
1689
1690 /* OMAP Pin Configuration */
1691 static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1692 {
1693     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1694     int offset = addr - s->pin_cfg_base;
1695
1696     switch (offset) {
1697     case 0x00:  /* FUNC_MUX_CTRL_0 */
1698     case 0x04:  /* FUNC_MUX_CTRL_1 */
1699     case 0x08:  /* FUNC_MUX_CTRL_2 */
1700         return s->func_mux_ctrl[offset >> 2];
1701
1702     case 0x0c:  /* COMP_MODE_CTRL_0 */
1703         return s->comp_mode_ctrl[0];
1704
1705     case 0x10:  /* FUNC_MUX_CTRL_3 */
1706     case 0x14:  /* FUNC_MUX_CTRL_4 */
1707     case 0x18:  /* FUNC_MUX_CTRL_5 */
1708     case 0x1c:  /* FUNC_MUX_CTRL_6 */
1709     case 0x20:  /* FUNC_MUX_CTRL_7 */
1710     case 0x24:  /* FUNC_MUX_CTRL_8 */
1711     case 0x28:  /* FUNC_MUX_CTRL_9 */
1712     case 0x2c:  /* FUNC_MUX_CTRL_A */
1713     case 0x30:  /* FUNC_MUX_CTRL_B */
1714     case 0x34:  /* FUNC_MUX_CTRL_C */
1715     case 0x38:  /* FUNC_MUX_CTRL_D */
1716         return s->func_mux_ctrl[(offset >> 2) - 1];
1717
1718     case 0x40:  /* PULL_DWN_CTRL_0 */
1719     case 0x44:  /* PULL_DWN_CTRL_1 */
1720     case 0x48:  /* PULL_DWN_CTRL_2 */
1721     case 0x4c:  /* PULL_DWN_CTRL_3 */
1722         return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1723
1724     case 0x50:  /* GATE_INH_CTRL_0 */
1725         return s->gate_inh_ctrl[0];
1726
1727     case 0x60:  /* VOLTAGE_CTRL_0 */
1728         return s->voltage_ctrl[0];
1729
1730     case 0x70:  /* TEST_DBG_CTRL_0 */
1731         return s->test_dbg_ctrl[0];
1732
1733     case 0x80:  /* MOD_CONF_CTRL_0 */
1734         return s->mod_conf_ctrl[0];
1735     }
1736
1737     OMAP_BAD_REG(addr);
1738     return 0;
1739 }
1740
1741 static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1742                 uint32_t diff, uint32_t value)
1743 {
1744     if (s->compat1509) {
1745         if (diff & (1 << 9))                    /* BLUETOOTH */
1746             omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1747                             (~value >> 9) & 1);
1748         if (diff & (1 << 7))                    /* USB.CLKO */
1749             omap_clk_onoff(omap_findclk(s, "usb.clko"),
1750                             (value >> 7) & 1);
1751     }
1752 }
1753
1754 static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1755                 uint32_t diff, uint32_t value)
1756 {
1757     if (s->compat1509) {
1758         if (diff & (1 << 31))                   /* MCBSP3_CLK_HIZ_DI */
1759             omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1760                             (value >> 31) & 1);
1761         if (diff & (1 << 1))                    /* CLK32K */
1762             omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1763                             (~value >> 1) & 1);
1764     }
1765 }
1766
1767 static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1768                 uint32_t diff, uint32_t value)
1769 {
1770     if (diff & (1 << 31))                       /* CONF_MOD_UART3_CLK_MODE_R */
1771          omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1772                          omap_findclk(s, ((value >> 31) & 1) ?
1773                                  "ck_48m" : "armper_ck"));
1774     if (diff & (1 << 30))                       /* CONF_MOD_UART2_CLK_MODE_R */
1775          omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1776                          omap_findclk(s, ((value >> 30) & 1) ?
1777                                  "ck_48m" : "armper_ck"));
1778     if (diff & (1 << 29))                       /* CONF_MOD_UART1_CLK_MODE_R */
1779          omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1780                          omap_findclk(s, ((value >> 29) & 1) ?
1781                                  "ck_48m" : "armper_ck"));
1782     if (diff & (1 << 23))                       /* CONF_MOD_MMC_SD_CLK_REQ_R */
1783          omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1784                          omap_findclk(s, ((value >> 23) & 1) ?
1785                                  "ck_48m" : "armper_ck"));
1786     if (diff & (1 << 12))                       /* CONF_MOD_COM_MCLK_12_48_S */
1787          omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1788                          omap_findclk(s, ((value >> 12) & 1) ?
1789                                  "ck_48m" : "armper_ck"));
1790     if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1791          omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1792 }
1793
1794 static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1795                 uint32_t value)
1796 {
1797     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1798     int offset = addr - s->pin_cfg_base;
1799     uint32_t diff;
1800
1801     switch (offset) {
1802     case 0x00:  /* FUNC_MUX_CTRL_0 */
1803         diff = s->func_mux_ctrl[offset >> 2] ^ value;
1804         s->func_mux_ctrl[offset >> 2] = value;
1805         omap_pin_funcmux0_update(s, diff, value);
1806         return;
1807
1808     case 0x04:  /* FUNC_MUX_CTRL_1 */
1809         diff = s->func_mux_ctrl[offset >> 2] ^ value;
1810         s->func_mux_ctrl[offset >> 2] = value;
1811         omap_pin_funcmux1_update(s, diff, value);
1812         return;
1813
1814     case 0x08:  /* FUNC_MUX_CTRL_2 */
1815         s->func_mux_ctrl[offset >> 2] = value;
1816         return;
1817
1818     case 0x0c:  /* COMP_MODE_CTRL_0 */
1819         s->comp_mode_ctrl[0] = value;
1820         s->compat1509 = (value != 0x0000eaef);
1821         omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1822         omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1823         return;
1824
1825     case 0x10:  /* FUNC_MUX_CTRL_3 */
1826     case 0x14:  /* FUNC_MUX_CTRL_4 */
1827     case 0x18:  /* FUNC_MUX_CTRL_5 */
1828     case 0x1c:  /* FUNC_MUX_CTRL_6 */
1829     case 0x20:  /* FUNC_MUX_CTRL_7 */
1830     case 0x24:  /* FUNC_MUX_CTRL_8 */
1831     case 0x28:  /* FUNC_MUX_CTRL_9 */
1832     case 0x2c:  /* FUNC_MUX_CTRL_A */
1833     case 0x30:  /* FUNC_MUX_CTRL_B */
1834     case 0x34:  /* FUNC_MUX_CTRL_C */
1835     case 0x38:  /* FUNC_MUX_CTRL_D */
1836         s->func_mux_ctrl[(offset >> 2) - 1] = value;
1837         return;
1838
1839     case 0x40:  /* PULL_DWN_CTRL_0 */
1840     case 0x44:  /* PULL_DWN_CTRL_1 */
1841     case 0x48:  /* PULL_DWN_CTRL_2 */
1842     case 0x4c:  /* PULL_DWN_CTRL_3 */
1843         s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1844         return;
1845
1846     case 0x50:  /* GATE_INH_CTRL_0 */
1847         s->gate_inh_ctrl[0] = value;
1848         return;
1849
1850     case 0x60:  /* VOLTAGE_CTRL_0 */
1851         s->voltage_ctrl[0] = value;
1852         return;
1853
1854     case 0x70:  /* TEST_DBG_CTRL_0 */
1855         s->test_dbg_ctrl[0] = value;
1856         return;
1857
1858     case 0x80:  /* MOD_CONF_CTRL_0 */
1859         diff = s->mod_conf_ctrl[0] ^ value;
1860         s->mod_conf_ctrl[0] = value;
1861         omap_pin_modconf1_update(s, diff, value);
1862         return;
1863
1864     default:
1865         OMAP_BAD_REG(addr);
1866     }
1867 }
1868
1869 static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1870     omap_badwidth_read32,
1871     omap_badwidth_read32,
1872     omap_pin_cfg_read,
1873 };
1874
1875 static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1876     omap_badwidth_write32,
1877     omap_badwidth_write32,
1878     omap_pin_cfg_write,
1879 };
1880
1881 static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1882 {
1883     /* Start in Compatibility Mode.  */
1884     mpu->compat1509 = 1;
1885     omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1886     omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1887     omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1888     memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1889     memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1890     memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1891     memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1892     memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1893     memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1894     memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1895 }
1896
1897 static void omap_pin_cfg_init(target_phys_addr_t base,
1898                 struct omap_mpu_state_s *mpu)
1899 {
1900     int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1901                     omap_pin_cfg_writefn, mpu);
1902
1903     mpu->pin_cfg_base = base;
1904     cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1905     omap_pin_cfg_reset(mpu);
1906 }
1907
1908 /* Device Identification, Die Identification */
1909 static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1910 {
1911     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1912
1913     switch (addr) {
1914     case 0xfffe1800:    /* DIE_ID_LSB */
1915         return 0xc9581f0e;
1916     case 0xfffe1804:    /* DIE_ID_MSB */
1917         return 0xa8858bfa;
1918
1919     case 0xfffe2000:    /* PRODUCT_ID_LSB */
1920         return 0x00aaaafc;
1921     case 0xfffe2004:    /* PRODUCT_ID_MSB */
1922         return 0xcafeb574;
1923
1924     case 0xfffed400:    /* JTAG_ID_LSB */
1925         switch (s->mpu_model) {
1926         case omap310:
1927             return 0x03310315;
1928         case omap1510:
1929             return 0x03310115;
1930         }
1931         break;
1932
1933     case 0xfffed404:    /* JTAG_ID_MSB */
1934         switch (s->mpu_model) {
1935         case omap310:
1936             return 0xfb57402f;
1937         case omap1510:
1938             return 0xfb47002f;
1939         }
1940         break;
1941     }
1942
1943     OMAP_BAD_REG(addr);
1944     return 0;
1945 }
1946
1947 static void omap_id_write(void *opaque, target_phys_addr_t addr,
1948                 uint32_t value)
1949 {
1950     OMAP_BAD_REG(addr);
1951 }
1952
1953 static CPUReadMemoryFunc *omap_id_readfn[] = {
1954     omap_badwidth_read32,
1955     omap_badwidth_read32,
1956     omap_id_read,
1957 };
1958
1959 static CPUWriteMemoryFunc *omap_id_writefn[] = {
1960     omap_badwidth_write32,
1961     omap_badwidth_write32,
1962     omap_id_write,
1963 };
1964
1965 static void omap_id_init(struct omap_mpu_state_s *mpu)
1966 {
1967     int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
1968                     omap_id_writefn, mpu);
1969     cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
1970     cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
1971     if (!cpu_is_omap15xx(mpu))
1972         cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
1973 }
1974
1975 /* MPUI Control (Dummy) */
1976 static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1977 {
1978     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1979     int offset = addr - s->mpui_base;
1980
1981     switch (offset) {
1982     case 0x00:  /* CTRL */
1983         return s->mpui_ctrl;
1984     case 0x04:  /* DEBUG_ADDR */
1985         return 0x01ffffff;
1986     case 0x08:  /* DEBUG_DATA */
1987         return 0xffffffff;
1988     case 0x0c:  /* DEBUG_FLAG */
1989         return 0x00000800;
1990     case 0x10:  /* STATUS */
1991         return 0x00000000;
1992
1993     /* Not in OMAP310 */
1994     case 0x14:  /* DSP_STATUS */
1995     case 0x18:  /* DSP_BOOT_CONFIG */
1996         return 0x00000000;
1997     case 0x1c:  /* DSP_MPUI_CONFIG */
1998         return 0x0000ffff;
1999     }
2000
2001     OMAP_BAD_REG(addr);
2002     return 0;
2003 }
2004
2005 static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2006                 uint32_t value)
2007 {
2008     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2009     int offset = addr - s->mpui_base;
2010
2011     switch (offset) {
2012     case 0x00:  /* CTRL */
2013         s->mpui_ctrl = value & 0x007fffff;
2014         break;
2015
2016     case 0x04:  /* DEBUG_ADDR */
2017     case 0x08:  /* DEBUG_DATA */
2018     case 0x0c:  /* DEBUG_FLAG */
2019     case 0x10:  /* STATUS */
2020     /* Not in OMAP310 */
2021     case 0x14:  /* DSP_STATUS */
2022         OMAP_RO_REG(addr);
2023     case 0x18:  /* DSP_BOOT_CONFIG */
2024     case 0x1c:  /* DSP_MPUI_CONFIG */
2025         break;
2026
2027     default:
2028         OMAP_BAD_REG(addr);
2029     }
2030 }
2031
2032 static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2033     omap_badwidth_read32,
2034     omap_badwidth_read32,
2035     omap_mpui_read,
2036 };
2037
2038 static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2039     omap_badwidth_write32,
2040     omap_badwidth_write32,
2041     omap_mpui_write,
2042 };
2043
2044 static void omap_mpui_reset(struct omap_mpu_state_s *s)
2045 {
2046     s->mpui_ctrl = 0x0003ff1b;
2047 }
2048
2049 static void omap_mpui_init(target_phys_addr_t base,
2050                 struct omap_mpu_state_s *mpu)
2051 {
2052     int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2053                     omap_mpui_writefn, mpu);
2054
2055     mpu->mpui_base = base;
2056     cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2057
2058     omap_mpui_reset(mpu);
2059 }
2060
2061 /* TIPB Bridges */
2062 struct omap_tipb_bridge_s {
2063     target_phys_addr_t base;
2064     qemu_irq abort;
2065
2066     int width_intr;
2067     uint16_t control;
2068     uint16_t alloc;
2069     uint16_t buffer;
2070     uint16_t enh_control;
2071 };
2072
2073 static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
2074 {
2075     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2076     int offset = addr - s->base;
2077
2078     switch (offset) {
2079     case 0x00:  /* TIPB_CNTL */
2080         return s->control;
2081     case 0x04:  /* TIPB_BUS_ALLOC */
2082         return s->alloc;
2083     case 0x08:  /* MPU_TIPB_CNTL */
2084         return s->buffer;
2085     case 0x0c:  /* ENHANCED_TIPB_CNTL */
2086         return s->enh_control;
2087     case 0x10:  /* ADDRESS_DBG */
2088     case 0x14:  /* DATA_DEBUG_LOW */
2089     case 0x18:  /* DATA_DEBUG_HIGH */
2090         return 0xffff;
2091     case 0x1c:  /* DEBUG_CNTR_SIG */
2092         return 0x00f8;
2093     }
2094
2095     OMAP_BAD_REG(addr);
2096     return 0;
2097 }
2098
2099 static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
2100                 uint32_t value)
2101 {
2102     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2103     int offset = addr - s->base;
2104
2105     switch (offset) {
2106     case 0x00:  /* TIPB_CNTL */
2107         s->control = value & 0xffff;
2108         break;
2109
2110     case 0x04:  /* TIPB_BUS_ALLOC */
2111         s->alloc = value & 0x003f;
2112         break;
2113
2114     case 0x08:  /* MPU_TIPB_CNTL */
2115         s->buffer = value & 0x0003;
2116         break;
2117
2118     case 0x0c:  /* ENHANCED_TIPB_CNTL */
2119         s->width_intr = !(value & 2);
2120         s->enh_control = value & 0x000f;
2121         break;
2122
2123     case 0x10:  /* ADDRESS_DBG */
2124     case 0x14:  /* DATA_DEBUG_LOW */
2125     case 0x18:  /* DATA_DEBUG_HIGH */
2126     case 0x1c:  /* DEBUG_CNTR_SIG */
2127         OMAP_RO_REG(addr);
2128         break;
2129
2130     default:
2131         OMAP_BAD_REG(addr);
2132     }
2133 }
2134
2135 static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2136     omap_badwidth_read16,
2137     omap_tipb_bridge_read,
2138     omap_tipb_bridge_read,
2139 };
2140
2141 static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2142     omap_badwidth_write16,
2143     omap_tipb_bridge_write,
2144     omap_tipb_bridge_write,
2145 };
2146
2147 static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2148 {
2149     s->control = 0xffff;
2150     s->alloc = 0x0009;
2151     s->buffer = 0x0000;
2152     s->enh_control = 0x000f;
2153 }
2154
2155 struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2156                 qemu_irq abort_irq, omap_clk clk)
2157 {
2158     int iomemtype;
2159     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2160             qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2161
2162     s->abort = abort_irq;
2163     s->base = base;
2164     omap_tipb_bridge_reset(s);
2165
2166     iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
2167                     omap_tipb_bridge_writefn, s);
2168     cpu_register_physical_memory(s->base, 0x100, iomemtype);
2169
2170     return s;
2171 }
2172
2173 /* Dummy Traffic Controller's Memory Interface */
2174 static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2175 {
2176     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2177     int offset = addr - s->tcmi_base;
2178     uint32_t ret;
2179
2180     switch (offset) {
2181     case 0xfffecc00:    /* IMIF_PRIO */
2182     case 0xfffecc04:    /* EMIFS_PRIO */
2183     case 0xfffecc08:    /* EMIFF_PRIO */
2184     case 0xfffecc0c:    /* EMIFS_CONFIG */
2185     case 0xfffecc10:    /* EMIFS_CS0_CONFIG */
2186     case 0xfffecc14:    /* EMIFS_CS1_CONFIG */
2187     case 0xfffecc18:    /* EMIFS_CS2_CONFIG */
2188     case 0xfffecc1c:    /* EMIFS_CS3_CONFIG */
2189     case 0xfffecc24:    /* EMIFF_MRS */
2190     case 0xfffecc28:    /* TIMEOUT1 */
2191     case 0xfffecc2c:    /* TIMEOUT2 */
2192     case 0xfffecc30:    /* TIMEOUT3 */
2193     case 0xfffecc3c:    /* EMIFF_SDRAM_CONFIG_2 */
2194     case 0xfffecc40:    /* EMIFS_CFG_DYN_WAIT */
2195         return s->tcmi_regs[offset >> 2];
2196
2197     case 0xfffecc20:    /* EMIFF_SDRAM_CONFIG */
2198         ret = s->tcmi_regs[offset >> 2];
2199         s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2200         /* XXX: We can try using the VGA_DIRTY flag for this */
2201         return ret;
2202     }
2203
2204     OMAP_BAD_REG(addr);
2205     return 0;
2206 }
2207
2208 static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2209                 uint32_t value)
2210 {
2211     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2212     int offset = addr - s->tcmi_base;
2213
2214     switch (offset) {
2215     case 0xfffecc00:    /* IMIF_PRIO */
2216     case 0xfffecc04:    /* EMIFS_PRIO */
2217     case 0xfffecc08:    /* EMIFF_PRIO */
2218     case 0xfffecc10:    /* EMIFS_CS0_CONFIG */
2219     case 0xfffecc14:    /* EMIFS_CS1_CONFIG */
2220     case 0xfffecc18:    /* EMIFS_CS2_CONFIG */
2221     case 0xfffecc1c:    /* EMIFS_CS3_CONFIG */
2222     case 0xfffecc20:    /* EMIFF_SDRAM_CONFIG */
2223     case 0xfffecc24:    /* EMIFF_MRS */
2224     case 0xfffecc28:    /* TIMEOUT1 */
2225     case 0xfffecc2c:    /* TIMEOUT2 */
2226     case 0xfffecc30:    /* TIMEOUT3 */
2227     case 0xfffecc3c:    /* EMIFF_SDRAM_CONFIG_2 */
2228     case 0xfffecc40:    /* EMIFS_CFG_DYN_WAIT */
2229         s->tcmi_regs[offset >> 2] = value;
2230         break;
2231     case 0xfffecc0c:    /* EMIFS_CONFIG */
2232         s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
2233         break;
2234
2235     default:
2236         OMAP_BAD_REG(addr);
2237     }
2238 }
2239
2240 static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2241     omap_badwidth_read32,
2242     omap_badwidth_read32,
2243     omap_tcmi_read,
2244 };
2245
2246 static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2247     omap_badwidth_write32,
2248     omap_badwidth_write32,
2249     omap_tcmi_write,
2250 };
2251
2252 static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
2253 {
2254     mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
2255     mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
2256     mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
2257     mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
2258     mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
2259     mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
2260     mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
2261     mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
2262     mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
2263     mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
2264     mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
2265     mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
2266     mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
2267     mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
2268     mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
2269 }
2270
2271 static void omap_tcmi_init(target_phys_addr_t base,
2272                 struct omap_mpu_state_s *mpu)
2273 {
2274     int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2275                     omap_tcmi_writefn, mpu);
2276
2277     mpu->tcmi_base = base;
2278     cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2279     omap_tcmi_reset(mpu);
2280 }
2281
2282 /* Digital phase-locked loops control */
2283 static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2284 {
2285     struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2286     int offset = addr - s->base;
2287
2288     if (offset == 0x00) /* CTL_REG */
2289         return s->mode;
2290
2291     OMAP_BAD_REG(addr);
2292     return 0;
2293 }
2294
2295 static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2296                 uint32_t value)
2297 {
2298     struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2299     uint16_t diff;
2300     int offset = addr - s->base;
2301     static const int bypass_div[4] = { 1, 2, 4, 4 };
2302     int div, mult;
2303
2304     if (offset == 0x00) {       /* CTL_REG */
2305         /* See omap_ulpd_pm_write() too */
2306         diff = s->mode & value;
2307         s->mode = value & 0x2fff;
2308         if (diff & (0x3ff << 2)) {
2309             if (value & (1 << 4)) {                     /* PLL_ENABLE */
2310                 div = ((value >> 5) & 3) + 1;           /* PLL_DIV */
2311                 mult = MIN((value >> 7) & 0x1f, 1);     /* PLL_MULT */
2312             } else {
2313                 div = bypass_div[((value >> 2) & 3)];   /* BYPASS_DIV */
2314                 mult = 1;
2315             }
2316             omap_clk_setrate(s->dpll, div, mult);
2317         }
2318
2319         /* Enter the desired mode.  */
2320         s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
2321
2322         /* Act as if the lock is restored.  */
2323         s->mode |= 2;
2324     } else {
2325         OMAP_BAD_REG(addr);
2326     }
2327 }
2328
2329 static CPUReadMemoryFunc *omap_dpll_readfn[] = {
2330     omap_badwidth_read16,
2331     omap_dpll_read,
2332     omap_badwidth_read16,
2333 };
2334
2335 static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
2336     omap_badwidth_write16,
2337     omap_dpll_write,
2338     omap_badwidth_write16,
2339 };
2340
2341 static void omap_dpll_reset(struct dpll_ctl_s *s)
2342 {
2343     s->mode = 0x2002;
2344     omap_clk_setrate(s->dpll, 1, 1);
2345 }
2346
2347 static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
2348                 omap_clk clk)
2349 {
2350     int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
2351                     omap_dpll_writefn, s);
2352
2353     s->base = base;
2354     s->dpll = clk;
2355     omap_dpll_reset(s);
2356
2357     cpu_register_physical_memory(s->base, 0x100, iomemtype);
2358 }
2359
2360 /* UARTs */
2361 struct omap_uart_s {
2362     SerialState *serial; /* TODO */
2363 };
2364
2365 static void omap_uart_reset(struct omap_uart_s *s)
2366 {
2367 }
2368
2369 struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2370                 qemu_irq irq, omap_clk clk, CharDriverState *chr)
2371 {
2372     struct omap_uart_s *s = (struct omap_uart_s *)
2373             qemu_mallocz(sizeof(struct omap_uart_s));
2374     if (chr)
2375         s->serial = serial_mm_init(base, 2, irq, chr, 1);
2376     return s;
2377 }
2378
2379 /* MPU Clock/Reset/Power Mode Control */
2380 static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2381 {
2382     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2383     int offset = addr - s->clkm.mpu_base;
2384
2385     switch (offset) {
2386     case 0x00:  /* ARM_CKCTL */
2387         return s->clkm.arm_ckctl;
2388
2389     case 0x04:  /* ARM_IDLECT1 */
2390         return s->clkm.arm_idlect1;
2391
2392     case 0x08:  /* ARM_IDLECT2 */
2393         return s->clkm.arm_idlect2;
2394
2395     case 0x0c:  /* ARM_EWUPCT */
2396         return s->clkm.arm_ewupct;
2397
2398     case 0x10:  /* ARM_RSTCT1 */
2399         return s->clkm.arm_rstct1;
2400
2401     case 0x14:  /* ARM_RSTCT2 */
2402         return s->clkm.arm_rstct2;
2403
2404     case 0x18:  /* ARM_SYSST */
2405         return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start;
2406
2407     case 0x1c:  /* ARM_CKOUT1 */
2408         return s->clkm.arm_ckout1;
2409
2410     case 0x20:  /* ARM_CKOUT2 */
2411         break;
2412     }
2413
2414     OMAP_BAD_REG(addr);
2415     return 0;
2416 }
2417
2418 static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2419                 uint16_t diff, uint16_t value)
2420 {
2421     omap_clk clk;
2422
2423     if (diff & (1 << 14)) {                             /* ARM_INTHCK_SEL */
2424         if (value & (1 << 14))
2425             /* Reserved */;
2426         else {
2427             clk = omap_findclk(s, "arminth_ck");
2428             omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2429         }
2430     }
2431     if (diff & (1 << 12)) {                             /* ARM_TIMXO */
2432         clk = omap_findclk(s, "armtim_ck");
2433         if (value & (1 << 12))
2434             omap_clk_reparent(clk, omap_findclk(s, "clkin"));
2435         else
2436             omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2437     }
2438     /* XXX: en_dspck */
2439     if (diff & (3 << 10)) {                             /* DSPMMUDIV */
2440         clk = omap_findclk(s, "dspmmu_ck");
2441         omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
2442     }
2443     if (diff & (3 << 8)) {                              /* TCDIV */
2444         clk = omap_findclk(s, "tc_ck");
2445         omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2446     }
2447     if (diff & (3 << 6)) {                              /* DSPDIV */
2448         clk = omap_findclk(s, "dsp_ck");
2449         omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2450     }
2451     if (diff & (3 << 4)) {                              /* ARMDIV */
2452         clk = omap_findclk(s, "arm_ck");
2453         omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2454     }
2455     if (diff & (3 << 2)) {                              /* LCDDIV */
2456         clk = omap_findclk(s, "lcd_ck");
2457         omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2458     }
2459     if (diff & (3 << 0)) {                              /* PERDIV */
2460         clk = omap_findclk(s, "armper_ck");
2461         omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2462     }
2463 }
2464
2465 static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2466                 uint16_t diff, uint16_t value)
2467 {
2468     omap_clk clk;
2469
2470     if (value & (1 << 11))                              /* SETARM_IDLE */
2471         cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2472     if (!(value & (1 << 10)))                           /* WKUP_MODE */
2473         qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */
2474
2475 #define SET_CANIDLE(clock, bit)                         \
2476     if (diff & (1 << bit)) {                            \
2477         clk = omap_findclk(s, clock);                   \
2478         omap_clk_canidle(clk, (value >> bit) & 1);      \
2479     }
2480     SET_CANIDLE("mpuwd_ck", 0)                          /* IDLWDT_ARM */
2481     SET_CANIDLE("armxor_ck", 1)                         /* IDLXORP_ARM */
2482     SET_CANIDLE("mpuper_ck", 2)                         /* IDLPER_ARM */
2483     SET_CANIDLE("lcd_ck", 3)                            /* IDLLCD_ARM */
2484     SET_CANIDLE("lb_ck", 4)                             /* IDLLB_ARM */
2485     SET_CANIDLE("hsab_ck", 5)                           /* IDLHSAB_ARM */
2486     SET_CANIDLE("tipb_ck", 6)                           /* IDLIF_ARM */
2487     SET_CANIDLE("dma_ck", 6)                            /* IDLIF_ARM */
2488     SET_CANIDLE("tc_ck", 6)                             /* IDLIF_ARM */
2489     SET_CANIDLE("dpll1", 7)                             /* IDLDPLL_ARM */
2490     SET_CANIDLE("dpll2", 7)                             /* IDLDPLL_ARM */
2491     SET_CANIDLE("dpll3", 7)                             /* IDLDPLL_ARM */
2492     SET_CANIDLE("mpui_ck", 8)                           /* IDLAPI_ARM */
2493     SET_CANIDLE("armtim_ck", 9)                         /* IDLTIM_ARM */
2494 }
2495
2496 static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2497                 uint16_t diff, uint16_t value)
2498 {
2499     omap_clk clk;
2500
2501 #define SET_ONOFF(clock, bit)                           \
2502     if (diff & (1 << bit)) {                            \
2503         clk = omap_findclk(s, clock);                   \
2504         omap_clk_onoff(clk, (value >> bit) & 1);        \
2505     }
2506     SET_ONOFF("mpuwd_ck", 0)                            /* EN_WDTCK */
2507     SET_ONOFF("armxor_ck", 1)                           /* EN_XORPCK */
2508     SET_ONOFF("mpuper_ck", 2)                           /* EN_PERCK */
2509     SET_ONOFF("lcd_ck", 3)                              /* EN_LCDCK */
2510     SET_ONOFF("lb_ck", 4)                               /* EN_LBCK */
2511     SET_ONOFF("hsab_ck", 5)                             /* EN_HSABCK */
2512     SET_ONOFF("mpui_ck", 6)                             /* EN_APICK */
2513     SET_ONOFF("armtim_ck", 7)                           /* EN_TIMCK */
2514     SET_CANIDLE("dma_ck", 8)                            /* DMACK_REQ */
2515     SET_ONOFF("arm_gpio_ck", 9)                         /* EN_GPIOCK */
2516     SET_ONOFF("lbfree_ck", 10)                          /* EN_LBFREECK */
2517 }
2518
2519 static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2520                 uint16_t diff, uint16_t value)
2521 {
2522     omap_clk clk;
2523
2524     if (diff & (3 << 4)) {                              /* TCLKOUT */
2525         clk = omap_findclk(s, "tclk_out");
2526         switch ((value >> 4) & 3) {
2527         case 1:
2528             omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
2529             omap_clk_onoff(clk, 1);
2530             break;
2531         case 2:
2532             omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2533             omap_clk_onoff(clk, 1);
2534             break;
2535         default:
2536             omap_clk_onoff(clk, 0);
2537         }
2538     }
2539     if (diff & (3 << 2)) {                              /* DCLKOUT */
2540         clk = omap_findclk(s, "dclk_out");
2541         switch ((value >> 2) & 3) {
2542         case 0:
2543             omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
2544             break;
2545         case 1:
2546             omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
2547             break;
2548         case 2:
2549             omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
2550             break;
2551         case 3:
2552             omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2553             break;
2554         }
2555     }
2556     if (diff & (3 << 0)) {                              /* ACLKOUT */
2557         clk = omap_findclk(s, "aclk_out");
2558         switch ((value >> 0) & 3) {
2559         case 1:
2560             omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2561             omap_clk_onoff(clk, 1);
2562             break;
2563         case 2:
2564             omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
2565             omap_clk_onoff(clk, 1);
2566             break;
2567         case 3:
2568             omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2569             omap_clk_onoff(clk, 1);
2570             break;
2571         default:
2572             omap_clk_onoff(clk, 0);
2573         }
2574     }
2575 }
2576
2577 static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2578                 uint32_t value)
2579 {
2580     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2581     int offset = addr - s->clkm.mpu_base;
2582     uint16_t diff;
2583     omap_clk clk;
2584     static const char *clkschemename[8] = {
2585         "fully synchronous", "fully asynchronous", "synchronous scalable",
2586         "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2587     };
2588
2589     switch (offset) {
2590     case 0x00:  /* ARM_CKCTL */
2591         diff = s->clkm.arm_ckctl ^ value;
2592         s->clkm.arm_ckctl = value & 0x7fff;
2593         omap_clkm_ckctl_update(s, diff, value);
2594         return;
2595
2596     case 0x04:  /* ARM_IDLECT1 */
2597         diff = s->clkm.arm_idlect1 ^ value;
2598         s->clkm.arm_idlect1 = value & 0x0fff;
2599         omap_clkm_idlect1_update(s, diff, value);
2600         return;
2601
2602     case 0x08:  /* ARM_IDLECT2 */
2603         diff = s->clkm.arm_idlect2 ^ value;
2604         s->clkm.arm_idlect2 = value & 0x07ff;
2605         omap_clkm_idlect2_update(s, diff, value);
2606         return;
2607
2608     case 0x0c:  /* ARM_EWUPCT */
2609         diff = s->clkm.arm_ewupct ^ value;
2610         s->clkm.arm_ewupct = value & 0x003f;
2611         return;
2612
2613     case 0x10:  /* ARM_RSTCT1 */
2614         diff = s->clkm.arm_rstct1 ^ value;
2615         s->clkm.arm_rstct1 = value & 0x0007;
2616         if (value & 9) {
2617             qemu_system_reset_request();
2618             s->clkm.cold_start = 0xa;
2619         }
2620         if (diff & ~value & 4) {                                /* DSP_RST */
2621             omap_mpui_reset(s);
2622             omap_tipb_bridge_reset(s->private_tipb);
2623             omap_tipb_bridge_reset(s->public_tipb);
2624         }
2625         if (diff & 2) {                                         /* DSP_EN */
2626             clk = omap_findclk(s, "dsp_ck");
2627             omap_clk_canidle(clk, (~value >> 1) & 1);
2628         }
2629         return;
2630
2631     case 0x14:  /* ARM_RSTCT2 */
2632         s->clkm.arm_rstct2 = value & 0x0001;
2633         return;
2634
2635     case 0x18:  /* ARM_SYSST */
2636         if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2637             s->clkm.clocking_scheme = (value >> 11) & 7;
2638             printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2639                             clkschemename[s->clkm.clocking_scheme]);
2640         }
2641         s->clkm.cold_start &= value & 0x3f;
2642         return;
2643
2644     case 0x1c:  /* ARM_CKOUT1 */
2645         diff = s->clkm.arm_ckout1 ^ value;
2646         s->clkm.arm_ckout1 = value & 0x003f;
2647         omap_clkm_ckout1_update(s, diff, value);
2648         return;
2649
2650     case 0x20:  /* ARM_CKOUT2 */
2651     default:
2652         OMAP_BAD_REG(addr);
2653     }
2654 }
2655
2656 static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2657     omap_badwidth_read16,
2658     omap_clkm_read,
2659     omap_badwidth_read16,
2660 };
2661
2662 static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2663     omap_badwidth_write16,
2664     omap_clkm_write,
2665     omap_badwidth_write16,
2666 };
2667
2668 static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2669 {
2670     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2671     int offset = addr - s->clkm.dsp_base;
2672
2673     switch (offset) {
2674     case 0x04:  /* DSP_IDLECT1 */
2675         return s->clkm.dsp_idlect1;
2676
2677     case 0x08:  /* DSP_IDLECT2 */
2678         return s->clkm.dsp_idlect2;
2679
2680     case 0x14:  /* DSP_RSTCT2 */
2681         return s->clkm.dsp_rstct2;
2682
2683     case 0x18:  /* DSP_SYSST */
2684         return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start |
2685                 (s->env->halted << 6);  /* Quite useless... */
2686     }
2687
2688     OMAP_BAD_REG(addr);
2689     return 0;
2690 }
2691
2692 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2693                 uint16_t diff, uint16_t value)
2694 {
2695     omap_clk clk;
2696
2697     SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2698 }
2699
2700 static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2701                 uint16_t diff, uint16_t value)
2702 {
2703     omap_clk clk;
2704
2705     SET_ONOFF("dspxor_ck", 1);                          /* EN_XORPCK */
2706 }
2707
2708 static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2709                 uint32_t value)
2710 {
2711     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2712     int offset = addr - s->clkm.dsp_base;
2713     uint16_t diff;
2714
2715     switch (offset) {
2716     case 0x04:  /* DSP_IDLECT1 */
2717         diff = s->clkm.dsp_idlect1 ^ value;
2718         s->clkm.dsp_idlect1 = value & 0x01f7;
2719         omap_clkdsp_idlect1_update(s, diff, value);
2720         break;
2721
2722     case 0x08:  /* DSP_IDLECT2 */
2723         s->clkm.dsp_idlect2 = value & 0x0037;
2724         diff = s->clkm.dsp_idlect1 ^ value;
2725         omap_clkdsp_idlect2_update(s, diff, value);
2726         break;
2727
2728     case 0x14:  /* DSP_RSTCT2 */
2729         s->clkm.dsp_rstct2 = value & 0x0001;
2730         break;
2731
2732     case 0x18:  /* DSP_SYSST */
2733         s->clkm.cold_start &= value & 0x3f;
2734         break;
2735
2736     default:
2737         OMAP_BAD_REG(addr);
2738     }
2739 }
2740
2741 static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2742     omap_badwidth_read16,
2743     omap_clkdsp_read,
2744     omap_badwidth_read16,
2745 };
2746
2747 static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2748     omap_badwidth_write16,
2749     omap_clkdsp_write,
2750     omap_badwidth_write16,
2751 };
2752
2753 static void omap_clkm_reset(struct omap_mpu_state_s *s)
2754 {
2755     if (s->wdt && s->wdt->reset)
2756         s->clkm.cold_start = 0x6;
2757     s->clkm.clocking_scheme = 0;
2758     omap_clkm_ckctl_update(s, ~0, 0x3000);
2759     s->clkm.arm_ckctl = 0x3000;
2760     omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 & 0x0400, 0x0400);
2761     s->clkm.arm_idlect1 = 0x0400;
2762     omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 & 0x0100, 0x0100);
2763     s->clkm.arm_idlect2 = 0x0100;
2764     s->clkm.arm_ewupct = 0x003f;
2765     s->clkm.arm_rstct1 = 0x0000;
2766     s->clkm.arm_rstct2 = 0x0000;
2767     s->clkm.arm_ckout1 = 0x0015;
2768     s->clkm.dpll1_mode = 0x2002;
2769     omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2770     s->clkm.dsp_idlect1 = 0x0040;
2771     omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2772     s->clkm.dsp_idlect2 = 0x0000;
2773     s->clkm.dsp_rstct2 = 0x0000;
2774 }
2775
2776 static void omap_clkm_init(target_phys_addr_t mpu_base,
2777                 target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2778 {
2779     int iomemtype[2] = {
2780         cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2781         cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2782     };
2783
2784     s->clkm.mpu_base = mpu_base;
2785     s->clkm.dsp_base = dsp_base;
2786     s->clkm.cold_start = 0x3a;
2787     omap_clkm_reset(s);
2788
2789     cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2790     cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2791 }
2792
2793 /* General chip reset */
2794 static void omap_mpu_reset(void *opaque)
2795 {
2796     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
2797
2798     omap_clkm_reset(mpu);
2799     omap_inth_reset(mpu->ih[0]);
2800     omap_inth_reset(mpu->ih[1]);
2801     omap_dma_reset(mpu->dma);
2802     omap_mpu_timer_reset(mpu->timer[0]);
2803     omap_mpu_timer_reset(mpu->timer[1]);
2804     omap_mpu_timer_reset(mpu->timer[2]);
2805     omap_wd_timer_reset(mpu->wdt);
2806     omap_os_timer_reset(mpu->os_timer);
2807     omap_lcdc_reset(mpu->lcd);
2808     omap_ulpd_pm_reset(mpu);
2809     omap_pin_cfg_reset(mpu);
2810     omap_mpui_reset(mpu);
2811     omap_tipb_bridge_reset(mpu->private_tipb);
2812     omap_tipb_bridge_reset(mpu->public_tipb);
2813     omap_dpll_reset(&mpu->dpll[0]);
2814     omap_dpll_reset(&mpu->dpll[1]);
2815     omap_dpll_reset(&mpu->dpll[2]);
2816     omap_uart_reset(mpu->uart1);
2817     omap_uart_reset(mpu->uart2);
2818     omap_uart_reset(mpu->uart3);
2819     omap_mmc_reset(mpu->mmc);
2820     cpu_reset(mpu->env);
2821 }
2822
2823 static void omap_mpu_wakeup(void *opaque, int irq, int req)
2824 {
2825     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
2826
2827     cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
2828 }
2829
2830 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
2831                 DisplayState *ds, const char *core)
2832 {
2833     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
2834             qemu_mallocz(sizeof(struct omap_mpu_state_s));
2835     ram_addr_t imif_base, emiff_base;
2836
2837     /* Core */
2838     s->mpu_model = omap310;
2839     s->env = cpu_init();
2840     s->sdram_size = sdram_size;
2841     s->sram_size = OMAP15XX_SRAM_SIZE;
2842
2843     cpu_arm_set_model(s->env, core ?: "ti925t");
2844
2845     /* Clocks */
2846     omap_clk_init(s);
2847
2848     /* Memory-mapped stuff */
2849     cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
2850                     (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
2851     cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
2852                     (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
2853
2854     omap_clkm_init(0xfffece00, 0xe1008000, s);
2855
2856     s->ih[0] = omap_inth_init(0xfffecb00, 0x100,
2857                     arm_pic_init_cpu(s->env),
2858                     omap_findclk(s, "arminth_ck"));
2859     s->ih[1] = omap_inth_init(0xfffe0000, 0x800,
2860                     &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ],
2861                     omap_findclk(s, "arminth_ck"));
2862     s->irq[0] = s->ih[0]->pins;
2863     s->irq[1] = s->ih[1]->pins;
2864
2865     s->dma = omap_dma_init(0xfffed800, s->irq[0], s,
2866                     omap_findclk(s, "dma_ck"));
2867     s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
2868     s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
2869     s->port[imif     ].addr_valid = omap_validate_imif_addr;
2870     s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
2871     s->port[local    ].addr_valid = omap_validate_local_addr;
2872     s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
2873
2874     s->timer[0] = omap_mpu_timer_init(0xfffec500,
2875                     s->irq[0][OMAP_INT_TIMER1],
2876                     omap_findclk(s, "mputim_ck"));
2877     s->timer[1] = omap_mpu_timer_init(0xfffec600,
2878                     s->irq[0][OMAP_INT_TIMER2],
2879                     omap_findclk(s, "mputim_ck"));
2880     s->timer[2] = omap_mpu_timer_init(0xfffec700,
2881                     s->irq[0][OMAP_INT_TIMER3],
2882                     omap_findclk(s, "mputim_ck"));
2883
2884     s->wdt = omap_wd_timer_init(0xfffec800,
2885                     s->irq[0][OMAP_INT_WD_TIMER],
2886                     omap_findclk(s, "armwdt_ck"));
2887
2888     s->os_timer = omap_os_timer_init(0xfffb9000,
2889                     s->irq[1][OMAP_INT_OS_TIMER],
2890                     omap_findclk(s, "clk32-kHz"));
2891
2892     s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
2893                     &s->dma->lcd_ch, ds, imif_base, emiff_base,
2894                     omap_findclk(s, "lcd_ck"));
2895
2896     omap_ulpd_pm_init(0xfffe0800, s);
2897     omap_pin_cfg_init(0xfffe1000, s);
2898     omap_id_init(s);
2899
2900     omap_mpui_init(0xfffec900, s);
2901
2902     s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
2903                     s->irq[0][OMAP_INT_BRIDGE_PRIV],
2904                     omap_findclk(s, "tipb_ck"));
2905     s->public_tipb = omap_tipb_bridge_init(0xfffed300,
2906                     s->irq[0][OMAP_INT_BRIDGE_PUB],
2907                     omap_findclk(s, "tipb_ck"));
2908
2909     omap_tcmi_init(0xfffecc00, s);
2910
2911     s->uart1 = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
2912                     omap_findclk(s, "uart1_ck"),
2913                     serial_hds[0]);
2914     s->uart2 = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
2915                     omap_findclk(s, "uart2_ck"),
2916                     serial_hds[0] ? serial_hds[1] : 0);
2917     s->uart3 = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
2918                     omap_findclk(s, "uart3_ck"),
2919                     serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
2920
2921     omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
2922     omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
2923     omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
2924
2925     s->mmc = omap_mmc_init(0xfffb7800, s->irq[1][OMAP_INT_OQN],
2926                     &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
2927
2928     qemu_register_reset(omap_mpu_reset, s);
2929     s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
2930
2931     return s;
2932 }