Statistics
| Branch: | Revision:

root / hw / omap.c @ 8731ac03

History | View | Annotate | Download (131.6 kB)

1
/*
2
 * TI OMAP processors emulation.
3
 *
4
 * Copyright (C) 2006-2007 Andrzej Zaborowski  <balrog@zabor.org>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as
8
 * published by the Free Software Foundation; either version 2 of
9
 * the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19
 * MA 02111-1307 USA
20
 */
21
#include "vl.h"
22
#include "arm_pic.h"
23

    
24
/* Should signal the TCMI */
25
uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
26
{
27
    uint8_t ret;
28

    
29
    OMAP_8B_REG(addr);
30
    cpu_physical_memory_read(addr, (void *) &ret, 1);
31
    return ret;
32
}
33

    
34
void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
35
                uint32_t value)
36
{
37
    uint8_t val8 = value;
38

    
39
    OMAP_8B_REG(addr);
40
    cpu_physical_memory_write(addr, (void *) &val8, 1);
41
}
42

    
43
uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
44
{
45
    uint16_t ret;
46

    
47
    OMAP_16B_REG(addr);
48
    cpu_physical_memory_read(addr, (void *) &ret, 2);
49
    return ret;
50
}
51

    
52
void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
53
                uint32_t value)
54
{
55
    uint16_t val16 = value;
56

    
57
    OMAP_16B_REG(addr);
58
    cpu_physical_memory_write(addr, (void *) &val16, 2);
59
}
60

    
61
uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
62
{
63
    uint32_t ret;
64

    
65
    OMAP_32B_REG(addr);
66
    cpu_physical_memory_read(addr, (void *) &ret, 4);
67
    return ret;
68
}
69

    
70
void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
71
                uint32_t value)
72
{
73
    OMAP_32B_REG(addr);
74
    cpu_physical_memory_write(addr, (void *) &value, 4);
75
}
76

    
77
/* Interrupt Handlers */
78
struct omap_intr_handler_s {
79
    qemu_irq *pins;
80
    qemu_irq *parent_pic;
81
    target_phys_addr_t base;
82

    
83
    /* state */
84
    uint32_t irqs;
85
    uint32_t mask;
86
    uint32_t sens_edge;
87
    uint32_t fiq;
88
    int priority[32];
89
    uint32_t new_irq_agr;
90
    uint32_t new_fiq_agr;
91
    int sir_irq;
92
    int sir_fiq;
93
    int stats[32];
94
};
95

    
96
static void omap_inth_update(struct omap_intr_handler_s *s)
97
{
98
    uint32_t irq = s->irqs & ~s->mask & ~s->fiq;
99
    uint32_t fiq = s->irqs & ~s->mask & s->fiq;
100

    
101
    if (s->new_irq_agr || !irq) {
102
       qemu_set_irq(s->parent_pic[ARM_PIC_CPU_IRQ], irq);
103
       if (irq)
104
           s->new_irq_agr = 0;
105
    }
106

    
107
    if (s->new_fiq_agr || !irq) {
108
        qemu_set_irq(s->parent_pic[ARM_PIC_CPU_FIQ], fiq);
109
        if (fiq)
110
            s->new_fiq_agr = 0;
111
    }
112
}
113

    
114
static void omap_inth_sir_update(struct omap_intr_handler_s *s)
115
{
116
    int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f;
117
    uint32_t level = s->irqs & ~s->mask;
118

    
119
    intr_irq = 0;
120
    intr_fiq = 0;
121
    p_irq = -1;
122
    p_fiq = -1;
123
    /* Find the interrupt line with the highest dynamic priority */
124
    for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, level >>= f) {
125
        p = s->priority[i];
126
        if (s->fiq & (1 << i)) {
127
            if (p > p_fiq) {
128
                p_fiq = p;
129
                intr_fiq = i;
130
            }
131
        } else {
132
            if (p > p_irq) {
133
                p_irq = p;
134
                intr_irq = i;
135
            }
136
        }
137

    
138
        f = ffs(level >> 1);
139
    }
140

    
141
    s->sir_irq = intr_irq;
142
    s->sir_fiq = intr_fiq;
143
}
144

    
145
#define INT_FALLING_EDGE        0
146
#define INT_LOW_LEVEL                1
147

    
148
static void omap_set_intr(void *opaque, int irq, int req)
149
{
150
    struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
151
    uint32_t rise;
152

    
153
    if (req) {
154
        rise = ~ih->irqs & (1 << irq);
155
        ih->irqs |= rise;
156
        ih->stats[irq] += !!rise;
157
    } else {
158
        rise = ih->sens_edge & ih->irqs & (1 << irq);
159
        ih->irqs &= ~rise;
160
    }
161

    
162
    if (rise & ~ih->mask) {
163
        omap_inth_sir_update(ih);
164

    
165
        omap_inth_update(ih);
166
    }
167
}
168

    
169
static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
170
{
171
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
172
    int i, offset = addr - s->base;
173

    
174
    switch (offset) {
175
    case 0x00:        /* ITR */
176
        return s->irqs;
177

    
178
    case 0x04:        /* MIR */
179
        return s->mask;
180

    
181
    case 0x10:        /* SIR_IRQ_CODE */
182
        i = s->sir_irq;
183
        if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
184
            s->irqs &= ~(1 << i);
185
            omap_inth_sir_update(s);
186
            omap_inth_update(s);
187
        }
188
        return i;
189

    
190
    case 0x14:        /* SIR_FIQ_CODE */
191
        i = s->sir_fiq;
192
        if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
193
            s->irqs &= ~(1 << i);
194
            omap_inth_sir_update(s);
195
            omap_inth_update(s);
196
        }
197
        return i;
198

    
199
    case 0x18:        /* CONTROL_REG */
200
        return 0;
201

    
202
    case 0x1c:        /* ILR0 */
203
    case 0x20:        /* ILR1 */
204
    case 0x24:        /* ILR2 */
205
    case 0x28:        /* ILR3 */
206
    case 0x2c:        /* ILR4 */
207
    case 0x30:        /* ILR5 */
208
    case 0x34:        /* ILR6 */
209
    case 0x38:        /* ILR7 */
210
    case 0x3c:        /* ILR8 */
211
    case 0x40:        /* ILR9 */
212
    case 0x44:        /* ILR10 */
213
    case 0x48:        /* ILR11 */
214
    case 0x4c:        /* ILR12 */
215
    case 0x50:        /* ILR13 */
216
    case 0x54:        /* ILR14 */
217
    case 0x58:        /* ILR15 */
218
    case 0x5c:        /* ILR16 */
219
    case 0x60:        /* ILR17 */
220
    case 0x64:        /* ILR18 */
221
    case 0x68:        /* ILR19 */
222
    case 0x6c:        /* ILR20 */
223
    case 0x70:        /* ILR21 */
224
    case 0x74:        /* ILR22 */
225
    case 0x78:        /* ILR23 */
226
    case 0x7c:        /* ILR24 */
227
    case 0x80:        /* ILR25 */
228
    case 0x84:        /* ILR26 */
229
    case 0x88:        /* ILR27 */
230
    case 0x8c:        /* ILR28 */
231
    case 0x90:        /* ILR29 */
232
    case 0x94:        /* ILR30 */
233
    case 0x98:        /* ILR31 */
234
        i = (offset - 0x1c) >> 2;
235
        return (s->priority[i] << 2) |
236
                (((s->sens_edge >> i) & 1) << 1) |
237
                ((s->fiq >> i) & 1);
238

    
239
    case 0x9c:        /* ISR */
240
        return 0x00000000;
241

    
242
    default:
243
        OMAP_BAD_REG(addr);
244
        break;
245
    }
246
    return 0;
247
}
248

    
249
static void omap_inth_write(void *opaque, target_phys_addr_t addr,
250
                uint32_t value)
251
{
252
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
253
    int i, offset = addr - s->base;
254

    
255
    switch (offset) {
256
    case 0x00:        /* ITR */
257
        s->irqs &= value | 1;
258
        omap_inth_sir_update(s);
259
        omap_inth_update(s);
260
        return;
261

    
262
    case 0x04:        /* MIR */
263
        s->mask = value;
264
        omap_inth_sir_update(s);
265
        omap_inth_update(s);
266
        return;
267

    
268
    case 0x10:        /* SIR_IRQ_CODE */
269
    case 0x14:        /* SIR_FIQ_CODE */
270
        OMAP_RO_REG(addr);
271
        break;
272

    
273
    case 0x18:        /* CONTROL_REG */
274
        if (value & 2)
275
            s->new_fiq_agr = ~0;
276
        if (value & 1)
277
            s->new_irq_agr = ~0;
278
        omap_inth_update(s);
279
        return;
280

    
281
    case 0x1c:        /* ILR0 */
282
    case 0x20:        /* ILR1 */
283
    case 0x24:        /* ILR2 */
284
    case 0x28:        /* ILR3 */
285
    case 0x2c:        /* ILR4 */
286
    case 0x30:        /* ILR5 */
287
    case 0x34:        /* ILR6 */
288
    case 0x38:        /* ILR7 */
289
    case 0x3c:        /* ILR8 */
290
    case 0x40:        /* ILR9 */
291
    case 0x44:        /* ILR10 */
292
    case 0x48:        /* ILR11 */
293
    case 0x4c:        /* ILR12 */
294
    case 0x50:        /* ILR13 */
295
    case 0x54:        /* ILR14 */
296
    case 0x58:        /* ILR15 */
297
    case 0x5c:        /* ILR16 */
298
    case 0x60:        /* ILR17 */
299
    case 0x64:        /* ILR18 */
300
    case 0x68:        /* ILR19 */
301
    case 0x6c:        /* ILR20 */
302
    case 0x70:        /* ILR21 */
303
    case 0x74:        /* ILR22 */
304
    case 0x78:        /* ILR23 */
305
    case 0x7c:        /* ILR24 */
306
    case 0x80:        /* ILR25 */
307
    case 0x84:        /* ILR26 */
308
    case 0x88:        /* ILR27 */
309
    case 0x8c:        /* ILR28 */
310
    case 0x90:        /* ILR29 */
311
    case 0x94:        /* ILR30 */
312
    case 0x98:        /* ILR31 */
313
        i = (offset - 0x1c) >> 2;
314
        s->priority[i] = (value >> 2) & 0x1f;
315
        s->sens_edge &= ~(1 << i);
316
        s->sens_edge |= ((value >> 1) & 1) << i;
317
        s->fiq &= ~(1 << i);
318
        s->fiq |= (value & 1) << i;
319
        return;
320

    
321
    case 0x9c:        /* ISR */
322
        for (i = 0; i < 32; i ++)
323
            if (value & (1 << i)) {
324
                omap_set_intr(s, i, 1);
325
                return;
326
            }
327
        return;
328

    
329
    default:
330
        OMAP_BAD_REG(addr);
331
    }
332
}
333

    
334
static CPUReadMemoryFunc *omap_inth_readfn[] = {
335
    omap_badwidth_read32,
336
    omap_badwidth_read32,
337
    omap_inth_read,
338
};
339

    
340
static CPUWriteMemoryFunc *omap_inth_writefn[] = {
341
    omap_inth_write,
342
    omap_inth_write,
343
    omap_inth_write,
344
};
345

    
346
static void omap_inth_reset(struct omap_intr_handler_s *s)
347
{
348
    s->irqs = 0x00000000;
349
    s->mask = 0xffffffff;
350
    s->sens_edge = 0x00000000;
351
    s->fiq = 0x00000000;
352
    memset(s->priority, 0, sizeof(s->priority));
353
    s->new_irq_agr = ~0;
354
    s->new_fiq_agr = ~0;
355
    s->sir_irq = 0;
356
    s->sir_fiq = 0;
357

    
358
    omap_inth_update(s);
359
}
360

    
361
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
362
                unsigned long size, qemu_irq parent[2], omap_clk clk)
363
{
364
    int iomemtype;
365
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
366
            qemu_mallocz(sizeof(struct omap_intr_handler_s));
367

    
368
    s->parent_pic = parent;
369
    s->base = base;
370
    s->pins = qemu_allocate_irqs(omap_set_intr, s, 32);
371
    omap_inth_reset(s);
372

    
373
    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
374
                    omap_inth_writefn, s);
375
    cpu_register_physical_memory(s->base, size, iomemtype);
376

    
377
    return s;
378
}
379

    
380
/* OMAP1 DMA module */
381
typedef enum {
382
    constant = 0,
383
    post_incremented,
384
    single_index,
385
    double_index,
386
} omap_dma_addressing_t;
387

    
388
struct omap_dma_channel_s {
389
    int burst[2];
390
    int pack[2];
391
    enum omap_dma_port port[2];
392
    target_phys_addr_t addr[2];
393
    omap_dma_addressing_t mode[2];
394
    int data_type;
395
    int end_prog;
396
    int repeat;
397
    int auto_init;
398
    int priority;
399
    int fs;
400
    int sync;
401
    int running;
402
    int interrupts;
403
    int status;
404
    int signalled;
405
    int post_sync;
406
    int transfer;
407
    uint16_t elements;
408
    uint16_t frames;
409
    uint16_t frame_index;
410
    uint16_t element_index;
411
    uint16_t cpc;
412

    
413
    struct omap_dma_reg_set_s {
414
        target_phys_addr_t src, dest;
415
        int frame;
416
        int element;
417
        int frame_delta[2];
418
        int elem_delta[2];
419
        int frames;
420
        int elements;
421
    } active_set;
422
};
423

    
424
struct omap_dma_s {
425
    qemu_irq *ih;
426
    QEMUTimer *tm;
427
    struct omap_mpu_state_s *mpu;
428
    target_phys_addr_t base;
429
    omap_clk clk;
430
    int64_t delay;
431
    uint32_t drq;
432

    
433
    uint16_t gcr;
434
    int run_count;
435

    
436
    int chans;
437
    struct omap_dma_channel_s ch[16];
438
    struct omap_dma_lcd_channel_s lcd_ch;
439
};
440

    
441
static void omap_dma_interrupts_update(struct omap_dma_s *s)
442
{
443
    /* First three interrupts are shared between two channels each.  */
444
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH0_6],
445
                    (s->ch[0].status | s->ch[6].status) & 0x3f);
446
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH1_7],
447
                    (s->ch[1].status | s->ch[7].status) & 0x3f);
448
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH2_8],
449
                    (s->ch[2].status | s->ch[8].status) & 0x3f);
450
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH3],
451
                    (s->ch[3].status) & 0x3f);
452
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH4],
453
                    (s->ch[4].status) & 0x3f);
454
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH5],
455
                    (s->ch[5].status) & 0x3f);
456
}
457

    
458
static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
459
{
460
    struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
461
    int i;
462

    
463
    /*
464
     * TODO: verify address ranges and alignment
465
     * TODO: port endianness
466
     */
467

    
468
    a->src = s->ch[ch].addr[0];
469
    a->dest = s->ch[ch].addr[1];
470
    a->frames = s->ch[ch].frames;
471
    a->elements = s->ch[ch].elements;
472
    a->frame = 0;
473
    a->element = 0;
474

    
475
    if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
476
        printf("%s: bad DMA request\n", __FUNCTION__);
477
        return;
478
    }
479

    
480
    for (i = 0; i < 2; i ++)
481
        switch (s->ch[ch].mode[i]) {
482
        case constant:
483
            a->elem_delta[i] = 0;
484
            a->frame_delta[i] = 0;
485
            break;
486
        case post_incremented:
487
            a->elem_delta[i] = s->ch[ch].data_type;
488
            a->frame_delta[i] = 0;
489
            break;
490
        case single_index:
491
            a->elem_delta[i] = s->ch[ch].data_type +
492
                s->ch[ch].element_index - 1;
493
            if (s->ch[ch].element_index > 0x7fff)
494
                a->elem_delta[i] -= 0x10000;
495
            a->frame_delta[i] = 0;
496
            break;
497
        case double_index:
498
            a->elem_delta[i] = s->ch[ch].data_type +
499
                s->ch[ch].element_index - 1;
500
            if (s->ch[ch].element_index > 0x7fff)
501
                a->elem_delta[i] -= 0x10000;
502
            a->frame_delta[i] = s->ch[ch].frame_index -
503
                s->ch[ch].element_index;
504
            if (s->ch[ch].frame_index > 0x7fff)
505
                a->frame_delta[i] -= 0x10000;
506
            break;
507
        default:
508
            break;
509
        }
510
}
511

    
512
static inline void omap_dma_request_run(struct omap_dma_s *s,
513
                int channel, int request)
