Statistics
| Branch: | Revision:

root / hw / omap1.c @ fad6cb1a

History | View | Annotate | Download (131.8 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
            cpu_abort(cpu_single_env, "%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
            cpu_abort(cpu_single_env, "%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"), 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"), 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
        cpu_abort(cpu_single_env, "%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
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
2786
                        __FUNCTION__, col, row);
2787

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

    
2793
    omap_mpuio_kbd_update(s);
2794
}
2795

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2962
    return s;
2963
}
2964

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3132
    return s;
3133
}
3134

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3227
    omap_pwl_reset(s);
3228

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3661
        s->round = 0;
3662
    }
3663

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

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

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

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

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

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

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

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

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

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

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

    
3745
    omap_rtc_reset(s);
3746

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

    
3751
    return s;
3752
}
3753

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4187
    OMAP_BAD_REG(addr);
4188
}
4189

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

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

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

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

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

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

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

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

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

    
4271
    return s;
4272
}
4273

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4437
    omap_lpg_reset(s);
4438

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

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

    
4445
    return s;
4446
}
4447

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

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

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

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

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

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

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

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

    
4546
    { 0 }
4547
};
4548

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4714
    omap_mpui_init(0xfffec900, s);
4715

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

    
4723
    omap_tcmi_init(0xfffecc00, s);
4724

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4801
    qemu_register_reset(omap1_mpu_reset, s);
4802

    
4803
    return s;
4804
}