Statistics
| Branch: | Revision:

root / hw / omap.c @ f9d43072

History | View | Annotate | Download (139 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 "hw.h"
22
#include "arm-misc.h"
23
#include "omap.h"
24
#include "sysemu.h"
25
#include "qemu-timer.h"
26
/* We use pc-style serial ports.  */
27
#include "pc.h"
28

    
29
/* Should signal the TCMI */
30
uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
31
{
32
    uint8_t ret;
33

    
34
    OMAP_8B_REG(addr);
35
    cpu_physical_memory_read(addr, (void *) &ret, 1);
36
    return ret;
37
}
38

    
39
void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
40
                uint32_t value)
41
{
42
    uint8_t val8 = value;
43

    
44
    OMAP_8B_REG(addr);
45
    cpu_physical_memory_write(addr, (void *) &val8, 1);
46
}
47

    
48
uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
49
{
50
    uint16_t ret;
51

    
52
    OMAP_16B_REG(addr);
53
    cpu_physical_memory_read(addr, (void *) &ret, 2);
54
    return ret;
55
}
56

    
57
void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
58
                uint32_t value)
59
{
60
    uint16_t val16 = value;
61

    
62
    OMAP_16B_REG(addr);
63
    cpu_physical_memory_write(addr, (void *) &val16, 2);
64
}
65

    
66
uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
67
{
68
    uint32_t ret;
69

    
70
    OMAP_32B_REG(addr);
71
    cpu_physical_memory_read(addr, (void *) &ret, 4);
72
    return ret;
73
}
74

    
75
void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
76
                uint32_t value)
77
{
78
    OMAP_32B_REG(addr);
79
    cpu_physical_memory_write(addr, (void *) &value, 4);
80
}
81

    
82
/* Interrupt Handlers */
83
struct omap_intr_handler_s {
84
    qemu_irq *pins;
85
    qemu_irq *parent_pic;
86
    target_phys_addr_t base;
87

    
88
    /* state */
89
    uint32_t irqs;
90
    uint32_t mask;
91
    uint32_t sens_edge;
92
    uint32_t fiq;
93
    int priority[32];
94
    uint32_t new_irq_agr;
95
    uint32_t new_fiq_agr;
96
    int sir_irq;
97
    int sir_fiq;
98
    int stats[32];
99
};
100

    
101
static void omap_inth_update(struct omap_intr_handler_s *s)
102
{
103
    uint32_t irq = s->irqs & ~s->mask & ~s->fiq;
104
    uint32_t fiq = s->irqs & ~s->mask & s->fiq;
105

    
106
    if (s->new_irq_agr || !irq) {
107
       qemu_set_irq(s->parent_pic[ARM_PIC_CPU_IRQ], irq);
108
       if (irq)
109
           s->new_irq_agr = 0;
110
    }
111

    
112
    if (s->new_fiq_agr || !irq) {
113
        qemu_set_irq(s->parent_pic[ARM_PIC_CPU_FIQ], fiq);
114
        if (fiq)
115
            s->new_fiq_agr = 0;
116
    }
117
}
118

    
119
static void omap_inth_sir_update(struct omap_intr_handler_s *s)
120
{
121
    int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f;
122
    uint32_t level = s->irqs & ~s->mask;
123

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

    
143
        f = ffs(level >> 1);
144
    }
145

    
146
    s->sir_irq = intr_irq;
147
    s->sir_fiq = intr_fiq;
148
}
149

    
150
#define INT_FALLING_EDGE        0
151
#define INT_LOW_LEVEL                1
152

    
153
static void omap_set_intr(void *opaque, int irq, int req)
154
{
155
    struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
156
    uint32_t rise;
157

    
158
    if (req) {
159
        rise = ~ih->irqs & (1 << irq);
160
        ih->irqs |= rise;
161
        ih->stats[irq] += !!rise;
162
    } else {
163
        rise = ih->sens_edge & ih->irqs & (1 << irq);
164
        ih->irqs &= ~rise;
165
    }
166

    
167
    if (rise & ~ih->mask) {
168
        omap_inth_sir_update(ih);
169

    
170
        omap_inth_update(ih);
171
    }
172
}
173

    
174
static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
175
{
176
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
177
    int i, offset = addr - s->base;
178

    
179
    switch (offset) {
180
    case 0x00:        /* ITR */
181
        return s->irqs;
182

    
183
    case 0x04:        /* MIR */
184
        return s->mask;
185

    
186
    case 0x10:        /* SIR_IRQ_CODE */
187
        i = s->sir_irq;
188
        if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
189
            s->irqs &= ~(1 << i);
190
            omap_inth_sir_update(s);
191
            omap_inth_update(s);
192
        }
193
        return i;
194

    
195
    case 0x14:        /* SIR_FIQ_CODE */
196
        i = s->sir_fiq;
197
        if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {
198
            s->irqs &= ~(1 << i);
199
            omap_inth_sir_update(s);
200
            omap_inth_update(s);
201
        }
202
        return i;
203

    
204
    case 0x18:        /* CONTROL_REG */
205
        return 0;
206

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

    
244
    case 0x9c:        /* ISR */
245
        return 0x00000000;
246

    
247
    default:
248
        OMAP_BAD_REG(addr);
249
        break;
250
    }
251
    return 0;
252
}
253

    
254
static void omap_inth_write(void *opaque, target_phys_addr_t addr,
255
                uint32_t value)
256
{
257
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
258
    int i, offset = addr - s->base;
259

    
260
    switch (offset) {
261
    case 0x00:        /* ITR */
262
        s->irqs &= value | 1;
263
        omap_inth_sir_update(s);
264
        omap_inth_update(s);
265
        return;
266

    
267
    case 0x04:        /* MIR */
268
        s->mask = value;
269
        omap_inth_sir_update(s);
270
        omap_inth_update(s);
271
        return;
272

    
273
    case 0x10:        /* SIR_IRQ_CODE */
274
    case 0x14:        /* SIR_FIQ_CODE */
275
        OMAP_RO_REG(addr);
276
        break;
277

    
278
    case 0x18:        /* CONTROL_REG */
279
        if (value & 2)
280
            s->new_fiq_agr = ~0;
281
        if (value & 1)
282
            s->new_irq_agr = ~0;
283
        omap_inth_update(s);
284
        return;
285

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

    
326
    case 0x9c:        /* ISR */
327
        for (i = 0; i < 32; i ++)
328
            if (value & (1 << i)) {
329
                omap_set_intr(s, i, 1);
330
                return;
331
            }
332
        return;
333

    
334
    default:
335
        OMAP_BAD_REG(addr);
336
    }
337
}
338

    
339
static CPUReadMemoryFunc *omap_inth_readfn[] = {
340
    omap_badwidth_read32,
341
    omap_badwidth_read32,
342
    omap_inth_read,
343
};
344

    
345
static CPUWriteMemoryFunc *omap_inth_writefn[] = {
346
    omap_inth_write,
347
    omap_inth_write,
348
    omap_inth_write,
349
};
350

    
351
static void omap_inth_reset(struct omap_intr_handler_s *s)
352
{
353
    s->irqs = 0x00000000;
354
    s->mask = 0xffffffff;
355
    s->sens_edge = 0x00000000;
356
    s->fiq = 0x00000000;
357
    memset(s->priority, 0, sizeof(s->priority));
358
    s->new_irq_agr = ~0;
359
    s->new_fiq_agr = ~0;
360
    s->sir_irq = 0;
361
    s->sir_fiq = 0;
362

    
363
    omap_inth_update(s);
364
}
365

    
366
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
367
                unsigned long size, qemu_irq parent[2], omap_clk clk)
368
{
369
    int iomemtype;
370
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
371
            qemu_mallocz(sizeof(struct omap_intr_handler_s));
372

    
373
    s->parent_pic = parent;
374
    s->base = base;
375
    s->pins = qemu_allocate_irqs(omap_set_intr, s, 32);
376
    omap_inth_reset(s);
377

    
378
    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
379
                    omap_inth_writefn, s);
380
    cpu_register_physical_memory(s->base, size, iomemtype);
381

    
382
    return s;
383
}
384

    
385
/* OMAP1 DMA module */
386
typedef enum {
387
    constant = 0,
388
    post_incremented,
389
    single_index,
390
    double_index,
391
} omap_dma_addressing_t;
392

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

    
418
    struct omap_dma_reg_set_s {
419
        target_phys_addr_t src, dest;
420
        int frame;
421
        int element;
422
        int frame_delta[2];
423
        int elem_delta[2];
424
        int frames;
425
        int elements;
426
    } active_set;
427
};
428

    
429
struct omap_dma_s {
430
    qemu_irq *ih;
431
    QEMUTimer *tm;
432
    struct omap_mpu_state_s *mpu;
433
    target_phys_addr_t base;
434
    omap_clk clk;
435
    int64_t delay;
436
    uint32_t drq;
437

    
438
    uint16_t gcr;
439
    int run_count;
440

    
441
    int chans;
442
    struct omap_dma_channel_s ch[16];
443
    struct omap_dma_lcd_channel_s lcd_ch;
444
};
445

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

    
463
static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
464
{
465
    struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
466
    int i;
467

    
468
    /*
469
     * TODO: verify address ranges and alignment
470
     * TODO: port endianness
471
     */
472

    
473
    a->src = s->ch[ch].addr[0];
474
    a->dest = s->ch[ch].addr[1];
475
    a->frames = s->ch[ch].frames;
476
    a->elements = s->ch[ch].elements;
477
    a->frame = 0;
478
    a->element = 0;
479

    
480
    if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
481
        printf("%s: bad DMA request\n", __FUNCTION__);
482
        return;
483
    }
484

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

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

    
528
    if (s->ch[channel].transfer) {
529
        if (request > 0) {
530
            s->ch[channel ++].post_sync = request;
531
            goto next_channel;
532
        }
533
        s->ch[channel].status |= 0x02;        /* Synchronisation drop */
534
        omap_dma_interrupts_update(s);
535
        return;
536
    }
537

    
538
    if (!s->ch[channel].signalled)
539
        s->run_count ++;
540
    s->ch[channel].signalled = 1;
541

    
542
    if (request > 0)
543
        s->ch[channel].status |= 0x40;        /* External request */
544

    
545
    if (s->delay && !qemu_timer_pending(s->tm))
546
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
547

    
548
    if (request > 0) {
549
        channel ++;
550
        goto next_channel;
551
    }
552
}
553

    
554
static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel)
555
{
556
    if (s->ch[channel].signalled)
557
        s->run_count --;
558
    s->ch[channel].signalled = 0;
559

    
560
    if (!s->run_count)
561
        qemu_del_timer(s->tm);
562
}
563

    
564
static void omap_dma_channel_run(struct omap_dma_s *s)
565
{
566
    int ch;
567
    uint16_t status;
568
    uint8_t value[4];
569
    struct omap_dma_port_if_s *src_p, *dest_p;
570
    struct omap_dma_reg_set_s *a;
571

    
572
    for (ch = 0; ch < 9; ch ++) {
573
        a = &s->ch[ch].active_set;
574

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

    
589
        status = s->ch[ch].status;
590
        while (status == s->ch[ch].status && s->ch[ch].signalled) {
591
            /* Transfer a single element */
592
            s->ch[ch].transfer = 1;
593
            cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
594
            cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
595
            s->ch[ch].transfer = 0;
596

    
597
            a->src += a->elem_delta[0];
598
            a->dest += a->elem_delta[1];
599
            a->element ++;
600

    
601
            /* Check interrupt conditions */
602
            if (a->element == a->elements) {
603
                a->element = 0;
604
                a->src += a->frame_delta[0];
605
                a->dest += a->frame_delta[1];
606
                a->frame ++;
607

    
608
                if (a->frame == a->frames) {
609
                    if (!s->ch[ch].repeat || !s->ch[ch].auto_init)
610
                        s->ch[ch].running = 0;
611

    
612
                    if (s->ch[ch].auto_init &&
613
                            (s->ch[ch].repeat ||
614
                             s->ch[ch].end_prog))
615
                        omap_dma_channel_load(s, ch);
616

    
617
                    if (s->ch[ch].interrupts & 0x20)
618
                        s->ch[ch].status |= 0x20;
619

    
620
                    if (!s->ch[ch].sync)
621
                        omap_dma_request_stop(s, ch);
622
                }
623

    
624
                if (s->ch[ch].interrupts & 0x08)
625
                    s->ch[ch].status |= 0x08;
626

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

    
634
            if (a->element == 1 && a->frame == a->frames - 1)
635
                if (s->ch[ch].interrupts & 0x10)
636
                    s->ch[ch].status |= 0x10;
637

    
638
            if (a->element == (a->elements >> 1))
639
                if (s->ch[ch].interrupts & 0x04)
640
                    s->ch[ch].status |= 0x04;
641

    
642
            if (s->ch[ch].sync && !s->ch[ch].fs &&
643
                            !(s->drq & (1 << s->ch[ch].sync))) {
644
                s->ch[ch].status &= ~0x40;
645
                omap_dma_request_stop(s, ch);
646
            }
647

    
648
            /*
649
             * Process requests made while the element was
650
             * being transferred.
651
             */
652
            if (s->ch[ch].post_sync) {
653
                omap_dma_request_run(s, 0, s->ch[ch].post_sync);
654
                s->ch[ch].post_sync = 0;
655
            }
656

    
657
#if 0
658
            break;
659
#endif
660
        }
661

    
662
        s->ch[ch].cpc = a->dest & 0x0000ffff;
663
    }
664

    
665
    omap_dma_interrupts_update(s);
666
    if (s->run_count && s->delay)
667
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
668
}
669

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

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

    
694
    case 0x04:        /* SYS_DMA_CICR_CH0 */
695
        *value = s->ch[ch].interrupts;
696
        break;
697

    
698
    case 0x06:        /* SYS_DMA_CSR_CH0 */
699
        /* FIXME: shared CSR for channels sharing the interrupts */
700
        *value = s->ch[ch].status;
701
        s->ch[ch].status &= 0x40;
702
        omap_dma_interrupts_update(s);
703
        break;
704

    
705
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
706
        *value = s->ch[ch].addr[0] & 0x0000ffff;
707
        break;
708

    
709
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
710
        *value = s->ch[ch].addr[0] >> 16;
711
        break;
712

    
713
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
714
        *value = s->ch[ch].addr[1] & 0x0000ffff;
715
        break;
716

    
717
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
718
        *value = s->ch[ch].addr[1] >> 16;
719
        break;
720

    
721
    case 0x10:        /* SYS_DMA_CEN_CH0 */
722
        *value = s->ch[ch].elements;
723
        break;
724

    
725
    case 0x12:        /* SYS_DMA_CFN_CH0 */
726
        *value = s->ch[ch].frames;
727
        break;
728

    
729
    case 0x14:        /* SYS_DMA_CFI_CH0 */
730
        *value = s->ch[ch].frame_index;
731
        break;
732

    
733
    case 0x16:        /* SYS_DMA_CEI_CH0 */
734
        *value = s->ch[ch].element_index;
735
        break;
736

    
737
    case 0x18:        /* SYS_DMA_CPC_CH0 */
738
        *value = s->ch[ch].cpc;
739
        break;
740

    
741
    default:
742
        return 1;
743
    }
744
    return 0;
745
}
746

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

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

    
794
    case 0x04:        /* SYS_DMA_CICR_CH0 */
795
        s->ch[ch].interrupts = value & 0x003f;
796
        break;
797

    
798
    case 0x06:        /* SYS_DMA_CSR_CH0 */
799
        return 1;
800

    
801
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
802
        s->ch[ch].addr[0] &= 0xffff0000;
803
        s->ch[ch].addr[0] |= value;
804
        break;
805

    
806
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
807
        s->ch[ch].addr[0] &= 0x0000ffff;
