Statistics
| Branch: | Revision:

root / hw / omap.c @ c3e88d8c

History | View | Annotate | Download (83.8 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_read16(void *opaque, target_phys_addr_t addr)
26
{
27
    OMAP_16B_REG(addr);
28
    return 0;
29
}
30

    
31
void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
32
                uint32_t value)
33
{
34
    OMAP_16B_REG(addr);
35
}
36

    
37
uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
38
{
39
    OMAP_32B_REG(addr);
40
    return 0;
41
}
42

    
43
void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
44
                uint32_t value)
45
{
46
    OMAP_32B_REG(addr);
47
}
48

    
49
#define likely
50
#define unlikely
51

    
52
/* Interrupt Handlers */
53
struct omap_intr_handler_s {
54
    qemu_irq *pins;
55
    qemu_irq *parent_pic;
56
    target_phys_addr_t base;
57

    
58
    /* state */
59
    uint32_t irqs;
60
    uint32_t mask;
61
    uint32_t sens_edge;
62
    uint32_t fiq;
63
    int priority[32];
64
    uint32_t new_irq_agr;
65
    uint32_t new_fiq_agr;
66
    int sir_irq;
67
    int sir_fiq;
68
    int stats[32];
69
};
70

    
71
static void omap_inth_update(struct omap_intr_handler_s *s)
72
{
73
    uint32_t irq = s->irqs & ~s->mask & ~s->fiq;
74
    uint32_t fiq = s->irqs & ~s->mask & s->fiq;
75

    
76
    if (s->new_irq_agr || !irq) {
77
       qemu_set_irq(s->parent_pic[ARM_PIC_CPU_IRQ], irq);
78
       if (irq)
79
           s->new_irq_agr = 0;
80
    }
81

    
82
    if (s->new_fiq_agr || !irq) {
83
        qemu_set_irq(s->parent_pic[ARM_PIC_CPU_FIQ], fiq);
84
        if (fiq)
85
            s->new_fiq_agr = 0;
86
    }
87
}
88

    
89
static void omap_inth_sir_update(struct omap_intr_handler_s *s)
90
{
91
    int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f;
92
    uint32_t level = s->irqs & ~s->mask;
93

    
94
    intr_irq = 0;
95
    intr_fiq = 0;
96
    p_irq = -1;
97
    p_fiq = -1;
98
    /* Find the interrupt line with the highest dynamic priority */
99
    for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, level >>= f) {
100
        p = s->priority[i];
101
        if (s->fiq & (1 << i)) {
102
            if (p > p_fiq) {
103
                p_fiq = p;
104
                intr_fiq = i;
105
            }
106
        } else {
107
            if (p > p_irq) {
108
                p_irq = p;
109
                intr_irq = i;
110
            }
111
        }
112

    
113
        f = ffs(level >> 1);
114
    }
115

    
116
    s->sir_irq = intr_irq;
117
    s->sir_fiq = intr_fiq;
118
}
119

    
120
#define INT_FALLING_EDGE        0
121
#define INT_LOW_LEVEL                1
122

    
123
static void omap_set_intr(void *opaque, int irq, int req)
124
{
125
    struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
126
    uint32_t rise;
127

    
128
    if (req) {
129
        rise = ~ih->irqs & (1 << irq);
130
        ih->irqs |= rise;
131
        ih->stats[irq] += !!rise;
132
    } else {
133
        rise = ih->sens_edge & ih->irqs & (1 << irq);
134
        ih->irqs &= ~rise;
135
    }
136

    
137
    if (rise & ~ih->mask) {
138
        omap_inth_sir_update(ih);
139

    
140
        omap_inth_update(ih);
141
    }
142
}
143

    
144
static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
145
{
146
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
147
    int i, offset = addr - s->base;
148

    
149
    switch (offset) {
150
    case 0x00:        /* ITR */
151
        return s->irqs;
152

    
153
    case 0x04:        /* MIR */
154
        return s->mask;
155

    
156
    case 0x10:        /* SIR_IRQ_CODE */
157
        i = s->sir_irq;
158
        if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
159
            s->irqs &= ~(1 << i);
160
            omap_inth_sir_update(s);
161
            omap_inth_update(s);
162
        }
163
        return i;
164

    
165
    case 0x14:        /* SIR_FIQ_CODE */
166
        i = s->sir_fiq;
167
        if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
168
            s->irqs &= ~(1 << i);
169
            omap_inth_sir_update(s);
170
            omap_inth_update(s);
171
        }
172
        return i;
173

    
174
    case 0x18:        /* CONTROL_REG */
175
        return 0;
176

    
177
    case 0x1c:        /* ILR0 */
178
    case 0x20:        /* ILR1 */
179
    case 0x24:        /* ILR2 */
180
    case 0x28:        /* ILR3 */
181
    case 0x2c:        /* ILR4 */
182
    case 0x30:        /* ILR5 */
183
    case 0x34:        /* ILR6 */
184
    case 0x38:        /* ILR7 */
185
    case 0x3c:        /* ILR8 */
186
    case 0x40:        /* ILR9 */
187
    case 0x44:        /* ILR10 */
188
    case 0x48:        /* ILR11 */
189
    case 0x4c:        /* ILR12 */
190
    case 0x50:        /* ILR13 */
191
    case 0x54:        /* ILR14 */
192
    case 0x58:        /* ILR15 */
193
    case 0x5c:        /* ILR16 */
194
    case 0x60:        /* ILR17 */
195
    case 0x64:        /* ILR18 */
196
    case 0x68:        /* ILR19 */
197
    case 0x6c:        /* ILR20 */
198
    case 0x70:        /* ILR21 */
199
    case 0x74:        /* ILR22 */
200
    case 0x78:        /* ILR23 */
201
    case 0x7c:        /* ILR24 */
202
    case 0x80:        /* ILR25 */
203
    case 0x84:        /* ILR26 */
204
    case 0x88:        /* ILR27 */
205
    case 0x8c:        /* ILR28 */
206
    case 0x90:        /* ILR29 */
207
    case 0x94:        /* ILR30 */
208
    case 0x98:        /* ILR31 */
209
        i = (offset - 0x1c) >> 2;
210
        return (s->priority[i] << 2) |
211
                (((s->sens_edge >> i) & 1) << 1) |
212
                ((s->fiq >> i) & 1);
213

    
214
    case 0x9c:        /* ISR */
215
        return 0x00000000;
216

    
217
    default:
218
        OMAP_BAD_REG(addr);
219
        break;
220
    }
221
    return 0;
222
}
223

    
224
static void omap_inth_write(void *opaque, target_phys_addr_t addr,
225
                uint32_t value)
226
{
227
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
228
    int i, offset = addr - s->base;
229

    
230
    switch (offset) {
231
    case 0x00:        /* ITR */
232
        s->irqs &= value;
233
        omap_inth_sir_update(s);
234
        omap_inth_update(s);
235
        return;
236

    
237
    case 0x04:        /* MIR */
238
        s->mask = value;
239
        omap_inth_sir_update(s);
240
        omap_inth_update(s);
241
        return;
242

    
243
    case 0x10:        /* SIR_IRQ_CODE */
244
    case 0x14:        /* SIR_FIQ_CODE */
245
        OMAP_RO_REG(addr);
246
        break;
247

    
248
    case 0x18:        /* CONTROL_REG */
249
        if (value & 2)
250
            s->new_fiq_agr = ~0;
251
        if (value & 1)
252
            s->new_irq_agr = ~0;
253
        omap_inth_update(s);
254
        return;
255

    
256
    case 0x1c:        /* ILR0 */
257
    case 0x20:        /* ILR1 */
258
    case 0x24:        /* ILR2 */
259
    case 0x28:        /* ILR3 */
260
    case 0x2c:        /* ILR4 */
261
    case 0x30:        /* ILR5 */
262
    case 0x34:        /* ILR6 */
263
    case 0x38:        /* ILR7 */
264
    case 0x3c:        /* ILR8 */
265
    case 0x40:        /* ILR9 */
266
    case 0x44:        /* ILR10 */
267
    case 0x48:        /* ILR11 */
268
    case 0x4c:        /* ILR12 */
269
    case 0x50:        /* ILR13 */
270
    case 0x54:        /* ILR14 */
271
    case 0x58:        /* ILR15 */
272
    case 0x5c:        /* ILR16 */
273
    case 0x60:        /* ILR17 */
274
    case 0x64:        /* ILR18 */
275
    case 0x68:        /* ILR19 */
276
    case 0x6c:        /* ILR20 */
277
    case 0x70:        /* ILR21 */
278
    case 0x74:        /* ILR22 */
279
    case 0x78:        /* ILR23 */
280
    case 0x7c:        /* ILR24 */
281
    case 0x80:        /* ILR25 */
282
    case 0x84:        /* ILR26 */
283
    case 0x88:        /* ILR27 */
284
    case 0x8c:        /* ILR28 */
285
    case 0x90:        /* ILR29 */
286
    case 0x94:        /* ILR30 */
287
    case 0x98:        /* ILR31 */
288
        i = (offset - 0x1c) >> 2;
289
        s->priority[i] = (value >> 2) & 0x1f;
290
        s->sens_edge &= ~(1 << i);
291
        s->sens_edge |= ((value >> 1) & 1) << i;
292
        s->fiq &= ~(1 << i);
293
        s->fiq |= (value & 1) << i;
294
        return;
295

    
296
    case 0x9c:        /* ISR */
297
        for (i = 0; i < 32; i ++)
298
            if (value & (1 << i)) {
299
                omap_set_intr(s, i, 1);
300
                return;
301
            }
302
        return;
303

    
304
    default:
305
        OMAP_BAD_REG(addr);
306
    }
307
}
308

    
309
static CPUReadMemoryFunc *omap_inth_readfn[] = {
310
    omap_badwidth_read32,
311
    omap_badwidth_read32,
312
    omap_inth_read,
313
};
314

    
315
static CPUWriteMemoryFunc *omap_inth_writefn[] = {
316
    omap_inth_write,
317
    omap_inth_write,
318
    omap_inth_write,
319
};
320

    
321
static void omap_inth_reset(struct omap_intr_handler_s *s)
322
{
323
    s->irqs = 0x00000000;
324
    s->mask = 0xffffffff;
325
    s->sens_edge = 0x00000000;
326
    s->fiq = 0x00000000;
327
    memset(s->priority, 0, sizeof(s->priority));
328
    s->new_irq_agr = ~0;
329
    s->new_fiq_agr = ~0;
330
    s->sir_irq = 0;
331
    s->sir_fiq = 0;
332

    
333
    omap_inth_update(s);
334
}
335

    
336
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
337
                unsigned long size, qemu_irq parent[2], omap_clk clk)
338
{
339
    int iomemtype;
340
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
341
            qemu_mallocz(sizeof(struct omap_intr_handler_s));
342

    
343
    s->parent_pic = parent;
344
    s->base = base;
345
    s->pins = qemu_allocate_irqs(omap_set_intr, s, 32);
346
    omap_inth_reset(s);
347

    
348
    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
349
                    omap_inth_writefn, s);
350
    cpu_register_physical_memory(s->base, size, iomemtype);
351

    
352
    return s;
