Statistics
| Branch: | Revision:

root / hw / omap.c @ 089b7c0a

History | View | Annotate | Download (158.4 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 line_no;
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
struct omap_dma_channel_s {
406
    /* transfer data */
407
    int burst[2];
408
    int pack[2];
409
    enum omap_dma_port port[2];
410
    target_phys_addr_t addr[2];
411
    omap_dma_addressing_t mode[2];
412
    uint16_t elements;
413
    uint16_t frames;
414
    int16_t frame_index[2];
415
    int16_t element_index[2];
416
    int data_type;
417

    
418
    /* transfer type */
419
    int transparent_copy;
420
    int constant_fill;
421
    uint32_t color;
422

    
423
    /* auto init and linked channel data */
424
    int end_prog;
425
    int repeat;
426
    int auto_init;
427
    int link_enabled;
428
    int link_next_ch;
429

    
430
    /* interruption data */
431
    int interrupts;
432
    int status;
433

    
434
    /* state data */
435
    int active;
436
    int enable;
437
    int sync;
438
    int pending_request;
439
    int waiting_end_prog;
440
    uint16_t cpc;
441

    
442
    /* sync type */
443
    int fs;
444
    int bs;
445

    
446
    /* compatibility */
447
    int omap_3_1_compatible_disable;
448

    
449
    struct omap_dma_reg_set_s {
450
        target_phys_addr_t src, dest;
451
        int frame;
452
        int element;
453
        int frame_delta[2];
454
        int elem_delta[2];
455
        int frames;
456
        int elements;
457
    } active_set;
458

    
459
    /* unused parameters */
460
    int priority;
461
    int interleave_disabled;
462
    int type;
463
};
464

    
465
struct omap_dma_s {
466
    qemu_irq irqs[16];
467
    QEMUTimer *tm;
468
    struct omap_mpu_state_s *mpu;
469
    target_phys_addr_t base;
470
    omap_clk clk;
471
    int64_t delay;
472
    uint32_t drq;
473
    enum omap_dma_model model;
474
    int omap_3_1_mapping_disabled;
475

    
476
    uint16_t gcr;
477
    int run_count;
478

    
479
    int chans;
480
    struct omap_dma_channel_s ch[16];
481
    struct omap_dma_lcd_channel_s lcd_ch;
482
};
483

    
484
/* Interrupts */
485
#define TIMEOUT_INTR    (1 << 0)
486
#define EVENT_DROP_INTR (1 << 1)
487
#define HALF_FRAME_INTR (1 << 2)
488
#define END_FRAME_INTR  (1 << 3)
489
#define LAST_FRAME_INTR (1 << 4)
490
#define END_BLOCK_INTR  (1 << 5)
491
#define SYNC            (1 << 6)
492

    
493
static int omap_dma_get_sibling_channel(struct omap_dma_s *s, int channel)
494
{
495
    if (s->omap_3_1_mapping_disabled)
496
        return -1;
497
    switch (channel) {
498
    case 0 ... 2:
499
        return channel + 6;
500
    case 6 ... 8:
501
        return channel % 6;
502
    }
503
    return -1;
504
}
505

    
506
static void omap_dma_interrupts_update(struct omap_dma_s *s)
507
{
508
    int i, sibiling, raise;
509

    
510
    if (s->omap_3_1_mapping_disabled) {
511
        for (i = 0; i < s->chans; i ++) {
512
            if (s->ch[i].status)
513
                qemu_irq_raise(s->irqs[i]);
514
        }
515
    } else {
516
        /* First three interrupts are shared between two channels each. */
517
        for (i = 0; i < 6; i ++) {
518
            raise = s->ch[i].status;
519
            sibiling = omap_dma_get_sibling_channel(s, i);
520
            if (sibiling != -1)
521
                raise |= s->ch[sibiling].status;
522
            if (raise)
523
                qemu_irq_raise(s->irqs[i]);
524
        }
525
    }
526
}
527

    
528
static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
529
{
530
    struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
531
    int i;
532
    int omap_3_1 = !s->ch[ch].omap_3_1_compatible_disable;
533

    
534
    /*
535
     * TODO: verify address ranges and alignment
536
     * TODO: port endianness
537
     */
538

    
539
    a->src = s->ch[ch].addr[0];
540
    a->dest = s->ch[ch].addr[1];
541
    a->frames = s->ch[ch].frames;
542
    a->elements = s->ch[ch].elements;
543
    a->frame = 0;
544
    a->element = 0;
545

    
546
    if (unlikely(!s->ch[ch].elements || !s->ch[ch].frames)) {
547
        printf("%s: bad DMA request\n", __FUNCTION__);
548
        return;
549
    }
550

    
551
    for (i = 0; i < 2; i ++)
552
        switch (s->ch[ch].mode[i]) {
553
        case constant:
554
            a->elem_delta[i] = 0;
555
            a->frame_delta[i] = 0;
556
            break;
557
        case post_incremented:
558
            a->elem_delta[i] = s->ch[ch].data_type;
559
            a->frame_delta[i] = 0;
560
            break;
561
        case single_index:
562
            a->elem_delta[i] = s->ch[ch].data_type +
563
                s->ch[ch].element_index[omap_3_1 ? 0 : i] - 1;
564
            a->frame_delta[i] = 0;
565
            break;
566
        case double_index:
567
            a->elem_delta[i] = s->ch[ch].data_type +
568
                s->ch[ch].element_index[omap_3_1 ? 0 : i] - 1;
569
            a->frame_delta[i] = s->ch[ch].frame_index[omap_3_1 ? 0 : i] -
570
                s->ch[ch].element_index[omap_3_1 ? 0 : i];
571
            break;
572
        default:
573
            break;
574
        }
575
}
576

    
577
static void omap_dma_activate_channel(struct omap_dma_s *s, int channel)
578
{
579
    if (!s->ch[channel].active) {
580
        s->ch[channel].active = 1;
581
        if (s->ch[channel].sync)
582
            s->ch[channel].status |= SYNC;
583
        s->run_count ++;
584
    }
585

    
586
    if (s->delay && !qemu_timer_pending(s->tm))
587
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
588
}
589

    
590
static void omap_dma_deactivate_channel(struct omap_dma_s *s, int channel)
591
{
592
    /* Update cpc */
593
    s->ch[channel].cpc = s->ch[channel].active_set.dest & 0xffff;
594

    
595
    if (s->ch[channel].pending_request &&
596
        !s->ch[channel].waiting_end_prog) {
597
        /* Don't deactivate the channel */
598
        s->ch[channel].pending_request = 0;
599
        return;
600
    }
601

    
602
    /* Don't deactive the channel if it is synchronized and the DMA request is
603
       active */
604
    if (s->ch[channel].sync && (s->drq & (1 << s->ch[channel].sync)))
605
        return;
606

    
607
    if (s->ch[channel].active) {
608
        s->ch[channel].active = 0;
609
        s->ch[channel].status &= ~SYNC;
610
        s->run_count --;
611
    }
612

    
613
    if (!s->run_count)
614
        qemu_del_timer(s->tm);
615
}
616

    
617
static void omap_dma_enable_channel(struct omap_dma_s *s, int channel)
618
{
619
    if (!s->ch[channel].enable) {
620
        s->ch[channel].enable = 1;
621
        s->ch[channel].waiting_end_prog = 0;
622
        omap_dma_channel_load(s, channel);
623
        if ((!s->ch[channel].sync) || (s->drq & (1 << s->ch[channel].sync)))
624
            omap_dma_activate_channel(s, channel);
625
    }
626
}
627

    
628
static void omap_dma_disable_channel(struct omap_dma_s *s, int channel)
629
{
630
    if (s->ch[channel].enable) {
631
        s->ch[channel].enable = 0;
632
        /* Discard any pending request */
633
        s->ch[channel].pending_request = 0;
634
        omap_dma_deactivate_channel(s, channel);
635
    }
636
}
637

    
638
static void omap_dma_channel_end_prog(struct omap_dma_s *s, int channel)
639
{
640
    if (s->ch[channel].waiting_end_prog) {
641
        s->ch[channel].waiting_end_prog = 0;
642
        if (!s->ch[channel].sync || s->ch[channel].pending_request) {
643
            s->ch[channel].pending_request = 0;
644
            omap_dma_activate_channel(s, channel);
645
        }
646
    }
647
}
648

    
649
static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s)
650
{
651
    s->omap_3_1_mapping_disabled = 0;
652
    s->chans = 9;
653
}
654

    
655
static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s)
656
{
657
    s->omap_3_1_mapping_disabled = 1;
658
    s->chans = 16;
659
}
660

    
661
static void omap_dma_process_request(struct omap_dma_s *s, int request)
662
{
663
    int channel;
664
    int drop_event = 0;
665

    
666
    for (channel = 0; channel < s->chans; channel ++) {
667
        if (s->ch[channel].enable && s->ch[channel].sync == request) {
668
            if (!s->ch[channel].active)
669
                omap_dma_activate_channel(s, channel);
670
            else if (!s->ch[channel].pending_request)
671
                s->ch[channel].pending_request = 1;
672
            else {
673
                /* Request collision */
674
                /* Second request received while processing other request */
675
                s->ch[channel].status |= EVENT_DROP_INTR;
676
                drop_event = 1;
677
            }
678
        }
679
    }
680

    
681
    if (drop_event)
682
        omap_dma_interrupts_update(s);
683
}
684

    
685
static void omap_dma_channel_run(struct omap_dma_s *s)
686
{
687
    int ch;
688
    uint16_t status;
689
    uint8_t value[4];
690
    struct omap_dma_port_if_s *src_p, *dest_p;
691
    struct omap_dma_reg_set_s *a;
692

    
693
    for (ch = 0; ch < s->chans; ch ++) {
694
        if (!s->ch[ch].active)
695
            continue;
696

    
697
        a = &s->ch[ch].active_set;
698

    
699
        src_p = &s->mpu->port[s->ch[ch].port[0]];
700
        dest_p = &s->mpu->port[s->ch[ch].port[1]];
701
        if ((!s->ch[ch].constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||
702
                        (!dest_p->addr_valid(s->mpu, a->dest))) {
703
#if 0
704
            /* Bus time-out */
705
            if (s->ch[ch].interrupts & TIMEOUT_INTR)
706
                s->ch[ch].status |= TIMEOUT_INTR;
707
            omap_dma_deactivate_channel(s, ch);
708
            continue;
709
#endif
710
            printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch);
711
        }
712

    
713
        status = s->ch[ch].status;
714
        while (status == s->ch[ch].status && s->ch[ch].active) {
715
            /* Transfer a single element */
716
            /* FIXME: check the endianness */
717
            if (!s->ch[ch].constant_fill)
718
                cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
719
            else
720
                *(uint32_t *) value = s->ch[ch].color;
721

    
722
            if (!s->ch[ch].transparent_copy ||
723
                    *(uint32_t *) value != s->ch[ch].color)
724
                cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
725

    
726
            a->src += a->elem_delta[0];
727
            a->dest += a->elem_delta[1];
728
            a->element ++;
729

    
730
            /* If the channel is element synchronized, deactivate it */
731
            if (s->ch[ch].sync && !s->ch[ch].fs && !s->ch[ch].bs)
732
                omap_dma_deactivate_channel(s, ch);
733

    
734
            /* If it is the last frame, set the LAST_FRAME interrupt */
735
            if (a->element == 1 && a->frame == a->frames - 1)
736
                if (s->ch[ch].interrupts & LAST_FRAME_INTR)
737
                    s->ch[ch].status |= LAST_FRAME_INTR;
738

    
739
            /* If the half of the frame was reached, set the HALF_FRAME
740
               interrupt */
741
            if (a->element == (a->elements >> 1))
742
                if (s->ch[ch].interrupts & HALF_FRAME_INTR)
743
                    s->ch[ch].status |= HALF_FRAME_INTR;
744

    
745
            if (a->element == a->elements) {
746
                /* End of Frame */
747
                a->element = 0;
748
                a->src += a->frame_delta[0];
749
                a->dest += a->frame_delta[1];
750
                a->frame ++;
751

    
752
                /* If the channel is frame synchronized, deactivate it */
753
                if (s->ch[ch].sync && s->ch[ch].fs)
754
                    omap_dma_deactivate_channel(s, ch);
755

    
756
                /* If the channel is async, update cpc */
757
                if (!s->ch[ch].sync)
758
                    s->ch[ch].cpc = a->dest & 0xffff;
759

    
760
                /* Set the END_FRAME interrupt */
761
                if (s->ch[ch].interrupts & END_FRAME_INTR)
762
                    s->ch[ch].status |= END_FRAME_INTR;
763

    
764
                if (a->frame == a->frames) {
765
                    /* End of Block */
766
                    /* Disable the channel */
767

    
768
                    if (s->ch[ch].omap_3_1_compatible_disable) {
769
                        omap_dma_disable_channel(s, ch);
770
                        if (s->ch[ch].link_enabled)
771
                            omap_dma_enable_channel(s, s->ch[ch].link_next_ch);
772
                    } else {
773
                        if (!s->ch[ch].auto_init)
774
                            omap_dma_disable_channel(s, ch);
775
                        else if (s->ch[ch].repeat || s->ch[ch].end_prog)
776
                            omap_dma_channel_load(s, ch);
777
                        else {
778
                            s->ch[ch].waiting_end_prog = 1;
779
                            omap_dma_deactivate_channel(s, ch);
780
                        }
781
                    }
782

    
783
                    if (s->ch[ch].interrupts & END_BLOCK_INTR)
784
                        s->ch[ch].status |= END_BLOCK_INTR;
785
                }
786
            }
787
        }
788
    }
789

    
790
    omap_dma_interrupts_update(s);
791
    if (s->run_count && s->delay)
792
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
793
}
794

    
795
static void omap_dma_reset(struct omap_dma_s *s)
796
{
797
    int i;
798

    
799
    qemu_del_timer(s->tm);
800
    s->gcr = 0x0004;
801
    s->drq = 0x00000000;
802
    s->run_count = 0;
803
    s->lcd_ch.src = emiff;
804
    s->lcd_ch.condition = 0;
805
    s->lcd_ch.interrupts = 0;
806
    s->lcd_ch.dual = 0;
807
    omap_dma_enable_3_1_mapping(s);
808
    memset(s->ch, 0, sizeof(s->ch));
809
    for (i = 0; i < s->chans; i ++)
810
        s->ch[i].interrupts = 0x0003;
811
}
812

    
813
static int omap_dma_ch_reg_read(struct omap_dma_s *s, int ch, int reg,
814
                uint16_t *value)
815
{
816
    int sibling;
817

    
818
    switch (reg) {
819
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
820
        *value = (s->ch[ch].burst[1] << 14) |
821
                (s->ch[ch].pack[1] << 13) |
822
                (s->ch[ch].port[1] << 9) |
823
                (s->ch[ch].burst[0] << 7) |
824
                (s->ch[ch].pack[0] << 6) |
825
                (s->ch[ch].port[0] << 2) |
826
                (s->ch[ch].data_type >> 1);
827
        break;
828

    
829
    case 0x02:        /* SYS_DMA_CCR_CH0 */
830
        if (s->model == omap_dma_3_1)
831
            *value = 0 << 10;                                /* FIFO_FLUSH bit */
832
        else
833
            *value = s->ch[ch].omap_3_1_compatible_disable << 10;
834
        *value |= (s->ch[ch].mode[1] << 14) |
835
                (s->ch[ch].mode[0] << 12) |
836
                (s->ch[ch].end_prog << 11) |
837
                (s->ch[ch].repeat << 9) |
838
                (s->ch[ch].auto_init << 8) |
839
                (s->ch[ch].enable << 7) |
840
                (s->ch[ch].priority << 6) |
841
                (s->ch[ch].fs << 5) | s->ch[ch].sync;
842
        break;
843

    
844
    case 0x04:        /* SYS_DMA_CICR_CH0 */
845
        *value = s->ch[ch].interrupts;
846
        break;
847

    
848
    case 0x06:        /* SYS_DMA_CSR_CH0 */
849
        sibling = omap_dma_get_sibling_channel(s, ch);
850
        *value = s->ch[ch].status;
851
        s->ch[ch].status &= SYNC;
852
        if (sibling != -1) {
853
            *value |= (s->ch[sibling].status & 0x3f) << 6;
854
            s->ch[sibling].status &= SYNC;
855
            if (sibling < ch) {
856
                qemu_irq_lower(s->irqs[sibling]);
857
                break;
858
            }
859
        }
860
        qemu_irq_lower(s->irqs[ch]);
861
        break;
862

    
863
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
864
        *value = s->ch[ch].addr[0] & 0x0000ffff;
865
        break;
866

    
867
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
868
        *value = s->ch[ch].addr[0] >> 16;
869
        break;
870

    
871
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
872
        *value = s->ch[ch].addr[1] & 0x0000ffff;
873
        break;
874

    
875
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
876
        *value = s->ch[ch].addr[1] >> 16;
877
        break;
878

    
879
    case 0x10:        /* SYS_DMA_CEN_CH0 */
880
        *value = s->ch[ch].elements;
881
        break;
882

    
883
    case 0x12:        /* SYS_DMA_CFN_CH0 */
884
        *value = s->ch[ch].frames;
885
        break;
886

    
887
    case 0x14:        /* SYS_DMA_CFI_CH0 */
888
        *value = s->ch[ch].frame_index[0];
889
        break;
890

    
891
    case 0x16:        /* SYS_DMA_CEI_CH0 */
892
        *value = s->ch[ch].element_index[0];
893
        break;
894

    
895
    case 0x18:        /* SYS_DMA_CPC_CH0 or DMA_CSAC */
896
        if (s->ch[ch].omap_3_1_compatible_disable)
897
            *value = s->ch[ch].active_set.src & 0xffff;        /* CSAC */
898
        else
899
            *value = s->ch[ch].cpc;
900
        break;
901

    
902
    case 0x1a:        /* DMA_CDAC */
903
        *value = s->ch[ch].active_set.dest & 0xffff;        /* CDAC */
904
        break;
905

    
906
    case 0x1c:        /* DMA_CDEI */
907
        *value = s->ch[ch].element_index[1];
908
        break;
909

    
910
    case 0x1e:        /* DMA_CDFI */
911
        *value = s->ch[ch].frame_index[1];
912
        break;
913

    
914
    case 0x20:        /* DMA_COLOR_L */
915
        *value = s->ch[ch].color & 0xffff;
916
        break;
917

    
918
    case 0x22:        /* DMA_COLOR_U */
919
        *value = s->ch[ch].color >> 16;
920
        break;
921

    
922
    case 0x24:        /* DMA_CCR2 */
923
        *value = (s->ch[ch].bs << 2) |
924
            (s->ch[ch].transparent_copy << 1) |
925
            s->ch[ch].constant_fill;
926
        break;
927

    
928
    case 0x28:        /* DMA_CLNK_CTRL */
929
        *value = (s->ch[ch].link_enabled << 15) |
930
            (s->ch[ch].link_next_ch & 0xf);
931
        break;
932

    
933
    case 0x2a:        /* DMA_LCH_CTRL */
934
        *value = (s->ch[ch].interleave_disabled << 15) |
935
            s->ch[ch].type;
936
        break;
937

    
938
    default:
939
        return 1;
940
    }
941
    return 0;
942
}
943

    
944
static int omap_dma_ch_reg_write(struct omap_dma_s *s,
945
                int ch, int reg, uint16_t value)
946
{
947
    switch (reg) {
948
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
949
        s->ch[ch].burst[1] = (value & 0xc000) >> 14;
950
        s->ch[ch].pack[1] = (value & 0x2000) >> 13;
951
        s->ch[ch].port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
952
        s->ch[ch].burst[0] = (value & 0x0180) >> 7;
953
        s->ch[ch].pack[0] = (value & 0x0040) >> 6;
954
        s->ch[ch].port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
955
        s->ch[ch].data_type = (1 << (value & 3));
956
        if (s->ch[ch].port[0] >= omap_dma_port_last)
957
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
958
                            s->ch[ch].port[0]);
959
        if (s->ch[ch].port[1] >= omap_dma_port_last)
960
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
961
                            s->ch[ch].port[1]);
962
        if ((value & 3) == 3)
963
            printf("%s: bad data_type for DMA channel %i\n", __FUNCTION__, ch);
964
        break;
965

    
966
    case 0x02:        /* SYS_DMA_CCR_CH0 */
967
        s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
968
        s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
969
        s->ch[ch].end_prog = (value & 0x0800) >> 11;
970
        if (s->model > omap_dma_3_1)
971
            s->ch[ch].omap_3_1_compatible_disable  = (value >> 10) & 0x1;
972
        s->ch[ch].repeat = (value & 0x0200) >> 9;
973
        s->ch[ch].auto_init = (value & 0x0100) >> 8;
974
        s->ch[ch].priority = (value & 0x0040) >> 6;
975
        s->ch[ch].fs = (value & 0x0020) >> 5;
976
        s->ch[ch].sync = value & 0x001f;
977

    
978
        if (value & 0x0080)
979
            omap_dma_enable_channel(s, ch);
980
        else
981
            omap_dma_disable_channel(s, ch);
982

    
983
        if (s->ch[ch].end_prog)
984
            omap_dma_channel_end_prog(s, ch);
985

    
986
        break;
987

    
988
    case 0x04:        /* SYS_DMA_CICR_CH0 */
989
        s->ch[ch].interrupts = value;
990
        break;
991

    
992
    case 0x06:        /* SYS_DMA_CSR_CH0 */
993
        return 1;
994

    
995
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
996
        s->ch[ch].addr[0] &= 0xffff0000;
997
        s->ch[ch].addr[0] |= value;
998
        break;
999

    
1000
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
1001
        s->ch[ch].addr[0] &= 0x0000ffff;
1002
        s->ch[ch].addr[0] |= (uint32_t) value << 16;
1003
        break;
1004

    
1005
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
1006
        s->ch[ch].addr[1] &= 0xffff0000;
1007
        s->ch[ch].addr[1] |= value;
1008
        break;
1009

    
1010
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
1011
        s->ch[ch].addr[1] &= 0x0000ffff;
