Statistics
| Branch: | Revision:

root / hw / omap1.c @ 2ac71179

History | View | Annotate | Download (131.7 kB)

1
/*
2
 * TI OMAP processors emulation.
3
 *
4
 * Copyright (C) 2006-2008 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 or
9
 * (at your option) version 3 of the License.
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 along
17
 * with this program; if not, write to the Free Software Foundation, Inc.,
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
 */
20
#include "hw.h"
21
#include "arm-misc.h"
22
#include "omap.h"
23
#include "sysemu.h"
24
#include "qemu-timer.h"
25
#include "qemu-char.h"
26
#include "soc_dma.h"
27
/* We use pc-style serial ports.  */
28
#include "pc.h"
29

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

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

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

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

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

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

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

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

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

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

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

    
83
/* Interrupt Handlers */
84
struct omap_intr_handler_bank_s {
85
    uint32_t irqs;
86
    uint32_t inputs;
87
    uint32_t mask;
88
    uint32_t fiq;
89
    uint32_t sens_edge;
90
    uint32_t swi;
91
    unsigned char priority[32];
92
};
93

    
94
struct omap_intr_handler_s {
95
    qemu_irq *pins;
96
    qemu_irq parent_intr[2];
97
    unsigned char nbanks;
98
    int level_only;
99

    
100
    /* state */
101
    uint32_t new_agr[2];
102
    int sir_intr[2];
103
    int autoidle;
104
    uint32_t mask;
105
    struct omap_intr_handler_bank_s bank[];
106
};
107

    
108
static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
109
{
110
    int i, j, sir_intr, p_intr, p, f;
111
    uint32_t level;
112
    sir_intr = 0;
113
    p_intr = 255;
114

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

    
135
static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
136
{
137
    int i;
138
    uint32_t has_intr = 0;
139

    
140
    for (i = 0; i < s->nbanks; ++i)
141
        has_intr |= s->bank[i].irqs & ~s->bank[i].mask &
142
                (is_fiq ? s->bank[i].fiq : ~s->bank[i].fiq);
143

    
144
    if (s->new_agr[is_fiq] & has_intr & s->mask) {
145
        s->new_agr[is_fiq] = 0;
146
        omap_inth_sir_update(s, is_fiq);
147
        qemu_set_irq(s->parent_intr[is_fiq], 1);
148
    }
149
}
150

    
151
#define INT_FALLING_EDGE        0
152
#define INT_LOW_LEVEL                1
153

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

    
159
    struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
160
    int n = irq & 31;
161

    
162
    if (req) {
163
        rise = ~bank->irqs & (1 << n);
164
        if (~bank->sens_edge & (1 << n))
165
            rise &= ~bank->inputs;
166

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

    
180
/* Simplified version with no edge detection */
181
static void omap_set_intr_noedge(void *opaque, int irq, int req)
182
{
183
    struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
184
    uint32_t rise;
185

    
186
    struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
187
    int n = irq & 31;
188

    
189
    if (req) {
190
        rise = ~bank->inputs & (1 << n);
191
        if (rise) {
192
            bank->irqs |= bank->inputs |= rise;
193
            omap_inth_update(ih, 0);
194
            omap_inth_update(ih, 1);
195
        }
196
    } else
197
        bank->irqs = (bank->inputs &= ~(1 << n)) | bank->swi;
198
}
199

    
200
static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
201
{
202
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
203
    int i, offset = addr;
204
    int bank_no = offset >> 8;
205
    int line_no;
206
    struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
207
    offset &= 0xff;
208

    
209
    switch (offset) {
210
    case 0x00:        /* ITR */
211
        return bank->irqs;
212

    
213
    case 0x04:        /* MIR */
214
        return bank->mask;
215

    
216
    case 0x10:        /* SIR_IRQ_CODE */
217
    case 0x14:  /* SIR_FIQ_CODE */
218
        if (bank_no != 0)
219
            break;
220
        line_no = s->sir_intr[(offset - 0x10) >> 2];
221
        bank = &s->bank[line_no >> 5];
222
        i = line_no & 31;
223
        if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
224
            bank->irqs &= ~(1 << i);
225
        return line_no;
226

    
227
    case 0x18:        /* CONTROL_REG */
228
        if (bank_no != 0)
229
            break;
230
        return 0;
231

    
232
    case 0x1c:        /* ILR0 */
233
    case 0x20:        /* ILR1 */
234
    case 0x24:        /* ILR2 */
235
    case 0x28:        /* ILR3 */
236
    case 0x2c:        /* ILR4 */
237
    case 0x30:        /* ILR5 */
238
    case 0x34:        /* ILR6 */
239
    case 0x38:        /* ILR7 */
240
    case 0x3c:        /* ILR8 */
241
    case 0x40:        /* ILR9 */
242
    case 0x44:        /* ILR10 */
243
    case 0x48:        /* ILR11 */
244
    case 0x4c:        /* ILR12 */
245
    case 0x50:        /* ILR13 */
246
    case 0x54:        /* ILR14 */
247
    case 0x58:        /* ILR15 */
248
    case 0x5c:        /* ILR16 */
249
    case 0x60:        /* ILR17 */
250
    case 0x64:        /* ILR18 */
251
    case 0x68:        /* ILR19 */
252
    case 0x6c:        /* ILR20 */
253
    case 0x70:        /* ILR21 */
254
    case 0x74:        /* ILR22 */
255
    case 0x78:        /* ILR23 */
256
    case 0x7c:        /* ILR24 */
257
    case 0x80:        /* ILR25 */
258
    case 0x84:        /* ILR26 */
259
    case 0x88:        /* ILR27 */
260
    case 0x8c:        /* ILR28 */
261
    case 0x90:        /* ILR29 */
262
    case 0x94:        /* ILR30 */
263
    case 0x98:        /* ILR31 */
264
        i = (offset - 0x1c) >> 2;
265
        return (bank->priority[i] << 2) |
266
                (((bank->sens_edge >> i) & 1) << 1) |
267
                ((bank->fiq >> i) & 1);
268

    
269
    case 0x9c:        /* ISR */
270
        return 0x00000000;
271

    
272
    }
273
    OMAP_BAD_REG(addr);
274
    return 0;
275
}
276

    
277
static void omap_inth_write(void *opaque, target_phys_addr_t addr,
278
                uint32_t value)
279
{
280
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
281
    int i, offset = addr;
282
    int bank_no = offset >> 8;
283
    struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
284
    offset &= 0xff;
285

    
286
    switch (offset) {
287
    case 0x00:        /* ITR */
288
        /* Important: ignore the clearing if the IRQ is level-triggered and
289
           the input bit is 1 */
290
        bank->irqs &= value | (bank->inputs & bank->sens_edge);
291
        return;
292

    
293
    case 0x04:        /* MIR */
294
        bank->mask = value;
295
        omap_inth_update(s, 0);
296
        omap_inth_update(s, 1);
297
        return;
298

    
299
    case 0x10:        /* SIR_IRQ_CODE */
300
    case 0x14:        /* SIR_FIQ_CODE */
301
        OMAP_RO_REG(addr);
302
        break;
303

    
304
    case 0x18:        /* CONTROL_REG */
305
        if (bank_no != 0)
306
            break;
307
        if (value & 2) {
308
            qemu_set_irq(s->parent_intr[1], 0);
309
            s->new_agr[1] = ~0;
310
            omap_inth_update(s, 1);
311
        }
312
        if (value & 1) {
313
            qemu_set_irq(s->parent_intr[0], 0);
314
            s->new_agr[0] = ~0;
315
            omap_inth_update(s, 0);
316
        }
317
        return;
318

    
319
    case 0x1c:        /* ILR0 */
320
    case 0x20:        /* ILR1 */
321
    case 0x24:        /* ILR2 */
322
    case 0x28:        /* ILR3 */
323
    case 0x2c:        /* ILR4 */
324
    case 0x30:        /* ILR5 */
325
    case 0x34:        /* ILR6 */
326
    case 0x38:        /* ILR7 */
327
    case 0x3c:        /* ILR8 */
328
    case 0x40:        /* ILR9 */
329
    case 0x44:        /* ILR10 */
330
    case 0x48:        /* ILR11 */
331
    case 0x4c:        /* ILR12 */
332
    case 0x50:        /* ILR13 */
333
    case 0x54:        /* ILR14 */
334
    case 0x58:        /* ILR15 */
335
    case 0x5c:        /* ILR16 */
336
    case 0x60:        /* ILR17 */
337
    case 0x64:        /* ILR18 */
338
    case 0x68:        /* ILR19 */
339
    case 0x6c:        /* ILR20 */
340
    case 0x70:        /* ILR21 */
341
    case 0x74:        /* ILR22 */
342
    case 0x78:        /* ILR23 */
343
    case 0x7c:        /* ILR24 */
344
    case 0x80:        /* ILR25 */
345
    case 0x84:        /* ILR26 */
346
    case 0x88:        /* ILR27 */
347
    case 0x8c:        /* ILR28 */
348
    case 0x90:        /* ILR29 */
349
    case 0x94:        /* ILR30 */
350
    case 0x98:        /* ILR31 */
351
        i = (offset - 0x1c) >> 2;
352
        bank->priority[i] = (value >> 2) & 0x1f;
353
        bank->sens_edge &= ~(1 << i);
354
        bank->sens_edge |= ((value >> 1) & 1) << i;
355
        bank->fiq &= ~(1 << i);
356
        bank->fiq |= (value & 1) << i;
357
        return;
358

    
359
    case 0x9c:        /* ISR */
360
        for (i = 0; i < 32; i ++)
361
            if (value & (1 << i)) {
362
                omap_set_intr(s, 32 * bank_no + i, 1);
363
                return;
364
            }
365
        return;
366
    }
367
    OMAP_BAD_REG(addr);
368
}
369

    
370
static CPUReadMemoryFunc *omap_inth_readfn[] = {
371
    omap_badwidth_read32,
372
    omap_badwidth_read32,
373
    omap_inth_read,
374
};
375

    
376
static CPUWriteMemoryFunc *omap_inth_writefn[] = {
377
    omap_inth_write,
378
    omap_inth_write,
379
    omap_inth_write,
380
};
381

    
382
void omap_inth_reset(struct omap_intr_handler_s *s)
383
{
384
    int i;
385

    
386
    for (i = 0; i < s->nbanks; ++i){
387
        s->bank[i].irqs = 0x00000000;
388
        s->bank[i].mask = 0xffffffff;
389
        s->bank[i].sens_edge = 0x00000000;
390
        s->bank[i].fiq = 0x00000000;
391
        s->bank[i].inputs = 0x00000000;
392
        s->bank[i].swi = 0x00000000;
393
        memset(s->bank[i].priority, 0, sizeof(s->bank[i].priority));
394

    
395
        if (s->level_only)
396
            s->bank[i].sens_edge = 0xffffffff;
397
    }
398

    
399
    s->new_agr[0] = ~0;
400
    s->new_agr[1] = ~0;
401
    s->sir_intr[0] = 0;
402
    s->sir_intr[1] = 0;
403
    s->autoidle = 0;
404
    s->mask = ~0;
405

    
406
    qemu_set_irq(s->parent_intr[0], 0);
407
    qemu_set_irq(s->parent_intr[1], 0);
408
}
409

    
410
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
411
                unsigned long size, unsigned char nbanks, qemu_irq **pins,
412
                qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk)
413
{
414
    int iomemtype;
415
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
416
            qemu_mallocz(sizeof(struct omap_intr_handler_s) +
417
                            sizeof(struct omap_intr_handler_bank_s) * nbanks);
418

    
419
    s->parent_intr[0] = parent_irq;
420
    s->parent_intr[1] = parent_fiq;
421
    s->nbanks = nbanks;
422
    s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
423
    if (pins)
424
        *pins = s->pins;
425

    
426
    omap_inth_reset(s);
427

    
428
    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
429
                    omap_inth_writefn, s);
430
    cpu_register_physical_memory(base, size, iomemtype);
431

    
432
    return s;
433
}
434

    
435
static uint32_t omap2_inth_read(void *opaque, target_phys_addr_t addr)
436
{
437
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
438
    int offset = addr;
439
    int bank_no, line_no;
440
    struct omap_intr_handler_bank_s *bank = 0;
441

    
442
    if ((offset & 0xf80) == 0x80) {
443
        bank_no = (offset & 0x60) >> 5;
444
        if (bank_no < s->nbanks) {
445
            offset &= ~0x60;
446
            bank = &s->bank[bank_no];
447
        }
448
    }
449

    
450
    switch (offset) {
451
    case 0x00:        /* INTC_REVISION */
452
        return 0x21;
453

    
454
    case 0x10:        /* INTC_SYSCONFIG */
455
        return (s->autoidle >> 2) & 1;
456

    
457
    case 0x14:        /* INTC_SYSSTATUS */
458
        return 1;                                                /* RESETDONE */
459

    
460
    case 0x40:        /* INTC_SIR_IRQ */
461
        return s->sir_intr[0];
462

    
463
    case 0x44:        /* INTC_SIR_FIQ */
464
        return s->sir_intr[1];
465

    
466
    case 0x48:        /* INTC_CONTROL */
467
        return (!s->mask) << 2;                                        /* GLOBALMASK */
468

    
469
    case 0x4c:        /* INTC_PROTECTION */
470
        return 0;
471

    
472
    case 0x50:        /* INTC_IDLE */
473
        return s->autoidle & 3;
474

    
475
    /* Per-bank registers */
476
    case 0x80:        /* INTC_ITR */
477
        return bank->inputs;
478

    
479
    case 0x84:        /* INTC_MIR */
480
        return bank->mask;
481

    
482
    case 0x88:        /* INTC_MIR_CLEAR */
483
    case 0x8c:        /* INTC_MIR_SET */
484
        return 0;
485

    
486
    case 0x90:        /* INTC_ISR_SET */
487
        return bank->swi;
488

    
489
    case 0x94:        /* INTC_ISR_CLEAR */
490
        return 0;
491

    
492
    case 0x98:        /* INTC_PENDING_IRQ */
493
        return bank->irqs & ~bank->mask & ~bank->fiq;
494

    
495
    case 0x9c:        /* INTC_PENDING_FIQ */
496
        return bank->irqs & ~bank->mask & bank->fiq;
497

    
498
    /* Per-line registers */
499
    case 0x100 ... 0x300:        /* INTC_ILR */
500
        bank_no = (offset - 0x100) >> 7;
501
        if (bank_no > s->nbanks)
502
            break;
503
        bank = &s->bank[bank_no];
504
        line_no = (offset & 0x7f) >> 2;
505
        return (bank->priority[line_no] << 2) |
506
                ((bank->fiq >> line_no) & 1);
507
    }
508
    OMAP_BAD_REG(addr);
509
    return 0;
510
}
511

    
512
static void omap2_inth_write(void *opaque, target_phys_addr_t addr,
513
                uint32_t value)
514
{
515
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
516
    int offset = addr;
517
    int bank_no, line_no;
518
    struct omap_intr_handler_bank_s *bank = 0;
519

    
520
    if ((offset & 0xf80) == 0x80) {
521
        bank_no = (offset & 0x60) >> 5;
522
        if (bank_no < s->nbanks) {
523
            offset &= ~0x60;
524
            bank = &s->bank[bank_no];
525
        }
526
    }
527

    
528
    switch (offset) {
529
    case 0x10:        /* INTC_SYSCONFIG */
530
        s->autoidle &= 4;
531
        s->autoidle |= (value & 1) << 2;
532
        if (value & 2)                                                /* SOFTRESET */
533
            omap_inth_reset(s);
534
        return;
535

    
536
    case 0x48:        /* INTC_CONTROL */
537
        s->mask = (value & 4) ? 0 : ~0;                                /* GLOBALMASK */
538
        if (value & 2) {                                        /* NEWFIQAGR */
539
            qemu_set_irq(s->parent_intr[1], 0);
540
            s->new_agr[1] = ~0;
541
            omap_inth_update(s, 1);
542
        }
543
        if (value & 1) {                                        /* NEWIRQAGR */
544
            qemu_set_irq(s->parent_intr[0], 0);
545
            s->new_agr[0] = ~0;
546
            omap_inth_update(s, 0);
547
        }
548
        return;
549

    
550
    case 0x4c:        /* INTC_PROTECTION */
551
        /* TODO: Make a bitmap (or sizeof(char)map) of access privileges
552
         * for every register, see Chapter 3 and 4 for privileged mode.  */
553
        if (value & 1)
554
            fprintf(stderr, "%s: protection mode enable attempt\n",
555
                            __FUNCTION__);
556
        return;
557

    
558
    case 0x50:        /* INTC_IDLE */
559
        s->autoidle &= ~3;
560
        s->autoidle |= value & 3;
561
        return;
562

    
563
    /* Per-bank registers */
564
    case 0x84:        /* INTC_MIR */
565
        bank->mask = value;
566
        omap_inth_update(s, 0);
567
        omap_inth_update(s, 1);
568
        return;
569

    
570
    case 0x88:        /* INTC_MIR_CLEAR */
571
        bank->mask &= ~value;
572
        omap_inth_update(s, 0);
573
        omap_inth_update(s, 1);
574
        return;
575

    
576
    case 0x8c:        /* INTC_MIR_SET */
577
        bank->mask |= value;
578
        return;
579

    
580
    case 0x90:        /* INTC_ISR_SET */
581
        bank->irqs |= bank->swi |= value;
582
        omap_inth_update(s, 0);
583
        omap_inth_update(s, 1);
584
        return;
585

    
586
    case 0x94:        /* INTC_ISR_CLEAR */
587
        bank->swi &= ~value;
588
        bank->irqs = bank->swi & bank->inputs;
589
        return;
590

    
591
    /* Per-line registers */
592
    case 0x100 ... 0x300:        /* INTC_ILR */
593
        bank_no = (offset - 0x100) >> 7;
594
        if (bank_no > s->nbanks)
595
            break;
596
        bank = &s->bank[bank_no];
597
        line_no = (offset & 0x7f) >> 2;
598
        bank->priority[line_no] = (value >> 2) & 0x3f;
599
        bank->fiq &= ~(1 << line_no);
600
        bank->fiq |= (value & 1) << line_no;
601
        return;
602

    
603
    case 0x00:        /* INTC_REVISION */
604
    case 0x14:        /* INTC_SYSSTATUS */
605
    case 0x40:        /* INTC_SIR_IRQ */
606
    case 0x44:        /* INTC_SIR_FIQ */
607
    case 0x80:        /* INTC_ITR */
608
    case 0x98:        /* INTC_PENDING_IRQ */
609
    case 0x9c:        /* INTC_PENDING_FIQ */
610
        OMAP_RO_REG(addr);
611
        return;
612
    }
613
    OMAP_BAD_REG(addr);
614
}
615

    
616
static CPUReadMemoryFunc *omap2_inth_readfn[] = {
617
    omap_badwidth_read32,
618
    omap_badwidth_read32,
619
    omap2_inth_read,
620
};
621

    
622
static CPUWriteMemoryFunc *omap2_inth_writefn[] = {
623
    omap2_inth_write,
624
    omap2_inth_write,
625
    omap2_inth_write,
626
};
627

    
628
struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base,
629
                int size, int nbanks, qemu_irq **pins,
