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,
25 #include "qemu-timer.h"
26 /* We use pc-style serial ports. */
29 /* Should signal the TCMI */
30 uint32_t omap_badwidth_read8(void *opaque
, target_phys_addr_t addr
)
35 cpu_physical_memory_read(addr
, (void *) &ret
, 1);
39 void omap_badwidth_write8(void *opaque
, target_phys_addr_t addr
,
45 cpu_physical_memory_write(addr
, (void *) &val8
, 1);
48 uint32_t omap_badwidth_read16(void *opaque
, target_phys_addr_t addr
)
53 cpu_physical_memory_read(addr
, (void *) &ret
, 2);
57 void omap_badwidth_write16(void *opaque
, target_phys_addr_t addr
,
60 uint16_t val16
= value
;
63 cpu_physical_memory_write(addr
, (void *) &val16
, 2);
66 uint32_t omap_badwidth_read32(void *opaque
, target_phys_addr_t addr
)
71 cpu_physical_memory_read(addr
, (void *) &ret
, 4);
75 void omap_badwidth_write32(void *opaque
, target_phys_addr_t addr
,
79 cpu_physical_memory_write(addr
, (void *) &value
, 4);
82 /* Interrupt Handlers */
83 struct omap_intr_handler_bank_s
{
89 unsigned char priority
[32];
92 struct omap_intr_handler_s
{
94 qemu_irq parent_intr
[2];
95 target_phys_addr_t base
;
101 struct omap_intr_handler_bank_s banks
[];
104 static void omap_inth_sir_update(struct omap_intr_handler_s
*s
, int is_fiq
)
106 int i
, j
, sir_intr
, p_intr
, p
, f
;
111 /* Find the interrupt line with the highest dynamic priority.
112 * Note: 0 denotes the hightest priority.
113 * If all interrupts have the same priority, the default order is IRQ_N,
114 * IRQ_N-1,...,IRQ_0. */
115 for (j
= 0; j
< s
->nbanks
; ++j
) {
116 level
= s
->banks
[j
].irqs
& ~s
->banks
[j
].mask
&
117 (is_fiq
? s
->banks
[j
].fiq
: ~s
->banks
[j
].fiq
);
118 for (f
= ffs(level
), i
= f
- 1, level
>>= f
- 1; f
; i
+= f
,
120 p
= s
->banks
[j
].priority
[i
];
123 sir_intr
= 32 * j
+ i
;
128 s
->sir_intr
[is_fiq
] = sir_intr
;
131 static inline void omap_inth_update(struct omap_intr_handler_s
*s
, int is_fiq
)
134 uint32_t has_intr
= 0;
136 for (i
= 0; i
< s
->nbanks
; ++i
)
137 has_intr
|= s
->banks
[i
].irqs
& ~s
->banks
[i
].mask
&
138 (is_fiq
? s
->banks
[i
].fiq
: ~s
->banks
[i
].fiq
);
140 if (s
->new_agr
[is_fiq
] && has_intr
) {
141 s
->new_agr
[is_fiq
] = 0;
142 omap_inth_sir_update(s
, is_fiq
);
143 qemu_set_irq(s
->parent_intr
[is_fiq
], 1);
147 #define INT_FALLING_EDGE 0
148 #define INT_LOW_LEVEL 1
150 static void omap_set_intr(void *opaque
, int irq
, int req
)
152 struct omap_intr_handler_s
*ih
= (struct omap_intr_handler_s
*) opaque
;
155 struct omap_intr_handler_bank_s
*bank
= &ih
->banks
[irq
>> 5];
159 rise
= ~bank
->irqs
& (1 << n
);
160 if (~bank
->sens_edge
& (1 << n
))
161 rise
&= ~bank
->inputs
& (1 << n
);
163 bank
->inputs
|= (1 << n
);
166 omap_inth_update(ih
, 0);
167 omap_inth_update(ih
, 1);
170 rise
= bank
->sens_edge
& bank
->irqs
& (1 << n
);
172 bank
->inputs
&= ~(1 << n
);
176 static uint32_t omap_inth_read(void *opaque
, target_phys_addr_t addr
)
178 struct omap_intr_handler_s
*s
= (struct omap_intr_handler_s
*) opaque
;
179 int i
, offset
= addr
- s
->base
;
180 int bank_no
= offset
>> 8;
182 struct omap_intr_handler_bank_s
*bank
= &s
->banks
[bank_no
];
192 case 0x10: /* SIR_IRQ_CODE */
193 case 0x14: /* SIR_FIQ_CODE */
196 line_no
= s
->sir_intr
[(offset
- 0x10) >> 2];
197 bank
= &s
->banks
[line_no
>> 5];
199 if (((bank
->sens_edge
>> i
) & 1) == INT_FALLING_EDGE
)
200 bank
->irqs
&= ~(1 << i
);
203 case 0x18: /* CONTROL_REG */
208 case 0x1c: /* ILR0 */
209 case 0x20: /* ILR1 */
210 case 0x24: /* ILR2 */
211 case 0x28: /* ILR3 */
212 case 0x2c: /* ILR4 */
213 case 0x30: /* ILR5 */
214 case 0x34: /* ILR6 */
215 case 0x38: /* ILR7 */
216 case 0x3c: /* ILR8 */
217 case 0x40: /* ILR9 */
218 case 0x44: /* ILR10 */
219 case 0x48: /* ILR11 */
220 case 0x4c: /* ILR12 */
221 case 0x50: /* ILR13 */
222 case 0x54: /* ILR14 */
223 case 0x58: /* ILR15 */
224 case 0x5c: /* ILR16 */
225 case 0x60: /* ILR17 */
226 case 0x64: /* ILR18 */
227 case 0x68: /* ILR19 */
228 case 0x6c: /* ILR20 */
229 case 0x70: /* ILR21 */
230 case 0x74: /* ILR22 */
231 case 0x78: /* ILR23 */
232 case 0x7c: /* ILR24 */
233 case 0x80: /* ILR25 */
234 case 0x84: /* ILR26 */
235 case 0x88: /* ILR27 */
236 case 0x8c: /* ILR28 */
237 case 0x90: /* ILR29 */
238 case 0x94: /* ILR30 */
239 case 0x98: /* ILR31 */
240 i
= (offset
- 0x1c) >> 2;
241 return (bank
->priority
[i
] << 2) |
242 (((bank
->sens_edge
>> i
) & 1) << 1) |
243 ((bank
->fiq
>> i
) & 1);
253 static void omap_inth_write(void *opaque
, target_phys_addr_t addr
,
256 struct omap_intr_handler_s
*s
= (struct omap_intr_handler_s
*) opaque
;
257 int i
, offset
= addr
- s
->base
;
258 int bank_no
= offset
>> 8;
259 struct omap_intr_handler_bank_s
*bank
= &s
->banks
[bank_no
];
264 /* Important: ignore the clearing if the IRQ is level-triggered and
265 the input bit is 1 */
266 bank
->irqs
&= value
| (bank
->inputs
& bank
->sens_edge
);
271 omap_inth_update(s
, 0);
272 omap_inth_update(s
, 1);
275 case 0x10: /* SIR_IRQ_CODE */
276 case 0x14: /* SIR_FIQ_CODE */
280 case 0x18: /* CONTROL_REG */
284 qemu_set_irq(s
->parent_intr
[1], 0);
286 omap_inth_update(s
, 1);
289 qemu_set_irq(s
->parent_intr
[0], 0);
291 omap_inth_update(s
, 0);
295 case 0x1c: /* ILR0 */
296 case 0x20: /* ILR1 */
297 case 0x24: /* ILR2 */
298 case 0x28: /* ILR3 */
299 case 0x2c: /* ILR4 */
300 case 0x30: /* ILR5 */
301 case 0x34: /* ILR6 */
302 case 0x38: /* ILR7 */
303 case 0x3c: /* ILR8 */
304 case 0x40: /* ILR9 */
305 case 0x44: /* ILR10 */
306 case 0x48: /* ILR11 */
307 case 0x4c: /* ILR12 */
308 case 0x50: /* ILR13 */
309 case 0x54: /* ILR14 */
310 case 0x58: /* ILR15 */
311 case 0x5c: /* ILR16 */
312 case 0x60: /* ILR17 */
313 case 0x64: /* ILR18 */
314 case 0x68: /* ILR19 */
315 case 0x6c: /* ILR20 */
316 case 0x70: /* ILR21 */
317 case 0x74: /* ILR22 */
318 case 0x78: /* ILR23 */
319 case 0x7c: /* ILR24 */
320 case 0x80: /* ILR25 */
321 case 0x84: /* ILR26 */
322 case 0x88: /* ILR27 */
323 case 0x8c: /* ILR28 */
324 case 0x90: /* ILR29 */
325 case 0x94: /* ILR30 */
326 case 0x98: /* ILR31 */
327 i
= (offset
- 0x1c) >> 2;
328 bank
->priority
[i
] = (value
>> 2) & 0x1f;
329 bank
->sens_edge
&= ~(1 << i
);
330 bank
->sens_edge
|= ((value
>> 1) & 1) << i
;
331 bank
->fiq
&= ~(1 << i
);
332 bank
->fiq
|= (value
& 1) << i
;
336 for (i
= 0; i
< 32; i
++)
337 if (value
& (1 << i
)) {
338 omap_set_intr(s
, 32 * bank_no
+ i
, 1);
346 static CPUReadMemoryFunc
*omap_inth_readfn
[] = {
347 omap_badwidth_read32
,
348 omap_badwidth_read32
,
352 static CPUWriteMemoryFunc
*omap_inth_writefn
[] = {
358 void omap_inth_reset(struct omap_intr_handler_s
*s
)
362 for (i
= 0; i
< s
->nbanks
; ++i
){
363 s
->banks
[i
].irqs
= 0x00000000;
364 s
->banks
[i
].mask
= 0xffffffff;
365 s
->banks
[i
].sens_edge
= 0x00000000;
366 s
->banks
[i
].fiq
= 0x00000000;
367 s
->banks
[i
].inputs
= 0x00000000;
368 memset(s
->banks
[i
].priority
, 0, sizeof(s
->banks
[i
].priority
));
376 qemu_set_irq(s
->parent_intr
[0], 0);
377 qemu_set_irq(s
->parent_intr
[1], 0);
380 struct omap_intr_handler_s
*omap_inth_init(target_phys_addr_t base
,
381 unsigned long size
, unsigned char nbanks
,
382 qemu_irq parent_irq
, qemu_irq parent_fiq
, omap_clk clk
)
385 struct omap_intr_handler_s
*s
= (struct omap_intr_handler_s
*)
386 qemu_mallocz(sizeof(struct omap_intr_handler_s
) +
387 sizeof(struct omap_intr_handler_bank_s
) * nbanks
);
389 s
->parent_intr
[0] = parent_irq
;
390 s
->parent_intr
[1] = parent_fiq
;
393 s
->pins
= qemu_allocate_irqs(omap_set_intr
, s
, nbanks
* 32);
397 iomemtype
= cpu_register_io_memory(0, omap_inth_readfn
,
398 omap_inth_writefn
, s
);
399 cpu_register_physical_memory(s
->base
, size
, iomemtype
);
404 /* OMAP1 DMA module */
405 struct omap_dma_channel_s
{
409 enum omap_dma_port port
[2];
410 target_phys_addr_t addr
[2];
411 omap_dma_addressing_t mode
[2];
414 int16_t frame_index
[2];
415 int16_t element_index
[2];
419 int transparent_copy
;
423 /* auto init and linked channel data */
430 /* interruption data */
439 int waiting_end_prog
;
447 int omap_3_1_compatible_disable
;
450 struct omap_dma_channel_s
*sibling
;
452 struct omap_dma_reg_set_s
{
453 target_phys_addr_t src
, dest
;
462 /* unused parameters */
464 int interleave_disabled
;
470 struct omap_mpu_state_s
*mpu
;
471 target_phys_addr_t base
;
475 enum omap_dma_model model
;
476 int omap_3_1_mapping_disabled
;
482 struct omap_dma_channel_s ch
[16];
483 struct omap_dma_lcd_channel_s lcd_ch
;
487 #define TIMEOUT_INTR (1 << 0)
488 #define EVENT_DROP_INTR (1 << 1)
489 #define HALF_FRAME_INTR (1 << 2)
490 #define END_FRAME_INTR (1 << 3)
491 #define LAST_FRAME_INTR (1 << 4)
492 #define END_BLOCK_INTR (1 << 5)
493 #define SYNC (1 << 6)
495 static void omap_dma_interrupts_update(struct omap_dma_s
*s
)
497 struct omap_dma_channel_s
*ch
= s
->ch
;
500 if (s
->omap_3_1_mapping_disabled
) {
501 for (i
= 0; i
< s
->chans
; i
++, ch
++)
503 qemu_irq_raise(ch
->irq
);
505 /* First three interrupts are shared between two channels each. */
506 for (i
= 0; i
< 6; i
++, ch
++) {
507 if (ch
->status
|| (ch
->sibling
&& ch
->sibling
->status
))
508 qemu_irq_raise(ch
->irq
);
513 static void omap_dma_channel_load(struct omap_dma_s
*s
,
514 struct omap_dma_channel_s
*ch
)
516 struct omap_dma_reg_set_s
*a
= &ch
->active_set
;
518 int omap_3_1
= !ch
->omap_3_1_compatible_disable
;
521 * TODO: verify address ranges and alignment
522 * TODO: port endianness
525 a
->src
= ch
->addr
[0];
526 a
->dest
= ch
->addr
[1];
527 a
->frames
= ch
->frames
;
528 a
->elements
= ch
->elements
;
532 if (unlikely(!ch
->elements
|| !ch
->frames
)) {
533 printf("%s: bad DMA request\n", __FUNCTION__
);
537 for (i
= 0; i
< 2; i
++)
538 switch (ch
->mode
[i
]) {
540 a
->elem_delta
[i
] = 0;
541 a
->frame_delta
[i
] = 0;
543 case post_incremented
:
544 a
->elem_delta
[i
] = ch
->data_type
;
545 a
->frame_delta
[i
] = 0;
548 a
->elem_delta
[i
] = ch
->data_type
+
549 ch
->element_index
[omap_3_1
? 0 : i
] - 1;
550 a
->frame_delta
[i
] = 0;
553 a
->elem_delta
[i
] = ch
->data_type
+
554 ch
->element_index
[omap_3_1
? 0 : i
] - 1;
555 a
->frame_delta
[i
] = ch
->frame_index
[omap_3_1
? 0 : i
] -
556 ch
->element_index
[omap_3_1
? 0 : i
];
563 static void omap_dma_activate_channel(struct omap_dma_s
*s
,
564 struct omap_dma_channel_s
*ch
)
573 if (s
->delay
&& !qemu_timer_pending(s
->tm
))
574 qemu_mod_timer(s
->tm
, qemu_get_clock(vm_clock
) + s
->delay
);
577 static void omap_dma_deactivate_channel(struct omap_dma_s
*s
,
578 struct omap_dma_channel_s
*ch
)
581 ch
->cpc
= ch
->active_set
.dest
& 0xffff;
583 if (ch
->pending_request
&& !ch
->waiting_end_prog
) {
584 /* Don't deactivate the channel */
585 ch
->pending_request
= 0;
589 /* Don't deactive the channel if it is synchronized and the DMA request is
591 if (ch
->sync
&& (s
->drq
& (1 << ch
->sync
)))
601 qemu_del_timer(s
->tm
);
604 static void omap_dma_enable_channel(struct omap_dma_s
*s
,
605 struct omap_dma_channel_s
*ch
)
609 ch
->waiting_end_prog
= 0;
610 omap_dma_channel_load(s
, ch
);
611 if ((!ch
->sync
) || (s
->drq
& (1 << ch
->sync
)))
612 omap_dma_activate_channel(s
, ch
);
616 static void omap_dma_disable_channel(struct omap_dma_s
*s
,
617 struct omap_dma_channel_s
*ch
)
621 /* Discard any pending request */
622 ch
->pending_request
= 0;
623 omap_dma_deactivate_channel(s
, ch
);
627 static void omap_dma_channel_end_prog(struct omap_dma_s
*s
,
628 struct omap_dma_channel_s
*ch
)
630 if (ch
->waiting_end_prog
) {
631 ch
->waiting_end_prog
= 0;
632 if (!ch
->sync
|| ch
->pending_request
) {
633 ch
->pending_request
= 0;
634 omap_dma_activate_channel(s
, ch
);
639 static void omap_dma_enable_3_1_mapping(struct omap_dma_s
*s
)
641 s
->omap_3_1_mapping_disabled
= 0;
645 static void omap_dma_disable_3_1_mapping(struct omap_dma_s
*s
)
647 s
->omap_3_1_mapping_disabled
= 1;
651 static void omap_dma_process_request(struct omap_dma_s
*s
, int request
)
655 struct omap_dma_channel_s
*ch
= s
->ch
;
657 for (channel
= 0; channel
< s
->chans
; channel
++, ch
++) {
658 if (ch
->enable
&& ch
->sync
== request
) {
660 omap_dma_activate_channel(s
, ch
);
661 else if (!ch
->pending_request
)
662 ch
->pending_request
= 1;
664 /* Request collision */
665 /* Second request received while processing other request */
666 ch
->status
|= EVENT_DROP_INTR
;
673 omap_dma_interrupts_update(s
);
676 static void omap_dma_channel_run(struct omap_dma_s
*s
)
681 struct omap_dma_port_if_s
*src_p
, *dest_p
;
682 struct omap_dma_reg_set_s
*a
;
683 struct omap_dma_channel_s
*ch
;
685 for (ch
= s
->ch
; n
; n
--, ch
++) {
691 src_p
= &s
->mpu
->port
[ch
->port
[0]];
692 dest_p
= &s
->mpu
->port
[ch
->port
[1]];
693 if ((!ch
->constant_fill
&& !src_p
->addr_valid(s
->mpu
, a
->src
)) ||
694 (!dest_p
->addr_valid(s
->mpu
, a
->dest
))) {
697 if (ch
->interrupts
& TIMEOUT_INTR
)
698 ch
->status
|= TIMEOUT_INTR
;
699 omap_dma_deactivate_channel(s
, ch
);
702 printf("%s: Bus time-out in DMA%i operation\n",
703 __FUNCTION__
, s
->chans
- n
);
707 while (status
== ch
->status
&& ch
->active
) {
708 /* Transfer a single element */
709 /* FIXME: check the endianness */
710 if (!ch
->constant_fill
)
711 cpu_physical_memory_read(a
->src
, value
, ch
->data_type
);
713 *(uint32_t *) value
= ch
->color
;
715 if (!ch
->transparent_copy
||
716 *(uint32_t *) value
!= ch
->color
)
717 cpu_physical_memory_write(a
->dest
, value
, ch
->data_type
);
719 a
->src
+= a
->elem_delta
[0];
720 a
->dest
+= a
->elem_delta
[1];
723 /* If the channel is element synchronized, deactivate it */
724 if (ch
->sync
&& !ch
->fs
&& !ch
->bs
)
725 omap_dma_deactivate_channel(s
, ch
);
727 /* If it is the last frame, set the LAST_FRAME interrupt */
728 if (a
->element
== 1 && a
->frame
== a
->frames
- 1)
729 if (ch
->interrupts
& LAST_FRAME_INTR
)
730 ch
->status
|= LAST_FRAME_INTR
;
732 /* If the half of the frame was reached, set the HALF_FRAME
734 if (a
->element
== (a
->elements
>> 1))
735 if (ch
->interrupts
& HALF_FRAME_INTR
)
736 ch
->status
|= HALF_FRAME_INTR
;
738 if (a
->element
== a
->elements
) {
741 a
->src
+= a
->frame_delta
[0];
742 a
->dest
+= a
->frame_delta
[1];
745 /* If the channel is frame synchronized, deactivate it */
746 if (ch
->sync
&& ch
->fs
)
747 omap_dma_deactivate_channel(s
, ch
);
749 /* If the channel is async, update cpc */
751 ch
->cpc
= a
->dest
& 0xffff;
753 /* Set the END_FRAME interrupt */
754 if (ch
->interrupts
& END_FRAME_INTR
)
755 ch
->status
|= END_FRAME_INTR
;
757 if (a
->frame
== a
->frames
) {
759 /* Disable the channel */
761 if (ch
->omap_3_1_compatible_disable
) {
762 omap_dma_disable_channel(s
, ch
);
763 if (ch
->link_enabled
)
764 omap_dma_enable_channel(s
,
765 &s
->ch
[ch
->link_next_ch
]);
768 omap_dma_disable_channel(s
, ch
);
769 else if (ch
->repeat
|| ch
->end_prog
)
770 omap_dma_channel_load(s
, ch
);
772 ch
->waiting_end_prog
= 1;
773 omap_dma_deactivate_channel(s
, ch
);
777 if (ch
->interrupts
& END_BLOCK_INTR
)
778 ch
->status
|= END_BLOCK_INTR
;
784 omap_dma_interrupts_update(s
);
785 if (s
->run_count
&& s
->delay
)
786 qemu_mod_timer(s
->tm
, qemu_get_clock(vm_clock
) + s
->delay
);
789 static void omap_dma_reset(struct omap_dma_s
*s
)
793 qemu_del_timer(s
->tm
);
797 s
->lcd_ch
.src
= emiff
;
798 s
->lcd_ch
.condition
= 0;
799 s
->lcd_ch
.interrupts
= 0;
801 omap_dma_enable_3_1_mapping(s
);
802 for (i
= 0; i
< s
->chans
; i
++) {
803 memset(&s
->ch
[i
].burst
, 0, sizeof(s
->ch
[i
].burst
));
804 memset(&s
->ch
[i
].port
, 0, sizeof(s
->ch
[i
].port
));
805 memset(&s
->ch
[i
].mode
, 0, sizeof(s
->ch
[i
].mode
));
806 memset(&s
->ch
[i
].elements
, 0, sizeof(s
->ch
[i
].elements
));
807 memset(&s
->ch
[i
].frames
, 0, sizeof(s
->ch
[i
].frames
));
808 memset(&s
->ch
[i
].frame_index
, 0, sizeof(s
->ch
[i
].frame_index
));
809 memset(&s
->ch
[i
].element_index
, 0, sizeof(s
->ch
[i
].element_index
));
810 memset(&s
->ch
[i
].data_type
, 0, sizeof(s
->ch
[i
].data_type
));
811 memset(&s
->ch
[i
].transparent_copy
, 0,
812 sizeof(s
->ch
[i
].transparent_copy
));
813 memset(&s
->ch
[i
].constant_fill
, 0, sizeof(s
->ch
[i
].constant_fill
));
814 memset(&s
->ch
[i
].color
, 0, sizeof(s
->ch
[i
].color
));
815 memset(&s
->ch
[i
].end_prog
, 0, sizeof(s
->ch
[i
].end_prog
));
816 memset(&s
->ch
[i
].repeat
, 0, sizeof(s
->ch
[i
].repeat
));
817 memset(&s
->ch
[i
].auto_init
, 0, sizeof(s
->ch
[i
].auto_init
));
818 memset(&s
->ch
[i
].link_enabled
, 0, sizeof(s
->ch
[i
].link_enabled
));
819 memset(&s
->ch
[i
].link_next_ch
, 0, sizeof(s
->ch
[i
].link_next_ch
));
820 s
->ch
[i
].interrupts
= 0x0003;
821 memset(&s
->ch
[i
].status
, 0, sizeof(s
->ch
[i
].status
));
822 memset(&s
->ch
[i
].active
, 0, sizeof(s
->ch
[i
].active
));
823 memset(&s
->ch
[i
].enable
, 0, sizeof(s
->ch
[i
].enable
));
824 memset(&s
->ch
[i
].sync
, 0, sizeof(s
->ch
[i
].sync
));
825 memset(&s
->ch
[i
].pending_request
, 0, sizeof(s
->ch
[i
].pending_request
));
826 memset(&s
->ch
[i
].waiting_end_prog
, 0,
827 sizeof(s
->ch
[i
].waiting_end_prog
));
828 memset(&s
->ch
[i
].cpc
, 0, sizeof(s
->ch
[i
].cpc
));
829 memset(&s
->ch
[i
].fs
, 0, sizeof(s
->ch
[i
].fs
));
830 memset(&s
->ch
[i
].bs
, 0, sizeof(s
->ch
[i
].bs
));
831 memset(&s
->ch
[i
].omap_3_1_compatible_disable
, 0,
832 sizeof(s
->ch
[i
].omap_3_1_compatible_disable
));
833 memset(&s
->ch
[i
].active_set
, 0, sizeof(s
->ch
[i
].active_set
));
834 memset(&s
->ch
[i
].priority
, 0, sizeof(s
->ch
[i
].priority
));
835 memset(&s
->ch
[i
].interleave_disabled
, 0,
836 sizeof(s
->ch
[i
].interleave_disabled
));
837 memset(&s
->ch
[i
].type
, 0, sizeof(s
->ch
[i
].type
));
841 static int omap_dma_ch_reg_read(struct omap_dma_s
*s
,
842 struct omap_dma_channel_s
*ch
, int reg
, uint16_t *value
)
845 case 0x00: /* SYS_DMA_CSDP_CH0 */
846 *value
= (ch
->burst
[1] << 14) |
847 (ch
->pack
[1] << 13) |
849 (ch
->burst
[0] << 7) |
852 (ch
->data_type
>> 1);
855 case 0x02: /* SYS_DMA_CCR_CH0 */
856 if (s
->model
== omap_dma_3_1
)
857 *value
= 0 << 10; /* FIFO_FLUSH reads as 0 */
859 *value
= ch
->omap_3_1_compatible_disable
<< 10;
860 *value
|= (ch
->mode
[1] << 14) |
861 (ch
->mode
[0] << 12) |
862 (ch
->end_prog
<< 11) |
864 (ch
->auto_init
<< 8) |
866 (ch
->priority
<< 6) |
867 (ch
->fs
<< 5) | ch
->sync
;
870 case 0x04: /* SYS_DMA_CICR_CH0 */
871 *value
= ch
->interrupts
;
874 case 0x06: /* SYS_DMA_CSR_CH0 */
877 if (!ch
->omap_3_1_compatible_disable
&& ch
->sibling
) {
878 *value
|= (ch
->sibling
->status
& 0x3f) << 6;
879 ch
->sibling
->status
&= SYNC
;
881 qemu_irq_lower(ch
->irq
);
884 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
885 *value
= ch
->addr
[0] & 0x0000ffff;
888 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
889 *value
= ch
->addr
[0] >> 16;
892 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
893 *value
= ch
->addr
[1] & 0x0000ffff;
896 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
897 *value
= ch
->addr
[1] >> 16;
900 case 0x10: /* SYS_DMA_CEN_CH0 */
901 *value
= ch
->elements
;
904 case 0x12: /* SYS_DMA_CFN_CH0 */
908 case 0x14: /* SYS_DMA_CFI_CH0 */
909 *value
= ch
->frame_index
[0];
912 case 0x16: /* SYS_DMA_CEI_CH0 */
913 *value
= ch
->element_index
[0];
916 case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */
917 if (ch
->omap_3_1_compatible_disable
)
918 *value
= ch
->active_set
.src
& 0xffff; /* CSAC */
923 case 0x1a: /* DMA_CDAC */
924 *value
= ch
->active_set
.dest
& 0xffff; /* CDAC */
927 case 0x1c: /* DMA_CDEI */
928 *value
= ch
->element_index
[1];
931 case 0x1e: /* DMA_CDFI */
932 *value
= ch
->frame_index
[1];
935 case 0x20: /* DMA_COLOR_L */
936 *value
= ch
->color
& 0xffff;
939 case 0x22: /* DMA_COLOR_U */
940 *value
= ch
->color
>> 16;
943 case 0x24: /* DMA_CCR2 */
944 *value
= (ch
->bs
<< 2) |
945 (ch
->transparent_copy
<< 1) |
949 case 0x28: /* DMA_CLNK_CTRL */
950 *value
= (ch
->link_enabled
<< 15) |
951 (ch
->link_next_ch
& 0xf);
954 case 0x2a: /* DMA_LCH_CTRL */
955 *value
= (ch
->interleave_disabled
<< 15) |
965 static int omap_dma_ch_reg_write(struct omap_dma_s
*s
,
966 struct omap_dma_channel_s
*ch
, int reg
, uint16_t value
)
969 case 0x00: /* SYS_DMA_CSDP_CH0 */
970 ch
->burst
[1] = (value
& 0xc000) >> 14;
971 ch
->pack
[1] = (value
& 0x2000) >> 13;
972 ch
->port
[1] = (enum omap_dma_port
) ((value
& 0x1e00) >> 9);
973 ch
->burst
[0] = (value
& 0x0180) >> 7;
974 ch
->pack
[0] = (value
& 0x0040) >> 6;
975 ch
->port
[0] = (enum omap_dma_port
) ((value
& 0x003c) >> 2);
976 ch
->data_type
= (1 << (value
& 3));
977 if (ch
->port
[0] >= omap_dma_port_last
)
978 printf("%s: invalid DMA port %i\n", __FUNCTION__
,
980 if (ch
->port
[1] >= omap_dma_port_last
)
981 printf("%s: invalid DMA port %i\n", __FUNCTION__
,
983 if ((value
& 3) == 3)
984 printf("%s: bad data_type for DMA channel\n", __FUNCTION__
);
987 case 0x02: /* SYS_DMA_CCR_CH0 */
988 ch
->mode
[1] = (omap_dma_addressing_t
) ((value
& 0xc000) >> 14);
989 ch
->mode
[0] = (omap_dma_addressing_t
) ((value
& 0x3000) >> 12);
990 ch
->end_prog
= (value
& 0x0800) >> 11;
991 if (s
->model
> omap_dma_3_1
)
992 ch
->omap_3_1_compatible_disable
= (value
>> 10) & 0x1;
993 ch
->repeat
= (value
& 0x0200) >> 9;
994 ch
->auto_init
= (value
& 0x0100) >> 8;
995 ch
->priority
= (value
& 0x0040) >> 6;
996 ch
->fs
= (value
& 0x0020) >> 5;
997 ch
->sync
= value
& 0x001f;
1000 omap_dma_enable_channel(s
, ch
);
1002 omap_dma_disable_channel(s
, ch
);
1005 omap_dma_channel_end_prog(s
, ch
);
1009 case 0x04: /* SYS_DMA_CICR_CH0 */
1010 ch
->interrupts
= value
;
1013 case 0x06: /* SYS_DMA_CSR_CH0 */
1014 OMAP_RO_REG((target_phys_addr_t
) reg
);
1017 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
1018 ch
->addr
[0] &= 0xffff0000;
1019 ch
->addr
[0] |= value
;
1022 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
1023 ch
->addr
[0] &= 0x0000ffff;
1024 ch
->addr
[0] |= (uint32_t) value
<< 16;
1027 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
1028 ch
->addr
[1] &= 0xffff0000;
1029 ch
->addr
[1] |= value
;
1032 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
1033 ch
->addr
[1] &= 0x0000ffff;
1034 ch
->addr
[1] |= (uint32_t) value
<< 16;
1037 case 0x10: /* SYS_DMA_CEN_CH0 */
1038 ch
->elements
= value
;
1041 case 0x12: /* SYS_DMA_CFN_CH0 */
1045 case 0x14: /* SYS_DMA_CFI_CH0 */
1046 ch
->frame_index
[0] = (int16_t) value
;
1049 case 0x16: /* SYS_DMA_CEI_CH0 */
1050 ch
->element_index
[0] = (int16_t) value
;
1053 case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */
1054 OMAP_RO_REG((target_phys_addr_t
) reg
);
1057 case 0x1c: /* DMA_CDEI */
1058 ch
->element_index
[1] = (int16_t) value
;
1061 case 0x1e: /* DMA_CDFI */
1062 ch
->frame_index
[1] = (int16_t) value
;
1065 case 0x20: /* DMA_COLOR_L */
1066 ch
->color
&= 0xffff0000;
1070 case 0x22: /* DMA_COLOR_U */
1071 ch
->color
&= 0xffff;
1072 ch
->color
|= value
<< 16;
1075 case 0x24: /* DMA_CCR2 */
1076 ch
->bs
= (value
>> 2) & 0x1;
1077 ch
->transparent_copy
= (value
>> 1) & 0x1;
1078 ch
->constant_fill
= value
& 0x1;
1081 case 0x28: /* DMA_CLNK_CTRL */
1082 ch
->link_enabled
= (value
>> 15) & 0x1;
1083 if (value
& (1 << 14)) { /* Stop_Lnk */
1084 ch
->link_enabled
= 0;
1085 omap_dma_disable_channel(s
, ch
);
1087 ch
->link_next_ch
= value
& 0x1f;
1090 case 0x2a: /* DMA_LCH_CTRL */
1091 ch
->interleave_disabled
= (value
>> 15) & 0x1;
1092 ch
->type
= value
& 0xf;
1101 static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s
*s
, int offset
,
1105 case 0xbc0: /* DMA_LCD_CSDP */
1106 s
->brust_f2
= (value
>> 14) & 0x3;
1107 s
->pack_f2
= (value
>> 13) & 0x1;
1108 s
->data_type_f2
= (1 << ((value
>> 11) & 0x3));
1109 s
->brust_f1
= (value
>> 7) & 0x3;
1110 s
->pack_f1
= (value
>> 6) & 0x1;
1111 s
->data_type_f1
= (1 << ((value
>> 0) & 0x3));
1114 case 0xbc2: /* DMA_LCD_CCR */
1115 s
->mode_f2
= (value
>> 14) & 0x3;
1116 s
->mode_f1
= (value
>> 12) & 0x3;
1117 s
->end_prog
= (value
>> 11) & 0x1;
1118 s
->omap_3_1_compatible_disable
= (value
>> 10) & 0x1;
1119 s
->repeat
= (value
>> 9) & 0x1;
1120 s
->auto_init
= (value
>> 8) & 0x1;
1121 s
->running
= (value
>> 7) & 0x1;
1122 s
->priority
= (value
>> 6) & 0x1;
1123 s
->bs
= (value
>> 4) & 0x1;
1126 case 0xbc4: /* DMA_LCD_CTRL */
1127 s
->dst
= (value
>> 8) & 0x1;
1128 s
->src
= ((value
>> 6) & 0x3) << 1;
1130 /* Assume no bus errors and thus no BUS_ERROR irq bits. */
1131 s
->interrupts
= (value
>> 1) & 1;
1132 s
->dual
= value
& 1;
1135 case 0xbc8: /* TOP_B1_L */
1136 s
->src_f1_top
&= 0xffff0000;
1137 s
->src_f1_top
|= 0x0000ffff & value
;
1140 case 0xbca: /* TOP_B1_U */
1141 s
->src_f1_top
&= 0x0000ffff;
1142 s
->src_f1_top
|= value
<< 16;
1145 case 0xbcc: /* BOT_B1_L */
1146 s
->src_f1_bottom
&= 0xffff0000;
1147 s
->src_f1_bottom
|= 0x0000ffff & value
;
1150 case 0xbce: /* BOT_B1_U */
1151 s
->src_f1_bottom
&= 0x0000ffff;
1152 s
->src_f1_bottom
|= (uint32_t) value
<< 16;
1155 case 0xbd0: /* TOP_B2_L */
1156 s
->src_f2_top
&= 0xffff0000;
1157 s
->src_f2_top
|= 0x0000ffff & value
;
1160 case 0xbd2: /* TOP_B2_U */
1161 s
->src_f2_top
&= 0x0000ffff;
1162 s
->src_f2_top
|= (uint32_t) value
<< 16;
1165 case 0xbd4: /* BOT_B2_L */
1166 s
->src_f2_bottom
&= 0xffff0000;
1167 s
->src_f2_bottom
|= 0x0000ffff & value
;
1170 case 0xbd6: /* BOT_B2_U */
1171 s
->src_f2_bottom
&= 0x0000ffff;
1172 s
->src_f2_bottom
|= (uint32_t) value
<< 16;
1175 case 0xbd8: /* DMA_LCD_SRC_EI_B1 */
1176 s
->element_index_f1
= value
;
1179 case 0xbda: /* DMA_LCD_SRC_FI_B1_L */
1180 s
->frame_index_f1
&= 0xffff0000;
1181 s
->frame_index_f1
|= 0x0000ffff & value
;
1184 case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */
1185 s
->frame_index_f1
&= 0x0000ffff;
1186 s
->frame_index_f1
|= (uint32_t) value
<< 16;
1189 case 0xbdc: /* DMA_LCD_SRC_EI_B2 */
1190 s
->element_index_f2
= value
;
1193 case 0xbde: /* DMA_LCD_SRC_FI_B2_L */
1194 s
->frame_index_f2
&= 0xffff0000;
1195 s
->frame_index_f2
|= 0x0000ffff & value
;
1198 case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */
1199 s
->frame_index_f2
&= 0x0000ffff;
1200 s
->frame_index_f2
|= (uint32_t) value
<< 16;
1203 case 0xbe0: /* DMA_LCD_SRC_EN_B1 */
1204 s
->elements_f1
= value
;
1207 case 0xbe4: /* DMA_LCD_SRC_FN_B1 */
1208 s
->frames_f1
= value
;
1211 case 0xbe2: /* DMA_LCD_SRC_EN_B2 */
1212 s
->elements_f2
= value
;
1215 case 0xbe6: /* DMA_LCD_SRC_FN_B2 */
1216 s
->frames_f2
= value
;
1219 case 0xbea: /* DMA_LCD_LCH_CTRL */
1220 s
->lch_type
= value
& 0xf;
1229 static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s
*s
, int offset
,
1233 case 0xbc0: /* DMA_LCD_CSDP */
1234 *ret
= (s
->brust_f2
<< 14) |
1235 (s
->pack_f2
<< 13) |
1236 ((s
->data_type_f2
>> 1) << 11) |
1237 (s
->brust_f1
<< 7) |
1239 ((s
->data_type_f1
>> 1) << 0);
1242 case 0xbc2: /* DMA_LCD_CCR */
1243 *ret
= (s
->mode_f2
<< 14) |
1244 (s
->mode_f1
<< 12) |
1245 (s
->end_prog
<< 11) |
1246 (s
->omap_3_1_compatible_disable
<< 10) |
1248 (s
->auto_init
<< 8) |
1250 (s
->priority
<< 6) |
1254 case 0xbc4: /* DMA_LCD_CTRL */
1255 qemu_irq_lower(s
->irq
);
1256 *ret
= (s
->dst
<< 8) |
1257 ((s
->src
& 0x6) << 5) |
1258 (s
->condition
<< 3) |
1259 (s
->interrupts
<< 1) |
1263 case 0xbc8: /* TOP_B1_L */
1264 *ret
= s
->src_f1_top
& 0xffff;
1267 case 0xbca: /* TOP_B1_U */
1268 *ret
= s
->src_f1_top
>> 16;
1271 case 0xbcc: /* BOT_B1_L */
1272 *ret
= s
->src_f1_bottom
& 0xffff;
1275 case 0xbce: /* BOT_B1_U */
1276 *ret
= s
->src_f1_bottom
>> 16;
1279 case 0xbd0: /* TOP_B2_L */
1280 *ret
= s
->src_f2_top
& 0xffff;
1283 case 0xbd2: /* TOP_B2_U */
1284 *ret
= s
->src_f2_top
>> 16;
1287 case 0xbd4: /* BOT_B2_L */
1288 *ret
= s
->src_f2_bottom
& 0xffff;
1291 case 0xbd6: /* BOT_B2_U */
1292 *ret
= s
->src_f2_bottom
>> 16;
1295 case 0xbd8: /* DMA_LCD_SRC_EI_B1 */
1296 *ret
= s
->element_index_f1
;
1299 case 0xbda: /* DMA_LCD_SRC_FI_B1_L */
1300 *ret
= s
->frame_index_f1
& 0xffff;
1303 case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */
1304 *ret
= s
->frame_index_f1
>> 16;
1307 case 0xbdc: /* DMA_LCD_SRC_EI_B2 */
1308 *ret
= s
->element_index_f2
;
1311 case 0xbde: /* DMA_LCD_SRC_FI_B2_L */
1312 *ret
= s
->frame_index_f2
& 0xffff;
1315 case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */
1316 *ret
= s
->frame_index_f2
>> 16;
1319 case 0xbe0: /* DMA_LCD_SRC_EN_B1 */
1320 *ret
= s
->elements_f1
;
1323 case 0xbe4: /* DMA_LCD_SRC_FN_B1 */
1324 *ret
= s
->frames_f1
;
1327 case 0xbe2: /* DMA_LCD_SRC_EN_B2 */
1328 *ret
= s
->elements_f2
;
1331 case 0xbe6: /* DMA_LCD_SRC_FN_B2 */
1332 *ret
= s
->frames_f2
;
1335 case 0xbea: /* DMA_LCD_LCH_CTRL */
1345 static int omap_dma_3_1_lcd_write(struct omap_dma_lcd_channel_s
*s
, int offset
,
1349 case 0x300: /* SYS_DMA_LCD_CTRL */
1350 s
->src
= (value
& 0x40) ? imif
: emiff
;
1352 /* Assume no bus errors and thus no BUS_ERROR irq bits. */
1353 s
->interrupts
= (value
>> 1) & 1;
1354 s
->dual
= value
& 1;
1357 case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
1358 s
->src_f1_top
&= 0xffff0000;
1359 s
->src_f1_top
|= 0x0000ffff & value
;
1362 case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
1363 s
->src_f1_top
&= 0x0000ffff;
1364 s
->src_f1_top
|= value
<< 16;
1367 case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
1368 s
->src_f1_bottom
&= 0xffff0000;
1369 s
->src_f1_bottom
|= 0x0000ffff & value
;
1372 case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
1373 s
->src_f1_bottom
&= 0x0000ffff;
1374 s
->src_f1_bottom
|= value
<< 16;
1377 case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
1378 s
->src_f2_top
&= 0xffff0000;
1379 s
->src_f2_top
|= 0x0000ffff & value
;
1382 case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
1383 s
->src_f2_top
&= 0x0000ffff;
1384 s
->src_f2_top
|= value
<< 16;
1387 case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
1388 s
->src_f2_bottom
&= 0xffff0000;
1389 s
->src_f2_bottom
|= 0x0000ffff & value
;
1392 case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
1393 s
->src_f2_bottom
&= 0x0000ffff;
1394 s
->src_f2_bottom
|= value
<< 16;
1403 static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s
*s
, int offset
,
1409 case 0x300: /* SYS_DMA_LCD_CTRL */
1412 qemu_irq_lower(s
->irq
);
1413 *ret
= ((s
->src
== imif
) << 6) | (i
<< 3) |
1414 (s
->interrupts
<< 1) | s
->dual
;
1417 case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
1418 *ret
= s
->src_f1_top
& 0xffff;
1421 case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
1422 *ret
= s
->src_f1_top
>> 16;
1425 case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
1426 *ret
= s
->src_f1_bottom
& 0xffff;
1429 case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
1430 *ret
= s
->src_f1_bottom
>> 16;
1433 case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
1434 *ret
= s
->src_f2_top
& 0xffff;
1437 case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
1438 *ret
= s
->src_f2_top
>> 16;
1441 case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
1442 *ret
= s
->src_f2_bottom
& 0xffff;
1445 case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
1446 *ret
= s
->src_f2_bottom
>> 16;
1455 static int omap_dma_sys_write(struct omap_dma_s
*s
, int offset
, uint16_t value
)
1458 case 0x400: /* SYS_DMA_GCR */
1462 case 0x404: /* DMA_GSCR */
1464 omap_dma_disable_3_1_mapping(s
);
1466 omap_dma_enable_3_1_mapping(s
);
1469 case 0x408: /* DMA_GRST */
1480 static int omap_dma_sys_read(struct omap_dma_s
*s
, int offset
,
1484 case 0x400: /* SYS_DMA_GCR */
1488 case 0x404: /* DMA_GSCR */
1489 *ret
= s
->omap_3_1_mapping_disabled
<< 3;
1492 case 0x408: /* DMA_GRST */
1496 case 0x442: /* DMA_HW_ID */
1497 case 0x444: /* DMA_PCh2_ID */
1498 case 0x446: /* DMA_PCh0_ID */
1499 case 0x448: /* DMA_PCh1_ID */
1500 case 0x44a: /* DMA_PChG_ID */
1501 case 0x44c: /* DMA_PChD_ID */
1505 case 0x44e: /* DMA_CAPS_0_U */
1506 *ret
= (1 << 3) | /* Constant Fill Capacity */
1507 (1 << 2); /* Transparent BLT Capacity */
1510 case 0x450: /* DMA_CAPS_0_L */
1511 case 0x452: /* DMA_CAPS_1_U */
1515 case 0x454: /* DMA_CAPS_1_L */
1516 *ret
= (1 << 1); /* 1-bit palletized capability */
1519 case 0x456: /* DMA_CAPS_2 */
1520 *ret
= (1 << 8) | /* SSDIC */
1521 (1 << 7) | /* DDIAC */
1522 (1 << 6) | /* DSIAC */
1523 (1 << 5) | /* DPIAC */
1524 (1 << 4) | /* DCAC */
1525 (1 << 3) | /* SDIAC */
1526 (1 << 2) | /* SSIAC */
1527 (1 << 1) | /* SPIAC */
1531 case 0x458: /* DMA_CAPS_3 */
1532 *ret
= (1 << 5) | /* CCC */
1534 (1 << 3) | /* ARC */
1535 (1 << 2) | /* AEC */
1536 (1 << 1) | /* FSC */
1540 case 0x45a: /* DMA_CAPS_4 */
1541 *ret
= (1 << 6) | /* SSC */
1542 (1 << 5) | /* BIC */
1543 (1 << 4) | /* LFIC */
1544 (1 << 3) | /* FIC */
1545 (1 << 2) | /* HFIC */
1546 (1 << 1) | /* EDIC */
1550 case 0x460: /* DMA_PCh2_SR */
1551 case 0x480: /* DMA_PCh0_SR */
1552 case 0x482: /* DMA_PCh1_SR */
1553 case 0x4c0: /* DMA_PChD_SR_0 */
1554 printf("%s: Physical Channel Status Registers not implemented.\n",
1565 static uint32_t omap_dma_read(void *opaque
, target_phys_addr_t addr
)
1567 struct omap_dma_s
*s
= (struct omap_dma_s
*) opaque
;
1568 int reg
, ch
, offset
= addr
- s
->base
;
1572 case 0x300 ... 0x3fe:
1573 if (s
->model
== omap_dma_3_1
|| !s
->omap_3_1_mapping_disabled
) {
1574 if (omap_dma_3_1_lcd_read(&s
->lcd_ch
, offset
, &ret
))
1579 case 0x000 ... 0x2fe:
1580 reg
= offset
& 0x3f;
1581 ch
= (offset
>> 6) & 0x0f;
1582 if (omap_dma_ch_reg_read(s
, &s
->ch
[ch
], reg
, &ret
))
1586 case 0x404 ... 0x4fe:
1587 if (s
->model
== omap_dma_3_1
)
1591 if (omap_dma_sys_read(s
, offset
, &ret
))
1595 case 0xb00 ... 0xbfe:
1596 if (s
->model
== omap_dma_3_2
&& s
->omap_3_1_mapping_disabled
) {
1597 if (omap_dma_3_2_lcd_read(&s
->lcd_ch
, offset
, &ret
))
1608 static void omap_dma_write(void *opaque
, target_phys_addr_t addr
,
1611 struct omap_dma_s
*s
= (struct omap_dma_s
*) opaque
;
1612 int reg
, ch
, offset
= addr
- s
->base
;
1615 case 0x300 ... 0x3fe:
1616 if (s
->model
== omap_dma_3_1
|| !s
->omap_3_1_mapping_disabled
) {
1617 if (omap_dma_3_1_lcd_write(&s
->lcd_ch
, offset
, value
))
1622 case 0x000 ... 0x2fe:
1623 reg
= offset
& 0x3f;
1624 ch
= (offset
>> 6) & 0x0f;
1625 if (omap_dma_ch_reg_write(s
, &s
->ch
[ch
], reg
, value
))
1629 case 0x404 ... 0x4fe:
1630 if (s
->model
== omap_dma_3_1
)
1634 if (omap_dma_sys_write(s
, offset
, value
))
1638 case 0xb00 ... 0xbfe:
1639 if (s
->model
== omap_dma_3_2
&& s
->omap_3_1_mapping_disabled
) {
1640 if (omap_dma_3_2_lcd_write(&s
->lcd_ch
, offset
, value
))
1650 static CPUReadMemoryFunc
*omap_dma_readfn
[] = {
1651 omap_badwidth_read16
,
1653 omap_badwidth_read16
,
1656 static CPUWriteMemoryFunc
*omap_dma_writefn
[] = {
1657 omap_badwidth_write16
,
1659 omap_badwidth_write16
,
1662 static void omap_dma_request(void *opaque
, int drq
, int req
)
1664 struct omap_dma_s
*s
= (struct omap_dma_s
*) opaque
;
1665 /* The request pins are level triggered. */
1667 if (~s
->drq
& (1 << drq
)) {
1669 omap_dma_process_request(s
, drq
);
1672 s
->drq
&= ~(1 << drq
);
1675 static void omap_dma_clk_update(void *opaque
, int line
, int on
)
1677 struct omap_dma_s
*s
= (struct omap_dma_s
*) opaque
;
1680 /* TODO: make a clever calculation */
1681 s
->delay
= ticks_per_sec
>> 8;
1683 qemu_mod_timer(s
->tm
, qemu_get_clock(vm_clock
) + s
->delay
);
1686 qemu_del_timer(s
->tm
);
1690 struct omap_dma_s
*omap_dma_init(target_phys_addr_t base
, qemu_irq
*irqs
,
1691 qemu_irq lcd_irq
, struct omap_mpu_state_s
*mpu
, omap_clk clk
,
1692 enum omap_dma_model model
)
1694 int iomemtype
, num_irqs
, memsize
, i
;
1695 struct omap_dma_s
*s
= (struct omap_dma_s
*)
1696 qemu_mallocz(sizeof(struct omap_dma_s
));
1698 if (model
== omap_dma_3_1
) {
1709 s
->lcd_ch
.irq
= lcd_irq
;
1710 s
->lcd_ch
.mpu
= mpu
;
1712 s
->ch
[num_irqs
].irq
= irqs
[num_irqs
];
1713 for (i
= 0; i
< 3; i
++) {
1714 s
->ch
[i
].sibling
= &s
->ch
[i
+ 6];
1715 s
->ch
[i
+ 6].sibling
= &s
->ch
[i
];
1717 s
->tm
= qemu_new_timer(vm_clock
, (QEMUTimerCB
*) omap_dma_channel_run
, s
);
1718 omap_clk_adduser(s
->clk
, qemu_allocate_irqs(omap_dma_clk_update
, s
, 1)[0]);
1719 mpu
->drq
= qemu_allocate_irqs(omap_dma_request
, s
, 32);
1721 omap_dma_clk_update(s
, 0, 1);
1723 iomemtype
= cpu_register_io_memory(0, omap_dma_readfn
,
1724 omap_dma_writefn
, s
);
1725 cpu_register_physical_memory(s
->base
, memsize
, iomemtype
);
1731 static int omap_validate_emiff_addr(struct omap_mpu_state_s
*s
,
1732 target_phys_addr_t addr
)
1734 return addr
>= OMAP_EMIFF_BASE
&& addr
< OMAP_EMIFF_BASE
+ s
->sdram_size
;
1737 static int omap_validate_emifs_addr(struct omap_mpu_state_s
*s
,
1738 target_phys_addr_t addr
)
1740 return addr
>= OMAP_EMIFS_BASE
&& addr
< OMAP_EMIFF_BASE
;
1743 static int omap_validate_imif_addr(struct omap_mpu_state_s
*s
,
1744 target_phys_addr_t addr
)
1746 return addr
>= OMAP_IMIF_BASE
&& addr
< OMAP_IMIF_BASE
+ s
->sram_size
;
1749 static int omap_validate_tipb_addr(struct omap_mpu_state_s
*s
,
1750 target_phys_addr_t addr
)
1752 return addr
>= 0xfffb0000 && addr
< 0xffff0000;
1755 static int omap_validate_local_addr(struct omap_mpu_state_s
*s
,
1756 target_phys_addr_t addr
)
1758 return addr
>= OMAP_LOCALBUS_BASE
&& addr
< OMAP_LOCALBUS_BASE
+ 0x1000000;
1761 static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s
*s
,
1762 target_phys_addr_t addr
)
1764 return addr
>= 0xe1010000 && addr
< 0xe1020004;
1768 struct omap_mpu_timer_s
{
1771 target_phys_addr_t base
;
1785 static inline uint32_t omap_timer_read(struct omap_mpu_timer_s
*timer
)
1787 uint64_t distance
= qemu_get_clock(vm_clock
) - timer
->time
;
1789 if (timer
->st
&& timer
->enable
&& timer
->rate
)
1790 return timer
->val
- muldiv64(distance
>> (timer
->ptv
+ 1),
1791 timer
->rate
, ticks_per_sec
);
1796 static inline void omap_timer_sync(struct omap_mpu_timer_s
*timer
)
1798 timer
->val
= omap_timer_read(timer
);
1799 timer
->time
= qemu_get_clock(vm_clock
);
1802 static inline void omap_timer_update(struct omap_mpu_timer_s
*timer
)
1806 if (timer
->enable
&& timer
->st
&& timer
->rate
) {
1807 timer
->val
= timer
->reset_val
; /* Should skip this on clk enable */
1808 expires
= muldiv64(timer
->val
<< (timer
->ptv
+ 1),
1809 ticks_per_sec
, timer
->rate
);
1811 /* If timer expiry would be sooner than in about 1 ms and
1812 * auto-reload isn't set, then fire immediately. This is a hack
1813 * to make systems like PalmOS run in acceptable time. PalmOS
1814 * sets the interval to a very low value and polls the status bit
1815 * in a busy loop when it wants to sleep just a couple of CPU
1817 if (expires
> (ticks_per_sec
>> 10) || timer
->ar
)
1818 qemu_mod_timer(timer
->timer
, timer
->time
+ expires
);
1823 /* Edge-triggered irq */
1824 qemu_irq_pulse(timer
->irq
);
1827 qemu_del_timer(timer
->timer
);
1830 static void omap_timer_tick(void *opaque
)
1832 struct omap_mpu_timer_s
*timer
= (struct omap_mpu_timer_s
*) opaque
;
1833 omap_timer_sync(timer
);
1841 /* Edge-triggered irq */
1842 qemu_irq_pulse(timer
->irq
);
1843 omap_timer_update(timer
);
1846 static void omap_timer_clk_update(void *opaque
, int line
, int on
)
1848 struct omap_mpu_timer_s
*timer
= (struct omap_mpu_timer_s
*) opaque
;
1850 omap_timer_sync(timer
);
1851 timer
->rate
= on
? omap_clk_getrate(timer
->clk
) : 0;
1852 omap_timer_update(timer
);
1855 static void omap_timer_clk_setup(struct omap_mpu_timer_s
*timer
)
1857 omap_clk_adduser(timer
->clk
,
1858 qemu_allocate_irqs(omap_timer_clk_update
, timer
, 1)[0]);
1859 timer
->rate
= omap_clk_getrate(timer
->clk
);
1862 static uint32_t omap_mpu_timer_read(void *opaque
, target_phys_addr_t addr
)
1864 struct omap_mpu_timer_s
*s
= (struct omap_mpu_timer_s
*) opaque
;
1865 int offset
= addr
- s
->base
;
1868 case 0x00: /* CNTL_TIMER */
1869 return (s
->enable
<< 5) | (s
->ptv
<< 2) | (s
->ar
<< 1) | s
->st
;
1871 case 0x04: /* LOAD_TIM */
1874 case 0x08: /* READ_TIM */
1875 return omap_timer_read(s
);
1882 static void omap_mpu_timer_write(void *opaque
, target_phys_addr_t addr
,
1885 struct omap_mpu_timer_s
*s
= (struct omap_mpu_timer_s
*) opaque
;
1886 int offset
= addr
- s
->base
;
1889 case 0x00: /* CNTL_TIMER */
1891 s
->enable
= (value
>> 5) & 1;
1892 s
->ptv
= (value
>> 2) & 7;
1893 s
->ar
= (value
>> 1) & 1;
1895 omap_timer_update(s
);
1898 case 0x04: /* LOAD_TIM */
1899 s
->reset_val
= value
;
1902 case 0x08: /* READ_TIM */
1911 static CPUReadMemoryFunc
*omap_mpu_timer_readfn
[] = {
1912 omap_badwidth_read32
,
1913 omap_badwidth_read32
,
1914 omap_mpu_timer_read
,
1917 static CPUWriteMemoryFunc
*omap_mpu_timer_writefn
[] = {
1918 omap_badwidth_write32
,
1919 omap_badwidth_write32
,
1920 omap_mpu_timer_write
,
1923 static void omap_mpu_timer_reset(struct omap_mpu_timer_s
*s
)
1925 qemu_del_timer(s
->timer
);
1927 s
->reset_val
= 31337;
1935 struct omap_mpu_timer_s
*omap_mpu_timer_init(target_phys_addr_t base
,
1936 qemu_irq irq
, omap_clk clk
)
1939 struct omap_mpu_timer_s
*s
= (struct omap_mpu_timer_s
*)
1940 qemu_mallocz(sizeof(struct omap_mpu_timer_s
));
1945 s
->timer
= qemu_new_timer(vm_clock
, omap_timer_tick
, s
);
1946 omap_mpu_timer_reset(s
);
1947 omap_timer_clk_setup(s
);
1949 iomemtype
= cpu_register_io_memory(0, omap_mpu_timer_readfn
,
1950 omap_mpu_timer_writefn
, s
);
1951 cpu_register_physical_memory(s
->base
, 0x100, iomemtype
);
1956 /* Watchdog timer */
1957 struct omap_watchdog_timer_s
{
1958 struct omap_mpu_timer_s timer
;
1965 static uint32_t omap_wd_timer_read(void *opaque
, target_phys_addr_t addr
)
1967 struct omap_watchdog_timer_s
*s
= (struct omap_watchdog_timer_s
*) opaque
;
1968 int offset
= addr
- s
->timer
.base
;
1971 case 0x00: /* CNTL_TIMER */
1972 return (s
->timer
.ptv
<< 9) | (s
->timer
.ar
<< 8) |
1973 (s
->timer
.st
<< 7) | (s
->free
<< 1);
1975 case 0x04: /* READ_TIMER */
1976 return omap_timer_read(&s
->timer
);
1978 case 0x08: /* TIMER_MODE */
1979 return s
->mode
<< 15;
1986 static void omap_wd_timer_write(void *opaque
, target_phys_addr_t addr
,
1989 struct omap_watchdog_timer_s
*s
= (struct omap_watchdog_timer_s
*) opaque
;
1990 int offset
= addr
- s
->timer
.base
;
1993 case 0x00: /* CNTL_TIMER */
1994 omap_timer_sync(&s
->timer
);
1995 s
->timer
.ptv
= (value
>> 9) & 7;
1996 s
->timer
.ar
= (value
>> 8) & 1;
1997 s
->timer
.st
= (value
>> 7) & 1;
1998 s
->free
= (value
>> 1) & 1;
1999 omap_timer_update(&s
->timer
);
2002 case 0x04: /* LOAD_TIMER */
2003 s
->timer
.reset_val
= value
& 0xffff;
2006 case 0x08: /* TIMER_MODE */
2007 if (!s
->mode
&& ((value
>> 15) & 1))
2008 omap_clk_get(s
->timer
.clk
);
2009 s
->mode
|= (value
>> 15) & 1;
2010 if (s
->last_wr
== 0xf5) {
2011 if ((value
& 0xff) == 0xa0) {
2014 omap_clk_put(s
->timer
.clk
);
2017 /* XXX: on T|E hardware somehow this has no effect,
2018 * on Zire 71 it works as specified. */
2020 qemu_system_reset_request();
2023 s
->last_wr
= value
& 0xff;
2031 static CPUReadMemoryFunc
*omap_wd_timer_readfn
[] = {
2032 omap_badwidth_read16
,
2034 omap_badwidth_read16
,
2037 static CPUWriteMemoryFunc
*omap_wd_timer_writefn
[] = {
2038 omap_badwidth_write16
,
2039 omap_wd_timer_write
,
2040 omap_badwidth_write16
,
2043 static void omap_wd_timer_reset(struct omap_watchdog_timer_s
*s
)
2045 qemu_del_timer(s
->timer
.timer
);
2047 omap_clk_get(s
->timer
.clk
);
2051 s
->timer
.enable
= 1;
2052 s
->timer
.it_ena
= 1;
2053 s
->timer
.reset_val
= 0xffff;
2058 omap_timer_update(&s
->timer
);
2061 struct omap_watchdog_timer_s
*omap_wd_timer_init(target_phys_addr_t base
,
2062 qemu_irq irq
, omap_clk clk
)
2065 struct omap_watchdog_timer_s
*s
= (struct omap_watchdog_timer_s
*)
2066 qemu_mallocz(sizeof(struct omap_watchdog_timer_s
));
2070 s
->timer
.base
= base
;
2071 s
->timer
.timer
= qemu_new_timer(vm_clock
, omap_timer_tick
, &s
->timer
);
2072 omap_wd_timer_reset(s
);
2073 omap_timer_clk_setup(&s
->timer
);
2075 iomemtype
= cpu_register_io_memory(0, omap_wd_timer_readfn
,
2076 omap_wd_timer_writefn
, s
);
2077 cpu_register_physical_memory(s
->timer
.base
, 0x100, iomemtype
);
2083 struct omap_32khz_timer_s
{
2084 struct omap_mpu_timer_s timer
;
2087 static uint32_t omap_os_timer_read(void *opaque
, target_phys_addr_t addr
)
2089 struct omap_32khz_timer_s
*s
= (struct omap_32khz_timer_s
*) opaque
;
2090 int offset
= addr
& OMAP_MPUI_REG_MASK
;
2093 case 0x00: /* TVR */
2094 return s
->timer
.reset_val
;
2096 case 0x04: /* TCR */
2097 return omap_timer_read(&s
->timer
);
2100 return (s
->timer
.ar
<< 3) | (s
->timer
.it_ena
<< 2) | s
->timer
.st
;
2109 static void omap_os_timer_write(void *opaque
, target_phys_addr_t addr
,
2112 struct omap_32khz_timer_s
*s
= (struct omap_32khz_timer_s
*) opaque
;
2113 int offset
= addr
& OMAP_MPUI_REG_MASK
;
2116 case 0x00: /* TVR */
2117 s
->timer
.reset_val
= value
& 0x00ffffff;
2120 case 0x04: /* TCR */
2125 s
->timer
.ar
= (value
>> 3) & 1;
2126 s
->timer
.it_ena
= (value
>> 2) & 1;
2127 if (s
->timer
.st
!= (value
& 1) || (value
& 2)) {
2128 omap_timer_sync(&s
->timer
);
2129 s
->timer
.enable
= value
& 1;
2130 s
->timer
.st
= value
& 1;
2131 omap_timer_update(&s
->timer
);
2140 static CPUReadMemoryFunc
*omap_os_timer_readfn
[] = {
2141 omap_badwidth_read32
,
2142 omap_badwidth_read32
,
2146 static CPUWriteMemoryFunc
*omap_os_timer_writefn
[] = {
2147 omap_badwidth_write32
,
2148 omap_badwidth_write32
,
2149 omap_os_timer_write
,
2152 static void omap_os_timer_reset(struct omap_32khz_timer_s
*s
)
2154 qemu_del_timer(s
->timer
.timer
);
2155 s
->timer
.enable
= 0;
2156 s
->timer
.it_ena
= 0;
2157 s
->timer
.reset_val
= 0x00ffffff;
2164 struct omap_32khz_timer_s
*omap_os_timer_init(target_phys_addr_t base
,
2165 qemu_irq irq
, omap_clk clk
)
2168 struct omap_32khz_timer_s
*s
= (struct omap_32khz_timer_s
*)
2169 qemu_mallocz(sizeof(struct omap_32khz_timer_s
));
2173 s
->timer
.base
= base
;
2174 s
->timer
.timer
= qemu_new_timer(vm_clock
, omap_timer_tick
, &s
->timer
);
2175 omap_os_timer_reset(s
);
2176 omap_timer_clk_setup(&s
->timer
);
2178 iomemtype
= cpu_register_io_memory(0, omap_os_timer_readfn
,
2179 omap_os_timer_writefn
, s
);
2180 cpu_register_physical_memory(s
->timer
.base
, 0x800, iomemtype
);
2185 /* Ultra Low-Power Device Module */
2186 static uint32_t omap_ulpd_pm_read(void *opaque
, target_phys_addr_t addr
)
2188 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2189 int offset
= addr
- s
->ulpd_pm_base
;
2193 case 0x14: /* IT_STATUS */
2194 ret
= s
->ulpd_pm_regs
[offset
>> 2];
2195 s
->ulpd_pm_regs
[offset
>> 2] = 0;
2196 qemu_irq_lower(s
->irq
[1][OMAP_INT_GAUGE_32K
]);
2199 case 0x18: /* Reserved */
2200 case 0x1c: /* Reserved */
2201 case 0x20: /* Reserved */
2202 case 0x28: /* Reserved */
2203 case 0x2c: /* Reserved */
2205 case 0x00: /* COUNTER_32_LSB */
2206 case 0x04: /* COUNTER_32_MSB */
2207 case 0x08: /* COUNTER_HIGH_FREQ_LSB */
2208 case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
2209 case 0x10: /* GAUGING_CTRL */
2210 case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
2211 case 0x30: /* CLOCK_CTRL */
2212 case 0x34: /* SOFT_REQ */
2213 case 0x38: /* COUNTER_32_FIQ */
2214 case 0x3c: /* DPLL_CTRL */
2215 case 0x40: /* STATUS_REQ */
2216 /* XXX: check clk::usecount state for every clock */
2217 case 0x48: /* LOCL_TIME */
2218 case 0x4c: /* APLL_CTRL */
2219 case 0x50: /* POWER_CTRL */
2220 return s
->ulpd_pm_regs
[offset
>> 2];
2227 static inline void omap_ulpd_clk_update(struct omap_mpu_state_s
*s
,
2228 uint16_t diff
, uint16_t value
)
2230 if (diff
& (1 << 4)) /* USB_MCLK_EN */
2231 omap_clk_onoff(omap_findclk(s
, "usb_clk0"), (value
>> 4) & 1);
2232 if (diff
& (1 << 5)) /* DIS_USB_PVCI_CLK */
2233 omap_clk_onoff(omap_findclk(s
, "usb_w2fc_ck"), (~value
>> 5) & 1);
2236 static inline void omap_ulpd_req_update(struct omap_mpu_state_s
*s
,
2237 uint16_t diff
, uint16_t value
)
2239 if (diff
& (1 << 0)) /* SOFT_DPLL_REQ */
2240 omap_clk_canidle(omap_findclk(s
, "dpll4"), (~value
>> 0) & 1);
2241 if (diff
& (1 << 1)) /* SOFT_COM_REQ */
2242 omap_clk_canidle(omap_findclk(s
, "com_mclk_out"), (~value
>> 1) & 1);
2243 if (diff
& (1 << 2)) /* SOFT_SDW_REQ */
2244 omap_clk_canidle(omap_findclk(s
, "bt_mclk_out"), (~value
>> 2) & 1);
2245 if (diff
& (1 << 3)) /* SOFT_USB_REQ */
2246 omap_clk_canidle(omap_findclk(s
, "usb_clk0"), (~value
>> 3) & 1);
2249 static void omap_ulpd_pm_write(void *opaque
, target_phys_addr_t addr
,
2252 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2253 int offset
= addr
- s
->ulpd_pm_base
;
2256 static const int bypass_div
[4] = { 1, 2, 4, 4 };
2260 case 0x00: /* COUNTER_32_LSB */
2261 case 0x04: /* COUNTER_32_MSB */
2262 case 0x08: /* COUNTER_HIGH_FREQ_LSB */
2263 case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
2264 case 0x14: /* IT_STATUS */
2265 case 0x40: /* STATUS_REQ */
2269 case 0x10: /* GAUGING_CTRL */
2270 /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
2271 if ((s
->ulpd_pm_regs
[offset
>> 2] ^ value
) & 1) {
2272 now
= qemu_get_clock(vm_clock
);
2275 s
->ulpd_gauge_start
= now
;
2277 now
-= s
->ulpd_gauge_start
;
2280 ticks
= muldiv64(now
, 32768, ticks_per_sec
);
2281 s
->ulpd_pm_regs
[0x00 >> 2] = (ticks
>> 0) & 0xffff;
2282 s
->ulpd_pm_regs
[0x04 >> 2] = (ticks
>> 16) & 0xffff;
2283 if (ticks
>> 32) /* OVERFLOW_32K */
2284 s
->ulpd_pm_regs
[0x14 >> 2] |= 1 << 2;
2286 /* High frequency ticks */
2287 ticks
= muldiv64(now
, 12000000, ticks_per_sec
);
2288 s
->ulpd_pm_regs
[0x08 >> 2] = (ticks
>> 0) & 0xffff;
2289 s
->ulpd_pm_regs
[0x0c >> 2] = (ticks
>> 16) & 0xffff;
2290 if (ticks
>> 32) /* OVERFLOW_HI_FREQ */
2291 s
->ulpd_pm_regs
[0x14 >> 2] |= 1 << 1;
2293 s
->ulpd_pm_regs
[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */
2294 qemu_irq_raise(s
->irq
[1][OMAP_INT_GAUGE_32K
]);
2297 s
->ulpd_pm_regs
[offset
>> 2] = value
;
2300 case 0x18: /* Reserved */
2301 case 0x1c: /* Reserved */
2302 case 0x20: /* Reserved */
2303 case 0x28: /* Reserved */
2304 case 0x2c: /* Reserved */
2306 case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
2307 case 0x38: /* COUNTER_32_FIQ */
2308 case 0x48: /* LOCL_TIME */
2309 case 0x50: /* POWER_CTRL */
2310 s
->ulpd_pm_regs
[offset
>> 2] = value
;
2313 case 0x30: /* CLOCK_CTRL */
2314 diff
= s
->ulpd_pm_regs
[offset
>> 2] ^ value
;
2315 s
->ulpd_pm_regs
[offset
>> 2] = value
& 0x3f;
2316 omap_ulpd_clk_update(s
, diff
, value
);
2319 case 0x34: /* SOFT_REQ */
2320 diff
= s
->ulpd_pm_regs
[offset
>> 2] ^ value
;
2321 s
->ulpd_pm_regs
[offset
>> 2] = value
& 0x1f;
2322 omap_ulpd_req_update(s
, diff
, value
);
2325 case 0x3c: /* DPLL_CTRL */
2326 /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
2327 * omitted altogether, probably a typo. */
2328 /* This register has identical semantics with DPLL(1:3) control
2329 * registers, see omap_dpll_write() */
2330 diff
= s
->ulpd_pm_regs
[offset
>> 2] & value
;
2331 s
->ulpd_pm_regs
[offset
>> 2] = value
& 0x2fff;
2332 if (diff
& (0x3ff << 2)) {
2333 if (value
& (1 << 4)) { /* PLL_ENABLE */
2334 div
= ((value
>> 5) & 3) + 1; /* PLL_DIV */
2335 mult
= MIN((value
>> 7) & 0x1f, 1); /* PLL_MULT */
2337 div
= bypass_div
[((value
>> 2) & 3)]; /* BYPASS_DIV */
2340 omap_clk_setrate(omap_findclk(s
, "dpll4"), div
, mult
);
2343 /* Enter the desired mode. */
2344 s
->ulpd_pm_regs
[offset
>> 2] =
2345 (s
->ulpd_pm_regs
[offset
>> 2] & 0xfffe) |
2346 ((s
->ulpd_pm_regs
[offset
>> 2] >> 4) & 1);
2348 /* Act as if the lock is restored. */
2349 s
->ulpd_pm_regs
[offset
>> 2] |= 2;
2352 case 0x4c: /* APLL_CTRL */
2353 diff
= s
->ulpd_pm_regs
[offset
>> 2] & value
;
2354 s
->ulpd_pm_regs
[offset
>> 2] = value
& 0xf;
2355 if (diff
& (1 << 0)) /* APLL_NDPLL_SWITCH */
2356 omap_clk_reparent(omap_findclk(s
, "ck_48m"), omap_findclk(s
,
2357 (value
& (1 << 0)) ? "apll" : "dpll4"));
2365 static CPUReadMemoryFunc
*omap_ulpd_pm_readfn
[] = {
2366 omap_badwidth_read16
,
2368 omap_badwidth_read16
,
2371 static CPUWriteMemoryFunc
*omap_ulpd_pm_writefn
[] = {
2372 omap_badwidth_write16
,
2374 omap_badwidth_write16
,
2377 static void omap_ulpd_pm_reset(struct omap_mpu_state_s
*mpu
)
2379 mpu
->ulpd_pm_regs
[0x00 >> 2] = 0x0001;
2380 mpu
->ulpd_pm_regs
[0x04 >> 2] = 0x0000;
2381 mpu
->ulpd_pm_regs
[0x08 >> 2] = 0x0001;
2382 mpu
->ulpd_pm_regs
[0x0c >> 2] = 0x0000;
2383 mpu
->ulpd_pm_regs
[0x10 >> 2] = 0x0000;
2384 mpu
->ulpd_pm_regs
[0x18 >> 2] = 0x01;
2385 mpu
->ulpd_pm_regs
[0x1c >> 2] = 0x01;
2386 mpu
->ulpd_pm_regs
[0x20 >> 2] = 0x01;
2387 mpu
->ulpd_pm_regs
[0x24 >> 2] = 0x03ff;
2388 mpu
->ulpd_pm_regs
[0x28 >> 2] = 0x01;
2389 mpu
->ulpd_pm_regs
[0x2c >> 2] = 0x01;
2390 omap_ulpd_clk_update(mpu
, mpu
->ulpd_pm_regs
[0x30 >> 2], 0x0000);
2391 mpu
->ulpd_pm_regs
[0x30 >> 2] = 0x0000;
2392 omap_ulpd_req_update(mpu
, mpu
->ulpd_pm_regs
[0x34 >> 2], 0x0000);
2393 mpu
->ulpd_pm_regs
[0x34 >> 2] = 0x0000;
2394 mpu
->ulpd_pm_regs
[0x38 >> 2] = 0x0001;
2395 mpu
->ulpd_pm_regs
[0x3c >> 2] = 0x2211;
2396 mpu
->ulpd_pm_regs
[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
2397 mpu
->ulpd_pm_regs
[0x48 >> 2] = 0x960;
2398 mpu
->ulpd_pm_regs
[0x4c >> 2] = 0x08;
2399 mpu
->ulpd_pm_regs
[0x50 >> 2] = 0x08;
2400 omap_clk_setrate(omap_findclk(mpu
, "dpll4"), 1, 4);
2401 omap_clk_reparent(omap_findclk(mpu
, "ck_48m"), omap_findclk(mpu
, "dpll4"));
2404 static void omap_ulpd_pm_init(target_phys_addr_t base
,
2405 struct omap_mpu_state_s
*mpu
)
2407 int iomemtype
= cpu_register_io_memory(0, omap_ulpd_pm_readfn
,
2408 omap_ulpd_pm_writefn
, mpu
);
2410 mpu
->ulpd_pm_base
= base
;
2411 cpu_register_physical_memory(mpu
->ulpd_pm_base
, 0x800, iomemtype
);
2412 omap_ulpd_pm_reset(mpu
);
2415 /* OMAP Pin Configuration */
2416 static uint32_t omap_pin_cfg_read(void *opaque
, target_phys_addr_t addr
)
2418 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2419 int offset
= addr
- s
->pin_cfg_base
;
2422 case 0x00: /* FUNC_MUX_CTRL_0 */
2423 case 0x04: /* FUNC_MUX_CTRL_1 */
2424 case 0x08: /* FUNC_MUX_CTRL_2 */
2425 return s
->func_mux_ctrl
[offset
>> 2];
2427 case 0x0c: /* COMP_MODE_CTRL_0 */
2428 return s
->comp_mode_ctrl
[0];
2430 case 0x10: /* FUNC_MUX_CTRL_3 */
2431 case 0x14: /* FUNC_MUX_CTRL_4 */
2432 case 0x18: /* FUNC_MUX_CTRL_5 */
2433 case 0x1c: /* FUNC_MUX_CTRL_6 */
2434 case 0x20: /* FUNC_MUX_CTRL_7 */
2435 case 0x24: /* FUNC_MUX_CTRL_8 */
2436 case 0x28: /* FUNC_MUX_CTRL_9 */
2437 case 0x2c: /* FUNC_MUX_CTRL_A */
2438 case 0x30: /* FUNC_MUX_CTRL_B */
2439 case 0x34: /* FUNC_MUX_CTRL_C */
2440 case 0x38: /* FUNC_MUX_CTRL_D */
2441 return s
->func_mux_ctrl
[(offset
>> 2) - 1];
2443 case 0x40: /* PULL_DWN_CTRL_0 */
2444 case 0x44: /* PULL_DWN_CTRL_1 */
2445 case 0x48: /* PULL_DWN_CTRL_2 */
2446 case 0x4c: /* PULL_DWN_CTRL_3 */
2447 return s
->pull_dwn_ctrl
[(offset
& 0xf) >> 2];
2449 case 0x50: /* GATE_INH_CTRL_0 */
2450 return s
->gate_inh_ctrl
[0];
2452 case 0x60: /* VOLTAGE_CTRL_0 */
2453 return s
->voltage_ctrl
[0];
2455 case 0x70: /* TEST_DBG_CTRL_0 */
2456 return s
->test_dbg_ctrl
[0];
2458 case 0x80: /* MOD_CONF_CTRL_0 */
2459 return s
->mod_conf_ctrl
[0];
2466 static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s
*s
,
2467 uint32_t diff
, uint32_t value
)
2469 if (s
->compat1509
) {
2470 if (diff
& (1 << 9)) /* BLUETOOTH */
2471 omap_clk_onoff(omap_findclk(s
, "bt_mclk_out"),
2473 if (diff
& (1 << 7)) /* USB.CLKO */
2474 omap_clk_onoff(omap_findclk(s
, "usb.clko"),
2479 static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s
*s
,
2480 uint32_t diff
, uint32_t value
)
2482 if (s
->compat1509
) {
2483 if (diff
& (1 << 31)) /* MCBSP3_CLK_HIZ_DI */
2484 omap_clk_onoff(omap_findclk(s
, "mcbsp3.clkx"),
2486 if (diff
& (1 << 1)) /* CLK32K */
2487 omap_clk_onoff(omap_findclk(s
, "clk32k_out"),
2492 static inline void omap_pin_modconf1_update(struct omap_mpu_state_s
*s
,
2493 uint32_t diff
, uint32_t value
)
2495 if (diff
& (1 << 31)) /* CONF_MOD_UART3_CLK_MODE_R */
2496 omap_clk_reparent(omap_findclk(s
, "uart3_ck"),
2497 omap_findclk(s
, ((value
>> 31) & 1) ?
2498 "ck_48m" : "armper_ck"));
2499 if (diff
& (1 << 30)) /* CONF_MOD_UART2_CLK_MODE_R */
2500 omap_clk_reparent(omap_findclk(s
, "uart2_ck"),
2501 omap_findclk(s
, ((value
>> 30) & 1) ?
2502 "ck_48m" : "armper_ck"));
2503 if (diff
& (1 << 29)) /* CONF_MOD_UART1_CLK_MODE_R */
2504 omap_clk_reparent(omap_findclk(s
, "uart1_ck"),
2505 omap_findclk(s
, ((value
>> 29) & 1) ?
2506 "ck_48m" : "armper_ck"));
2507 if (diff
& (1 << 23)) /* CONF_MOD_MMC_SD_CLK_REQ_R */
2508 omap_clk_reparent(omap_findclk(s
, "mmc_ck"),
2509 omap_findclk(s
, ((value
>> 23) & 1) ?
2510 "ck_48m" : "armper_ck"));
2511 if (diff
& (1 << 12)) /* CONF_MOD_COM_MCLK_12_48_S */
2512 omap_clk_reparent(omap_findclk(s
, "com_mclk_out"),
2513 omap_findclk(s
, ((value
>> 12) & 1) ?
2514 "ck_48m" : "armper_ck"));
2515 if (diff
& (1 << 9)) /* CONF_MOD_USB_HOST_HHC_UHO */
2516 omap_clk_onoff(omap_findclk(s
, "usb_hhc_ck"), (value
>> 9) & 1);
2519 static void omap_pin_cfg_write(void *opaque
, target_phys_addr_t addr
,
2522 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2523 int offset
= addr
- s
->pin_cfg_base
;
2527 case 0x00: /* FUNC_MUX_CTRL_0 */
2528 diff
= s
->func_mux_ctrl
[offset
>> 2] ^ value
;
2529 s
->func_mux_ctrl
[offset
>> 2] = value
;
2530 omap_pin_funcmux0_update(s
, diff
, value
);
2533 case 0x04: /* FUNC_MUX_CTRL_1 */
2534 diff
= s
->func_mux_ctrl
[offset
>> 2] ^ value
;
2535 s
->func_mux_ctrl
[offset
>> 2] = value
;
2536 omap_pin_funcmux1_update(s
, diff
, value
);
2539 case 0x08: /* FUNC_MUX_CTRL_2 */
2540 s
->func_mux_ctrl
[offset
>> 2] = value
;
2543 case 0x0c: /* COMP_MODE_CTRL_0 */
2544 s
->comp_mode_ctrl
[0] = value
;
2545 s
->compat1509
= (value
!= 0x0000eaef);
2546 omap_pin_funcmux0_update(s
, ~0, s
->func_mux_ctrl
[0]);
2547 omap_pin_funcmux1_update(s
, ~0, s
->func_mux_ctrl
[1]);
2550 case 0x10: /* FUNC_MUX_CTRL_3 */
2551 case 0x14: /* FUNC_MUX_CTRL_4 */
2552 case 0x18: /* FUNC_MUX_CTRL_5 */
2553 case 0x1c: /* FUNC_MUX_CTRL_6 */
2554 case 0x20: /* FUNC_MUX_CTRL_7 */
2555 case 0x24: /* FUNC_MUX_CTRL_8 */
2556 case 0x28: /* FUNC_MUX_CTRL_9 */
2557 case 0x2c: /* FUNC_MUX_CTRL_A */
2558 case 0x30: /* FUNC_MUX_CTRL_B */
2559 case 0x34: /* FUNC_MUX_CTRL_C */
2560 case 0x38: /* FUNC_MUX_CTRL_D */
2561 s
->func_mux_ctrl
[(offset
>> 2) - 1] = value
;
2564 case 0x40: /* PULL_DWN_CTRL_0 */
2565 case 0x44: /* PULL_DWN_CTRL_1 */
2566 case 0x48: /* PULL_DWN_CTRL_2 */
2567 case 0x4c: /* PULL_DWN_CTRL_3 */
2568 s
->pull_dwn_ctrl
[(offset
& 0xf) >> 2] = value
;
2571 case 0x50: /* GATE_INH_CTRL_0 */
2572 s
->gate_inh_ctrl
[0] = value
;
2575 case 0x60: /* VOLTAGE_CTRL_0 */
2576 s
->voltage_ctrl
[0] = value
;
2579 case 0x70: /* TEST_DBG_CTRL_0 */
2580 s
->test_dbg_ctrl
[0] = value
;
2583 case 0x80: /* MOD_CONF_CTRL_0 */
2584 diff
= s
->mod_conf_ctrl
[0] ^ value
;
2585 s
->mod_conf_ctrl
[0] = value
;
2586 omap_pin_modconf1_update(s
, diff
, value
);
2594 static CPUReadMemoryFunc
*omap_pin_cfg_readfn
[] = {
2595 omap_badwidth_read32
,
2596 omap_badwidth_read32
,
2600 static CPUWriteMemoryFunc
*omap_pin_cfg_writefn
[] = {
2601 omap_badwidth_write32
,
2602 omap_badwidth_write32
,
2606 static void omap_pin_cfg_reset(struct omap_mpu_state_s
*mpu
)
2608 /* Start in Compatibility Mode. */
2609 mpu
->compat1509
= 1;
2610 omap_pin_funcmux0_update(mpu
, mpu
->func_mux_ctrl
[0], 0);
2611 omap_pin_funcmux1_update(mpu
, mpu
->func_mux_ctrl
[1], 0);
2612 omap_pin_modconf1_update(mpu
, mpu
->mod_conf_ctrl
[0], 0);
2613 memset(mpu
->func_mux_ctrl
, 0, sizeof(mpu
->func_mux_ctrl
));
2614 memset(mpu
->comp_mode_ctrl
, 0, sizeof(mpu
->comp_mode_ctrl
));
2615 memset(mpu
->pull_dwn_ctrl
, 0, sizeof(mpu
->pull_dwn_ctrl
));
2616 memset(mpu
->gate_inh_ctrl
, 0, sizeof(mpu
->gate_inh_ctrl
));
2617 memset(mpu
->voltage_ctrl
, 0, sizeof(mpu
->voltage_ctrl
));
2618 memset(mpu
->test_dbg_ctrl
, 0, sizeof(mpu
->test_dbg_ctrl
));
2619 memset(mpu
->mod_conf_ctrl
, 0, sizeof(mpu
->mod_conf_ctrl
));
2622 static void omap_pin_cfg_init(target_phys_addr_t base
,
2623 struct omap_mpu_state_s
*mpu
)
2625 int iomemtype
= cpu_register_io_memory(0, omap_pin_cfg_readfn
,
2626 omap_pin_cfg_writefn
, mpu
);
2628 mpu
->pin_cfg_base
= base
;
2629 cpu_register_physical_memory(mpu
->pin_cfg_base
, 0x800, iomemtype
);
2630 omap_pin_cfg_reset(mpu
);
2633 /* Device Identification, Die Identification */
2634 static uint32_t omap_id_read(void *opaque
, target_phys_addr_t addr
)
2636 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2639 case 0xfffe1800: /* DIE_ID_LSB */
2641 case 0xfffe1804: /* DIE_ID_MSB */
2644 case 0xfffe2000: /* PRODUCT_ID_LSB */
2646 case 0xfffe2004: /* PRODUCT_ID_MSB */
2649 case 0xfffed400: /* JTAG_ID_LSB */
2650 switch (s
->mpu_model
) {
2658 case 0xfffed404: /* JTAG_ID_MSB */
2659 switch (s
->mpu_model
) {
2672 static void omap_id_write(void *opaque
, target_phys_addr_t addr
,
2678 static CPUReadMemoryFunc
*omap_id_readfn
[] = {
2679 omap_badwidth_read32
,
2680 omap_badwidth_read32
,
2684 static CPUWriteMemoryFunc
*omap_id_writefn
[] = {
2685 omap_badwidth_write32
,
2686 omap_badwidth_write32
,
2690 static void omap_id_init(struct omap_mpu_state_s
*mpu
)
2692 int iomemtype
= cpu_register_io_memory(0, omap_id_readfn
,
2693 omap_id_writefn
, mpu
);
2694 cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype
);
2695 cpu_register_physical_memory(0xfffed400, 0x100, iomemtype
);
2696 if (!cpu_is_omap15xx(mpu
))
2697 cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype
);
2700 /* MPUI Control (Dummy) */
2701 static uint32_t omap_mpui_read(void *opaque
, target_phys_addr_t addr
)
2703 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2704 int offset
= addr
- s
->mpui_base
;
2707 case 0x00: /* CTRL */
2708 return s
->mpui_ctrl
;
2709 case 0x04: /* DEBUG_ADDR */
2711 case 0x08: /* DEBUG_DATA */
2713 case 0x0c: /* DEBUG_FLAG */
2715 case 0x10: /* STATUS */
2718 /* Not in OMAP310 */
2719 case 0x14: /* DSP_STATUS */
2720 case 0x18: /* DSP_BOOT_CONFIG */
2722 case 0x1c: /* DSP_MPUI_CONFIG */
2730 static void omap_mpui_write(void *opaque
, target_phys_addr_t addr
,
2733 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2734 int offset
= addr
- s
->mpui_base
;
2737 case 0x00: /* CTRL */
2738 s
->mpui_ctrl
= value
& 0x007fffff;
2741 case 0x04: /* DEBUG_ADDR */
2742 case 0x08: /* DEBUG_DATA */
2743 case 0x0c: /* DEBUG_FLAG */
2744 case 0x10: /* STATUS */
2745 /* Not in OMAP310 */
2746 case 0x14: /* DSP_STATUS */
2748 case 0x18: /* DSP_BOOT_CONFIG */
2749 case 0x1c: /* DSP_MPUI_CONFIG */
2757 static CPUReadMemoryFunc
*omap_mpui_readfn
[] = {
2758 omap_badwidth_read32
,
2759 omap_badwidth_read32
,
2763 static CPUWriteMemoryFunc
*omap_mpui_writefn
[] = {
2764 omap_badwidth_write32
,
2765 omap_badwidth_write32
,
2769 static void omap_mpui_reset(struct omap_mpu_state_s
*s
)
2771 s
->mpui_ctrl
= 0x0003ff1b;
2774 static void omap_mpui_init(target_phys_addr_t base
,
2775 struct omap_mpu_state_s
*mpu
)
2777 int iomemtype
= cpu_register_io_memory(0, omap_mpui_readfn
,
2778 omap_mpui_writefn
, mpu
);
2780 mpu
->mpui_base
= base
;
2781 cpu_register_physical_memory(mpu
->mpui_base
, 0x100, iomemtype
);
2783 omap_mpui_reset(mpu
);
2787 struct omap_tipb_bridge_s
{
2788 target_phys_addr_t base
;
2795 uint16_t enh_control
;
2798 static uint32_t omap_tipb_bridge_read(void *opaque
, target_phys_addr_t addr
)
2800 struct omap_tipb_bridge_s
*s
= (struct omap_tipb_bridge_s
*) opaque
;
2801 int offset
= addr
- s
->base
;
2804 case 0x00: /* TIPB_CNTL */
2806 case 0x04: /* TIPB_BUS_ALLOC */
2808 case 0x08: /* MPU_TIPB_CNTL */
2810 case 0x0c: /* ENHANCED_TIPB_CNTL */
2811 return s
->enh_control
;
2812 case 0x10: /* ADDRESS_DBG */
2813 case 0x14: /* DATA_DEBUG_LOW */
2814 case 0x18: /* DATA_DEBUG_HIGH */
2816 case 0x1c: /* DEBUG_CNTR_SIG */
2824 static void omap_tipb_bridge_write(void *opaque
, target_phys_addr_t addr
,
2827 struct omap_tipb_bridge_s
*s
= (struct omap_tipb_bridge_s
*) opaque
;
2828 int offset
= addr
- s
->base
;
2831 case 0x00: /* TIPB_CNTL */
2832 s
->control
= value
& 0xffff;
2835 case 0x04: /* TIPB_BUS_ALLOC */
2836 s
->alloc
= value
& 0x003f;
2839 case 0x08: /* MPU_TIPB_CNTL */
2840 s
->buffer
= value
& 0x0003;
2843 case 0x0c: /* ENHANCED_TIPB_CNTL */
2844 s
->width_intr
= !(value
& 2);
2845 s
->enh_control
= value
& 0x000f;
2848 case 0x10: /* ADDRESS_DBG */
2849 case 0x14: /* DATA_DEBUG_LOW */
2850 case 0x18: /* DATA_DEBUG_HIGH */
2851 case 0x1c: /* DEBUG_CNTR_SIG */
2860 static CPUReadMemoryFunc
*omap_tipb_bridge_readfn
[] = {
2861 omap_badwidth_read16
,
2862 omap_tipb_bridge_read
,
2863 omap_tipb_bridge_read
,
2866 static CPUWriteMemoryFunc
*omap_tipb_bridge_writefn
[] = {
2867 omap_badwidth_write16
,
2868 omap_tipb_bridge_write
,
2869 omap_tipb_bridge_write
,
2872 static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s
*s
)
2874 s
->control
= 0xffff;
2877 s
->enh_control
= 0x000f;
2880 struct omap_tipb_bridge_s
*omap_tipb_bridge_init(target_phys_addr_t base
,
2881 qemu_irq abort_irq
, omap_clk clk
)
2884 struct omap_tipb_bridge_s
*s
= (struct omap_tipb_bridge_s
*)
2885 qemu_mallocz(sizeof(struct omap_tipb_bridge_s
));
2887 s
->abort
= abort_irq
;
2889 omap_tipb_bridge_reset(s
);
2891 iomemtype
= cpu_register_io_memory(0, omap_tipb_bridge_readfn
,
2892 omap_tipb_bridge_writefn
, s
);
2893 cpu_register_physical_memory(s
->base
, 0x100, iomemtype
);
2898 /* Dummy Traffic Controller's Memory Interface */
2899 static uint32_t omap_tcmi_read(void *opaque
, target_phys_addr_t addr
)
2901 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2902 int offset
= addr
- s
->tcmi_base
;
2906 case 0x00: /* IMIF_PRIO */
2907 case 0x04: /* EMIFS_PRIO */
2908 case 0x08: /* EMIFF_PRIO */
2909 case 0x0c: /* EMIFS_CONFIG */
2910 case 0x10: /* EMIFS_CS0_CONFIG */
2911 case 0x14: /* EMIFS_CS1_CONFIG */
2912 case 0x18: /* EMIFS_CS2_CONFIG */
2913 case 0x1c: /* EMIFS_CS3_CONFIG */
2914 case 0x24: /* EMIFF_MRS */
2915 case 0x28: /* TIMEOUT1 */
2916 case 0x2c: /* TIMEOUT2 */
2917 case 0x30: /* TIMEOUT3 */
2918 case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
2919 case 0x40: /* EMIFS_CFG_DYN_WAIT */
2920 return s
->tcmi_regs
[offset
>> 2];
2922 case 0x20: /* EMIFF_SDRAM_CONFIG */
2923 ret
= s
->tcmi_regs
[offset
>> 2];
2924 s
->tcmi_regs
[offset
>> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2925 /* XXX: We can try using the VGA_DIRTY flag for this */
2933 static void omap_tcmi_write(void *opaque
, target_phys_addr_t addr
,
2936 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
2937 int offset
= addr
- s
->tcmi_base
;
2940 case 0x00: /* IMIF_PRIO */
2941 case 0x04: /* EMIFS_PRIO */
2942 case 0x08: /* EMIFF_PRIO */
2943 case 0x10: /* EMIFS_CS0_CONFIG */
2944 case 0x14: /* EMIFS_CS1_CONFIG */
2945 case 0x18: /* EMIFS_CS2_CONFIG */
2946 case 0x1c: /* EMIFS_CS3_CONFIG */
2947 case 0x20: /* EMIFF_SDRAM_CONFIG */
2948 case 0x24: /* EMIFF_MRS */
2949 case 0x28: /* TIMEOUT1 */
2950 case 0x2c: /* TIMEOUT2 */
2951 case 0x30: /* TIMEOUT3 */
2952 case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
2953 case 0x40: /* EMIFS_CFG_DYN_WAIT */
2954 s
->tcmi_regs
[offset
>> 2] = value
;
2956 case 0x0c: /* EMIFS_CONFIG */
2957 s
->tcmi_regs
[offset
>> 2] = (value
& 0xf) | (1 << 4);
2965 static CPUReadMemoryFunc
*omap_tcmi_readfn
[] = {
2966 omap_badwidth_read32
,
2967 omap_badwidth_read32
,
2971 static CPUWriteMemoryFunc
*omap_tcmi_writefn
[] = {
2972 omap_badwidth_write32
,
2973 omap_badwidth_write32
,
2977 static void omap_tcmi_reset(struct omap_mpu_state_s
*mpu
)
2979 mpu
->tcmi_regs
[0x00 >> 2] = 0x00000000;
2980 mpu
->tcmi_regs
[0x04 >> 2] = 0x00000000;
2981 mpu
->tcmi_regs
[0x08 >> 2] = 0x00000000;
2982 mpu
->tcmi_regs
[0x0c >> 2] = 0x00000010;
2983 mpu
->tcmi_regs
[0x10 >> 2] = 0x0010fffb;
2984 mpu
->tcmi_regs
[0x14 >> 2] = 0x0010fffb;
2985 mpu
->tcmi_regs
[0x18 >> 2] = 0x0010fffb;
2986 mpu
->tcmi_regs
[0x1c >> 2] = 0x0010fffb;
2987 mpu
->tcmi_regs
[0x20 >> 2] = 0x00618800;
2988 mpu
->tcmi_regs
[0x24 >> 2] = 0x00000037;
2989 mpu
->tcmi_regs
[0x28 >> 2] = 0x00000000;
2990 mpu
->tcmi_regs
[0x2c >> 2] = 0x00000000;
2991 mpu
->tcmi_regs
[0x30 >> 2] = 0x00000000;
2992 mpu
->tcmi_regs
[0x3c >> 2] = 0x00000003;
2993 mpu
->tcmi_regs
[0x40 >> 2] = 0x00000000;
2996 static void omap_tcmi_init(target_phys_addr_t base
,
2997 struct omap_mpu_state_s
*mpu
)
2999 int iomemtype
= cpu_register_io_memory(0, omap_tcmi_readfn
,
3000 omap_tcmi_writefn
, mpu
);
3002 mpu
->tcmi_base
= base
;
3003 cpu_register_physical_memory(mpu
->tcmi_base
, 0x100, iomemtype
);
3004 omap_tcmi_reset(mpu
);
3007 /* Digital phase-locked loops control */
3008 static uint32_t omap_dpll_read(void *opaque
, target_phys_addr_t addr
)
3010 struct dpll_ctl_s
*s
= (struct dpll_ctl_s
*) opaque
;
3011 int offset
= addr
- s
->base
;
3013 if (offset
== 0x00) /* CTL_REG */
3020 static void omap_dpll_write(void *opaque
, target_phys_addr_t addr
,
3023 struct dpll_ctl_s
*s
= (struct dpll_ctl_s
*) opaque
;
3025 int offset
= addr
- s
->base
;
3026 static const int bypass_div
[4] = { 1, 2, 4, 4 };
3029 if (offset
== 0x00) { /* CTL_REG */
3030 /* See omap_ulpd_pm_write() too */
3031 diff
= s
->mode
& value
;
3032 s
->mode
= value
& 0x2fff;
3033 if (diff
& (0x3ff << 2)) {
3034 if (value
& (1 << 4)) { /* PLL_ENABLE */
3035 div
= ((value
>> 5) & 3) + 1; /* PLL_DIV */
3036 mult
= MIN((value
>> 7) & 0x1f, 1); /* PLL_MULT */
3038 div
= bypass_div
[((value
>> 2) & 3)]; /* BYPASS_DIV */
3041 omap_clk_setrate(s
->dpll
, div
, mult
);
3044 /* Enter the desired mode. */
3045 s
->mode
= (s
->mode
& 0xfffe) | ((s
->mode
>> 4) & 1);
3047 /* Act as if the lock is restored. */
3054 static CPUReadMemoryFunc
*omap_dpll_readfn
[] = {
3055 omap_badwidth_read16
,
3057 omap_badwidth_read16
,
3060 static CPUWriteMemoryFunc
*omap_dpll_writefn
[] = {
3061 omap_badwidth_write16
,
3063 omap_badwidth_write16
,
3066 static void omap_dpll_reset(struct dpll_ctl_s
*s
)
3069 omap_clk_setrate(s
->dpll
, 1, 1);
3072 static void omap_dpll_init(struct dpll_ctl_s
*s
, target_phys_addr_t base
,
3075 int iomemtype
= cpu_register_io_memory(0, omap_dpll_readfn
,
3076 omap_dpll_writefn
, s
);
3082 cpu_register_physical_memory(s
->base
, 0x100, iomemtype
);
3086 struct omap_uart_s
{
3087 SerialState
*serial
; /* TODO */
3090 static void omap_uart_reset(struct omap_uart_s
*s
)
3094 struct omap_uart_s
*omap_uart_init(target_phys_addr_t base
,
3095 qemu_irq irq
, omap_clk clk
, CharDriverState
*chr
)
3097 struct omap_uart_s
*s
= (struct omap_uart_s
*)
3098 qemu_mallocz(sizeof(struct omap_uart_s
));
3100 s
->serial
= serial_mm_init(base
, 2, irq
, chr
, 1);
3104 /* MPU Clock/Reset/Power Mode Control */
3105 static uint32_t omap_clkm_read(void *opaque
, target_phys_addr_t addr
)
3107 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
3108 int offset
= addr
- s
->clkm
.mpu_base
;
3111 case 0x00: /* ARM_CKCTL */
3112 return s
->clkm
.arm_ckctl
;
3114 case 0x04: /* ARM_IDLECT1 */
3115 return s
->clkm
.arm_idlect1
;
3117 case 0x08: /* ARM_IDLECT2 */
3118 return s
->clkm
.arm_idlect2
;
3120 case 0x0c: /* ARM_EWUPCT */
3121 return s
->clkm
.arm_ewupct
;
3123 case 0x10: /* ARM_RSTCT1 */
3124 return s
->clkm
.arm_rstct1
;
3126 case 0x14: /* ARM_RSTCT2 */
3127 return s
->clkm
.arm_rstct2
;
3129 case 0x18: /* ARM_SYSST */
3130 return (s
->clkm
.clocking_scheme
<< 11) | s
->clkm
.cold_start
;
3132 case 0x1c: /* ARM_CKOUT1 */
3133 return s
->clkm
.arm_ckout1
;
3135 case 0x20: /* ARM_CKOUT2 */
3143 static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s
*s
,
3144 uint16_t diff
, uint16_t value
)
3148 if (diff
& (1 << 14)) { /* ARM_INTHCK_SEL */
3149 if (value
& (1 << 14))
3152 clk
= omap_findclk(s
, "arminth_ck");
3153 omap_clk_reparent(clk
, omap_findclk(s
, "tc_ck"));
3156 if (diff
& (1 << 12)) { /* ARM_TIMXO */
3157 clk
= omap_findclk(s
, "armtim_ck");
3158 if (value
& (1 << 12))
3159 omap_clk_reparent(clk
, omap_findclk(s
, "clkin"));
3161 omap_clk_reparent(clk
, omap_findclk(s
, "ck_gen1"));
3164 if (diff
& (3 << 10)) { /* DSPMMUDIV */
3165 clk
= omap_findclk(s
, "dspmmu_ck");
3166 omap_clk_setrate(clk
, 1 << ((value
>> 10) & 3), 1);
3168 if (diff
& (3 << 8)) { /* TCDIV */
3169 clk
= omap_findclk(s
, "tc_ck");
3170 omap_clk_setrate(clk
, 1 << ((value
>> 8) & 3), 1);
3172 if (diff
& (3 << 6)) { /* DSPDIV */
3173 clk
= omap_findclk(s
, "dsp_ck");
3174 omap_clk_setrate(clk
, 1 << ((value
>> 6) & 3), 1);
3176 if (diff
& (3 << 4)) { /* ARMDIV */
3177 clk
= omap_findclk(s
, "arm_ck");
3178 omap_clk_setrate(clk
, 1 << ((value
>> 4) & 3), 1);
3180 if (diff
& (3 << 2)) { /* LCDDIV */
3181 clk
= omap_findclk(s
, "lcd_ck");
3182 omap_clk_setrate(clk
, 1 << ((value
>> 2) & 3), 1);
3184 if (diff
& (3 << 0)) { /* PERDIV */
3185 clk
= omap_findclk(s
, "armper_ck");
3186 omap_clk_setrate(clk
, 1 << ((value
>> 0) & 3), 1);
3190 static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s
*s
,
3191 uint16_t diff
, uint16_t value
)
3195 if (value
& (1 << 11)) /* SETARM_IDLE */
3196 cpu_interrupt(s
->env
, CPU_INTERRUPT_HALT
);
3197 if (!(value
& (1 << 10))) /* WKUP_MODE */
3198 qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */
3200 #define SET_CANIDLE(clock, bit) \
3201 if (diff & (1 << bit)) { \
3202 clk = omap_findclk(s, clock); \
3203 omap_clk_canidle(clk, (value >> bit) & 1); \
3205 SET_CANIDLE("mpuwd_ck", 0) /* IDLWDT_ARM */
3206 SET_CANIDLE("armxor_ck", 1) /* IDLXORP_ARM */
3207 SET_CANIDLE("mpuper_ck", 2) /* IDLPER_ARM */
3208 SET_CANIDLE("lcd_ck", 3) /* IDLLCD_ARM */
3209 SET_CANIDLE("lb_ck", 4) /* IDLLB_ARM */
3210 SET_CANIDLE("hsab_ck", 5) /* IDLHSAB_ARM */
3211 SET_CANIDLE("tipb_ck", 6) /* IDLIF_ARM */
3212 SET_CANIDLE("dma_ck", 6) /* IDLIF_ARM */
3213 SET_CANIDLE("tc_ck", 6) /* IDLIF_ARM */
3214 SET_CANIDLE("dpll1", 7) /* IDLDPLL_ARM */
3215 SET_CANIDLE("dpll2", 7) /* IDLDPLL_ARM */
3216 SET_CANIDLE("dpll3", 7) /* IDLDPLL_ARM */
3217 SET_CANIDLE("mpui_ck", 8) /* IDLAPI_ARM */
3218 SET_CANIDLE("armtim_ck", 9) /* IDLTIM_ARM */
3221 static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s
*s
,
3222 uint16_t diff
, uint16_t value
)
3226 #define SET_ONOFF(clock, bit) \
3227 if (diff & (1 << bit)) { \
3228 clk = omap_findclk(s, clock); \
3229 omap_clk_onoff(clk, (value >> bit) & 1); \
3231 SET_ONOFF("mpuwd_ck", 0) /* EN_WDTCK */
3232 SET_ONOFF("armxor_ck", 1) /* EN_XORPCK */
3233 SET_ONOFF("mpuper_ck", 2) /* EN_PERCK */
3234 SET_ONOFF("lcd_ck", 3) /* EN_LCDCK */
3235 SET_ONOFF("lb_ck", 4) /* EN_LBCK */
3236 SET_ONOFF("hsab_ck", 5) /* EN_HSABCK */
3237 SET_ONOFF("mpui_ck", 6) /* EN_APICK */
3238 SET_ONOFF("armtim_ck", 7) /* EN_TIMCK */
3239 SET_CANIDLE("dma_ck", 8) /* DMACK_REQ */
3240 SET_ONOFF("arm_gpio_ck", 9) /* EN_GPIOCK */
3241 SET_ONOFF("lbfree_ck", 10) /* EN_LBFREECK */
3244 static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s
*s
,
3245 uint16_t diff
, uint16_t value
)
3249 if (diff
& (3 << 4)) { /* TCLKOUT */
3250 clk
= omap_findclk(s
, "tclk_out");
3251 switch ((value
>> 4) & 3) {
3253 omap_clk_reparent(clk
, omap_findclk(s
, "ck_gen3"));
3254 omap_clk_onoff(clk
, 1);
3257 omap_clk_reparent(clk
, omap_findclk(s
, "tc_ck"));
3258 omap_clk_onoff(clk
, 1);
3261 omap_clk_onoff(clk
, 0);
3264 if (diff
& (3 << 2)) { /* DCLKOUT */
3265 clk
= omap_findclk(s
, "dclk_out");
3266 switch ((value
>> 2) & 3) {
3268 omap_clk_reparent(clk
, omap_findclk(s
, "dspmmu_ck"));
3271 omap_clk_reparent(clk
, omap_findclk(s
, "ck_gen2"));
3274 omap_clk_reparent(clk
, omap_findclk(s
, "dsp_ck"));
3277 omap_clk_reparent(clk
, omap_findclk(s
, "ck_ref14"));
3281 if (diff
& (3 << 0)) { /* ACLKOUT */
3282 clk
= omap_findclk(s
, "aclk_out");
3283 switch ((value
>> 0) & 3) {
3285 omap_clk_reparent(clk
, omap_findclk(s
, "ck_gen1"));
3286 omap_clk_onoff(clk
, 1);
3289 omap_clk_reparent(clk
, omap_findclk(s
, "arm_ck"));
3290 omap_clk_onoff(clk
, 1);
3293 omap_clk_reparent(clk
, omap_findclk(s
, "ck_ref14"));
3294 omap_clk_onoff(clk
, 1);
3297 omap_clk_onoff(clk
, 0);
3302 static void omap_clkm_write(void *opaque
, target_phys_addr_t addr
,
3305 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
3306 int offset
= addr
- s
->clkm
.mpu_base
;
3309 static const char *clkschemename
[8] = {
3310 "fully synchronous", "fully asynchronous", "synchronous scalable",
3311 "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
3315 case 0x00: /* ARM_CKCTL */
3316 diff
= s
->clkm
.arm_ckctl
^ value
;
3317 s
->clkm
.arm_ckctl
= value
& 0x7fff;
3318 omap_clkm_ckctl_update(s
, diff
, value
);
3321 case 0x04: /* ARM_IDLECT1 */
3322 diff
= s
->clkm
.arm_idlect1
^ value
;
3323 s
->clkm
.arm_idlect1
= value
& 0x0fff;
3324 omap_clkm_idlect1_update(s
, diff
, value
);
3327 case 0x08: /* ARM_IDLECT2 */
3328 diff
= s
->clkm
.arm_idlect2
^ value
;
3329 s
->clkm
.arm_idlect2
= value
& 0x07ff;
3330 omap_clkm_idlect2_update(s
, diff
, value
);
3333 case 0x0c: /* ARM_EWUPCT */
3334 diff
= s
->clkm
.arm_ewupct
^ value
;
3335 s
->clkm
.arm_ewupct
= value
& 0x003f;
3338 case 0x10: /* ARM_RSTCT1 */
3339 diff
= s
->clkm
.arm_rstct1
^ value
;
3340 s
->clkm
.arm_rstct1
= value
& 0x0007;
3342 qemu_system_reset_request();
3343 s
->clkm
.cold_start
= 0xa;
3345 if (diff
& ~value
& 4) { /* DSP_RST */
3347 omap_tipb_bridge_reset(s
->private_tipb
);
3348 omap_tipb_bridge_reset(s
->public_tipb
);
3350 if (diff
& 2) { /* DSP_EN */
3351 clk
= omap_findclk(s
, "dsp_ck");
3352 omap_clk_canidle(clk
, (~value
>> 1) & 1);
3356 case 0x14: /* ARM_RSTCT2 */
3357 s
->clkm
.arm_rstct2
= value
& 0x0001;
3360 case 0x18: /* ARM_SYSST */
3361 if ((s
->clkm
.clocking_scheme
^ (value
>> 11)) & 7) {
3362 s
->clkm
.clocking_scheme
= (value
>> 11) & 7;
3363 printf("%s: clocking scheme set to %s\n", __FUNCTION__
,
3364 clkschemename
[s
->clkm
.clocking_scheme
]);
3366 s
->clkm
.cold_start
&= value
& 0x3f;
3369 case 0x1c: /* ARM_CKOUT1 */
3370 diff
= s
->clkm
.arm_ckout1
^ value
;
3371 s
->clkm
.arm_ckout1
= value
& 0x003f;
3372 omap_clkm_ckout1_update(s
, diff
, value
);
3375 case 0x20: /* ARM_CKOUT2 */
3381 static CPUReadMemoryFunc
*omap_clkm_readfn
[] = {
3382 omap_badwidth_read16
,
3384 omap_badwidth_read16
,
3387 static CPUWriteMemoryFunc
*omap_clkm_writefn
[] = {
3388 omap_badwidth_write16
,
3390 omap_badwidth_write16
,
3393 static uint32_t omap_clkdsp_read(void *opaque
, target_phys_addr_t addr
)
3395 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
3396 int offset
= addr
- s
->clkm
.dsp_base
;
3399 case 0x04: /* DSP_IDLECT1 */
3400 return s
->clkm
.dsp_idlect1
;
3402 case 0x08: /* DSP_IDLECT2 */
3403 return s
->clkm
.dsp_idlect2
;
3405 case 0x14: /* DSP_RSTCT2 */
3406 return s
->clkm
.dsp_rstct2
;
3408 case 0x18: /* DSP_SYSST */
3409 return (s
->clkm
.clocking_scheme
<< 11) | s
->clkm
.cold_start
|
3410 (s
->env
->halted
<< 6); /* Quite useless... */
3417 static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s
*s
,
3418 uint16_t diff
, uint16_t value
)
3422 SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */
3425 static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s
*s
,
3426 uint16_t diff
, uint16_t value
)
3430 SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */
3433 static void omap_clkdsp_write(void *opaque
, target_phys_addr_t addr
,
3436 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
3437 int offset
= addr
- s
->clkm
.dsp_base
;
3441 case 0x04: /* DSP_IDLECT1 */
3442 diff
= s
->clkm
.dsp_idlect1
^ value
;
3443 s
->clkm
.dsp_idlect1
= value
& 0x01f7;
3444 omap_clkdsp_idlect1_update(s
, diff
, value
);
3447 case 0x08: /* DSP_IDLECT2 */
3448 s
->clkm
.dsp_idlect2
= value
& 0x0037;
3449 diff
= s
->clkm
.dsp_idlect1
^ value
;
3450 omap_clkdsp_idlect2_update(s
, diff
, value
);
3453 case 0x14: /* DSP_RSTCT2 */
3454 s
->clkm
.dsp_rstct2
= value
& 0x0001;
3457 case 0x18: /* DSP_SYSST */
3458 s
->clkm
.cold_start
&= value
& 0x3f;
3466 static CPUReadMemoryFunc
*omap_clkdsp_readfn
[] = {
3467 omap_badwidth_read16
,
3469 omap_badwidth_read16
,
3472 static CPUWriteMemoryFunc
*omap_clkdsp_writefn
[] = {
3473 omap_badwidth_write16
,
3475 omap_badwidth_write16
,
3478 static void omap_clkm_reset(struct omap_mpu_state_s
*s
)
3480 if (s
->wdt
&& s
->wdt
->reset
)
3481 s
->clkm
.cold_start
= 0x6;
3482 s
->clkm
.clocking_scheme
= 0;
3483 omap_clkm_ckctl_update(s
, ~0, 0x3000);
3484 s
->clkm
.arm_ckctl
= 0x3000;
3485 omap_clkm_idlect1_update(s
, s
->clkm
.arm_idlect1
^ 0x0400, 0x0400);
3486 s
->clkm
.arm_idlect1
= 0x0400;
3487 omap_clkm_idlect2_update(s
, s
->clkm
.arm_idlect2
^ 0x0100, 0x0100);
3488 s
->clkm
.arm_idlect2
= 0x0100;
3489 s
->clkm
.arm_ewupct
= 0x003f;
3490 s
->clkm
.arm_rstct1
= 0x0000;
3491 s
->clkm
.arm_rstct2
= 0x0000;
3492 s
->clkm
.arm_ckout1
= 0x0015;
3493 s
->clkm
.dpll1_mode
= 0x2002;
3494 omap_clkdsp_idlect1_update(s
, s
->clkm
.dsp_idlect1
^ 0x0040, 0x0040);
3495 s
->clkm
.dsp_idlect1
= 0x0040;
3496 omap_clkdsp_idlect2_update(s
, ~0, 0x0000);
3497 s
->clkm
.dsp_idlect2
= 0x0000;
3498 s
->clkm
.dsp_rstct2
= 0x0000;
3501 static void omap_clkm_init(target_phys_addr_t mpu_base
,
3502 target_phys_addr_t dsp_base
, struct omap_mpu_state_s
*s
)
3504 int iomemtype
[2] = {
3505 cpu_register_io_memory(0, omap_clkm_readfn
, omap_clkm_writefn
, s
),
3506 cpu_register_io_memory(0, omap_clkdsp_readfn
, omap_clkdsp_writefn
, s
),
3509 s
->clkm
.mpu_base
= mpu_base
;
3510 s
->clkm
.dsp_base
= dsp_base
;
3511 s
->clkm
.arm_idlect1
= 0x03ff;
3512 s
->clkm
.arm_idlect2
= 0x0100;
3513 s
->clkm
.dsp_idlect1
= 0x0002;
3515 s
->clkm
.cold_start
= 0x3a;
3517 cpu_register_physical_memory(s
->clkm
.mpu_base
, 0x100, iomemtype
[0]);
3518 cpu_register_physical_memory(s
->clkm
.dsp_base
, 0x1000, iomemtype
[1]);
3522 struct omap_mpuio_s
{
3523 target_phys_addr_t base
;
3527 qemu_irq handler
[16];
3548 static void omap_mpuio_set(void *opaque
, int line
, int level
)
3550 struct omap_mpuio_s
*s
= (struct omap_mpuio_s
*) opaque
;
3551 uint16_t prev
= s
->inputs
;
3554 s
->inputs
|= 1 << line
;
3556 s
->inputs
&= ~(1 << line
);
3558 if (((1 << line
) & s
->dir
& ~s
->mask
) && s
->clk
) {
3559 if ((s
->edge
& s
->inputs
& ~prev
) | (~s
->edge
& ~s
->inputs
& prev
)) {
3560 s
->ints
|= 1 << line
;
3561 qemu_irq_raise(s
->irq
);
3564 if ((s
->event
& (1 << 0)) && /* SET_GPIO_EVENT_MODE */
3565 (s
->event
>> 1) == line
) /* PIN_SELECT */
3566 s
->latch
= s
->inputs
;
3570 static void omap_mpuio_kbd_update(struct omap_mpuio_s
*s
)
3573 uint8_t *row
, rows
= 0, cols
= ~s
->cols
;
3575 for (row
= s
->buttons
+ 4, i
= 1 << 4; i
; row
--, i
>>= 1)
3579 qemu_set_irq(s
->kbd_irq
, rows
&& !s
->kbd_mask
&& s
->clk
);
3580 s
->row_latch
= ~rows
;
3583 static uint32_t omap_mpuio_read(void *opaque
, target_phys_addr_t addr
)
3585 struct omap_mpuio_s
*s
= (struct omap_mpuio_s
*) opaque
;
3586 int offset
= addr
& OMAP_MPUI_REG_MASK
;
3590 case 0x00: /* INPUT_LATCH */
3593 case 0x04: /* OUTPUT_REG */
3596 case 0x08: /* IO_CNTL */
3599 case 0x10: /* KBR_LATCH */
3600 return s
->row_latch
;
3602 case 0x14: /* KBC_REG */
3605 case 0x18: /* GPIO_EVENT_MODE_REG */
3608 case 0x1c: /* GPIO_INT_EDGE_REG */
3611 case 0x20: /* KBD_INT */
3612 return (~s
->row_latch
& 0x1f) && !s
->kbd_mask
;
3614 case 0x24: /* GPIO_INT */
3618 qemu_irq_lower(s
->irq
);
3621 case 0x28: /* KBD_MASKIT */
3624 case 0x2c: /* GPIO_MASKIT */
3627 case 0x30: /* GPIO_DEBOUNCING_REG */
3630 case 0x34: /* GPIO_LATCH_REG */
3638 static void omap_mpuio_write(void *opaque
, target_phys_addr_t addr
,
3641 struct omap_mpuio_s
*s
= (struct omap_mpuio_s
*) opaque
;
3642 int offset
= addr
& OMAP_MPUI_REG_MASK
;
3647 case 0x04: /* OUTPUT_REG */
3648 diff
= (s
->outputs
^ value
) & ~s
->dir
;
3650 while ((ln
= ffs(diff
))) {
3653 qemu_set_irq(s
->handler
[ln
], (value
>> ln
) & 1);
3658 case 0x08: /* IO_CNTL */
3659 diff
= s
->outputs
& (s
->dir
^ value
);
3662 value
= s
->outputs
& ~s
->dir
;
3663 while ((ln
= ffs(diff
))) {
3666 qemu_set_irq(s
->handler
[ln
], (value
>> ln
) & 1);
3671 case 0x14: /* KBC_REG */
3673 omap_mpuio_kbd_update(s
);
3676 case 0x18: /* GPIO_EVENT_MODE_REG */
3677 s
->event
= value
& 0x1f;
3680 case 0x1c: /* GPIO_INT_EDGE_REG */
3684 case 0x28: /* KBD_MASKIT */
3685 s
->kbd_mask
= value
& 1;
3686 omap_mpuio_kbd_update(s
);
3689 case 0x2c: /* GPIO_MASKIT */
3693 case 0x30: /* GPIO_DEBOUNCING_REG */
3694 s
->debounce
= value
& 0x1ff;
3697 case 0x00: /* INPUT_LATCH */
3698 case 0x10: /* KBR_LATCH */
3699 case 0x20: /* KBD_INT */
3700 case 0x24: /* GPIO_INT */
3701 case 0x34: /* GPIO_LATCH_REG */
3711 static CPUReadMemoryFunc
*omap_mpuio_readfn
[] = {
3712 omap_badwidth_read16
,
3714 omap_badwidth_read16
,
3717 static CPUWriteMemoryFunc
*omap_mpuio_writefn
[] = {
3718 omap_badwidth_write16
,
3720 omap_badwidth_write16
,
3723 static void omap_mpuio_reset(struct omap_mpuio_s
*s
)
3735 s
->row_latch
= 0x1f;
3739 static void omap_mpuio_onoff(void *opaque
, int line
, int on
)
3741 struct omap_mpuio_s
*s
= (struct omap_mpuio_s
*) opaque
;
3745 omap_mpuio_kbd_update(s
);
3748 struct omap_mpuio_s
*omap_mpuio_init(target_phys_addr_t base
,
3749 qemu_irq kbd_int
, qemu_irq gpio_int
, qemu_irq wakeup
,
3753 struct omap_mpuio_s
*s
= (struct omap_mpuio_s
*)
3754 qemu_mallocz(sizeof(struct omap_mpuio_s
));
3758 s
->kbd_irq
= kbd_int
;
3760 s
->in
= qemu_allocate_irqs(omap_mpuio_set
, s
, 16);
3761 omap_mpuio_reset(s
);
3763 iomemtype
= cpu_register_io_memory(0, omap_mpuio_readfn
,
3764 omap_mpuio_writefn
, s
);
3765 cpu_register_physical_memory(s
->base
, 0x800, iomemtype
);
3767 omap_clk_adduser(clk
, qemu_allocate_irqs(omap_mpuio_onoff
, s
, 1)[0]);
3772 qemu_irq
*omap_mpuio_in_get(struct omap_mpuio_s
*s
)
3777 void omap_mpuio_out_set(struct omap_mpuio_s
*s
, int line
, qemu_irq handler
)
3779 if (line
>= 16 || line
< 0)
3780 cpu_abort(cpu_single_env
, "%s: No GPIO line %i\n", __FUNCTION__
, line
);
3781 s
->handler
[line
] = handler
;
3784 void omap_mpuio_key(struct omap_mpuio_s
*s
, int row
, int col
, int down
)
3786 if (row
>= 5 || row
< 0)
3787 cpu_abort(cpu_single_env
, "%s: No key %i-%i\n",
3788 __FUNCTION__
, col
, row
);
3791 s
->buttons
[row
] |= 1 << col
;
3793 s
->buttons
[row
] &= ~(1 << col
);
3795 omap_mpuio_kbd_update(s
);
3798 /* General-Purpose I/O */
3799 struct omap_gpio_s
{
3800 target_phys_addr_t base
;
3803 qemu_irq handler
[16];
3814 static void omap_gpio_set(void *opaque
, int line
, int level
)
3816 struct omap_gpio_s
*s
= (struct omap_gpio_s
*) opaque
;
3817 uint16_t prev
= s
->inputs
;
3820 s
->inputs
|= 1 << line
;
3822 s
->inputs
&= ~(1 << line
);
3824 if (((s
->edge
& s
->inputs
& ~prev
) | (~s
->edge
& ~s
->inputs
& prev
)) &
3825 (1 << line
) & s
->dir
& ~s
->mask
) {
3826 s
->ints
|= 1 << line
;
3827 qemu_irq_raise(s
->irq
);
3831 static uint32_t omap_gpio_read(void *opaque
, target_phys_addr_t addr
)
3833 struct omap_gpio_s
*s
= (struct omap_gpio_s
*) opaque
;
3834 int offset
= addr
& OMAP_MPUI_REG_MASK
;
3837 case 0x00: /* DATA_INPUT */
3838 return s
->inputs
& s
->pins
;
3840 case 0x04: /* DATA_OUTPUT */
3843 case 0x08: /* DIRECTION_CONTROL */
3846 case 0x0c: /* INTERRUPT_CONTROL */
3849 case 0x10: /* INTERRUPT_MASK */
3852 case 0x14: /* INTERRUPT_STATUS */
3855 case 0x18: /* PIN_CONTROL (not in OMAP310) */
3864 static void omap_gpio_write(void *opaque
, target_phys_addr_t addr
,
3867 struct omap_gpio_s
*s
= (struct omap_gpio_s
*) opaque
;
3868 int offset
= addr
& OMAP_MPUI_REG_MASK
;
3873 case 0x00: /* DATA_INPUT */
3877 case 0x04: /* DATA_OUTPUT */
3878 diff
= (s
->outputs
^ value
) & ~s
->dir
;
3880 while ((ln
= ffs(diff
))) {
3883 qemu_set_irq(s
->handler
[ln
], (value
>> ln
) & 1);
3888 case 0x08: /* DIRECTION_CONTROL */
3889 diff
= s
->outputs
& (s
->dir
^ value
);
3892 value
= s
->outputs
& ~s
->dir
;
3893 while ((ln
= ffs(diff
))) {
3896 qemu_set_irq(s
->handler
[ln
], (value
>> ln
) & 1);
3901 case 0x0c: /* INTERRUPT_CONTROL */
3905 case 0x10: /* INTERRUPT_MASK */
3909 case 0x14: /* INTERRUPT_STATUS */
3912 qemu_irq_lower(s
->irq
);
3915 case 0x18: /* PIN_CONTROL (not in OMAP310 TRM) */
3926 /* *Some* sources say the memory region is 32-bit. */
3927 static CPUReadMemoryFunc
*omap_gpio_readfn
[] = {
3928 omap_badwidth_read16
,
3930 omap_badwidth_read16
,
3933 static CPUWriteMemoryFunc
*omap_gpio_writefn
[] = {
3934 omap_badwidth_write16
,
3936 omap_badwidth_write16
,
3939 static void omap_gpio_reset(struct omap_gpio_s
*s
)
3950 struct omap_gpio_s
*omap_gpio_init(target_phys_addr_t base
,
3951 qemu_irq irq
, omap_clk clk
)
3954 struct omap_gpio_s
*s
= (struct omap_gpio_s
*)
3955 qemu_mallocz(sizeof(struct omap_gpio_s
));
3959 s
->in
= qemu_allocate_irqs(omap_gpio_set
, s
, 16);
3962 iomemtype
= cpu_register_io_memory(0, omap_gpio_readfn
,
3963 omap_gpio_writefn
, s
);
3964 cpu_register_physical_memory(s
->base
, 0x1000, iomemtype
);
3969 qemu_irq
*omap_gpio_in_get(struct omap_gpio_s
*s
)
3974 void omap_gpio_out_set(struct omap_gpio_s
*s
, int line
, qemu_irq handler
)
3976 if (line
>= 16 || line
< 0)
3977 cpu_abort(cpu_single_env
, "%s: No GPIO line %i\n", __FUNCTION__
, line
);
3978 s
->handler
[line
] = handler
;
3981 /* MicroWire Interface */
3982 struct omap_uwire_s
{
3983 target_phys_addr_t base
;
3993 struct uwire_slave_s
*chip
[4];
3996 static void omap_uwire_transfer_start(struct omap_uwire_s
*s
)
3998 int chipselect
= (s
->control
>> 10) & 3; /* INDEX */
3999 struct uwire_slave_s
*slave
= s
->chip
[chipselect
];
4001 if ((s
->control
>> 5) & 0x1f) { /* NB_BITS_WR */
4002 if (s
->control
& (1 << 12)) /* CS_CMD */
4003 if (slave
&& slave
->send
)
4004 slave
->send(slave
->opaque
,
4005 s
->txbuf
>> (16 - ((s
->control
>> 5) & 0x1f)));
4006 s
->control
&= ~(1 << 14); /* CSRB */
4007 /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
4008 * a DRQ. When is the level IRQ supposed to be reset? */
4011 if ((s
->control
>> 0) & 0x1f) { /* NB_BITS_RD */
4012 if (s
->control
& (1 << 12)) /* CS_CMD */
4013 if (slave
&& slave
->receive
)
4014 s
->rxbuf
= slave
->receive(slave
->opaque
);
4015 s
->control
|= 1 << 15; /* RDRB */
4016 /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
4017 * a DRQ. When is the level IRQ supposed to be reset? */
4021 static uint32_t omap_uwire_read(void *opaque
, target_phys_addr_t addr
)
4023 struct omap_uwire_s
*s
= (struct omap_uwire_s
*) opaque
;
4024 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4027 case 0x00: /* RDR */
4028 s
->control
&= ~(1 << 15); /* RDRB */
4031 case 0x04: /* CSR */
4034 case 0x08: /* SR1 */
4036 case 0x0c: /* SR2 */
4038 case 0x10: /* SR3 */
4040 case 0x14: /* SR4 */
4042 case 0x18: /* SR5 */
4050 static void omap_uwire_write(void *opaque
, target_phys_addr_t addr
,
4053 struct omap_uwire_s
*s
= (struct omap_uwire_s
*) opaque
;
4054 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4057 case 0x00: /* TDR */
4058 s
->txbuf
= value
; /* TD */
4059 if ((s
->setup
[4] & (1 << 2)) && /* AUTO_TX_EN */
4060 ((s
->setup
[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */
4061 (s
->control
& (1 << 12)))) { /* CS_CMD */
4062 s
->control
|= 1 << 14; /* CSRB */
4063 omap_uwire_transfer_start(s
);
4067 case 0x04: /* CSR */
4068 s
->control
= value
& 0x1fff;
4069 if (value
& (1 << 13)) /* START */
4070 omap_uwire_transfer_start(s
);
4073 case 0x08: /* SR1 */
4074 s
->setup
[0] = value
& 0x003f;
4077 case 0x0c: /* SR2 */
4078 s
->setup
[1] = value
& 0x0fc0;
4081 case 0x10: /* SR3 */
4082 s
->setup
[2] = value
& 0x0003;
4085 case 0x14: /* SR4 */
4086 s
->setup
[3] = value
& 0x0001;
4089 case 0x18: /* SR5 */
4090 s
->setup
[4] = value
& 0x000f;
4099 static CPUReadMemoryFunc
*omap_uwire_readfn
[] = {
4100 omap_badwidth_read16
,
4102 omap_badwidth_read16
,
4105 static CPUWriteMemoryFunc
*omap_uwire_writefn
[] = {
4106 omap_badwidth_write16
,
4108 omap_badwidth_write16
,
4111 static void omap_uwire_reset(struct omap_uwire_s
*s
)
4121 struct omap_uwire_s
*omap_uwire_init(target_phys_addr_t base
,
4122 qemu_irq
*irq
, qemu_irq dma
, omap_clk clk
)
4125 struct omap_uwire_s
*s
= (struct omap_uwire_s
*)
4126 qemu_mallocz(sizeof(struct omap_uwire_s
));
4132 omap_uwire_reset(s
);
4134 iomemtype
= cpu_register_io_memory(0, omap_uwire_readfn
,
4135 omap_uwire_writefn
, s
);
4136 cpu_register_physical_memory(s
->base
, 0x800, iomemtype
);
4141 void omap_uwire_attach(struct omap_uwire_s
*s
,
4142 struct uwire_slave_s
*slave
, int chipselect
)
4144 if (chipselect
< 0 || chipselect
> 3)
4145 cpu_abort(cpu_single_env
, "%s: Bad chipselect %i\n", __FUNCTION__
,
4148 s
->chip
[chipselect
] = slave
;
4151 /* Pseudonoise Pulse-Width Light Modulator */
4152 static void omap_pwl_update(struct omap_mpu_state_s
*s
)
4154 int output
= (s
->pwl
.clk
&& s
->pwl
.enable
) ? s
->pwl
.level
: 0;
4156 if (output
!= s
->pwl
.output
) {
4157 s
->pwl
.output
= output
;
4158 printf("%s: Backlight now at %i/256\n", __FUNCTION__
, output
);
4162 static uint32_t omap_pwl_read(void *opaque
, target_phys_addr_t addr
)
4164 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
4165 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4168 case 0x00: /* PWL_LEVEL */
4169 return s
->pwl
.level
;
4170 case 0x04: /* PWL_CTRL */
4171 return s
->pwl
.enable
;
4177 static void omap_pwl_write(void *opaque
, target_phys_addr_t addr
,
4180 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
4181 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4184 case 0x00: /* PWL_LEVEL */
4185 s
->pwl
.level
= value
;
4188 case 0x04: /* PWL_CTRL */
4189 s
->pwl
.enable
= value
& 1;
4198 static CPUReadMemoryFunc
*omap_pwl_readfn
[] = {
4200 omap_badwidth_read8
,
4201 omap_badwidth_read8
,
4204 static CPUWriteMemoryFunc
*omap_pwl_writefn
[] = {
4206 omap_badwidth_write8
,
4207 omap_badwidth_write8
,
4210 static void omap_pwl_reset(struct omap_mpu_state_s
*s
)
4219 static void omap_pwl_clk_update(void *opaque
, int line
, int on
)
4221 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
4227 static void omap_pwl_init(target_phys_addr_t base
, struct omap_mpu_state_s
*s
,
4234 iomemtype
= cpu_register_io_memory(0, omap_pwl_readfn
,
4235 omap_pwl_writefn
, s
);
4236 cpu_register_physical_memory(base
, 0x800, iomemtype
);
4238 omap_clk_adduser(clk
, qemu_allocate_irqs(omap_pwl_clk_update
, s
, 1)[0]);
4241 /* Pulse-Width Tone module */
4242 static uint32_t omap_pwt_read(void *opaque
, target_phys_addr_t addr
)
4244 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
4245 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4248 case 0x00: /* FRC */
4250 case 0x04: /* VCR */
4252 case 0x08: /* GCR */
4259 static void omap_pwt_write(void *opaque
, target_phys_addr_t addr
,
4262 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*) opaque
;
4263 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4266 case 0x00: /* FRC */
4267 s
->pwt
.frc
= value
& 0x3f;
4269 case 0x04: /* VRC */
4270 if ((value
^ s
->pwt
.vrc
) & 1) {
4272 printf("%s: %iHz buzz on\n", __FUNCTION__
, (int)
4273 /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
4274 ((omap_clk_getrate(s
->pwt
.clk
) >> 3) /
4275 /* Pre-multiplexer divider */
4276 ((s
->pwt
.gcr
& 2) ? 1 : 154) /
4277 /* Octave multiplexer */
4278 (2 << (value
& 3)) *
4279 /* 101/107 divider */
4280 ((value
& (1 << 2)) ? 101 : 107) *
4282 ((value
& (1 << 3)) ? 49 : 55) *
4284 ((value
& (1 << 4)) ? 50 : 63) *
4285 /* 80/127 divider */
4286 ((value
& (1 << 5)) ? 80 : 127) /
4287 (107 * 55 * 63 * 127)));
4289 printf("%s: silence!\n", __FUNCTION__
);
4291 s
->pwt
.vrc
= value
& 0x7f;
4293 case 0x08: /* GCR */
4294 s
->pwt
.gcr
= value
& 3;
4302 static CPUReadMemoryFunc
*omap_pwt_readfn
[] = {
4304 omap_badwidth_read8
,
4305 omap_badwidth_read8
,
4308 static CPUWriteMemoryFunc
*omap_pwt_writefn
[] = {
4310 omap_badwidth_write8
,
4311 omap_badwidth_write8
,
4314 static void omap_pwt_reset(struct omap_mpu_state_s
*s
)
4321 static void omap_pwt_init(target_phys_addr_t base
, struct omap_mpu_state_s
*s
,
4329 iomemtype
= cpu_register_io_memory(0, omap_pwt_readfn
,
4330 omap_pwt_writefn
, s
);
4331 cpu_register_physical_memory(base
, 0x800, iomemtype
);
4334 /* Real-time Clock module */
4336 target_phys_addr_t base
;
4348 struct tm
*(*convert
)(const time_t *timep
, struct tm
*result
);
4352 struct tm current_tm
;
4357 static void omap_rtc_interrupts_update(struct omap_rtc_s
*s
)
4359 /* s->alarm is level-triggered */
4360 qemu_set_irq(s
->alarm
, (s
->status
>> 6) & 1);
4363 static void omap_rtc_alarm_update(struct omap_rtc_s
*s
)
4365 s
->alarm_ti
= mktime(&s
->alarm_tm
);
4366 if (s
->alarm_ti
== -1)
4367 printf("%s: conversion failed\n", __FUNCTION__
);
4370 static inline uint8_t omap_rtc_bcd(int num
)
4372 return ((num
/ 10) << 4) | (num
% 10);
4375 static inline int omap_rtc_bin(uint8_t num
)
4377 return (num
& 15) + 10 * (num
>> 4);
4380 static uint32_t omap_rtc_read(void *opaque
, target_phys_addr_t addr
)
4382 struct omap_rtc_s
*s
= (struct omap_rtc_s
*) opaque
;
4383 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4387 case 0x00: /* SECONDS_REG */
4388 return omap_rtc_bcd(s
->current_tm
.tm_sec
);
4390 case 0x04: /* MINUTES_REG */
4391 return omap_rtc_bcd(s
->current_tm
.tm_min
);
4393 case 0x08: /* HOURS_REG */
4395 return ((s
->current_tm
.tm_hour
> 11) << 7) |
4396 omap_rtc_bcd(((s
->current_tm
.tm_hour
- 1) % 12) + 1);
4398 return omap_rtc_bcd(s
->current_tm
.tm_hour
);
4400 case 0x0c: /* DAYS_REG */
4401 return omap_rtc_bcd(s
->current_tm
.tm_mday
);
4403 case 0x10: /* MONTHS_REG */
4404 return omap_rtc_bcd(s
->current_tm
.tm_mon
+ 1);
4406 case 0x14: /* YEARS_REG */
4407 return omap_rtc_bcd(s
->current_tm
.tm_year
% 100);
4409 case 0x18: /* WEEK_REG */
4410 return s
->current_tm
.tm_wday
;
4412 case 0x20: /* ALARM_SECONDS_REG */
4413 return omap_rtc_bcd(s
->alarm_tm
.tm_sec
);
4415 case 0x24: /* ALARM_MINUTES_REG */
4416 return omap_rtc_bcd(s
->alarm_tm
.tm_min
);
4418 case 0x28: /* ALARM_HOURS_REG */
4420 return ((s
->alarm_tm
.tm_hour
> 11) << 7) |
4421 omap_rtc_bcd(((s
->alarm_tm
.tm_hour
- 1) % 12) + 1);
4423 return omap_rtc_bcd(s
->alarm_tm
.tm_hour
);
4425 case 0x2c: /* ALARM_DAYS_REG */
4426 return omap_rtc_bcd(s
->alarm_tm
.tm_mday
);
4428 case 0x30: /* ALARM_MONTHS_REG */
4429 return omap_rtc_bcd(s
->alarm_tm
.tm_mon
+ 1);
4431 case 0x34: /* ALARM_YEARS_REG */
4432 return omap_rtc_bcd(s
->alarm_tm
.tm_year
% 100);
4434 case 0x40: /* RTC_CTRL_REG */
4435 return (s
->pm_am
<< 3) | (s
->auto_comp
<< 2) |
4436 (s
->round
<< 1) | s
->running
;
4438 case 0x44: /* RTC_STATUS_REG */
4443 case 0x48: /* RTC_INTERRUPTS_REG */
4444 return s
->interrupts
;
4446 case 0x4c: /* RTC_COMP_LSB_REG */
4447 return ((uint16_t) s
->comp_reg
) & 0xff;
4449 case 0x50: /* RTC_COMP_MSB_REG */
4450 return ((uint16_t) s
->comp_reg
) >> 8;
4457 static void omap_rtc_write(void *opaque
, target_phys_addr_t addr
,
4460 struct omap_rtc_s
*s
= (struct omap_rtc_s
*) opaque
;
4461 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4466 case 0x00: /* SECONDS_REG */
4468 printf("RTC SEC_REG <-- %02x\n", value
);
4470 s
->ti
-= s
->current_tm
.tm_sec
;
4471 s
->ti
+= omap_rtc_bin(value
);
4474 case 0x04: /* MINUTES_REG */
4476 printf("RTC MIN_REG <-- %02x\n", value
);
4478 s
->ti
-= s
->current_tm
.tm_min
* 60;
4479 s
->ti
+= omap_rtc_bin(value
) * 60;
4482 case 0x08: /* HOURS_REG */
4484 printf("RTC HRS_REG <-- %02x\n", value
);
4486 s
->ti
-= s
->current_tm
.tm_hour
* 3600;
4488 s
->ti
+= (omap_rtc_bin(value
& 0x3f) & 12) * 3600;
4489 s
->ti
+= ((value
>> 7) & 1) * 43200;
4491 s
->ti
+= omap_rtc_bin(value
& 0x3f) * 3600;
4494 case 0x0c: /* DAYS_REG */
4496 printf("RTC DAY_REG <-- %02x\n", value
);
4498 s
->ti
-= s
->current_tm
.tm_mday
* 86400;
4499 s
->ti
+= omap_rtc_bin(value
) * 86400;
4502 case 0x10: /* MONTHS_REG */
4504 printf("RTC MTH_REG <-- %02x\n", value
);
4506 memcpy(&new_tm
, &s
->current_tm
, sizeof(new_tm
));
4507 new_tm
.tm_mon
= omap_rtc_bin(value
);
4508 ti
[0] = mktime(&s
->current_tm
);
4509 ti
[1] = mktime(&new_tm
);
4511 if (ti
[0] != -1 && ti
[1] != -1) {
4515 /* A less accurate version */
4516 s
->ti
-= s
->current_tm
.tm_mon
* 2592000;
4517 s
->ti
+= omap_rtc_bin(value
) * 2592000;
4521 case 0x14: /* YEARS_REG */
4523 printf("RTC YRS_REG <-- %02x\n", value
);
4525 memcpy(&new_tm
, &s
->current_tm
, sizeof(new_tm
));
4526 new_tm
.tm_year
+= omap_rtc_bin(value
) - (new_tm
.tm_year
% 100);
4527 ti
[0] = mktime(&s
->current_tm
);
4528 ti
[1] = mktime(&new_tm
);
4530 if (ti
[0] != -1 && ti
[1] != -1) {
4534 /* A less accurate version */
4535 s
->ti
-= (s
->current_tm
.tm_year
% 100) * 31536000;
4536 s
->ti
+= omap_rtc_bin(value
) * 31536000;
4540 case 0x18: /* WEEK_REG */
4541 return; /* Ignored */
4543 case 0x20: /* ALARM_SECONDS_REG */
4545 printf("ALM SEC_REG <-- %02x\n", value
);
4547 s
->alarm_tm
.tm_sec
= omap_rtc_bin(value
);
4548 omap_rtc_alarm_update(s
);
4551 case 0x24: /* ALARM_MINUTES_REG */
4553 printf("ALM MIN_REG <-- %02x\n", value
);
4555 s
->alarm_tm
.tm_min
= omap_rtc_bin(value
);
4556 omap_rtc_alarm_update(s
);
4559 case 0x28: /* ALARM_HOURS_REG */
4561 printf("ALM HRS_REG <-- %02x\n", value
);
4564 s
->alarm_tm
.tm_hour
=
4565 ((omap_rtc_bin(value
& 0x3f)) % 12) +
4566 ((value
>> 7) & 1) * 12;
4568 s
->alarm_tm
.tm_hour
= omap_rtc_bin(value
);
4569 omap_rtc_alarm_update(s
);
4572 case 0x2c: /* ALARM_DAYS_REG */
4574 printf("ALM DAY_REG <-- %02x\n", value
);
4576 s
->alarm_tm
.tm_mday
= omap_rtc_bin(value
);
4577 omap_rtc_alarm_update(s
);
4580 case 0x30: /* ALARM_MONTHS_REG */
4582 printf("ALM MON_REG <-- %02x\n", value
);
4584 s
->alarm_tm
.tm_mon
= omap_rtc_bin(value
);
4585 omap_rtc_alarm_update(s
);
4588 case 0x34: /* ALARM_YEARS_REG */
4590 printf("ALM YRS_REG <-- %02x\n", value
);
4592 s
->alarm_tm
.tm_year
= omap_rtc_bin(value
);
4593 omap_rtc_alarm_update(s
);
4596 case 0x40: /* RTC_CTRL_REG */
4598 printf("RTC CONTROL <-- %02x\n", value
);
4600 s
->pm_am
= (value
>> 3) & 1;
4601 s
->auto_comp
= (value
>> 2) & 1;
4602 s
->round
= (value
>> 1) & 1;
4603 s
->running
= value
& 1;
4605 s
->status
|= s
->running
<< 1;
4608 case 0x44: /* RTC_STATUS_REG */
4610 printf("RTC STATUSL <-- %02x\n", value
);
4612 s
->status
&= ~((value
& 0xc0) ^ 0x80);
4613 omap_rtc_interrupts_update(s
);
4616 case 0x48: /* RTC_INTERRUPTS_REG */
4618 printf("RTC INTRS <-- %02x\n", value
);
4620 s
->interrupts
= value
;
4623 case 0x4c: /* RTC_COMP_LSB_REG */
4625 printf("RTC COMPLSB <-- %02x\n", value
);
4627 s
->comp_reg
&= 0xff00;
4628 s
->comp_reg
|= 0x00ff & value
;
4631 case 0x50: /* RTC_COMP_MSB_REG */
4633 printf("RTC COMPMSB <-- %02x\n", value
);
4635 s
->comp_reg
&= 0x00ff;
4636 s
->comp_reg
|= 0xff00 & (value
<< 8);
4645 static CPUReadMemoryFunc
*omap_rtc_readfn
[] = {
4647 omap_badwidth_read8
,
4648 omap_badwidth_read8
,
4651 static CPUWriteMemoryFunc
*omap_rtc_writefn
[] = {
4653 omap_badwidth_write8
,
4654 omap_badwidth_write8
,
4657 static void omap_rtc_tick(void *opaque
)
4659 struct omap_rtc_s
*s
= opaque
;
4662 /* Round to nearest full minute. */
4663 if (s
->current_tm
.tm_sec
< 30)
4664 s
->ti
-= s
->current_tm
.tm_sec
;
4666 s
->ti
+= 60 - s
->current_tm
.tm_sec
;
4671 localtime_r(&s
->ti
, &s
->current_tm
);
4673 if ((s
->interrupts
& 0x08) && s
->ti
== s
->alarm_ti
) {
4675 omap_rtc_interrupts_update(s
);
4678 if (s
->interrupts
& 0x04)
4679 switch (s
->interrupts
& 3) {
4682 qemu_irq_pulse(s
->irq
);
4685 if (s
->current_tm
.tm_sec
)
4688 qemu_irq_pulse(s
->irq
);
4691 if (s
->current_tm
.tm_sec
|| s
->current_tm
.tm_min
)
4694 qemu_irq_pulse(s
->irq
);
4697 if (s
->current_tm
.tm_sec
||
4698 s
->current_tm
.tm_min
|| s
->current_tm
.tm_hour
)
4701 qemu_irq_pulse(s
->irq
);
4711 * Every full hour add a rough approximation of the compensation
4712 * register to the 32kHz Timer (which drives the RTC) value.
4714 if (s
->auto_comp
&& !s
->current_tm
.tm_sec
&& !s
->current_tm
.tm_min
)
4715 s
->tick
+= s
->comp_reg
* 1000 / 32768;
4717 qemu_mod_timer(s
->clk
, s
->tick
);
4720 static void omap_rtc_reset(struct omap_rtc_s
*s
)
4728 s
->tick
= qemu_get_clock(rt_clock
);
4729 memset(&s
->alarm_tm
, 0, sizeof(s
->alarm_tm
));
4730 s
->alarm_tm
.tm_mday
= 0x01;
4733 s
->ti
= mktime(s
->convert(&s
->ti
, &s
->current_tm
));
4735 omap_rtc_alarm_update(s
);
4739 struct omap_rtc_s
*omap_rtc_init(target_phys_addr_t base
,
4740 qemu_irq
*irq
, omap_clk clk
)
4743 struct omap_rtc_s
*s
= (struct omap_rtc_s
*)
4744 qemu_mallocz(sizeof(struct omap_rtc_s
));
4749 s
->clk
= qemu_new_timer(rt_clock
, omap_rtc_tick
, s
);
4750 s
->convert
= rtc_utc
? gmtime_r
: localtime_r
;
4754 iomemtype
= cpu_register_io_memory(0, omap_rtc_readfn
,
4755 omap_rtc_writefn
, s
);
4756 cpu_register_physical_memory(s
->base
, 0x800, iomemtype
);
4761 /* Multi-channel Buffered Serial Port interfaces */
4762 struct omap_mcbsp_s
{
4763 target_phys_addr_t base
;
4782 struct i2s_codec_s
*codec
;
4783 QEMUTimer
*source_timer
;
4784 QEMUTimer
*sink_timer
;
4787 static void omap_mcbsp_intr_update(struct omap_mcbsp_s
*s
)
4791 switch ((s
->spcr
[0] >> 4) & 3) { /* RINTM */
4793 irq
= (s
->spcr
[0] >> 1) & 1; /* RRDY */
4796 irq
= (s
->spcr
[0] >> 3) & 1; /* RSYNCERR */
4804 qemu_irq_pulse(s
->rxirq
);
4806 switch ((s
->spcr
[1] >> 4) & 3) { /* XINTM */
4808 irq
= (s
->spcr
[1] >> 1) & 1; /* XRDY */
4811 irq
= (s
->spcr
[1] >> 3) & 1; /* XSYNCERR */
4819 qemu_irq_pulse(s
->txirq
);
4822 static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s
*s
)
4824 if ((s
->spcr
[0] >> 1) & 1) /* RRDY */
4825 s
->spcr
[0] |= 1 << 2; /* RFULL */
4826 s
->spcr
[0] |= 1 << 1; /* RRDY */
4827 qemu_irq_raise(s
->rxdrq
);
4828 omap_mcbsp_intr_update(s
);
4831 static void omap_mcbsp_source_tick(void *opaque
)
4833 struct omap_mcbsp_s
*s
= (struct omap_mcbsp_s
*) opaque
;
4834 static const int bps
[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
4839 printf("%s: Rx FIFO overrun\n", __FUNCTION__
);
4841 s
->rx_req
= s
->rx_rate
<< bps
[(s
->rcr
[0] >> 5) & 7];
4843 omap_mcbsp_rx_newdata(s
);
4844 qemu_mod_timer(s
->source_timer
, qemu_get_clock(vm_clock
) + ticks_per_sec
);
4847 static void omap_mcbsp_rx_start(struct omap_mcbsp_s
*s
)
4849 if (!s
->codec
|| !s
->codec
->rts
)
4850 omap_mcbsp_source_tick(s
);
4851 else if (s
->codec
->in
.len
) {
4852 s
->rx_req
= s
->codec
->in
.len
;
4853 omap_mcbsp_rx_newdata(s
);
4857 static void omap_mcbsp_rx_stop(struct omap_mcbsp_s
*s
)
4859 qemu_del_timer(s
->source_timer
);
4862 static void omap_mcbsp_rx_done(struct omap_mcbsp_s
*s
)
4864 s
->spcr
[0] &= ~(1 << 1); /* RRDY */
4865 qemu_irq_lower(s
->rxdrq
);
4866 omap_mcbsp_intr_update(s
);
4869 static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s
*s
)
4871 s
->spcr
[1] |= 1 << 1; /* XRDY */
4872 qemu_irq_raise(s
->txdrq
);
4873 omap_mcbsp_intr_update(s
);
4876 static void omap_mcbsp_sink_tick(void *opaque
)
4878 struct omap_mcbsp_s
*s
= (struct omap_mcbsp_s
*) opaque
;
4879 static const int bps
[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
4884 printf("%s: Tx FIFO underrun\n", __FUNCTION__
);
4886 s
->tx_req
= s
->tx_rate
<< bps
[(s
->xcr
[0] >> 5) & 7];
4888 omap_mcbsp_tx_newdata(s
);
4889 qemu_mod_timer(s
->sink_timer
, qemu_get_clock(vm_clock
) + ticks_per_sec
);
4892 static void omap_mcbsp_tx_start(struct omap_mcbsp_s
*s
)
4894 if (!s
->codec
|| !s
->codec
->cts
)
4895 omap_mcbsp_sink_tick(s
);
4896 else if (s
->codec
->out
.size
) {
4897 s
->tx_req
= s
->codec
->out
.size
;
4898 omap_mcbsp_tx_newdata(s
);
4902 static void omap_mcbsp_tx_done(struct omap_mcbsp_s
*s
)
4904 s
->spcr
[1] &= ~(1 << 1); /* XRDY */
4905 qemu_irq_lower(s
->txdrq
);
4906 omap_mcbsp_intr_update(s
);
4907 if (s
->codec
&& s
->codec
->cts
)
4908 s
->codec
->tx_swallow(s
->codec
->opaque
);
4911 static void omap_mcbsp_tx_stop(struct omap_mcbsp_s
*s
)
4914 omap_mcbsp_tx_done(s
);
4915 qemu_del_timer(s
->sink_timer
);
4918 static void omap_mcbsp_req_update(struct omap_mcbsp_s
*s
)
4920 int prev_rx_rate
, prev_tx_rate
;
4921 int rx_rate
= 0, tx_rate
= 0;
4922 int cpu_rate
= 1500000; /* XXX */
4924 /* TODO: check CLKSTP bit */
4925 if (s
->spcr
[1] & (1 << 6)) { /* GRST */
4926 if (s
->spcr
[0] & (1 << 0)) { /* RRST */
4927 if ((s
->srgr
[1] & (1 << 13)) && /* CLKSM */
4928 (s
->pcr
& (1 << 8))) { /* CLKRM */
4929 if (~s
->pcr
& (1 << 7)) /* SCLKME */
4930 rx_rate
= cpu_rate
/
4931 ((s
->srgr
[0] & 0xff) + 1); /* CLKGDV */
4934 rx_rate
= s
->codec
->rx_rate
;
4937 if (s
->spcr
[1] & (1 << 0)) { /* XRST */
4938 if ((s
->srgr
[1] & (1 << 13)) && /* CLKSM */
4939 (s
->pcr
& (1 << 9))) { /* CLKXM */
4940 if (~s
->pcr
& (1 << 7)) /* SCLKME */
4941 tx_rate
= cpu_rate
/
4942 ((s
->srgr
[0] & 0xff) + 1); /* CLKGDV */
4945 tx_rate
= s
->codec
->tx_rate
;
4948 prev_tx_rate
= s
->tx_rate
;
4949 prev_rx_rate
= s
->rx_rate
;
4950 s
->tx_rate
= tx_rate
;
4951 s
->rx_rate
= rx_rate
;
4954 s
->codec
->set_rate(s
->codec
->opaque
, rx_rate
, tx_rate
);
4956 if (!prev_tx_rate
&& tx_rate
)
4957 omap_mcbsp_tx_start(s
);
4958 else if (s
->tx_rate
&& !tx_rate
)
4959 omap_mcbsp_tx_stop(s
);
4961 if (!prev_rx_rate
&& rx_rate
)
4962 omap_mcbsp_rx_start(s
);
4963 else if (prev_tx_rate
&& !tx_rate
)
4964 omap_mcbsp_rx_stop(s
);
4967 static uint32_t omap_mcbsp_read(void *opaque
, target_phys_addr_t addr
)
4969 struct omap_mcbsp_s
*s
= (struct omap_mcbsp_s
*) opaque
;
4970 int offset
= addr
& OMAP_MPUI_REG_MASK
;
4974 case 0x00: /* DRR2 */
4975 if (((s
->rcr
[0] >> 5) & 7) < 3) /* RWDLEN1 */
4978 case 0x02: /* DRR1 */
4979 if (s
->rx_req
< 2) {
4980 printf("%s: Rx FIFO underrun\n", __FUNCTION__
);
4981 omap_mcbsp_rx_done(s
);
4984 if (s
->codec
&& s
->codec
->in
.len
>= 2) {
4985 ret
= s
->codec
->in
.fifo
[s
->codec
->in
.start
++] << 8;
4986 ret
|= s
->codec
->in
.fifo
[s
->codec
->in
.start
++];
4987 s
->codec
->in
.len
-= 2;
4991 omap_mcbsp_rx_done(s
);
4996 case 0x04: /* DXR2 */
4997 case 0x06: /* DXR1 */
5000 case 0x08: /* SPCR2 */
5002 case 0x0a: /* SPCR1 */
5004 case 0x0c: /* RCR2 */
5006 case 0x0e: /* RCR1 */
5008 case 0x10: /* XCR2 */
5010 case 0x12: /* XCR1 */
5012 case 0x14: /* SRGR2 */
5014 case 0x16: /* SRGR1 */
5016 case 0x18: /* MCR2 */
5018 case 0x1a: /* MCR1 */
5020 case 0x1c: /* RCERA */
5022 case 0x1e: /* RCERB */
5024 case 0x20: /* XCERA */
5026 case 0x22: /* XCERB */
5028 case 0x24: /* PCR0 */
5030 case 0x26: /* RCERC */
5032 case 0x28: /* RCERD */
5034 case 0x2a: /* XCERC */
5036 case 0x2c: /* XCERD */
5038 case 0x2e: /* RCERE */
5040 case 0x30: /* RCERF */
5042 case 0x32: /* XCERE */
5044 case 0x34: /* XCERF */
5046 case 0x36: /* RCERG */
5048 case 0x38: /* RCERH */
5050 case 0x3a: /* XCERG */
5052 case 0x3c: /* XCERH */
5060 static void omap_mcbsp_writeh(void *opaque
, target_phys_addr_t addr
,
5063 struct omap_mcbsp_s
*s
= (struct omap_mcbsp_s
*) opaque
;
5064 int offset
= addr
& OMAP_MPUI_REG_MASK
;
5067 case 0x00: /* DRR2 */
5068 case 0x02: /* DRR1 */
5072 case 0x04: /* DXR2 */
5073 if (((s
->xcr
[0] >> 5) & 7) < 3) /* XWDLEN1 */
5076 case 0x06: /* DXR1 */
5077 if (s
->tx_req
> 1) {
5079 if (s
->codec
&& s
->codec
->cts
) {
5080 s
->codec
->out
.fifo
[s
->codec
->out
.len
++] = (value
>> 8) & 0xff;
5081 s
->codec
->out
.fifo
[s
->codec
->out
.len
++] = (value
>> 0) & 0xff;
5084 omap_mcbsp_tx_done(s
);
5086 printf("%s: Tx FIFO overrun\n", __FUNCTION__
);
5089 case 0x08: /* SPCR2 */
5090 s
->spcr
[1] &= 0x0002;
5091 s
->spcr
[1] |= 0x03f9 & value
;
5092 s
->spcr
[1] |= 0x0004 & (value
<< 2); /* XEMPTY := XRST */
5093 if (~value
& 1) /* XRST */
5095 omap_mcbsp_req_update(s
);
5097 case 0x0a: /* SPCR1 */
5098 s
->spcr
[0] &= 0x0006;
5099 s
->spcr
[0] |= 0xf8f9 & value
;
5100 if (value
& (1 << 15)) /* DLB */
5101 printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__
);
5102 if (~value
& 1) { /* RRST */
5105 omap_mcbsp_rx_done(s
);
5107 omap_mcbsp_req_update(s
);
5110 case 0x0c: /* RCR2 */
5111 s
->rcr
[1] = value
& 0xffff;
5113 case 0x0e: /* RCR1 */
5114 s
->rcr
[0] = value
& 0x7fe0;
5116 case 0x10: /* XCR2 */
5117 s
->xcr
[1] = value
& 0xffff;
5119 case 0x12: /* XCR1 */
5120 s
->xcr
[0] = value
& 0x7fe0;
5122 case 0x14: /* SRGR2 */
5123 s
->srgr
[1] = value
& 0xffff;
5124 omap_mcbsp_req_update(s
);
5126 case 0x16: /* SRGR1 */
5127 s
->srgr
[0] = value
& 0xffff;
5128 omap_mcbsp_req_update(s
);
5130 case 0x18: /* MCR2 */
5131 s
->mcr
[1] = value
& 0x03e3;
5132 if (value
& 3) /* XMCM */
5133 printf("%s: Tx channel selection mode enable attempt\n",
5136 case 0x1a: /* MCR1 */
5137 s
->mcr
[0] = value
& 0x03e1;
5138 if (value
& 1) /* RMCM */
5139 printf("%s: Rx channel selection mode enable attempt\n",
5142 case 0x1c: /* RCERA */
5143 s
->rcer
[0] = value
& 0xffff;
5145 case 0x1e: /* RCERB */
5146 s
->rcer
[1] = value
& 0xffff;
5148 case 0x20: /* XCERA */
5149 s
->xcer
[0] = value
& 0xffff;
5151 case 0x22: /* XCERB */
5152 s
->xcer
[1] = value
& 0xffff;
5154 case 0x24: /* PCR0 */
5155 s
->pcr
= value
& 0x7faf;
5157 case 0x26: /* RCERC */
5158 s
->rcer
[2] = value
& 0xffff;
5160 case 0x28: /* RCERD */
5161 s
->rcer
[3] = value
& 0xffff;
5163 case 0x2a: /* XCERC */
5164 s
->xcer
[2] = value
& 0xffff;
5166 case 0x2c: /* XCERD */
5167 s
->xcer
[3] = value
& 0xffff;
5169 case 0x2e: /* RCERE */
5170 s
->rcer
[4] = value
& 0xffff;
5172 case 0x30: /* RCERF */
5173 s
->rcer
[5] = value
& 0xffff;
5175 case 0x32: /* XCERE */
5176 s
->xcer
[4] = value
& 0xffff;
5178 case 0x34: /* XCERF */
5179 s
->xcer
[5] = value
& 0xffff;
5181 case 0x36: /* RCERG */
5182 s
->rcer
[6] = value
& 0xffff;
5184 case 0x38: /* RCERH */
5185 s
->rcer
[7] = value
& 0xffff;
5187 case 0x3a: /* XCERG */
5188 s
->xcer
[6] = value
& 0xffff;
5190 case 0x3c: /* XCERH */
5191 s
->xcer
[7] = value
& 0xffff;
5198 static void omap_mcbsp_writew(void *opaque
, target_phys_addr_t addr
,
5201 struct omap_mcbsp_s
*s
= (struct omap_mcbsp_s
*) opaque
;
5202 int offset
= addr
& OMAP_MPUI_REG_MASK
;
5204 if (offset
== 0x04) { /* DXR */
5205 if (((s
->xcr
[0] >> 5) & 7) < 3) /* XWDLEN1 */
5207 if (s
->tx_req
> 3) {
5209 if (s
->codec
&& s
->codec
->cts
) {
5210 s
->codec
->out
.fifo
[s
->codec
->out
.len
++] =
5211 (value
>> 24) & 0xff;
5212 s
->codec
->out
.fifo
[s
->codec
->out
.len
++] =
5213 (value
>> 16) & 0xff;
5214 s
->codec
->out
.fifo
[s
->codec
->out
.len
++] =
5215 (value
>> 8) & 0xff;
5216 s
->codec
->out
.fifo
[s
->codec
->out
.len
++] =
5217 (value
>> 0) & 0xff;
5220 omap_mcbsp_tx_done(s
);
5222 printf("%s: Tx FIFO overrun\n", __FUNCTION__
);
5226 omap_badwidth_write16(opaque
, addr
, value
);
5229 static CPUReadMemoryFunc
*omap_mcbsp_readfn
[] = {
5230 omap_badwidth_read16
,
5232 omap_badwidth_read16
,
5235 static CPUWriteMemoryFunc
*omap_mcbsp_writefn
[] = {
5236 omap_badwidth_write16
,
5241 static void omap_mcbsp_reset(struct omap_mcbsp_s
*s
)
5243 memset(&s
->spcr
, 0, sizeof(s
->spcr
));
5244 memset(&s
->rcr
, 0, sizeof(s
->rcr
));
5245 memset(&s
->xcr
, 0, sizeof(s
->xcr
));
5246 s
->srgr
[0] = 0x0001;
5247 s
->srgr
[1] = 0x2000;
5248 memset(&s
->mcr
, 0, sizeof(s
->mcr
));
5249 memset(&s
->pcr
, 0, sizeof(s
->pcr
));
5250 memset(&s
->rcer
, 0, sizeof(s
->rcer
));
5251 memset(&s
->xcer
, 0, sizeof(s
->xcer
));
5256 qemu_del_timer(s
->source_timer
);
5257 qemu_del_timer(s
->sink_timer
);
5260 struct omap_mcbsp_s
*omap_mcbsp_init(target_phys_addr_t base
,
5261 qemu_irq
*irq
, qemu_irq
*dma
, omap_clk clk
)
5264 struct omap_mcbsp_s
*s
= (struct omap_mcbsp_s
*)
5265 qemu_mallocz(sizeof(struct omap_mcbsp_s
));
5272 s
->sink_timer
= qemu_new_timer(vm_clock
, omap_mcbsp_sink_tick
, s
);
5273 s
->source_timer
= qemu_new_timer(vm_clock
, omap_mcbsp_source_tick
, s
);
5274 omap_mcbsp_reset(s
);
5276 iomemtype
= cpu_register_io_memory(0, omap_mcbsp_readfn
,
5277 omap_mcbsp_writefn
, s
);
5278 cpu_register_physical_memory(s
->base
, 0x800, iomemtype
);
5283 static void omap_mcbsp_i2s_swallow(void *opaque
, int line
, int level
)
5285 struct omap_mcbsp_s
*s
= (struct omap_mcbsp_s
*) opaque
;
5288 s
->rx_req
= s
->codec
->in
.len
;
5289 omap_mcbsp_rx_newdata(s
);
5293 static void omap_mcbsp_i2s_start(void *opaque
, int line
, int level
)
5295 struct omap_mcbsp_s
*s
= (struct omap_mcbsp_s
*) opaque
;
5298 s
->tx_req
= s
->codec
->out
.size
;
5299 omap_mcbsp_tx_newdata(s
);
5303 void omap_mcbsp_i2s_attach(struct omap_mcbsp_s
*s
, struct i2s_codec_s
*slave
)
5306 slave
->rx_swallow
= qemu_allocate_irqs(omap_mcbsp_i2s_swallow
, s
, 1)[0];
5307 slave
->tx_start
= qemu_allocate_irqs(omap_mcbsp_i2s_start
, s
, 1)[0];
5310 /* LED Pulse Generators */
5312 target_phys_addr_t base
;
5323 static void omap_lpg_tick(void *opaque
)
5325 struct omap_lpg_s
*s
= opaque
;
5328 qemu_mod_timer(s
->tm
, qemu_get_clock(rt_clock
) + s
->period
- s
->on
);
5330 qemu_mod_timer(s
->tm
, qemu_get_clock(rt_clock
) + s
->on
);
5332 s
->cycle
= !s
->cycle
;
5333 printf("%s: LED is %s\n", __FUNCTION__
, s
->cycle
? "on" : "off");
5336 static void omap_lpg_update(struct omap_lpg_s
*s
)
5338 int64_t on
, period
= 1, ticks
= 1000;
5339 static const int per
[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
5341 if (~s
->control
& (1 << 6)) /* LPGRES */
5343 else if (s
->control
& (1 << 7)) /* PERM_ON */
5346 period
= muldiv64(ticks
, per
[s
->control
& 7], /* PERCTRL */
5348 on
= (s
->clk
&& s
->power
) ? muldiv64(ticks
,
5349 per
[(s
->control
>> 3) & 7], 256) : 0; /* ONCTRL */
5352 qemu_del_timer(s
->tm
);
5353 if (on
== period
&& s
->on
< s
->period
)
5354 printf("%s: LED is on\n", __FUNCTION__
);
5355 else if (on
== 0 && s
->on
)
5356 printf("%s: LED is off\n", __FUNCTION__
);
5357 else if (on
&& (on
!= s
->on
|| period
!= s
->period
)) {
5369 static void omap_lpg_reset(struct omap_lpg_s
*s
)
5377 static uint32_t omap_lpg_read(void *opaque
, target_phys_addr_t addr
)
5379 struct omap_lpg_s
*s
= (struct omap_lpg_s
*) opaque
;
5380 int offset
= addr
& OMAP_MPUI_REG_MASK
;
5383 case 0x00: /* LCR */
5386 case 0x04: /* PMR */
5394 static void omap_lpg_write(void *opaque
, target_phys_addr_t addr
,
5397 struct omap_lpg_s
*s
= (struct omap_lpg_s
*) opaque
;
5398 int offset
= addr
& OMAP_MPUI_REG_MASK
;
5401 case 0x00: /* LCR */
5402 if (~value
& (1 << 6)) /* LPGRES */
5404 s
->control
= value
& 0xff;
5408 case 0x04: /* PMR */
5409 s
->power
= value
& 0x01;
5419 static CPUReadMemoryFunc
*omap_lpg_readfn
[] = {
5421 omap_badwidth_read8
,
5422 omap_badwidth_read8
,
5425 static CPUWriteMemoryFunc
*omap_lpg_writefn
[] = {
5427 omap_badwidth_write8
,
5428 omap_badwidth_write8
,
5431 static void omap_lpg_clk_update(void *opaque
, int line
, int on
)
5433 struct omap_lpg_s
*s
= (struct omap_lpg_s
*) opaque
;
5439 struct omap_lpg_s
*omap_lpg_init(target_phys_addr_t base
, omap_clk clk
)
5442 struct omap_lpg_s
*s
= (struct omap_lpg_s
*)
5443 qemu_mallocz(sizeof(struct omap_lpg_s
));
5446 s
->tm
= qemu_new_timer(rt_clock
, omap_lpg_tick
, s
);
5450 iomemtype
= cpu_register_io_memory(0, omap_lpg_readfn
,
5451 omap_lpg_writefn
, s
);
5452 cpu_register_physical_memory(s
->base
, 0x800, iomemtype
);
5454 omap_clk_adduser(clk
, qemu_allocate_irqs(omap_lpg_clk_update
, s
, 1)[0]);
5459 /* MPUI Peripheral Bridge configuration */
5460 static uint32_t omap_mpui_io_read(void *opaque
, target_phys_addr_t addr
)
5462 if (addr
== OMAP_MPUI_BASE
) /* CMR */
5469 static CPUReadMemoryFunc
*omap_mpui_io_readfn
[] = {
5470 omap_badwidth_read16
,
5472 omap_badwidth_read16
,
5475 static CPUWriteMemoryFunc
*omap_mpui_io_writefn
[] = {
5476 omap_badwidth_write16
,
5477 omap_badwidth_write16
,
5478 omap_badwidth_write16
,
5481 static void omap_setup_mpui_io(struct omap_mpu_state_s
*mpu
)
5483 int iomemtype
= cpu_register_io_memory(0, omap_mpui_io_readfn
,
5484 omap_mpui_io_writefn
, mpu
);
5485 cpu_register_physical_memory(OMAP_MPUI_BASE
, 0x7fff, iomemtype
);
5488 /* General chip reset */
5489 static void omap_mpu_reset(void *opaque
)
5491 struct omap_mpu_state_s
*mpu
= (struct omap_mpu_state_s
*) opaque
;
5493 omap_inth_reset(mpu
->ih
[0]);
5494 omap_inth_reset(mpu
->ih
[1]);
5495 omap_dma_reset(mpu
->dma
);
5496 omap_mpu_timer_reset(mpu
->timer
[0]);
5497 omap_mpu_timer_reset(mpu
->timer
[1]);
5498 omap_mpu_timer_reset(mpu
->timer
[2]);
5499 omap_wd_timer_reset(mpu
->wdt
);
5500 omap_os_timer_reset(mpu
->os_timer
);
5501 omap_lcdc_reset(mpu
->lcd
);
5502 omap_ulpd_pm_reset(mpu
);
5503 omap_pin_cfg_reset(mpu
);
5504 omap_mpui_reset(mpu
);
5505 omap_tipb_bridge_reset(mpu
->private_tipb
);
5506 omap_tipb_bridge_reset(mpu
->public_tipb
);
5507 omap_dpll_reset(&mpu
->dpll
[0]);
5508 omap_dpll_reset(&mpu
->dpll
[1]);
5509 omap_dpll_reset(&mpu
->dpll
[2]);
5510 omap_uart_reset(mpu
->uart
[0]);
5511 omap_uart_reset(mpu
->uart
[1]);
5512 omap_uart_reset(mpu
->uart
[2]);
5513 omap_mmc_reset(mpu
->mmc
);
5514 omap_mpuio_reset(mpu
->mpuio
);
5515 omap_gpio_reset(mpu
->gpio
);
5516 omap_uwire_reset(mpu
->microwire
);
5517 omap_pwl_reset(mpu
);
5518 omap_pwt_reset(mpu
);
5519 omap_i2c_reset(mpu
->i2c
);
5520 omap_rtc_reset(mpu
->rtc
);
5521 omap_mcbsp_reset(mpu
->mcbsp1
);
5522 omap_mcbsp_reset(mpu
->mcbsp2
);
5523 omap_mcbsp_reset(mpu
->mcbsp3
);
5524 omap_lpg_reset(mpu
->led
[0]);
5525 omap_lpg_reset(mpu
->led
[1]);
5526 omap_clkm_reset(mpu
);
5527 cpu_reset(mpu
->env
);
5530 static const struct omap_map_s
{
5531 target_phys_addr_t phys_dsp
;
5532 target_phys_addr_t phys_mpu
;
5535 } omap15xx_dsp_mm
[] = {
5537 { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" }, /* CS0 */
5538 { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" }, /* CS1 */
5539 { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" }, /* CS3 */
5540 { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" }, /* CS4 */
5541 { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" }, /* CS5 */
5542 { 0xe1013000, 0xfffb3000, 0x800, "uWire" }, /* CS6 */
5543 { 0xe1013800, 0xfffb3800, 0x800, "I^2C" }, /* CS7 */
5544 { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" }, /* CS8 */
5545 { 0xe1014800, 0xfffb4800, 0x800, "RTC" }, /* CS9 */
5546 { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" }, /* CS10 */
5547 { 0xe1015800, 0xfffb5800, 0x800, "PWL" }, /* CS11 */
5548 { 0xe1016000, 0xfffb6000, 0x800, "PWT" }, /* CS12 */
5549 { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" }, /* CS14 */
5550 { 0xe1017800, 0xfffb7800, 0x800, "MMC" }, /* CS15 */
5551 { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" }, /* CS18 */
5552 { 0xe1019800, 0xfffb9800, 0x800, "UART3" }, /* CS19 */
5553 { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" }, /* CS25 */
5555 { 0xe101e000, 0xfffce000, 0x800, "GPIOs" }, /* CS28 */
5560 static void omap_setup_dsp_mapping(const struct omap_map_s
*map
)
5564 for (; map
->phys_dsp
; map
++) {
5565 io
= cpu_get_physical_page_desc(map
->phys_mpu
);
5567 cpu_register_physical_memory(map
->phys_dsp
, map
->size
, io
);
5571 static void omap_mpu_wakeup(void *opaque
, int irq
, int req
)
5573 struct omap_mpu_state_s
*mpu
= (struct omap_mpu_state_s
*) opaque
;
5575 if (mpu
->env
->halted
)
5576 cpu_interrupt(mpu
->env
, CPU_INTERRUPT_EXITTB
);
5579 struct dma_irq_map
{
5584 static const struct dma_irq_map omap_dma_irq_map
[] = {
5585 { 0, OMAP_INT_DMA_CH0_6
},
5586 { 0, OMAP_INT_DMA_CH1_7
},
5587 { 0, OMAP_INT_DMA_CH2_8
},
5588 { 0, OMAP_INT_DMA_CH3
},
5589 { 0, OMAP_INT_DMA_CH4
},
5590 { 0, OMAP_INT_DMA_CH5
},
5591 { 1, OMAP_INT_1610_DMA_CH6
},
5592 { 1, OMAP_INT_1610_DMA_CH7
},
5593 { 1, OMAP_INT_1610_DMA_CH8
},
5594 { 1, OMAP_INT_1610_DMA_CH9
},
5595 { 1, OMAP_INT_1610_DMA_CH10
},
5596 { 1, OMAP_INT_1610_DMA_CH11
},
5597 { 1, OMAP_INT_1610_DMA_CH12
},
5598 { 1, OMAP_INT_1610_DMA_CH13
},
5599 { 1, OMAP_INT_1610_DMA_CH14
},
5600 { 1, OMAP_INT_1610_DMA_CH15
}
5603 struct omap_mpu_state_s
*omap310_mpu_init(unsigned long sdram_size
,
5604 DisplayState
*ds
, const char *core
)
5607 struct omap_mpu_state_s
*s
= (struct omap_mpu_state_s
*)
5608 qemu_mallocz(sizeof(struct omap_mpu_state_s
));
5609 ram_addr_t imif_base
, emiff_base
;
5611 qemu_irq dma_irqs
[6];
5618 s
->mpu_model
= omap310
;
5619 s
->env
= cpu_init(core
);
5621 fprintf(stderr
, "Unable to find CPU definition\n");
5624 s
->sdram_size
= sdram_size
;
5625 s
->sram_size
= OMAP15XX_SRAM_SIZE
;
5627 s
->wakeup
= qemu_allocate_irqs(omap_mpu_wakeup
, s
, 1)[0];
5632 /* Memory-mapped stuff */
5633 cpu_register_physical_memory(OMAP_EMIFF_BASE
, s
->sdram_size
,
5634 (emiff_base
= qemu_ram_alloc(s
->sdram_size
)) | IO_MEM_RAM
);
5635 cpu_register_physical_memory(OMAP_IMIF_BASE
, s
->sram_size
,
5636 (imif_base
= qemu_ram_alloc(s
->sram_size
)) | IO_MEM_RAM
);
5638 omap_clkm_init(0xfffece00, 0xe1008000, s
);
5640 cpu_irq
= arm_pic_init_cpu(s
->env
);
5641 s
->ih
[0] = omap_inth_init(0xfffecb00, 0x100, 1,
5642 cpu_irq
[ARM_PIC_CPU_IRQ
], cpu_irq
[ARM_PIC_CPU_FIQ
],
5643 omap_findclk(s
, "arminth_ck"));
5644 s
->ih
[1] = omap_inth_init(0xfffe0000, 0x800, 1,
5645 s
->ih
[0]->pins
[OMAP_INT_15XX_IH2_IRQ
], NULL
,
5646 omap_findclk(s
, "arminth_ck"));
5647 s
->irq
[0] = s
->ih
[0]->pins
;
5648 s
->irq
[1] = s
->ih
[1]->pins
;
5650 for (i
= 0; i
< 6; i
++)
5651 dma_irqs
[i
] = s
->irq
[omap_dma_irq_map
[i
].ih
][omap_dma_irq_map
[i
].intr
];
5652 s
->dma
= omap_dma_init(0xfffed800, dma_irqs
, s
->irq
[0][OMAP_INT_DMA_LCD
],
5653 s
, omap_findclk(s
, "dma_ck"), omap_dma_3_1
);
5655 s
->port
[emiff
].addr_valid
= omap_validate_emiff_addr
;
5656 s
->port
[emifs
].addr_valid
= omap_validate_emifs_addr
;
5657 s
->port
[imif
].addr_valid
= omap_validate_imif_addr
;
5658 s
->port
[tipb
].addr_valid
= omap_validate_tipb_addr
;
5659 s
->port
[local
].addr_valid
= omap_validate_local_addr
;
5660 s
->port
[tipb_mpui
].addr_valid
= omap_validate_tipb_mpui_addr
;
5662 s
->timer
[0] = omap_mpu_timer_init(0xfffec500,
5663 s
->irq
[0][OMAP_INT_TIMER1
],
5664 omap_findclk(s
, "mputim_ck"));
5665 s
->timer
[1] = omap_mpu_timer_init(0xfffec600,
5666 s
->irq
[0][OMAP_INT_TIMER2
],
5667 omap_findclk(s
, "mputim_ck"));
5668 s
->timer
[2] = omap_mpu_timer_init(0xfffec700,
5669 s
->irq
[0][OMAP_INT_TIMER3
],
5670 omap_findclk(s
, "mputim_ck"));
5672 s
->wdt
= omap_wd_timer_init(0xfffec800,
5673 s
->irq
[0][OMAP_INT_WD_TIMER
],
5674 omap_findclk(s
, "armwdt_ck"));
5676 s
->os_timer
= omap_os_timer_init(0xfffb9000,
5677 s
->irq
[1][OMAP_INT_OS_TIMER
],
5678 omap_findclk(s
, "clk32-kHz"));
5680 s
->lcd
= omap_lcdc_init(0xfffec000, s
->irq
[0][OMAP_INT_LCD_CTRL
],
5681 &s
->dma
->lcd_ch
, ds
, imif_base
, emiff_base
,
5682 omap_findclk(s
, "lcd_ck"));
5684 omap_ulpd_pm_init(0xfffe0800, s
);
5685 omap_pin_cfg_init(0xfffe1000, s
);
5688 omap_mpui_init(0xfffec900, s
);
5690 s
->private_tipb
= omap_tipb_bridge_init(0xfffeca00,
5691 s
->irq
[0][OMAP_INT_BRIDGE_PRIV
],
5692 omap_findclk(s
, "tipb_ck"));
5693 s
->public_tipb
= omap_tipb_bridge_init(0xfffed300,
5694 s
->irq
[0][OMAP_INT_BRIDGE_PUB
],
5695 omap_findclk(s
, "tipb_ck"));
5697 omap_tcmi_init(0xfffecc00, s
);
5699 s
->uart
[0] = omap_uart_init(0xfffb0000, s
->irq
[1][OMAP_INT_UART1
],
5700 omap_findclk(s
, "uart1_ck"),
5702 s
->uart
[1] = omap_uart_init(0xfffb0800, s
->irq
[1][OMAP_INT_UART2
],
5703 omap_findclk(s
, "uart2_ck"),
5704 serial_hds
[0] ? serial_hds
[1] : 0);
5705 s
->uart
[2] = omap_uart_init(0xe1019800, s
->irq
[0][OMAP_INT_UART3
],
5706 omap_findclk(s
, "uart3_ck"),
5707 serial_hds
[0] && serial_hds
[1] ? serial_hds
[2] : 0);
5709 omap_dpll_init(&s
->dpll
[0], 0xfffecf00, omap_findclk(s
, "dpll1"));
5710 omap_dpll_init(&s
->dpll
[1], 0xfffed000, omap_findclk(s
, "dpll2"));
5711 omap_dpll_init(&s
->dpll
[2], 0xfffed100, omap_findclk(s
, "dpll3"));
5713 sdindex
= drive_get_index(IF_SD
, 0, 0);
5714 if (sdindex
== -1) {
5715 fprintf(stderr
, "qemu: missing SecureDigital device\n");
5718 s
->mmc
= omap_mmc_init(0xfffb7800, drives_table
[sdindex
].bdrv
,
5719 s
->irq
[1][OMAP_INT_OQN
], &s
->drq
[OMAP_DMA_MMC_TX
],
5720 omap_findclk(s
, "mmc_ck"));
5722 s
->mpuio
= omap_mpuio_init(0xfffb5000,
5723 s
->irq
[1][OMAP_INT_KEYBOARD
], s
->irq
[1][OMAP_INT_MPUIO
],
5724 s
->wakeup
, omap_findclk(s
, "clk32-kHz"));
5726 s
->gpio
= omap_gpio_init(0xfffce000, s
->irq
[0][OMAP_INT_GPIO_BANK1
],
5727 omap_findclk(s
, "arm_gpio_ck"));
5729 s
->microwire
= omap_uwire_init(0xfffb3000, &s
->irq
[1][OMAP_INT_uWireTX
],
5730 s
->drq
[OMAP_DMA_UWIRE_TX
], omap_findclk(s
, "mpuper_ck"));
5732 omap_pwl_init(0xfffb5800, s
, omap_findclk(s
, "armxor_ck"));
5733 omap_pwt_init(0xfffb6000, s
, omap_findclk(s
, "armxor_ck"));
5735 s
->i2c
= omap_i2c_init(0xfffb3800, s
->irq
[1][OMAP_INT_I2C
],
5736 &s
->drq
[OMAP_DMA_I2C_RX
], omap_findclk(s
, "mpuper_ck"));
5738 s
->rtc
= omap_rtc_init(0xfffb4800, &s
->irq
[1][OMAP_INT_RTC_TIMER
],
5739 omap_findclk(s
, "clk32-kHz"));
5741 s
->mcbsp1
= omap_mcbsp_init(0xfffb1800, &s
->irq
[1][OMAP_INT_McBSP1TX
],
5742 &s
->drq
[OMAP_DMA_MCBSP1_TX
], omap_findclk(s
, "dspxor_ck"));
5743 s
->mcbsp2
= omap_mcbsp_init(0xfffb1000, &s
->irq
[0][OMAP_INT_310_McBSP2_TX
],
5744 &s
->drq
[OMAP_DMA_MCBSP2_TX
], omap_findclk(s
, "mpuper_ck"));
5745 s
->mcbsp3
= omap_mcbsp_init(0xfffb7000, &s
->irq
[1][OMAP_INT_McBSP3TX
],
5746 &s
->drq
[OMAP_DMA_MCBSP3_TX
], omap_findclk(s
, "dspxor_ck"));
5748 s
->led
[0] = omap_lpg_init(0xfffbd000, omap_findclk(s
, "clk32-kHz"));
5749 s
->led
[1] = omap_lpg_init(0xfffbd800, omap_findclk(s
, "clk32-kHz"));
5751 /* Register mappings not currenlty implemented:
5752 * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310)
5753 * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310)
5754 * USB W2FC fffb4000 - fffb47ff
5755 * Camera Interface fffb6800 - fffb6fff
5756 * USB Host fffba000 - fffba7ff
5757 * FAC fffba800 - fffbafff
5758 * HDQ/1-Wire fffbc000 - fffbc7ff
5759 * TIPB switches fffbc800 - fffbcfff
5760 * Mailbox fffcf000 - fffcf7ff
5761 * Local bus IF fffec100 - fffec1ff
5762 * Local bus MMU fffec200 - fffec2ff
5763 * DSP MMU fffed200 - fffed2ff
5766 omap_setup_dsp_mapping(omap15xx_dsp_mm
);
5767 omap_setup_mpui_io(s
);
5769 qemu_register_reset(omap_mpu_reset
, s
);