808
        s->ch[ch].addr[0] |= (uint32_t) value << 16;
809
        break;
810

    
811
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
812
        s->ch[ch].addr[1] &= 0xffff0000;
813
        s->ch[ch].addr[1] |= value;
814
        break;
815

    
816
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
817
        s->ch[ch].addr[1] &= 0x0000ffff;
818
        s->ch[ch].addr[1] |= (uint32_t) value << 16;
819
        break;
820

    
821
    case 0x10:        /* SYS_DMA_CEN_CH0 */
822
        s->ch[ch].elements = value & 0xffff;
823
        break;
824

    
825
    case 0x12:        /* SYS_DMA_CFN_CH0 */
826
        s->ch[ch].frames = value & 0xffff;
827
        break;
828

    
829
    case 0x14:        /* SYS_DMA_CFI_CH0 */
830
        s->ch[ch].frame_index = value & 0xffff;
831
        break;
832

    
833
    case 0x16:        /* SYS_DMA_CEI_CH0 */
834
        s->ch[ch].element_index = value & 0xffff;
835
        break;
836

    
837
    case 0x18:        /* SYS_DMA_CPC_CH0 */
838
        return 1;
839

    
840
    default:
841
        OMAP_BAD_REG((target_phys_addr_t) reg);
842
    }
843
    return 0;
844
}
845

    
846
static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
847
{
848
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
849
    int i, reg, ch, offset = addr - s->base;
850
    uint16_t ret;
851

    
852
    switch (offset) {
853
    case 0x000 ... 0x2fe:
854
        reg = offset & 0x3f;
855
        ch = (offset >> 6) & 0x0f;
856
        if (omap_dma_ch_reg_read(s, ch, reg, &ret))
857
            break;
858
        return ret;
859

    
860
    case 0x300:        /* SYS_DMA_LCD_CTRL */
861
        i = s->lcd_ch.condition;
862
        s->lcd_ch.condition = 0;
863
        qemu_irq_lower(s->lcd_ch.irq);
864
        return ((s->lcd_ch.src == imif) << 6) | (i << 3) |
865
                (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
866

    
867
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
868
        return s->lcd_ch.src_f1_top & 0xffff;
869

    
870
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
871
        return s->lcd_ch.src_f1_top >> 16;
872

    
873
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
874
        return s->lcd_ch.src_f1_bottom & 0xffff;
875

    
876
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
877
        return s->lcd_ch.src_f1_bottom >> 16;
878

    
879
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
880
        return s->lcd_ch.src_f2_top & 0xffff;
881

    
882
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
883
        return s->lcd_ch.src_f2_top >> 16;
884

    
885
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
886
        return s->lcd_ch.src_f2_bottom & 0xffff;
887

    
888
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
889
        return s->lcd_ch.src_f2_bottom >> 16;
890

    
891
    case 0x400:        /* SYS_DMA_GCR */
892
        return s->gcr;
893
    }
894

    
895
    OMAP_BAD_REG(addr);
896
    return 0;
897
}
898

    
899
static void omap_dma_write(void *opaque, target_phys_addr_t addr,
900
                uint32_t value)
901
{
902
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
903
    int reg, ch, offset = addr - s->base;
904

    
905
    switch (offset) {
906
    case 0x000 ... 0x2fe:
907
        reg = offset & 0x3f;
908
        ch = (offset >> 6) & 0x0f;
909
        if (omap_dma_ch_reg_write(s, ch, reg, value))
910
            OMAP_RO_REG(addr);
911
        break;
912

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

    
921
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
922
        s->lcd_ch.src_f1_top &= 0xffff0000;
923
        s->lcd_ch.src_f1_top |= 0x0000ffff & value;
924
        break;
925

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

    
931
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
932
        s->lcd_ch.src_f1_bottom &= 0xffff0000;
933
        s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
934
        break;
935

    
936
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
937
        s->lcd_ch.src_f1_bottom &= 0x0000ffff;
938
        s->lcd_ch.src_f1_bottom |= value << 16;
939
        break;
940

    
941
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
942
        s->lcd_ch.src_f2_top &= 0xffff0000;
943
        s->lcd_ch.src_f2_top |= 0x0000ffff & value;
944
        break;
945

    
946
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
947
        s->lcd_ch.src_f2_top &= 0x0000ffff;
948
        s->lcd_ch.src_f2_top |= value << 16;
949
        break;
950

    
951
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
952
        s->lcd_ch.src_f2_bottom &= 0xffff0000;
953
        s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
954
        break;
955

    
956
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
957
        s->lcd_ch.src_f2_bottom &= 0x0000ffff;
958
        s->lcd_ch.src_f2_bottom |= value << 16;
959
        break;
960

    
961
    case 0x400:        /* SYS_DMA_GCR */
962
        s->gcr = value & 0x000c;
963
        break;
964

    
965
    default:
966
        OMAP_BAD_REG(addr);
967
    }
968
}
969

    
970
static CPUReadMemoryFunc *omap_dma_readfn[] = {
971
    omap_badwidth_read16,
972
    omap_dma_read,
973
    omap_badwidth_read16,
974
};
975

    
976
static CPUWriteMemoryFunc *omap_dma_writefn[] = {
977
    omap_badwidth_write16,
978
    omap_dma_write,
979
    omap_badwidth_write16,
980
};
981

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

    
995
static void omap_dma_clk_update(void *opaque, int line, int on)
996
{
997
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
998

    
999
    if (on) {
1000
        /* TODO: make a clever calculation */
1001
        s->delay = ticks_per_sec >> 8;
1002
        if (s->run_count)
1003
            qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
1004
    } else {
1005
        s->delay = 0;
1006
        qemu_del_timer(s->tm);
1007
    }
1008
}
1009

    
1010
static void omap_dma_reset(struct omap_dma_s *s)
1011
{
1012
    int i;
1013

    
1014
    qemu_del_timer(s->tm);
1015
    s->gcr = 0x0004;
1016
    s->drq = 0x00000000;
1017
    s->run_count = 0;
1018
    s->lcd_ch.src = emiff;
1019
    s->lcd_ch.condition = 0;
1020
    s->lcd_ch.interrupts = 0;
1021
    s->lcd_ch.dual = 0;
1022
    memset(s->ch, 0, sizeof(s->ch));
1023
    for (i = 0; i < s->chans; i ++)
1024
        s->ch[i].interrupts = 0x0003;
1025
}
1026

    
1027
struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
1028
                qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk)
1029
{
1030
    int iomemtype;
1031
    struct omap_dma_s *s = (struct omap_dma_s *)
1032
            qemu_mallocz(sizeof(struct omap_dma_s));
1033

    
1034
    s->ih = pic;
1035
    s->base = base;
1036
    s->chans = 9;
1037
    s->mpu = mpu;
1038
    s->clk = clk;
1039
    s->lcd_ch.irq = pic[OMAP_INT_DMA_LCD];
1040
    s->lcd_ch.mpu = mpu;
1041
    s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1042
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1043
    mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1044
    omap_dma_reset(s);
1045
    omap_dma_clk_update(s, 0, 1);
1046

    
1047
    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1048
                    omap_dma_writefn, s);
1049
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
1050

    
1051
    return s;
1052
}
1053

    
1054
/* DMA ports */
1055
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1056
                target_phys_addr_t addr)
1057
{
1058
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1059
}
1060

    
1061
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1062
                target_phys_addr_t addr)
1063
{
1064
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1065
}
1066

    
1067
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1068
                target_phys_addr_t addr)
1069
{
1070
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1071
}
1072

    
1073
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1074
                target_phys_addr_t addr)
1075
{
1076
    return addr >= 0xfffb0000 && addr < 0xffff0000;
1077
}
1078

    
1079
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
1080
                target_phys_addr_t addr)
1081
{
1082
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1083
}
1084

    
1085
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1086
                target_phys_addr_t addr)
1087
{
1088
    return addr >= 0xe1010000 && addr < 0xe1020004;
1089
}
1090

    
1091
/* MPU OS timers */
1092
struct omap_mpu_timer_s {
1093
    qemu_irq irq;
1094
    omap_clk clk;
1095
    target_phys_addr_t base;
1096
    uint32_t val;
1097
    int64_t time;
1098
    QEMUTimer *timer;
1099
    int64_t rate;
1100
    int it_ena;
1101

    
1102
    int enable;
1103
    int ptv;
1104
    int ar;
1105
    int st;
1106
    uint32_t reset_val;
1107
};
1108

    
1109
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1110
{
1111
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
1112

    
1113
    if (timer->st && timer->enable && timer->rate)
1114
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
1115
                        timer->rate, ticks_per_sec);
1116
    else
1117
        return timer->val;
1118
}
1119

    
1120
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1121
{
1122
    timer->val = omap_timer_read(timer);
1123
    timer->time = qemu_get_clock(vm_clock);
1124
}
1125

    
1126
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1127
{
1128
    int64_t expires;
1129

    
1130
    if (timer->enable && timer->st && timer->rate) {
1131
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
1132
        expires = muldiv64(timer->val << (timer->ptv + 1),
1133
                        ticks_per_sec, timer->rate);
1134

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

    
1153
static void omap_timer_tick(void *opaque)
1154
{
1155
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1156
    omap_timer_sync(timer);
1157

    
1158
    if (!timer->ar) {
1159
        timer->val = 0;
1160
        timer->st = 0;
1161
    }
1162

    
1163
    if (timer->it_ena)
1164
        qemu_irq_raise(timer->irq);
1165
    omap_timer_update(timer);
1166
}
1167

    
1168
static void omap_timer_clk_update(void *opaque, int line, int on)
1169
{
1170
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1171

    
1172
    omap_timer_sync(timer);
1173
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1174
    omap_timer_update(timer);
1175
}
1176

    
1177
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
1178
{
1179
    omap_clk_adduser(timer->clk,
1180
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
1181
    timer->rate = omap_clk_getrate(timer->clk);
1182
}
1183

    
1184
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
1185
{
1186
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1187
    int offset = addr - s->base;
1188

    
1189
    switch (offset) {
1190
    case 0x00:        /* CNTL_TIMER */
1191
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1192

    
1193
    case 0x04:        /* LOAD_TIM */
1194
        break;
1195

    
1196
    case 0x08:        /* READ_TIM */
1197
        return omap_timer_read(s);
1198
    }
1199

    
1200
    OMAP_BAD_REG(addr);
1201
    return 0;
1202
}
1203

    
1204
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1205
                uint32_t value)
1206
{
1207
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1208
    int offset = addr - s->base;
1209

    
1210
    switch (offset) {
1211
    case 0x00:        /* CNTL_TIMER */
1212
        omap_timer_sync(s);
1213
        s->enable = (value >> 5) & 1;
1214
        s->ptv = (value >> 2) & 7;
1215
        s->ar = (value >> 1) & 1;
1216
        s->st = value & 1;
1217
        omap_timer_update(s);
1218
        return;
1219

    
1220
    case 0x04:        /* LOAD_TIM */
1221
        s->reset_val = value;
1222
        return;
1223

    
1224
    case 0x08:        /* READ_TIM */
1225
        OMAP_RO_REG(addr);
1226
        break;
1227

    
1228
    default:
1229
        OMAP_BAD_REG(addr);
1230
    }
1231
}
1232

    
1233
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1234
    omap_badwidth_read32,
1235
    omap_badwidth_read32,
1236
    omap_mpu_timer_read,
1237
};
1238

    
1239
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1240
    omap_badwidth_write32,
1241
    omap_badwidth_write32,
1242
    omap_mpu_timer_write,
1243
};
1244

    
1245
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
1246
{
1247
    qemu_del_timer(s->timer);
1248
    s->enable = 0;
1249
    s->reset_val = 31337;
1250
    s->val = 0;
1251
    s->ptv = 0;
1252
    s->ar = 0;
1253
    s->st = 0;
1254
    s->it_ena = 1;
1255
}
1256

    
1257
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1258
                qemu_irq irq, omap_clk clk)
1259
{
1260
    int iomemtype;
1261
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1262
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
1263

    
1264
    s->irq = irq;
1265
    s->clk = clk;
1266
    s->base = base;
1267
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
1268
    omap_mpu_timer_reset(s);
1269
    omap_timer_clk_setup(s);
1270

    
1271
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
1272
                    omap_mpu_timer_writefn, s);
1273
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1274

    
1275
    return s;
1276
}
1277

    
1278
/* Watchdog timer */
1279
struct omap_watchdog_timer_s {
1280
    struct omap_mpu_timer_s timer;
1281
    uint8_t last_wr;
1282
    int mode;
1283
    int free;
1284
    int reset;
1285
};
1286

    
1287
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
1288
{
1289
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1290
    int offset = addr - s->timer.base;
1291

    
1292
    switch (offset) {
1293
    case 0x00:        /* CNTL_TIMER */
1294
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
1295
                (s->timer.st << 7) | (s->free << 1);
1296

    
1297
    case 0x04:        /* READ_TIMER */
1298
        return omap_timer_read(&s->timer);
1299

    
1300
    case 0x08:        /* TIMER_MODE */
1301
        return s->mode << 15;
1302
    }
1303

    
1304
    OMAP_BAD_REG(addr);
1305
    return 0;
1306
}
1307

    
1308
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1309
                uint32_t value)
1310
{
1311
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1312
    int offset = addr - s->timer.base;
1313

    
1314
    switch (offset) {
1315
    case 0x00:        /* CNTL_TIMER */
1316
        omap_timer_sync(&s->timer);
1317
        s->timer.ptv = (value >> 9) & 7;
1318
        s->timer.ar = (value >> 8) & 1;
1319
        s->timer.st = (value >> 7) & 1;
1320
        s->free = (value >> 1) & 1;
1321
        omap_timer_update(&s->timer);
1322
        break;
1323

    
1324
    case 0x04:        /* LOAD_TIMER */
1325
        s->timer.reset_val = value & 0xffff;
1326
        break;
1327

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

    
1348
    default:
1349
        OMAP_BAD_REG(addr);
1350
    }
1351
}
1352

    
1353
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
1354
    omap_badwidth_read16,
1355
    omap_wd_timer_read,
1356
    omap_badwidth_read16,
1357
};
1358

    
1359
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
1360
    omap_badwidth_write16,
1361
    omap_wd_timer_write,
1362
    omap_badwidth_write16,
1363
};
1364

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

    
1383
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
1384
                qemu_irq irq, omap_clk clk)
1385
{
1386
    int iomemtype;
1387
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
1388
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
1389

    
1390
    s->timer.irq = irq;
1391
    s->timer.clk = clk;
1392
    s->timer.base = base;
1393
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1394
    omap_wd_timer_reset(s);
1395
    omap_timer_clk_setup(&s->timer);
1396

    
1397
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
1398
                    omap_wd_timer_writefn, s);
1399
    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
1400

    
1401
    return s;
1402
}
1403

    
1404
/* 32-kHz timer */
1405
struct omap_32khz_timer_s {
1406
    struct omap_mpu_timer_s timer;
1407
};
1408

    
1409
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
1410
{
1411
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1412
    int offset = addr & OMAP_MPUI_REG_MASK;
1413

    
1414
    switch (offset) {
1415
    case 0x00:        /* TVR */
1416
        return s->timer.reset_val;
1417

    
1418
    case 0x04:        /* TCR */
1419
        return omap_timer_read(&s->timer);
1420

    
1421
    case 0x08:        /* CR */
1422
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
1423

    
1424
    default:
1425
        break;
1426
    }
1427
    OMAP_BAD_REG(addr);
1428
    return 0;
1429
}
1430

    
1431
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1432
                uint32_t value)