630
                qemu_irq parent_irq, qemu_irq parent_fiq,
631
                omap_clk fclk, omap_clk iclk)
632
{
633
    int iomemtype;
634
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
635
            qemu_mallocz(sizeof(struct omap_intr_handler_s) +
636
                            sizeof(struct omap_intr_handler_bank_s) * nbanks);
637

    
638
    s->parent_intr[0] = parent_irq;
639
    s->parent_intr[1] = parent_fiq;
640
    s->nbanks = nbanks;
641
    s->level_only = 1;
642
    s->pins = qemu_allocate_irqs(omap_set_intr_noedge, s, nbanks * 32);
643
    if (pins)
644
        *pins = s->pins;
645

    
646
    omap_inth_reset(s);
647

    
648
    iomemtype = cpu_register_io_memory(0, omap2_inth_readfn,
649
                    omap2_inth_writefn, s);
650
    cpu_register_physical_memory(base, size, iomemtype);
651

    
652
    return s;
653
}
654

    
655
/* MPU OS timers */
656
struct omap_mpu_timer_s {
657
    qemu_irq irq;
658
    omap_clk clk;
659
    uint32_t val;
660
    int64_t time;
661
    QEMUTimer *timer;
662
    QEMUBH *tick;
663
    int64_t rate;
664
    int it_ena;
665

    
666
    int enable;
667
    int ptv;
668
    int ar;
669
    int st;
670
    uint32_t reset_val;
671
};
672

    
673
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
674
{
675
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
676

    
677
    if (timer->st && timer->enable && timer->rate)
678
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
679
                        timer->rate, ticks_per_sec);
680
    else
681
        return timer->val;
682
}
683

    
684
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
685
{
686
    timer->val = omap_timer_read(timer);
687
    timer->time = qemu_get_clock(vm_clock);
688
}
689

    
690
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
691
{
692
    int64_t expires;
693

    
694
    if (timer->enable && timer->st && timer->rate) {
695
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
696
        expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
697
                        ticks_per_sec, timer->rate);
698

    
699
        /* If timer expiry would be sooner than in about 1 ms and
700
         * auto-reload isn't set, then fire immediately.  This is a hack
701
         * to make systems like PalmOS run in acceptable time.  PalmOS
702
         * sets the interval to a very low value and polls the status bit
703
         * in a busy loop when it wants to sleep just a couple of CPU
704
         * ticks.  */
705
        if (expires > (ticks_per_sec >> 10) || timer->ar)
706
            qemu_mod_timer(timer->timer, timer->time + expires);
707
        else
708
            qemu_bh_schedule(timer->tick);
709
    } else
710
        qemu_del_timer(timer->timer);
711
}
712

    
713
static void omap_timer_fire(void *opaque)
714
{
715
    struct omap_mpu_timer_s *timer = opaque;
716

    
717
    if (!timer->ar) {
718
        timer->val = 0;
719
        timer->st = 0;
720
    }
721

    
722
    if (timer->it_ena)
723
        /* Edge-triggered irq */
724
        qemu_irq_pulse(timer->irq);
725
}
726

    
727
static void omap_timer_tick(void *opaque)
728
{
729
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
730

    
731
    omap_timer_sync(timer);
732
    omap_timer_fire(timer);
733
    omap_timer_update(timer);
734
}
735

    
736
static void omap_timer_clk_update(void *opaque, int line, int on)
737
{
738
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
739

    
740
    omap_timer_sync(timer);
741
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
742
    omap_timer_update(timer);
743
}
744

    
745
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
746
{
747
    omap_clk_adduser(timer->clk,
748
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
749
    timer->rate = omap_clk_getrate(timer->clk);
750
}
751

    
752
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
753
{
754
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
755

    
756
    switch (addr) {
757
    case 0x00:        /* CNTL_TIMER */
758
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
759

    
760
    case 0x04:        /* LOAD_TIM */
761
        break;
762

    
763
    case 0x08:        /* READ_TIM */
764
        return omap_timer_read(s);
765
    }
766

    
767
    OMAP_BAD_REG(addr);
768
    return 0;
769
}
770

    
771
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
772
                uint32_t value)
773
{
774
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
775

    
776
    switch (addr) {
777
    case 0x00:        /* CNTL_TIMER */
778
        omap_timer_sync(s);
779
        s->enable = (value >> 5) & 1;
780
        s->ptv = (value >> 2) & 7;
781
        s->ar = (value >> 1) & 1;
782
        s->st = value & 1;
783
        omap_timer_update(s);
784
        return;
785

    
786
    case 0x04:        /* LOAD_TIM */
787
        s->reset_val = value;
788
        return;
789

    
790
    case 0x08:        /* READ_TIM */
791
        OMAP_RO_REG(addr);
792
        break;
793

    
794
    default:
795
        OMAP_BAD_REG(addr);
796
    }
797
}
798

    
799
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
800
    omap_badwidth_read32,
801
    omap_badwidth_read32,
802
    omap_mpu_timer_read,
803
};
804

    
805
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
806
    omap_badwidth_write32,
807
    omap_badwidth_write32,
808
    omap_mpu_timer_write,
809
};
810

    
811
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
812
{
813
    qemu_del_timer(s->timer);
814
    s->enable = 0;
815
    s->reset_val = 31337;
816
    s->val = 0;
817
    s->ptv = 0;
818
    s->ar = 0;
819
    s->st = 0;
820
    s->it_ena = 1;
821
}
822

    
823
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
824
                qemu_irq irq, omap_clk clk)
825
{
826
    int iomemtype;
827
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
828
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
829

    
830
    s->irq = irq;
831
    s->clk = clk;
832
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
833
    s->tick = qemu_bh_new(omap_timer_fire, s);
834
    omap_mpu_timer_reset(s);
835
    omap_timer_clk_setup(s);
836

    
837
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
838
                    omap_mpu_timer_writefn, s);
839
    cpu_register_physical_memory(base, 0x100, iomemtype);
840

    
841
    return s;
842
}
843

    
844
/* Watchdog timer */
845
struct omap_watchdog_timer_s {
846
    struct omap_mpu_timer_s timer;
847
    uint8_t last_wr;
848
    int mode;
849
    int free;
850
    int reset;
851
};
852

    
853
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
854
{
855
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
856

    
857
    switch (addr) {
858
    case 0x00:        /* CNTL_TIMER */
859
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
860
                (s->timer.st << 7) | (s->free << 1);
861

    
862
    case 0x04:        /* READ_TIMER */
863
        return omap_timer_read(&s->timer);
864

    
865
    case 0x08:        /* TIMER_MODE */
866
        return s->mode << 15;
867
    }
868

    
869
    OMAP_BAD_REG(addr);
870
    return 0;
871
}
872

    
873
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
874
                uint32_t value)
875
{
876
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
877

    
878
    switch (addr) {
879
    case 0x00:        /* CNTL_TIMER */
880
        omap_timer_sync(&s->timer);
881
        s->timer.ptv = (value >> 9) & 7;
882
        s->timer.ar = (value >> 8) & 1;
883
        s->timer.st = (value >> 7) & 1;
884
        s->free = (value >> 1) & 1;
885
        omap_timer_update(&s->timer);
886
        break;
887

    
888
    case 0x04:        /* LOAD_TIMER */
889
        s->timer.reset_val = value & 0xffff;
890
        break;
891

    
892
    case 0x08:        /* TIMER_MODE */
893
        if (!s->mode && ((value >> 15) & 1))
894
            omap_clk_get(s->timer.clk);
895
        s->mode |= (value >> 15) & 1;
896
        if (s->last_wr == 0xf5) {
897
            if ((value & 0xff) == 0xa0) {
898
                if (s->mode) {
899
                    s->mode = 0;
900
                    omap_clk_put(s->timer.clk);
901
                }
902
            } else {
903
                /* XXX: on T|E hardware somehow this has no effect,
904
                 * on Zire 71 it works as specified.  */
905
                s->reset = 1;
906
                qemu_system_reset_request();
907
            }
908
        }
909
        s->last_wr = value & 0xff;
910
        break;
911

    
912
    default:
913
        OMAP_BAD_REG(addr);
914
    }
915
}
916

    
917
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
918
    omap_badwidth_read16,
919
    omap_wd_timer_read,
920
    omap_badwidth_read16,
921
};
922

    
923
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
924
    omap_badwidth_write16,
925
    omap_wd_timer_write,
926
    omap_badwidth_write16,
927
};
928

    
929
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
930
{
931
    qemu_del_timer(s->timer.timer);
932
    if (!s->mode)
933
        omap_clk_get(s->timer.clk);
934
    s->mode = 1;
935
    s->free = 1;
936
    s->reset = 0;
937
    s->timer.enable = 1;
938
    s->timer.it_ena = 1;
939
    s->timer.reset_val = 0xffff;
940
    s->timer.val = 0;
941
    s->timer.st = 0;
942
    s->timer.ptv = 0;
943
    s->timer.ar = 0;
944
    omap_timer_update(&s->timer);
945
}
946

    
947
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
948
                qemu_irq irq, omap_clk clk)
949
{
950
    int iomemtype;
951
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
952
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
953

    
954
    s->timer.irq = irq;
955
    s->timer.clk = clk;
956
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
957
    omap_wd_timer_reset(s);
958
    omap_timer_clk_setup(&s->timer);
959

    
960
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
961
                    omap_wd_timer_writefn, s);
962
    cpu_register_physical_memory(base, 0x100, iomemtype);
963

    
964
    return s;
965
}
966

    
967
/* 32-kHz timer */
968
struct omap_32khz_timer_s {
969
    struct omap_mpu_timer_s timer;
970
};
971

    
972
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
973
{
974
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
975
    int offset = addr & OMAP_MPUI_REG_MASK;
976

    
977
    switch (offset) {
978
    case 0x00:        /* TVR */
979
        return s->timer.reset_val;
980

    
981
    case 0x04:        /* TCR */
982
        return omap_timer_read(&s->timer);
983

    
984
    case 0x08:        /* CR */
985
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
986

    
987
    default:
988
        break;
989
    }
990
    OMAP_BAD_REG(addr);
991
    return 0;
992
}
993

    
994
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
995
                uint32_t value)
996
{
997
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
998
    int offset = addr & OMAP_MPUI_REG_MASK;
999

    
1000
    switch (offset) {
1001
    case 0x00:        /* TVR */
1002
        s->timer.reset_val = value & 0x00ffffff;
1003
        break;
1004

    
1005
    case 0x04:        /* TCR */
1006
        OMAP_RO_REG(addr);
1007
        break;
1008

    
1009
    case 0x08:        /* CR */
1010
        s->timer.ar = (value >> 3) & 1;
1011
        s->timer.it_ena = (value >> 2) & 1;
1012
        if (s->timer.st != (value & 1) || (value & 2)) {
1013
            omap_timer_sync(&s->timer);
1014
            s->timer.enable = value & 1;
1015
            s->timer.st = value & 1;
1016
            omap_timer_update(&s->timer);
1017
        }
1018
        break;
1019

    
1020
    default:
1021
        OMAP_BAD_REG(addr);
1022
    }
1023
}
1024

    
1025
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1026
    omap_badwidth_read32,
1027
    omap_badwidth_read32,
1028
    omap_os_timer_read,
1029
};
1030

    
1031
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1032
    omap_badwidth_write32,
1033
    omap_badwidth_write32,
1034
    omap_os_timer_write,
1035
};
1036

    
1037
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1038
{
1039
    qemu_del_timer(s->timer.timer);
1040
    s->timer.enable = 0;
1041
    s->timer.it_ena = 0;
1042
    s->timer.reset_val = 0x00ffffff;
1043
    s->timer.val = 0;
1044
    s->timer.st = 0;
1045
    s->timer.ptv = 0;
1046
    s->timer.ar = 1;
1047
}
1048

    
1049
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1050
                qemu_irq irq, omap_clk clk)
1051
{
1052
    int iomemtype;
1053
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1054
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1055

    
1056
    s->timer.irq = irq;
1057
    s->timer.clk = clk;
1058
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1059
    omap_os_timer_reset(s);
1060
    omap_timer_clk_setup(&s->timer);
1061

    
1062
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1063
                    omap_os_timer_writefn, s);
1064
    cpu_register_physical_memory(base, 0x800, iomemtype);
1065

    
1066
    return s;
1067
}
1068

    
1069
/* Ultra Low-Power Device Module */
1070
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1071
{
1072
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1073
    uint16_t ret;
1074

    
1075
    switch (addr) {
1076
    case 0x14:        /* IT_STATUS */
1077
        ret = s->ulpd_pm_regs[addr >> 2];
1078
        s->ulpd_pm_regs[addr >> 2] = 0;
1079
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1080
        return ret;
1081

    
1082
    case 0x18:        /* Reserved */
1083
    case 0x1c:        /* Reserved */
1084
    case 0x20:        /* Reserved */
1085
    case 0x28:        /* Reserved */
1086
    case 0x2c:        /* Reserved */
1087
        OMAP_BAD_REG(addr);
1088
    case 0x00:        /* COUNTER_32_LSB */
1089
    case 0x04:        /* COUNTER_32_MSB */
1090
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1091
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1092
    case 0x10:        /* GAUGING_CTRL */
1093
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1094
    case 0x30:        /* CLOCK_CTRL */
1095
    case 0x34:        /* SOFT_REQ */
1096
    case 0x38:        /* COUNTER_32_FIQ */
1097
    case 0x3c:        /* DPLL_CTRL */
1098
    case 0x40:        /* STATUS_REQ */
1099
        /* XXX: check clk::usecount state for every clock */
1100
    case 0x48:        /* LOCL_TIME */
1101
    case 0x4c:        /* APLL_CTRL */
1102
    case 0x50:        /* POWER_CTRL */
1103
        return s->ulpd_pm_regs[addr >> 2];
1104
    }
1105

    
1106
    OMAP_BAD_REG(addr);
1107
    return 0;
1108
}
1109

    
1110
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1111
                uint16_t diff, uint16_t value)
1112
{
1113
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
1114
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1115
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1116
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1117
}
1118

    
1119
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1120
                uint16_t diff, uint16_t value)
1121
{
1122
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1123
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1124
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1125
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1126
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1127
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1128
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1129
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1130
}
1131

    
1132
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1133
                uint32_t value)
1134
{
1135
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1136
    int64_t now, ticks;
1137
    int div, mult;
1138
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1139
    uint16_t diff;
1140

    
1141
    switch (addr) {
1142
    case 0x00:        /* COUNTER_32_LSB */
1143
    case 0x04:        /* COUNTER_32_MSB */
1144
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1145
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1146
    case 0x14:        /* IT_STATUS */
1147
    case 0x40:        /* STATUS_REQ */
1148
        OMAP_RO_REG(addr);
1149
        break;
1150

    
1151
    case 0x10:        /* GAUGING_CTRL */
1152
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1153
        if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
1154
            now = qemu_get_clock(vm_clock);
1155

    
1156
            if (value & 1)
1157
                s->ulpd_gauge_start = now;
1158
            else {
1159
                now -= s->ulpd_gauge_start;
1160

    
1161
                /* 32-kHz ticks */
1162
                ticks = muldiv64(now, 32768, ticks_per_sec);
1163
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1164
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1165
                if (ticks >> 32)        /* OVERFLOW_32K */
1166
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1167

    
1168
                /* High frequency ticks */
1169
                ticks = muldiv64(now, 12000000, ticks_per_sec);
1170
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1171
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1172
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1173
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1174

    
1175
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
1176
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1177
            }
1178
        }
1179
        s->ulpd_pm_regs[addr >> 2] = value;
1180
        break;
1181

    
1182
    case 0x18:        /* Reserved */
1183
    case 0x1c:        /* Reserved */
1184
    case 0x20:        /* Reserved */
1185
    case 0x28:        /* Reserved */
1186
    case 0x2c:        /* Reserved */
1187
        OMAP_BAD_REG(addr);
1188
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1189
    case 0x38:        /* COUNTER_32_FIQ */
1190
    case 0x48:        /* LOCL_TIME */
1191
    case 0x50:        /* POWER_CTRL */
1192
        s->ulpd_pm_regs[addr >> 2] = value;
1193
        break;
1194

    
1195
    case 0x30:        /* CLOCK_CTRL */
1196
        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
1197
        s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
1198
        omap_ulpd_clk_update(s, diff, value);
1199
        break;
1200

    
1201
    case 0x34:        /* SOFT_REQ */
1202
        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
1203
        s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
1204
        omap_ulpd_req_update(s, diff, value);
1205
        break;
1206

    
1207
    case 0x3c:        /* DPLL_CTRL */
1208
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
1209
         * omitted altogether, probably a typo.  */
1210
        /* This register has identical semantics with DPLL(1:3) control
1211
         * registers, see omap_dpll_write() */
1212
        diff = s->ulpd_pm_regs[addr >> 2] & value;
1213
        s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
1214
        if (diff & (0x3ff << 2)) {
1215
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1216
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1217
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1218
            } else {
1219
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1220
                mult = 1;
1221
            }
1222
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
1223
        }
1224

    
1225
        /* Enter the desired mode.  */
1226
        s->ulpd_pm_regs[addr >> 2] =
1227
                (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
1228
                ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
1229

    
1230
        /* Act as if the lock is restored.  */
1231
        s->ulpd_pm_regs[addr >> 2] |= 2;
1232
        break;
1233

    
1234
    case 0x4c:        /* APLL_CTRL */
1235
        diff = s->ulpd_pm_regs[addr >> 2] & value;
1236
        s->ulpd_pm_regs[addr >> 2] = value & 0xf;
1237
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
1238
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1239
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
1240
        break;
1241

    
1242
    default:
1243
        OMAP_BAD_REG(addr);
1244
    }
1245
}
1246

    
1247
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1248
    omap_badwidth_read16,
1249
    omap_ulpd_pm_read,
1250
    omap_badwidth_read16,
1251
};
1252

    
1253
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1254
    omap_badwidth_write16,