353
}
354

    
355
/* OMAP1 DMA module */
356
typedef enum {
357
    constant = 0,
358
    post_incremented,
359
    single_index,
360
    double_index,
361
} omap_dma_addressing_t;
362

    
363
struct omap_dma_channel_s {
364
    int burst[2];
365
    int pack[2];
366
    enum omap_dma_port port[2];
367
    target_phys_addr_t addr[2];
368
    omap_dma_addressing_t mode[2];
369
    int data_type;
370
    int end_prog;
371
    int repeat;
372
    int auto_init;
373
    int priority;
374
    int fs;
375
    int sync;
376
    int running;
377
    int interrupts;
378
    int status;
379
    int signalled;
380
    int post_sync;
381
    int transfer;
382
    uint16_t elements;
383
    uint16_t frames;
384
    uint16_t frame_index;
385
    uint16_t element_index;
386
    uint16_t cpc;
387

    
388
    struct omap_dma_reg_set_s {
389
        target_phys_addr_t src, dest;
390
        int frame;
391
        int element;
392
        int frame_delta[2];
393
        int elem_delta[2];
394
        int frames;
395
        int elements;
396
    } active_set;
397
};
398

    
399
struct omap_dma_s {
400
    qemu_irq *ih;
401
    QEMUTimer *tm;
402
    struct omap_mpu_state_s *mpu;
403
    target_phys_addr_t base;
404
    omap_clk clk;
405
    int64_t delay;
406
    uint32_t drq;
407

    
408
    uint16_t gcr;
409
    int run_count;
410

    
411
    int chans;
412
    struct omap_dma_channel_s ch[16];
413
    struct omap_dma_lcd_channel_s lcd_ch;
414
};
415

    
416
static void omap_dma_interrupts_update(struct omap_dma_s *s)
417
{
418
    /* First three interrupts are shared between two channels each.  */
419
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH0_6],
420
                    (s->ch[0].status | s->ch[6].status) & 0x3f);
421
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH1_7],
422
                    (s->ch[1].status | s->ch[7].status) & 0x3f);
423
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH2_8],
424
                    (s->ch[2].status | s->ch[8].status) & 0x3f);
425
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH3],
426
                    (s->ch[3].status) & 0x3f);
427
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH4],
428
                    (s->ch[4].status) & 0x3f);
429
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH5],
430
                    (s->ch[5].status) & 0x3f);
431
}
432

    
433
static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
434
{
435
    struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
436
    int i;
437

    
438
    /*
439
     * TODO: verify address ranges and alignment
440
     * TODO: port endianness
441
     */
442

    
443
    a->src = s->ch[ch].addr[0];
444
    a->dest = s->ch[ch].addr[1];
445
    a->frames = s->ch[ch].frames;
446
    a->elements = s->ch[ch].elements;
447
    a->frame = 0;
448
    a->element = 0;
449

    
450
    if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
451
        printf("%s: bad DMA request\n", __FUNCTION__);
452
        return;
453
    }
454

    
455
    for (i = 0; i < 2; i ++)
456
        switch (s->ch[ch].mode[i]) {
457
        case constant:
458
            a->elem_delta[i] = 0;
459
            a->frame_delta[i] = 0;
460
            break;
461
        case post_incremented:
462
            a->elem_delta[i] = s->ch[ch].data_type;
463
            a->frame_delta[i] = 0;
464
            break;
465
        case single_index:
466
            a->elem_delta[i] = s->ch[ch].data_type +
467
                s->ch[ch].element_index - 1;
468
            if (s->ch[ch].element_index > 0x7fff)
469
                a->elem_delta[i] -= 0x10000;
470
            a->frame_delta[i] = 0;
471
            break;
472
        case double_index:
473
            a->elem_delta[i] = s->ch[ch].data_type +
474
                s->ch[ch].element_index - 1;
475
            if (s->ch[ch].element_index > 0x7fff)
476
                a->elem_delta[i] -= 0x10000;
477
            a->frame_delta[i] = s->ch[ch].frame_index -
478
                s->ch[ch].element_index;
479
            if (s->ch[ch].frame_index > 0x7fff)
480
                a->frame_delta[i] -= 0x10000;
481
            break;
482
        default:
483
            break;
484
        }
485
}
486

    
487
static inline void omap_dma_request_run(struct omap_dma_s *s,
488
                int channel, int request)
489
{
490
next_channel:
491
    if (request > 0)
492
        for (; channel < 9; channel ++)
493
            if (s->ch[channel].sync == request && s->ch[channel].running)
494
                break;
495
    if (channel >= 9)
496
        return;
497

    
498
    if (s->ch[channel].transfer) {
499
        if (request > 0) {
500
            s->ch[channel ++].post_sync = request;
501
            goto next_channel;
502
        }
503
        s->ch[channel].status |= 0x02;        /* Synchronisation drop */
504
        omap_dma_interrupts_update(s);
505
        return;
506
    }
507

    
508
    if (!s->ch[channel].signalled)
509
        s->run_count ++;
510
    s->ch[channel].signalled = 1;
511

    
512
    if (request > 0)
513
        s->ch[channel].status |= 0x40;        /* External request */
514

    
515
    if (s->delay && !qemu_timer_pending(s->tm))
516
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
517

    
518
    if (request > 0) {
519
        channel ++;
520
        goto next_channel;
521
    }
522
}
523

    
524
static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel)
525
{
526
    if (s->ch[channel].signalled)
527
        s->run_count --;
528
    s->ch[channel].signalled = 0;
529

    
530
    if (!s->run_count)
531
        qemu_del_timer(s->tm);
532
}
533

    
534
static void omap_dma_channel_run(struct omap_dma_s *s)
535
{
536
    int ch;
537
    uint16_t status;
538
    uint8_t value[4];
539
    struct omap_dma_port_if_s *src_p, *dest_p;
540
    struct omap_dma_reg_set_s *a;
541

    
542
    for (ch = 0; ch < 9; ch ++) {
543
        a = &s->ch[ch].active_set;
544

    
545
        src_p = &s->mpu->port[s->ch[ch].port[0]];
546
        dest_p = &s->mpu->port[s->ch[ch].port[1]];
547
        if (s->ch[ch].signalled && (!src_p->addr_valid(s->mpu, a->src) ||
548
                    !dest_p->addr_valid(s->mpu, a->dest))) {
549
#if 0
550
            /* Bus time-out */
551
            if (s->ch[ch].interrupts & 0x01)
552
                s->ch[ch].status |= 0x01;
553
            omap_dma_request_stop(s, ch);
554
            continue;
555
#endif
556
            printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch);
557
        }
558

    
559
        status = s->ch[ch].status;
560
        while (status == s->ch[ch].status && s->ch[ch].signalled) {
561
            /* Transfer a single element */
562
            s->ch[ch].transfer = 1;
563
            cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
564
            cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
565
            s->ch[ch].transfer = 0;
566

    
567
            a->src += a->elem_delta[0];
568
            a->dest += a->elem_delta[1];
569
            a->element ++;
570

    
571
            /* Check interrupt conditions */
572
            if (a->element == a->elements) {
573
                a->element = 0;
574
                a->src += a->frame_delta[0];
575
                a->dest += a->frame_delta[1];
576
                a->frame ++;
577

    
578
                if (a->frame == a->frames) {
579
                    if (!s->ch[ch].repeat || !s->ch[ch].auto_init)
580
                        s->ch[ch].running = 0;
581

    
582
                    if (s->ch[ch].auto_init &&
583
                            (s->ch[ch].repeat ||
584
                             s->ch[ch].end_prog))
585
                        omap_dma_channel_load(s, ch);
586

    
587
                    if (s->ch[ch].interrupts & 0x20)
588
                        s->ch[ch].status |= 0x20;
589

    
590
                    if (!s->ch[ch].sync)
591
                        omap_dma_request_stop(s, ch);
592
                }
593

    
594
                if (s->ch[ch].interrupts & 0x08)
595
                    s->ch[ch].status |= 0x08;
596

    
597
                if (s->ch[ch].sync && s->ch[ch].fs &&
598
                                !(s->drq & (1 << s->ch[ch].sync))) {
599
                    s->ch[ch].status &= ~0x40;
600
                    omap_dma_request_stop(s, ch);
601
                }
602
            }
603

    
604
            if (a->element == 1 && a->frame == a->frames - 1)
605
                if (s->ch[ch].interrupts & 0x10)
606
                    s->ch[ch].status |= 0x10;
607

    
608
            if (a->element == (a->elements >> 1))
609
                if (s->ch[ch].interrupts & 0x04)
610
                    s->ch[ch].status |= 0x04;
611

    
612
            if (s->ch[ch].sync && !s->ch[ch].fs &&
613
                            !(s->drq & (1 << s->ch[ch].sync))) {
614
                s->ch[ch].status &= ~0x40;
615
                omap_dma_request_stop(s, ch);
616
            }
617

    
618
            /*
619
             * Process requests made while the element was
620
             * being transferred.
621
             */
622
            if (s->ch[ch].post_sync) {
623
                omap_dma_request_run(s, 0, s->ch[ch].post_sync);
624
                s->ch[ch].post_sync = 0;
625
            }
626

    
627
#if 0
628
            break;
629
#endif
630
        }
631

    
632
        s->ch[ch].cpc = a->dest & 0x0000ffff;
633
    }
634

    
635
    omap_dma_interrupts_update(s);
636
    if (s->run_count && s->delay)
637
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
638
}
639

    
640
static int omap_dma_ch_reg_read(struct omap_dma_s *s,
641
                int ch, int reg, uint16_t *value) {
642
    switch (reg) {
643
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
644
        *value = (s->ch[ch].burst[1] << 14) |
645
                (s->ch[ch].pack[1] << 13) |
646
                (s->ch[ch].port[1] << 9) |
647
                (s->ch[ch].burst[0] << 7) |
648
                (s->ch[ch].pack[0] << 6) |
649
                (s->ch[ch].port[0] << 2) |
650
                (s->ch[ch].data_type >> 1);
651
        break;
652

    
653
    case 0x02:        /* SYS_DMA_CCR_CH0 */
654
        *value = (s->ch[ch].mode[1] << 14) |
655
                (s->ch[ch].mode[0] << 12) |
656
                (s->ch[ch].end_prog << 11) |
657
                (s->ch[ch].repeat << 9) |
658
                (s->ch[ch].auto_init << 8) |
659
                (s->ch[ch].running << 7) |
660
                (s->ch[ch].priority << 6) |
661
                (s->ch[ch].fs << 5) | s->ch[ch].sync;
662
        break;
663

    
664
    case 0x04:        /* SYS_DMA_CICR_CH0 */
665
        *value = s->ch[ch].interrupts;
666
        break;
667

    
668
    case 0x06:        /* SYS_DMA_CSR_CH0 */
669
        /* FIXME: shared CSR for channels sharing the interrupts */
670
        *value = s->ch[ch].status;
671
        s->ch[ch].status &= 0x40;
672
        omap_dma_interrupts_update(s);
673
        break;
674

    
675
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
676
        *value = s->ch[ch].addr[0] & 0x0000ffff;
677
        break;
678

    
679
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
680
        *value = s->ch[ch].addr[0] >> 16;
681
        break;
682

    
683
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
684
        *value = s->ch[ch].addr[1] & 0x0000ffff;
685
        break;
686

    
687
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
688
        *value = s->ch[ch].addr[1] >> 16;
689
        break;
690

    
691
    case 0x10:        /* SYS_DMA_CEN_CH0 */
692
        *value = s->ch[ch].elements;
693
        break;
694

    
695
    case 0x12:        /* SYS_DMA_CFN_CH0 */
696
        *value = s->ch[ch].frames;
697
        break;
698

    
699
    case 0x14:        /* SYS_DMA_CFI_CH0 */
700
        *value = s->ch[ch].frame_index;
701
        break;
702

    
703
    case 0x16:        /* SYS_DMA_CEI_CH0 */
704
        *value = s->ch[ch].element_index;
705
        break;
706

    
707
    case 0x18:        /* SYS_DMA_CPC_CH0 */
708
        *value = s->ch[ch].cpc;
709
        break;
710

    
711
    default:
712
        return 1;
713
    }
714
    return 0;
715
}
716

    
717
static int omap_dma_ch_reg_write(struct omap_dma_s *s,
718
                int ch, int reg, uint16_t value) {
719
    switch (reg) {
720
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
721
        s->ch[ch].burst[1] = (value & 0xc000) >> 14;
722
        s->ch[ch].pack[1] = (value & 0x2000) >> 13;
723
        s->ch[ch].port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
724
        s->ch[ch].burst[0] = (value & 0x0180) >> 7;
725
        s->ch[ch].pack[0] = (value & 0x0040) >> 6;
726
        s->ch[ch].port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
727
        s->ch[ch].data_type = (1 << (value & 3));
728
        if (s->ch[ch].port[0] >= omap_dma_port_last)
729
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
730
                            s->ch[ch].port[0]);
731
        if (s->ch[ch].port[1] >= omap_dma_port_last)
732
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
733
                            s->ch[ch].port[1]);