1433
{
1434
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1435
    int offset = addr & OMAP_MPUI_REG_MASK;
1436

    
1437
    switch (offset) {
1438
    case 0x00:        /* TVR */
1439
        s->timer.reset_val = value & 0x00ffffff;
1440
        break;
1441

    
1442
    case 0x04:        /* TCR */
1443
        OMAP_RO_REG(addr);
1444
        break;
1445

    
1446
    case 0x08:        /* CR */
1447
        s->timer.ar = (value >> 3) & 1;
1448
        s->timer.it_ena = (value >> 2) & 1;
1449
        if (s->timer.st != (value & 1) || (value & 2)) {
1450
            omap_timer_sync(&s->timer);
1451
            s->timer.enable = value & 1;
1452
            s->timer.st = value & 1;
1453
            omap_timer_update(&s->timer);
1454
        }
1455
        break;
1456

    
1457
    default:
1458
        OMAP_BAD_REG(addr);
1459
    }
1460
}
1461

    
1462
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1463
    omap_badwidth_read32,
1464
    omap_badwidth_read32,
1465
    omap_os_timer_read,
1466
};
1467

    
1468
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1469
    omap_badwidth_write32,
1470
    omap_badwidth_write32,
1471
    omap_os_timer_write,
1472
};
1473

    
1474
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1475
{
1476
    qemu_del_timer(s->timer.timer);
1477
    s->timer.enable = 0;
1478
    s->timer.it_ena = 0;
1479
    s->timer.reset_val = 0x00ffffff;
1480
    s->timer.val = 0;
1481
    s->timer.st = 0;
1482
    s->timer.ptv = 0;
1483
    s->timer.ar = 1;
1484
}
1485

    
1486
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1487
                qemu_irq irq, omap_clk clk)
1488
{
1489
    int iomemtype;
1490
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1491
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1492

    
1493
    s->timer.irq = irq;
1494
    s->timer.clk = clk;
1495
    s->timer.base = base;
1496
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1497
    omap_os_timer_reset(s);
1498
    omap_timer_clk_setup(&s->timer);
1499

    
1500
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1501
                    omap_os_timer_writefn, s);
1502
    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
1503

    
1504
    return s;
1505
}
1506

    
1507
/* Ultra Low-Power Device Module */
1508
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1509
{
1510
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1511
    int offset = addr - s->ulpd_pm_base;
1512
    uint16_t ret;
1513

    
1514
    switch (offset) {
1515
    case 0x14:        /* IT_STATUS */
1516
        ret = s->ulpd_pm_regs[offset >> 2];
1517
        s->ulpd_pm_regs[offset >> 2] = 0;
1518
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1519
        return ret;
1520

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

    
1545
    OMAP_BAD_REG(addr);
1546
    return 0;
1547
}
1548

    
1549
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1550
                uint16_t diff, uint16_t value)
1551
{
1552
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
1553
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1554
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1555
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1556
}
1557

    
1558
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1559
                uint16_t diff, uint16_t value)
1560
{
1561
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1562
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1563
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1564
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1565
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1566
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1567
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1568
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1569
}
1570

    
1571
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1572
                uint32_t value)
1573
{
1574
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1575
    int offset = addr - s->ulpd_pm_base;
1576
    int64_t now, ticks;
1577
    int div, mult;
1578
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1579
    uint16_t diff;
1580

    
1581
    switch (offset) {
1582
    case 0x00:        /* COUNTER_32_LSB */
1583
    case 0x04:        /* COUNTER_32_MSB */
1584
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1585
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1586
    case 0x14:        /* IT_STATUS */
1587
    case 0x40:        /* STATUS_REQ */
1588
        OMAP_RO_REG(addr);
1589
        break;
1590

    
1591
    case 0x10:        /* GAUGING_CTRL */
1592
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1593
        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
1594
            now = qemu_get_clock(vm_clock);
1595

    
1596
            if (value & 1)
1597
                s->ulpd_gauge_start = now;
1598
            else {
1599
                now -= s->ulpd_gauge_start;
1600

    
1601
                /* 32-kHz ticks */
1602
                ticks = muldiv64(now, 32768, ticks_per_sec);
1603
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1604
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1605
                if (ticks >> 32)        /* OVERFLOW_32K */
1606
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1607

    
1608
                /* High frequency ticks */
1609
                ticks = muldiv64(now, 12000000, ticks_per_sec);
1610
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1611
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1612
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1613
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1614

    
1615
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
1616
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1617
            }
1618
        }
1619
        s->ulpd_pm_regs[offset >> 2] = value;
1620
        break;
1621

    
1622
    case 0x18:        /* Reserved */
1623
    case 0x1c:        /* Reserved */
1624
    case 0x20:        /* Reserved */
1625
    case 0x28:        /* Reserved */
1626
    case 0x2c:        /* Reserved */
1627
        OMAP_BAD_REG(addr);
1628
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1629
    case 0x38:        /* COUNTER_32_FIQ */
1630
    case 0x48:        /* LOCL_TIME */
1631
    case 0x50:        /* POWER_CTRL */
1632
        s->ulpd_pm_regs[offset >> 2] = value;
1633
        break;
1634

    
1635
    case 0x30:        /* CLOCK_CTRL */
1636
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1637
        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
1638
        omap_ulpd_clk_update(s, diff, value);
1639
        break;
1640

    
1641
    case 0x34:        /* SOFT_REQ */
1642
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1643
        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
1644
        omap_ulpd_req_update(s, diff, value);
1645
        break;
1646

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

    
1665
        /* Enter the desired mode.  */
1666
        s->ulpd_pm_regs[offset >> 2] =
1667
                (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
1668
                ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
1669

    
1670
        /* Act as if the lock is restored.  */
1671
        s->ulpd_pm_regs[offset >> 2] |= 2;
1672
        break;
1673

    
1674
    case 0x4c:        /* APLL_CTRL */
1675
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1676
        s->ulpd_pm_regs[offset >> 2] = value & 0xf;
1677
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
1678
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1679
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
1680
        break;
1681

    
1682
    default:
1683
        OMAP_BAD_REG(addr);
1684
    }
1685
}
1686

    
1687
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1688
    omap_badwidth_read16,
1689
    omap_ulpd_pm_read,
1690
    omap_badwidth_read16,
1691
};
1692

    
1693
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1694
    omap_badwidth_write16,
1695
    omap_ulpd_pm_write,
1696
    omap_badwidth_write16,
1697
};
1698

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

    
1726
static void omap_ulpd_pm_init(target_phys_addr_t base,
1727
                struct omap_mpu_state_s *mpu)
1728
{
1729
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1730
                    omap_ulpd_pm_writefn, mpu);
1731

    
1732
    mpu->ulpd_pm_base = base;
1733
    cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1734
    omap_ulpd_pm_reset(mpu);
1735
}
1736

    
1737
/* OMAP Pin Configuration */
1738
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1739
{
1740
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1741
    int offset = addr - s->pin_cfg_base;
1742

    
1743
    switch (offset) {
1744
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1745
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1746
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1747
        return s->func_mux_ctrl[offset >> 2];
1748

    
1749
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1750
        return s->comp_mode_ctrl[0];
1751

    
1752
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1753
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1754
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1755
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1756
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1757
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1758
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1759
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1760
    case 0x30:        /* FUNC_MUX_CTRL_B */
1761
    case 0x34:        /* FUNC_MUX_CTRL_C */
1762
    case 0x38:        /* FUNC_MUX_CTRL_D */
1763
        return s->func_mux_ctrl[(offset >> 2) - 1];
1764

    
1765
    case 0x40:        /* PULL_DWN_CTRL_0 */
1766
    case 0x44:        /* PULL_DWN_CTRL_1 */
1767
    case 0x48:        /* PULL_DWN_CTRL_2 */
1768
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1769
        return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1770

    
1771
    case 0x50:        /* GATE_INH_CTRL_0 */
1772
        return s->gate_inh_ctrl[0];
1773

    
1774
    case 0x60:        /* VOLTAGE_CTRL_0 */
1775
        return s->voltage_ctrl[0];
1776

    
1777
    case 0x70:        /* TEST_DBG_CTRL_0 */
1778
        return s->test_dbg_ctrl[0];
1779

    
1780
    case 0x80:        /* MOD_CONF_CTRL_0 */
1781
        return s->mod_conf_ctrl[0];
1782
    }
1783

    
1784
    OMAP_BAD_REG(addr);
1785
    return 0;
1786
}
1787

    
1788
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1789
                uint32_t diff, uint32_t value)
1790
{
1791
    if (s->compat1509) {
1792
        if (diff & (1 << 9))                        /* BLUETOOTH */
1793
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1794
                            (~value >> 9) & 1);
1795
        if (diff & (1 << 7))                        /* USB.CLKO */
1796
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
1797
                            (value >> 7) & 1);
1798
    }
1799
}
1800

    
1801
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1802
                uint32_t diff, uint32_t value)
1803
{
1804
    if (s->compat1509) {
1805
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
1806
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1807
                            (value >> 31) & 1);
1808
        if (diff & (1 << 1))                        /* CLK32K */
1809
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1810
                            (~value >> 1) & 1);
1811
    }
1812
}
1813

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

    
1841
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1842
                uint32_t value)
1843
{
1844
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1845
    int offset = addr - s->pin_cfg_base;
1846
    uint32_t diff;
1847

    
1848
    switch (offset) {
1849
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1850
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1851
        s->func_mux_ctrl[offset >> 2] = value;
1852
        omap_pin_funcmux0_update(s, diff, value);
1853
        return;
1854

    
1855
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1856
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1857
        s->func_mux_ctrl[offset >> 2] = value;
1858
        omap_pin_funcmux1_update(s, diff, value);
1859
        return;
1860

    
1861
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1862
        s->func_mux_ctrl[offset >> 2] = value;
1863
        return;
1864

    
1865
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1866
        s->comp_mode_ctrl[0] = value;
1867
        s->compat1509 = (value != 0x0000eaef);
1868
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1869
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1870
        return;
1871

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

    
1886
    case 0x40:        /* PULL_DWN_CTRL_0 */
1887
    case 0x44:        /* PULL_DWN_CTRL_1 */
1888
    case 0x48:        /* PULL_DWN_CTRL_2 */
1889
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1890
        s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1891
        return;
1892

    
1893
    case 0x50:        /* GATE_INH_CTRL_0 */
1894
        s->gate_inh_ctrl[0] = value;
1895
        return;
1896

    
1897
    case 0x60:        /* VOLTAGE_CTRL_0 */
1898
        s->voltage_ctrl[0] = value;
1899
        return;
1900

    
1901
    case 0x70:        /* TEST_DBG_CTRL_0 */
1902
        s->test_dbg_ctrl[0] = value;
1903
        return;
1904

    
1905
    case 0x80:        /* MOD_CONF_CTRL_0 */
1906
        diff = s->mod_conf_ctrl[0] ^ value;
1907
        s->mod_conf_ctrl[0] = value;
1908
        omap_pin_modconf1_update(s, diff, value);
1909
        return;
1910

    
1911
    default:
1912
        OMAP_BAD_REG(addr);
1913
    }
1914
}
1915

    
1916
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1917
    omap_badwidth_read32,
1918
    omap_badwidth_read32,
1919
    omap_pin_cfg_read,
1920
};
1921

    
1922
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1923
    omap_badwidth_write32,
1924
    omap_badwidth_write32,
1925
    omap_pin_cfg_write,
1926
};
1927

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

    
1944
static void omap_pin_cfg_init(target_phys_addr_t base,
1945
                struct omap_mpu_state_s *mpu)
1946
{
1947
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1948
                    omap_pin_cfg_writefn, mpu);
1949

    
1950
    mpu->pin_cfg_base = base;
1951
    cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1952
    omap_pin_cfg_reset(mpu);
1953
}
1954

    
1955
/* Device Identification, Die Identification */
1956
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1957
{
1958
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1959

    
1960
    switch (addr) {
1961
    case 0xfffe1800:        /* DIE_ID_LSB */
1962
        return 0xc9581f0e;
1963
    case 0xfffe1804:        /* DIE_ID_MSB */
1964
        return 0xa8858bfa;
1965

    
1966
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
1967
        return 0x00aaaafc;
1968
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
1969
        return 0xcafeb574;
1970

    
1971
    case 0xfffed400:        /* JTAG_ID_LSB */
1972
        switch (s->mpu_model) {
1973
        case omap310:
1974
            return 0x03310315;
1975
        case omap1510:
1976
            return 0x03310115;
1977
        }
1978
        break;
1979

    
1980
    case 0xfffed404:        /* JTAG_ID_MSB */
1981
        switch (s->mpu_model) {
1982
        case omap310:
1983
            return 0xfb57402f;
1984
        case omap1510:
1985
            return 0xfb47002f;
1986
        }
1987
        break;
1988
    }
1989

    
1990
    OMAP_BAD_REG(addr);
1991
    return 0;
1992
}
1993

    
1994
static void omap_id_write(void *opaque, target_phys_addr_t addr,
1995
                uint32_t value)
1996
{
1997
    OMAP_BAD_REG(addr);
1998
}
1999

    
2000
static CPUReadMemoryFunc *omap_id_readfn[] = {
2001
    omap_badwidth_read32,
2002
    omap_badwidth_read32,
2003
    omap_id_read,
2004
};
2005

    
2006
static CPUWriteMemoryFunc *omap_id_writefn[] = {
2007
    omap_badwidth_write32,
2008
    omap_badwidth_write32,
2009
    omap_id_write,
2010
};
2011

    
2012
static void omap_id_init(struct omap_mpu_state_s *mpu)
2013
{
2014
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
2015
                    omap_id_writefn, mpu);
2016
    cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
2017
    cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
2018
    if (!cpu_is_omap15xx(mpu))
2019
        cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
2020
}
2021

    
2022
/* MPUI Control (Dummy) */
2023
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
2024
{
2025
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2026
    int offset = addr - s->mpui_base;
2027

    
2028
    switch (offset) {
2029
    case 0x00:        /* CTRL */
2030
        return s->mpui_ctrl;
2031
    case 0x04:        /* DEBUG_ADDR */
2032
        return 0x01ffffff;
2033
    case 0x08:        /* DEBUG_DATA */
2034
        return 0xffffffff;
2035
    case 0x0c:        /* DEBUG_FLAG */
2036
        return 0x00000800;
2037
    case 0x10:        /* STATUS */
2038
        return 0x00000000;
2039

    
2040
    /* Not in OMAP310 */
2041
    case 0x14:        /* DSP_STATUS */
2042
    case 0x18:        /* DSP_BOOT_CONFIG */
2043
        return 0x00000000;
2044
    case 0x1c:        /* DSP_MPUI_CONFIG */
2045
        return 0x0000ffff;
2046
    }
2047

    
2048
    OMAP_BAD_REG(addr);
2049
    return 0;
2050
}
2051

    
2052
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2053
                uint32_t value)
2054
{
2055
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2056
    int offset = addr - s->mpui_base;
2057

    
2058
    switch (offset) {
2059
    case 0x00:        /* CTRL */
2060
        s->mpui_ctrl = value & 0x007fffff;
2061
        break;
2062

    
2063
    case 0x04:        /* DEBUG_ADDR */
2064
    case 0x08:        /* DEBUG_DATA */
2065
    case 0x0c:        /* DEBUG_FLAG */
2066
    case 0x10:        /* STATUS */
2067
    /* Not in OMAP310 */
2068
    case 0x14:        /* DSP_STATUS */
2069
        OMAP_RO_REG(addr);
2070
    case 0x18:        /* DSP_BOOT_CONFIG */
2071
    case 0x1c:        /* DSP_MPUI_CONFIG */
2072
        break;
2073

    
2074
    default:
2075
        OMAP_BAD_REG(addr);
2076
    }
2077
}
2078

    
2079
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2080
    omap_badwidth_read32,
2081
    omap_badwidth_read32,
2082
    omap_mpui_read,
2083
};
2084

    
2085
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2086
    omap_badwidth_write32,
2087
    omap_badwidth_write32,
