Statistics
| Branch: | Revision:

root / hw / omap.c @ cf965d24

History | View | Annotate | Download (118.9 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;
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((unsigned long) 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 >> 5;
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
                s->mode = 0;
1329
                omap_clk_put(s->timer.clk);
1330
            } else {
1331
                /* XXX: on T|E hardware somehow this has no effect,
1332
                 * on Zire 71 it works as specified.  */
1333
                s->reset = 1;
1334
                qemu_system_reset_request();
1335
            }
1336
        }
1337
        s->last_wr = value & 0xff;
1338
        break;
1339

    
1340
    default:
1341
        OMAP_BAD_REG(addr);
1342
    }
1343
}
1344

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

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

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

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

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

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

    
1393
    return s;
1394
}
1395

    
1396
/* 32-kHz timer */
1397
struct omap_32khz_timer_s {
1398
    struct omap_mpu_timer_s timer;
1399
};
1400

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

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

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

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

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

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

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

    
1434
    case 0x04:        /* TCR */
1435
        OMAP_RO_REG(addr);
1436
        break;
1437

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

    
1449
    default:
1450
        OMAP_BAD_REG(addr);
1451
    }
1452
}
1453

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

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

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

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

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

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

    
1496
    return s;
1497
}
1498

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

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

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

    
1537
    OMAP_BAD_REG(addr);
1538
    return 0;
1539
}
1540

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1674
    default:
1675
        OMAP_BAD_REG(addr);
1676
    }
1677
}
1678

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1776
    OMAP_BAD_REG(addr);
1777
    return 0;
1778
}
1779

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1903
    default:
1904
        OMAP_BAD_REG(addr);
1905
    }
1906
}
1907

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

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

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

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

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

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

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

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

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

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

    
1982
    OMAP_BAD_REG(addr);
1983
    return 0;
1984
}
1985

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

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

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

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

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

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

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

    
2040
    OMAP_BAD_REG(addr);
2041
    return 0;
2042
}
2043

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

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

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

    
2066
    default:
2067
        OMAP_BAD_REG(addr);
2068
    }
2069
}
2070

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

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

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

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

    
2094
    mpu->mpui_base = base;
2095
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2096

    
2097
    omap_mpui_reset(mpu);
2098
}
2099

    
2100
/* TIPB Bridges */
2101
struct omap_tipb_bridge_s {
2102
    target_phys_addr_t base;
2103
    qemu_irq abort;
2104

    
2105
    int width_intr;
2106
    uint16_t control;
2107
    uint16_t alloc;
2108
    uint16_t buffer;
2109
    uint16_t enh_control;
2110
};
2111

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

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

    
2134
    OMAP_BAD_REG(addr);
2135
    return 0;
2136
}
2137

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

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

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

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

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

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

    
2169
    default:
2170
        OMAP_BAD_REG(addr);
2171
    }
2172
}
2173

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

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

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

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

    
2201
    s->abort = abort_irq;
2202
    s->base = base;
2203
    omap_tipb_bridge_reset(s);
2204

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

    
2209
    return s;
2210
}
2211

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

    
2219
    switch (offset) {
2220
    case 0xfffecc00:        /* IMIF_PRIO */
2221
    case 0xfffecc04:        /* EMIFS_PRIO */
2222
    case 0xfffecc08:        /* EMIFF_PRIO */
2223
    case 0xfffecc0c:        /* EMIFS_CONFIG */
2224
    case 0xfffecc10:        /* EMIFS_CS0_CONFIG */
2225
    case 0xfffecc14:        /* EMIFS_CS1_CONFIG */
2226
    case 0xfffecc18:        /* EMIFS_CS2_CONFIG */
2227
    case 0xfffecc1c:        /* EMIFS_CS3_CONFIG */
2228
    case 0xfffecc24:        /* EMIFF_MRS */
2229
    case 0xfffecc28:        /* TIMEOUT1 */
2230
    case 0xfffecc2c:        /* TIMEOUT2 */
2231
    case 0xfffecc30:        /* TIMEOUT3 */
2232
    case 0xfffecc3c:        /* EMIFF_SDRAM_CONFIG_2 */
2233
    case 0xfffecc40:        /* EMIFS_CFG_DYN_WAIT */
2234
        return s->tcmi_regs[offset >> 2];
2235

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

    
2243
    OMAP_BAD_REG(addr);
2244
    return 0;
2245
}
2246

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

    
2253
    switch (offset) {
2254
    case 0xfffecc00:        /* IMIF_PRIO */
2255
    case 0xfffecc04:        /* EMIFS_PRIO */
2256
    case 0xfffecc08:        /* EMIFF_PRIO */
2257
    case 0xfffecc10:        /* EMIFS_CS0_CONFIG */
2258
    case 0xfffecc14:        /* EMIFS_CS1_CONFIG */
2259
    case 0xfffecc18:        /* EMIFS_CS2_CONFIG */
2260
    case 0xfffecc1c:        /* EMIFS_CS3_CONFIG */
2261
    case 0xfffecc20:        /* EMIFF_SDRAM_CONFIG */
2262
    case 0xfffecc24:        /* EMIFF_MRS */
2263
    case 0xfffecc28:        /* TIMEOUT1 */
2264
    case 0xfffecc2c:        /* TIMEOUT2 */
2265
    case 0xfffecc30:        /* TIMEOUT3 */
2266
    case 0xfffecc3c:        /* EMIFF_SDRAM_CONFIG_2 */
2267
    case 0xfffecc40:        /* EMIFS_CFG_DYN_WAIT */
2268
        s->tcmi_regs[offset >> 2] = value;
2269
        break;
2270
    case 0xfffecc0c:        /* EMIFS_CONFIG */
2271
        s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
2272
        break;
2273

    
2274
    default:
2275
        OMAP_BAD_REG(addr);
2276
    }
2277
}
2278

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

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

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

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

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

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

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

    
2330
    OMAP_BAD_REG(addr);
2331
    return 0;
2332
}
2333

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

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

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

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

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

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

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

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

    
2392
    s->base = base;
2393
    s->dpll = clk;
2394
    omap_dpll_reset(s);
2395

    
2396
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2397
}
2398

    
2399
/* UARTs */
2400
struct omap_uart_s {
2401
    SerialState *serial; /* TODO */
2402
};
2403

    
2404
static void omap_uart_reset(struct omap_uart_s *s)
2405
{
2406
}
2407

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

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

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

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

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

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

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

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

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

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

    
2449
    case 0x20:        /* ARM_CKOUT2 */