734
        if ((value & 3) == 3)
735
            printf("%s: bad data_type for DMA channel %i\n", __FUNCTION__, ch);
736
        break;
737

    
738
    case 0x02:        /* SYS_DMA_CCR_CH0 */
739
        s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
740
        s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
741
        s->ch[ch].end_prog = (value & 0x0800) >> 11;
742
        s->ch[ch].repeat = (value & 0x0200) >> 9;
743
        s->ch[ch].auto_init = (value & 0x0100) >> 8;
744
        s->ch[ch].priority = (value & 0x0040) >> 6;
745
        s->ch[ch].fs = (value & 0x0020) >> 5;
746
        s->ch[ch].sync = value & 0x001f;
747
        if (value & 0x0080) {
748
            if (s->ch[ch].running) {
749
                if (!s->ch[ch].signalled &&
750
                                s->ch[ch].auto_init && s->ch[ch].end_prog)
751
                    omap_dma_channel_load(s, ch);
752
            } else {
753
                s->ch[ch].running = 1;
754
                omap_dma_channel_load(s, ch);
755
            }
756
            if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync)))
757
                omap_dma_request_run(s, ch, 0);
758
        } else {
759
            s->ch[ch].running = 0;
760
            omap_dma_request_stop(s, ch);
761
        }
762
        break;
763

    
764
    case 0x04:        /* SYS_DMA_CICR_CH0 */
765
        s->ch[ch].interrupts = value & 0x003f;
766
        break;
767

    
768
    case 0x06:        /* SYS_DMA_CSR_CH0 */
769
        return 1;
770

    
771
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
772
        s->ch[ch].addr[0] &= 0xffff0000;
773
        s->ch[ch].addr[0] |= value;
774
        break;
775

    
776
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
777
        s->ch[ch].addr[0] &= 0x0000ffff;
778
        s->ch[ch].addr[0] |= value << 16;
779
        break;
780

    
781
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
782
        s->ch[ch].addr[1] &= 0xffff0000;
783
        s->ch[ch].addr[1] |= value;
784
        break;
785

    
786
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
787
        s->ch[ch].addr[1] &= 0x0000ffff;
788
        s->ch[ch].addr[1] |= value << 16;
789
        break;
790

    
791
    case 0x10:        /* SYS_DMA_CEN_CH0 */
792
        s->ch[ch].elements = value & 0xffff;
793
        break;
794

    
795
    case 0x12:        /* SYS_DMA_CFN_CH0 */
796
        s->ch[ch].frames = value & 0xffff;
797
        break;
798

    
799
    case 0x14:        /* SYS_DMA_CFI_CH0 */
800
        s->ch[ch].frame_index = value & 0xffff;
801
        break;
802

    
803
    case 0x16:        /* SYS_DMA_CEI_CH0 */
804
        s->ch[ch].element_index = value & 0xffff;
805
        break;
806

    
807
    case 0x18:        /* SYS_DMA_CPC_CH0 */
808
        return 1;
809

    
810
    default:
811
        OMAP_BAD_REG((unsigned long) reg);
812
    }
813
    return 0;
814
}
815

    
816
static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
817
{
818
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
819
    int i, reg, ch, offset = addr - s->base;
820
    uint16_t ret;
821

    
822
    switch (offset) {
823
    case 0x000 ... 0x2fe:
824
        reg = offset & 0x3f;
825
        ch = (offset >> 6) & 0x0f;
826
        if (omap_dma_ch_reg_read(s, ch, reg, &ret))
827
            break;
828
        return ret;
829

    
830
    case 0x300:        /* SYS_DMA_LCD_CTRL */
831
        i = s->lcd_ch.condition;
832
        s->lcd_ch.condition = 0;
833
        qemu_irq_lower(s->lcd_ch.irq);
834
        return ((s->lcd_ch.src == imif) << 6) | (i << 3) |
835
                (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
836

    
837
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
838
        return s->lcd_ch.src_f1_top & 0xffff;
839

    
840
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
841
        return s->lcd_ch.src_f1_top >> 16;
842

    
843
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
844
        return s->lcd_ch.src_f1_bottom & 0xffff;
845

    
846
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
847
        return s->lcd_ch.src_f1_bottom >> 16;
848

    
849
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
850
        return s->lcd_ch.src_f2_top & 0xffff;
851

    
852
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
853
        return s->lcd_ch.src_f2_top >> 16;
854

    
855
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
856
        return s->lcd_ch.src_f2_bottom & 0xffff;
857

    
858
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
859
        return s->lcd_ch.src_f2_bottom >> 16;
860

    
861
    case 0x400:        /* SYS_DMA_GCR */
862
        return s->gcr;
863
    }
864

    
865
    OMAP_BAD_REG(addr);
866
    return 0;
867
}
868

    
869
static void omap_dma_write(void *opaque, target_phys_addr_t addr,
870
                uint32_t value)
871
{
872
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
873
    int reg, ch, offset = addr - s->base;
874

    
875
    switch (offset) {
876
    case 0x000 ... 0x2fe:
877
        reg = offset & 0x3f;
878
        ch = (offset >> 6) & 0x0f;
879
        if (omap_dma_ch_reg_write(s, ch, reg, value))
880
            OMAP_RO_REG(addr);
881
        break;
882

    
883
    case 0x300:        /* SYS_DMA_LCD_CTRL */
884
        s->lcd_ch.src = (value & 0x40) ? imif : emiff;
885
        s->lcd_ch.condition = 0;
886
        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
887
        s->lcd_ch.interrupts = (value >> 1) & 1;
888
        s->lcd_ch.dual = value & 1;
889
        break;
890

    
891
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
892
        s->lcd_ch.src_f1_top &= 0xffff0000;
893
        s->lcd_ch.src_f1_top |= 0x0000ffff & value;
894
        break;
895

    
896
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
897
        s->lcd_ch.src_f1_top &= 0x0000ffff;
898
        s->lcd_ch.src_f1_top |= value << 16;
899
        break;
900

    
901
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
902
        s->lcd_ch.src_f1_bottom &= 0xffff0000;
903
        s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
904
        break;
905

    
906
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
907
        s->lcd_ch.src_f1_bottom &= 0x0000ffff;
908
        s->lcd_ch.src_f1_bottom |= value << 16;
909
        break;
910

    
911
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
912
        s->lcd_ch.src_f2_top &= 0xffff0000;
913
        s->lcd_ch.src_f2_top |= 0x0000ffff & value;
914
        break;
915

    
916
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
917
        s->lcd_ch.src_f2_top &= 0x0000ffff;
918
        s->lcd_ch.src_f2_top |= value << 16;
919
        break;
920

    
921
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
922
        s->lcd_ch.src_f2_bottom &= 0xffff0000;
923
        s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
924
        break;
925

    
926
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
927
        s->lcd_ch.src_f2_bottom &= 0x0000ffff;
928
        s->lcd_ch.src_f2_bottom |= value << 16;
929
        break;
930

    
931
    case 0x400:        /* SYS_DMA_GCR */
932
        s->gcr = value & 0x000c;
933
        break;
934

    
935
    default:
936
        OMAP_BAD_REG(addr);
937
    }
938
}
939

    
940
static CPUReadMemoryFunc *omap_dma_readfn[] = {
941
    omap_badwidth_read16,
942
    omap_dma_read,
943
    omap_badwidth_read16,
944
};
945

    
946
static CPUWriteMemoryFunc *omap_dma_writefn[] = {
947
    omap_badwidth_write16,
948
    omap_dma_write,
949
    omap_badwidth_write16,
950
};
951

    
952
static void omap_dma_request(void *opaque, int drq, int req)
953
{
954
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
955
    /* The request pins are level triggered.  */
956
    if (req) {
957
        if (~s->drq & (1 << drq)) {
958
            s->drq |= 1 << drq;
959
            omap_dma_request_run(s, 0, drq);
960
        }
961
    } else
962
        s->drq &= ~(1 << drq);
963
}
964

    
965
static void omap_dma_clk_update(void *opaque, int line, int on)
966
{
967
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
968

    
969
    if (on) {
970
        s->delay = ticks_per_sec >> 5;
971
        if (s->run_count)
972
            qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
973
    } else {
974
        s->delay = 0;
975
        qemu_del_timer(s->tm);
976
    }
977
}
978

    
979
static void omap_dma_reset(struct omap_dma_s *s)
980
{
981
    int i;
982

    
983
    qemu_del_timer(s->tm);
984
    s->gcr = 0x0004;
985
    s->drq = 0x00000000;
986
    s->run_count = 0;
987
    s->lcd_ch.src = emiff;
988
    s->lcd_ch.condition = 0;
989
    s->lcd_ch.interrupts = 0;
990
    s->lcd_ch.dual = 0;
991
    memset(s->ch, 0, sizeof(s->ch));
992
    for (i = 0; i < s->chans; i ++)
993
        s->ch[i].interrupts = 0x0003;
994
}
995

    
996
struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
997
                qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk)
998
{
999
    int iomemtype;
1000
    struct omap_dma_s *s = (struct omap_dma_s *)
1001
            qemu_mallocz(sizeof(struct omap_dma_s));
1002

    
1003
    s->ih = pic;
1004
    s->base = base;
1005
    s->chans = 9;
1006
    s->mpu = mpu;
1007
    s->clk = clk;
1008
    s->lcd_ch.irq = pic[OMAP_INT_DMA_LCD];
1009
    s->lcd_ch.mpu = mpu;
1010
    s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1011
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1012
    mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1013
    omap_dma_reset(s);
1014
    omap_dma_clk_update(s, 0, 1);
1015

    
1016
    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1017
                    omap_dma_writefn, s);
1018
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
1019

    
1020
    return s;
1021
}
1022

    
1023
/* DMA ports */
1024
int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1025
                target_phys_addr_t addr)
1026
{
1027
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1028
}
1029

    
1030
int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1031
                target_phys_addr_t addr)
1032
{
1033
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1034
}
1035

    
1036
int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1037
                target_phys_addr_t addr)
1038
{
1039
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1040
}
1041

    
1042
int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1043
                target_phys_addr_t addr)
1044
{
1045
    return addr >= 0xfffb0000 && addr < 0xffff0000;
1046
}
1047

    
1048
int omap_validate_local_addr(struct omap_mpu_state_s *s,
1049
                target_phys_addr_t addr)
1050
{
1051
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1052
}
1053

    
1054
int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1055
                target_phys_addr_t addr)