2088
    omap_mpui_write,
2089
};
2090

    
2091
static void omap_mpui_reset(struct omap_mpu_state_s *s)
2092
{
2093
    s->mpui_ctrl = 0x0003ff1b;
2094
}
2095

    
2096
static void omap_mpui_init(target_phys_addr_t base,
2097
                struct omap_mpu_state_s *mpu)
2098
{
2099
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2100
                    omap_mpui_writefn, mpu);
2101

    
2102
    mpu->mpui_base = base;
2103
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2104

    
2105
    omap_mpui_reset(mpu);
2106
}
2107

    
2108
/* TIPB Bridges */
2109
struct omap_tipb_bridge_s {
2110
    target_phys_addr_t base;
2111
    qemu_irq abort;
2112

    
2113
    int width_intr;
2114
    uint16_t control;
2115
    uint16_t alloc;
2116
    uint16_t buffer;
2117
    uint16_t enh_control;
2118
};
2119

    
2120
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
2121
{
2122
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2123
    int offset = addr - s->base;
2124

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

    
2142
    OMAP_BAD_REG(addr);
2143
    return 0;
2144
}
2145

    
2146
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
2147
                uint32_t value)
2148
{
2149
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2150
    int offset = addr - s->base;
2151

    
2152
    switch (offset) {
2153
    case 0x00:        /* TIPB_CNTL */
2154
        s->control = value & 0xffff;
2155
        break;
2156

    
2157
    case 0x04:        /* TIPB_BUS_ALLOC */
2158
        s->alloc = value & 0x003f;
2159
        break;
2160

    
2161
    case 0x08:        /* MPU_TIPB_CNTL */
2162
        s->buffer = value & 0x0003;
2163
        break;
2164

    
2165
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2166
        s->width_intr = !(value & 2);
2167
        s->enh_control = value & 0x000f;
2168
        break;
2169

    
2170
    case 0x10:        /* ADDRESS_DBG */
2171
    case 0x14:        /* DATA_DEBUG_LOW */
2172
    case 0x18:        /* DATA_DEBUG_HIGH */
2173
    case 0x1c:        /* DEBUG_CNTR_SIG */
2174
        OMAP_RO_REG(addr);
2175
        break;
2176

    
2177
    default:
2178
        OMAP_BAD_REG(addr);
2179
    }
2180
}
2181

    
2182
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2183
    omap_badwidth_read16,
2184
    omap_tipb_bridge_read,
2185
    omap_tipb_bridge_read,
2186
};
2187

    
2188
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2189
    omap_badwidth_write16,
2190
    omap_tipb_bridge_write,
2191
    omap_tipb_bridge_write,
2192
};
2193

    
2194
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2195
{
2196
    s->control = 0xffff;
2197
    s->alloc = 0x0009;
2198
    s->buffer = 0x0000;
2199
    s->enh_control = 0x000f;
2200
}
2201

    
2202
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2203
                qemu_irq abort_irq, omap_clk clk)
2204
{
2205
    int iomemtype;
2206
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2207
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2208

    
2209
    s->abort = abort_irq;
2210
    s->base = base;
2211
    omap_tipb_bridge_reset(s);
2212

    
2213
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
2214
                    omap_tipb_bridge_writefn, s);
2215
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2216

    
2217
    return s;
2218
}
2219

    
2220
/* Dummy Traffic Controller's Memory Interface */
2221
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2222
{
2223
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2224
    int offset = addr - s->tcmi_base;
2225
    uint32_t ret;
2226

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

    
2244
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
2245
        ret = s->tcmi_regs[offset >> 2];
2246
        s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2247
        /* XXX: We can try using the VGA_DIRTY flag for this */
2248
        return ret;
2249
    }
2250

    
2251
    OMAP_BAD_REG(addr);
2252
    return 0;
2253
}
2254

    
2255
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2256
                uint32_t value)
2257
{
2258
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2259
    int offset = addr - s->tcmi_base;
2260

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

    
2282
    default:
2283
        OMAP_BAD_REG(addr);
2284
    }
2285
}
2286

    
2287
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2288
    omap_badwidth_read32,
2289
    omap_badwidth_read32,
2290
    omap_tcmi_read,
2291
};
2292

    
2293
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2294
    omap_badwidth_write32,
2295
    omap_badwidth_write32,
2296
    omap_tcmi_write,
2297
};
2298

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

    
2318
static void omap_tcmi_init(target_phys_addr_t base,
2319
                struct omap_mpu_state_s *mpu)
2320
{
2321
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2322
                    omap_tcmi_writefn, mpu);
2323

    
2324
    mpu->tcmi_base = base;
2325
    cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2326
    omap_tcmi_reset(mpu);
2327
}
2328

    
2329
/* Digital phase-locked loops control */
2330
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2331
{
2332
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2333
    int offset = addr - s->base;
2334

    
2335
    if (offset == 0x00)        /* CTL_REG */
2336
        return s->mode;
2337

    
2338
    OMAP_BAD_REG(addr);
2339
    return 0;
2340
}
2341

    
2342
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2343
                uint32_t value)
2344
{
2345
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2346
    uint16_t diff;
2347
    int offset = addr - s->base;
2348
    static const int bypass_div[4] = { 1, 2, 4, 4 };
2349
    int div, mult;
2350

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

    
2366
        /* Enter the desired mode.  */
2367
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
2368

    
2369
        /* Act as if the lock is restored.  */
2370
        s->mode |= 2;
2371
    } else {
2372
        OMAP_BAD_REG(addr);
2373
    }
2374
}
2375

    
2376
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
2377
    omap_badwidth_read16,
2378
    omap_dpll_read,
2379
    omap_badwidth_read16,
2380
};
2381

    
2382
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
2383
    omap_badwidth_write16,
2384
    omap_dpll_write,
2385
    omap_badwidth_write16,
2386
};
2387

    
2388
static void omap_dpll_reset(struct dpll_ctl_s *s)
2389
{
2390
    s->mode = 0x2002;
2391
    omap_clk_setrate(s->dpll, 1, 1);
2392
}
2393

    
2394
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
2395
                omap_clk clk)
2396
{
2397
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
2398
                    omap_dpll_writefn, s);
2399

    
2400
    s->base = base;
2401
    s->dpll = clk;
2402
    omap_dpll_reset(s);
2403

    
2404
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2405
}
2406

    
2407
/* UARTs */
2408
struct omap_uart_s {
2409
    SerialState *serial; /* TODO */
2410
};
2411

    
2412
static void omap_uart_reset(struct omap_uart_s *s)
2413
{
2414
}
2415

    
2416
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2417
                qemu_irq irq, omap_clk clk, CharDriverState *chr)
2418
{
2419
    struct omap_uart_s *s = (struct omap_uart_s *)
2420
            qemu_mallocz(sizeof(struct omap_uart_s));
2421
    if (chr)
2422
        s->serial = serial_mm_init(base, 2, irq, chr, 1);
2423
    return s;
2424
}
2425

    
2426
/* MPU Clock/Reset/Power Mode Control */
2427
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2428
{
2429
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2430
    int offset = addr - s->clkm.mpu_base;
2431

    
2432
    switch (offset) {
2433
    case 0x00:        /* ARM_CKCTL */
2434
        return s->clkm.arm_ckctl;
2435

    
2436
    case 0x04:        /* ARM_IDLECT1 */
2437
        return s->clkm.arm_idlect1;
2438

    
2439
    case 0x08:        /* ARM_IDLECT2 */
2440
        return s->clkm.arm_idlect2;
2441

    
2442
    case 0x0c:        /* ARM_EWUPCT */
2443
        return s->clkm.arm_ewupct;
2444

    
2445
    case 0x10:        /* ARM_RSTCT1 */
2446
        return s->clkm.arm_rstct1;
2447

    
2448
    case 0x14:        /* ARM_RSTCT2 */
2449
        return s->clkm.arm_rstct2;
2450

    
2451
    case 0x18:        /* ARM_SYSST */
2452
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
2453

    
2454
    case 0x1c:        /* ARM_CKOUT1 */
2455
        return s->clkm.arm_ckout1;
2456

    
2457
    case 0x20:        /* ARM_CKOUT2 */
2458
        break;
2459
    }
2460

    
2461
    OMAP_BAD_REG(addr);
2462
    return 0;
2463
}
2464

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

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

    
2512
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2513
                uint16_t diff, uint16_t value)
2514
{
2515
    omap_clk clk;
2516

    
2517
    if (value & (1 << 11))                                /* SETARM_IDLE */
2518
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2519
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2520
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2521

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

    
2543
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2544
                uint16_t diff, uint16_t value)
2545
{
2546
    omap_clk clk;
2547

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

    
2566
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2567
                uint16_t diff, uint16_t value)
2568
{
2569
    omap_clk clk;
2570

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

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

    
2636
    switch (offset) {
2637
    case 0x00:        /* ARM_CKCTL */
2638
        diff = s->clkm.arm_ckctl ^ value;
2639
        s->clkm.arm_ckctl = value & 0x7fff;
2640
        omap_clkm_ckctl_update(s, diff, value);
2641
        return;
2642

    
2643
    case 0x04:        /* ARM_IDLECT1 */
2644
        diff = s->clkm.arm_idlect1 ^ value;
2645
        s->clkm.arm_idlect1 = value & 0x0fff;
2646
        omap_clkm_idlect1_update(s, diff, value);
2647
        return;
2648

    
2649
    case 0x08:        /* ARM_IDLECT2 */
2650
        diff = s->clkm.arm_idlect2 ^ value;
2651
        s->clkm.arm_idlect2 = value & 0x07ff;
2652
        omap_clkm_idlect2_update(s, diff, value);
2653
        return;
2654

    
2655
    case 0x0c:        /* ARM_EWUPCT */
2656
        diff = s->clkm.arm_ewupct ^ value;
2657
        s->clkm.arm_ewupct = value & 0x003f;
2658
        return;
2659

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

    
2678
    case 0x14:        /* ARM_RSTCT2 */
2679
        s->clkm.arm_rstct2 = value & 0x0001;
2680
        return;
2681

    
2682
    case 0x18:        /* ARM_SYSST */
2683
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2684
            s->clkm.clocking_scheme = (value >> 11) & 7;
2685
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2686
                            clkschemename[s->clkm.clocking_scheme]);
2687
        }
2688
        s->clkm.cold_start &= value & 0x3f;
2689
        return;
2690

    
2691
    case 0x1c:        /* ARM_CKOUT1 */
2692
        diff = s->clkm.arm_ckout1 ^ value;
2693
        s->clkm.arm_ckout1 = value & 0x003f;
2694
        omap_clkm_ckout1_update(s, diff, value);
2695
        return;
2696

    
2697
    case 0x20:        /* ARM_CKOUT2 */
2698
    default:
2699
        OMAP_BAD_REG(addr);
2700
    }
2701
}
2702

    
2703
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2704
    omap_badwidth_read16,
2705
    omap_clkm_read,
2706
    omap_badwidth_read16,
2707
};
2708

    
2709
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2710
    omap_badwidth_write16,
2711
    omap_clkm_write,
2712
    omap_badwidth_write16,
2713
};
2714

    
2715
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2716
{
2717
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2718
    int offset = addr - s->clkm.dsp_base;
2719

    
2720
    switch (offset) {
2721
    case 0x04:        /* DSP_IDLECT1 */
2722
        return s->clkm.dsp_idlect1;
2723

    
2724
    case 0x08:        /* DSP_IDLECT2 */
2725
        return s->clkm.dsp_idlect2;
2726

    
2727
    case 0x14:        /* DSP_RSTCT2 */
2728
        return s->clkm.dsp_rstct2;
2729

    
2730
    case 0x18:        /* DSP_SYSST */
2731
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
2732
                (s->env->halted << 6);        /* Quite useless... */
2733
    }
2734

    
2735
    OMAP_BAD_REG(addr);
2736
    return 0;
2737
}
2738

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

    
2744
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2745
}
2746

    
2747
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2748
                uint16_t diff, uint16_t value)
2749
{
2750
    omap_clk clk;
2751

    
2752
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2753
}
2754

    
2755
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2756
                uint32_t value)
2757
{
2758
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2759
    int offset = addr - s->clkm.dsp_base;
2760
    uint16_t diff;
2761

    
2762
    switch (offset) {
2763
    case 0x04:        /* DSP_IDLECT1 */
2764
        diff = s->clkm.dsp_idlect1 ^ value;
2765
        s->clkm.dsp_idlect1 = value & 0x01f7;
2766
        omap_clkdsp_idlect1_update(s, diff, value);
2767
        break;
2768

    
2769
    case 0x08:        /* DSP_IDLECT2 */
2770
        s->clkm.dsp_idlect2 = value & 0x0037;
2771
        diff = s->clkm.dsp_idlect1 ^ value;
2772
        omap_clkdsp_idlect2_update(s, diff, value);
2773
        break;
2774

    
2775
    case 0x14:        /* DSP_RSTCT2 */
2776
        s->clkm.dsp_rstct2 = value & 0x0001;
2777
        break;
2778

    
2779
    case 0x18:        /* DSP_SYSST */
2780
        s->clkm.cold_start &= value & 0x3f;
2781
        break;
2782

    
2783
    default:
2784
        OMAP_BAD_REG(addr);
2785
    }
2786
}
2787

    
2788
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2789
    omap_badwidth_read16,
2790
    omap_clkdsp_read,
2791
    omap_badwidth_read16,
2792
};
2793

    
2794
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2795
    omap_badwidth_write16,
2796
    omap_clkdsp_write,
2797
    omap_badwidth_write16,
2798
};
2799

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

    
2823
static void omap_clkm_init(target_phys_addr_t mpu_base,
2824
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2825
{
2826
    int iomemtype[2] = {
2827
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2828
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2829
    };
2830

    
2831
    s->clkm.mpu_base = mpu_base;
2832
    s->clkm.dsp_base = dsp_base;
2833
    s->clkm.arm_idlect1 = 0x03ff;
2834
    s->clkm.arm_idlect2 = 0x0100;
2835
    s->clkm.dsp_idlect1 = 0x0002;
2836
    omap_clkm_reset(s);
2837
    s->clkm.cold_start = 0x3a;
2838

    
2839
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2840
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2841
}
2842

    
2843
/* MPU I/O */
2844
struct omap_mpuio_s {
2845
    target_phys_addr_t base;
2846
    qemu_irq irq;
2847
    qemu_irq kbd_irq;
2848
    qemu_irq *in;
2849
    qemu_irq handler[16];
2850
    qemu_irq wakeup;
2851

    
2852
    uint16_t inputs;
2853
    uint16_t outputs;
2854
    uint16_t dir;
2855
    uint16_t edge;
2856
    uint16_t mask;
2857
    uint16_t ints;
2858

    
2859
    uint16_t debounce;
2860
    uint16_t latch;
2861
    uint8_t event;
2862

    
2863
    uint8_t buttons[5];
2864
    uint8_t row_latch;
2865
    uint8_t cols;
2866
    int kbd_mask;
2867
    int clk;
2868
};
2869

    
2870
static void omap_mpuio_set(void *opaque, int line, int level)
2871
{
2872
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2873
    uint16_t prev = s->inputs;
2874

    
2875
    if (level)
2876
        s->inputs |= 1 << line;
2877
    else
2878
        s->inputs &= ~(1 << line);
2879

    
2880
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2881
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2882
            s->ints |= 1 << line;
2883
            qemu_irq_raise(s->irq);
2884
            /* TODO: wakeup */
2885
        }
2886
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
2887
                (s->event >> 1) == line)        /* PIN_SELECT */
2888
            s->latch = s->inputs;
2889
    }
