Statistics
| Branch: | Revision:

root / hw / omap.c @ 02645926

History | View | Annotate | Download (116.2 kB)

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

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

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

    
34
void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
35
                uint32_t value)
36
{
37
    OMAP_8B_REG(addr);
38
}
39

    
40
uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
41
{
42
    OMAP_16B_REG(addr);
43
    return 0;
44
}
45

    
46
void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
47
                uint32_t value)
48
{
49
    OMAP_16B_REG(addr);
50
}
51

    
52
uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
53
{
54
    OMAP_32B_REG(addr);
55
    return 0;
56
}
57

    
58
void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
59
                uint32_t value)
60
{
61
    OMAP_32B_REG(addr);
62
}
63

    
64
/* Interrupt Handlers */
65
struct omap_intr_handler_s {
66
    qemu_irq *pins;
67
    qemu_irq *parent_pic;
68
    target_phys_addr_t base;
69

    
70
    /* state */
71
    uint32_t irqs;
72
    uint32_t mask;
73
    uint32_t sens_edge;
74
    uint32_t fiq;
75
    int priority[32];
76
    uint32_t new_irq_agr;
77
    uint32_t new_fiq_agr;
78
    int sir_irq;
79
    int sir_fiq;
80
    int stats[32];
81
};
82

    
83
static void omap_inth_update(struct omap_intr_handler_s *s)
84
{
85
    uint32_t irq = s->irqs & ~s->mask & ~s->fiq;
86
    uint32_t fiq = s->irqs & ~s->mask & s->fiq;
87

    
88
    if (s->new_irq_agr || !irq) {
89
       qemu_set_irq(s->parent_pic[ARM_PIC_CPU_IRQ], irq);
90
       if (irq)
91
           s->new_irq_agr = 0;
92
    }
93

    
94
    if (s->new_fiq_agr || !irq) {
95
        qemu_set_irq(s->parent_pic[ARM_PIC_CPU_FIQ], fiq);
96
        if (fiq)
97
            s->new_fiq_agr = 0;
98
    }
99
}
100

    
101
static void omap_inth_sir_update(struct omap_intr_handler_s *s)
102
{
103
    int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f;
104
    uint32_t level = s->irqs & ~s->mask;
105

    
106
    intr_irq = 0;
107
    intr_fiq = 0;
108
    p_irq = -1;
109
    p_fiq = -1;
110
    /* Find the interrupt line with the highest dynamic priority */
111
    for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, level >>= f) {
112
        p = s->priority[i];
113
        if (s->fiq & (1 << i)) {
114
            if (p > p_fiq) {
115
                p_fiq = p;
116
                intr_fiq = i;
117
            }
118
        } else {
119
            if (p > p_irq) {
120
                p_irq = p;
121
                intr_irq = i;
122
            }
123
        }
124

    
125
        f = ffs(level >> 1);
126
    }
127

    
128
    s->sir_irq = intr_irq;
129
    s->sir_fiq = intr_fiq;
130
}
131

    
132
#define INT_FALLING_EDGE        0
133
#define INT_LOW_LEVEL                1
134

    
135
static void omap_set_intr(void *opaque, int irq, int req)
136
{
137
    struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
138
    uint32_t rise;
139

    
140
    if (req) {
141
        rise = ~ih->irqs & (1 << irq);
142
        ih->irqs |= rise;
143
        ih->stats[irq] += !!rise;
144
    } else {
145
        rise = ih->sens_edge & ih->irqs & (1 << irq);
146
        ih->irqs &= ~rise;
147
    }
148

    
149
    if (rise & ~ih->mask) {
150
        omap_inth_sir_update(ih);
151

    
152
        omap_inth_update(ih);
153
    }
154
}
155

    
156
static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
157
{
158
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
159
    int i, offset = addr - s->base;
160

    
161
    switch (offset) {
162
    case 0x00:        /* ITR */
163
        return s->irqs;
164

    
165
    case 0x04:        /* MIR */
166
        return s->mask;
167

    
168
    case 0x10:        /* SIR_IRQ_CODE */
169
        i = s->sir_irq;
170
        if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
171
            s->irqs &= ~(1 << i);
172
            omap_inth_sir_update(s);
173
            omap_inth_update(s);
174
        }
175
        return i;
176

    
177
    case 0x14:        /* SIR_FIQ_CODE */
178
        i = s->sir_fiq;
179
        if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
180
            s->irqs &= ~(1 << i);
181
            omap_inth_sir_update(s);
182
            omap_inth_update(s);
183
        }
184
        return i;
185

    
186
    case 0x18:        /* CONTROL_REG */
187
        return 0;
188

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

    
226
    case 0x9c:        /* ISR */
227
        return 0x00000000;
228

    
229
    default:
230
        OMAP_BAD_REG(addr);
231
        break;
232
    }
233
    return 0;
234
}
235

    
236
static void omap_inth_write(void *opaque, target_phys_addr_t addr,
237
                uint32_t value)
238
{
239
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
240
    int i, offset = addr - s->base;
241

    
242
    switch (offset) {
243
    case 0x00:        /* ITR */
244
        s->irqs &= value;
245
        omap_inth_sir_update(s);
246
        omap_inth_update(s);
247
        return;
248

    
249
    case 0x04:        /* MIR */
250
        s->mask = value;
251
        omap_inth_sir_update(s);
252
        omap_inth_update(s);
253
        return;
254

    
255
    case 0x10:        /* SIR_IRQ_CODE */
256
    case 0x14:        /* SIR_FIQ_CODE */
257
        OMAP_RO_REG(addr);
258
        break;
259

    
260
    case 0x18:        /* CONTROL_REG */
261
        if (value & 2)
262
            s->new_fiq_agr = ~0;
263
        if (value & 1)
264
            s->new_irq_agr = ~0;
265
        omap_inth_update(s);
266
        return;
267

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

    
308
    case 0x9c:        /* ISR */
309
        for (i = 0; i < 32; i ++)
310
            if (value & (1 << i)) {
311
                omap_set_intr(s, i, 1);
312
                return;
313
            }
314
        return;
315

    
316
    default:
317
        OMAP_BAD_REG(addr);
318
    }
319
}
320

    
321
static CPUReadMemoryFunc *omap_inth_readfn[] = {
322
    omap_badwidth_read32,
323
    omap_badwidth_read32,
324
    omap_inth_read,
325
};
326

    
327
static CPUWriteMemoryFunc *omap_inth_writefn[] = {
328
    omap_inth_write,
329
    omap_inth_write,
330
    omap_inth_write,
331
};
332

    
333
static void omap_inth_reset(struct omap_intr_handler_s *s)
334
{
335
    s->irqs = 0x00000000;
336
    s->mask = 0xffffffff;
337
    s->sens_edge = 0x00000000;
338
    s->fiq = 0x00000000;
339
    memset(s->priority, 0, sizeof(s->priority));
340
    s->new_irq_agr = ~0;
341
    s->new_fiq_agr = ~0;
342
    s->sir_irq = 0;
343
    s->sir_fiq = 0;
344

    
345
    omap_inth_update(s);
346
}
347

    
348
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
349
                unsigned long size, qemu_irq parent[2], omap_clk clk)
350
{
351
    int iomemtype;
352
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
353
            qemu_mallocz(sizeof(struct omap_intr_handler_s));
354

    
355
    s->parent_pic = parent;
356
    s->base = base;
357
    s->pins = qemu_allocate_irqs(omap_set_intr, s, 32);
358
    omap_inth_reset(s);
359

    
360
    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
361
                    omap_inth_writefn, s);
362
    cpu_register_physical_memory(s->base, size, iomemtype);
363

    
364
    return s;
365
}
366

    
367
/* OMAP1 DMA module */
368
typedef enum {
369
    constant = 0,
370
    post_incremented,
371
    single_index,
372
    double_index,
373
} omap_dma_addressing_t;
374

    
375
struct omap_dma_channel_s {
376
    int burst[2];
377
    int pack[2];
378
    enum omap_dma_port port[2];
379
    target_phys_addr_t addr[2];
380
    omap_dma_addressing_t mode[2];
381
    int data_type;
382
    int end_prog;
383
    int repeat;
384
    int auto_init;
385
    int priority;
386
    int fs;
387
    int sync;
388
    int running;
389
    int interrupts;
390
    int status;
391
    int signalled;
392
    int post_sync;
393
    int transfer;
394
    uint16_t elements;
395
    uint16_t frames;
396
    uint16_t frame_index;
397
    uint16_t element_index;
398
    uint16_t cpc;
399

    
400
    struct omap_dma_reg_set_s {
401
        target_phys_addr_t src, dest;
402
        int frame;
403
        int element;
404
        int frame_delta[2];
405
        int elem_delta[2];
406
        int frames;
407
        int elements;
408
    } active_set;
409
};
410

    
411
struct omap_dma_s {
412
    qemu_irq *ih;
413
    QEMUTimer *tm;
414
    struct omap_mpu_state_s *mpu;
415
    target_phys_addr_t base;
416
    omap_clk clk;
417
    int64_t delay;
418
    uint32_t drq;
419

    
420
    uint16_t gcr;
421
    int run_count;
422

    
423
    int chans;
424
    struct omap_dma_channel_s ch[16];
425
    struct omap_dma_lcd_channel_s lcd_ch;
426
};
427

    
428
static void omap_dma_interrupts_update(struct omap_dma_s *s)
429
{
430
    /* First three interrupts are shared between two channels each.  */
431
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH0_6],
432
                    (s->ch[0].status | s->ch[6].status) & 0x3f);
433
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH1_7],
434
                    (s->ch[1].status | s->ch[7].status) & 0x3f);
435
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH2_8],
436
                    (s->ch[2].status | s->ch[8].status) & 0x3f);
437
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH3],
438
                    (s->ch[3].status) & 0x3f);
439
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH4],
440
                    (s->ch[4].status) & 0x3f);
441
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH5],
442
                    (s->ch[5].status) & 0x3f);
443
}
444

    
445
static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
446
{
447
    struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
448
    int i;
449

    
450
    /*
451
     * TODO: verify address ranges and alignment
452
     * TODO: port endianness
453
     */
454

    
455
    a->src = s->ch[ch].addr[0];
456
    a->dest = s->ch[ch].addr[1];
457
    a->frames = s->ch[ch].frames;
458
    a->elements = s->ch[ch].elements;
459
    a->frame = 0;
460
    a->element = 0;
461

    
462
    if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
463
        printf("%s: bad DMA request\n", __FUNCTION__);
464
        return;
465
    }
466

    
467
    for (i = 0; i < 2; i ++)
468
        switch (s->ch[ch].mode[i]) {
469
        case constant:
470
            a->elem_delta[i] = 0;
471
            a->frame_delta[i] = 0;
472
            break;
473
        case post_incremented:
474
            a->elem_delta[i] = s->ch[ch].data_type;
475
            a->frame_delta[i] = 0;
476
            break;
477
        case single_index:
478
            a->elem_delta[i] = s->ch[ch].data_type +
479
                s->ch[ch].element_index - 1;
480
            if (s->ch[ch].element_index > 0x7fff)
481
                a->elem_delta[i] -= 0x10000;
482
            a->frame_delta[i] = 0;
483
            break;
484
        case double_index:
485
            a->elem_delta[i] = s->ch[ch].data_type +
486
                s->ch[ch].element_index - 1;
487
            if (s->ch[ch].element_index > 0x7fff)
488
                a->elem_delta[i] -= 0x10000;
489
            a->frame_delta[i] = s->ch[ch].frame_index -
490
                s->ch[ch].element_index;
491
            if (s->ch[ch].frame_index > 0x7fff)
492
                a->frame_delta[i] -= 0x10000;
493
            break;
494
        default:
495
            break;
496
        }
497
}
498

    
499
static inline void omap_dma_request_run(struct omap_dma_s *s,
500
                int channel, int request)
501
{
502
next_channel:
503
    if (request > 0)
504
        for (; channel < 9; channel ++)
505
            if (s->ch[channel].sync == request && s->ch[channel].running)
506
                break;
507
    if (channel >= 9)
508
        return;
509

    
510
    if (s->ch[channel].transfer) {
511
        if (request > 0) {
512
            s->ch[channel ++].post_sync = request;
513
            goto next_channel;
514
        }
515
        s->ch[channel].status |= 0x02;        /* Synchronisation drop */
516
        omap_dma_interrupts_update(s);
517
        return;
518
    }
519

    
520
    if (!s->ch[channel].signalled)
521
        s->run_count ++;
522
    s->ch[channel].signalled = 1;
523

    
524
    if (request > 0)
525
        s->ch[channel].status |= 0x40;        /* External request */
526

    
527
    if (s->delay && !qemu_timer_pending(s->tm))
528
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
529

    
530
    if (request > 0) {
531
        channel ++;
532
        goto next_channel;
533
    }
534
}
535

    
536
static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel)
537
{
538
    if (s->ch[channel].signalled)
539
        s->run_count --;
540
    s->ch[channel].signalled = 0;
541

    
542
    if (!s->run_count)
543
        qemu_del_timer(s->tm);
544
}
545

    
546
static void omap_dma_channel_run(struct omap_dma_s *s)
547
{
548
    int ch;
549
    uint16_t status;
550
    uint8_t value[4];
551
    struct omap_dma_port_if_s *src_p, *dest_p;
552
    struct omap_dma_reg_set_s *a;
553

    
554
    for (ch = 0; ch < 9; ch ++) {
555
        a = &s->ch[ch].active_set;
556

    
557
        src_p = &s->mpu->port[s->ch[ch].port[0]];
558
        dest_p = &s->mpu->port[s->ch[ch].port[1]];
559
        if (s->ch[ch].signalled && (!src_p->addr_valid(s->mpu, a->src) ||
560
                    !dest_p->addr_valid(s->mpu, a->dest))) {
561
#if 0
562
            /* Bus time-out */
563
            if (s->ch[ch].interrupts & 0x01)
564
                s->ch[ch].status |= 0x01;
565
            omap_dma_request_stop(s, ch);
566
            continue;
567
#endif
568
            printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch);
569
        }
570

    
571
        status = s->ch[ch].status;
572
        while (status == s->ch[ch].status && s->ch[ch].signalled) {
573
            /* Transfer a single element */
574
            s->ch[ch].transfer = 1;
575
            cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
576
            cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
577
            s->ch[ch].transfer = 0;
578

    
579
            a->src += a->elem_delta[0];
580
            a->dest += a->elem_delta[1];
581
            a->element ++;
582

    
583
            /* Check interrupt conditions */
584
            if (a->element == a->elements) {
585
                a->element = 0;
586
                a->src += a->frame_delta[0];
587
                a->dest += a->frame_delta[1];
588
                a->frame ++;
589

    
590
                if (a->frame == a->frames) {
591
                    if (!s->ch[ch].repeat || !s->ch[ch].auto_init)
592
                        s->ch[ch].running = 0;
593

    
594
                    if (s->ch[ch].auto_init &&
595
                            (s->ch[ch].repeat ||
596
                             s->ch[ch].end_prog))
597
                        omap_dma_channel_load(s, ch);
598

    
599
                    if (s->ch[ch].interrupts & 0x20)
600
                        s->ch[ch].status |= 0x20;
601

    
602
                    if (!s->ch[ch].sync)
603
                        omap_dma_request_stop(s, ch);
604
                }
605

    
606
                if (s->ch[ch].interrupts & 0x08)
607
                    s->ch[ch].status |= 0x08;
608

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

    
616
            if (a->element == 1 && a->frame == a->frames - 1)
617
                if (s->ch[ch].interrupts & 0x10)
618
                    s->ch[ch].status |= 0x10;
619

    
620
            if (a->element == (a->elements >> 1))
621
                if (s->ch[ch].interrupts & 0x04)
622
                    s->ch[ch].status |= 0x04;
623

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

    
630
            /*
631
             * Process requests made while the element was
632
             * being transferred.
633
             */
634
            if (s->ch[ch].post_sync) {
635
                omap_dma_request_run(s, 0, s->ch[ch].post_sync);
636
                s->ch[ch].post_sync = 0;
637
            }
638

    
639
#if 0
640
            break;
641
#endif
642
        }
643

    
644
        s->ch[ch].cpc = a->dest & 0x0000ffff;
645
    }
646

    
647
    omap_dma_interrupts_update(s);
648
    if (s->run_count && s->delay)
649
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
650
}
651

    
652
static int omap_dma_ch_reg_read(struct omap_dma_s *s,
653
                int ch, int reg, uint16_t *value) {
654
    switch (reg) {
655
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
656
        *value = (s->ch[ch].burst[1] << 14) |
657
                (s->ch[ch].pack[1] << 13) |
658
                (s->ch[ch].port[1] << 9) |
659
                (s->ch[ch].burst[0] << 7) |
660
                (s->ch[ch].pack[0] << 6) |
661
                (s->ch[ch].port[0] << 2) |
662
                (s->ch[ch].data_type >> 1);
663
        break;
664

    
665
    case 0x02:        /* SYS_DMA_CCR_CH0 */
666
        *value = (s->ch[ch].mode[1] << 14) |
667
                (s->ch[ch].mode[0] << 12) |
668
                (s->ch[ch].end_prog << 11) |
669
                (s->ch[ch].repeat << 9) |
670
                (s->ch[ch].auto_init << 8) |
671
                (s->ch[ch].running << 7) |
672
                (s->ch[ch].priority << 6) |
673
                (s->ch[ch].fs << 5) | s->ch[ch].sync;
674
        break;
675

    
676
    case 0x04:        /* SYS_DMA_CICR_CH0 */
677
        *value = s->ch[ch].interrupts;
678
        break;
679

    
680
    case 0x06:        /* SYS_DMA_CSR_CH0 */
681
        /* FIXME: shared CSR for channels sharing the interrupts */
682
        *value = s->ch[ch].status;
683
        s->ch[ch].status &= 0x40;
684
        omap_dma_interrupts_update(s);
685
        break;
686

    
687
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
688
        *value = s->ch[ch].addr[0] & 0x0000ffff;
689
        break;
690

    
691
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
692
        *value = s->ch[ch].addr[0] >> 16;
693
        break;
694

    
695
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
696
        *value = s->ch[ch].addr[1] & 0x0000ffff;
697
        break;
698

    
699
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
700
        *value = s->ch[ch].addr[1] >> 16;
701
        break;
702

    
703
    case 0x10:        /* SYS_DMA_CEN_CH0 */
704
        *value = s->ch[ch].elements;
705
        break;
706

    
707
    case 0x12:        /* SYS_DMA_CFN_CH0 */
708
        *value = s->ch[ch].frames;
709
        break;
710

    
711
    case 0x14:        /* SYS_DMA_CFI_CH0 */
712
        *value = s->ch[ch].frame_index;
713
        break;
714

    
715
    case 0x16:        /* SYS_DMA_CEI_CH0 */
716
        *value = s->ch[ch].element_index;
717
        break;
718

    
719
    case 0x18:        /* SYS_DMA_CPC_CH0 */
720
        *value = s->ch[ch].cpc;
721
        break;
722

    
723
    default:
724
        return 1;
725
    }
726
    return 0;
727
}
728

    
729
static int omap_dma_ch_reg_write(struct omap_dma_s *s,
730
                int ch, int reg, uint16_t value) {
731
    switch (reg) {
732
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
733
        s->ch[ch].burst[1] = (value & 0xc000) >> 14;
734
        s->ch[ch].pack[1] = (value & 0x2000) >> 13;
735
        s->ch[ch].port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
736
        s->ch[ch].burst[0] = (value & 0x0180) >> 7;
737
        s->ch[ch].pack[0] = (value & 0x0040) >> 6;
738
        s->ch[ch].port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
739
        s->ch[ch].data_type = (1 << (value & 3));
740
        if (s->ch[ch].port[0] >= omap_dma_port_last)
741
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
742
                            s->ch[ch].port[0]);
743
        if (s->ch[ch].port[1] >= omap_dma_port_last)
744
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
745
                            s->ch[ch].port[1]);