1255
    omap_ulpd_pm_write,
1256
    omap_badwidth_write16,
1257
};
1258

    
1259
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
1260
{
1261
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
1262
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
1263
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
1264
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
1265
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
1266
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
1267
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
1268
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
1269
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
1270
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
1271
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
1272
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
1273
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
1274
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
1275
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
1276
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
1277
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
1278
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
1279
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
1280
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
1281
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
1282
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
1283
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
1284
}
1285

    
1286
static void omap_ulpd_pm_init(target_phys_addr_t base,
1287
                struct omap_mpu_state_s *mpu)
1288
{
1289
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1290
                    omap_ulpd_pm_writefn, mpu);
1291

    
1292
    cpu_register_physical_memory(base, 0x800, iomemtype);
1293
    omap_ulpd_pm_reset(mpu);
1294
}
1295

    
1296
/* OMAP Pin Configuration */
1297
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1298
{
1299
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1300

    
1301
    switch (addr) {
1302
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1303
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1304
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1305
        return s->func_mux_ctrl[addr >> 2];
1306

    
1307
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1308
        return s->comp_mode_ctrl[0];
1309

    
1310
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1311
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1312
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1313
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1314
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1315
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1316
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1317
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1318
    case 0x30:        /* FUNC_MUX_CTRL_B */
1319
    case 0x34:        /* FUNC_MUX_CTRL_C */
1320
    case 0x38:        /* FUNC_MUX_CTRL_D */
1321
        return s->func_mux_ctrl[(addr >> 2) - 1];
1322

    
1323
    case 0x40:        /* PULL_DWN_CTRL_0 */
1324
    case 0x44:        /* PULL_DWN_CTRL_1 */
1325
    case 0x48:        /* PULL_DWN_CTRL_2 */
1326
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1327
        return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
1328

    
1329
    case 0x50:        /* GATE_INH_CTRL_0 */
1330
        return s->gate_inh_ctrl[0];
1331

    
1332
    case 0x60:        /* VOLTAGE_CTRL_0 */
1333
        return s->voltage_ctrl[0];
1334

    
1335
    case 0x70:        /* TEST_DBG_CTRL_0 */
1336
        return s->test_dbg_ctrl[0];
1337

    
1338
    case 0x80:        /* MOD_CONF_CTRL_0 */
1339
        return s->mod_conf_ctrl[0];
1340
    }
1341

    
1342
    OMAP_BAD_REG(addr);
1343
    return 0;
1344
}
1345

    
1346
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1347
                uint32_t diff, uint32_t value)
1348
{
1349
    if (s->compat1509) {
1350
        if (diff & (1 << 9))                        /* BLUETOOTH */
1351
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1352
                            (~value >> 9) & 1);
1353
        if (diff & (1 << 7))                        /* USB.CLKO */
1354
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
1355
                            (value >> 7) & 1);
1356
    }
1357
}
1358

    
1359
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1360
                uint32_t diff, uint32_t value)
1361
{
1362
    if (s->compat1509) {
1363
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
1364
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1365
                            (value >> 31) & 1);
1366
        if (diff & (1 << 1))                        /* CLK32K */
1367
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1368
                            (~value >> 1) & 1);
1369
    }
1370
}
1371

    
1372
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1373
                uint32_t diff, uint32_t value)
1374
{
1375
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
1376
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1377
                         omap_findclk(s, ((value >> 31) & 1) ?
1378
                                 "ck_48m" : "armper_ck"));
1379
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
1380
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1381
                         omap_findclk(s, ((value >> 30) & 1) ?
1382
                                 "ck_48m" : "armper_ck"));
1383
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
1384
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1385
                         omap_findclk(s, ((value >> 29) & 1) ?
1386
                                 "ck_48m" : "armper_ck"));
1387
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
1388
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1389
                         omap_findclk(s, ((value >> 23) & 1) ?
1390
                                 "ck_48m" : "armper_ck"));
1391
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
1392
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1393
                         omap_findclk(s, ((value >> 12) & 1) ?
1394
                                 "ck_48m" : "armper_ck"));
1395
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1396
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1397
}
1398

    
1399
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1400
                uint32_t value)
1401
{
1402
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1403
    uint32_t diff;
1404

    
1405
    switch (addr) {
1406
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1407
        diff = s->func_mux_ctrl[addr >> 2] ^ value;
1408
        s->func_mux_ctrl[addr >> 2] = value;
1409
        omap_pin_funcmux0_update(s, diff, value);
1410
        return;
1411

    
1412
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1413
        diff = s->func_mux_ctrl[addr >> 2] ^ value;
1414
        s->func_mux_ctrl[addr >> 2] = value;
1415
        omap_pin_funcmux1_update(s, diff, value);
1416
        return;
1417

    
1418
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1419
        s->func_mux_ctrl[addr >> 2] = value;
1420
        return;
1421

    
1422
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1423
        s->comp_mode_ctrl[0] = value;
1424
        s->compat1509 = (value != 0x0000eaef);
1425
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1426
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1427
        return;
1428

    
1429
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1430
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1431
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1432
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1433
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1434
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1435
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1436
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1437
    case 0x30:        /* FUNC_MUX_CTRL_B */
1438
    case 0x34:        /* FUNC_MUX_CTRL_C */
1439
    case 0x38:        /* FUNC_MUX_CTRL_D */
1440
        s->func_mux_ctrl[(addr >> 2) - 1] = value;
1441
        return;
1442

    
1443
    case 0x40:        /* PULL_DWN_CTRL_0 */
1444
    case 0x44:        /* PULL_DWN_CTRL_1 */
1445
    case 0x48:        /* PULL_DWN_CTRL_2 */
1446
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1447
        s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
1448
        return;
1449

    
1450
    case 0x50:        /* GATE_INH_CTRL_0 */
1451
        s->gate_inh_ctrl[0] = value;
1452
        return;
1453

    
1454
    case 0x60:        /* VOLTAGE_CTRL_0 */
1455
        s->voltage_ctrl[0] = value;
1456
        return;
1457

    
1458
    case 0x70:        /* TEST_DBG_CTRL_0 */
1459
        s->test_dbg_ctrl[0] = value;
1460
        return;
1461

    
1462
    case 0x80:        /* MOD_CONF_CTRL_0 */
1463
        diff = s->mod_conf_ctrl[0] ^ value;
1464
        s->mod_conf_ctrl[0] = value;
1465
        omap_pin_modconf1_update(s, diff, value);
1466
        return;
1467

    
1468
    default:
1469
        OMAP_BAD_REG(addr);
1470
    }
1471
}
1472

    
1473
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1474
    omap_badwidth_read32,
1475
    omap_badwidth_read32,
1476
    omap_pin_cfg_read,
1477
};
1478

    
1479
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1480
    omap_badwidth_write32,
1481
    omap_badwidth_write32,
1482
    omap_pin_cfg_write,
1483
};
1484

    
1485
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1486
{
1487
    /* Start in Compatibility Mode.  */
1488
    mpu->compat1509 = 1;
1489
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1490
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1491
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1492
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1493
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1494
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1495
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1496
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1497
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1498
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1499
}
1500

    
1501
static void omap_pin_cfg_init(target_phys_addr_t base,
1502
                struct omap_mpu_state_s *mpu)
1503
{
1504
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1505
                    omap_pin_cfg_writefn, mpu);
1506

    
1507
    cpu_register_physical_memory(base, 0x800, iomemtype);
1508
    omap_pin_cfg_reset(mpu);
1509
}
1510

    
1511
/* Device Identification, Die Identification */
1512
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1513
{
1514
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1515

    
1516
    switch (addr) {
1517
    case 0xfffe1800:        /* DIE_ID_LSB */
1518
        return 0xc9581f0e;
1519
    case 0xfffe1804:        /* DIE_ID_MSB */
1520
        return 0xa8858bfa;
1521

    
1522
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
1523
        return 0x00aaaafc;
1524
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
1525
        return 0xcafeb574;
1526

    
1527
    case 0xfffed400:        /* JTAG_ID_LSB */
1528
        switch (s->mpu_model) {
1529
        case omap310:
1530
            return 0x03310315;
1531
        case omap1510:
1532
            return 0x03310115;
1533
        default:
1534
            hw_error("%s: bad mpu model\n", __FUNCTION__);
1535
        }
1536
        break;
1537

    
1538
    case 0xfffed404:        /* JTAG_ID_MSB */
1539
        switch (s->mpu_model) {
1540
        case omap310:
1541
            return 0xfb57402f;
1542
        case omap1510:
1543
            return 0xfb47002f;
1544
        default:
1545
            hw_error("%s: bad mpu model\n", __FUNCTION__);
1546
        }
1547
        break;
1548
    }
1549

    
1550
    OMAP_BAD_REG(addr);
1551
    return 0;
1552
}
1553

    
1554
static void omap_id_write(void *opaque, target_phys_addr_t addr,
1555
                uint32_t value)
1556
{
1557
    OMAP_BAD_REG(addr);
1558
}
1559

    
1560
static CPUReadMemoryFunc *omap_id_readfn[] = {
1561
    omap_badwidth_read32,
1562
    omap_badwidth_read32,
1563
    omap_id_read,
1564
};
1565

    
1566
static CPUWriteMemoryFunc *omap_id_writefn[] = {
1567
    omap_badwidth_write32,
1568
    omap_badwidth_write32,
1569
    omap_id_write,
1570
};
1571

    
1572
static void omap_id_init(struct omap_mpu_state_s *mpu)
1573
{
1574
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
1575
                    omap_id_writefn, mpu);
1576
    cpu_register_physical_memory_offset(0xfffe1800, 0x800, iomemtype, 0xfffe1800);
1577
    cpu_register_physical_memory_offset(0xfffed400, 0x100, iomemtype, 0xfffed400);
1578
    if (!cpu_is_omap15xx(mpu))
1579
        cpu_register_physical_memory_offset(0xfffe2000, 0x800, iomemtype, 0xfffe2000);
1580
}
1581

    
1582
/* MPUI Control (Dummy) */
1583
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1584
{
1585
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1586

    
1587
    switch (addr) {
1588
    case 0x00:        /* CTRL */
1589
        return s->mpui_ctrl;
1590
    case 0x04:        /* DEBUG_ADDR */
1591
        return 0x01ffffff;
1592
    case 0x08:        /* DEBUG_DATA */
1593
        return 0xffffffff;
1594
    case 0x0c:        /* DEBUG_FLAG */
1595
        return 0x00000800;
1596
    case 0x10:        /* STATUS */
1597
        return 0x00000000;
1598

    
1599
    /* Not in OMAP310 */
1600
    case 0x14:        /* DSP_STATUS */
1601
    case 0x18:        /* DSP_BOOT_CONFIG */
1602
        return 0x00000000;
1603
    case 0x1c:        /* DSP_MPUI_CONFIG */
1604
        return 0x0000ffff;
1605
    }
1606

    
1607
    OMAP_BAD_REG(addr);
1608
    return 0;
1609
}
1610

    
1611
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
1612
                uint32_t value)
1613
{
1614
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1615

    
1616
    switch (addr) {
1617
    case 0x00:        /* CTRL */
1618
        s->mpui_ctrl = value & 0x007fffff;
1619
        break;
1620

    
1621
    case 0x04:        /* DEBUG_ADDR */
1622
    case 0x08:        /* DEBUG_DATA */
1623
    case 0x0c:        /* DEBUG_FLAG */
1624
    case 0x10:        /* STATUS */
1625
    /* Not in OMAP310 */
1626
    case 0x14:        /* DSP_STATUS */
1627
        OMAP_RO_REG(addr);
1628
    case 0x18:        /* DSP_BOOT_CONFIG */
1629
    case 0x1c:        /* DSP_MPUI_CONFIG */
1630
        break;
1631

    
1632
    default:
1633
        OMAP_BAD_REG(addr);
1634
    }
1635
}
1636

    
1637
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
1638
    omap_badwidth_read32,
1639
    omap_badwidth_read32,
1640
    omap_mpui_read,
1641
};
1642

    
1643
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
1644
    omap_badwidth_write32,
1645
    omap_badwidth_write32,
1646
    omap_mpui_write,
1647
};
1648

    
1649
static void omap_mpui_reset(struct omap_mpu_state_s *s)
1650
{
1651
    s->mpui_ctrl = 0x0003ff1b;
1652
}
1653

    
1654
static void omap_mpui_init(target_phys_addr_t base,
1655
                struct omap_mpu_state_s *mpu)
1656
{
1657
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
1658
                    omap_mpui_writefn, mpu);
1659

    
1660
    cpu_register_physical_memory(base, 0x100, iomemtype);
1661

    
1662
    omap_mpui_reset(mpu);
1663
}
1664

    
1665
/* TIPB Bridges */
1666
struct omap_tipb_bridge_s {
1667
    qemu_irq abort;
1668

    
1669
    int width_intr;
1670
    uint16_t control;
1671
    uint16_t alloc;
1672
    uint16_t buffer;
1673
    uint16_t enh_control;
1674
};
1675

    
1676
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
1677
{
1678
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1679

    
1680
    switch (addr) {
1681
    case 0x00:        /* TIPB_CNTL */
1682
        return s->control;
1683
    case 0x04:        /* TIPB_BUS_ALLOC */
1684
        return s->alloc;
1685
    case 0x08:        /* MPU_TIPB_CNTL */
1686
        return s->buffer;
1687
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1688
        return s->enh_control;
1689
    case 0x10:        /* ADDRESS_DBG */
1690
    case 0x14:        /* DATA_DEBUG_LOW */
1691
    case 0x18:        /* DATA_DEBUG_HIGH */
1692
        return 0xffff;
1693
    case 0x1c:        /* DEBUG_CNTR_SIG */
1694
        return 0x00f8;
1695
    }
1696

    
1697
    OMAP_BAD_REG(addr);
1698
    return 0;
1699
}
1700

    
1701
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
1702
                uint32_t value)
1703
{
1704
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1705

    
1706
    switch (addr) {
1707
    case 0x00:        /* TIPB_CNTL */
1708
        s->control = value & 0xffff;
1709
        break;
1710

    
1711
    case 0x04:        /* TIPB_BUS_ALLOC */
1712
        s->alloc = value & 0x003f;
1713
        break;
1714

    
1715
    case 0x08:        /* MPU_TIPB_CNTL */
1716
        s->buffer = value & 0x0003;
1717
        break;
1718

    
1719
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1720
        s->width_intr = !(value & 2);
1721
        s->enh_control = value & 0x000f;
1722
        break;
1723

    
1724
    case 0x10:        /* ADDRESS_DBG */
1725
    case 0x14:        /* DATA_DEBUG_LOW */
1726
    case 0x18:        /* DATA_DEBUG_HIGH */
1727
    case 0x1c:        /* DEBUG_CNTR_SIG */
1728
        OMAP_RO_REG(addr);
1729
        break;
1730

    
1731
    default:
1732
        OMAP_BAD_REG(addr);
1733
    }
1734
}
1735

    
1736
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
1737
    omap_badwidth_read16,
1738
    omap_tipb_bridge_read,
1739
    omap_tipb_bridge_read,
1740
};
1741

    
1742
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
1743
    omap_badwidth_write16,
1744
    omap_tipb_bridge_write,
1745
    omap_tipb_bridge_write,
1746
};
1747

    
1748
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1749
{
1750
    s->control = 0xffff;
1751
    s->alloc = 0x0009;
1752
    s->buffer = 0x0000;
1753
    s->enh_control = 0x000f;
1754
}
1755

    
1756
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
1757
                qemu_irq abort_irq, omap_clk clk)
1758
{
1759
    int iomemtype;
1760
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
1761
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
1762

    
1763
    s->abort = abort_irq;
1764
    omap_tipb_bridge_reset(s);
1765

    
1766
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
1767
                    omap_tipb_bridge_writefn, s);
1768
    cpu_register_physical_memory(base, 0x100, iomemtype);
1769

    
1770
    return s;
1771
}
1772

    
1773
/* Dummy Traffic Controller's Memory Interface */
1774
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
1775
{
1776
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1777
    uint32_t ret;
1778

    
1779
    switch (addr) {
1780
    case 0x00:        /* IMIF_PRIO */
1781
    case 0x04:        /* EMIFS_PRIO */
1782
    case 0x08:        /* EMIFF_PRIO */
1783
    case 0x0c:        /* EMIFS_CONFIG */
1784
    case 0x10:        /* EMIFS_CS0_CONFIG */
1785
    case 0x14:        /* EMIFS_CS1_CONFIG */
1786
    case 0x18:        /* EMIFS_CS2_CONFIG */
1787
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1788
    case 0x24:        /* EMIFF_MRS */
1789
    case 0x28:        /* TIMEOUT1 */
1790
    case 0x2c:        /* TIMEOUT2 */
1791
    case 0x30:        /* TIMEOUT3 */
1792
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1793
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1794
        return s->tcmi_regs[addr >> 2];
1795

    
1796
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1797
        ret = s->tcmi_regs[addr >> 2];
1798
        s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1799
        /* XXX: We can try using the VGA_DIRTY flag for this */
1800
        return ret;
1801
    }
1802

    
1803
    OMAP_BAD_REG(addr);
1804
    return 0;
1805
}
1806

    
1807
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
1808
                uint32_t value)
1809
{
1810
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1811

    
1812
    switch (addr) {
1813
    case 0x00:        /* IMIF_PRIO */
1814
    case 0x04:        /* EMIFS_PRIO */
1815
    case 0x08:        /* EMIFF_PRIO */
1816
    case 0x10:        /* EMIFS_CS0_CONFIG */
1817
    case 0x14:        /* EMIFS_CS1_CONFIG */
1818
    case 0x18:        /* EMIFS_CS2_CONFIG */
1819
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1820
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1821
    case 0x24:        /* EMIFF_MRS */
1822
    case 0x28:        /* TIMEOUT1 */
1823
    case 0x2c:        /* TIMEOUT2 */
1824
    case 0x30:        /* TIMEOUT3 */
1825
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1826
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1827
        s->tcmi_regs[addr >> 2] = value;
1828
        break;
1829
    case 0x0c:        /* EMIFS_CONFIG */
1830
        s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
1831
        break;
1832

    
1833
    default:
1834
        OMAP_BAD_REG(addr);
1835
    }
1836
}
1837

    
1838
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
1839
    omap_badwidth_read32,
1840
    omap_badwidth_read32,
1841
    omap_tcmi_read,
1842
};
1843

    
1844
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
1845
    omap_badwidth_write32,
1846
    omap_badwidth_write32,
1847
    omap_tcmi_write,
