Statistics
| Branch: | Revision:

root / hw / omap.c @ 106627d0

History | View | Annotate | Download (140.7 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_bank_s {
84
    uint32_t irqs;
85
    uint32_t inputs;
86
    uint32_t mask;
87
    uint32_t fiq;
88
    uint32_t sens_edge;
89
    unsigned char priority[32];
90
};
91

    
92
struct omap_intr_handler_s {
93
    qemu_irq *pins;
94
    qemu_irq parent_intr[2];
95
    target_phys_addr_t base;
96
    unsigned char nbanks;
97

    
98
    /* state */
99
    uint32_t new_agr[2];
100
    int sir_intr[2];
101
    struct omap_intr_handler_bank_s banks[];
102
};
103

    
104
static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
105
{
106
    int i, j, sir_intr, p_intr, p, f;
107
    uint32_t level;
108
    sir_intr = 0;
109
    p_intr = 255;
110

    
111
    /* Find the interrupt line with the highest dynamic priority.
112
     * Note: 0 denotes the hightest priority.
113
     * If all interrupts have the same priority, the default order is IRQ_N,
114
     * IRQ_N-1,...,IRQ_0. */
115
    for (j = 0; j < s->nbanks; ++j) {
116
        level = s->banks[j].irqs & ~s->banks[j].mask &
117
                (is_fiq ? s->banks[j].fiq : ~s->banks[j].fiq);
118
        for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,
119
                        level >>= f) {
120
            p = s->banks[j].priority[i];
121
            if (p <= p_intr) {
122
                p_intr = p;
123
                sir_intr = 32 * j + i;
124
            }
125
            f = ffs(level >> 1);
126
        }
127
    }
128
    s->sir_intr[is_fiq] = sir_intr;
129
}
130

    
131
static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
132
{
133
    int i;
134
    uint32_t has_intr = 0;
135

    
136
    for (i = 0; i < s->nbanks; ++i)
137
        has_intr |= s->banks[i].irqs & ~s->banks[i].mask &
138
                (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq);
139

    
140
    if (s->new_agr[is_fiq] && has_intr) {
141
        s->new_agr[is_fiq] = 0;
142
        omap_inth_sir_update(s, is_fiq);
143
        qemu_set_irq(s->parent_intr[is_fiq], 1);
144
    }
145
}
146

    
147
#define INT_FALLING_EDGE        0
148
#define INT_LOW_LEVEL                1
149

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

    
155
    struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5];
156
    int n = irq & 31;
157

    
158
    if (req) {
159
        rise = ~bank->irqs & (1 << n);
160
        if (~bank->sens_edge & (1 << n))
161
            rise &= ~bank->inputs & (1 << n);
162

    
163
        bank->inputs |= (1 << n);
164
        if (rise) {
165
            bank->irqs |= rise;
166
            omap_inth_update(ih, 0);
167
            omap_inth_update(ih, 1);
168
        }
169
    } else {
170
        rise = bank->sens_edge & bank->irqs & (1 << n);
171
        bank->irqs &= ~rise;
172
        bank->inputs &= ~(1 << n);
173
    }
174
}
175

    
176
static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
177
{
178
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
179
    int i, offset = addr - s->base;
180
    int bank_no = offset >> 8;
181
    int line_no;
182
    struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
183
    offset &= 0xff;
184

    
185
    switch (offset) {
186
    case 0x00:        /* ITR */
187
        return bank->irqs;
188

    
189
    case 0x04:        /* MIR */
190
        return bank->mask;
191

    
192
    case 0x10:        /* SIR_IRQ_CODE */
193
    case 0x14:  /* SIR_FIQ_CODE */
194
        if (bank_no != 0)
195
            break;
196
        line_no = s->sir_intr[(offset - 0x10) >> 2];
197
        bank = &s->banks[line_no >> 5];
198
        i = line_no & 31;
199
        if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
200
            bank->irqs &= ~(1 << i);
201
        return i;
202

    
203
    case 0x18:        /* CONTROL_REG */
204
        if (bank_no != 0)
205
            break;
206
        return 0;
207

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

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

    
248
    }
249
    OMAP_BAD_REG(addr);
250
    return 0;
251
}
252

    
253
static void omap_inth_write(void *opaque, target_phys_addr_t addr,
254
                uint32_t value)
255
{
256
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
257
    int i, offset = addr - s->base;
258
    int bank_no = offset >> 8;
259
    struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
260
    offset &= 0xff;
261

    
262
    switch (offset) {
263
    case 0x00:        /* ITR */
264
        /* Important: ignore the clearing if the IRQ is level-triggered and
265
           the input bit is 1 */
266
        bank->irqs &= value | (bank->inputs & bank->sens_edge);
267
        return;
268

    
269
    case 0x04:        /* MIR */
270
        bank->mask = value;
271
        omap_inth_update(s, 0);
272
        omap_inth_update(s, 1);
273
        return;
274

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

    
280
    case 0x18:        /* CONTROL_REG */
281
        if (bank_no != 0)
282
            break;
283
        if (value & 2) {
284
            qemu_set_irq(s->parent_intr[1], 0);
285
            s->new_agr[1] = ~0;
286
            omap_inth_update(s, 1);
287
        }
288
        if (value & 1) {
289
            qemu_set_irq(s->parent_intr[0], 0);
290
            s->new_agr[0] = ~0;
291
            omap_inth_update(s, 0);
292
        }
293
        return;
294

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

    
335
    case 0x9c:        /* ISR */
336
        for (i = 0; i < 32; i ++)
337
            if (value & (1 << i)) {
338
                omap_set_intr(s, 32 * bank_no + i, 1);
339
                return;
340
            }
341
        return;
342
    }
343
    OMAP_BAD_REG(addr);
344
}
345

    
346
static CPUReadMemoryFunc *omap_inth_readfn[] = {
347
    omap_badwidth_read32,
348
    omap_badwidth_read32,
349
    omap_inth_read,
350
};
351

    
352
static CPUWriteMemoryFunc *omap_inth_writefn[] = {
353
    omap_inth_write,
354
    omap_inth_write,
355
    omap_inth_write,
356
};
357

    
358
void omap_inth_reset(struct omap_intr_handler_s *s)
359
{
360
    int i;
361

    
362
    for (i = 0; i < s->nbanks; ++i){
363
        s->banks[i].irqs = 0x00000000;
364
        s->banks[i].mask = 0xffffffff;
365
        s->banks[i].sens_edge = 0x00000000;
366
        s->banks[i].fiq = 0x00000000;
367
        s->banks[i].inputs = 0x00000000;
368
        memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority));
369
    }
370

    
371
    s->new_agr[0] = ~0;
372
    s->new_agr[1] = ~0;
373
    s->sir_intr[0] = 0;
374
    s->sir_intr[1] = 0;
375

    
376
    qemu_set_irq(s->parent_intr[0], 0);
377
    qemu_set_irq(s->parent_intr[1], 0);
378
}
379

    
380
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
381
                unsigned long size, unsigned char nbanks,
382
                qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk)
383
{
384
    int iomemtype;
385
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
386
            qemu_mallocz(sizeof(struct omap_intr_handler_s) +
387
                            sizeof(struct omap_intr_handler_bank_s) * nbanks);
388

    
389
    s->parent_intr[0] = parent_irq;
390
    s->parent_intr[1] = parent_fiq;
391
    s->base = base;
392
    s->nbanks = nbanks;
393
    s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
394

    
395
    omap_inth_reset(s);
396

    
397
    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
398
                    omap_inth_writefn, s);
399
    cpu_register_physical_memory(s->base, size, iomemtype);
400

    
401
    return s;
402
}
403

    
404
/* OMAP1 DMA module */
405
typedef enum {
406
    constant = 0,
407
    post_incremented,
408
    single_index,
409
    double_index,
410
} omap_dma_addressing_t;
411

    
412
struct omap_dma_channel_s {
413
    int burst[2];
414
    int pack[2];
415
    enum omap_dma_port port[2];
416
    target_phys_addr_t addr[2];
417
    omap_dma_addressing_t mode[2];
418
    int data_type;
419
    int end_prog;
420
    int repeat;
421
    int auto_init;
422
    int priority;
423
    int fs;
424
    int sync;
425
    int running;
426
    int interrupts;
427
    int status;
428
    int signalled;
429
    int post_sync;
430
    int transfer;
431
    uint16_t elements;
432
    uint16_t frames;
433
    uint16_t frame_index;
434
    uint16_t element_index;
435
    uint16_t cpc;
436

    
437
    struct omap_dma_reg_set_s {
438
        target_phys_addr_t src, dest;
439
        int frame;
440
        int element;
441
        int frame_delta[2];
442
        int elem_delta[2];
443
        int frames;
444
        int elements;
445
    } active_set;
446
};
447

    
448
struct omap_dma_s {
449
    qemu_irq *ih;
450
    QEMUTimer *tm;
451
    struct omap_mpu_state_s *mpu;
452
    target_phys_addr_t base;
453
    omap_clk clk;
454
    int64_t delay;
455
    uint32_t drq;
456

    
457
    uint16_t gcr;
458
    int run_count;
459

    
460
    int chans;
461
    struct omap_dma_channel_s ch[16];
462
    struct omap_dma_lcd_channel_s lcd_ch;
463
};
464

    
465
static void omap_dma_interrupts_update(struct omap_dma_s *s)
466
{
467
    /* First three interrupts are shared between two channels each.  */
468
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH0_6],
469
                    (s->ch[0].status | s->ch[6].status) & 0x3f);
470
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH1_7],
471
                    (s->ch[1].status | s->ch[7].status) & 0x3f);
472
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH2_8],
473
                    (s->ch[2].status | s->ch[8].status) & 0x3f);
474
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH3],
475
                    (s->ch[3].status) & 0x3f);
476
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH4],
477
                    (s->ch[4].status) & 0x3f);
478
    qemu_set_irq(s->ih[OMAP_INT_DMA_CH5],
479
                    (s->ch[5].status) & 0x3f);
480
}
481

    
482
static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
483
{
484
    struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
485
    int i;
486

    
487
    /*
488
     * TODO: verify address ranges and alignment
489
     * TODO: port endianness
490
     */
491

    
492
    a->src = s->ch[ch].addr[0];
493
    a->dest = s->ch[ch].addr[1];
494
    a->frames = s->ch[ch].frames;
495
    a->elements = s->ch[ch].elements;
496
    a->frame = 0;
497
    a->element = 0;
498

    
499
    if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
500
        printf("%s: bad DMA request\n", __FUNCTION__);
501
        return;
502
    }
503

    
504
    for (i = 0; i < 2; i ++)
505
        switch (s->ch[ch].mode[i]) {
506
        case constant:
507
            a->elem_delta[i] = 0;
508
            a->frame_delta[i] = 0;
509
            break;
510
        case post_incremented:
511
            a->elem_delta[i] = s->ch[ch].data_type;
512
            a->frame_delta[i] = 0;
513
            break;
514
        case single_index:
515
            a->elem_delta[i] = s->ch[ch].data_type +
516
                s->ch[ch].element_index - 1;
517
            if (s->ch[ch].element_index > 0x7fff)
518
                a->elem_delta[i] -= 0x10000;
519
            a->frame_delta[i] = 0;
520
            break;
521
        case double_index:
522
            a->elem_delta[i] = s->ch[ch].data_type +
523
                s->ch[ch].element_index - 1;
524
            if (s->ch[ch].element_index > 0x7fff)
525
                a->elem_delta[i] -= 0x10000;
526
            a->frame_delta[i] = s->ch[ch].frame_index -
527
                s->ch[ch].element_index;
528
            if (s->ch[ch].frame_index > 0x7fff)
529
                a->frame_delta[i] -= 0x10000;
530
            break;
531
        default:
532
            break;
533
        }
534
}
535

    
536
static inline void omap_dma_request_run(struct omap_dma_s *s,
537
                int channel, int request)
538
{
539
next_channel:
540
    if (request > 0)
541
        for (; channel < 9; channel ++)
542
            if (s->ch[channel].sync == request && s->ch[channel].running)
543
                break;
544
    if (channel >= 9)
545
        return;
546

    
547
    if (s->ch[channel].transfer) {
548
        if (request > 0) {
549
            s->ch[channel ++].post_sync = request;
550
            goto next_channel;
551
        }
552
        s->ch[channel].status |= 0x02;        /* Synchronisation drop */
553
        omap_dma_interrupts_update(s);
554
        return;
555
    }
556

    
557
    if (!s->ch[channel].signalled)
558
        s->run_count ++;
559
    s->ch[channel].signalled = 1;
560

    
561
    if (request > 0)
562
        s->ch[channel].status |= 0x40;        /* External request */
563

    
564
    if (s->delay && !qemu_timer_pending(s->tm))
565
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
566

    
567
    if (request > 0) {
568
        channel ++;
569
        goto next_channel;
570
    }
571
}
572

    
573
static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel)
574
{
575
    if (s->ch[channel].signalled)
576
        s->run_count --;
577
    s->ch[channel].signalled = 0;
578

    
579
    if (!s->run_count)
580
        qemu_del_timer(s->tm);
581
}
582

    
583
static void omap_dma_channel_run(struct omap_dma_s *s)
584
{
585
    int ch;
586
    uint16_t status;
587
    uint8_t value[4];
588
    struct omap_dma_port_if_s *src_p, *dest_p;
589
    struct omap_dma_reg_set_s *a;
590

    
591
    for (ch = 0; ch < 9; ch ++) {
592
        a = &s->ch[ch].active_set;
593

    
594
        src_p = &s->mpu->port[s->ch[ch].port[0]];
595
        dest_p = &s->mpu->port[s->ch[ch].port[1]];
596
        if (s->ch[ch].signalled && (!src_p->addr_valid(s->mpu, a->src) ||
597
                    !dest_p->addr_valid(s->mpu, a->dest))) {
598
#if 0
599
            /* Bus time-out */
600
            if (s->ch[ch].interrupts & 0x01)
601
                s->ch[ch].status |= 0x01;
602
            omap_dma_request_stop(s, ch);
603
            continue;
604
#endif
605
            printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch);
606
        }
607

    
608
        status = s->ch[ch].status;
609
        while (status == s->ch[ch].status && s->ch[ch].signalled) {
610
            /* Transfer a single element */
611
            s->ch[ch].transfer = 1;
612
            cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
613
            cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
614
            s->ch[ch].transfer = 0;
615

    
616
            a->src += a->elem_delta[0];
617
            a->dest += a->elem_delta[1];
618
            a->element ++;
619

    
620
            /* Check interrupt conditions */
621
            if (a->element == a->elements) {
622
                a->element = 0;
623
                a->src += a->frame_delta[0];
624
                a->dest += a->frame_delta[1];
625
                a->frame ++;
626

    
627
                if (a->frame == a->frames) {
628
                    if (!s->ch[ch].repeat || !s->ch[ch].auto_init)
629
                        s->ch[ch].running = 0;
630

    
631
                    if (s->ch[ch].auto_init &&
632
                            (s->ch[ch].repeat ||
633
                             s->ch[ch].end_prog))
634
                        omap_dma_channel_load(s, ch);
635

    
636
                    if (s->ch[ch].interrupts & 0x20)
637
                        s->ch[ch].status |= 0x20;
638

    
639
                    if (!s->ch[ch].sync)
640
                        omap_dma_request_stop(s, ch);
641
                }
642

    
643
                if (s->ch[ch].interrupts & 0x08)
644
                    s->ch[ch].status |= 0x08;
645

    
646
                if (s->ch[ch].sync && s->ch[ch].fs &&
647
                                !(s->drq & (1 << s->ch[ch].sync))) {
648
                    s->ch[ch].status &= ~0x40;
649
                    omap_dma_request_stop(s, ch);
650
                }
651
            }
652

    
653
            if (a->element == 1 && a->frame == a->frames - 1)
654
                if (s->ch[ch].interrupts & 0x10)
655
                    s->ch[ch].status |= 0x10;
656

    
657
            if (a->element == (a->elements >> 1))
658
                if (s->ch[ch].interrupts & 0x04)
659
                    s->ch[ch].status |= 0x04;
660

    
661
            if (s->ch[ch].sync && !s->ch[ch].fs &&
662
                            !(s->drq & (1 << s->ch[ch].sync))) {
663
                s->ch[ch].status &= ~0x40;
664
                omap_dma_request_stop(s, ch);
665
            }
666

    
667
            /*
668
             * Process requests made while the element was
669
             * being transferred.
670
             */
671
            if (s->ch[ch].post_sync) {
672
                omap_dma_request_run(s, 0, s->ch[ch].post_sync);
673
                s->ch[ch].post_sync = 0;
674
            }
675

    
676
#if 0
677
            break;
678
#endif
679
        }
680

    
681
        s->ch[ch].cpc = a->dest & 0x0000ffff;
682
    }
683

    
684
    omap_dma_interrupts_update(s);
685
    if (s->run_count && s->delay)
686
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
687
}
688

    
689
static int omap_dma_ch_reg_read(struct omap_dma_s *s,
690
                int ch, int reg, uint16_t *value) {
691
    switch (reg) {
692
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
693
        *value = (s->ch[ch].burst[1] << 14) |
694
                (s->ch[ch].pack[1] << 13) |
695
                (s->ch[ch].port[1] << 9) |
696
                (s->ch[ch].burst[0] << 7) |
697
                (s->ch[ch].pack[0] << 6) |
698
                (s->ch[ch].port[0] << 2) |
699
                (s->ch[ch].data_type >> 1);
700
        break;
701

    
702
    case 0x02:        /* SYS_DMA_CCR_CH0 */
703
        *value = (s->ch[ch].mode[1] << 14) |
704
                (s->ch[ch].mode[0] << 12) |
705
                (s->ch[ch].end_prog << 11) |
706
                (s->ch[ch].repeat << 9) |
707
                (s->ch[ch].auto_init << 8) |
708
                (s->ch[ch].running << 7) |
709
                (s->ch[ch].priority << 6) |
710
                (s->ch[ch].fs << 5) | s->ch[ch].sync;
711
        break;
712

    
713
    case 0x04:        /* SYS_DMA_CICR_CH0 */
714
        *value = s->ch[ch].interrupts;
715
        break;
716

    
717
    case 0x06:        /* SYS_DMA_CSR_CH0 */
718
        /* FIXME: shared CSR for channels sharing the interrupts */
719
        *value = s->ch[ch].status;
720
        s->ch[ch].status &= 0x40;
721
        omap_dma_interrupts_update(s);
722
        break;
723

    
724
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
725
        *value = s->ch[ch].addr[0] & 0x0000ffff;
726
        break;
727

    
728
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
729
        *value = s->ch[ch].addr[0] >> 16;
730
        break;
731

    
732
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
733
        *value = s->ch[ch].addr[1] & 0x0000ffff;
734
        break;
735

    
736
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
737
        *value = s->ch[ch].addr[1] >> 16;
738
        break;
739

    
740
    case 0x10:        /* SYS_DMA_CEN_CH0 */
741
        *value = s->ch[ch].elements;
742
        break;
743

    
744
    case 0x12:        /* SYS_DMA_CFN_CH0 */
745
        *value = s->ch[ch].frames;
746
        break;
747

    
748
    case 0x14:        /* SYS_DMA_CFI_CH0 */
749
        *value = s->ch[ch].frame_index;
750
        break;
751

    
752
    case 0x16:        /* SYS_DMA_CEI_CH0 */
753
        *value = s->ch[ch].element_index;
754
        break;
755

    
756
    case 0x18:        /* SYS_DMA_CPC_CH0 */
757
        *value = s->ch[ch].cpc;
758
        break;
759

    
760
    default:
761
        return 1;
762
    }
763
    return 0;
764
}
765

    
766
static int omap_dma_ch_reg_write(struct omap_dma_s *s,
767
                int ch, int reg, uint16_t value) {
768
    switch (reg) {
769
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
770
        s->ch[ch].burst[1] = (value & 0xc000) >> 14;
771
        s->ch[ch].pack[1] = (value & 0x2000) >> 13;
772
        s->ch[ch].port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
773
        s->ch[ch].burst[0] = (value & 0x0180) >> 7;
774
        s->ch[ch].pack[0] = (value & 0x0040) >> 6;
775
        s->ch[ch].port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
776
        s->ch[ch].data_type = (1 << (value & 3));
777
        if (s->ch[ch].port[0] >= omap_dma_port_last)
778
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
779
                            s->ch[ch].port[0]);
780
        if (s->ch[ch].port[1] >= omap_dma_port_last)
781
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
782
                            s->ch[ch].port[1]);