746
        if ((value & 3) == 3)
747
            printf("%s: bad data_type for DMA channel %i\n", __FUNCTION__, ch);
748
        break;
749

    
750
    case 0x02:        /* SYS_DMA_CCR_CH0 */
751
        s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
752
        s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
753
        s->ch[ch].end_prog = (value & 0x0800) >> 11;
754
        s->ch[ch].repeat = (value & 0x0200) >> 9;
755
        s->ch[ch].auto_init = (value & 0x0100) >> 8;
756
        s->ch[ch].priority = (value & 0x0040) >> 6;
757
        s->ch[ch].fs = (value & 0x0020) >> 5;
758
        s->ch[ch].sync = value & 0x001f;
759
        if (value & 0x0080) {
760
            if (s->ch[ch].running) {
761
                if (!s->ch[ch].signalled &&
762
                                s->ch[ch].auto_init && s->ch[ch].end_prog)
763
                    omap_dma_channel_load(s, ch);
764
            } else {
765
                s->ch[ch].running = 1;
766
                omap_dma_channel_load(s, ch);
767
            }
768
            if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync)))
769
                omap_dma_request_run(s, ch, 0);
770
        } else {
771
            s->ch[ch].running = 0;
772
            omap_dma_request_stop(s, ch);
773
        }
774
        break;
775

    
776
    case 0x04:        /* SYS_DMA_CICR_CH0 */
777
        s->ch[ch].interrupts = value & 0x003f;
778
        break;
779

    
780
    case 0x06:        /* SYS_DMA_CSR_CH0 */
781
        return 1;
782

    
783
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
784
        s->ch[ch].addr[0] &= 0xffff0000;
785
        s->ch[ch].addr[0] |= value;
786
        break;
787

    
788
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
789
        s->ch[ch].addr[0] &= 0x0000ffff;
790
        s->ch[ch].addr[0] |= value << 16;
791
        break;
792

    
793
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
794
        s->ch[ch].addr[1] &= 0xffff0000;
795
        s->ch[ch].addr[1] |= value;
796
        break;
797

    
798
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
799
        s->ch[ch].addr[1] &= 0x0000ffff;
800
        s->ch[ch].addr[1] |= value << 16;
801
        break;
802

    
803
    case 0x10:        /* SYS_DMA_CEN_CH0 */
804
        s->ch[ch].elements = value & 0xffff;
805
        break;
806

    
807
    case 0x12:        /* SYS_DMA_CFN_CH0 */
808
        s->ch[ch].frames = value & 0xffff;
809
        break;
810

    
811
    case 0x14:        /* SYS_DMA_CFI_CH0 */
812
        s->ch[ch].frame_index = value & 0xffff;
813
        break;
814

    
815
    case 0x16:        /* SYS_DMA_CEI_CH0 */
816
        s->ch[ch].element_index = value & 0xffff;
817
        break;
818

    
819
    case 0x18:        /* SYS_DMA_CPC_CH0 */
820
        return 1;
821

    
822
    default:
823
        OMAP_BAD_REG((unsigned long) reg);
824
    }
825
    return 0;
826
}
827

    
828
static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
829
{
830
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
831
    int i, reg, ch, offset = addr - s->base;
832
    uint16_t ret;
833

    
834
    switch (offset) {
835
    case 0x000 ... 0x2fe:
836
        reg = offset & 0x3f;
837
        ch = (offset >> 6) & 0x0f;
838
        if (omap_dma_ch_reg_read(s, ch, reg, &ret))
839
            break;
840
        return ret;
841

    
842
    case 0x300:        /* SYS_DMA_LCD_CTRL */
843
        i = s->lcd_ch.condition;
844
        s->lcd_ch.condition = 0;
845
        qemu_irq_lower(s->lcd_ch.irq);
846
        return ((s->lcd_ch.src == imif) << 6) | (i << 3) |
847
                (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
848

    
849
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
850
        return s->lcd_ch.src_f1_top & 0xffff;
851

    
852
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
853
        return s->lcd_ch.src_f1_top >> 16;
854

    
855
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
856
        return s->lcd_ch.src_f1_bottom & 0xffff;
857

    
858
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
859
        return s->lcd_ch.src_f1_bottom >> 16;
860

    
861
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
862
        return s->lcd_ch.src_f2_top & 0xffff;
863

    
864
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
865
        return s->lcd_ch.src_f2_top >> 16;
866

    
867
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
868
        return s->lcd_ch.src_f2_bottom & 0xffff;
869

    
870
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
871
        return s->lcd_ch.src_f2_bottom >> 16;
872

    
873
    case 0x400:        /* SYS_DMA_GCR */
874
        return s->gcr;
875
    }
876

    
877
    OMAP_BAD_REG(addr);
878
    return 0;
879
}
880

    
881
static void omap_dma_write(void *opaque, target_phys_addr_t addr,
882
                uint32_t value)
883
{
884
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
885
    int reg, ch, offset = addr - s->base;
886

    
887
    switch (offset) {
888
    case 0x000 ... 0x2fe:
889
        reg = offset & 0x3f;
890
        ch = (offset >> 6) & 0x0f;
891
        if (omap_dma_ch_reg_write(s, ch, reg, value))
892
            OMAP_RO_REG(addr);
893
        break;
894

    
895
    case 0x300:        /* SYS_DMA_LCD_CTRL */
896
        s->lcd_ch.src = (value & 0x40) ? imif : emiff;
897
        s->lcd_ch.condition = 0;
898
        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
899
        s->lcd_ch.interrupts = (value >> 1) & 1;
900
        s->lcd_ch.dual = value & 1;
901
        break;
902

    
903
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
904
        s->lcd_ch.src_f1_top &= 0xffff0000;
905
        s->lcd_ch.src_f1_top |= 0x0000ffff & value;
906
        break;
907

    
908
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
909
        s->lcd_ch.src_f1_top &= 0x0000ffff;
910
        s->lcd_ch.src_f1_top |= value << 16;
911
        break;
912

    
913
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
914
        s->lcd_ch.src_f1_bottom &= 0xffff0000;
915
        s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
916
        break;
917

    
918
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
919
        s->lcd_ch.src_f1_bottom &= 0x0000ffff;
920
        s->lcd_ch.src_f1_bottom |= value << 16;
921
        break;
922

    
923
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
924
        s->lcd_ch.src_f2_top &= 0xffff0000;
925
        s->lcd_ch.src_f2_top |= 0x0000ffff & value;
926
        break;
927

    
928
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
929
        s->lcd_ch.src_f2_top &= 0x0000ffff;
930
        s->lcd_ch.src_f2_top |= value << 16;
931
        break;
932

    
933
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
934
        s->lcd_ch.src_f2_bottom &= 0xffff0000;
935
        s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
936
        break;
937

    
938
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
939
        s->lcd_ch.src_f2_bottom &= 0x0000ffff;
940
        s->lcd_ch.src_f2_bottom |= value << 16;
941
        break;
942

    
943
    case 0x400:        /* SYS_DMA_GCR */
944
        s->gcr = value & 0x000c;
945
        break;
946

    
947
    default:
948
        OMAP_BAD_REG(addr);
949
    }
950
}
951

    
952
static CPUReadMemoryFunc *omap_dma_readfn[] = {
953
    omap_badwidth_read16,
954
    omap_dma_read,
955
    omap_badwidth_read16,
956
};
957

    
958
static CPUWriteMemoryFunc *omap_dma_writefn[] = {
959
    omap_badwidth_write16,
960
    omap_dma_write,
961
    omap_badwidth_write16,
962
};
963

    
964
static void omap_dma_request(void *opaque, int drq, int req)
965
{
966
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
967
    /* The request pins are level triggered.  */
968
    if (req) {
969
        if (~s->drq & (1 << drq)) {
970
            s->drq |= 1 << drq;
971
            omap_dma_request_run(s, 0, drq);
972
        }
973
    } else
974
        s->drq &= ~(1 << drq);
975
}
976

    
977
static void omap_dma_clk_update(void *opaque, int line, int on)
978
{
979
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
980

    
981
    if (on) {
982
        s->delay = ticks_per_sec >> 5;
983
        if (s->run_count)
984
            qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
985
    } else {
986
        s->delay = 0;
987
        qemu_del_timer(s->tm);
988
    }
989
}
990

    
991
static void omap_dma_reset(struct omap_dma_s *s)
992
{
993
    int i;
994

    
995
    qemu_del_timer(s->tm);
996
    s->gcr = 0x0004;
997
    s->drq = 0x00000000;
998
    s->run_count = 0;
999
    s->lcd_ch.src = emiff;
1000
    s->lcd_ch.condition = 0;
1001
    s->lcd_ch.interrupts = 0;
1002
    s->lcd_ch.dual = 0;
1003
    memset(s->ch, 0, sizeof(s->ch));
1004
    for (i = 0; i < s->chans; i ++)
1005
        s->ch[i].interrupts = 0x0003;
1006
}
1007

    
1008
struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
1009
                qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk)
1010
{
1011
    int iomemtype;
1012
    struct omap_dma_s *s = (struct omap_dma_s *)
1013
            qemu_mallocz(sizeof(struct omap_dma_s));
1014

    
1015
    s->ih = pic;
1016
    s->base = base;
1017
    s->chans = 9;
1018
    s->mpu = mpu;
1019
    s->clk = clk;
1020
    s->lcd_ch.irq = pic[OMAP_INT_DMA_LCD];
1021
    s->lcd_ch.mpu = mpu;
1022
    s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1023
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1024
    mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1025
    omap_dma_reset(s);
1026
    omap_dma_clk_update(s, 0, 1);
1027

    
1028
    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1029
                    omap_dma_writefn, s);
1030
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
1031

    
1032
    return s;
1033
}
1034

    
1035
/* DMA ports */
1036
int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1037
                target_phys_addr_t addr)
1038
{
1039
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1040
}
1041

    
1042
int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1043
                target_phys_addr_t addr)
1044
{
1045
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1046
}
1047

    
1048
int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1049
                target_phys_addr_t addr)
1050
{
1051
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1052
}
1053

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

    
1060
int omap_validate_local_addr(struct omap_mpu_state_s *s,
1061
                target_phys_addr_t addr)
1062
{
1063
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1064
}
1065

    
1066
int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1067
                target_phys_addr_t addr)
1068
{
1069
    return addr >= 0xe1010000 && addr < 0xe1020004;
1070
}
1071

    
1072
/* MPU OS timers */
1073
struct omap_mpu_timer_s {
1074
    qemu_irq irq;
1075
    omap_clk clk;
1076
    target_phys_addr_t base;
1077
    uint32_t val;
1078
    int64_t time;
1079
    QEMUTimer *timer;
1080
    int64_t rate;
1081
    int it_ena;
1082

    
1083
    int enable;
1084
    int ptv;
1085
    int ar;
1086
    int st;
1087
    uint32_t reset_val;
1088
};
1089

    
1090
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1091
{
1092
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
1093

    
1094
    if (timer->st && timer->enable && timer->rate)
1095
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
1096
                        timer->rate, ticks_per_sec);
1097
    else
1098
        return timer->val;