2450
        break;
2451
    }
2452

    
2453
    OMAP_BAD_REG(addr);
2454
    return 0;
2455
}
2456

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2727
    OMAP_BAD_REG(addr);
2728
    return 0;
2729
}
2730

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

    
2736
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2737
}
2738

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

    
2744
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2745
}
2746

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

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

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

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

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

    
2775
    default:
2776
        OMAP_BAD_REG(addr);
2777
    }
2778
}
2779

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

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

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

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

    
2823
    s->clkm.mpu_base = mpu_base;
2824
    s->clkm.dsp_base = dsp_base;
2825
    s->clkm.cold_start = 0x3a;
2826
    omap_clkm_reset(s);
2827

    
2828
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2829
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2830
}
2831

    
2832
/* MPU I/O */
2833
struct omap_mpuio_s {
2834
    target_phys_addr_t base;
2835
    qemu_irq irq;
2836
    qemu_irq kbd_irq;
2837
    qemu_irq *in;
2838
    qemu_irq handler[16];
2839
    qemu_irq wakeup;
2840

    
2841
    uint16_t inputs;
2842
    uint16_t outputs;
2843
    uint16_t dir;
2844
    uint16_t edge;
2845
    uint16_t mask;
2846
    uint16_t ints;
2847

    
2848
    uint16_t debounce;
2849
    uint16_t latch;
2850
    uint8_t event;
2851

    
2852
    uint8_t buttons[5];
2853
    uint8_t row_latch;
2854
    uint8_t cols;
2855
    int kbd_mask;
2856
    int clk;
2857
};
2858

    
2859
static void omap_mpuio_set(void *opaque, int line, int level)
2860
{
2861
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2862
    uint16_t prev = s->inputs;
2863

    
2864
    if (level)
2865
        s->inputs |= 1 << line;
2866
    else
2867
        s->inputs &= ~(1 << line);
2868

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

    
2881
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2882
{
2883
    int i;
2884
    uint8_t *row, rows = 0, cols = ~s->cols;
2885

    
2886
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2887
        if (*row & cols)
2888
            rows |= i;
2889

    
2890
    qemu_set_irq(s->kbd_irq, rows && ~s->kbd_mask && s->clk);
2891
    s->row_latch = rows ^ 0x1f;
2892
}
2893

    
2894
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2895
{
2896
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2897
    int offset = addr & OMAP_MPUI_REG_MASK;
2898
    uint16_t ret;
2899

    
2900
    switch (offset) {
2901
    case 0x00:        /* INPUT_LATCH */
2902
        return s->inputs;
2903

    
2904
    case 0x04:        /* OUTPUT_REG */
2905
        return s->outputs;
2906

    
2907
    case 0x08:        /* IO_CNTL */
2908
        return s->dir;
2909

    
2910
    case 0x10:        /* KBR_LATCH */
2911
        return s->row_latch;
2912

    
2913
    case 0x14:        /* KBC_REG */
2914
        return s->cols;
2915

    
2916
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2917
        return s->event;
2918

    
2919
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2920
        return s->edge;
2921

    
2922
    case 0x20:        /* KBD_INT */
2923
        return (s->row_latch != 0x1f) && !s->kbd_mask;
2924

    
2925
    case 0x24:        /* GPIO_INT */
2926
        ret = s->ints;
2927
        s->ints &= s->mask;
2928
        if (ret)
2929
            qemu_irq_lower(s->irq);
2930
        return ret;
2931

    
2932
    case 0x28:        /* KBD_MASKIT */
2933
        return s->kbd_mask;
2934

    
2935
    case 0x2c:        /* GPIO_MASKIT */
2936
        return s->mask;
2937

    
2938
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2939
        return s->debounce;
2940

    
2941
    case 0x34:        /* GPIO_LATCH_REG */
2942
        return s->latch;
2943
    }
2944

    
2945
    OMAP_BAD_REG(addr);
2946
    return 0;
2947
}
2948

    
2949
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2950
                uint32_t value)
2951
{
2952
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2953
    int offset = addr & OMAP_MPUI_REG_MASK;
2954
    uint16_t diff;
2955
    int ln;
2956

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

    
2970
    case 0x08:        /* IO_CNTL */
2971
        diff = s->outputs & (s->dir ^ value);
2972
        s->dir = value;
2973

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

    
2983
    case 0x14:        /* KBC_REG */
2984
        s->cols = value;
2985
        omap_mpuio_kbd_update(s);
2986
        break;
2987

    
2988
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2989
        s->event = value & 0x1f;
2990
        break;
2991

    
2992
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2993
        s->edge = value;
2994
        break;
2995

    
2996
    case 0x28:        /* KBD_MASKIT */
2997
        s->kbd_mask = value & 1;
2998
        omap_mpuio_kbd_update(s);
2999
        break;
3000

    
3001
    case 0x2c:        /* GPIO_MASKIT */
3002
        s->mask = value;
3003
        break;
3004

    
3005
    case 0x30:        /* GPIO_DEBOUNCING_REG */
3006
        s->debounce = value & 0x1ff;
3007
        break;
3008

    
3009
    case 0x00:        /* INPUT_LATCH */
3010
    case 0x10:        /* KBR_LATCH */
3011
    case 0x20:        /* KBD_INT */
3012
    case 0x24:        /* GPIO_INT */
3013
    case 0x34:        /* GPIO_LATCH_REG */
3014
        OMAP_RO_REG(addr);
3015
        return;
3016

    
3017
    default:
3018
        OMAP_BAD_REG(addr);
3019
        return;
3020
    }
3021
}
3022

    
3023
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
3024
    omap_badwidth_read16,
3025
    omap_mpuio_read,
3026
    omap_badwidth_read16,
3027
};
3028

    
3029
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
3030
    omap_badwidth_write16,
3031
    omap_mpuio_write,
3032
    omap_badwidth_write16,
3033
};
3034

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

    
3051
static void omap_mpuio_onoff(void *opaque, int line, int on)
3052
{
3053
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3054

    
3055
    s->clk = on;
3056
    if (on)
3057
        omap_mpuio_kbd_update(s);
3058
}
3059

    
3060
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
3061
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
3062
                omap_clk clk)
3063
{
3064
    int iomemtype;
3065
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
3066
            qemu_mallocz(sizeof(struct omap_mpuio_s));
3067

    
3068
    s->base = base;
3069
    s->irq = gpio_int;
3070
    s->kbd_irq = kbd_int;
3071
    s->wakeup = wakeup;
3072
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
3073
    omap_mpuio_reset(s);
3074

    
3075
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
3076
                    omap_mpuio_writefn, s);