514
{
515
next_channel:
516
    if (request > 0)
517
        for (; channel < 9; channel ++)
518
            if (s->ch[channel].sync == request && s->ch[channel].running)
519
                break;
520
    if (channel >= 9)
521
        return;
522

    
523
    if (s->ch[channel].transfer) {
524
        if (request > 0) {
525
            s->ch[channel ++].post_sync = request;
526
            goto next_channel;
527
        }
528
        s->ch[channel].status |= 0x02;        /* Synchronisation drop */
529
        omap_dma_interrupts_update(s);
530
        return;
531
    }
532

    
533
    if (!s->ch[channel].signalled)
534
        s->run_count ++;
535
    s->ch[channel].signalled = 1;
536

    
537
    if (request > 0)
538
        s->ch[channel].status |= 0x40;        /* External request */
539

    
540
    if (s->delay && !qemu_timer_pending(s->tm))
541
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
542

    
543
    if (request > 0) {
544
        channel ++;
545
        goto next_channel;
546
    }
547
}
548

    
549
static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel)
550
{
551
    if (s->ch[channel].signalled)
552
        s->run_count --;
553
    s->ch[channel].signalled = 0;
554

    
555
    if (!s->run_count)
556
        qemu_del_timer(s->tm);
557
}
558

    
559
static void omap_dma_channel_run(struct omap_dma_s *s)
560
{
561
    int ch;
562
    uint16_t status;
563
    uint8_t value[4];
564
    struct omap_dma_port_if_s *src_p, *dest_p;
565
    struct omap_dma_reg_set_s *a;
566

    
567
    for (ch = 0; ch < 9; ch ++) {
568
        a = &s->ch[ch].active_set;
569

    
570
        src_p = &s->mpu->port[s->ch[ch].port[0]];
571
        dest_p = &s->mpu->port[s->ch[ch].port[1]];
572
        if (s->ch[ch].signalled && (!src_p->addr_valid(s->mpu, a->src) ||
573
                    !dest_p->addr_valid(s->mpu, a->dest))) {
574
#if 0
575
            /* Bus time-out */
576
            if (s->ch[ch].interrupts & 0x01)
577
                s->ch[ch].status |= 0x01;
578
            omap_dma_request_stop(s, ch);
579
            continue;
580
#endif
581
            printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch);
582
        }
583

    
584
        status = s->ch[ch].status;
585
        while (status == s->ch[ch].status && s->ch[ch].signalled) {
586
            /* Transfer a single element */
587
            s->ch[ch].transfer = 1;
588
            cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
589
            cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
590
            s->ch[ch].transfer = 0;
591

    
592
            a->src += a->elem_delta[0];
593
            a->dest += a->elem_delta[1];
594
            a->element ++;
595

    
596
            /* Check interrupt conditions */
597
            if (a->element == a->elements) {
598
                a->element = 0;
599
                a->src += a->frame_delta[0];
600
                a->dest += a->frame_delta[1];
601
                a->frame ++;
602

    
603
                if (a->frame == a->frames) {
604
                    if (!s->ch[ch].repeat || !s->ch[ch].auto_init)
605
                        s->ch[ch].running = 0;
606

    
607
                    if (s->ch[ch].auto_init &&
608
                            (s->ch[ch].repeat ||
609
                             s->ch[ch].end_prog))
610
                        omap_dma_channel_load(s, ch);
611

    
612
                    if (s->ch[ch].interrupts & 0x20)
613
                        s->ch[ch].status |= 0x20;
614

    
615
                    if (!s->ch[ch].sync)
616
                        omap_dma_request_stop(s, ch);
617
                }
618

    
619
                if (s->ch[ch].interrupts & 0x08)
620
                    s->ch[ch].status |= 0x08;
621

    
622
                if (s->ch[ch].sync && s->ch[ch].fs &&
623
                                !(s->drq & (1 << s->ch[ch].sync))) {
624
                    s->ch[ch].status &= ~0x40;
625
                    omap_dma_request_stop(s, ch);
626
                }
627
            }
628

    
629
            if (a->element == 1 && a->frame == a->frames - 1)
630
                if (s->ch[ch].interrupts & 0x10)
631
                    s->ch[ch].status |= 0x10;
632

    
633
            if (a->element == (a->elements >> 1))
634
                if (s->ch[ch].interrupts & 0x04)
635
                    s->ch[ch].status |= 0x04;
636

    
637
            if (s->ch[ch].sync && !s->ch[ch].fs &&
638
                            !(s->drq & (1 << s->ch[ch].sync))) {
639
                s->ch[ch].status &= ~0x40;
640
                omap_dma_request_stop(s, ch);
641
            }
642

    
643
            /*
644
             * Process requests made while the element was
645
             * being transferred.
646
             */
647
            if (s->ch[ch].post_sync) {
648
                omap_dma_request_run(s, 0, s->ch[ch].post_sync);
649
                s->ch[ch].post_sync = 0;
650
            }
651

    
652
#if 0
653
            break;
654
#endif
655
        }
656

    
657
        s->ch[ch].cpc = a->dest & 0x0000ffff;
658
    }
659

    
660
    omap_dma_interrupts_update(s);
661
    if (s->run_count && s->delay)
662
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
663
}
664

    
665
static int omap_dma_ch_reg_read(struct omap_dma_s *s,
666
                int ch, int reg, uint16_t *value) {
667
    switch (reg) {
668
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
669
        *value = (s->ch[ch].burst[1] << 14) |
670
                (s->ch[ch].pack[1] << 13) |
671
                (s->ch[ch].port[1] << 9) |
672
                (s->ch[ch].burst[0] << 7) |
673
                (s->ch[ch].pack[0] << 6) |
674
                (s->ch[ch].port[0] << 2) |
675
                (s->ch[ch].data_type >> 1);
676
        break;
677

    
678
    case 0x02:        /* SYS_DMA_CCR_CH0 */
679
        *value = (s->ch[ch].mode[1] << 14) |
680
                (s->ch[ch].mode[0] << 12) |
681
                (s->ch[ch].end_prog << 11) |
682
                (s->ch[ch].repeat << 9) |
683
                (s->ch[ch].auto_init << 8) |
684
                (s->ch[ch].running << 7) |
685
                (s->ch[ch].priority << 6) |
686
                (s->ch[ch].fs << 5) | s->ch[ch].sync;
687
        break;
688

    
689
    case 0x04:        /* SYS_DMA_CICR_CH0 */
690
        *value = s->ch[ch].interrupts;
691
        break;
692

    
693
    case 0x06:        /* SYS_DMA_CSR_CH0 */
694
        /* FIXME: shared CSR for channels sharing the interrupts */
695
        *value = s->ch[ch].status;
696
        s->ch[ch].status &= 0x40;
697
        omap_dma_interrupts_update(s);
698
        break;
699

    
700
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
701
        *value = s->ch[ch].addr[0] & 0x0000ffff;
702
        break;
703

    
704
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
705
        *value = s->ch[ch].addr[0] >> 16;
706
        break;
707

    
708
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
709
        *value = s->ch[ch].addr[1] & 0x0000ffff;
710
        break;
711

    
712
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
713
        *value = s->ch[ch].addr[1] >> 16;
714
        break;
715

    
716
    case 0x10:        /* SYS_DMA_CEN_CH0 */
717
        *value = s->ch[ch].elements;
718
        break;
719

    
720
    case 0x12:        /* SYS_DMA_CFN_CH0 */
721
        *value = s->ch[ch].frames;
722
        break;
723

    
724
    case 0x14:        /* SYS_DMA_CFI_CH0 */
725
        *value = s->ch[ch].frame_index;
726
        break;
727

    
728
    case 0x16:        /* SYS_DMA_CEI_CH0 */
729
        *value = s->ch[ch].element_index;
730
        break;
731

    
732
    case 0x18:        /* SYS_DMA_CPC_CH0 */
733
        *value = s->ch[ch].cpc;
734
        break;
735

    
736
    default:
737
        return 1;
738
    }
739
    return 0;
740
}
741

    
742
static int omap_dma_ch_reg_write(struct omap_dma_s *s,
743
                int ch, int reg, uint16_t value) {
744
    switch (reg) {
745
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
746
        s->ch[ch].burst[1] = (value & 0xc000) >> 14;
747
        s->ch[ch].pack[1] = (value & 0x2000) >> 13;
748
        s->ch[ch].port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
749
        s->ch[ch].burst[0] = (value & 0x0180) >> 7;
750
        s->ch[ch].pack[0] = (value & 0x0040) >> 6;
751
        s->ch[ch].port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
752
        s->ch[ch].data_type = (1 << (value & 3));
753
        if (s->ch[ch].port[0] >= omap_dma_port_last)
754
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
755
                            s->ch[ch].port[0]);
756
        if (s->ch[ch].port[1] >= omap_dma_port_last)
757
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
758
                            s->ch[ch].port[1]);
759
        if ((value & 3) == 3)
760
            printf("%s: bad data_type for DMA channel %i\n", __FUNCTION__, ch);
761
        break;
762

    
763
    case 0x02:        /* SYS_DMA_CCR_CH0 */
764
        s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
765
        s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
766
        s->ch[ch].end_prog = (value & 0x0800) >> 11;
767
        s->ch[ch].repeat = (value & 0x0200) >> 9;
768
        s->ch[ch].auto_init = (value & 0x0100) >> 8;
769
        s->ch[ch].priority = (value & 0x0040) >> 6;
770
        s->ch[ch].fs = (value & 0x0020) >> 5;
771
        s->ch[ch].sync = value & 0x001f;
772
        if (value & 0x0080) {
773
            if (s->ch[ch].running) {
774
                if (!s->ch[ch].signalled &&
775
                                s->ch[ch].auto_init && s->ch[ch].end_prog)
776
                    omap_dma_channel_load(s, ch);
777
            } else {
778
                s->ch[ch].running = 1;
779
                omap_dma_channel_load(s, ch);
780
            }
781
            if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync)))
782
                omap_dma_request_run(s, ch, 0);
783
        } else {
784
            s->ch[ch].running = 0;
785
            omap_dma_request_stop(s, ch);
786
        }
787
        break;
788

    
789
    case 0x04:        /* SYS_DMA_CICR_CH0 */
790
        s->ch[ch].interrupts = value & 0x003f;
791
        break;
792

    
793
    case 0x06:        /* SYS_DMA_CSR_CH0 */
794
        return 1;
795

    
796
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
797
        s->ch[ch].addr[0] &= 0xffff0000;
798
        s->ch[ch].addr[0] |= value;
799
        break;
800

    
801
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
802
        s->ch[ch].addr[0] &= 0x0000ffff;
803
        s->ch[ch].addr[0] |= (uint32_t) value << 16;
804
        break;
805

    
806
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
807
        s->ch[ch].addr[1] &= 0xffff0000;
808
        s->ch[ch].addr[1] |= value;
809
        break;
810

    
811
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
812
        s->ch[ch].addr[1] &= 0x0000ffff;
813
        s->ch[ch].addr[1] |= (uint32_t) value << 16;
814
        break;
815

    
816
    case 0x10:        /* SYS_DMA_CEN_CH0 */
817
        s->ch[ch].elements = value & 0xffff;
818
        break;
819

    
820
    case 0x12:        /* SYS_DMA_CFN_CH0 */
821
        s->ch[ch].frames = value & 0xffff;
822
        break;
823

    
824
    case 0x14:        /* SYS_DMA_CFI_CH0 */
825
        s->ch[ch].frame_index = value & 0xffff;
826
        break;
827

    
828
    case 0x16:        /* SYS_DMA_CEI_CH0 */
829
        s->ch[ch].element_index = value & 0xffff;
830
        break;
831

    
832
    case 0x18:        /* SYS_DMA_CPC_CH0 */
833
        return 1;
834

    
835
    default:
836
        OMAP_BAD_REG((target_phys_addr_t) reg);
837
    }
838
    return 0;
839
}
840

    
841
static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
842
{
843
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
844
    int i, reg, ch, offset = addr - s->base;
845
    uint16_t ret;
846

    
847
    switch (offset) {
848
    case 0x000 ... 0x2fe:
849
        reg = offset & 0x3f;
850
        ch = (offset >> 6) & 0x0f;
851
        if (omap_dma_ch_reg_read(s, ch, reg, &ret))
852
            break;
853
        return ret;
854

    
855
    case 0x300:        /* SYS_DMA_LCD_CTRL */
856
        i = s->lcd_ch.condition;
857
        s->lcd_ch.condition = 0;
858
        qemu_irq_lower(s->lcd_ch.irq);
859
        return ((s->lcd_ch.src == imif) << 6) | (i << 3) |
860
                (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
861

    
862
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
863
        return s->lcd_ch.src_f1_top & 0xffff;
864

    
865
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
866
        return s->lcd_ch.src_f1_top >> 16;
867

    
868
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
869
        return s->lcd_ch.src_f1_bottom & 0xffff;
870

    
871
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
872
        return s->lcd_ch.src_f1_bottom >> 16;
873

    
874
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
875
        return s->lcd_ch.src_f2_top & 0xffff;
876

    
877
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
878
        return s->lcd_ch.src_f2_top >> 16;
879

    
880
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
881
        return s->lcd_ch.src_f2_bottom & 0xffff;
882

    
883
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
884
        return s->lcd_ch.src_f2_bottom >> 16;
885

    
886
    case 0x400:        /* SYS_DMA_GCR */
887
        return s->gcr;
888
    }
889

    
890
    OMAP_BAD_REG(addr);
891
    return 0;
892
}
893

    
894
static void omap_dma_write(void *opaque, target_phys_addr_t addr,
895
                uint32_t value)
896
{
897
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
898
    int reg, ch, offset = addr - s->base;
899

    
900
    switch (offset) {
901
    case 0x000 ... 0x2fe:
902
        reg = offset & 0x3f;
903
        ch = (offset >> 6) & 0x0f;
904
        if (omap_dma_ch_reg_write(s, ch, reg, value))
905
            OMAP_RO_REG(addr);
906
        break;
907

    
908
    case 0x300:        /* SYS_DMA_LCD_CTRL */
909
        s->lcd_ch.src = (value & 0x40) ? imif : emiff;
910
        s->lcd_ch.condition = 0;
911
        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
912
        s->lcd_ch.interrupts = (value >> 1) & 1;
913
        s->lcd_ch.dual = value & 1;
914
        break;
915

    
916
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
917
        s->lcd_ch.src_f1_top &= 0xffff0000;
918
        s->lcd_ch.src_f1_top |= 0x0000ffff & value;
919
        break;
920

    
921
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
922
        s->lcd_ch.src_f1_top &= 0x0000ffff;
923
        s->lcd_ch.src_f1_top |= value << 16;
924
        break;
925

    
926
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
927
        s->lcd_ch.src_f1_bottom &= 0xffff0000;
928
        s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
929
        break;
930

    
931
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
932
        s->lcd_ch.src_f1_bottom &= 0x0000ffff;
933
        s->lcd_ch.src_f1_bottom |= value << 16;
934
        break;
935

    
936
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
937
        s->lcd_ch.src_f2_top &= 0xffff0000;
938
        s->lcd_ch.src_f2_top |= 0x0000ffff & value;
939
        break;
940

    
941
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
942
        s->lcd_ch.src_f2_top &= 0x0000ffff;
943
        s->lcd_ch.src_f2_top |= value << 16;
944
        break;
945

    
946
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
947
        s->lcd_ch.src_f2_bottom &= 0xffff0000;
948
        s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
949
        break;
950

    
951
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
952
        s->lcd_ch.src_f2_bottom &= 0x0000ffff;
953
        s->lcd_ch.src_f2_bottom |= value << 16;
954
        break;
955

    
956
    case 0x400:        /* SYS_DMA_GCR */
957
        s->gcr = value & 0x000c;
958
        break;
959

    
960
    default:
961
        OMAP_BAD_REG(addr);
962
    }
963
}
964

    
965
static CPUReadMemoryFunc *omap_dma_readfn[] = {
966
    omap_badwidth_read16,
967
    omap_dma_read,
968
    omap_badwidth_read16,
969
};
970

    
971
static CPUWriteMemoryFunc *omap_dma_writefn[] = {
972
    omap_badwidth_write16,
973
    omap_dma_write,
974
    omap_badwidth_write16,
975
};
976

    
977
static void omap_dma_request(void *opaque, int drq, int req)
978
{
979
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
980
    /* The request pins are level triggered.  */
981
    if (req) {
982
        if (~s->drq & (1 << drq)) {
983
            s->drq |= 1 << drq;
984
            omap_dma_request_run(s, 0, drq);
985
        }
986
    } else
987
        s->drq &= ~(1 << drq);
988
}
989

    
990
static void omap_dma_clk_update(void *opaque, int line, int on)
991
{
992
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
993

    
994
    if (on) {
995
        s->delay = ticks_per_sec >> 7;
996
        if (s->run_count)
997
            qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
998
    } else {
999
        s->delay = 0;
1000
        qemu_del_timer(s->tm);
1001
    }
1002
}
1003

    
1004
static void omap_dma_reset(struct omap_dma_s *s)
1005
{
1006
    int i;
1007

    
1008
    qemu_del_timer(s->tm);
1009
    s->gcr = 0x0004;
1010
    s->drq = 0x00000000;
1011
    s->run_count = 0;
1012
    s->lcd_ch.src = emiff;
1013
    s->lcd_ch.condition = 0;
1014
    s->lcd_ch.interrupts = 0;
1015
    s->lcd_ch.dual = 0;
1016
    memset(s->ch, 0, sizeof(s->ch));
1017
    for (i = 0; i < s->chans; i ++)
1018
        s->ch[i].interrupts = 0x0003;
1019
}
1020

    
1021
struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
1022
                qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk)
1023
{
1024
    int iomemtype;
1025
    struct omap_dma_s *s = (struct omap_dma_s *)
1026
            qemu_mallocz(sizeof(struct omap_dma_s));
1027

    
1028
    s->ih = pic;
1029
    s->base = base;
1030
    s->chans = 9;
1031
    s->mpu = mpu;
1032
    s->clk = clk;
1033
    s->lcd_ch.irq = pic[OMAP_INT_DMA_LCD];
1034
    s->lcd_ch.mpu = mpu;
1035
    s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1036
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1037
    mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1038
    omap_dma_reset(s);
1039
    omap_dma_clk_update(s, 0, 1);
1040

    
1041
    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1042
                    omap_dma_writefn, s);
1043
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
1044

    
1045
    return s;
1046
}
1047

    
1048
/* DMA ports */
1049
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1050
                target_phys_addr_t addr)
1051
{
1052
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1053
}
1054

    
1055
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1056
                target_phys_addr_t addr)
1057
{
1058
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1059
}
1060

    
1061
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1062
                target_phys_addr_t addr)
1063
{
1064
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1065
}
1066

    
1067
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1068
                target_phys_addr_t addr)
1069
{
1070
    return addr >= 0xfffb0000 && addr < 0xffff0000;
1071
}
1072

    
1073
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
1074
                target_phys_addr_t addr)
1075
{
1076
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1077
}
1078

    
1079
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1080
                target_phys_addr_t addr)
1081
{
1082
    return addr >= 0xe1010000 && addr < 0xe1020004;
1083
}
1084

    
1085
/* MPU OS timers */
1086
struct omap_mpu_timer_s {
1087
    qemu_irq irq;
1088
    omap_clk clk;
1089
    target_phys_addr_t base;
1090
    uint32_t val;
1091
    int64_t time;
1092
    QEMUTimer *timer;
1093
    int64_t rate;
1094
    int it_ena;
1095

    
1096
    int enable;
1097
    int ptv;
1098
    int ar;
1099
    int st;
1100
    uint32_t reset_val;
1101
};
1102

    
1103
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1104
{
1105
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
1106

    
1107
    if (timer->st && timer->enable && timer->rate)
1108
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
1109
                        timer->rate, ticks_per_sec);
1110
    else
1111
        return timer->val;