1099
}
1100

    
1101
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1102
{
1103
    timer->val = omap_timer_read(timer);
1104
    timer->time = qemu_get_clock(vm_clock);
1105
}
1106

    
1107
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1108
{
1109
    int64_t expires;
1110

    
1111
    if (timer->enable && timer->st && timer->rate) {
1112
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
1113
        expires = timer->time + muldiv64(timer->val << (timer->ptv + 1),
1114
                        ticks_per_sec, timer->rate);
1115
        qemu_mod_timer(timer->timer, expires);
1116
    } else
1117
        qemu_del_timer(timer->timer);
1118
}
1119

    
1120
static void omap_timer_tick(void *opaque)
1121
{
1122
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1123
    omap_timer_sync(timer);
1124

    
1125
    if (!timer->ar) {
1126
        timer->val = 0;
1127
        timer->st = 0;
1128
    }
1129

    
1130
    if (timer->it_ena)
1131
        qemu_irq_raise(timer->irq);
1132
    omap_timer_update(timer);
1133
}
1134

    
1135
static void omap_timer_clk_update(void *opaque, int line, int on)
1136
{
1137
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1138

    
1139
    omap_timer_sync(timer);
1140
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1141
    omap_timer_update(timer);
1142
}
1143

    
1144
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
1145
{
1146
    omap_clk_adduser(timer->clk,
1147
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
1148
    timer->rate = omap_clk_getrate(timer->clk);
1149
}
1150

    
1151
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
1152
{
1153
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1154
    int offset = addr - s->base;
1155

    
1156
    switch (offset) {
1157
    case 0x00:        /* CNTL_TIMER */
1158
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1159

    
1160
    case 0x04:        /* LOAD_TIM */
1161
        break;
1162

    
1163
    case 0x08:        /* READ_TIM */
1164
        return omap_timer_read(s);
1165
    }
1166

    
1167
    OMAP_BAD_REG(addr);
1168
    return 0;
1169
}
1170

    
1171
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1172
                uint32_t value)
1173
{
1174
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1175
    int offset = addr - s->base;
1176

    
1177
    switch (offset) {
1178
    case 0x00:        /* CNTL_TIMER */
1179
        omap_timer_sync(s);
1180
        s->enable = (value >> 5) & 1;
1181
        s->ptv = (value >> 2) & 7;
1182
        s->ar = (value >> 1) & 1;
1183
        s->st = value & 1;
1184
        omap_timer_update(s);
1185
        return;
1186

    
1187
    case 0x04:        /* LOAD_TIM */
1188
        s->reset_val = value;
1189
        return;
1190

    
1191
    case 0x08:        /* READ_TIM */
1192
        OMAP_RO_REG(addr);
1193
        break;
1194

    
1195
    default:
1196
        OMAP_BAD_REG(addr);
1197
    }
1198
}
1199

    
1200
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1201
    omap_badwidth_read32,
1202
    omap_badwidth_read32,
1203
    omap_mpu_timer_read,
1204
};
1205

    
1206
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1207
    omap_badwidth_write32,
1208
    omap_badwidth_write32,
1209
    omap_mpu_timer_write,
1210
};
1211

    
1212
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
1213
{
1214
    qemu_del_timer(s->timer);
1215
    s->enable = 0;
1216
    s->reset_val = 31337;
1217
    s->val = 0;
1218
    s->ptv = 0;
1219
    s->ar = 0;
1220
    s->st = 0;
1221
    s->it_ena = 1;
1222
}
1223

    
1224
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1225
                qemu_irq irq, omap_clk clk)
1226
{
1227
    int iomemtype;
1228
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1229
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
1230

    
1231
    s->irq = irq;
1232
    s->clk = clk;
1233
    s->base = base;
1234
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
1235
    omap_mpu_timer_reset(s);
1236
    omap_timer_clk_setup(s);
1237

    
1238
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
1239
                    omap_mpu_timer_writefn, s);
1240
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1241

    
1242
    return s;
1243
}
1244

    
1245
/* Watchdog timer */
1246
struct omap_watchdog_timer_s {
1247
    struct omap_mpu_timer_s timer;
1248
    uint8_t last_wr;
1249
    int mode;
1250
    int free;
1251
    int reset;
1252
};
1253

    
1254
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
1255
{
1256
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1257
    int offset = addr - s->timer.base;
1258

    
1259
    switch (offset) {
1260
    case 0x00:        /* CNTL_TIMER */
1261
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
1262
                (s->timer.st << 7) | (s->free << 1);
1263

    
1264
    case 0x04:        /* READ_TIMER */
1265
        return omap_timer_read(&s->timer);
1266

    
1267
    case 0x08:        /* TIMER_MODE */
1268
        return s->mode << 15;
1269
    }
1270

    
1271
    OMAP_BAD_REG(addr);
1272
    return 0;
1273
}
1274

    
1275
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1276
                uint32_t value)
1277
{
1278
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1279
    int offset = addr - s->timer.base;
1280

    
1281
    switch (offset) {
1282
    case 0x00:        /* CNTL_TIMER */
1283
        omap_timer_sync(&s->timer);
1284
        s->timer.ptv = (value >> 9) & 7;
1285
        s->timer.ar = (value >> 8) & 1;
1286
        s->timer.st = (value >> 7) & 1;
1287
        s->free = (value >> 1) & 1;
1288
        omap_timer_update(&s->timer);
1289
        break;
1290

    
1291
    case 0x04:        /* LOAD_TIMER */
1292
        s->timer.reset_val = value & 0xffff;
1293
        break;
1294

    
1295
    case 0x08:        /* TIMER_MODE */
1296
        if (!s->mode && ((value >> 15) & 1))
1297
            omap_clk_get(s->timer.clk);
1298
        s->mode |= (value >> 15) & 1;
1299
        if (s->last_wr == 0xf5) {
1300
            if ((value & 0xff) == 0xa0) {
1301
                s->mode = 0;
1302
                omap_clk_put(s->timer.clk);
1303
            } else {
1304
                /* XXX: on T|E hardware somehow this has no effect,
1305
                 * on Zire 71 it works as specified.  */
1306
                s->reset = 1;
1307
                qemu_system_reset_request();
1308
            }
1309
        }
1310
        s->last_wr = value & 0xff;
1311
        break;
1312

    
1313
    default:
1314
        OMAP_BAD_REG(addr);
1315
    }
1316
}
1317

    
1318
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
1319
    omap_badwidth_read16,
1320
    omap_wd_timer_read,
1321
    omap_badwidth_read16,
1322
};
1323

    
1324
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
1325
    omap_badwidth_write16,
1326
    omap_wd_timer_write,
1327
    omap_badwidth_write16,
1328
};
1329

    
1330
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
1331
{
1332
    qemu_del_timer(s->timer.timer);
1333
    if (!s->mode)
1334
        omap_clk_get(s->timer.clk);
1335
    s->mode = 1;
1336
    s->free = 1;
1337
    s->reset = 0;
1338
    s->timer.enable = 1;
1339
    s->timer.it_ena = 1;
1340
    s->timer.reset_val = 0xffff;
1341
    s->timer.val = 0;
1342
    s->timer.st = 0;
1343
    s->timer.ptv = 0;
1344
    s->timer.ar = 0;
1345
    omap_timer_update(&s->timer);
1346
}
1347

    
1348
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
1349
                qemu_irq irq, omap_clk clk)
1350
{
1351
    int iomemtype;
1352
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
1353
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
1354

    
1355
    s->timer.irq = irq;
1356
    s->timer.clk = clk;
1357
    s->timer.base = base;
1358
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1359
    omap_wd_timer_reset(s);
1360
    omap_timer_clk_setup(&s->timer);
1361

    
1362
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
1363
                    omap_wd_timer_writefn, s);
1364
    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
1365

    
1366
    return s;
1367
}
1368

    
1369
/* 32-kHz timer */
1370
struct omap_32khz_timer_s {
1371
    struct omap_mpu_timer_s timer;
1372
};
1373

    
1374
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
1375
{
1376
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1377
    int offset = addr - s->timer.base;
1378

    
1379
    switch (offset) {
1380
    case 0x00:        /* TVR */
1381
        return s->timer.reset_val;
1382

    
1383
    case 0x04:        /* TCR */
1384
        return omap_timer_read(&s->timer);
1385

    
1386
    case 0x08:        /* CR */
1387
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
1388

    
1389
    default:
1390
        break;
1391
    }
1392
    OMAP_BAD_REG(addr);
1393
    return 0;
1394
}
1395

    
1396
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1397
                uint32_t value)
1398
{
1399
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1400
    int offset = addr - s->timer.base;
1401

    
1402
    switch (offset) {
1403
    case 0x00:        /* TVR */
1404
        s->timer.reset_val = value & 0x00ffffff;
1405
        break;
1406

    
1407
    case 0x04:        /* TCR */
1408
        OMAP_RO_REG(addr);
1409
        break;
1410

    
1411
    case 0x08:        /* CR */
1412
        s->timer.ar = (value >> 3) & 1;
1413
        s->timer.it_ena = (value >> 2) & 1;
1414
        if (s->timer.st != (value & 1) || (value & 2)) {
1415
            omap_timer_sync(&s->timer);
1416
            s->timer.enable = value & 1;
1417
            s->timer.st = value & 1;
1418
            omap_timer_update(&s->timer);
1419
        }
1420
        break;
1421

    
1422
    default:
1423
        OMAP_BAD_REG(addr);
1424
    }
1425
}
1426

    
1427
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1428
    omap_badwidth_read32,
1429
    omap_badwidth_read32,
1430
    omap_os_timer_read,
1431
};
1432

    
1433
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1434
    omap_badwidth_write32,
1435
    omap_badwidth_write32,
1436
    omap_os_timer_write,
1437
};
1438

    
1439
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1440
{
1441
    qemu_del_timer(s->timer.timer);
1442
    s->timer.enable = 0;
1443
    s->timer.it_ena = 0;
1444
    s->timer.reset_val = 0x00ffffff;
1445
    s->timer.val = 0;
1446
    s->timer.st = 0;
1447
    s->timer.ptv = 0;
1448
    s->timer.ar = 1;
1449
}
1450

    
1451
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1452
                qemu_irq irq, omap_clk clk)
1453
{
1454
    int iomemtype;
1455
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1456
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1457

    
1458
    s->timer.irq = irq;
1459
    s->timer.clk = clk;
1460
    s->timer.base = base;
1461
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1462
    omap_os_timer_reset(s);
1463
    omap_timer_clk_setup(&s->timer);
1464

    
1465
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1466
                    omap_os_timer_writefn, s);
1467
    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
1468

    
1469
    return s;
1470
}
1471

    
1472
/* Ultra Low-Power Device Module */
1473
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1474
{
1475
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1476
    int offset = addr - s->ulpd_pm_base;
1477
    uint16_t ret;
1478

    
1479
    switch (offset) {
1480
    case 0x14:        /* IT_STATUS */
1481
        ret = s->ulpd_pm_regs[offset >> 2];
1482
        s->ulpd_pm_regs[offset >> 2] = 0;
1483
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1484
        return ret;
1485

    
1486
    case 0x18:        /* Reserved */
1487
    case 0x1c:        /* Reserved */
1488
    case 0x20:        /* Reserved */
1489
    case 0x28:        /* Reserved */
1490
    case 0x2c:        /* Reserved */
1491
        OMAP_BAD_REG(addr);
1492
    case 0x00:        /* COUNTER_32_LSB */
1493
    case 0x04:        /* COUNTER_32_MSB */
1494
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1495
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1496
    case 0x10:        /* GAUGING_CTRL */
1497
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1498
    case 0x30:        /* CLOCK_CTRL */
1499
    case 0x34:        /* SOFT_REQ */
1500
    case 0x38:        /* COUNTER_32_FIQ */
1501
    case 0x3c:        /* DPLL_CTRL */
1502
    case 0x40:        /* STATUS_REQ */
1503
        /* XXX: check clk::usecount state for every clock */
1504
    case 0x48:        /* LOCL_TIME */
1505
    case 0x4c:        /* APLL_CTRL */
1506
    case 0x50:        /* POWER_CTRL */
1507
        return s->ulpd_pm_regs[offset >> 2];
1508
    }
1509

    
1510
    OMAP_BAD_REG(addr);
1511
    return 0;
1512
}
1513

    
1514
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1515
                uint16_t diff, uint16_t value)
1516
{
1517
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
1518
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1519
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1520
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1521
}
1522

    
1523
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1524
                uint16_t diff, uint16_t value)
1525
{
1526
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1527
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1528
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1529
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1530
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1531
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1532
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1533
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1534
}
1535

    
1536
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1537
                uint32_t value)
1538
{
1539
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1540
    int offset = addr - s->ulpd_pm_base;
1541
    int64_t now, ticks;
1542
    int div, mult;
1543
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1544
    uint16_t diff;
1545

    
1546
    switch (offset) {
1547
    case 0x00:        /* COUNTER_32_LSB */
1548
    case 0x04:        /* COUNTER_32_MSB */
1549
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1550
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1551
    case 0x14:        /* IT_STATUS */
1552
    case 0x40:        /* STATUS_REQ */
1553
        OMAP_RO_REG(addr);
1554
        break;
1555

    
1556
    case 0x10:        /* GAUGING_CTRL */
1557
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1558
        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
1559
            now = qemu_get_clock(vm_clock);
1560

    
1561
            if (value & 1)
1562
                s->ulpd_gauge_start = now;
1563
            else {
1564
                now -= s->ulpd_gauge_start;
1565

    
1566
                /* 32-kHz ticks */
1567
                ticks = muldiv64(now, 32768, ticks_per_sec);
1568
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1569
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1570
                if (ticks >> 32)        /* OVERFLOW_32K */
1571
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1572

    
1573
                /* High frequency ticks */
1574
                ticks = muldiv64(now, 12000000, ticks_per_sec);
1575
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1576
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1577
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1578
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1579

    
1580
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
1581
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1582
            }
1583
        }
1584
        s->ulpd_pm_regs[offset >> 2] = value;
1585
        break;
1586

    
1587
    case 0x18:        /* Reserved */
1588
    case 0x1c:        /* Reserved */
1589
    case 0x20:        /* Reserved */
1590
    case 0x28:        /* Reserved */
1591
    case 0x2c:        /* Reserved */
1592
        OMAP_BAD_REG(addr);
1593
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1594
    case 0x38:        /* COUNTER_32_FIQ */
1595
    case 0x48:        /* LOCL_TIME */
1596
    case 0x50:        /* POWER_CTRL */
1597
        s->ulpd_pm_regs[offset >> 2] = value;
1598
        break;
1599

    
1600
    case 0x30:        /* CLOCK_CTRL */
1601
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1602
        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
1603
        omap_ulpd_clk_update(s, diff, value);
1604
        break;
1605

    
1606
    case 0x34:        /* SOFT_REQ */
1607
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1608
        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
1609
        omap_ulpd_req_update(s, diff, value);
1610
        break;
1611

    
1612
    case 0x3c:        /* DPLL_CTRL */
1613
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
1614
         * omitted altogether, probably a typo.  */
1615
        /* This register has identical semantics with DPLL(1:3) control
1616
         * registers, see omap_dpll_write() */
1617
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1618
        s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
1619
        if (diff & (0x3ff << 2)) {
1620
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1621
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1622
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1623
            } else {
1624
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1625
                mult = 1;
1626
            }
1627
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
1628
        }
1629

    
1630
        /* Enter the desired mode.  */
1631
        s->ulpd_pm_regs[offset >> 2] =
1632
                (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
1633
                ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
1634

    
1635
        /* Act as if the lock is restored.  */
1636
        s->ulpd_pm_regs[offset >> 2] |= 2;
1637
        break;
1638

    
1639
    case 0x4c:        /* APLL_CTRL */
1640
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1641
        s->ulpd_pm_regs[offset >> 2] = value & 0xf;
1642
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
1643
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1644
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
1645
        break;
1646

    
1647
    default:
1648
        OMAP_BAD_REG(addr);
1649
    }
1650
}
1651

    
1652
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1653
    omap_badwidth_read16,
1654
    omap_ulpd_pm_read,
1655
    omap_badwidth_read16,
1656
};
1657

    
1658
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1659
    omap_badwidth_write16,
1660
    omap_ulpd_pm_write,
1661
    omap_badwidth_write16,
1662
};
1663

    
1664
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
1665
{
1666
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
1667
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
1668
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
1669
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
1670
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
1671
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
1672
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
1673
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
1674
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
1675
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
1676
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
1677
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
1678
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
1679
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
1680
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
1681
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
1682
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
1683
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
1684
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
1685
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
1686
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
1687
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
1688
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
1689
}
1690

    
1691
static void omap_ulpd_pm_init(target_phys_addr_t base,
1692
                struct omap_mpu_state_s *mpu)