1848
};
1849

    
1850
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1851
{
1852
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1853
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1854
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1855
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1856
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1857
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1858
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1859
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1860
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1861
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1862
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1863
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1864
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1865
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1866
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1867
}
1868

    
1869
static void omap_tcmi_init(target_phys_addr_t base,
1870
                struct omap_mpu_state_s *mpu)
1871
{
1872
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
1873
                    omap_tcmi_writefn, mpu);
1874

    
1875
    cpu_register_physical_memory(base, 0x100, iomemtype);
1876
    omap_tcmi_reset(mpu);
1877
}
1878

    
1879
/* Digital phase-locked loops control */
1880
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
1881
{
1882
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1883

    
1884
    if (addr == 0x00)        /* CTL_REG */
1885
        return s->mode;
1886

    
1887
    OMAP_BAD_REG(addr);
1888
    return 0;
1889
}
1890

    
1891
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
1892
                uint32_t value)
1893
{
1894
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1895
    uint16_t diff;
1896
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1897
    int div, mult;
1898

    
1899
    if (addr == 0x00) {        /* CTL_REG */
1900
        /* See omap_ulpd_pm_write() too */
1901
        diff = s->mode & value;
1902
        s->mode = value & 0x2fff;
1903
        if (diff & (0x3ff << 2)) {
1904
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1905
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1906
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1907
            } else {
1908
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1909
                mult = 1;
1910
            }
1911
            omap_clk_setrate(s->dpll, div, mult);
1912
        }
1913

    
1914
        /* Enter the desired mode.  */
1915
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1916

    
1917
        /* Act as if the lock is restored.  */
1918
        s->mode |= 2;
1919
    } else {
1920
        OMAP_BAD_REG(addr);
1921
    }
1922
}
1923

    
1924
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
1925
    omap_badwidth_read16,
1926
    omap_dpll_read,
1927
    omap_badwidth_read16,
1928
};
1929

    
1930
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
1931
    omap_badwidth_write16,
1932
    omap_dpll_write,
1933
    omap_badwidth_write16,
1934
};
1935

    
1936
static void omap_dpll_reset(struct dpll_ctl_s *s)
1937
{
1938
    s->mode = 0x2002;
1939
    omap_clk_setrate(s->dpll, 1, 1);
1940
}
1941

    
1942
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
1943
                omap_clk clk)
1944
{
1945
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
1946
                    omap_dpll_writefn, s);
1947

    
1948
    s->dpll = clk;
1949
    omap_dpll_reset(s);
1950

    
1951
    cpu_register_physical_memory(base, 0x100, iomemtype);
1952
}
1953

    
1954
/* UARTs */
1955
struct omap_uart_s {
1956
    target_phys_addr_t base;
1957
    SerialState *serial; /* TODO */
1958
    struct omap_target_agent_s *ta;
1959
    omap_clk fclk;
1960
    qemu_irq irq;
1961

    
1962
    uint8_t eblr;
1963
    uint8_t syscontrol;
1964
    uint8_t wkup;
1965
    uint8_t cfps;
1966
    uint8_t mdr[2];
1967
    uint8_t scr;
1968
    uint8_t clksel;
1969
};
1970

    
1971
void omap_uart_reset(struct omap_uart_s *s)
1972
{
1973
    s->eblr = 0x00;
1974
    s->syscontrol = 0;
1975
    s->wkup = 0x3f;
1976
    s->cfps = 0x69;
1977
    s->clksel = 0;
1978
}
1979

    
1980
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
1981
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
1982
                qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr)
1983
{
1984
    struct omap_uart_s *s = (struct omap_uart_s *)
1985
            qemu_mallocz(sizeof(struct omap_uart_s));
1986

    
1987
    s->base = base;
1988
    s->fclk = fclk;
1989
    s->irq = irq;
1990
    s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
1991
                               chr ?: qemu_chr_open("null", "null", NULL), 1);
1992

    
1993
    return s;
1994
}
1995

    
1996
static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr)
1997
{
1998
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
1999

    
2000
    addr &= 0xff;
2001
    switch (addr) {
2002
    case 0x20:        /* MDR1 */
2003
        return s->mdr[0];
2004
    case 0x24:        /* MDR2 */
2005
        return s->mdr[1];
2006
    case 0x40:        /* SCR */
2007
        return s->scr;
2008
    case 0x44:        /* SSR */
2009
        return 0x0;
2010
    case 0x48:        /* EBLR (OMAP2) */
2011
        return s->eblr;
2012
    case 0x4C:        /* OSC_12M_SEL (OMAP1) */
2013
        return s->clksel;
2014
    case 0x50:        /* MVR */
2015
        return 0x30;
2016
    case 0x54:        /* SYSC (OMAP2) */
2017
        return s->syscontrol;
2018
    case 0x58:        /* SYSS (OMAP2) */
2019
        return 1;
2020
    case 0x5c:        /* WER (OMAP2) */
2021
        return s->wkup;
2022
    case 0x60:        /* CFPS (OMAP2) */
2023
        return s->cfps;
2024
    }
2025

    
2026
    OMAP_BAD_REG(addr);
2027
    return 0;
2028
}
2029

    
2030
static void omap_uart_write(void *opaque, target_phys_addr_t addr,
2031
                uint32_t value)
2032
{
2033
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
2034

    
2035
    addr &= 0xff;
2036
    switch (addr) {
2037
    case 0x20:        /* MDR1 */
2038
        s->mdr[0] = value & 0x7f;
2039
        break;
2040
    case 0x24:        /* MDR2 */
2041
        s->mdr[1] = value & 0xff;
2042
        break;
2043
    case 0x40:        /* SCR */
2044
        s->scr = value & 0xff;
2045
        break;
2046
    case 0x48:        /* EBLR (OMAP2) */
2047
        s->eblr = value & 0xff;
2048
        break;
2049
    case 0x4C:        /* OSC_12M_SEL (OMAP1) */
2050
        s->clksel = value & 1;
2051
        break;
2052
    case 0x44:        /* SSR */
2053
    case 0x50:        /* MVR */
2054
    case 0x58:        /* SYSS (OMAP2) */
2055
        OMAP_RO_REG(addr);
2056
        break;
2057
    case 0x54:        /* SYSC (OMAP2) */
2058
        s->syscontrol = value & 0x1d;
2059
        if (value & 2)
2060
            omap_uart_reset(s);
2061
        break;
2062
    case 0x5c:        /* WER (OMAP2) */
2063
        s->wkup = value & 0x7f;
2064
        break;
2065
    case 0x60:        /* CFPS (OMAP2) */
2066
        s->cfps = value & 0xff;
2067
        break;
2068
    default:
2069
        OMAP_BAD_REG(addr);
2070
    }
2071
}
2072

    
2073
static CPUReadMemoryFunc *omap_uart_readfn[] = {
2074
    omap_uart_read,
2075
    omap_uart_read,
2076
    omap_badwidth_read8,
2077
};
2078

    
2079
static CPUWriteMemoryFunc *omap_uart_writefn[] = {
2080
    omap_uart_write,
2081
    omap_uart_write,
2082
    omap_badwidth_write8,
2083
};
2084

    
2085
struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta,
2086
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
2087
                qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr)
2088
{
2089
    target_phys_addr_t base = omap_l4_attach(ta, 0, 0);
2090
    struct omap_uart_s *s = omap_uart_init(base, irq,
2091
                    fclk, iclk, txdma, rxdma, chr);
2092
    int iomemtype = cpu_register_io_memory(0, omap_uart_readfn,
2093
                    omap_uart_writefn, s);
2094

    
2095
    s->ta = ta;
2096

    
2097
    cpu_register_physical_memory(base + 0x20, 0x100, iomemtype);
2098

    
2099
    return s;
2100
}
2101

    
2102
void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
2103
{
2104
    /* TODO: Should reuse or destroy current s->serial */
2105
    s->serial = serial_mm_init(s->base, 2, s->irq,
2106
                    omap_clk_getrate(s->fclk) / 16,
2107
                    chr ?: qemu_chr_open("null", "null", NULL), 1);
2108
}
2109

    
2110
/* MPU Clock/Reset/Power Mode Control */
2111
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2112
{
2113
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2114

    
2115
    switch (addr) {
2116
    case 0x00:        /* ARM_CKCTL */
2117
        return s->clkm.arm_ckctl;
2118

    
2119
    case 0x04:        /* ARM_IDLECT1 */
2120
        return s->clkm.arm_idlect1;
2121

    
2122
    case 0x08:        /* ARM_IDLECT2 */
2123
        return s->clkm.arm_idlect2;
2124

    
2125
    case 0x0c:        /* ARM_EWUPCT */
2126
        return s->clkm.arm_ewupct;
2127

    
2128
    case 0x10:        /* ARM_RSTCT1 */
2129
        return s->clkm.arm_rstct1;
2130

    
2131
    case 0x14:        /* ARM_RSTCT2 */
2132
        return s->clkm.arm_rstct2;
2133

    
2134
    case 0x18:        /* ARM_SYSST */
2135
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
2136

    
2137
    case 0x1c:        /* ARM_CKOUT1 */
2138
        return s->clkm.arm_ckout1;
2139

    
2140
    case 0x20:        /* ARM_CKOUT2 */
2141
        break;
2142
    }
2143

    
2144
    OMAP_BAD_REG(addr);
2145
    return 0;
2146
}
2147

    
2148
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2149
                uint16_t diff, uint16_t value)
2150
{
2151
    omap_clk clk;
2152

    
2153
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
2154
        if (value & (1 << 14))
2155
            /* Reserved */;
2156
        else {
2157
            clk = omap_findclk(s, "arminth_ck");
2158
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2159
        }
2160
    }
2161
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
2162
        clk = omap_findclk(s, "armtim_ck");
2163
        if (value & (1 << 12))
2164
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
2165
        else
2166
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2167
    }
2168
    /* XXX: en_dspck */
2169
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
2170
        clk = omap_findclk(s, "dspmmu_ck");
2171
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
2172
    }
2173
    if (diff & (3 << 8)) {                                /* TCDIV */
2174
        clk = omap_findclk(s, "tc_ck");
2175
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2176
    }
2177
    if (diff & (3 << 6)) {                                /* DSPDIV */
2178
        clk = omap_findclk(s, "dsp_ck");
2179
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2180
    }
2181
    if (diff & (3 << 4)) {                                /* ARMDIV */
2182
        clk = omap_findclk(s, "arm_ck");
2183
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2184
    }
2185
    if (diff & (3 << 2)) {                                /* LCDDIV */
2186
        clk = omap_findclk(s, "lcd_ck");
2187
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2188
    }
2189
    if (diff & (3 << 0)) {                                /* PERDIV */
2190
        clk = omap_findclk(s, "armper_ck");
2191
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2192
    }
2193
}
2194

    
2195
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2196
                uint16_t diff, uint16_t value)
2197
{
2198
    omap_clk clk;
2199

    
2200
    if (value & (1 << 11))                                /* SETARM_IDLE */
2201
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2202
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2203
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2204

    
2205
#define SET_CANIDLE(clock, bit)                                \
2206
    if (diff & (1 << bit)) {                                \
2207
        clk = omap_findclk(s, clock);                        \
2208
        omap_clk_canidle(clk, (value >> bit) & 1);        \
2209
    }
2210
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
2211
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
2212
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
2213
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
2214
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
2215
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
2216
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
2217
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
2218
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
2219
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
2220
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
2221
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
2222
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
2223
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
2224
}
2225

    
2226
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2227
                uint16_t diff, uint16_t value)
2228
{
2229
    omap_clk clk;
2230

    
2231
#define SET_ONOFF(clock, bit)                                \
2232
    if (diff & (1 << bit)) {                                \
2233
        clk = omap_findclk(s, clock);                        \
2234
        omap_clk_onoff(clk, (value >> bit) & 1);        \
2235
    }
2236
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
2237
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
2238
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
2239
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
2240
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
2241
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
2242
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
2243
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
2244
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
2245
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
2246
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
2247
}
2248

    
2249
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2250
                uint16_t diff, uint16_t value)
2251
{
2252
    omap_clk clk;
2253

    
2254
    if (diff & (3 << 4)) {                                /* TCLKOUT */
2255
        clk = omap_findclk(s, "tclk_out");
2256
        switch ((value >> 4) & 3) {
2257
        case 1:
2258
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
2259
            omap_clk_onoff(clk, 1);
2260
            break;
2261
        case 2:
2262
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2263
            omap_clk_onoff(clk, 1);
2264
            break;
2265
        default:
2266
            omap_clk_onoff(clk, 0);
2267
        }
2268
    }
2269
    if (diff & (3 << 2)) {                                /* DCLKOUT */
2270
        clk = omap_findclk(s, "dclk_out");
2271
        switch ((value >> 2) & 3) {
2272
        case 0:
2273
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
2274
            break;
2275
        case 1:
2276
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
2277
            break;
2278
        case 2:
2279
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
2280
            break;
2281
        case 3:
2282
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2283
            break;
2284
        }
2285
    }
2286
    if (diff & (3 << 0)) {                                /* ACLKOUT */
2287
        clk = omap_findclk(s, "aclk_out");
2288
        switch ((value >> 0) & 3) {
2289
        case 1:
2290
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2291
            omap_clk_onoff(clk, 1);
2292
            break;
2293
        case 2:
2294
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
2295
            omap_clk_onoff(clk, 1);
2296
            break;
2297
        case 3:
2298
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2299
            omap_clk_onoff(clk, 1);
2300
            break;
2301
        default:
2302
            omap_clk_onoff(clk, 0);
2303
        }
2304
    }
2305
}
2306

    
2307
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2308
                uint32_t value)
2309
{
2310
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2311
    uint16_t diff;
2312
    omap_clk clk;
2313
    static const char *clkschemename[8] = {
2314
        "fully synchronous", "fully asynchronous", "synchronous scalable",
2315
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2316
    };
2317

    
2318
    switch (addr) {
2319
    case 0x00:        /* ARM_CKCTL */
2320
        diff = s->clkm.arm_ckctl ^ value;
2321
        s->clkm.arm_ckctl = value & 0x7fff;
2322
        omap_clkm_ckctl_update(s, diff, value);
2323
        return;
2324

    
2325
    case 0x04:        /* ARM_IDLECT1 */
2326
        diff = s->clkm.arm_idlect1 ^ value;
2327
        s->clkm.arm_idlect1 = value & 0x0fff;
2328
        omap_clkm_idlect1_update(s, diff, value);
2329
        return;
2330

    
2331
    case 0x08:        /* ARM_IDLECT2 */
2332
        diff = s->clkm.arm_idlect2 ^ value;
2333
        s->clkm.arm_idlect2 = value & 0x07ff;
2334
        omap_clkm_idlect2_update(s, diff, value);
2335
        return;
2336

    
2337
    case 0x0c:        /* ARM_EWUPCT */
2338
        diff = s->clkm.arm_ewupct ^ value;
2339
        s->clkm.arm_ewupct = value & 0x003f;
2340
        return;
2341

    
2342
    case 0x10:        /* ARM_RSTCT1 */
2343
        diff = s->clkm.arm_rstct1 ^ value;
2344
        s->clkm.arm_rstct1 = value & 0x0007;
2345
        if (value & 9) {
2346
            qemu_system_reset_request();
2347
            s->clkm.cold_start = 0xa;
2348
        }
2349
        if (diff & ~value & 4) {                                /* DSP_RST */
2350
            omap_mpui_reset(s);
2351
            omap_tipb_bridge_reset(s->private_tipb);
2352
            omap_tipb_bridge_reset(s->public_tipb);
2353
        }
2354
        if (diff & 2) {                                                /* DSP_EN */
2355
            clk = omap_findclk(s, "dsp_ck");
2356
            omap_clk_canidle(clk, (~value >> 1) & 1);
2357
        }
2358
        return;
2359

    
2360
    case 0x14:        /* ARM_RSTCT2 */
2361
        s->clkm.arm_rstct2 = value & 0x0001;
2362
        return;
2363

    
2364
    case 0x18:        /* ARM_SYSST */
2365
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2366
            s->clkm.clocking_scheme = (value >> 11) & 7;
2367
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2368
                            clkschemename[s->clkm.clocking_scheme]);
2369
        }
2370
        s->clkm.cold_start &= value & 0x3f;
2371
        return;
2372

    
2373
    case 0x1c:        /* ARM_CKOUT1 */
2374
        diff = s->clkm.arm_ckout1 ^ value;
2375
        s->clkm.arm_ckout1 = value & 0x003f;
2376
        omap_clkm_ckout1_update(s, diff, value);
2377
        return;
2378

    
2379
    case 0x20:        /* ARM_CKOUT2 */
2380
    default:
2381
        OMAP_BAD_REG(addr);
2382
    }
2383
}
2384

    
2385
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2386
    omap_badwidth_read16,
2387
    omap_clkm_read,
2388
    omap_badwidth_read16,
2389
};
2390

    
2391
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2392
    omap_badwidth_write16,
2393
    omap_clkm_write,
2394
    omap_badwidth_write16,
2395
};
2396

    
2397
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2398
{
2399
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2400

    
2401
    switch (addr) {
2402
    case 0x04:        /* DSP_IDLECT1 */
2403
        return s->clkm.dsp_idlect1;
2404

    
2405
    case 0x08:        /* DSP_IDLECT2 */
2406
        return s->clkm.dsp_idlect2;
2407

    
2408
    case 0x14:        /* DSP_RSTCT2 */
2409
        return s->clkm.dsp_rstct2;
2410

    
2411
    case 0x18:        /* DSP_SYSST */
2412
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
2413
                (s->env->halted << 6);        /* Quite useless... */
2414
    }
2415

    
2416
    OMAP_BAD_REG(addr);
2417
    return 0;
2418
}
2419

    
2420
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2421
                uint16_t diff, uint16_t value)
2422
{
2423
    omap_clk clk;
2424

    
2425
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2426
}
2427

    
2428
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2429
                uint16_t diff, uint16_t value)
2430
{
2431
    omap_clk clk;
2432

    
2433
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2434
}
2435

    
2436
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2437
                uint32_t value)