1012
        s->ch[ch].addr[1] |= (uint32_t) value << 16;
1013
        break;
1014

    
1015
    case 0x10:        /* SYS_DMA_CEN_CH0 */
1016
        s->ch[ch].elements = value;
1017
        break;
1018

    
1019
    case 0x12:        /* SYS_DMA_CFN_CH0 */
1020
        s->ch[ch].frames = value;
1021
        break;
1022

    
1023
    case 0x14:        /* SYS_DMA_CFI_CH0 */
1024
        s->ch[ch].frame_index[0] = (int16_t) value;
1025
        break;
1026

    
1027
    case 0x16:        /* SYS_DMA_CEI_CH0 */
1028
        s->ch[ch].element_index[0] = (int16_t) value;
1029
        break;
1030

    
1031
    case 0x18:        /* SYS_DMA_CPC_CH0 or DMA_CSAC */
1032
        OMAP_RO_REG((target_phys_addr_t) reg);
1033
        break;
1034

    
1035
    case 0x1c:        /* DMA_CDEI */
1036
        s->ch[ch].element_index[1] = (int16_t) value;
1037
        break;
1038

    
1039
    case 0x1e:        /* DMA_CDFI */
1040
        s->ch[ch].frame_index[1] = (int16_t) value;
1041
        break;
1042

    
1043
    case 0x20:        /* DMA_COLOR_L */
1044
        s->ch[ch].color &= 0xffff0000;
1045
        s->ch[ch].color |= value;
1046
        break;
1047

    
1048
    case 0x22:        /* DMA_COLOR_U */
1049
        s->ch[ch].color &= 0xffff;
1050
        s->ch[ch].color |= value << 16;
1051
        break;
1052

    
1053
    case 0x24:        /* DMA_CCR2 */
1054
        s->ch[ch].bs  = (value >> 2) & 0x1;
1055
        s->ch[ch].transparent_copy = (value >> 1) & 0x1;
1056
        s->ch[ch].constant_fill = value & 0x1;
1057
        break;
1058

    
1059
    case 0x28:        /* DMA_CLNK_CTRL */
1060
        s->ch[ch].link_enabled = (value >> 15) & 0x1;
1061
        if (value & (1 << 14)) {                        /* Stop_Lnk */
1062
            s->ch[ch].link_enabled = 0;
1063
            omap_dma_disable_channel(s, ch);
1064
        }
1065
        s->ch[ch].link_next_ch = value & 0x1f;
1066
        break;
1067

    
1068
    case 0x2a:        /* DMA_LCH_CTRL */
1069
        s->ch[ch].interleave_disabled = (value >> 15) & 0x1;
1070
        s->ch[ch].type = value & 0xf;
1071
        break;
1072

    
1073
    default:
1074
        return 1;
1075
    }
1076
    return 0;
1077
}
1078

    
1079
static int omap_dma_3_2_lcd_write(struct omap_dma_s *s, int offset,
1080
                uint16_t value)
1081
{
1082
    switch (offset) {
1083
    case 0xbc0:        /* DMA_LCD_CSDP */
1084
        s->lcd_ch.brust_f2 = (value >> 14) & 0x3;
1085
        s->lcd_ch.pack_f2 = (value >> 13) & 0x1;
1086
        s->lcd_ch.data_type_f2 = (1 << ((value >> 11) & 0x3));
1087
        s->lcd_ch.brust_f1 = (value >> 7) & 0x3;
1088
        s->lcd_ch.pack_f1 = (value >> 6) & 0x1;
1089
        s->lcd_ch.data_type_f1 = (1 << ((value >> 0) & 0x3));
1090
        break;
1091

    
1092
    case 0xbc2:        /* DMA_LCD_CCR */
1093
        s->lcd_ch.mode_f2 = (value >> 14) & 0x3;
1094
        s->lcd_ch.mode_f1 = (value >> 12) & 0x3;
1095
        s->lcd_ch.end_prog = (value >> 11) & 0x1;
1096
        s->lcd_ch.omap_3_1_compatible_disable = (value >> 10) & 0x1;
1097
        s->lcd_ch.repeat = (value >> 9) & 0x1;
1098
        s->lcd_ch.auto_init = (value >> 8) & 0x1;
1099
        s->lcd_ch.running = (value >> 7) & 0x1;
1100
        s->lcd_ch.priority = (value >> 6) & 0x1;
1101
        s->lcd_ch.bs = (value >> 4) & 0x1;
1102
        break;
1103

    
1104
    case 0xbc4:        /* DMA_LCD_CTRL */
1105
        s->lcd_ch.dst = (value >> 8) & 0x1;
1106
        s->lcd_ch.src = ((value >> 6) & 0x3) << 1;
1107
        s->lcd_ch.condition = 0;
1108
        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
1109
        s->lcd_ch.interrupts = (value >> 1) & 1;
1110
        s->lcd_ch.dual = value & 1;
1111
        break;
1112

    
1113
    case 0xbc8:        /* TOP_B1_L */
1114
        s->lcd_ch.src_f1_top &= 0xffff0000;
1115
        s->lcd_ch.src_f1_top |= 0x0000ffff & value;
1116
        break;
1117

    
1118
    case 0xbca:        /* TOP_B1_U */
1119
        s->lcd_ch.src_f1_top &= 0x0000ffff;
1120
        s->lcd_ch.src_f1_top |= value << 16;
1121
        break;
1122

    
1123
    case 0xbcc:        /* BOT_B1_L */
1124
        s->lcd_ch.src_f1_bottom &= 0xffff0000;
1125
        s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
1126
        break;
1127

    
1128
    case 0xbce:        /* BOT_B1_U */
1129
        s->lcd_ch.src_f1_bottom &= 0x0000ffff;
1130
        s->lcd_ch.src_f1_bottom |= (uint32_t) value << 16;
1131
        break;
1132

    
1133
    case 0xbd0:        /* TOP_B2_L */
1134
        s->lcd_ch.src_f2_top &= 0xffff0000;
1135
        s->lcd_ch.src_f2_top |= 0x0000ffff & value;
1136
        break;
1137

    
1138
    case 0xbd2:        /* TOP_B2_U */
1139
        s->lcd_ch.src_f2_top &= 0x0000ffff;
1140
        s->lcd_ch.src_f2_top |= (uint32_t) value << 16;
1141
        break;
1142

    
1143
    case 0xbd4:        /* BOT_B2_L */
1144
        s->lcd_ch.src_f2_bottom &= 0xffff0000;
1145
        s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
1146
        break;
1147

    
1148
    case 0xbd6:        /* BOT_B2_U */
1149
        s->lcd_ch.src_f2_bottom &= 0x0000ffff;
1150
        s->lcd_ch.src_f2_bottom |= (uint32_t) value << 16;
1151
        break;
1152

    
1153
    case 0xbd8:        /* DMA_LCD_SRC_EI_B1 */
1154
        s->lcd_ch.element_index_f1 = value;
1155
        break;
1156

    
1157
    case 0xbda:        /* DMA_LCD_SRC_FI_B1_L */
1158
        s->lcd_ch.frame_index_f1 &= 0xffff0000;
1159
        s->lcd_ch.frame_index_f1 |= 0x0000ffff & value;
1160
        break;
1161

    
1162
    case 0xbf4:        /* DMA_LCD_SRC_FI_B1_U */
1163
        s->lcd_ch.frame_index_f1 &= 0x0000ffff;
1164
        s->lcd_ch.frame_index_f1 |= (uint32_t) value << 16;
1165
        break;
1166

    
1167
    case 0xbdc:        /* DMA_LCD_SRC_EI_B2 */
1168
        s->lcd_ch.element_index_f2 = value;
1169
        break;
1170

    
1171
    case 0xbde:        /* DMA_LCD_SRC_FI_B2_L */
1172
        s->lcd_ch.frame_index_f2 &= 0xffff0000;
1173
        s->lcd_ch.frame_index_f2 |= 0x0000ffff & value;
1174
        break;
1175

    
1176
    case 0xbf6:        /* DMA_LCD_SRC_FI_B2_U */
1177
        s->lcd_ch.frame_index_f2 &= 0x0000ffff;
1178
        s->lcd_ch.frame_index_f2 |= (uint32_t) value << 16;
1179
        break;
1180

    
1181
    case 0xbe0:        /* DMA_LCD_SRC_EN_B1 */
1182
        s->lcd_ch.elements_f1 = value;
1183
        break;
1184

    
1185
    case 0xbe4:        /* DMA_LCD_SRC_FN_B1 */
1186
        s->lcd_ch.frames_f1 = value;
1187
        break;
1188

    
1189
    case 0xbe2:        /* DMA_LCD_SRC_EN_B2 */
1190
        s->lcd_ch.elements_f2 = value;
1191
        break;
1192

    
1193
    case 0xbe6:        /* DMA_LCD_SRC_FN_B2 */
1194
        s->lcd_ch.frames_f2 = value;
1195
        break;
1196

    
1197
    case 0xbea:        /* DMA_LCD_LCH_CTRL */
1198
        s->lcd_ch.lch_type = value & 0xf;
1199
        break;
1200

    
1201
    default:
1202
        return 1;
1203
    }
1204
    return 0;
1205
}
1206

    
1207
static int omap_dma_3_2_lcd_read(struct omap_dma_s *s, int offset,
1208
                uint16_t *ret)
1209
{
1210
    switch (offset) {
1211
    case 0xbc0:        /* DMA_LCD_CSDP */
1212
        *ret = (s->lcd_ch.brust_f2 << 14) |
1213
            (s->lcd_ch.pack_f2 << 13) |
1214
            ((s->lcd_ch.data_type_f2 >> 1) << 11) |
1215
            (s->lcd_ch.brust_f1 << 7) |
1216
            (s->lcd_ch.pack_f1 << 6) |
1217
            ((s->lcd_ch.data_type_f1 >> 1) << 0);
1218
        break;
1219

    
1220
    case 0xbc2:        /* DMA_LCD_CCR */
1221
        *ret = (s->lcd_ch.mode_f2 << 14) |
1222
            (s->lcd_ch.mode_f1 << 12) |
1223
            (s->lcd_ch.end_prog << 11) |
1224
            (s->lcd_ch.omap_3_1_compatible_disable << 10) |
1225
            (s->lcd_ch.repeat << 9) |
1226
            (s->lcd_ch.auto_init << 8) |
1227
            (s->lcd_ch.running << 7) |
1228
            (s->lcd_ch.priority << 6) |
1229
            (s->lcd_ch.bs << 4);
1230
        break;
1231

    
1232
    case 0xbc4:        /* DMA_LCD_CTRL */
1233
        qemu_irq_lower(s->lcd_ch.irq);
1234
        *ret = (s->lcd_ch.dst << 8) |
1235
            ((s->lcd_ch.src & 0x6) << 5) |
1236
            (s->lcd_ch.condition << 3) |
1237
            (s->lcd_ch.interrupts << 1) |
1238
            s->lcd_ch.dual;
1239
        break;
1240

    
1241
    case 0xbc8:        /* TOP_B1_L */
1242
        *ret = s->lcd_ch.src_f1_top & 0xffff;
1243
        break;
1244

    
1245
    case 0xbca:        /* TOP_B1_U */
1246
        *ret = s->lcd_ch.src_f1_top >> 16;
1247
        break;
1248

    
1249
    case 0xbcc:        /* BOT_B1_L */
1250
        *ret = s->lcd_ch.src_f1_bottom & 0xffff;
1251
        break;
1252

    
1253
    case 0xbce:        /* BOT_B1_U */
1254
        *ret = s->lcd_ch.src_f1_bottom >> 16;
1255
        break;
1256

    
1257
    case 0xbd0:        /* TOP_B2_L */
1258
        *ret = s->lcd_ch.src_f2_top & 0xffff;
1259
        break;
1260

    
1261
    case 0xbd2:        /* TOP_B2_U */
1262
        *ret = s->lcd_ch.src_f2_top >> 16;
1263
        break;
1264

    
1265
    case 0xbd4:        /* BOT_B2_L */
1266
        *ret = s->lcd_ch.src_f2_bottom & 0xffff;
1267
        break;
1268

    
1269
    case 0xbd6:        /* BOT_B2_U */
1270
        *ret = s->lcd_ch.src_f2_bottom >> 16;
1271
        break;
1272

    
1273
    case 0xbd8:        /* DMA_LCD_SRC_EI_B1 */
1274
        *ret = s->lcd_ch.element_index_f1;
1275
        break;
1276

    
1277
    case 0xbda:        /* DMA_LCD_SRC_FI_B1_L */
1278
        *ret = s->lcd_ch.frame_index_f1 & 0xffff;
1279
        break;
1280

    
1281
    case 0xbf4:        /* DMA_LCD_SRC_FI_B1_U */
1282
        *ret = s->lcd_ch.frame_index_f1 >> 16;
1283
        break;
1284

    
1285
    case 0xbdc:        /* DMA_LCD_SRC_EI_B2 */
1286
        *ret = s->lcd_ch.element_index_f2;
1287
        break;
1288

    
1289
    case 0xbde:        /* DMA_LCD_SRC_FI_B2_L */
1290
        *ret = s->lcd_ch.frame_index_f2 & 0xffff;
1291
        break;
1292

    
1293
    case 0xbf6:        /* DMA_LCD_SRC_FI_B2_U */
1294
        *ret = s->lcd_ch.frame_index_f2 >> 16;
1295
        break;
1296

    
1297
    case 0xbe0:        /* DMA_LCD_SRC_EN_B1 */
1298
        *ret = s->lcd_ch.elements_f1;
1299
        break;
1300

    
1301
    case 0xbe4:        /* DMA_LCD_SRC_FN_B1 */
1302
        *ret = s->lcd_ch.frames_f1;
1303
        break;
1304

    
1305
    case 0xbe2:        /* DMA_LCD_SRC_EN_B2 */
1306
        *ret = s->lcd_ch.elements_f2;
1307
        break;
1308

    
1309
    case 0xbe6:        /* DMA_LCD_SRC_FN_B2 */
1310
        *ret = s->lcd_ch.frames_f2;
1311
        break;
1312

    
1313
    case 0xbea:        /* DMA_LCD_LCH_CTRL */
1314
        *ret = s->lcd_ch.lch_type;
1315
        break;
1316

    
1317
    default:
1318
        return 1;
1319
    }
1320
    return 0;
1321
}
1322

    
1323
static int omap_dma_3_1_lcd_write(struct omap_dma_s *s, int offset,
1324
                uint16_t value)
1325
{
1326
    switch (offset) {
1327
    case 0x300:        /* SYS_DMA_LCD_CTRL */
1328
        s->lcd_ch.src = (value & 0x40) ? imif : emiff;
1329
        s->lcd_ch.condition = 0;
1330
        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
1331
        s->lcd_ch.interrupts = (value >> 1) & 1;
1332
        s->lcd_ch.dual = value & 1;
1333
        break;
1334

    
1335
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
1336
        s->lcd_ch.src_f1_top &= 0xffff0000;
1337
        s->lcd_ch.src_f1_top |= 0x0000ffff & value;
1338
        break;
1339

    
1340
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
1341
        s->lcd_ch.src_f1_top &= 0x0000ffff;
1342
        s->lcd_ch.src_f1_top |= value << 16;
1343
        break;
1344

    
1345
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
1346
        s->lcd_ch.src_f1_bottom &= 0xffff0000;
1347
        s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
1348
        break;
1349

    
1350
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
1351
        s->lcd_ch.src_f1_bottom &= 0x0000ffff;
1352
        s->lcd_ch.src_f1_bottom |= value << 16;
1353
        break;
1354

    
1355
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
1356
        s->lcd_ch.src_f2_top &= 0xffff0000;
1357
        s->lcd_ch.src_f2_top |= 0x0000ffff & value;
1358
        break;
1359

    
1360
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
1361
        s->lcd_ch.src_f2_top &= 0x0000ffff;
1362
        s->lcd_ch.src_f2_top |= value << 16;
1363
        break;
1364

    
1365
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
1366
        s->lcd_ch.src_f2_bottom &= 0xffff0000;
1367
        s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
1368
        break;
1369

    
1370
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
1371
        s->lcd_ch.src_f2_bottom &= 0x0000ffff;
1372
        s->lcd_ch.src_f2_bottom |= value << 16;
1373
        break;
1374

    
1375
    default:
1376
        return 1;
1377
    }
1378
    return 0;
1379
}
1380

    
1381
static int omap_dma_3_1_lcd_read(struct omap_dma_s *s, int offset,
1382
                uint16_t *ret)
1383
{
1384
    int i;
1385

    
1386
    switch (offset) {
1387
    case 0x300:        /* SYS_DMA_LCD_CTRL */
1388
        i = s->lcd_ch.condition;
1389
        s->lcd_ch.condition = 0;
1390
        qemu_irq_lower(s->lcd_ch.irq);
1391
        *ret = ((s->lcd_ch.src == imif) << 6) | (i << 3) |
1392
                (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
1393
        break;
1394

    
1395
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
1396
        *ret = s->lcd_ch.src_f1_top & 0xffff;
1397
        break;
1398

    
1399
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
1400
        *ret = s->lcd_ch.src_f1_top >> 16;
1401
        break;
1402

    
1403
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
1404
        *ret = s->lcd_ch.src_f1_bottom & 0xffff;
1405
        break;
1406

    
1407
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
1408
        *ret = s->lcd_ch.src_f1_bottom >> 16;
1409
        break;
1410

    
1411
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
1412
        *ret = s->lcd_ch.src_f2_top & 0xffff;
1413
        break;
1414

    
1415
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
1416
        *ret = s->lcd_ch.src_f2_top >> 16;
1417
        break;
1418

    
1419
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
1420
        *ret = s->lcd_ch.src_f2_bottom & 0xffff;
1421
        break;
1422

    
1423
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
1424
        *ret = s->lcd_ch.src_f2_bottom >> 16;
1425
        break;
1426

    
1427
    default:
1428
        return 1;
1429
    }
1430
    return 0;
1431
}
1432

    
1433
static int omap_dma_sys_write(struct omap_dma_s *s, int offset, uint16_t value)
1434
{
1435
    switch (offset) {
1436
    case 0x400:        /* SYS_DMA_GCR */
1437
        s->gcr = value;
1438
        break;
1439

    
1440
    case 0x404:        /* DMA_GSCR */
1441
        if (value & 0x8)
1442
            omap_dma_disable_3_1_mapping(s);
1443
        else
1444
            omap_dma_enable_3_1_mapping(s);
1445
        break;
1446

    
1447
    case 0x408:        /* DMA_GRST */
1448
        if (value & 0x1)
1449
            omap_dma_reset(s);
1450
        break;
1451

    
1452
    default:
1453
        return 1;
1454
    }
1455
    return 0;
1456
}
1457

    
1458
static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
1459
                uint16_t *ret)
1460
{
1461
    switch (offset) {
1462
    case 0x400:        /* SYS_DMA_GCR */
1463
        *ret = s->gcr;
1464
        break;
1465

    
1466
    case 0x404:        /* DMA_GSCR */
1467
        *ret = s->omap_3_1_mapping_disabled << 3;
1468
        break;
1469

    
1470
    case 0x408:        /* DMA_GRST */
1471
        *ret = 0;
1472
        break;
1473

    
1474
    case 0x442:        /* DMA_HW_ID */
1475
    case 0x444:        /* DMA_PCh2_ID */
1476
    case 0x446:        /* DMA_PCh0_ID */
1477
    case 0x448:        /* DMA_PCh1_ID */
1478
    case 0x44a:        /* DMA_PChG_ID */
1479
    case 0x44c:        /* DMA_PChD_ID */
1480
        *ret = 1;
1481
        break;
1482

    
1483
    case 0x44e:        /* DMA_CAPS_0_U */
1484
        *ret = (1 << 3) | /* Constant Fill Capacity */
1485
            (1 << 2);     /* Transparent BLT Capacity */
1486
        break;
1487

    
1488
    case 0x450:        /* DMA_CAPS_0_L */
1489
    case 0x452:        /* DMA_CAPS_1_U */
1490
        *ret = 0;
1491
        break;
1492

    
1493
    case 0x454:        /* DMA_CAPS_1_L */
1494
        *ret = (1 << 1); /* 1-bit palletized capability */
1495
        break;
1496

    
1497
    case 0x456:        /* DMA_CAPS_2 */
1498
        *ret = (1 << 8) | /* SSDIC */
1499
            (1 << 7) |    /* DDIAC */
1500
            (1 << 6) |    /* DSIAC */
1501
            (1 << 5) |    /* DPIAC */
1502
            (1 << 4) |    /* DCAC  */
1503
            (1 << 3) |    /* SDIAC */
1504
            (1 << 2) |    /* SSIAC */
1505
            (1 << 1) |    /* SPIAC */
1506
            1;            /* SCAC  */
1507
        break;
1508

    
1509
    case 0x458:        /* DMA_CAPS_3 */
1510
        *ret = (1 << 5) | /* CCC */
1511
            (1 << 4) |    /* IC  */
1512
            (1 << 3) |    /* ARC */
1513
            (1 << 2) |    /* AEC */
1514
            (1 << 1) |    /* FSC */
1515
            1;            /* ESC */
1516
        break;
1517

    
1518
    case 0x45a:        /* DMA_CAPS_4 */
1519
        *ret = (1 << 6) | /* SSC  */
1520
            (1 << 5) |    /* BIC  */
1521
            (1 << 4) |    /* LFIC */
1522
            (1 << 3) |    /* FIC  */
1523
            (1 << 2) |    /* HFIC */
1524
            (1 << 1) |    /* EDIC */
1525
            1;            /* TOIC */
1526
        break;
1527

    
1528
    case 0x460:        /* DMA_PCh2_SR */
1529
    case 0x480:        /* DMA_PCh0_SR */
1530
    case 0x482:        /* DMA_PCh1_SR */
1531
    case 0x4c0:        /* DMA_PChD_SR_0 */
1532
        printf("%s: Physical Channel Status Registers not implemented.\n",
1533
               __FUNCTION__);
1534
        *ret = 0xff;
1535
        break;
1536

    
1537
    default:
1538
        return 1;
1539
    }
1540
    return 0;
1541
}
1542

    
1543
static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
1544
{
1545
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1546
    int reg, ch, offset = addr - s->base;
1547
    uint16_t ret;
1548

    
1549
    switch (offset) {
1550
    case 0x300 ... 0x3fe:
1551
        if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
1552
            if (omap_dma_3_1_lcd_read(s, offset, &ret))
1553
                break;
1554
            return ret;
1555
        }
1556
        /* Fall through. */
1557
    case 0x000 ... 0x2fe:
1558
        reg = offset & 0x3f;
1559
        ch = (offset >> 6) & 0x0f;
1560
        if (omap_dma_ch_reg_read(s, ch, reg, &ret))
1561
            break;
1562
        return ret;
1563

    
1564
    case 0x404 ... 0x4fe:
1565
        if (s->model == omap_dma_3_1)
1566
            break;
1567
        /* Fall through. */
1568
    case 0x400:
1569
        if (omap_dma_sys_read(s, offset, &ret))
1570
            break;
1571
        return ret;
1572

    
1573
    case 0xb00 ... 0xbfe:
1574
        if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
1575
            if (omap_dma_3_2_lcd_read(s, offset, &ret))
1576
                break;
1577
            return ret;
1578
        }