2890
}
2891

    
2892
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2893
{
2894
    int i;
2895
    uint8_t *row, rows = 0, cols = ~s->cols;
2896

    
2897
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2898
        if (*row & cols)
2899
            rows |= i;
2900

    
2901
    qemu_set_irq(s->kbd_irq, rows && ~s->kbd_mask && s->clk);
2902
    s->row_latch = rows ^ 0x1f;
2903
}
2904

    
2905
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2906
{
2907
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2908
    int offset = addr & OMAP_MPUI_REG_MASK;
2909
    uint16_t ret;
2910

    
2911
    switch (offset) {
2912
    case 0x00:        /* INPUT_LATCH */
2913
        return s->inputs;
2914

    
2915
    case 0x04:        /* OUTPUT_REG */
2916
        return s->outputs;
2917

    
2918
    case 0x08:        /* IO_CNTL */
2919
        return s->dir;
2920

    
2921
    case 0x10:        /* KBR_LATCH */
2922
        return s->row_latch;
2923

    
2924
    case 0x14:        /* KBC_REG */
2925
        return s->cols;
2926

    
2927
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2928
        return s->event;
2929

    
2930
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2931
        return s->edge;
2932

    
2933
    case 0x20:        /* KBD_INT */
2934
        return (s->row_latch != 0x1f) && !s->kbd_mask;
2935

    
2936
    case 0x24:        /* GPIO_INT */
2937
        ret = s->ints;
2938
        s->ints &= s->mask;
2939
        if (ret)
2940
            qemu_irq_lower(s->irq);
2941
        return ret;
2942

    
2943
    case 0x28:        /* KBD_MASKIT */
2944
        return s->kbd_mask;
2945

    
2946
    case 0x2c:        /* GPIO_MASKIT */
2947
        return s->mask;
2948

    
2949
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2950
        return s->debounce;
2951

    
2952
    case 0x34:        /* GPIO_LATCH_REG */
2953
        return s->latch;
2954
    }
2955

    
2956
    OMAP_BAD_REG(addr);
2957
    return 0;
2958
}
2959

    
2960
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2961
                uint32_t value)
2962
{
2963
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2964
    int offset = addr & OMAP_MPUI_REG_MASK;
2965
    uint16_t diff;
2966
    int ln;
2967

    
2968
    switch (offset) {
2969
    case 0x04:        /* OUTPUT_REG */
2970
        diff = (s->outputs ^ value) & ~s->dir;
2971
        s->outputs = value;
2972
        while ((ln = ffs(diff))) {
2973
            ln --;
2974
            if (s->handler[ln])
2975
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2976
            diff &= ~(1 << ln);
2977
        }
2978
        break;
2979

    
2980
    case 0x08:        /* IO_CNTL */
2981
        diff = s->outputs & (s->dir ^ value);
2982
        s->dir = value;
2983

    
2984
        value = s->outputs & ~s->dir;
2985
        while ((ln = ffs(diff))) {
2986
            ln --;
2987
            if (s->handler[ln])
2988
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2989
            diff &= ~(1 << ln);
2990
        }
2991
        break;
2992

    
2993
    case 0x14:        /* KBC_REG */
2994
        s->cols = value;
2995
        omap_mpuio_kbd_update(s);
2996
        break;
2997

    
2998
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2999
        s->event = value & 0x1f;
3000
        break;
3001

    
3002
    case 0x1c:        /* GPIO_INT_EDGE_REG */
3003
        s->edge = value;
3004
        break;
3005

    
3006
    case 0x28:        /* KBD_MASKIT */
3007
        s->kbd_mask = value & 1;
3008
        omap_mpuio_kbd_update(s);
3009
        break;
3010

    
3011
    case 0x2c:        /* GPIO_MASKIT */
3012
        s->mask = value;
3013
        break;
3014

    
3015
    case 0x30:        /* GPIO_DEBOUNCING_REG */
3016
        s->debounce = value & 0x1ff;
3017
        break;
3018

    
3019
    case 0x00:        /* INPUT_LATCH */
3020
    case 0x10:        /* KBR_LATCH */
3021
    case 0x20:        /* KBD_INT */
3022
    case 0x24:        /* GPIO_INT */
3023
    case 0x34:        /* GPIO_LATCH_REG */
3024
        OMAP_RO_REG(addr);
3025
        return;
3026

    
3027
    default:
3028
        OMAP_BAD_REG(addr);
3029
        return;
3030
    }
3031
}
3032

    
3033
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
3034
    omap_badwidth_read16,
3035
    omap_mpuio_read,
3036
    omap_badwidth_read16,
3037
};
3038

    
3039
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
3040
    omap_badwidth_write16,
3041
    omap_mpuio_write,
3042
    omap_badwidth_write16,
3043
};
3044

    
3045
static void omap_mpuio_reset(struct omap_mpuio_s *s)
3046
{
3047
    s->inputs = 0;
3048
    s->outputs = 0;
3049
    s->dir = ~0;
3050
    s->event = 0;
3051
    s->edge = 0;
3052
    s->kbd_mask = 0;
3053
    s->mask = 0;
3054
    s->debounce = 0;
3055
    s->latch = 0;
3056
    s->ints = 0;
3057
    s->row_latch = 0x1f;
3058
    s->clk = 1;
3059
}
3060

    
3061
static void omap_mpuio_onoff(void *opaque, int line, int on)
3062
{
3063
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3064

    
3065
    s->clk = on;
3066
    if (on)
3067
        omap_mpuio_kbd_update(s);
3068
}
3069

    
3070
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
3071
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
3072
                omap_clk clk)
3073
{
3074
    int iomemtype;
3075
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
3076
            qemu_mallocz(sizeof(struct omap_mpuio_s));
3077

    
3078
    s->base = base;
3079
    s->irq = gpio_int;
3080
    s->kbd_irq = kbd_int;
3081
    s->wakeup = wakeup;
3082
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
3083
    omap_mpuio_reset(s);
3084

    
3085
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
3086
                    omap_mpuio_writefn, s);
3087
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3088

    
3089
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
3090

    
3091
    return s;
3092
}
3093

    
3094
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
3095
{
3096
    return s->in;
3097
}
3098

    
3099
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
3100
{
3101
    if (line >= 16 || line < 0)
3102
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3103
    s->handler[line] = handler;
3104
}
3105

    
3106
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
3107
{
3108
    if (row >= 5 || row < 0)
3109
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
3110
                        __FUNCTION__, col, row);
3111

    
3112
    if (down)
3113
        s->buttons[row] |= 1 << col;
3114
    else
3115
        s->buttons[row] &= ~(1 << col);
3116

    
3117
    omap_mpuio_kbd_update(s);
3118
}
3119

    
3120
/* General-Purpose I/O */
3121
struct omap_gpio_s {
3122
    target_phys_addr_t base;
3123
    qemu_irq irq;
3124
    qemu_irq *in;
3125
    qemu_irq handler[16];
3126

    
3127
    uint16_t inputs;
3128
    uint16_t outputs;
3129
    uint16_t dir;
3130
    uint16_t edge;
3131
    uint16_t mask;
3132
    uint16_t ints;
3133
    uint16_t pins;
3134
};
3135

    
3136
static void omap_gpio_set(void *opaque, int line, int level)
3137
{
3138
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3139
    uint16_t prev = s->inputs;
3140

    
3141
    if (level)
3142
        s->inputs |= 1 << line;
3143
    else
3144
        s->inputs &= ~(1 << line);
3145

    
3146
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
3147
                    (1 << line) & s->dir & ~s->mask) {
3148
        s->ints |= 1 << line;
3149
        qemu_irq_raise(s->irq);
3150
    }
3151
}
3152

    
3153
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
3154
{
3155
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3156
    int offset = addr & OMAP_MPUI_REG_MASK;
3157

    
3158
    switch (offset) {
3159
    case 0x00:        /* DATA_INPUT */
3160
        return s->inputs & s->pins;
3161

    
3162
    case 0x04:        /* DATA_OUTPUT */
3163
        return s->outputs;
3164

    
3165
    case 0x08:        /* DIRECTION_CONTROL */
3166
        return s->dir;
3167

    
3168
    case 0x0c:        /* INTERRUPT_CONTROL */
3169
        return s->edge;
3170

    
3171
    case 0x10:        /* INTERRUPT_MASK */
3172
        return s->mask;
3173

    
3174
    case 0x14:        /* INTERRUPT_STATUS */
3175
        return s->ints;
3176

    
3177
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
3178
        OMAP_BAD_REG(addr);
3179
        return s->pins;
3180
    }
3181

    
3182
    OMAP_BAD_REG(addr);
3183
    return 0;
3184
}
3185

    
3186
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
3187
                uint32_t value)
3188
{
3189
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3190
    int offset = addr & OMAP_MPUI_REG_MASK;
3191
    uint16_t diff;
3192
    int ln;
3193

    
3194
    switch (offset) {
3195
    case 0x00:        /* DATA_INPUT */
3196
        OMAP_RO_REG(addr);
3197
        return;
3198

    
3199
    case 0x04:        /* DATA_OUTPUT */
3200
        diff = (s->outputs ^ value) & ~s->dir;
3201
        s->outputs = value;
3202
        while ((ln = ffs(diff))) {
3203
            ln --;
3204
            if (s->handler[ln])
3205
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3206
            diff &= ~(1 << ln);
3207
        }
3208
        break;
3209

    
3210
    case 0x08:        /* DIRECTION_CONTROL */
3211
        diff = s->outputs & (s->dir ^ value);
3212
        s->dir = value;
3213

    
3214
        value = s->outputs & ~s->dir;
3215
        while ((ln = ffs(diff))) {
3216
            ln --;
3217
            if (s->handler[ln])
3218
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3219
            diff &= ~(1 << ln);
3220
        }
3221
        break;
3222

    
3223
    case 0x0c:        /* INTERRUPT_CONTROL */
3224
        s->edge = value;
3225
        break;
3226

    
3227
    case 0x10:        /* INTERRUPT_MASK */
3228
        s->mask = value;
3229
        break;
3230

    
3231
    case 0x14:        /* INTERRUPT_STATUS */
3232
        s->ints &= ~value;
3233
        if (!s->ints)
3234
            qemu_irq_lower(s->irq);
3235
        break;
3236

    
3237
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
3238
        OMAP_BAD_REG(addr);
3239
        s->pins = value;
3240
        break;
3241

    
3242
    default:
3243
        OMAP_BAD_REG(addr);
3244
        return;
3245
    }
3246
}
3247

    
3248
/* *Some* sources say the memory region is 32-bit.  */
3249
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
3250
    omap_badwidth_read16,
3251
    omap_gpio_read,
3252
    omap_badwidth_read16,
3253
};
3254

    
3255
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
3256
    omap_badwidth_write16,
3257
    omap_gpio_write,
3258
    omap_badwidth_write16,
3259
};
3260

    
3261
static void omap_gpio_reset(struct omap_gpio_s *s)
3262
{
3263
    s->inputs = 0;
3264
    s->outputs = ~0;
3265
    s->dir = ~0;
3266
    s->edge = ~0;
3267
    s->mask = ~0;
3268
    s->ints = 0;
3269
    s->pins = ~0;
3270
}
3271

    
3272
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
3273
                qemu_irq irq, omap_clk clk)
3274
{
3275
    int iomemtype;
3276
    struct omap_gpio_s *s = (struct omap_gpio_s *)
3277
            qemu_mallocz(sizeof(struct omap_gpio_s));
3278

    
3279
    s->base = base;
3280
    s->irq = irq;
3281
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
3282
    omap_gpio_reset(s);
3283

    
3284
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
3285
                    omap_gpio_writefn, s);
3286
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3287

    
3288
    return s;
3289
}
3290

    
3291
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
3292
{
3293
    return s->in;
3294
}
3295

    
3296
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3297
{
3298
    if (line >= 16 || line < 0)
3299
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3300
    s->handler[line] = handler;
3301
}
3302

    
3303
/* MicroWire Interface */
3304
struct omap_uwire_s {
3305
    target_phys_addr_t base;
3306
    qemu_irq txirq;
3307
    qemu_irq rxirq;
3308
    qemu_irq txdrq;
3309

    
3310
    uint16_t txbuf;
3311
    uint16_t rxbuf;
3312
    uint16_t control;
3313
    uint16_t setup[5];
3314

    
3315
    struct uwire_slave_s *chip[4];
3316
};
3317

    
3318
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3319
{
3320
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3321
    struct uwire_slave_s *slave = s->chip[chipselect];
3322

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

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

    
3343
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3344
{
3345
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3346
    int offset = addr & OMAP_MPUI_REG_MASK;
3347

    
3348
    switch (offset) {
3349
    case 0x00:        /* RDR */
3350
        s->control &= ~(1 << 15);                        /* RDRB */
3351
        return s->rxbuf;
3352

    
3353
    case 0x04:        /* CSR */
3354
        return s->control;
3355

    
3356
    case 0x08:        /* SR1 */
3357
        return s->setup[0];
3358
    case 0x0c:        /* SR2 */
3359
        return s->setup[1];
3360
    case 0x10:        /* SR3 */
3361
        return s->setup[2];
3362
    case 0x14:        /* SR4 */
3363
        return s->setup[3];
3364
    case 0x18:        /* SR5 */
3365
        return s->setup[4];
3366
    }
3367

    
3368
    OMAP_BAD_REG(addr);
3369
    return 0;
3370
}
3371

    
3372
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3373
                uint32_t value)
3374
{
3375
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3376
    int offset = addr & OMAP_MPUI_REG_MASK;
3377

    
3378
    switch (offset) {
3379
    case 0x00:        /* TDR */
3380
        s->txbuf = value;                                /* TD */
3381
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3382
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3383
                         (s->control & (1 << 12)))) {        /* CS_CMD */
3384
            s->control |= 1 << 14;                        /* CSRB */
3385
            omap_uwire_transfer_start(s);
3386
        }
3387
        break;
3388

    
3389
    case 0x04:        /* CSR */
3390
        s->control = value & 0x1fff;
3391
        if (value & (1 << 13))                                /* START */
3392
            omap_uwire_transfer_start(s);
3393
        break;
3394

    
3395
    case 0x08:        /* SR1 */
3396
        s->setup[0] = value & 0x003f;
3397
        break;
3398

    
3399
    case 0x0c:        /* SR2 */
3400
        s->setup[1] = value & 0x0fc0;
3401
        break;
3402

    
3403
    case 0x10:        /* SR3 */
3404
        s->setup[2] = value & 0x0003;
3405
        break;
3406

    
3407
    case 0x14:        /* SR4 */
3408
        s->setup[3] = value & 0x0001;
3409
        break;
3410

    
3411
    case 0x18:        /* SR5 */
3412
        s->setup[4] = value & 0x000f;
3413
        break;
3414

    
3415
    default:
3416
        OMAP_BAD_REG(addr);
3417
        return;
3418
    }
3419
}
3420

    
3421
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3422
    omap_badwidth_read16,
3423
    omap_uwire_read,
3424
    omap_badwidth_read16,
3425
};
3426

    
3427
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3428
    omap_badwidth_write16,
3429
    omap_uwire_write,
3430
    omap_badwidth_write16,
3431
};
3432

    
3433
static void omap_uwire_reset(struct omap_uwire_s *s)
3434
{
3435
    s->control = 0;
3436
    s->setup[0] = 0;
3437
    s->setup[1] = 0;
3438
    s->setup[2] = 0;
3439
    s->setup[3] = 0;
3440
    s->setup[4] = 0;
3441
}
3442

    
3443
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3444
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3445
{
3446
    int iomemtype;
3447
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3448
            qemu_mallocz(sizeof(struct omap_uwire_s));
3449

    
3450
    s->base = base;
3451
    s->txirq = irq[0];
3452
    s->rxirq = irq[1];
3453
    s->txdrq = dma;
3454
    omap_uwire_reset(s);
3455

    
3456
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3457
                    omap_uwire_writefn, s);