1693
{
1694
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1695
                    omap_ulpd_pm_writefn, mpu);
1696

    
1697
    mpu->ulpd_pm_base = base;
1698
    cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1699
    omap_ulpd_pm_reset(mpu);
1700
}
1701

    
1702
/* OMAP Pin Configuration */
1703
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1704
{
1705
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1706
    int offset = addr - s->pin_cfg_base;
1707

    
1708
    switch (offset) {
1709
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1710
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1711
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1712
        return s->func_mux_ctrl[offset >> 2];
1713

    
1714
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1715
        return s->comp_mode_ctrl[0];
1716

    
1717
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1718
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1719
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1720
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1721
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1722
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1723
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1724
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1725
    case 0x30:        /* FUNC_MUX_CTRL_B */
1726
    case 0x34:        /* FUNC_MUX_CTRL_C */
1727
    case 0x38:        /* FUNC_MUX_CTRL_D */
1728
        return s->func_mux_ctrl[(offset >> 2) - 1];
1729

    
1730
    case 0x40:        /* PULL_DWN_CTRL_0 */
1731
    case 0x44:        /* PULL_DWN_CTRL_1 */
1732
    case 0x48:        /* PULL_DWN_CTRL_2 */
1733
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1734
        return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1735

    
1736
    case 0x50:        /* GATE_INH_CTRL_0 */
1737
        return s->gate_inh_ctrl[0];
1738

    
1739
    case 0x60:        /* VOLTAGE_CTRL_0 */
1740
        return s->voltage_ctrl[0];
1741

    
1742
    case 0x70:        /* TEST_DBG_CTRL_0 */
1743
        return s->test_dbg_ctrl[0];
1744

    
1745
    case 0x80:        /* MOD_CONF_CTRL_0 */
1746
        return s->mod_conf_ctrl[0];
1747
    }
1748

    
1749
    OMAP_BAD_REG(addr);
1750
    return 0;
1751
}
1752

    
1753
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1754
                uint32_t diff, uint32_t value)
1755
{
1756
    if (s->compat1509) {
1757
        if (diff & (1 << 9))                        /* BLUETOOTH */
1758
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1759
                            (~value >> 9) & 1);
1760
        if (diff & (1 << 7))                        /* USB.CLKO */
1761
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
1762
                            (value >> 7) & 1);
1763
    }
1764
}
1765

    
1766
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1767
                uint32_t diff, uint32_t value)
1768
{
1769
    if (s->compat1509) {
1770
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
1771
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1772
                            (value >> 31) & 1);
1773
        if (diff & (1 << 1))                        /* CLK32K */
1774
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1775
                            (~value >> 1) & 1);
1776
    }
1777
}
1778

    
1779
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1780
                uint32_t diff, uint32_t value)
1781
{
1782
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
1783
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1784
                         omap_findclk(s, ((value >> 31) & 1) ?
1785
                                 "ck_48m" : "armper_ck"));
1786
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
1787
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1788
                         omap_findclk(s, ((value >> 30) & 1) ?
1789
                                 "ck_48m" : "armper_ck"));
1790
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
1791
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1792
                         omap_findclk(s, ((value >> 29) & 1) ?
1793
                                 "ck_48m" : "armper_ck"));
1794
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
1795
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1796
                         omap_findclk(s, ((value >> 23) & 1) ?
1797
                                 "ck_48m" : "armper_ck"));
1798
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
1799
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1800
                         omap_findclk(s, ((value >> 12) & 1) ?
1801
                                 "ck_48m" : "armper_ck"));
1802
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1803
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1804
}
1805

    
1806
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1807
                uint32_t value)
1808
{
1809
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1810
    int offset = addr - s->pin_cfg_base;
1811
    uint32_t diff;
1812

    
1813
    switch (offset) {
1814
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1815
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1816
        s->func_mux_ctrl[offset >> 2] = value;
1817
        omap_pin_funcmux0_update(s, diff, value);
1818
        return;
1819

    
1820
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1821
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1822
        s->func_mux_ctrl[offset >> 2] = value;
1823
        omap_pin_funcmux1_update(s, diff, value);
1824
        return;
1825

    
1826
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1827
        s->func_mux_ctrl[offset >> 2] = value;
1828
        return;
1829

    
1830
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1831
        s->comp_mode_ctrl[0] = value;
1832
        s->compat1509 = (value != 0x0000eaef);
1833
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1834
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1835
        return;
1836

    
1837
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1838
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1839
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1840
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1841
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1842
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1843
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1844
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1845
    case 0x30:        /* FUNC_MUX_CTRL_B */
1846
    case 0x34:        /* FUNC_MUX_CTRL_C */
1847
    case 0x38:        /* FUNC_MUX_CTRL_D */
1848
        s->func_mux_ctrl[(offset >> 2) - 1] = value;
1849
        return;
1850

    
1851
    case 0x40:        /* PULL_DWN_CTRL_0 */
1852
    case 0x44:        /* PULL_DWN_CTRL_1 */
1853
    case 0x48:        /* PULL_DWN_CTRL_2 */
1854
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1855
        s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1856
        return;
1857

    
1858
    case 0x50:        /* GATE_INH_CTRL_0 */
1859
        s->gate_inh_ctrl[0] = value;
1860
        return;
1861

    
1862
    case 0x60:        /* VOLTAGE_CTRL_0 */
1863
        s->voltage_ctrl[0] = value;
1864
        return;
1865

    
1866
    case 0x70:        /* TEST_DBG_CTRL_0 */
1867
        s->test_dbg_ctrl[0] = value;
1868
        return;
1869

    
1870
    case 0x80:        /* MOD_CONF_CTRL_0 */
1871
        diff = s->mod_conf_ctrl[0] ^ value;
1872
        s->mod_conf_ctrl[0] = value;
1873
        omap_pin_modconf1_update(s, diff, value);
1874
        return;
1875

    
1876
    default:
1877
        OMAP_BAD_REG(addr);
1878
    }
1879
}
1880

    
1881
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1882
    omap_badwidth_read32,
1883
    omap_badwidth_read32,
1884
    omap_pin_cfg_read,
1885
};
1886

    
1887
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1888
    omap_badwidth_write32,
1889
    omap_badwidth_write32,
1890
    omap_pin_cfg_write,
1891
};
1892

    
1893
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1894
{
1895
    /* Start in Compatibility Mode.  */
1896
    mpu->compat1509 = 1;
1897
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1898
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1899
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1900
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1901
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1902
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1903
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1904
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1905
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1906
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1907
}
1908

    
1909
static void omap_pin_cfg_init(target_phys_addr_t base,
1910
                struct omap_mpu_state_s *mpu)
1911
{
1912
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1913
                    omap_pin_cfg_writefn, mpu);
1914

    
1915
    mpu->pin_cfg_base = base;
1916
    cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1917
    omap_pin_cfg_reset(mpu);
1918
}
1919

    
1920
/* Device Identification, Die Identification */
1921
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1922
{
1923
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1924

    
1925
    switch (addr) {
1926
    case 0xfffe1800:        /* DIE_ID_LSB */
1927
        return 0xc9581f0e;
1928
    case 0xfffe1804:        /* DIE_ID_MSB */
1929
        return 0xa8858bfa;
1930

    
1931
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
1932
        return 0x00aaaafc;
1933
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
1934
        return 0xcafeb574;
1935

    
1936
    case 0xfffed400:        /* JTAG_ID_LSB */
1937
        switch (s->mpu_model) {
1938
        case omap310:
1939
            return 0x03310315;
1940
        case omap1510:
1941
            return 0x03310115;
1942
        }
1943
        break;
1944

    
1945
    case 0xfffed404:        /* JTAG_ID_MSB */
1946
        switch (s->mpu_model) {
1947
        case omap310:
1948
            return 0xfb57402f;
1949
        case omap1510:
1950
            return 0xfb47002f;
1951
        }
1952
        break;
1953
    }
1954

    
1955
    OMAP_BAD_REG(addr);
1956
    return 0;
1957
}
1958

    
1959
static void omap_id_write(void *opaque, target_phys_addr_t addr,
1960
                uint32_t value)
1961
{
1962
    OMAP_BAD_REG(addr);
1963
}
1964

    
1965
static CPUReadMemoryFunc *omap_id_readfn[] = {
1966
    omap_badwidth_read32,
1967
    omap_badwidth_read32,
1968
    omap_id_read,
1969
};
1970

    
1971
static CPUWriteMemoryFunc *omap_id_writefn[] = {
1972
    omap_badwidth_write32,
1973
    omap_badwidth_write32,
1974
    omap_id_write,
1975
};
1976

    
1977
static void omap_id_init(struct omap_mpu_state_s *mpu)
1978
{
1979
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
1980
                    omap_id_writefn, mpu);
1981
    cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
1982
    cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
1983
    if (!cpu_is_omap15xx(mpu))
1984
        cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
1985
}
1986

    
1987
/* MPUI Control (Dummy) */
1988
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1989
{
1990
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1991
    int offset = addr - s->mpui_base;
1992

    
1993
    switch (offset) {
1994
    case 0x00:        /* CTRL */
1995
        return s->mpui_ctrl;
1996
    case 0x04:        /* DEBUG_ADDR */
1997
        return 0x01ffffff;
1998
    case 0x08:        /* DEBUG_DATA */
1999
        return 0xffffffff;
2000
    case 0x0c:        /* DEBUG_FLAG */
2001
        return 0x00000800;
2002
    case 0x10:        /* STATUS */
2003
        return 0x00000000;
2004

    
2005
    /* Not in OMAP310 */
2006
    case 0x14:        /* DSP_STATUS */
2007
    case 0x18:        /* DSP_BOOT_CONFIG */
2008
        return 0x00000000;
2009
    case 0x1c:        /* DSP_MPUI_CONFIG */
2010
        return 0x0000ffff;
2011
    }
2012

    
2013
    OMAP_BAD_REG(addr);
2014
    return 0;
2015
}
2016

    
2017
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2018
                uint32_t value)
2019
{
2020
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2021
    int offset = addr - s->mpui_base;
2022

    
2023
    switch (offset) {
2024
    case 0x00:        /* CTRL */
2025
        s->mpui_ctrl = value & 0x007fffff;
2026
        break;
2027

    
2028
    case 0x04:        /* DEBUG_ADDR */
2029
    case 0x08:        /* DEBUG_DATA */
2030
    case 0x0c:        /* DEBUG_FLAG */
2031
    case 0x10:        /* STATUS */
2032
    /* Not in OMAP310 */
2033
    case 0x14:        /* DSP_STATUS */
2034
        OMAP_RO_REG(addr);
2035
    case 0x18:        /* DSP_BOOT_CONFIG */
2036
    case 0x1c:        /* DSP_MPUI_CONFIG */
2037
        break;
2038

    
2039
    default:
2040
        OMAP_BAD_REG(addr);
2041
    }
2042
}
2043

    
2044
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2045
    omap_badwidth_read32,
2046
    omap_badwidth_read32,
2047
    omap_mpui_read,
2048
};
2049

    
2050
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2051
    omap_badwidth_write32,
2052
    omap_badwidth_write32,
2053
    omap_mpui_write,
2054
};
2055

    
2056
static void omap_mpui_reset(struct omap_mpu_state_s *s)
2057
{
2058
    s->mpui_ctrl = 0x0003ff1b;
2059
}
2060

    
2061
static void omap_mpui_init(target_phys_addr_t base,
2062
                struct omap_mpu_state_s *mpu)
2063
{
2064
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2065
                    omap_mpui_writefn, mpu);
2066

    
2067
    mpu->mpui_base = base;
2068
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2069

    
2070
    omap_mpui_reset(mpu);
2071
}
2072

    
2073
/* TIPB Bridges */
2074
struct omap_tipb_bridge_s {
2075
    target_phys_addr_t base;
2076
    qemu_irq abort;
2077

    
2078
    int width_intr;
2079
    uint16_t control;
2080
    uint16_t alloc;
2081
    uint16_t buffer;
2082
    uint16_t enh_control;
2083
};
2084

    
2085
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
2086
{
2087
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2088
    int offset = addr - s->base;
2089

    
2090
    switch (offset) {
2091
    case 0x00:        /* TIPB_CNTL */
2092
        return s->control;
2093
    case 0x04:        /* TIPB_BUS_ALLOC */
2094
        return s->alloc;
2095
    case 0x08:        /* MPU_TIPB_CNTL */
2096
        return s->buffer;
2097
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2098
        return s->enh_control;
2099
    case 0x10:        /* ADDRESS_DBG */
2100
    case 0x14:        /* DATA_DEBUG_LOW */
2101
    case 0x18:        /* DATA_DEBUG_HIGH */
2102
        return 0xffff;
2103
    case 0x1c:        /* DEBUG_CNTR_SIG */
2104
        return 0x00f8;
2105
    }
2106

    
2107
    OMAP_BAD_REG(addr);
2108
    return 0;
2109
}
2110

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

    
2117
    switch (offset) {
2118
    case 0x00:        /* TIPB_CNTL */
2119
        s->control = value & 0xffff;
2120
        break;
2121

    
2122
    case 0x04:        /* TIPB_BUS_ALLOC */
2123
        s->alloc = value & 0x003f;
2124
        break;
2125

    
2126
    case 0x08:        /* MPU_TIPB_CNTL */
2127
        s->buffer = value & 0x0003;
2128
        break;
2129

    
2130
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2131
        s->width_intr = !(value & 2);
2132
        s->enh_control = value & 0x000f;
2133
        break;
2134

    
2135
    case 0x10:        /* ADDRESS_DBG */
2136
    case 0x14:        /* DATA_DEBUG_LOW */
2137
    case 0x18:        /* DATA_DEBUG_HIGH */
2138
    case 0x1c:        /* DEBUG_CNTR_SIG */
2139
        OMAP_RO_REG(addr);
2140
        break;
2141

    
2142
    default:
2143
        OMAP_BAD_REG(addr);
2144
    }
2145
}
2146

    
2147
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2148
    omap_badwidth_read16,
2149
    omap_tipb_bridge_read,
2150
    omap_tipb_bridge_read,
2151
};
2152

    
2153
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2154
    omap_badwidth_write16,
2155
    omap_tipb_bridge_write,
2156
    omap_tipb_bridge_write,
2157
};
2158

    
2159
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2160
{
2161
    s->control = 0xffff;
2162
    s->alloc = 0x0009;
2163
    s->buffer = 0x0000;
2164
    s->enh_control = 0x000f;
2165
}
2166

    
2167
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2168
                qemu_irq abort_irq, omap_clk clk)
2169
{
2170
    int iomemtype;
2171
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2172
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2173

    
2174
    s->abort = abort_irq;
2175
    s->base = base;
2176
    omap_tipb_bridge_reset(s);
2177

    
2178
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
2179
                    omap_tipb_bridge_writefn, s);
2180
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2181

    
2182
    return s;
2183
}
2184

    
2185
/* Dummy Traffic Controller's Memory Interface */
2186
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2187
{
2188
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2189
    int offset = addr - s->tcmi_base;
2190
    uint32_t ret;
2191

    
2192
    switch (offset) {
2193
    case 0xfffecc00:        /* IMIF_PRIO */
2194
    case 0xfffecc04:        /* EMIFS_PRIO */
2195
    case 0xfffecc08:        /* EMIFF_PRIO */
2196
    case 0xfffecc0c:        /* EMIFS_CONFIG */
2197
    case 0xfffecc10:        /* EMIFS_CS0_CONFIG */
2198
    case 0xfffecc14:        /* EMIFS_CS1_CONFIG */
2199
    case 0xfffecc18:        /* EMIFS_CS2_CONFIG */
2200
    case 0xfffecc1c:        /* EMIFS_CS3_CONFIG */
2201
    case 0xfffecc24:        /* EMIFF_MRS */
2202
    case 0xfffecc28:        /* TIMEOUT1 */
2203
    case 0xfffecc2c:        /* TIMEOUT2 */
2204
    case 0xfffecc30:        /* TIMEOUT3 */
2205
    case 0xfffecc3c:        /* EMIFF_SDRAM_CONFIG_2 */
2206
    case 0xfffecc40:        /* EMIFS_CFG_DYN_WAIT */
2207
        return s->tcmi_regs[offset >> 2];
2208

    
2209
    case 0xfffecc20:        /* EMIFF_SDRAM_CONFIG */
2210
        ret = s->tcmi_regs[offset >> 2];
2211
        s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2212
        /* XXX: We can try using the VGA_DIRTY flag for this */
2213
        return ret;
2214
    }
2215

    
2216
    OMAP_BAD_REG(addr);
2217
    return 0;
2218
}
2219

    
2220
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2221
                uint32_t value)