1579
        break;
1580
    }
1581

    
1582
    OMAP_BAD_REG(addr);
1583
    return 0;
1584
}
1585

    
1586
static void omap_dma_write(void *opaque, target_phys_addr_t addr,
1587
                uint32_t value)
1588
{
1589
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1590
    int reg, ch, offset = addr - s->base;
1591

    
1592
    switch (offset) {
1593
    case 0x300 ... 0x3fe:
1594
        if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
1595
            if (omap_dma_3_1_lcd_write(s, offset, value))
1596
                break;
1597
            return;
1598
        }
1599
        /* Fall through.  */
1600
    case 0x000 ... 0x2fe:
1601
        reg = offset & 0x3f;
1602
        ch = (offset >> 6) & 0x0f;
1603
        if (omap_dma_ch_reg_write(s, ch, reg, value))
1604
            break;
1605
        return;
1606

    
1607
    case 0x404 ... 0x4fe:
1608
        if (s->model == omap_dma_3_1)
1609
            break;
1610
    case 0x400:
1611
        /* Fall through. */
1612
        if (omap_dma_sys_write(s, offset, value))
1613
            break;
1614
        return;
1615

    
1616
    case 0xb00 ... 0xbfe:
1617
        if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
1618
            if (omap_dma_3_2_lcd_write(s, offset, value))
1619
                break;
1620
            return;
1621
        }
1622
        break;
1623
    }
1624

    
1625
    OMAP_BAD_REG(addr);
1626
}
1627

    
1628
static CPUReadMemoryFunc *omap_dma_readfn[] = {
1629
    omap_badwidth_read16,
1630
    omap_dma_read,
1631
    omap_badwidth_read16,
1632
};
1633

    
1634
static CPUWriteMemoryFunc *omap_dma_writefn[] = {
1635
    omap_badwidth_write16,
1636
    omap_dma_write,
1637
    omap_badwidth_write16,
1638
};
1639

    
1640
static void omap_dma_request(void *opaque, int drq, int req)
1641
{
1642
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1643
    /* The request pins are level triggered.  */
1644
    if (req) {
1645
        if (~s->drq & (1 << drq)) {
1646
            s->drq |= 1 << drq;
1647
            omap_dma_process_request(s, drq);
1648
        }
1649
    } else
1650
        s->drq &= ~(1 << drq);
1651
}
1652

    
1653
static void omap_dma_clk_update(void *opaque, int line, int on)
1654
{
1655
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1656

    
1657
    if (on) {
1658
        /* TODO: make a clever calculation */
1659
        s->delay = ticks_per_sec >> 8;
1660
        if (s->run_count)
1661
            qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
1662
    } else {
1663
        s->delay = 0;
1664
        qemu_del_timer(s->tm);
1665
    }
1666
}
1667

    
1668
struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
1669
                qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
1670
                enum omap_dma_model model)
1671
{
1672
    int iomemtype, num_irqs, memsize;
1673
    struct omap_dma_s *s = (struct omap_dma_s *)
1674
            qemu_mallocz(sizeof(struct omap_dma_s));
1675

    
1676
    if (model == omap_dma_3_1) {
1677
        num_irqs = 6;
1678
        memsize = 0x800;
1679
    } else {
1680
        num_irqs = 16;
1681
        memsize = 0xc00;
1682
    }
1683
    memcpy(s->irqs, irqs, num_irqs * sizeof(qemu_irq));
1684
    s->base = base;
1685
    s->model = model;
1686
    s->mpu = mpu;
1687
    s->clk = clk;
1688
    s->lcd_ch.irq = lcd_irq;
1689
    s->lcd_ch.mpu = mpu;
1690
    s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1691
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1692
    mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1693
    omap_dma_reset(s);
1694
    omap_dma_clk_update(s, 0, 1);
1695

    
1696
    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1697
                    omap_dma_writefn, s);
1698
    cpu_register_physical_memory(s->base, memsize, iomemtype);
1699

    
1700
    return s;
1701
}
1702

    
1703
/* DMA ports */
1704
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
1705
                target_phys_addr_t addr)
1706
{
1707
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
1708
}
1709

    
1710
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
1711
                target_phys_addr_t addr)
1712
{
1713
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
1714
}
1715

    
1716
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
1717
                target_phys_addr_t addr)
1718
{
1719
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
1720
}
1721

    
1722
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
1723
                target_phys_addr_t addr)
1724
{
1725
    return addr >= 0xfffb0000 && addr < 0xffff0000;
1726
}
1727

    
1728
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
1729
                target_phys_addr_t addr)
1730
{
1731
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
1732
}
1733

    
1734
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
1735
                target_phys_addr_t addr)
1736
{
1737
    return addr >= 0xe1010000 && addr < 0xe1020004;
1738
}
1739

    
1740
/* MPU OS timers */
1741
struct omap_mpu_timer_s {
1742
    qemu_irq irq;
1743
    omap_clk clk;
1744
    target_phys_addr_t base;
1745
    uint32_t val;
1746
    int64_t time;
1747
    QEMUTimer *timer;
1748
    int64_t rate;
1749
    int it_ena;
1750

    
1751
    int enable;
1752
    int ptv;
1753
    int ar;
1754
    int st;
1755
    uint32_t reset_val;
1756
};
1757

    
1758
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
1759
{
1760
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
1761

    
1762
    if (timer->st && timer->enable && timer->rate)
1763
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
1764
                        timer->rate, ticks_per_sec);
1765
    else
1766
        return timer->val;
1767
}
1768

    
1769
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
1770
{
1771
    timer->val = omap_timer_read(timer);
1772
    timer->time = qemu_get_clock(vm_clock);
1773
}
1774

    
1775
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1776
{
1777
    int64_t expires;
1778

    
1779
    if (timer->enable && timer->st && timer->rate) {
1780
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
1781
        expires = muldiv64(timer->val << (timer->ptv + 1),
1782
                        ticks_per_sec, timer->rate);
1783

    
1784
        /* If timer expiry would be sooner than in about 1 ms and
1785
         * auto-reload isn't set, then fire immediately.  This is a hack
1786
         * to make systems like PalmOS run in acceptable time.  PalmOS
1787
         * sets the interval to a very low value and polls the status bit
1788
         * in a busy loop when it wants to sleep just a couple of CPU
1789
         * ticks.  */
1790
        if (expires > (ticks_per_sec >> 10) || timer->ar)
1791
            qemu_mod_timer(timer->timer, timer->time + expires);
1792
        else {
1793
            timer->val = 0;
1794
            timer->st = 0;
1795
            if (timer->it_ena)
1796
                /* Edge-triggered irq */
1797
                qemu_irq_pulse(timer->irq);
1798
        }
1799
    } else
1800
        qemu_del_timer(timer->timer);
1801
}
1802

    
1803
static void omap_timer_tick(void *opaque)
1804
{
1805
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1806
    omap_timer_sync(timer);
1807

    
1808
    if (!timer->ar) {
1809
        timer->val = 0;
1810
        timer->st = 0;
1811
    }
1812

    
1813
    if (timer->it_ena)
1814
        /* Edge-triggered irq */
1815
        qemu_irq_pulse(timer->irq);
1816
    omap_timer_update(timer);
1817
}
1818

    
1819
static void omap_timer_clk_update(void *opaque, int line, int on)
1820
{
1821
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
1822

    
1823
    omap_timer_sync(timer);
1824
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1825
    omap_timer_update(timer);
1826
}
1827

    
1828
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
1829
{
1830
    omap_clk_adduser(timer->clk,
1831
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
1832
    timer->rate = omap_clk_getrate(timer->clk);
1833
}
1834

    
1835
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
1836
{
1837
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1838
    int offset = addr - s->base;
1839

    
1840
    switch (offset) {
1841
    case 0x00:        /* CNTL_TIMER */
1842
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
1843

    
1844
    case 0x04:        /* LOAD_TIM */
1845
        break;
1846

    
1847
    case 0x08:        /* READ_TIM */
1848
        return omap_timer_read(s);
1849
    }
1850

    
1851
    OMAP_BAD_REG(addr);
1852
    return 0;
1853
}
1854

    
1855
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
1856
                uint32_t value)
1857
{
1858
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
1859
    int offset = addr - s->base;
1860

    
1861
    switch (offset) {
1862
    case 0x00:        /* CNTL_TIMER */
1863
        omap_timer_sync(s);
1864
        s->enable = (value >> 5) & 1;
1865
        s->ptv = (value >> 2) & 7;
1866
        s->ar = (value >> 1) & 1;
1867
        s->st = value & 1;
1868
        omap_timer_update(s);
1869
        return;
1870

    
1871
    case 0x04:        /* LOAD_TIM */
1872
        s->reset_val = value;
1873
        return;
1874

    
1875
    case 0x08:        /* READ_TIM */
1876
        OMAP_RO_REG(addr);
1877
        break;
1878

    
1879
    default:
1880
        OMAP_BAD_REG(addr);
1881
    }
1882
}
1883

    
1884
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
1885
    omap_badwidth_read32,
1886
    omap_badwidth_read32,
1887
    omap_mpu_timer_read,
1888
};
1889

    
1890
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
1891
    omap_badwidth_write32,
1892
    omap_badwidth_write32,
1893
    omap_mpu_timer_write,
1894
};
1895

    
1896
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
1897
{
1898
    qemu_del_timer(s->timer);
1899
    s->enable = 0;
1900
    s->reset_val = 31337;
1901
    s->val = 0;
1902
    s->ptv = 0;
1903
    s->ar = 0;
1904
    s->st = 0;
1905
    s->it_ena = 1;
1906
}
1907

    
1908
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
1909
                qemu_irq irq, omap_clk clk)
1910
{
1911
    int iomemtype;
1912
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
1913
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
1914

    
1915
    s->irq = irq;
1916
    s->clk = clk;
1917
    s->base = base;
1918
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
1919
    omap_mpu_timer_reset(s);
1920
    omap_timer_clk_setup(s);
1921

    
1922
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
1923
                    omap_mpu_timer_writefn, s);
1924
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1925

    
1926
    return s;
1927
}
1928

    
1929
/* Watchdog timer */
1930
struct omap_watchdog_timer_s {
1931
    struct omap_mpu_timer_s timer;
1932
    uint8_t last_wr;
1933
    int mode;
1934
    int free;
1935
    int reset;
1936
};
1937

    
1938
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
1939
{
1940
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1941
    int offset = addr - s->timer.base;
1942

    
1943
    switch (offset) {
1944
    case 0x00:        /* CNTL_TIMER */
1945
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
1946
                (s->timer.st << 7) | (s->free << 1);
1947

    
1948
    case 0x04:        /* READ_TIMER */
1949
        return omap_timer_read(&s->timer);
1950

    
1951
    case 0x08:        /* TIMER_MODE */
1952
        return s->mode << 15;
1953
    }
1954

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

    
1959
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
1960
                uint32_t value)
1961
{
1962
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
1963
    int offset = addr - s->timer.base;
1964

    
1965
    switch (offset) {
1966
    case 0x00:        /* CNTL_TIMER */
1967
        omap_timer_sync(&s->timer);
1968
        s->timer.ptv = (value >> 9) & 7;
1969
        s->timer.ar = (value >> 8) & 1;
1970
        s->timer.st = (value >> 7) & 1;
1971
        s->free = (value >> 1) & 1;
1972
        omap_timer_update(&s->timer);
1973
        break;
1974

    
1975
    case 0x04:        /* LOAD_TIMER */
1976
        s->timer.reset_val = value & 0xffff;
1977
        break;
1978

    
1979
    case 0x08:        /* TIMER_MODE */
1980
        if (!s->mode && ((value >> 15) & 1))
1981
            omap_clk_get(s->timer.clk);
1982
        s->mode |= (value >> 15) & 1;
1983
        if (s->last_wr == 0xf5) {
1984
            if ((value & 0xff) == 0xa0) {
1985
                if (s->mode) {
1986
                    s->mode = 0;
1987
                    omap_clk_put(s->timer.clk);
1988
                }
1989
            } else {
1990
                /* XXX: on T|E hardware somehow this has no effect,
1991
                 * on Zire 71 it works as specified.  */
1992
                s->reset = 1;
1993
                qemu_system_reset_request();
1994
            }
1995
        }
1996
        s->last_wr = value & 0xff;
1997
        break;
1998

    
1999
    default:
2000
        OMAP_BAD_REG(addr);
2001
    }
2002
}
2003

    
2004
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
2005
    omap_badwidth_read16,
2006
    omap_wd_timer_read,
2007
    omap_badwidth_read16,
2008
};
2009

    
2010
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
2011
    omap_badwidth_write16,
2012
    omap_wd_timer_write,
2013
    omap_badwidth_write16,
2014
};
2015

    
2016
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
2017
{
2018
    qemu_del_timer(s->timer.timer);
2019
    if (!s->mode)
2020
        omap_clk_get(s->timer.clk);
2021
    s->mode = 1;
2022
    s->free = 1;
2023
    s->reset = 0;
2024
    s->timer.enable = 1;
2025
    s->timer.it_ena = 1;
2026
    s->timer.reset_val = 0xffff;
2027
    s->timer.val = 0;
2028
    s->timer.st = 0;
2029
    s->timer.ptv = 0;
2030
    s->timer.ar = 0;
2031
    omap_timer_update(&s->timer);
2032
}
2033

    
2034
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
2035
                qemu_irq irq, omap_clk clk)
2036
{
2037
    int iomemtype;
2038
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
2039
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
2040

    
2041
    s->timer.irq = irq;
2042
    s->timer.clk = clk;
2043
    s->timer.base = base;
2044
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
2045
    omap_wd_timer_reset(s);
2046
    omap_timer_clk_setup(&s->timer);
2047

    
2048
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
2049
                    omap_wd_timer_writefn, s);
2050
    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
2051

    
2052
    return s;
2053
}
2054

    
2055
/* 32-kHz timer */
2056
struct omap_32khz_timer_s {
2057
    struct omap_mpu_timer_s timer;
2058
};
2059

    
2060
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
2061
{
2062
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
2063
    int offset = addr & OMAP_MPUI_REG_MASK;
2064

    
2065
    switch (offset) {
2066
    case 0x00:        /* TVR */
2067
        return s->timer.reset_val;
2068

    
2069
    case 0x04:        /* TCR */
2070
        return omap_timer_read(&s->timer);
2071

    
2072
    case 0x08:        /* CR */
2073
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
2074

    
2075
    default:
2076
        break;
2077
    }
2078
    OMAP_BAD_REG(addr);
2079
    return 0;
2080
}
2081

    
2082
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
2083
                uint32_t value)
2084
{
2085
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
2086
    int offset = addr & OMAP_MPUI_REG_MASK;
2087

    
2088
    switch (offset) {
2089
    case 0x00:        /* TVR */
2090
        s->timer.reset_val = value & 0x00ffffff;
2091
        break;
2092

    
2093
    case 0x04:        /* TCR */
2094
        OMAP_RO_REG(addr);
2095
        break;
2096

    
2097
    case 0x08:        /* CR */
2098
        s->timer.ar = (value >> 3) & 1;
2099
        s->timer.it_ena = (value >> 2) & 1;
2100
        if (s->timer.st != (value & 1) || (value & 2)) {
2101
            omap_timer_sync(&s->timer);
2102
            s->timer.enable = value & 1;
2103
            s->timer.st = value & 1;
2104
            omap_timer_update(&s->timer);
2105
        }
2106
        break;
2107

    
2108
    default:
2109
        OMAP_BAD_REG(addr);
2110
    }
2111
}
2112

    
2113
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
2114
    omap_badwidth_read32,
2115
    omap_badwidth_read32,
2116
    omap_os_timer_read,
2117
};
2118

    
2119
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
2120
    omap_badwidth_write32,
2121
    omap_badwidth_write32,
2122
    omap_os_timer_write,
2123
};
2124

    
2125
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
2126
{
2127
    qemu_del_timer(s->timer.timer);
2128
    s->timer.enable = 0;
2129
    s->timer.it_ena = 0;
2130
    s->timer.reset_val = 0x00ffffff;
2131
    s->timer.val = 0;
2132
    s->timer.st = 0;
2133
    s->timer.ptv = 0;
2134
    s->timer.ar = 1;
2135
}
2136

    
2137
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
2138
                qemu_irq irq, omap_clk clk)
2139
{
2140
    int iomemtype;
2141
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
2142
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
2143

    
2144
    s->timer.irq = irq;
2145
    s->timer.clk = clk;
2146
    s->timer.base = base;
2147
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
2148
    omap_os_timer_reset(s);
2149
    omap_timer_clk_setup(&s->timer);
2150

    
2151
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
2152
                    omap_os_timer_writefn, s);
2153
    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
2154

    
2155
    return s;
2156
}
2157

    
2158
/* Ultra Low-Power Device Module */
2159
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
2160
{
2161
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2162
    int offset = addr - s->ulpd_pm_base;
2163
    uint16_t ret;
2164

    
2165
    switch (offset) {
2166
    case 0x14:        /* IT_STATUS */
2167
        ret = s->ulpd_pm_regs[offset >> 2];
2168
        s->ulpd_pm_regs[offset >> 2] = 0;
2169
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
2170
        return ret;
2171

    
2172
    case 0x18:        /* Reserved */
2173
    case 0x1c:        /* Reserved */
2174
    case 0x20:        /* Reserved */
2175
    case 0x28:        /* Reserved */
2176
    case 0x2c:        /* Reserved */
2177
        OMAP_BAD_REG(addr);
2178
    case 0x00:        /* COUNTER_32_LSB */
2179
    case 0x04:        /* COUNTER_32_MSB */
2180
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
2181
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
2182
    case 0x10:        /* GAUGING_CTRL */
2183
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
2184
    case 0x30:        /* CLOCK_CTRL */
2185
    case 0x34:        /* SOFT_REQ */
2186
    case 0x38:        /* COUNTER_32_FIQ */
2187
    case 0x3c:        /* DPLL_CTRL */
2188
    case 0x40:        /* STATUS_REQ */
2189
        /* XXX: check clk::usecount state for every clock */
2190
    case 0x48:        /* LOCL_TIME */
2191
    case 0x4c:        /* APLL_CTRL */
2192
    case 0x50:        /* POWER_CTRL */
2193
        return s->ulpd_pm_regs[offset >> 2];
2194
    }
2195

    
2196
    OMAP_BAD_REG(addr);
2197
    return 0;
2198
}
2199

    
2200
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
2201
                uint16_t diff, uint16_t value)
2202
{
2203
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
2204
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
2205
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
2206
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
2207
}
2208

    
2209
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
2210
                uint16_t diff, uint16_t value)
2211
{
2212
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
2213
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
2214
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
2215
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
2216
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
2217
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
2218
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
2219
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
2220
}
2221

    
2222
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
2223
                uint32_t value)
2224
{
2225
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2226
    int offset = addr - s->ulpd_pm_base;
2227
    int64_t now, ticks;
2228
    int div, mult;
2229
    static const int bypass_div[4] = { 1, 2, 4, 4 };
2230
    uint16_t diff;
2231

    
2232
    switch (offset) {
2233
    case 0x00:        /* COUNTER_32_LSB */
2234
    case 0x04:        /* COUNTER_32_MSB */
2235
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
2236
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
2237
    case 0x14:        /* IT_STATUS */
2238
    case 0x40:        /* STATUS_REQ */
2239
        OMAP_RO_REG(addr);
2240
        break;
2241

    
2242
    case 0x10:        /* GAUGING_CTRL */
2243
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
2244
        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
2245
            now = qemu_get_clock(vm_clock);
2246

    
2247
            if (value & 1)
2248
                s->ulpd_gauge_start = now;
2249
            else {
2250
                now -= s->ulpd_gauge_start;
2251

    
2252
                /* 32-kHz ticks */
2253
                ticks = muldiv64(now, 32768, ticks_per_sec);
2254
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
2255
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
2256
                if (ticks >> 32)        /* OVERFLOW_32K */
2257
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
2258

    
2259
                /* High frequency ticks */
2260
                ticks = muldiv64(now, 12000000, ticks_per_sec);
2261
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
2262
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
2263
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
2264
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
2265

    
2266
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
2267
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
2268
            }
2269
        }
2270
        s->ulpd_pm_regs[offset >> 2] = value;
2271
        break;
2272

    
2273
    case 0x18:        /* Reserved */
2274
    case 0x1c:        /* Reserved */
2275
    case 0x20:        /* Reserved */
2276
    case 0x28:        /* Reserved */
2277
    case 0x2c:        /* Reserved */
2278
        OMAP_BAD_REG(addr);
2279
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
2280
    case 0x38:        /* COUNTER_32_FIQ */
2281
    case 0x48:        /* LOCL_TIME */
2282
    case 0x50:        /* POWER_CTRL */
2283
        s->ulpd_pm_regs[offset >> 2] = value;
2284
        break;
2285

    
2286
    case 0x30:        /* CLOCK_CTRL */
2287
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
2288
        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
2289
        omap_ulpd_clk_update(s, diff, value);
2290
        break;
2291

    
2292
    case 0x34:        /* SOFT_REQ */
2293
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
2294
        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
2295
        omap_ulpd_req_update(s, diff, value);
2296
        break;
2297

    
2298
    case 0x3c:        /* DPLL_CTRL */
2299
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
2300
         * omitted altogether, probably a typo.  */
2301
        /* This register has identical semantics with DPLL(1:3) control
2302
         * registers, see omap_dpll_write() */
2303
        diff = s->ulpd_pm_regs[offset >> 2] & value;
2304
        s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
2305
        if (diff & (0x3ff << 2)) {
2306
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
2307
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
2308
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
2309
            } else {
2310
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
2311
                mult = 1;
2312
            }
2313
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
2314
        }