783
        if ((value & 3) == 3)
784
            printf("%s: bad data_type for DMA channel %i\n", __FUNCTION__, ch);
785
        break;
786

    
787
    case 0x02:        /* SYS_DMA_CCR_CH0 */
788
        s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
789
        s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
790
        s->ch[ch].end_prog = (value & 0x0800) >> 11;
791
        s->ch[ch].repeat = (value & 0x0200) >> 9;
792
        s->ch[ch].auto_init = (value & 0x0100) >> 8;
793
        s->ch[ch].priority = (value & 0x0040) >> 6;
794
        s->ch[ch].fs = (value & 0x0020) >> 5;
795
        s->ch[ch].sync = value & 0x001f;
796
        if (value & 0x0080) {
797
            if (s->ch[ch].running) {
798
                if (!s->ch[ch].signalled &&
799
                                s->ch[ch].auto_init && s->ch[ch].end_prog)
800
                    omap_dma_channel_load(s, ch);
801
            } else {
802
                s->ch[ch].running = 1;
803
                omap_dma_channel_load(s, ch);
804
            }
805
            if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync)))
806
                omap_dma_request_run(s, ch, 0);
807
        } else {
808
            s->ch[ch].running = 0;
809
            omap_dma_request_stop(s, ch);
810
        }
811
        break;
812

    
813
    case 0x04:        /* SYS_DMA_CICR_CH0 */
814
        s->ch[ch].interrupts = value & 0x003f;
815
        break;
816

    
817
    case 0x06:        /* SYS_DMA_CSR_CH0 */
818
        return 1;
819

    
820
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
821
        s->ch[ch].addr[0] &= 0xffff0000;
822
        s->ch[ch].addr[0] |= value;
823
        break;
824

    
825
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
826
        s->ch[ch].addr[0] &= 0x0000ffff;
827
        s->ch[ch].addr[0] |= (uint32_t) value << 16;
828
        break;
829

    
830
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
831
        s->ch[ch].addr[1] &= 0xffff0000;
832
        s->ch[ch].addr[1] |= value;
833
        break;
834

    
835
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
836
        s->ch[ch].addr[1] &= 0x0000ffff;
837
        s->ch[ch].addr[1] |= (uint32_t) value << 16;
838
        break;
839

    
840
    case 0x10:        /* SYS_DMA_CEN_CH0 */
841
        s->ch[ch].elements = value & 0xffff;
842
        break;
843

    
844
    case 0x12:        /* SYS_DMA_CFN_CH0 */
845
        s->ch[ch].frames = value & 0xffff;
846
        break;
847

    
848
    case 0x14:        /* SYS_DMA_CFI_CH0 */
849
        s->ch[ch].frame_index = value & 0xffff;
850
        break;
851

    
852
    case 0x16:        /* SYS_DMA_CEI_CH0 */
853
        s->ch[ch].element_index = value & 0xffff;
854
        break;
855

    
856
    case 0x18:        /* SYS_DMA_CPC_CH0 */
857
        return 1;
858

    
859
    default:
860
        OMAP_BAD_REG((target_phys_addr_t) reg);
861
    }
862
    return 0;
863
}
864

    
865
static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
866
{
867
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
868
    int i, reg, ch, offset = addr - s->base;
869
    uint16_t ret;
870

    
871
    switch (offset) {
872
    case 0x000 ... 0x2fe:
873
        reg = offset & 0x3f;
874
        ch = (offset >> 6) & 0x0f;
875
        if (omap_dma_ch_reg_read(s, ch, reg, &ret))
876
            break;
877
        return ret;
878

    
879
    case 0x300:        /* SYS_DMA_LCD_CTRL */
880
        i = s->lcd_ch.condition;
881
        s->lcd_ch.condition = 0;
882
        qemu_irq_lower(s->lcd_ch.irq);
883
        return ((s->lcd_ch.src == imif) << 6) | (i << 3) |
884
                (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
885

    
886
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
887
        return s->lcd_ch.src_f1_top & 0xffff;
888

    
889
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
890
        return s->lcd_ch.src_f1_top >> 16;
891

    
892
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
893
        return s->lcd_ch.src_f1_bottom & 0xffff;
894

    
895
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
896
        return s->lcd_ch.src_f1_bottom >> 16;
897

    
898
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
899
        return s->lcd_ch.src_f2_top & 0xffff;
900

    
901
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
902
        return s->lcd_ch.src_f2_top >> 16;
903

    
904
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
905
        return s->lcd_ch.src_f2_bottom & 0xffff;
906

    
907
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
908
        return s->lcd_ch.src_f2_bottom >> 16;
909

    
910
    case 0x400:        /* SYS_DMA_GCR */
911
        return s->gcr;
912
    }
913

    
914
    OMAP_BAD_REG(addr);
915
    return 0;
916
}
917

    
918
static void omap_dma_write(void *opaque, target_phys_addr_t addr,
919
                uint32_t value)
920
{
921
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
922
    int reg, ch, offset = addr - s->base;
923

    
924
    switch (offset) {
925
    case 0x000 ... 0x2fe:
926
        reg = offset & 0x3f;
927
        ch = (offset >> 6) & 0x0f;
928
        if (omap_dma_ch_reg_write(s, ch, reg, value))
929
            OMAP_RO_REG(addr);
930
        break;
931

    
932
    case 0x300:        /* SYS_DMA_LCD_CTRL */
933
        s->lcd_ch.src = (value & 0x40) ? imif : emiff;
934
        s->lcd_ch.condition = 0;
935
        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
936
        s->lcd_ch.interrupts = (value >> 1) & 1;
937
        s->lcd_ch.dual = value & 1;
938
        break;
939

    
940
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
941
        s->lcd_ch.src_f1_top &= 0xffff0000;
942
        s->lcd_ch.src_f1_top |= 0x0000ffff & value;
943
        break;
944

    
945
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
946
        s->lcd_ch.src_f1_top &= 0x0000ffff;
947
        s->lcd_ch.src_f1_top |= value << 16;
948
        break;
949

    
950
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
951
        s->lcd_ch.src_f1_bottom &= 0xffff0000;
952
        s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
953
        break;
954

    
955
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
956
        s->lcd_ch.src_f1_bottom &= 0x0000ffff;
957
        s->lcd_ch.src_f1_bottom |= value << 16;
958
        break;
959

    
960
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
961
        s->lcd_ch.src_f2_top &= 0xffff0000;
962
        s->lcd_ch.src_f2_top |= 0x0000ffff & value;
963
        break;
964

    
965
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
966
        s->lcd_ch.src_f2_top &= 0x0000ffff;
967
        s->lcd_ch.src_f2_top |= value << 16;
968
        break;
969

    
970
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
971
        s->lcd_ch.src_f2_bottom &= 0xffff0000;
972
        s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
973
        break;
974

    
975
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
976
        s->lcd_ch.src_f2_bottom &= 0x0000ffff;
977
        s->lcd_ch.src_f2_bottom |= value << 16;
978
        break;
979

    
980
    case 0x400:        /* SYS_DMA_GCR */
981
        s->gcr = value & 0x000c;
982
        break;
983

    
984
    default:
985
        OMAP_BAD_REG(addr);
986
    }
987
}
988

    
989
static CPUReadMemoryFunc *omap_dma_readfn[] = {
990
    omap_badwidth_read16,
991
    omap_dma_read,
992
    omap_badwidth_read16,
993
};
994

    
995
static CPUWriteMemoryFunc *omap_dma_writefn[] = {
996
    omap_badwidth_write16,
997
    omap_dma_write,
998
    omap_badwidth_write16,
999
};
1000

    
1001
static void omap_dma_request(void *opaque, int drq, int req)
1002
{
1003
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1004
    /* The request pins are level triggered.  */
1005
    if (req) {
1006
        if (~s->drq & (1 << drq)) {
1007
            s->drq |= 1 << drq;
1008
            omap_dma_request_run(s, 0, drq);
1009
        }
1010
    } else
1011
        s->drq &= ~(1 << drq);
1012
}
1013

    
1014
static void omap_dma_clk_update(void *opaque, int line, int on)
1015
{
1016
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1017

    
1018
    if (on) {
1019
        /* TODO: make a clever calculation */
1020
        s->delay = ticks_per_sec >> 8;
1021
        if (s->run_count)
1022
            qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
1023
    } else {
1024
        s->delay = 0;
1025
        qemu_del_timer(s->tm);
1026
    }
1027
}
1028

    
1029
static void omap_dma_reset(struct omap_dma_s *s)
1030
{
1031
    int i;
1032

    
1033
    qemu_del_timer(s->tm);
1034
    s->gcr = 0x0004;
1035
    s->drq = 0x00000000;
1036
    s->run_count = 0;
1037
    s->lcd_ch.src = emiff;
1038
    s->lcd_ch.condition = 0;
1039
    s->lcd_ch.interrupts = 0;
1040
    s->lcd_ch.dual = 0;
1041
    memset(s->ch, 0, sizeof(s->ch));
1042
    for (i = 0; i < s->chans; i ++)
1043
        s->ch[i].interrupts = 0x0003;
1044
}
1045

    
1046
struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
1047
                qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk)
1048
{
1049
    int iomemtype;
1050
    struct omap_dma_s *s = (struct omap_dma_s *)
1051
            qemu_mallocz(sizeof(struct omap_dma_s));
1052

    
1053
    s->ih = pic;
1054
    s->base = base;
1055
    s->chans = 9;
1056
    s->mpu = mpu;
1057
    s->clk = clk;
1058
    s->lcd_ch.irq = pic[OMAP_INT_DMA_LCD];
1059
    s->lcd_ch.mpu = mpu;
1060
    s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1061
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1062
    mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1063
    omap_dma_reset(s);
1064
    omap_dma_clk_update(s, 0, 1);
1065

    
1066
    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1067
                    omap_dma_writefn, s);
1068
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
1069

    
1070
    return s;
1071
}
1072

    
1073
/* DMA ports */
1074
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1075
                target_phys_addr_t addr)
1076
{
1077
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1078
}
1079

    
1080
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1081
                target_phys_addr_t addr)
1082
{
1083
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1084
}
1085

    
1086
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1087
                target_phys_addr_t addr)
1088
{
1089
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1090
}
1091

    
1092
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1093
                target_phys_addr_t addr)
1094
{
1095
    return addr >= 0xfffb0000 && addr < 0xffff0000;
1096
}
1097

    
1098
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
1099
                target_phys_addr_t addr)
1100
{
1101
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1102
}
1103

    
1104
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1105
                target_phys_addr_t addr)
1106
{
1107
    return addr >= 0xe1010000 && addr < 0xe1020004;
1108
}
1109

    
1110
/* MPU OS timers */
1111
struct omap_mpu_timer_s {
1112
    qemu_irq irq;
1113
    omap_clk clk;
1114
    target_phys_addr_t base;
1115
    uint32_t val;
1116
    int64_t time;
1117
    QEMUTimer *timer;
1118
    int64_t rate;
1119
    int it_ena;
1120

    
1121
    int enable;
1122
    int ptv;
1123
    int ar;
1124
    int st;
1125
    uint32_t reset_val;
1126
};
1127

    
1128
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1129
{
1130
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
1131

    
1132
    if (timer->st && timer->enable && timer->rate)
1133
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
1134
                        timer->rate, ticks_per_sec);
1135
    else
1136
        return timer->val;
1137
}
1138

    
1139
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1140
{
1141
    timer->val = omap_timer_read(timer);
1142
    timer->time = qemu_get_clock(vm_clock);
1143
}
1144

    
1145
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1146
{
1147
    int64_t expires;
1148

    
1149
    if (timer->enable && timer->st && timer->rate) {
1150
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
1151
        expires = muldiv64(timer->val << (timer->ptv + 1),
1152
                        ticks_per_sec, timer->rate);
1153

    
1154
        /* If timer expiry would be sooner than in about 1 ms and
1155
         * auto-reload isn't set, then fire immediately.  This is a hack
1156
         * to make systems like PalmOS run in acceptable time.  PalmOS
1157
         * sets the interval to a very low value and polls the status bit
1158
         * in a busy loop when it wants to sleep just a couple of CPU
1159
         * ticks.  */
1160
        if (expires > (ticks_per_sec >> 10) || timer->ar)
1161
            qemu_mod_timer(timer->timer, timer->time + expires);
1162
        else {
1163
            timer->val = 0;
1164
            timer->st = 0;
1165
            if (timer->it_ena)
1166
                /* Edge-triggered irq */
1167
                qemu_irq_pulse(timer->irq);
1168
        }
1169
    } else
1170
        qemu_del_timer(timer->timer);
1171
}
1172

    
1173
static void omap_timer_tick(void *opaque)
1174
{
1175
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1176
    omap_timer_sync(timer);
1177

    
1178
    if (!timer->ar) {
1179
        timer->val = 0;
1180
        timer->st = 0;
1181
    }
1182

    
1183
    if (timer->it_ena)
1184
        /* Edge-triggered irq */
1185
        qemu_irq_pulse(timer->irq);
1186
    omap_timer_update(timer);
1187
}
1188

    
1189
static void omap_timer_clk_update(void *opaque, int line, int on)
1190
{
1191
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1192

    
1193
    omap_timer_sync(timer);
1194
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1195
    omap_timer_update(timer);
1196
}
1197

    
1198
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
1199
{
1200
    omap_clk_adduser(timer->clk,
1201
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
1202
    timer->rate = omap_clk_getrate(timer->clk);
1203
}
1204

    
1205
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
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
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1213

    
1214
    case 0x04:        /* LOAD_TIM */
1215
        break;
1216

    
1217
    case 0x08:        /* READ_TIM */
1218
        return omap_timer_read(s);
1219
    }
1220

    
1221
    OMAP_BAD_REG(addr);
1222
    return 0;
1223
}
1224

    
1225
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1226
                uint32_t value)
1227
{
1228
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1229
    int offset = addr - s->base;
1230

    
1231
    switch (offset) {
1232
    case 0x00:        /* CNTL_TIMER */
1233
        omap_timer_sync(s);
1234
        s->enable = (value >> 5) & 1;
1235
        s->ptv = (value >> 2) & 7;
1236
        s->ar = (value >> 1) & 1;
1237
        s->st = value & 1;
1238
        omap_timer_update(s);
1239
        return;
1240

    
1241
    case 0x04:        /* LOAD_TIM */
1242
        s->reset_val = value;
1243
        return;
1244

    
1245
    case 0x08:        /* READ_TIM */
1246
        OMAP_RO_REG(addr);
1247
        break;
1248

    
1249
    default:
1250
        OMAP_BAD_REG(addr);
1251
    }
1252
}
1253

    
1254
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1255
    omap_badwidth_read32,
1256
    omap_badwidth_read32,
1257
    omap_mpu_timer_read,
1258
};
1259

    
1260
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1261
    omap_badwidth_write32,
1262
    omap_badwidth_write32,
1263
    omap_mpu_timer_write,
1264
};
1265

    
1266
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
1267
{
1268
    qemu_del_timer(s->timer);
1269
    s->enable = 0;
1270
    s->reset_val = 31337;
1271
    s->val = 0;
1272
    s->ptv = 0;
1273
    s->ar = 0;
1274
    s->st = 0;
1275
    s->it_ena = 1;
1276
}
1277

    
1278
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1279
                qemu_irq irq, omap_clk clk)
1280
{
1281
    int iomemtype;
1282
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1283
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
1284

    
1285
    s->irq = irq;
1286
    s->clk = clk;
1287
    s->base = base;
1288
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
1289
    omap_mpu_timer_reset(s);
1290
    omap_timer_clk_setup(s);
1291

    
1292
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
1293
                    omap_mpu_timer_writefn, s);
1294
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1295

    
1296
    return s;
1297
}
1298

    
1299
/* Watchdog timer */
1300
struct omap_watchdog_timer_s {
1301
    struct omap_mpu_timer_s timer;
1302
    uint8_t last_wr;
1303
    int mode;
1304
    int free;
1305
    int reset;
1306
};
1307

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

    
1313
    switch (offset) {
1314
    case 0x00:        /* CNTL_TIMER */
1315
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
1316
                (s->timer.st << 7) | (s->free << 1);
1317

    
1318
    case 0x04:        /* READ_TIMER */
1319
        return omap_timer_read(&s->timer);
1320

    
1321
    case 0x08:        /* TIMER_MODE */
1322
        return s->mode << 15;
1323
    }
1324

    
1325
    OMAP_BAD_REG(addr);
1326
    return 0;
1327
}
1328

    
1329
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1330
                uint32_t value)
1331
{
1332
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1333
    int offset = addr - s->timer.base;
1334

    
1335
    switch (offset) {
1336
    case 0x00:        /* CNTL_TIMER */
1337
        omap_timer_sync(&s->timer);
1338
        s->timer.ptv = (value >> 9) & 7;
1339
        s->timer.ar = (value >> 8) & 1;
1340
        s->timer.st = (value >> 7) & 1;
1341
        s->free = (value >> 1) & 1;
1342
        omap_timer_update(&s->timer);
1343
        break;
1344

    
1345
    case 0x04:        /* LOAD_TIMER */
1346
        s->timer.reset_val = value & 0xffff;
1347
        break;
1348

    
1349
    case 0x08:        /* TIMER_MODE */
1350
        if (!s->mode && ((value >> 15) & 1))
1351
            omap_clk_get(s->timer.clk);
1352
        s->mode |= (value >> 15) & 1;
1353
        if (s->last_wr == 0xf5) {
1354
            if ((value & 0xff) == 0xa0) {
1355
                if (s->mode) {
1356
                    s->mode = 0;
1357
                    omap_clk_put(s->timer.clk);
1358
                }
1359
            } else {
1360
                /* XXX: on T|E hardware somehow this has no effect,
1361
                 * on Zire 71 it works as specified.  */
1362
                s->reset = 1;
1363
                qemu_system_reset_request();
1364
            }
1365
        }
1366
        s->last_wr = value & 0xff;
1367
        break;
1368

    
1369
    default:
1370
        OMAP_BAD_REG(addr);
1371
    }
1372
}
1373

    
1374
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
1375
    omap_badwidth_read16,