1112
}
1113

    
1114
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1115
{
1116
    timer->val = omap_timer_read(timer);
1117
    timer->time = qemu_get_clock(vm_clock);
1118
}
1119

    
1120
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1121
{
1122
    int64_t expires;
1123

    
1124
    if (timer->enable && timer->st && timer->rate) {
1125
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
1126
        expires = muldiv64(timer->val << (timer->ptv + 1),
1127
                        ticks_per_sec, timer->rate);
1128

    
1129
        /* If timer expiry would be sooner than in about 1 ms and
1130
         * auto-reload isn't set, then fire immediately.  This is a hack
1131
         * to make systems like PalmOS run in acceptable time.  PalmOS
1132
         * sets the interval to a very low value and polls the status bit
1133
         * in a busy loop when it wants to sleep just a couple of CPU
1134
         * ticks.  */
1135
        if (expires > (ticks_per_sec >> 10) || timer->ar)
1136
            qemu_mod_timer(timer->timer, timer->time + expires);
1137
        else {
1138
            timer->val = 0;
1139
            timer->st = 0;
1140
            if (timer->it_ena)
1141
                qemu_irq_raise(timer->irq);
1142
        }
1143
    } else
1144
        qemu_del_timer(timer->timer);
1145
}
1146

    
1147
static void omap_timer_tick(void *opaque)
1148
{
1149
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1150
    omap_timer_sync(timer);
1151

    
1152
    if (!timer->ar) {
1153
        timer->val = 0;
1154
        timer->st = 0;
1155
    }
1156

    
1157
    if (timer->it_ena)
1158
        qemu_irq_raise(timer->irq);
1159
    omap_timer_update(timer);
1160
}
1161

    
1162
static void omap_timer_clk_update(void *opaque, int line, int on)
1163
{
1164
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1165

    
1166
    omap_timer_sync(timer);
1167
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1168
    omap_timer_update(timer);
1169
}
1170

    
1171
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
1172
{
1173
    omap_clk_adduser(timer->clk,
1174
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
1175
    timer->rate = omap_clk_getrate(timer->clk);
1176
}
1177

    
1178
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
1179
{
1180
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1181
    int offset = addr - s->base;
1182

    
1183
    switch (offset) {
1184
    case 0x00:        /* CNTL_TIMER */
1185
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1186

    
1187
    case 0x04:        /* LOAD_TIM */
1188
        break;
1189

    
1190
    case 0x08:        /* READ_TIM */
1191
        return omap_timer_read(s);
1192
    }
1193

    
1194
    OMAP_BAD_REG(addr);
1195
    return 0;
1196
}
1197

    
1198
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1199
                uint32_t value)
1200
{
1201
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1202
    int offset = addr - s->base;
1203

    
1204
    switch (offset) {
1205
    case 0x00:        /* CNTL_TIMER */
1206
        omap_timer_sync(s);
1207
        s->enable = (value >> 5) & 1;
1208
        s->ptv = (value >> 2) & 7;
1209
        s->ar = (value >> 1) & 1;
1210
        s->st = value & 1;
1211
        omap_timer_update(s);
1212
        return;
1213

    
1214
    case 0x04:        /* LOAD_TIM */
1215
        s->reset_val = value;
1216
        return;
1217

    
1218
    case 0x08:        /* READ_TIM */
1219
        OMAP_RO_REG(addr);
1220
        break;
1221

    
1222
    default:
1223
        OMAP_BAD_REG(addr);
1224
    }
1225
}
1226

    
1227
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1228
    omap_badwidth_read32,
1229
    omap_badwidth_read32,
1230
    omap_mpu_timer_read,
1231
};
1232

    
1233
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1234
    omap_badwidth_write32,
1235
    omap_badwidth_write32,
1236
    omap_mpu_timer_write,
1237
};
1238

    
1239
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
1240
{
1241
    qemu_del_timer(s->timer);
1242
    s->enable = 0;
1243
    s->reset_val = 31337;
1244
    s->val = 0;
1245
    s->ptv = 0;
1246
    s->ar = 0;
1247
    s->st = 0;
1248
    s->it_ena = 1;
1249
}
1250

    
1251
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1252
                qemu_irq irq, omap_clk clk)
1253
{
1254
    int iomemtype;
1255
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1256
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
1257

    
1258
    s->irq = irq;
1259
    s->clk = clk;
1260
    s->base = base;
1261
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
1262
    omap_mpu_timer_reset(s);
1263
    omap_timer_clk_setup(s);
1264

    
1265
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
1266
                    omap_mpu_timer_writefn, s);
1267
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1268

    
1269
    return s;
1270
}
1271

    
1272
/* Watchdog timer */
1273
struct omap_watchdog_timer_s {
1274
    struct omap_mpu_timer_s timer;
1275
    uint8_t last_wr;
1276
    int mode;
1277
    int free;
1278
    int reset;
1279
};
1280

    
1281
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
1282
{
1283
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1284
    int offset = addr - s->timer.base;
1285

    
1286
    switch (offset) {
1287
    case 0x00:        /* CNTL_TIMER */
1288
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
1289
                (s->timer.st << 7) | (s->free << 1);
1290

    
1291
    case 0x04:        /* READ_TIMER */
1292
        return omap_timer_read(&s->timer);
1293

    
1294
    case 0x08:        /* TIMER_MODE */
1295
        return s->mode << 15;
1296
    }
1297

    
1298
    OMAP_BAD_REG(addr);
1299
    return 0;
1300
}
1301

    
1302
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1303
                uint32_t value)
1304
{
1305
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1306
    int offset = addr - s->timer.base;
1307

    
1308
    switch (offset) {
1309
    case 0x00:        /* CNTL_TIMER */
1310
        omap_timer_sync(&s->timer);
1311
        s->timer.ptv = (value >> 9) & 7;
1312
        s->timer.ar = (value >> 8) & 1;
1313
        s->timer.st = (value >> 7) & 1;
1314
        s->free = (value >> 1) & 1;
1315
        omap_timer_update(&s->timer);
1316
        break;
1317

    
1318
    case 0x04:        /* LOAD_TIMER */
1319
        s->timer.reset_val = value & 0xffff;
1320
        break;
1321

    
1322
    case 0x08:        /* TIMER_MODE */
1323
        if (!s->mode && ((value >> 15) & 1))
1324
            omap_clk_get(s->timer.clk);
1325
        s->mode |= (value >> 15) & 1;
1326
        if (s->last_wr == 0xf5) {
1327
            if ((value & 0xff) == 0xa0) {
1328
                if (s->mode) {
1329
                    s->mode = 0;
1330
                    omap_clk_put(s->timer.clk);
1331
                }
1332
            } else {
1333
                /* XXX: on T|E hardware somehow this has no effect,
1334
                 * on Zire 71 it works as specified.  */
1335
                s->reset = 1;
1336
                qemu_system_reset_request();
1337
            }
1338
        }
1339
        s->last_wr = value & 0xff;
1340
        break;
1341

    
1342
    default:
1343
        OMAP_BAD_REG(addr);
1344
    }
1345
}
1346

    
1347
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
1348
    omap_badwidth_read16,
1349
    omap_wd_timer_read,
1350
    omap_badwidth_read16,
1351
};
1352

    
1353
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
1354
    omap_badwidth_write16,
1355
    omap_wd_timer_write,
1356
    omap_badwidth_write16,
1357
};
1358

    
1359
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
1360
{
1361
    qemu_del_timer(s->timer.timer);
1362
    if (!s->mode)
1363
        omap_clk_get(s->timer.clk);
1364
    s->mode = 1;
1365
    s->free = 1;
1366
    s->reset = 0;
1367
    s->timer.enable = 1;
1368
    s->timer.it_ena = 1;
1369
    s->timer.reset_val = 0xffff;
1370
    s->timer.val = 0;
1371
    s->timer.st = 0;
1372
    s->timer.ptv = 0;
1373
    s->timer.ar = 0;
1374
    omap_timer_update(&s->timer);
1375
}
1376

    
1377
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
1378
                qemu_irq irq, omap_clk clk)
1379
{
1380
    int iomemtype;
1381
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
1382
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
1383

    
1384
    s->timer.irq = irq;
1385
    s->timer.clk = clk;
1386
    s->timer.base = base;
1387
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1388
    omap_wd_timer_reset(s);
1389
    omap_timer_clk_setup(&s->timer);
1390

    
1391
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
1392
                    omap_wd_timer_writefn, s);
1393
    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
1394

    
1395
    return s;
1396
}
1397

    
1398
/* 32-kHz timer */
1399
struct omap_32khz_timer_s {
1400
    struct omap_mpu_timer_s timer;
1401
};
1402

    
1403
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
1404
{
1405
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1406
    int offset = addr & OMAP_MPUI_REG_MASK;
1407

    
1408
    switch (offset) {
1409
    case 0x00:        /* TVR */
1410
        return s->timer.reset_val;
1411

    
1412
    case 0x04:        /* TCR */
1413
        return omap_timer_read(&s->timer);
1414

    
1415
    case 0x08:        /* CR */
1416
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
1417

    
1418
    default:
1419
        break;
1420
    }
1421
    OMAP_BAD_REG(addr);
1422
    return 0;
1423
}
1424

    
1425
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1426
                uint32_t value)
1427
{
1428
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1429
    int offset = addr & OMAP_MPUI_REG_MASK;
1430

    
1431
    switch (offset) {
1432
    case 0x00:        /* TVR */
1433
        s->timer.reset_val = value & 0x00ffffff;
1434
        break;
1435

    
1436
    case 0x04:        /* TCR */
1437
        OMAP_RO_REG(addr);
1438
        break;
1439

    
1440
    case 0x08:        /* CR */
1441
        s->timer.ar = (value >> 3) & 1;
1442
        s->timer.it_ena = (value >> 2) & 1;
1443
        if (s->timer.st != (value & 1) || (value & 2)) {
1444
            omap_timer_sync(&s->timer);
1445
            s->timer.enable = value & 1;
1446
            s->timer.st = value & 1;
1447
            omap_timer_update(&s->timer);
1448
        }
1449
        break;
1450

    
1451
    default:
1452
        OMAP_BAD_REG(addr);
1453
    }
1454
}
1455

    
1456
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1457
    omap_badwidth_read32,
1458
    omap_badwidth_read32,
1459
    omap_os_timer_read,
1460
};
1461

    
1462
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1463
    omap_badwidth_write32,
1464
    omap_badwidth_write32,
1465
    omap_os_timer_write,
1466
};
1467

    
1468
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1469
{
1470
    qemu_del_timer(s->timer.timer);
1471
    s->timer.enable = 0;
1472
    s->timer.it_ena = 0;
1473
    s->timer.reset_val = 0x00ffffff;
1474
    s->timer.val = 0;
1475
    s->timer.st = 0;
1476
    s->timer.ptv = 0;
1477
    s->timer.ar = 1;
1478
}
1479

    
1480
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1481
                qemu_irq irq, omap_clk clk)
1482
{
1483
    int iomemtype;
1484
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1485
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1486

    
1487
    s->timer.irq = irq;
1488
    s->timer.clk = clk;
1489
    s->timer.base = base;
1490
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1491
    omap_os_timer_reset(s);
1492
    omap_timer_clk_setup(&s->timer);
1493

    
1494
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1495
                    omap_os_timer_writefn, s);
1496
    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
1497

    
1498
    return s;
1499
}
1500

    
1501
/* Ultra Low-Power Device Module */
1502
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1503
{
1504
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1505
    int offset = addr - s->ulpd_pm_base;
1506
    uint16_t ret;
1507

    
1508
    switch (offset) {
1509
    case 0x14:        /* IT_STATUS */
1510
        ret = s->ulpd_pm_regs[offset >> 2];
1511
        s->ulpd_pm_regs[offset >> 2] = 0;
1512
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1513
        return ret;
1514

    
1515
    case 0x18:        /* Reserved */
1516
    case 0x1c:        /* Reserved */
1517
    case 0x20:        /* Reserved */
1518
    case 0x28:        /* Reserved */
1519
    case 0x2c:        /* Reserved */
1520
        OMAP_BAD_REG(addr);
1521
    case 0x00:        /* COUNTER_32_LSB */
1522
    case 0x04:        /* COUNTER_32_MSB */
1523
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1524
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1525
    case 0x10:        /* GAUGING_CTRL */
1526
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1527
    case 0x30:        /* CLOCK_CTRL */
1528
    case 0x34:        /* SOFT_REQ */
1529
    case 0x38:        /* COUNTER_32_FIQ */
1530
    case 0x3c:        /* DPLL_CTRL */
1531
    case 0x40:        /* STATUS_REQ */
1532
        /* XXX: check clk::usecount state for every clock */
1533
    case 0x48:        /* LOCL_TIME */
1534
    case 0x4c:        /* APLL_CTRL */
1535
    case 0x50:        /* POWER_CTRL */
1536
        return s->ulpd_pm_regs[offset >> 2];
1537
    }
1538

    
1539
    OMAP_BAD_REG(addr);
1540
    return 0;
1541
}
1542

    
1543
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1544
                uint16_t diff, uint16_t value)
1545
{
1546
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
1547
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1548
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1549
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1550
}
1551

    
1552
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1553
                uint16_t diff, uint16_t value)
1554
{
1555
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1556
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1557
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1558
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1559
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1560
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1561
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1562
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1563
}
1564

    
1565
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1566
                uint32_t value)
1567
{
1568
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1569
    int offset = addr - s->ulpd_pm_base;
1570
    int64_t now, ticks;
1571
    int div, mult;
1572
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1573
    uint16_t diff;
1574

    
1575
    switch (offset) {
1576
    case 0x00:        /* COUNTER_32_LSB */
1577
    case 0x04:        /* COUNTER_32_MSB */
1578
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1579
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1580
    case 0x14:        /* IT_STATUS */
1581
    case 0x40:        /* STATUS_REQ */
1582
        OMAP_RO_REG(addr);
1583
        break;
1584

    
1585
    case 0x10:        /* GAUGING_CTRL */
1586
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1587
        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
1588
            now = qemu_get_clock(vm_clock);
1589

    
1590
            if (value & 1)
1591
                s->ulpd_gauge_start = now;
1592
            else {
1593
                now -= s->ulpd_gauge_start;
1594

    
1595
                /* 32-kHz ticks */
1596
                ticks = muldiv64(now, 32768, ticks_per_sec);
1597
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1598
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1599
                if (ticks >> 32)        /* OVERFLOW_32K */
1600
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1601

    
1602
                /* High frequency ticks */
1603
                ticks = muldiv64(now, 12000000, ticks_per_sec);
1604
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1605
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1606
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1607
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1608

    
1609
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
1610
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1611
            }
1612
        }
1613
        s->ulpd_pm_regs[offset >> 2] = value;
1614
        break;
1615

    
1616
    case 0x18:        /* Reserved */
1617
    case 0x1c:        /* Reserved */
1618
    case 0x20:        /* Reserved */
1619
    case 0x28:        /* Reserved */
1620
    case 0x2c:        /* Reserved */
1621
        OMAP_BAD_REG(addr);
1622
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1623
    case 0x38:        /* COUNTER_32_FIQ */
1624
    case 0x48:        /* LOCL_TIME */
1625
    case 0x50:        /* POWER_CTRL */
1626
        s->ulpd_pm_regs[offset >> 2] = value;
1627
        break;
1628

    
1629
    case 0x30:        /* CLOCK_CTRL */
1630
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1631
        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
1632
        omap_ulpd_clk_update(s, diff, value);
1633
        break;
1634

    
1635
    case 0x34:        /* SOFT_REQ */
1636
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1637
        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
1638
        omap_ulpd_req_update(s, diff, value);
1639
        break;
1640

    
1641
    case 0x3c:        /* DPLL_CTRL */
1642
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
1643
         * omitted altogether, probably a typo.  */
1644
        /* This register has identical semantics with DPLL(1:3) control
1645
         * registers, see omap_dpll_write() */
1646
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1647
        s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
1648
        if (diff & (0x3ff << 2)) {
1649
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1650
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1651
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1652
            } else {
1653
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1654
                mult = 1;
1655
            }
1656
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
1657
        }
1658

    
1659
        /* Enter the desired mode.  */
1660
        s->ulpd_pm_regs[offset >> 2] =
1661
                (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
1662
                ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
1663

    
1664
        /* Act as if the lock is restored.  */
1665
        s->ulpd_pm_regs[offset >> 2] |= 2;
1666
        break;
1667

    
1668
    case 0x4c:        /* APLL_CTRL */
1669
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1670
        s->ulpd_pm_regs[offset >> 2] = value & 0xf;
1671
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
1672
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1673
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
1674
        break;
1675

    
1676
    default:
1677
        OMAP_BAD_REG(addr);
1678
    }
1679
}
1680

    
1681
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1682
    omap_badwidth_read16,
1683
    omap_ulpd_pm_read,
1684
    omap_badwidth_read16,
1685
};
1686

    
1687
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1688
    omap_badwidth_write16,
1689
    omap_ulpd_pm_write,
1690
    omap_badwidth_write16,
1691
};
1692

    
1693
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
1694
{
1695
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
1696
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
1697
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
1698
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
1699
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
1700
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
1701
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
1702
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
1703
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
1704
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
1705
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
1706
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
1707
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
1708
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
1709
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
1710
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
1711
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
1712
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
1713
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
1714
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
1715
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
1716
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
1717
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
1718
}
1719

    
1720
static void omap_ulpd_pm_init(target_phys_addr_t base,
1721
                struct omap_mpu_state_s *mpu)
1722
{
1723
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1724
                    omap_ulpd_pm_writefn, mpu);
1725

    
1726
    mpu->ulpd_pm_base = base;
1727
    cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1728
    omap_ulpd_pm_reset(mpu);
1729
}
1730

    
1731
/* OMAP Pin Configuration */
1732
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1733
{
1734
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1735
    int offset = addr - s->pin_cfg_base;
1736

    
1737
    switch (offset) {
1738
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1739
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1740
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1741
        return s->func_mux_ctrl[offset >> 2];
1742

    
1743
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1744
        return s->comp_mode_ctrl[0];
1745

    
1746
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1747
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1748
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1749
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1750
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1751
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1752
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1753
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1754
    case 0x30:        /* FUNC_MUX_CTRL_B */
1755
    case 0x34:        /* FUNC_MUX_CTRL_C */
1756
    case 0x38:        /* FUNC_MUX_CTRL_D */
1757
        return s->func_mux_ctrl[(offset >> 2) - 1];
1758

    
1759
    case 0x40:        /* PULL_DWN_CTRL_0 */
1760
    case 0x44:        /* PULL_DWN_CTRL_1 */
1761
    case 0x48:        /* PULL_DWN_CTRL_2 */
1762
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1763
        return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1764

    
1765
    case 0x50:        /* GATE_INH_CTRL_0 */
1766
        return s->gate_inh_ctrl[0];
1767

    
1768
    case 0x60:        /* VOLTAGE_CTRL_0 */
1769
        return s->voltage_ctrl[0];
1770

    
1771
    case 0x70:        /* TEST_DBG_CTRL_0 */
1772
        return s->test_dbg_ctrl[0];
1773

    
1774
    case 0x80:        /* MOD_CONF_CTRL_0 */
1775
        return s->mod_conf_ctrl[0];
1776
    }
1777

    
1778
    OMAP_BAD_REG(addr);
1779
    return 0;
1780
}
1781

    
1782
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1783
                uint32_t diff, uint32_t value)
1784
{
1785
    if (s->compat1509) {
1786
        if (diff & (1 << 9))                        /* BLUETOOTH */
1787
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1788
                            (~value >> 9) & 1);
1789
        if (diff & (1 << 7))                        /* USB.CLKO */
1790
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
1791
                            (value >> 7) & 1);
1792
    }
1793
}
1794

    
1795
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1796
                uint32_t diff, uint32_t value)