3458
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3459

    
3460
    return s;
3461
}
3462

    
3463
void omap_uwire_attach(struct omap_uwire_s *s,
3464
                struct uwire_slave_s *slave, int chipselect)
3465
{
3466
    if (chipselect < 0 || chipselect > 3)
3467
        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
3468
                        chipselect);
3469

    
3470
    s->chip[chipselect] = slave;
3471
}
3472

    
3473
/* Pseudonoise Pulse-Width Light Modulator */
3474
static void omap_pwl_update(struct omap_mpu_state_s *s)
3475
{
3476
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3477

    
3478
    if (output != s->pwl.output) {
3479
        s->pwl.output = output;
3480
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3481
    }
3482
}
3483

    
3484
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3485
{
3486
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3487
    int offset = addr & OMAP_MPUI_REG_MASK;
3488

    
3489
    switch (offset) {
3490
    case 0x00:        /* PWL_LEVEL */
3491
        return s->pwl.level;
3492
    case 0x04:        /* PWL_CTRL */
3493
        return s->pwl.enable;
3494
    }
3495
    OMAP_BAD_REG(addr);
3496
    return 0;
3497
}
3498

    
3499
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3500
                uint32_t value)
3501
{
3502
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3503
    int offset = addr & OMAP_MPUI_REG_MASK;
3504

    
3505
    switch (offset) {
3506
    case 0x00:        /* PWL_LEVEL */
3507
        s->pwl.level = value;
3508
        omap_pwl_update(s);
3509
        break;
3510
    case 0x04:        /* PWL_CTRL */
3511
        s->pwl.enable = value & 1;
3512
        omap_pwl_update(s);
3513
        break;
3514
    default:
3515
        OMAP_BAD_REG(addr);
3516
        return;
3517
    }
3518
}
3519

    
3520
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3521
    omap_pwl_read,
3522
    omap_badwidth_read8,
3523
    omap_badwidth_read8,
3524
};
3525

    
3526
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3527
    omap_pwl_write,
3528
    omap_badwidth_write8,
3529
    omap_badwidth_write8,
3530
};
3531

    
3532
static void omap_pwl_reset(struct omap_mpu_state_s *s)
3533
{
3534
    s->pwl.output = 0;
3535
    s->pwl.level = 0;
3536
    s->pwl.enable = 0;
3537
    s->pwl.clk = 1;
3538
    omap_pwl_update(s);
3539
}
3540

    
3541
static void omap_pwl_clk_update(void *opaque, int line, int on)
3542
{
3543
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3544

    
3545
    s->pwl.clk = on;
3546
    omap_pwl_update(s);
3547
}
3548

    
3549
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3550
                omap_clk clk)
3551
{
3552
    int iomemtype;
3553

    
3554
    omap_pwl_reset(s);
3555

    
3556
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3557
                    omap_pwl_writefn, s);
3558
    cpu_register_physical_memory(base, 0x800, iomemtype);
3559

    
3560
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3561
}
3562

    
3563
/* Pulse-Width Tone module */
3564
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3565
{
3566
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3567
    int offset = addr & OMAP_MPUI_REG_MASK;
3568

    
3569
    switch (offset) {
3570
    case 0x00:        /* FRC */
3571
        return s->pwt.frc;
3572
    case 0x04:        /* VCR */
3573
        return s->pwt.vrc;
3574
    case 0x08:        /* GCR */
3575
        return s->pwt.gcr;
3576
    }
3577
    OMAP_BAD_REG(addr);
3578
    return 0;
3579
}
3580

    
3581
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3582
                uint32_t value)
3583
{
3584
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3585
    int offset = addr & OMAP_MPUI_REG_MASK;
3586

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

    
3624
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3625
    omap_pwt_read,
3626
    omap_badwidth_read8,
3627
    omap_badwidth_read8,
3628
};
3629

    
3630
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3631
    omap_pwt_write,
3632
    omap_badwidth_write8,
3633
    omap_badwidth_write8,
3634
};
3635

    
3636
static void omap_pwt_reset(struct omap_mpu_state_s *s)
3637
{
3638
    s->pwt.frc = 0;
3639
    s->pwt.vrc = 0;
3640
    s->pwt.gcr = 0;
3641
}
3642

    
3643
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3644
                omap_clk clk)
3645
{
3646
    int iomemtype;
3647

    
3648
    s->pwt.clk = clk;
3649
    omap_pwt_reset(s);
3650

    
3651
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3652
                    omap_pwt_writefn, s);
3653
    cpu_register_physical_memory(base, 0x800, iomemtype);
3654
}
3655

    
3656
/* Real-time Clock module */
3657
struct omap_rtc_s {
3658
    target_phys_addr_t base;
3659
    qemu_irq irq;
3660
    qemu_irq alarm;
3661
    QEMUTimer *clk;
3662

    
3663
    uint8_t interrupts;
3664
    uint8_t status;
3665
    int16_t comp_reg;
3666
    int running;
3667
    int pm_am;
3668
    int auto_comp;
3669
    int round;
3670
    struct tm *(*convert)(const time_t *timep, struct tm *result);
3671
    struct tm alarm_tm;
3672
    time_t alarm_ti;
3673

    
3674
    struct tm current_tm;
3675
    time_t ti;
3676
    uint64_t tick;
3677
};
3678

    
3679
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3680
{
3681
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3682
}
3683

    
3684
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3685
{
3686
    s->alarm_ti = mktime(&s->alarm_tm);
3687
    if (s->alarm_ti == -1)
3688
        printf("%s: conversion failed\n", __FUNCTION__);
3689
}
3690

    
3691
static inline uint8_t omap_rtc_bcd(int num)
3692
{
3693
    return ((num / 10) << 4) | (num % 10);
3694
}
3695

    
3696
static inline int omap_rtc_bin(uint8_t num)
3697
{
3698
    return (num & 15) + 10 * (num >> 4);
3699
}
3700

    
3701
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3702
{
3703
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3704
    int offset = addr & OMAP_MPUI_REG_MASK;
3705
    uint8_t i;
3706

    
3707
    switch (offset) {
3708
    case 0x00:        /* SECONDS_REG */
3709
        return omap_rtc_bcd(s->current_tm.tm_sec);
3710

    
3711
    case 0x04:        /* MINUTES_REG */
3712
        return omap_rtc_bcd(s->current_tm.tm_min);
3713

    
3714
    case 0x08:        /* HOURS_REG */
3715
        if (s->pm_am)
3716
            return ((s->current_tm.tm_hour > 11) << 7) |
3717
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3718
        else
3719
            return omap_rtc_bcd(s->current_tm.tm_hour);
3720

    
3721
    case 0x0c:        /* DAYS_REG */
3722
        return omap_rtc_bcd(s->current_tm.tm_mday);
3723

    
3724
    case 0x10:        /* MONTHS_REG */
3725
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3726

    
3727
    case 0x14:        /* YEARS_REG */
3728
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3729

    
3730
    case 0x18:        /* WEEK_REG */
3731
        return s->current_tm.tm_wday;
3732

    
3733
    case 0x20:        /* ALARM_SECONDS_REG */
3734
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3735

    
3736
    case 0x24:        /* ALARM_MINUTES_REG */
3737
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3738

    
3739
    case 0x28:        /* ALARM_HOURS_REG */
3740
        if (s->pm_am)
3741
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3742
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3743
        else
3744
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
3745

    
3746
    case 0x2c:        /* ALARM_DAYS_REG */
3747
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3748

    
3749
    case 0x30:        /* ALARM_MONTHS_REG */
3750
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3751

    
3752
    case 0x34:        /* ALARM_YEARS_REG */
3753
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3754

    
3755
    case 0x40:        /* RTC_CTRL_REG */
3756
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3757
                (s->round << 1) | s->running;
3758

    
3759
    case 0x44:        /* RTC_STATUS_REG */
3760
        i = s->status;
3761
        s->status &= ~0x3d;
3762
        return i;
3763

    
3764
    case 0x48:        /* RTC_INTERRUPTS_REG */
3765
        return s->interrupts;
3766

    
3767
    case 0x4c:        /* RTC_COMP_LSB_REG */
3768
        return ((uint16_t) s->comp_reg) & 0xff;
3769

    
3770
    case 0x50:        /* RTC_COMP_MSB_REG */
3771
        return ((uint16_t) s->comp_reg) >> 8;
3772
    }
3773

    
3774
    OMAP_BAD_REG(addr);
3775
    return 0;
3776
}
3777

    
3778
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3779
                uint32_t value)
3780
{
3781
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3782
    int offset = addr & OMAP_MPUI_REG_MASK;
3783
    struct tm new_tm;
3784
    time_t ti[2];
3785

    
3786
    switch (offset) {
3787
    case 0x00:        /* SECONDS_REG */
3788
#if ALMDEBUG
3789
        printf("RTC SEC_REG <-- %02x\n", value);
3790
#endif
3791
        s->ti -= s->current_tm.tm_sec;
3792
        s->ti += omap_rtc_bin(value);
3793
        return;
3794

    
3795
    case 0x04:        /* MINUTES_REG */
3796
#if ALMDEBUG
3797
        printf("RTC MIN_REG <-- %02x\n", value);
3798
#endif
3799
        s->ti -= s->current_tm.tm_min * 60;
3800
        s->ti += omap_rtc_bin(value) * 60;
3801
        return;
3802

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

    
3815
    case 0x0c:        /* DAYS_REG */
3816
#if ALMDEBUG
3817
        printf("RTC DAY_REG <-- %02x\n", value);
3818
#endif
3819
        s->ti -= s->current_tm.tm_mday * 86400;
3820
        s->ti += omap_rtc_bin(value) * 86400;
3821
        return;
3822

    
3823
    case 0x10:        /* MONTHS_REG */
3824
#if ALMDEBUG
3825
        printf("RTC MTH_REG <-- %02x\n", value);
3826
#endif
3827
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3828
        new_tm.tm_mon = omap_rtc_bin(value);
3829
        ti[0] = mktime(&s->current_tm);
3830
        ti[1] = mktime(&new_tm);
3831

    
3832
        if (ti[0] != -1 && ti[1] != -1) {
3833
            s->ti -= ti[0];
3834
            s->ti += ti[1];
3835
        } else {
3836
            /* A less accurate version */
3837
            s->ti -= s->current_tm.tm_mon * 2592000;
3838
            s->ti += omap_rtc_bin(value) * 2592000;
3839
        }
3840
        return;
3841

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

    
3851
        if (ti[0] != -1 && ti[1] != -1) {
3852
            s->ti -= ti[0];
3853
            s->ti += ti[1];
3854
        } else {
3855
            /* A less accurate version */
3856
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3857
            s->ti += omap_rtc_bin(value) * 31536000;
3858
        }
3859
        return;
3860

    
3861
    case 0x18:        /* WEEK_REG */
3862
        return;        /* Ignored */
3863

    
3864
    case 0x20:        /* ALARM_SECONDS_REG */
3865
#if ALMDEBUG
3866
        printf("ALM SEC_REG <-- %02x\n", value);
3867
#endif
3868
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3869
        omap_rtc_alarm_update(s);
3870
        return;
3871

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

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

    
3893
    case 0x2c:        /* ALARM_DAYS_REG */
3894
#if ALMDEBUG
3895
        printf("ALM DAY_REG <-- %02x\n", value);
3896
#endif
3897
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3898
        omap_rtc_alarm_update(s);
3899
        return;
3900

    
3901
    case 0x30:        /* ALARM_MONTHS_REG */
3902
#if ALMDEBUG
3903
        printf("ALM MON_REG <-- %02x\n", value);
3904
#endif
3905
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3906
        omap_rtc_alarm_update(s);
3907
        return;
3908

    
3909
    case 0x34:        /* ALARM_YEARS_REG */
3910
#if ALMDEBUG
3911
        printf("ALM YRS_REG <-- %02x\n", value);
3912
#endif
3913
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3914
        omap_rtc_alarm_update(s);
3915
        return;
3916

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

    
3929
    case 0x44:        /* RTC_STATUS_REG */
3930
#if ALMDEBUG
3931
        printf("RTC STATUSL <-- %02x\n", value);
3932
#endif
3933
        s->status &= ~((value & 0xc0) ^ 0x80);
3934
        omap_rtc_interrupts_update(s);
3935
        return;
3936

    
3937
    case 0x48:        /* RTC_INTERRUPTS_REG */
3938
#if ALMDEBUG
3939
        printf("RTC INTRS <-- %02x\n", value);
3940
#endif
3941
        s->interrupts = value;
3942
        return;
3943

    
3944
    case 0x4c:        /* RTC_COMP_LSB_REG */
3945
#if ALMDEBUG
3946
        printf("RTC COMPLSB <-- %02x\n", value);
3947
#endif
3948
        s->comp_reg &= 0xff00;
3949
        s->comp_reg |= 0x00ff & value;
3950
        return;
3951

    
3952
    case 0x50:        /* RTC_COMP_MSB_REG */
3953
#if ALMDEBUG
3954
        printf("RTC COMPMSB <-- %02x\n", value);
3955
#endif
3956
        s->comp_reg &= 0x00ff;
3957
        s->comp_reg |= 0xff00 & (value << 8);
3958
        return;
3959

    
3960
    default:
3961
        OMAP_BAD_REG(addr);
3962
        return;
3963
    }
3964
}
3965

    
3966
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3967
    omap_rtc_read,
3968
    omap_badwidth_read8,
3969
    omap_badwidth_read8,
3970
};
3971

    
3972
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3973
    omap_rtc_write,
3974
    omap_badwidth_write8,
3975
    omap_badwidth_write8,
3976
};
3977

    
3978
static void omap_rtc_tick(void *opaque)
3979
{
3980
    struct omap_rtc_s *s = opaque;
3981

    
3982
    if (s->round) {
3983
        /* Round to nearest full minute.  */
3984
        if (s->current_tm.tm_sec < 30)
3985
            s->ti -= s->current_tm.tm_sec;
3986
        else
3987
            s->ti += 60 - s->current_tm.tm_sec;
3988

    
3989
        s->round = 0;
3990
    }
3991

    
3992
    localtime_r(&s->ti, &s->current_tm);
3993

    
3994
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3995
        s->status |= 0x40;
3996
        omap_rtc_interrupts_update(s);
3997
    }
3998

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

    
4026
    /* Move on */
4027
    if (s->running)
4028
        s->ti ++;
4029
    s->tick += 1000;
4030

    
4031
    /*
4032
     * Every full hour add a rough approximation of the compensation
4033
     * register to the 32kHz Timer (which drives the RTC) value. 
4034
     */
4035
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
4036
        s->tick += s->comp_reg * 1000 / 32768;
4037

    
4038
    qemu_mod_timer(s->clk, s->tick);
4039
}
4040

    
4041
static void omap_rtc_reset(struct omap_rtc_s *s)
4042
{
4043
    s->interrupts = 0;
4044
    s->comp_reg = 0;
4045
    s->running = 0;
4046
    s->pm_am = 0;
4047
    s->auto_comp = 0;
4048
    s->round = 0;
4049
    s->tick = qemu_get_clock(rt_clock);
4050
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
4051
    s->alarm_tm.tm_mday = 0x01;
4052
    s->status = 1 << 7;
4053
    time(&s->ti);
4054
    s->ti = mktime(s->convert(&s->ti, &s->current_tm));
4055

    
4056
    omap_rtc_alarm_update(s);
4057
    omap_rtc_tick(s);
4058
}
4059

    
4060
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
4061
                qemu_irq *irq, omap_clk clk)
4062
{
4063
    int iomemtype;
4064
    struct omap_rtc_s *s = (struct omap_rtc_s *)
4065
            qemu_mallocz(sizeof(struct omap_rtc_s));
4066

    
4067
    s->base = base;
4068
    s->irq = irq[0];
4069
    s->alarm = irq[1];
4070
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
4071
    s->convert = rtc_utc ? gmtime_r : localtime_r;
4072

    
4073
    omap_rtc_reset(s);
4074

    
4075
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
4076
                    omap_rtc_writefn, s);