1376
    omap_wd_timer_read,
1377
    omap_badwidth_read16,
1378
};
1379

    
1380
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
1381
    omap_badwidth_write16,
1382
    omap_wd_timer_write,
1383
    omap_badwidth_write16,
1384
};
1385

    
1386
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
1387
{
1388
    qemu_del_timer(s->timer.timer);
1389
    if (!s->mode)
1390
        omap_clk_get(s->timer.clk);
1391
    s->mode = 1;
1392
    s->free = 1;
1393
    s->reset = 0;
1394
    s->timer.enable = 1;
1395
    s->timer.it_ena = 1;
1396
    s->timer.reset_val = 0xffff;
1397
    s->timer.val = 0;
1398
    s->timer.st = 0;
1399
    s->timer.ptv = 0;
1400
    s->timer.ar = 0;
1401
    omap_timer_update(&s->timer);
1402
}
1403

    
1404
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
1405
                qemu_irq irq, omap_clk clk)
1406
{
1407
    int iomemtype;
1408
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
1409
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
1410

    
1411
    s->timer.irq = irq;
1412
    s->timer.clk = clk;
1413
    s->timer.base = base;
1414
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1415
    omap_wd_timer_reset(s);
1416
    omap_timer_clk_setup(&s->timer);
1417

    
1418
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
1419
                    omap_wd_timer_writefn, s);
1420
    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
1421

    
1422
    return s;
1423
}
1424

    
1425
/* 32-kHz timer */
1426
struct omap_32khz_timer_s {
1427
    struct omap_mpu_timer_s timer;
1428
};
1429

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

    
1435
    switch (offset) {
1436
    case 0x00:        /* TVR */
1437
        return s->timer.reset_val;
1438

    
1439
    case 0x04:        /* TCR */
1440
        return omap_timer_read(&s->timer);
1441

    
1442
    case 0x08:        /* CR */
1443
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
1444

    
1445
    default:
1446
        break;
1447
    }
1448
    OMAP_BAD_REG(addr);
1449
    return 0;
1450
}
1451

    
1452
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1453
                uint32_t value)
1454
{
1455
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1456
    int offset = addr & OMAP_MPUI_REG_MASK;
1457

    
1458
    switch (offset) {
1459
    case 0x00:        /* TVR */
1460
        s->timer.reset_val = value & 0x00ffffff;
1461
        break;
1462

    
1463
    case 0x04:        /* TCR */
1464
        OMAP_RO_REG(addr);
1465
        break;
1466

    
1467
    case 0x08:        /* CR */
1468
        s->timer.ar = (value >> 3) & 1;
1469
        s->timer.it_ena = (value >> 2) & 1;
1470
        if (s->timer.st != (value & 1) || (value & 2)) {
1471
            omap_timer_sync(&s->timer);
1472
            s->timer.enable = value & 1;
1473
            s->timer.st = value & 1;
1474
            omap_timer_update(&s->timer);
1475
        }
1476
        break;
1477

    
1478
    default:
1479
        OMAP_BAD_REG(addr);
1480
    }
1481
}
1482

    
1483
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1484
    omap_badwidth_read32,
1485
    omap_badwidth_read32,
1486
    omap_os_timer_read,
1487
};
1488

    
1489
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1490
    omap_badwidth_write32,
1491
    omap_badwidth_write32,
1492
    omap_os_timer_write,
1493
};
1494

    
1495
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1496
{
1497
    qemu_del_timer(s->timer.timer);
1498
    s->timer.enable = 0;
1499
    s->timer.it_ena = 0;
1500
    s->timer.reset_val = 0x00ffffff;
1501
    s->timer.val = 0;
1502
    s->timer.st = 0;
1503
    s->timer.ptv = 0;
1504
    s->timer.ar = 1;
1505
}
1506

    
1507
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1508
                qemu_irq irq, omap_clk clk)
1509
{
1510
    int iomemtype;
1511
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1512
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1513

    
1514
    s->timer.irq = irq;
1515
    s->timer.clk = clk;
1516
    s->timer.base = base;
1517
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1518
    omap_os_timer_reset(s);
1519
    omap_timer_clk_setup(&s->timer);
1520

    
1521
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1522
                    omap_os_timer_writefn, s);
1523
    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
1524

    
1525
    return s;
1526
}
1527

    
1528
/* Ultra Low-Power Device Module */
1529
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1530
{
1531
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1532
    int offset = addr - s->ulpd_pm_base;
1533
    uint16_t ret;
1534

    
1535
    switch (offset) {
1536
    case 0x14:        /* IT_STATUS */
1537
        ret = s->ulpd_pm_regs[offset >> 2];
1538
        s->ulpd_pm_regs[offset >> 2] = 0;
1539
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1540
        return ret;
1541

    
1542
    case 0x18:        /* Reserved */
1543
    case 0x1c:        /* Reserved */
1544
    case 0x20:        /* Reserved */
1545
    case 0x28:        /* Reserved */
1546
    case 0x2c:        /* Reserved */
1547
        OMAP_BAD_REG(addr);
1548
    case 0x00:        /* COUNTER_32_LSB */
1549
    case 0x04:        /* COUNTER_32_MSB */
1550
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1551
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1552
    case 0x10:        /* GAUGING_CTRL */
1553
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1554
    case 0x30:        /* CLOCK_CTRL */
1555
    case 0x34:        /* SOFT_REQ */
1556
    case 0x38:        /* COUNTER_32_FIQ */
1557
    case 0x3c:        /* DPLL_CTRL */
1558
    case 0x40:        /* STATUS_REQ */
1559
        /* XXX: check clk::usecount state for every clock */
1560
    case 0x48:        /* LOCL_TIME */
1561
    case 0x4c:        /* APLL_CTRL */
1562
    case 0x50:        /* POWER_CTRL */
1563
        return s->ulpd_pm_regs[offset >> 2];
1564
    }
1565

    
1566
    OMAP_BAD_REG(addr);
1567
    return 0;
1568
}
1569

    
1570
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1571
                uint16_t diff, uint16_t value)
1572
{
1573
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
1574
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1575
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1576
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1577
}
1578

    
1579
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1580
                uint16_t diff, uint16_t value)
1581
{
1582
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1583
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1584
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1585
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1586
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1587
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1588
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1589
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1590
}
1591

    
1592
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1593
                uint32_t value)
1594
{
1595
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1596
    int offset = addr - s->ulpd_pm_base;
1597
    int64_t now, ticks;
1598
    int div, mult;
1599
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1600
    uint16_t diff;
1601

    
1602
    switch (offset) {
1603
    case 0x00:        /* COUNTER_32_LSB */
1604
    case 0x04:        /* COUNTER_32_MSB */
1605
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1606
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1607
    case 0x14:        /* IT_STATUS */
1608
    case 0x40:        /* STATUS_REQ */
1609
        OMAP_RO_REG(addr);
1610
        break;
1611

    
1612
    case 0x10:        /* GAUGING_CTRL */
1613
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1614
        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
1615
            now = qemu_get_clock(vm_clock);
1616

    
1617
            if (value & 1)
1618
                s->ulpd_gauge_start = now;
1619
            else {
1620
                now -= s->ulpd_gauge_start;
1621

    
1622
                /* 32-kHz ticks */
1623
                ticks = muldiv64(now, 32768, ticks_per_sec);
1624
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1625
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1626
                if (ticks >> 32)        /* OVERFLOW_32K */
1627
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1628

    
1629
                /* High frequency ticks */
1630
                ticks = muldiv64(now, 12000000, ticks_per_sec);
1631
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1632
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1633
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1634
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1635

    
1636
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
1637
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1638
            }
1639
        }
1640
        s->ulpd_pm_regs[offset >> 2] = value;
1641
        break;
1642

    
1643
    case 0x18:        /* Reserved */
1644
    case 0x1c:        /* Reserved */
1645
    case 0x20:        /* Reserved */
1646
    case 0x28:        /* Reserved */
1647
    case 0x2c:        /* Reserved */
1648
        OMAP_BAD_REG(addr);
1649
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1650
    case 0x38:        /* COUNTER_32_FIQ */
1651
    case 0x48:        /* LOCL_TIME */
1652
    case 0x50:        /* POWER_CTRL */
1653
        s->ulpd_pm_regs[offset >> 2] = value;
1654
        break;
1655

    
1656
    case 0x30:        /* CLOCK_CTRL */
1657
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1658
        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
1659
        omap_ulpd_clk_update(s, diff, value);
1660
        break;
1661

    
1662
    case 0x34:        /* SOFT_REQ */
1663
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1664
        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
1665
        omap_ulpd_req_update(s, diff, value);
1666
        break;
1667

    
1668
    case 0x3c:        /* DPLL_CTRL */
1669
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
1670
         * omitted altogether, probably a typo.  */
1671
        /* This register has identical semantics with DPLL(1:3) control
1672
         * registers, see omap_dpll_write() */
1673
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1674
        s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
1675
        if (diff & (0x3ff << 2)) {
1676
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1677
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1678
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1679
            } else {
1680
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1681
                mult = 1;
1682
            }
1683
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
1684
        }
1685

    
1686
        /* Enter the desired mode.  */
1687
        s->ulpd_pm_regs[offset >> 2] =
1688
                (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
1689
                ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
1690

    
1691
        /* Act as if the lock is restored.  */
1692
        s->ulpd_pm_regs[offset >> 2] |= 2;
1693
        break;
1694

    
1695
    case 0x4c:        /* APLL_CTRL */
1696
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1697
        s->ulpd_pm_regs[offset >> 2] = value & 0xf;
1698
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
1699
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1700
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
1701
        break;
1702

    
1703
    default:
1704
        OMAP_BAD_REG(addr);
1705
    }
1706
}
1707

    
1708
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1709
    omap_badwidth_read16,
1710
    omap_ulpd_pm_read,
1711
    omap_badwidth_read16,
1712
};
1713

    
1714
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1715
    omap_badwidth_write16,
1716
    omap_ulpd_pm_write,
1717
    omap_badwidth_write16,
1718
};
1719

    
1720
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
1721
{
1722
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
1723
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
1724
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
1725
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
1726
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
1727
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
1728
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
1729
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
1730
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
1731
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
1732
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
1733
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
1734
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
1735
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
1736
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
1737
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
1738
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
1739
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
1740
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
1741
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
1742
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
1743
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
1744
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
1745
}
1746

    
1747
static void omap_ulpd_pm_init(target_phys_addr_t base,
1748
                struct omap_mpu_state_s *mpu)
1749
{
1750
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1751
                    omap_ulpd_pm_writefn, mpu);
1752

    
1753
    mpu->ulpd_pm_base = base;
1754
    cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1755
    omap_ulpd_pm_reset(mpu);
1756
}
1757

    
1758
/* OMAP Pin Configuration */
1759
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1760
{
1761
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1762
    int offset = addr - s->pin_cfg_base;
1763

    
1764
    switch (offset) {
1765
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1766
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1767
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1768
        return s->func_mux_ctrl[offset >> 2];
1769

    
1770
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1771
        return s->comp_mode_ctrl[0];
1772

    
1773
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1774
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1775
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1776
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1777
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1778
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1779
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1780
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1781
    case 0x30:        /* FUNC_MUX_CTRL_B */
1782
    case 0x34:        /* FUNC_MUX_CTRL_C */
1783
    case 0x38:        /* FUNC_MUX_CTRL_D */
1784
        return s->func_mux_ctrl[(offset >> 2) - 1];
1785

    
1786
    case 0x40:        /* PULL_DWN_CTRL_0 */
1787
    case 0x44:        /* PULL_DWN_CTRL_1 */
1788
    case 0x48:        /* PULL_DWN_CTRL_2 */
1789
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1790
        return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1791

    
1792
    case 0x50:        /* GATE_INH_CTRL_0 */
1793
        return s->gate_inh_ctrl[0];
1794

    
1795
    case 0x60:        /* VOLTAGE_CTRL_0 */
1796
        return s->voltage_ctrl[0];
1797

    
1798
    case 0x70:        /* TEST_DBG_CTRL_0 */
1799
        return s->test_dbg_ctrl[0];
1800

    
1801
    case 0x80:        /* MOD_CONF_CTRL_0 */
1802
        return s->mod_conf_ctrl[0];
1803
    }
1804

    
1805
    OMAP_BAD_REG(addr);
1806
    return 0;
1807
}
1808

    
1809
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1810
                uint32_t diff, uint32_t value)
1811
{
1812
    if (s->compat1509) {
1813
        if (diff & (1 << 9))                        /* BLUETOOTH */
1814
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1815
                            (~value >> 9) & 1);
1816
        if (diff & (1 << 7))                        /* USB.CLKO */
1817
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
1818
                            (value >> 7) & 1);
1819
    }
1820
}
1821

    
1822
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1823
                uint32_t diff, uint32_t value)
1824
{
1825
    if (s->compat1509) {
1826
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
1827
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1828
                            (value >> 31) & 1);
1829
        if (diff & (1 << 1))                        /* CLK32K */
1830
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1831
                            (~value >> 1) & 1);
1832
    }
1833
}
1834

    
1835
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1836
                uint32_t diff, uint32_t value)
1837
{
1838
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
1839
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1840
                         omap_findclk(s, ((value >> 31) & 1) ?
1841
                                 "ck_48m" : "armper_ck"));
1842
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
1843
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1844
                         omap_findclk(s, ((value >> 30) & 1) ?
1845
                                 "ck_48m" : "armper_ck"));
1846
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
1847
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1848
                         omap_findclk(s, ((value >> 29) & 1) ?
1849
                                 "ck_48m" : "armper_ck"));
1850
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
1851
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1852
                         omap_findclk(s, ((value >> 23) & 1) ?
1853
                                 "ck_48m" : "armper_ck"));
1854
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
1855
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1856
                         omap_findclk(s, ((value >> 12) & 1) ?
1857
                                 "ck_48m" : "armper_ck"));
1858
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1859
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1860
}
1861

    
1862
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1863
                uint32_t value)
1864
{
1865
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1866
    int offset = addr - s->pin_cfg_base;
1867
    uint32_t diff;
1868

    
1869
    switch (offset) {
1870
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1871
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1872
        s->func_mux_ctrl[offset >> 2] = value;
1873
        omap_pin_funcmux0_update(s, diff, value);
1874
        return;
1875

    
1876
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1877
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1878
        s->func_mux_ctrl[offset >> 2] = value;
1879
        omap_pin_funcmux1_update(s, diff, value);
1880
        return;
1881

    
1882
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1883
        s->func_mux_ctrl[offset >> 2] = value;
1884
        return;
1885

    
1886
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1887
        s->comp_mode_ctrl[0] = value;
1888
        s->compat1509 = (value != 0x0000eaef);
1889
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1890
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1891
        return;
1892

    
1893
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1894
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1895
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1896
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1897
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1898
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1899
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1900
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1901
    case 0x30:        /* FUNC_MUX_CTRL_B */
1902
    case 0x34:        /* FUNC_MUX_CTRL_C */
1903
    case 0x38:        /* FUNC_MUX_CTRL_D */
1904
        s->func_mux_ctrl[(offset >> 2) - 1] = value;
1905
        return;
1906

    
1907
    case 0x40:        /* PULL_DWN_CTRL_0 */
1908
    case 0x44:        /* PULL_DWN_CTRL_1 */
1909
    case 0x48:        /* PULL_DWN_CTRL_2 */
1910
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1911
        s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1912
        return;
1913

    
1914
    case 0x50:        /* GATE_INH_CTRL_0 */
1915
        s->gate_inh_ctrl[0] = value;
1916
        return;
1917

    
1918
    case 0x60:        /* VOLTAGE_CTRL_0 */
1919
        s->voltage_ctrl[0] = value;
1920
        return;
1921

    
1922
    case 0x70:        /* TEST_DBG_CTRL_0 */
1923
        s->test_dbg_ctrl[0] = value;
1924
        return;
1925

    
1926
    case 0x80:        /* MOD_CONF_CTRL_0 */
1927
        diff = s->mod_conf_ctrl[0] ^ value;
1928
        s->mod_conf_ctrl[0] = value;
1929
        omap_pin_modconf1_update(s, diff, value);
1930
        return;
1931

    
1932
    default:
1933
        OMAP_BAD_REG(addr);
1934
    }
1935
}
1936

    
1937
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1938
    omap_badwidth_read32,
1939
    omap_badwidth_read32,
1940
    omap_pin_cfg_read,
1941
};
1942

    
1943
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1944
    omap_badwidth_write32,
1945
    omap_badwidth_write32,
1946
    omap_pin_cfg_write,
1947
};
1948

    
1949
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1950
{
1951
    /* Start in Compatibility Mode.  */
1952
    mpu->compat1509 = 1;
1953
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1954
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1955
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1956
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1957
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1958
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1959
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1960
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1961
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1962
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1963
}
1964

    
1965
static void omap_pin_cfg_init(target_phys_addr_t base,
1966
                struct omap_mpu_state_s *mpu)
1967
{
1968
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1969
                    omap_pin_cfg_writefn, mpu);
1970

    
1971
    mpu->pin_cfg_base = base;
1972
    cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1973
    omap_pin_cfg_reset(mpu);
1974
}
1975

    
1976
/* Device Identification, Die Identification */
1977
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1978
{
1979
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1980

    
1981
    switch (addr) {
1982
    case 0xfffe1800:        /* DIE_ID_LSB */
1983
        return 0xc9581f0e;
1984
    case 0xfffe1804:        /* DIE_ID_MSB */
1985
        return 0xa8858bfa;
1986

    
1987
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
1988
        return 0x00aaaafc;
1989
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
1990
        return 0xcafeb574;
1991

    
1992
    case 0xfffed400:        /* JTAG_ID_LSB */
1993
        switch (s->mpu_model) {
1994
        case omap310:
1995
            return 0x03310315;
1996
        case omap1510:
1997
            return 0x03310115;
1998
        }
1999
        break;
2000

    
2001
    case 0xfffed404:        /* JTAG_ID_MSB */
2002
        switch (s->mpu_model) {
2003
        case omap310:
2004
            return 0xfb57402f;
2005
        case omap1510:
2006
            return 0xfb47002f;
2007
        }
2008
        break;
2009
    }
2010

    
2011
    OMAP_BAD_REG(addr);
2012
    return 0;
2013
}
2014

    
2015
static void omap_id_write(void *opaque, target_phys_addr_t addr,
2016
                uint32_t value)
2017
{
2018
    OMAP_BAD_REG(addr);
2019
}
2020

    
2021
static CPUReadMemoryFunc *omap_id_readfn[] = {
2022
    omap_badwidth_read32,
2023
    omap_badwidth_read32,
2024
    omap_id_read,
2025
};
2026

    
2027
static CPUWriteMemoryFunc *omap_id_writefn[] = {
2028
    omap_badwidth_write32,
2029
    omap_badwidth_write32,
2030
    omap_id_write,
2031
};
2032

    
2033
static void omap_id_init(struct omap_mpu_state_s *mpu)
2034
{
2035
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
2036
                    omap_id_writefn, mpu);