2315

    
2316
        /* Enter the desired mode.  */
2317
        s->ulpd_pm_regs[offset >> 2] =
2318
                (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
2319
                ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
2320

    
2321
        /* Act as if the lock is restored.  */
2322
        s->ulpd_pm_regs[offset >> 2] |= 2;
2323
        break;
2324

    
2325
    case 0x4c:        /* APLL_CTRL */
2326
        diff = s->ulpd_pm_regs[offset >> 2] & value;
2327
        s->ulpd_pm_regs[offset >> 2] = value & 0xf;
2328
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
2329
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
2330
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
2331
        break;
2332

    
2333
    default:
2334
        OMAP_BAD_REG(addr);
2335
    }
2336
}
2337

    
2338
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
2339
    omap_badwidth_read16,
2340
    omap_ulpd_pm_read,
2341
    omap_badwidth_read16,
2342
};
2343

    
2344
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
2345
    omap_badwidth_write16,
2346
    omap_ulpd_pm_write,
2347
    omap_badwidth_write16,
2348
};
2349

    
2350
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
2351
{
2352
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
2353
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
2354
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
2355
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
2356
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
2357
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
2358
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
2359
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
2360
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
2361
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
2362
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
2363
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
2364
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
2365
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
2366
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
2367
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
2368
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
2369
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
2370
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
2371
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
2372
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
2373
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
2374
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
2375
}
2376

    
2377
static void omap_ulpd_pm_init(target_phys_addr_t base,
2378
                struct omap_mpu_state_s *mpu)
2379
{
2380
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
2381
                    omap_ulpd_pm_writefn, mpu);
2382

    
2383
    mpu->ulpd_pm_base = base;
2384
    cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
2385
    omap_ulpd_pm_reset(mpu);
2386
}
2387

    
2388
/* OMAP Pin Configuration */
2389
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
2390
{
2391
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2392
    int offset = addr - s->pin_cfg_base;
2393

    
2394
    switch (offset) {
2395
    case 0x00:        /* FUNC_MUX_CTRL_0 */
2396
    case 0x04:        /* FUNC_MUX_CTRL_1 */
2397
    case 0x08:        /* FUNC_MUX_CTRL_2 */
2398
        return s->func_mux_ctrl[offset >> 2];
2399

    
2400
    case 0x0c:        /* COMP_MODE_CTRL_0 */
2401
        return s->comp_mode_ctrl[0];
2402

    
2403
    case 0x10:        /* FUNC_MUX_CTRL_3 */
2404
    case 0x14:        /* FUNC_MUX_CTRL_4 */
2405
    case 0x18:        /* FUNC_MUX_CTRL_5 */
2406
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
2407
    case 0x20:        /* FUNC_MUX_CTRL_7 */
2408
    case 0x24:        /* FUNC_MUX_CTRL_8 */
2409
    case 0x28:        /* FUNC_MUX_CTRL_9 */
2410
    case 0x2c:        /* FUNC_MUX_CTRL_A */
2411
    case 0x30:        /* FUNC_MUX_CTRL_B */
2412
    case 0x34:        /* FUNC_MUX_CTRL_C */
2413
    case 0x38:        /* FUNC_MUX_CTRL_D */
2414
        return s->func_mux_ctrl[(offset >> 2) - 1];
2415

    
2416
    case 0x40:        /* PULL_DWN_CTRL_0 */
2417
    case 0x44:        /* PULL_DWN_CTRL_1 */
2418
    case 0x48:        /* PULL_DWN_CTRL_2 */
2419
    case 0x4c:        /* PULL_DWN_CTRL_3 */
2420
        return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
2421

    
2422
    case 0x50:        /* GATE_INH_CTRL_0 */
2423
        return s->gate_inh_ctrl[0];
2424

    
2425
    case 0x60:        /* VOLTAGE_CTRL_0 */
2426
        return s->voltage_ctrl[0];
2427

    
2428
    case 0x70:        /* TEST_DBG_CTRL_0 */
2429
        return s->test_dbg_ctrl[0];
2430

    
2431
    case 0x80:        /* MOD_CONF_CTRL_0 */
2432
        return s->mod_conf_ctrl[0];
2433
    }
2434

    
2435
    OMAP_BAD_REG(addr);
2436
    return 0;
2437
}
2438

    
2439
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
2440
                uint32_t diff, uint32_t value)
2441
{
2442
    if (s->compat1509) {
2443
        if (diff & (1 << 9))                        /* BLUETOOTH */
2444
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
2445
                            (~value >> 9) & 1);
2446
        if (diff & (1 << 7))                        /* USB.CLKO */
2447
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
2448
                            (value >> 7) & 1);
2449
    }
2450
}
2451

    
2452
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
2453
                uint32_t diff, uint32_t value)
2454
{
2455
    if (s->compat1509) {
2456
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
2457
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
2458
                            (value >> 31) & 1);
2459
        if (diff & (1 << 1))                        /* CLK32K */
2460
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
2461
                            (~value >> 1) & 1);
2462
    }
2463
}
2464

    
2465
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
2466
                uint32_t diff, uint32_t value)
2467
{
2468
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
2469
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
2470
                         omap_findclk(s, ((value >> 31) & 1) ?
2471
                                 "ck_48m" : "armper_ck"));
2472
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
2473
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
2474
                         omap_findclk(s, ((value >> 30) & 1) ?
2475
                                 "ck_48m" : "armper_ck"));
2476
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
2477
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
2478
                         omap_findclk(s, ((value >> 29) & 1) ?
2479
                                 "ck_48m" : "armper_ck"));
2480
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
2481
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
2482
                         omap_findclk(s, ((value >> 23) & 1) ?
2483
                                 "ck_48m" : "armper_ck"));
2484
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
2485
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
2486
                         omap_findclk(s, ((value >> 12) & 1) ?
2487
                                 "ck_48m" : "armper_ck"));
2488
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
2489
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
2490
}
2491

    
2492
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
2493
                uint32_t value)
2494
{
2495
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2496
    int offset = addr - s->pin_cfg_base;
2497
    uint32_t diff;
2498

    
2499
    switch (offset) {
2500
    case 0x00:        /* FUNC_MUX_CTRL_0 */
2501
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
2502
        s->func_mux_ctrl[offset >> 2] = value;
2503
        omap_pin_funcmux0_update(s, diff, value);
2504
        return;
2505

    
2506
    case 0x04:        /* FUNC_MUX_CTRL_1 */
2507
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
2508
        s->func_mux_ctrl[offset >> 2] = value;
2509
        omap_pin_funcmux1_update(s, diff, value);
2510
        return;
2511

    
2512
    case 0x08:        /* FUNC_MUX_CTRL_2 */
2513
        s->func_mux_ctrl[offset >> 2] = value;
2514
        return;
2515

    
2516
    case 0x0c:        /* COMP_MODE_CTRL_0 */
2517
        s->comp_mode_ctrl[0] = value;
2518
        s->compat1509 = (value != 0x0000eaef);
2519
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
2520
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
2521
        return;
2522

    
2523
    case 0x10:        /* FUNC_MUX_CTRL_3 */
2524
    case 0x14:        /* FUNC_MUX_CTRL_4 */
2525
    case 0x18:        /* FUNC_MUX_CTRL_5 */
2526
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
2527
    case 0x20:        /* FUNC_MUX_CTRL_7 */
2528
    case 0x24:        /* FUNC_MUX_CTRL_8 */
2529
    case 0x28:        /* FUNC_MUX_CTRL_9 */
2530
    case 0x2c:        /* FUNC_MUX_CTRL_A */
2531
    case 0x30:        /* FUNC_MUX_CTRL_B */
2532
    case 0x34:        /* FUNC_MUX_CTRL_C */
2533
    case 0x38:        /* FUNC_MUX_CTRL_D */
2534
        s->func_mux_ctrl[(offset >> 2) - 1] = value;
2535
        return;
2536

    
2537
    case 0x40:        /* PULL_DWN_CTRL_0 */
2538
    case 0x44:        /* PULL_DWN_CTRL_1 */
2539
    case 0x48:        /* PULL_DWN_CTRL_2 */
2540
    case 0x4c:        /* PULL_DWN_CTRL_3 */
2541
        s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
2542
        return;
2543

    
2544
    case 0x50:        /* GATE_INH_CTRL_0 */
2545
        s->gate_inh_ctrl[0] = value;
2546
        return;
2547

    
2548
    case 0x60:        /* VOLTAGE_CTRL_0 */
2549
        s->voltage_ctrl[0] = value;
2550
        return;
2551

    
2552
    case 0x70:        /* TEST_DBG_CTRL_0 */
2553
        s->test_dbg_ctrl[0] = value;
2554
        return;
2555

    
2556
    case 0x80:        /* MOD_CONF_CTRL_0 */
2557
        diff = s->mod_conf_ctrl[0] ^ value;
2558
        s->mod_conf_ctrl[0] = value;
2559
        omap_pin_modconf1_update(s, diff, value);
2560
        return;
2561

    
2562
    default:
2563
        OMAP_BAD_REG(addr);
2564
    }
2565
}
2566

    
2567
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
2568
    omap_badwidth_read32,
2569
    omap_badwidth_read32,
2570
    omap_pin_cfg_read,
2571
};
2572

    
2573
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
2574
    omap_badwidth_write32,
2575
    omap_badwidth_write32,
2576
    omap_pin_cfg_write,
2577
};
2578

    
2579
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
2580
{
2581
    /* Start in Compatibility Mode.  */
2582
    mpu->compat1509 = 1;
2583
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
2584
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
2585
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
2586
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
2587
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
2588
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
2589
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
2590
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
2591
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
2592
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
2593
}
2594

    
2595
static void omap_pin_cfg_init(target_phys_addr_t base,
2596
                struct omap_mpu_state_s *mpu)
2597
{
2598
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
2599
                    omap_pin_cfg_writefn, mpu);
2600

    
2601
    mpu->pin_cfg_base = base;
2602
    cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
2603
    omap_pin_cfg_reset(mpu);
2604
}
2605

    
2606
/* Device Identification, Die Identification */
2607
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
2608
{
2609
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2610

    
2611
    switch (addr) {
2612
    case 0xfffe1800:        /* DIE_ID_LSB */
2613
        return 0xc9581f0e;
2614
    case 0xfffe1804:        /* DIE_ID_MSB */
2615
        return 0xa8858bfa;
2616

    
2617
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
2618
        return 0x00aaaafc;
2619
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
2620
        return 0xcafeb574;
2621

    
2622
    case 0xfffed400:        /* JTAG_ID_LSB */
2623
        switch (s->mpu_model) {
2624
        case omap310:
2625
            return 0x03310315;
2626
        case omap1510:
2627
            return 0x03310115;
2628
        }
2629
        break;
2630

    
2631
    case 0xfffed404:        /* JTAG_ID_MSB */
2632
        switch (s->mpu_model) {
2633
        case omap310:
2634
            return 0xfb57402f;
2635
        case omap1510:
2636
            return 0xfb47002f;
2637
        }
2638
        break;
2639
    }
2640

    
2641
    OMAP_BAD_REG(addr);
2642
    return 0;
2643
}
2644

    
2645
static void omap_id_write(void *opaque, target_phys_addr_t addr,
2646
                uint32_t value)
2647
{
2648
    OMAP_BAD_REG(addr);
2649
}
2650

    
2651
static CPUReadMemoryFunc *omap_id_readfn[] = {
2652
    omap_badwidth_read32,
2653
    omap_badwidth_read32,
2654
    omap_id_read,
2655
};
2656

    
2657
static CPUWriteMemoryFunc *omap_id_writefn[] = {
2658
    omap_badwidth_write32,
2659
    omap_badwidth_write32,
2660
    omap_id_write,
2661
};
2662

    
2663
static void omap_id_init(struct omap_mpu_state_s *mpu)
2664
{
2665
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
2666
                    omap_id_writefn, mpu);
2667
    cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
2668
    cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
2669
    if (!cpu_is_omap15xx(mpu))
2670
        cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
2671
}
2672

    
2673
/* MPUI Control (Dummy) */
2674
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
2675
{
2676
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2677
    int offset = addr - s->mpui_base;
2678

    
2679
    switch (offset) {
2680
    case 0x00:        /* CTRL */
2681
        return s->mpui_ctrl;
2682
    case 0x04:        /* DEBUG_ADDR */
2683
        return 0x01ffffff;
2684
    case 0x08:        /* DEBUG_DATA */
2685
        return 0xffffffff;
2686
    case 0x0c:        /* DEBUG_FLAG */
2687
        return 0x00000800;
2688
    case 0x10:        /* STATUS */
2689
        return 0x00000000;
2690

    
2691
    /* Not in OMAP310 */
2692
    case 0x14:        /* DSP_STATUS */
2693
    case 0x18:        /* DSP_BOOT_CONFIG */
2694
        return 0x00000000;
2695
    case 0x1c:        /* DSP_MPUI_CONFIG */
2696
        return 0x0000ffff;
2697
    }
2698

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

    
2703
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
2704
                uint32_t value)
2705
{
2706
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2707
    int offset = addr - s->mpui_base;
2708

    
2709
    switch (offset) {
2710
    case 0x00:        /* CTRL */
2711
        s->mpui_ctrl = value & 0x007fffff;
2712
        break;
2713

    
2714
    case 0x04:        /* DEBUG_ADDR */
2715
    case 0x08:        /* DEBUG_DATA */
2716
    case 0x0c:        /* DEBUG_FLAG */
2717
    case 0x10:        /* STATUS */
2718
    /* Not in OMAP310 */
2719
    case 0x14:        /* DSP_STATUS */
2720
        OMAP_RO_REG(addr);
2721
    case 0x18:        /* DSP_BOOT_CONFIG */
2722
    case 0x1c:        /* DSP_MPUI_CONFIG */
2723
        break;
2724

    
2725
    default:
2726
        OMAP_BAD_REG(addr);
2727
    }
2728
}
2729

    
2730
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
2731
    omap_badwidth_read32,
2732
    omap_badwidth_read32,
2733
    omap_mpui_read,
2734
};
2735

    
2736
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
2737
    omap_badwidth_write32,
2738
    omap_badwidth_write32,
2739
    omap_mpui_write,
2740
};
2741

    
2742
static void omap_mpui_reset(struct omap_mpu_state_s *s)
2743
{
2744
    s->mpui_ctrl = 0x0003ff1b;
2745
}
2746

    
2747
static void omap_mpui_init(target_phys_addr_t base,
2748
                struct omap_mpu_state_s *mpu)
2749
{
2750
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
2751
                    omap_mpui_writefn, mpu);
2752

    
2753
    mpu->mpui_base = base;
2754
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
2755

    
2756
    omap_mpui_reset(mpu);
2757
}
2758

    
2759
/* TIPB Bridges */
2760
struct omap_tipb_bridge_s {
2761
    target_phys_addr_t base;
2762
    qemu_irq abort;
2763

    
2764
    int width_intr;
2765
    uint16_t control;
2766
    uint16_t alloc;
2767
    uint16_t buffer;
2768
    uint16_t enh_control;
2769
};
2770

    
2771
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
2772
{
2773
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2774
    int offset = addr - s->base;
2775

    
2776
    switch (offset) {
2777
    case 0x00:        /* TIPB_CNTL */
2778
        return s->control;
2779
    case 0x04:        /* TIPB_BUS_ALLOC */
2780
        return s->alloc;
2781
    case 0x08:        /* MPU_TIPB_CNTL */
2782
        return s->buffer;
2783
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2784
        return s->enh_control;
2785
    case 0x10:        /* ADDRESS_DBG */
2786
    case 0x14:        /* DATA_DEBUG_LOW */
2787
    case 0x18:        /* DATA_DEBUG_HIGH */
2788
        return 0xffff;
2789
    case 0x1c:        /* DEBUG_CNTR_SIG */
2790
        return 0x00f8;
2791
    }
2792

    
2793
    OMAP_BAD_REG(addr);
2794
    return 0;
2795
}
2796

    
2797
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
2798
                uint32_t value)
2799
{
2800
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
2801
    int offset = addr - s->base;
2802

    
2803
    switch (offset) {
2804
    case 0x00:        /* TIPB_CNTL */
2805
        s->control = value & 0xffff;
2806
        break;
2807

    
2808
    case 0x04:        /* TIPB_BUS_ALLOC */
2809
        s->alloc = value & 0x003f;
2810
        break;
2811

    
2812
    case 0x08:        /* MPU_TIPB_CNTL */
2813
        s->buffer = value & 0x0003;
2814
        break;
2815

    
2816
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
2817
        s->width_intr = !(value & 2);
2818
        s->enh_control = value & 0x000f;
2819
        break;
2820

    
2821
    case 0x10:        /* ADDRESS_DBG */
2822
    case 0x14:        /* DATA_DEBUG_LOW */
2823
    case 0x18:        /* DATA_DEBUG_HIGH */
2824
    case 0x1c:        /* DEBUG_CNTR_SIG */
2825
        OMAP_RO_REG(addr);
2826
        break;
2827

    
2828
    default:
2829
        OMAP_BAD_REG(addr);
2830
    }
2831
}
2832

    
2833
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
2834
    omap_badwidth_read16,
2835
    omap_tipb_bridge_read,
2836
    omap_tipb_bridge_read,
2837
};
2838

    
2839
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
2840
    omap_badwidth_write16,
2841
    omap_tipb_bridge_write,
2842
    omap_tipb_bridge_write,
2843
};
2844

    
2845
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
2846
{
2847
    s->control = 0xffff;
2848
    s->alloc = 0x0009;
2849
    s->buffer = 0x0000;
2850
    s->enh_control = 0x000f;
2851
}
2852

    
2853
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
2854
                qemu_irq abort_irq, omap_clk clk)
2855
{
2856
    int iomemtype;
2857
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
2858
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
2859

    
2860
    s->abort = abort_irq;
2861
    s->base = base;
2862
    omap_tipb_bridge_reset(s);
2863

    
2864
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
2865
                    omap_tipb_bridge_writefn, s);
2866
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
2867

    
2868
    return s;
2869
}
2870

    
2871
/* Dummy Traffic Controller's Memory Interface */
2872
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
2873
{
2874
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2875
    int offset = addr - s->tcmi_base;
2876
    uint32_t ret;
2877

    
2878
    switch (offset) {
2879
    case 0x00:        /* IMIF_PRIO */
2880
    case 0x04:        /* EMIFS_PRIO */
2881
    case 0x08:        /* EMIFF_PRIO */
2882
    case 0x0c:        /* EMIFS_CONFIG */
2883
    case 0x10:        /* EMIFS_CS0_CONFIG */
2884
    case 0x14:        /* EMIFS_CS1_CONFIG */
2885
    case 0x18:        /* EMIFS_CS2_CONFIG */
2886
    case 0x1c:        /* EMIFS_CS3_CONFIG */
2887
    case 0x24:        /* EMIFF_MRS */
2888
    case 0x28:        /* TIMEOUT1 */
2889
    case 0x2c:        /* TIMEOUT2 */
2890
    case 0x30:        /* TIMEOUT3 */
2891
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
2892
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
2893
        return s->tcmi_regs[offset >> 2];
2894

    
2895
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
2896
        ret = s->tcmi_regs[offset >> 2];
2897
        s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
2898
        /* XXX: We can try using the VGA_DIRTY flag for this */
2899
        return ret;
2900
    }
2901

    
2902
    OMAP_BAD_REG(addr);
2903
    return 0;
2904
}
2905

    
2906
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
2907
                uint32_t value)
2908
{
2909
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2910
    int offset = addr - s->tcmi_base;
2911

    
2912
    switch (offset) {
2913
    case 0x00:        /* IMIF_PRIO */
2914
    case 0x04:        /* EMIFS_PRIO */
2915
    case 0x08:        /* EMIFF_PRIO */
2916
    case 0x10:        /* EMIFS_CS0_CONFIG */
2917
    case 0x14:        /* EMIFS_CS1_CONFIG */
2918
    case 0x18:        /* EMIFS_CS2_CONFIG */
2919
    case 0x1c:        /* EMIFS_CS3_CONFIG */
2920
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
2921
    case 0x24:        /* EMIFF_MRS */
2922
    case 0x28:        /* TIMEOUT1 */
2923
    case 0x2c:        /* TIMEOUT2 */
2924
    case 0x30:        /* TIMEOUT3 */
2925
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
2926
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
2927
        s->tcmi_regs[offset >> 2] = value;
2928
        break;
2929
    case 0x0c:        /* EMIFS_CONFIG */
2930
        s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
2931
        break;
2932

    
2933
    default:
2934
        OMAP_BAD_REG(addr);
2935
    }
2936
}
2937

    
2938
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
2939
    omap_badwidth_read32,
2940
    omap_badwidth_read32,
2941
    omap_tcmi_read,
2942
};
2943

    
2944
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
2945
    omap_badwidth_write32,
2946
    omap_badwidth_write32,
2947
    omap_tcmi_write,
2948
};
2949

    
2950
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
2951
{
2952
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
2953
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
2954
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
2955
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
2956
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
2957
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
2958
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
2959
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
2960
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
2961
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
2962
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
2963
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
2964
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
2965
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
2966
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
2967
}
2968

    
2969
static void omap_tcmi_init(target_phys_addr_t base,
2970
                struct omap_mpu_state_s *mpu)
2971
{
2972
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
2973
                    omap_tcmi_writefn, mpu);