1797
{
1798
    if (s->compat1509) {
1799
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
1800
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1801
                            (value >> 31) & 1);
1802
        if (diff & (1 << 1))                        /* CLK32K */
1803
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1804
                            (~value >> 1) & 1);
1805
    }
1806
}
1807

    
1808
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1809
                uint32_t diff, uint32_t value)
1810
{
1811
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
1812
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1813
                         omap_findclk(s, ((value >> 31) & 1) ?
1814
                                 "ck_48m" : "armper_ck"));
1815
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
1816
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1817
                         omap_findclk(s, ((value >> 30) & 1) ?
1818
                                 "ck_48m" : "armper_ck"));
1819
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
1820
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1821
                         omap_findclk(s, ((value >> 29) & 1) ?
1822
                                 "ck_48m" : "armper_ck"));
1823
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
1824
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1825
                         omap_findclk(s, ((value >> 23) & 1) ?
1826
                                 "ck_48m" : "armper_ck"));
1827
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
1828
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1829
                         omap_findclk(s, ((value >> 12) & 1) ?
1830
                                 "ck_48m" : "armper_ck"));
1831
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1832
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1833
}
1834

    
1835
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1836
                uint32_t value)
1837
{
1838
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1839
    int offset = addr - s->pin_cfg_base;
1840
    uint32_t diff;
1841

    
1842
    switch (offset) {
1843
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1844
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1845
        s->func_mux_ctrl[offset >> 2] = value;
1846
        omap_pin_funcmux0_update(s, diff, value);
1847
        return;
1848

    
1849
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1850
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1851
        s->func_mux_ctrl[offset >> 2] = value;
1852
        omap_pin_funcmux1_update(s, diff, value);
1853
        return;
1854

    
1855
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1856
        s->func_mux_ctrl[offset >> 2] = value;
1857
        return;
1858

    
1859
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1860
        s->comp_mode_ctrl[0] = value;
1861
        s->compat1509 = (value != 0x0000eaef);
1862
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1863
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1864
        return;
1865

    
1866
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1867
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1868
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1869
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1870
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1871
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1872
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1873
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1874
    case 0x30:        /* FUNC_MUX_CTRL_B */
1875
    case 0x34:        /* FUNC_MUX_CTRL_C */
1876
    case 0x38:        /* FUNC_MUX_CTRL_D */
1877
        s->func_mux_ctrl[(offset >> 2) - 1] = value;
1878
        return;
1879

    
1880
    case 0x40:        /* PULL_DWN_CTRL_0 */
1881
    case 0x44:        /* PULL_DWN_CTRL_1 */
1882
    case 0x48:        /* PULL_DWN_CTRL_2 */
1883
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1884
        s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1885
        return;
1886

    
1887
    case 0x50:        /* GATE_INH_CTRL_0 */
1888
        s->gate_inh_ctrl[0] = value;
1889
        return;
1890

    
1891
    case 0x60:        /* VOLTAGE_CTRL_0 */
1892
        s->voltage_ctrl[0] = value;
1893
        return;
1894

    
1895
    case 0x70:        /* TEST_DBG_CTRL_0 */
1896
        s->test_dbg_ctrl[0] = value;
1897
        return;
1898

    
1899
    case 0x80:        /* MOD_CONF_CTRL_0 */
1900
        diff = s->mod_conf_ctrl[0] ^ value;
1901
        s->mod_conf_ctrl[0] = value;
1902
        omap_pin_modconf1_update(s, diff, value);
1903
        return;
1904

    
1905
    default:
1906
        OMAP_BAD_REG(addr);
1907
    }
1908
}
1909

    
1910
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1911
    omap_badwidth_read32,
1912
    omap_badwidth_read32,
1913
    omap_pin_cfg_read,
1914
};
1915

    
1916
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1917
    omap_badwidth_write32,
1918
    omap_badwidth_write32,
1919
    omap_pin_cfg_write,
1920
};
1921

    
1922
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1923
{
1924
    /* Start in Compatibility Mode.  */
1925
    mpu->compat1509 = 1;
1926
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1927
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1928
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1929
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1930
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1931
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1932
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1933
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1934
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1935
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1936
}
1937

    
1938
static void omap_pin_cfg_init(target_phys_addr_t base,
1939
                struct omap_mpu_state_s *mpu)
1940
{
1941
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1942
                    omap_pin_cfg_writefn, mpu);
1943

    
1944
    mpu->pin_cfg_base = base;
1945
    cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1946
    omap_pin_cfg_reset(mpu);
1947
}
1948

    
1949
/* Device Identification, Die Identification */
1950
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1951
{
1952
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1953

    
1954
    switch (addr) {
1955
    case 0xfffe1800:        /* DIE_ID_LSB */
1956
        return 0xc9581f0e;
1957
    case 0xfffe1804:        /* DIE_ID_MSB */
1958
        return 0xa8858bfa;
1959

    
1960
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
1961
        return 0x00aaaafc;
1962
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
1963
        return 0xcafeb574;
1964

    
1965
    case 0xfffed400:        /* JTAG_ID_LSB */
1966
        switch (s->mpu_model) {
1967
        case omap310:
1968
            return 0x03310315;
1969
        case omap1510:
1970
            return 0x03310115;
1971
        }
1972
        break;
1973

    
1974
    case 0xfffed404:        /* JTAG_ID_MSB */
1975
        switch (s->mpu_model) {
1976
        case omap310:
1977
            return 0xfb57402f;
1978
        case omap1510:
1979
            return 0xfb47002f;
1980
        }
1981
        break;
1982
    }
1983

    
1984
    OMAP_BAD_REG(addr);
1985
    return 0;
1986
}
1987

    
1988
static void omap_id_write(void *opaque, target_phys_addr_t addr,
1989
                uint32_t value)
1990
{
1991
    OMAP_BAD_REG(addr);
1992
}
1993

    
1994
static CPUReadMemoryFunc *omap_id_readfn[] = {
1995
    omap_badwidth_read32,
1996
    omap_badwidth_read32,
1997
    omap_id_read,
1998
};
1999

    
2000
static CPUWriteMemoryFunc *omap_id_writefn[] = {
2001
    omap_badwidth_write32,
2002
    omap_badwidth_write32,
2003
    omap_id_write,
2004
};
2005

    
2006
static void omap_id_init(struct omap_mpu_state_s *mpu)
2007
{
2008
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
2009
                    omap_id_writefn, mpu);
2010
    cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
2011
    cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
2012
    if (!cpu_is_omap15xx(mpu))
2013
        cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
2014
}
2015

    
2016
/* MPUI Control (Dummy) */
2017
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
2018
{
2019
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2020
    int offset = addr - s->mpui_base;
2021

    
2022
    switch (offset) {
2023
    case 0x00:        /* CTRL */
2024
        return s->mpui_ctrl;
2025
    case 0x04:        /* DEBUG_ADDR */
2026
        return 0x01ffffff;
2027
    case 0x08:        /* DEBUG_DATA */
2028
        return 0xffffffff;
2029
    case 0x0c:        /* DEBUG_FLAG */
2030
        return 0x00000800;
2031
    case 0x10:        /* STATUS */
2032
        return 0x00000000;
2033

    
2034
    /* Not in OMAP310 */
2035
    case 0x14:        /* DSP_STATUS */
2036
    case 0x18:        /* DSP_BOOT_CONFIG */
2037
        return 0x00000000;
2038
    case 0x1c:        /* DSP_MPUI_CONFIG */
2039
        return 0x0000ffff;
2040
    }
2041

    
2042
    OMAP_BAD_REG(addr);
2043
    return 0;
2044
}
2045

    
2046
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2047
                uint32_t value)
2048
{
2049
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2050
    int offset = addr - s->mpui_base;
2051

    
2052
    switch (offset) {
2053
    case 0x00:        /* CTRL */
2054
        s->mpui_ctrl = value & 0x007fffff;
2055
        break;
2056

    
2057
    case 0x04:        /* DEBUG_ADDR */
2058
    case 0x08:        /* DEBUG_DATA */
2059
    case 0x0c:        /* DEBUG_FLAG */
2060
    case 0x10:        /* STATUS */
2061
    /* Not in OMAP310 */
2062
    case 0x14:        /* DSP_STATUS */
2063
        OMAP_RO_REG(addr);
2064
    case 0x18:        /* DSP_BOOT_CONFIG */
2065
    case 0x1c:        /* DSP_MPUI_CONFIG */
2066
        break;
2067

    
2068
    default:
2069
        OMAP_BAD_REG(addr);
2070
    }
2071
}
2072

    
2073
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2074
    omap_badwidth_read32,
2075
    omap_badwidth_read32,
2076
    omap_mpui_read,
2077
};
2078

    
2079
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2080
    omap_badwidth_write32,
2081
    omap_badwidth_write32,
2082
    omap_mpui_write,
2083
};
2084

    
2085
static void omap_mpui_reset(struct omap_mpu_state_s *s)
2086
{
2087
    s->mpui_ctrl = 0x0003ff1b;
2088
}
2089

    
2090
static void omap_mpui_init(target_phys_addr_t base,
2091
                struct omap_mpu_state_s *mpu)
2092
{
2093
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2094
                    omap_mpui_writefn, mpu);
2095

    
2096
    mpu->mpui_base = base;
2097
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2098

    
2099
    omap_mpui_reset(mpu);
2100
}
2101

    
2102
/* TIPB Bridges */
2103
struct omap_tipb_bridge_s {
2104
    target_phys_addr_t base;
2105
    qemu_irq abort;
2106

    
2107
    int width_intr;
2108
    uint16_t control;
2109
    uint16_t alloc;
2110
    uint16_t buffer;
2111
    uint16_t enh_control;
2112
};
2113

    
2114
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
2115
{
2116
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2117
    int offset = addr - s->base;
2118

    
2119
    switch (offset) {
2120
    case 0x00:        /* TIPB_CNTL */
2121
        return s->control;
2122
    case 0x04:        /* TIPB_BUS_ALLOC */
2123
        return s->alloc;
2124
    case 0x08:        /* MPU_TIPB_CNTL */
2125
        return s->buffer;
2126
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2127
        return s->enh_control;
2128
    case 0x10:        /* ADDRESS_DBG */
2129
    case 0x14:        /* DATA_DEBUG_LOW */
2130
    case 0x18:        /* DATA_DEBUG_HIGH */
2131
        return 0xffff;
2132
    case 0x1c:        /* DEBUG_CNTR_SIG */
2133
        return 0x00f8;
2134
    }
2135

    
2136
    OMAP_BAD_REG(addr);
2137
    return 0;
2138
}
2139

    
2140
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
2141
                uint32_t value)
2142
{
2143
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2144
    int offset = addr - s->base;
2145

    
2146
    switch (offset) {
2147
    case 0x00:        /* TIPB_CNTL */
2148
        s->control = value & 0xffff;
2149
        break;
2150

    
2151
    case 0x04:        /* TIPB_BUS_ALLOC */
2152
        s->alloc = value & 0x003f;
2153
        break;
2154

    
2155
    case 0x08:        /* MPU_TIPB_CNTL */
2156
        s->buffer = value & 0x0003;
2157
        break;
2158

    
2159
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2160
        s->width_intr = !(value & 2);
2161
        s->enh_control = value & 0x000f;
2162
        break;
2163

    
2164
    case 0x10:        /* ADDRESS_DBG */
2165
    case 0x14:        /* DATA_DEBUG_LOW */
2166
    case 0x18:        /* DATA_DEBUG_HIGH */
2167
    case 0x1c:        /* DEBUG_CNTR_SIG */
2168
        OMAP_RO_REG(addr);
2169
        break;
2170

    
2171
    default:
2172
        OMAP_BAD_REG(addr);
2173
    }
2174
}
2175

    
2176
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2177
    omap_badwidth_read16,
2178
    omap_tipb_bridge_read,
2179
    omap_tipb_bridge_read,
2180
};
2181

    
2182
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2183
    omap_badwidth_write16,
2184
    omap_tipb_bridge_write,
2185
    omap_tipb_bridge_write,
2186
};
2187

    
2188
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2189
{
2190
    s->control = 0xffff;
2191
    s->alloc = 0x0009;
2192
    s->buffer = 0x0000;
2193
    s->enh_control = 0x000f;
2194
}
2195

    
2196
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2197
                qemu_irq abort_irq, omap_clk clk)
2198
{
2199
    int iomemtype;
2200
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2201
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2202

    
2203
    s->abort = abort_irq;
2204
    s->base = base;
2205
    omap_tipb_bridge_reset(s);
2206

    
2207
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
2208
                    omap_tipb_bridge_writefn, s);
2209
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2210

    
2211
    return s;
2212
}
2213

    
2214
/* Dummy Traffic Controller's Memory Interface */
2215
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2216
{
2217
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2218
    int offset = addr - s->tcmi_base;
2219
    uint32_t ret;
2220

    
2221
    switch (offset) {
2222
    case 0x00:        /* IMIF_PRIO */
2223
    case 0x04:        /* EMIFS_PRIO */
2224
    case 0x08:        /* EMIFF_PRIO */
2225
    case 0x0c:        /* EMIFS_CONFIG */
2226
    case 0x10:        /* EMIFS_CS0_CONFIG */
2227
    case 0x14:        /* EMIFS_CS1_CONFIG */
2228
    case 0x18:        /* EMIFS_CS2_CONFIG */
2229
    case 0x1c:        /* EMIFS_CS3_CONFIG */
2230
    case 0x24:        /* EMIFF_MRS */
2231
    case 0x28:        /* TIMEOUT1 */
2232
    case 0x2c:        /* TIMEOUT2 */
2233
    case 0x30:        /* TIMEOUT3 */
2234
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
2235
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
2236
        return s->tcmi_regs[offset >> 2];
2237

    
2238
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
2239
        ret = s->tcmi_regs[offset >> 2];
2240
        s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2241
        /* XXX: We can try using the VGA_DIRTY flag for this */
2242
        return ret;
2243
    }
2244

    
2245
    OMAP_BAD_REG(addr);
2246
    return 0;
2247
}
2248

    
2249
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2250
                uint32_t value)
2251
{
2252
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2253
    int offset = addr - s->tcmi_base;
2254

    
2255
    switch (offset) {
2256
    case 0x00:        /* IMIF_PRIO */
2257
    case 0x04:        /* EMIFS_PRIO */
2258
    case 0x08:        /* EMIFF_PRIO */
2259
    case 0x10:        /* EMIFS_CS0_CONFIG */
2260
    case 0x14:        /* EMIFS_CS1_CONFIG */
2261
    case 0x18:        /* EMIFS_CS2_CONFIG */
2262
    case 0x1c:        /* EMIFS_CS3_CONFIG */
2263
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
2264
    case 0x24:        /* EMIFF_MRS */
2265
    case 0x28:        /* TIMEOUT1 */
2266
    case 0x2c:        /* TIMEOUT2 */
2267
    case 0x30:        /* TIMEOUT3 */
2268
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
2269
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
2270
        s->tcmi_regs[offset >> 2] = value;
2271
        break;
2272
    case 0x0c:        /* EMIFS_CONFIG */
2273
        s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
2274
        break;
2275

    
2276
    default:
2277
        OMAP_BAD_REG(addr);
2278
    }
2279
}
2280

    
2281
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2282
    omap_badwidth_read32,
2283
    omap_badwidth_read32,
2284
    omap_tcmi_read,
2285
};
2286

    
2287
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2288
    omap_badwidth_write32,
2289
    omap_badwidth_write32,
2290
    omap_tcmi_write,
2291
};
2292

    
2293
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
2294
{
2295
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
2296
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
2297
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
2298
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
2299
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
2300
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
2301
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
2302
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
2303
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
2304
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
2305
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
2306
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
2307
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
2308
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
2309
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
2310
}
2311

    
2312
static void omap_tcmi_init(target_phys_addr_t base,
2313
                struct omap_mpu_state_s *mpu)
2314
{
2315
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2316
                    omap_tcmi_writefn, mpu);
2317

    
2318
    mpu->tcmi_base = base;
2319
    cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2320
    omap_tcmi_reset(mpu);
2321
}
2322

    
2323
/* Digital phase-locked loops control */
2324
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2325
{
2326
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2327
    int offset = addr - s->base;
2328

    
2329
    if (offset == 0x00)        /* CTL_REG */
2330
        return s->mode;
2331

    
2332
    OMAP_BAD_REG(addr);
2333
    return 0;
2334
}
2335

    
2336
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2337
                uint32_t value)
2338
{
2339
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2340
    uint16_t diff;
2341
    int offset = addr - s->base;
2342
    static const int bypass_div[4] = { 1, 2, 4, 4 };
2343
    int div, mult;
2344

    
2345
    if (offset == 0x00) {        /* CTL_REG */
2346
        /* See omap_ulpd_pm_write() too */
2347
        diff = s->mode & value;
2348
        s->mode = value & 0x2fff;
2349
        if (diff & (0x3ff << 2)) {
2350
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
2351
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
2352
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
2353
            } else {
2354
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
2355
                mult = 1;
2356
            }
2357
            omap_clk_setrate(s->dpll, div, mult);
2358
        }
2359

    
2360
        /* Enter the desired mode.  */
2361
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
2362

    
2363
        /* Act as if the lock is restored.  */
2364
        s->mode |= 2;
2365
    } else {
2366
        OMAP_BAD_REG(addr);
2367
    }
2368
}
2369

    
2370
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
2371
    omap_badwidth_read16,
2372
    omap_dpll_read,
2373
    omap_badwidth_read16,
2374
};
2375

    
2376
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
2377
    omap_badwidth_write16,
2378
    omap_dpll_write,
2379
    omap_badwidth_write16,
2380
};
2381

    
2382
static void omap_dpll_reset(struct dpll_ctl_s *s)
2383
{
2384
    s->mode = 0x2002;
2385
    omap_clk_setrate(s->dpll, 1, 1);
2386
}
2387

    
2388
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
2389
                omap_clk clk)
2390
{
2391
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
2392
                    omap_dpll_writefn, s);
2393

    
2394
    s->base = base;
2395
    s->dpll = clk;
2396
    omap_dpll_reset(s);
2397

    
2398
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2399
}
2400

    
2401
/* UARTs */
2402
struct omap_uart_s {
2403
    SerialState *serial; /* TODO */
2404
};
2405

    
2406
static void omap_uart_reset(struct omap_uart_s *s)
2407
{
2408
}
2409

    
2410
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2411
                qemu_irq irq, omap_clk clk, CharDriverState *chr)