3077
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3078

    
3079
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
3080

    
3081
    return s;
3082
}
3083

    
3084
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
3085
{
3086
    return s->in;
3087
}
3088

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

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

    
3102
    if (down)
3103
        s->buttons[row] |= 1 << col;
3104
    else
3105
        s->buttons[row] &= ~(1 << col);
3106

    
3107
    omap_mpuio_kbd_update(s);
3108
}
3109

    
3110
/* General-Purpose I/O */
3111
struct omap_gpio_s {
3112
    target_phys_addr_t base;
3113
    qemu_irq irq;
3114
    qemu_irq *in;
3115
    qemu_irq handler[16];
3116

    
3117
    uint16_t inputs;
3118
    uint16_t outputs;
3119
    uint16_t dir;
3120
    uint16_t edge;
3121
    uint16_t mask;
3122
    uint16_t ints;
3123
};
3124

    
3125
static void omap_gpio_set(void *opaque, int line, int level)
3126
{
3127
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3128
    uint16_t prev = s->inputs;
3129

    
3130
    if (level)
3131
        s->inputs |= 1 << line;
3132
    else
3133
        s->inputs &= ~(1 << line);
3134

    
3135
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
3136
                    (1 << line) & s->dir & ~s->mask) {
3137
        s->ints |= 1 << line;
3138
        qemu_irq_raise(s->irq);
3139
    }
3140
}
3141

    
3142
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
3143
{
3144
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3145
    int offset = addr & OMAP_MPUI_REG_MASK;
3146

    
3147
    switch (offset) {
3148
    case 0x00:        /* DATA_INPUT */
3149
        return s->inputs;
3150

    
3151
    case 0x04:        /* DATA_OUTPUT */
3152
        return s->outputs;
3153

    
3154
    case 0x08:        /* DIRECTION_CONTROL */
3155
        return s->dir;
3156

    
3157
    case 0x0c:        /* INTERRUPT_CONTROL */
3158
        return s->edge;
3159

    
3160
    case 0x10:        /* INTERRUPT_MASK */
3161
        return s->mask;
3162

    
3163
    case 0x14:        /* INTERRUPT_STATUS */
3164
        return s->ints;
3165
    }
3166

    
3167
    OMAP_BAD_REG(addr);
3168
    return 0;
3169
}
3170

    
3171
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
3172
                uint32_t value)
3173
{
3174
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3175
    int offset = addr & OMAP_MPUI_REG_MASK;
3176
    uint16_t diff;
3177
    int ln;
3178

    
3179
    switch (offset) {
3180
    case 0x00:        /* DATA_INPUT */
3181
        OMAP_RO_REG(addr);
3182
        return;
3183

    
3184
    case 0x04:        /* DATA_OUTPUT */
3185
        diff = (s->outputs ^ value) & ~s->dir;
3186
        s->outputs = value;
3187
        while ((ln = ffs(diff))) {
3188
            ln --;
3189
            if (s->handler[ln])
3190
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3191
            diff &= ~(1 << ln);
3192
        }
3193
        break;
3194

    
3195
    case 0x08:        /* DIRECTION_CONTROL */
3196
        diff = s->outputs & (s->dir ^ value);
3197
        s->dir = value;
3198

    
3199
        value = s->outputs & ~s->dir;
3200
        while ((ln = ffs(diff))) {
3201
            ln --;
3202
            if (s->handler[ln])
3203
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3204
            diff &= ~(1 << ln);
3205
        }
3206
        break;
3207

    
3208
    case 0x0c:        /* INTERRUPT_CONTROL */
3209
        s->edge = value;
3210
        break;
3211

    
3212
    case 0x10:        /* INTERRUPT_MASK */
3213
        s->mask = value;
3214
        break;
3215

    
3216
    case 0x14:        /* INTERRUPT_STATUS */
3217
        s->ints &= ~value;
3218
        if (!s->ints)
3219
            qemu_irq_lower(s->irq);
3220
        break;
3221

    
3222
    default:
3223
        OMAP_BAD_REG(addr);
3224
        return;
3225
    }
3226
}
3227

    
3228
/* *Some* sources say the memory region is 32-bit.  */
3229
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
3230
    omap_badwidth_read16,
3231
    omap_gpio_read,
3232
    omap_badwidth_read16,
3233
};
3234

    
3235
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
3236
    omap_badwidth_write16,
3237
    omap_gpio_write,
3238
    omap_badwidth_write16,
3239
};
3240

    
3241
void omap_gpio_reset(struct omap_gpio_s *s)
3242
{
3243
    s->inputs = 0;
3244
    s->outputs = ~0;
3245
    s->dir = ~0;
3246
    s->edge = ~0;
3247
    s->mask = ~0;
3248
    s->ints = 0;
3249
}
3250

    
3251
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
3252
                qemu_irq irq, omap_clk clk)
3253
{
3254
    int iomemtype;
3255
    struct omap_gpio_s *s = (struct omap_gpio_s *)
3256
            qemu_mallocz(sizeof(struct omap_gpio_s));
3257

    
3258
    s->base = base;
3259
    s->irq = irq;
3260
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
3261
    omap_gpio_reset(s);
3262

    
3263
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
3264
                    omap_gpio_writefn, s);
3265
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3266

    
3267
    return s;
3268
}
3269

    
3270
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
3271
{
3272
    return s->in;
3273
}
3274

    
3275
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3276
{
3277
    if (line >= 16 || line < 0)
3278
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3279
    s->handler[line] = handler;
3280
}
3281

    
3282
/* MicroWire Interface */
3283
struct omap_uwire_s {
3284
    target_phys_addr_t base;
3285
    qemu_irq txirq;
3286
    qemu_irq rxirq;
3287
    qemu_irq txdrq;
3288

    
3289
    uint16_t txbuf;
3290
    uint16_t rxbuf;
3291
    uint16_t control;
3292
    uint16_t setup[5];
3293

    
3294
    struct uwire_slave_s *chip[4];
3295
};
3296

    
3297
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3298
{
3299
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3300
    struct uwire_slave_s *slave = s->chip[chipselect];
3301

    
3302
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
3303
        if (s->control & (1 << 12))                        /* CS_CMD */
3304
            if (slave && slave->send)
3305
                slave->send(slave->opaque,
3306
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3307
        s->control &= ~(1 << 14);                        /* CSRB */
3308
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3309
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3310
    }
3311

    
3312
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
3313
        if (s->control & (1 << 12))                        /* CS_CMD */
3314
            if (slave && slave->receive)
3315
                s->rxbuf = slave->receive(slave->opaque);
3316
        s->control |= 1 << 15;                                /* RDRB */
3317
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3318
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3319
    }