2037
    cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
2038
    cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
2039
    if (!cpu_is_omap15xx(mpu))
2040
        cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
2041
}
2042

    
2043
/* MPUI Control (Dummy) */
2044
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
2045
{
2046
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2047
    int offset = addr - s->mpui_base;
2048

    
2049
    switch (offset) {
2050
    case 0x00:        /* CTRL */
2051
        return s->mpui_ctrl;
2052
    case 0x04:        /* DEBUG_ADDR */
2053
        return 0x01ffffff;
2054
    case 0x08:        /* DEBUG_DATA */
2055
        return 0xffffffff;
2056
    case 0x0c:        /* DEBUG_FLAG */
2057
        return 0x00000800;
2058
    case 0x10:        /* STATUS */
2059
        return 0x00000000;
2060

    
2061
    /* Not in OMAP310 */
2062
    case 0x14:        /* DSP_STATUS */
2063
    case 0x18:        /* DSP_BOOT_CONFIG */
2064
        return 0x00000000;
2065
    case 0x1c:        /* DSP_MPUI_CONFIG */
2066
        return 0x0000ffff;
2067
    }
2068

    
2069
    OMAP_BAD_REG(addr);
2070
    return 0;
2071
}
2072

    
2073
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2074
                uint32_t value)
2075
{
2076
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2077
    int offset = addr - s->mpui_base;
2078

    
2079
    switch (offset) {
2080
    case 0x00:        /* CTRL */
2081
        s->mpui_ctrl = value & 0x007fffff;
2082
        break;
2083

    
2084
    case 0x04:        /* DEBUG_ADDR */
2085
    case 0x08:        /* DEBUG_DATA */
2086
    case 0x0c:        /* DEBUG_FLAG */
2087
    case 0x10:        /* STATUS */
2088
    /* Not in OMAP310 */
2089
    case 0x14:        /* DSP_STATUS */
2090
        OMAP_RO_REG(addr);
2091
    case 0x18:        /* DSP_BOOT_CONFIG */
2092
    case 0x1c:        /* DSP_MPUI_CONFIG */
2093
        break;
2094

    
2095
    default:
2096
        OMAP_BAD_REG(addr);
2097
    }
2098
}
2099

    
2100
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2101
    omap_badwidth_read32,
2102
    omap_badwidth_read32,
2103
    omap_mpui_read,
2104
};
2105

    
2106
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2107
    omap_badwidth_write32,
2108
    omap_badwidth_write32,
2109
    omap_mpui_write,
2110
};
2111

    
2112
static void omap_mpui_reset(struct omap_mpu_state_s *s)
2113
{
2114
    s->mpui_ctrl = 0x0003ff1b;
2115
}
2116

    
2117
static void omap_mpui_init(target_phys_addr_t base,
2118
                struct omap_mpu_state_s *mpu)
2119
{
2120
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2121
                    omap_mpui_writefn, mpu);
2122

    
2123
    mpu->mpui_base = base;
2124
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2125

    
2126
    omap_mpui_reset(mpu);
2127
}
2128

    
2129
/* TIPB Bridges */
2130
struct omap_tipb_bridge_s {
2131
    target_phys_addr_t base;
2132
    qemu_irq abort;
2133

    
2134
    int width_intr;
2135
    uint16_t control;
2136
    uint16_t alloc;
2137
    uint16_t buffer;
2138
    uint16_t enh_control;
2139
};
2140

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

    
2146
    switch (offset) {
2147
    case 0x00:        /* TIPB_CNTL */
2148
        return s->control;
2149
    case 0x04:        /* TIPB_BUS_ALLOC */
2150
        return s->alloc;
2151
    case 0x08:        /* MPU_TIPB_CNTL */
2152
        return s->buffer;
2153
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2154
        return s->enh_control;
2155
    case 0x10:        /* ADDRESS_DBG */
2156
    case 0x14:        /* DATA_DEBUG_LOW */
2157
    case 0x18:        /* DATA_DEBUG_HIGH */
2158
        return 0xffff;
2159
    case 0x1c:        /* DEBUG_CNTR_SIG */
2160
        return 0x00f8;
2161
    }
2162

    
2163
    OMAP_BAD_REG(addr);
2164
    return 0;
2165
}
2166

    
2167
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
2168
                uint32_t value)
2169
{
2170
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2171
    int offset = addr - s->base;
2172

    
2173
    switch (offset) {
2174
    case 0x00:        /* TIPB_CNTL */
2175
        s->control = value & 0xffff;
2176
        break;
2177

    
2178
    case 0x04:        /* TIPB_BUS_ALLOC */
2179
        s->alloc = value & 0x003f;
2180
        break;
2181

    
2182
    case 0x08:        /* MPU_TIPB_CNTL */
2183
        s->buffer = value & 0x0003;
2184
        break;
2185

    
2186
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2187
        s->width_intr = !(value & 2);
2188
        s->enh_control = value & 0x000f;
2189
        break;
2190

    
2191
    case 0x10:        /* ADDRESS_DBG */
2192
    case 0x14:        /* DATA_DEBUG_LOW */
2193
    case 0x18:        /* DATA_DEBUG_HIGH */
2194
    case 0x1c:        /* DEBUG_CNTR_SIG */
2195
        OMAP_RO_REG(addr);
2196
        break;
2197

    
2198
    default:
2199
        OMAP_BAD_REG(addr);
2200
    }
2201
}
2202

    
2203
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2204
    omap_badwidth_read16,
2205
    omap_tipb_bridge_read,
2206
    omap_tipb_bridge_read,
2207
};
2208

    
2209
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2210
    omap_badwidth_write16,
2211
    omap_tipb_bridge_write,
2212
    omap_tipb_bridge_write,
2213
};
2214

    
2215
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2216
{
2217
    s->control = 0xffff;
2218
    s->alloc = 0x0009;
2219
    s->buffer = 0x0000;
2220
    s->enh_control = 0x000f;
2221
}
2222

    
2223
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2224
                qemu_irq abort_irq, omap_clk clk)
2225
{
2226
    int iomemtype;
2227
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2228
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2229

    
2230
    s->abort = abort_irq;
2231
    s->base = base;
2232
    omap_tipb_bridge_reset(s);
2233

    
2234
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
2235
                    omap_tipb_bridge_writefn, s);
2236
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2237

    
2238
    return s;
2239
}
2240

    
2241
/* Dummy Traffic Controller's Memory Interface */
2242
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2243
{
2244
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2245
    int offset = addr - s->tcmi_base;
2246
    uint32_t ret;
2247

    
2248
    switch (offset) {
2249
    case 0x00:        /* IMIF_PRIO */
2250
    case 0x04:        /* EMIFS_PRIO */
2251
    case 0x08:        /* EMIFF_PRIO */
2252
    case 0x0c:        /* EMIFS_CONFIG */
2253
    case 0x10:        /* EMIFS_CS0_CONFIG */
2254
    case 0x14:        /* EMIFS_CS1_CONFIG */
2255
    case 0x18:        /* EMIFS_CS2_CONFIG */
2256
    case 0x1c:        /* EMIFS_CS3_CONFIG */
2257
    case 0x24:        /* EMIFF_MRS */
2258
    case 0x28:        /* TIMEOUT1 */
2259
    case 0x2c:        /* TIMEOUT2 */
2260
    case 0x30:        /* TIMEOUT3 */
2261
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
2262
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
2263
        return s->tcmi_regs[offset >> 2];
2264

    
2265
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
2266
        ret = s->tcmi_regs[offset >> 2];
2267
        s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2268
        /* XXX: We can try using the VGA_DIRTY flag for this */
2269
        return ret;
2270
    }
2271

    
2272
    OMAP_BAD_REG(addr);
2273
    return 0;
2274
}
2275

    
2276
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2277
                uint32_t value)
2278
{
2279
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2280
    int offset = addr - s->tcmi_base;
2281

    
2282
    switch (offset) {
2283
    case 0x00:        /* IMIF_PRIO */
2284
    case 0x04:        /* EMIFS_PRIO */
2285
    case 0x08:        /* EMIFF_PRIO */
2286
    case 0x10:        /* EMIFS_CS0_CONFIG */
2287
    case 0x14:        /* EMIFS_CS1_CONFIG */
2288
    case 0x18:        /* EMIFS_CS2_CONFIG */
2289
    case 0x1c:        /* EMIFS_CS3_CONFIG */
2290
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
2291
    case 0x24:        /* EMIFF_MRS */
2292
    case 0x28:        /* TIMEOUT1 */
2293
    case 0x2c:        /* TIMEOUT2 */
2294
    case 0x30:        /* TIMEOUT3 */
2295
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
2296
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
2297
        s->tcmi_regs[offset >> 2] = value;
2298
        break;
2299
    case 0x0c:        /* EMIFS_CONFIG */
2300
        s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
2301
        break;
2302

    
2303
    default:
2304
        OMAP_BAD_REG(addr);
2305
    }
2306
}
2307

    
2308
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2309
    omap_badwidth_read32,
2310
    omap_badwidth_read32,
2311
    omap_tcmi_read,
2312
};
2313

    
2314
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2315
    omap_badwidth_write32,
2316
    omap_badwidth_write32,
2317
    omap_tcmi_write,
2318
};
2319

    
2320
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
2321
{
2322
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
2323
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
2324
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
2325
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
2326
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
2327
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
2328
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
2329
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
2330
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
2331
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
2332
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
2333
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
2334
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
2335
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
2336
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
2337
}
2338

    
2339
static void omap_tcmi_init(target_phys_addr_t base,
2340
                struct omap_mpu_state_s *mpu)
2341
{
2342
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2343
                    omap_tcmi_writefn, mpu);
2344

    
2345
    mpu->tcmi_base = base;
2346
    cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2347
    omap_tcmi_reset(mpu);
2348
}
2349

    
2350
/* Digital phase-locked loops control */
2351
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2352
{
2353
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2354
    int offset = addr - s->base;
2355

    
2356
    if (offset == 0x00)        /* CTL_REG */
2357
        return s->mode;
2358

    
2359
    OMAP_BAD_REG(addr);
2360
    return 0;
2361
}
2362

    
2363
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2364
                uint32_t value)
2365
{
2366
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2367
    uint16_t diff;
2368
    int offset = addr - s->base;
2369
    static const int bypass_div[4] = { 1, 2, 4, 4 };
2370
    int div, mult;
2371

    
2372
    if (offset == 0x00) {        /* CTL_REG */
2373
        /* See omap_ulpd_pm_write() too */
2374
        diff = s->mode & value;
2375
        s->mode = value & 0x2fff;
2376
        if (diff & (0x3ff << 2)) {
2377
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
2378
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
2379
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
2380
            } else {
2381
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
2382
                mult = 1;
2383
            }
2384
            omap_clk_setrate(s->dpll, div, mult);
2385
        }
2386

    
2387
        /* Enter the desired mode.  */
2388
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
2389

    
2390
        /* Act as if the lock is restored.  */
2391
        s->mode |= 2;
2392
    } else {
2393
        OMAP_BAD_REG(addr);
2394
    }
2395
}
2396

    
2397
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
2398
    omap_badwidth_read16,
2399
    omap_dpll_read,
2400
    omap_badwidth_read16,
2401
};
2402

    
2403
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
2404
    omap_badwidth_write16,
2405
    omap_dpll_write,
2406
    omap_badwidth_write16,
2407
};
2408

    
2409
static void omap_dpll_reset(struct dpll_ctl_s *s)
2410
{
2411
    s->mode = 0x2002;
2412
    omap_clk_setrate(s->dpll, 1, 1);
2413
}
2414

    
2415
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
2416
                omap_clk clk)
2417
{
2418
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
2419
                    omap_dpll_writefn, s);
2420

    
2421
    s->base = base;
2422
    s->dpll = clk;
2423
    omap_dpll_reset(s);
2424

    
2425
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2426
}
2427

    
2428
/* UARTs */
2429
struct omap_uart_s {
2430
    SerialState *serial; /* TODO */
2431
};
2432

    
2433
static void omap_uart_reset(struct omap_uart_s *s)
2434
{
2435
}
2436

    
2437
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2438
                qemu_irq irq, omap_clk clk, CharDriverState *chr)
2439
{
2440
    struct omap_uart_s *s = (struct omap_uart_s *)
2441
            qemu_mallocz(sizeof(struct omap_uart_s));
2442
    if (chr)
2443
        s->serial = serial_mm_init(base, 2, irq, chr, 1);
2444
    return s;
2445
}
2446

    
2447
/* MPU Clock/Reset/Power Mode Control */
2448
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2449
{
2450
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2451
    int offset = addr - s->clkm.mpu_base;
2452

    
2453
    switch (offset) {
2454
    case 0x00:        /* ARM_CKCTL */
2455
        return s->clkm.arm_ckctl;
2456

    
2457
    case 0x04:        /* ARM_IDLECT1 */
2458
        return s->clkm.arm_idlect1;
2459

    
2460
    case 0x08:        /* ARM_IDLECT2 */
2461
        return s->clkm.arm_idlect2;
2462

    
2463
    case 0x0c:        /* ARM_EWUPCT */
2464
        return s->clkm.arm_ewupct;
2465

    
2466
    case 0x10:        /* ARM_RSTCT1 */
2467
        return s->clkm.arm_rstct1;
2468

    
2469
    case 0x14:        /* ARM_RSTCT2 */
2470
        return s->clkm.arm_rstct2;
2471

    
2472
    case 0x18:        /* ARM_SYSST */
2473
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
2474

    
2475
    case 0x1c:        /* ARM_CKOUT1 */
2476
        return s->clkm.arm_ckout1;
2477

    
2478
    case 0x20:        /* ARM_CKOUT2 */
2479
        break;
2480
    }
2481

    
2482
    OMAP_BAD_REG(addr);
2483
    return 0;
2484
}
2485

    
2486
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2487
                uint16_t diff, uint16_t value)
2488
{
2489
    omap_clk clk;
2490

    
2491
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
2492
        if (value & (1 << 14))
2493
            /* Reserved */;
2494
        else {
2495
            clk = omap_findclk(s, "arminth_ck");
2496
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2497
        }
2498
    }
2499
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
2500
        clk = omap_findclk(s, "armtim_ck");
2501
        if (value & (1 << 12))
2502
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
2503
        else
2504
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2505
    }
2506
    /* XXX: en_dspck */
2507
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
2508
        clk = omap_findclk(s, "dspmmu_ck");
2509
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
2510
    }
2511
    if (diff & (3 << 8)) {                                /* TCDIV */
2512
        clk = omap_findclk(s, "tc_ck");
2513
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2514
    }
2515
    if (diff & (3 << 6)) {                                /* DSPDIV */
2516
        clk = omap_findclk(s, "dsp_ck");
2517
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2518
    }
2519
    if (diff & (3 << 4)) {                                /* ARMDIV */
2520
        clk = omap_findclk(s, "arm_ck");
2521
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2522
    }
2523
    if (diff & (3 << 2)) {                                /* LCDDIV */
2524
        clk = omap_findclk(s, "lcd_ck");
2525
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2526
    }
2527
    if (diff & (3 << 0)) {                                /* PERDIV */
2528
        clk = omap_findclk(s, "armper_ck");
2529
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2530
    }
2531
}
2532

    
2533
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2534
                uint16_t diff, uint16_t value)
2535
{
2536
    omap_clk clk;
2537

    
2538
    if (value & (1 << 11))                                /* SETARM_IDLE */
2539
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2540
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2541
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2542

    
2543
#define SET_CANIDLE(clock, bit)                                \
2544
    if (diff & (1 << bit)) {                                \
2545
        clk = omap_findclk(s, clock);                        \
2546
        omap_clk_canidle(clk, (value >> bit) & 1);        \
2547
    }
2548
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
2549
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
2550
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
2551
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
2552
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
2553
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
2554
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
2555
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
2556
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
2557
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
2558
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
2559
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
2560
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
2561
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
2562
}
2563

    
2564
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2565
                uint16_t diff, uint16_t value)
2566
{
2567
    omap_clk clk;
2568

    
2569
#define SET_ONOFF(clock, bit)                                \
2570
    if (diff & (1 << bit)) {                                \
2571
        clk = omap_findclk(s, clock);                        \
2572
        omap_clk_onoff(clk, (value >> bit) & 1);        \
2573
    }
2574
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
2575
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
2576
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
2577
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
2578
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
2579
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
2580
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
2581
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
2582
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
2583
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
2584
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
2585
}
2586

    
2587
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2588
                uint16_t diff, uint16_t value)
2589
{
2590
    omap_clk clk;
2591

    
2592
    if (diff & (3 << 4)) {                                /* TCLKOUT */
2593
        clk = omap_findclk(s, "tclk_out");
2594
        switch ((value >> 4) & 3) {
2595
        case 1:
2596
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
2597
            omap_clk_onoff(clk, 1);
2598
            break;
2599
        case 2:
2600
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2601
            omap_clk_onoff(clk, 1);
2602
            break;
2603
        default:
2604
            omap_clk_onoff(clk, 0);
2605
        }
2606
    }
2607
    if (diff & (3 << 2)) {                                /* DCLKOUT */
2608
        clk = omap_findclk(s, "dclk_out");
2609
        switch ((value >> 2) & 3) {
2610
        case 0:
2611
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
2612
            break;
2613
        case 1:
2614
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
2615
            break;
2616
        case 2:
2617
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
2618
            break;
2619
        case 3:
2620
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2621
            break;
2622
        }
2623
    }
2624
    if (diff & (3 << 0)) {                                /* ACLKOUT */
2625
        clk = omap_findclk(s, "aclk_out");
2626
        switch ((value >> 0) & 3) {
2627
        case 1:
2628
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2629
            omap_clk_onoff(clk, 1);
2630
            break;
2631
        case 2:
2632
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
2633
            omap_clk_onoff(clk, 1);
2634
            break;
2635
        case 3:
2636
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2637
            omap_clk_onoff(clk, 1);
2638
            break;
2639
        default:
2640
            omap_clk_onoff(clk, 0);
2641
        }
2642
    }
2643
}
2644

    
2645
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2646
                uint32_t value)