2438
{
2439
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2440
    uint16_t diff;
2441

    
2442
    switch (addr) {
2443
    case 0x04:        /* DSP_IDLECT1 */
2444
        diff = s->clkm.dsp_idlect1 ^ value;
2445
        s->clkm.dsp_idlect1 = value & 0x01f7;
2446
        omap_clkdsp_idlect1_update(s, diff, value);
2447
        break;
2448

    
2449
    case 0x08:        /* DSP_IDLECT2 */
2450
        s->clkm.dsp_idlect2 = value & 0x0037;
2451
        diff = s->clkm.dsp_idlect1 ^ value;
2452
        omap_clkdsp_idlect2_update(s, diff, value);
2453
        break;
2454

    
2455
    case 0x14:        /* DSP_RSTCT2 */
2456
        s->clkm.dsp_rstct2 = value & 0x0001;
2457
        break;
2458

    
2459
    case 0x18:        /* DSP_SYSST */
2460
        s->clkm.cold_start &= value & 0x3f;
2461
        break;
2462

    
2463
    default:
2464
        OMAP_BAD_REG(addr);
2465
    }
2466
}
2467

    
2468
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2469
    omap_badwidth_read16,
2470
    omap_clkdsp_read,
2471
    omap_badwidth_read16,
2472
};
2473

    
2474
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2475
    omap_badwidth_write16,
2476
    omap_clkdsp_write,
2477
    omap_badwidth_write16,
2478
};
2479

    
2480
static void omap_clkm_reset(struct omap_mpu_state_s *s)
2481
{
2482
    if (s->wdt && s->wdt->reset)
2483
        s->clkm.cold_start = 0x6;
2484
    s->clkm.clocking_scheme = 0;
2485
    omap_clkm_ckctl_update(s, ~0, 0x3000);
2486
    s->clkm.arm_ckctl = 0x3000;
2487
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
2488
    s->clkm.arm_idlect1 = 0x0400;
2489
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
2490
    s->clkm.arm_idlect2 = 0x0100;
2491
    s->clkm.arm_ewupct = 0x003f;
2492
    s->clkm.arm_rstct1 = 0x0000;
2493
    s->clkm.arm_rstct2 = 0x0000;
2494
    s->clkm.arm_ckout1 = 0x0015;
2495
    s->clkm.dpll1_mode = 0x2002;
2496
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2497
    s->clkm.dsp_idlect1 = 0x0040;
2498
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2499
    s->clkm.dsp_idlect2 = 0x0000;
2500
    s->clkm.dsp_rstct2 = 0x0000;
2501
}
2502

    
2503
static void omap_clkm_init(target_phys_addr_t mpu_base,
2504
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2505
{
2506
    int iomemtype[2] = {
2507
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2508
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2509
    };
2510

    
2511
    s->clkm.arm_idlect1 = 0x03ff;
2512
    s->clkm.arm_idlect2 = 0x0100;
2513
    s->clkm.dsp_idlect1 = 0x0002;
2514
    omap_clkm_reset(s);
2515
    s->clkm.cold_start = 0x3a;
2516

    
2517
    cpu_register_physical_memory(mpu_base, 0x100, iomemtype[0]);
2518
    cpu_register_physical_memory(dsp_base, 0x1000, iomemtype[1]);
2519
}
2520

    
2521
/* MPU I/O */
2522
struct omap_mpuio_s {
2523
    qemu_irq irq;
2524
    qemu_irq kbd_irq;
2525
    qemu_irq *in;
2526
    qemu_irq handler[16];
2527
    qemu_irq wakeup;
2528

    
2529
    uint16_t inputs;
2530
    uint16_t outputs;
2531
    uint16_t dir;
2532
    uint16_t edge;
2533
    uint16_t mask;
2534
    uint16_t ints;
2535

    
2536
    uint16_t debounce;
2537
    uint16_t latch;
2538
    uint8_t event;
2539

    
2540
    uint8_t buttons[5];
2541
    uint8_t row_latch;
2542
    uint8_t cols;
2543
    int kbd_mask;
2544
    int clk;
2545
};
2546

    
2547
static void omap_mpuio_set(void *opaque, int line, int level)
2548
{
2549
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2550
    uint16_t prev = s->inputs;
2551

    
2552
    if (level)
2553
        s->inputs |= 1 << line;
2554
    else
2555
        s->inputs &= ~(1 << line);
2556

    
2557
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2558
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2559
            s->ints |= 1 << line;
2560
            qemu_irq_raise(s->irq);
2561
            /* TODO: wakeup */
2562
        }
2563
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
2564
                (s->event >> 1) == line)        /* PIN_SELECT */
2565
            s->latch = s->inputs;
2566
    }
2567
}
2568

    
2569
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2570
{
2571
    int i;
2572
    uint8_t *row, rows = 0, cols = ~s->cols;
2573

    
2574
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2575
        if (*row & cols)
2576
            rows |= i;
2577

    
2578
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
2579
    s->row_latch = ~rows;
2580
}
2581

    
2582
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2583
{
2584
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2585
    int offset = addr & OMAP_MPUI_REG_MASK;
2586
    uint16_t ret;
2587

    
2588
    switch (offset) {
2589
    case 0x00:        /* INPUT_LATCH */
2590
        return s->inputs;
2591

    
2592
    case 0x04:        /* OUTPUT_REG */
2593
        return s->outputs;
2594

    
2595
    case 0x08:        /* IO_CNTL */
2596
        return s->dir;
2597

    
2598
    case 0x10:        /* KBR_LATCH */
2599
        return s->row_latch;
2600

    
2601
    case 0x14:        /* KBC_REG */
2602
        return s->cols;
2603

    
2604
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2605
        return s->event;
2606

    
2607
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2608
        return s->edge;
2609

    
2610
    case 0x20:        /* KBD_INT */
2611
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
2612

    
2613
    case 0x24:        /* GPIO_INT */
2614
        ret = s->ints;
2615
        s->ints &= s->mask;
2616
        if (ret)
2617
            qemu_irq_lower(s->irq);
2618
        return ret;
2619

    
2620
    case 0x28:        /* KBD_MASKIT */
2621
        return s->kbd_mask;
2622

    
2623
    case 0x2c:        /* GPIO_MASKIT */
2624
        return s->mask;
2625

    
2626
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2627
        return s->debounce;
2628

    
2629
    case 0x34:        /* GPIO_LATCH_REG */
2630
        return s->latch;
2631
    }
2632

    
2633
    OMAP_BAD_REG(addr);
2634
    return 0;
2635
}
2636

    
2637
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2638
                uint32_t value)
2639
{
2640
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2641
    int offset = addr & OMAP_MPUI_REG_MASK;
2642
    uint16_t diff;
2643
    int ln;
2644

    
2645
    switch (offset) {
2646
    case 0x04:        /* OUTPUT_REG */
2647
        diff = (s->outputs ^ value) & ~s->dir;
2648
        s->outputs = value;
2649
        while ((ln = ffs(diff))) {
2650
            ln --;
2651
            if (s->handler[ln])
2652
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2653
            diff &= ~(1 << ln);
2654
        }
2655
        break;
2656

    
2657
    case 0x08:        /* IO_CNTL */
2658
        diff = s->outputs & (s->dir ^ value);
2659
        s->dir = value;
2660

    
2661
        value = s->outputs & ~s->dir;
2662
        while ((ln = ffs(diff))) {
2663
            ln --;
2664
            if (s->handler[ln])
2665
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2666
            diff &= ~(1 << ln);
2667
        }
2668
        break;
2669

    
2670
    case 0x14:        /* KBC_REG */
2671
        s->cols = value;
2672
        omap_mpuio_kbd_update(s);
2673
        break;
2674

    
2675
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2676
        s->event = value & 0x1f;
2677
        break;
2678

    
2679
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2680
        s->edge = value;
2681
        break;
2682

    
2683
    case 0x28:        /* KBD_MASKIT */
2684
        s->kbd_mask = value & 1;
2685
        omap_mpuio_kbd_update(s);
2686
        break;
2687

    
2688
    case 0x2c:        /* GPIO_MASKIT */
2689
        s->mask = value;
2690
        break;
2691

    
2692
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2693
        s->debounce = value & 0x1ff;
2694
        break;
2695

    
2696
    case 0x00:        /* INPUT_LATCH */
2697
    case 0x10:        /* KBR_LATCH */
2698
    case 0x20:        /* KBD_INT */
2699
    case 0x24:        /* GPIO_INT */
2700
    case 0x34:        /* GPIO_LATCH_REG */
2701
        OMAP_RO_REG(addr);
2702
        return;
2703

    
2704
    default:
2705
        OMAP_BAD_REG(addr);
2706
        return;
2707
    }
2708
}
2709

    
2710
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
2711
    omap_badwidth_read16,
2712
    omap_mpuio_read,
2713
    omap_badwidth_read16,
2714
};
2715

    
2716
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
2717
    omap_badwidth_write16,
2718
    omap_mpuio_write,
2719
    omap_badwidth_write16,
2720
};
2721

    
2722
static void omap_mpuio_reset(struct omap_mpuio_s *s)
2723
{
2724
    s->inputs = 0;
2725
    s->outputs = 0;
2726
    s->dir = ~0;
2727
    s->event = 0;
2728
    s->edge = 0;
2729
    s->kbd_mask = 0;
2730
    s->mask = 0;
2731
    s->debounce = 0;
2732
    s->latch = 0;
2733
    s->ints = 0;
2734
    s->row_latch = 0x1f;
2735
    s->clk = 1;
2736
}
2737

    
2738
static void omap_mpuio_onoff(void *opaque, int line, int on)
2739
{
2740
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2741

    
2742
    s->clk = on;
2743
    if (on)
2744
        omap_mpuio_kbd_update(s);
2745
}
2746

    
2747
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
2748
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2749
                omap_clk clk)
2750
{
2751
    int iomemtype;
2752
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2753
            qemu_mallocz(sizeof(struct omap_mpuio_s));
2754

    
2755
    s->irq = gpio_int;
2756
    s->kbd_irq = kbd_int;
2757
    s->wakeup = wakeup;
2758
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2759
    omap_mpuio_reset(s);
2760

    
2761
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
2762
                    omap_mpuio_writefn, s);
2763
    cpu_register_physical_memory(base, 0x800, iomemtype);
2764

    
2765
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2766

    
2767
    return s;
2768
}
2769

    
2770
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2771
{
2772
    return s->in;
2773
}
2774

    
2775
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2776
{
2777
    if (line >= 16 || line < 0)
2778
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
2779
    s->handler[line] = handler;
2780
}
2781

    
2782
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2783
{
2784
    if (row >= 5 || row < 0)
2785
        hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
2786

    
2787
    if (down)
2788
        s->buttons[row] |= 1 << col;
2789
    else
2790
        s->buttons[row] &= ~(1 << col);
2791

    
2792
    omap_mpuio_kbd_update(s);
2793
}
2794

    
2795
/* General-Purpose I/O */
2796
struct omap_gpio_s {
2797
    qemu_irq irq;
2798
    qemu_irq *in;
2799
    qemu_irq handler[16];
2800

    
2801
    uint16_t inputs;
2802
    uint16_t outputs;
2803
    uint16_t dir;
2804
    uint16_t edge;
2805
    uint16_t mask;
2806
    uint16_t ints;
2807
    uint16_t pins;
2808
};
2809

    
2810
static void omap_gpio_set(void *opaque, int line, int level)
2811
{
2812
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2813
    uint16_t prev = s->inputs;
2814

    
2815
    if (level)
2816
        s->inputs |= 1 << line;
2817
    else
2818
        s->inputs &= ~(1 << line);
2819

    
2820
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
2821
                    (1 << line) & s->dir & ~s->mask) {
2822
        s->ints |= 1 << line;
2823
        qemu_irq_raise(s->irq);
2824
    }
2825
}
2826

    
2827
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
2828
{
2829
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2830
    int offset = addr & OMAP_MPUI_REG_MASK;
2831

    
2832
    switch (offset) {
2833
    case 0x00:        /* DATA_INPUT */
2834
        return s->inputs & s->pins;
2835

    
2836
    case 0x04:        /* DATA_OUTPUT */
2837
        return s->outputs;
2838

    
2839
    case 0x08:        /* DIRECTION_CONTROL */
2840
        return s->dir;
2841

    
2842
    case 0x0c:        /* INTERRUPT_CONTROL */
2843
        return s->edge;
2844

    
2845
    case 0x10:        /* INTERRUPT_MASK */
2846
        return s->mask;
2847

    
2848
    case 0x14:        /* INTERRUPT_STATUS */
2849
        return s->ints;
2850

    
2851
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
2852
        OMAP_BAD_REG(addr);
2853
        return s->pins;
2854
    }
2855

    
2856
    OMAP_BAD_REG(addr);
2857
    return 0;
2858
}
2859

    
2860
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
2861
                uint32_t value)
2862
{
2863
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2864
    int offset = addr & OMAP_MPUI_REG_MASK;
2865
    uint16_t diff;
2866
    int ln;
2867

    
2868
    switch (offset) {
2869
    case 0x00:        /* DATA_INPUT */
2870
        OMAP_RO_REG(addr);
2871
        return;
2872

    
2873
    case 0x04:        /* DATA_OUTPUT */
2874
        diff = (s->outputs ^ value) & ~s->dir;
2875
        s->outputs = value;
2876
        while ((ln = ffs(diff))) {
2877
            ln --;
2878
            if (s->handler[ln])
2879
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2880
            diff &= ~(1 << ln);
2881
        }
2882
        break;
2883

    
2884
    case 0x08:        /* DIRECTION_CONTROL */
2885
        diff = s->outputs & (s->dir ^ value);
2886
        s->dir = value;
2887

    
2888
        value = s->outputs & ~s->dir;
2889
        while ((ln = ffs(diff))) {
2890
            ln --;
2891
            if (s->handler[ln])
2892
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2893
            diff &= ~(1 << ln);
2894
        }
2895
        break;
2896

    
2897
    case 0x0c:        /* INTERRUPT_CONTROL */
2898
        s->edge = value;
2899
        break;
2900

    
2901
    case 0x10:        /* INTERRUPT_MASK */
2902
        s->mask = value;
2903
        break;
2904

    
2905
    case 0x14:        /* INTERRUPT_STATUS */
2906
        s->ints &= ~value;
2907
        if (!s->ints)
2908
            qemu_irq_lower(s->irq);
2909
        break;
2910

    
2911
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
2912
        OMAP_BAD_REG(addr);
2913
        s->pins = value;
2914
        break;
2915

    
2916
    default:
2917
        OMAP_BAD_REG(addr);
2918
        return;
2919
    }
2920
}
2921

    
2922
/* *Some* sources say the memory region is 32-bit.  */
2923
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
2924
    omap_badwidth_read16,
2925
    omap_gpio_read,
2926
    omap_badwidth_read16,
2927
};
2928

    
2929
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
2930
    omap_badwidth_write16,
2931
    omap_gpio_write,
2932
    omap_badwidth_write16,
2933
};
2934

    
2935
static void omap_gpio_reset(struct omap_gpio_s *s)
2936
{
2937
    s->inputs = 0;
2938
    s->outputs = ~0;
2939
    s->dir = ~0;
2940
    s->edge = ~0;
2941
    s->mask = ~0;
2942
    s->ints = 0;
2943
    s->pins = ~0;
2944
}
2945

    
2946
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
2947
                qemu_irq irq, omap_clk clk)
2948
{
2949
    int iomemtype;
2950
    struct omap_gpio_s *s = (struct omap_gpio_s *)
2951
            qemu_mallocz(sizeof(struct omap_gpio_s));
2952

    
2953
    s->irq = irq;
2954
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
2955
    omap_gpio_reset(s);
2956

    
2957
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
2958
                    omap_gpio_writefn, s);
2959
    cpu_register_physical_memory(base, 0x1000, iomemtype);
2960

    
2961
    return s;
2962
}
2963

    
2964
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
2965
{
2966
    return s->in;
2967
}
2968

    
2969
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
2970
{
2971
    if (line >= 16 || line < 0)
2972
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
2973
    s->handler[line] = handler;
2974
}
2975

    
2976
/* MicroWire Interface */
2977
struct omap_uwire_s {
2978
    qemu_irq txirq;
2979
    qemu_irq rxirq;
2980
    qemu_irq txdrq;
2981

    
2982
    uint16_t txbuf;
2983
    uint16_t rxbuf;
2984
    uint16_t control;
2985
    uint16_t setup[5];
2986

    
2987
    struct uwire_slave_s *chip[4];
2988
};
2989

    
2990
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2991
{
2992
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
2993
    struct uwire_slave_s *slave = s->chip[chipselect];
2994

    
2995
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
2996
        if (s->control & (1 << 12))                        /* CS_CMD */
2997
            if (slave && slave->send)
2998
                slave->send(slave->opaque,
2999
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3000
        s->control &= ~(1 << 14);                        /* CSRB */
3001
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3002
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3003
    }
3004

    
3005
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
3006
        if (s->control & (1 << 12))                        /* CS_CMD */
3007
            if (slave && slave->receive)
3008
                s->rxbuf = slave->receive(slave->opaque);
3009
        s->control |= 1 << 15;                                /* RDRB */
3010
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3011
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3012
    }
3013
}
3014

    
3015
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3016
{
3017
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3018
    int offset = addr & OMAP_MPUI_REG_MASK;
3019

    
3020
    switch (offset) {
3021
    case 0x00:        /* RDR */
3022
        s->control &= ~(1 << 15);                        /* RDRB */
3023
        return s->rxbuf;
3024

    
3025
    case 0x04:        /* CSR */
3026
        return s->control;
3027

    
3028
    case 0x08:        /* SR1 */
3029
        return s->setup[0];
3030
    case 0x0c:        /* SR2 */
3031
        return s->setup[1];
3032
    case 0x10:        /* SR3 */
3033
        return s->setup[2];
3034
    case 0x14:        /* SR4 */
3035
        return s->setup[3];
3036
    case 0x18:        /* SR5 */
3037
        return s->setup[4];
3038
    }
3039

    
3040
    OMAP_BAD_REG(addr);
3041
    return 0;
3042
}
3043

    
3044
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3045
                uint32_t value)
3046
{
3047
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3048
    int offset = addr & OMAP_MPUI_REG_MASK;
3049

    
3050
    switch (offset) {
3051
    case 0x00:        /* TDR */
3052
        s->txbuf = value;                                /* TD */
3053
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3054
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3055
                         (s->control & (1 << 12)))) {        /* CS_CMD */
3056
            s->control |= 1 << 14;                        /* CSRB */
3057
            omap_uwire_transfer_start(s);
3058
        }
3059
        break;
3060

    
3061
    case 0x04:        /* CSR */
3062
        s->control = value & 0x1fff;
3063
        if (value & (1 << 13))                                /* START */
3064
            omap_uwire_transfer_start(s);
3065
        break;
3066

    
3067
    case 0x08:        /* SR1 */
3068
        s->setup[0] = value & 0x003f;
3069
        break;
3070

    
3071
    case 0x0c:        /* SR2 */
3072
        s->setup[1] = value & 0x0fc0;