3320
}
3321

    
3322
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3323
{
3324
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3325
    int offset = addr & OMAP_MPUI_REG_MASK;
3326

    
3327
    switch (offset) {
3328
    case 0x00:        /* RDR */
3329
        s->control &= ~(1 << 15);                        /* RDRB */
3330
        return s->rxbuf;
3331

    
3332
    case 0x04:        /* CSR */
3333
        return s->control;
3334

    
3335
    case 0x08:        /* SR1 */
3336
        return s->setup[0];
3337
    case 0x0c:        /* SR2 */
3338
        return s->setup[1];
3339
    case 0x10:        /* SR3 */
3340
        return s->setup[2];
3341
    case 0x14:        /* SR4 */
3342
        return s->setup[3];
3343
    case 0x18:        /* SR5 */
3344
        return s->setup[4];
3345
    }
3346

    
3347
    OMAP_BAD_REG(addr);
3348
    return 0;
3349
}
3350

    
3351
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3352
                uint32_t value)
3353
{
3354
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3355
    int offset = addr & OMAP_MPUI_REG_MASK;
3356

    
3357
    switch (offset) {
3358
    case 0x00:        /* TDR */
3359
        s->txbuf = value;                                /* TD */
3360
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3361
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3362
                         (s->control & (1 << 12)))) {        /* CS_CMD */
3363
            s->control |= 1 << 14;                        /* CSRB */
3364
            omap_uwire_transfer_start(s);
3365
        }
3366
        break;
3367

    
3368
    case 0x04:        /* CSR */
3369
        s->control = value & 0x1fff;
3370
        if (value & (1 << 13))                                /* START */
3371
            omap_uwire_transfer_start(s);
3372
        break;
3373

    
3374
    case 0x08:        /* SR1 */
3375
        s->setup[0] = value & 0x003f;
3376
        break;
3377

    
3378
    case 0x0c:        /* SR2 */
3379
        s->setup[1] = value & 0x0fc0;
3380
        break;
3381

    
3382
    case 0x10:        /* SR3 */
3383
        s->setup[2] = value & 0x0003;
3384
        break;
3385

    
3386
    case 0x14:        /* SR4 */
3387
        s->setup[3] = value & 0x0001;
3388
        break;
3389

    
3390
    case 0x18:        /* SR5 */
3391
        s->setup[4] = value & 0x000f;
3392
        break;
3393

    
3394
    default:
3395
        OMAP_BAD_REG(addr);
3396
        return;
3397
    }
3398
}
3399

    
3400
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3401
    omap_badwidth_read16,
3402
    omap_uwire_read,
3403
    omap_badwidth_read16,
3404
};
3405

    
3406
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3407
    omap_badwidth_write16,
3408
    omap_uwire_write,
3409
    omap_badwidth_write16,
3410
};
3411

    
3412
void omap_uwire_reset(struct omap_uwire_s *s)
3413
{
3414
    s->control = 0;
3415
    s->setup[0] = 0;
3416
    s->setup[1] = 0;
3417
    s->setup[2] = 0;
3418
    s->setup[3] = 0;
3419
    s->setup[4] = 0;
3420
}
3421

    
3422
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3423
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3424
{
3425
    int iomemtype;
3426
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3427
            qemu_mallocz(sizeof(struct omap_uwire_s));
3428

    
3429
    s->base = base;
3430
    s->txirq = irq[0];
3431
    s->rxirq = irq[1];
3432
    s->txdrq = dma;
3433
    omap_uwire_reset(s);
3434

    
3435
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3436
                    omap_uwire_writefn, s);
3437
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3438

    
3439
    return s;
3440
}
3441

    
3442
void omap_uwire_attach(struct omap_uwire_s *s,
3443
                struct uwire_slave_s *slave, int chipselect)
3444
{
3445
    if (chipselect < 0 || chipselect > 3)
3446
        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
3447
                        chipselect);
3448

    
3449
    s->chip[chipselect] = slave;
3450
}
3451

    
3452
/* Pseudonoise Pulse-Width Light Modulator */
3453
void omap_pwl_update(struct omap_mpu_state_s *s)
3454
{
3455
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3456

    
3457
    if (output != s->pwl.output) {
3458
        s->pwl.output = output;
3459
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3460
    }
3461
}
3462

    
3463
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3464
{
3465
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3466
    int offset = addr & OMAP_MPUI_REG_MASK;
3467

    
3468
    switch (offset) {
3469
    case 0x00:        /* PWL_LEVEL */
3470
        return s->pwl.level;
3471
    case 0x04:        /* PWL_CTRL */
3472
        return s->pwl.enable;
3473
    }
3474
    OMAP_BAD_REG(addr);
3475
    return 0;
3476
}
3477

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

    
3484
    switch (offset) {
3485
    case 0x00:        /* PWL_LEVEL */
3486
        s->pwl.level = value;
3487
        omap_pwl_update(s);
3488
        break;
3489
    case 0x04:        /* PWL_CTRL */
3490
        s->pwl.enable = value & 1;
3491
        omap_pwl_update(s);
3492
        break;
3493
    default:
3494
        OMAP_BAD_REG(addr);
3495
        return;
3496
    }
3497
}
3498

    
3499
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3500
    omap_pwl_read,
3501
    omap_badwidth_read8,
3502
    omap_badwidth_read8,
3503
};
3504

    
3505
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3506
    omap_pwl_write,
3507
    omap_badwidth_write8,
3508
    omap_badwidth_write8,
3509
};
3510

    
3511
void omap_pwl_reset(struct omap_mpu_state_s *s)
3512
{
3513
    s->pwl.output = 0;
3514
    s->pwl.level = 0;
3515
    s->pwl.enable = 0;
3516
    s->pwl.clk = 1;
3517
    omap_pwl_update(s);
3518
}
3519

    
3520
static void omap_pwl_clk_update(void *opaque, int line, int on)
3521
{
3522
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3523

    
3524
    s->pwl.clk = on;
3525
    omap_pwl_update(s);
3526
}
3527

    
3528
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3529
                omap_clk clk)
3530
{
3531
    int iomemtype;
3532

    
3533
    omap_pwl_reset(s);
3534

    
3535
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3536
                    omap_pwl_writefn, s);