2647
{
2648
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2649
    int offset = addr - s->clkm.mpu_base;
2650
    uint16_t diff;
2651
    omap_clk clk;
2652
    static const char *clkschemename[8] = {
2653
        "fully synchronous", "fully asynchronous", "synchronous scalable",
2654
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2655
    };
2656

    
2657
    switch (offset) {
2658
    case 0x00:        /* ARM_CKCTL */
2659
        diff = s->clkm.arm_ckctl ^ value;
2660
        s->clkm.arm_ckctl = value & 0x7fff;
2661
        omap_clkm_ckctl_update(s, diff, value);
2662
        return;
2663

    
2664
    case 0x04:        /* ARM_IDLECT1 */
2665
        diff = s->clkm.arm_idlect1 ^ value;
2666
        s->clkm.arm_idlect1 = value & 0x0fff;
2667
        omap_clkm_idlect1_update(s, diff, value);
2668
        return;
2669

    
2670
    case 0x08:        /* ARM_IDLECT2 */
2671
        diff = s->clkm.arm_idlect2 ^ value;
2672
        s->clkm.arm_idlect2 = value & 0x07ff;
2673
        omap_clkm_idlect2_update(s, diff, value);
2674
        return;
2675

    
2676
    case 0x0c:        /* ARM_EWUPCT */
2677
        diff = s->clkm.arm_ewupct ^ value;
2678
        s->clkm.arm_ewupct = value & 0x003f;
2679
        return;
2680

    
2681
    case 0x10:        /* ARM_RSTCT1 */
2682
        diff = s->clkm.arm_rstct1 ^ value;
2683
        s->clkm.arm_rstct1 = value & 0x0007;
2684
        if (value & 9) {
2685
            qemu_system_reset_request();
2686
            s->clkm.cold_start = 0xa;
2687
        }
2688
        if (diff & ~value & 4) {                                /* DSP_RST */
2689
            omap_mpui_reset(s);
2690
            omap_tipb_bridge_reset(s->private_tipb);
2691
            omap_tipb_bridge_reset(s->public_tipb);
2692
        }
2693
        if (diff & 2) {                                                /* DSP_EN */
2694
            clk = omap_findclk(s, "dsp_ck");
2695
            omap_clk_canidle(clk, (~value >> 1) & 1);
2696
        }
2697
        return;
2698

    
2699
    case 0x14:        /* ARM_RSTCT2 */
2700
        s->clkm.arm_rstct2 = value & 0x0001;
2701
        return;
2702

    
2703
    case 0x18:        /* ARM_SYSST */
2704
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2705
            s->clkm.clocking_scheme = (value >> 11) & 7;
2706
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2707
                            clkschemename[s->clkm.clocking_scheme]);
2708
        }
2709
        s->clkm.cold_start &= value & 0x3f;
2710
        return;
2711

    
2712
    case 0x1c:        /* ARM_CKOUT1 */
2713
        diff = s->clkm.arm_ckout1 ^ value;
2714
        s->clkm.arm_ckout1 = value & 0x003f;
2715
        omap_clkm_ckout1_update(s, diff, value);
2716
        return;
2717

    
2718
    case 0x20:        /* ARM_CKOUT2 */
2719
    default:
2720
        OMAP_BAD_REG(addr);
2721
    }
2722
}
2723

    
2724
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2725
    omap_badwidth_read16,
2726
    omap_clkm_read,
2727
    omap_badwidth_read16,
2728
};
2729

    
2730
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2731
    omap_badwidth_write16,
2732
    omap_clkm_write,
2733
    omap_badwidth_write16,
2734
};
2735

    
2736
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2737
{
2738
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2739
    int offset = addr - s->clkm.dsp_base;
2740

    
2741
    switch (offset) {
2742
    case 0x04:        /* DSP_IDLECT1 */
2743
        return s->clkm.dsp_idlect1;
2744

    
2745
    case 0x08:        /* DSP_IDLECT2 */
2746
        return s->clkm.dsp_idlect2;
2747

    
2748
    case 0x14:        /* DSP_RSTCT2 */
2749
        return s->clkm.dsp_rstct2;
2750

    
2751
    case 0x18:        /* DSP_SYSST */
2752
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
2753
                (s->env->halted << 6);        /* Quite useless... */
2754
    }
2755

    
2756
    OMAP_BAD_REG(addr);
2757
    return 0;
2758
}
2759

    
2760
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2761
                uint16_t diff, uint16_t value)
2762
{
2763
    omap_clk clk;
2764

    
2765
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2766
}
2767

    
2768
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2769
                uint16_t diff, uint16_t value)
2770
{
2771
    omap_clk clk;
2772

    
2773
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2774
}
2775

    
2776
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2777
                uint32_t value)
2778
{
2779
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2780
    int offset = addr - s->clkm.dsp_base;
2781
    uint16_t diff;
2782

    
2783
    switch (offset) {
2784
    case 0x04:        /* DSP_IDLECT1 */
2785
        diff = s->clkm.dsp_idlect1 ^ value;
2786
        s->clkm.dsp_idlect1 = value & 0x01f7;
2787
        omap_clkdsp_idlect1_update(s, diff, value);
2788
        break;
2789

    
2790
    case 0x08:        /* DSP_IDLECT2 */
2791
        s->clkm.dsp_idlect2 = value & 0x0037;
2792
        diff = s->clkm.dsp_idlect1 ^ value;
2793
        omap_clkdsp_idlect2_update(s, diff, value);
2794
        break;
2795

    
2796
    case 0x14:        /* DSP_RSTCT2 */
2797
        s->clkm.dsp_rstct2 = value & 0x0001;
2798
        break;
2799

    
2800
    case 0x18:        /* DSP_SYSST */
2801
        s->clkm.cold_start &= value & 0x3f;
2802
        break;
2803

    
2804
    default:
2805
        OMAP_BAD_REG(addr);
2806
    }
2807
}
2808

    
2809
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2810
    omap_badwidth_read16,
2811
    omap_clkdsp_read,
2812
    omap_badwidth_read16,
2813
};
2814

    
2815
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2816
    omap_badwidth_write16,
2817
    omap_clkdsp_write,
2818
    omap_badwidth_write16,
2819
};
2820

    
2821
static void omap_clkm_reset(struct omap_mpu_state_s *s)
2822
{
2823
    if (s->wdt && s->wdt->reset)
2824
        s->clkm.cold_start = 0x6;
2825
    s->clkm.clocking_scheme = 0;
2826
    omap_clkm_ckctl_update(s, ~0, 0x3000);
2827
    s->clkm.arm_ckctl = 0x3000;
2828
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
2829
    s->clkm.arm_idlect1 = 0x0400;
2830
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
2831
    s->clkm.arm_idlect2 = 0x0100;
2832
    s->clkm.arm_ewupct = 0x003f;
2833
    s->clkm.arm_rstct1 = 0x0000;
2834
    s->clkm.arm_rstct2 = 0x0000;
2835
    s->clkm.arm_ckout1 = 0x0015;
2836
    s->clkm.dpll1_mode = 0x2002;
2837
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2838
    s->clkm.dsp_idlect1 = 0x0040;
2839
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2840
    s->clkm.dsp_idlect2 = 0x0000;
2841
    s->clkm.dsp_rstct2 = 0x0000;
2842
}
2843

    
2844
static void omap_clkm_init(target_phys_addr_t mpu_base,
2845
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2846
{
2847
    int iomemtype[2] = {
2848
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2849
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2850
    };
2851

    
2852
    s->clkm.mpu_base = mpu_base;
2853
    s->clkm.dsp_base = dsp_base;
2854
    s->clkm.arm_idlect1 = 0x03ff;
2855
    s->clkm.arm_idlect2 = 0x0100;
2856
    s->clkm.dsp_idlect1 = 0x0002;
2857
    omap_clkm_reset(s);
2858
    s->clkm.cold_start = 0x3a;
2859

    
2860
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2861
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2862
}
2863

    
2864
/* MPU I/O */
2865
struct omap_mpuio_s {
2866
    target_phys_addr_t base;
2867
    qemu_irq irq;
2868
    qemu_irq kbd_irq;
2869
    qemu_irq *in;
2870
    qemu_irq handler[16];
2871
    qemu_irq wakeup;
2872

    
2873
    uint16_t inputs;
2874
    uint16_t outputs;
2875
    uint16_t dir;
2876
    uint16_t edge;
2877
    uint16_t mask;
2878
    uint16_t ints;
2879

    
2880
    uint16_t debounce;
2881
    uint16_t latch;
2882
    uint8_t event;
2883

    
2884
    uint8_t buttons[5];
2885
    uint8_t row_latch;
2886
    uint8_t cols;
2887
    int kbd_mask;
2888
    int clk;
2889
};
2890

    
2891
static void omap_mpuio_set(void *opaque, int line, int level)
2892
{
2893
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2894
    uint16_t prev = s->inputs;
2895

    
2896
    if (level)
2897
        s->inputs |= 1 << line;
2898
    else
2899
        s->inputs &= ~(1 << line);
2900

    
2901
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2902
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2903
            s->ints |= 1 << line;
2904
            qemu_irq_raise(s->irq);
2905
            /* TODO: wakeup */
2906
        }
2907
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
2908
                (s->event >> 1) == line)        /* PIN_SELECT */
2909
            s->latch = s->inputs;
2910
    }
2911
}
2912

    
2913
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2914
{
2915
    int i;
2916
    uint8_t *row, rows = 0, cols = ~s->cols;
2917

    
2918
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2919
        if (*row & cols)
2920
            rows |= i;
2921

    
2922
    qemu_set_irq(s->kbd_irq, rows && ~s->kbd_mask && s->clk);
2923
    s->row_latch = rows ^ 0x1f;
2924
}
2925

    
2926
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2927
{
2928
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2929
    int offset = addr & OMAP_MPUI_REG_MASK;
2930
    uint16_t ret;
2931

    
2932
    switch (offset) {
2933
    case 0x00:        /* INPUT_LATCH */
2934
        return s->inputs;
2935

    
2936
    case 0x04:        /* OUTPUT_REG */
2937
        return s->outputs;
2938

    
2939
    case 0x08:        /* IO_CNTL */
2940
        return s->dir;
2941

    
2942
    case 0x10:        /* KBR_LATCH */
2943
        return s->row_latch;
2944

    
2945
    case 0x14:        /* KBC_REG */
2946
        return s->cols;
2947

    
2948
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2949
        return s->event;
2950

    
2951
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2952
        return s->edge;
2953

    
2954
    case 0x20:        /* KBD_INT */
2955
        return (s->row_latch != 0x1f) && !s->kbd_mask;
2956

    
2957
    case 0x24:        /* GPIO_INT */
2958
        ret = s->ints;
2959
        s->ints &= s->mask;
2960
        if (ret)
2961
            qemu_irq_lower(s->irq);
2962
        return ret;
2963

    
2964
    case 0x28:        /* KBD_MASKIT */
2965
        return s->kbd_mask;
2966

    
2967
    case 0x2c:        /* GPIO_MASKIT */
2968
        return s->mask;
2969

    
2970
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2971
        return s->debounce;
2972

    
2973
    case 0x34:        /* GPIO_LATCH_REG */
2974
        return s->latch;
2975
    }
2976

    
2977
    OMAP_BAD_REG(addr);
2978
    return 0;
2979
}
2980

    
2981
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2982
                uint32_t value)
2983
{
2984
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2985
    int offset = addr & OMAP_MPUI_REG_MASK;
2986
    uint16_t diff;
2987
    int ln;
2988

    
2989
    switch (offset) {
2990
    case 0x04:        /* OUTPUT_REG */
2991
        diff = (s->outputs ^ value) & ~s->dir;
2992
        s->outputs = value;
2993
        while ((ln = ffs(diff))) {
2994
            ln --;
2995
            if (s->handler[ln])
2996
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2997
            diff &= ~(1 << ln);
2998
        }
2999
        break;
3000

    
3001
    case 0x08:        /* IO_CNTL */
3002
        diff = s->outputs & (s->dir ^ value);
3003
        s->dir = value;
3004

    
3005
        value = s->outputs & ~s->dir;
3006
        while ((ln = ffs(diff))) {
3007
            ln --;
3008
            if (s->handler[ln])
3009
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3010
            diff &= ~(1 << ln);
3011
        }
3012
        break;
3013

    
3014
    case 0x14:        /* KBC_REG */
3015
        s->cols = value;
3016
        omap_mpuio_kbd_update(s);
3017
        break;
3018

    
3019
    case 0x18:        /* GPIO_EVENT_MODE_REG */
3020
        s->event = value & 0x1f;
3021
        break;
3022

    
3023
    case 0x1c:        /* GPIO_INT_EDGE_REG */
3024
        s->edge = value;
3025
        break;
3026

    
3027
    case 0x28:        /* KBD_MASKIT */
3028
        s->kbd_mask = value & 1;
3029
        omap_mpuio_kbd_update(s);
3030
        break;
3031

    
3032
    case 0x2c:        /* GPIO_MASKIT */
3033
        s->mask = value;
3034
        break;
3035

    
3036
    case 0x30:        /* GPIO_DEBOUNCING_REG */
3037
        s->debounce = value & 0x1ff;
3038
        break;
3039

    
3040
    case 0x00:        /* INPUT_LATCH */
3041
    case 0x10:        /* KBR_LATCH */
3042
    case 0x20:        /* KBD_INT */
3043
    case 0x24:        /* GPIO_INT */
3044
    case 0x34:        /* GPIO_LATCH_REG */
3045
        OMAP_RO_REG(addr);
3046
        return;
3047

    
3048
    default:
3049
        OMAP_BAD_REG(addr);
3050
        return;
3051
    }
3052
}
3053

    
3054
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
3055
    omap_badwidth_read16,
3056
    omap_mpuio_read,
3057
    omap_badwidth_read16,
3058
};
3059

    
3060
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
3061
    omap_badwidth_write16,
3062
    omap_mpuio_write,
3063
    omap_badwidth_write16,
3064
};
3065

    
3066
static void omap_mpuio_reset(struct omap_mpuio_s *s)
3067
{
3068
    s->inputs = 0;
3069
    s->outputs = 0;
3070
    s->dir = ~0;
3071
    s->event = 0;
3072
    s->edge = 0;
3073
    s->kbd_mask = 0;
3074
    s->mask = 0;
3075
    s->debounce = 0;
3076
    s->latch = 0;
3077
    s->ints = 0;
3078
    s->row_latch = 0x1f;
3079
    s->clk = 1;
3080
}
3081

    
3082
static void omap_mpuio_onoff(void *opaque, int line, int on)
3083
{
3084
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3085

    
3086
    s->clk = on;
3087
    if (on)
3088
        omap_mpuio_kbd_update(s);
3089
}
3090

    
3091
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
3092
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
3093
                omap_clk clk)
3094
{
3095
    int iomemtype;
3096
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
3097
            qemu_mallocz(sizeof(struct omap_mpuio_s));
3098

    
3099
    s->base = base;
3100
    s->irq = gpio_int;
3101
    s->kbd_irq = kbd_int;
3102
    s->wakeup = wakeup;
3103
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
3104
    omap_mpuio_reset(s);
3105

    
3106
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
3107
                    omap_mpuio_writefn, s);
3108
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3109

    
3110
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
3111

    
3112
    return s;
3113
}
3114

    
3115
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
3116
{
3117
    return s->in;
3118
}
3119

    
3120
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
3121
{
3122
    if (line >= 16 || line < 0)
3123
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3124
    s->handler[line] = handler;
3125
}
3126

    
3127
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
3128
{
3129
    if (row >= 5 || row < 0)
3130
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
3131
                        __FUNCTION__, col, row);
3132

    
3133
    if (down)
3134
        s->buttons[row] |= 1 << col;
3135
    else
3136
        s->buttons[row] &= ~(1 << col);
3137

    
3138
    omap_mpuio_kbd_update(s);
3139
}
3140

    
3141
/* General-Purpose I/O */
3142
struct omap_gpio_s {
3143
    target_phys_addr_t base;
3144
    qemu_irq irq;
3145
    qemu_irq *in;
3146
    qemu_irq handler[16];
3147

    
3148
    uint16_t inputs;
3149
    uint16_t outputs;
3150
    uint16_t dir;
3151
    uint16_t edge;
3152
    uint16_t mask;
3153
    uint16_t ints;
3154
    uint16_t pins;
3155
};
3156

    
3157
static void omap_gpio_set(void *opaque, int line, int level)
3158
{
3159
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3160
    uint16_t prev = s->inputs;
3161

    
3162
    if (level)
3163
        s->inputs |= 1 << line;
3164
    else
3165
        s->inputs &= ~(1 << line);
3166

    
3167
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
3168
                    (1 << line) & s->dir & ~s->mask) {
3169
        s->ints |= 1 << line;
3170
        qemu_irq_raise(s->irq);
3171
    }
3172
}
3173

    
3174
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
3175
{
3176
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3177
    int offset = addr & OMAP_MPUI_REG_MASK;
3178

    
3179
    switch (offset) {
3180
    case 0x00:        /* DATA_INPUT */
3181
        return s->inputs & s->pins;
3182

    
3183
    case 0x04:        /* DATA_OUTPUT */
3184
        return s->outputs;
3185

    
3186
    case 0x08:        /* DIRECTION_CONTROL */
3187
        return s->dir;
3188

    
3189
    case 0x0c:        /* INTERRUPT_CONTROL */
3190
        return s->edge;
3191

    
3192
    case 0x10:        /* INTERRUPT_MASK */
3193
        return s->mask;
3194

    
3195
    case 0x14:        /* INTERRUPT_STATUS */
3196
        return s->ints;
3197

    
3198
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
3199
        OMAP_BAD_REG(addr);
3200
        return s->pins;
3201
    }
3202

    
3203
    OMAP_BAD_REG(addr);
3204
    return 0;
3205
}
3206

    
3207
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
3208
                uint32_t value)
3209
{
3210
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3211
    int offset = addr & OMAP_MPUI_REG_MASK;
3212
    uint16_t diff;
3213
    int ln;
3214

    
3215
    switch (offset) {
3216
    case 0x00:        /* DATA_INPUT */
3217
        OMAP_RO_REG(addr);
3218
        return;
3219

    
3220
    case 0x04:        /* DATA_OUTPUT */
3221
        diff = (s->outputs ^ value) & ~s->dir;
3222
        s->outputs = value;
3223
        while ((ln = ffs(diff))) {
3224
            ln --;
3225
            if (s->handler[ln])
3226
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3227
            diff &= ~(1 << ln);
3228
        }
3229
        break;
3230

    
3231
    case 0x08:        /* DIRECTION_CONTROL */
3232
        diff = s->outputs & (s->dir ^ value);
3233
        s->dir = value;
3234

    
3235
        value = s->outputs & ~s->dir;
3236
        while ((ln = ffs(diff))) {
3237
            ln --;
3238
            if (s->handler[ln])
3239
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3240
            diff &= ~(1 << ln);
3241
        }
3242
        break;
3243

    
3244
    case 0x0c:        /* INTERRUPT_CONTROL */
3245
        s->edge = value;
3246
        break;
3247

    
3248
    case 0x10:        /* INTERRUPT_MASK */
3249
        s->mask = value;
3250
        break;
3251

    
3252
    case 0x14:        /* INTERRUPT_STATUS */
3253
        s->ints &= ~value;
3254
        if (!s->ints)
3255
            qemu_irq_lower(s->irq);
3256
        break;
3257

    
3258
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
3259
        OMAP_BAD_REG(addr);
3260
        s->pins = value;
3261
        break;
3262

    
3263
    default:
3264
        OMAP_BAD_REG(addr);
3265
        return;
3266
    }
3267
}
3268

    
3269
/* *Some* sources say the memory region is 32-bit.  */
3270
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
3271
    omap_badwidth_read16,
3272
    omap_gpio_read,
3273
    omap_badwidth_read16,
3274
};
3275

    
3276
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
3277
    omap_badwidth_write16,
3278
    omap_gpio_write,
3279
    omap_badwidth_write16,
