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);