2222
{
2223
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2224
    int offset = addr - s->tcmi_base;
2225

    
2226
    switch (offset) {
2227
    case 0xfffecc00:        /* IMIF_PRIO */
2228
    case 0xfffecc04:        /* EMIFS_PRIO */
2229
    case 0xfffecc08:        /* EMIFF_PRIO */
2230
    case 0xfffecc10:        /* EMIFS_CS0_CONFIG */
2231
    case 0xfffecc14:        /* EMIFS_CS1_CONFIG */
2232
    case 0xfffecc18:        /* EMIFS_CS2_CONFIG */
2233
    case 0xfffecc1c:        /* EMIFS_CS3_CONFIG */
2234
    case 0xfffecc20:        /* EMIFF_SDRAM_CONFIG */
2235
    case 0xfffecc24:        /* EMIFF_MRS */
2236
    case 0xfffecc28:        /* TIMEOUT1 */
2237
    case 0xfffecc2c:        /* TIMEOUT2 */
2238
    case 0xfffecc30:        /* TIMEOUT3 */
2239
    case 0xfffecc3c:        /* EMIFF_SDRAM_CONFIG_2 */
2240
    case 0xfffecc40:        /* EMIFS_CFG_DYN_WAIT */
2241
        s->tcmi_regs[offset >> 2] = value;
2242
        break;
2243
    case 0xfffecc0c:        /* EMIFS_CONFIG */
2244
        s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
2245
        break;
2246

    
2247
    default:
2248
        OMAP_BAD_REG(addr);
2249
    }
2250
}
2251

    
2252
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2253
    omap_badwidth_read32,
2254
    omap_badwidth_read32,
2255
    omap_tcmi_read,
2256
};
2257

    
2258
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2259
    omap_badwidth_write32,
2260
    omap_badwidth_write32,
2261
    omap_tcmi_write,
2262
};
2263

    
2264
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
2265
{
2266
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
2267
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
2268
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
2269
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
2270
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
2271
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
2272
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
2273
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
2274
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
2275
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
2276
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
2277
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
2278
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
2279
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
2280
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
2281
}
2282

    
2283
static void omap_tcmi_init(target_phys_addr_t base,
2284
                struct omap_mpu_state_s *mpu)
2285
{
2286
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2287
                    omap_tcmi_writefn, mpu);
2288

    
2289
    mpu->tcmi_base = base;
2290
    cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2291
    omap_tcmi_reset(mpu);
2292
}
2293

    
2294
/* Digital phase-locked loops control */
2295
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2296
{
2297
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2298
    int offset = addr - s->base;
2299

    
2300
    if (offset == 0x00)        /* CTL_REG */
2301
        return s->mode;
2302

    
2303
    OMAP_BAD_REG(addr);
2304
    return 0;
2305
}
2306

    
2307
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2308
                uint32_t value)
2309
{
2310
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2311
    uint16_t diff;
2312
    int offset = addr - s->base;
2313
    static const int bypass_div[4] = { 1, 2, 4, 4 };
2314
    int div, mult;
2315

    
2316
    if (offset == 0x00) {        /* CTL_REG */
2317
        /* See omap_ulpd_pm_write() too */
2318
        diff = s->mode & value;
2319
        s->mode = value & 0x2fff;
2320
        if (diff & (0x3ff << 2)) {
2321
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
2322
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
2323
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
2324
            } else {
2325
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
2326
                mult = 1;
2327
            }
2328
            omap_clk_setrate(s->dpll, div, mult);
2329
        }
2330

    
2331
        /* Enter the desired mode.  */
2332
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
2333

    
2334
        /* Act as if the lock is restored.  */
2335
        s->mode |= 2;
2336
    } else {
2337
        OMAP_BAD_REG(addr);
2338
    }
2339
}
2340

    
2341
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
2342
    omap_badwidth_read16,
2343
    omap_dpll_read,
2344
    omap_badwidth_read16,
2345
};
2346

    
2347
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
2348
    omap_badwidth_write16,
2349
    omap_dpll_write,
2350
    omap_badwidth_write16,
2351
};
2352

    
2353
static void omap_dpll_reset(struct dpll_ctl_s *s)
2354
{
2355
    s->mode = 0x2002;
2356
    omap_clk_setrate(s->dpll, 1, 1);
2357
}
2358

    
2359
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
2360
                omap_clk clk)
2361
{
2362
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
2363
                    omap_dpll_writefn, s);
2364

    
2365
    s->base = base;
2366
    s->dpll = clk;
2367
    omap_dpll_reset(s);
2368

    
2369
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2370
}
2371

    
2372
/* UARTs */
2373
struct omap_uart_s {
2374
    SerialState *serial; /* TODO */
2375
};
2376

    
2377
static void omap_uart_reset(struct omap_uart_s *s)
2378
{
2379
}
2380

    
2381
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2382
                qemu_irq irq, omap_clk clk, CharDriverState *chr)
2383
{
2384
    struct omap_uart_s *s = (struct omap_uart_s *)
2385
            qemu_mallocz(sizeof(struct omap_uart_s));
2386
    if (chr)
2387
        s->serial = serial_mm_init(base, 2, irq, chr, 1);
2388
    return s;
2389
}
2390

    
2391
/* MPU Clock/Reset/Power Mode Control */
2392
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2393
{
2394
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2395
    int offset = addr - s->clkm.mpu_base;
2396

    
2397
    switch (offset) {
2398
    case 0x00:        /* ARM_CKCTL */
2399
        return s->clkm.arm_ckctl;
2400

    
2401
    case 0x04:        /* ARM_IDLECT1 */
2402
        return s->clkm.arm_idlect1;
2403

    
2404
    case 0x08:        /* ARM_IDLECT2 */
2405
        return s->clkm.arm_idlect2;
2406

    
2407
    case 0x0c:        /* ARM_EWUPCT */
2408
        return s->clkm.arm_ewupct;
2409

    
2410
    case 0x10:        /* ARM_RSTCT1 */
2411
        return s->clkm.arm_rstct1;
2412

    
2413
    case 0x14:        /* ARM_RSTCT2 */
2414
        return s->clkm.arm_rstct2;
2415

    
2416
    case 0x18:        /* ARM_SYSST */
2417
        return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start;
2418

    
2419
    case 0x1c:        /* ARM_CKOUT1 */
2420
        return s->clkm.arm_ckout1;
2421

    
2422
    case 0x20:        /* ARM_CKOUT2 */
2423
        break;
2424
    }
2425

    
2426
    OMAP_BAD_REG(addr);
2427
    return 0;
2428
}
2429

    
2430
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2431
                uint16_t diff, uint16_t value)
2432
{
2433
    omap_clk clk;
2434

    
2435
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
2436
        if (value & (1 << 14))
2437
            /* Reserved */;
2438
        else {
2439
            clk = omap_findclk(s, "arminth_ck");
2440
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2441
        }
2442
    }
2443
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
2444
        clk = omap_findclk(s, "armtim_ck");
2445
        if (value & (1 << 12))
2446
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
2447
        else
2448
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2449
    }
2450
    /* XXX: en_dspck */
2451
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
2452
        clk = omap_findclk(s, "dspmmu_ck");
2453
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
2454
    }
2455
    if (diff & (3 << 8)) {                                /* TCDIV */
2456
        clk = omap_findclk(s, "tc_ck");
2457
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2458
    }
2459
    if (diff & (3 << 6)) {                                /* DSPDIV */
2460
        clk = omap_findclk(s, "dsp_ck");
2461
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2462
    }
2463
    if (diff & (3 << 4)) {                                /* ARMDIV */
2464
        clk = omap_findclk(s, "arm_ck");
2465
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2466
    }
2467
    if (diff & (3 << 2)) {                                /* LCDDIV */
2468
        clk = omap_findclk(s, "lcd_ck");
2469
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2470
    }
2471
    if (diff & (3 << 0)) {                                /* PERDIV */
2472
        clk = omap_findclk(s, "armper_ck");
2473
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2474
    }
2475
}
2476

    
2477
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2478
                uint16_t diff, uint16_t value)
2479
{
2480
    omap_clk clk;
2481

    
2482
    if (value & (1 << 11))                                /* SETARM_IDLE */
2483
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2484
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2485
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2486

    
2487
#define SET_CANIDLE(clock, bit)                                \
2488
    if (diff & (1 << bit)) {                                \
2489
        clk = omap_findclk(s, clock);                        \
2490
        omap_clk_canidle(clk, (value >> bit) & 1);        \
2491
    }
2492
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
2493
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
2494
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
2495
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
2496
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
2497
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
2498
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
2499
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
2500
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
2501
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
2502
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
2503
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
2504
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
2505
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
2506
}
2507

    
2508
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2509
                uint16_t diff, uint16_t value)
2510
{
2511
    omap_clk clk;
2512

    
2513
#define SET_ONOFF(clock, bit)                                \
2514
    if (diff & (1 << bit)) {                                \
2515
        clk = omap_findclk(s, clock);                        \
2516
        omap_clk_onoff(clk, (value >> bit) & 1);        \
2517
    }
2518
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
2519
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
2520
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
2521
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
2522
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
2523
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
2524
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
2525
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
2526
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
2527
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
2528
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
2529
}
2530

    
2531
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2532
                uint16_t diff, uint16_t value)
2533
{
2534
    omap_clk clk;
2535

    
2536
    if (diff & (3 << 4)) {                                /* TCLKOUT */
2537
        clk = omap_findclk(s, "tclk_out");
2538
        switch ((value >> 4) & 3) {
2539
        case 1:
2540
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
2541
            omap_clk_onoff(clk, 1);
2542
            break;
2543
        case 2:
2544
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2545
            omap_clk_onoff(clk, 1);
2546
            break;
2547
        default:
2548
            omap_clk_onoff(clk, 0);
2549
        }
2550
    }
2551
    if (diff & (3 << 2)) {                                /* DCLKOUT */
2552
        clk = omap_findclk(s, "dclk_out");
2553
        switch ((value >> 2) & 3) {
2554
        case 0:
2555
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
2556
            break;
2557
        case 1:
2558
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
2559
            break;
2560
        case 2:
2561
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
2562
            break;
2563
        case 3:
2564
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2565
            break;
2566
        }
2567
    }
2568
    if (diff & (3 << 0)) {                                /* ACLKOUT */
2569
        clk = omap_findclk(s, "aclk_out");
2570
        switch ((value >> 0) & 3) {
2571
        case 1:
2572
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2573
            omap_clk_onoff(clk, 1);
2574
            break;
2575
        case 2:
2576
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
2577
            omap_clk_onoff(clk, 1);
2578
            break;
2579
        case 3:
2580
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2581
            omap_clk_onoff(clk, 1);
2582
            break;
2583
        default:
2584
            omap_clk_onoff(clk, 0);
2585
        }
2586
    }
2587
}
2588

    
2589
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2590
                uint32_t value)
2591
{
2592
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2593
    int offset = addr - s->clkm.mpu_base;
2594
    uint16_t diff;
2595
    omap_clk clk;
2596
    static const char *clkschemename[8] = {
2597
        "fully synchronous", "fully asynchronous", "synchronous scalable",
2598
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2599
    };
2600

    
2601
    switch (offset) {
2602
    case 0x00:        /* ARM_CKCTL */
2603
        diff = s->clkm.arm_ckctl ^ value;
2604
        s->clkm.arm_ckctl = value & 0x7fff;
2605
        omap_clkm_ckctl_update(s, diff, value);
2606
        return;
2607

    
2608
    case 0x04:        /* ARM_IDLECT1 */
2609
        diff = s->clkm.arm_idlect1 ^ value;
2610
        s->clkm.arm_idlect1 = value & 0x0fff;
2611
        omap_clkm_idlect1_update(s, diff, value);
2612
        return;
2613

    
2614
    case 0x08:        /* ARM_IDLECT2 */
2615
        diff = s->clkm.arm_idlect2 ^ value;
2616
        s->clkm.arm_idlect2 = value & 0x07ff;
2617
        omap_clkm_idlect2_update(s, diff, value);
2618
        return;
2619

    
2620
    case 0x0c:        /* ARM_EWUPCT */
2621
        diff = s->clkm.arm_ewupct ^ value;
2622
        s->clkm.arm_ewupct = value & 0x003f;
2623
        return;
2624

    
2625
    case 0x10:        /* ARM_RSTCT1 */
2626
        diff = s->clkm.arm_rstct1 ^ value;
2627
        s->clkm.arm_rstct1 = value & 0x0007;
2628
        if (value & 9) {
2629
            qemu_system_reset_request();
2630
            s->clkm.cold_start = 0xa;
2631
        }
2632
        if (diff & ~value & 4) {                                /* DSP_RST */
2633
            omap_mpui_reset(s);
2634
            omap_tipb_bridge_reset(s->private_tipb);
2635
            omap_tipb_bridge_reset(s->public_tipb);
2636
        }
2637
        if (diff & 2) {                                                /* DSP_EN */
2638
            clk = omap_findclk(s, "dsp_ck");
2639
            omap_clk_canidle(clk, (~value >> 1) & 1);
2640
        }
2641
        return;
2642

    
2643
    case 0x14:        /* ARM_RSTCT2 */
2644
        s->clkm.arm_rstct2 = value & 0x0001;
2645
        return;
2646

    
2647
    case 0x18:        /* ARM_SYSST */
2648
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2649
            s->clkm.clocking_scheme = (value >> 11) & 7;
2650
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2651
                            clkschemename[s->clkm.clocking_scheme]);
2652
        }
2653
        s->clkm.cold_start &= value & 0x3f;
2654
        return;
2655

    
2656
    case 0x1c:        /* ARM_CKOUT1 */
2657
        diff = s->clkm.arm_ckout1 ^ value;
2658
        s->clkm.arm_ckout1 = value & 0x003f;
2659
        omap_clkm_ckout1_update(s, diff, value);
2660
        return;
2661

    
2662
    case 0x20:        /* ARM_CKOUT2 */
2663
    default:
2664
        OMAP_BAD_REG(addr);
2665
    }
2666
}
2667

    
2668
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2669
    omap_badwidth_read16,
2670
    omap_clkm_read,
2671
    omap_badwidth_read16,
2672
};
2673

    
2674
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2675
    omap_badwidth_write16,
2676
    omap_clkm_write,
2677
    omap_badwidth_write16,
2678
};
2679

    
2680
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2681
{
2682
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2683
    int offset = addr - s->clkm.dsp_base;
2684

    
2685
    switch (offset) {
2686
    case 0x04:        /* DSP_IDLECT1 */
2687
        return s->clkm.dsp_idlect1;
2688

    
2689
    case 0x08:        /* DSP_IDLECT2 */
2690
        return s->clkm.dsp_idlect2;
2691

    
2692
    case 0x14:        /* DSP_RSTCT2 */
2693
        return s->clkm.dsp_rstct2;
2694

    
2695
    case 0x18:        /* DSP_SYSST */
2696
        return (s->clkm.clocking_scheme < 11) | s->clkm.cold_start |
2697
                (s->env->halted << 6);        /* Quite useless... */
2698
    }
2699

    
2700
    OMAP_BAD_REG(addr);
2701
    return 0;
2702
}
2703

    
2704
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2705
                uint16_t diff, uint16_t value)