1056
{
1057
    return addr >= 0xe1010000 && addr < 0xe1020004;
1058
}
1059

    
1060
/* MPU OS timers */
1061
struct omap_mpu_timer_s {
1062
    qemu_irq irq;
1063
    omap_clk clk;
1064
    target_phys_addr_t base;
1065
    uint32_t val;
1066
    int64_t time;
1067
    QEMUTimer *timer;
1068
    int64_t rate;
1069
    int it_ena;
1070

    
1071
    int enable;
1072
    int ptv;
1073
    int ar;
1074
    int st;
1075
    uint32_t reset_val;
1076
};
1077

    
1078
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1079
{
1080
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
1081

    
1082
    if (timer->st && timer->enable && timer->rate)
1083
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
1084
                        timer->rate, ticks_per_sec);
1085
    else
1086
        return timer->val;
1087
}
1088

    
1089
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1090
{
1091
    timer->val = omap_timer_read(timer);
1092
    timer->time = qemu_get_clock(vm_clock);
1093
}
1094

    
1095
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1096
{
1097
    int64_t expires;
1098

    
1099
    if (timer->enable && timer->st && timer->rate) {
1100
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
1101
        expires = timer->time + muldiv64(timer->val << (timer->ptv + 1),
1102
                        ticks_per_sec, timer->rate);
1103
        qemu_mod_timer(timer->timer, expires);
1104
    } else
1105
        qemu_del_timer(timer->timer);
1106
}
1107

    
1108
static void omap_timer_tick(void *opaque)
1109
{
1110
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1111
    omap_timer_sync(timer);
1112

    
1113
    if (!timer->ar) {
1114
        timer->val = 0;
1115
        timer->st = 0;
1116
    }
1117

    
1118
    if (timer->it_ena)
1119
        qemu_irq_raise(timer->irq);
1120
    omap_timer_update(timer);
1121
}
1122

    
1123
static void omap_timer_clk_update(void *opaque, int line, int on)
1124
{
1125
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1126

    
1127
    omap_timer_sync(timer);
1128
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1129
    omap_timer_update(timer);
1130
}
1131

    
1132
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
1133
{
1134
    omap_clk_adduser(timer->clk,
1135
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
1136
    timer->rate = omap_clk_getrate(timer->clk);
1137
}
1138

    
1139
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
1140
{
1141
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1142
    int offset = addr - s->base;
1143

    
1144
    switch (offset) {
1145
    case 0x00:        /* CNTL_TIMER */
1146
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1147

    
1148
    case 0x04:        /* LOAD_TIM */
1149
        break;
1150

    
1151
    case 0x08:        /* READ_TIM */
1152
        return omap_timer_read(s);
1153
    }
1154

    
1155
    OMAP_BAD_REG(addr);
1156
    return 0;
1157
}
1158

    
1159
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1160
                uint32_t value)
1161
{
1162
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1163
    int offset = addr - s->base;
1164

    
1165
    switch (offset) {
1166
    case 0x00:        /* CNTL_TIMER */
1167
        omap_timer_sync(s);
1168
        s->enable = (value >> 5) & 1;
1169
        s->ptv = (value >> 2) & 7;
1170
        s->ar = (value >> 1) & 1;
1171
        s->st = value & 1;
1172
        omap_timer_update(s);
1173
        return;
1174

    
1175
    case 0x04:        /* LOAD_TIM */
1176
        s->reset_val = value;
1177
        return;
1178

    
1179
    case 0x08:        /* READ_TIM */
1180
        OMAP_RO_REG(addr);
1181
        break;
1182

    
1183
    default:
1184
        OMAP_BAD_REG(addr);
1185
    }
1186
}
1187

    
1188
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1189
    omap_badwidth_read32,
1190
    omap_badwidth_read32,
1191
    omap_mpu_timer_read,
1192
};
1193

    
1194
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1195
    omap_badwidth_write32,
1196
    omap_badwidth_write32,
1197
    omap_mpu_timer_write,
1198
};
1199

    
1200
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
1201
{
1202
    qemu_del_timer(s->timer);
1203
    s->enable = 0;
1204
    s->reset_val = 31337;
1205
    s->val = 0;
1206
    s->ptv = 0;
1207
    s->ar = 0;
1208
    s->st = 0;
1209
    s->it_ena = 1;
1210
}
1211

    
1212
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1213
                qemu_irq irq, omap_clk clk)
1214
{
1215
    int iomemtype;
1216
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1217
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
1218

    
1219
    s->irq = irq;
1220
    s->clk = clk;
1221
    s->base = base;
1222
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
1223
    omap_mpu_timer_reset(s);
1224
    omap_timer_clk_setup(s);
1225

    
1226
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
1227
                    omap_mpu_timer_writefn, s);
1228
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1229

    
1230
    return s;
1231
}
1232

    
1233
/* Watchdog timer */
1234
struct omap_watchdog_timer_s {
1235
    struct omap_mpu_timer_s timer;
1236
    uint8_t last_wr;
1237
    int mode;
1238
    int free;
1239
    int reset;
1240
};
1241

    
1242
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
1243
{
1244
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1245
    int offset = addr - s->timer.base;
1246

    
1247
    switch (offset) {
1248
    case 0x00:        /* CNTL_TIMER */
1249
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
1250
                (s->timer.st << 7) | (s->free << 1);
1251

    
1252
    case 0x04:        /* READ_TIMER */
1253
        return omap_timer_read(&s->timer);
1254

    
1255
    case 0x08:        /* TIMER_MODE */
1256
        return s->mode << 15;
1257
    }
1258

    
1259
    OMAP_BAD_REG(addr);
1260
    return 0;
1261
}
1262

    
1263
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1264
                uint32_t value)
1265
{
1266
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1267
    int offset = addr - s->timer.base;
1268

    
1269
    switch (offset) {
1270
    case 0x00:        /* CNTL_TIMER */
1271
        omap_timer_sync(&s->timer);
1272
        s->timer.ptv = (value >> 9) & 7;
1273
        s->timer.ar = (value >> 8) & 1;
1274
        s->timer.st = (value >> 7) & 1;
1275
        s->free = (value >> 1) & 1;
1276
        omap_timer_update(&s->timer);
1277
        break;
1278

    
1279
    case 0x04:        /* LOAD_TIMER */
1280
        s->timer.reset_val = value & 0xffff;
1281
        break;
1282

    
1283
    case 0x08:        /* TIMER_MODE */
1284
        if (!s->mode && ((value >> 15) & 1))
1285
            omap_clk_get(s->timer.clk);
1286
        s->mode |= (value >> 15) & 1;
1287
        if (s->last_wr == 0xf5) {
1288
            if ((value & 0xff) == 0xa0) {
1289
                s->mode = 0;
1290
                omap_clk_put(s->timer.clk);
1291
            } else {
1292
                /* XXX: on T|E hardware somehow this has no effect,
1293
                 * on Zire 71 it works as specified.  */
1294
                s->reset = 1;
1295
                qemu_system_reset_request();
1296
            }
1297
        }
1298
        s->last_wr = value & 0xff;
1299
        break;
1300

    
1301
    default:
1302
        OMAP_BAD_REG(addr);
1303
    }
1304
}
1305

    
1306
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
1307
    omap_badwidth_read16,
1308
    omap_wd_timer_read,
1309
    omap_badwidth_read16,
1310
};
1311

    
1312
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
1313
    omap_badwidth_write16,
1314
    omap_wd_timer_write,
1315
    omap_badwidth_write16,
1316
};
1317

    
1318
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
1319
{
1320
    qemu_del_timer(s->timer.timer);
1321
    if (!s->mode)
1322
        omap_clk_get(s->timer.clk);
1323
    s->mode = 1;
1324
    s->free = 1;
1325
    s->reset = 0;
1326
    s->timer.enable = 1;
1327
    s->timer.it_ena = 1;
1328
    s->timer.reset_val = 0xffff;
1329
    s->timer.val = 0;
1330
    s->timer.st = 0;
1331
    s->timer.ptv = 0;
1332
    s->timer.ar = 0;
1333
    omap_timer_update(&s->timer);
1334
}
1335

    
1336
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
1337
                qemu_irq irq, omap_clk clk)
1338
{
1339
    int iomemtype;
1340
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
1341
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
1342

    
1343
    s->timer.irq = irq;
1344
    s->timer.clk = clk;
1345
    s->timer.base = base;
1346
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1347
    omap_wd_timer_reset(s);
1348
    omap_timer_clk_setup(&s->timer);
1349

    
1350
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
1351
                    omap_wd_timer_writefn, s);
1352
    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
1353

    
1354
    return s;
1355
}
1356

    
1357
/* 32-kHz timer */
1358
struct omap_32khz_timer_s {
1359
    struct omap_mpu_timer_s timer;
1360
};
1361

    
1362
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
1363
{
1364
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1365
    int offset = addr - s->timer.base;
1366

    
1367
    switch (offset) {
1368
    case 0x00:        /* TVR */
1369
        return s->timer.reset_val;
1370

    
1371
    case 0x04:        /* TCR */
1372
        return omap_timer_read(&s->timer);
1373

    
1374
    case 0x08:        /* CR */
1375
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
1376

    
1377
    default:
1378
        break;
1379
    }
1380
    OMAP_BAD_REG(addr);
1381
    return 0;
1382
}
1383

    
1384
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1385
                uint32_t value)
1386
{
1387
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1388
    int offset = addr - s->timer.base;
1389

    
1390
    switch (offset) {
1391
    case 0x00:        /* TVR */
1392
        s->timer.reset_val = value & 0x00ffffff;
1393
        break;
1394

    
1395
    case 0x04:        /* TCR */
1396
        OMAP_RO_REG(addr);
1397
        break;
1398

    
1399
    case 0x08:        /* CR */
1400
        s->timer.ar = (value >> 3) & 1;
1401
        s->timer.it_ena = (value >> 2) & 1;
1402
        if (s->timer.st != (value & 1) || (value & 2)) {
1403
            omap_timer_sync(&s->timer);
1404
            s->timer.enable = value & 1;
1405
            s->timer.st = value & 1;
1406
            omap_timer_update(&s->timer);
1407
        }
1408
        break;
1409

    
1410
    default:
1411
        OMAP_BAD_REG(addr);
1412
    }
1413
}
1414

    
1415
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1416
    omap_badwidth_read32,
1417
    omap_badwidth_read32,
1418
    omap_os_timer_read,
1419
};
1420

    
1421
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1422
    omap_badwidth_write32,
1423
    omap_badwidth_write32,
1424
    omap_os_timer_write,
1425
};
1426

    
1427
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1428
{
1429
    qemu_del_timer(s->timer.timer);
1430
    s->timer.enable = 0;
1431
    s->timer.it_ena = 0;
1432
    s->timer.reset_val = 0x00ffffff;
1433
    s->timer.val = 0;
1434
    s->timer.st = 0;
1435
    s->timer.ptv = 0;
1436
    s->timer.ar = 1;
1437
}
1438

    
1439
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1440
                qemu_irq irq, omap_clk clk)
1441
{
1442
    int iomemtype;
1443
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1444
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1445

    
1446
    s->timer.irq = irq;
1447
    s->timer.clk = clk;
1448
    s->timer.base = base;
1449
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1450
    omap_os_timer_reset(s);
1451
    omap_timer_clk_setup(&s->timer);
1452

    
1453
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1454
                    omap_os_timer_writefn, s);
1455
    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
1456

    
1457
    return s;