3537
    cpu_register_physical_memory(base, 0x800, iomemtype);
3538

    
3539
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3540
}
3541

    
3542
/* Pulse-Width Tone module */
3543
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3544
{
3545
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3546
    int offset = addr & OMAP_MPUI_REG_MASK;
3547

    
3548
    switch (offset) {
3549
    case 0x00:        /* FRC */
3550
        return s->pwt.frc;
3551
    case 0x04:        /* VCR */
3552
        return s->pwt.vrc;
3553
    case 0x08:        /* GCR */
3554
        return s->pwt.gcr;
3555
    }
3556
    OMAP_BAD_REG(addr);
3557
    return 0;
3558
}
3559

    
3560
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3561
                uint32_t value)
3562
{
3563
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3564
    int offset = addr & OMAP_MPUI_REG_MASK;
3565

    
3566
    switch (offset) {
3567
    case 0x00:        /* FRC */
3568
        s->pwt.frc = value & 0x3f;
3569
        break;
3570
    case 0x04:        /* VRC */
3571
        if ((value ^ s->pwt.vrc) & 1) {
3572
            if (value & 1)
3573
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
3574
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
3575
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
3576
                                 /* Pre-multiplexer divider */
3577
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
3578
                                 /* Octave multiplexer */
3579
                                 (2 << (value & 3)) *
3580
                                 /* 101/107 divider */
3581
                                 ((value & (1 << 2)) ? 101 : 107) *
3582
                                 /*  49/55 divider */
3583
                                 ((value & (1 << 3)) ?  49 : 55) *
3584
                                 /*  50/63 divider */
3585
                                 ((value & (1 << 4)) ?  50 : 63) *
3586
                                 /*  80/127 divider */
3587
                                 ((value & (1 << 5)) ?  80 : 127) /
3588
                                 (107 * 55 * 63 * 127)));
3589
            else
3590
                printf("%s: silence!\n", __FUNCTION__);
3591
        }
3592
        s->pwt.vrc = value & 0x7f;
3593
        break;
3594
    case 0x08:        /* GCR */
3595
        s->pwt.gcr = value & 3;
3596
        break;
3597
    default:
3598
        OMAP_BAD_REG(addr);
3599
        return;
3600
    }
3601
}
3602

    
3603
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3604
    omap_pwt_read,
3605
    omap_badwidth_read8,
3606
    omap_badwidth_read8,
3607
};
3608

    
3609
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3610
    omap_pwt_write,
3611
    omap_badwidth_write8,
3612
    omap_badwidth_write8,
3613
};
3614

    
3615
void omap_pwt_reset(struct omap_mpu_state_s *s)
3616
{
3617
    s->pwt.frc = 0;
3618
    s->pwt.vrc = 0;
3619
    s->pwt.gcr = 0;
3620
}
3621

    
3622
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3623
                omap_clk clk)
3624
{
3625
    int iomemtype;
3626

    
3627
    s->pwt.clk = clk;
3628
    omap_pwt_reset(s);
3629

    
3630
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3631
                    omap_pwt_writefn, s);
3632
    cpu_register_physical_memory(base, 0x800, iomemtype);
3633
}
3634

    
3635
/* Real-time Clock module */
3636
struct omap_rtc_s {
3637
    target_phys_addr_t base;
3638
    qemu_irq irq;
3639
    qemu_irq alarm;
3640
    QEMUTimer *clk;
3641

    
3642
    uint8_t interrupts;
3643
    uint8_t status;
3644
    int16_t comp_reg;
3645
    int running;
3646
    int pm_am;
3647
    int auto_comp;
3648
    int round;
3649
    struct tm *(*convert)(const time_t *timep, struct tm *result);
3650
    struct tm alarm_tm;
3651
    time_t alarm_ti;
3652

    
3653
    struct tm current_tm;
3654
    time_t ti;
3655
    uint64_t tick;
3656
};
3657

    
3658
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3659
{
3660
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3661
}
3662

    
3663
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3664
{
3665
    s->alarm_ti = mktime(&s->alarm_tm);
3666
    if (s->alarm_ti == -1)
3667
        printf("%s: conversion failed\n", __FUNCTION__);
3668
}
3669

    
3670
static inline uint8_t omap_rtc_bcd(int num)
3671
{
3672
    return ((num / 10) << 4) | (num % 10);
3673
}
3674

    
3675
static inline int omap_rtc_bin(uint8_t num)
3676
{
3677
    return (num & 15) + 10 * (num >> 4);
3678
}
3679

    
3680
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3681
{
3682
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3683
    int offset = addr & OMAP_MPUI_REG_MASK;
3684
    uint8_t i;
3685

    
3686
    switch (offset) {
3687
    case 0x00:        /* SECONDS_REG */
3688
        return omap_rtc_bcd(s->current_tm.tm_sec);
3689

    
3690
    case 0x04:        /* MINUTES_REG */
3691
        return omap_rtc_bcd(s->current_tm.tm_min);
3692

    
3693
    case 0x08:        /* HOURS_REG */
3694
        if (s->pm_am)
3695
            return ((s->current_tm.tm_hour > 11) << 7) |
3696
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3697
        else
3698
            return omap_rtc_bcd(s->current_tm.tm_hour);
3699

    
3700
    case 0x0c:        /* DAYS_REG */
3701
        return omap_rtc_bcd(s->current_tm.tm_mday);
3702

    
3703
    case 0x10:        /* MONTHS_REG */
3704
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3705

    
3706
    case 0x14:        /* YEARS_REG */
3707
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3708

    
3709
    case 0x18:        /* WEEK_REG */
3710
        return s->current_tm.tm_wday;
3711

    
3712
    case 0x20:        /* ALARM_SECONDS_REG */
3713
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3714

    
3715
    case 0x24:        /* ALARM_MINUTES_REG */
3716
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3717

    
3718
    case 0x28:        /* ALARM_HOURS_REG */
3719
        if (s->pm_am)
3720
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3721
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3722
        else
3723
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
3724

    
3725
    case 0x2c:        /* ALARM_DAYS_REG */
3726
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3727

    
3728
    case 0x30:        /* ALARM_MONTHS_REG */
3729
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3730

    
3731
    case 0x34:        /* ALARM_YEARS_REG */
3732
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3733

    
3734
    case 0x40:        /* RTC_CTRL_REG */
3735
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3736
                (s->round << 1) | s->running;
3737

    
3738
    case 0x44:        /* RTC_STATUS_REG */
3739
        i = s->status;
3740
        s->status &= ~0x3d;
3741
        return i;
3742

    
3743
    case 0x48:        /* RTC_INTERRUPTS_REG */
3744
        return s->interrupts;
3745

    
3746
    case 0x4c:        /* RTC_COMP_LSB_REG */
3747
        return ((uint16_t) s->comp_reg) & 0xff;
3748

    
3749
    case 0x50:        /* RTC_COMP_MSB_REG */
3750
        return ((uint16_t) s->comp_reg) >> 8;
3751
    }
3752

    
3753
    OMAP_BAD_REG(addr);
3754
    return 0;
3755
}
3756

    
3757
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3758
                uint32_t value)