2412
{
2413
    struct omap_uart_s *s = (struct omap_uart_s *)
2414
            qemu_mallocz(sizeof(struct omap_uart_s));
2415
    if (chr)
2416
        s->serial = serial_mm_init(base, 2, irq, chr, 1);
2417
    return s;
2418
}
2419

    
2420
/* MPU Clock/Reset/Power Mode Control */
2421
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2422
{
2423
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2424
    int offset = addr - s->clkm.mpu_base;
2425

    
2426
    switch (offset) {
2427
    case 0x00:        /* ARM_CKCTL */
2428
        return s->clkm.arm_ckctl;
2429

    
2430
    case 0x04:        /* ARM_IDLECT1 */
2431
        return s->clkm.arm_idlect1;
2432

    
2433
    case 0x08:        /* ARM_IDLECT2 */
2434
        return s->clkm.arm_idlect2;
2435

    
2436
    case 0x0c:        /* ARM_EWUPCT */
2437
        return s->clkm.arm_ewupct;
2438

    
2439
    case 0x10:        /* ARM_RSTCT1 */
2440
        return s->clkm.arm_rstct1;
2441

    
2442
    case 0x14:        /* ARM_RSTCT2 */
2443
        return s->clkm.arm_rstct2;
2444

    
2445
    case 0x18:        /* ARM_SYSST */
2446
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
2447

    
2448
    case 0x1c:        /* ARM_CKOUT1 */
2449
        return s->clkm.arm_ckout1;
2450

    
2451
    case 0x20:        /* ARM_CKOUT2 */
2452
        break;
2453
    }
2454

    
2455
    OMAP_BAD_REG(addr);
2456
    return 0;
2457
}
2458

    
2459
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2460
                uint16_t diff, uint16_t value)
2461
{
2462
    omap_clk clk;
2463

    
2464
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
2465
        if (value & (1 << 14))
2466
            /* Reserved */;
2467
        else {
2468
            clk = omap_findclk(s, "arminth_ck");
2469
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2470
        }
2471
    }
2472
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
2473
        clk = omap_findclk(s, "armtim_ck");
2474
        if (value & (1 << 12))
2475
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
2476
        else
2477
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2478
    }
2479
    /* XXX: en_dspck */
2480
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
2481
        clk = omap_findclk(s, "dspmmu_ck");
2482
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
2483
    }
2484
    if (diff & (3 << 8)) {                                /* TCDIV */
2485
        clk = omap_findclk(s, "tc_ck");
2486
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2487
    }
2488
    if (diff & (3 << 6)) {                                /* DSPDIV */
2489
        clk = omap_findclk(s, "dsp_ck");
2490
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2491
    }
2492
    if (diff & (3 << 4)) {                                /* ARMDIV */
2493
        clk = omap_findclk(s, "arm_ck");
2494
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2495
    }
2496
    if (diff & (3 << 2)) {                                /* LCDDIV */
2497
        clk = omap_findclk(s, "lcd_ck");
2498
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2499
    }
2500
    if (diff & (3 << 0)) {                                /* PERDIV */
2501
        clk = omap_findclk(s, "armper_ck");
2502
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2503
    }
2504
}
2505

    
2506
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2507
                uint16_t diff, uint16_t value)
2508
{
2509
    omap_clk clk;
2510

    
2511
    if (value & (1 << 11))                                /* SETARM_IDLE */
2512
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2513
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2514
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2515

    
2516
#define SET_CANIDLE(clock, bit)                                \
2517
    if (diff & (1 << bit)) {                                \
2518
        clk = omap_findclk(s, clock);                        \
2519
        omap_clk_canidle(clk, (value >> bit) & 1);        \
2520
    }
2521
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
2522
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
2523
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
2524
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
2525
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
2526
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
2527
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
2528
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
2529
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
2530
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
2531
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
2532
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
2533
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
2534
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
2535
}
2536

    
2537
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2538
                uint16_t diff, uint16_t value)
2539
{
2540
    omap_clk clk;
2541

    
2542
#define SET_ONOFF(clock, bit)                                \
2543
    if (diff & (1 << bit)) {                                \
2544
        clk = omap_findclk(s, clock);                        \
2545
        omap_clk_onoff(clk, (value >> bit) & 1);        \
2546
    }
2547
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
2548
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
2549
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
2550
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
2551
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
2552
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
2553
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
2554
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
2555
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
2556
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
2557
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
2558
}
2559

    
2560
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2561
                uint16_t diff, uint16_t value)
2562
{
2563
    omap_clk clk;
2564

    
2565
    if (diff & (3 << 4)) {                                /* TCLKOUT */
2566
        clk = omap_findclk(s, "tclk_out");
2567
        switch ((value >> 4) & 3) {
2568
        case 1:
2569
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
2570
            omap_clk_onoff(clk, 1);
2571
            break;
2572
        case 2:
2573
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2574
            omap_clk_onoff(clk, 1);
2575
            break;
2576
        default:
2577
            omap_clk_onoff(clk, 0);
2578
        }
2579
    }
2580
    if (diff & (3 << 2)) {                                /* DCLKOUT */
2581
        clk = omap_findclk(s, "dclk_out");
2582
        switch ((value >> 2) & 3) {
2583
        case 0:
2584
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
2585
            break;
2586
        case 1:
2587
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
2588
            break;
2589
        case 2:
2590
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
2591
            break;
2592
        case 3:
2593
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2594
            break;
2595
        }
2596
    }
2597
    if (diff & (3 << 0)) {                                /* ACLKOUT */
2598
        clk = omap_findclk(s, "aclk_out");
2599
        switch ((value >> 0) & 3) {
2600
        case 1:
2601
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2602
            omap_clk_onoff(clk, 1);
2603
            break;
2604
        case 2:
2605
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
2606
            omap_clk_onoff(clk, 1);
2607
            break;
2608
        case 3:
2609
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2610
            omap_clk_onoff(clk, 1);
2611
            break;
2612
        default:
2613
            omap_clk_onoff(clk, 0);
2614
        }
2615
    }
2616
}
2617

    
2618
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2619
                uint32_t value)
2620
{
2621
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2622
    int offset = addr - s->clkm.mpu_base;
2623
    uint16_t diff;
2624
    omap_clk clk;
2625
    static const char *clkschemename[8] = {
2626
        "fully synchronous", "fully asynchronous", "synchronous scalable",
2627
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2628
    };
2629

    
2630
    switch (offset) {
2631
    case 0x00:        /* ARM_CKCTL */
2632
        diff = s->clkm.arm_ckctl ^ value;
2633
        s->clkm.arm_ckctl = value & 0x7fff;
2634
        omap_clkm_ckctl_update(s, diff, value);
2635
        return;
2636

    
2637
    case 0x04:        /* ARM_IDLECT1 */
2638
        diff = s->clkm.arm_idlect1 ^ value;
2639
        s->clkm.arm_idlect1 = value & 0x0fff;
2640
        omap_clkm_idlect1_update(s, diff, value);
2641
        return;
2642

    
2643
    case 0x08:        /* ARM_IDLECT2 */
2644
        diff = s->clkm.arm_idlect2 ^ value;
2645
        s->clkm.arm_idlect2 = value & 0x07ff;
2646
        omap_clkm_idlect2_update(s, diff, value);
2647
        return;
2648

    
2649
    case 0x0c:        /* ARM_EWUPCT */
2650
        diff = s->clkm.arm_ewupct ^ value;
2651
        s->clkm.arm_ewupct = value & 0x003f;
2652
        return;
2653

    
2654
    case 0x10:        /* ARM_RSTCT1 */
2655
        diff = s->clkm.arm_rstct1 ^ value;
2656
        s->clkm.arm_rstct1 = value & 0x0007;
2657
        if (value & 9) {
2658
            qemu_system_reset_request();
2659
            s->clkm.cold_start = 0xa;
2660
        }
2661
        if (diff & ~value & 4) {                                /* DSP_RST */
2662
            omap_mpui_reset(s);
2663
            omap_tipb_bridge_reset(s->private_tipb);
2664
            omap_tipb_bridge_reset(s->public_tipb);
2665
        }
2666
        if (diff & 2) {                                                /* DSP_EN */
2667
            clk = omap_findclk(s, "dsp_ck");
2668
            omap_clk_canidle(clk, (~value >> 1) & 1);
2669
        }
2670
        return;
2671

    
2672
    case 0x14:        /* ARM_RSTCT2 */
2673
        s->clkm.arm_rstct2 = value & 0x0001;
2674
        return;
2675

    
2676
    case 0x18:        /* ARM_SYSST */
2677
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2678
            s->clkm.clocking_scheme = (value >> 11) & 7;
2679
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2680
                            clkschemename[s->clkm.clocking_scheme]);
2681
        }
2682
        s->clkm.cold_start &= value & 0x3f;
2683
        return;
2684

    
2685
    case 0x1c:        /* ARM_CKOUT1 */
2686
        diff = s->clkm.arm_ckout1 ^ value;
2687
        s->clkm.arm_ckout1 = value & 0x003f;
2688
        omap_clkm_ckout1_update(s, diff, value);
2689
        return;
2690

    
2691
    case 0x20:        /* ARM_CKOUT2 */
2692
    default:
2693
        OMAP_BAD_REG(addr);
2694
    }
2695
}
2696

    
2697
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2698
    omap_badwidth_read16,
2699
    omap_clkm_read,
2700
    omap_badwidth_read16,
2701
};
2702

    
2703
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2704
    omap_badwidth_write16,
2705
    omap_clkm_write,
2706
    omap_badwidth_write16,
2707
};
2708

    
2709
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2710
{
2711
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2712
    int offset = addr - s->clkm.dsp_base;
2713

    
2714
    switch (offset) {
2715
    case 0x04:        /* DSP_IDLECT1 */
2716
        return s->clkm.dsp_idlect1;
2717

    
2718
    case 0x08:        /* DSP_IDLECT2 */
2719
        return s->clkm.dsp_idlect2;
2720

    
2721
    case 0x14:        /* DSP_RSTCT2 */
2722
        return s->clkm.dsp_rstct2;
2723

    
2724
    case 0x18:        /* DSP_SYSST */
2725
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
2726
                (s->env->halted << 6);        /* Quite useless... */
2727
    }
2728

    
2729
    OMAP_BAD_REG(addr);
2730
    return 0;
2731
}
2732

    
2733
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2734
                uint16_t diff, uint16_t value)
2735
{
2736
    omap_clk clk;
2737

    
2738
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2739
}
2740

    
2741
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2742
                uint16_t diff, uint16_t value)
2743
{
2744
    omap_clk clk;
2745

    
2746
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2747
}
2748

    
2749
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2750
                uint32_t value)
2751
{
2752
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2753
    int offset = addr - s->clkm.dsp_base;
2754
    uint16_t diff;
2755

    
2756
    switch (offset) {
2757
    case 0x04:        /* DSP_IDLECT1 */
2758
        diff = s->clkm.dsp_idlect1 ^ value;
2759
        s->clkm.dsp_idlect1 = value & 0x01f7;
2760
        omap_clkdsp_idlect1_update(s, diff, value);
2761
        break;
2762

    
2763
    case 0x08:        /* DSP_IDLECT2 */
2764
        s->clkm.dsp_idlect2 = value & 0x0037;
2765
        diff = s->clkm.dsp_idlect1 ^ value;
2766
        omap_clkdsp_idlect2_update(s, diff, value);
2767
        break;
2768

    
2769
    case 0x14:        /* DSP_RSTCT2 */
2770
        s->clkm.dsp_rstct2 = value & 0x0001;
2771
        break;
2772

    
2773
    case 0x18:        /* DSP_SYSST */
2774
        s->clkm.cold_start &= value & 0x3f;
2775
        break;
2776

    
2777
    default:
2778
        OMAP_BAD_REG(addr);
2779
    }
2780
}
2781

    
2782
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2783
    omap_badwidth_read16,
2784
    omap_clkdsp_read,
2785
    omap_badwidth_read16,
2786
};
2787

    
2788
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2789
    omap_badwidth_write16,
2790
    omap_clkdsp_write,
2791
    omap_badwidth_write16,
2792
};
2793

    
2794
static void omap_clkm_reset(struct omap_mpu_state_s *s)
2795
{
2796
    if (s->wdt && s->wdt->reset)
2797
        s->clkm.cold_start = 0x6;
2798
    s->clkm.clocking_scheme = 0;
2799
    omap_clkm_ckctl_update(s, ~0, 0x3000);
2800
    s->clkm.arm_ckctl = 0x3000;
2801
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
2802
    s->clkm.arm_idlect1 = 0x0400;
2803
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
2804
    s->clkm.arm_idlect2 = 0x0100;
2805
    s->clkm.arm_ewupct = 0x003f;
2806
    s->clkm.arm_rstct1 = 0x0000;
2807
    s->clkm.arm_rstct2 = 0x0000;
2808
    s->clkm.arm_ckout1 = 0x0015;
2809
    s->clkm.dpll1_mode = 0x2002;
2810
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2811
    s->clkm.dsp_idlect1 = 0x0040;
2812
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2813
    s->clkm.dsp_idlect2 = 0x0000;
2814
    s->clkm.dsp_rstct2 = 0x0000;
2815
}
2816

    
2817
static void omap_clkm_init(target_phys_addr_t mpu_base,
2818
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2819
{
2820
    int iomemtype[2] = {
2821
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2822
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2823
    };
2824

    
2825
    s->clkm.mpu_base = mpu_base;
2826
    s->clkm.dsp_base = dsp_base;
2827
    s->clkm.arm_idlect1 = 0x03ff;
2828
    s->clkm.arm_idlect2 = 0x0100;
2829
    s->clkm.dsp_idlect1 = 0x0002;
2830
    omap_clkm_reset(s);
2831
    s->clkm.cold_start = 0x3a;
2832

    
2833
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2834
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2835
}
2836

    
2837
/* MPU I/O */
2838
struct omap_mpuio_s {
2839
    target_phys_addr_t base;
2840
    qemu_irq irq;
2841
    qemu_irq kbd_irq;
2842
    qemu_irq *in;
2843
    qemu_irq handler[16];
2844
    qemu_irq wakeup;
2845

    
2846
    uint16_t inputs;
2847
    uint16_t outputs;
2848
    uint16_t dir;
2849
    uint16_t edge;
2850
    uint16_t mask;
2851
    uint16_t ints;
2852

    
2853
    uint16_t debounce;
2854
    uint16_t latch;
2855
    uint8_t event;
2856

    
2857
    uint8_t buttons[5];
2858
    uint8_t row_latch;
2859
    uint8_t cols;
2860
    int kbd_mask;
2861
    int clk;
2862
};
2863

    
2864
static void omap_mpuio_set(void *opaque, int line, int level)
2865
{
2866
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2867
    uint16_t prev = s->inputs;
2868

    
2869
    if (level)
2870
        s->inputs |= 1 << line;
2871
    else
2872
        s->inputs &= ~(1 << line);
2873

    
2874
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2875
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2876
            s->ints |= 1 << line;
2877
            qemu_irq_raise(s->irq);
2878
            /* TODO: wakeup */
2879
        }
2880
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
2881
                (s->event >> 1) == line)        /* PIN_SELECT */
2882
            s->latch = s->inputs;
2883
    }
2884
}
2885

    
2886
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2887
{
2888
    int i;
2889
    uint8_t *row, rows = 0, cols = ~s->cols;
2890

    
2891
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2892
        if (*row & cols)
2893
            rows |= i;
2894

    
2895
    qemu_set_irq(s->kbd_irq, rows && ~s->kbd_mask && s->clk);
2896
    s->row_latch = rows ^ 0x1f;
2897
}
2898

    
2899
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2900
{
2901
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2902
    int offset = addr & OMAP_MPUI_REG_MASK;
2903
    uint16_t ret;
2904

    
2905
    switch (offset) {
2906
    case 0x00:        /* INPUT_LATCH */
2907
        return s->inputs;
2908

    
2909
    case 0x04:        /* OUTPUT_REG */
2910
        return s->outputs;
2911

    
2912
    case 0x08:        /* IO_CNTL */
2913
        return s->dir;
2914

    
2915
    case 0x10:        /* KBR_LATCH */
2916
        return s->row_latch;
2917

    
2918
    case 0x14:        /* KBC_REG */
2919
        return s->cols;
2920

    
2921
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2922
        return s->event;
2923

    
2924
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2925
        return s->edge;
2926

    
2927
    case 0x20:        /* KBD_INT */
2928
        return (s->row_latch != 0x1f) && !s->kbd_mask;
2929

    
2930
    case 0x24:        /* GPIO_INT */
2931
        ret = s->ints;
2932
        s->ints &= s->mask;
2933
        if (ret)
2934
            qemu_irq_lower(s->irq);
2935
        return ret;
2936

    
2937
    case 0x28:        /* KBD_MASKIT */
2938
        return s->kbd_mask;
2939

    
2940
    case 0x2c:        /* GPIO_MASKIT */
2941
        return s->mask;
2942

    
2943
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2944
        return s->debounce;
2945

    
2946
    case 0x34:        /* GPIO_LATCH_REG */
2947
        return s->latch;
2948
    }
2949

    
2950
    OMAP_BAD_REG(addr);
2951
    return 0;
2952
}
2953

    
2954
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2955
                uint32_t value)
2956
{
2957
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2958
    int offset = addr & OMAP_MPUI_REG_MASK;
2959
    uint16_t diff;
2960
    int ln;
2961

    
2962
    switch (offset) {
2963
    case 0x04:        /* OUTPUT_REG */
2964
        diff = (s->outputs ^ value) & ~s->dir;
2965
        s->outputs = value;
2966
        while ((ln = ffs(diff))) {
2967
            ln --;
2968
            if (s->handler[ln])
2969
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2970
            diff &= ~(1 << ln);
2971
        }
2972
        break;
2973

    
2974
    case 0x08:        /* IO_CNTL */
2975
        diff = s->outputs & (s->dir ^ value);
2976
        s->dir = value;
2977

    
2978
        value = s->outputs & ~s->dir;
2979
        while ((ln = ffs(diff))) {
2980
            ln --;
2981
            if (s->handler[ln])
2982
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2983
            diff &= ~(1 << ln);
2984
        }
2985
        break;
2986

    
2987
    case 0x14:        /* KBC_REG */
2988
        s->cols = value;
2989
        omap_mpuio_kbd_update(s);
2990
        break;
2991

    
2992
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2993
        s->event = value & 0x1f;
2994
        break;
2995

    
2996
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2997
        s->edge = value;
2998
        break;
2999

    
3000
    case 0x28:        /* KBD_MASKIT */
3001
        s->kbd_mask = value & 1;
3002
        omap_mpuio_kbd_update(s);
3003
        break;
3004

    
3005
    case 0x2c:        /* GPIO_MASKIT */
3006
        s->mask = value;
3007
        break;
3008

    
3009
    case 0x30:        /* GPIO_DEBOUNCING_REG */
3010
        s->debounce = value & 0x1ff;
3011
        break;
3012

    
3013
    case 0x00:        /* INPUT_LATCH */
3014
    case 0x10:        /* KBR_LATCH */
3015
    case 0x20:        /* KBD_INT */
3016
    case 0x24:        /* GPIO_INT */
3017
    case 0x34:        /* GPIO_LATCH_REG */
3018
        OMAP_RO_REG(addr);
3019
        return;
3020

    
3021
    default:
3022
        OMAP_BAD_REG(addr);
3023
        return;
3024
    }
3025
}
3026

    
3027
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
3028
    omap_badwidth_read16,