2706
{
2707
    omap_clk clk;
2708

    
2709
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2710
}
2711

    
2712
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2713
                uint16_t diff, uint16_t value)
2714
{
2715
    omap_clk clk;
2716

    
2717
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2718
}
2719

    
2720
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2721
                uint32_t value)
2722
{
2723
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2724
    int offset = addr - s->clkm.dsp_base;
2725
    uint16_t diff;
2726

    
2727
    switch (offset) {
2728
    case 0x04:        /* DSP_IDLECT1 */
2729
        diff = s->clkm.dsp_idlect1 ^ value;
2730
        s->clkm.dsp_idlect1 = value & 0x01f7;
2731
        omap_clkdsp_idlect1_update(s, diff, value);
2732
        break;
2733

    
2734
    case 0x08:        /* DSP_IDLECT2 */
2735
        s->clkm.dsp_idlect2 = value & 0x0037;
2736
        diff = s->clkm.dsp_idlect1 ^ value;
2737
        omap_clkdsp_idlect2_update(s, diff, value);
2738
        break;
2739

    
2740
    case 0x14:        /* DSP_RSTCT2 */
2741
        s->clkm.dsp_rstct2 = value & 0x0001;
2742
        break;
2743

    
2744
    case 0x18:        /* DSP_SYSST */
2745
        s->clkm.cold_start &= value & 0x3f;
2746
        break;
2747

    
2748
    default:
2749
        OMAP_BAD_REG(addr);
2750
    }
2751
}
2752

    
2753
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2754
    omap_badwidth_read16,
2755
    omap_clkdsp_read,
2756
    omap_badwidth_read16,
2757
};
2758

    
2759
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2760
    omap_badwidth_write16,
2761
    omap_clkdsp_write,
2762
    omap_badwidth_write16,
2763
};
2764

    
2765
static void omap_clkm_reset(struct omap_mpu_state_s *s)
2766
{
2767
    if (s->wdt && s->wdt->reset)
2768
        s->clkm.cold_start = 0x6;
2769
    s->clkm.clocking_scheme = 0;
2770
    omap_clkm_ckctl_update(s, ~0, 0x3000);
2771
    s->clkm.arm_ckctl = 0x3000;
2772
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 & 0x0400, 0x0400);
2773
    s->clkm.arm_idlect1 = 0x0400;
2774
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 & 0x0100, 0x0100);
2775
    s->clkm.arm_idlect2 = 0x0100;
2776
    s->clkm.arm_ewupct = 0x003f;
2777
    s->clkm.arm_rstct1 = 0x0000;
2778
    s->clkm.arm_rstct2 = 0x0000;
2779
    s->clkm.arm_ckout1 = 0x0015;
2780
    s->clkm.dpll1_mode = 0x2002;
2781
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2782
    s->clkm.dsp_idlect1 = 0x0040;
2783
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2784
    s->clkm.dsp_idlect2 = 0x0000;
2785
    s->clkm.dsp_rstct2 = 0x0000;
2786
}
2787

    
2788
static void omap_clkm_init(target_phys_addr_t mpu_base,
2789
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2790
{
2791
    int iomemtype[2] = {
2792
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2793
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2794
    };
2795

    
2796
    s->clkm.mpu_base = mpu_base;
2797
    s->clkm.dsp_base = dsp_base;
2798
    s->clkm.cold_start = 0x3a;
2799
    omap_clkm_reset(s);
2800

    
2801
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2802
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2803
}
2804

    
2805
/* MPU I/O */
2806
struct omap_mpuio_s {
2807
    target_phys_addr_t base;
2808
    qemu_irq irq;
2809
    qemu_irq kbd_irq;
2810
    qemu_irq *in;
2811
    qemu_irq handler[16];
2812
    qemu_irq wakeup;
2813

    
2814
    uint16_t inputs;
2815
    uint16_t outputs;
2816
    uint16_t dir;
2817
    uint16_t edge;
2818
    uint16_t mask;
2819
    uint16_t ints;
2820

    
2821
    uint16_t debounce;
2822
    uint16_t latch;
2823
    uint8_t event;
2824

    
2825
    uint8_t buttons[5];
2826
    uint8_t row_latch;
2827
    uint8_t cols;
2828
    int kbd_mask;
2829
    int clk;
2830
};
2831

    
2832
static void omap_mpuio_set(void *opaque, int line, int level)
2833
{
2834
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2835
    uint16_t prev = s->inputs;
2836

    
2837
    if (level)
2838
        s->inputs |= 1 << line;
2839
    else
2840
        s->inputs &= ~(1 << line);
2841

    
2842
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2843
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2844
            s->ints |= 1 << line;
2845
            qemu_irq_raise(s->irq);
2846
            /* TODO: wakeup */
2847
        }
2848
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
2849
                (s->event >> 1) == line)        /* PIN_SELECT */
2850
            s->latch = s->inputs;
2851
    }
2852
}
2853

    
2854
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2855
{
2856
    int i;
2857
    uint8_t *row, rows = 0, cols = ~s->cols;
2858

    
2859
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2860
        if (*row & cols)
2861
            rows |= i;
2862

    
2863
    qemu_set_irq(s->kbd_irq, rows && ~s->kbd_mask && s->clk);
2864
    s->row_latch = rows ^ 0x1f;
2865
}
2866

    
2867
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2868
{
2869
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2870
    int offset = addr - s->base;
2871
    uint16_t ret;
2872

    
2873
    switch (offset) {
2874
    case 0x00:        /* INPUT_LATCH */
2875
        return s->inputs;
2876

    
2877
    case 0x04:        /* OUTPUT_REG */
2878
        return s->outputs;
2879

    
2880
    case 0x08:        /* IO_CNTL */
2881
        return s->dir;
2882

    
2883
    case 0x10:        /* KBR_LATCH */
2884
        return s->row_latch;
2885

    
2886
    case 0x14:        /* KBC_REG */
2887
        return s->cols;
2888

    
2889
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2890
        return s->event;
2891

    
2892
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2893
        return s->edge;
2894

    
2895
    case 0x20:        /* KBD_INT */
2896
        return (s->row_latch != 0x1f) && !s->kbd_mask;
2897

    
2898
    case 0x24:        /* GPIO_INT */
2899
        ret = s->ints;
2900
        s->ints &= s->mask;
2901
        if (ret)
2902
            qemu_irq_lower(s->irq);
2903
        return ret;
2904

    
2905
    case 0x28:        /* KBD_MASKIT */
2906
        return s->kbd_mask;
2907

    
2908
    case 0x2c:        /* GPIO_MASKIT */
2909
        return s->mask;
2910

    
2911
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2912
        return s->debounce;
2913

    
2914
    case 0x34:        /* GPIO_LATCH_REG */
2915
        return s->latch;
2916
    }
2917

    
2918
    OMAP_BAD_REG(addr);
2919
    return 0;
2920
}
2921

    
2922
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2923
                uint32_t value)
2924
{
2925
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2926
    int offset = addr - s->base;
2927
    uint16_t diff;
2928
    int ln;
2929

    
2930
    switch (offset) {
2931
    case 0x04:        /* OUTPUT_REG */
2932
        diff = s->outputs ^ (value & ~s->dir);
2933
        s->outputs = value;
2934
        value &= ~s->dir;
2935
        while ((ln = ffs(diff))) {
2936
            ln --;
2937
            if (s->handler[ln])
2938
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2939
            diff &= ~(1 << ln);
2940
        }
2941
        break;
2942

    
2943
    case 0x08:        /* IO_CNTL */
2944
        diff = s->outputs & (s->dir ^ value);
2945
        s->dir = value;
2946

    
2947
        value = s->outputs & ~s->dir;
2948
        while ((ln = ffs(diff))) {
2949
            ln --;
2950
            if (s->handler[ln])
2951
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2952
            diff &= ~(1 << ln);
2953
        }
2954
        break;
2955

    
2956
    case 0x14:        /* KBC_REG */
2957
        s->cols = value;
2958
        omap_mpuio_kbd_update(s);
2959
        break;
2960

    
2961
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2962
        s->event = value & 0x1f;
2963
        break;
2964

    
2965
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2966
        s->edge = value;
2967
        break;
2968

    
2969
    case 0x28:        /* KBD_MASKIT */
2970
        s->kbd_mask = value & 1;
2971
        omap_mpuio_kbd_update(s);
2972
        break;
2973

    
2974
    case 0x2c:        /* GPIO_MASKIT */
2975
        s->mask = value;
2976
        break;
2977

    
2978
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2979
        s->debounce = value & 0x1ff;
2980
        break;
2981

    
2982
    case 0x00:        /* INPUT_LATCH */
2983
    case 0x10:        /* KBR_LATCH */
2984
    case 0x20:        /* KBD_INT */
2985
    case 0x24:        /* GPIO_INT */
2986
    case 0x34:        /* GPIO_LATCH_REG */
2987
        OMAP_RO_REG(addr);
2988
        return;
2989

    
2990
    default:
2991
        OMAP_BAD_REG(addr);
2992
        return;
2993
    }
2994
}
2995

    
2996
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
2997
    omap_badwidth_read16,
2998
    omap_mpuio_read,
2999
    omap_badwidth_read16,
3000
};
3001

    
3002
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
3003
    omap_badwidth_write16,
3004
    omap_mpuio_write,
3005
    omap_badwidth_write16,
3006
};
3007

    
3008
void omap_mpuio_reset(struct omap_mpuio_s *s)
3009
{
3010
    s->inputs = 0;
3011
    s->outputs = 0;
3012
    s->dir = ~0;
3013
    s->event = 0;
3014
    s->edge = 0;
3015
    s->kbd_mask = 0;
3016
    s->mask = 0;
3017
    s->debounce = 0;
3018
    s->latch = 0;
3019
    s->ints = 0;
3020
    s->row_latch = 0x1f;
3021
    s->clk = 1;
3022
}
3023

    
3024
static void omap_mpuio_onoff(void *opaque, int line, int on)
3025
{
3026
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3027

    
3028
    s->clk = on;
3029
    if (on)
3030
        omap_mpuio_kbd_update(s);
3031
}
3032

    
3033
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
3034
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
3035
                omap_clk clk)
3036
{
3037
    int iomemtype;
3038
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
3039
            qemu_mallocz(sizeof(struct omap_mpuio_s));
3040

    
3041
    s->base = base;
3042
    s->irq = gpio_int;
3043
    s->kbd_irq = kbd_int;
3044
    s->wakeup = wakeup;
3045
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
3046
    omap_mpuio_reset(s);
3047

    
3048
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
3049
                    omap_mpuio_writefn, s);
3050
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3051

    
3052
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
3053

    
3054
    return s;
3055
}
3056

    
3057
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
3058
{
3059
    return s->in;
3060
}
3061

    
3062
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
3063
{
3064
    if (line >= 16 || line < 0)
3065
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3066
    s->handler[line] = handler;
3067
}
3068

    
3069
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
3070
{
3071
    if (row >= 5 || row < 0)
3072
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
3073
                        __FUNCTION__, col, row);
3074

    
3075
    if (down)
3076
        s->buttons[row] |= 1 << col;
3077
    else
3078
        s->buttons[row] &= ~(1 << col);
3079

    
3080
    omap_mpuio_kbd_update(s);
3081
}
3082

    
3083
/* General-Purpose I/O */
3084
struct omap_gpio_s {
3085
    target_phys_addr_t base;
3086
    qemu_irq irq;
3087
    qemu_irq *in;
3088
    qemu_irq handler[16];
3089

    
3090
    uint16_t inputs;
3091
    uint16_t outputs;
3092
    uint16_t dir;
3093
    uint16_t edge;
3094
    uint16_t mask;
3095
    uint16_t ints;
3096
};
3097

    
3098
static void omap_gpio_set(void *opaque, int line, int level)
3099
{
3100
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3101
    uint16_t prev = s->inputs;
3102

    
3103
    if (level)
3104
        s->inputs |= 1 << line;
3105
    else
3106
        s->inputs &= ~(1 << line);
3107

    
3108
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
3109
                    (1 << line) & s->dir & ~s->mask) {
3110
        s->ints |= 1 << line;
3111
        qemu_irq_raise(s->irq);
3112
    }
3113
}
3114

    
3115
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
3116
{
3117
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3118
    int offset = addr - s->base;
3119

    
3120
    switch (offset) {
3121
    case 0x00:        /* DATA_INPUT */
3122
        return s->inputs;
3123

    
3124
    case 0x04:        /* DATA_OUTPUT */
3125
        return s->outputs;
3126

    
3127
    case 0x08:        /* DIRECTION_CONTROL */
3128
        return s->dir;
3129

    
3130
    case 0x0c:        /* INTERRUPT_CONTROL */
3131
        return s->edge;
3132

    
3133
    case 0x10:        /* INTERRUPT_MASK */
3134
        return s->mask;
3135

    
3136
    case 0x14:        /* INTERRUPT_STATUS */
3137
        return s->ints;
3138
    }
3139

    
3140
    OMAP_BAD_REG(addr);
3141
    return 0;
3142
}
3143

    
3144
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
3145
                uint32_t value)
3146
{
3147
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3148
    int offset = addr - s->base;
3149
    uint16_t diff;
3150
    int ln;
3151

    
3152
    switch (offset) {
3153
    case 0x00:        /* DATA_INPUT */
3154
        OMAP_RO_REG(addr);
3155
        return;
3156

    
3157
    case 0x04:        /* DATA_OUTPUT */
3158
        diff = (s->outputs ^ value) & ~s->dir;
3159
        s->outputs = value;
3160
        while ((ln = ffs(diff))) {
3161
            ln --;
3162
            if (s->handler[ln])
3163
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3164
            diff &= ~(1 << ln);
3165
        }
3166
        break;
3167

    
3168
    case 0x08:        /* DIRECTION_CONTROL */
3169
        diff = s->outputs & (s->dir ^ value);
3170
        s->dir = value;
3171

    
3172
        value = s->outputs & ~s->dir;
3173
        while ((ln = ffs(diff))) {
3174
            ln --;
3175
            if (s->handler[ln])
3176
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3177
            diff &= ~(1 << ln);
3178
        }
3179
        break;
3180

    
3181
    case 0x0c:        /* INTERRUPT_CONTROL */
3182
        s->edge = value;
3183
        break;
3184

    
3185
    case 0x10:        /* INTERRUPT_MASK */
3186
        s->mask = value;
3187
        break;
3188

    
3189
    case 0x14:        /* INTERRUPT_STATUS */
3190
        s->ints &= ~value;
3191
        if (!s->ints)
3192
            qemu_irq_lower(s->irq);
3193
        break;
3194

    
3195
    default:
3196
        OMAP_BAD_REG(addr);
3197
        return;
3198
    }
3199
}
3200

    
3201
/* *Some* sources say the memory region is 32-bit.  */
3202
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
3203
    omap_badwidth_read16,
3204
    omap_gpio_read,
3205
    omap_badwidth_read16,
3206
};
3207

    
3208
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
3209
    omap_badwidth_write16,
3210
    omap_gpio_write,
3211
    omap_badwidth_write16,
3212
};
3213

    
3214
void omap_gpio_reset(struct omap_gpio_s *s)
3215
{
3216
    s->inputs = 0;
3217
    s->outputs = ~0;
3218
    s->dir = ~0;
3219
    s->edge = ~0;
3220
    s->mask = ~0;
3221
    s->ints = 0;
3222
}
3223

    
3224
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
3225
                qemu_irq irq, omap_clk clk)
3226
{
3227
    int iomemtype;
3228
    struct omap_gpio_s *s = (struct omap_gpio_s *)
3229
            qemu_mallocz(sizeof(struct omap_gpio_s));
3230

    
3231
    s->base = base;
3232
    s->irq = irq;
3233
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
3234
    omap_gpio_reset(s);
3235

    
3236
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
3237
                    omap_gpio_writefn, s);