3759
{
3760
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3761
    int offset = addr & OMAP_MPUI_REG_MASK;
3762
    struct tm new_tm;
3763
    time_t ti[2];
3764

    
3765
    switch (offset) {
3766
    case 0x00:        /* SECONDS_REG */
3767
#if ALMDEBUG
3768
        printf("RTC SEC_REG <-- %02x\n", value);
3769
#endif
3770
        s->ti -= s->current_tm.tm_sec;
3771
        s->ti += omap_rtc_bin(value);
3772
        return;
3773

    
3774
    case 0x04:        /* MINUTES_REG */
3775
#if ALMDEBUG
3776
        printf("RTC MIN_REG <-- %02x\n", value);
3777
#endif
3778
        s->ti -= s->current_tm.tm_min * 60;
3779
        s->ti += omap_rtc_bin(value) * 60;
3780
        return;
3781

    
3782
    case 0x08:        /* HOURS_REG */
3783
#if ALMDEBUG
3784
        printf("RTC HRS_REG <-- %02x\n", value);
3785
#endif
3786
        s->ti -= s->current_tm.tm_hour * 3600;
3787
        if (s->pm_am) {
3788
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3789
            s->ti += ((value >> 7) & 1) * 43200;
3790
        } else
3791
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3792
        return;
3793

    
3794
    case 0x0c:        /* DAYS_REG */
3795
#if ALMDEBUG
3796
        printf("RTC DAY_REG <-- %02x\n", value);
3797
#endif
3798
        s->ti -= s->current_tm.tm_mday * 86400;
3799
        s->ti += omap_rtc_bin(value) * 86400;
3800
        return;
3801

    
3802
    case 0x10:        /* MONTHS_REG */
3803
#if ALMDEBUG
3804
        printf("RTC MTH_REG <-- %02x\n", value);
3805
#endif
3806
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3807
        new_tm.tm_mon = omap_rtc_bin(value);
3808
        ti[0] = mktime(&s->current_tm);
3809
        ti[1] = mktime(&new_tm);
3810

    
3811
        if (ti[0] != -1 && ti[1] != -1) {
3812
            s->ti -= ti[0];
3813
            s->ti += ti[1];
3814
        } else {
3815
            /* A less accurate version */
3816
            s->ti -= s->current_tm.tm_mon * 2592000;
3817
            s->ti += omap_rtc_bin(value) * 2592000;
3818
        }
3819
        return;
3820

    
3821
    case 0x14:        /* YEARS_REG */
3822
#if ALMDEBUG
3823
        printf("RTC YRS_REG <-- %02x\n", value);
3824
#endif
3825
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3826
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3827
        ti[0] = mktime(&s->current_tm);
3828
        ti[1] = mktime(&new_tm);
3829

    
3830
        if (ti[0] != -1 && ti[1] != -1) {
3831
            s->ti -= ti[0];
3832
            s->ti += ti[1];
3833
        } else {
3834
            /* A less accurate version */
3835
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3836
            s->ti += omap_rtc_bin(value) * 31536000;
3837
        }
3838
        return;
3839

    
3840
    case 0x18:        /* WEEK_REG */
3841
        return;        /* Ignored */
3842

    
3843
    case 0x20:        /* ALARM_SECONDS_REG */
3844
#if ALMDEBUG
3845
        printf("ALM SEC_REG <-- %02x\n", value);
3846
#endif
3847
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3848
        omap_rtc_alarm_update(s);
3849
        return;
3850

    
3851
    case 0x24:        /* ALARM_MINUTES_REG */
3852
#if ALMDEBUG
3853
        printf("ALM MIN_REG <-- %02x\n", value);
3854
#endif
3855
        s->alarm_tm.tm_min = omap_rtc_bin(value);
3856
        omap_rtc_alarm_update(s);
3857
        return;
3858

    
3859
    case 0x28:        /* ALARM_HOURS_REG */
3860
#if ALMDEBUG
3861
        printf("ALM HRS_REG <-- %02x\n", value);
3862
#endif
3863
        if (s->pm_am)
3864
            s->alarm_tm.tm_hour =
3865
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
3866
                    ((value >> 7) & 1) * 12;
3867
        else
3868
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
3869
        omap_rtc_alarm_update(s);
3870
        return;
3871

    
3872
    case 0x2c:        /* ALARM_DAYS_REG */
3873
#if ALMDEBUG
3874
        printf("ALM DAY_REG <-- %02x\n", value);
3875
#endif
3876
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3877
        omap_rtc_alarm_update(s);
3878
        return;
3879

    
3880
    case 0x30:        /* ALARM_MONTHS_REG */
3881
#if ALMDEBUG
3882
        printf("ALM MON_REG <-- %02x\n", value);
3883
#endif
3884
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3885
        omap_rtc_alarm_update(s);
3886
        return;
3887

    
3888
    case 0x34:        /* ALARM_YEARS_REG */
3889
#if ALMDEBUG
3890
        printf("ALM YRS_REG <-- %02x\n", value);
3891
#endif
3892
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3893
        omap_rtc_alarm_update(s);
3894
        return;
3895

    
3896
    case 0x40:        /* RTC_CTRL_REG */
3897
#if ALMDEBUG
3898
        printf("RTC CONTROL <-- %02x\n", value);
3899
#endif
3900
        s->pm_am = (value >> 3) & 1;
3901
        s->auto_comp = (value >> 2) & 1;
3902
        s->round = (value >> 1) & 1;
3903
        s->running = value & 1;
3904
        s->status &= 0xfd;
3905
        s->status |= s->running << 1;
3906
        return;
3907

    
3908
    case 0x44:        /* RTC_STATUS_REG */
3909
#if ALMDEBUG
3910
        printf("RTC STATUSL <-- %02x\n", value);
3911
#endif
3912
        s->status &= ~((value & 0xc0) ^ 0x80);
3913
        omap_rtc_interrupts_update(s);
3914
        return;
3915

    
3916
    case 0x48:        /* RTC_INTERRUPTS_REG */
3917
#if ALMDEBUG
3918
        printf("RTC INTRS <-- %02x\n", value);
3919
#endif
3920
        s->interrupts = value;
3921
        return;
3922

    
3923
    case 0x4c:        /* RTC_COMP_LSB_REG */
3924
#if ALMDEBUG
3925
        printf("RTC COMPLSB <-- %02x\n", value);
3926
#endif
3927
        s->comp_reg &= 0xff00;
3928
        s->comp_reg |= 0x00ff & value;
3929
        return;
3930

    
3931
    case 0x50:        /* RTC_COMP_MSB_REG */
3932
#if ALMDEBUG
3933
        printf("RTC COMPMSB <-- %02x\n", value);
3934
#endif
3935
        s->comp_reg &= 0x00ff;
3936
        s->comp_reg |= 0xff00 & (value << 8);
3937
        return;
3938

    
3939
    default:
3940
        OMAP_BAD_REG(addr);
3941
        return;
3942
    }
3943
}
3944

    
3945
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3946
    omap_rtc_read,