2974

    
2975
    mpu->tcmi_base = base;
2976
    cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
2977
    omap_tcmi_reset(mpu);
2978
}
2979

    
2980
/* Digital phase-locked loops control */
2981
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
2982
{
2983
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2984
    int offset = addr - s->base;
2985

    
2986
    if (offset == 0x00)        /* CTL_REG */
2987
        return s->mode;
2988

    
2989
    OMAP_BAD_REG(addr);
2990
    return 0;
2991
}
2992

    
2993
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
2994
                uint32_t value)
2995
{
2996
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
2997
    uint16_t diff;
2998
    int offset = addr - s->base;
2999
    static const int bypass_div[4] = { 1, 2, 4, 4 };
3000
    int div, mult;
3001

    
3002
    if (offset == 0x00) {        /* CTL_REG */
3003
        /* See omap_ulpd_pm_write() too */
3004
        diff = s->mode & value;
3005
        s->mode = value & 0x2fff;
3006
        if (diff & (0x3ff << 2)) {
3007
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
3008
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
3009
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
3010
            } else {
3011
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
3012
                mult = 1;
3013
            }
3014
            omap_clk_setrate(s->dpll, div, mult);
3015
        }
3016

    
3017
        /* Enter the desired mode.  */
3018
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
3019

    
3020
        /* Act as if the lock is restored.  */
3021
        s->mode |= 2;
3022
    } else {
3023
        OMAP_BAD_REG(addr);
3024
    }
3025
}
3026

    
3027
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
3028
    omap_badwidth_read16,
3029
    omap_dpll_read,
3030
    omap_badwidth_read16,
3031
};
3032

    
3033
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
3034
    omap_badwidth_write16,
3035
    omap_dpll_write,
3036
    omap_badwidth_write16,
3037
};
3038

    
3039
static void omap_dpll_reset(struct dpll_ctl_s *s)
3040
{
3041
    s->mode = 0x2002;
3042
    omap_clk_setrate(s->dpll, 1, 1);
3043
}
3044

    
3045
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
3046
                omap_clk clk)
3047
{
3048
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
3049
                    omap_dpll_writefn, s);
3050

    
3051
    s->base = base;
3052
    s->dpll = clk;
3053
    omap_dpll_reset(s);
3054

    
3055
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
3056
}
3057

    
3058
/* UARTs */
3059
struct omap_uart_s {
3060
    SerialState *serial; /* TODO */
3061
};
3062

    
3063
static void omap_uart_reset(struct omap_uart_s *s)
3064
{
3065
}
3066

    
3067
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
3068
                qemu_irq irq, omap_clk clk, CharDriverState *chr)
3069
{
3070
    struct omap_uart_s *s = (struct omap_uart_s *)
3071
            qemu_mallocz(sizeof(struct omap_uart_s));
3072
    if (chr)
3073
        s->serial = serial_mm_init(base, 2, irq, chr, 1);
3074
    return s;
3075
}
3076

    
3077
/* MPU Clock/Reset/Power Mode Control */
3078
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
3079
{
3080
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3081
    int offset = addr - s->clkm.mpu_base;
3082

    
3083
    switch (offset) {
3084
    case 0x00:        /* ARM_CKCTL */
3085
        return s->clkm.arm_ckctl;
3086

    
3087
    case 0x04:        /* ARM_IDLECT1 */
3088
        return s->clkm.arm_idlect1;
3089

    
3090
    case 0x08:        /* ARM_IDLECT2 */
3091
        return s->clkm.arm_idlect2;
3092

    
3093
    case 0x0c:        /* ARM_EWUPCT */
3094
        return s->clkm.arm_ewupct;
3095

    
3096
    case 0x10:        /* ARM_RSTCT1 */
3097
        return s->clkm.arm_rstct1;
3098

    
3099
    case 0x14:        /* ARM_RSTCT2 */
3100
        return s->clkm.arm_rstct2;
3101

    
3102
    case 0x18:        /* ARM_SYSST */
3103
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
3104

    
3105
    case 0x1c:        /* ARM_CKOUT1 */
3106
        return s->clkm.arm_ckout1;
3107

    
3108
    case 0x20:        /* ARM_CKOUT2 */
3109
        break;
3110
    }
3111

    
3112
    OMAP_BAD_REG(addr);
3113
    return 0;
3114
}
3115

    
3116
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
3117
                uint16_t diff, uint16_t value)
3118
{
3119
    omap_clk clk;
3120

    
3121
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
3122
        if (value & (1 << 14))
3123
            /* Reserved */;
3124
        else {
3125
            clk = omap_findclk(s, "arminth_ck");
3126
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
3127
        }
3128
    }
3129
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
3130
        clk = omap_findclk(s, "armtim_ck");
3131
        if (value & (1 << 12))
3132
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
3133
        else
3134
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
3135
    }
3136
    /* XXX: en_dspck */
3137
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
3138
        clk = omap_findclk(s, "dspmmu_ck");
3139
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
3140
    }
3141
    if (diff & (3 << 8)) {                                /* TCDIV */
3142
        clk = omap_findclk(s, "tc_ck");
3143
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
3144
    }
3145
    if (diff & (3 << 6)) {                                /* DSPDIV */
3146
        clk = omap_findclk(s, "dsp_ck");
3147
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
3148
    }
3149
    if (diff & (3 << 4)) {                                /* ARMDIV */
3150
        clk = omap_findclk(s, "arm_ck");
3151
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
3152
    }
3153
    if (diff & (3 << 2)) {                                /* LCDDIV */
3154
        clk = omap_findclk(s, "lcd_ck");
3155
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
3156
    }
3157
    if (diff & (3 << 0)) {                                /* PERDIV */
3158
        clk = omap_findclk(s, "armper_ck");
3159
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
3160
    }
3161
}
3162

    
3163
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
3164
                uint16_t diff, uint16_t value)
3165
{
3166
    omap_clk clk;
3167

    
3168
    if (value & (1 << 11))                                /* SETARM_IDLE */
3169
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
3170
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
3171
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
3172

    
3173
#define SET_CANIDLE(clock, bit)                                \
3174
    if (diff & (1 << bit)) {                                \
3175
        clk = omap_findclk(s, clock);                        \
3176
        omap_clk_canidle(clk, (value >> bit) & 1);        \
3177
    }
3178
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
3179
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
3180
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
3181
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
3182
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
3183
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
3184
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
3185
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
3186
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
3187
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
3188
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
3189
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
3190
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
3191
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
3192
}
3193

    
3194
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
3195
                uint16_t diff, uint16_t value)
3196
{
3197
    omap_clk clk;
3198

    
3199
#define SET_ONOFF(clock, bit)                                \
3200
    if (diff & (1 << bit)) {                                \
3201
        clk = omap_findclk(s, clock);                        \
3202
        omap_clk_onoff(clk, (value >> bit) & 1);        \
3203
    }
3204
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
3205
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
3206
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
3207
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
3208
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
3209
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
3210
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
3211
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
3212
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
3213
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
3214
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
3215
}
3216

    
3217
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
3218
                uint16_t diff, uint16_t value)
3219
{
3220
    omap_clk clk;
3221

    
3222
    if (diff & (3 << 4)) {                                /* TCLKOUT */
3223
        clk = omap_findclk(s, "tclk_out");
3224
        switch ((value >> 4) & 3) {
3225
        case 1:
3226
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
3227
            omap_clk_onoff(clk, 1);
3228
            break;
3229
        case 2:
3230
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
3231
            omap_clk_onoff(clk, 1);
3232
            break;
3233
        default:
3234
            omap_clk_onoff(clk, 0);
3235
        }
3236
    }
3237
    if (diff & (3 << 2)) {                                /* DCLKOUT */
3238
        clk = omap_findclk(s, "dclk_out");
3239
        switch ((value >> 2) & 3) {
3240
        case 0:
3241
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
3242
            break;
3243
        case 1:
3244
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
3245
            break;
3246
        case 2:
3247
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
3248
            break;
3249
        case 3:
3250
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
3251
            break;
3252
        }
3253
    }
3254
    if (diff & (3 << 0)) {                                /* ACLKOUT */
3255
        clk = omap_findclk(s, "aclk_out");
3256
        switch ((value >> 0) & 3) {
3257
        case 1:
3258
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
3259
            omap_clk_onoff(clk, 1);
3260
            break;
3261
        case 2:
3262
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
3263
            omap_clk_onoff(clk, 1);
3264
            break;
3265
        case 3:
3266
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
3267
            omap_clk_onoff(clk, 1);
3268
            break;
3269
        default:
3270
            omap_clk_onoff(clk, 0);
3271
        }
3272
    }
3273
}
3274

    
3275
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
3276
                uint32_t value)
3277
{
3278
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3279
    int offset = addr - s->clkm.mpu_base;
3280
    uint16_t diff;
3281
    omap_clk clk;
3282
    static const char *clkschemename[8] = {
3283
        "fully synchronous", "fully asynchronous", "synchronous scalable",
3284
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
3285
    };
3286

    
3287
    switch (offset) {
3288
    case 0x00:        /* ARM_CKCTL */
3289
        diff = s->clkm.arm_ckctl ^ value;
3290
        s->clkm.arm_ckctl = value & 0x7fff;
3291
        omap_clkm_ckctl_update(s, diff, value);
3292
        return;
3293

    
3294
    case 0x04:        /* ARM_IDLECT1 */
3295
        diff = s->clkm.arm_idlect1 ^ value;
3296
        s->clkm.arm_idlect1 = value & 0x0fff;
3297
        omap_clkm_idlect1_update(s, diff, value);
3298
        return;
3299

    
3300
    case 0x08:        /* ARM_IDLECT2 */
3301
        diff = s->clkm.arm_idlect2 ^ value;
3302
        s->clkm.arm_idlect2 = value & 0x07ff;
3303
        omap_clkm_idlect2_update(s, diff, value);
3304
        return;
3305

    
3306
    case 0x0c:        /* ARM_EWUPCT */
3307
        diff = s->clkm.arm_ewupct ^ value;
3308
        s->clkm.arm_ewupct = value & 0x003f;
3309
        return;
3310

    
3311
    case 0x10:        /* ARM_RSTCT1 */
3312
        diff = s->clkm.arm_rstct1 ^ value;
3313
        s->clkm.arm_rstct1 = value & 0x0007;
3314
        if (value & 9) {
3315
            qemu_system_reset_request();
3316
            s->clkm.cold_start = 0xa;
3317
        }
3318
        if (diff & ~value & 4) {                                /* DSP_RST */
3319
            omap_mpui_reset(s);
3320
            omap_tipb_bridge_reset(s->private_tipb);
3321
            omap_tipb_bridge_reset(s->public_tipb);
3322
        }
3323
        if (diff & 2) {                                                /* DSP_EN */
3324
            clk = omap_findclk(s, "dsp_ck");
3325
            omap_clk_canidle(clk, (~value >> 1) & 1);
3326
        }
3327
        return;
3328

    
3329
    case 0x14:        /* ARM_RSTCT2 */
3330
        s->clkm.arm_rstct2 = value & 0x0001;
3331
        return;
3332

    
3333
    case 0x18:        /* ARM_SYSST */
3334
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
3335
            s->clkm.clocking_scheme = (value >> 11) & 7;
3336
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
3337
                            clkschemename[s->clkm.clocking_scheme]);
3338
        }
3339
        s->clkm.cold_start &= value & 0x3f;
3340
        return;
3341

    
3342
    case 0x1c:        /* ARM_CKOUT1 */
3343
        diff = s->clkm.arm_ckout1 ^ value;
3344
        s->clkm.arm_ckout1 = value & 0x003f;
3345
        omap_clkm_ckout1_update(s, diff, value);
3346
        return;
3347

    
3348
    case 0x20:        /* ARM_CKOUT2 */
3349
    default:
3350
        OMAP_BAD_REG(addr);
3351
    }
3352
}
3353

    
3354
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
3355
    omap_badwidth_read16,
3356
    omap_clkm_read,
3357
    omap_badwidth_read16,
3358
};
3359

    
3360
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
3361
    omap_badwidth_write16,
3362
    omap_clkm_write,
3363
    omap_badwidth_write16,
3364
};
3365

    
3366
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
3367
{
3368
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3369
    int offset = addr - s->clkm.dsp_base;
3370

    
3371
    switch (offset) {
3372
    case 0x04:        /* DSP_IDLECT1 */
3373
        return s->clkm.dsp_idlect1;
3374

    
3375
    case 0x08:        /* DSP_IDLECT2 */
3376
        return s->clkm.dsp_idlect2;
3377

    
3378
    case 0x14:        /* DSP_RSTCT2 */
3379
        return s->clkm.dsp_rstct2;
3380

    
3381
    case 0x18:        /* DSP_SYSST */
3382
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
3383
                (s->env->halted << 6);        /* Quite useless... */
3384
    }
3385

    
3386
    OMAP_BAD_REG(addr);
3387
    return 0;
3388
}
3389

    
3390
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
3391
                uint16_t diff, uint16_t value)
3392
{
3393
    omap_clk clk;
3394

    
3395
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
3396
}
3397

    
3398
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
3399
                uint16_t diff, uint16_t value)
3400
{
3401
    omap_clk clk;
3402

    
3403
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
3404
}
3405

    
3406
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
3407
                uint32_t value)
3408
{
3409
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3410
    int offset = addr - s->clkm.dsp_base;
3411
    uint16_t diff;
3412

    
3413
    switch (offset) {
3414
    case 0x04:        /* DSP_IDLECT1 */
3415
        diff = s->clkm.dsp_idlect1 ^ value;
3416
        s->clkm.dsp_idlect1 = value & 0x01f7;
3417
        omap_clkdsp_idlect1_update(s, diff, value);
3418
        break;
3419

    
3420
    case 0x08:        /* DSP_IDLECT2 */
3421
        s->clkm.dsp_idlect2 = value & 0x0037;
3422
        diff = s->clkm.dsp_idlect1 ^ value;
3423
        omap_clkdsp_idlect2_update(s, diff, value);
3424
        break;
3425

    
3426
    case 0x14:        /* DSP_RSTCT2 */
3427
        s->clkm.dsp_rstct2 = value & 0x0001;
3428
        break;
3429

    
3430
    case 0x18:        /* DSP_SYSST */
3431
        s->clkm.cold_start &= value & 0x3f;
3432
        break;
3433

    
3434
    default:
3435
        OMAP_BAD_REG(addr);
3436
    }
3437
}
3438

    
3439
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
3440
    omap_badwidth_read16,
3441
    omap_clkdsp_read,
3442
    omap_badwidth_read16,
3443
};
3444

    
3445
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
3446
    omap_badwidth_write16,
3447
    omap_clkdsp_write,
3448
    omap_badwidth_write16,
3449
};
3450

    
3451
static void omap_clkm_reset(struct omap_mpu_state_s *s)
3452
{
3453
    if (s->wdt && s->wdt->reset)
3454
        s->clkm.cold_start = 0x6;
3455
    s->clkm.clocking_scheme = 0;
3456
    omap_clkm_ckctl_update(s, ~0, 0x3000);
3457
    s->clkm.arm_ckctl = 0x3000;
3458
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
3459
    s->clkm.arm_idlect1 = 0x0400;
3460
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
3461
    s->clkm.arm_idlect2 = 0x0100;
3462
    s->clkm.arm_ewupct = 0x003f;
3463
    s->clkm.arm_rstct1 = 0x0000;
3464
    s->clkm.arm_rstct2 = 0x0000;
3465
    s->clkm.arm_ckout1 = 0x0015;
3466
    s->clkm.dpll1_mode = 0x2002;
3467
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
3468
    s->clkm.dsp_idlect1 = 0x0040;
3469
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
3470
    s->clkm.dsp_idlect2 = 0x0000;
3471
    s->clkm.dsp_rstct2 = 0x0000;
3472
}
3473

    
3474
static void omap_clkm_init(target_phys_addr_t mpu_base,
3475
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
3476
{
3477
    int iomemtype[2] = {
3478
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
3479
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
3480
    };
3481

    
3482
    s->clkm.mpu_base = mpu_base;
3483
    s->clkm.dsp_base = dsp_base;
3484
    s->clkm.arm_idlect1 = 0x03ff;
3485
    s->clkm.arm_idlect2 = 0x0100;
3486
    s->clkm.dsp_idlect1 = 0x0002;
3487
    omap_clkm_reset(s);
3488
    s->clkm.cold_start = 0x3a;
3489

    
3490
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
3491
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
3492
}
3493

    
3494
/* MPU I/O */
3495
struct omap_mpuio_s {
3496
    target_phys_addr_t base;
3497
    qemu_irq irq;
3498
    qemu_irq kbd_irq;
3499
    qemu_irq *in;
3500
    qemu_irq handler[16];
3501
    qemu_irq wakeup;
3502

    
3503
    uint16_t inputs;
3504
    uint16_t outputs;
3505
    uint16_t dir;
3506
    uint16_t edge;
3507
    uint16_t mask;
3508
    uint16_t ints;
3509

    
3510
    uint16_t debounce;
3511
    uint16_t latch;
3512
    uint8_t event;
3513

    
3514
    uint8_t buttons[5];
3515
    uint8_t row_latch;
3516
    uint8_t cols;
3517
    int kbd_mask;
3518
    int clk;
3519
};
3520

    
3521
static void omap_mpuio_set(void *opaque, int line, int level)
3522
{
3523
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3524
    uint16_t prev = s->inputs;
3525

    
3526
    if (level)
3527
        s->inputs |= 1 << line;
3528
    else
3529
        s->inputs &= ~(1 << line);
3530

    
3531
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
3532
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
3533
            s->ints |= 1 << line;
3534
            qemu_irq_raise(s->irq);
3535
            /* TODO: wakeup */
3536
        }
3537
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
3538
                (s->event >> 1) == line)        /* PIN_SELECT */
3539
            s->latch = s->inputs;
3540
    }
3541
}
3542

    
3543
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
3544
{
3545
    int i;
3546
    uint8_t *row, rows = 0, cols = ~s->cols;
3547

    
3548
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
3549
        if (*row & cols)
3550
            rows |= i;
3551

    
3552
    qemu_set_irq(s->kbd_irq, rows && ~s->kbd_mask && s->clk);
3553
    s->row_latch = rows ^ 0x1f;
3554
}
3555

    
3556
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
3557
{
3558
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3559
    int offset = addr & OMAP_MPUI_REG_MASK;
3560
    uint16_t ret;
3561

    
3562
    switch (offset) {
3563
    case 0x00:        /* INPUT_LATCH */
3564
        return s->inputs;
3565

    
3566
    case 0x04:        /* OUTPUT_REG */
3567
        return s->outputs;
3568

    
3569
    case 0x08:        /* IO_CNTL */
3570
        return s->dir;
3571

    
3572
    case 0x10:        /* KBR_LATCH */
3573
        return s->row_latch;
3574

    
3575
    case 0x14:        /* KBC_REG */
3576
        return s->cols;
3577

    
3578
    case 0x18:        /* GPIO_EVENT_MODE_REG */
3579
        return s->event;
3580

    
3581
    case 0x1c:        /* GPIO_INT_EDGE_REG */
3582
        return s->edge;
3583

    
3584
    case 0x20:        /* KBD_INT */
3585
        return (s->row_latch != 0x1f) && !s->kbd_mask;
3586

    
3587
    case 0x24:        /* GPIO_INT */
3588
        ret = s->ints;
3589
        s->ints &= s->mask;
3590
        if (ret)
3591
            qemu_irq_lower(s->irq);
3592
        return ret;
3593

    
3594
    case 0x28:        /* KBD_MASKIT */
3595
        return s->kbd_mask;
3596

    
3597
    case 0x2c:        /* GPIO_MASKIT */
3598
        return s->mask;
3599

    
3600
    case 0x30:        /* GPIO_DEBOUNCING_REG */
3601
        return s->debounce;
3602

    
3603
    case 0x34:        /* GPIO_LATCH_REG */
3604
        return s->latch;
3605
    }
3606

    
3607
    OMAP_BAD_REG(addr);
3608
    return 0;
3609
}
3610

    
3611
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
3612
                uint32_t value)
3613
{
3614
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3615
    int offset = addr & OMAP_MPUI_REG_MASK;
3616
    uint16_t diff;
3617
    int ln;
3618

    
3619
    switch (offset) {
3620
    case 0x04:        /* OUTPUT_REG */
3621
        diff = (s->outputs ^ value) & ~s->dir;
3622
        s->outputs = value;
3623
        while ((ln = ffs(diff))) {
3624
            ln --;
3625
            if (s->handler[ln])
3626
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3627
            diff &= ~(1 << ln);
3628
        }
3629
        break;
3630

    
3631
    case 0x08:        /* IO_CNTL */
3632
        diff = s->outputs & (s->dir ^ value);
3633
        s->dir = value;
3634

    
3635
        value = s->outputs & ~s->dir;
3636
        while ((ln = ffs(diff))) {
3637
            ln --;
3638
            if (s->handler[ln])
3639
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3640
            diff &= ~(1 << ln);
3641
        }
3642
        break;
3643

    
3644
    case 0x14:        /* KBC_REG */
3645
        s->cols = value;
3646
        omap_mpuio_kbd_update(s);
3647
        break;
3648

    
3649
    case 0x18:        /* GPIO_EVENT_MODE_REG */
3650
        s->event = value & 0x1f;
3651
        break;
3652

    
3653
    case 0x1c:        /* GPIO_INT_EDGE_REG */
3654
        s->edge = value;
3655
        break;
3656

    
3657
    case 0x28:        /* KBD_MASKIT */
3658
        s->kbd_mask = value & 1;
3659
        omap_mpuio_kbd_update(s);
3660
        break;
3661

    
3662
    case 0x2c:        /* GPIO_MASKIT */
3663
        s->mask = value;
3664
        break;
3665

    
3666
    case 0x30:        /* GPIO_DEBOUNCING_REG */
3667
        s->debounce = value & 0x1ff;
3668
        break;
3669

    
3670
    case 0x00:        /* INPUT_LATCH */
3671
    case 0x10:        /* KBR_LATCH */
3672
    case 0x20:        /* KBD_INT */
3673
    case 0x24:        /* GPIO_INT */
3674
    case 0x34:        /* GPIO_LATCH_REG */
3675
        OMAP_RO_REG(addr);
3676
        return;
3677

    
3678
    default:
3679
        OMAP_BAD_REG(addr);
3680
        return;
3681
    }
3682
}
3683

    
3684
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
3685
    omap_badwidth_read16,