3238
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3239

    
3240
    return s;
3241
}
3242

    
3243
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
3244
{
3245
    return s->in;
3246
}
3247

    
3248
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3249
{
3250
    if (line >= 16 || line < 0)
3251
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3252
    s->handler[line] = handler;
3253
}
3254

    
3255
/* MicroWire Interface */
3256
struct omap_uwire_s {
3257
    target_phys_addr_t base;
3258
    qemu_irq txirq;
3259
    qemu_irq rxirq;
3260
    qemu_irq txdrq;
3261

    
3262
    uint16_t txbuf;
3263
    uint16_t rxbuf;
3264
    uint16_t control;
3265
    uint16_t setup[5];
3266

    
3267
    struct uwire_slave_s *chip[4];
3268
};
3269

    
3270
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3271
{
3272
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3273
    struct uwire_slave_s *slave = s->chip[chipselect];
3274

    
3275
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
3276
        if (s->control & (1 << 12))                        /* CS_CMD */
3277
            if (slave && slave->send)
3278
                slave->send(slave->opaque,
3279
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3280
        s->control &= ~(1 << 14);                        /* CSRB */
3281
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3282
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3283
    }
3284

    
3285
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
3286
        if (s->control & (1 << 12))                        /* CS_CMD */
3287
            if (slave && slave->receive)
3288
                s->rxbuf = slave->receive(slave->opaque);
3289
        s->control |= 1 << 15;                                /* RDRB */
3290
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3291
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3292
    }
3293
}
3294

    
3295
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3296
{
3297
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3298
    int offset = addr - s->base;
3299

    
3300
    switch (offset) {
3301
    case 0x00:        /* RDR */
3302
        s->control &= ~(1 << 15);                        /* RDRB */
3303
        return s->rxbuf;
3304

    
3305
    case 0x04:        /* CSR */
3306
        return s->control;
3307

    
3308
    case 0x08:        /* SR1 */
3309
        return s->setup[0];
3310
    case 0x0c:        /* SR2 */
3311
        return s->setup[1];
3312
    case 0x10:        /* SR3 */
3313
        return s->setup[2];
3314
    case 0x14:        /* SR4 */
3315
        return s->setup[3];
3316
    case 0x18:        /* SR5 */
3317
        return s->setup[4];
3318
    }
3319

    
3320
    OMAP_BAD_REG(addr);
3321
    return 0;
3322
}
3323

    
3324
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3325
                uint32_t value)
3326
{
3327
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3328
    int offset = addr - s->base;
3329

    
3330
    switch (offset) {
3331
    case 0x00:        /* TDR */
3332
        s->txbuf = value;                                /* TD */
3333
        s->control |= 1 << 14;                                /* CSRB */
3334
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3335
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3336
                         (s->control & (1 << 12))))        /* CS_CMD */
3337
            omap_uwire_transfer_start(s);
3338
        break;
3339

    
3340
    case 0x04:        /* CSR */
3341
        s->control = value & 0x1fff;
3342
        if (value & (1 << 13))                                /* START */
3343
            omap_uwire_transfer_start(s);
3344
        break;
3345

    
3346
    case 0x08:        /* SR1 */
3347
        s->setup[0] = value & 0x003f;
3348
        break;
3349

    
3350
    case 0x0c:        /* SR2 */
3351
        s->setup[1] = value & 0x0fc0;
3352
        break;
3353

    
3354
    case 0x10:        /* SR3 */
3355
        s->setup[2] = value & 0x0003;
3356
        break;
3357

    
3358
    case 0x14:        /* SR4 */
3359
        s->setup[3] = value & 0x0001;
3360
        break;
3361

    
3362
    case 0x18:        /* SR5 */
3363
        s->setup[4] = value & 0x000f;
3364
        break;
3365

    
3366
    default:
3367
        OMAP_BAD_REG(addr);
3368
        return;
3369
    }
3370
}
3371

    
3372
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3373
    omap_badwidth_read16,
3374
    omap_uwire_read,
3375
    omap_badwidth_read16,
3376
};
3377

    
3378
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3379
    omap_badwidth_write16,
3380
    omap_uwire_write,
3381
    omap_badwidth_write16,
3382
};
3383

    
3384
void omap_uwire_reset(struct omap_uwire_s *s)
3385
{
3386
    s->control = 0;
3387
    s->setup[0] = 0;
3388
    s->setup[1] = 0;
3389
    s->setup[2] = 0;
3390
    s->setup[3] = 0;
3391
    s->setup[4] = 0;
3392
}
3393

    
3394
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3395
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3396
{
3397
    int iomemtype;
3398
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3399
            qemu_mallocz(sizeof(struct omap_uwire_s));
3400

    
3401
    s->base = base;
3402
    s->txirq = irq[0];
3403
    s->rxirq = irq[1];
3404
    s->txdrq = dma;
3405
    omap_uwire_reset(s);
3406

    
3407
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3408
                    omap_uwire_writefn, s);
3409
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3410

    
3411
    return s;
3412
}
3413

    
3414
void omap_uwire_attach(struct omap_uwire_s *s,
3415
                struct uwire_slave_s *slave, int chipselect)
3416
{
3417
    if (chipselect < 0 || chipselect > 3)
3418
        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
3419
                        chipselect);
3420

    
3421
    s->chip[chipselect] = slave;
3422
}
3423

    
3424
/* Pseudonoise Pulse-Width Light Modulator */
3425
void omap_pwl_update(struct omap_mpu_state_s *s)
3426
{
3427
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3428

    
3429
    if (output != s->pwl.output) {
3430
        s->pwl.output = output;
3431
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3432
    }
3433
}
3434

    
3435
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3436
{
3437
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3438
    int offset = addr - s->pwl.base;
3439

    
3440
    switch (offset) {
3441
    case 0x00:        /* PWL_LEVEL */
3442
        return s->pwl.level;
3443
    case 0x04:        /* PWL_CTRL */
3444
        return s->pwl.enable;
3445
    }
3446
    OMAP_BAD_REG(addr);
3447
    return 0;
3448
}
3449

    
3450
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3451
                uint32_t value)
3452
{
3453
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3454
    int offset = addr - s->pwl.base;
3455

    
3456
    switch (offset) {
3457
    case 0x00:        /* PWL_LEVEL */
3458
        s->pwl.level = value;
3459
        omap_pwl_update(s);
3460
        break;
3461
    case 0x04:        /* PWL_CTRL */
3462
        s->pwl.enable = value & 1;
3463
        omap_pwl_update(s);
3464
        break;
3465
    default:
3466
        OMAP_BAD_REG(addr);
3467
        return;
3468
    }
3469
}
3470

    
3471
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3472
    omap_pwl_read,
3473
    omap_badwidth_read8,
3474
    omap_badwidth_read8,
3475
};
3476

    
3477
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3478
    omap_pwl_write,
3479
    omap_badwidth_write8,
3480
    omap_badwidth_write8,
3481
};
3482

    
3483
void omap_pwl_reset(struct omap_mpu_state_s *s)
3484
{
3485
    s->pwl.output = 0;
3486
    s->pwl.level = 0;
3487
    s->pwl.enable = 0;
3488
    s->pwl.clk = 1;
3489
    omap_pwl_update(s);
3490
}
3491

    
3492
static void omap_pwl_clk_update(void *opaque, int line, int on)
3493
{
3494
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3495

    
3496
    s->pwl.clk = on;
3497
    omap_pwl_update(s);
3498
}
3499

    
3500
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3501
                omap_clk clk)
3502
{
3503
    int iomemtype;
3504

    
3505
    s->pwl.base = base;
3506
    omap_pwl_reset(s);
3507

    
3508
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3509
                    omap_pwl_writefn, s);
3510
    cpu_register_physical_memory(s->pwl.base, 0x800, iomemtype);
3511

    
3512
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3513
}
3514

    
3515
/* Pulse-Width Tone module */
3516
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3517
{
3518
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3519
    int offset = addr - s->pwt.base;
3520

    
3521
    switch (offset) {
3522
    case 0x00:        /* FRC */
3523
        return s->pwt.frc;
3524
    case 0x04:        /* VCR */
3525
        return s->pwt.vrc;
3526
    case 0x08:        /* GCR */
3527
        return s->pwt.gcr;
3528
    }
3529
    OMAP_BAD_REG(addr);
3530
    return 0;
3531
}
3532

    
3533
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3534
                uint32_t value)
3535
{
3536
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3537
    int offset = addr - s->pwt.base;
3538

    
3539
    switch (offset) {
3540
    case 0x00:        /* FRC */
3541
        s->pwt.frc = value & 0x3f;
3542
        break;
3543
    case 0x04:        /* VRC */
3544
        if ((value ^ s->pwt.vrc) & 1) {
3545
            if (value & 1)
3546
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
3547
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
3548
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
3549
                                 /* Pre-multiplexer divider */
3550
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
3551
                                 /* Octave multiplexer */
3552
                                 (2 << (value & 3)) *
3553
                                 /* 101/107 divider */
3554
                                 ((value & (1 << 2)) ? 101 : 107) *
3555
                                 /*  49/55 divider */
3556
                                 ((value & (1 << 3)) ?  49 : 55) *
3557
                                 /*  50/63 divider */
3558
                                 ((value & (1 << 4)) ?  50 : 63) *
3559
                                 /*  80/127 divider */
3560
                                 ((value & (1 << 5)) ?  80 : 127) /
3561
                                 (107 * 55 * 63 * 127)));
3562
            else
3563
                printf("%s: silence!\n", __FUNCTION__);
3564
        }
3565
        s->pwt.vrc = value & 0x7f;
3566
        break;
3567
    case 0x08:        /* GCR */
3568
        s->pwt.gcr = value & 3;
3569
        break;
3570
    default:
3571
        OMAP_BAD_REG(addr);
3572
        return;
3573
    }
3574
}
3575

    
3576
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3577
    omap_pwt_read,
3578
    omap_badwidth_read8,
3579
    omap_badwidth_read8,
3580
};
3581

    
3582
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3583
    omap_pwt_write,
3584
    omap_badwidth_write8,
3585
    omap_badwidth_write8,
3586
};
3587

    
3588
void omap_pwt_reset(struct omap_mpu_state_s *s)
3589
{
3590
    s->pwt.frc = 0;
3591
    s->pwt.vrc = 0;
3592
    s->pwt.gcr = 0;
3593
}
3594

    
3595
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3596
                omap_clk clk)
3597
{
3598
    int iomemtype;
3599

    
3600
    s->pwt.base = base;
3601
    s->pwt.clk = clk;
3602
    omap_pwt_reset(s);
3603

    
3604
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3605
                    omap_pwt_writefn, s);
3606
    cpu_register_physical_memory(s->pwt.base, 0x800, iomemtype);
3607
}
3608

    
3609
/* Real-time Clock module */
3610
struct omap_rtc_s {
3611
    target_phys_addr_t base;
3612
    qemu_irq irq;
3613
    qemu_irq alarm;
3614
    QEMUTimer *clk;
3615

    
3616
    uint8_t interrupts;
3617
    uint8_t status;
3618
    int16_t comp_reg;
3619
    int running;
3620
    int pm_am;
3621
    int auto_comp;
3622
    int round;
3623
    struct tm *(*convert)(const time_t *timep, struct tm *result);
3624
    struct tm alarm_tm;
3625
    time_t alarm_ti;
3626

    
3627
    struct tm current_tm;
3628
    time_t ti;
3629
    uint64_t tick;
3630
};
3631

    
3632
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3633
{
3634
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3635
}
3636

    
3637
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3638
{
3639
    s->alarm_ti = mktime(&s->alarm_tm);
3640
    if (s->alarm_ti == -1)
3641
        printf("%s: conversion failed\n", __FUNCTION__);
3642
}
3643

    
3644
static inline uint8_t omap_rtc_bcd(int num)
3645
{
3646
    return ((num / 10) << 4) | (num % 10);
3647
}
3648

    
3649
static inline int omap_rtc_bin(uint8_t num)
3650
{
3651
    return (num & 15) + 10 * (num >> 4);
3652
}
3653

    
3654
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3655
{
3656
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3657
    int offset = addr - s->base;
3658
    uint8_t i;
3659

    
3660
    switch (offset) {
3661
    case 0x00:        /* SECONDS_REG */
3662
        return omap_rtc_bcd(s->current_tm.tm_sec);
3663

    
3664
    case 0x04:        /* MINUTES_REG */
3665
        return omap_rtc_bcd(s->current_tm.tm_min);
3666

    
3667
    case 0x08:        /* HOURS_REG */
3668
        if (s->pm_am)
3669
            return ((s->current_tm.tm_hour > 11) << 7) |
3670
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3671
        else
3672
            return omap_rtc_bcd(s->current_tm.tm_hour);
3673

    
3674
    case 0x0c:        /* DAYS_REG */
3675
        return omap_rtc_bcd(s->current_tm.tm_mday);
3676

    
3677
    case 0x10:        /* MONTHS_REG */
3678
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3679

    
3680
    case 0x14:        /* YEARS_REG */
3681
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3682

    
3683
    case 0x18:        /* WEEK_REG */
3684
        return s->current_tm.tm_wday;
3685

    
3686
    case 0x20:        /* ALARM_SECONDS_REG */
3687
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3688

    
3689
    case 0x24:        /* ALARM_MINUTES_REG */
3690
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3691

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

    
3699
    case 0x2c:        /* ALARM_DAYS_REG */
3700
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3701

    
3702
    case 0x30:        /* ALARM_MONTHS_REG */
3703
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3704

    
3705
    case 0x34:        /* ALARM_YEARS_REG */
3706
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3707

    
3708
    case 0x40:        /* RTC_CTRL_REG */
3709
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3710
                (s->round << 1) | s->running;
3711

    
3712
    case 0x44:        /* RTC_STATUS_REG */
3713
        i = s->status;
3714
        s->status &= ~0x3d;
3715
        return i;
3716

    
3717
    case 0x48:        /* RTC_INTERRUPTS_REG */
3718
        return s->interrupts;
3719

    
3720
    case 0x4c:        /* RTC_COMP_LSB_REG */
3721
        return ((uint16_t) s->comp_reg) & 0xff;
3722

    
3723
    case 0x50:        /* RTC_COMP_MSB_REG */
3724
        return ((uint16_t) s->comp_reg) >> 8;
3725
    }
3726

    
3727
    OMAP_BAD_REG(addr);
3728
    return 0;
3729
}
3730

    
3731
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3732
                uint32_t value)