1458
}
1459

    
1460
/* Ultra Low-Power Device Module */
1461
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1462
{
1463
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1464
    int offset = addr - s->ulpd_pm_base;
1465
    uint16_t ret;
1466

    
1467
    switch (offset) {
1468
    case 0x14:        /* IT_STATUS */
1469
        ret = s->ulpd_pm_regs[offset >> 2];
1470
        s->ulpd_pm_regs[offset >> 2] = 0;
1471
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1472
        return ret;
1473

    
1474
    case 0x18:        /* Reserved */
1475
    case 0x1c:        /* Reserved */
1476
    case 0x20:        /* Reserved */
1477
    case 0x28:        /* Reserved */
1478
    case 0x2c:        /* Reserved */
1479
        OMAP_BAD_REG(addr);
1480
    case 0x00:        /* COUNTER_32_LSB */
1481
    case 0x04:        /* COUNTER_32_MSB */
1482
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1483
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1484
    case 0x10:        /* GAUGING_CTRL */
1485
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1486
    case 0x30:        /* CLOCK_CTRL */
1487
    case 0x34:        /* SOFT_REQ */
1488
    case 0x38:        /* COUNTER_32_FIQ */
1489
    case 0x3c:        /* DPLL_CTRL */
1490
    case 0x40:        /* STATUS_REQ */
1491
        /* XXX: check clk::usecount state for every clock */
1492
    case 0x48:        /* LOCL_TIME */
1493
    case 0x4c:        /* APLL_CTRL */
1494
    case 0x50:        /* POWER_CTRL */
1495
        return s->ulpd_pm_regs[offset >> 2];
1496
    }
1497

    
1498
    OMAP_BAD_REG(addr);
1499
    return 0;
1500
}
1501

    
1502
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1503
                uint16_t diff, uint16_t value)
1504
{
1505
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
1506
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1507
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1508
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1509
}
1510

    
1511
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1512
                uint16_t diff, uint16_t value)
1513
{
1514
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1515
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1516
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1517
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1518
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1519
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1520
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1521
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1522
}
1523

    
1524
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1525
                uint32_t value)
1526
{
1527
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1528
    int offset = addr - s->ulpd_pm_base;
1529
    int64_t now, ticks;
1530
    int div, mult;
1531
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1532
    uint16_t diff;
1533

    
1534
    switch (offset) {
1535
    case 0x00:        /* COUNTER_32_LSB */
1536
    case 0x04:        /* COUNTER_32_MSB */
1537
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1538
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1539
    case 0x14:        /* IT_STATUS */
1540
    case 0x40:        /* STATUS_REQ */
1541
        OMAP_RO_REG(addr);
1542
        break;
1543

    
1544
    case 0x10:        /* GAUGING_CTRL */
1545
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1546
        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
1547
            now = qemu_get_clock(vm_clock);
1548

    
1549
            if (value & 1)
1550
                s->ulpd_gauge_start = now;
1551
            else {
1552
                now -= s->ulpd_gauge_start;
1553

    
1554
                /* 32-kHz ticks */
1555
                ticks = muldiv64(now, 32768, ticks_per_sec);
1556
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1557
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1558
                if (ticks >> 32)        /* OVERFLOW_32K */
1559
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1560

    
1561
                /* High frequency ticks */
1562
                ticks = muldiv64(now, 12000000, ticks_per_sec);
1563
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1564
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1565
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1566
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1567

    
1568
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
1569
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1570
            }
1571
        }
1572
        s->ulpd_pm_regs[offset >> 2] = value;
1573
        break;
1574

    
1575
    case 0x18:        /* Reserved */
1576
    case 0x1c:        /* Reserved */
1577
    case 0x20:        /* Reserved */
1578
    case 0x28:        /* Reserved */
1579
    case 0x2c:        /* Reserved */
1580
        OMAP_BAD_REG(addr);
1581
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1582
    case 0x38:        /* COUNTER_32_FIQ */
1583
    case 0x48:        /* LOCL_TIME */
1584
    case 0x50:        /* POWER_CTRL */
1585
        s->ulpd_pm_regs[offset >> 2] = value;
1586
        break;
1587

    
1588
    case 0x30:        /* CLOCK_CTRL */
1589
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1590
        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
1591
        omap_ulpd_clk_update(s, diff, value);
1592
        break;
1593

    
1594
    case 0x34:        /* SOFT_REQ */
1595
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1596
        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
1597
        omap_ulpd_req_update(s, diff, value);
1598
        break;
1599

    
1600
    case 0x3c:        /* DPLL_CTRL */
1601
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
1602
         * omitted altogether, probably a typo.  */
1603
        /* This register has identical semantics with DPLL(1:3) control
1604
         * registers, see omap_dpll_write() */
1605
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1606
        s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
1607
        if (diff & (0x3ff << 2)) {
1608
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1609
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1610
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1611
            } else {
1612
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1613
                mult = 1;
1614
            }
1615
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
1616
        }
1617

    
1618
        /* Enter the desired mode.  */
1619
        s->ulpd_pm_regs[offset >> 2] =
1620
                (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
1621
                ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
1622

    
1623
        /* Act as if the lock is restored.  */
1624
        s->ulpd_pm_regs[offset >> 2] |= 2;
1625
        break;
1626

    
1627
    case 0x4c:        /* APLL_CTRL */
1628
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1629
        s->ulpd_pm_regs[offset >> 2] = value & 0xf;
1630
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
1631
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1632
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
1633
        break;
1634

    
1635
    default:
1636
        OMAP_BAD_REG(addr);
1637
    }
1638
}
1639

    
1640
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1641
    omap_badwidth_read16,
1642
    omap_ulpd_pm_read,
1643
    omap_badwidth_read16,
1644
};
1645

    
1646
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1647
    omap_badwidth_write16,
1648
    omap_ulpd_pm_write,
1649
    omap_badwidth_write16,
1650
};
1651

    
1652
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
1653
{
1654
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
1655
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
1656
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
1657
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
1658
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
1659
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
1660
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
1661
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
1662
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
1663
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
1664
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
1665
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
1666
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
1667
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
1668
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
1669
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
1670
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
1671
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
1672
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
1673
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
1674
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
1675
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
1676
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
1677
}
1678

    
1679
static void omap_ulpd_pm_init(target_phys_addr_t base,
1680
                struct omap_mpu_state_s *mpu)
1681
{
1682
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1683
                    omap_ulpd_pm_writefn, mpu);
1684

    
1685
    mpu->ulpd_pm_base = base;
1686
    cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1687
    omap_ulpd_pm_reset(mpu);
1688
}
1689

    
1690
/* OMAP Pin Configuration */
1691
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1692
{
1693
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1694
    int offset = addr - s->pin_cfg_base;
1695

    
1696
    switch (offset) {
1697
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1698
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1699
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1700
        return s->func_mux_ctrl[offset >> 2];
1701

    
1702
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1703
        return s->comp_mode_ctrl[0];
1704

    
1705
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1706
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1707
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1708
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1709
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1710
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1711
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1712
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1713
    case 0x30:        /* FUNC_MUX_CTRL_B */
1714
    case 0x34:        /* FUNC_MUX_CTRL_C */
1715
    case 0x38:        /* FUNC_MUX_CTRL_D */
1716
        return s->func_mux_ctrl[(offset >> 2) - 1];
1717

    
1718
    case 0x40:        /* PULL_DWN_CTRL_0 */
1719
    case 0x44:        /* PULL_DWN_CTRL_1 */
1720
    case 0x48:        /* PULL_DWN_CTRL_2 */
1721
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1722
        return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1723

    
1724
    case 0x50:        /* GATE_INH_CTRL_0 */
1725
        return s->gate_inh_ctrl[0];
1726

    
1727
    case 0x60:        /* VOLTAGE_CTRL_0 */
1728
        return s->voltage_ctrl[0];
1729

    
1730
    case 0x70:        /* TEST_DBG_CTRL_0 */
1731
        return s->test_dbg_ctrl[0];
1732

    
1733
    case 0x80:        /* MOD_CONF_CTRL_0 */
1734
        return s->mod_conf_ctrl[0];
1735
    }
1736

    
1737
    OMAP_BAD_REG(addr);
1738
    return 0;
1739
}
1740

    
1741
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1742
                uint32_t diff, uint32_t value)
1743
{
1744
    if (s->compat1509) {
1745
        if (diff & (1 << 9))                        /* BLUETOOTH */
1746
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1747
                            (~value >> 9) & 1);
1748
        if (diff & (1 << 7))                        /* USB.CLKO */
1749
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
1750
                            (value >> 7) & 1);
1751
    }
1752
}
1753

    
1754
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1755
                uint32_t diff, uint32_t value)
1756
{
1757
    if (s->compat1509) {
1758
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
1759
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1760
                            (value >> 31) & 1);
1761
        if (diff & (1 << 1))                        /* CLK32K */
1762
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1763
                            (~value >> 1) & 1);
1764
    }
1765
}
1766

    
1767
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1768
                uint32_t diff, uint32_t value)
1769
{
1770
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
1771
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1772
                         omap_findclk(s, ((value >> 31) & 1) ?
1773
                                 "ck_48m" : "armper_ck"));
1774
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
1775
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1776
                         omap_findclk(s, ((value >> 30) & 1) ?
1777
                                 "ck_48m" : "armper_ck"));
1778
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
1779
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1780
                         omap_findclk(s, ((value >> 29) & 1) ?
1781
                                 "ck_48m" : "armper_ck"));
1782
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
1783
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1784
                         omap_findclk(s, ((value >> 23) & 1) ?
1785
                                 "ck_48m" : "armper_ck"));
1786
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
1787
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1788
                         omap_findclk(s, ((value >> 12) & 1) ?
1789
                                 "ck_48m" : "armper_ck"));
1790
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1791
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1792
}
1793

    
1794
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1795
                uint32_t value)
1796
{
1797
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1798
    int offset = addr - s->pin_cfg_base;
1799
    uint32_t diff;
1800

    
1801
    switch (offset) {
1802
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1803
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1804
        s->func_mux_ctrl[offset >> 2] = value;
1805
        omap_pin_funcmux0_update(s, diff, value);
1806
        return;
1807

    
1808
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1809
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1810
        s->func_mux_ctrl[offset >> 2] = value;
1811
        omap_pin_funcmux1_update(s, diff, value);
1812
        return;
1813

    
1814
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1815
        s->func_mux_ctrl[offset >> 2] = value;
1816
        return;
1817

    
1818
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1819
        s->comp_mode_ctrl[0] = value;
1820
        s->compat1509 = (value != 0x0000eaef);
1821
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1822
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1823
        return;
1824

    
1825
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1826
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1827
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1828
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1829
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1830
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1831
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1832
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1833
    case 0x30:        /* FUNC_MUX_CTRL_B */
1834
    case 0x34:        /* FUNC_MUX_CTRL_C */
1835
    case 0x38:        /* FUNC_MUX_CTRL_D */
1836
        s->func_mux_ctrl[(offset >> 2) - 1] = value;
1837
        return;
1838

    
1839
    case 0x40:        /* PULL_DWN_CTRL_0 */
1840
    case 0x44:        /* PULL_DWN_CTRL_1 */
1841
    case 0x48:        /* PULL_DWN_CTRL_2 */
1842
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1843
        s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1844
        return;
1845

    
1846
    case 0x50:        /* GATE_INH_CTRL_0 */
1847
        s->gate_inh_ctrl[0] = value;
1848
        return;
1849

    
1850
    case 0x60:        /* VOLTAGE_CTRL_0 */
1851
        s->voltage_ctrl[0] = value;
1852
        return;
1853

    
1854
    case 0x70:        /* TEST_DBG_CTRL_0 */
1855
        s->test_dbg_ctrl[0] = value;
1856
        return;
1857

    
1858
    case 0x80:        /* MOD_CONF_CTRL_0 */
1859
        diff = s->mod_conf_ctrl[0] ^ value;
1860
        s->mod_conf_ctrl[0] = value;
1861
        omap_pin_modconf1_update(s, diff, value);
1862
        return;
1863

    
1864
    default:
1865
        OMAP_BAD_REG(addr);
1866
    }
1867
}
1868

    
1869
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1870
    omap_badwidth_read32,