3686
    omap_mpuio_read,
3687
    omap_badwidth_read16,
3688
};
3689

    
3690
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
3691
    omap_badwidth_write16,
3692
    omap_mpuio_write,
3693
    omap_badwidth_write16,
3694
};
3695

    
3696
static void omap_mpuio_reset(struct omap_mpuio_s *s)
3697
{
3698
    s->inputs = 0;
3699
    s->outputs = 0;
3700
    s->dir = ~0;
3701
    s->event = 0;
3702
    s->edge = 0;
3703
    s->kbd_mask = 0;
3704
    s->mask = 0;
3705
    s->debounce = 0;
3706
    s->latch = 0;
3707
    s->ints = 0;
3708
    s->row_latch = 0x1f;
3709
    s->clk = 1;
3710
}
3711

    
3712
static void omap_mpuio_onoff(void *opaque, int line, int on)
3713
{
3714
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
3715

    
3716
    s->clk = on;
3717
    if (on)
3718
        omap_mpuio_kbd_update(s);
3719
}
3720

    
3721
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
3722
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
3723
                omap_clk clk)
3724
{
3725
    int iomemtype;
3726
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
3727
            qemu_mallocz(sizeof(struct omap_mpuio_s));
3728

    
3729
    s->base = base;
3730
    s->irq = gpio_int;
3731
    s->kbd_irq = kbd_int;
3732
    s->wakeup = wakeup;
3733
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
3734
    omap_mpuio_reset(s);
3735

    
3736
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
3737
                    omap_mpuio_writefn, s);
3738
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3739

    
3740
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
3741

    
3742
    return s;
3743
}
3744

    
3745
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
3746
{
3747
    return s->in;
3748
}
3749

    
3750
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
3751
{
3752
    if (line >= 16 || line < 0)
3753
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3754
    s->handler[line] = handler;
3755
}
3756

    
3757
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
3758
{
3759
    if (row >= 5 || row < 0)
3760
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
3761
                        __FUNCTION__, col, row);
3762

    
3763
    if (down)
3764
        s->buttons[row] |= 1 << col;
3765
    else
3766
        s->buttons[row] &= ~(1 << col);
3767

    
3768
    omap_mpuio_kbd_update(s);
3769
}
3770

    
3771
/* General-Purpose I/O */
3772
struct omap_gpio_s {
3773
    target_phys_addr_t base;
3774
    qemu_irq irq;
3775
    qemu_irq *in;
3776
    qemu_irq handler[16];
3777

    
3778
    uint16_t inputs;
3779
    uint16_t outputs;
3780
    uint16_t dir;
3781
    uint16_t edge;
3782
    uint16_t mask;
3783
    uint16_t ints;
3784
    uint16_t pins;
3785
};
3786

    
3787
static void omap_gpio_set(void *opaque, int line, int level)
3788
{
3789
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3790
    uint16_t prev = s->inputs;
3791

    
3792
    if (level)
3793
        s->inputs |= 1 << line;
3794
    else
3795
        s->inputs &= ~(1 << line);
3796

    
3797
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
3798
                    (1 << line) & s->dir & ~s->mask) {
3799
        s->ints |= 1 << line;
3800
        qemu_irq_raise(s->irq);
3801
    }
3802
}
3803

    
3804
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
3805
{
3806
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3807
    int offset = addr & OMAP_MPUI_REG_MASK;
3808

    
3809
    switch (offset) {
3810
    case 0x00:        /* DATA_INPUT */
3811
        return s->inputs & s->pins;
3812

    
3813
    case 0x04:        /* DATA_OUTPUT */
3814
        return s->outputs;
3815

    
3816
    case 0x08:        /* DIRECTION_CONTROL */
3817
        return s->dir;
3818

    
3819
    case 0x0c:        /* INTERRUPT_CONTROL */
3820
        return s->edge;
3821

    
3822
    case 0x10:        /* INTERRUPT_MASK */
3823
        return s->mask;
3824

    
3825
    case 0x14:        /* INTERRUPT_STATUS */
3826
        return s->ints;
3827

    
3828
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
3829
        OMAP_BAD_REG(addr);
3830
        return s->pins;
3831
    }
3832

    
3833
    OMAP_BAD_REG(addr);
3834
    return 0;
3835
}
3836

    
3837
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
3838
                uint32_t value)
3839
{
3840
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3841
    int offset = addr & OMAP_MPUI_REG_MASK;
3842
    uint16_t diff;
3843
    int ln;
3844

    
3845
    switch (offset) {
3846
    case 0x00:        /* DATA_INPUT */
3847
        OMAP_RO_REG(addr);
3848
        return;
3849

    
3850
    case 0x04:        /* DATA_OUTPUT */
3851
        diff = (s->outputs ^ value) & ~s->dir;
3852
        s->outputs = value;
3853
        while ((ln = ffs(diff))) {
3854
            ln --;
3855
            if (s->handler[ln])
3856
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3857
            diff &= ~(1 << ln);
3858
        }
3859
        break;
3860

    
3861
    case 0x08:        /* DIRECTION_CONTROL */
3862
        diff = s->outputs & (s->dir ^ value);
3863
        s->dir = value;
3864

    
3865
        value = s->outputs & ~s->dir;
3866
        while ((ln = ffs(diff))) {
3867
            ln --;
3868
            if (s->handler[ln])
3869
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
3870
            diff &= ~(1 << ln);
3871
        }
3872
        break;
3873

    
3874
    case 0x0c:        /* INTERRUPT_CONTROL */
3875
        s->edge = value;
3876
        break;
3877

    
3878
    case 0x10:        /* INTERRUPT_MASK */
3879
        s->mask = value;
3880
        break;
3881

    
3882
    case 0x14:        /* INTERRUPT_STATUS */
3883
        s->ints &= ~value;
3884
        if (!s->ints)
3885
            qemu_irq_lower(s->irq);
3886
        break;
3887

    
3888
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
3889
        OMAP_BAD_REG(addr);
3890
        s->pins = value;
3891
        break;
3892

    
3893
    default:
3894
        OMAP_BAD_REG(addr);
3895
        return;
3896
    }
3897
}
3898

    
3899
/* *Some* sources say the memory region is 32-bit.  */
3900
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
3901
    omap_badwidth_read16,
3902
    omap_gpio_read,
3903
    omap_badwidth_read16,
3904
};
3905

    
3906
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
3907
    omap_badwidth_write16,
3908
    omap_gpio_write,
3909
    omap_badwidth_write16,
3910
};
3911

    
3912
static void omap_gpio_reset(struct omap_gpio_s *s)
3913
{
3914
    s->inputs = 0;
3915
    s->outputs = ~0;
3916
    s->dir = ~0;
3917
    s->edge = ~0;
3918
    s->mask = ~0;
3919
    s->ints = 0;
3920
    s->pins = ~0;
3921
}
3922

    
3923
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
3924
                qemu_irq irq, omap_clk clk)
3925
{
3926
    int iomemtype;
3927
    struct omap_gpio_s *s = (struct omap_gpio_s *)
3928
            qemu_mallocz(sizeof(struct omap_gpio_s));
3929

    
3930
    s->base = base;
3931
    s->irq = irq;
3932
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
3933
    omap_gpio_reset(s);
3934

    
3935
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
3936
                    omap_gpio_writefn, s);
3937
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3938

    
3939
    return s;
3940
}
3941

    
3942
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
3943
{
3944
    return s->in;
3945
}
3946

    
3947
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3948
{
3949
    if (line >= 16 || line < 0)
3950
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3951
    s->handler[line] = handler;
3952
}
3953

    
3954
/* MicroWire Interface */
3955
struct omap_uwire_s {
3956
    target_phys_addr_t base;
3957
    qemu_irq txirq;
3958
    qemu_irq rxirq;
3959
    qemu_irq txdrq;
3960

    
3961
    uint16_t txbuf;
3962
    uint16_t rxbuf;
3963
    uint16_t control;
3964
    uint16_t setup[5];
3965

    
3966
    struct uwire_slave_s *chip[4];
3967
};
3968

    
3969
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3970
{
3971
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3972
    struct uwire_slave_s *slave = s->chip[chipselect];
3973

    
3974
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
3975
        if (s->control & (1 << 12))                        /* CS_CMD */
3976
            if (slave && slave->send)
3977
                slave->send(slave->opaque,
3978
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3979
        s->control &= ~(1 << 14);                        /* CSRB */
3980
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3981
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3982
    }
3983

    
3984
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
3985
        if (s->control & (1 << 12))                        /* CS_CMD */
3986
            if (slave && slave->receive)
3987
                s->rxbuf = slave->receive(slave->opaque);
3988
        s->control |= 1 << 15;                                /* RDRB */
3989
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3990
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3991
    }
3992
}
3993

    
3994
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3995
{
3996
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3997
    int offset = addr & OMAP_MPUI_REG_MASK;
3998

    
3999
    switch (offset) {
4000
    case 0x00:        /* RDR */
4001
        s->control &= ~(1 << 15);                        /* RDRB */
4002
        return s->rxbuf;
4003

    
4004
    case 0x04:        /* CSR */
4005
        return s->control;
4006

    
4007
    case 0x08:        /* SR1 */
4008
        return s->setup[0];
4009
    case 0x0c:        /* SR2 */
4010
        return s->setup[1];
4011
    case 0x10:        /* SR3 */
4012
        return s->setup[2];
4013
    case 0x14:        /* SR4 */
4014
        return s->setup[3];
4015
    case 0x18:        /* SR5 */
4016
        return s->setup[4];
4017
    }
4018

    
4019
    OMAP_BAD_REG(addr);
4020
    return 0;
4021
}
4022

    
4023
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
4024
                uint32_t value)
4025
{
4026
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
4027
    int offset = addr & OMAP_MPUI_REG_MASK;
4028

    
4029
    switch (offset) {
4030
    case 0x00:        /* TDR */
4031
        s->txbuf = value;                                /* TD */
4032
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
4033
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
4034
                         (s->control & (1 << 12)))) {        /* CS_CMD */
4035
            s->control |= 1 << 14;                        /* CSRB */
4036
            omap_uwire_transfer_start(s);
4037
        }
4038
        break;
4039

    
4040
    case 0x04:        /* CSR */
4041
        s->control = value & 0x1fff;
4042
        if (value & (1 << 13))                                /* START */
4043
            omap_uwire_transfer_start(s);
4044
        break;
4045

    
4046
    case 0x08:        /* SR1 */
4047
        s->setup[0] = value & 0x003f;
4048
        break;
4049

    
4050
    case 0x0c:        /* SR2 */
4051
        s->setup[1] = value & 0x0fc0;
4052
        break;
4053

    
4054
    case 0x10:        /* SR3 */
4055
        s->setup[2] = value & 0x0003;
4056
        break;
4057

    
4058
    case 0x14:        /* SR4 */
4059
        s->setup[3] = value & 0x0001;
4060
        break;
4061

    
4062
    case 0x18:        /* SR5 */
4063
        s->setup[4] = value & 0x000f;
4064
        break;
4065

    
4066
    default:
4067
        OMAP_BAD_REG(addr);
4068
        return;
4069
    }
4070
}
4071

    
4072
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
4073
    omap_badwidth_read16,
4074
    omap_uwire_read,
4075
    omap_badwidth_read16,
4076
};
4077

    
4078
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
4079
    omap_badwidth_write16,
4080
    omap_uwire_write,
4081
    omap_badwidth_write16,
4082
};
4083

    
4084
static void omap_uwire_reset(struct omap_uwire_s *s)
4085
{
4086
    s->control = 0;
4087
    s->setup[0] = 0;
4088
    s->setup[1] = 0;
4089
    s->setup[2] = 0;
4090
    s->setup[3] = 0;
4091
    s->setup[4] = 0;
4092
}
4093

    
4094
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
4095
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
4096
{
4097
    int iomemtype;
4098
    struct omap_uwire_s *s = (struct omap_uwire_s *)
4099
            qemu_mallocz(sizeof(struct omap_uwire_s));
4100

    
4101
    s->base = base;
4102
    s->txirq = irq[0];
4103
    s->rxirq = irq[1];
4104
    s->txdrq = dma;
4105
    omap_uwire_reset(s);
4106

    
4107
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
4108
                    omap_uwire_writefn, s);
4109
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4110

    
4111
    return s;
4112
}
4113

    
4114
void omap_uwire_attach(struct omap_uwire_s *s,
4115
                struct uwire_slave_s *slave, int chipselect)
4116
{
4117
    if (chipselect < 0 || chipselect > 3)
4118
        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
4119
                        chipselect);
4120

    
4121
    s->chip[chipselect] = slave;
4122
}
4123

    
4124
/* Pseudonoise Pulse-Width Light Modulator */
4125
static void omap_pwl_update(struct omap_mpu_state_s *s)
4126
{
4127
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
4128

    
4129
    if (output != s->pwl.output) {
4130
        s->pwl.output = output;
4131
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
4132
    }
4133
}
4134

    
4135
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
4136
{
4137
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
4138
    int offset = addr & OMAP_MPUI_REG_MASK;
4139

    
4140
    switch (offset) {
4141
    case 0x00:        /* PWL_LEVEL */
4142
        return s->pwl.level;
4143
    case 0x04:        /* PWL_CTRL */
4144
        return s->pwl.enable;
4145
    }
4146
    OMAP_BAD_REG(addr);
4147
    return 0;
4148
}
4149

    
4150
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
4151
                uint32_t value)
4152
{
4153
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
4154
    int offset = addr & OMAP_MPUI_REG_MASK;
4155

    
4156
    switch (offset) {
4157
    case 0x00:        /* PWL_LEVEL */
4158
        s->pwl.level = value;
4159
        omap_pwl_update(s);
4160
        break;
4161
    case 0x04:        /* PWL_CTRL */
4162
        s->pwl.enable = value & 1;
4163
        omap_pwl_update(s);
4164
        break;
4165
    default:
4166
        OMAP_BAD_REG(addr);
4167
        return;
4168
    }
4169
}
4170

    
4171
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
4172
    omap_pwl_read,
4173
    omap_badwidth_read8,
4174
    omap_badwidth_read8,
4175
};
4176

    
4177
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
4178
    omap_pwl_write,
4179
    omap_badwidth_write8,
4180
    omap_badwidth_write8,
4181
};
4182

    
4183
static void omap_pwl_reset(struct omap_mpu_state_s *s)
4184
{
4185
    s->pwl.output = 0;
4186
    s->pwl.level = 0;
4187
    s->pwl.enable = 0;
4188
    s->pwl.clk = 1;
4189
    omap_pwl_update(s);
4190
}
4191

    
4192
static void omap_pwl_clk_update(void *opaque, int line, int on)
4193
{
4194
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
4195

    
4196
    s->pwl.clk = on;
4197
    omap_pwl_update(s);
4198
}
4199

    
4200
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
4201
                omap_clk clk)
4202
{
4203
    int iomemtype;
4204

    
4205
    omap_pwl_reset(s);
4206

    
4207
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
4208
                    omap_pwl_writefn, s);
4209
    cpu_register_physical_memory(base, 0x800, iomemtype);
4210

    
4211
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
4212
}
4213

    
4214
/* Pulse-Width Tone module */
4215
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
4216
{
4217
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
4218
    int offset = addr & OMAP_MPUI_REG_MASK;
4219

    
4220
    switch (offset) {
4221
    case 0x00:        /* FRC */
4222
        return s->pwt.frc;
4223
    case 0x04:        /* VCR */
4224
        return s->pwt.vrc;
4225
    case 0x08:        /* GCR */
4226
        return s->pwt.gcr;
4227
    }
4228
    OMAP_BAD_REG(addr);
4229
    return 0;
4230
}
4231

    
4232
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
4233
                uint32_t value)
4234
{
4235
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
4236
    int offset = addr & OMAP_MPUI_REG_MASK;
4237

    
4238
    switch (offset) {
4239
    case 0x00:        /* FRC */
4240
        s->pwt.frc = value & 0x3f;
4241
        break;
4242
    case 0x04:        /* VRC */
4243
        if ((value ^ s->pwt.vrc) & 1) {
4244
            if (value & 1)
4245
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
4246
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
4247
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
4248
                                 /* Pre-multiplexer divider */
4249
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
4250
                                 /* Octave multiplexer */
4251
                                 (2 << (value & 3)) *
4252
                                 /* 101/107 divider */
4253
                                 ((value & (1 << 2)) ? 101 : 107) *
4254
                                 /*  49/55 divider */
4255
                                 ((value & (1 << 3)) ?  49 : 55) *
4256
                                 /*  50/63 divider */
4257
                                 ((value & (1 << 4)) ?  50 : 63) *
4258
                                 /*  80/127 divider */
4259
                                 ((value & (1 << 5)) ?  80 : 127) /
4260
                                 (107 * 55 * 63 * 127)));
4261
            else
4262
                printf("%s: silence!\n", __FUNCTION__);
4263
        }
4264
        s->pwt.vrc = value & 0x7f;
4265
        break;
4266
    case 0x08:        /* GCR */
4267
        s->pwt.gcr = value & 3;
4268
        break;
4269
    default:
4270
        OMAP_BAD_REG(addr);
4271
        return;
4272
    }
4273
}
4274

    
4275
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
4276
    omap_pwt_read,
4277
    omap_badwidth_read8,
4278
    omap_badwidth_read8,
4279
};
4280

    
4281
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
4282
    omap_pwt_write,
4283
    omap_badwidth_write8,
4284
    omap_badwidth_write8,
4285
};
4286

    
4287
static void omap_pwt_reset(struct omap_mpu_state_s *s)
4288
{
4289
    s->pwt.frc = 0;
4290
    s->pwt.vrc = 0;
4291
    s->pwt.gcr = 0;
4292
}
4293

    
4294
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
4295
                omap_clk clk)
4296
{
4297
    int iomemtype;
4298

    
4299
    s->pwt.clk = clk;
4300
    omap_pwt_reset(s);
4301

    
4302
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
4303
                    omap_pwt_writefn, s);
4304
    cpu_register_physical_memory(base, 0x800, iomemtype);
4305
}
4306

    
4307
/* Real-time Clock module */
4308
struct omap_rtc_s {
4309
    target_phys_addr_t base;
4310
    qemu_irq irq;
4311
    qemu_irq alarm;
4312
    QEMUTimer *clk;
4313

    
4314
    uint8_t interrupts;
4315
    uint8_t status;
4316
    int16_t comp_reg;
4317
    int running;
4318
    int pm_am;
4319
    int auto_comp;
4320
    int round;
4321
    struct tm *(*convert)(const time_t *timep, struct tm *result);
4322
    struct tm alarm_tm;
4323
    time_t alarm_ti;
4324

    
4325
    struct tm current_tm;
4326
    time_t ti;
4327
    uint64_t tick;
4328
};
4329

    
4330
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
4331
{
4332
    /* s->alarm is level-triggered */
4333
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
4334
}
4335

    
4336
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
4337
{
4338
    s->alarm_ti = mktime(&s->alarm_tm);
4339
    if (s->alarm_ti == -1)
4340
        printf("%s: conversion failed\n", __FUNCTION__);
4341
}
4342

    
4343
static inline uint8_t omap_rtc_bcd(int num)
4344
{
4345
    return ((num / 10) << 4) | (num % 10);
4346
}
4347

    
4348
static inline int omap_rtc_bin(uint8_t num)
4349
{
4350
    return (num & 15) + 10 * (num >> 4);
4351
}
4352

    
4353
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
4354
{
4355
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
4356
    int offset = addr & OMAP_MPUI_REG_MASK;
4357
    uint8_t i;
4358

    
4359
    switch (offset) {
4360
    case 0x00:        /* SECONDS_REG */
4361
        return omap_rtc_bcd(s->current_tm.tm_sec);
4362

    
4363
    case 0x04:        /* MINUTES_REG */
4364
        return omap_rtc_bcd(s->current_tm.tm_min);
4365

    
4366
    case 0x08:        /* HOURS_REG */
4367
        if (s->pm_am)
4368
            return ((s->current_tm.tm_hour > 11) << 7) |
4369
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
4370
        else
4371
            return omap_rtc_bcd(s->current_tm.tm_hour);
4372

    
4373
    case 0x0c:        /* DAYS_REG */
4374
        return omap_rtc_bcd(s->current_tm.tm_mday);
4375

    
4376
    case 0x10:        /* MONTHS_REG */
4377
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
4378

    
4379
    case 0x14:        /* YEARS_REG */
4380
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
4381

    
4382
    case 0x18:        /* WEEK_REG */
4383
        return s->current_tm.tm_wday;
4384

    
4385
    case 0x20:        /* ALARM_SECONDS_REG */
4386
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
4387

    
4388
    case 0x24:        /* ALARM_MINUTES_REG */
4389
        return omap_rtc_bcd(s->alarm_tm.tm_min);
4390

    
4391
    case 0x28:        /* ALARM_HOURS_REG */
4392
        if (s->pm_am)
4393
            return ((s->alarm_tm.tm_hour > 11) << 7) |
4394
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
4395
        else
4396
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
4397

    
4398
    case 0x2c:        /* ALARM_DAYS_REG */
4399
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
4400

    
4401
    case 0x30:        /* ALARM_MONTHS_REG */
4402
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
4403

    
4404
    case 0x34:        /* ALARM_YEARS_REG */
4405
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
4406

    
4407
    case 0x40:        /* RTC_CTRL_REG */
4408
        return (s->pm_am << 3) | (s->auto_comp << 2) |
4409
                (s->round << 1) | s->running;
4410

    
4411
    case 0x44:        /* RTC_STATUS_REG */
4412
        i = s->status;
4413
        s->status &= ~0x3d;
4414
        return i;
4415

    
4416
    case 0x48:        /* RTC_INTERRUPTS_REG */
4417
        return s->interrupts;
4418

    
4419
    case 0x4c:        /* RTC_COMP_LSB_REG */
4420
        return ((uint16_t) s->comp_reg) & 0xff;
4421

    
4422
    case 0x50:        /* RTC_COMP_MSB_REG */
4423
        return ((uint16_t) s->comp_reg) >> 8;
4424
    }
4425

    
4426
    OMAP_BAD_REG(addr);
4427
    return 0;
4428
}
4429

    
4430
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
4431
                uint32_t value)
