Fix typo in comment, by Andreas Faerber.
[qemu/dscho.git] / hw / omap.c
blobe56e663a1581b46b3cb2e1825887f87b8e7e6d78
1 /*
2 * TI OMAP processors emulation.
4 * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
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.
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.
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
21 #include "vl.h"
22 #include "arm_pic.h"
24 /* Should signal the TCMI */
25 uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
27 OMAP_16B_REG(addr);
28 return 0;
31 void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
32 uint32_t value)
34 OMAP_16B_REG(addr);
37 uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
39 OMAP_32B_REG(addr);
40 return 0;
43 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
44 uint32_t value)
46 OMAP_32B_REG(addr);
49 #define likely
50 #define unlikely
52 /* Interrupt Handlers */
53 struct omap_intr_handler_s {
54 qemu_irq *pins;
55 qemu_irq *parent_pic;
56 target_phys_addr_t base;
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];
71 static void omap_inth_update(struct omap_intr_handler_s *s)
73 uint32_t irq = s->irqs & ~s->mask & ~s->fiq;
74 uint32_t fiq = s->irqs & ~s->mask & s->fiq;
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;
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;
89 static void omap_inth_sir_update(struct omap_intr_handler_s *s)
91 int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f;
92 uint32_t level = s->irqs & ~s->mask;
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;
106 } else {
107 if (p > p_irq) {
108 p_irq = p;
109 intr_irq = i;
113 f = ffs(level >> 1);
116 s->sir_irq = intr_irq;
117 s->sir_fiq = intr_fiq;
120 #define INT_FALLING_EDGE 0
121 #define INT_LOW_LEVEL 1
123 static void omap_set_intr(void *opaque, int irq, int req)
125 struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
126 uint32_t rise;
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;
137 if (rise & ~ih->mask) {
138 omap_inth_sir_update(ih);
140 omap_inth_update(ih);
144 static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
146 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
147 int i, offset = addr - s->base;
149 switch (offset) {
150 case 0x00: /* ITR */
151 return s->irqs;
153 case 0x04: /* MIR */
154 return s->mask;
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);
163 return i;
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);
172 return i;
174 case 0x18: /* CONTROL_REG */
175 return 0;
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);
214 case 0x9c: /* ISR */
215 return 0x00000000;
217 default:
218 OMAP_BAD_REG(addr);
219 break;
221 return 0;
224 static void omap_inth_write(void *opaque, target_phys_addr_t addr,
225 uint32_t value)
227 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
228 int i, offset = addr - s->base;
230 switch (offset) {
231 case 0x00: /* ITR */
232 s->irqs &= value;
233 omap_inth_sir_update(s);
234 omap_inth_update(s);
235 return;
237 case 0x04: /* MIR */
238 s->mask = value;
239 omap_inth_sir_update(s);
240 omap_inth_update(s);
241 return;
243 case 0x10: /* SIR_IRQ_CODE */
244 case 0x14: /* SIR_FIQ_CODE */
245 OMAP_RO_REG(addr);
246 break;
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;
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;
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;
302 return;
304 default:
305 OMAP_BAD_REG(addr);
309 static CPUReadMemoryFunc *omap_inth_readfn[] = {
310 omap_badwidth_read32,
311 omap_badwidth_read32,
312 omap_inth_read,
315 static CPUWriteMemoryFunc *omap_inth_writefn[] = {
316 omap_inth_write,
317 omap_inth_write,
318 omap_inth_write,
321 static void omap_inth_reset(struct omap_intr_handler_s *s)
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;
333 omap_inth_update(s);
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)
339 int iomemtype;
340 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
341 qemu_mallocz(sizeof(struct omap_intr_handler_s));
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);
348 iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
349 omap_inth_writefn, s);
350 cpu_register_physical_memory(s->base, size, iomemtype);
352 return s;
355 /* OMAP1 DMA module */
356 typedef enum {
357 constant = 0,
358 post_incremented,
359 single_index,
360 double_index,
361 } omap_dma_addressing_t;
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;
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;
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;
408 uint16_t gcr;
409 int run_count;
411 int chans;
412 struct omap_dma_channel_s ch[16];
413 struct omap_dma_lcd_channel_s lcd_ch;
416 static void omap_dma_interrupts_update(struct omap_dma_s *s)
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);
433 static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
435 struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
436 int i;
439 * TODO: verify address ranges and alignment
440 * TODO: port endianness
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;
450 if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
451 printf("%s: bad DMA request\n", __FUNCTION__);
452 return;
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;
487 static inline void omap_dma_request_run(struct omap_dma_s *s,
488 int channel, int request)
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;
498 if (s->ch[channel].transfer) {
499 if (request > 0) {
500 s->ch[channel ++].post_sync = request;
501 goto next_channel;
503 s->ch[channel].status |= 0x02; /* Synchronisation drop */
504 omap_dma_interrupts_update(s);
505 return;
508 if (!s->ch[channel].signalled)
509 s->run_count ++;
510 s->ch[channel].signalled = 1;
512 if (request > 0)
513 s->ch[channel].status |= 0x40; /* External request */
515 if (s->delay && !qemu_timer_pending(s->tm))
516 qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
518 if (request > 0) {
519 channel ++;
520 goto next_channel;
524 static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel)
526 if (s->ch[channel].signalled)
527 s->run_count --;
528 s->ch[channel].signalled = 0;
530 if (!s->run_count)
531 qemu_del_timer(s->tm);
534 static void omap_dma_channel_run(struct omap_dma_s *s)
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;
542 for (ch = 0; ch < 9; ch ++) {
543 a = &s->ch[ch].active_set;
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);
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;
567 a->src += a->elem_delta[0];
568 a->dest += a->elem_delta[1];
569 a->element ++;
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 ++;
578 if (a->frame == a->frames) {
579 if (!s->ch[ch].repeat || !s->ch[ch].auto_init)
580 s->ch[ch].running = 0;
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);
587 if (s->ch[ch].interrupts & 0x20)
588 s->ch[ch].status |= 0x20;
590 if (!s->ch[ch].sync)
591 omap_dma_request_stop(s, ch);
594 if (s->ch[ch].interrupts & 0x08)
595 s->ch[ch].status |= 0x08;
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);
604 if (a->element == 1 && a->frame == a->frames - 1)
605 if (s->ch[ch].interrupts & 0x10)
606 s->ch[ch].status |= 0x10;
608 if (a->element == (a->elements >> 1))
609 if (s->ch[ch].interrupts & 0x04)
610 s->ch[ch].status |= 0x04;
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);
619 * Process requests made while the element was
620 * being transferred.
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;
627 #if 0
628 break;
629 #endif
632 s->ch[ch].cpc = a->dest & 0x0000ffff;
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);
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;
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;
664 case 0x04: /* SYS_DMA_CICR_CH0 */
665 *value = s->ch[ch].interrupts;
666 break;
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;
675 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
676 *value = s->ch[ch].addr[0] & 0x0000ffff;
677 break;
679 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
680 *value = s->ch[ch].addr[0] >> 16;
681 break;
683 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
684 *value = s->ch[ch].addr[1] & 0x0000ffff;
685 break;
687 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
688 *value = s->ch[ch].addr[1] >> 16;
689 break;
691 case 0x10: /* SYS_DMA_CEN_CH0 */
692 *value = s->ch[ch].elements;
693 break;
695 case 0x12: /* SYS_DMA_CFN_CH0 */
696 *value = s->ch[ch].frames;
697 break;
699 case 0x14: /* SYS_DMA_CFI_CH0 */
700 *value = s->ch[ch].frame_index;
701 break;
703 case 0x16: /* SYS_DMA_CEI_CH0 */
704 *value = s->ch[ch].element_index;
705 break;
707 case 0x18: /* SYS_DMA_CPC_CH0 */
708 *value = s->ch[ch].cpc;
709 break;
711 default:
712 return 1;
714 return 0;
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;
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);
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);
762 break;
764 case 0x04: /* SYS_DMA_CICR_CH0 */
765 s->ch[ch].interrupts = value & 0x003f;
766 break;
768 case 0x06: /* SYS_DMA_CSR_CH0 */
769 return 1;
771 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
772 s->ch[ch].addr[0] &= 0xffff0000;
773 s->ch[ch].addr[0] |= value;
774 break;
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;
781 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
782 s->ch[ch].addr[1] &= 0xffff0000;
783 s->ch[ch].addr[1] |= value;
784 break;
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;
791 case 0x10: /* SYS_DMA_CEN_CH0 */
792 s->ch[ch].elements = value & 0xffff;
793 break;
795 case 0x12: /* SYS_DMA_CFN_CH0 */
796 s->ch[ch].frames = value & 0xffff;
797 break;
799 case 0x14: /* SYS_DMA_CFI_CH0 */
800 s->ch[ch].frame_index = value & 0xffff;
801 break;
803 case 0x16: /* SYS_DMA_CEI_CH0 */
804 s->ch[ch].element_index = value & 0xffff;
805 break;
807 case 0x18: /* SYS_DMA_CPC_CH0 */
808 return 1;
810 default:
811 OMAP_BAD_REG((unsigned long) reg);
813 return 0;
816 static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
818 struct omap_dma_s *s = (struct omap_dma_s *) opaque;
819 int i, reg, ch, offset = addr - s->base;
820 uint16_t ret;
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;
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;
837 case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
838 return s->lcd_ch.src_f1_top & 0xffff;
840 case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
841 return s->lcd_ch.src_f1_top >> 16;
843 case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
844 return s->lcd_ch.src_f1_bottom & 0xffff;
846 case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
847 return s->lcd_ch.src_f1_bottom >> 16;
849 case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
850 return s->lcd_ch.src_f2_top & 0xffff;
852 case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
853 return s->lcd_ch.src_f2_top >> 16;
855 case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
856 return s->lcd_ch.src_f2_bottom & 0xffff;
858 case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
859 return s->lcd_ch.src_f2_bottom >> 16;
861 case 0x400: /* SYS_DMA_GCR */
862 return s->gcr;
865 OMAP_BAD_REG(addr);
866 return 0;
869 static void omap_dma_write(void *opaque, target_phys_addr_t addr,
870 uint32_t value)
872 struct omap_dma_s *s = (struct omap_dma_s *) opaque;
873 int reg, ch, offset = addr - s->base;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
931 case 0x400: /* SYS_DMA_GCR */
932 s->gcr = value & 0x000c;
933 break;
935 default:
936 OMAP_BAD_REG(addr);
940 static CPUReadMemoryFunc *omap_dma_readfn[] = {
941 omap_badwidth_read16,
942 omap_dma_read,
943 omap_badwidth_read16,
946 static CPUWriteMemoryFunc *omap_dma_writefn[] = {
947 omap_badwidth_write16,
948 omap_dma_write,
949 omap_badwidth_write16,
952 static void omap_dma_request(void *opaque, int drq, int req)
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);
961 } else
962 s->drq &= ~(1 << drq);
965 static void omap_dma_clk_update(void *opaque, int line, int on)
967 struct omap_dma_s *s = (struct omap_dma_s *) opaque;
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);
979 static void omap_dma_reset(struct omap_dma_s *s)
981 int i;
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;
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)
999 int iomemtype;
1000 struct omap_dma_s *s = (struct omap_dma_s *)
1001 qemu_mallocz(sizeof(struct omap_dma_s));
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);
1016 iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1017 omap_dma_writefn, s);
1018 cpu_register_physical_memory(s->base, 0x800, iomemtype);
1020 return s;
1023 /* DMA ports */
1024 int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1025 target_phys_addr_t addr)
1027 return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1030 int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1031 target_phys_addr_t addr)
1033 return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1036 int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1037 target_phys_addr_t addr)
1039 return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1042 int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1043 target_phys_addr_t addr)
1045 return addr >= 0xfffb0000 && addr < 0xffff0000;
1048 int omap_validate_local_addr(struct omap_mpu_state_s *s,
1049 target_phys_addr_t addr)
1051 return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1054 int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1055 target_phys_addr_t addr)
1057 return addr >= 0xe1010000 && addr < 0xe1020004;
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;
1071 int enable;
1072 int ptv;
1073 int ar;
1074 int st;
1075 uint32_t reset_val;
1078 static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1080 uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
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;
1089 static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1091 timer->val = omap_timer_read(timer);
1092 timer->time = qemu_get_clock(vm_clock);
1095 static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1097 int64_t expires;
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);
1108 static void omap_timer_tick(void *opaque)
1110 struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1111 omap_timer_sync(timer);
1113 if (!timer->ar) {
1114 timer->val = 0;
1115 timer->st = 0;
1118 if (timer->it_ena)
1119 qemu_irq_raise(timer->irq);
1120 omap_timer_update(timer);
1123 static void omap_timer_clk_update(void *opaque, int line, int on)
1125 struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1127 omap_timer_sync(timer);
1128 timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1129 omap_timer_update(timer);
1132 static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
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);
1139 static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
1141 struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1142 int offset = addr - s->base;
1144 switch (offset) {
1145 case 0x00: /* CNTL_TIMER */
1146 return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1148 case 0x04: /* LOAD_TIM */
1149 break;
1151 case 0x08: /* READ_TIM */
1152 return omap_timer_read(s);
1155 OMAP_BAD_REG(addr);
1156 return 0;
1159 static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1160 uint32_t value)
1162 struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1163 int offset = addr - s->base;
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;
1175 case 0x04: /* LOAD_TIM */
1176 s->reset_val = value;
1177 return;
1179 case 0x08: /* READ_TIM */
1180 OMAP_RO_REG(addr);
1181 break;
1183 default:
1184 OMAP_BAD_REG(addr);
1188 static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1189 omap_badwidth_read32,
1190 omap_badwidth_read32,
1191 omap_mpu_timer_read,
1194 static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1195 omap_badwidth_write32,
1196 omap_badwidth_write32,
1197 omap_mpu_timer_write,
1200 static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
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;
1212 struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1213 qemu_irq irq, omap_clk clk)
1215 int iomemtype;
1216 struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1217 qemu_mallocz(sizeof(struct omap_mpu_timer_s));
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);
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);
1230 return s;
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;
1242 static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
1244 struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1245 int offset = addr - s->timer.base;
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);
1252 case 0x04: /* READ_TIMER */
1253 return omap_timer_read(&s->timer);
1255 case 0x08: /* TIMER_MODE */
1256 return s->mode << 15;
1259 OMAP_BAD_REG(addr);
1260 return 0;
1263 static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1264 uint32_t value)
1266 struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1267 int offset = addr - s->timer.base;
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;
1279 case 0x04: /* LOAD_TIMER */
1280 s->timer.reset_val = value & 0xffff;
1281 break;
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();
1298 s->last_wr = value & 0xff;
1299 break;
1301 default:
1302 OMAP_BAD_REG(addr);
1306 static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
1307 omap_badwidth_read16,
1308 omap_wd_timer_read,
1309 omap_badwidth_read16,
1312 static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
1313 omap_badwidth_write16,
1314 omap_wd_timer_write,
1315 omap_badwidth_write16,
1318 static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
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);
1336 struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
1337 qemu_irq irq, omap_clk clk)
1339 int iomemtype;
1340 struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
1341 qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
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);
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);
1354 return s;
1357 /* 32-kHz timer */
1358 struct omap_32khz_timer_s {
1359 struct omap_mpu_timer_s timer;
1362 static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
1364 struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1365 int offset = addr - s->timer.base;
1367 switch (offset) {
1368 case 0x00: /* TVR */
1369 return s->timer.reset_val;
1371 case 0x04: /* TCR */
1372 return omap_timer_read(&s->timer);
1374 case 0x08: /* CR */
1375 return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
1377 default:
1378 break;
1380 OMAP_BAD_REG(addr);
1381 return 0;
1384 static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1385 uint32_t value)
1387 struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1388 int offset = addr - s->timer.base;
1390 switch (offset) {
1391 case 0x00: /* TVR */
1392 s->timer.reset_val = value & 0x00ffffff;
1393 break;
1395 case 0x04: /* TCR */
1396 OMAP_RO_REG(addr);
1397 break;
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);
1408 break;
1410 default:
1411 OMAP_BAD_REG(addr);
1415 static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1416 omap_badwidth_read32,
1417 omap_badwidth_read32,
1418 omap_os_timer_read,
1421 static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1422 omap_badwidth_write32,
1423 omap_badwidth_write32,
1424 omap_os_timer_write,
1427 static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
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;
1439 struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1440 qemu_irq irq, omap_clk clk)
1442 int iomemtype;
1443 struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1444 qemu_mallocz(sizeof(struct omap_32khz_timer_s));
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);
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);
1457 return s;
1460 /* Ultra Low-Power Device Module */
1461 static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
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;
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;
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];
1498 OMAP_BAD_REG(addr);
1499 return 0;
1502 static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1503 uint16_t diff, uint16_t value)
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);
1511 static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1512 uint16_t diff, uint16_t value)
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);
1524 static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1525 uint32_t value)
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;
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;
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);
1549 if (value & 1)
1550 s->ulpd_gauge_start = now;
1551 else {
1552 now -= s->ulpd_gauge_start;
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;
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;
1568 s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */
1569 qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1572 s->ulpd_pm_regs[offset >> 2] = value;
1573 break;
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;
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;
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;
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;
1615 omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
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);
1623 /* Act as if the lock is restored. */
1624 s->ulpd_pm_regs[offset >> 2] |= 2;
1625 break;
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;
1635 default:
1636 OMAP_BAD_REG(addr);
1640 static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1641 omap_badwidth_read16,
1642 omap_ulpd_pm_read,
1643 omap_badwidth_read16,
1646 static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1647 omap_badwidth_write16,
1648 omap_ulpd_pm_write,
1649 omap_badwidth_write16,
1652 static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
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"));
1679 static void omap_ulpd_pm_init(target_phys_addr_t base,
1680 struct omap_mpu_state_s *mpu)
1682 int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1683 omap_ulpd_pm_writefn, mpu);
1685 mpu->ulpd_pm_base = base;
1686 cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1687 omap_ulpd_pm_reset(mpu);
1690 /* OMAP Pin Configuration */
1691 static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1693 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1694 int offset = addr - s->pin_cfg_base;
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];
1702 case 0x0c: /* COMP_MODE_CTRL_0 */
1703 return s->comp_mode_ctrl[0];
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];
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];
1724 case 0x50: /* GATE_INH_CTRL_0 */
1725 return s->gate_inh_ctrl[0];
1727 case 0x60: /* VOLTAGE_CTRL_0 */
1728 return s->voltage_ctrl[0];
1730 case 0x70: /* TEST_DBG_CTRL_0 */
1731 return s->test_dbg_ctrl[0];
1733 case 0x80: /* MOD_CONF_CTRL_0 */
1734 return s->mod_conf_ctrl[0];
1737 OMAP_BAD_REG(addr);
1738 return 0;
1741 static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1742 uint32_t diff, uint32_t value)
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);
1754 static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1755 uint32_t diff, uint32_t value)
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);
1767 static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1768 uint32_t diff, uint32_t value)
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);
1794 static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1795 uint32_t value)
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;
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;
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;
1814 case 0x08: /* FUNC_MUX_CTRL_2 */
1815 s->func_mux_ctrl[offset >> 2] = value;
1816 return;
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;
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;
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;
1846 case 0x50: /* GATE_INH_CTRL_0 */
1847 s->gate_inh_ctrl[0] = value;
1848 return;
1850 case 0x60: /* VOLTAGE_CTRL_0 */
1851 s->voltage_ctrl[0] = value;
1852 return;
1854 case 0x70: /* TEST_DBG_CTRL_0 */
1855 s->test_dbg_ctrl[0] = value;
1856 return;
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;
1864 default:
1865 OMAP_BAD_REG(addr);
1869 static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1870 omap_badwidth_read32,
1871 omap_badwidth_read32,
1872 omap_pin_cfg_read,
1875 static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1876 omap_badwidth_write32,
1877 omap_badwidth_write32,
1878 omap_pin_cfg_write,
1881 static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
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));
1897 static void omap_pin_cfg_init(target_phys_addr_t base,
1898 struct omap_mpu_state_s *mpu)
1900 int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1901 omap_pin_cfg_writefn, mpu);
1903 mpu->pin_cfg_base = base;
1904 cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1905 omap_pin_cfg_reset(mpu);
1908 /* Device Identification, Die Identification */
1909 static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1911 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1913 switch (addr) {
1914 case 0xfffe1800: /* DIE_ID_LSB */
1915 return 0xc9581f0e;
1916 case 0xfffe1804: /* DIE_ID_MSB */
1917 return 0xa8858bfa;
1919 case 0xfffe2000: /* PRODUCT_ID_LSB */
1920 return 0x00aaaafc;
1921 case 0xfffe2004: /* PRODUCT_ID_MSB */
1922 return 0xcafeb574;
1924 case 0xfffed400: /* JTAG_ID_LSB */
1925 switch (s->mpu_model) {
1926 case omap310:
1927 return 0x03310315;
1928 case omap1510:
1929 return 0x03310115;
1931 break;
1933 case 0xfffed404: /* JTAG_ID_MSB */
1934 switch (s->mpu_model) {
1935 case omap310:
1936 return 0xfb57402f;
1937 case omap1510:
1938 return 0xfb47002f;
1940 break;
1943 OMAP_BAD_REG(addr);
1944 return 0;
1947 static void omap_id_write(void *opaque, target_phys_addr_t addr,
1948 uint32_t value)
1950 OMAP_BAD_REG(addr);
1953 static CPUReadMemoryFunc *omap_id_readfn[] = {
1954 omap_badwidth_read32,
1955 omap_badwidth_read32,
1956 omap_id_read,
1959 static CPUWriteMemoryFunc *omap_id_writefn[] = {
1960 omap_badwidth_write32,
1961 omap_badwidth_write32,
1962 omap_id_write,
1965 static void omap_id_init(struct omap_mpu_state_s *mpu)
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);
1975 /* MPUI Control (Dummy) */
1976 static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1978 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1979 int offset = addr - s->mpui_base;
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;
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;
2001 OMAP_BAD_REG(addr);
2002 return 0;
2005 static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2006 uint32_t value)
2008 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2009 int offset = addr - s->mpui_base;
2011 switch (offset) {
2012 case 0x00: /* CTRL */
2013 s->mpui_ctrl = value & 0x007fffff;
2014 break;
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;
2027 default:
2028 OMAP_BAD_REG(addr);
2032 static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2033 omap_badwidth_read32,
2034 omap_badwidth_read32,
2035 omap_mpui_read,
2038 static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2039 omap_badwidth_write32,
2040 omap_badwidth_write32,
2041 omap_mpui_write,
2044 static void omap_mpui_reset(struct omap_mpu_state_s *s)
2046 s->mpui_ctrl = 0x0003ff1b;
2049 static void omap_mpui_init(target_phys_addr_t base,
2050 struct omap_mpu_state_s *mpu)
2052 int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2053 omap_mpui_writefn, mpu);
2055 mpu->mpui_base = base;
2056 cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2058 omap_mpui_reset(mpu);
2061 /* TIPB Bridges */
2062 struct omap_tipb_bridge_s {
2063 target_phys_addr_t base;
2064 qemu_irq abort;
2066 int width_intr;
2067 uint16_t control;
2068 uint16_t alloc;
2069 uint16_t buffer;
2070 uint16_t enh_control;
2073 static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
2075 struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2076 int offset = addr - s->base;
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;
2095 OMAP_BAD_REG(addr);
2096 return 0;
2099 static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
2100 uint32_t value)
2102 struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2103 int offset = addr - s->base;
2105 switch (offset) {
2106 case 0x00: /* TIPB_CNTL */
2107 s->control = value & 0xffff;
2108 break;
2110 case 0x04: /* TIPB_BUS_ALLOC */
2111 s->alloc = value & 0x003f;
2112 break;
2114 case 0x08: /* MPU_TIPB_CNTL */
2115 s->buffer = value & 0x0003;
2116 break;
2118 case 0x0c: /* ENHANCED_TIPB_CNTL */
2119 s->width_intr = !(value & 2);
2120 s->enh_control = value & 0x000f;
2121 break;
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;
2130 default:
2131 OMAP_BAD_REG(addr);
2135 static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2136 omap_badwidth_read16,
2137 omap_tipb_bridge_read,
2138 omap_tipb_bridge_read,
2141 static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2142 omap_badwidth_write16,
2143 omap_tipb_bridge_write,
2144 omap_tipb_bridge_write,
2147 static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2149 s->control = 0xffff;
2150 s->alloc = 0x0009;
2151 s->buffer = 0x0000;
2152 s->enh_control = 0x000f;
2155 struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2156 qemu_irq abort_irq, omap_clk clk)
2158 int iomemtype;
2159 struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2160 qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2162 s->abort = abort_irq;
2163 s->base = base;
2164 omap_tipb_bridge_reset(s);
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);
2170 return s;
2173 /* Dummy Traffic Controller's Memory Interface */
2174 static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2176 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2177 int offset = addr - s->tcmi_base;
2178 uint32_t ret;
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];
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;
2204 OMAP_BAD_REG(addr);
2205 return 0;
2208 static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2209 uint32_t value)
2211 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2212 int offset = addr - s->tcmi_base;
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;
2235 default:
2236 OMAP_BAD_REG(addr);
2240 static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2241 omap_badwidth_read32,
2242 omap_badwidth_read32,
2243 omap_tcmi_read,
2246 static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2247 omap_badwidth_write32,
2248 omap_badwidth_write32,
2249 omap_tcmi_write,
2252 static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
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;
2271 static void omap_tcmi_init(target_phys_addr_t base,
2272 struct omap_mpu_state_s *mpu)
2274 int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2275 omap_tcmi_writefn, mpu);
2277 mpu->tcmi_base = base;
2278 cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2279 omap_tcmi_reset(mpu);
2282 /* Digital phase-locked loops control */
2283 static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2285 struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2286 int offset = addr - s->base;
2288 if (offset == 0x00) /* CTL_REG */
2289 return s->mode;
2291 OMAP_BAD_REG(addr);
2292 return 0;
2295 static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2296 uint32_t value)
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;
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;
2316 omap_clk_setrate(s->dpll, div, mult);
2319 /* Enter the desired mode. */
2320 s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
2322 /* Act as if the lock is restored. */
2323 s->mode |= 2;
2324 } else {
2325 OMAP_BAD_REG(addr);
2329 static CPUReadMemoryFunc *omap_dpll_readfn[] = {
2330 omap_badwidth_read16,
2331 omap_dpll_read,
2332 omap_badwidth_read16,
2335 static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
2336 omap_badwidth_write16,
2337 omap_dpll_write,
2338 omap_badwidth_write16,
2341 static void omap_dpll_reset(struct dpll_ctl_s *s)
2343 s->mode = 0x2002;
2344 omap_clk_setrate(s->dpll, 1, 1);
2347 static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
2348 omap_clk clk)
2350 int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
2351 omap_dpll_writefn, s);
2353 s->base = base;
2354 s->dpll = clk;
2355 omap_dpll_reset(s);
2357 cpu_register_physical_memory(s->base, 0x100, iomemtype);
2360 /* UARTs */
2361 struct omap_uart_s {
2362 SerialState *serial; /* TODO */
2365 static void omap_uart_reset(struct omap_uart_s *s)
2369 struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2370 qemu_irq irq, omap_clk clk, CharDriverState *chr)
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;
2379 /* MPU Clock/Reset/Power Mode Control */
2380 static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2382 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2383 int offset = addr - s->clkm.mpu_base;
2385 switch (offset) {
2386 case 0x00: /* ARM_CKCTL */
2387 return s->clkm.arm_ckctl;
2389 case 0x04: /* ARM_IDLECT1 */
2390 return s->clkm.arm_idlect1;
2392 case 0x08: /* ARM_IDLECT2 */
2393 return s->clkm.arm_idlect2;
2395 case 0x0c: /* ARM_EWUPCT */
2396 return s->clkm.arm_ewupct;
2398 case 0x10: /* ARM_RSTCT1 */
2399 return s->clkm.arm_rstct1;
2401 case 0x14: /* ARM_RSTCT2 */
2402 return s->clkm.arm_rstct2;
2404 case 0x18: /* ARM_SYSST */
2405 return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start;
2407 case 0x1c: /* ARM_CKOUT1 */
2408 return s->clkm.arm_ckout1;
2410 case 0x20: /* ARM_CKOUT2 */
2411 break;
2414 OMAP_BAD_REG(addr);
2415 return 0;
2418 static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2419 uint16_t diff, uint16_t value)
2421 omap_clk clk;
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"));
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"));
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);
2443 if (diff & (3 << 8)) { /* TCDIV */
2444 clk = omap_findclk(s, "tc_ck");
2445 omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2447 if (diff & (3 << 6)) { /* DSPDIV */
2448 clk = omap_findclk(s, "dsp_ck");
2449 omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2451 if (diff & (3 << 4)) { /* ARMDIV */
2452 clk = omap_findclk(s, "arm_ck");
2453 omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2455 if (diff & (3 << 2)) { /* LCDDIV */
2456 clk = omap_findclk(s, "lcd_ck");
2457 omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2459 if (diff & (3 << 0)) { /* PERDIV */
2460 clk = omap_findclk(s, "armper_ck");
2461 omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2465 static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2466 uint16_t diff, uint16_t value)
2468 omap_clk clk;
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 */
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); \
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 */
2496 static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2497 uint16_t diff, uint16_t value)
2499 omap_clk clk;
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); \
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 */
2519 static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2520 uint16_t diff, uint16_t value)
2522 omap_clk clk;
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);
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;
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);
2577 static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2578 uint32_t value)
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",
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;
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;
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;
2608 case 0x0c: /* ARM_EWUPCT */
2609 diff = s->clkm.arm_ewupct ^ value;
2610 s->clkm.arm_ewupct = value & 0x003f;
2611 return;
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;
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);
2625 if (diff & 2) { /* DSP_EN */
2626 clk = omap_findclk(s, "dsp_ck");
2627 omap_clk_canidle(clk, (~value >> 1) & 1);
2629 return;
2631 case 0x14: /* ARM_RSTCT2 */
2632 s->clkm.arm_rstct2 = value & 0x0001;
2633 return;
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]);
2641 s->clkm.cold_start &= value & 0x3f;
2642 return;
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;
2650 case 0x20: /* ARM_CKOUT2 */
2651 default:
2652 OMAP_BAD_REG(addr);
2656 static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2657 omap_badwidth_read16,
2658 omap_clkm_read,
2659 omap_badwidth_read16,
2662 static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2663 omap_badwidth_write16,
2664 omap_clkm_write,
2665 omap_badwidth_write16,
2668 static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2670 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2671 int offset = addr - s->clkm.dsp_base;
2673 switch (offset) {
2674 case 0x04: /* DSP_IDLECT1 */
2675 return s->clkm.dsp_idlect1;
2677 case 0x08: /* DSP_IDLECT2 */
2678 return s->clkm.dsp_idlect2;
2680 case 0x14: /* DSP_RSTCT2 */
2681 return s->clkm.dsp_rstct2;
2683 case 0x18: /* DSP_SYSST */
2684 return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start |
2685 (s->env->halted << 6); /* Quite useless... */
2688 OMAP_BAD_REG(addr);
2689 return 0;
2692 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2693 uint16_t diff, uint16_t value)
2695 omap_clk clk;
2697 SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */
2700 static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2701 uint16_t diff, uint16_t value)
2703 omap_clk clk;
2705 SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */
2708 static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2709 uint32_t value)
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;
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;
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;
2728 case 0x14: /* DSP_RSTCT2 */
2729 s->clkm.dsp_rstct2 = value & 0x0001;
2730 break;
2732 case 0x18: /* DSP_SYSST */
2733 s->clkm.cold_start &= value & 0x3f;
2734 break;
2736 default:
2737 OMAP_BAD_REG(addr);
2741 static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2742 omap_badwidth_read16,
2743 omap_clkdsp_read,
2744 omap_badwidth_read16,
2747 static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2748 omap_badwidth_write16,
2749 omap_clkdsp_write,
2750 omap_badwidth_write16,
2753 static void omap_clkm_reset(struct omap_mpu_state_s *s)
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;
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)
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),
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);
2789 cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2790 cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2793 /* General chip reset */
2794 static void omap_mpu_reset(void *opaque)
2796 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
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);
2823 static void omap_mpu_wakeup(void *opaque, int irq, int req)
2825 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
2827 cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
2830 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
2831 DisplayState *ds, const char *core)
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;
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;
2843 cpu_arm_set_model(s->env, core ?: "ti925t");
2845 /* Clocks */
2846 omap_clk_init(s);
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);
2854 omap_clkm_init(0xfffece00, 0xe1008000, s);
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;
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;
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"));
2884 s->wdt = omap_wd_timer_init(0xfffec800,
2885 s->irq[0][OMAP_INT_WD_TIMER],
2886 omap_findclk(s, "armwdt_ck"));
2888 s->os_timer = omap_os_timer_init(0xfffb9000,
2889 s->irq[1][OMAP_INT_OS_TIMER],
2890 omap_findclk(s, "clk32-kHz"));
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"));
2896 omap_ulpd_pm_init(0xfffe0800, s);
2897 omap_pin_cfg_init(0xfffe1000, s);
2898 omap_id_init(s);
2900 omap_mpui_init(0xfffec900, s);
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"));
2909 omap_tcmi_init(0xfffecc00, s);
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);
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"));
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"));
2928 qemu_register_reset(omap_mpu_reset, s);
2929 s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
2931 return s;