3280
};
3281

    
3282
static void omap_gpio_reset(struct omap_gpio_s *s)
3283
{
3284
    s->inputs = 0;
3285
    s->outputs = ~0;
3286
    s->dir = ~0;
3287
    s->edge = ~0;
3288
    s->mask = ~0;
3289
    s->ints = 0;
3290
    s->pins = ~0;
3291
}
3292

    
3293
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
3294
                qemu_irq irq, omap_clk clk)
3295
{
3296
    int iomemtype;
3297
    struct omap_gpio_s *s = (struct omap_gpio_s *)
3298
            qemu_mallocz(sizeof(struct omap_gpio_s));
3299

    
3300
    s->base = base;
3301
    s->irq = irq;
3302
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
3303
    omap_gpio_reset(s);
3304

    
3305
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
3306
                    omap_gpio_writefn, s);
3307
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3308

    
3309
    return s;
3310
}
3311

    
3312
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
3313
{
3314
    return s->in;
3315
}
3316

    
3317
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3318
{
3319
    if (line >= 16 || line < 0)
3320
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3321
    s->handler[line] = handler;
3322
}
3323

    
3324
/* MicroWire Interface */
3325
struct omap_uwire_s {
3326
    target_phys_addr_t base;
3327
    qemu_irq txirq;
3328
    qemu_irq rxirq;
3329
    qemu_irq txdrq;
3330

    
3331
    uint16_t txbuf;
3332
    uint16_t rxbuf;
3333
    uint16_t control;
3334
    uint16_t setup[5];
3335

    
3336
    struct uwire_slave_s *chip[4];
3337
};
3338

    
3339
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3340
{
3341
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3342
    struct uwire_slave_s *slave = s->chip[chipselect];
3343

    
3344
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
3345
        if (s->control & (1 << 12))                        /* CS_CMD */
3346
            if (slave && slave->send)
3347
                slave->send(slave->opaque,
3348
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3349
        s->control &= ~(1 << 14);                        /* CSRB */
3350
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3351
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3352
    }
3353

    
3354
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
3355
        if (s->control & (1 << 12))                        /* CS_CMD */
3356
            if (slave && slave->receive)
3357
                s->rxbuf = slave->receive(slave->opaque);
3358
        s->control |= 1 << 15;                                /* RDRB */
3359
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3360
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3361
    }
3362
}
3363

    
3364
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3365
{
3366
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3367
    int offset = addr & OMAP_MPUI_REG_MASK;
3368

    
3369
    switch (offset) {
3370
    case 0x00:        /* RDR */
3371
        s->control &= ~(1 << 15);                        /* RDRB */
3372
        return s->rxbuf;
3373

    
3374
    case 0x04:        /* CSR */
3375
        return s->control;
3376

    
3377
    case 0x08:        /* SR1 */
3378
        return s->setup[0];
3379
    case 0x0c:        /* SR2 */
3380
        return s->setup[1];
3381
    case 0x10:        /* SR3 */
3382
        return s->setup[2];
3383
    case 0x14:        /* SR4 */
3384
        return s->setup[3];
3385
    case 0x18:        /* SR5 */
3386
        return s->setup[4];
3387
    }
3388

    
3389
    OMAP_BAD_REG(addr);
3390
    return 0;
3391
}
3392

    
3393
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3394
                uint32_t value)
3395
{
3396
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3397
    int offset = addr & OMAP_MPUI_REG_MASK;
3398

    
3399
    switch (offset) {
3400
    case 0x00:        /* TDR */
3401
        s->txbuf = value;                                /* TD */
3402
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3403
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3404
                         (s->control & (1 << 12)))) {        /* CS_CMD */
3405
            s->control |= 1 << 14;                        /* CSRB */
3406
            omap_uwire_transfer_start(s);
3407
        }
3408
        break;
3409

    
3410
    case 0x04:        /* CSR */
3411
        s->control = value & 0x1fff;
3412
        if (value & (1 << 13))                                /* START */
3413
            omap_uwire_transfer_start(s);
3414
        break;
3415

    
3416
    case 0x08:        /* SR1 */
3417
        s->setup[0] = value & 0x003f;
3418
        break;
3419

    
3420
    case 0x0c:        /* SR2 */
3421
        s->setup[1] = value & 0x0fc0;
3422
        break;
3423

    
3424
    case 0x10:        /* SR3 */
3425
        s->setup[2] = value & 0x0003;
3426
        break;
3427

    
3428
    case 0x14:        /* SR4 */
3429
        s->setup[3] = value & 0x0001;
3430
        break;
3431

    
3432
    case 0x18:        /* SR5 */
3433
        s->setup[4] = value & 0x000f;
3434
        break;
3435

    
3436
    default:
3437
        OMAP_BAD_REG(addr);
3438
        return;
3439
    }
3440
}
3441

    
3442
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3443
    omap_badwidth_read16,
3444
    omap_uwire_read,
3445
    omap_badwidth_read16,
3446
};
3447

    
3448
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3449
    omap_badwidth_write16,
3450
    omap_uwire_write,
3451
    omap_badwidth_write16,
3452
};
3453

    
3454
static void omap_uwire_reset(struct omap_uwire_s *s)
3455
{
3456
    s->control = 0;
3457
    s->setup[0] = 0;
3458
    s->setup[1] = 0;
3459
    s->setup[2] = 0;
3460
    s->setup[3] = 0;
3461
    s->setup[4] = 0;
3462
}
3463

    
3464
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3465
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3466
{
3467
    int iomemtype;
3468
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3469
            qemu_mallocz(sizeof(struct omap_uwire_s));
3470

    
3471
    s->base = base;
3472
    s->txirq = irq[0];
3473
    s->rxirq = irq[1];
3474
    s->txdrq = dma;
3475
    omap_uwire_reset(s);
3476

    
3477
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3478
                    omap_uwire_writefn, s);
3479
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3480

    
3481
    return s;
3482
}
3483

    
3484
void omap_uwire_attach(struct omap_uwire_s *s,
3485
                struct uwire_slave_s *slave, int chipselect)
3486
{
3487
    if (chipselect < 0 || chipselect > 3)
3488
        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
3489
                        chipselect);
3490

    
3491
    s->chip[chipselect] = slave;
3492
}
3493

    
3494
/* Pseudonoise Pulse-Width Light Modulator */
3495
static void omap_pwl_update(struct omap_mpu_state_s *s)
3496
{
3497
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3498

    
3499
    if (output != s->pwl.output) {
3500
        s->pwl.output = output;
3501
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3502
    }
3503
}
3504

    
3505
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3506
{
3507
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3508
    int offset = addr & OMAP_MPUI_REG_MASK;
3509

    
3510
    switch (offset) {
3511
    case 0x00:        /* PWL_LEVEL */
3512
        return s->pwl.level;
3513
    case 0x04:        /* PWL_CTRL */
3514
        return s->pwl.enable;
3515
    }
3516
    OMAP_BAD_REG(addr);
3517
    return 0;
3518
}
3519

    
3520
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3521
                uint32_t value)
3522
{
3523
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3524
    int offset = addr & OMAP_MPUI_REG_MASK;
3525

    
3526
    switch (offset) {
3527
    case 0x00:        /* PWL_LEVEL */
3528
        s->pwl.level = value;
3529
        omap_pwl_update(s);
3530
        break;
3531
    case 0x04:        /* PWL_CTRL */
3532
        s->pwl.enable = value & 1;
3533
        omap_pwl_update(s);
3534
        break;
3535
    default:
3536
        OMAP_BAD_REG(addr);
3537
        return;
3538
    }
3539
}
3540

    
3541
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3542
    omap_pwl_read,
3543
    omap_badwidth_read8,
3544
    omap_badwidth_read8,
3545
};
3546

    
3547
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3548
    omap_pwl_write,
3549
    omap_badwidth_write8,
3550
    omap_badwidth_write8,
3551
};
3552

    
3553
static void omap_pwl_reset(struct omap_mpu_state_s *s)
3554
{
3555
    s->pwl.output = 0;
3556
    s->pwl.level = 0;
3557
    s->pwl.enable = 0;
3558
    s->pwl.clk = 1;
3559
    omap_pwl_update(s);
3560
}
3561

    
3562
static void omap_pwl_clk_update(void *opaque, int line, int on)
3563
{
3564
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3565

    
3566
    s->pwl.clk = on;
3567
    omap_pwl_update(s);
3568
}
3569

    
3570
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3571
                omap_clk clk)
3572
{
3573
    int iomemtype;
3574

    
3575
    omap_pwl_reset(s);
3576

    
3577
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3578
                    omap_pwl_writefn, s);
3579
    cpu_register_physical_memory(base, 0x800, iomemtype);
3580

    
3581
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3582
}
3583

    
3584
/* Pulse-Width Tone module */
3585
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3586
{
3587
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3588
    int offset = addr & OMAP_MPUI_REG_MASK;
3589

    
3590
    switch (offset) {
3591
    case 0x00:        /* FRC */
3592
        return s->pwt.frc;
3593
    case 0x04:        /* VCR */
3594
        return s->pwt.vrc;
3595
    case 0x08:        /* GCR */
3596
        return s->pwt.gcr;
3597
    }
3598
    OMAP_BAD_REG(addr);
3599
    return 0;
3600
}
3601

    
3602
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3603
                uint32_t value)
3604
{
3605
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3606
    int offset = addr & OMAP_MPUI_REG_MASK;
3607

    
3608
    switch (offset) {
3609
    case 0x00:        /* FRC */
3610
        s->pwt.frc = value & 0x3f;
3611
        break;
3612
    case 0x04:        /* VRC */
3613
        if ((value ^ s->pwt.vrc) & 1) {
3614
            if (value & 1)
3615
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
3616
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
3617
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
3618
                                 /* Pre-multiplexer divider */
3619
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
3620
                                 /* Octave multiplexer */
3621
                                 (2 << (value & 3)) *
3622
                                 /* 101/107 divider */
3623
                                 ((value & (1 << 2)) ? 101 : 107) *
3624
                                 /*  49/55 divider */
3625
                                 ((value & (1 << 3)) ?  49 : 55) *
3626
                                 /*  50/63 divider */
3627
                                 ((value & (1 << 4)) ?  50 : 63) *
3628
                                 /*  80/127 divider */
3629
                                 ((value & (1 << 5)) ?  80 : 127) /
3630
                                 (107 * 55 * 63 * 127)));
3631
            else
3632
                printf("%s: silence!\n", __FUNCTION__);
3633
        }
3634
        s->pwt.vrc = value & 0x7f;
3635
        break;
3636
    case 0x08:        /* GCR */
3637
        s->pwt.gcr = value & 3;
3638
        break;
3639
    default:
3640
        OMAP_BAD_REG(addr);
3641
        return;
3642
    }
3643
}
3644

    
3645
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3646
    omap_pwt_read,
3647
    omap_badwidth_read8,
3648
    omap_badwidth_read8,
3649
};
3650

    
3651
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3652
    omap_pwt_write,
3653
    omap_badwidth_write8,
3654
    omap_badwidth_write8,
3655
};
3656

    
3657
static void omap_pwt_reset(struct omap_mpu_state_s *s)
3658
{
3659
    s->pwt.frc = 0;
3660
    s->pwt.vrc = 0;
3661
    s->pwt.gcr = 0;
3662
}
3663

    
3664
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3665
                omap_clk clk)
3666
{
3667
    int iomemtype;
3668

    
3669
    s->pwt.clk = clk;
3670
    omap_pwt_reset(s);
3671

    
3672
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3673
                    omap_pwt_writefn, s);
3674
    cpu_register_physical_memory(base, 0x800, iomemtype);
3675
}
3676

    
3677
/* Real-time Clock module */
3678
struct omap_rtc_s {
3679
    target_phys_addr_t base;
3680
    qemu_irq irq;
3681
    qemu_irq alarm;
3682
    QEMUTimer *clk;
3683

    
3684
    uint8_t interrupts;
3685
    uint8_t status;
3686
    int16_t comp_reg;
3687
    int running;
3688
    int pm_am;
3689
    int auto_comp;
3690
    int round;
3691
    struct tm *(*convert)(const time_t *timep, struct tm *result);
3692
    struct tm alarm_tm;
3693
    time_t alarm_ti;
3694

    
3695
    struct tm current_tm;
3696
    time_t ti;
3697
    uint64_t tick;
3698
};
3699

    
3700
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3701
{
3702
    /* s->alarm is level-triggered */
3703
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3704
}
3705

    
3706
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3707
{
3708
    s->alarm_ti = mktime(&s->alarm_tm);
3709
    if (s->alarm_ti == -1)
3710
        printf("%s: conversion failed\n", __FUNCTION__);
3711
}
3712

    
3713
static inline uint8_t omap_rtc_bcd(int num)
3714
{
3715
    return ((num / 10) << 4) | (num % 10);
3716
}
3717

    
3718
static inline int omap_rtc_bin(uint8_t num)
3719
{
3720
    return (num & 15) + 10 * (num >> 4);
3721
}
3722

    
3723
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3724
{
3725
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3726
    int offset = addr & OMAP_MPUI_REG_MASK;
3727
    uint8_t i;
3728

    
3729
    switch (offset) {
3730
    case 0x00:        /* SECONDS_REG */
3731
        return omap_rtc_bcd(s->current_tm.tm_sec);
3732

    
3733
    case 0x04:        /* MINUTES_REG */
3734
        return omap_rtc_bcd(s->current_tm.tm_min);
3735

    
3736
    case 0x08:        /* HOURS_REG */
3737
        if (s->pm_am)
3738
            return ((s->current_tm.tm_hour > 11) << 7) |
3739
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3740
        else
3741
            return omap_rtc_bcd(s->current_tm.tm_hour);
3742

    
3743
    case 0x0c:        /* DAYS_REG */
3744
        return omap_rtc_bcd(s->current_tm.tm_mday);
3745

    
3746
    case 0x10:        /* MONTHS_REG */
3747
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3748

    
3749
    case 0x14:        /* YEARS_REG */
3750
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3751

    
3752
    case 0x18:        /* WEEK_REG */
3753
        return s->current_tm.tm_wday;
3754

    
3755
    case 0x20:        /* ALARM_SECONDS_REG */
3756
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3757

    
3758
    case 0x24:        /* ALARM_MINUTES_REG */
3759
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3760

    
3761
    case 0x28:        /* ALARM_HOURS_REG */
3762
        if (s->pm_am)
3763
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3764
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3765
        else
3766
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
3767

    
3768
    case 0x2c:        /* ALARM_DAYS_REG */
3769
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3770

    
3771
    case 0x30:        /* ALARM_MONTHS_REG */
3772
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3773

    
3774
    case 0x34:        /* ALARM_YEARS_REG */
3775
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3776

    
3777
    case 0x40:        /* RTC_CTRL_REG */
3778
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3779
                (s->round << 1) | s->running;
3780

    
3781
    case 0x44:        /* RTC_STATUS_REG */
3782
        i = s->status;
3783
        s->status &= ~0x3d;
3784
        return i;
3785

    
3786
    case 0x48:        /* RTC_INTERRUPTS_REG */
3787
        return s->interrupts;
3788

    
3789
    case 0x4c:        /* RTC_COMP_LSB_REG */
3790
        return ((uint16_t) s->comp_reg) & 0xff;
3791

    
3792
    case 0x50:        /* RTC_COMP_MSB_REG */
3793
        return ((uint16_t) s->comp_reg) >> 8;
3794
    }
3795

    
3796
    OMAP_BAD_REG(addr);
3797
    return 0;
3798
}
3799

    
3800
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3801
                uint32_t value)
3802
{
3803
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3804
    int offset = addr & OMAP_MPUI_REG_MASK;
3805
    struct tm new_tm;
3806
    time_t ti[2];
3807

    
3808
    switch (offset) {
3809
    case 0x00:        /* SECONDS_REG */
3810
#if ALMDEBUG
3811
        printf("RTC SEC_REG <-- %02x\n", value);
3812
#endif
3813
        s->ti -= s->current_tm.tm_sec;
3814
        s->ti += omap_rtc_bin(value);
3815
        return;
3816

    
3817
    case 0x04:        /* MINUTES_REG */
3818
#if ALMDEBUG
3819
        printf("RTC MIN_REG <-- %02x\n", value);
3820
#endif
3821
        s->ti -= s->current_tm.tm_min * 60;
3822
        s->ti += omap_rtc_bin(value) * 60;
3823
        return;
3824

    
3825
    case 0x08:        /* HOURS_REG */
3826
#if ALMDEBUG
3827
        printf("RTC HRS_REG <-- %02x\n", value);
3828
#endif
3829
        s->ti -= s->current_tm.tm_hour * 3600;
3830
        if (s->pm_am) {
3831
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3832
            s->ti += ((value >> 7) & 1) * 43200;
3833
        } else
3834
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3835
        return;
3836

    
3837
    case 0x0c:        /* DAYS_REG */
3838
#if ALMDEBUG
3839
        printf("RTC DAY_REG <-- %02x\n", value);
3840
#endif
3841
        s->ti -= s->current_tm.tm_mday * 86400;
3842
        s->ti += omap_rtc_bin(value) * 86400;
3843
        return;
3844

    
3845
    case 0x10:        /* MONTHS_REG */
3846
#if ALMDEBUG
3847
        printf("RTC MTH_REG <-- %02x\n", value);
3848
#endif
3849
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3850
        new_tm.tm_mon = omap_rtc_bin(value);
3851
        ti[0] = mktime(&s->current_tm);
3852
        ti[1] = mktime(&new_tm);
3853

    
3854
        if (ti[0] != -1 && ti[1] != -1) {
3855
            s->ti -= ti[0];
3856
            s->ti += ti[1];
3857
        } else {
3858
            /* A less accurate version */
3859
            s->ti -= s->current_tm.tm_mon * 2592000;
3860
            s->ti += omap_rtc_bin(value) * 2592000;
3861
        }
3862
        return;
3863

    
3864
    case 0x14:        /* YEARS_REG */
3865
#if ALMDEBUG
3866
        printf("RTC YRS_REG <-- %02x\n", value);
3867
#endif
3868
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3869
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3870
        ti[0] = mktime(&s->current_tm);
3871
        ti[1] = mktime(&new_tm);
3872

    
3873
        if (ti[0] != -1 && ti[1] != -1) {
3874
            s->ti -= ti[0];
3875
            s->ti += ti[1];
3876
        } else {
3877
            /* A less accurate version */
3878
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3879
            s->ti += omap_rtc_bin(value) * 31536000;
3880
        }
3881
        return;
3882

    
3883
    case 0x18:        /* WEEK_REG */
3884
        return;        /* Ignored */
3885

    
3886
    case 0x20:        /* ALARM_SECONDS_REG */
3887
#if ALMDEBUG
3888
        printf("ALM SEC_REG <-- %02x\n", value);
3889
#endif
3890
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3891
        omap_rtc_alarm_update(s);
3892
        return;
3893

    
3894
    case 0x24:        /* ALARM_MINUTES_REG */
3895
#if ALMDEBUG
3896
        printf("ALM MIN_REG <-- %02x\n", value);
3897
#endif
3898
        s->alarm_tm.tm_min = omap_rtc_bin(value);
3899
        omap_rtc_alarm_update(s);
3900
        return;
3901

    
3902
    case 0x28:        /* ALARM_HOURS_REG */
3903
#if ALMDEBUG
3904
        printf("ALM HRS_REG <-- %02x\n", value);
3905
#endif
3906
        if (s->pm_am)
3907
            s->alarm_tm.tm_hour =
3908
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
3909
                    ((value >> 7) & 1) * 12;
3910
        else
3911
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
3912
        omap_rtc_alarm_update(s);
3913
        return;
3914

    
3915
    case 0x2c:        /* ALARM_DAYS_REG */
3916
#if ALMDEBUG
3917
        printf("ALM DAY_REG <-- %02x\n", value);
3918
#endif
3919
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3920
        omap_rtc_alarm_update(s);
3921
        return;
3922

    
3923
    case 0x30:        /* ALARM_MONTHS_REG */
3924
#if ALMDEBUG
3925
        printf("ALM MON_REG <-- %02x\n", value);
3926
#endif
3927
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3928
        omap_rtc_alarm_update(s);
3929
        return;
3930

    
3931
    case 0x34:        /* ALARM_YEARS_REG */
3932
#if ALMDEBUG
3933
        printf("ALM YRS_REG <-- %02x\n", value);
3934
#endif
3935
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3936
        omap_rtc_alarm_update(s);
3937
        return;
3938

    
3939
    case 0x40:        /* RTC_CTRL_REG */
3940
#if ALMDEBUG
3941
        printf("RTC CONTROL <-- %02x\n", value);
3942
#endif
3943
        s->pm_am = (value >> 3) & 1;
3944
        s->auto_comp = (value >> 2) & 1;
3945
        s->round = (value >> 1) & 1;
3946
        s->running = value & 1;
3947
        s->status &= 0xfd;
3948
        s->status |= s->running << 1;
3949
        return;
3950

    
3951
    case 0x44:        /* RTC_STATUS_REG */
3952
#if ALMDEBUG
3953
        printf("RTC STATUSL <-- %02x\n", value);
3954
#endif
3955
        s->status &= ~((value & 0xc0) ^ 0x80);
3956
        omap_rtc_interrupts_update(s);
3957
        return;
3958

    
3959
    case 0x48:        /* RTC_INTERRUPTS_REG */
3960
#if ALMDEBUG
3961
        printf("RTC INTRS <-- %02x\n", value);
3962
#endif
3963
        s->interrupts = value;
3964
        return;
3965

    
3966
    case 0x4c:        /* RTC_COMP_LSB_REG */
3967
#if ALMDEBUG
3968
        printf("RTC COMPLSB <-- %02x\n", value);
3969
#endif
3970
        s->comp_reg &= 0xff00;
3971
        s->comp_reg |= 0x00ff & value;
3972
        return;
3973

    
3974
    case 0x50:        /* RTC_COMP_MSB_REG */
3975
#if ALMDEBUG
3976
        printf("RTC COMPMSB <-- %02x\n", value);
3977
#endif
3978
        s->comp_reg &= 0x00ff;
3979
        s->comp_reg |= 0xff00 & (value << 8);
3980
        return;
3981

    
3982
    default:
3983
        OMAP_BAD_REG(addr);
3984
        return;
3985
    }
3986
}
3987

    
3988
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3989
    omap_rtc_read,