3733
{
3734
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3735
    int offset = addr - s->base;
3736
    struct tm new_tm;
3737
    time_t ti[2];
3738

    
3739
    switch (offset) {
3740
    case 0x00:        /* SECONDS_REG */
3741
#if ALMDEBUG
3742
        printf("RTC SEC_REG <-- %02x\n", value);
3743
#endif
3744
        s->ti -= s->current_tm.tm_sec;
3745
        s->ti += omap_rtc_bin(value);
3746
        return;
3747

    
3748
    case 0x04:        /* MINUTES_REG */
3749
#if ALMDEBUG
3750
        printf("RTC MIN_REG <-- %02x\n", value);
3751
#endif
3752
        s->ti -= s->current_tm.tm_min * 60;
3753
        s->ti += omap_rtc_bin(value) * 60;
3754
        return;
3755

    
3756
    case 0x08:        /* HOURS_REG */
3757
#if ALMDEBUG
3758
        printf("RTC HRS_REG <-- %02x\n", value);
3759
#endif
3760
        s->ti -= s->current_tm.tm_hour * 3600;
3761
        if (s->pm_am) {
3762
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3763
            s->ti += ((value >> 7) & 1) * 43200;
3764
        } else
3765
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3766
        return;
3767

    
3768
    case 0x0c:        /* DAYS_REG */
3769
#if ALMDEBUG
3770
        printf("RTC DAY_REG <-- %02x\n", value);
3771
#endif
3772
        s->ti -= s->current_tm.tm_mday * 86400;
3773
        s->ti += omap_rtc_bin(value) * 86400;
3774
        return;
3775

    
3776
    case 0x10:        /* MONTHS_REG */
3777
#if ALMDEBUG
3778
        printf("RTC MTH_REG <-- %02x\n", value);
3779
#endif
3780
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3781
        new_tm.tm_mon = omap_rtc_bin(value);
3782
        ti[0] = mktime(&s->current_tm);
3783
        ti[1] = mktime(&new_tm);
3784

    
3785
        if (ti[0] != -1 && ti[1] != -1) {
3786
            s->ti -= ti[0];
3787
            s->ti += ti[1];
3788
        } else {
3789
            /* A less accurate version */
3790
            s->ti -= s->current_tm.tm_mon * 2592000;
3791
            s->ti += omap_rtc_bin(value) * 2592000;
3792
        }
3793
        return;
3794

    
3795
    case 0x14:        /* YEARS_REG */
3796
#if ALMDEBUG
3797
        printf("RTC YRS_REG <-- %02x\n", value);
3798
#endif
3799
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3800
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3801
        ti[0] = mktime(&s->current_tm);
3802
        ti[1] = mktime(&new_tm);
3803

    
3804
        if (ti[0] != -1 && ti[1] != -1) {
3805
            s->ti -= ti[0];
3806
            s->ti += ti[1];
3807
        } else {
3808
            /* A less accurate version */
3809
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3810
            s->ti += omap_rtc_bin(value) * 31536000;
3811
        }
3812
        return;
3813

    
3814
    case 0x18:        /* WEEK_REG */
3815
        return;        /* Ignored */
3816

    
3817
    case 0x20:        /* ALARM_SECONDS_REG */
3818
#if ALMDEBUG
3819
        printf("ALM SEC_REG <-- %02x\n", value);
3820
#endif
3821
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3822
        omap_rtc_alarm_update(s);
3823
        return;
3824

    
3825
    case 0x24:        /* ALARM_MINUTES_REG */
3826
#if ALMDEBUG
3827
        printf("ALM MIN_REG <-- %02x\n", value);
3828
#endif
3829
        s->alarm_tm.tm_min = omap_rtc_bin(value);
3830
        omap_rtc_alarm_update(s);
3831
        return;
3832

    
3833
    case 0x28:        /* ALARM_HOURS_REG */
3834
#if ALMDEBUG
3835
        printf("ALM HRS_REG <-- %02x\n", value);
3836
#endif
3837
        if (s->pm_am)
3838
            s->alarm_tm.tm_hour =
3839
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
3840
                    ((value >> 7) & 1) * 12;
3841
        else
3842
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
3843
        omap_rtc_alarm_update(s);
3844
        return;
3845

    
3846
    case 0x2c:        /* ALARM_DAYS_REG */
3847
#if ALMDEBUG
3848
        printf("ALM DAY_REG <-- %02x\n", value);
3849
#endif
3850
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3851
        omap_rtc_alarm_update(s);
3852
        return;
3853

    
3854
    case 0x30:        /* ALARM_MONTHS_REG */
3855
#if ALMDEBUG
3856
        printf("ALM MON_REG <-- %02x\n", value);
3857
#endif
3858
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3859
        omap_rtc_alarm_update(s);
3860
        return;
3861

    
3862
    case 0x34:        /* ALARM_YEARS_REG */
3863
#if ALMDEBUG
3864
        printf("ALM YRS_REG <-- %02x\n", value);
3865
#endif
3866
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3867
        omap_rtc_alarm_update(s);
3868
        return;
3869

    
3870
    case 0x40:        /* RTC_CTRL_REG */
3871
#if ALMDEBUG
3872
        printf("RTC CONTROL <-- %02x\n", value);
3873
#endif
3874
        s->pm_am = (value >> 3) & 1;
3875
        s->auto_comp = (value >> 2) & 1;
3876
        s->round = (value >> 1) & 1;
3877
        s->running = value & 1;
3878
        s->status &= 0xfd;
3879
        s->status |= s->running << 1;
3880
        return;
3881

    
3882
    case 0x44:        /* RTC_STATUS_REG */
3883
#if ALMDEBUG
3884
        printf("RTC STATUSL <-- %02x\n", value);
3885
#endif
3886
        s->status &= ~((value & 0xc0) ^ 0x80);
3887
        omap_rtc_interrupts_update(s);
3888
        return;
3889

    
3890
    case 0x48:        /* RTC_INTERRUPTS_REG */
3891
#if ALMDEBUG
3892
        printf("RTC INTRS <-- %02x\n", value);
3893
#endif
3894
        s->interrupts = value;
3895
        return;
3896

    
3897
    case 0x4c:        /* RTC_COMP_LSB_REG */
3898
#if ALMDEBUG
3899
        printf("RTC COMPLSB <-- %02x\n", value);
3900
#endif
3901
        s->comp_reg &= 0xff00;
3902
        s->comp_reg |= 0x00ff & value;
3903
        return;
3904

    
3905
    case 0x50:        /* RTC_COMP_MSB_REG */
3906
#if ALMDEBUG
3907
        printf("RTC COMPMSB <-- %02x\n", value);
3908
#endif
3909
        s->comp_reg &= 0x00ff;
3910
        s->comp_reg |= 0xff00 & (value << 8);
3911
        return;
3912

    
3913
    default:
3914
        OMAP_BAD_REG(addr);
3915
        return;
3916
    }
3917
}
3918

    
3919
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3920
    omap_rtc_read,
3921
    omap_badwidth_read8,
3922
    omap_badwidth_read8,
3923
};
3924

    
3925
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3926
    omap_rtc_write,
3927
    omap_badwidth_write8,
3928
    omap_badwidth_write8,
3929
};
3930

    
3931
static void omap_rtc_tick(void *opaque)
3932
{
3933
    struct omap_rtc_s *s = opaque;
3934

    
3935
    if (s->round) {
3936
        /* Round to nearest full minute.  */
3937
        if (s->current_tm.tm_sec < 30)
3938
            s->ti -= s->current_tm.tm_sec;
3939
        else
3940
            s->ti += 60 - s->current_tm.tm_sec;
3941

    
3942
        s->round = 0;
3943
    }
3944

    
3945
    localtime_r(&s->ti, &s->current_tm);
3946

    
3947
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3948
        s->status |= 0x40;
3949
        omap_rtc_interrupts_update(s);
3950
    }
3951

    
3952
    if (s->interrupts & 0x04)
3953
        switch (s->interrupts & 3) {
3954
        case 0:
3955
            s->status |= 0x04;
3956
            qemu_irq_raise(s->irq);
3957
            break;
3958
        case 1:
3959
            if (s->current_tm.tm_sec)
3960
                break;
3961
            s->status |= 0x08;
3962
            qemu_irq_raise(s->irq);
3963
            break;
3964
        case 2:
3965
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
3966
                break;
3967
            s->status |= 0x10;
3968
            qemu_irq_raise(s->irq);
3969
            break;
3970
        case 3:
3971
            if (s->current_tm.tm_sec ||
3972
                            s->current_tm.tm_min || s->current_tm.tm_hour)
3973
                break;
3974
            s->status |= 0x20;
3975
            qemu_irq_raise(s->irq);
3976
            break;
3977
        }
3978

    
3979
    /* Move on */
3980
    if (s->running)
3981
        s->ti ++;
3982
    s->tick += 1000;
3983

    
3984
    /*
3985
     * Every full hour add a rough approximation of the compensation
3986
     * register to the 32kHz Timer (which drives the RTC) value. 
3987
     */
3988
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
3989
        s->tick += s->comp_reg * 1000 / 32768;
3990

    
3991
    qemu_mod_timer(s->clk, s->tick);
3992
}
3993

    
3994
void omap_rtc_reset(struct omap_rtc_s *s)
3995
{
3996
    s->interrupts = 0;
3997
    s->comp_reg = 0;
3998
    s->running = 0;
3999
    s->pm_am = 0;
4000
    s->auto_comp = 0;
4001
    s->round = 0;
4002
    s->tick = qemu_get_clock(rt_clock);
4003
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
4004
    s->alarm_tm.tm_mday = 0x01;
4005
    s->status = 1 << 7;
4006
    time(&s->ti);
4007
    s->ti = mktime(s->convert(&s->ti, &s->current_tm));
4008

    
4009
    omap_rtc_alarm_update(s);
4010
    omap_rtc_tick(s);
4011
}
4012

    
4013
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
4014
                qemu_irq *irq, omap_clk clk)
4015
{
4016
    int iomemtype;
4017
    struct omap_rtc_s *s = (struct omap_rtc_s *)
4018
            qemu_mallocz(sizeof(struct omap_rtc_s));
4019

    
4020
    s->base = base;
4021
    s->irq = irq[0];
4022
    s->alarm = irq[1];
4023
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
4024
    s->convert = rtc_utc ? gmtime_r : localtime_r;
4025

    
4026
    omap_rtc_reset(s);
4027

    
4028
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
4029
                    omap_rtc_writefn, s);
4030
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4031

    
4032
    return s;
4033
}
4034

    
4035
/* General chip reset */
4036
static void omap_mpu_reset(void *opaque)
4037
{
4038
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4039

    
4040
    omap_clkm_reset(mpu);
4041
    omap_inth_reset(mpu->ih[0]);
4042
    omap_inth_reset(mpu->ih[1]);
4043
    omap_dma_reset(mpu->dma);
4044
    omap_mpu_timer_reset(mpu->timer[0]);
4045
    omap_mpu_timer_reset(mpu->timer[1]);
4046
    omap_mpu_timer_reset(mpu->timer[2]);
4047
    omap_wd_timer_reset(mpu->wdt);
4048
    omap_os_timer_reset(mpu->os_timer);
4049
    omap_lcdc_reset(mpu->lcd);
4050
    omap_ulpd_pm_reset(mpu);
4051
    omap_pin_cfg_reset(mpu);
4052
    omap_mpui_reset(mpu);
4053
    omap_tipb_bridge_reset(mpu->private_tipb);
4054
    omap_tipb_bridge_reset(mpu->public_tipb);
4055
    omap_dpll_reset(&mpu->dpll[0]);
4056
    omap_dpll_reset(&mpu->dpll[1]);
4057
    omap_dpll_reset(&mpu->dpll[2]);
4058
    omap_uart_reset(mpu->uart[0]);
4059
    omap_uart_reset(mpu->uart[1]);
4060
    omap_uart_reset(mpu->uart[2]);
4061
    omap_mmc_reset(mpu->mmc);
4062
    omap_mpuio_reset(mpu->mpuio);
4063
    omap_gpio_reset(mpu->gpio);
4064
    omap_uwire_reset(mpu->microwire);
4065
    omap_pwl_reset(mpu);
4066
    omap_pwt_reset(mpu);
4067
    omap_i2c_reset(mpu->i2c);
4068
    omap_rtc_reset(mpu->rtc);
4069
    cpu_reset(mpu->env);
4070
}
4071

    
4072
static void omap_mpu_wakeup(void *opaque, int irq, int req)
4073
{
4074
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4075

    
4076
    if (mpu->env->halted)
4077
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4078
}
4079

    
4080
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4081
                DisplayState *ds, const char *core)
4082
{
4083
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4084
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4085
    ram_addr_t imif_base, emiff_base;
4086

    
4087
    /* Core */
4088
    s->mpu_model = omap310;
4089
    s->env = cpu_init();
4090
    s->sdram_size = sdram_size;
4091
    s->sram_size = OMAP15XX_SRAM_SIZE;
4092

    
4093
    cpu_arm_set_model(s->env, core ?: "ti925t");
4094

    
4095
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4096

    
4097
    /* Clocks */
4098
    omap_clk_init(s);
4099

    
4100
    /* Memory-mapped stuff */
4101
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4102
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4103
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4104
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4105

    
4106
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4107

    
4108
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100,
4109
                    arm_pic_init_cpu(s->env),
4110
                    omap_findclk(s, "arminth_ck"));
4111
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800,
4112
                    &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ],
4113
                    omap_findclk(s, "arminth_ck"));
4114
    s->irq[0] = s->ih[0]->pins;
4115
    s->irq[1] = s->ih[1]->pins;
4116

    
4117
    s->dma = omap_dma_init(0xfffed800, s->irq[0], s,
4118
                    omap_findclk(s, "dma_ck"));
4119
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4120
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4121
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4122
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4123
    s->port[local    ].addr_valid = omap_validate_local_addr;
4124
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4125

    
4126
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4127
                    s->irq[0][OMAP_INT_TIMER1],
4128
                    omap_findclk(s, "mputim_ck"));
4129
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4130
                    s->irq[0][OMAP_INT_TIMER2],
4131
                    omap_findclk(s, "mputim_ck"));
4132
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4133
                    s->irq[0][OMAP_INT_TIMER3],
4134
                    omap_findclk(s, "mputim_ck"));
4135

    
4136
    s->wdt = omap_wd_timer_init(0xfffec800,
4137
                    s->irq[0][OMAP_INT_WD_TIMER],
4138
                    omap_findclk(s, "armwdt_ck"));
4139

    
4140
    s->os_timer = omap_os_timer_init(0xfffb9000,
4141
                    s->irq[1][OMAP_INT_OS_TIMER],
4142
                    omap_findclk(s, "clk32-kHz"));
4143

    
4144
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4145
                    &s->dma->lcd_ch, ds, imif_base, emiff_base,
4146
                    omap_findclk(s, "lcd_ck"));
4147

    
4148
    omap_ulpd_pm_init(0xfffe0800, s);
4149
    omap_pin_cfg_init(0xfffe1000, s);
4150
    omap_id_init(s);
4151

    
4152
    omap_mpui_init(0xfffec900, s);
4153

    
4154
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4155
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4156
                    omap_findclk(s, "tipb_ck"));
4157
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4158
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4159
                    omap_findclk(s, "tipb_ck"));
4160

    
4161
    omap_tcmi_init(0xfffecc00, s);
4162

    
4163
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4164
                    omap_findclk(s, "uart1_ck"),
4165
                    serial_hds[0]);
4166
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4167
                    omap_findclk(s, "uart2_ck"),
4168
                    serial_hds[0] ? serial_hds[1] : 0);
4169
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4170
                    omap_findclk(s, "uart3_ck"),
4171
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4172

    
4173
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4174
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4175
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4176

    
4177
    s->mmc = omap_mmc_init(0xfffb7800, s->irq[1][OMAP_INT_OQN],
4178
                    &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
4179

    
4180
    s->mpuio = omap_mpuio_init(0xfffb5000,
4181
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4182
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
4183

    
4184
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4185
                    omap_findclk(s, "arm_gpio_ck"));
4186

    
4187
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4188
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4189

    
4190
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "clk32-kHz"));
4191
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "xtal_osc_12m"));
4192

    
4193
    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4194
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4195

    
4196
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4197
                    omap_findclk(s, "clk32-kHz"));
4198

    
4199
    /* Register mappings not currenlty implemented:
4200
     * McBSP2 Comm        fffb1000 - fffb17ff
4201
     * McBSP1 Audio        fffb1800 - fffb1fff (not mapped on OMAP310)
4202
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4203
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4204
     * USB W2FC                fffb4000 - fffb47ff
4205
     * Camera Interface        fffb6800 - fffb6fff
4206
     * McBSP3                fffb7000 - fffb77ff (not mapped on OMAP310)
4207
     * USB Host                fffba000 - fffba7ff
4208
     * FAC                fffba800 - fffbafff
4209
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4210
     * LED1                fffbd000 - fffbd7ff
4211
     * LED2                fffbd800 - fffbdfff
4212
     * Mailbox                fffcf000 - fffcf7ff
4213
     * Local bus IF        fffec100 - fffec1ff
4214
     * Local bus MMU        fffec200 - fffec2ff
4215
     * DSP MMU                fffed200 - fffed2ff
4216
     */
4217

    
4218
    qemu_register_reset(omap_mpu_reset, s);
4219

    
4220
    return s;
4221
}