3073
        break;
3074

    
3075
    case 0x10:        /* SR3 */
3076
        s->setup[2] = value & 0x0003;
3077
        break;
3078

    
3079
    case 0x14:        /* SR4 */
3080
        s->setup[3] = value & 0x0001;
3081
        break;
3082

    
3083
    case 0x18:        /* SR5 */
3084
        s->setup[4] = value & 0x000f;
3085
        break;
3086

    
3087
    default:
3088
        OMAP_BAD_REG(addr);
3089
        return;
3090
    }
3091
}
3092

    
3093
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3094
    omap_badwidth_read16,
3095
    omap_uwire_read,
3096
    omap_badwidth_read16,
3097
};
3098

    
3099
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3100
    omap_badwidth_write16,
3101
    omap_uwire_write,
3102
    omap_badwidth_write16,
3103
};
3104

    
3105
static void omap_uwire_reset(struct omap_uwire_s *s)
3106
{
3107
    s->control = 0;
3108
    s->setup[0] = 0;
3109
    s->setup[1] = 0;
3110
    s->setup[2] = 0;
3111
    s->setup[3] = 0;
3112
    s->setup[4] = 0;
3113
}
3114

    
3115
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3116
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3117
{
3118
    int iomemtype;
3119
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3120
            qemu_mallocz(sizeof(struct omap_uwire_s));
3121

    
3122
    s->txirq = irq[0];
3123
    s->rxirq = irq[1];
3124
    s->txdrq = dma;
3125
    omap_uwire_reset(s);
3126

    
3127
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3128
                    omap_uwire_writefn, s);
3129
    cpu_register_physical_memory(base, 0x800, iomemtype);
3130

    
3131
    return s;
3132
}
3133

    
3134
void omap_uwire_attach(struct omap_uwire_s *s,
3135
                struct uwire_slave_s *slave, int chipselect)
3136
{
3137
    if (chipselect < 0 || chipselect > 3) {
3138
        fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
3139
        exit(-1);
3140
    }
3141

    
3142
    s->chip[chipselect] = slave;
3143
}
3144

    
3145
/* Pseudonoise Pulse-Width Light Modulator */
3146
static void omap_pwl_update(struct omap_mpu_state_s *s)
3147
{
3148
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3149

    
3150
    if (output != s->pwl.output) {
3151
        s->pwl.output = output;
3152
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3153
    }
3154
}
3155

    
3156
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3157
{
3158
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3159
    int offset = addr & OMAP_MPUI_REG_MASK;
3160

    
3161
    switch (offset) {
3162
    case 0x00:        /* PWL_LEVEL */
3163
        return s->pwl.level;
3164
    case 0x04:        /* PWL_CTRL */
3165
        return s->pwl.enable;
3166
    }
3167
    OMAP_BAD_REG(addr);
3168
    return 0;
3169
}
3170

    
3171
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3172
                uint32_t value)
3173
{
3174
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3175
    int offset = addr & OMAP_MPUI_REG_MASK;
3176

    
3177
    switch (offset) {
3178
    case 0x00:        /* PWL_LEVEL */
3179
        s->pwl.level = value;
3180
        omap_pwl_update(s);
3181
        break;
3182
    case 0x04:        /* PWL_CTRL */
3183
        s->pwl.enable = value & 1;
3184
        omap_pwl_update(s);
3185
        break;
3186
    default:
3187
        OMAP_BAD_REG(addr);
3188
        return;
3189
    }
3190
}
3191

    
3192
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3193
    omap_pwl_read,
3194
    omap_badwidth_read8,
3195
    omap_badwidth_read8,
3196
};
3197

    
3198
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3199
    omap_pwl_write,
3200
    omap_badwidth_write8,
3201
    omap_badwidth_write8,
3202
};
3203

    
3204
static void omap_pwl_reset(struct omap_mpu_state_s *s)
3205
{
3206
    s->pwl.output = 0;
3207
    s->pwl.level = 0;
3208
    s->pwl.enable = 0;
3209
    s->pwl.clk = 1;
3210
    omap_pwl_update(s);
3211
}
3212

    
3213
static void omap_pwl_clk_update(void *opaque, int line, int on)
3214
{
3215
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3216

    
3217
    s->pwl.clk = on;
3218
    omap_pwl_update(s);
3219
}
3220

    
3221
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3222
                omap_clk clk)
3223
{
3224
    int iomemtype;
3225

    
3226
    omap_pwl_reset(s);
3227

    
3228
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3229
                    omap_pwl_writefn, s);
3230
    cpu_register_physical_memory(base, 0x800, iomemtype);
3231

    
3232
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3233
}
3234

    
3235
/* Pulse-Width Tone module */
3236
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3237
{
3238
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3239
    int offset = addr & OMAP_MPUI_REG_MASK;
3240

    
3241
    switch (offset) {
3242
    case 0x00:        /* FRC */
3243
        return s->pwt.frc;
3244
    case 0x04:        /* VCR */
3245
        return s->pwt.vrc;
3246
    case 0x08:        /* GCR */
3247
        return s->pwt.gcr;
3248
    }
3249
    OMAP_BAD_REG(addr);
3250
    return 0;
3251
}
3252

    
3253
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3254
                uint32_t value)
3255
{
3256
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3257
    int offset = addr & OMAP_MPUI_REG_MASK;
3258

    
3259
    switch (offset) {
3260
    case 0x00:        /* FRC */
3261
        s->pwt.frc = value & 0x3f;
3262
        break;
3263
    case 0x04:        /* VRC */
3264
        if ((value ^ s->pwt.vrc) & 1) {
3265
            if (value & 1)
3266
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
3267
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
3268
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
3269
                                 /* Pre-multiplexer divider */
3270
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
3271
                                 /* Octave multiplexer */
3272
                                 (2 << (value & 3)) *
3273
                                 /* 101/107 divider */
3274
                                 ((value & (1 << 2)) ? 101 : 107) *
3275
                                 /*  49/55 divider */
3276
                                 ((value & (1 << 3)) ?  49 : 55) *
3277
                                 /*  50/63 divider */
3278
                                 ((value & (1 << 4)) ?  50 : 63) *
3279
                                 /*  80/127 divider */
3280
                                 ((value & (1 << 5)) ?  80 : 127) /
3281
                                 (107 * 55 * 63 * 127)));
3282
            else
3283
                printf("%s: silence!\n", __FUNCTION__);
3284
        }
3285
        s->pwt.vrc = value & 0x7f;
3286
        break;
3287
    case 0x08:        /* GCR */
3288
        s->pwt.gcr = value & 3;
3289
        break;
3290
    default:
3291
        OMAP_BAD_REG(addr);
3292
        return;
3293
    }
3294
}
3295

    
3296
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3297
    omap_pwt_read,
3298
    omap_badwidth_read8,
3299
    omap_badwidth_read8,
3300
};
3301

    
3302
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3303
    omap_pwt_write,
3304
    omap_badwidth_write8,
3305
    omap_badwidth_write8,
3306
};
3307

    
3308
static void omap_pwt_reset(struct omap_mpu_state_s *s)
3309
{
3310
    s->pwt.frc = 0;
3311
    s->pwt.vrc = 0;
3312
    s->pwt.gcr = 0;
3313
}
3314

    
3315
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3316
                omap_clk clk)
3317
{
3318
    int iomemtype;
3319

    
3320
    s->pwt.clk = clk;
3321
    omap_pwt_reset(s);
3322

    
3323
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3324
                    omap_pwt_writefn, s);
3325
    cpu_register_physical_memory(base, 0x800, iomemtype);
3326
}
3327

    
3328
/* Real-time Clock module */
3329
struct omap_rtc_s {
3330
    qemu_irq irq;
3331
    qemu_irq alarm;
3332
    QEMUTimer *clk;
3333

    
3334
    uint8_t interrupts;
3335
    uint8_t status;
3336
    int16_t comp_reg;
3337
    int running;
3338
    int pm_am;
3339
    int auto_comp;
3340
    int round;
3341
    struct tm alarm_tm;
3342
    time_t alarm_ti;
3343

    
3344
    struct tm current_tm;
3345
    time_t ti;
3346
    uint64_t tick;
3347
};
3348

    
3349
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3350
{
3351
    /* s->alarm is level-triggered */
3352
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3353
}
3354

    
3355
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3356
{
3357
    s->alarm_ti = mktimegm(&s->alarm_tm);
3358
    if (s->alarm_ti == -1)
3359
        printf("%s: conversion failed\n", __FUNCTION__);
3360
}
3361

    
3362
static inline uint8_t omap_rtc_bcd(int num)
3363
{
3364
    return ((num / 10) << 4) | (num % 10);
3365
}
3366

    
3367
static inline int omap_rtc_bin(uint8_t num)
3368
{
3369
    return (num & 15) + 10 * (num >> 4);
3370
}
3371

    
3372
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3373
{
3374
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3375
    int offset = addr & OMAP_MPUI_REG_MASK;
3376
    uint8_t i;
3377

    
3378
    switch (offset) {
3379
    case 0x00:        /* SECONDS_REG */
3380
        return omap_rtc_bcd(s->current_tm.tm_sec);
3381

    
3382
    case 0x04:        /* MINUTES_REG */
3383
        return omap_rtc_bcd(s->current_tm.tm_min);
3384

    
3385
    case 0x08:        /* HOURS_REG */
3386
        if (s->pm_am)
3387
            return ((s->current_tm.tm_hour > 11) << 7) |
3388
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3389
        else
3390
            return omap_rtc_bcd(s->current_tm.tm_hour);
3391

    
3392
    case 0x0c:        /* DAYS_REG */
3393
        return omap_rtc_bcd(s->current_tm.tm_mday);
3394

    
3395
    case 0x10:        /* MONTHS_REG */
3396
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3397

    
3398
    case 0x14:        /* YEARS_REG */
3399
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3400

    
3401
    case 0x18:        /* WEEK_REG */
3402
        return s->current_tm.tm_wday;
3403

    
3404
    case 0x20:        /* ALARM_SECONDS_REG */
3405
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3406

    
3407
    case 0x24:        /* ALARM_MINUTES_REG */
3408
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3409

    
3410
    case 0x28:        /* ALARM_HOURS_REG */
3411
        if (s->pm_am)
3412
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3413
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3414
        else
3415
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
3416

    
3417
    case 0x2c:        /* ALARM_DAYS_REG */
3418
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3419

    
3420
    case 0x30:        /* ALARM_MONTHS_REG */
3421
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3422

    
3423
    case 0x34:        /* ALARM_YEARS_REG */
3424
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3425

    
3426
    case 0x40:        /* RTC_CTRL_REG */
3427
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3428
                (s->round << 1) | s->running;
3429

    
3430
    case 0x44:        /* RTC_STATUS_REG */
3431
        i = s->status;
3432
        s->status &= ~0x3d;
3433
        return i;
3434

    
3435
    case 0x48:        /* RTC_INTERRUPTS_REG */
3436
        return s->interrupts;
3437

    
3438
    case 0x4c:        /* RTC_COMP_LSB_REG */
3439
        return ((uint16_t) s->comp_reg) & 0xff;
3440

    
3441
    case 0x50:        /* RTC_COMP_MSB_REG */
3442
        return ((uint16_t) s->comp_reg) >> 8;
3443
    }
3444

    
3445
    OMAP_BAD_REG(addr);
3446
    return 0;
3447
}
3448

    
3449
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3450
                uint32_t value)
3451
{
3452
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3453
    int offset = addr & OMAP_MPUI_REG_MASK;
3454
    struct tm new_tm;
3455
    time_t ti[2];
3456

    
3457
    switch (offset) {
3458
    case 0x00:        /* SECONDS_REG */
3459
#ifdef ALMDEBUG
3460
        printf("RTC SEC_REG <-- %02x\n", value);
3461
#endif
3462
        s->ti -= s->current_tm.tm_sec;
3463
        s->ti += omap_rtc_bin(value);
3464
        return;
3465

    
3466
    case 0x04:        /* MINUTES_REG */
3467
#ifdef ALMDEBUG
3468
        printf("RTC MIN_REG <-- %02x\n", value);
3469
#endif
3470
        s->ti -= s->current_tm.tm_min * 60;
3471
        s->ti += omap_rtc_bin(value) * 60;
3472
        return;
3473

    
3474
    case 0x08:        /* HOURS_REG */
3475
#ifdef ALMDEBUG
3476
        printf("RTC HRS_REG <-- %02x\n", value);
3477
#endif
3478
        s->ti -= s->current_tm.tm_hour * 3600;
3479
        if (s->pm_am) {
3480
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3481
            s->ti += ((value >> 7) & 1) * 43200;
3482
        } else
3483
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3484
        return;
3485

    
3486
    case 0x0c:        /* DAYS_REG */
3487
#ifdef ALMDEBUG
3488
        printf("RTC DAY_REG <-- %02x\n", value);
3489
#endif
3490
        s->ti -= s->current_tm.tm_mday * 86400;
3491
        s->ti += omap_rtc_bin(value) * 86400;
3492
        return;
3493

    
3494
    case 0x10:        /* MONTHS_REG */
3495
#ifdef ALMDEBUG
3496
        printf("RTC MTH_REG <-- %02x\n", value);
3497
#endif
3498
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3499
        new_tm.tm_mon = omap_rtc_bin(value);
3500
        ti[0] = mktimegm(&s->current_tm);
3501
        ti[1] = mktimegm(&new_tm);
3502

    
3503
        if (ti[0] != -1 && ti[1] != -1) {
3504
            s->ti -= ti[0];
3505
            s->ti += ti[1];
3506
        } else {
3507
            /* A less accurate version */
3508
            s->ti -= s->current_tm.tm_mon * 2592000;
3509
            s->ti += omap_rtc_bin(value) * 2592000;
3510
        }
3511
        return;
3512

    
3513
    case 0x14:        /* YEARS_REG */
3514
#ifdef ALMDEBUG
3515
        printf("RTC YRS_REG <-- %02x\n", value);
3516
#endif
3517
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3518
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3519
        ti[0] = mktimegm(&s->current_tm);
3520
        ti[1] = mktimegm(&new_tm);
3521

    
3522
        if (ti[0] != -1 && ti[1] != -1) {
3523
            s->ti -= ti[0];
3524
            s->ti += ti[1];
3525
        } else {
3526
            /* A less accurate version */
3527
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3528
            s->ti += omap_rtc_bin(value) * 31536000;
3529
        }
3530
        return;
3531

    
3532
    case 0x18:        /* WEEK_REG */
3533
        return;        /* Ignored */
3534

    
3535
    case 0x20:        /* ALARM_SECONDS_REG */
3536
#ifdef ALMDEBUG
3537
        printf("ALM SEC_REG <-- %02x\n", value);
3538
#endif
3539
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3540
        omap_rtc_alarm_update(s);
3541
        return;
3542

    
3543
    case 0x24:        /* ALARM_MINUTES_REG */
3544
#ifdef ALMDEBUG
3545
        printf("ALM MIN_REG <-- %02x\n", value);
3546
#endif
3547
        s->alarm_tm.tm_min = omap_rtc_bin(value);
3548
        omap_rtc_alarm_update(s);
3549
        return;
3550

    
3551
    case 0x28:        /* ALARM_HOURS_REG */
3552
#ifdef ALMDEBUG
3553
        printf("ALM HRS_REG <-- %02x\n", value);
3554
#endif
3555
        if (s->pm_am)
3556
            s->alarm_tm.tm_hour =
3557
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
3558
                    ((value >> 7) & 1) * 12;
3559
        else
3560
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
3561
        omap_rtc_alarm_update(s);
3562
        return;
3563

    
3564
    case 0x2c:        /* ALARM_DAYS_REG */
3565
#ifdef ALMDEBUG
3566
        printf("ALM DAY_REG <-- %02x\n", value);
3567
#endif
3568
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3569
        omap_rtc_alarm_update(s);
3570
        return;
3571

    
3572
    case 0x30:        /* ALARM_MONTHS_REG */
3573
#ifdef ALMDEBUG
3574
        printf("ALM MON_REG <-- %02x\n", value);
3575
#endif
3576
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3577
        omap_rtc_alarm_update(s);
3578
        return;
3579

    
3580
    case 0x34:        /* ALARM_YEARS_REG */
3581
#ifdef ALMDEBUG
3582
        printf("ALM YRS_REG <-- %02x\n", value);
3583
#endif
3584
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3585
        omap_rtc_alarm_update(s);
3586
        return;
3587

    
3588
    case 0x40:        /* RTC_CTRL_REG */
3589
#ifdef ALMDEBUG
3590
        printf("RTC CONTROL <-- %02x\n", value);
3591
#endif
3592
        s->pm_am = (value >> 3) & 1;
3593
        s->auto_comp = (value >> 2) & 1;
3594
        s->round = (value >> 1) & 1;
3595
        s->running = value & 1;
3596
        s->status &= 0xfd;
3597
        s->status |= s->running << 1;
3598
        return;
3599

    
3600
    case 0x44:        /* RTC_STATUS_REG */
3601
#ifdef ALMDEBUG
3602
        printf("RTC STATUSL <-- %02x\n", value);
3603
#endif
3604
        s->status &= ~((value & 0xc0) ^ 0x80);
3605
        omap_rtc_interrupts_update(s);
3606
        return;
3607

    
3608
    case 0x48:        /* RTC_INTERRUPTS_REG */
3609
#ifdef ALMDEBUG
3610
        printf("RTC INTRS <-- %02x\n", value);
3611
#endif
3612
        s->interrupts = value;
3613
        return;
3614

    
3615
    case 0x4c:        /* RTC_COMP_LSB_REG */
3616
#ifdef ALMDEBUG
3617
        printf("RTC COMPLSB <-- %02x\n", value);
3618
#endif
3619
        s->comp_reg &= 0xff00;
3620
        s->comp_reg |= 0x00ff & value;
3621
        return;
3622

    
3623
    case 0x50:        /* RTC_COMP_MSB_REG */
3624
#ifdef ALMDEBUG
3625
        printf("RTC COMPMSB <-- %02x\n", value);
3626
#endif
3627
        s->comp_reg &= 0x00ff;
3628
        s->comp_reg |= 0xff00 & (value << 8);
3629
        return;
3630

    
3631
    default:
3632
        OMAP_BAD_REG(addr);
3633
        return;
3634
    }
3635
}
3636

    
3637
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3638
    omap_rtc_read,
3639
    omap_badwidth_read8,
3640
    omap_badwidth_read8,
3641
};
3642

    
3643
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3644
    omap_rtc_write,
3645
    omap_badwidth_write8,
3646
    omap_badwidth_write8,