3990
    omap_badwidth_read8,
3991
    omap_badwidth_read8,
3992
};
3993

    
3994
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3995
    omap_rtc_write,
3996
    omap_badwidth_write8,
3997
    omap_badwidth_write8,
3998
};
3999

    
4000
static void omap_rtc_tick(void *opaque)
4001
{
4002
    struct omap_rtc_s *s = opaque;
4003

    
4004
    if (s->round) {
4005
        /* Round to nearest full minute.  */
4006
        if (s->current_tm.tm_sec < 30)
4007
            s->ti -= s->current_tm.tm_sec;
4008
        else
4009
            s->ti += 60 - s->current_tm.tm_sec;
4010

    
4011
        s->round = 0;
4012
    }
4013

    
4014
    localtime_r(&s->ti, &s->current_tm);
4015

    
4016
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
4017
        s->status |= 0x40;
4018
        omap_rtc_interrupts_update(s);
4019
    }
4020

    
4021
    if (s->interrupts & 0x04)
4022
        switch (s->interrupts & 3) {
4023
        case 0:
4024
            s->status |= 0x04;
4025
            qemu_irq_pulse(s->irq);
4026
            break;
4027
        case 1:
4028
            if (s->current_tm.tm_sec)
4029
                break;
4030
            s->status |= 0x08;
4031
            qemu_irq_pulse(s->irq);
4032
            break;
4033
        case 2:
4034
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
4035
                break;
4036
            s->status |= 0x10;
4037
            qemu_irq_pulse(s->irq);
4038
            break;
4039
        case 3:
4040
            if (s->current_tm.tm_sec ||
4041
                            s->current_tm.tm_min || s->current_tm.tm_hour)
4042
                break;
4043
            s->status |= 0x20;
4044
            qemu_irq_pulse(s->irq);
4045
            break;
4046
        }
4047

    
4048
    /* Move on */
4049
    if (s->running)
4050
        s->ti ++;
4051
    s->tick += 1000;
4052

    
4053
    /*
4054
     * Every full hour add a rough approximation of the compensation
4055
     * register to the 32kHz Timer (which drives the RTC) value. 
4056
     */
4057
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
4058
        s->tick += s->comp_reg * 1000 / 32768;
4059

    
4060
    qemu_mod_timer(s->clk, s->tick);
4061
}
4062

    
4063
static void omap_rtc_reset(struct omap_rtc_s *s)
4064
{
4065
    s->interrupts = 0;
4066
    s->comp_reg = 0;
4067
    s->running = 0;
4068
    s->pm_am = 0;
4069
    s->auto_comp = 0;
4070
    s->round = 0;
4071
    s->tick = qemu_get_clock(rt_clock);
4072
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
4073
    s->alarm_tm.tm_mday = 0x01;
4074
    s->status = 1 << 7;
4075
    time(&s->ti);
4076
    s->ti = mktime(s->convert(&s->ti, &s->current_tm));
4077

    
4078
    omap_rtc_alarm_update(s);
4079
    omap_rtc_tick(s);
4080
}
4081

    
4082
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
4083
                qemu_irq *irq, omap_clk clk)
4084
{
4085
    int iomemtype;
4086
    struct omap_rtc_s *s = (struct omap_rtc_s *)
4087
            qemu_mallocz(sizeof(struct omap_rtc_s));
4088

    
4089
    s->base = base;
4090
    s->irq = irq[0];
4091
    s->alarm = irq[1];
4092
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
4093
    s->convert = rtc_utc ? gmtime_r : localtime_r;
4094

    
4095
    omap_rtc_reset(s);
4096

    
4097
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
4098
                    omap_rtc_writefn, s);
4099
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4100

    
4101
    return s;
4102
}
4103

    
4104
/* Multi-channel Buffered Serial Port interfaces */
4105
struct omap_mcbsp_s {
4106
    target_phys_addr_t base;
4107
    qemu_irq txirq;
4108
    qemu_irq rxirq;
4109
    qemu_irq txdrq;
4110
    qemu_irq rxdrq;
4111

    
4112
    uint16_t spcr[2];
4113
    uint16_t rcr[2];
4114
    uint16_t xcr[2];
4115
    uint16_t srgr[2];
4116
    uint16_t mcr[2];
4117
    uint16_t pcr;
4118
    uint16_t rcer[8];
4119
    uint16_t xcer[8];
4120
    int tx_rate;
4121
    int rx_rate;
4122
    int tx_req;
4123
    int rx_req;
4124

    
4125
    struct i2s_codec_s *codec;
4126
    QEMUTimer *source_timer;
4127
    QEMUTimer *sink_timer;
4128
};
4129

    
4130
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
4131
{
4132
    int irq;
4133

    
4134
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
4135
    case 0:
4136
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
4137
        break;
4138
    case 3:
4139
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
4140
        break;
4141
    default:
4142
        irq = 0;
4143
        break;
4144
    }
4145

    
4146
    if (irq)
4147
        qemu_irq_pulse(s->rxirq);
4148

    
4149
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
4150
    case 0:
4151
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
4152
        break;
4153
    case 3:
4154
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
4155
        break;
4156
    default:
4157
        irq = 0;
4158
        break;
4159
    }
4160

    
4161
    if (irq)
4162
        qemu_irq_pulse(s->txirq);
4163
}
4164

    
4165
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
4166
{
4167
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
4168
        s->spcr[0] |= 1 << 2;                                /* RFULL */
4169
    s->spcr[0] |= 1 << 1;                                /* RRDY */
4170
    qemu_irq_raise(s->rxdrq);
4171
    omap_mcbsp_intr_update(s);
4172
}
4173

    
4174
static void omap_mcbsp_source_tick(void *opaque)
4175
{
4176
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4177
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
4178

    
4179
    if (!s->rx_rate)
4180
        return;
4181
    if (s->rx_req)
4182
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
4183

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

    
4186
    omap_mcbsp_rx_newdata(s);
4187
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
4188
}
4189

    
4190
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
4191
{
4192
    if (!s->codec || !s->codec->rts)
4193
        omap_mcbsp_source_tick(s);
4194
    else if (s->codec->in.len) {
4195
        s->rx_req = s->codec->in.len;
4196
        omap_mcbsp_rx_newdata(s);
4197
    }
4198
}
4199

    
4200
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
4201
{
4202
    qemu_del_timer(s->source_timer);
4203
}
4204

    
4205
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
4206
{
4207
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
4208
    qemu_irq_lower(s->rxdrq);
4209
    omap_mcbsp_intr_update(s);
4210
}
4211

    
4212
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
4213
{
4214
    s->spcr[1] |= 1 << 1;                                /* XRDY */
4215
    qemu_irq_raise(s->txdrq);
4216
    omap_mcbsp_intr_update(s);
4217
}
4218

    
4219
static void omap_mcbsp_sink_tick(void *opaque)
4220
{
4221
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4222
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
4223

    
4224
    if (!s->tx_rate)
4225
        return;
4226
    if (s->tx_req)
4227
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
4228

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

    
4231
    omap_mcbsp_tx_newdata(s);
4232
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
4233
}
4234

    
4235
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
4236
{
4237
    if (!s->codec || !s->codec->cts)
4238
        omap_mcbsp_sink_tick(s);
4239
    else if (s->codec->out.size) {
4240
        s->tx_req = s->codec->out.size;
4241
        omap_mcbsp_tx_newdata(s);
4242
    }
4243
}
4244

    
4245
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
4246
{
4247
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
4248
    qemu_irq_lower(s->txdrq);
4249
    omap_mcbsp_intr_update(s);
4250
    if (s->codec && s->codec->cts)
4251
        s->codec->tx_swallow(s->codec->opaque);
4252
}
4253

    
4254
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
4255
{
4256
    s->tx_req = 0;
4257
    omap_mcbsp_tx_done(s);
4258
    qemu_del_timer(s->sink_timer);
4259
}
4260

    
4261
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
4262
{
4263
    int prev_rx_rate, prev_tx_rate;
4264
    int rx_rate = 0, tx_rate = 0;
4265
    int cpu_rate = 1500000;        /* XXX */
4266

    
4267
    /* TODO: check CLKSTP bit */
4268
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
4269
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
4270
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
4271
                            (s->pcr & (1 << 8))) {        /* CLKRM */
4272
                if (~s->pcr & (1 << 7))                        /* SCLKME */
4273
                    rx_rate = cpu_rate /
4274
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
4275
            } else
4276
                if (s->codec)
4277
                    rx_rate = s->codec->rx_rate;
4278
        }
4279

    
4280
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
4281
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
4282
                            (s->pcr & (1 << 9))) {        /* CLKXM */
4283
                if (~s->pcr & (1 << 7))                        /* SCLKME */
4284
                    tx_rate = cpu_rate /
4285
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
4286
            } else
4287
                if (s->codec)
4288
                    tx_rate = s->codec->tx_rate;
4289
        }
4290
    }
4291
    prev_tx_rate = s->tx_rate;
4292
    prev_rx_rate = s->rx_rate;
4293
    s->tx_rate = tx_rate;
4294
    s->rx_rate = rx_rate;
4295

    
4296
    if (s->codec)
4297
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
4298

    
4299
    if (!prev_tx_rate && tx_rate)
4300
        omap_mcbsp_tx_start(s);
4301
    else if (s->tx_rate && !tx_rate)
4302
        omap_mcbsp_tx_stop(s);
4303

    
4304
    if (!prev_rx_rate && rx_rate)
4305
        omap_mcbsp_rx_start(s);
4306
    else if (prev_tx_rate && !tx_rate)
4307
        omap_mcbsp_rx_stop(s);
4308
}
4309

    
4310
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
4311
{
4312
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4313
    int offset = addr & OMAP_MPUI_REG_MASK;
4314
    uint16_t ret;
4315

    
4316
    switch (offset) {
4317
    case 0x00:        /* DRR2 */
4318
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
4319
            return 0x0000;
4320
        /* Fall through.  */
4321
    case 0x02:        /* DRR1 */
4322
        if (s->rx_req < 2) {
4323
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
4324
            omap_mcbsp_rx_done(s);
4325
        } else {
4326
            s->tx_req -= 2;
4327
            if (s->codec && s->codec->in.len >= 2) {
4328
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
4329
                ret |= s->codec->in.fifo[s->codec->in.start ++];
4330
                s->codec->in.len -= 2;
4331
            } else
4332
                ret = 0x0000;
4333
            if (!s->tx_req)
4334
                omap_mcbsp_rx_done(s);
4335
            return ret;
4336
        }
4337
        return 0x0000;
4338

    
4339
    case 0x04:        /* DXR2 */
4340
    case 0x06:        /* DXR1 */
4341
        return 0x0000;
4342

    
4343
    case 0x08:        /* SPCR2 */
4344
        return s->spcr[1];
4345
    case 0x0a:        /* SPCR1 */
4346
        return s->spcr[0];
4347
    case 0x0c:        /* RCR2 */
4348
        return s->rcr[1];
4349
    case 0x0e:        /* RCR1 */
4350
        return s->rcr[0];
4351
    case 0x10:        /* XCR2 */
4352
        return s->xcr[1];
4353
    case 0x12:        /* XCR1 */
4354
        return s->xcr[0];
4355
    case 0x14:        /* SRGR2 */
4356
        return s->srgr[1];
4357
    case 0x16:        /* SRGR1 */
4358
        return s->srgr[0];
4359
    case 0x18:        /* MCR2 */
4360
        return s->mcr[1];
4361
    case 0x1a:        /* MCR1 */
4362
        return s->mcr[0];
4363
    case 0x1c:        /* RCERA */
4364
        return s->rcer[0];
4365
    case 0x1e:        /* RCERB */
4366
        return s->rcer[1];
4367
    case 0x20:        /* XCERA */
4368
        return s->xcer[0];
4369
    case 0x22:        /* XCERB */
4370
        return s->xcer[1];
4371
    case 0x24:        /* PCR0 */
4372
        return s->pcr;
4373
    case 0x26:        /* RCERC */
4374
        return s->rcer[2];
4375
    case 0x28:        /* RCERD */
4376
        return s->rcer[3];
4377
    case 0x2a:        /* XCERC */
4378
        return s->xcer[2];
4379
    case 0x2c:        /* XCERD */
4380
        return s->xcer[3];
4381
    case 0x2e:        /* RCERE */
4382
        return s->rcer[4];
4383
    case 0x30:        /* RCERF */
4384
        return s->rcer[5];
4385
    case 0x32:        /* XCERE */
4386
        return s->xcer[4];
4387
    case 0x34:        /* XCERF */
4388
        return s->xcer[5];
4389
    case 0x36:        /* RCERG */
4390
        return s->rcer[6];
4391
    case 0x38:        /* RCERH */
4392
        return s->rcer[7];
4393
    case 0x3a:        /* XCERG */
4394
        return s->xcer[6];
4395
    case 0x3c:        /* XCERH */
4396
        return s->xcer[7];
4397
    }
4398

    
4399
    OMAP_BAD_REG(addr);
4400
    return 0;
4401
}
4402

    
4403
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
4404
                uint32_t value)
4405
{
4406
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4407
    int offset = addr & OMAP_MPUI_REG_MASK;
4408

    
4409
    switch (offset) {
4410
    case 0x00:        /* DRR2 */
4411
    case 0x02:        /* DRR1 */
4412
        OMAP_RO_REG(addr);
4413
        return;
4414

    
4415
    case 0x04:        /* DXR2 */
4416
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4417
            return;
4418
        /* Fall through.  */
4419
    case 0x06:        /* DXR1 */
4420
        if (s->tx_req > 1) {
4421
            s->tx_req -= 2;
4422
            if (s->codec && s->codec->cts) {
4423
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
4424
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
4425
            }
4426
            if (s->tx_req < 2)
4427
                omap_mcbsp_tx_done(s);
4428
        } else
4429
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4430
        return;
4431

    
4432
    case 0x08:        /* SPCR2 */
4433
        s->spcr[1] &= 0x0002;
4434
        s->spcr[1] |= 0x03f9 & value;
4435
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
4436
        if (~value & 1)                                        /* XRST */
4437
            s->spcr[1] &= ~6;
4438
        omap_mcbsp_req_update(s);
4439
        return;
4440
    case 0x0a:        /* SPCR1 */
4441
        s->spcr[0] &= 0x0006;
4442
        s->spcr[0] |= 0xf8f9 & value;
4443
        if (value & (1 << 15))                                /* DLB */
4444
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
4445
        if (~value & 1) {                                /* RRST */
4446
            s->spcr[0] &= ~6;
4447
            s->rx_req = 0;
4448
            omap_mcbsp_rx_done(s);
4449
        }
4450
        omap_mcbsp_req_update(s);
4451
        return;
4452

    
4453
    case 0x0c:        /* RCR2 */
4454
        s->rcr[1] = value & 0xffff;
4455
        return;
4456
    case 0x0e:        /* RCR1 */
4457
        s->rcr[0] = value & 0x7fe0;
4458
        return;
4459
    case 0x10:        /* XCR2 */
4460
        s->xcr[1] = value & 0xffff;
4461
        return;
4462
    case 0x12:        /* XCR1 */
4463
        s->xcr[0] = value & 0x7fe0;
4464
        return;
4465
    case 0x14:        /* SRGR2 */
4466
        s->srgr[1] = value & 0xffff;
4467
        omap_mcbsp_req_update(s);
4468
        return;
4469
    case 0x16:        /* SRGR1 */
4470
        s->srgr[0] = value & 0xffff;
4471
        omap_mcbsp_req_update(s);
4472
        return;
4473
    case 0x18:        /* MCR2 */
4474
        s->mcr[1] = value & 0x03e3;
4475
        if (value & 3)                                        /* XMCM */
4476
            printf("%s: Tx channel selection mode enable attempt\n",
4477
                            __FUNCTION__);
4478
        return;
4479
    case 0x1a:        /* MCR1 */
4480
        s->mcr[0] = value & 0x03e1;
4481
        if (value & 1)                                        /* RMCM */
4482
            printf("%s: Rx channel selection mode enable attempt\n",
4483
                            __FUNCTION__);
4484
        return;
4485
    case 0x1c:        /* RCERA */
4486
        s->rcer[0] = value & 0xffff;
4487
        return;
4488
    case 0x1e:        /* RCERB */
4489
        s->rcer[1] = value & 0xffff;
4490
        return;
4491
    case 0x20:        /* XCERA */
4492
        s->xcer[0] = value & 0xffff;
4493
        return;
4494
    case 0x22:        /* XCERB */
4495
        s->xcer[1] = value & 0xffff;
4496
        return;
4497
    case 0x24:        /* PCR0 */
4498
        s->pcr = value & 0x7faf;
4499
        return;
4500
    case 0x26:        /* RCERC */
4501
        s->rcer[2] = value & 0xffff;
4502
        return;
4503
    case 0x28:        /* RCERD */
4504
        s->rcer[3] = value & 0xffff;
4505
        return;
4506
    case 0x2a:        /* XCERC */
4507
        s->xcer[2] = value & 0xffff;
4508
        return;
4509
    case 0x2c:        /* XCERD */
4510
        s->xcer[3] = value & 0xffff;
4511
        return;
4512
    case 0x2e:        /* RCERE */
4513
        s->rcer[4] = value & 0xffff;
4514
        return;
4515
    case 0x30:        /* RCERF */
4516
        s->rcer[5] = value & 0xffff;
4517
        return;
4518
    case 0x32:        /* XCERE */
4519
        s->xcer[4] = value & 0xffff;
4520
        return;
4521
    case 0x34:        /* XCERF */
4522
        s->xcer[5] = value & 0xffff;
4523
        return;
4524
    case 0x36:        /* RCERG */
4525
        s->rcer[6] = value & 0xffff;
4526
        return;
4527
    case 0x38:        /* RCERH */
4528
        s->rcer[7] = value & 0xffff;
4529
        return;
4530
    case 0x3a:        /* XCERG */
4531
        s->xcer[6] = value & 0xffff;
4532
        return;
4533
    case 0x3c:        /* XCERH */
4534
        s->xcer[7] = value & 0xffff;
4535
        return;
4536
    }
4537

    
4538
    OMAP_BAD_REG(addr);
4539
}
4540

    
4541
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
4542
                uint32_t value)