3947
    omap_badwidth_read8,
3948
    omap_badwidth_read8,
3949
};
3950

    
3951
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3952
    omap_rtc_write,
3953
    omap_badwidth_write8,
3954
    omap_badwidth_write8,
3955
};
3956

    
3957
static void omap_rtc_tick(void *opaque)
3958
{
3959
    struct omap_rtc_s *s = opaque;
3960

    
3961
    if (s->round) {
3962
        /* Round to nearest full minute.  */
3963
        if (s->current_tm.tm_sec < 30)
3964
            s->ti -= s->current_tm.tm_sec;
3965
        else
3966
            s->ti += 60 - s->current_tm.tm_sec;
3967

    
3968
        s->round = 0;
3969
    }
3970

    
3971
    localtime_r(&s->ti, &s->current_tm);
3972

    
3973
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3974
        s->status |= 0x40;
3975
        omap_rtc_interrupts_update(s);
3976
    }
3977

    
3978
    if (s->interrupts & 0x04)
3979
        switch (s->interrupts & 3) {
3980
        case 0:
3981
            s->status |= 0x04;
3982
            qemu_irq_raise(s->irq);
3983
            break;
3984
        case 1:
3985
            if (s->current_tm.tm_sec)
3986
                break;
3987
            s->status |= 0x08;
3988
            qemu_irq_raise(s->irq);
3989
            break;
3990
        case 2:
3991
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
3992
                break;
3993
            s->status |= 0x10;
3994
            qemu_irq_raise(s->irq);
3995
            break;
3996
        case 3:
3997
            if (s->current_tm.tm_sec ||
3998
                            s->current_tm.tm_min || s->current_tm.tm_hour)
3999
                break;
4000
            s->status |= 0x20;
4001
            qemu_irq_raise(s->irq);
4002
            break;
4003
        }
4004

    
4005
    /* Move on */
4006
    if (s->running)
4007
        s->ti ++;
4008
    s->tick += 1000;
4009

    
4010
    /*
4011
     * Every full hour add a rough approximation of the compensation
4012
     * register to the 32kHz Timer (which drives the RTC) value. 
4013
     */
4014
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
4015
        s->tick += s->comp_reg * 1000 / 32768;
4016

    
4017
    qemu_mod_timer(s->clk, s->tick);
4018
}
4019

    
4020
void omap_rtc_reset(struct omap_rtc_s *s)
4021
{
4022
    s->interrupts = 0;
4023
    s->comp_reg = 0;
4024
    s->running = 0;
4025
    s->pm_am = 0;
4026
    s->auto_comp = 0;
4027
    s->round = 0;
4028
    s->tick = qemu_get_clock(rt_clock);
4029
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
4030
    s->alarm_tm.tm_mday = 0x01;
4031
    s->status = 1 << 7;
4032
    time(&s->ti);
4033
    s->ti = mktime(s->convert(&s->ti, &s->current_tm));
4034

    
4035
    omap_rtc_alarm_update(s);
4036
    omap_rtc_tick(s);
4037
}
4038

    
4039
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
4040
                qemu_irq *irq, omap_clk clk)
4041
{
4042
    int iomemtype;
4043
    struct omap_rtc_s *s = (struct omap_rtc_s *)
4044
            qemu_mallocz(sizeof(struct omap_rtc_s));
4045

    
4046
    s->base = base;
4047
    s->irq = irq[0];
4048
    s->alarm = irq[1];
4049
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
4050
    s->convert = rtc_utc ? gmtime_r : localtime_r;
4051

    
4052
    omap_rtc_reset(s);
4053

    
4054
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
4055
                    omap_rtc_writefn, s);
4056
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4057

    
4058
    return s;
4059
}
4060

    
4061
/* General chip reset */
4062
static void omap_mpu_reset(void *opaque)
4063
{
4064
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4065

    
4066
    omap_clkm_reset(mpu);
4067
    omap_inth_reset(mpu->ih[0]);
4068
    omap_inth_reset(mpu->ih[1]);
4069
    omap_dma_reset(mpu->dma);
4070
    omap_mpu_timer_reset(mpu->timer[0]);
4071
    omap_mpu_timer_reset(mpu->timer[1]);
4072
    omap_mpu_timer_reset(mpu->timer[2]);
4073
    omap_wd_timer_reset(mpu->wdt);
4074
    omap_os_timer_reset(mpu->os_timer);
4075
    omap_lcdc_reset(mpu->lcd);
4076
    omap_ulpd_pm_reset(mpu);
4077
    omap_pin_cfg_reset(mpu);
4078
    omap_mpui_reset(mpu);
4079
    omap_tipb_bridge_reset(mpu->private_tipb);
4080
    omap_tipb_bridge_reset(mpu->public_tipb);
4081
    omap_dpll_reset(&mpu->dpll[0]);
4082
    omap_dpll_reset(&mpu->dpll[1]);
4083
    omap_dpll_reset(&mpu->dpll[2]);
4084
    omap_uart_reset(mpu->uart[0]);
4085
    omap_uart_reset(mpu->uart[1]);
4086
    omap_uart_reset(mpu->uart[2]);
4087
    omap_mmc_reset(mpu->mmc);
4088
    omap_mpuio_reset(mpu->mpuio);
4089
    omap_gpio_reset(mpu->gpio);
4090
    omap_uwire_reset(mpu->microwire);
4091
    omap_pwl_reset(mpu);
4092
    omap_pwt_reset(mpu);
4093
    omap_i2c_reset(mpu->i2c);
4094
    omap_rtc_reset(mpu->rtc);
4095
    cpu_reset(mpu->env);
4096
}
4097

    
4098
static const struct omap_map_s {
4099
    target_phys_addr_t phys_dsp;
4100
    target_phys_addr_t phys_mpu;
4101
    uint32_t size;
4102
    const char *name;
4103
} omap15xx_dsp_mm[] = {
4104
    /* Strobe 0 */
4105
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
4106
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
4107
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
4108
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
4109
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
4110
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
4111
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
4112
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
4113
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
4114
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
4115
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
4116
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
4117
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
4118
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
4119
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
4120
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
4121
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
4122
    /* Strobe 1 */
4123
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
4124

    
4125
    { 0 }
4126
};
4127

    
4128
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4129
{
4130
    int io;
4131

    
4132
    for (; map->phys_dsp; map ++) {
4133
        io = cpu_get_physical_page_desc(map->phys_mpu);
4134

    
4135
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4136
    }
4137
}
4138

    
4139
static void omap_mpu_wakeup(void *opaque, int irq, int req)
4140
{
4141
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4142

    
4143
    if (mpu->env->halted)
4144
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4145
}
4146

    
4147
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4148
                DisplayState *ds, const char *core)