1871
    omap_badwidth_read32,
1872
    omap_pin_cfg_read,
1873
};
1874

    
1875
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1876
    omap_badwidth_write32,
1877
    omap_badwidth_write32,
1878
    omap_pin_cfg_write,
1879
};
1880

    
1881
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1882
{
1883
    /* Start in Compatibility Mode.  */
1884
    mpu->compat1509 = 1;
1885
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1886
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1887
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1888
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1889
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1890
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1891
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1892
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1893
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1894
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1895
}
1896

    
1897
static void omap_pin_cfg_init(target_phys_addr_t base,
1898
                struct omap_mpu_state_s *mpu)
1899
{
1900
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1901
                    omap_pin_cfg_writefn, mpu);
1902

    
1903
    mpu->pin_cfg_base = base;
1904
    cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1905
    omap_pin_cfg_reset(mpu);
1906
}
1907

    
1908
/* Device Identification, Die Identification */
1909
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1910
{
1911
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1912

    
1913
    switch (addr) {
1914
    case 0xfffe1800:        /* DIE_ID_LSB */
1915
        return 0xc9581f0e;
1916
    case 0xfffe1804:        /* DIE_ID_MSB */
1917
        return 0xa8858bfa;
1918

    
1919
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
1920
        return 0x00aaaafc;
1921
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
1922
        return 0xcafeb574;
1923

    
1924
    case 0xfffed400:        /* JTAG_ID_LSB */
1925
        switch (s->mpu_model) {
1926
        case omap310:
1927
            return 0x03310315;
1928
        case omap1510:
1929
            return 0x03310115;
1930
        }
1931
        break;
1932

    
1933
    case 0xfffed404:        /* JTAG_ID_MSB */
1934
        switch (s->mpu_model) {
1935
        case omap310:
1936
            return 0xfb57402f;
1937
        case omap1510:
1938
            return 0xfb47002f;
1939
        }
1940
        break;
1941
    }
1942

    
1943
    OMAP_BAD_REG(addr);
1944
    return 0;
1945
}
1946

    
1947
static void omap_id_write(void *opaque, target_phys_addr_t addr,
1948
                uint32_t value)
1949
{
1950
    OMAP_BAD_REG(addr);
1951
}
1952

    
1953
static CPUReadMemoryFunc *omap_id_readfn[] = {
1954
    omap_badwidth_read32,
1955
    omap_badwidth_read32,
1956
    omap_id_read,
1957
};
1958

    
1959
static CPUWriteMemoryFunc *omap_id_writefn[] = {
1960
    omap_badwidth_write32,
1961
    omap_badwidth_write32,
1962
    omap_id_write,
1963
};
1964

    
1965
static void omap_id_init(struct omap_mpu_state_s *mpu)
1966
{
1967
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
1968
                    omap_id_writefn, mpu);
1969
    cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
1970
    cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
1971
    if (!cpu_is_omap15xx(mpu))
1972
        cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
1973
}
1974

    
1975
/* MPUI Control (Dummy) */
1976
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1977
{
1978
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1979
    int offset = addr - s->mpui_base;
1980

    
1981
    switch (offset) {
1982
    case 0x00:        /* CTRL */
1983
        return s->mpui_ctrl;
1984
    case 0x04:        /* DEBUG_ADDR */
1985
        return 0x01ffffff;
1986
    case 0x08:        /* DEBUG_DATA */
1987
        return 0xffffffff;
1988
    case 0x0c:        /* DEBUG_FLAG */
1989
        return 0x00000800;
1990
    case 0x10:        /* STATUS */
1991
        return 0x00000000;
1992

    
1993
    /* Not in OMAP310 */
1994
    case 0x14:        /* DSP_STATUS */
1995
    case 0x18:        /* DSP_BOOT_CONFIG */
1996
        return 0x00000000;
1997
    case 0x1c:        /* DSP_MPUI_CONFIG */
1998
        return 0x0000ffff;
1999
    }
2000

    
2001
    OMAP_BAD_REG(addr);
2002
    return 0;
2003
}
2004

    
2005
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2006
                uint32_t value)
2007
{
2008
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2009
    int offset = addr - s->mpui_base;
2010

    
2011
    switch (offset) {
2012
    case 0x00:        /* CTRL */
2013
        s->mpui_ctrl = value & 0x007fffff;
2014
        break;
2015

    
2016
    case 0x04:        /* DEBUG_ADDR */
2017
    case 0x08:        /* DEBUG_DATA */
2018
    case 0x0c:        /* DEBUG_FLAG */
2019
    case 0x10:        /* STATUS */
2020
    /* Not in OMAP310 */
2021
    case 0x14:        /* DSP_STATUS */
2022
        OMAP_RO_REG(addr);
2023
    case 0x18:        /* DSP_BOOT_CONFIG */
2024
    case 0x1c:        /* DSP_MPUI_CONFIG */
2025
        break;
2026

    
2027
    default:
2028
        OMAP_BAD_REG(addr);
2029
    }
2030
}
2031

    
2032
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2033
    omap_badwidth_read32,
2034
    omap_badwidth_read32,
2035
    omap_mpui_read,
2036
};
2037

    
2038
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2039
    omap_badwidth_write32,
2040
    omap_badwidth_write32,
2041
    omap_mpui_write,
2042
};
2043

    
2044
static void omap_mpui_reset(struct omap_mpu_state_s *s)
2045
{
2046
    s->mpui_ctrl = 0x0003ff1b;
2047
}
2048

    
2049
static void omap_mpui_init(target_phys_addr_t base,
2050
                struct omap_mpu_state_s *mpu)
2051
{
2052
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2053
                    omap_mpui_writefn, mpu);
2054

    
2055
    mpu->mpui_base = base;
2056
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2057

    
2058
    omap_mpui_reset(mpu);
2059
}
2060

    
2061
/* TIPB Bridges */
2062
struct omap_tipb_bridge_s {
2063
    target_phys_addr_t base;
2064
    qemu_irq abort;
2065

    
2066
    int width_intr;
2067
    uint16_t control;
2068
    uint16_t alloc;
2069
    uint16_t buffer;
2070
    uint16_t enh_control;
2071
};
2072

    
2073
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
2074
{
2075
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2076
    int offset = addr - s->base;
2077

    
2078
    switch (offset) {
2079
    case 0x00:        /* TIPB_CNTL */
2080
        return s->control;
2081
    case 0x04:        /* TIPB_BUS_ALLOC */
2082
        return s->alloc;
2083
    case 0x08:        /* MPU_TIPB_CNTL */
2084
        return s->buffer;
2085
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2086
        return s->enh_control;
2087
    case 0x10:        /* ADDRESS_DBG */
2088
    case 0x14:        /* DATA_DEBUG_LOW */
2089
    case 0x18:        /* DATA_DEBUG_HIGH */
2090
        return 0xffff;
2091
    case 0x1c:        /* DEBUG_CNTR_SIG */
2092
        return 0x00f8;
2093
    }
2094

    
2095
    OMAP_BAD_REG(addr);
2096
    return 0;
2097
}
2098

    
2099
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
2100
                uint32_t value)
2101
{
2102
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2103
    int offset = addr - s->base;
2104

    
2105
    switch (offset) {
2106
    case 0x00:        /* TIPB_CNTL */
2107
        s->control = value & 0xffff;
2108
        break;
2109

    
2110
    case 0x04:        /* TIPB_BUS_ALLOC */
2111
        s->alloc = value & 0x003f;
2112
        break;
2113

    
2114
    case 0x08:        /* MPU_TIPB_CNTL */
2115
        s->buffer = value & 0x0003;
2116
        break;
2117

    
2118
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2119
        s->width_intr = !(value & 2);
2120
        s->enh_control = value & 0x000f;
2121
        break;
2122

    
2123
    case 0x10:        /* ADDRESS_DBG */
2124
    case 0x14:        /* DATA_DEBUG_LOW */
2125
    case 0x18:        /* DATA_DEBUG_HIGH */
2126
    case 0x1c:        /* DEBUG_CNTR_SIG */
2127
        OMAP_RO_REG(addr);
2128
        break;
2129

    
2130
    default:
2131
        OMAP_BAD_REG(addr);
2132
    }
2133
}
2134

    
2135
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2136
    omap_badwidth_read16,
2137
    omap_tipb_bridge_read,
2138
    omap_tipb_bridge_read,
2139
};
2140

    
2141
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2142
    omap_badwidth_write16,
2143
    omap_tipb_bridge_write,
2144
    omap_tipb_bridge_write,
2145
};
2146

    
2147
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2148
{
2149
    s->control = 0xffff;
2150
    s->alloc = 0x0009;
2151
    s->buffer = 0x0000;
2152
    s->enh_control = 0x000f;
2153
}
2154

    
2155
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2156
                qemu_irq abort_irq, omap_clk clk)
2157
{
2158
    int iomemtype;
2159
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2160
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2161

    
2162
    s->abort = abort_irq;
2163
    s->base = base;
2164
    omap_tipb_bridge_reset(s);
2165

    
2166
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
2167
                    omap_tipb_bridge_writefn, s);
2168
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2169

    
2170
    return s;
2171
}
2172

    
2173
/* Dummy Traffic Controller's Memory Interface */
2174
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2175
{
2176
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2177
    int offset = addr - s->tcmi_base;
2178
    uint32_t ret;
2179

    
2180
    switch (offset) {
2181
    case 0xfffecc00:        /* IMIF_PRIO */
2182
    case 0xfffecc04:        /* EMIFS_PRIO */
2183
    case 0xfffecc08:        /* EMIFF_PRIO */
2184
    case 0xfffecc0c:        /* EMIFS_CONFIG */
2185
    case 0xfffecc10:        /* EMIFS_CS0_CONFIG */
2186
    case 0xfffecc14:        /* EMIFS_CS1_CONFIG */
2187
    case 0xfffecc18:        /* EMIFS_CS2_CONFIG */
2188
    case 0xfffecc1c:        /* EMIFS_CS3_CONFIG */
2189
    case 0xfffecc24:        /* EMIFF_MRS */
2190
    case 0xfffecc28:        /* TIMEOUT1 */
2191
    case 0xfffecc2c:        /* TIMEOUT2 */
2192
    case 0xfffecc30:        /* TIMEOUT3 */
2193
    case 0xfffecc3c:        /* EMIFF_SDRAM_CONFIG_2 */
2194
    case 0xfffecc40:        /* EMIFS_CFG_DYN_WAIT */
2195
        return s->tcmi_regs[offset >> 2];
2196

    
2197
    case 0xfffecc20:        /* EMIFF_SDRAM_CONFIG */
2198
        ret = s->tcmi_regs[offset >> 2];
2199
        s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2200
        /* XXX: We can try using the VGA_DIRTY flag for this */
2201
        return ret;
2202
    }
2203

    
2204
    OMAP_BAD_REG(addr);
2205
    return 0;
2206
}
2207

    
2208
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2209
                uint32_t value)