3647
};
3648

    
3649
static void omap_rtc_tick(void *opaque)
3650
{
3651
    struct omap_rtc_s *s = opaque;
3652

    
3653
    if (s->round) {
3654
        /* Round to nearest full minute.  */
3655
        if (s->current_tm.tm_sec < 30)
3656
            s->ti -= s->current_tm.tm_sec;
3657
        else
3658
            s->ti += 60 - s->current_tm.tm_sec;
3659

    
3660
        s->round = 0;
3661
    }
3662

    
3663
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
3664

    
3665
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3666
        s->status |= 0x40;
3667
        omap_rtc_interrupts_update(s);
3668
    }
3669

    
3670
    if (s->interrupts & 0x04)
3671
        switch (s->interrupts & 3) {
3672
        case 0:
3673
            s->status |= 0x04;
3674
            qemu_irq_pulse(s->irq);
3675
            break;
3676
        case 1:
3677
            if (s->current_tm.tm_sec)
3678
                break;
3679
            s->status |= 0x08;
3680
            qemu_irq_pulse(s->irq);
3681
            break;
3682
        case 2:
3683
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
3684
                break;
3685
            s->status |= 0x10;
3686
            qemu_irq_pulse(s->irq);
3687
            break;
3688
        case 3:
3689
            if (s->current_tm.tm_sec ||
3690
                            s->current_tm.tm_min || s->current_tm.tm_hour)
3691
                break;
3692
            s->status |= 0x20;
3693
            qemu_irq_pulse(s->irq);
3694
            break;
3695
        }
3696

    
3697
    /* Move on */
3698
    if (s->running)
3699
        s->ti ++;
3700
    s->tick += 1000;
3701

    
3702
    /*
3703
     * Every full hour add a rough approximation of the compensation
3704
     * register to the 32kHz Timer (which drives the RTC) value. 
3705
     */
3706
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
3707
        s->tick += s->comp_reg * 1000 / 32768;
3708

    
3709
    qemu_mod_timer(s->clk, s->tick);
3710
}
3711

    
3712
static void omap_rtc_reset(struct omap_rtc_s *s)
3713
{
3714
    struct tm tm;
3715

    
3716
    s->interrupts = 0;
3717
    s->comp_reg = 0;
3718
    s->running = 0;
3719
    s->pm_am = 0;
3720
    s->auto_comp = 0;
3721
    s->round = 0;
3722
    s->tick = qemu_get_clock(rt_clock);
3723
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
3724
    s->alarm_tm.tm_mday = 0x01;
3725
    s->status = 1 << 7;
3726
    qemu_get_timedate(&tm, 0);
3727
    s->ti = mktimegm(&tm);
3728

    
3729
    omap_rtc_alarm_update(s);
3730
    omap_rtc_tick(s);
3731
}
3732

    
3733
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
3734
                qemu_irq *irq, omap_clk clk)
3735
{
3736
    int iomemtype;
3737
    struct omap_rtc_s *s = (struct omap_rtc_s *)
3738
            qemu_mallocz(sizeof(struct omap_rtc_s));
3739

    
3740
    s->irq = irq[0];
3741
    s->alarm = irq[1];
3742
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
3743

    
3744
    omap_rtc_reset(s);
3745

    
3746
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
3747
                    omap_rtc_writefn, s);
3748
    cpu_register_physical_memory(base, 0x800, iomemtype);
3749

    
3750
    return s;
3751
}
3752

    
3753
/* Multi-channel Buffered Serial Port interfaces */
3754
struct omap_mcbsp_s {
3755
    qemu_irq txirq;
3756
    qemu_irq rxirq;
3757
    qemu_irq txdrq;
3758
    qemu_irq rxdrq;
3759

    
3760
    uint16_t spcr[2];
3761
    uint16_t rcr[2];
3762
    uint16_t xcr[2];
3763
    uint16_t srgr[2];
3764
    uint16_t mcr[2];
3765
    uint16_t pcr;
3766
    uint16_t rcer[8];
3767
    uint16_t xcer[8];
3768
    int tx_rate;
3769
    int rx_rate;
3770
    int tx_req;
3771
    int rx_req;
3772

    
3773
    struct i2s_codec_s *codec;
3774
    QEMUTimer *source_timer;
3775
    QEMUTimer *sink_timer;
3776
};
3777

    
3778
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
3779
{
3780
    int irq;
3781

    
3782
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
3783
    case 0:
3784
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
3785
        break;
3786
    case 3:
3787
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
3788
        break;
3789
    default:
3790
        irq = 0;
3791
        break;
3792
    }
3793

    
3794
    if (irq)
3795
        qemu_irq_pulse(s->rxirq);
3796

    
3797
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
3798
    case 0:
3799
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
3800
        break;
3801
    case 3:
3802
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
3803
        break;
3804
    default:
3805
        irq = 0;
3806
        break;
3807
    }
3808

    
3809
    if (irq)
3810
        qemu_irq_pulse(s->txirq);
3811
}
3812

    
3813
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
3814
{
3815
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
3816
        s->spcr[0] |= 1 << 2;                                /* RFULL */
3817
    s->spcr[0] |= 1 << 1;                                /* RRDY */
3818
    qemu_irq_raise(s->rxdrq);
3819
    omap_mcbsp_intr_update(s);
3820
}
3821

    
3822
static void omap_mcbsp_source_tick(void *opaque)
3823
{
3824
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3825
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3826

    
3827
    if (!s->rx_rate)
3828
        return;
3829
    if (s->rx_req)
3830
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
3831

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

    
3834
    omap_mcbsp_rx_newdata(s);
3835
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
3836
}
3837

    
3838
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3839
{
3840
    if (!s->codec || !s->codec->rts)
3841
        omap_mcbsp_source_tick(s);
3842
    else if (s->codec->in.len) {
3843
        s->rx_req = s->codec->in.len;
3844
        omap_mcbsp_rx_newdata(s);
3845
    }
3846
}
3847

    
3848
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3849
{
3850
    qemu_del_timer(s->source_timer);
3851
}
3852

    
3853
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3854
{
3855
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
3856
    qemu_irq_lower(s->rxdrq);
3857
    omap_mcbsp_intr_update(s);
3858
}
3859

    
3860
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3861
{
3862
    s->spcr[1] |= 1 << 1;                                /* XRDY */
3863
    qemu_irq_raise(s->txdrq);
3864
    omap_mcbsp_intr_update(s);
3865
}
3866

    
3867
static void omap_mcbsp_sink_tick(void *opaque)
3868
{
3869
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3870
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3871

    
3872
    if (!s->tx_rate)
3873
        return;
3874
    if (s->tx_req)
3875
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
3876

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

    
3879
    omap_mcbsp_tx_newdata(s);
3880
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
3881
}
3882

    
3883
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3884
{
3885
    if (!s->codec || !s->codec->cts)
3886
        omap_mcbsp_sink_tick(s);
3887
    else if (s->codec->out.size) {
3888
        s->tx_req = s->codec->out.size;
3889
        omap_mcbsp_tx_newdata(s);
3890
    }
3891
}
3892

    
3893
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3894
{
3895
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
3896
    qemu_irq_lower(s->txdrq);
3897
    omap_mcbsp_intr_update(s);
3898
    if (s->codec && s->codec->cts)
3899
        s->codec->tx_swallow(s->codec->opaque);
3900
}
3901

    
3902
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3903
{
3904
    s->tx_req = 0;
3905
    omap_mcbsp_tx_done(s);
3906
    qemu_del_timer(s->sink_timer);
3907
}
3908

    
3909
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3910
{
3911
    int prev_rx_rate, prev_tx_rate;
3912
    int rx_rate = 0, tx_rate = 0;
3913
    int cpu_rate = 1500000;        /* XXX */
3914

    
3915
    /* TODO: check CLKSTP bit */
3916
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
3917
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
3918
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3919
                            (s->pcr & (1 << 8))) {        /* CLKRM */
3920
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3921
                    rx_rate = cpu_rate /
3922
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3923
            } else
3924
                if (s->codec)
3925
                    rx_rate = s->codec->rx_rate;
3926
        }
3927

    
3928
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
3929
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3930
                            (s->pcr & (1 << 9))) {        /* CLKXM */
3931
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3932
                    tx_rate = cpu_rate /
3933
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3934
            } else
3935
                if (s->codec)
3936
                    tx_rate = s->codec->tx_rate;
3937
        }
3938
    }
3939
    prev_tx_rate = s->tx_rate;
3940
    prev_rx_rate = s->rx_rate;
3941
    s->tx_rate = tx_rate;
3942
    s->rx_rate = rx_rate;
3943

    
3944
    if (s->codec)
3945
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3946

    
3947
    if (!prev_tx_rate && tx_rate)
3948
        omap_mcbsp_tx_start(s);
3949
    else if (s->tx_rate && !tx_rate)
3950
        omap_mcbsp_tx_stop(s);
3951

    
3952
    if (!prev_rx_rate && rx_rate)
3953
        omap_mcbsp_rx_start(s);
3954
    else if (prev_tx_rate && !tx_rate)
3955
        omap_mcbsp_rx_stop(s);
3956
}
3957

    
3958
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
3959
{
3960
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3961
    int offset = addr & OMAP_MPUI_REG_MASK;
3962
    uint16_t ret;
3963

    
3964
    switch (offset) {
3965
    case 0x00:        /* DRR2 */
3966
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
3967
            return 0x0000;
3968
        /* Fall through.  */
3969
    case 0x02:        /* DRR1 */
3970
        if (s->rx_req < 2) {
3971
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
3972
            omap_mcbsp_rx_done(s);
3973
        } else {
3974
            s->tx_req -= 2;
3975
            if (s->codec && s->codec->in.len >= 2) {
3976
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3977
                ret |= s->codec->in.fifo[s->codec->in.start ++];
3978
                s->codec->in.len -= 2;
3979
            } else
3980
                ret = 0x0000;
3981
            if (!s->tx_req)
3982
                omap_mcbsp_rx_done(s);
3983
            return ret;
3984
        }
3985
        return 0x0000;
3986

    
3987
    case 0x04:        /* DXR2 */
3988
    case 0x06:        /* DXR1 */
3989
        return 0x0000;
3990

    
3991
    case 0x08:        /* SPCR2 */
3992
        return s->spcr[1];
3993
    case 0x0a:        /* SPCR1 */
3994
        return s->spcr[0];
3995
    case 0x0c:        /* RCR2 */
3996
        return s->rcr[1];
3997
    case 0x0e:        /* RCR1 */
3998
        return s->rcr[0];
3999
    case 0x10:        /* XCR2 */
4000
        return s->xcr[1];
4001
    case 0x12:        /* XCR1 */
4002
        return s->xcr[0];
4003
    case 0x14:        /* SRGR2 */
4004
        return s->srgr[1];
4005
    case 0x16:        /* SRGR1 */
4006
        return s->srgr[0];
4007
    case 0x18:        /* MCR2 */
4008
        return s->mcr[1];
4009
    case 0x1a:        /* MCR1 */
4010
        return s->mcr[0];
4011
    case 0x1c:        /* RCERA */
4012
        return s->rcer[0];
4013
    case 0x1e:        /* RCERB */
4014
        return s->rcer[1];
4015
    case 0x20:        /* XCERA */
4016
        return s->xcer[0];
4017
    case 0x22:        /* XCERB */
4018
        return s->xcer[1];
4019
    case 0x24:        /* PCR0 */
4020
        return s->pcr;
4021
    case 0x26:        /* RCERC */
4022
        return s->rcer[2];
4023
    case 0x28:        /* RCERD */
4024
        return s->rcer[3];
4025
    case 0x2a:        /* XCERC */
4026
        return s->xcer[2];
4027
    case 0x2c:        /* XCERD */
4028
        return s->xcer[3];
4029
    case 0x2e:        /* RCERE */
4030
        return s->rcer[4];
4031
    case 0x30:        /* RCERF */
4032
        return s->rcer[5];
4033
    case 0x32:        /* XCERE */
4034
        return s->xcer[4];
4035
    case 0x34:        /* XCERF */
4036
        return s->xcer[5];
4037
    case 0x36:        /* RCERG */
4038
        return s->rcer[6];
4039
    case 0x38:        /* RCERH */
4040
        return s->rcer[7];
4041
    case 0x3a:        /* XCERG */
4042
        return s->xcer[6];
4043
    case 0x3c:        /* XCERH */
4044
        return s->xcer[7];
4045
    }
4046

    
4047
    OMAP_BAD_REG(addr);
4048
    return 0;
4049
}
4050

    
4051
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
4052
                uint32_t value)
4053
{
4054
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4055
    int offset = addr & OMAP_MPUI_REG_MASK;
4056

    
4057
    switch (offset) {
4058
    case 0x00:        /* DRR2 */
4059
    case 0x02:        /* DRR1 */
4060
        OMAP_RO_REG(addr);
4061
        return;
4062

    
4063
    case 0x04:        /* DXR2 */
4064
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4065
            return;
4066
        /* Fall through.  */
4067
    case 0x06:        /* DXR1 */
4068
        if (s->tx_req > 1) {
4069
            s->tx_req -= 2;
4070
            if (s->codec && s->codec->cts) {
4071
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
4072
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
4073
            }
4074
            if (s->tx_req < 2)
4075
                omap_mcbsp_tx_done(s);
4076
        } else
4077
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4078
        return;
4079

    
4080
    case 0x08:        /* SPCR2 */
4081
        s->spcr[1] &= 0x0002;
4082
        s->spcr[1] |= 0x03f9 & value;
4083
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
4084
        if (~value & 1)                                        /* XRST */
4085
            s->spcr[1] &= ~6;
4086
        omap_mcbsp_req_update(s);
4087
        return;
4088
    case 0x0a:        /* SPCR1 */
4089
        s->spcr[0] &= 0x0006;
4090
        s->spcr[0] |= 0xf8f9 & value;
4091
        if (value & (1 << 15))                                /* DLB */
4092
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
4093
        if (~value & 1) {                                /* RRST */
4094
            s->spcr[0] &= ~6;
4095
            s->rx_req = 0;
4096
            omap_mcbsp_rx_done(s);
4097
        }
4098
        omap_mcbsp_req_update(s);
4099
        return;
4100

    
4101
    case 0x0c:        /* RCR2 */
4102
        s->rcr[1] = value & 0xffff;
4103
        return;
4104
    case 0x0e:        /* RCR1 */
4105
        s->rcr[0] = value & 0x7fe0;
4106
        return;
4107
    case 0x10:        /* XCR2 */
4108
        s->xcr[1] = value & 0xffff;
4109
        return;
4110
    case 0x12:        /* XCR1 */
4111
        s->xcr[0] = value & 0x7fe0;
4112
        return;
4113
    case 0x14:        /* SRGR2 */
4114
        s->srgr[1] = value & 0xffff;
4115
        omap_mcbsp_req_update(s);
4116
        return;
4117
    case 0x16:        /* SRGR1 */
4118
        s->srgr[0] = value & 0xffff;
4119
        omap_mcbsp_req_update(s);
4120
        return;
4121
    case 0x18:        /* MCR2 */
4122
        s->mcr[1] = value & 0x03e3;
4123
        if (value & 3)                                        /* XMCM */
4124
            printf("%s: Tx channel selection mode enable attempt\n",
4125
                            __FUNCTION__);
4126
        return;
4127
    case 0x1a:        /* MCR1 */
4128
        s->mcr[0] = value & 0x03e1;
4129
        if (value & 1)                                        /* RMCM */
4130
            printf("%s: Rx channel selection mode enable attempt\n",
4131
                            __FUNCTION__);
4132
        return;
4133
    case 0x1c:        /* RCERA */
4134
        s->rcer[0] = value & 0xffff;
4135
        return;
4136
    case 0x1e:        /* RCERB */
4137
        s->rcer[1] = value & 0xffff;
4138
        return;
4139
    case 0x20:        /* XCERA */
4140
        s->xcer[0] = value & 0xffff;
4141
        return;
4142
    case 0x22:        /* XCERB */
4143
        s->xcer[1] = value & 0xffff;
4144
        return;
4145
    case 0x24:        /* PCR0 */
4146
        s->pcr = value & 0x7faf;
4147
        return;
4148
    case 0x26:        /* RCERC */
4149
        s->rcer[2] = value & 0xffff;
4150
        return;
4151
    case 0x28:        /* RCERD */
4152
        s->rcer[3] = value & 0xffff;
4153
        return;
4154
    case 0x2a:        /* XCERC */
4155
        s->xcer[2] = value & 0xffff;
4156
        return;
4157
    case 0x2c:        /* XCERD */
4158
        s->xcer[3] = value & 0xffff;
4159
        return;
4160
    case 0x2e:        /* RCERE */
4161
        s->rcer[4] = value & 0xffff;
4162
        return;
4163
    case 0x30:        /* RCERF */
4164
        s->rcer[5] = value & 0xffff;
4165
        return;
4166
    case 0x32:        /* XCERE */
4167
        s->xcer[4] = value & 0xffff;
4168
        return;
4169
    case 0x34:        /* XCERF */
4170
        s->xcer[5] = value & 0xffff;
4171
        return;
4172
    case 0x36:        /* RCERG */
4173
        s->rcer[6] = value & 0xffff;
4174
        return;
4175
    case 0x38:        /* RCERH */
4176
        s->rcer[7] = value & 0xffff;
4177
        return;
4178
    case 0x3a:        /* XCERG */
4179
        s->xcer[6] = value & 0xffff;
4180
        return;
4181
    case 0x3c:        /* XCERH */
4182
        s->xcer[7] = value & 0xffff;
4183
        return;
4184
    }
4185

    
4186
    OMAP_BAD_REG(addr);
4187
}
4188

    
4189
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
4190
                uint32_t value)
4191
{
4192
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4193
    int offset = addr & OMAP_MPUI_REG_MASK;
4194

    
4195
    if (offset == 0x04) {                                /* DXR */
4196
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4197
            return;
4198
        if (s->tx_req > 3) {
4199
            s->tx_req -= 4;
4200
            if (s->codec && s->codec->cts) {
4201
                s->codec->out.fifo[s->codec->out.len ++] =
4202
                        (value >> 24) & 0xff;
4203
                s->codec->out.fifo[s->codec->out.len ++] =
4204
                        (value >> 16) & 0xff;
4205
                s->codec->out.fifo[s->codec->out.len ++] =
4206
                        (value >> 8) & 0xff;
4207
                s->codec->out.fifo[s->codec->out.len ++] =
4208
                        (value >> 0) & 0xff;
4209
            }
4210
            if (s->tx_req < 4)
4211
                omap_mcbsp_tx_done(s);
4212
        } else
4213
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4214
        return;
4215
    }
4216

    
4217
    omap_badwidth_write16(opaque, addr, value);
4218
}
4219

    
4220
static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
4221
    omap_badwidth_read16,