3029
    omap_mpuio_read,
3030
    omap_badwidth_read16,
3031
};
3032

    
3033
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
3034
    omap_badwidth_write16,
3035
    omap_mpuio_write,
3036
    omap_badwidth_write16,
3037
};
3038

    
3039
void omap_mpuio_reset(struct omap_mpuio_s *s)
3040
{
3041
    s->inputs = 0;
3042
    s->outputs = 0;
3043
    s->dir = ~0;
3044
    s->event = 0;
3045
    s->edge = 0;
3046
    s->kbd_mask = 0;
3047
    s->mask = 0;
3048
    s->debounce = 0;
3049
    s->latch = 0;
3050
    s->ints = 0;
3051
    s->row_latch = 0x1f;
3052
    s->clk = 1;
3053
}
3054

    
3055
static void omap_mpuio_onoff(void *opaque, int line, int on)
3056
{
3057
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3058

    
3059
    s->clk = on;
3060
    if (on)
3061
        omap_mpuio_kbd_update(s);
3062
}
3063

    
3064
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
3065
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
3066
                omap_clk clk)
3067
{
3068
    int iomemtype;
3069
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
3070
            qemu_mallocz(sizeof(struct omap_mpuio_s));
3071

    
3072
    s->base = base;
3073
    s->irq = gpio_int;
3074
    s->kbd_irq = kbd_int;
3075
    s->wakeup = wakeup;
3076
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
3077
    omap_mpuio_reset(s);
3078

    
3079
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
3080
                    omap_mpuio_writefn, s);
3081
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3082

    
3083
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
3084

    
3085
    return s;
3086
}
3087

    
3088
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
3089
{
3090
    return s->in;
3091
}
3092

    
3093
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
3094
{
3095
    if (line >= 16 || line < 0)
3096
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3097
    s->handler[line] = handler;
3098
}
3099

    
3100
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
3101
{
3102
    if (row >= 5 || row < 0)
3103
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
3104
                        __FUNCTION__, col, row);
3105

    
3106
    if (down)
3107
        s->buttons[row] |= 1 << col;
3108
    else
3109
        s->buttons[row] &= ~(1 << col);
3110

    
3111
    omap_mpuio_kbd_update(s);
3112
}
3113

    
3114
/* General-Purpose I/O */
3115
struct omap_gpio_s {
3116
    target_phys_addr_t base;
3117
    qemu_irq irq;
3118
    qemu_irq *in;
3119
    qemu_irq handler[16];
3120

    
3121
    uint16_t inputs;
3122
    uint16_t outputs;
3123
    uint16_t dir;
3124
    uint16_t edge;
3125
    uint16_t mask;
3126
    uint16_t ints;
3127
    uint16_t pins;
3128
};
3129

    
3130
static void omap_gpio_set(void *opaque, int line, int level)
3131
{
3132
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3133
    uint16_t prev = s->inputs;
3134

    
3135
    if (level)
3136
        s->inputs |= 1 << line;
3137
    else
3138
        s->inputs &= ~(1 << line);
3139

    
3140
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
3141
                    (1 << line) & s->dir & ~s->mask) {
3142
        s->ints |= 1 << line;
3143
        qemu_irq_raise(s->irq);
3144
    }
3145
}
3146

    
3147
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
3148
{
3149
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3150
    int offset = addr & OMAP_MPUI_REG_MASK;
3151

    
3152
    switch (offset) {
3153
    case 0x00:        /* DATA_INPUT */
3154
        return s->inputs & s->pins;
3155

    
3156
    case 0x04:        /* DATA_OUTPUT */
3157
        return s->outputs;
3158

    
3159
    case 0x08:        /* DIRECTION_CONTROL */
3160
        return s->dir;
3161

    
3162
    case 0x0c:        /* INTERRUPT_CONTROL */
3163
        return s->edge;
3164

    
3165
    case 0x10:        /* INTERRUPT_MASK */
3166
        return s->mask;
3167

    
3168
    case 0x14:        /* INTERRUPT_STATUS */
3169
        return s->ints;
3170

    
3171
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
3172
        OMAP_BAD_REG(addr);
3173
        return s->pins;
3174
    }
3175

    
3176
    OMAP_BAD_REG(addr);
3177
    return 0;
3178
}
3179

    
3180
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
3181
                uint32_t value)
3182
{
3183
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3184
    int offset = addr & OMAP_MPUI_REG_MASK;
3185
    uint16_t diff;
3186
    int ln;
3187

    
3188
    switch (offset) {
3189
    case 0x00:        /* DATA_INPUT */
3190
        OMAP_RO_REG(addr);
3191
        return;
3192

    
3193
    case 0x04:        /* DATA_OUTPUT */
3194
        diff = (s->outputs ^ value) & ~s->dir;
3195
        s->outputs = value;
3196
        while ((ln = ffs(diff))) {
3197
            ln --;
3198
            if (s->handler[ln])
3199
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3200
            diff &= ~(1 << ln);
3201
        }
3202
        break;
3203

    
3204
    case 0x08:        /* DIRECTION_CONTROL */
3205
        diff = s->outputs & (s->dir ^ value);
3206
        s->dir = value;
3207

    
3208
        value = s->outputs & ~s->dir;
3209
        while ((ln = ffs(diff))) {
3210
            ln --;
3211
            if (s->handler[ln])
3212
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3213
            diff &= ~(1 << ln);
3214
        }
3215
        break;
3216

    
3217
    case 0x0c:        /* INTERRUPT_CONTROL */
3218
        s->edge = value;
3219
        break;
3220

    
3221
    case 0x10:        /* INTERRUPT_MASK */
3222
        s->mask = value;
3223
        break;
3224

    
3225
    case 0x14:        /* INTERRUPT_STATUS */
3226
        s->ints &= ~value;
3227
        if (!s->ints)
3228
            qemu_irq_lower(s->irq);
3229
        break;
3230

    
3231
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
3232
        OMAP_BAD_REG(addr);
3233
        s->pins = value;
3234
        break;
3235

    
3236
    default:
3237
        OMAP_BAD_REG(addr);
3238
        return;
3239
    }
3240
}
3241

    
3242
/* *Some* sources say the memory region is 32-bit.  */
3243
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
3244
    omap_badwidth_read16,
3245
    omap_gpio_read,
3246
    omap_badwidth_read16,
3247
};
3248

    
3249
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
3250
    omap_badwidth_write16,
3251
    omap_gpio_write,
3252
    omap_badwidth_write16,
3253
};
3254

    
3255
void omap_gpio_reset(struct omap_gpio_s *s)
3256
{
3257
    s->inputs = 0;
3258
    s->outputs = ~0;
3259
    s->dir = ~0;
3260
    s->edge = ~0;
3261
    s->mask = ~0;
3262
    s->ints = 0;
3263
    s->pins = ~0;
3264
}
3265

    
3266
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
3267
                qemu_irq irq, omap_clk clk)
3268
{
3269
    int iomemtype;
3270
    struct omap_gpio_s *s = (struct omap_gpio_s *)
3271
            qemu_mallocz(sizeof(struct omap_gpio_s));
3272

    
3273
    s->base = base;
3274
    s->irq = irq;
3275
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
3276
    omap_gpio_reset(s);
3277

    
3278
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
3279
                    omap_gpio_writefn, s);
3280
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3281

    
3282
    return s;
3283
}
3284

    
3285
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
3286
{
3287
    return s->in;
3288
}
3289

    
3290
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3291
{
3292
    if (line >= 16 || line < 0)
3293
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3294
    s->handler[line] = handler;
3295
}
3296

    
3297
/* MicroWire Interface */
3298
struct omap_uwire_s {
3299
    target_phys_addr_t base;
3300
    qemu_irq txirq;
3301
    qemu_irq rxirq;
3302
    qemu_irq txdrq;
3303

    
3304
    uint16_t txbuf;
3305
    uint16_t rxbuf;
3306
    uint16_t control;
3307
    uint16_t setup[5];
3308

    
3309
    struct uwire_slave_s *chip[4];
3310
};
3311

    
3312
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3313
{
3314
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3315
    struct uwire_slave_s *slave = s->chip[chipselect];
3316

    
3317
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
3318
        if (s->control & (1 << 12))                        /* CS_CMD */
3319
            if (slave && slave->send)
3320
                slave->send(slave->opaque,
3321
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3322
        s->control &= ~(1 << 14);                        /* CSRB */
3323
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3324
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3325
    }
3326

    
3327
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
3328
        if (s->control & (1 << 12))                        /* CS_CMD */
3329
            if (slave && slave->receive)
3330
                s->rxbuf = slave->receive(slave->opaque);
3331
        s->control |= 1 << 15;                                /* RDRB */
3332
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3333
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3334
    }
3335
}
3336

    
3337
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3338
{
3339
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3340
    int offset = addr & OMAP_MPUI_REG_MASK;
3341

    
3342
    switch (offset) {
3343
    case 0x00:        /* RDR */
3344
        s->control &= ~(1 << 15);                        /* RDRB */
3345
        return s->rxbuf;
3346

    
3347
    case 0x04:        /* CSR */
3348
        return s->control;
3349

    
3350
    case 0x08:        /* SR1 */
3351
        return s->setup[0];
3352
    case 0x0c:        /* SR2 */
3353
        return s->setup[1];
3354
    case 0x10:        /* SR3 */
3355
        return s->setup[2];
3356
    case 0x14:        /* SR4 */
3357
        return s->setup[3];
3358
    case 0x18:        /* SR5 */
3359
        return s->setup[4];
3360
    }
3361

    
3362
    OMAP_BAD_REG(addr);
3363
    return 0;
3364
}
3365

    
3366
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3367
                uint32_t value)
3368
{
3369
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3370
    int offset = addr & OMAP_MPUI_REG_MASK;
3371

    
3372
    switch (offset) {
3373
    case 0x00:        /* TDR */
3374
        s->txbuf = value;                                /* TD */
3375
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3376
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3377
                         (s->control & (1 << 12)))) {        /* CS_CMD */
3378
            s->control |= 1 << 14;                        /* CSRB */
3379
            omap_uwire_transfer_start(s);
3380
        }
3381
        break;
3382

    
3383
    case 0x04:        /* CSR */
3384
        s->control = value & 0x1fff;
3385
        if (value & (1 << 13))                                /* START */
3386
            omap_uwire_transfer_start(s);
3387
        break;
3388

    
3389
    case 0x08:        /* SR1 */
3390
        s->setup[0] = value & 0x003f;
3391
        break;
3392

    
3393
    case 0x0c:        /* SR2 */
3394
        s->setup[1] = value & 0x0fc0;
3395
        break;
3396

    
3397
    case 0x10:        /* SR3 */
3398
        s->setup[2] = value & 0x0003;
3399
        break;
3400

    
3401
    case 0x14:        /* SR4 */
3402
        s->setup[3] = value & 0x0001;
3403
        break;
3404

    
3405
    case 0x18:        /* SR5 */
3406
        s->setup[4] = value & 0x000f;
3407
        break;
3408

    
3409
    default:
3410
        OMAP_BAD_REG(addr);
3411
        return;
3412
    }
3413
}
3414

    
3415
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3416
    omap_badwidth_read16,
3417
    omap_uwire_read,
3418
    omap_badwidth_read16,
3419
};
3420

    
3421
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3422
    omap_badwidth_write16,
3423
    omap_uwire_write,
3424
    omap_badwidth_write16,
3425
};
3426

    
3427
void omap_uwire_reset(struct omap_uwire_s *s)
3428
{
3429
    s->control = 0;
3430
    s->setup[0] = 0;
3431
    s->setup[1] = 0;
3432
    s->setup[2] = 0;
3433
    s->setup[3] = 0;
3434
    s->setup[4] = 0;
3435
}
3436

    
3437
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3438
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3439
{
3440
    int iomemtype;
3441
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3442
            qemu_mallocz(sizeof(struct omap_uwire_s));
3443

    
3444
    s->base = base;
3445
    s->txirq = irq[0];
3446
    s->rxirq = irq[1];
3447
    s->txdrq = dma;
3448
    omap_uwire_reset(s);
3449

    
3450
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3451
                    omap_uwire_writefn, s);
3452
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3453

    
3454
    return s;
3455
}
3456

    
3457
void omap_uwire_attach(struct omap_uwire_s *s,
3458
                struct uwire_slave_s *slave, int chipselect)
3459
{
3460
    if (chipselect < 0 || chipselect > 3)
3461
        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
3462
                        chipselect);
3463

    
3464
    s->chip[chipselect] = slave;
3465
}
3466

    
3467
/* Pseudonoise Pulse-Width Light Modulator */
3468
void omap_pwl_update(struct omap_mpu_state_s *s)
3469
{
3470
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3471

    
3472
    if (output != s->pwl.output) {
3473
        s->pwl.output = output;
3474
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3475
    }
3476
}
3477

    
3478
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3479
{
3480
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3481
    int offset = addr & OMAP_MPUI_REG_MASK;
3482

    
3483
    switch (offset) {
3484
    case 0x00:        /* PWL_LEVEL */
3485
        return s->pwl.level;
3486
    case 0x04:        /* PWL_CTRL */
3487
        return s->pwl.enable;
3488
    }
3489
    OMAP_BAD_REG(addr);
3490
    return 0;
3491
}
3492

    
3493
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3494
                uint32_t value)
3495
{
3496
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3497
    int offset = addr & OMAP_MPUI_REG_MASK;
3498

    
3499
    switch (offset) {
3500
    case 0x00:        /* PWL_LEVEL */
3501
        s->pwl.level = value;
3502
        omap_pwl_update(s);
3503
        break;
3504
    case 0x04:        /* PWL_CTRL */
3505
        s->pwl.enable = value & 1;
3506
        omap_pwl_update(s);
3507
        break;
3508
    default:
3509
        OMAP_BAD_REG(addr);
3510
        return;
3511
    }
3512
}
3513

    
3514
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3515
    omap_pwl_read,
3516
    omap_badwidth_read8,
3517
    omap_badwidth_read8,
3518
};
3519

    
3520
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3521
    omap_pwl_write,
3522
    omap_badwidth_write8,
3523
    omap_badwidth_write8,
3524
};
3525

    
3526
void omap_pwl_reset(struct omap_mpu_state_s *s)
3527
{
3528
    s->pwl.output = 0;
3529
    s->pwl.level = 0;
3530
    s->pwl.enable = 0;
3531
    s->pwl.clk = 1;
3532
    omap_pwl_update(s);
3533
}
3534

    
3535
static void omap_pwl_clk_update(void *opaque, int line, int on)
3536
{
3537
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3538

    
3539
    s->pwl.clk = on;
3540
    omap_pwl_update(s);
3541
}
3542

    
3543
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3544
                omap_clk clk)
3545
{
3546
    int iomemtype;
3547

    
3548
    omap_pwl_reset(s);
3549

    
3550
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3551
                    omap_pwl_writefn, s);
3552
    cpu_register_physical_memory(base, 0x800, iomemtype);
3553

    
3554
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3555
}
3556

    
3557
/* Pulse-Width Tone module */
3558
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3559
{
3560
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3561
    int offset = addr & OMAP_MPUI_REG_MASK;
3562

    
3563
    switch (offset) {
3564
    case 0x00:        /* FRC */
3565
        return s->pwt.frc;
3566
    case 0x04:        /* VCR */
3567
        return s->pwt.vrc;
3568
    case 0x08:        /* GCR */
3569
        return s->pwt.gcr;
3570
    }
3571
    OMAP_BAD_REG(addr);
3572
    return 0;
3573
}
3574

    
3575
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3576
                uint32_t value)
3577
{
3578
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3579
    int offset = addr & OMAP_MPUI_REG_MASK;
3580

    
3581
    switch (offset) {
3582
    case 0x00:        /* FRC */
3583
        s->pwt.frc = value & 0x3f;
3584
        break;
3585
    case 0x04:        /* VRC */
3586
        if ((value ^ s->pwt.vrc) & 1) {
3587
            if (value & 1)
3588
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
3589
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
3590
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
3591
                                 /* Pre-multiplexer divider */
3592
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
3593
                                 /* Octave multiplexer */
3594
                                 (2 << (value & 3)) *
3595
                                 /* 101/107 divider */
3596
                                 ((value & (1 << 2)) ? 101 : 107) *
3597
                                 /*  49/55 divider */
3598
                                 ((value & (1 << 3)) ?  49 : 55) *
3599
                                 /*  50/63 divider */
3600
                                 ((value & (1 << 4)) ?  50 : 63) *
3601
                                 /*  80/127 divider */
3602
                                 ((value & (1 << 5)) ?  80 : 127) /
3603
                                 (107 * 55 * 63 * 127)));
3604
            else
3605
                printf("%s: silence!\n", __FUNCTION__);
3606
        }
3607
        s->pwt.vrc = value & 0x7f;
3608
        break;
3609
    case 0x08:        /* GCR */
3610
        s->pwt.gcr = value & 3;
3611
        break;
3612
    default:
3613
        OMAP_BAD_REG(addr);
3614
        return;
3615
    }
3616
}
3617

    
3618
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3619
    omap_pwt_read,
3620
    omap_badwidth_read8,
3621
    omap_badwidth_read8,
3622
};
3623

    
3624
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3625
    omap_pwt_write,
3626
    omap_badwidth_write8,
3627
    omap_badwidth_write8,
3628
};
3629

    
3630
void omap_pwt_reset(struct omap_mpu_state_s *s)
3631
{
3632
    s->pwt.frc = 0;
3633
    s->pwt.vrc = 0;
3634
    s->pwt.gcr = 0;
3635
}
3636

    
3637
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3638
                omap_clk clk)
3639
{
3640
    int iomemtype;
3641

    
3642
    s->pwt.clk = clk;
3643
    omap_pwt_reset(s);
3644

    
3645
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3646
                    omap_pwt_writefn, s);
3647
    cpu_register_physical_memory(base, 0x800, iomemtype);
