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,
24 /* Should signal the TCMI */
25 uint32_t omap_badwidth_read16(void *opaque
, target_phys_addr_t addr
)
31 void omap_badwidth_write16(void *opaque
, target_phys_addr_t addr
,
37 uint32_t omap_badwidth_read32(void *opaque
, target_phys_addr_t addr
)
43 void omap_badwidth_write32(void *opaque
, target_phys_addr_t addr
,
52 /* Interrupt Handlers */
53 struct omap_intr_handler_s
{
56 target_phys_addr_t base
;
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
);
82 if (s
->new_fiq_agr
|| !irq
) {
83 qemu_set_irq(s
->parent_pic
[ARM_PIC_CPU_FIQ
], fiq
);
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
;
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
) {
101 if (s
->fiq
& (1 << i
)) {
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
;
129 rise
= ~ih
->irqs
& (1 << irq
);
131 ih
->stats
[irq
] += !!rise
;
133 rise
= ih
->sens_edge
& ih
->irqs
& (1 << irq
);
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
;
156 case 0x10: /* SIR_IRQ_CODE */
158 if (((s
->sens_edge
>> i
) & 1) == INT_FALLING_EDGE
&& i
) {
159 s
->irqs
&= ~(1 << i
);
160 omap_inth_sir_update(s
);
165 case 0x14: /* SIR_FIQ_CODE */
167 if (((s
->sens_edge
>> i
) & 1) == INT_FALLING_EDGE
&& i
) {
168 s
->irqs
&= ~(1 << i
);
169 omap_inth_sir_update(s
);
174 case 0x18: /* CONTROL_REG */
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) |
224 static void omap_inth_write(void *opaque
, target_phys_addr_t addr
,
227 struct omap_intr_handler_s
*s
= (struct omap_intr_handler_s
*) opaque
;
228 int i
, offset
= addr
- s
->base
;
233 omap_inth_sir_update(s
);
239 omap_inth_sir_update(s
);
243 case 0x10: /* SIR_IRQ_CODE */
244 case 0x14: /* SIR_FIQ_CODE */
248 case 0x18: /* CONTROL_REG */
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
;
293 s
->fiq
|= (value
& 1) << i
;
297 for (i
= 0; i
< 32; i
++)
298 if (value
& (1 << i
)) {
299 omap_set_intr(s
, i
, 1);
309 static CPUReadMemoryFunc
*omap_inth_readfn
[] = {
310 omap_badwidth_read32
,
311 omap_badwidth_read32
,
315 static CPUWriteMemoryFunc
*omap_inth_writefn
[] = {
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;
327 memset(s
->priority
, 0, sizeof(s
->priority
));
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
)
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
;
345 s
->pins
= qemu_allocate_irqs(omap_set_intr
, s
, 32);
348 iomemtype
= cpu_register_io_memory(0, omap_inth_readfn
,
349 omap_inth_writefn
, s
);
350 cpu_register_physical_memory(s
->base
, size
, iomemtype
);
355 /* OMAP1 DMA module */
361 } omap_dma_addressing_t
;
363 struct omap_dma_channel_s
{
366 enum omap_dma_port port
[2];
367 target_phys_addr_t addr
[2];
368 omap_dma_addressing_t mode
[2];
384 uint16_t frame_index
;
385 uint16_t element_index
;
388 struct omap_dma_reg_set_s
{
389 target_phys_addr_t src
, dest
;
402 struct omap_mpu_state_s
*mpu
;
403 target_phys_addr_t base
;
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
;
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
;
450 if (unlikely(!s
->ch
[ch
].elements
|| !s
->ch
[ch
].frames
)) {
451 printf("%s: bad DMA request\n", __FUNCTION__
);
455 for (i
= 0; i
< 2; i
++)
456 switch (s
->ch
[ch
].mode
[i
]) {
458 a
->elem_delta
[i
] = 0;
459 a
->frame_delta
[i
] = 0;
461 case post_incremented
:
462 a
->elem_delta
[i
] = s
->ch
[ch
].data_type
;
463 a
->frame_delta
[i
] = 0;
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;
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;
487 static inline void omap_dma_request_run(struct omap_dma_s
*s
,
488 int channel
, int request
)
492 for (; channel
< 9; channel
++)
493 if (s
->ch
[channel
].sync
== request
&& s
->ch
[channel
].running
)
498 if (s
->ch
[channel
].transfer
) {
500 s
->ch
[channel
++].post_sync
= request
;
503 s
->ch
[channel
].status
|= 0x02; /* Synchronisation drop */
504 omap_dma_interrupts_update(s
);
508 if (!s
->ch
[channel
].signalled
)
510 s
->ch
[channel
].signalled
= 1;
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
);
524 static inline void omap_dma_request_stop(struct omap_dma_s
*s
, int channel
)
526 if (s
->ch
[channel
].signalled
)
528 s
->ch
[channel
].signalled
= 0;
531 qemu_del_timer(s
->tm
);
534 static void omap_dma_channel_run(struct omap_dma_s
*s
)
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
))) {
551 if (s
->ch
[ch
].interrupts
& 0x01)
552 s
->ch
[ch
].status
|= 0x01;
553 omap_dma_request_stop(s
, ch
);
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];
571 /* Check interrupt conditions */
572 if (a
->element
== a
->elements
) {
574 a
->src
+= a
->frame_delta
[0];
575 a
->dest
+= a
->frame_delta
[1];
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
&&
585 omap_dma_channel_load(s
, ch
);
587 if (s
->ch
[ch
].interrupts
& 0x20)
588 s
->ch
[ch
].status
|= 0x20;
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
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;
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
) {
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);
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
;
664 case 0x04: /* SYS_DMA_CICR_CH0 */
665 *value
= s
->ch
[ch
].interrupts
;
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
);
675 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
676 *value
= s
->ch
[ch
].addr
[0] & 0x0000ffff;
679 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
680 *value
= s
->ch
[ch
].addr
[0] >> 16;
683 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
684 *value
= s
->ch
[ch
].addr
[1] & 0x0000ffff;
687 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
688 *value
= s
->ch
[ch
].addr
[1] >> 16;
691 case 0x10: /* SYS_DMA_CEN_CH0 */
692 *value
= s
->ch
[ch
].elements
;
695 case 0x12: /* SYS_DMA_CFN_CH0 */
696 *value
= s
->ch
[ch
].frames
;
699 case 0x14: /* SYS_DMA_CFI_CH0 */
700 *value
= s
->ch
[ch
].frame_index
;
703 case 0x16: /* SYS_DMA_CEI_CH0 */
704 *value
= s
->ch
[ch
].element_index
;
707 case 0x18: /* SYS_DMA_CPC_CH0 */
708 *value
= s
->ch
[ch
].cpc
;
717 static int omap_dma_ch_reg_write(struct omap_dma_s
*s
,
718 int ch
, int reg
, uint16_t value
) {
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__
,
731 if (s
->ch
[ch
].port
[1] >= omap_dma_port_last
)
732 printf("%s: invalid DMA port %i\n", __FUNCTION__
,
734 if ((value
& 3) == 3)
735 printf("%s: bad data_type for DMA channel %i\n", __FUNCTION__
, ch
);
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
);
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);
759 s
->ch
[ch
].running
= 0;
760 omap_dma_request_stop(s
, ch
);
764 case 0x04: /* SYS_DMA_CICR_CH0 */
765 s
->ch
[ch
].interrupts
= value
& 0x003f;
768 case 0x06: /* SYS_DMA_CSR_CH0 */
771 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
772 s
->ch
[ch
].addr
[0] &= 0xffff0000;
773 s
->ch
[ch
].addr
[0] |= value
;
776 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
777 s
->ch
[ch
].addr
[0] &= 0x0000ffff;
778 s
->ch
[ch
].addr
[0] |= value
<< 16;
781 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
782 s
->ch
[ch
].addr
[1] &= 0xffff0000;
783 s
->ch
[ch
].addr
[1] |= value
;
786 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
787 s
->ch
[ch
].addr
[1] &= 0x0000ffff;
788 s
->ch
[ch
].addr
[1] |= value
<< 16;
791 case 0x10: /* SYS_DMA_CEN_CH0 */
792 s
->ch
[ch
].elements
= value
& 0xffff;
795 case 0x12: /* SYS_DMA_CFN_CH0 */
796 s
->ch
[ch
].frames
= value
& 0xffff;
799 case 0x14: /* SYS_DMA_CFI_CH0 */
800 s
->ch
[ch
].frame_index
= value
& 0xffff;
803 case 0x16: /* SYS_DMA_CEI_CH0 */
804 s
->ch
[ch
].element_index
= value
& 0xffff;
807 case 0x18: /* SYS_DMA_CPC_CH0 */
811 OMAP_BAD_REG((unsigned long) reg
);
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
;
823 case 0x000 ... 0x2fe:
825 ch
= (offset
>> 6) & 0x0f;
826 if (omap_dma_ch_reg_read(s
, ch
, reg
, &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 */
869 static void omap_dma_write(void *opaque
, target_phys_addr_t addr
,
872 struct omap_dma_s
*s
= (struct omap_dma_s
*) opaque
;
873 int reg
, ch
, offset
= addr
- s
->base
;
876 case 0x000 ... 0x2fe:
878 ch
= (offset
>> 6) & 0x0f;
879 if (omap_dma_ch_reg_write(s
, ch
, reg
, value
))
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;
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
;
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;
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
;
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;
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
;
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;
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
;
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;
931 case 0x400: /* SYS_DMA_GCR */
932 s
->gcr
= value
& 0x000c;
940 static CPUReadMemoryFunc
*omap_dma_readfn
[] = {
941 omap_badwidth_read16
,
943 omap_badwidth_read16
,
946 static CPUWriteMemoryFunc
*omap_dma_writefn
[] = {
947 omap_badwidth_write16
,
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. */
957 if (~s
->drq
& (1 << drq
)) {
959 omap_dma_request_run(s
, 0, drq
);
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
;
970 s
->delay
= ticks_per_sec
>> 5;
972 qemu_mod_timer(s
->tm
, qemu_get_clock(vm_clock
) + s
->delay
);
975 qemu_del_timer(s
->tm
);
979 static void omap_dma_reset(struct omap_dma_s
*s
)
983 qemu_del_timer(s
->tm
);
987 s
->lcd_ch
.src
= emiff
;
988 s
->lcd_ch
.condition
= 0;
989 s
->lcd_ch
.interrupts
= 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
)
1000 struct omap_dma_s
*s
= (struct omap_dma_s
*)
1001 qemu_mallocz(sizeof(struct omap_dma_s
));
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);
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
);
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;
1061 struct omap_mpu_timer_s
{
1064 target_phys_addr_t base
;
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
);
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
)
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
);
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
);
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
;
1145 case 0x00: /* CNTL_TIMER */
1146 return (s
->enable
<< 5) | (s
->ptv
<< 2) | (s
->ar
<< 1) | s
->st
;
1148 case 0x04: /* LOAD_TIM */
1151 case 0x08: /* READ_TIM */
1152 return omap_timer_read(s
);
1159 static void omap_mpu_timer_write(void *opaque
, target_phys_addr_t addr
,
1162 struct omap_mpu_timer_s
*s
= (struct omap_mpu_timer_s
*) opaque
;
1163 int offset
= addr
- s
->base
;
1166 case 0x00: /* CNTL_TIMER */
1168 s
->enable
= (value
>> 5) & 1;
1169 s
->ptv
= (value
>> 2) & 7;
1170 s
->ar
= (value
>> 1) & 1;
1172 omap_timer_update(s
);
1175 case 0x04: /* LOAD_TIM */
1176 s
->reset_val
= value
;
1179 case 0x08: /* READ_TIM */
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
);
1204 s
->reset_val
= 31337;
1212 struct omap_mpu_timer_s
*omap_mpu_timer_init(target_phys_addr_t base
,
1213 qemu_irq irq
, omap_clk clk
)
1216 struct omap_mpu_timer_s
*s
= (struct omap_mpu_timer_s
*)
1217 qemu_mallocz(sizeof(struct omap_mpu_timer_s
));
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
);
1233 /* Watchdog timer */
1234 struct omap_watchdog_timer_s
{
1235 struct omap_mpu_timer_s timer
;
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
;
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;
1263 static void omap_wd_timer_write(void *opaque
, target_phys_addr_t addr
,
1266 struct omap_watchdog_timer_s
*s
= (struct omap_watchdog_timer_s
*) opaque
;
1267 int offset
= addr
- s
->timer
.base
;
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
);
1279 case 0x04: /* LOAD_TIMER */
1280 s
->timer
.reset_val
= value
& 0xffff;
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) {
1290 omap_clk_put(s
->timer
.clk
);
1292 /* XXX: on T|E hardware somehow this has no effect,
1293 * on Zire 71 it works as specified. */
1295 qemu_system_reset_request();
1298 s
->last_wr
= value
& 0xff;
1306 static CPUReadMemoryFunc
*omap_wd_timer_readfn
[] = {
1307 omap_badwidth_read16
,
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
);
1322 omap_clk_get(s
->timer
.clk
);
1326 s
->timer
.enable
= 1;
1327 s
->timer
.it_ena
= 1;
1328 s
->timer
.reset_val
= 0xffff;
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
)
1340 struct omap_watchdog_timer_s
*s
= (struct omap_watchdog_timer_s
*)
1341 qemu_mallocz(sizeof(struct omap_watchdog_timer_s
));
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
);
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
;
1368 case 0x00: /* TVR */
1369 return s
->timer
.reset_val
;
1371 case 0x04: /* TCR */
1372 return omap_timer_read(&s
->timer
);
1375 return (s
->timer
.ar
<< 3) | (s
->timer
.it_ena
<< 2) | s
->timer
.st
;
1384 static void omap_os_timer_write(void *opaque
, target_phys_addr_t addr
,
1387 struct omap_32khz_timer_s
*s
= (struct omap_32khz_timer_s
*) opaque
;
1388 int offset
= addr
- s
->timer
.base
;
1391 case 0x00: /* TVR */
1392 s
->timer
.reset_val
= value
& 0x00ffffff;
1395 case 0x04: /* TCR */
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
);
1415 static CPUReadMemoryFunc
*omap_os_timer_readfn
[] = {
1416 omap_badwidth_read32
,
1417 omap_badwidth_read32
,
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;
1439 struct omap_32khz_timer_s
*omap_os_timer_init(target_phys_addr_t base
,
1440 qemu_irq irq
, omap_clk clk
)
1443 struct omap_32khz_timer_s
*s
= (struct omap_32khz_timer_s
*)
1444 qemu_mallocz(sizeof(struct omap_32khz_timer_s
));
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
);
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
;
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
]);
1474 case 0x18: /* Reserved */
1475 case 0x1c: /* Reserved */
1476 case 0x20: /* Reserved */
1477 case 0x28: /* Reserved */
1478 case 0x2c: /* Reserved */
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];
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
,
1527 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
1528 int offset
= addr
- s
->ulpd_pm_base
;
1531 static const int bypass_div
[4] = { 1, 2, 4, 4 };
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 */
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
);
1550 s
->ulpd_gauge_start
= now
;
1552 now
-= s
->ulpd_gauge_start
;
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
;
1575 case 0x18: /* Reserved */
1576 case 0x1c: /* Reserved */
1577 case 0x20: /* Reserved */
1578 case 0x28: /* Reserved */
1579 case 0x2c: /* Reserved */
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
;
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
);
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
);
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 */
1612 div
= bypass_div
[((value
>> 2) & 3)]; /* BYPASS_DIV */
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;
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"));
1640 static CPUReadMemoryFunc
*omap_ulpd_pm_readfn
[] = {
1641 omap_badwidth_read16
,
1643 omap_badwidth_read16
,
1646 static CPUWriteMemoryFunc
*omap_ulpd_pm_writefn
[] = {
1647 omap_badwidth_write16
,
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
;
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];
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"),
1748 if (diff
& (1 << 7)) /* USB.CLKO */
1749 omap_clk_onoff(omap_findclk(s
, "usb.clko"),
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"),
1761 if (diff
& (1 << 1)) /* CLK32K */
1762 omap_clk_onoff(omap_findclk(s
, "clk32k_out"),
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
,
1797 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
1798 int offset
= addr
- s
->pin_cfg_base
;
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
);
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
);
1814 case 0x08: /* FUNC_MUX_CTRL_2 */
1815 s
->func_mux_ctrl
[offset
>> 2] = value
;
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]);
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
;
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
;
1846 case 0x50: /* GATE_INH_CTRL_0 */
1847 s
->gate_inh_ctrl
[0] = value
;
1850 case 0x60: /* VOLTAGE_CTRL_0 */
1851 s
->voltage_ctrl
[0] = value
;
1854 case 0x70: /* TEST_DBG_CTRL_0 */
1855 s
->test_dbg_ctrl
[0] = value
;
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
);
1869 static CPUReadMemoryFunc
*omap_pin_cfg_readfn
[] = {
1870 omap_badwidth_read32
,
1871 omap_badwidth_read32
,
1875 static CPUWriteMemoryFunc
*omap_pin_cfg_writefn
[] = {
1876 omap_badwidth_write32
,
1877 omap_badwidth_write32
,
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
;
1914 case 0xfffe1800: /* DIE_ID_LSB */
1916 case 0xfffe1804: /* DIE_ID_MSB */
1919 case 0xfffe2000: /* PRODUCT_ID_LSB */
1921 case 0xfffe2004: /* PRODUCT_ID_MSB */
1924 case 0xfffed400: /* JTAG_ID_LSB */
1925 switch (s
->mpu_model
) {
1933 case 0xfffed404: /* JTAG_ID_MSB */
1934 switch (s
->mpu_model
) {
1947 static void omap_id_write(void *opaque
, target_phys_addr_t addr
,
1953 static CPUReadMemoryFunc
*omap_id_readfn
[] = {
1954 omap_badwidth_read32
,
1955 omap_badwidth_read32
,
1959 static CPUWriteMemoryFunc
*omap_id_writefn
[] = {
1960 omap_badwidth_write32
,
1961 omap_badwidth_write32
,
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
;
1982 case 0x00: /* CTRL */
1983 return s
->mpui_ctrl
;
1984 case 0x04: /* DEBUG_ADDR */
1986 case 0x08: /* DEBUG_DATA */
1988 case 0x0c: /* DEBUG_FLAG */
1990 case 0x10: /* STATUS */
1993 /* Not in OMAP310 */
1994 case 0x14: /* DSP_STATUS */
1995 case 0x18: /* DSP_BOOT_CONFIG */
1997 case 0x1c: /* DSP_MPUI_CONFIG */
2005 static void omap_mpui_write(void *opaque
, target_phys_addr_t addr
,
2008 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2009 int offset
= addr
- s
->mpui_base
;
2012 case 0x00: /* CTRL */
2013 s
->mpui_ctrl
= value
& 0x007fffff;
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 */
2023 case 0x18: /* DSP_BOOT_CONFIG */
2024 case 0x1c: /* DSP_MPUI_CONFIG */
2032 static CPUReadMemoryFunc
*omap_mpui_readfn
[] = {
2033 omap_badwidth_read32
,
2034 omap_badwidth_read32
,
2038 static CPUWriteMemoryFunc
*omap_mpui_writefn
[] = {
2039 omap_badwidth_write32
,
2040 omap_badwidth_write32
,
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
);
2062 struct omap_tipb_bridge_s
{
2063 target_phys_addr_t base
;
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
;
2079 case 0x00: /* TIPB_CNTL */
2081 case 0x04: /* TIPB_BUS_ALLOC */
2083 case 0x08: /* MPU_TIPB_CNTL */
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 */
2091 case 0x1c: /* DEBUG_CNTR_SIG */
2099 static void omap_tipb_bridge_write(void *opaque
, target_phys_addr_t addr
,
2102 struct omap_tipb_bridge_s
*s
= (struct omap_tipb_bridge_s
*) opaque
;
2103 int offset
= addr
- s
->base
;
2106 case 0x00: /* TIPB_CNTL */
2107 s
->control
= value
& 0xffff;
2110 case 0x04: /* TIPB_BUS_ALLOC */
2111 s
->alloc
= value
& 0x003f;
2114 case 0x08: /* MPU_TIPB_CNTL */
2115 s
->buffer
= value
& 0x0003;
2118 case 0x0c: /* ENHANCED_TIPB_CNTL */
2119 s
->width_intr
= !(value
& 2);
2120 s
->enh_control
= value
& 0x000f;
2123 case 0x10: /* ADDRESS_DBG */
2124 case 0x14: /* DATA_DEBUG_LOW */
2125 case 0x18: /* DATA_DEBUG_HIGH */
2126 case 0x1c: /* DEBUG_CNTR_SIG */
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;
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
)
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
;
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
);
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
;
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 */
2208 static void omap_tcmi_write(void *opaque
, target_phys_addr_t addr
,
2211 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2212 int offset
= addr
- s
->tcmi_base
;
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
;
2231 case 0xfffecc0c: /* EMIFS_CONFIG */
2232 s
->tcmi_regs
[offset
>> 2] = (value
& 0xf) | (1 << 4);
2240 static CPUReadMemoryFunc
*omap_tcmi_readfn
[] = {
2241 omap_badwidth_read32
,
2242 omap_badwidth_read32
,
2246 static CPUWriteMemoryFunc
*omap_tcmi_writefn
[] = {
2247 omap_badwidth_write32
,
2248 omap_badwidth_write32
,
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 */
2295 static void omap_dpll_write(void *opaque
, target_phys_addr_t addr
,
2298 struct dpll_ctl_s
*s
= (struct dpll_ctl_s
*) opaque
;
2300 int offset
= addr
- s
->base
;
2301 static const int bypass_div
[4] = { 1, 2, 4, 4 };
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 */
2313 div
= bypass_div
[((value
>> 2) & 3)]; /* BYPASS_DIV */
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. */
2329 static CPUReadMemoryFunc
*omap_dpll_readfn
[] = {
2330 omap_badwidth_read16
,
2332 omap_badwidth_read16
,
2335 static CPUWriteMemoryFunc
*omap_dpll_writefn
[] = {
2336 omap_badwidth_write16
,
2338 omap_badwidth_write16
,
2341 static void omap_dpll_reset(struct dpll_ctl_s
*s
)
2344 omap_clk_setrate(s
->dpll
, 1, 1);
2347 static void omap_dpll_init(struct dpll_ctl_s
*s
, target_phys_addr_t base
,
2350 int iomemtype
= cpu_register_io_memory(0, omap_dpll_readfn
,
2351 omap_dpll_writefn
, s
);
2357 cpu_register_physical_memory(s
->base
, 0x100, iomemtype
);
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
));
2375 s
->serial
= serial_mm_init(base
, 2, irq
, chr
, 1);
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
;
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 */
2418 static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s
*s
,
2419 uint16_t diff
, uint16_t value
)
2423 if (diff
& (1 << 14)) { /* ARM_INTHCK_SEL */
2424 if (value
& (1 << 14))
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"));
2436 omap_clk_reparent(clk
, omap_findclk(s
, "ck_gen1"));
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
)
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
)
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
)
2524 if (diff
& (3 << 4)) { /* TCLKOUT */
2525 clk
= omap_findclk(s
, "tclk_out");
2526 switch ((value
>> 4) & 3) {
2528 omap_clk_reparent(clk
, omap_findclk(s
, "ck_gen3"));
2529 omap_clk_onoff(clk
, 1);
2532 omap_clk_reparent(clk
, omap_findclk(s
, "tc_ck"));
2533 omap_clk_onoff(clk
, 1);
2536 omap_clk_onoff(clk
, 0);
2539 if (diff
& (3 << 2)) { /* DCLKOUT */
2540 clk
= omap_findclk(s
, "dclk_out");
2541 switch ((value
>> 2) & 3) {
2543 omap_clk_reparent(clk
, omap_findclk(s
, "dspmmu_ck"));
2546 omap_clk_reparent(clk
, omap_findclk(s
, "ck_gen2"));
2549 omap_clk_reparent(clk
, omap_findclk(s
, "dsp_ck"));
2552 omap_clk_reparent(clk
, omap_findclk(s
, "ck_ref14"));
2556 if (diff
& (3 << 0)) { /* ACLKOUT */
2557 clk
= omap_findclk(s
, "aclk_out");
2558 switch ((value
>> 0) & 3) {
2560 omap_clk_reparent(clk
, omap_findclk(s
, "ck_gen1"));
2561 omap_clk_onoff(clk
, 1);
2564 omap_clk_reparent(clk
, omap_findclk(s
, "arm_ck"));
2565 omap_clk_onoff(clk
, 1);
2568 omap_clk_reparent(clk
, omap_findclk(s
, "ck_ref14"));
2569 omap_clk_onoff(clk
, 1);
2572 omap_clk_onoff(clk
, 0);
2577 static void omap_clkm_write(void *opaque
, target_phys_addr_t addr
,
2580 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2581 int offset
= addr
- s
->clkm
.mpu_base
;
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",
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
);
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
);
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
);
2608 case 0x0c: /* ARM_EWUPCT */
2609 diff
= s
->clkm
.arm_ewupct
^ value
;
2610 s
->clkm
.arm_ewupct
= value
& 0x003f;
2613 case 0x10: /* ARM_RSTCT1 */
2614 diff
= s
->clkm
.arm_rstct1
^ value
;
2615 s
->clkm
.arm_rstct1
= value
& 0x0007;
2617 qemu_system_reset_request();
2618 s
->clkm
.cold_start
= 0xa;
2620 if (diff
& ~value
& 4) { /* DSP_RST */
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);
2631 case 0x14: /* ARM_RSTCT2 */
2632 s
->clkm
.arm_rstct2
= value
& 0x0001;
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;
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
);
2650 case 0x20: /* ARM_CKOUT2 */
2656 static CPUReadMemoryFunc
*omap_clkm_readfn
[] = {
2657 omap_badwidth_read16
,
2659 omap_badwidth_read16
,
2662 static CPUWriteMemoryFunc
*omap_clkm_writefn
[] = {
2663 omap_badwidth_write16
,
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
;
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... */
2692 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s
*s
,
2693 uint16_t diff
, uint16_t value
)
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
)
2705 SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */
2708 static void omap_clkdsp_write(void *opaque
, target_phys_addr_t addr
,
2711 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2712 int offset
= addr
- s
->clkm
.dsp_base
;
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
);
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
);
2728 case 0x14: /* DSP_RSTCT2 */
2729 s
->clkm
.dsp_rstct2
= value
& 0x0001;
2732 case 0x18: /* DSP_SYSST */
2733 s
->clkm
.cold_start
&= value
& 0x3f;
2741 static CPUReadMemoryFunc
*omap_clkdsp_readfn
[] = {
2742 omap_badwidth_read16
,
2744 omap_badwidth_read16
,
2747 static CPUWriteMemoryFunc
*omap_clkdsp_writefn
[] = {
2748 omap_badwidth_write16
,
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;
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
;
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");
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
);
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"),
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];