4222
    omap_mcbsp_read,
4223
    omap_badwidth_read16,
4224
};
4225

    
4226
static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
4227
    omap_badwidth_write16,
4228
    omap_mcbsp_writeh,
4229
    omap_mcbsp_writew,
4230
};
4231

    
4232
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
4233
{
4234
    memset(&s->spcr, 0, sizeof(s->spcr));
4235
    memset(&s->rcr, 0, sizeof(s->rcr));
4236
    memset(&s->xcr, 0, sizeof(s->xcr));
4237
    s->srgr[0] = 0x0001;
4238
    s->srgr[1] = 0x2000;
4239
    memset(&s->mcr, 0, sizeof(s->mcr));
4240
    memset(&s->pcr, 0, sizeof(s->pcr));
4241
    memset(&s->rcer, 0, sizeof(s->rcer));
4242
    memset(&s->xcer, 0, sizeof(s->xcer));
4243
    s->tx_req = 0;
4244
    s->rx_req = 0;
4245
    s->tx_rate = 0;
4246
    s->rx_rate = 0;
4247
    qemu_del_timer(s->source_timer);
4248
    qemu_del_timer(s->sink_timer);
4249
}
4250

    
4251
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
4252
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
4253
{
4254
    int iomemtype;
4255
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
4256
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
4257

    
4258
    s->txirq = irq[0];
4259
    s->rxirq = irq[1];
4260
    s->txdrq = dma[0];
4261
    s->rxdrq = dma[1];
4262
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
4263
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
4264
    omap_mcbsp_reset(s);
4265

    
4266
    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
4267
                    omap_mcbsp_writefn, s);
4268
    cpu_register_physical_memory(base, 0x800, iomemtype);
4269

    
4270
    return s;
4271
}
4272

    
4273
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4274
{
4275
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4276

    
4277
    if (s->rx_rate) {
4278
        s->rx_req = s->codec->in.len;
4279
        omap_mcbsp_rx_newdata(s);
4280
    }
4281
}
4282

    
4283
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
4284
{
4285
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4286

    
4287
    if (s->tx_rate) {
4288
        s->tx_req = s->codec->out.size;
4289
        omap_mcbsp_tx_newdata(s);
4290
    }
4291
}
4292

    
4293
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
4294
{
4295
    s->codec = slave;
4296
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4297
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4298
}
4299

    
4300
/* LED Pulse Generators */
4301
struct omap_lpg_s {
4302
    QEMUTimer *tm;
4303

    
4304
    uint8_t control;
4305
    uint8_t power;
4306
    int64_t on;
4307
    int64_t period;
4308
    int clk;
4309
    int cycle;
4310
};
4311

    
4312
static void omap_lpg_tick(void *opaque)
4313
{
4314
    struct omap_lpg_s *s = opaque;
4315

    
4316
    if (s->cycle)
4317
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
4318
    else
4319
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
4320

    
4321
    s->cycle = !s->cycle;
4322
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
4323
}
4324

    
4325
static void omap_lpg_update(struct omap_lpg_s *s)
4326
{
4327
    int64_t on, period = 1, ticks = 1000;
4328
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
4329

    
4330
    if (~s->control & (1 << 6))                                        /* LPGRES */
4331
        on = 0;
4332
    else if (s->control & (1 << 7))                                /* PERM_ON */
4333
        on = period;
4334
    else {
4335
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
4336
                        256 / 32);
4337
        on = (s->clk && s->power) ? muldiv64(ticks,
4338
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
4339
    }
4340

    
4341
    qemu_del_timer(s->tm);
4342
    if (on == period && s->on < s->period)
4343
        printf("%s: LED is on\n", __FUNCTION__);
4344
    else if (on == 0 && s->on)
4345
        printf("%s: LED is off\n", __FUNCTION__);
4346
    else if (on && (on != s->on || period != s->period)) {
4347
        s->cycle = 0;
4348
        s->on = on;
4349
        s->period = period;
4350
        omap_lpg_tick(s);
4351
        return;
4352
    }
4353

    
4354
    s->on = on;
4355
    s->period = period;
4356
}
4357

    
4358
static void omap_lpg_reset(struct omap_lpg_s *s)
4359
{
4360
    s->control = 0x00;
4361
    s->power = 0x00;
4362
    s->clk = 1;
4363
    omap_lpg_update(s);
4364
}
4365

    
4366
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
4367
{
4368
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4369
    int offset = addr & OMAP_MPUI_REG_MASK;
4370

    
4371
    switch (offset) {
4372
    case 0x00:        /* LCR */
4373
        return s->control;
4374

    
4375
    case 0x04:        /* PMR */
4376
        return s->power;
4377
    }
4378

    
4379
    OMAP_BAD_REG(addr);
4380
    return 0;
4381
}
4382

    
4383
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
4384
                uint32_t value)
4385
{
4386
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4387
    int offset = addr & OMAP_MPUI_REG_MASK;
4388

    
4389
    switch (offset) {
4390
    case 0x00:        /* LCR */
4391
        if (~value & (1 << 6))                                        /* LPGRES */
4392
            omap_lpg_reset(s);
4393
        s->control = value & 0xff;
4394
        omap_lpg_update(s);
4395
        return;
4396

    
4397
    case 0x04:        /* PMR */
4398
        s->power = value & 0x01;
4399
        omap_lpg_update(s);
4400
        return;
4401

    
4402
    default:
4403
        OMAP_BAD_REG(addr);
4404
        return;
4405
    }
4406
}
4407

    
4408
static CPUReadMemoryFunc *omap_lpg_readfn[] = {
4409
    omap_lpg_read,
4410
    omap_badwidth_read8,
4411
    omap_badwidth_read8,
4412
};
4413

    
4414
static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
4415
    omap_lpg_write,
4416
    omap_badwidth_write8,
4417
    omap_badwidth_write8,
4418
};
4419

    
4420
static void omap_lpg_clk_update(void *opaque, int line, int on)
4421
{
4422
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4423

    
4424
    s->clk = on;
4425
    omap_lpg_update(s);
4426
}
4427

    
4428
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4429
{
4430
    int iomemtype;
4431
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4432
            qemu_mallocz(sizeof(struct omap_lpg_s));
4433

    
4434
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4435

    
4436
    omap_lpg_reset(s);
4437

    
4438
    iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
4439
                    omap_lpg_writefn, s);
4440
    cpu_register_physical_memory(base, 0x800, iomemtype);
4441

    
4442
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4443

    
4444
    return s;
4445
}
4446

    
4447
/* MPUI Peripheral Bridge configuration */
4448
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
4449
{
4450
    if (addr == OMAP_MPUI_BASE)        /* CMR */
4451
        return 0xfe4d;
4452

    
4453
    OMAP_BAD_REG(addr);
4454
    return 0;
4455
}
4456

    
4457
static CPUReadMemoryFunc *omap_mpui_io_readfn[] = {
4458
    omap_badwidth_read16,
4459
    omap_mpui_io_read,
4460
    omap_badwidth_read16,
4461
};
4462

    
4463
static CPUWriteMemoryFunc *omap_mpui_io_writefn[] = {
4464
    omap_badwidth_write16,
4465
    omap_badwidth_write16,
4466
    omap_badwidth_write16,
4467
};
4468

    
4469
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4470
{
4471
    int iomemtype = cpu_register_io_memory(0, omap_mpui_io_readfn,
4472
                    omap_mpui_io_writefn, mpu);
4473
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
4474
}
4475

    
4476
/* General chip reset */
4477
static void omap1_mpu_reset(void *opaque)
4478
{
4479
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4480

    
4481
    omap_inth_reset(mpu->ih[0]);
4482
    omap_inth_reset(mpu->ih[1]);
4483
    omap_dma_reset(mpu->dma);
4484
    omap_mpu_timer_reset(mpu->timer[0]);
4485
    omap_mpu_timer_reset(mpu->timer[1]);
4486
    omap_mpu_timer_reset(mpu->timer[2]);
4487
    omap_wd_timer_reset(mpu->wdt);
4488
    omap_os_timer_reset(mpu->os_timer);
4489
    omap_lcdc_reset(mpu->lcd);
4490
    omap_ulpd_pm_reset(mpu);
4491
    omap_pin_cfg_reset(mpu);
4492
    omap_mpui_reset(mpu);
4493
    omap_tipb_bridge_reset(mpu->private_tipb);
4494
    omap_tipb_bridge_reset(mpu->public_tipb);
4495
    omap_dpll_reset(&mpu->dpll[0]);
4496
    omap_dpll_reset(&mpu->dpll[1]);
4497
    omap_dpll_reset(&mpu->dpll[2]);
4498
    omap_uart_reset(mpu->uart[0]);
4499
    omap_uart_reset(mpu->uart[1]);
4500
    omap_uart_reset(mpu->uart[2]);
4501
    omap_mmc_reset(mpu->mmc);
4502
    omap_mpuio_reset(mpu->mpuio);
4503
    omap_gpio_reset(mpu->gpio);
4504
    omap_uwire_reset(mpu->microwire);
4505
    omap_pwl_reset(mpu);
4506
    omap_pwt_reset(mpu);
4507
    omap_i2c_reset(mpu->i2c[0]);
4508
    omap_rtc_reset(mpu->rtc);
4509
    omap_mcbsp_reset(mpu->mcbsp1);
4510
    omap_mcbsp_reset(mpu->mcbsp2);
4511
    omap_mcbsp_reset(mpu->mcbsp3);
4512
    omap_lpg_reset(mpu->led[0]);
4513
    omap_lpg_reset(mpu->led[1]);
4514
    omap_clkm_reset(mpu);
4515
    cpu_reset(mpu->env);
4516
}
4517

    
4518
static const struct omap_map_s {
4519
    target_phys_addr_t phys_dsp;
4520
    target_phys_addr_t phys_mpu;
4521
    uint32_t size;
4522
    const char *name;
4523
} omap15xx_dsp_mm[] = {
4524
    /* Strobe 0 */
4525
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
4526
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
4527
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
4528
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
4529
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
4530
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
4531
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
4532
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
4533
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
4534
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
4535
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
4536
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
4537
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
4538
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
4539
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
4540
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
4541
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
4542
    /* Strobe 1 */
4543
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
4544

    
4545
    { 0 }
4546
};
4547

    
4548
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4549
{
4550
    int io;
4551

    
4552
    for (; map->phys_dsp; map ++) {
4553
        io = cpu_get_physical_page_desc(map->phys_mpu);
4554

    
4555
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4556
    }
4557
}
4558

    
4559
void omap_mpu_wakeup(void *opaque, int irq, int req)
4560
{
4561
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4562

    
4563
    if (mpu->env->halted)
4564
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4565
}
4566

    
4567
static const struct dma_irq_map omap1_dma_irq_map[] = {
4568
    { 0, OMAP_INT_DMA_CH0_6 },
4569
    { 0, OMAP_INT_DMA_CH1_7 },
4570
    { 0, OMAP_INT_DMA_CH2_8 },
4571
    { 0, OMAP_INT_DMA_CH3 },
4572
    { 0, OMAP_INT_DMA_CH4 },
4573
    { 0, OMAP_INT_DMA_CH5 },
4574
    { 1, OMAP_INT_1610_DMA_CH6 },
4575
    { 1, OMAP_INT_1610_DMA_CH7 },
4576
    { 1, OMAP_INT_1610_DMA_CH8 },
4577
    { 1, OMAP_INT_1610_DMA_CH9 },
4578
    { 1, OMAP_INT_1610_DMA_CH10 },
4579
    { 1, OMAP_INT_1610_DMA_CH11 },
4580
    { 1, OMAP_INT_1610_DMA_CH12 },
4581
    { 1, OMAP_INT_1610_DMA_CH13 },
4582
    { 1, OMAP_INT_1610_DMA_CH14 },
4583
    { 1, OMAP_INT_1610_DMA_CH15 }
4584
};
4585

    
4586
/* DMA ports for OMAP1 */
4587
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
4588
                target_phys_addr_t addr)
4589
{
4590
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
4591
}
4592

    
4593
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
4594
                target_phys_addr_t addr)
4595
{
4596
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
4597
}
4598

    
4599
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
4600
                target_phys_addr_t addr)
4601
{
4602
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
4603
}
4604

    
4605
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
4606
                target_phys_addr_t addr)
4607
{
4608
    return addr >= 0xfffb0000 && addr < 0xffff0000;
4609
}
4610

    
4611
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
4612
                target_phys_addr_t addr)
4613
{
4614
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
4615
}
4616

    
4617
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
4618
                target_phys_addr_t addr)
4619
{
4620
    return addr >= 0xe1010000 && addr < 0xe1020004;
4621
}
4622

    
4623
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4624
                const char *core)
4625
{
4626
    int i;
4627
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4628
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4629
    ram_addr_t imif_base, emiff_base;
4630
    qemu_irq *cpu_irq;
4631
    qemu_irq dma_irqs[6];
4632
    int sdindex;
4633

    
4634
    if (!core)
4635
        core = "ti925t";
4636

    
4637
    /* Core */
4638
    s->mpu_model = omap310;
4639
    s->env = cpu_init(core);
4640
    if (!s->env) {
4641
        fprintf(stderr, "Unable to find CPU definition\n");
4642
        exit(1);
4643
    }
4644
    s->sdram_size = sdram_size;
4645
    s->sram_size = OMAP15XX_SRAM_SIZE;
4646

    
4647
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4648

    
4649
    /* Clocks */
4650
    omap_clk_init(s);
4651

    
4652
    /* Memory-mapped stuff */
4653
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4654
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4655
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4656
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4657

    
4658
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4659

    
4660
    cpu_irq = arm_pic_init_cpu(s->env);
4661
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
4662
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4663
                    omap_findclk(s, "arminth_ck"));
4664
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1],
4665
                    s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
4666
                    omap_findclk(s, "arminth_ck"));
4667

    
4668
    for (i = 0; i < 6; i ++)
4669
        dma_irqs[i] =
4670
                s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr];
4671
    s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
4672
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
4673

    
4674
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4675
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4676
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4677
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4678
    s->port[local    ].addr_valid = omap_validate_local_addr;
4679
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4680

    
4681
    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
4682
    soc_dma_port_add_mem_ram(s->dma,
4683
                    emiff_base, OMAP_EMIFF_BASE, s->sdram_size);
4684
    soc_dma_port_add_mem_ram(s->dma,
4685
                    imif_base, OMAP_IMIF_BASE, s->sram_size);
4686

    
4687
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4688
                    s->irq[0][OMAP_INT_TIMER1],
4689
                    omap_findclk(s, "mputim_ck"));
4690
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4691
                    s->irq[0][OMAP_INT_TIMER2],
4692
                    omap_findclk(s, "mputim_ck"));
4693
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4694
                    s->irq[0][OMAP_INT_TIMER3],
4695
                    omap_findclk(s, "mputim_ck"));
4696

    
4697
    s->wdt = omap_wd_timer_init(0xfffec800,
4698
                    s->irq[0][OMAP_INT_WD_TIMER],
4699
                    omap_findclk(s, "armwdt_ck"));
4700

    
4701
    s->os_timer = omap_os_timer_init(0xfffb9000,
4702
                    s->irq[1][OMAP_INT_OS_TIMER],
4703
                    omap_findclk(s, "clk32-kHz"));
4704

    
4705
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4706
                    omap_dma_get_lcdch(s->dma), imif_base, emiff_base,
4707
                    omap_findclk(s, "lcd_ck"));
4708

    
4709
    omap_ulpd_pm_init(0xfffe0800, s);
4710
    omap_pin_cfg_init(0xfffe1000, s);
4711
    omap_id_init(s);
4712

    
4713
    omap_mpui_init(0xfffec900, s);
4714

    
4715
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4716
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4717
                    omap_findclk(s, "tipb_ck"));
4718
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4719
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4720
                    omap_findclk(s, "tipb_ck"));
4721

    
4722
    omap_tcmi_init(0xfffecc00, s);
4723

    
4724
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4725
                    omap_findclk(s, "uart1_ck"),
4726
                    omap_findclk(s, "uart1_ck"),
4727
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
4728
                    serial_hds[0]);
4729
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4730
                    omap_findclk(s, "uart2_ck"),
4731
                    omap_findclk(s, "uart2_ck"),
4732
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
4733
                    serial_hds[0] ? serial_hds[1] : 0);
4734
    s->uart[2] = omap_uart_init(0xfffb9800, s->irq[0][OMAP_INT_UART3],
4735
                    omap_findclk(s, "uart3_ck"),
4736
                    omap_findclk(s, "uart3_ck"),
4737
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
4738
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4739

    
4740
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4741
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4742
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4743

    
4744
    sdindex = drive_get_index(IF_SD, 0, 0);
4745
    if (sdindex == -1) {
4746
        fprintf(stderr, "qemu: missing SecureDigital device\n");
4747
        exit(1);
4748
    }
4749
    s->mmc = omap_mmc_init(0xfffb7800, drives_table[sdindex].bdrv,
4750
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
4751
                    omap_findclk(s, "mmc_ck"));
4752

    
4753
    s->mpuio = omap_mpuio_init(0xfffb5000,
4754
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4755
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
4756

    
4757
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4758
                    omap_findclk(s, "arm_gpio_ck"));
4759

    
4760
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4761
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4762

    
4763
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4764
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4765

    
4766
    s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4767
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4768

    
4769
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4770
                    omap_findclk(s, "clk32-kHz"));
4771

    
4772
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
4773
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4774
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
4775
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4776
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
4777
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4778

    
4779
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
4780
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
4781

    
4782
    /* Register mappings not currenlty implemented:
4783
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4784
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4785
     * USB W2FC                fffb4000 - fffb47ff
4786
     * Camera Interface        fffb6800 - fffb6fff
4787
     * USB Host                fffba000 - fffba7ff
4788
     * FAC                fffba800 - fffbafff
4789
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4790
     * TIPB switches        fffbc800 - fffbcfff
4791
     * Mailbox                fffcf000 - fffcf7ff
4792
     * Local bus IF        fffec100 - fffec1ff
4793
     * Local bus MMU        fffec200 - fffec2ff
4794
     * DSP MMU                fffed200 - fffed2ff
4795
     */
4796

    
4797
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
4798
    omap_setup_mpui_io(s);
4799

    
4800
    qemu_register_reset(omap1_mpu_reset, s);
4801

    
4802
    return s;
4803
}