4432
{
4433
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
4434
    int offset = addr & OMAP_MPUI_REG_MASK;
4435
    struct tm new_tm;
4436
    time_t ti[2];
4437

    
4438
    switch (offset) {
4439
    case 0x00:        /* SECONDS_REG */
4440
#if ALMDEBUG
4441
        printf("RTC SEC_REG <-- %02x\n", value);
4442
#endif
4443
        s->ti -= s->current_tm.tm_sec;
4444
        s->ti += omap_rtc_bin(value);
4445
        return;
4446

    
4447
    case 0x04:        /* MINUTES_REG */
4448
#if ALMDEBUG
4449
        printf("RTC MIN_REG <-- %02x\n", value);
4450
#endif
4451
        s->ti -= s->current_tm.tm_min * 60;
4452
        s->ti += omap_rtc_bin(value) * 60;
4453
        return;
4454

    
4455
    case 0x08:        /* HOURS_REG */
4456
#if ALMDEBUG
4457
        printf("RTC HRS_REG <-- %02x\n", value);
4458
#endif
4459
        s->ti -= s->current_tm.tm_hour * 3600;
4460
        if (s->pm_am) {
4461
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
4462
            s->ti += ((value >> 7) & 1) * 43200;
4463
        } else
4464
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
4465
        return;
4466

    
4467
    case 0x0c:        /* DAYS_REG */
4468
#if ALMDEBUG
4469
        printf("RTC DAY_REG <-- %02x\n", value);
4470
#endif
4471
        s->ti -= s->current_tm.tm_mday * 86400;
4472
        s->ti += omap_rtc_bin(value) * 86400;
4473
        return;
4474

    
4475
    case 0x10:        /* MONTHS_REG */
4476
#if ALMDEBUG
4477
        printf("RTC MTH_REG <-- %02x\n", value);
4478
#endif
4479
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
4480
        new_tm.tm_mon = omap_rtc_bin(value);
4481
        ti[0] = mktime(&s->current_tm);
4482
        ti[1] = mktime(&new_tm);
4483

    
4484
        if (ti[0] != -1 && ti[1] != -1) {
4485
            s->ti -= ti[0];
4486
            s->ti += ti[1];
4487
        } else {
4488
            /* A less accurate version */
4489
            s->ti -= s->current_tm.tm_mon * 2592000;
4490
            s->ti += omap_rtc_bin(value) * 2592000;
4491
        }
4492
        return;
4493

    
4494
    case 0x14:        /* YEARS_REG */
4495
#if ALMDEBUG
4496
        printf("RTC YRS_REG <-- %02x\n", value);
4497
#endif
4498
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
4499
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
4500
        ti[0] = mktime(&s->current_tm);
4501
        ti[1] = mktime(&new_tm);
4502

    
4503
        if (ti[0] != -1 && ti[1] != -1) {
4504
            s->ti -= ti[0];
4505
            s->ti += ti[1];
4506
        } else {
4507
            /* A less accurate version */
4508
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
4509
            s->ti += omap_rtc_bin(value) * 31536000;
4510
        }
4511
        return;
4512

    
4513
    case 0x18:        /* WEEK_REG */
4514
        return;        /* Ignored */
4515

    
4516
    case 0x20:        /* ALARM_SECONDS_REG */
4517
#if ALMDEBUG
4518
        printf("ALM SEC_REG <-- %02x\n", value);
4519
#endif
4520
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
4521
        omap_rtc_alarm_update(s);
4522
        return;
4523

    
4524
    case 0x24:        /* ALARM_MINUTES_REG */
4525
#if ALMDEBUG
4526
        printf("ALM MIN_REG <-- %02x\n", value);
4527
#endif
4528
        s->alarm_tm.tm_min = omap_rtc_bin(value);
4529
        omap_rtc_alarm_update(s);
4530
        return;
4531

    
4532
    case 0x28:        /* ALARM_HOURS_REG */
4533
#if ALMDEBUG
4534
        printf("ALM HRS_REG <-- %02x\n", value);
4535
#endif
4536
        if (s->pm_am)
4537
            s->alarm_tm.tm_hour =
4538
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
4539
                    ((value >> 7) & 1) * 12;
4540
        else
4541
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
4542
        omap_rtc_alarm_update(s);
4543
        return;
4544

    
4545
    case 0x2c:        /* ALARM_DAYS_REG */
4546
#if ALMDEBUG
4547
        printf("ALM DAY_REG <-- %02x\n", value);
4548
#endif
4549
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
4550
        omap_rtc_alarm_update(s);
4551
        return;
4552

    
4553
    case 0x30:        /* ALARM_MONTHS_REG */
4554
#if ALMDEBUG
4555
        printf("ALM MON_REG <-- %02x\n", value);
4556
#endif
4557
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
4558
        omap_rtc_alarm_update(s);
4559
        return;
4560

    
4561
    case 0x34:        /* ALARM_YEARS_REG */
4562
#if ALMDEBUG
4563
        printf("ALM YRS_REG <-- %02x\n", value);
4564
#endif
4565
        s->alarm_tm.tm_year = omap_rtc_bin(value);
4566
        omap_rtc_alarm_update(s);
4567
        return;
4568

    
4569
    case 0x40:        /* RTC_CTRL_REG */
4570
#if ALMDEBUG
4571
        printf("RTC CONTROL <-- %02x\n", value);
4572
#endif
4573
        s->pm_am = (value >> 3) & 1;
4574
        s->auto_comp = (value >> 2) & 1;
4575
        s->round = (value >> 1) & 1;
4576
        s->running = value & 1;
4577
        s->status &= 0xfd;
4578
        s->status |= s->running << 1;
4579
        return;
4580

    
4581
    case 0x44:        /* RTC_STATUS_REG */
4582
#if ALMDEBUG
4583
        printf("RTC STATUSL <-- %02x\n", value);
4584
#endif
4585
        s->status &= ~((value & 0xc0) ^ 0x80);
4586
        omap_rtc_interrupts_update(s);
4587
        return;
4588

    
4589
    case 0x48:        /* RTC_INTERRUPTS_REG */
4590
#if ALMDEBUG
4591
        printf("RTC INTRS <-- %02x\n", value);
4592
#endif
4593
        s->interrupts = value;
4594
        return;
4595

    
4596
    case 0x4c:        /* RTC_COMP_LSB_REG */
4597
#if ALMDEBUG
4598
        printf("RTC COMPLSB <-- %02x\n", value);
4599
#endif
4600
        s->comp_reg &= 0xff00;
4601
        s->comp_reg |= 0x00ff & value;
4602
        return;
4603

    
4604
    case 0x50:        /* RTC_COMP_MSB_REG */
4605
#if ALMDEBUG
4606
        printf("RTC COMPMSB <-- %02x\n", value);
4607
#endif
4608
        s->comp_reg &= 0x00ff;
4609
        s->comp_reg |= 0xff00 & (value << 8);
4610
        return;
4611

    
4612
    default:
4613
        OMAP_BAD_REG(addr);
4614
        return;
4615
    }
4616
}
4617

    
4618
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
4619
    omap_rtc_read,
4620
    omap_badwidth_read8,
4621
    omap_badwidth_read8,
4622
};
4623

    
4624
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
4625
    omap_rtc_write,
4626
    omap_badwidth_write8,
4627
    omap_badwidth_write8,
4628
};
4629

    
4630
static void omap_rtc_tick(void *opaque)
4631
{
4632
    struct omap_rtc_s *s = opaque;
4633

    
4634
    if (s->round) {
4635
        /* Round to nearest full minute.  */
4636
        if (s->current_tm.tm_sec < 30)
4637
            s->ti -= s->current_tm.tm_sec;
4638
        else
4639
            s->ti += 60 - s->current_tm.tm_sec;
4640

    
4641
        s->round = 0;
4642
    }
4643

    
4644
    localtime_r(&s->ti, &s->current_tm);
4645

    
4646
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
4647
        s->status |= 0x40;
4648
        omap_rtc_interrupts_update(s);
4649
    }
4650

    
4651
    if (s->interrupts & 0x04)
4652
        switch (s->interrupts & 3) {
4653
        case 0:
4654
            s->status |= 0x04;
4655
            qemu_irq_pulse(s->irq);
4656
            break;
4657
        case 1:
4658
            if (s->current_tm.tm_sec)
4659
                break;
4660
            s->status |= 0x08;
4661
            qemu_irq_pulse(s->irq);
4662
            break;
4663
        case 2:
4664
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
4665
                break;
4666
            s->status |= 0x10;
4667
            qemu_irq_pulse(s->irq);
4668
            break;
4669
        case 3:
4670
            if (s->current_tm.tm_sec ||
4671
                            s->current_tm.tm_min || s->current_tm.tm_hour)
4672
                break;
4673
            s->status |= 0x20;
4674
            qemu_irq_pulse(s->irq);
4675
            break;
4676
        }
4677

    
4678
    /* Move on */
4679
    if (s->running)
4680
        s->ti ++;
4681
    s->tick += 1000;
4682

    
4683
    /*
4684
     * Every full hour add a rough approximation of the compensation
4685
     * register to the 32kHz Timer (which drives the RTC) value. 
4686
     */
4687
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
4688
        s->tick += s->comp_reg * 1000 / 32768;
4689

    
4690
    qemu_mod_timer(s->clk, s->tick);
4691
}
4692

    
4693
static void omap_rtc_reset(struct omap_rtc_s *s)
4694
{
4695
    s->interrupts = 0;
4696
    s->comp_reg = 0;
4697
    s->running = 0;
4698
    s->pm_am = 0;
4699
    s->auto_comp = 0;
4700
    s->round = 0;
4701
    s->tick = qemu_get_clock(rt_clock);
4702
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
4703
    s->alarm_tm.tm_mday = 0x01;
4704
    s->status = 1 << 7;
4705
    time(&s->ti);
4706
    s->ti = mktime(s->convert(&s->ti, &s->current_tm));
4707

    
4708
    omap_rtc_alarm_update(s);
4709
    omap_rtc_tick(s);
4710
}
4711

    
4712
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
4713
                qemu_irq *irq, omap_clk clk)
4714
{
4715
    int iomemtype;
4716
    struct omap_rtc_s *s = (struct omap_rtc_s *)
4717
            qemu_mallocz(sizeof(struct omap_rtc_s));
4718

    
4719
    s->base = base;
4720
    s->irq = irq[0];
4721
    s->alarm = irq[1];
4722
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
4723
    s->convert = rtc_utc ? gmtime_r : localtime_r;
4724

    
4725
    omap_rtc_reset(s);
4726

    
4727
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
4728
                    omap_rtc_writefn, s);
4729
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4730

    
4731
    return s;
4732
}
4733

    
4734
/* Multi-channel Buffered Serial Port interfaces */
4735
struct omap_mcbsp_s {
4736
    target_phys_addr_t base;
4737
    qemu_irq txirq;
4738
    qemu_irq rxirq;
4739
    qemu_irq txdrq;
4740
    qemu_irq rxdrq;
4741

    
4742
    uint16_t spcr[2];
4743
    uint16_t rcr[2];
4744
    uint16_t xcr[2];
4745
    uint16_t srgr[2];
4746
    uint16_t mcr[2];
4747
    uint16_t pcr;
4748
    uint16_t rcer[8];
4749
    uint16_t xcer[8];
4750
    int tx_rate;
4751
    int rx_rate;
4752
    int tx_req;
4753
    int rx_req;
4754

    
4755
    struct i2s_codec_s *codec;
4756
    QEMUTimer *source_timer;
4757
    QEMUTimer *sink_timer;
4758
};
4759

    
4760
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
4761
{
4762
    int irq;
4763

    
4764
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
4765
    case 0:
4766
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
4767
        break;
4768
    case 3:
4769
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
4770
        break;
4771
    default:
4772
        irq = 0;
4773
        break;
4774
    }
4775

    
4776
    if (irq)
4777
        qemu_irq_pulse(s->rxirq);
4778

    
4779
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
4780
    case 0:
4781
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
4782
        break;
4783
    case 3:
4784
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
4785
        break;
4786
    default:
4787
        irq = 0;
4788
        break;
4789
    }
4790

    
4791
    if (irq)
4792
        qemu_irq_pulse(s->txirq);
4793
}
4794

    
4795
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
4796
{
4797
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
4798
        s->spcr[0] |= 1 << 2;                                /* RFULL */
4799
    s->spcr[0] |= 1 << 1;                                /* RRDY */
4800
    qemu_irq_raise(s->rxdrq);
4801
    omap_mcbsp_intr_update(s);
4802
}
4803

    
4804
static void omap_mcbsp_source_tick(void *opaque)
4805
{
4806
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4807
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
4808

    
4809
    if (!s->rx_rate)
4810
        return;
4811
    if (s->rx_req)
4812
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
4813

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

    
4816
    omap_mcbsp_rx_newdata(s);
4817
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
4818
}
4819

    
4820
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
4821
{
4822
    if (!s->codec || !s->codec->rts)
4823
        omap_mcbsp_source_tick(s);
4824
    else if (s->codec->in.len) {
4825
        s->rx_req = s->codec->in.len;
4826
        omap_mcbsp_rx_newdata(s);
4827
    }
4828
}
4829

    
4830
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
4831
{
4832
    qemu_del_timer(s->source_timer);
4833
}
4834

    
4835
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
4836
{
4837
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
4838
    qemu_irq_lower(s->rxdrq);
4839
    omap_mcbsp_intr_update(s);
4840
}
4841

    
4842
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
4843
{
4844
    s->spcr[1] |= 1 << 1;                                /* XRDY */
4845
    qemu_irq_raise(s->txdrq);
4846
    omap_mcbsp_intr_update(s);
4847
}
4848

    
4849
static void omap_mcbsp_sink_tick(void *opaque)
4850
{
4851
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4852
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
4853

    
4854
    if (!s->tx_rate)
4855
        return;
4856
    if (s->tx_req)
4857
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
4858

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

    
4861
    omap_mcbsp_tx_newdata(s);
4862
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
4863
}
4864

    
4865
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
4866
{
4867
    if (!s->codec || !s->codec->cts)
4868
        omap_mcbsp_sink_tick(s);
4869
    else if (s->codec->out.size) {
4870
        s->tx_req = s->codec->out.size;
4871
        omap_mcbsp_tx_newdata(s);
4872
    }
4873
}
4874

    
4875
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
4876
{
4877
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
4878
    qemu_irq_lower(s->txdrq);
4879
    omap_mcbsp_intr_update(s);
4880
    if (s->codec && s->codec->cts)
4881
        s->codec->tx_swallow(s->codec->opaque);
4882
}
4883

    
4884
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
4885
{
4886
    s->tx_req = 0;
4887
    omap_mcbsp_tx_done(s);
4888
    qemu_del_timer(s->sink_timer);
4889
}
4890

    
4891
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
4892
{
4893
    int prev_rx_rate, prev_tx_rate;
4894
    int rx_rate = 0, tx_rate = 0;
4895
    int cpu_rate = 1500000;        /* XXX */
4896

    
4897
    /* TODO: check CLKSTP bit */
4898
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
4899
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
4900
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
4901
                            (s->pcr & (1 << 8))) {        /* CLKRM */
4902
                if (~s->pcr & (1 << 7))                        /* SCLKME */
4903
                    rx_rate = cpu_rate /
4904
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
4905
            } else
4906
                if (s->codec)
4907
                    rx_rate = s->codec->rx_rate;
4908
        }
4909

    
4910
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
4911
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
4912
                            (s->pcr & (1 << 9))) {        /* CLKXM */
4913
                if (~s->pcr & (1 << 7))                        /* SCLKME */
4914
                    tx_rate = cpu_rate /
4915
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
4916
            } else
4917
                if (s->codec)
4918
                    tx_rate = s->codec->tx_rate;
4919
        }
4920
    }
4921
    prev_tx_rate = s->tx_rate;
4922
    prev_rx_rate = s->rx_rate;
4923
    s->tx_rate = tx_rate;
4924
    s->rx_rate = rx_rate;
4925

    
4926
    if (s->codec)
4927
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
4928

    
4929
    if (!prev_tx_rate && tx_rate)
4930
        omap_mcbsp_tx_start(s);
4931
    else if (s->tx_rate && !tx_rate)
4932
        omap_mcbsp_tx_stop(s);
4933

    
4934
    if (!prev_rx_rate && rx_rate)
4935
        omap_mcbsp_rx_start(s);
4936
    else if (prev_tx_rate && !tx_rate)
4937
        omap_mcbsp_rx_stop(s);
4938
}
4939

    
4940
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
4941
{
4942
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4943
    int offset = addr & OMAP_MPUI_REG_MASK;
4944
    uint16_t ret;
4945

    
4946
    switch (offset) {
4947
    case 0x00:        /* DRR2 */
4948
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
4949
            return 0x0000;
4950
        /* Fall through.  */
4951
    case 0x02:        /* DRR1 */
4952
        if (s->rx_req < 2) {
4953
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
4954
            omap_mcbsp_rx_done(s);
4955
        } else {
4956
            s->tx_req -= 2;
4957
            if (s->codec && s->codec->in.len >= 2) {
4958
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
4959
                ret |= s->codec->in.fifo[s->codec->in.start ++];
4960
                s->codec->in.len -= 2;
4961
            } else
4962
                ret = 0x0000;
4963
            if (!s->tx_req)
4964
                omap_mcbsp_rx_done(s);
4965
            return ret;
4966
        }
4967
        return 0x0000;
4968

    
4969
    case 0x04:        /* DXR2 */
4970
    case 0x06:        /* DXR1 */
4971
        return 0x0000;
4972

    
4973
    case 0x08:        /* SPCR2 */
4974
        return s->spcr[1];
4975
    case 0x0a:        /* SPCR1 */
4976
        return s->spcr[0];
4977
    case 0x0c:        /* RCR2 */
4978
        return s->rcr[1];
4979
    case 0x0e:        /* RCR1 */
4980
        return s->rcr[0];
4981
    case 0x10:        /* XCR2 */
4982
        return s->xcr[1];
4983
    case 0x12:        /* XCR1 */
4984
        return s->xcr[0];
4985
    case 0x14:        /* SRGR2 */
4986
        return s->srgr[1];
4987
    case 0x16:        /* SRGR1 */
4988
        return s->srgr[0];
4989
    case 0x18:        /* MCR2 */
4990
        return s->mcr[1];
4991
    case 0x1a:        /* MCR1 */
4992
        return s->mcr[0];
4993
    case 0x1c:        /* RCERA */
4994
        return s->rcer[0];
4995
    case 0x1e:        /* RCERB */
4996
        return s->rcer[1];
4997
    case 0x20:        /* XCERA */
4998
        return s->xcer[0];
4999
    case 0x22:        /* XCERB */
5000
        return s->xcer[1];
5001
    case 0x24:        /* PCR0 */
5002
        return s->pcr;
5003
    case 0x26:        /* RCERC */
5004
        return s->rcer[2];
5005
    case 0x28:        /* RCERD */
5006
        return s->rcer[3];
5007
    case 0x2a:        /* XCERC */
5008
        return s->xcer[2];
5009
    case 0x2c:        /* XCERD */
5010
        return s->xcer[3];
5011
    case 0x2e:        /* RCERE */
5012
        return s->rcer[4];
5013
    case 0x30:        /* RCERF */
5014
        return s->rcer[5];
5015
    case 0x32:        /* XCERE */
5016
        return s->xcer[4];
5017
    case 0x34:        /* XCERF */
5018
        return s->xcer[5];
5019
    case 0x36:        /* RCERG */
5020
        return s->rcer[6];
5021
    case 0x38:        /* RCERH */
5022
        return s->rcer[7];
5023
    case 0x3a:        /* XCERG */
5024
        return s->xcer[6];
5025
    case 0x3c:        /* XCERH */
5026
        return s->xcer[7];
5027
    }
5028

    
5029
    OMAP_BAD_REG(addr);
5030
    return 0;
5031
}
5032

    
5033
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
5034
                uint32_t value)