4543
{
4544
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4545
    int offset = addr & OMAP_MPUI_REG_MASK;
4546

    
4547
    if (offset == 0x04) {                                /* DXR */
4548
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4549
            return;
4550
        if (s->tx_req > 3) {
4551
            s->tx_req -= 4;
4552
            if (s->codec && s->codec->cts) {
4553
                s->codec->out.fifo[s->codec->out.len ++] =
4554
                        (value >> 24) & 0xff;
4555
                s->codec->out.fifo[s->codec->out.len ++] =
4556
                        (value >> 16) & 0xff;
4557
                s->codec->out.fifo[s->codec->out.len ++] =
4558
                        (value >> 8) & 0xff;
4559
                s->codec->out.fifo[s->codec->out.len ++] =
4560
                        (value >> 0) & 0xff;
4561
            }
4562
            if (s->tx_req < 4)
4563
                omap_mcbsp_tx_done(s);
4564
        } else
4565
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4566
        return;
4567
    }
4568

    
4569
    omap_badwidth_write16(opaque, addr, value);
4570
}
4571

    
4572
static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
4573
    omap_badwidth_read16,
4574
    omap_mcbsp_read,
4575
    omap_badwidth_read16,
4576
};
4577

    
4578
static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
4579
    omap_badwidth_write16,
4580
    omap_mcbsp_writeh,
4581
    omap_mcbsp_writew,
4582
};
4583

    
4584
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
4585
{
4586
    memset(&s->spcr, 0, sizeof(s->spcr));
4587
    memset(&s->rcr, 0, sizeof(s->rcr));
4588
    memset(&s->xcr, 0, sizeof(s->xcr));
4589
    s->srgr[0] = 0x0001;
4590
    s->srgr[1] = 0x2000;
4591
    memset(&s->mcr, 0, sizeof(s->mcr));
4592
    memset(&s->pcr, 0, sizeof(s->pcr));
4593
    memset(&s->rcer, 0, sizeof(s->rcer));
4594
    memset(&s->xcer, 0, sizeof(s->xcer));
4595
    s->tx_req = 0;
4596
    s->rx_req = 0;
4597
    s->tx_rate = 0;
4598
    s->rx_rate = 0;
4599
    qemu_del_timer(s->source_timer);
4600
    qemu_del_timer(s->sink_timer);
4601
}
4602

    
4603
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
4604
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
4605
{
4606
    int iomemtype;
4607
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
4608
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
4609

    
4610
    s->base = base;
4611
    s->txirq = irq[0];
4612
    s->rxirq = irq[1];
4613
    s->txdrq = dma[0];
4614
    s->rxdrq = dma[1];
4615
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
4616
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
4617
    omap_mcbsp_reset(s);
4618

    
4619
    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
4620
                    omap_mcbsp_writefn, s);
4621
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4622

    
4623
    return s;
4624
}
4625

    
4626
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4627
{
4628
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4629

    
4630
    if (s->rx_rate) {
4631
        s->rx_req = s->codec->in.len;
4632
        omap_mcbsp_rx_newdata(s);
4633
    }
4634
}
4635

    
4636
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
4637
{
4638
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4639

    
4640
    if (s->tx_rate) {
4641
        s->tx_req = s->codec->out.size;
4642
        omap_mcbsp_tx_newdata(s);
4643
    }
4644
}
4645

    
4646
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
4647
{
4648
    s->codec = slave;
4649
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4650
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4651
}
4652

    
4653
/* LED Pulse Generators */
4654
struct omap_lpg_s {
4655
    target_phys_addr_t base;
4656
    QEMUTimer *tm;
4657

    
4658
    uint8_t control;
4659
    uint8_t power;
4660
    int64_t on;
4661
    int64_t period;
4662
    int clk;
4663
    int cycle;
4664
};
4665

    
4666
static void omap_lpg_tick(void *opaque)
4667
{
4668
    struct omap_lpg_s *s = opaque;
4669

    
4670
    if (s->cycle)
4671
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
4672
    else
4673
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
4674

    
4675
    s->cycle = !s->cycle;
4676
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
4677
}
4678

    
4679
static void omap_lpg_update(struct omap_lpg_s *s)
4680
{
4681
    int64_t on, period = 1, ticks = 1000;
4682
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
4683

    
4684
    if (~s->control & (1 << 6))                                        /* LPGRES */
4685
        on = 0;
4686
    else if (s->control & (1 << 7))                                /* PERM_ON */
4687
        on = period;
4688
    else {
4689
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
4690
                        256 / 32);
4691
        on = (s->clk && s->power) ? muldiv64(ticks,
4692
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
4693
    }
4694

    
4695
    qemu_del_timer(s->tm);
4696
    if (on == period && s->on < s->period)
4697
        printf("%s: LED is on\n", __FUNCTION__);
4698
    else if (on == 0 && s->on)
4699
        printf("%s: LED is off\n", __FUNCTION__);
4700
    else if (on && (on != s->on || period != s->period)) {
4701
        s->cycle = 0;
4702
        s->on = on;
4703
        s->period = period;
4704
        omap_lpg_tick(s);
4705
        return;
4706
    }
4707

    
4708
    s->on = on;
4709
    s->period = period;
4710
}
4711

    
4712
static void omap_lpg_reset(struct omap_lpg_s *s)
4713
{
4714
    s->control = 0x00;
4715
    s->power = 0x00;
4716
    s->clk = 1;
4717
    omap_lpg_update(s);
4718
}
4719

    
4720
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
4721
{
4722
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4723
    int offset = addr & OMAP_MPUI_REG_MASK;
4724

    
4725
    switch (offset) {
4726
    case 0x00:        /* LCR */
4727
        return s->control;
4728

    
4729
    case 0x04:        /* PMR */
4730
        return s->power;
4731
    }
4732

    
4733
    OMAP_BAD_REG(addr);
4734
    return 0;
4735
}
4736

    
4737
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
4738
                uint32_t value)
4739
{
4740
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4741
    int offset = addr & OMAP_MPUI_REG_MASK;
4742

    
4743
    switch (offset) {
4744
    case 0x00:        /* LCR */
4745
        if (~value & (1 << 6))                                        /* LPGRES */
4746
            omap_lpg_reset(s);
4747
        s->control = value & 0xff;
4748
        omap_lpg_update(s);
4749
        return;
4750

    
4751
    case 0x04:        /* PMR */
4752
        s->power = value & 0x01;
4753
        omap_lpg_update(s);
4754
        return;
4755

    
4756
    default:
4757
        OMAP_BAD_REG(addr);
4758
        return;
4759
    }
4760
}
4761

    
4762
static CPUReadMemoryFunc *omap_lpg_readfn[] = {
4763
    omap_lpg_read,
4764
    omap_badwidth_read8,
4765
    omap_badwidth_read8,
4766
};
4767

    
4768
static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
4769
    omap_lpg_write,
4770
    omap_badwidth_write8,
4771
    omap_badwidth_write8,
4772
};
4773

    
4774
static void omap_lpg_clk_update(void *opaque, int line, int on)
4775
{
4776
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4777

    
4778
    s->clk = on;
4779
    omap_lpg_update(s);
4780
}
4781

    
4782
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4783
{
4784
    int iomemtype;
4785
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4786
            qemu_mallocz(sizeof(struct omap_lpg_s));
4787

    
4788
    s->base = base;
4789
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4790

    
4791
    omap_lpg_reset(s);
4792

    
4793
    iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
4794
                    omap_lpg_writefn, s);
4795
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4796

    
4797
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4798

    
4799
    return s;
4800
}
4801

    
4802
/* MPUI Peripheral Bridge configuration */
4803
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
4804
{
4805
    if (addr == OMAP_MPUI_BASE)        /* CMR */
4806
        return 0xfe4d;
4807

    
4808
    OMAP_BAD_REG(addr);
4809
    return 0;
4810
}
4811

    
4812
static CPUReadMemoryFunc *omap_mpui_io_readfn[] = {
4813
    omap_badwidth_read16,
4814
    omap_mpui_io_read,
4815
    omap_badwidth_read16,
4816
};
4817

    
4818
static CPUWriteMemoryFunc *omap_mpui_io_writefn[] = {
4819
    omap_badwidth_write16,
4820
    omap_badwidth_write16,
4821
    omap_badwidth_write16,
4822
};
4823

    
4824
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4825
{
4826
    int iomemtype = cpu_register_io_memory(0, omap_mpui_io_readfn,
4827
                    omap_mpui_io_writefn, mpu);
4828
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
4829
}
4830

    
4831
/* General chip reset */
4832
static void omap_mpu_reset(void *opaque)
4833
{
4834
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4835

    
4836
    omap_inth_reset(mpu->ih[0]);
4837
    omap_inth_reset(mpu->ih[1]);
4838
    omap_dma_reset(mpu->dma);
4839
    omap_mpu_timer_reset(mpu->timer[0]);
4840
    omap_mpu_timer_reset(mpu->timer[1]);
4841
    omap_mpu_timer_reset(mpu->timer[2]);
4842
    omap_wd_timer_reset(mpu->wdt);
4843
    omap_os_timer_reset(mpu->os_timer);
4844
    omap_lcdc_reset(mpu->lcd);
4845
    omap_ulpd_pm_reset(mpu);
4846
    omap_pin_cfg_reset(mpu);
4847
    omap_mpui_reset(mpu);
4848
    omap_tipb_bridge_reset(mpu->private_tipb);
4849
    omap_tipb_bridge_reset(mpu->public_tipb);
4850
    omap_dpll_reset(&mpu->dpll[0]);
4851
    omap_dpll_reset(&mpu->dpll[1]);
4852
    omap_dpll_reset(&mpu->dpll[2]);
4853
    omap_uart_reset(mpu->uart[0]);
4854
    omap_uart_reset(mpu->uart[1]);
4855
    omap_uart_reset(mpu->uart[2]);
4856
    omap_mmc_reset(mpu->mmc);
4857
    omap_mpuio_reset(mpu->mpuio);
4858
    omap_gpio_reset(mpu->gpio);
4859
    omap_uwire_reset(mpu->microwire);
4860
    omap_pwl_reset(mpu);
4861
    omap_pwt_reset(mpu);
4862
    omap_i2c_reset(mpu->i2c);
4863
    omap_rtc_reset(mpu->rtc);
4864
    omap_mcbsp_reset(mpu->mcbsp1);
4865
    omap_mcbsp_reset(mpu->mcbsp2);
4866
    omap_mcbsp_reset(mpu->mcbsp3);
4867
    omap_lpg_reset(mpu->led[0]);
4868
    omap_lpg_reset(mpu->led[1]);
4869
    omap_clkm_reset(mpu);
4870
    cpu_reset(mpu->env);
4871
}
4872

    
4873
static const struct omap_map_s {
4874
    target_phys_addr_t phys_dsp;
4875
    target_phys_addr_t phys_mpu;
4876
    uint32_t size;
4877
    const char *name;
4878
} omap15xx_dsp_mm[] = {
4879
    /* Strobe 0 */
4880
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
4881
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
4882
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
4883
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
4884
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
4885
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
4886
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
4887
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
4888
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
4889
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
4890
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
4891
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
4892
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
4893
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
4894
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
4895
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
4896
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
4897
    /* Strobe 1 */
4898
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
4899

    
4900
    { 0 }
4901
};
4902

    
4903
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4904
{
4905
    int io;
4906

    
4907
    for (; map->phys_dsp; map ++) {
4908
        io = cpu_get_physical_page_desc(map->phys_mpu);
4909

    
4910
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4911
    }
4912
}
4913

    
4914
static void omap_mpu_wakeup(void *opaque, int irq, int req)
4915
{
4916
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4917

    
4918
    if (mpu->env->halted)
4919
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4920
}
4921

    
4922
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4923
                DisplayState *ds, const char *core)
4924
{
4925
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4926
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4927
    ram_addr_t imif_base, emiff_base;
4928
    qemu_irq *cpu_irq;
4929
    int sdindex;
4930

    
4931
    if (!core)
4932
        core = "ti925t";
4933

    
4934
    /* Core */
4935
    s->mpu_model = omap310;
4936
    s->env = cpu_init(core);
4937
    if (!s->env) {
4938
        fprintf(stderr, "Unable to find CPU definition\n");
4939
        exit(1);
4940
    }
4941
    s->sdram_size = sdram_size;
4942
    s->sram_size = OMAP15XX_SRAM_SIZE;
4943

    
4944
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4945

    
4946
    /* Clocks */
4947
    omap_clk_init(s);
4948

    
4949
    /* Memory-mapped stuff */
4950
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4951
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4952
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4953
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4954

    
4955
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4956

    
4957
    cpu_irq = arm_pic_init_cpu(s->env);
4958
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1,
4959
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4960
                    omap_findclk(s, "arminth_ck"));
4961
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1,
4962
                    s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
4963
                    omap_findclk(s, "arminth_ck"));
4964
    s->irq[0] = s->ih[0]->pins;
4965
    s->irq[1] = s->ih[1]->pins;
4966

    
4967
    s->dma = omap_dma_init(0xfffed800, s->irq[0], s,
4968
                    omap_findclk(s, "dma_ck"));
4969
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4970
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4971
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4972
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4973
    s->port[local    ].addr_valid = omap_validate_local_addr;
4974
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4975

    
4976
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4977
                    s->irq[0][OMAP_INT_TIMER1],
4978
                    omap_findclk(s, "mputim_ck"));
4979
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4980
                    s->irq[0][OMAP_INT_TIMER2],
4981
                    omap_findclk(s, "mputim_ck"));
4982
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4983
                    s->irq[0][OMAP_INT_TIMER3],
4984
                    omap_findclk(s, "mputim_ck"));
4985

    
4986
    s->wdt = omap_wd_timer_init(0xfffec800,
4987
                    s->irq[0][OMAP_INT_WD_TIMER],
4988
                    omap_findclk(s, "armwdt_ck"));
4989

    
4990
    s->os_timer = omap_os_timer_init(0xfffb9000,
4991
                    s->irq[1][OMAP_INT_OS_TIMER],
4992
                    omap_findclk(s, "clk32-kHz"));
4993

    
4994
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4995
                    &s->dma->lcd_ch, ds, imif_base, emiff_base,
4996
                    omap_findclk(s, "lcd_ck"));
4997

    
4998
    omap_ulpd_pm_init(0xfffe0800, s);
4999
    omap_pin_cfg_init(0xfffe1000, s);
5000
    omap_id_init(s);
5001

    
5002
    omap_mpui_init(0xfffec900, s);
5003

    
5004
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
5005
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
5006
                    omap_findclk(s, "tipb_ck"));
5007
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
5008
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
5009
                    omap_findclk(s, "tipb_ck"));
5010

    
5011
    omap_tcmi_init(0xfffecc00, s);
5012

    
5013
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
5014
                    omap_findclk(s, "uart1_ck"),
5015
                    serial_hds[0]);
5016
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
5017
                    omap_findclk(s, "uart2_ck"),
5018
                    serial_hds[0] ? serial_hds[1] : 0);
5019
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
5020
                    omap_findclk(s, "uart3_ck"),
5021
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
5022

    
5023
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
5024
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
5025
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
5026

    
5027
    sdindex = drive_get_index(IF_SD, 0, 0);
5028
    if (sdindex == -1) {
5029
        fprintf(stderr, "qemu: missing SecureDigital device\n");
5030
        exit(1);
5031
    }
5032
    s->mmc = omap_mmc_init(0xfffb7800, drives_table[sdindex].bdrv,
5033
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
5034
                    omap_findclk(s, "mmc_ck"));
5035

    
5036
    s->mpuio = omap_mpuio_init(0xfffb5000,
5037
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
5038
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
5039

    
5040
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
5041
                    omap_findclk(s, "arm_gpio_ck"));
5042

    
5043
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
5044
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
5045

    
5046
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
5047
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
5048

    
5049
    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
5050
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
5051

    
5052
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
5053
                    omap_findclk(s, "clk32-kHz"));
5054

    
5055
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
5056
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
5057
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
5058
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
5059
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
5060
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
5061

    
5062
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
5063
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
5064

    
5065
    /* Register mappings not currenlty implemented:
5066
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
5067
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
5068
     * USB W2FC                fffb4000 - fffb47ff
5069
     * Camera Interface        fffb6800 - fffb6fff
5070
     * USB Host                fffba000 - fffba7ff
5071
     * FAC                fffba800 - fffbafff
5072
     * HDQ/1-Wire        fffbc000 - fffbc7ff
5073
     * TIPB switches        fffbc800 - fffbcfff
5074
     * Mailbox                fffcf000 - fffcf7ff
5075
     * Local bus IF        fffec100 - fffec1ff
5076
     * Local bus MMU        fffec200 - fffec2ff
5077
     * DSP MMU                fffed200 - fffed2ff
5078
     */
5079

    
5080
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
5081
    omap_setup_mpui_io(s);
5082

    
5083
    qemu_register_reset(omap_mpu_reset, s);
5084

    
5085
    return s;
5086
}