3648
}
3649

    
3650
/* Real-time Clock module */
3651
struct omap_rtc_s {
3652
    target_phys_addr_t base;
3653
    qemu_irq irq;
3654
    qemu_irq alarm;
3655
    QEMUTimer *clk;
3656

    
3657
    uint8_t interrupts;
3658
    uint8_t status;
3659
    int16_t comp_reg;
3660
    int running;
3661
    int pm_am;
3662
    int auto_comp;
3663
    int round;
3664
    struct tm *(*convert)(const time_t *timep, struct tm *result);
3665
    struct tm alarm_tm;
3666
    time_t alarm_ti;
3667

    
3668
    struct tm current_tm;
3669
    time_t ti;
3670
    uint64_t tick;
3671
};
3672

    
3673
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3674
{
3675
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3676
}
3677

    
3678
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3679
{
3680
    s->alarm_ti = mktime(&s->alarm_tm);
3681
    if (s->alarm_ti == -1)
3682
        printf("%s: conversion failed\n", __FUNCTION__);
3683
}
3684

    
3685
static inline uint8_t omap_rtc_bcd(int num)
3686
{
3687
    return ((num / 10) << 4) | (num % 10);
3688
}
3689

    
3690
static inline int omap_rtc_bin(uint8_t num)
3691
{
3692
    return (num & 15) + 10 * (num >> 4);
3693
}
3694

    
3695
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3696
{
3697
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3698
    int offset = addr & OMAP_MPUI_REG_MASK;
3699
    uint8_t i;
3700

    
3701
    switch (offset) {
3702
    case 0x00:        /* SECONDS_REG */
3703
        return omap_rtc_bcd(s->current_tm.tm_sec);
3704

    
3705
    case 0x04:        /* MINUTES_REG */
3706
        return omap_rtc_bcd(s->current_tm.tm_min);
3707

    
3708
    case 0x08:        /* HOURS_REG */
3709
        if (s->pm_am)
3710
            return ((s->current_tm.tm_hour > 11) << 7) |
3711
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3712
        else
3713
            return omap_rtc_bcd(s->current_tm.tm_hour);
3714

    
3715
    case 0x0c:        /* DAYS_REG */
3716
        return omap_rtc_bcd(s->current_tm.tm_mday);
3717

    
3718
    case 0x10:        /* MONTHS_REG */
3719
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3720

    
3721
    case 0x14:        /* YEARS_REG */
3722
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3723

    
3724
    case 0x18:        /* WEEK_REG */
3725
        return s->current_tm.tm_wday;
3726

    
3727
    case 0x20:        /* ALARM_SECONDS_REG */
3728
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3729

    
3730
    case 0x24:        /* ALARM_MINUTES_REG */
3731
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3732

    
3733
    case 0x28:        /* ALARM_HOURS_REG */
3734
        if (s->pm_am)
3735
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3736
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3737
        else
3738
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
3739

    
3740
    case 0x2c:        /* ALARM_DAYS_REG */
3741
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3742

    
3743
    case 0x30:        /* ALARM_MONTHS_REG */
3744
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3745

    
3746
    case 0x34:        /* ALARM_YEARS_REG */
3747
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3748

    
3749
    case 0x40:        /* RTC_CTRL_REG */
3750
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3751
                (s->round << 1) | s->running;
3752

    
3753
    case 0x44:        /* RTC_STATUS_REG */
3754
        i = s->status;
3755
        s->status &= ~0x3d;
3756
        return i;
3757

    
3758
    case 0x48:        /* RTC_INTERRUPTS_REG */
3759
        return s->interrupts;
3760

    
3761
    case 0x4c:        /* RTC_COMP_LSB_REG */
3762
        return ((uint16_t) s->comp_reg) & 0xff;
3763

    
3764
    case 0x50:        /* RTC_COMP_MSB_REG */
3765
        return ((uint16_t) s->comp_reg) >> 8;
3766
    }
3767

    
3768
    OMAP_BAD_REG(addr);
3769
    return 0;
3770
}
3771

    
3772
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3773
                uint32_t value)
3774
{
3775
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3776
    int offset = addr & OMAP_MPUI_REG_MASK;
3777
    struct tm new_tm;
3778
    time_t ti[2];
3779

    
3780
    switch (offset) {
3781
    case 0x00:        /* SECONDS_REG */
3782
#if ALMDEBUG
3783
        printf("RTC SEC_REG <-- %02x\n", value);
3784
#endif
3785
        s->ti -= s->current_tm.tm_sec;
3786
        s->ti += omap_rtc_bin(value);
3787
        return;
3788

    
3789
    case 0x04:        /* MINUTES_REG */
3790
#if ALMDEBUG
3791
        printf("RTC MIN_REG <-- %02x\n", value);
3792
#endif
3793
        s->ti -= s->current_tm.tm_min * 60;
3794
        s->ti += omap_rtc_bin(value) * 60;
3795
        return;
3796

    
3797
    case 0x08:        /* HOURS_REG */
3798
#if ALMDEBUG
3799
        printf("RTC HRS_REG <-- %02x\n", value);
3800
#endif
3801
        s->ti -= s->current_tm.tm_hour * 3600;
3802
        if (s->pm_am) {
3803
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3804
            s->ti += ((value >> 7) & 1) * 43200;
3805
        } else
3806
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3807
        return;
3808

    
3809
    case 0x0c:        /* DAYS_REG */
3810
#if ALMDEBUG
3811
        printf("RTC DAY_REG <-- %02x\n", value);
3812
#endif
3813
        s->ti -= s->current_tm.tm_mday * 86400;
3814
        s->ti += omap_rtc_bin(value) * 86400;
3815
        return;
3816

    
3817
    case 0x10:        /* MONTHS_REG */
3818
#if ALMDEBUG
3819
        printf("RTC MTH_REG <-- %02x\n", value);
3820
#endif
3821
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3822
        new_tm.tm_mon = omap_rtc_bin(value);
3823
        ti[0] = mktime(&s->current_tm);
3824
        ti[1] = mktime(&new_tm);
3825

    
3826
        if (ti[0] != -1 && ti[1] != -1) {
3827
            s->ti -= ti[0];
3828
            s->ti += ti[1];
3829
        } else {
3830
            /* A less accurate version */
3831
            s->ti -= s->current_tm.tm_mon * 2592000;
3832
            s->ti += omap_rtc_bin(value) * 2592000;
3833
        }
3834
        return;
3835

    
3836
    case 0x14:        /* YEARS_REG */
3837
#if ALMDEBUG
3838
        printf("RTC YRS_REG <-- %02x\n", value);
3839
#endif
3840
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3841
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3842
        ti[0] = mktime(&s->current_tm);
3843
        ti[1] = mktime(&new_tm);
3844

    
3845
        if (ti[0] != -1 && ti[1] != -1) {
3846
            s->ti -= ti[0];
3847
            s->ti += ti[1];
3848
        } else {
3849
            /* A less accurate version */
3850
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3851
            s->ti += omap_rtc_bin(value) * 31536000;
3852
        }
3853
        return;
3854

    
3855
    case 0x18:        /* WEEK_REG */
3856
        return;        /* Ignored */
3857

    
3858
    case 0x20:        /* ALARM_SECONDS_REG */
3859
#if ALMDEBUG
3860
        printf("ALM SEC_REG <-- %02x\n", value);
3861
#endif
3862
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3863
        omap_rtc_alarm_update(s);
3864
        return;
3865

    
3866
    case 0x24:        /* ALARM_MINUTES_REG */
3867
#if ALMDEBUG
3868
        printf("ALM MIN_REG <-- %02x\n", value);
3869
#endif
3870
        s->alarm_tm.tm_min = omap_rtc_bin(value);
3871
        omap_rtc_alarm_update(s);
3872
        return;
3873

    
3874
    case 0x28:        /* ALARM_HOURS_REG */
3875
#if ALMDEBUG
3876
        printf("ALM HRS_REG <-- %02x\n", value);
3877
#endif
3878
        if (s->pm_am)
3879
            s->alarm_tm.tm_hour =
3880
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
3881
                    ((value >> 7) & 1) * 12;
3882
        else
3883
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
3884
        omap_rtc_alarm_update(s);
3885
        return;
3886

    
3887
    case 0x2c:        /* ALARM_DAYS_REG */
3888
#if ALMDEBUG
3889
        printf("ALM DAY_REG <-- %02x\n", value);
3890
#endif
3891
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3892
        omap_rtc_alarm_update(s);
3893
        return;
3894

    
3895
    case 0x30:        /* ALARM_MONTHS_REG */
3896
#if ALMDEBUG
3897
        printf("ALM MON_REG <-- %02x\n", value);
3898
#endif
3899
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3900
        omap_rtc_alarm_update(s);
3901
        return;
3902

    
3903
    case 0x34:        /* ALARM_YEARS_REG */
3904
#if ALMDEBUG
3905
        printf("ALM YRS_REG <-- %02x\n", value);
3906
#endif
3907
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3908
        omap_rtc_alarm_update(s);
3909
        return;
3910

    
3911
    case 0x40:        /* RTC_CTRL_REG */
3912
#if ALMDEBUG
3913
        printf("RTC CONTROL <-- %02x\n", value);
3914
#endif
3915
        s->pm_am = (value >> 3) & 1;
3916
        s->auto_comp = (value >> 2) & 1;
3917
        s->round = (value >> 1) & 1;
3918
        s->running = value & 1;
3919
        s->status &= 0xfd;
3920
        s->status |= s->running << 1;
3921
        return;
3922

    
3923
    case 0x44:        /* RTC_STATUS_REG */
3924
#if ALMDEBUG
3925
        printf("RTC STATUSL <-- %02x\n", value);
3926
#endif
3927
        s->status &= ~((value & 0xc0) ^ 0x80);
3928
        omap_rtc_interrupts_update(s);
3929
        return;
3930

    
3931
    case 0x48:        /* RTC_INTERRUPTS_REG */
3932
#if ALMDEBUG
3933
        printf("RTC INTRS <-- %02x\n", value);
3934
#endif
3935
        s->interrupts = value;
3936
        return;
3937

    
3938
    case 0x4c:        /* RTC_COMP_LSB_REG */
3939
#if ALMDEBUG
3940
        printf("RTC COMPLSB <-- %02x\n", value);
3941
#endif
3942
        s->comp_reg &= 0xff00;
3943
        s->comp_reg |= 0x00ff & value;
3944
        return;
3945

    
3946
    case 0x50:        /* RTC_COMP_MSB_REG */
3947
#if ALMDEBUG
3948
        printf("RTC COMPMSB <-- %02x\n", value);
3949
#endif
3950
        s->comp_reg &= 0x00ff;
3951
        s->comp_reg |= 0xff00 & (value << 8);
3952
        return;
3953

    
3954
    default:
3955
        OMAP_BAD_REG(addr);
3956
        return;
3957
    }
3958
}
3959

    
3960
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3961
    omap_rtc_read,
3962
    omap_badwidth_read8,
3963
    omap_badwidth_read8,
3964
};
3965

    
3966
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3967
    omap_rtc_write,
3968
    omap_badwidth_write8,
3969
    omap_badwidth_write8,
3970
};
3971

    
3972
static void omap_rtc_tick(void *opaque)
3973
{
3974
    struct omap_rtc_s *s = opaque;
3975

    
3976
    if (s->round) {
3977
        /* Round to nearest full minute.  */
3978
        if (s->current_tm.tm_sec < 30)
3979
            s->ti -= s->current_tm.tm_sec;
3980
        else
3981
            s->ti += 60 - s->current_tm.tm_sec;
3982

    
3983
        s->round = 0;
3984
    }
3985

    
3986
    localtime_r(&s->ti, &s->current_tm);
3987

    
3988
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3989
        s->status |= 0x40;
3990
        omap_rtc_interrupts_update(s);
3991
    }
3992

    
3993
    if (s->interrupts & 0x04)
3994
        switch (s->interrupts & 3) {
3995
        case 0:
3996
            s->status |= 0x04;
3997
            qemu_irq_raise(s->irq);
3998
            break;
3999
        case 1:
4000
            if (s->current_tm.tm_sec)
4001
                break;
4002
            s->status |= 0x08;
4003
            qemu_irq_raise(s->irq);
4004
            break;
4005
        case 2:
4006
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
4007
                break;
4008
            s->status |= 0x10;
4009
            qemu_irq_raise(s->irq);
4010
            break;
4011
        case 3:
4012
            if (s->current_tm.tm_sec ||
4013
                            s->current_tm.tm_min || s->current_tm.tm_hour)
4014
                break;
4015
            s->status |= 0x20;
4016
            qemu_irq_raise(s->irq);
4017
            break;
4018
        }
4019

    
4020
    /* Move on */
4021
    if (s->running)
4022
        s->ti ++;
4023
    s->tick += 1000;
4024

    
4025
    /*
4026
     * Every full hour add a rough approximation of the compensation
4027
     * register to the 32kHz Timer (which drives the RTC) value. 
4028
     */
4029
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
4030
        s->tick += s->comp_reg * 1000 / 32768;
4031

    
4032
    qemu_mod_timer(s->clk, s->tick);
4033
}
4034

    
4035
void omap_rtc_reset(struct omap_rtc_s *s)
4036
{
4037
    s->interrupts = 0;
4038
    s->comp_reg = 0;
4039
    s->running = 0;
4040
    s->pm_am = 0;
4041
    s->auto_comp = 0;
4042
    s->round = 0;
4043
    s->tick = qemu_get_clock(rt_clock);
4044
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
4045
    s->alarm_tm.tm_mday = 0x01;
4046
    s->status = 1 << 7;
4047
    time(&s->ti);
4048
    s->ti = mktime(s->convert(&s->ti, &s->current_tm));
4049

    
4050
    omap_rtc_alarm_update(s);
4051
    omap_rtc_tick(s);
4052
}
4053

    
4054
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
4055
                qemu_irq *irq, omap_clk clk)
4056
{
4057
    int iomemtype;
4058
    struct omap_rtc_s *s = (struct omap_rtc_s *)
4059
            qemu_mallocz(sizeof(struct omap_rtc_s));
4060

    
4061
    s->base = base;
4062
    s->irq = irq[0];
4063
    s->alarm = irq[1];
4064
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
4065
    s->convert = rtc_utc ? gmtime_r : localtime_r;
4066

    
4067
    omap_rtc_reset(s);
4068

    
4069
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
4070
                    omap_rtc_writefn, s);
4071
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4072

    
4073
    return s;
4074
}
4075

    
4076
/* Multi-channel Buffered Serial Port interfaces */
4077
struct omap_mcbsp_s {
4078
    target_phys_addr_t base;
4079
    qemu_irq txirq;
4080
    qemu_irq rxirq;
4081
    qemu_irq txdrq;
4082
    qemu_irq rxdrq;
4083

    
4084
    uint16_t spcr[2];
4085
    uint16_t rcr[2];
4086
    uint16_t xcr[2];
4087
    uint16_t srgr[2];
4088
    uint16_t mcr[2];
4089
    uint16_t pcr;
4090
    uint16_t rcer[8];
4091
    uint16_t xcer[8];
4092
    int tx_rate;
4093
    int rx_rate;
4094
    int tx_req;
4095

    
4096
    struct i2s_codec_s *codec;
4097
};
4098

    
4099
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
4100
{
4101
    int irq;
4102

    
4103
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
4104
    case 0:
4105
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
4106
        break;
4107
    case 3:
4108
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
4109
        break;
4110
    default:
4111
        irq = 0;
4112
        break;
4113
    }
4114

    
4115
    qemu_set_irq(s->rxirq, irq);
4116

    
4117
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
4118
    case 0:
4119
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
4120
        break;
4121
    case 3:
4122
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
4123
        break;
4124
    default:
4125
        irq = 0;
4126
        break;
4127
    }
4128

    
4129
    qemu_set_irq(s->txirq, irq);
4130
}
4131

    
4132
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
4133
{
4134
    int prev = s->tx_req;
4135

    
4136
    s->tx_req = (s->tx_rate ||
4137
                    (s->spcr[0] & (1 << 12))) &&        /* CLKSTP */
4138
            (s->spcr[1] & (1 << 6)) &&                        /* GRST */
4139
            (s->spcr[1] & (1 << 0));                        /* XRST */
4140

    
4141
    if (!s->tx_req && prev) {
4142
        s->spcr[1] &= ~(1 << 1);                        /* XRDY */
4143
        qemu_irq_lower(s->txdrq);
4144
        omap_mcbsp_intr_update(s);
4145

    
4146
        if (s->codec)
4147
            s->codec->tx_swallow(s->codec->opaque);
4148
    } else if (s->codec && s->tx_req && !prev) {
4149
        s->spcr[1] |= 1 << 1;                                /* XRDY */
4150
        qemu_irq_raise(s->txdrq);
4151
        omap_mcbsp_intr_update(s);
4152
    }
4153
}
4154

    
4155
static void omap_mcbsp_rate_update(struct omap_mcbsp_s *s)
4156
{
4157
    int rx_clk = 0, tx_clk = 0;
4158
    int cpu_rate = 1500000;        /* XXX */
4159
    if (!s->codec)
4160
        return;
4161

    
4162
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
4163
        if (s->spcr[0] & (1 << 0))                        /* RRST */
4164
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
4165
                            (s->pcr & (1 << 8)))        /* CLKRM */
4166
                if (~s->pcr & (1 << 7))                        /* SCLKME */
4167
                    rx_clk = cpu_rate /
4168
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
4169
        if (s->spcr[1] & (1 << 0))                        /* XRST */
4170
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
4171
                            (s->pcr & (1 << 9)))        /* CLKXM */
4172
                if (~s->pcr & (1 << 7))                        /* SCLKME */
4173
                    tx_clk = cpu_rate /
4174
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
4175
    }
4176

    
4177
    s->codec->set_rate(s->codec->opaque, rx_clk, tx_clk);