4077
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4078

    
4079
    return s;
4080
}
4081

    
4082
/* Multi-channel Buffered Serial Port interfaces */
4083
struct omap_mcbsp_s {
4084
    target_phys_addr_t base;
4085
    qemu_irq txirq;
4086
    qemu_irq rxirq;
4087
    qemu_irq txdrq;
4088
    qemu_irq rxdrq;
4089

    
4090
    uint16_t spcr[2];
4091
    uint16_t rcr[2];
4092
    uint16_t xcr[2];
4093
    uint16_t srgr[2];
4094
    uint16_t mcr[2];
4095
    uint16_t pcr;
4096
    uint16_t rcer[8];
4097
    uint16_t xcer[8];
4098
    int tx_rate;
4099
    int rx_rate;
4100
    int tx_req;
4101
    int rx_req;
4102

    
4103
    struct i2s_codec_s *codec;
4104
    QEMUTimer *source_timer;
4105
    QEMUTimer *sink_timer;
4106
};
4107

    
4108
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
4109
{
4110
    int irq;
4111

    
4112
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
4113
    case 0:
4114
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
4115
        break;
4116
    case 3:
4117
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
4118
        break;
4119
    default:
4120
        irq = 0;
4121
        break;
4122
    }
4123

    
4124
    qemu_set_irq(s->rxirq, irq);
4125

    
4126
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
4127
    case 0:
4128
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
4129
        break;
4130
    case 3:
4131
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
4132
        break;
4133
    default:
4134
        irq = 0;
4135
        break;
4136
    }
4137

    
4138
    qemu_set_irq(s->txirq, irq);
4139
}
4140

    
4141
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
4142
{
4143
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
4144
        s->spcr[0] |= 1 << 2;                                /* RFULL */
4145
    s->spcr[0] |= 1 << 1;                                /* RRDY */
4146
    qemu_irq_raise(s->rxdrq);
4147
    omap_mcbsp_intr_update(s);
4148
}
4149

    
4150
static void omap_mcbsp_source_tick(void *opaque)
4151
{
4152
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4153
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
4154

    
4155
    if (!s->rx_rate)
4156
        return;
4157
    if (s->rx_req)
4158
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
4159

    
4160
    s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
4161

    
4162
    omap_mcbsp_rx_newdata(s);
4163
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
4164
}
4165

    
4166
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
4167
{
4168
    if (!s->codec || !s->codec->rts)
4169
        omap_mcbsp_source_tick(s);
4170
    else if (s->codec->in.len) {
4171
        s->rx_req = s->codec->in.len;
4172
        omap_mcbsp_rx_newdata(s);
4173
    }
4174
}
4175

    
4176
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
4177
{
4178
    qemu_del_timer(s->source_timer);
4179
}
4180

    
4181
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
4182
{
4183
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
4184
    qemu_irq_lower(s->rxdrq);
4185
    omap_mcbsp_intr_update(s);
4186
}
4187

    
4188
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
4189
{
4190
    s->spcr[1] |= 1 << 1;                                /* XRDY */
4191
    qemu_irq_raise(s->txdrq);
4192
    omap_mcbsp_intr_update(s);
4193
}
4194

    
4195
static void omap_mcbsp_sink_tick(void *opaque)
4196
{
4197
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4198
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
4199

    
4200
    if (!s->tx_rate)
4201
        return;
4202
    if (s->tx_req)
4203
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
4204

    
4205
    s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
4206

    
4207
    omap_mcbsp_tx_newdata(s);
4208
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
4209
}
4210

    
4211
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
4212
{
4213
    if (!s->codec || !s->codec->cts)
4214
        omap_mcbsp_sink_tick(s);
4215
    else if (s->codec->out.size) {
4216
        s->tx_req = s->codec->out.size;
4217
        omap_mcbsp_tx_newdata(s);
4218
    }
4219
}
4220

    
4221
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
4222
{
4223
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
4224
    qemu_irq_lower(s->txdrq);
4225
    omap_mcbsp_intr_update(s);
4226
    if (s->codec && s->codec->cts)
4227
        s->codec->tx_swallow(s->codec->opaque);
4228
}
4229

    
4230
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
4231
{
4232
    s->tx_req = 0;
4233
    omap_mcbsp_tx_done(s);
4234
    qemu_del_timer(s->sink_timer);
4235
}
4236

    
4237
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
4238
{
4239
    int prev_rx_rate, prev_tx_rate;
4240
    int rx_rate = 0, tx_rate = 0;
4241
    int cpu_rate = 1500000;        /* XXX */
4242

    
4243
    /* TODO: check CLKSTP bit */
4244
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
4245
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
4246
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
4247
                            (s->pcr & (1 << 8))) {        /* CLKRM */
4248
                if (~s->pcr & (1 << 7))                        /* SCLKME */
4249
                    rx_rate = cpu_rate /
4250
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
4251
            } else
4252
                if (s->codec)
4253
                    rx_rate = s->codec->rx_rate;
4254
        }
4255

    
4256
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
4257
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
4258
                            (s->pcr & (1 << 9))) {        /* CLKXM */
4259
                if (~s->pcr & (1 << 7))                        /* SCLKME */
4260
                    tx_rate = cpu_rate /
4261
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
4262
            } else
4263
                if (s->codec)
4264
                    tx_rate = s->codec->tx_rate;
4265
        }
4266
    }
4267
    prev_tx_rate = s->tx_rate;
4268
    prev_rx_rate = s->rx_rate;
4269
    s->tx_rate = tx_rate;
4270
    s->rx_rate = rx_rate;
4271

    
4272
    if (s->codec)
4273
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
4274

    
4275
    if (!prev_tx_rate && tx_rate)
4276
        omap_mcbsp_tx_start(s);
4277
    else if (s->tx_rate && !tx_rate)
4278
        omap_mcbsp_tx_stop(s);
4279

    
4280
    if (!prev_rx_rate && rx_rate)
4281
        omap_mcbsp_rx_start(s);
4282
    else if (prev_tx_rate && !tx_rate)
4283
        omap_mcbsp_rx_stop(s);
4284
}
4285

    
4286
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
4287
{
4288
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4289
    int offset = addr & OMAP_MPUI_REG_MASK;
4290
    uint16_t ret;
4291

    
4292
    switch (offset) {
4293
    case 0x00:        /* DRR2 */
4294
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
4295
            return 0x0000;
4296
        /* Fall through.  */
4297
    case 0x02:        /* DRR1 */
4298
        if (s->rx_req < 2) {
4299
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
4300
            omap_mcbsp_rx_done(s);
4301
        } else {
4302
            s->tx_req -= 2;
4303
            if (s->codec && s->codec->in.len >= 2) {
4304
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
4305
                ret |= s->codec->in.fifo[s->codec->in.start ++];
4306
                s->codec->in.len -= 2;
4307
            } else
4308
                ret = 0x0000;
4309
            if (!s->tx_req)
4310
                omap_mcbsp_rx_done(s);
4311
            return ret;
4312
        }
4313
        return 0x0000;
4314

    
4315
    case 0x04:        /* DXR2 */
4316
    case 0x06:        /* DXR1 */
4317
        return 0x0000;
4318

    
4319
    case 0x08:        /* SPCR2 */
4320
        return s->spcr[1];
4321
    case 0x0a:        /* SPCR1 */
4322
        return s->spcr[0];
4323
    case 0x0c:        /* RCR2 */
4324
        return s->rcr[1];
4325
    case 0x0e:        /* RCR1 */
4326
        return s->rcr[0];
4327
    case 0x10:        /* XCR2 */
4328
        return s->xcr[1];
4329
    case 0x12:        /* XCR1 */
4330
        return s->xcr[0];
4331
    case 0x14:        /* SRGR2 */
4332
        return s->srgr[1];
4333
    case 0x16:        /* SRGR1 */
4334
        return s->srgr[0];
4335
    case 0x18:        /* MCR2 */
4336
        return s->mcr[1];
4337
    case 0x1a:        /* MCR1 */
4338
        return s->mcr[0];
4339
    case 0x1c:        /* RCERA */
4340
        return s->rcer[0];
4341
    case 0x1e:        /* RCERB */
4342
        return s->rcer[1];
4343
    case 0x20:        /* XCERA */
4344
        return s->xcer[0];
4345
    case 0x22:        /* XCERB */
4346
        return s->xcer[1];
4347
    case 0x24:        /* PCR0 */
4348
        return s->pcr;
4349
    case 0x26:        /* RCERC */
4350
        return s->rcer[2];
4351
    case 0x28:        /* RCERD */
4352
        return s->rcer[3];
4353
    case 0x2a:        /* XCERC */
4354
        return s->xcer[2];
4355
    case 0x2c:        /* XCERD */
4356
        return s->xcer[3];
4357
    case 0x2e:        /* RCERE */
4358
        return s->rcer[4];
4359
    case 0x30:        /* RCERF */
4360
        return s->rcer[5];
4361
    case 0x32:        /* XCERE */
4362
        return s->xcer[4];
4363
    case 0x34:        /* XCERF */
4364
        return s->xcer[5];
4365
    case 0x36:        /* RCERG */
4366
        return s->rcer[6];
4367
    case 0x38:        /* RCERH */
4368
        return s->rcer[7];
4369
    case 0x3a:        /* XCERG */
4370
        return s->xcer[6];
4371
    case 0x3c:        /* XCERH */
4372
        return s->xcer[7];
4373
    }
4374

    
4375
    OMAP_BAD_REG(addr);
4376
    return 0;
4377
}
4378

    
4379
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
4380
                uint32_t value)
4381
{
4382
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4383
    int offset = addr & OMAP_MPUI_REG_MASK;
4384

    
4385
    switch (offset) {
4386
    case 0x00:        /* DRR2 */
4387
    case 0x02:        /* DRR1 */
4388
        OMAP_RO_REG(addr);
4389
        return;
4390

    
4391
    case 0x04:        /* DXR2 */
4392
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4393
            return;
4394
        /* Fall through.  */
4395
    case 0x06:        /* DXR1 */
4396
        if (s->tx_req > 1) {
4397
            s->tx_req -= 2;
4398
            if (s->codec && s->codec->cts) {
4399
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
4400
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
4401
            }
4402
            if (s->tx_req < 2)
4403
                omap_mcbsp_tx_done(s);
4404
        } else
4405
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4406
        return;
4407

    
4408
    case 0x08:        /* SPCR2 */
4409
        s->spcr[1] &= 0x0002;
4410
        s->spcr[1] |= 0x03f9 & value;
4411
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
4412
        if (~value & 1)                                        /* XRST */
4413
            s->spcr[1] &= ~6;
4414
        omap_mcbsp_req_update(s);
4415
        return;
4416
    case 0x0a:        /* SPCR1 */
4417
        s->spcr[0] &= 0x0006;
4418
        s->spcr[0] |= 0xf8f9 & value;
4419
        if (value & (1 << 15))                                /* DLB */
4420
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
4421
        if (~value & 1) {                                /* RRST */
4422
            s->spcr[0] &= ~6;
4423
            s->rx_req = 0;
4424
            omap_mcbsp_rx_done(s);
4425
        }
4426
        omap_mcbsp_req_update(s);
4427
        return;
4428

    
4429
    case 0x0c:        /* RCR2 */
4430
        s->rcr[1] = value & 0xffff;
4431
        return;
4432
    case 0x0e:        /* RCR1 */
4433
        s->rcr[0] = value & 0x7fe0;
4434
        return;
4435
    case 0x10:        /* XCR2 */
4436
        s->xcr[1] = value & 0xffff;
4437
        return;
4438
    case 0x12:        /* XCR1 */
4439
        s->xcr[0] = value & 0x7fe0;
4440
        return;
4441
    case 0x14:        /* SRGR2 */
4442
        s->srgr[1] = value & 0xffff;
4443
        omap_mcbsp_req_update(s);
4444
        return;
4445
    case 0x16:        /* SRGR1 */
4446
        s->srgr[0] = value & 0xffff;
4447
        omap_mcbsp_req_update(s);
4448
        return;
4449
    case 0x18:        /* MCR2 */
4450
        s->mcr[1] = value & 0x03e3;
4451
        if (value & 3)                                        /* XMCM */
4452
            printf("%s: Tx channel selection mode enable attempt\n",
4453
                            __FUNCTION__);
4454
        return;
4455
    case 0x1a:        /* MCR1 */
4456
        s->mcr[0] = value & 0x03e1;
4457
        if (value & 1)                                        /* RMCM */
4458
            printf("%s: Rx channel selection mode enable attempt\n",
4459
                            __FUNCTION__);
4460
        return;
4461
    case 0x1c:        /* RCERA */
4462
        s->rcer[0] = value & 0xffff;
4463
        return;
4464
    case 0x1e:        /* RCERB */
4465
        s->rcer[1] = value & 0xffff;
4466
        return;
4467
    case 0x20:        /* XCERA */
4468
        s->xcer[0] = value & 0xffff;
4469
        return;
4470
    case 0x22:        /* XCERB */
4471
        s->xcer[1] = value & 0xffff;
4472
        return;
4473
    case 0x24:        /* PCR0 */
4474
        s->pcr = value & 0x7faf;
4475
        return;
4476
    case 0x26:        /* RCERC */
4477
        s->rcer[2] = value & 0xffff;
4478
        return;
4479
    case 0x28:        /* RCERD */
4480
        s->rcer[3] = value & 0xffff;
4481
        return;
4482
    case 0x2a:        /* XCERC */
4483
        s->xcer[2] = value & 0xffff;
4484
        return;
4485
    case 0x2c:        /* XCERD */
4486
        s->xcer[3] = value & 0xffff;
4487
        return;
4488
    case 0x2e:        /* RCERE */
4489
        s->rcer[4] = value & 0xffff;
4490
        return;
4491
    case 0x30:        /* RCERF */
4492
        s->rcer[5] = value & 0xffff;
4493
        return;
4494
    case 0x32:        /* XCERE */
4495
        s->xcer[4] = value & 0xffff;
4496
        return;
4497
    case 0x34:        /* XCERF */
4498
        s->xcer[5] = value & 0xffff;
4499
        return;
4500
    case 0x36:        /* RCERG */
4501
        s->rcer[6] = value & 0xffff;
4502
        return;
4503
    case 0x38:        /* RCERH */
4504
        s->rcer[7] = value & 0xffff;
4505
        return;
4506
    case 0x3a:        /* XCERG */
4507
        s->xcer[6] = value & 0xffff;
4508
        return;
4509
    case 0x3c:        /* XCERH */
4510
        s->xcer[7] = value & 0xffff;
4511
        return;
4512
    }
4513

    
4514
    OMAP_BAD_REG(addr);
4515
}
4516

    
4517
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
4518
                uint32_t value)
4519
{
4520
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4521
    int offset = addr & OMAP_MPUI_REG_MASK;
4522

    
4523
    if (offset == 0x04) {                                /* DXR */
4524
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4525
            return;
4526
        if (s->tx_req > 3) {
4527
            s->tx_req -= 4;
4528
            if (s->codec && s->codec->cts) {
4529
                s->codec->out.fifo[s->codec->out.len ++] =
4530
                        (value >> 24) & 0xff;
4531
                s->codec->out.fifo[s->codec->out.len ++] =
4532
                        (value >> 16) & 0xff;
4533
                s->codec->out.fifo[s->codec->out.len ++] =
4534
                        (value >> 8) & 0xff;
4535
                s->codec->out.fifo[s->codec->out.len ++] =
4536
                        (value >> 0) & 0xff;
4537
            }
4538
            if (s->tx_req < 4)
4539
                omap_mcbsp_tx_done(s);
4540
        } else
4541
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4542
        return;
4543
    }
4544

    
4545
    omap_badwidth_write16(opaque, addr, value);
4546
}
4547

    
4548
static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
4549
    omap_badwidth_read16,