5035
{
5036
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
5037
    int offset = addr & OMAP_MPUI_REG_MASK;
5038

    
5039
    switch (offset) {
5040
    case 0x00:        /* DRR2 */
5041
    case 0x02:        /* DRR1 */
5042
        OMAP_RO_REG(addr);
5043
        return;
5044

    
5045
    case 0x04:        /* DXR2 */
5046
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
5047
            return;
5048
        /* Fall through.  */
5049
    case 0x06:        /* DXR1 */
5050
        if (s->tx_req > 1) {
5051
            s->tx_req -= 2;
5052
            if (s->codec && s->codec->cts) {
5053
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
5054
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
5055
            }
5056
            if (s->tx_req < 2)
5057
                omap_mcbsp_tx_done(s);
5058
        } else
5059
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
5060
        return;
5061

    
5062
    case 0x08:        /* SPCR2 */
5063
        s->spcr[1] &= 0x0002;
5064
        s->spcr[1] |= 0x03f9 & value;
5065
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
5066
        if (~value & 1)                                        /* XRST */
5067
            s->spcr[1] &= ~6;
5068
        omap_mcbsp_req_update(s);
5069
        return;
5070
    case 0x0a:        /* SPCR1 */
5071
        s->spcr[0] &= 0x0006;
5072
        s->spcr[0] |= 0xf8f9 & value;
5073
        if (value & (1 << 15))                                /* DLB */
5074
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
5075
        if (~value & 1) {                                /* RRST */
5076
            s->spcr[0] &= ~6;
5077
            s->rx_req = 0;
5078
            omap_mcbsp_rx_done(s);
5079
        }
5080
        omap_mcbsp_req_update(s);
5081
        return;
5082

    
5083
    case 0x0c:        /* RCR2 */
5084
        s->rcr[1] = value & 0xffff;
5085
        return;
5086
    case 0x0e:        /* RCR1 */
5087
        s->rcr[0] = value & 0x7fe0;
5088
        return;
5089
    case 0x10:        /* XCR2 */
5090
        s->xcr[1] = value & 0xffff;
5091
        return;
5092
    case 0x12:        /* XCR1 */
5093
        s->xcr[0] = value & 0x7fe0;
5094
        return;
5095
    case 0x14:        /* SRGR2 */
5096
        s->srgr[1] = value & 0xffff;
5097
        omap_mcbsp_req_update(s);
5098
        return;
5099
    case 0x16:        /* SRGR1 */
5100
        s->srgr[0] = value & 0xffff;
5101
        omap_mcbsp_req_update(s);
5102
        return;
5103
    case 0x18:        /* MCR2 */
5104
        s->mcr[1] = value & 0x03e3;
5105
        if (value & 3)                                        /* XMCM */
5106
            printf("%s: Tx channel selection mode enable attempt\n",
5107
                            __FUNCTION__);
5108
        return;
5109
    case 0x1a:        /* MCR1 */
5110
        s->mcr[0] = value & 0x03e1;
5111
        if (value & 1)                                        /* RMCM */
5112
            printf("%s: Rx channel selection mode enable attempt\n",
5113
                            __FUNCTION__);
5114
        return;
5115
    case 0x1c:        /* RCERA */
5116
        s->rcer[0] = value & 0xffff;
5117
        return;
5118
    case 0x1e:        /* RCERB */
5119
        s->rcer[1] = value & 0xffff;
5120
        return;
5121
    case 0x20:        /* XCERA */
5122
        s->xcer[0] = value & 0xffff;
5123
        return;
5124
    case 0x22:        /* XCERB */
5125
        s->xcer[1] = value & 0xffff;
5126
        return;
5127
    case 0x24:        /* PCR0 */
5128
        s->pcr = value & 0x7faf;
5129
        return;
5130
    case 0x26:        /* RCERC */
5131
        s->rcer[2] = value & 0xffff;
5132
        return;
5133
    case 0x28:        /* RCERD */
5134
        s->rcer[3] = value & 0xffff;
5135
        return;
5136
    case 0x2a:        /* XCERC */
5137
        s->xcer[2] = value & 0xffff;
5138
        return;
5139
    case 0x2c:        /* XCERD */
5140
        s->xcer[3] = value & 0xffff;
5141
        return;
5142
    case 0x2e:        /* RCERE */
5143
        s->rcer[4] = value & 0xffff;
5144
        return;
5145
    case 0x30:        /* RCERF */
5146
        s->rcer[5] = value & 0xffff;
5147
        return;
5148
    case 0x32:        /* XCERE */
5149
        s->xcer[4] = value & 0xffff;
5150
        return;
5151
    case 0x34:        /* XCERF */
5152
        s->xcer[5] = value & 0xffff;
5153
        return;
5154
    case 0x36:        /* RCERG */
5155
        s->rcer[6] = value & 0xffff;
5156
        return;
5157
    case 0x38:        /* RCERH */
5158
        s->rcer[7] = value & 0xffff;
5159
        return;
5160
    case 0x3a:        /* XCERG */
5161
        s->xcer[6] = value & 0xffff;
5162
        return;
5163
    case 0x3c:        /* XCERH */
5164
        s->xcer[7] = value & 0xffff;
5165
        return;
5166
    }
5167

    
5168
    OMAP_BAD_REG(addr);
5169
}
5170

    
5171
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
5172
                uint32_t value)
5173
{
5174
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
5175
    int offset = addr & OMAP_MPUI_REG_MASK;
5176

    
5177
    if (offset == 0x04) {                                /* DXR */
5178
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
5179
            return;
5180
        if (s->tx_req > 3) {
5181
            s->tx_req -= 4;
5182
            if (s->codec && s->codec->cts) {
5183
                s->codec->out.fifo[s->codec->out.len ++] =
5184
                        (value >> 24) & 0xff;
5185
                s->codec->out.fifo[s->codec->out.len ++] =
5186
                        (value >> 16) & 0xff;
5187
                s->codec->out.fifo[s->codec->out.len ++] =
5188
                        (value >> 8) & 0xff;
5189
                s->codec->out.fifo[s->codec->out.len ++] =
5190
                        (value >> 0) & 0xff;
5191
            }
5192
            if (s->tx_req < 4)
5193
                omap_mcbsp_tx_done(s);
5194
        } else
5195
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
5196
        return;
5197
    }
5198

    
5199
    omap_badwidth_write16(opaque, addr, value);
5200
}
5201

    
5202
static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
5203
    omap_badwidth_read16,
5204
    omap_mcbsp_read,
5205
    omap_badwidth_read16,
5206
};
5207

    
5208
static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
5209
    omap_badwidth_write16,
5210
    omap_mcbsp_writeh,
5211
    omap_mcbsp_writew,
5212
};
5213

    
5214
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
5215
{
5216
    memset(&s->spcr, 0, sizeof(s->spcr));
5217
    memset(&s->rcr, 0, sizeof(s->rcr));
5218
    memset(&s->xcr, 0, sizeof(s->xcr));
5219
    s->srgr[0] = 0x0001;
5220
    s->srgr[1] = 0x2000;
5221
    memset(&s->mcr, 0, sizeof(s->mcr));
5222
    memset(&s->pcr, 0, sizeof(s->pcr));
5223
    memset(&s->rcer, 0, sizeof(s->rcer));
5224
    memset(&s->xcer, 0, sizeof(s->xcer));
5225
    s->tx_req = 0;
5226
    s->rx_req = 0;
5227
    s->tx_rate = 0;
5228
    s->rx_rate = 0;
5229
    qemu_del_timer(s->source_timer);
5230
    qemu_del_timer(s->sink_timer);
5231
}
5232

    
5233
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
5234
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
5235
{
5236
    int iomemtype;
5237
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
5238
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
5239

    
5240
    s->base = base;
5241
    s->txirq = irq[0];
5242
    s->rxirq = irq[1];
5243
    s->txdrq = dma[0];
5244
    s->rxdrq = dma[1];
5245
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
5246
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
5247
    omap_mcbsp_reset(s);
5248

    
5249
    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
5250
                    omap_mcbsp_writefn, s);
5251
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
5252

    
5253
    return s;
5254
}
5255

    
5256
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
5257
{
5258
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
5259

    
5260
    if (s->rx_rate) {
5261
        s->rx_req = s->codec->in.len;
5262
        omap_mcbsp_rx_newdata(s);
5263
    }
5264
}
5265

    
5266
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
5267
{
5268
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
5269

    
5270
    if (s->tx_rate) {
5271
        s->tx_req = s->codec->out.size;
5272
        omap_mcbsp_tx_newdata(s);
5273
    }
5274
}
5275

    
5276
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
5277
{
5278
    s->codec = slave;
5279
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
5280
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
5281
}
5282

    
5283
/* LED Pulse Generators */
5284
struct omap_lpg_s {
5285
    target_phys_addr_t base;
5286
    QEMUTimer *tm;
5287

    
5288
    uint8_t control;
5289
    uint8_t power;
5290
    int64_t on;
5291
    int64_t period;
5292
    int clk;
5293
    int cycle;
5294
};
5295

    
5296
static void omap_lpg_tick(void *opaque)
5297
{
5298
    struct omap_lpg_s *s = opaque;
5299

    
5300
    if (s->cycle)
5301
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
5302
    else
5303
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
5304

    
5305
    s->cycle = !s->cycle;
5306
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
5307
}
5308

    
5309
static void omap_lpg_update(struct omap_lpg_s *s)
5310
{
5311
    int64_t on, period = 1, ticks = 1000;
5312
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
5313

    
5314
    if (~s->control & (1 << 6))                                        /* LPGRES */
5315
        on = 0;
5316
    else if (s->control & (1 << 7))                                /* PERM_ON */
5317
        on = period;
5318
    else {
5319
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
5320
                        256 / 32);
5321
        on = (s->clk && s->power) ? muldiv64(ticks,
5322
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
5323
    }
5324

    
5325
    qemu_del_timer(s->tm);
5326
    if (on == period && s->on < s->period)
5327
        printf("%s: LED is on\n", __FUNCTION__);
5328
    else if (on == 0 && s->on)
5329
        printf("%s: LED is off\n", __FUNCTION__);
5330
    else if (on && (on != s->on || period != s->period)) {
5331
        s->cycle = 0;
5332
        s->on = on;
5333
        s->period = period;
5334
        omap_lpg_tick(s);
5335
        return;
5336
    }
5337

    
5338
    s->on = on;
5339
    s->period = period;
5340
}
5341

    
5342
static void omap_lpg_reset(struct omap_lpg_s *s)
5343
{
5344
    s->control = 0x00;
5345
    s->power = 0x00;
5346
    s->clk = 1;
5347
    omap_lpg_update(s);
5348
}
5349

    
5350
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
5351
{
5352
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
5353
    int offset = addr & OMAP_MPUI_REG_MASK;
5354

    
5355
    switch (offset) {
5356
    case 0x00:        /* LCR */
5357
        return s->control;
5358

    
5359
    case 0x04:        /* PMR */
5360
        return s->power;
5361
    }
5362

    
5363
    OMAP_BAD_REG(addr);
5364
    return 0;
5365
}
5366

    
5367
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
5368
                uint32_t value)
5369
{
5370
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
5371
    int offset = addr & OMAP_MPUI_REG_MASK;
5372

    
5373
    switch (offset) {
5374
    case 0x00:        /* LCR */
5375
        if (~value & (1 << 6))                                        /* LPGRES */
5376
            omap_lpg_reset(s);
5377
        s->control = value & 0xff;
5378
        omap_lpg_update(s);
5379
        return;
5380

    
5381
    case 0x04:        /* PMR */
5382
        s->power = value & 0x01;
5383
        omap_lpg_update(s);
5384
        return;
5385

    
5386
    default:
5387
        OMAP_BAD_REG(addr);
5388
        return;
5389
    }
5390
}
5391

    
5392
static CPUReadMemoryFunc *omap_lpg_readfn[] = {
5393
    omap_lpg_read,
5394
    omap_badwidth_read8,
5395
    omap_badwidth_read8,
5396
};
5397

    
5398
static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
5399
    omap_lpg_write,
5400
    omap_badwidth_write8,
5401
    omap_badwidth_write8,
5402
};
5403

    
5404
static void omap_lpg_clk_update(void *opaque, int line, int on)
5405
{
5406
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
5407

    
5408
    s->clk = on;
5409
    omap_lpg_update(s);
5410
}
5411

    
5412
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
5413
{
5414
    int iomemtype;
5415
    struct omap_lpg_s *s = (struct omap_lpg_s *)
5416
            qemu_mallocz(sizeof(struct omap_lpg_s));
5417

    
5418
    s->base = base;
5419
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
5420

    
5421
    omap_lpg_reset(s);
5422

    
5423
    iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
5424
                    omap_lpg_writefn, s);
5425
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
5426

    
5427
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
5428

    
5429
    return s;
5430
}
5431

    
5432
/* MPUI Peripheral Bridge configuration */
5433
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
5434
{
5435
    if (addr == OMAP_MPUI_BASE)        /* CMR */
5436
        return 0xfe4d;
5437

    
5438
    OMAP_BAD_REG(addr);
5439
    return 0;
5440
}
5441

    
5442
static CPUReadMemoryFunc *omap_mpui_io_readfn[] = {
5443
    omap_badwidth_read16,
5444
    omap_mpui_io_read,
5445
    omap_badwidth_read16,
5446
};
5447

    
5448
static CPUWriteMemoryFunc *omap_mpui_io_writefn[] = {
5449
    omap_badwidth_write16,
5450
    omap_badwidth_write16,
5451
    omap_badwidth_write16,
5452
};
5453

    
5454
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
5455
{
5456
    int iomemtype = cpu_register_io_memory(0, omap_mpui_io_readfn,
5457
                    omap_mpui_io_writefn, mpu);
5458
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
5459
}
5460

    
5461
/* General chip reset */
5462
static void omap_mpu_reset(void *opaque)
5463
{
5464
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
5465

    
5466
    omap_inth_reset(mpu->ih[0]);
5467
    omap_inth_reset(mpu->ih[1]);
5468
    omap_dma_reset(mpu->dma);
5469
    omap_mpu_timer_reset(mpu->timer[0]);
5470
    omap_mpu_timer_reset(mpu->timer[1]);
5471
    omap_mpu_timer_reset(mpu->timer[2]);
5472
    omap_wd_timer_reset(mpu->wdt);
5473
    omap_os_timer_reset(mpu->os_timer);
5474
    omap_lcdc_reset(mpu->lcd);
5475
    omap_ulpd_pm_reset(mpu);
5476
    omap_pin_cfg_reset(mpu);
5477
    omap_mpui_reset(mpu);
5478
    omap_tipb_bridge_reset(mpu->private_tipb);
5479
    omap_tipb_bridge_reset(mpu->public_tipb);
5480
    omap_dpll_reset(&mpu->dpll[0]);
5481
    omap_dpll_reset(&mpu->dpll[1]);
5482
    omap_dpll_reset(&mpu->dpll[2]);
5483
    omap_uart_reset(mpu->uart[0]);
5484
    omap_uart_reset(mpu->uart[1]);
5485
    omap_uart_reset(mpu->uart[2]);
5486
    omap_mmc_reset(mpu->mmc);
5487
    omap_mpuio_reset(mpu->mpuio);
5488
    omap_gpio_reset(mpu->gpio);
5489
    omap_uwire_reset(mpu->microwire);
5490
    omap_pwl_reset(mpu);
5491
    omap_pwt_reset(mpu);
5492
    omap_i2c_reset(mpu->i2c);
5493
    omap_rtc_reset(mpu->rtc);
5494
    omap_mcbsp_reset(mpu->mcbsp1);
5495
    omap_mcbsp_reset(mpu->mcbsp2);
5496
    omap_mcbsp_reset(mpu->mcbsp3);
5497
    omap_lpg_reset(mpu->led[0]);
5498
    omap_lpg_reset(mpu->led[1]);
5499
    omap_clkm_reset(mpu);
5500
    cpu_reset(mpu->env);
5501
}
5502

    
5503
static const struct omap_map_s {
5504
    target_phys_addr_t phys_dsp;
5505
    target_phys_addr_t phys_mpu;
5506
    uint32_t size;
5507
    const char *name;
5508
} omap15xx_dsp_mm[] = {
5509
    /* Strobe 0 */
5510
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
5511
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
5512
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
5513
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
5514
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
5515
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
5516
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
5517
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
5518
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
5519
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
5520
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
5521
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
5522
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
5523
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
5524
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
5525
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
5526
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
5527
    /* Strobe 1 */
5528
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
5529

    
5530
    { 0 }
5531
};
5532

    
5533
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
5534
{
5535
    int io;
5536

    
5537
    for (; map->phys_dsp; map ++) {
5538
        io = cpu_get_physical_page_desc(map->phys_mpu);
5539

    
5540
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
5541
    }
5542
}
5543

    
5544
static void omap_mpu_wakeup(void *opaque, int irq, int req)
5545
{
5546
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
5547

    
5548
    if (mpu->env->halted)
5549
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
5550
}
5551

    
5552
struct dma_irq_map {
5553
    int ih;
5554
    int intr;
5555
};
5556

    
5557
static const struct dma_irq_map omap_dma_irq_map[] = {
5558
    { 0, OMAP_INT_DMA_CH0_6 },
5559
    { 0, OMAP_INT_DMA_CH1_7 },
5560
    { 0, OMAP_INT_DMA_CH2_8 },
5561
    { 0, OMAP_INT_DMA_CH3 },
5562
    { 0, OMAP_INT_DMA_CH4 },
5563
    { 0, OMAP_INT_DMA_CH5 },
5564
    { 1, OMAP_INT_1610_DMA_CH6 },
5565
    { 1, OMAP_INT_1610_DMA_CH7 },
5566
    { 1, OMAP_INT_1610_DMA_CH8 },
5567
    { 1, OMAP_INT_1610_DMA_CH9 },
5568
    { 1, OMAP_INT_1610_DMA_CH10 },
5569
    { 1, OMAP_INT_1610_DMA_CH11 },
5570
    { 1, OMAP_INT_1610_DMA_CH12 },
5571
    { 1, OMAP_INT_1610_DMA_CH13 },
5572
    { 1, OMAP_INT_1610_DMA_CH14 },
5573
    { 1, OMAP_INT_1610_DMA_CH15 }
5574
};
5575

    
5576
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
5577
                DisplayState *ds, const char *core)
5578
{
5579
    int i;
5580
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
5581
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
5582
    ram_addr_t imif_base, emiff_base;
5583
    qemu_irq *cpu_irq;
5584
    qemu_irq dma_irqs[6];
5585
    int sdindex;
5586

    
5587
    if (!core)
5588
        core = "ti925t";
5589

    
5590
    /* Core */
5591
    s->mpu_model = omap310;
5592
    s->env = cpu_init(core);
5593
    if (!s->env) {
5594
        fprintf(stderr, "Unable to find CPU definition\n");
5595
        exit(1);
5596
    }
5597
    s->sdram_size = sdram_size;
5598
    s->sram_size = OMAP15XX_SRAM_SIZE;
5599

    
5600
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
5601

    
5602
    /* Clocks */
5603
    omap_clk_init(s);
5604

    
5605
    /* Memory-mapped stuff */
5606
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
5607
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
5608
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
5609
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
5610

    
5611
    omap_clkm_init(0xfffece00, 0xe1008000, s);
5612

    
5613
    cpu_irq = arm_pic_init_cpu(s->env);
5614
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1,
5615
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
5616
                    omap_findclk(s, "arminth_ck"));
5617
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1,
5618
                    s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
5619
                    omap_findclk(s, "arminth_ck"));
5620
    s->irq[0] = s->ih[0]->pins;
5621
    s->irq[1] = s->ih[1]->pins;
5622

    
5623
    for (i = 0; i < 6; i ++)
5624
        dma_irqs[i] = s->irq[omap_dma_irq_map[i].ih][omap_dma_irq_map[i].intr];
5625
    s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
5626
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
5627

    
5628
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
5629
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
5630
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
5631
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
5632
    s->port[local    ].addr_valid = omap_validate_local_addr;
5633
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
5634

    
5635
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
5636
                    s->irq[0][OMAP_INT_TIMER1],
5637
                    omap_findclk(s, "mputim_ck"));
5638
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
5639
                    s->irq[0][OMAP_INT_TIMER2],
5640
                    omap_findclk(s, "mputim_ck"));
5641
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
5642
                    s->irq[0][OMAP_INT_TIMER3],
5643
                    omap_findclk(s, "mputim_ck"));
5644

    
5645
    s->wdt = omap_wd_timer_init(0xfffec800,
5646
                    s->irq[0][OMAP_INT_WD_TIMER],
5647
                    omap_findclk(s, "armwdt_ck"));
5648

    
5649
    s->os_timer = omap_os_timer_init(0xfffb9000,
5650
                    s->irq[1][OMAP_INT_OS_TIMER],
5651
                    omap_findclk(s, "clk32-kHz"));
5652

    
5653
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
5654
                    &s->dma->lcd_ch, ds, imif_base, emiff_base,
5655
                    omap_findclk(s, "lcd_ck"));
5656

    
5657
    omap_ulpd_pm_init(0xfffe0800, s);
5658
    omap_pin_cfg_init(0xfffe1000, s);
5659
    omap_id_init(s);
5660

    
5661
    omap_mpui_init(0xfffec900, s);
5662

    
5663
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
5664
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
5665
                    omap_findclk(s, "tipb_ck"));
5666
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
5667
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
5668
                    omap_findclk(s, "tipb_ck"));
5669

    
5670
    omap_tcmi_init(0xfffecc00, s);
5671

    
5672
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
5673
                    omap_findclk(s, "uart1_ck"),
5674
                    serial_hds[0]);
5675
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
5676
                    omap_findclk(s, "uart2_ck"),
5677
                    serial_hds[0] ? serial_hds[1] : 0);
5678
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
5679
                    omap_findclk(s, "uart3_ck"),
5680
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
5681

    
5682
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
5683
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
5684
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
5685

    
5686
    sdindex = drive_get_index(IF_SD, 0, 0);
5687
    if (sdindex == -1) {
5688
        fprintf(stderr, "qemu: missing SecureDigital device\n");
5689
        exit(1);
5690
    }
5691
    s->mmc = omap_mmc_init(0xfffb7800, drives_table[sdindex].bdrv,
5692
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
5693
                    omap_findclk(s, "mmc_ck"));
5694

    
5695
    s->mpuio = omap_mpuio_init(0xfffb5000,
5696
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
5697
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
5698

    
5699
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
5700
                    omap_findclk(s, "arm_gpio_ck"));
5701

    
5702
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
5703
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
5704

    
5705
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
5706
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
5707

    
5708
    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
5709
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
5710

    
5711
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
5712
                    omap_findclk(s, "clk32-kHz"));
5713

    
5714
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
5715
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
5716
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
5717
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
5718
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
5719
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
5720

    
5721
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
5722
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
5723

    
5724
    /* Register mappings not currenlty implemented:
5725
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
5726
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
5727
     * USB W2FC                fffb4000 - fffb47ff
5728
     * Camera Interface        fffb6800 - fffb6fff
5729
     * USB Host                fffba000 - fffba7ff
5730
     * FAC                fffba800 - fffbafff
5731
     * HDQ/1-Wire        fffbc000 - fffbc7ff
5732
     * TIPB switches        fffbc800 - fffbcfff
5733
     * Mailbox                fffcf000 - fffcf7ff
5734
     * Local bus IF        fffec100 - fffec1ff
5735
     * Local bus MMU        fffec200 - fffec2ff
5736
     * DSP MMU                fffed200 - fffed2ff
5737
     */
5738

    
5739
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
5740
    omap_setup_mpui_io(s);
5741

    
5742
    qemu_register_reset(omap_mpu_reset, s);
5743

    
5744
    return s;
5745
}