2210
{
2211
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2212
    int offset = addr - s->tcmi_base;
2213

    
2214
    switch (offset) {
2215
    case 0xfffecc00:        /* IMIF_PRIO */
2216
    case 0xfffecc04:        /* EMIFS_PRIO */
2217
    case 0xfffecc08:        /* EMIFF_PRIO */
2218
    case 0xfffecc10:        /* EMIFS_CS0_CONFIG */
2219
    case 0xfffecc14:        /* EMIFS_CS1_CONFIG */
2220
    case 0xfffecc18:        /* EMIFS_CS2_CONFIG */
2221
    case 0xfffecc1c:        /* EMIFS_CS3_CONFIG */
2222
    case 0xfffecc20:        /* EMIFF_SDRAM_CONFIG */
2223
    case 0xfffecc24:        /* EMIFF_MRS */
2224
    case 0xfffecc28:        /* TIMEOUT1 */
2225
    case 0xfffecc2c:        /* TIMEOUT2 */
2226
    case 0xfffecc30:        /* TIMEOUT3 */
2227
    case 0xfffecc3c:        /* EMIFF_SDRAM_CONFIG_2 */
2228
    case 0xfffecc40:        /* EMIFS_CFG_DYN_WAIT */
2229
        s->tcmi_regs[offset >> 2] = value;
2230
        break;
2231
    case 0xfffecc0c:        /* EMIFS_CONFIG */
2232
        s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
2233
        break;
2234

    
2235
    default:
2236
        OMAP_BAD_REG(addr);
2237
    }
2238
}
2239

    
2240
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2241
    omap_badwidth_read32,
2242
    omap_badwidth_read32,
2243
    omap_tcmi_read,
2244
};
2245

    
2246
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2247
    omap_badwidth_write32,
2248
    omap_badwidth_write32,
2249
    omap_tcmi_write,
2250
};
2251

    
2252
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
2253
{
2254
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
2255
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
2256
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
2257
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
2258
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
2259
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
2260
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
2261
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
2262
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
2263
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
2264
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
2265
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
2266
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
2267
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
2268
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
2269
}
2270

    
2271
static void omap_tcmi_init(target_phys_addr_t base,
2272
                struct omap_mpu_state_s *mpu)
2273
{
2274
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2275
                    omap_tcmi_writefn, mpu);
2276

    
2277
    mpu->tcmi_base = base;
2278
    cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2279
    omap_tcmi_reset(mpu);
2280
}
2281

    
2282
/* Digital phase-locked loops control */
2283
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2284
{
2285
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2286
    int offset = addr - s->base;
2287

    
2288
    if (offset == 0x00)        /* CTL_REG */
2289
        return s->mode;
2290

    
2291
    OMAP_BAD_REG(addr);
2292
    return 0;
2293
}
2294

    
2295
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2296
                uint32_t value)
2297
{
2298
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2299
    uint16_t diff;
2300
    int offset = addr - s->base;
2301
    static const int bypass_div[4] = { 1, 2, 4, 4 };
2302
    int div, mult;
2303

    
2304
    if (offset == 0x00) {        /* CTL_REG */
2305
        /* See omap_ulpd_pm_write() too */
2306
        diff = s->mode & value;
2307
        s->mode = value & 0x2fff;
2308
        if (diff & (0x3ff << 2)) {
2309
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
2310
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
2311
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
2312
            } else {
2313
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
2314
                mult = 1;
2315
            }
2316
            omap_clk_setrate(s->dpll, div, mult);
2317
        }
2318

    
2319
        /* Enter the desired mode.  */
2320
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
2321

    
2322
        /* Act as if the lock is restored.  */
2323
        s->mode |= 2;
2324
    } else {
2325
        OMAP_BAD_REG(addr);
2326
    }
2327
}
2328

    
2329
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
2330
    omap_badwidth_read16,
2331
    omap_dpll_read,
2332
    omap_badwidth_read16,
2333
};
2334

    
2335
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
2336
    omap_badwidth_write16,
2337
    omap_dpll_write,
2338
    omap_badwidth_write16,
2339
};
2340

    
2341
static void omap_dpll_reset(struct dpll_ctl_s *s)
2342
{
2343
    s->mode = 0x2002;
2344
    omap_clk_setrate(s->dpll, 1, 1);
2345
}
2346

    
2347
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
2348
                omap_clk clk)
2349
{
2350
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
2351
                    omap_dpll_writefn, s);
2352

    
2353
    s->base = base;
2354
    s->dpll = clk;
2355
    omap_dpll_reset(s);
2356

    
2357
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2358
}
2359

    
2360
/* UARTs */
2361
struct omap_uart_s {
2362
    SerialState *serial; /* TODO */
2363
};
2364

    
2365
static void omap_uart_reset(struct omap_uart_s *s)
2366
{
2367
}
2368

    
2369
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2370
                qemu_irq irq, omap_clk clk, CharDriverState *chr)
2371
{
2372
    struct omap_uart_s *s = (struct omap_uart_s *)
2373
            qemu_mallocz(sizeof(struct omap_uart_s));
2374
    if (chr)
2375
        s->serial = serial_mm_init(base, 2, irq, chr, 1);
2376
    return s;
2377
}
2378

    
2379
/* MPU Clock/Reset/Power Mode Control */
2380
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2381
{
2382
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2383
    int offset = addr - s->clkm.mpu_base;
2384

    
2385
    switch (offset) {
2386
    case 0x00:        /* ARM_CKCTL */
2387
        return s->clkm.arm_ckctl;
2388

    
2389
    case 0x04:        /* ARM_IDLECT1 */
2390
        return s->clkm.arm_idlect1;
2391

    
2392
    case 0x08:        /* ARM_IDLECT2 */
2393
        return s->clkm.arm_idlect2;
2394

    
2395
    case 0x0c:        /* ARM_EWUPCT */
2396
        return s->clkm.arm_ewupct;
2397

    
2398
    case 0x10:        /* ARM_RSTCT1 */
2399
        return s->clkm.arm_rstct1;
2400

    
2401
    case 0x14:        /* ARM_RSTCT2 */
2402
        return s->clkm.arm_rstct2;
2403

    
2404
    case 0x18:        /* ARM_SYSST */
2405
        return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start;
2406

    
2407
    case 0x1c:        /* ARM_CKOUT1 */
2408
        return s->clkm.arm_ckout1;
2409

    
2410
    case 0x20:        /* ARM_CKOUT2 */
2411
        break;
2412
    }
2413

    
2414
    OMAP_BAD_REG(addr);
2415
    return 0;
2416
}
2417

    
2418
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2419
                uint16_t diff, uint16_t value)
2420
{
2421
    omap_clk clk;
2422

    
2423
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
2424
        if (value & (1 << 14))
2425
            /* Reserved */;
2426
        else {
2427
            clk = omap_findclk(s, "arminth_ck");
2428
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2429
        }
2430
    }
2431
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
2432
        clk = omap_findclk(s, "armtim_ck");
2433
        if (value & (1 << 12))
2434
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
2435
        else
2436
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2437
    }
2438
    /* XXX: en_dspck */
2439
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
2440
        clk = omap_findclk(s, "dspmmu_ck");
2441
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
2442
    }
2443
    if (diff & (3 << 8)) {                                /* TCDIV */
2444
        clk = omap_findclk(s, "tc_ck");
2445
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2446
    }
2447
    if (diff & (3 << 6)) {                                /* DSPDIV */
2448
        clk = omap_findclk(s, "dsp_ck");
2449
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2450
    }
2451
    if (diff & (3 << 4)) {                                /* ARMDIV */
2452
        clk = omap_findclk(s, "arm_ck");
2453
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2454
    }
2455
    if (diff & (3 << 2)) {                                /* LCDDIV */
2456
        clk = omap_findclk(s, "lcd_ck");
2457
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2458
    }
2459
    if (diff & (3 << 0)) {                                /* PERDIV */
2460
        clk = omap_findclk(s, "armper_ck");
2461
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2462
    }
2463
}
2464

    
2465
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2466
                uint16_t diff, uint16_t value)
2467
{
2468
    omap_clk clk;
2469

    
2470
    if (value & (1 << 11))                                /* SETARM_IDLE */
2471
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2472
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2473
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2474

    
2475
#define SET_CANIDLE(clock, bit)                                \
2476
    if (diff & (1 << bit)) {                                \
2477
        clk = omap_findclk(s, clock);                        \
2478
        omap_clk_canidle(clk, (value >> bit) & 1);        \
2479
    }
2480
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
2481
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
2482
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
2483
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
2484
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
2485
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
2486
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
2487
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
2488
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
2489
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
2490
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
2491
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
2492
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
2493
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
2494
}
2495

    
2496
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2497
                uint16_t diff, uint16_t value)
2498
{
2499
    omap_clk clk;
2500

    
2501
#define SET_ONOFF(clock, bit)                                \
2502
    if (diff & (1 << bit)) {                                \
2503
        clk = omap_findclk(s, clock);                        \
2504
        omap_clk_onoff(clk, (value >> bit) & 1);        \
2505
    }
2506
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
2507
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
2508
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
2509
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
2510
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
2511
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
2512
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
2513
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
2514
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
2515
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
2516
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
2517
}
2518

    
2519
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2520
                uint16_t diff, uint16_t value)
2521
{
2522
    omap_clk clk;
2523

    
2524
    if (diff & (3 << 4)) {                                /* TCLKOUT */
2525
        clk = omap_findclk(s, "tclk_out");
2526
        switch ((value >> 4) & 3) {
2527
        case 1:
2528
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
2529
            omap_clk_onoff(clk, 1);
2530
            break;
2531
        case 2:
2532
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2533
            omap_clk_onoff(clk, 1);
2534
            break;
2535
        default:
2536
            omap_clk_onoff(clk, 0);
2537
        }
2538
    }
2539
    if (diff & (3 << 2)) {                                /* DCLKOUT */
2540
        clk = omap_findclk(s, "dclk_out");
2541
        switch ((value >> 2) & 3) {
2542
        case 0:
2543
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
2544
            break;
2545
        case 1:
2546
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
2547
            break;
2548
        case 2:
2549
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
2550
            break;
2551
        case 3:
2552
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2553
            break;
2554
        }
2555
    }
2556
    if (diff & (3 << 0)) {                                /* ACLKOUT */
2557
        clk = omap_findclk(s, "aclk_out");
2558
        switch ((value >> 0) & 3) {
2559
        case 1:
2560
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2561
            omap_clk_onoff(clk, 1);
2562
            break;
2563
        case 2:
2564
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
2565
            omap_clk_onoff(clk, 1);
2566
            break;
2567
        case 3:
2568
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2569
            omap_clk_onoff(clk, 1);
2570
            break;
2571
        default:
2572
            omap_clk_onoff(clk, 0);
2573
        }
2574
    }
2575
}
2576

    
2577
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2578
                uint32_t value)