4149
{
4150
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4151
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4152
    ram_addr_t imif_base, emiff_base;
4153

    
4154
    /* Core */
4155
    s->mpu_model = omap310;
4156
    s->env = cpu_init();
4157
    s->sdram_size = sdram_size;
4158
    s->sram_size = OMAP15XX_SRAM_SIZE;
4159

    
4160
    cpu_arm_set_model(s->env, core ?: "ti925t");
4161

    
4162
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4163

    
4164
    /* Clocks */
4165
    omap_clk_init(s);
4166

    
4167
    /* Memory-mapped stuff */
4168
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4169
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4170
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4171
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4172

    
4173
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4174

    
4175
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100,
4176
                    arm_pic_init_cpu(s->env),
4177
                    omap_findclk(s, "arminth_ck"));
4178
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800,
4179
                    &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ],
4180
                    omap_findclk(s, "arminth_ck"));
4181
    s->irq[0] = s->ih[0]->pins;
4182
    s->irq[1] = s->ih[1]->pins;
4183

    
4184
    s->dma = omap_dma_init(0xfffed800, s->irq[0], s,
4185
                    omap_findclk(s, "dma_ck"));
4186
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4187
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4188
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4189
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4190
    s->port[local    ].addr_valid = omap_validate_local_addr;
4191
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4192

    
4193
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4194
                    s->irq[0][OMAP_INT_TIMER1],
4195
                    omap_findclk(s, "mputim_ck"));
4196
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4197
                    s->irq[0][OMAP_INT_TIMER2],
4198
                    omap_findclk(s, "mputim_ck"));
4199
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4200
                    s->irq[0][OMAP_INT_TIMER3],
4201
                    omap_findclk(s, "mputim_ck"));
4202

    
4203
    s->wdt = omap_wd_timer_init(0xfffec800,
4204
                    s->irq[0][OMAP_INT_WD_TIMER],
4205
                    omap_findclk(s, "armwdt_ck"));
4206

    
4207
    s->os_timer = omap_os_timer_init(0xfffb9000,
4208
                    s->irq[1][OMAP_INT_OS_TIMER],
4209
                    omap_findclk(s, "clk32-kHz"));
4210

    
4211
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4212
                    &s->dma->lcd_ch, ds, imif_base, emiff_base,
4213
                    omap_findclk(s, "lcd_ck"));
4214

    
4215
    omap_ulpd_pm_init(0xfffe0800, s);
4216
    omap_pin_cfg_init(0xfffe1000, s);
4217
    omap_id_init(s);
4218

    
4219
    omap_mpui_init(0xfffec900, s);
4220

    
4221
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4222
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4223
                    omap_findclk(s, "tipb_ck"));
4224
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4225
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4226
                    omap_findclk(s, "tipb_ck"));
4227

    
4228
    omap_tcmi_init(0xfffecc00, s);
4229

    
4230
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4231
                    omap_findclk(s, "uart1_ck"),
4232
                    serial_hds[0]);
4233
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4234
                    omap_findclk(s, "uart2_ck"),
4235
                    serial_hds[0] ? serial_hds[1] : 0);
4236
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4237
                    omap_findclk(s, "uart3_ck"),
4238
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4239

    
4240
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4241
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4242
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4243

    
4244
    s->mmc = omap_mmc_init(0xfffb7800, s->irq[1][OMAP_INT_OQN],
4245
                    &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
4246

    
4247
    s->mpuio = omap_mpuio_init(0xfffb5000,
4248
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4249
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
4250

    
4251
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4252
                    omap_findclk(s, "arm_gpio_ck"));
4253

    
4254
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4255
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4256

    
4257
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "clk32-kHz"));
4258
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "xtal_osc_12m"));
4259

    
4260
    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4261
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4262

    
4263
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4264
                    omap_findclk(s, "clk32-kHz"));
4265

    
4266
    /* Register mappings not currenlty implemented:
4267
     * McBSP2 Comm        fffb1000 - fffb17ff
4268
     * McBSP1 Audio        fffb1800 - fffb1fff (not mapped on OMAP310)
4269
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4270
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4271
     * USB W2FC                fffb4000 - fffb47ff
4272
     * Camera Interface        fffb6800 - fffb6fff
4273
     * McBSP3                fffb7000 - fffb77ff (not mapped on OMAP310)
4274
     * USB Host                fffba000 - fffba7ff
4275
     * FAC                fffba800 - fffbafff
4276
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4277
     * TIPB switches        fffbc800 - fffbcfff
4278
     * LED1                fffbd000 - fffbd7ff
4279
     * LED2                fffbd800 - fffbdfff
4280
     * Mailbox                fffcf000 - fffcf7ff
4281
     * Local bus IF        fffec100 - fffec1ff
4282
     * Local bus MMU        fffec200 - fffec2ff
4283
     * DSP MMU                fffed200 - fffed2ff
4284
     */
4285

    
4286
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
4287

    
4288
    qemu_register_reset(omap_mpu_reset, s);
4289

    
4290
    return s;
4291
}