4178
}
4179

    
4180
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
4181
{
4182
    if (!(s->spcr[0] & 1)) {                                /* RRST */
4183
        if (s->codec)
4184
            s->codec->in.len = 0;
4185
        return;
4186
    }
4187

    
4188
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
4189
        s->spcr[0] |= 1 << 2;                                /* RFULL */
4190
    s->spcr[0] |= 1 << 1;                                /* RRDY */
4191
    qemu_irq_raise(s->rxdrq);
4192
    omap_mcbsp_intr_update(s);
4193
}
4194

    
4195
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
4196
{
4197
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
4198
    qemu_irq_lower(s->rxdrq);
4199
    omap_mcbsp_intr_update(s);
4200
}
4201

    
4202
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
4203
{
4204
    if (s->tx_rate)
4205
        return;
4206
    s->tx_rate = 1;
4207
    omap_mcbsp_req_update(s);
4208
}
4209

    
4210
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
4211
{
4212
    s->tx_rate = 0;
4213
    omap_mcbsp_req_update(s);
4214
}
4215

    
4216
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
4217
{
4218
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4219
    int offset = addr & OMAP_MPUI_REG_MASK;
4220
    uint16_t ret;
4221

    
4222
    switch (offset) {
4223
    case 0x00:        /* DRR2 */
4224
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
4225
            return 0x0000;
4226
        /* Fall through.  */
4227
    case 0x02:        /* DRR1 */
4228
        if (!s->codec)
4229
            return 0x0000;
4230
        if (s->codec->in.len < 2) {
4231
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
4232
            omap_mcbsp_rx_stop(s);
4233
        } else {
4234
            s->codec->in.len -= 2;
4235
            ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
4236
            ret |= s->codec->in.fifo[s->codec->in.start ++];
4237
            if (!s->codec->in.len)
4238
                omap_mcbsp_rx_stop(s);
4239
            return ret;
4240
        }
4241
        return 0x0000;
4242

    
4243
    case 0x04:        /* DXR2 */
4244
    case 0x06:        /* DXR1 */
4245
        return 0x0000;
4246

    
4247
    case 0x08:        /* SPCR2 */
4248
        return s->spcr[1];
4249
    case 0x0a:        /* SPCR1 */
4250
        return s->spcr[0];
4251
    case 0x0c:        /* RCR2 */
4252
        return s->rcr[1];
4253
    case 0x0e:        /* RCR1 */
4254
        return s->rcr[0];
4255
    case 0x10:        /* XCR2 */
4256
        return s->xcr[1];
4257
    case 0x12:        /* XCR1 */
4258
        return s->xcr[0];
4259
    case 0x14:        /* SRGR2 */
4260
        return s->srgr[1];
4261
    case 0x16:        /* SRGR1 */
4262
        return s->srgr[0];
4263
    case 0x18:        /* MCR2 */
4264
        return s->mcr[1];
4265
    case 0x1a:        /* MCR1 */
4266
        return s->mcr[0];
4267
    case 0x1c:        /* RCERA */
4268
        return s->rcer[0];
4269
    case 0x1e:        /* RCERB */
4270
        return s->rcer[1];
4271
    case 0x20:        /* XCERA */
4272
        return s->xcer[0];
4273
    case 0x22:        /* XCERB */
4274
        return s->xcer[1];
4275
    case 0x24:        /* PCR0 */
4276
        return s->pcr;
4277
    case 0x26:        /* RCERC */
4278
        return s->rcer[2];
4279
    case 0x28:        /* RCERD */
4280
        return s->rcer[3];
4281
    case 0x2a:        /* XCERC */
4282
        return s->xcer[2];
4283
    case 0x2c:        /* XCERD */
4284
        return s->xcer[3];
4285
    case 0x2e:        /* RCERE */
4286
        return s->rcer[4];
4287
    case 0x30:        /* RCERF */
4288
        return s->rcer[5];
4289
    case 0x32:        /* XCERE */
4290
        return s->xcer[4];
4291
    case 0x34:        /* XCERF */
4292
        return s->xcer[5];
4293
    case 0x36:        /* RCERG */
4294
        return s->rcer[6];
4295
    case 0x38:        /* RCERH */
4296
        return s->rcer[7];
4297
    case 0x3a:        /* XCERG */
4298
        return s->xcer[6];
4299
    case 0x3c:        /* XCERH */
4300
        return s->xcer[7];
4301
    }
4302

    
4303
    OMAP_BAD_REG(addr);
4304
    return 0;
4305
}
4306

    
4307
static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr,
4308
                uint32_t value)
4309
{
4310
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4311
    int offset = addr & OMAP_MPUI_REG_MASK;
4312

    
4313
    switch (offset) {
4314
    case 0x00:        /* DRR2 */
4315
    case 0x02:        /* DRR1 */
4316
        OMAP_RO_REG(addr);
4317
        return;
4318

    
4319
    case 0x04:        /* DXR2 */
4320
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4321
            return;
4322
        /* Fall through.  */
4323
    case 0x06:        /* DXR1 */
4324
        if (!s->codec)
4325
            return;
4326
        if (s->tx_req) {
4327
            if (s->codec->out.len > s->codec->out.size - 2) {
4328
                printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4329
                omap_mcbsp_tx_stop(s);
4330
            } else {
4331
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
4332
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
4333
                if (s->codec->out.len >= s->codec->out.size)
4334
                    omap_mcbsp_tx_stop(s);
4335
            }
4336
        } else
4337
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4338
        return;
4339

    
4340
    case 0x08:        /* SPCR2 */
4341
        s->spcr[1] &= 0x0002;
4342
        s->spcr[1] |= 0x03f9 & value;
4343
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
4344
        if (~value & 1) {                                /* XRST */
4345
            s->spcr[1] &= ~6;
4346
            qemu_irq_lower(s->rxdrq);
4347
            if (s->codec)
4348
                s->codec->out.len = 0;
4349
        }
4350
        if (s->codec)
4351
            omap_mcbsp_rate_update(s);
4352
        omap_mcbsp_req_update(s);
4353
        return;
4354
    case 0x0a:        /* SPCR1 */
4355
        s->spcr[0] &= 0x0006;
4356
        s->spcr[0] |= 0xf8f9 & value;
4357
        if (value & (1 << 15))                                /* DLB */
4358
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
4359
        if (~value & 1) {                                /* RRST */
4360
            s->spcr[0] &= ~6;
4361
            qemu_irq_lower(s->txdrq);
4362
            if (s->codec)
4363
                s->codec->in.len = 0;
4364
        }
4365
        if (s->codec)
4366
            omap_mcbsp_rate_update(s);
4367
        omap_mcbsp_req_update(s);
4368
        return;
4369

    
4370
    case 0x0c:        /* RCR2 */
4371
        s->rcr[1] = value & 0xffff;
4372
        return;
4373
    case 0x0e:        /* RCR1 */
4374
        s->rcr[0] = value & 0x7fe0;
4375
        return;
4376
    case 0x10:        /* XCR2 */
4377
        s->xcr[1] = value & 0xffff;
4378
        return;
4379
    case 0x12:        /* XCR1 */
4380
        s->xcr[0] = value & 0x7fe0;
4381
        return;
4382
    case 0x14:        /* SRGR2 */
4383
        s->srgr[1] = value & 0xffff;
4384
        omap_mcbsp_rate_update(s);
4385
        return;
4386
    case 0x16:        /* SRGR1 */
4387
        s->srgr[0] = value & 0xffff;
4388
        omap_mcbsp_rate_update(s);
4389
        return;
4390
    case 0x18:        /* MCR2 */
4391
        s->mcr[1] = value & 0x03e3;
4392
        if (value & 3)                                        /* XMCM */
4393
            printf("%s: Tx channel selection mode enable attempt\n",
4394
                            __FUNCTION__);
4395
        return;
4396
    case 0x1a:        /* MCR1 */
4397
        s->mcr[0] = value & 0x03e1;
4398
        if (value & 1)                                        /* RMCM */
4399
            printf("%s: Rx channel selection mode enable attempt\n",
4400
                            __FUNCTION__);
4401
        return;
4402
    case 0x1c:        /* RCERA */
4403
        s->rcer[0] = value & 0xffff;
4404
        return;
4405
    case 0x1e:        /* RCERB */
4406
        s->rcer[1] = value & 0xffff;
4407
        return;
4408
    case 0x20:        /* XCERA */
4409
        s->xcer[0] = value & 0xffff;
4410
        return;
4411
    case 0x22:        /* XCERB */
4412
        s->xcer[1] = value & 0xffff;
4413
        return;
4414
    case 0x24:        /* PCR0 */
4415
        s->pcr = value & 0x7faf;
4416
        return;
4417
    case 0x26:        /* RCERC */
4418
        s->rcer[2] = value & 0xffff;
4419
        return;
4420
    case 0x28:        /* RCERD */
4421
        s->rcer[3] = value & 0xffff;
4422
        return;
4423
    case 0x2a:        /* XCERC */
4424
        s->xcer[2] = value & 0xffff;
4425
        return;
4426
    case 0x2c:        /* XCERD */
4427
        s->xcer[3] = value & 0xffff;
4428
        return;
4429
    case 0x2e:        /* RCERE */
4430
        s->rcer[4] = value & 0xffff;
4431
        return;
4432
    case 0x30:        /* RCERF */
4433
        s->rcer[5] = value & 0xffff;
4434
        return;
4435
    case 0x32:        /* XCERE */
4436
        s->xcer[4] = value & 0xffff;
4437
        return;
4438
    case 0x34:        /* XCERF */
4439
        s->xcer[5] = value & 0xffff;
4440
        return;
4441
    case 0x36:        /* RCERG */
4442
        s->rcer[6] = value & 0xffff;
4443
        return;
4444
    case 0x38:        /* RCERH */
4445
        s->rcer[7] = value & 0xffff;
4446
        return;
4447
    case 0x3a:        /* XCERG */
4448
        s->xcer[6] = value & 0xffff;
4449
        return;
4450
    case 0x3c:        /* XCERH */
4451
        s->xcer[7] = value & 0xffff;
4452
        return;
4453
    }
4454

    
4455
    OMAP_BAD_REG(addr);
4456
}
4457

    
4458
static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
4459
    omap_badwidth_read16,
4460
    omap_mcbsp_read,
4461
    omap_badwidth_read16,
4462
};
4463

    
4464
static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
4465
    omap_badwidth_write16,
4466
    omap_mcbsp_write,
4467
    omap_badwidth_write16,
4468
};
4469

    
4470
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
4471
{
4472
    memset(&s->spcr, 0, sizeof(s->spcr));
4473
    memset(&s->rcr, 0, sizeof(s->rcr));
4474
    memset(&s->xcr, 0, sizeof(s->xcr));
4475
    s->srgr[0] = 0x0001;
4476
    s->srgr[1] = 0x2000;
4477
    memset(&s->mcr, 0, sizeof(s->mcr));
4478
    memset(&s->pcr, 0, sizeof(s->pcr));
4479
    memset(&s->rcer, 0, sizeof(s->rcer));
4480
    memset(&s->xcer, 0, sizeof(s->xcer));
4481
    s->tx_req = 0;
4482
    s->tx_rate = 0;
4483
    s->rx_rate = 0;
4484
}
4485

    
4486
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
4487
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
4488
{
4489
    int iomemtype;
4490
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
4491
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
4492

    
4493
    s->base = base;
4494
    s->txirq = irq[0];
4495
    s->rxirq = irq[1];
4496
    s->txdrq = dma[0];
4497
    s->rxdrq = dma[1];
4498
    omap_mcbsp_reset(s);
4499

    
4500
    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
4501
                    omap_mcbsp_writefn, s);
4502
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4503

    
4504
    return s;
4505
}
4506

    
4507
void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4508
{
4509
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4510

    
4511
    omap_mcbsp_rx_start(s);
4512
}
4513

    
4514
void omap_mcbsp_i2s_start(void *opaque, int line, int level)
4515
{
4516
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4517

    
4518
    omap_mcbsp_tx_start(s);
4519
}
4520

    
4521
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
4522
{
4523
    s->codec = slave;
4524
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4525
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4526
}
4527

    
4528
/* General chip reset */
4529
static void omap_mpu_reset(void *opaque)
4530
{
4531
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4532

    
4533
    omap_clkm_reset(mpu);
4534
    omap_inth_reset(mpu->ih[0]);
4535
    omap_inth_reset(mpu->ih[1]);
4536
    omap_dma_reset(mpu->dma);
4537
    omap_mpu_timer_reset(mpu->timer[0]);
4538
    omap_mpu_timer_reset(mpu->timer[1]);
4539
    omap_mpu_timer_reset(mpu->timer[2]);
4540
    omap_wd_timer_reset(mpu->wdt);
4541
    omap_os_timer_reset(mpu->os_timer);
4542
    omap_lcdc_reset(mpu->lcd);
4543
    omap_ulpd_pm_reset(mpu);
4544
    omap_pin_cfg_reset(mpu);
4545
    omap_mpui_reset(mpu);
4546
    omap_tipb_bridge_reset(mpu->private_tipb);
4547
    omap_tipb_bridge_reset(mpu->public_tipb);
4548
    omap_dpll_reset(&mpu->dpll[0]);
4549
    omap_dpll_reset(&mpu->dpll[1]);
4550
    omap_dpll_reset(&mpu->dpll[2]);
4551
    omap_uart_reset(mpu->uart[0]);
4552
    omap_uart_reset(mpu->uart[1]);
4553
    omap_uart_reset(mpu->uart[2]);
4554
    omap_mmc_reset(mpu->mmc);
4555
    omap_mpuio_reset(mpu->mpuio);
4556
    omap_gpio_reset(mpu->gpio);
4557
    omap_uwire_reset(mpu->microwire);
4558
    omap_pwl_reset(mpu);
4559
    omap_pwt_reset(mpu);
4560
    omap_i2c_reset(mpu->i2c);
4561
    omap_rtc_reset(mpu->rtc);
4562
    omap_mcbsp_reset(mpu->mcbsp1);
4563
    omap_mcbsp_reset(mpu->mcbsp2);
4564
    omap_mcbsp_reset(mpu->mcbsp3);
4565
    cpu_reset(mpu->env);
4566
}
4567

    
4568
static const struct omap_map_s {
4569
    target_phys_addr_t phys_dsp;
4570
    target_phys_addr_t phys_mpu;
4571
    uint32_t size;
4572
    const char *name;
4573
} omap15xx_dsp_mm[] = {
4574
    /* Strobe 0 */
4575
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
4576
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
4577
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
4578
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
4579
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
4580
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
4581
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
4582
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
4583
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
4584
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
4585
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
4586
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
4587
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
4588
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
4589
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
4590
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
4591
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
4592
    /* Strobe 1 */
4593
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
4594

    
4595
    { 0 }
4596
};
4597

    
4598
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4599
{
4600
    int io;
4601

    
4602
    for (; map->phys_dsp; map ++) {
4603
        io = cpu_get_physical_page_desc(map->phys_mpu);
4604

    
4605
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4606
    }
4607
}
4608

    
4609
static void omap_mpu_wakeup(void *opaque, int irq, int req)
4610
{
4611
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4612

    
4613
    if (mpu->env->halted)
4614
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4615
}
4616

    
4617
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4618
                DisplayState *ds, const char *core)
4619
{
4620
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4621
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4622
    ram_addr_t imif_base, emiff_base;
4623
    
4624
    if (!core)
4625
        core = "ti925t";
4626

    
4627
    /* Core */
4628
    s->mpu_model = omap310;
4629
    s->env = cpu_init(core);
4630
    if (!s->env) {
4631
        fprintf(stderr, "Unable to find CPU definition\n");
4632
        exit(1);
4633
    }
4634
    s->sdram_size = sdram_size;
4635
    s->sram_size = OMAP15XX_SRAM_SIZE;
4636

    
4637
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4638

    
4639
    /* Clocks */
4640
    omap_clk_init(s);
4641

    
4642
    /* Memory-mapped stuff */
4643
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4644
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4645
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4646
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4647

    
4648
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4649

    
4650
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100,
4651
                    arm_pic_init_cpu(s->env),
4652
                    omap_findclk(s, "arminth_ck"));
4653
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800,
4654
                    &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ],
4655
                    omap_findclk(s, "arminth_ck"));
4656
    s->irq[0] = s->ih[0]->pins;
4657
    s->irq[1] = s->ih[1]->pins;
4658

    
4659
    s->dma = omap_dma_init(0xfffed800, s->irq[0], s,
4660
                    omap_findclk(s, "dma_ck"));
4661
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4662
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4663
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4664
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4665
    s->port[local    ].addr_valid = omap_validate_local_addr;
4666
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4667

    
4668
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4669
                    s->irq[0][OMAP_INT_TIMER1],
4670
                    omap_findclk(s, "mputim_ck"));
4671
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4672
                    s->irq[0][OMAP_INT_TIMER2],
4673
                    omap_findclk(s, "mputim_ck"));
4674
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4675
                    s->irq[0][OMAP_INT_TIMER3],
4676
                    omap_findclk(s, "mputim_ck"));
4677

    
4678
    s->wdt = omap_wd_timer_init(0xfffec800,
4679
                    s->irq[0][OMAP_INT_WD_TIMER],
4680
                    omap_findclk(s, "armwdt_ck"));
4681

    
4682
    s->os_timer = omap_os_timer_init(0xfffb9000,
4683
                    s->irq[1][OMAP_INT_OS_TIMER],
4684
                    omap_findclk(s, "clk32-kHz"));
4685

    
4686
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4687
                    &s->dma->lcd_ch, ds, imif_base, emiff_base,
4688
                    omap_findclk(s, "lcd_ck"));
4689

    
4690
    omap_ulpd_pm_init(0xfffe0800, s);
4691
    omap_pin_cfg_init(0xfffe1000, s);
4692
    omap_id_init(s);
4693

    
4694
    omap_mpui_init(0xfffec900, s);
4695

    
4696
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4697
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4698
                    omap_findclk(s, "tipb_ck"));
4699
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4700
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4701
                    omap_findclk(s, "tipb_ck"));
4702

    
4703
    omap_tcmi_init(0xfffecc00, s);
4704

    
4705
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4706
                    omap_findclk(s, "uart1_ck"),
4707
                    serial_hds[0]);
4708
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4709
                    omap_findclk(s, "uart2_ck"),
4710
                    serial_hds[0] ? serial_hds[1] : 0);
4711
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4712
                    omap_findclk(s, "uart3_ck"),
4713
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4714

    
4715
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4716
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4717
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4718

    
4719
    s->mmc = omap_mmc_init(0xfffb7800, s->irq[1][OMAP_INT_OQN],
4720
                    &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
4721

    
4722
    s->mpuio = omap_mpuio_init(0xfffb5000,
4723
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4724
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
4725

    
4726
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4727
                    omap_findclk(s, "arm_gpio_ck"));
4728

    
4729
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4730
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4731

    
4732
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4733
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4734

    
4735
    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4736
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4737

    
4738
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4739
                    omap_findclk(s, "clk32-kHz"));
4740

    
4741
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
4742
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4743
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
4744
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4745
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
4746
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4747

    
4748
    /* Register mappings not currenlty implemented:
4749
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4750
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4751
     * USB W2FC                fffb4000 - fffb47ff
4752
     * Camera Interface        fffb6800 - fffb6fff
4753
     * USB Host                fffba000 - fffba7ff
4754
     * FAC                fffba800 - fffbafff
4755
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4756
     * TIPB switches        fffbc800 - fffbcfff
4757
     * LED1                fffbd000 - fffbd7ff
4758
     * LED2                fffbd800 - fffbdfff
4759
     * Mailbox                fffcf000 - fffcf7ff
4760
     * Local bus IF        fffec100 - fffec1ff
4761
     * Local bus MMU        fffec200 - fffec2ff
4762
     * DSP MMU                fffed200 - fffed2ff
4763
     */
4764

    
4765
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
4766

    
4767
    qemu_register_reset(omap_mpu_reset, s);
4768

    
4769
    return s;
4770
}