2579
{
2580
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2581
    int offset = addr - s->clkm.mpu_base;
2582
    uint16_t diff;
2583
    omap_clk clk;
2584
    static const char *clkschemename[8] = {
2585
        "fully synchronous", "fully asynchronous", "synchronous scalable",
2586
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2587
    };
2588

    
2589
    switch (offset) {
2590
    case 0x00:        /* ARM_CKCTL */
2591
        diff = s->clkm.arm_ckctl ^ value;
2592
        s->clkm.arm_ckctl = value & 0x7fff;
2593
        omap_clkm_ckctl_update(s, diff, value);
2594
        return;
2595

    
2596
    case 0x04:        /* ARM_IDLECT1 */
2597
        diff = s->clkm.arm_idlect1 ^ value;
2598
        s->clkm.arm_idlect1 = value & 0x0fff;
2599
        omap_clkm_idlect1_update(s, diff, value);
2600
        return;
2601

    
2602
    case 0x08:        /* ARM_IDLECT2 */
2603
        diff = s->clkm.arm_idlect2 ^ value;
2604
        s->clkm.arm_idlect2 = value & 0x07ff;
2605
        omap_clkm_idlect2_update(s, diff, value);
2606
        return;
2607

    
2608
    case 0x0c:        /* ARM_EWUPCT */
2609
        diff = s->clkm.arm_ewupct ^ value;
2610
        s->clkm.arm_ewupct = value & 0x003f;
2611
        return;
2612

    
2613
    case 0x10:        /* ARM_RSTCT1 */
2614
        diff = s->clkm.arm_rstct1 ^ value;
2615
        s->clkm.arm_rstct1 = value & 0x0007;
2616
        if (value & 9) {
2617
            qemu_system_reset_request();
2618
            s->clkm.cold_start = 0xa;
2619
        }
2620
        if (diff & ~value & 4) {                                /* DSP_RST */
2621
            omap_mpui_reset(s);
2622
            omap_tipb_bridge_reset(s->private_tipb);
2623
            omap_tipb_bridge_reset(s->public_tipb);
2624
        }
2625
        if (diff & 2) {                                                /* DSP_EN */
2626
            clk = omap_findclk(s, "dsp_ck");
2627
            omap_clk_canidle(clk, (~value >> 1) & 1);
2628
        }
2629
        return;
2630

    
2631
    case 0x14:        /* ARM_RSTCT2 */
2632
        s->clkm.arm_rstct2 = value & 0x0001;
2633
        return;
2634

    
2635
    case 0x18:        /* ARM_SYSST */
2636
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2637
            s->clkm.clocking_scheme = (value >> 11) & 7;
2638
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2639
                            clkschemename[s->clkm.clocking_scheme]);
2640
        }
2641
        s->clkm.cold_start &= value & 0x3f;
2642
        return;
2643

    
2644
    case 0x1c:        /* ARM_CKOUT1 */
2645
        diff = s->clkm.arm_ckout1 ^ value;
2646
        s->clkm.arm_ckout1 = value & 0x003f;
2647
        omap_clkm_ckout1_update(s, diff, value);
2648
        return;
2649

    
2650
    case 0x20:        /* ARM_CKOUT2 */
2651
    default:
2652
        OMAP_BAD_REG(addr);
2653
    }
2654
}
2655

    
2656
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2657
    omap_badwidth_read16,
2658
    omap_clkm_read,
2659
    omap_badwidth_read16,
2660
};
2661

    
2662
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2663
    omap_badwidth_write16,
2664
    omap_clkm_write,
2665
    omap_badwidth_write16,
2666
};
2667

    
2668
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2669
{
2670
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2671
    int offset = addr - s->clkm.dsp_base;
2672

    
2673
    switch (offset) {
2674
    case 0x04:        /* DSP_IDLECT1 */
2675
        return s->clkm.dsp_idlect1;
2676

    
2677
    case 0x08:        /* DSP_IDLECT2 */
2678
        return s->clkm.dsp_idlect2;
2679

    
2680
    case 0x14:        /* DSP_RSTCT2 */
2681
        return s->clkm.dsp_rstct2;
2682

    
2683
    case 0x18:        /* DSP_SYSST */
2684
        return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start |
2685
                (s->env->halted << 6);        /* Quite useless... */
2686
    }
2687

    
2688
    OMAP_BAD_REG(addr);
2689
    return 0;
2690
}
2691

    
2692
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2693
                uint16_t diff, uint16_t value)
2694
{
2695
    omap_clk clk;
2696

    
2697
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2698
}
2699

    
2700
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2701
                uint16_t diff, uint16_t value)
2702
{
2703
    omap_clk clk;
2704

    
2705
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2706
}
2707

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

    
2715
    switch (offset) {
2716
    case 0x04:        /* DSP_IDLECT1 */
2717
        diff = s->clkm.dsp_idlect1 ^ value;
2718
        s->clkm.dsp_idlect1 = value & 0x01f7;
2719
        omap_clkdsp_idlect1_update(s, diff, value);
2720
        break;
2721

    
2722
    case 0x08:        /* DSP_IDLECT2 */
2723
        s->clkm.dsp_idlect2 = value & 0x0037;
2724
        diff = s->clkm.dsp_idlect1 ^ value;
2725
        omap_clkdsp_idlect2_update(s, diff, value);
2726
        break;
2727

    
2728
    case 0x14:        /* DSP_RSTCT2 */
2729
        s->clkm.dsp_rstct2 = value & 0x0001;
2730
        break;
2731

    
2732
    case 0x18:        /* DSP_SYSST */
2733
        s->clkm.cold_start &= value & 0x3f;
2734
        break;
2735

    
2736
    default:
2737
        OMAP_BAD_REG(addr);
2738
    }
2739
}
2740

    
2741
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2742
    omap_badwidth_read16,
2743
    omap_clkdsp_read,
2744
    omap_badwidth_read16,
2745
};
2746

    
2747
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2748
    omap_badwidth_write16,
2749
    omap_clkdsp_write,
2750
    omap_badwidth_write16,
2751
};
2752

    
2753
static void omap_clkm_reset(struct omap_mpu_state_s *s)
2754
{
2755
    if (s->wdt && s->wdt->reset)
2756
        s->clkm.cold_start = 0x6;
2757
    s->clkm.clocking_scheme = 0;
2758
    omap_clkm_ckctl_update(s, ~0, 0x3000);
2759
    s->clkm.arm_ckctl = 0x3000;
2760
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 & 0x0400, 0x0400);
2761
    s->clkm.arm_idlect1 = 0x0400;
2762
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 & 0x0100, 0x0100);
2763
    s->clkm.arm_idlect2 = 0x0100;
2764
    s->clkm.arm_ewupct = 0x003f;
2765
    s->clkm.arm_rstct1 = 0x0000;
2766
    s->clkm.arm_rstct2 = 0x0000;
2767
    s->clkm.arm_ckout1 = 0x0015;
2768
    s->clkm.dpll1_mode = 0x2002;
2769
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2770
    s->clkm.dsp_idlect1 = 0x0040;
2771
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2772
    s->clkm.dsp_idlect2 = 0x0000;
2773
    s->clkm.dsp_rstct2 = 0x0000;
2774
}
2775

    
2776
static void omap_clkm_init(target_phys_addr_t mpu_base,
2777
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2778
{
2779
    int iomemtype[2] = {
2780
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2781
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2782
    };
2783

    
2784
    s->clkm.mpu_base = mpu_base;
2785
    s->clkm.dsp_base = dsp_base;
2786
    s->clkm.cold_start = 0x3a;
2787
    omap_clkm_reset(s);
2788

    
2789
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2790
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2791
}
2792

    
2793
/* General chip reset */
2794
static void omap_mpu_reset(void *opaque)
2795
{
2796
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
2797

    
2798
    omap_clkm_reset(mpu);
2799
    omap_inth_reset(mpu->ih[0]);
2800
    omap_inth_reset(mpu->ih[1]);
2801
    omap_dma_reset(mpu->dma);
2802
    omap_mpu_timer_reset(mpu->timer[0]);
2803
    omap_mpu_timer_reset(mpu->timer[1]);
2804
    omap_mpu_timer_reset(mpu->timer[2]);
2805
    omap_wd_timer_reset(mpu->wdt);
2806
    omap_os_timer_reset(mpu->os_timer);
2807
    omap_lcdc_reset(mpu->lcd);
2808
    omap_ulpd_pm_reset(mpu);
2809
    omap_pin_cfg_reset(mpu);
2810
    omap_mpui_reset(mpu);
2811
    omap_tipb_bridge_reset(mpu->private_tipb);
2812
    omap_tipb_bridge_reset(mpu->public_tipb);
2813
    omap_dpll_reset(&mpu->dpll[0]);
2814
    omap_dpll_reset(&mpu->dpll[1]);
2815
    omap_dpll_reset(&mpu->dpll[2]);
2816
    omap_uart_reset(mpu->uart1);
2817
    omap_uart_reset(mpu->uart2);
2818
    omap_uart_reset(mpu->uart3);
2819
    omap_mmc_reset(mpu->mmc);
2820
    cpu_reset(mpu->env);
2821
}
2822

    
2823
static void omap_mpu_wakeup(void *opaque, int irq, int req)
2824
{
2825
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
2826

    
2827
    cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
2828
}
2829

    
2830
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
2831
                DisplayState *ds, const char *core)
2832
{
2833
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
2834
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
2835
    ram_addr_t imif_base, emiff_base;
2836

    
2837
    /* Core */
2838
    s->mpu_model = omap310;
2839
    s->env = cpu_init();
2840
    s->sdram_size = sdram_size;
2841
    s->sram_size = OMAP15XX_SRAM_SIZE;
2842

    
2843
    cpu_arm_set_model(s->env, core ?: "ti925t");
2844

    
2845
    /* Clocks */
2846
    omap_clk_init(s);
2847

    
2848
    /* Memory-mapped stuff */
2849
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
2850
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
2851
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
2852
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
2853

    
2854
    omap_clkm_init(0xfffece00, 0xe1008000, s);
2855

    
2856
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100,
2857
                    arm_pic_init_cpu(s->env),
2858
                    omap_findclk(s, "arminth_ck"));
2859
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800,
2860
                    &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ],
2861
                    omap_findclk(s, "arminth_ck"));
2862
    s->irq[0] = s->ih[0]->pins;
2863
    s->irq[1] = s->ih[1]->pins;
2864

    
2865
    s->dma = omap_dma_init(0xfffed800, s->irq[0], s,
2866
                    omap_findclk(s, "dma_ck"));
2867
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
2868
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
2869
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
2870
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
2871
    s->port[local    ].addr_valid = omap_validate_local_addr;
2872
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
2873

    
2874
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
2875
                    s->irq[0][OMAP_INT_TIMER1],
2876
                    omap_findclk(s, "mputim_ck"));
2877
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
2878
                    s->irq[0][OMAP_INT_TIMER2],
2879
                    omap_findclk(s, "mputim_ck"));
2880
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
2881
                    s->irq[0][OMAP_INT_TIMER3],
2882
                    omap_findclk(s, "mputim_ck"));
2883

    
2884
    s->wdt = omap_wd_timer_init(0xfffec800,
2885
                    s->irq[0][OMAP_INT_WD_TIMER],
2886
                    omap_findclk(s, "armwdt_ck"));
2887

    
2888
    s->os_timer = omap_os_timer_init(0xfffb9000,
2889
                    s->irq[1][OMAP_INT_OS_TIMER],
2890
                    omap_findclk(s, "clk32-kHz"));
2891

    
2892
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
2893
                    &s->dma->lcd_ch, ds, imif_base, emiff_base,
2894
                    omap_findclk(s, "lcd_ck"));
2895

    
2896
    omap_ulpd_pm_init(0xfffe0800, s);
2897
    omap_pin_cfg_init(0xfffe1000, s);
2898
    omap_id_init(s);
2899

    
2900
    omap_mpui_init(0xfffec900, s);
2901

    
2902
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
2903
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
2904
                    omap_findclk(s, "tipb_ck"));
2905
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
2906
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
2907
                    omap_findclk(s, "tipb_ck"));
2908

    
2909
    omap_tcmi_init(0xfffecc00, s);
2910

    
2911
    s->uart1 = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
2912
                    omap_findclk(s, "uart1_ck"),
2913
                    serial_hds[0]);
2914
    s->uart2 = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
2915
                    omap_findclk(s, "uart2_ck"),
2916
                    serial_hds[0] ? serial_hds[1] : 0);
2917
    s->uart3 = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
2918
                    omap_findclk(s, "uart3_ck"),
2919
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
2920

    
2921
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
2922
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
2923
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
2924

    
2925
    s->mmc = omap_mmc_init(0xfffb7800, s->irq[1][OMAP_INT_OQN],
2926
                    &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
2927

    
2928
    qemu_register_reset(omap_mpu_reset, s);
2929
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
2930

    
2931
    return s;
2932
}