4550
    omap_mcbsp_read,
4551
    omap_badwidth_read16,
4552
};
4553

    
4554
static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
4555
    omap_badwidth_write16,
4556
    omap_mcbsp_writeh,
4557
    omap_mcbsp_writew,
4558
};
4559

    
4560
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
4561
{
4562
    memset(&s->spcr, 0, sizeof(s->spcr));
4563
    memset(&s->rcr, 0, sizeof(s->rcr));
4564
    memset(&s->xcr, 0, sizeof(s->xcr));
4565
    s->srgr[0] = 0x0001;
4566
    s->srgr[1] = 0x2000;
4567
    memset(&s->mcr, 0, sizeof(s->mcr));
4568
    memset(&s->pcr, 0, sizeof(s->pcr));
4569
    memset(&s->rcer, 0, sizeof(s->rcer));
4570
    memset(&s->xcer, 0, sizeof(s->xcer));
4571
    s->tx_req = 0;
4572
    s->rx_req = 0;
4573
    s->tx_rate = 0;
4574
    s->rx_rate = 0;
4575
    qemu_del_timer(s->source_timer);
4576
    qemu_del_timer(s->sink_timer);
4577
}
4578

    
4579
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
4580
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
4581
{
4582
    int iomemtype;
4583
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
4584
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
4585

    
4586
    s->base = base;
4587
    s->txirq = irq[0];
4588
    s->rxirq = irq[1];
4589
    s->txdrq = dma[0];
4590
    s->rxdrq = dma[1];
4591
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
4592
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
4593
    omap_mcbsp_reset(s);
4594

    
4595
    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
4596
                    omap_mcbsp_writefn, s);
4597
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4598

    
4599
    return s;
4600
}
4601

    
4602
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4603
{
4604
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4605

    
4606
    if (s->rx_rate) {
4607
        s->rx_req = s->codec->in.len;
4608
        omap_mcbsp_rx_newdata(s);
4609
    }
4610
}
4611

    
4612
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
4613
{
4614
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4615

    
4616
    if (s->tx_rate) {
4617
        s->tx_req = s->codec->out.size;
4618
        omap_mcbsp_tx_newdata(s);
4619
    }
4620
}
4621

    
4622
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
4623
{
4624
    s->codec = slave;
4625
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4626
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4627
}
4628

    
4629
/* LED Pulse Generators */
4630
struct omap_lpg_s {
4631
    target_phys_addr_t base;
4632
    QEMUTimer *tm;
4633

    
4634
    uint8_t control;
4635
    uint8_t power;
4636
    int64_t on;
4637
    int64_t period;
4638
    int clk;
4639
    int cycle;
4640
};
4641

    
4642
static void omap_lpg_tick(void *opaque)
4643
{
4644
    struct omap_lpg_s *s = opaque;
4645

    
4646
    if (s->cycle)
4647
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
4648
    else
4649
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
4650

    
4651
    s->cycle = !s->cycle;
4652
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
4653
}
4654

    
4655
static void omap_lpg_update(struct omap_lpg_s *s)
4656
{
4657
    int64_t on, period = 1, ticks = 1000;
4658
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
4659

    
4660
    if (~s->control & (1 << 6))                                        /* LPGRES */
4661
        on = 0;
4662
    else if (s->control & (1 << 7))                                /* PERM_ON */
4663
        on = period;
4664
    else {
4665
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
4666
                        256 / 32);
4667
        on = (s->clk && s->power) ? muldiv64(ticks,
4668
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
4669
    }
4670

    
4671
    qemu_del_timer(s->tm);
4672
    if (on == period && s->on < s->period)
4673
        printf("%s: LED is on\n", __FUNCTION__);
4674
    else if (on == 0 && s->on)
4675
        printf("%s: LED is off\n", __FUNCTION__);
4676
    else if (on && (on != s->on || period != s->period)) {
4677
        s->cycle = 0;
4678
        s->on = on;
4679
        s->period = period;
4680
        omap_lpg_tick(s);
4681
        return;
4682
    }
4683

    
4684
    s->on = on;
4685
    s->period = period;
4686
}
4687

    
4688
static void omap_lpg_reset(struct omap_lpg_s *s)
4689
{
4690
    s->control = 0x00;
4691
    s->power = 0x00;
4692
    s->clk = 1;
4693
    omap_lpg_update(s);
4694
}
4695

    
4696
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
4697
{
4698
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4699
    int offset = addr & OMAP_MPUI_REG_MASK;
4700

    
4701
    switch (offset) {
4702
    case 0x00:        /* LCR */
4703
        return s->control;
4704

    
4705
    case 0x04:        /* PMR */
4706
        return s->power;
4707
    }
4708

    
4709
    OMAP_BAD_REG(addr);
4710
    return 0;
4711
}
4712

    
4713
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
4714
                uint32_t value)
4715
{
4716
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4717
    int offset = addr & OMAP_MPUI_REG_MASK;
4718

    
4719
    switch (offset) {
4720
    case 0x00:        /* LCR */
4721
        if (~value & (1 << 6))                                        /* LPGRES */
4722
            omap_lpg_reset(s);
4723
        s->control = value & 0xff;
4724
        omap_lpg_update(s);
4725
        return;
4726

    
4727
    case 0x04:        /* PMR */
4728
        s->power = value & 0x01;
4729
        omap_lpg_update(s);
4730
        return;
4731

    
4732
    default:
4733
        OMAP_BAD_REG(addr);
4734
        return;
4735
    }
4736
}
4737

    
4738
static CPUReadMemoryFunc *omap_lpg_readfn[] = {
4739
    omap_lpg_read,
4740
    omap_badwidth_read8,
4741
    omap_badwidth_read8,
4742
};
4743

    
4744
static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
4745
    omap_lpg_write,
4746
    omap_badwidth_write8,
4747
    omap_badwidth_write8,
4748
};
4749

    
4750
static void omap_lpg_clk_update(void *opaque, int line, int on)
4751
{
4752
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4753

    
4754
    s->clk = on;
4755
    omap_lpg_update(s);
4756
}
4757

    
4758
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4759
{
4760
    int iomemtype;
4761
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4762
            qemu_mallocz(sizeof(struct omap_lpg_s));
4763

    
4764
    s->base = base;
4765
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4766

    
4767
    omap_lpg_reset(s);
4768

    
4769
    iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
4770
                    omap_lpg_writefn, s);
4771
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4772

    
4773
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4774

    
4775
    return s;
4776
}
4777

    
4778
/* MPUI Peripheral Bridge configuration */
4779
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
4780
{
4781
    if (addr == OMAP_MPUI_BASE)        /* CMR */
4782
        return 0xfe4d;
4783

    
4784
    OMAP_BAD_REG(addr);
4785
    return 0;
4786
}
4787

    
4788
static CPUReadMemoryFunc *omap_mpui_io_readfn[] = {
4789
    omap_badwidth_read16,
4790
    omap_mpui_io_read,
4791
    omap_badwidth_read16,
4792
};
4793

    
4794
static CPUWriteMemoryFunc *omap_mpui_io_writefn[] = {
4795
    omap_badwidth_write16,
4796
    omap_badwidth_write16,
4797
    omap_badwidth_write16,
4798
};
4799

    
4800
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4801
{
4802
    int iomemtype = cpu_register_io_memory(0, omap_mpui_io_readfn,
4803
                    omap_mpui_io_writefn, mpu);
4804
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
4805
}
4806

    
4807
/* General chip reset */
4808
static void omap_mpu_reset(void *opaque)
4809
{
4810
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4811

    
4812
    omap_clkm_reset(mpu);
4813
    omap_inth_reset(mpu->ih[0]);
4814
    omap_inth_reset(mpu->ih[1]);
4815
    omap_dma_reset(mpu->dma);
4816
    omap_mpu_timer_reset(mpu->timer[0]);
4817
    omap_mpu_timer_reset(mpu->timer[1]);
4818
    omap_mpu_timer_reset(mpu->timer[2]);
4819
    omap_wd_timer_reset(mpu->wdt);
4820
    omap_os_timer_reset(mpu->os_timer);
4821
    omap_lcdc_reset(mpu->lcd);
4822
    omap_ulpd_pm_reset(mpu);
4823
    omap_pin_cfg_reset(mpu);
4824
    omap_mpui_reset(mpu);
4825
    omap_tipb_bridge_reset(mpu->private_tipb);
4826
    omap_tipb_bridge_reset(mpu->public_tipb);
4827
    omap_dpll_reset(&mpu->dpll[0]);
4828
    omap_dpll_reset(&mpu->dpll[1]);
4829
    omap_dpll_reset(&mpu->dpll[2]);
4830
    omap_uart_reset(mpu->uart[0]);
4831
    omap_uart_reset(mpu->uart[1]);
4832
    omap_uart_reset(mpu->uart[2]);
4833
    omap_mmc_reset(mpu->mmc);
4834
    omap_mpuio_reset(mpu->mpuio);
4835
    omap_gpio_reset(mpu->gpio);
4836
    omap_uwire_reset(mpu->microwire);
4837
    omap_pwl_reset(mpu);
4838
    omap_pwt_reset(mpu);
4839
    omap_i2c_reset(mpu->i2c);
4840
    omap_rtc_reset(mpu->rtc);
4841
    omap_mcbsp_reset(mpu->mcbsp1);
4842
    omap_mcbsp_reset(mpu->mcbsp2);
4843
    omap_mcbsp_reset(mpu->mcbsp3);
4844
    omap_lpg_reset(mpu->led[0]);
4845
    omap_lpg_reset(mpu->led[1]);
4846
    cpu_reset(mpu->env);
4847
}
4848

    
4849
static const struct omap_map_s {
4850
    target_phys_addr_t phys_dsp;
4851
    target_phys_addr_t phys_mpu;
4852
    uint32_t size;
4853
    const char *name;
4854
} omap15xx_dsp_mm[] = {
4855
    /* Strobe 0 */
4856
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
4857
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
4858
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
4859
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
4860
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
4861
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
4862
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
4863
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
4864
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
4865
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
4866
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
4867
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
4868
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
4869
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
4870
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
4871
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
4872
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
4873
    /* Strobe 1 */
4874
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
4875

    
4876
    { 0 }
4877
};
4878

    
4879
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4880
{
4881
    int io;
4882

    
4883
    for (; map->phys_dsp; map ++) {
4884
        io = cpu_get_physical_page_desc(map->phys_mpu);
4885

    
4886
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4887
    }
4888
}
4889

    
4890
static void omap_mpu_wakeup(void *opaque, int irq, int req)
4891
{
4892
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4893

    
4894
    if (mpu->env->halted)
4895
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4896
}
4897

    
4898
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4899
                DisplayState *ds, const char *core)
4900
{
4901
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4902
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4903
    ram_addr_t imif_base, emiff_base;
4904
    
4905
    if (!core)
4906
        core = "ti925t";
4907

    
4908
    /* Core */
4909
    s->mpu_model = omap310;
4910
    s->env = cpu_init(core);
4911
    if (!s->env) {
4912
        fprintf(stderr, "Unable to find CPU definition\n");
4913
        exit(1);
4914
    }
4915
    s->sdram_size = sdram_size;
4916
    s->sram_size = OMAP15XX_SRAM_SIZE;
4917

    
4918
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4919

    
4920
    /* Clocks */
4921
    omap_clk_init(s);
4922

    
4923
    /* Memory-mapped stuff */
4924
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4925
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4926
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4927
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4928

    
4929
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4930

    
4931
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100,
4932
                    arm_pic_init_cpu(s->env),
4933
                    omap_findclk(s, "arminth_ck"));
4934
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800,
4935
                    &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ],
4936
                    omap_findclk(s, "arminth_ck"));
4937
    s->irq[0] = s->ih[0]->pins;
4938
    s->irq[1] = s->ih[1]->pins;
4939

    
4940
    s->dma = omap_dma_init(0xfffed800, s->irq[0], s,
4941
                    omap_findclk(s, "dma_ck"));
4942
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4943
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4944
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4945
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4946
    s->port[local    ].addr_valid = omap_validate_local_addr;
4947
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4948

    
4949
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4950
                    s->irq[0][OMAP_INT_TIMER1],
4951
                    omap_findclk(s, "mputim_ck"));
4952
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4953
                    s->irq[0][OMAP_INT_TIMER2],
4954
                    omap_findclk(s, "mputim_ck"));
4955
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4956
                    s->irq[0][OMAP_INT_TIMER3],
4957
                    omap_findclk(s, "mputim_ck"));
4958

    
4959
    s->wdt = omap_wd_timer_init(0xfffec800,
4960
                    s->irq[0][OMAP_INT_WD_TIMER],
4961
                    omap_findclk(s, "armwdt_ck"));
4962

    
4963
    s->os_timer = omap_os_timer_init(0xfffb9000,
4964
                    s->irq[1][OMAP_INT_OS_TIMER],
4965
                    omap_findclk(s, "clk32-kHz"));
4966

    
4967
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4968
                    &s->dma->lcd_ch, ds, imif_base, emiff_base,
4969
                    omap_findclk(s, "lcd_ck"));
4970

    
4971
    omap_ulpd_pm_init(0xfffe0800, s);
4972
    omap_pin_cfg_init(0xfffe1000, s);
4973
    omap_id_init(s);
4974

    
4975
    omap_mpui_init(0xfffec900, s);
4976

    
4977
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4978
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4979
                    omap_findclk(s, "tipb_ck"));
4980
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4981
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4982
                    omap_findclk(s, "tipb_ck"));
4983

    
4984
    omap_tcmi_init(0xfffecc00, s);
4985

    
4986
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4987
                    omap_findclk(s, "uart1_ck"),
4988
                    serial_hds[0]);
4989
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4990
                    omap_findclk(s, "uart2_ck"),
4991
                    serial_hds[0] ? serial_hds[1] : 0);
4992
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4993
                    omap_findclk(s, "uart3_ck"),
4994
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4995

    
4996
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4997
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4998
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4999

    
5000
    s->mmc = omap_mmc_init(0xfffb7800, sd_bdrv, s->irq[1][OMAP_INT_OQN],
5001
                    &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
5002

    
5003
    s->mpuio = omap_mpuio_init(0xfffb5000,
5004
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
5005
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
5006

    
5007
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
5008
                    omap_findclk(s, "arm_gpio_ck"));
5009

    
5010
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
5011
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
5012

    
5013
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
5014
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
5015

    
5016
    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
5017
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
5018

    
5019
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
5020
                    omap_findclk(s, "clk32-kHz"));
5021

    
5022
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
5023
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
5024
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
5025
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
5026
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
5027
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
5028

    
5029
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
5030
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
5031

    
5032
    /* Register mappings not currenlty implemented:
5033
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
5034
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
5035
     * USB W2FC                fffb4000 - fffb47ff
5036
     * Camera Interface        fffb6800 - fffb6fff
5037
     * USB Host                fffba000 - fffba7ff
5038
     * FAC                fffba800 - fffbafff
5039
     * HDQ/1-Wire        fffbc000 - fffbc7ff
5040
     * TIPB switches        fffbc800 - fffbcfff
5041
     * Mailbox                fffcf000 - fffcf7ff
5042
     * Local bus IF        fffec100 - fffec1ff
5043
     * Local bus MMU        fffec200 - fffec2ff
5044
     * DSP MMU                fffed200 - fffed2ff
5045
     */
5046

    
5047
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
5048
    omap_setup_mpui_io(s);
5049

    
5050
    qemu_register_reset(omap_mpu_reset, s);
5051

    
5052
    return s;
5053
}