Statistics
| Branch: | Revision:

root / hw / omap1.c @ 75554a3c

History | View | Annotate | Download (133.1 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
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19
 * MA 02111-1307 USA
20
 */
21
#include "hw.h"
22
#include "arm-misc.h"
23
#include "omap.h"
24
#include "sysemu.h"
25
#include "qemu-timer.h"
26
#include "qemu-char.h"
27
#include "soc_dma.h"
28
/* We use pc-style serial ports.  */
29
#include "pc.h"
30

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
153
#define INT_FALLING_EDGE        0
154
#define INT_LOW_LEVEL                1
155

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

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

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

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

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

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

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

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

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

    
215
    case 0x04:        /* MIR */
216
        return bank->mask;
217

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

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

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

    
271
    case 0x9c:        /* ISR */
272
        return 0x00000000;
273

    
274
    }
275
    OMAP_BAD_REG(addr);
276
    return 0;
277
}
278

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

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

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

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

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

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

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

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

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

    
384
void omap_inth_reset(struct omap_intr_handler_s *s)
385
{
386
    int i;
387

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

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

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

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

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

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

    
429
    omap_inth_reset(s);
430

    
431
    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
432
                    omap_inth_writefn, s);
433
    cpu_register_physical_memory(s->base, size, iomemtype);
434

    
435
    return s;
436
}
437

    
438
static uint32_t omap2_inth_read(void *opaque, target_phys_addr_t addr)
439
{
440
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
441
    int offset = addr - s->base;
442
    int bank_no, line_no;
443
    struct omap_intr_handler_bank_s *bank = 0;
444

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

    
453
    switch (offset) {
454
    case 0x00:        /* INTC_REVISION */
455
        return 0x21;
456

    
457
    case 0x10:        /* INTC_SYSCONFIG */
458
        return (s->autoidle >> 2) & 1;
459

    
460
    case 0x14:        /* INTC_SYSSTATUS */
461
        return 1;                                                /* RESETDONE */
462

    
463
    case 0x40:        /* INTC_SIR_IRQ */
464
        return s->sir_intr[0];
465

    
466
    case 0x44:        /* INTC_SIR_FIQ */
467
        return s->sir_intr[1];
468

    
469
    case 0x48:        /* INTC_CONTROL */
470
        return (!s->mask) << 2;                                        /* GLOBALMASK */
471

    
472
    case 0x4c:        /* INTC_PROTECTION */
473
        return 0;
474

    
475
    case 0x50:        /* INTC_IDLE */
476
        return s->autoidle & 3;
477

    
478
    /* Per-bank registers */
479
    case 0x80:        /* INTC_ITR */
480
        return bank->inputs;
481

    
482
    case 0x84:        /* INTC_MIR */
483
        return bank->mask;
484

    
485
    case 0x88:        /* INTC_MIR_CLEAR */
486
    case 0x8c:        /* INTC_MIR_SET */
487
        return 0;
488

    
489
    case 0x90:        /* INTC_ISR_SET */
490
        return bank->swi;
491

    
492
    case 0x94:        /* INTC_ISR_CLEAR */
493
        return 0;
494

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

    
498
    case 0x9c:        /* INTC_PENDING_FIQ */
499
        return bank->irqs & ~bank->mask & bank->fiq;
500

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

    
515
static void omap2_inth_write(void *opaque, target_phys_addr_t addr,
516
                uint32_t value)
517
{
518
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
519
    int offset = addr - s->base;
520
    int bank_no, line_no;
521
    struct omap_intr_handler_bank_s *bank = 0;
522

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

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

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

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

    
561
    case 0x50:        /* INTC_IDLE */
562
        s->autoidle &= ~3;
563
        s->autoidle |= value & 3;
564
        return;
565

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

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

    
579
    case 0x8c:        /* INTC_MIR_SET */
580
        bank->mask |= value;
581
        return;
582

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

    
589
    case 0x94:        /* INTC_ISR_CLEAR */
590
        bank->swi &= ~value;
591
        bank->irqs = bank->swi & bank->inputs;
592
        return;
593

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

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

    
619
static CPUReadMemoryFunc *omap2_inth_readfn[] = {
620
    omap_badwidth_read32,
621
    omap_badwidth_read32,
622
    omap2_inth_read,
623
};
624

    
625
static CPUWriteMemoryFunc *omap2_inth_writefn[] = {
626
    omap2_inth_write,
627
    omap2_inth_write,
628
    omap2_inth_write,
629
};
630

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

    
641
    s->parent_intr[0] = parent_irq;
642
    s->parent_intr[1] = parent_fiq;
643
    s->base = base;
644
    s->nbanks = nbanks;
645
    s->level_only = 1;
646
    s->pins = qemu_allocate_irqs(omap_set_intr_noedge, s, nbanks * 32);
647
    if (pins)
648
        *pins = s->pins;
649

    
650
    omap_inth_reset(s);
651

    
652
    iomemtype = cpu_register_io_memory(0, omap2_inth_readfn,
653
                    omap2_inth_writefn, s);
654
    cpu_register_physical_memory(s->base, size, iomemtype);
655

    
656
    return s;
657
}
658

    
659
/* MPU OS timers */
660
struct omap_mpu_timer_s {
661
    qemu_irq irq;
662
    omap_clk clk;
663
    target_phys_addr_t base;
664
    uint32_t val;
665
    int64_t time;
666
    QEMUTimer *timer;
667
    int64_t rate;
668
    int it_ena;
669

    
670
    int enable;
671
    int ptv;
672
    int ar;
673
    int st;
674
    uint32_t reset_val;
675
};
676

    
677
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
678
{
679
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
680

    
681
    if (timer->st && timer->enable && timer->rate)
682
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
683
                        timer->rate, ticks_per_sec);
684
    else
685
        return timer->val;
686
}
687

    
688
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
689
{
690
    timer->val = omap_timer_read(timer);
691
    timer->time = qemu_get_clock(vm_clock);
692
}
693

    
694
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
695
{
696
    int64_t expires;
697

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

    
703
        /* If timer expiry would be sooner than in about 1 ms and
704
         * auto-reload isn't set, then fire immediately.  This is a hack
705
         * to make systems like PalmOS run in acceptable time.  PalmOS
706
         * sets the interval to a very low value and polls the status bit
707
         * in a busy loop when it wants to sleep just a couple of CPU
708
         * ticks.  */
709
        if (expires > (ticks_per_sec >> 10) || timer->ar)
710
            qemu_mod_timer(timer->timer, timer->time + expires);
711
        else {
712
            timer->val = 0;
713
            timer->st = 0;
714
            if (timer->it_ena)
715
                /* Edge-triggered irq */
716
                qemu_irq_pulse(timer->irq);
717
        }
718
    } else
719
        qemu_del_timer(timer->timer);
720
}
721

    
722
static void omap_timer_tick(void *opaque)
723
{
724
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
725
    omap_timer_sync(timer);
726

    
727
    if (!timer->ar) {
728
        timer->val = 0;
729
        timer->st = 0;
730
    }
731

    
732
    if (timer->it_ena)
733
        /* Edge-triggered irq */
734
        qemu_irq_pulse(timer->irq);
735
    omap_timer_update(timer);
736
}
737

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

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

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

    
754
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
755
{
756
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
757
    int offset = addr - s->base;
758

    
759
    switch (offset) {
760
    case 0x00:        /* CNTL_TIMER */
761
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
762

    
763
    case 0x04:        /* LOAD_TIM */
764
        break;
765

    
766
    case 0x08:        /* READ_TIM */
767
        return omap_timer_read(s);
768
    }
769

    
770
    OMAP_BAD_REG(addr);
771
    return 0;
772
}
773

    
774
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
775
                uint32_t value)
776
{
777
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
778
    int offset = addr - s->base;
779

    
780
    switch (offset) {
781
    case 0x00:        /* CNTL_TIMER */
782
        omap_timer_sync(s);
783
        s->enable = (value >> 5) & 1;
784
        s->ptv = (value >> 2) & 7;
785
        s->ar = (value >> 1) & 1;
786
        s->st = value & 1;
787
        omap_timer_update(s);
788
        return;
789

    
790
    case 0x04:        /* LOAD_TIM */
791
        s->reset_val = value;
792
        return;
793

    
794
    case 0x08:        /* READ_TIM */
795
        OMAP_RO_REG(addr);
796
        break;
797

    
798
    default:
799
        OMAP_BAD_REG(addr);
800
    }
801
}
802

    
803
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
804
    omap_badwidth_read32,
805
    omap_badwidth_read32,
806
    omap_mpu_timer_read,
807
};
808

    
809
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
810
    omap_badwidth_write32,
811
    omap_badwidth_write32,
812
    omap_mpu_timer_write,
813
};
814

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

    
827
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
828
                qemu_irq irq, omap_clk clk)
829
{
830
    int iomemtype;
831
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
832
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
833

    
834
    s->irq = irq;
835
    s->clk = clk;
836
    s->base = base;
837
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
838
    omap_mpu_timer_reset(s);
839
    omap_timer_clk_setup(s);
840

    
841
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
842
                    omap_mpu_timer_writefn, s);
843
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
844

    
845
    return s;
846
}
847

    
848
/* Watchdog timer */
849
struct omap_watchdog_timer_s {
850
    struct omap_mpu_timer_s timer;
851
    uint8_t last_wr;
852
    int mode;
853
    int free;
854
    int reset;
855
};
856

    
857
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
858
{
859
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
860
    int offset = addr - s->timer.base;
861

    
862
    switch (offset) {
863
    case 0x00:        /* CNTL_TIMER */
864
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
865
                (s->timer.st << 7) | (s->free << 1);
866

    
867
    case 0x04:        /* READ_TIMER */
868
        return omap_timer_read(&s->timer);
869

    
870
    case 0x08:        /* TIMER_MODE */
871
        return s->mode << 15;
872
    }
873

    
874
    OMAP_BAD_REG(addr);
875
    return 0;
876
}
877

    
878
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
879
                uint32_t value)
880
{
881
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
882
    int offset = addr - s->timer.base;
883

    
884
    switch (offset) {
885
    case 0x00:        /* CNTL_TIMER */
886
        omap_timer_sync(&s->timer);
887
        s->timer.ptv = (value >> 9) & 7;
888
        s->timer.ar = (value >> 8) & 1;
889
        s->timer.st = (value >> 7) & 1;
890
        s->free = (value >> 1) & 1;
891
        omap_timer_update(&s->timer);
892
        break;
893

    
894
    case 0x04:        /* LOAD_TIMER */
895
        s->timer.reset_val = value & 0xffff;
896
        break;
897

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

    
918
    default:
919
        OMAP_BAD_REG(addr);
920
    }
921
}
922

    
923
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
924
    omap_badwidth_read16,
925
    omap_wd_timer_read,
926
    omap_badwidth_read16,
927
};
928

    
929
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
930
    omap_badwidth_write16,
931
    omap_wd_timer_write,
932
    omap_badwidth_write16,
933
};
934

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

    
953
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
954
                qemu_irq irq, omap_clk clk)
955
{
956
    int iomemtype;
957
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
958
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
959

    
960
    s->timer.irq = irq;
961
    s->timer.clk = clk;
962
    s->timer.base = base;
963
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
964
    omap_wd_timer_reset(s);
965
    omap_timer_clk_setup(&s->timer);
966

    
967
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
968
                    omap_wd_timer_writefn, s);
969
    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
970

    
971
    return s;
972
}
973

    
974
/* 32-kHz timer */
975
struct omap_32khz_timer_s {
976
    struct omap_mpu_timer_s timer;
977
};
978

    
979
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
980
{
981
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
982
    int offset = addr & OMAP_MPUI_REG_MASK;
983

    
984
    switch (offset) {
985
    case 0x00:        /* TVR */
986
        return s->timer.reset_val;
987

    
988
    case 0x04:        /* TCR */
989
        return omap_timer_read(&s->timer);
990

    
991
    case 0x08:        /* CR */
992
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
993

    
994
    default:
995
        break;
996
    }
997
    OMAP_BAD_REG(addr);
998
    return 0;
999
}
1000

    
1001
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
1002
                uint32_t value)
1003
{
1004
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
1005
    int offset = addr & OMAP_MPUI_REG_MASK;
1006

    
1007
    switch (offset) {
1008
    case 0x00:        /* TVR */
1009
        s->timer.reset_val = value & 0x00ffffff;
1010
        break;
1011

    
1012
    case 0x04:        /* TCR */
1013
        OMAP_RO_REG(addr);
1014
        break;
1015

    
1016
    case 0x08:        /* CR */
1017
        s->timer.ar = (value >> 3) & 1;
1018
        s->timer.it_ena = (value >> 2) & 1;
1019
        if (s->timer.st != (value & 1) || (value & 2)) {
1020
            omap_timer_sync(&s->timer);
1021
            s->timer.enable = value & 1;
1022
            s->timer.st = value & 1;
1023
            omap_timer_update(&s->timer);
1024
        }
1025
        break;
1026

    
1027
    default:
1028
        OMAP_BAD_REG(addr);
1029
    }
1030
}
1031

    
1032
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
1033
    omap_badwidth_read32,
1034
    omap_badwidth_read32,
1035
    omap_os_timer_read,
1036
};
1037

    
1038
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
1039
    omap_badwidth_write32,
1040
    omap_badwidth_write32,
1041
    omap_os_timer_write,
1042
};
1043

    
1044
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
1045
{
1046
    qemu_del_timer(s->timer.timer);
1047
    s->timer.enable = 0;
1048
    s->timer.it_ena = 0;
1049
    s->timer.reset_val = 0x00ffffff;
1050
    s->timer.val = 0;
1051
    s->timer.st = 0;
1052
    s->timer.ptv = 0;
1053
    s->timer.ar = 1;
1054
}
1055

    
1056
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
1057
                qemu_irq irq, omap_clk clk)
1058
{
1059
    int iomemtype;
1060
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
1061
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
1062

    
1063
    s->timer.irq = irq;
1064
    s->timer.clk = clk;
1065
    s->timer.base = base;
1066
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
1067
    omap_os_timer_reset(s);
1068
    omap_timer_clk_setup(&s->timer);
1069

    
1070
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
1071
                    omap_os_timer_writefn, s);
1072
    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
1073

    
1074
    return s;
1075
}
1076

    
1077
/* Ultra Low-Power Device Module */
1078
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
1079
{
1080
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1081
    int offset = addr - s->ulpd_pm_base;
1082
    uint16_t ret;
1083

    
1084
    switch (offset) {
1085
    case 0x14:        /* IT_STATUS */
1086
        ret = s->ulpd_pm_regs[offset >> 2];
1087
        s->ulpd_pm_regs[offset >> 2] = 0;
1088
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
1089
        return ret;
1090

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

    
1115
    OMAP_BAD_REG(addr);
1116
    return 0;
1117
}
1118

    
1119
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
1120
                uint16_t diff, uint16_t value)
1121
{
1122
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
1123
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
1124
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
1125
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
1126
}
1127

    
1128
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
1129
                uint16_t diff, uint16_t value)
1130
{
1131
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
1132
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
1133
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
1134
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
1135
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
1136
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
1137
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
1138
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
1139
}
1140

    
1141
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
1142
                uint32_t value)
1143
{
1144
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1145
    int offset = addr - s->ulpd_pm_base;
1146
    int64_t now, ticks;
1147
    int div, mult;
1148
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1149
    uint16_t diff;
1150

    
1151
    switch (offset) {
1152
    case 0x00:        /* COUNTER_32_LSB */
1153
    case 0x04:        /* COUNTER_32_MSB */
1154
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
1155
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
1156
    case 0x14:        /* IT_STATUS */
1157
    case 0x40:        /* STATUS_REQ */
1158
        OMAP_RO_REG(addr);
1159
        break;
1160

    
1161
    case 0x10:        /* GAUGING_CTRL */
1162
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
1163
        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
1164
            now = qemu_get_clock(vm_clock);
1165

    
1166
            if (value & 1)
1167
                s->ulpd_gauge_start = now;
1168
            else {
1169
                now -= s->ulpd_gauge_start;
1170

    
1171
                /* 32-kHz ticks */
1172
                ticks = muldiv64(now, 32768, ticks_per_sec);
1173
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
1174
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
1175
                if (ticks >> 32)        /* OVERFLOW_32K */
1176
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
1177

    
1178
                /* High frequency ticks */
1179
                ticks = muldiv64(now, 12000000, ticks_per_sec);
1180
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
1181
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
1182
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
1183
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
1184

    
1185
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
1186
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
1187
            }
1188
        }
1189
        s->ulpd_pm_regs[offset >> 2] = value;
1190
        break;
1191

    
1192
    case 0x18:        /* Reserved */
1193
    case 0x1c:        /* Reserved */
1194
    case 0x20:        /* Reserved */
1195
    case 0x28:        /* Reserved */
1196
    case 0x2c:        /* Reserved */
1197
        OMAP_BAD_REG(addr);
1198
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
1199
    case 0x38:        /* COUNTER_32_FIQ */
1200
    case 0x48:        /* LOCL_TIME */
1201
    case 0x50:        /* POWER_CTRL */
1202
        s->ulpd_pm_regs[offset >> 2] = value;
1203
        break;
1204

    
1205
    case 0x30:        /* CLOCK_CTRL */
1206
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1207
        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
1208
        omap_ulpd_clk_update(s, diff, value);
1209
        break;
1210

    
1211
    case 0x34:        /* SOFT_REQ */
1212
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
1213
        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
1214
        omap_ulpd_req_update(s, diff, value);
1215
        break;
1216

    
1217
    case 0x3c:        /* DPLL_CTRL */
1218
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
1219
         * omitted altogether, probably a typo.  */
1220
        /* This register has identical semantics with DPLL(1:3) control
1221
         * registers, see omap_dpll_write() */
1222
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1223
        s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
1224
        if (diff & (0x3ff << 2)) {
1225
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1226
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1227
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1228
            } else {
1229
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1230
                mult = 1;
1231
            }
1232
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
1233
        }
1234

    
1235
        /* Enter the desired mode.  */
1236
        s->ulpd_pm_regs[offset >> 2] =
1237
                (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
1238
                ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
1239

    
1240
        /* Act as if the lock is restored.  */
1241
        s->ulpd_pm_regs[offset >> 2] |= 2;
1242
        break;
1243

    
1244
    case 0x4c:        /* APLL_CTRL */
1245
        diff = s->ulpd_pm_regs[offset >> 2] & value;
1246
        s->ulpd_pm_regs[offset >> 2] = value & 0xf;
1247
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
1248
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
1249
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
1250
        break;
1251

    
1252
    default:
1253
        OMAP_BAD_REG(addr);
1254
    }
1255
}
1256

    
1257
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1258
    omap_badwidth_read16,
1259
    omap_ulpd_pm_read,
1260
    omap_badwidth_read16,
1261
};
1262

    
1263
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1264
    omap_badwidth_write16,
1265
    omap_ulpd_pm_write,
1266
    omap_badwidth_write16,
1267
};
1268

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

    
1296
static void omap_ulpd_pm_init(target_phys_addr_t base,
1297
                struct omap_mpu_state_s *mpu)
1298
{
1299
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1300
                    omap_ulpd_pm_writefn, mpu);
1301

    
1302
    mpu->ulpd_pm_base = base;
1303
    cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1304
    omap_ulpd_pm_reset(mpu);
1305
}
1306

    
1307
/* OMAP Pin Configuration */
1308
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1309
{
1310
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1311
    int offset = addr - s->pin_cfg_base;
1312

    
1313
    switch (offset) {
1314
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1315
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1316
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1317
        return s->func_mux_ctrl[offset >> 2];
1318

    
1319
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1320
        return s->comp_mode_ctrl[0];
1321

    
1322
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1323
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1324
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1325
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1326
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1327
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1328
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1329
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1330
    case 0x30:        /* FUNC_MUX_CTRL_B */
1331
    case 0x34:        /* FUNC_MUX_CTRL_C */
1332
    case 0x38:        /* FUNC_MUX_CTRL_D */
1333
        return s->func_mux_ctrl[(offset >> 2) - 1];
1334

    
1335
    case 0x40:        /* PULL_DWN_CTRL_0 */
1336
    case 0x44:        /* PULL_DWN_CTRL_1 */
1337
    case 0x48:        /* PULL_DWN_CTRL_2 */
1338
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1339
        return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1340

    
1341
    case 0x50:        /* GATE_INH_CTRL_0 */
1342
        return s->gate_inh_ctrl[0];
1343

    
1344
    case 0x60:        /* VOLTAGE_CTRL_0 */
1345
        return s->voltage_ctrl[0];
1346

    
1347
    case 0x70:        /* TEST_DBG_CTRL_0 */
1348
        return s->test_dbg_ctrl[0];
1349

    
1350
    case 0x80:        /* MOD_CONF_CTRL_0 */
1351
        return s->mod_conf_ctrl[0];
1352
    }
1353

    
1354
    OMAP_BAD_REG(addr);
1355
    return 0;
1356
}
1357

    
1358
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1359
                uint32_t diff, uint32_t value)
1360
{
1361
    if (s->compat1509) {
1362
        if (diff & (1 << 9))                        /* BLUETOOTH */
1363
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1364
                            (~value >> 9) & 1);
1365
        if (diff & (1 << 7))                        /* USB.CLKO */
1366
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
1367
                            (value >> 7) & 1);
1368
    }
1369
}
1370

    
1371
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1372
                uint32_t diff, uint32_t value)
1373
{
1374
    if (s->compat1509) {
1375
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
1376
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1377
                            (value >> 31) & 1);
1378
        if (diff & (1 << 1))                        /* CLK32K */
1379
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1380
                            (~value >> 1) & 1);
1381
    }
1382
}
1383

    
1384
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1385
                uint32_t diff, uint32_t value)
1386
{
1387
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
1388
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1389
                         omap_findclk(s, ((value >> 31) & 1) ?
1390
                                 "ck_48m" : "armper_ck"));
1391
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
1392
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1393
                         omap_findclk(s, ((value >> 30) & 1) ?
1394
                                 "ck_48m" : "armper_ck"));
1395
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
1396
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1397
                         omap_findclk(s, ((value >> 29) & 1) ?
1398
                                 "ck_48m" : "armper_ck"));
1399
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
1400
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1401
                         omap_findclk(s, ((value >> 23) & 1) ?
1402
                                 "ck_48m" : "armper_ck"));
1403
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
1404
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1405
                         omap_findclk(s, ((value >> 12) & 1) ?
1406
                                 "ck_48m" : "armper_ck"));
1407
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1408
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1409
}
1410

    
1411
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1412
                uint32_t value)
1413
{
1414
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1415
    int offset = addr - s->pin_cfg_base;
1416
    uint32_t diff;
1417

    
1418
    switch (offset) {
1419
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1420
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1421
        s->func_mux_ctrl[offset >> 2] = value;
1422
        omap_pin_funcmux0_update(s, diff, value);
1423
        return;
1424

    
1425
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1426
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1427
        s->func_mux_ctrl[offset >> 2] = value;
1428
        omap_pin_funcmux1_update(s, diff, value);
1429
        return;
1430

    
1431
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1432
        s->func_mux_ctrl[offset >> 2] = value;
1433
        return;
1434

    
1435
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1436
        s->comp_mode_ctrl[0] = value;
1437
        s->compat1509 = (value != 0x0000eaef);
1438
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1439
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1440
        return;
1441

    
1442
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1443
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1444
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1445
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1446
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1447
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1448
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1449
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1450
    case 0x30:        /* FUNC_MUX_CTRL_B */
1451
    case 0x34:        /* FUNC_MUX_CTRL_C */
1452
    case 0x38:        /* FUNC_MUX_CTRL_D */
1453
        s->func_mux_ctrl[(offset >> 2) - 1] = value;
1454
        return;
1455

    
1456
    case 0x40:        /* PULL_DWN_CTRL_0 */
1457
    case 0x44:        /* PULL_DWN_CTRL_1 */
1458
    case 0x48:        /* PULL_DWN_CTRL_2 */
1459
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1460
        s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1461
        return;
1462

    
1463
    case 0x50:        /* GATE_INH_CTRL_0 */
1464
        s->gate_inh_ctrl[0] = value;
1465
        return;
1466

    
1467
    case 0x60:        /* VOLTAGE_CTRL_0 */
1468
        s->voltage_ctrl[0] = value;
1469
        return;
1470

    
1471
    case 0x70:        /* TEST_DBG_CTRL_0 */
1472
        s->test_dbg_ctrl[0] = value;
1473
        return;
1474

    
1475
    case 0x80:        /* MOD_CONF_CTRL_0 */
1476
        diff = s->mod_conf_ctrl[0] ^ value;
1477
        s->mod_conf_ctrl[0] = value;
1478
        omap_pin_modconf1_update(s, diff, value);
1479
        return;
1480

    
1481
    default:
1482
        OMAP_BAD_REG(addr);
1483
    }
1484
}
1485

    
1486
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1487
    omap_badwidth_read32,
1488
    omap_badwidth_read32,
1489
    omap_pin_cfg_read,
1490
};
1491

    
1492
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1493
    omap_badwidth_write32,
1494
    omap_badwidth_write32,
1495
    omap_pin_cfg_write,
1496
};
1497

    
1498
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1499
{
1500
    /* Start in Compatibility Mode.  */
1501
    mpu->compat1509 = 1;
1502
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1503
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1504
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1505
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1506
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1507
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1508
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1509
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1510
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1511
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1512
}
1513

    
1514
static void omap_pin_cfg_init(target_phys_addr_t base,
1515
                struct omap_mpu_state_s *mpu)
1516
{
1517
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1518
                    omap_pin_cfg_writefn, mpu);
1519

    
1520
    mpu->pin_cfg_base = base;
1521
    cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1522
    omap_pin_cfg_reset(mpu);
1523
}
1524

    
1525
/* Device Identification, Die Identification */
1526
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1527
{
1528
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1529

    
1530
    switch (addr) {
1531
    case 0xfffe1800:        /* DIE_ID_LSB */
1532
        return 0xc9581f0e;
1533
    case 0xfffe1804:        /* DIE_ID_MSB */
1534
        return 0xa8858bfa;
1535

    
1536
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
1537
        return 0x00aaaafc;
1538
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
1539
        return 0xcafeb574;
1540

    
1541
    case 0xfffed400:        /* JTAG_ID_LSB */
1542
        switch (s->mpu_model) {
1543
        case omap310:
1544
            return 0x03310315;
1545
        case omap1510:
1546
            return 0x03310115;
1547
        default:
1548
            cpu_abort(cpu_single_env, "%s: bad mpu model\n", __FUNCTION__);
1549
        }
1550
        break;
1551

    
1552
    case 0xfffed404:        /* JTAG_ID_MSB */
1553
        switch (s->mpu_model) {
1554
        case omap310:
1555
            return 0xfb57402f;
1556
        case omap1510:
1557
            return 0xfb47002f;
1558
        default:
1559
            cpu_abort(cpu_single_env, "%s: bad mpu model\n", __FUNCTION__);
1560
        }
1561
        break;
1562
    }
1563

    
1564
    OMAP_BAD_REG(addr);
1565
    return 0;
1566
}
1567

    
1568
static void omap_id_write(void *opaque, target_phys_addr_t addr,
1569
                uint32_t value)
1570
{
1571
    OMAP_BAD_REG(addr);
1572
}
1573

    
1574
static CPUReadMemoryFunc *omap_id_readfn[] = {
1575
    omap_badwidth_read32,
1576
    omap_badwidth_read32,
1577
    omap_id_read,
1578
};
1579

    
1580
static CPUWriteMemoryFunc *omap_id_writefn[] = {
1581
    omap_badwidth_write32,
1582
    omap_badwidth_write32,
1583
    omap_id_write,
1584
};
1585

    
1586
static void omap_id_init(struct omap_mpu_state_s *mpu)
1587
{
1588
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
1589
                    omap_id_writefn, mpu);
1590
    cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
1591
    cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
1592
    if (!cpu_is_omap15xx(mpu))
1593
        cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
1594
}
1595

    
1596
/* MPUI Control (Dummy) */
1597
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1598
{
1599
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1600
    int offset = addr - s->mpui_base;
1601

    
1602
    switch (offset) {
1603
    case 0x00:        /* CTRL */
1604
        return s->mpui_ctrl;
1605
    case 0x04:        /* DEBUG_ADDR */
1606
        return 0x01ffffff;
1607
    case 0x08:        /* DEBUG_DATA */
1608
        return 0xffffffff;
1609
    case 0x0c:        /* DEBUG_FLAG */
1610
        return 0x00000800;
1611
    case 0x10:        /* STATUS */
1612
        return 0x00000000;
1613

    
1614
    /* Not in OMAP310 */
1615
    case 0x14:        /* DSP_STATUS */
1616
    case 0x18:        /* DSP_BOOT_CONFIG */
1617
        return 0x00000000;
1618
    case 0x1c:        /* DSP_MPUI_CONFIG */
1619
        return 0x0000ffff;
1620
    }
1621

    
1622
    OMAP_BAD_REG(addr);
1623
    return 0;
1624
}
1625

    
1626
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
1627
                uint32_t value)
1628
{
1629
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1630
    int offset = addr - s->mpui_base;
1631

    
1632
    switch (offset) {
1633
    case 0x00:        /* CTRL */
1634
        s->mpui_ctrl = value & 0x007fffff;
1635
        break;
1636

    
1637
    case 0x04:        /* DEBUG_ADDR */
1638
    case 0x08:        /* DEBUG_DATA */
1639
    case 0x0c:        /* DEBUG_FLAG */
1640
    case 0x10:        /* STATUS */
1641
    /* Not in OMAP310 */
1642
    case 0x14:        /* DSP_STATUS */
1643
        OMAP_RO_REG(addr);
1644
    case 0x18:        /* DSP_BOOT_CONFIG */
1645
    case 0x1c:        /* DSP_MPUI_CONFIG */
1646
        break;
1647

    
1648
    default:
1649
        OMAP_BAD_REG(addr);
1650
    }
1651
}
1652

    
1653
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
1654
    omap_badwidth_read32,
1655
    omap_badwidth_read32,
1656
    omap_mpui_read,
1657
};
1658

    
1659
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
1660
    omap_badwidth_write32,
1661
    omap_badwidth_write32,
1662
    omap_mpui_write,
1663
};
1664

    
1665
static void omap_mpui_reset(struct omap_mpu_state_s *s)
1666
{
1667
    s->mpui_ctrl = 0x0003ff1b;
1668
}
1669

    
1670
static void omap_mpui_init(target_phys_addr_t base,
1671
                struct omap_mpu_state_s *mpu)
1672
{
1673
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
1674
                    omap_mpui_writefn, mpu);
1675

    
1676
    mpu->mpui_base = base;
1677
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
1678

    
1679
    omap_mpui_reset(mpu);
1680
}
1681

    
1682
/* TIPB Bridges */
1683
struct omap_tipb_bridge_s {
1684
    target_phys_addr_t base;
1685
    qemu_irq abort;
1686

    
1687
    int width_intr;
1688
    uint16_t control;
1689
    uint16_t alloc;
1690
    uint16_t buffer;
1691
    uint16_t enh_control;
1692
};
1693

    
1694
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
1695
{
1696
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1697
    int offset = addr - s->base;
1698

    
1699
    switch (offset) {
1700
    case 0x00:        /* TIPB_CNTL */
1701
        return s->control;
1702
    case 0x04:        /* TIPB_BUS_ALLOC */
1703
        return s->alloc;
1704
    case 0x08:        /* MPU_TIPB_CNTL */
1705
        return s->buffer;
1706
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1707
        return s->enh_control;
1708
    case 0x10:        /* ADDRESS_DBG */
1709
    case 0x14:        /* DATA_DEBUG_LOW */
1710
    case 0x18:        /* DATA_DEBUG_HIGH */
1711
        return 0xffff;
1712
    case 0x1c:        /* DEBUG_CNTR_SIG */
1713
        return 0x00f8;
1714
    }
1715

    
1716
    OMAP_BAD_REG(addr);
1717
    return 0;
1718
}
1719

    
1720
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
1721
                uint32_t value)
1722
{
1723
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1724
    int offset = addr - s->base;
1725

    
1726
    switch (offset) {
1727
    case 0x00:        /* TIPB_CNTL */
1728
        s->control = value & 0xffff;
1729
        break;
1730

    
1731
    case 0x04:        /* TIPB_BUS_ALLOC */
1732
        s->alloc = value & 0x003f;
1733
        break;
1734

    
1735
    case 0x08:        /* MPU_TIPB_CNTL */
1736
        s->buffer = value & 0x0003;
1737
        break;
1738

    
1739
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1740
        s->width_intr = !(value & 2);
1741
        s->enh_control = value & 0x000f;
1742
        break;
1743

    
1744
    case 0x10:        /* ADDRESS_DBG */
1745
    case 0x14:        /* DATA_DEBUG_LOW */
1746
    case 0x18:        /* DATA_DEBUG_HIGH */
1747
    case 0x1c:        /* DEBUG_CNTR_SIG */
1748
        OMAP_RO_REG(addr);
1749
        break;
1750

    
1751
    default:
1752
        OMAP_BAD_REG(addr);
1753
    }
1754
}
1755

    
1756
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
1757
    omap_badwidth_read16,
1758
    omap_tipb_bridge_read,
1759
    omap_tipb_bridge_read,
1760
};
1761

    
1762
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
1763
    omap_badwidth_write16,
1764
    omap_tipb_bridge_write,
1765
    omap_tipb_bridge_write,
1766
};
1767

    
1768
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1769
{
1770
    s->control = 0xffff;
1771
    s->alloc = 0x0009;
1772
    s->buffer = 0x0000;
1773
    s->enh_control = 0x000f;
1774
}
1775

    
1776
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
1777
                qemu_irq abort_irq, omap_clk clk)
1778
{
1779
    int iomemtype;
1780
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
1781
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
1782

    
1783
    s->abort = abort_irq;
1784
    s->base = base;
1785
    omap_tipb_bridge_reset(s);
1786

    
1787
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
1788
                    omap_tipb_bridge_writefn, s);
1789
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1790

    
1791
    return s;
1792
}
1793

    
1794
/* Dummy Traffic Controller's Memory Interface */
1795
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
1796
{
1797
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1798
    int offset = addr - s->tcmi_base;
1799
    uint32_t ret;
1800

    
1801
    switch (offset) {
1802
    case 0x00:        /* IMIF_PRIO */
1803
    case 0x04:        /* EMIFS_PRIO */
1804
    case 0x08:        /* EMIFF_PRIO */
1805
    case 0x0c:        /* EMIFS_CONFIG */
1806
    case 0x10:        /* EMIFS_CS0_CONFIG */
1807
    case 0x14:        /* EMIFS_CS1_CONFIG */
1808
    case 0x18:        /* EMIFS_CS2_CONFIG */
1809
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1810
    case 0x24:        /* EMIFF_MRS */
1811
    case 0x28:        /* TIMEOUT1 */
1812
    case 0x2c:        /* TIMEOUT2 */
1813
    case 0x30:        /* TIMEOUT3 */
1814
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1815
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1816
        return s->tcmi_regs[offset >> 2];
1817

    
1818
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1819
        ret = s->tcmi_regs[offset >> 2];
1820
        s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1821
        /* XXX: We can try using the VGA_DIRTY flag for this */
1822
        return ret;
1823
    }
1824

    
1825
    OMAP_BAD_REG(addr);
1826
    return 0;
1827
}
1828

    
1829
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
1830
                uint32_t value)
1831
{
1832
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1833
    int offset = addr - s->tcmi_base;
1834

    
1835
    switch (offset) {
1836
    case 0x00:        /* IMIF_PRIO */
1837
    case 0x04:        /* EMIFS_PRIO */
1838
    case 0x08:        /* EMIFF_PRIO */
1839
    case 0x10:        /* EMIFS_CS0_CONFIG */
1840
    case 0x14:        /* EMIFS_CS1_CONFIG */
1841
    case 0x18:        /* EMIFS_CS2_CONFIG */
1842
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1843
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1844
    case 0x24:        /* EMIFF_MRS */
1845
    case 0x28:        /* TIMEOUT1 */
1846
    case 0x2c:        /* TIMEOUT2 */
1847
    case 0x30:        /* TIMEOUT3 */
1848
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1849
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1850
        s->tcmi_regs[offset >> 2] = value;
1851
        break;
1852
    case 0x0c:        /* EMIFS_CONFIG */
1853
        s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
1854
        break;
1855

    
1856
    default:
1857
        OMAP_BAD_REG(addr);
1858
    }
1859
}
1860

    
1861
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
1862
    omap_badwidth_read32,
1863
    omap_badwidth_read32,
1864
    omap_tcmi_read,
1865
};
1866

    
1867
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
1868
    omap_badwidth_write32,
1869
    omap_badwidth_write32,
1870
    omap_tcmi_write,
1871
};
1872

    
1873
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1874
{
1875
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1876
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1877
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1878
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1879
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1880
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1881
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1882
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1883
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1884
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1885
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1886
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1887
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1888
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1889
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1890
}
1891

    
1892
static void omap_tcmi_init(target_phys_addr_t base,
1893
                struct omap_mpu_state_s *mpu)
1894
{
1895
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
1896
                    omap_tcmi_writefn, mpu);
1897

    
1898
    mpu->tcmi_base = base;
1899
    cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
1900
    omap_tcmi_reset(mpu);
1901
}
1902

    
1903
/* Digital phase-locked loops control */
1904
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
1905
{
1906
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1907
    int offset = addr - s->base;
1908

    
1909
    if (offset == 0x00)        /* CTL_REG */
1910
        return s->mode;
1911

    
1912
    OMAP_BAD_REG(addr);
1913
    return 0;
1914
}
1915

    
1916
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
1917
                uint32_t value)
1918
{
1919
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1920
    uint16_t diff;
1921
    int offset = addr - s->base;
1922
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1923
    int div, mult;
1924

    
1925
    if (offset == 0x00) {        /* CTL_REG */
1926
        /* See omap_ulpd_pm_write() too */
1927
        diff = s->mode & value;
1928
        s->mode = value & 0x2fff;
1929
        if (diff & (0x3ff << 2)) {
1930
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1931
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1932
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1933
            } else {
1934
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1935
                mult = 1;
1936
            }
1937
            omap_clk_setrate(s->dpll, div, mult);
1938
        }
1939

    
1940
        /* Enter the desired mode.  */
1941
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1942

    
1943
        /* Act as if the lock is restored.  */
1944
        s->mode |= 2;
1945
    } else {
1946
        OMAP_BAD_REG(addr);
1947
    }
1948
}
1949

    
1950
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
1951
    omap_badwidth_read16,
1952
    omap_dpll_read,
1953
    omap_badwidth_read16,
1954
};
1955

    
1956
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
1957
    omap_badwidth_write16,
1958
    omap_dpll_write,
1959
    omap_badwidth_write16,
1960
};
1961

    
1962
static void omap_dpll_reset(struct dpll_ctl_s *s)
1963
{
1964
    s->mode = 0x2002;
1965
    omap_clk_setrate(s->dpll, 1, 1);
1966
}
1967

    
1968
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
1969
                omap_clk clk)
1970
{
1971
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
1972
                    omap_dpll_writefn, s);
1973

    
1974
    s->base = base;
1975
    s->dpll = clk;
1976
    omap_dpll_reset(s);
1977

    
1978
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1979
}
1980

    
1981
/* UARTs */
1982
struct omap_uart_s {
1983
    SerialState *serial; /* TODO */
1984
    struct omap_target_agent_s *ta;
1985
    target_phys_addr_t base;
1986
    omap_clk fclk;
1987
    qemu_irq irq;
1988

    
1989
    uint8_t eblr;
1990
    uint8_t syscontrol;
1991
    uint8_t wkup;
1992
    uint8_t cfps;
1993
    uint8_t mdr[2];
1994
    uint8_t scr;
1995
};
1996

    
1997
void omap_uart_reset(struct omap_uart_s *s)
1998
{
1999
    s->eblr = 0x00;
2000
    s->syscontrol = 0;
2001
    s->wkup = 0x3f;
2002
    s->cfps = 0x69;
2003
}
2004

    
2005
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
2006
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
2007
                qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr)
2008
{
2009
    struct omap_uart_s *s = (struct omap_uart_s *)
2010
            qemu_mallocz(sizeof(struct omap_uart_s));
2011

    
2012
    s->base = base;
2013
    s->fclk = fclk;
2014
    s->irq = irq;
2015
    s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
2016
                               chr ?: qemu_chr_open("null"), 1);
2017

    
2018
    return s;
2019
}
2020

    
2021
static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr)
2022
{
2023
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
2024
    int offset = addr - s->base;
2025

    
2026
    switch (offset) {
2027
    case 0x20:        /* MDR1 */
2028
        return s->mdr[0];
2029
    case 0x24:        /* MDR2 */
2030
        return s->mdr[1];
2031
    case 0x40:        /* SCR */
2032
        return s->scr;
2033
    case 0x44:        /* SSR */
2034
        return 0x0;
2035
    case 0x48:        /* EBLR */
2036
        return s->eblr;
2037
    case 0x50:        /* MVR */
2038
        return 0x30;
2039
    case 0x54:        /* SYSC */
2040
        return s->syscontrol;
2041
    case 0x58:        /* SYSS */
2042
        return 1;
2043
    case 0x5c:        /* WER */
2044
        return s->wkup;
2045
    case 0x60:        /* CFPS */
2046
        return s->cfps;
2047
    }
2048

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

    
2053
static void omap_uart_write(void *opaque, target_phys_addr_t addr,
2054
                uint32_t value)
2055
{
2056
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
2057
    int offset = addr - s->base;
2058

    
2059
    switch (offset) {
2060
    case 0x20:        /* MDR1 */
2061
        s->mdr[0] = value & 0x7f;
2062
        break;
2063
    case 0x24:        /* MDR2 */
2064
        s->mdr[1] = value & 0xff;
2065
        break;
2066
    case 0x40:        /* SCR */
2067
        s->scr = value & 0xff;
2068
        break;
2069
    case 0x48:        /* EBLR */
2070
        s->eblr = value & 0xff;
2071
        break;
2072
    case 0x44:        /* SSR */
2073
    case 0x50:        /* MVR */
2074
    case 0x58:        /* SYSS */
2075
        OMAP_RO_REG(addr);
2076
        break;
2077
    case 0x54:        /* SYSC */
2078
        s->syscontrol = value & 0x1d;
2079
        if (value & 2)
2080
            omap_uart_reset(s);
2081
        break;
2082
    case 0x5c:        /* WER */
2083
        s->wkup = value & 0x7f;
2084
        break;
2085
    case 0x60:        /* CFPS */
2086
        s->cfps = value & 0xff;
2087
        break;
2088
    default:
2089
        OMAP_BAD_REG(addr);
2090
    }
2091
}
2092

    
2093
static CPUReadMemoryFunc *omap_uart_readfn[] = {
2094
    omap_uart_read,
2095
    omap_uart_read,
2096
    omap_badwidth_read8,
2097
};
2098

    
2099
static CPUWriteMemoryFunc *omap_uart_writefn[] = {
2100
    omap_uart_write,
2101
    omap_uart_write,
2102
    omap_badwidth_write8,
2103
};
2104

    
2105
struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta,
2106
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
2107
                qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr)
2108
{
2109
    target_phys_addr_t base = omap_l4_attach(ta, 0, 0);
2110
    struct omap_uart_s *s = omap_uart_init(base, irq,
2111
                    fclk, iclk, txdma, rxdma, chr);
2112
    int iomemtype = cpu_register_io_memory(0, omap_uart_readfn,
2113
                    omap_uart_writefn, s);
2114

    
2115
    s->ta = ta;
2116

    
2117
    cpu_register_physical_memory(s->base + 0x20, 0x100, iomemtype);
2118

    
2119
    return s;
2120
}
2121

    
2122
void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
2123
{
2124
    /* TODO: Should reuse or destroy current s->serial */
2125
    s->serial = serial_mm_init(s->base, 2, s->irq,
2126
                    omap_clk_getrate(s->fclk) / 16,
2127
                    chr ?: qemu_chr_open("null"), 1);
2128
}
2129

    
2130
/* MPU Clock/Reset/Power Mode Control */
2131
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2132
{
2133
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2134
    int offset = addr - s->clkm.mpu_base;
2135

    
2136
    switch (offset) {
2137
    case 0x00:        /* ARM_CKCTL */
2138
        return s->clkm.arm_ckctl;
2139

    
2140
    case 0x04:        /* ARM_IDLECT1 */
2141
        return s->clkm.arm_idlect1;
2142

    
2143
    case 0x08:        /* ARM_IDLECT2 */
2144
        return s->clkm.arm_idlect2;
2145

    
2146
    case 0x0c:        /* ARM_EWUPCT */
2147
        return s->clkm.arm_ewupct;
2148

    
2149
    case 0x10:        /* ARM_RSTCT1 */
2150
        return s->clkm.arm_rstct1;
2151

    
2152
    case 0x14:        /* ARM_RSTCT2 */
2153
        return s->clkm.arm_rstct2;
2154

    
2155
    case 0x18:        /* ARM_SYSST */
2156
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
2157

    
2158
    case 0x1c:        /* ARM_CKOUT1 */
2159
        return s->clkm.arm_ckout1;
2160

    
2161
    case 0x20:        /* ARM_CKOUT2 */
2162
        break;
2163
    }
2164

    
2165
    OMAP_BAD_REG(addr);
2166
    return 0;
2167
}
2168

    
2169
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2170
                uint16_t diff, uint16_t value)
2171
{
2172
    omap_clk clk;
2173

    
2174
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
2175
        if (value & (1 << 14))
2176
            /* Reserved */;
2177
        else {
2178
            clk = omap_findclk(s, "arminth_ck");
2179
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2180
        }
2181
    }
2182
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
2183
        clk = omap_findclk(s, "armtim_ck");
2184
        if (value & (1 << 12))
2185
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
2186
        else
2187
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2188
    }
2189
    /* XXX: en_dspck */
2190
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
2191
        clk = omap_findclk(s, "dspmmu_ck");
2192
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
2193
    }
2194
    if (diff & (3 << 8)) {                                /* TCDIV */
2195
        clk = omap_findclk(s, "tc_ck");
2196
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
2197
    }
2198
    if (diff & (3 << 6)) {                                /* DSPDIV */
2199
        clk = omap_findclk(s, "dsp_ck");
2200
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
2201
    }
2202
    if (diff & (3 << 4)) {                                /* ARMDIV */
2203
        clk = omap_findclk(s, "arm_ck");
2204
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
2205
    }
2206
    if (diff & (3 << 2)) {                                /* LCDDIV */
2207
        clk = omap_findclk(s, "lcd_ck");
2208
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
2209
    }
2210
    if (diff & (3 << 0)) {                                /* PERDIV */
2211
        clk = omap_findclk(s, "armper_ck");
2212
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
2213
    }
2214
}
2215

    
2216
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2217
                uint16_t diff, uint16_t value)
2218
{
2219
    omap_clk clk;
2220

    
2221
    if (value & (1 << 11))                                /* SETARM_IDLE */
2222
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2223
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2224
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2225

    
2226
#define SET_CANIDLE(clock, bit)                                \
2227
    if (diff & (1 << bit)) {                                \
2228
        clk = omap_findclk(s, clock);                        \
2229
        omap_clk_canidle(clk, (value >> bit) & 1);        \
2230
    }
2231
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
2232
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
2233
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
2234
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
2235
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
2236
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
2237
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
2238
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
2239
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
2240
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
2241
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
2242
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
2243
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
2244
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
2245
}
2246

    
2247
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2248
                uint16_t diff, uint16_t value)
2249
{
2250
    omap_clk clk;
2251

    
2252
#define SET_ONOFF(clock, bit)                                \
2253
    if (diff & (1 << bit)) {                                \
2254
        clk = omap_findclk(s, clock);                        \
2255
        omap_clk_onoff(clk, (value >> bit) & 1);        \
2256
    }
2257
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
2258
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
2259
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
2260
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
2261
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
2262
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
2263
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
2264
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
2265
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
2266
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
2267
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
2268
}
2269

    
2270
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2271
                uint16_t diff, uint16_t value)
2272
{
2273
    omap_clk clk;
2274

    
2275
    if (diff & (3 << 4)) {                                /* TCLKOUT */
2276
        clk = omap_findclk(s, "tclk_out");
2277
        switch ((value >> 4) & 3) {
2278
        case 1:
2279
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
2280
            omap_clk_onoff(clk, 1);
2281
            break;
2282
        case 2:
2283
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
2284
            omap_clk_onoff(clk, 1);
2285
            break;
2286
        default:
2287
            omap_clk_onoff(clk, 0);
2288
        }
2289
    }
2290
    if (diff & (3 << 2)) {                                /* DCLKOUT */
2291
        clk = omap_findclk(s, "dclk_out");
2292
        switch ((value >> 2) & 3) {
2293
        case 0:
2294
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
2295
            break;
2296
        case 1:
2297
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
2298
            break;
2299
        case 2:
2300
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
2301
            break;
2302
        case 3:
2303
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2304
            break;
2305
        }
2306
    }
2307
    if (diff & (3 << 0)) {                                /* ACLKOUT */
2308
        clk = omap_findclk(s, "aclk_out");
2309
        switch ((value >> 0) & 3) {
2310
        case 1:
2311
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
2312
            omap_clk_onoff(clk, 1);
2313
            break;
2314
        case 2:
2315
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
2316
            omap_clk_onoff(clk, 1);
2317
            break;
2318
        case 3:
2319
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
2320
            omap_clk_onoff(clk, 1);
2321
            break;
2322
        default:
2323
            omap_clk_onoff(clk, 0);
2324
        }
2325
    }
2326
}
2327

    
2328
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2329
                uint32_t value)
2330
{
2331
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2332
    int offset = addr - s->clkm.mpu_base;
2333
    uint16_t diff;
2334
    omap_clk clk;
2335
    static const char *clkschemename[8] = {
2336
        "fully synchronous", "fully asynchronous", "synchronous scalable",
2337
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2338
    };
2339

    
2340
    switch (offset) {
2341
    case 0x00:        /* ARM_CKCTL */
2342
        diff = s->clkm.arm_ckctl ^ value;
2343
        s->clkm.arm_ckctl = value & 0x7fff;
2344
        omap_clkm_ckctl_update(s, diff, value);
2345
        return;
2346

    
2347
    case 0x04:        /* ARM_IDLECT1 */
2348
        diff = s->clkm.arm_idlect1 ^ value;
2349
        s->clkm.arm_idlect1 = value & 0x0fff;
2350
        omap_clkm_idlect1_update(s, diff, value);
2351
        return;
2352

    
2353
    case 0x08:        /* ARM_IDLECT2 */
2354
        diff = s->clkm.arm_idlect2 ^ value;
2355
        s->clkm.arm_idlect2 = value & 0x07ff;
2356
        omap_clkm_idlect2_update(s, diff, value);
2357
        return;
2358

    
2359
    case 0x0c:        /* ARM_EWUPCT */
2360
        diff = s->clkm.arm_ewupct ^ value;
2361
        s->clkm.arm_ewupct = value & 0x003f;
2362
        return;
2363

    
2364
    case 0x10:        /* ARM_RSTCT1 */
2365
        diff = s->clkm.arm_rstct1 ^ value;
2366
        s->clkm.arm_rstct1 = value & 0x0007;
2367
        if (value & 9) {
2368
            qemu_system_reset_request();
2369
            s->clkm.cold_start = 0xa;
2370
        }
2371
        if (diff & ~value & 4) {                                /* DSP_RST */
2372
            omap_mpui_reset(s);
2373
            omap_tipb_bridge_reset(s->private_tipb);
2374
            omap_tipb_bridge_reset(s->public_tipb);
2375
        }
2376
        if (diff & 2) {                                                /* DSP_EN */
2377
            clk = omap_findclk(s, "dsp_ck");
2378
            omap_clk_canidle(clk, (~value >> 1) & 1);
2379
        }
2380
        return;
2381

    
2382
    case 0x14:        /* ARM_RSTCT2 */
2383
        s->clkm.arm_rstct2 = value & 0x0001;
2384
        return;
2385

    
2386
    case 0x18:        /* ARM_SYSST */
2387
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2388
            s->clkm.clocking_scheme = (value >> 11) & 7;
2389
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2390
                            clkschemename[s->clkm.clocking_scheme]);
2391
        }
2392
        s->clkm.cold_start &= value & 0x3f;
2393
        return;
2394

    
2395
    case 0x1c:        /* ARM_CKOUT1 */
2396
        diff = s->clkm.arm_ckout1 ^ value;
2397
        s->clkm.arm_ckout1 = value & 0x003f;
2398
        omap_clkm_ckout1_update(s, diff, value);
2399
        return;
2400

    
2401
    case 0x20:        /* ARM_CKOUT2 */
2402
    default:
2403
        OMAP_BAD_REG(addr);
2404
    }
2405
}
2406

    
2407
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2408
    omap_badwidth_read16,
2409
    omap_clkm_read,
2410
    omap_badwidth_read16,
2411
};
2412

    
2413
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2414
    omap_badwidth_write16,
2415
    omap_clkm_write,
2416
    omap_badwidth_write16,
2417
};
2418

    
2419
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2420
{
2421
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2422
    int offset = addr - s->clkm.dsp_base;
2423

    
2424
    switch (offset) {
2425
    case 0x04:        /* DSP_IDLECT1 */
2426
        return s->clkm.dsp_idlect1;
2427

    
2428
    case 0x08:        /* DSP_IDLECT2 */
2429
        return s->clkm.dsp_idlect2;
2430

    
2431
    case 0x14:        /* DSP_RSTCT2 */
2432
        return s->clkm.dsp_rstct2;
2433

    
2434
    case 0x18:        /* DSP_SYSST */
2435
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
2436
                (s->env->halted << 6);        /* Quite useless... */
2437
    }
2438

    
2439
    OMAP_BAD_REG(addr);
2440
    return 0;
2441
}
2442

    
2443
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2444
                uint16_t diff, uint16_t value)
2445
{
2446
    omap_clk clk;
2447

    
2448
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2449
}
2450

    
2451
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2452
                uint16_t diff, uint16_t value)
2453
{
2454
    omap_clk clk;
2455

    
2456
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2457
}
2458

    
2459
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2460
                uint32_t value)
2461
{
2462
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2463
    int offset = addr - s->clkm.dsp_base;
2464
    uint16_t diff;
2465

    
2466
    switch (offset) {
2467
    case 0x04:        /* DSP_IDLECT1 */
2468
        diff = s->clkm.dsp_idlect1 ^ value;
2469
        s->clkm.dsp_idlect1 = value & 0x01f7;
2470
        omap_clkdsp_idlect1_update(s, diff, value);
2471
        break;
2472

    
2473
    case 0x08:        /* DSP_IDLECT2 */
2474
        s->clkm.dsp_idlect2 = value & 0x0037;
2475
        diff = s->clkm.dsp_idlect1 ^ value;
2476
        omap_clkdsp_idlect2_update(s, diff, value);
2477
        break;
2478

    
2479
    case 0x14:        /* DSP_RSTCT2 */
2480
        s->clkm.dsp_rstct2 = value & 0x0001;
2481
        break;
2482

    
2483
    case 0x18:        /* DSP_SYSST */
2484
        s->clkm.cold_start &= value & 0x3f;
2485
        break;
2486

    
2487
    default:
2488
        OMAP_BAD_REG(addr);
2489
    }
2490
}
2491

    
2492
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2493
    omap_badwidth_read16,
2494
    omap_clkdsp_read,
2495
    omap_badwidth_read16,
2496
};
2497

    
2498
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2499
    omap_badwidth_write16,
2500
    omap_clkdsp_write,
2501
    omap_badwidth_write16,
2502
};
2503

    
2504
static void omap_clkm_reset(struct omap_mpu_state_s *s)
2505
{
2506
    if (s->wdt && s->wdt->reset)
2507
        s->clkm.cold_start = 0x6;
2508
    s->clkm.clocking_scheme = 0;
2509
    omap_clkm_ckctl_update(s, ~0, 0x3000);
2510
    s->clkm.arm_ckctl = 0x3000;
2511
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
2512
    s->clkm.arm_idlect1 = 0x0400;
2513
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
2514
    s->clkm.arm_idlect2 = 0x0100;
2515
    s->clkm.arm_ewupct = 0x003f;
2516
    s->clkm.arm_rstct1 = 0x0000;
2517
    s->clkm.arm_rstct2 = 0x0000;
2518
    s->clkm.arm_ckout1 = 0x0015;
2519
    s->clkm.dpll1_mode = 0x2002;
2520
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2521
    s->clkm.dsp_idlect1 = 0x0040;
2522
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2523
    s->clkm.dsp_idlect2 = 0x0000;
2524
    s->clkm.dsp_rstct2 = 0x0000;
2525
}
2526

    
2527
static void omap_clkm_init(target_phys_addr_t mpu_base,
2528
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2529
{
2530
    int iomemtype[2] = {
2531
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2532
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2533
    };
2534

    
2535
    s->clkm.mpu_base = mpu_base;
2536
    s->clkm.dsp_base = dsp_base;
2537
    s->clkm.arm_idlect1 = 0x03ff;
2538
    s->clkm.arm_idlect2 = 0x0100;
2539
    s->clkm.dsp_idlect1 = 0x0002;
2540
    omap_clkm_reset(s);
2541
    s->clkm.cold_start = 0x3a;
2542

    
2543
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2544
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2545
}
2546

    
2547
/* MPU I/O */
2548
struct omap_mpuio_s {
2549
    target_phys_addr_t base;
2550
    qemu_irq irq;
2551
    qemu_irq kbd_irq;
2552
    qemu_irq *in;
2553
    qemu_irq handler[16];
2554
    qemu_irq wakeup;
2555

    
2556
    uint16_t inputs;
2557
    uint16_t outputs;
2558
    uint16_t dir;
2559
    uint16_t edge;
2560
    uint16_t mask;
2561
    uint16_t ints;
2562

    
2563
    uint16_t debounce;
2564
    uint16_t latch;
2565
    uint8_t event;
2566

    
2567
    uint8_t buttons[5];
2568
    uint8_t row_latch;
2569
    uint8_t cols;
2570
    int kbd_mask;
2571
    int clk;
2572
};
2573

    
2574
static void omap_mpuio_set(void *opaque, int line, int level)
2575
{
2576
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2577
    uint16_t prev = s->inputs;
2578

    
2579
    if (level)
2580
        s->inputs |= 1 << line;
2581
    else
2582
        s->inputs &= ~(1 << line);
2583

    
2584
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2585
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2586
            s->ints |= 1 << line;
2587
            qemu_irq_raise(s->irq);
2588
            /* TODO: wakeup */
2589
        }
2590
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
2591
                (s->event >> 1) == line)        /* PIN_SELECT */
2592
            s->latch = s->inputs;
2593
    }
2594
}
2595

    
2596
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2597
{
2598
    int i;
2599
    uint8_t *row, rows = 0, cols = ~s->cols;
2600

    
2601
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2602
        if (*row & cols)
2603
            rows |= i;
2604

    
2605
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
2606
    s->row_latch = ~rows;
2607
}
2608

    
2609
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2610
{
2611
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2612
    int offset = addr & OMAP_MPUI_REG_MASK;
2613
    uint16_t ret;
2614

    
2615
    switch (offset) {
2616
    case 0x00:        /* INPUT_LATCH */
2617
        return s->inputs;
2618

    
2619
    case 0x04:        /* OUTPUT_REG */
2620
        return s->outputs;
2621

    
2622
    case 0x08:        /* IO_CNTL */
2623
        return s->dir;
2624

    
2625
    case 0x10:        /* KBR_LATCH */
2626
        return s->row_latch;
2627

    
2628
    case 0x14:        /* KBC_REG */
2629
        return s->cols;
2630

    
2631
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2632
        return s->event;
2633

    
2634
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2635
        return s->edge;
2636

    
2637
    case 0x20:        /* KBD_INT */
2638
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
2639

    
2640
    case 0x24:        /* GPIO_INT */
2641
        ret = s->ints;
2642
        s->ints &= s->mask;
2643
        if (ret)
2644
            qemu_irq_lower(s->irq);
2645
        return ret;
2646

    
2647
    case 0x28:        /* KBD_MASKIT */
2648
        return s->kbd_mask;
2649

    
2650
    case 0x2c:        /* GPIO_MASKIT */
2651
        return s->mask;
2652

    
2653
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2654
        return s->debounce;
2655

    
2656
    case 0x34:        /* GPIO_LATCH_REG */
2657
        return s->latch;
2658
    }
2659

    
2660
    OMAP_BAD_REG(addr);
2661
    return 0;
2662
}
2663

    
2664
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2665
                uint32_t value)
2666
{
2667
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2668
    int offset = addr & OMAP_MPUI_REG_MASK;
2669
    uint16_t diff;
2670
    int ln;
2671

    
2672
    switch (offset) {
2673
    case 0x04:        /* OUTPUT_REG */
2674
        diff = (s->outputs ^ value) & ~s->dir;
2675
        s->outputs = value;
2676
        while ((ln = ffs(diff))) {
2677
            ln --;
2678
            if (s->handler[ln])
2679
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2680
            diff &= ~(1 << ln);
2681
        }
2682
        break;
2683

    
2684
    case 0x08:        /* IO_CNTL */
2685
        diff = s->outputs & (s->dir ^ value);
2686
        s->dir = value;
2687

    
2688
        value = s->outputs & ~s->dir;
2689
        while ((ln = ffs(diff))) {
2690
            ln --;
2691
            if (s->handler[ln])
2692
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2693
            diff &= ~(1 << ln);
2694
        }
2695
        break;
2696

    
2697
    case 0x14:        /* KBC_REG */
2698
        s->cols = value;
2699
        omap_mpuio_kbd_update(s);
2700
        break;
2701

    
2702
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2703
        s->event = value & 0x1f;
2704
        break;
2705

    
2706
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2707
        s->edge = value;
2708
        break;
2709

    
2710
    case 0x28:        /* KBD_MASKIT */
2711
        s->kbd_mask = value & 1;
2712
        omap_mpuio_kbd_update(s);
2713
        break;
2714

    
2715
    case 0x2c:        /* GPIO_MASKIT */
2716
        s->mask = value;
2717
        break;
2718

    
2719
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2720
        s->debounce = value & 0x1ff;
2721
        break;
2722

    
2723
    case 0x00:        /* INPUT_LATCH */
2724
    case 0x10:        /* KBR_LATCH */
2725
    case 0x20:        /* KBD_INT */
2726
    case 0x24:        /* GPIO_INT */
2727
    case 0x34:        /* GPIO_LATCH_REG */
2728
        OMAP_RO_REG(addr);
2729
        return;
2730

    
2731
    default:
2732
        OMAP_BAD_REG(addr);
2733
        return;
2734
    }
2735
}
2736

    
2737
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
2738
    omap_badwidth_read16,
2739
    omap_mpuio_read,
2740
    omap_badwidth_read16,
2741
};
2742

    
2743
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
2744
    omap_badwidth_write16,
2745
    omap_mpuio_write,
2746
    omap_badwidth_write16,
2747
};
2748

    
2749
static void omap_mpuio_reset(struct omap_mpuio_s *s)
2750
{
2751
    s->inputs = 0;
2752
    s->outputs = 0;
2753
    s->dir = ~0;
2754
    s->event = 0;
2755
    s->edge = 0;
2756
    s->kbd_mask = 0;
2757
    s->mask = 0;
2758
    s->debounce = 0;
2759
    s->latch = 0;
2760
    s->ints = 0;
2761
    s->row_latch = 0x1f;
2762
    s->clk = 1;
2763
}
2764

    
2765
static void omap_mpuio_onoff(void *opaque, int line, int on)
2766
{
2767
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2768

    
2769
    s->clk = on;
2770
    if (on)
2771
        omap_mpuio_kbd_update(s);
2772
}
2773

    
2774
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
2775
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2776
                omap_clk clk)
2777
{
2778
    int iomemtype;
2779
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2780
            qemu_mallocz(sizeof(struct omap_mpuio_s));
2781

    
2782
    s->base = base;
2783
    s->irq = gpio_int;
2784
    s->kbd_irq = kbd_int;
2785
    s->wakeup = wakeup;
2786
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2787
    omap_mpuio_reset(s);
2788

    
2789
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
2790
                    omap_mpuio_writefn, s);
2791
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
2792

    
2793
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2794

    
2795
    return s;
2796
}
2797

    
2798
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2799
{
2800
    return s->in;
2801
}
2802

    
2803
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2804
{
2805
    if (line >= 16 || line < 0)
2806
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
2807
    s->handler[line] = handler;
2808
}
2809

    
2810
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2811
{
2812
    if (row >= 5 || row < 0)
2813
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
2814
                        __FUNCTION__, col, row);
2815

    
2816
    if (down)
2817
        s->buttons[row] |= 1 << col;
2818
    else
2819
        s->buttons[row] &= ~(1 << col);
2820

    
2821
    omap_mpuio_kbd_update(s);
2822
}
2823

    
2824
/* General-Purpose I/O */
2825
struct omap_gpio_s {
2826
    target_phys_addr_t base;
2827
    qemu_irq irq;
2828
    qemu_irq *in;
2829
    qemu_irq handler[16];
2830

    
2831
    uint16_t inputs;
2832
    uint16_t outputs;
2833
    uint16_t dir;
2834
    uint16_t edge;
2835
    uint16_t mask;
2836
    uint16_t ints;
2837
    uint16_t pins;
2838
};
2839

    
2840
static void omap_gpio_set(void *opaque, int line, int level)
2841
{
2842
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2843
    uint16_t prev = s->inputs;
2844

    
2845
    if (level)
2846
        s->inputs |= 1 << line;
2847
    else
2848
        s->inputs &= ~(1 << line);
2849

    
2850
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
2851
                    (1 << line) & s->dir & ~s->mask) {
2852
        s->ints |= 1 << line;
2853
        qemu_irq_raise(s->irq);
2854
    }
2855
}
2856

    
2857
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
2858
{
2859
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2860
    int offset = addr & OMAP_MPUI_REG_MASK;
2861

    
2862
    switch (offset) {
2863
    case 0x00:        /* DATA_INPUT */
2864
        return s->inputs & s->pins;
2865

    
2866
    case 0x04:        /* DATA_OUTPUT */
2867
        return s->outputs;
2868

    
2869
    case 0x08:        /* DIRECTION_CONTROL */
2870
        return s->dir;
2871

    
2872
    case 0x0c:        /* INTERRUPT_CONTROL */
2873
        return s->edge;
2874

    
2875
    case 0x10:        /* INTERRUPT_MASK */
2876
        return s->mask;
2877

    
2878
    case 0x14:        /* INTERRUPT_STATUS */
2879
        return s->ints;
2880

    
2881
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
2882
        OMAP_BAD_REG(addr);
2883
        return s->pins;
2884
    }
2885

    
2886
    OMAP_BAD_REG(addr);
2887
    return 0;
2888
}
2889

    
2890
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
2891
                uint32_t value)
2892
{
2893
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2894
    int offset = addr & OMAP_MPUI_REG_MASK;
2895
    uint16_t diff;
2896
    int ln;
2897

    
2898
    switch (offset) {
2899
    case 0x00:        /* DATA_INPUT */
2900
        OMAP_RO_REG(addr);
2901
        return;
2902

    
2903
    case 0x04:        /* DATA_OUTPUT */
2904
        diff = (s->outputs ^ value) & ~s->dir;
2905
        s->outputs = value;
2906
        while ((ln = ffs(diff))) {
2907
            ln --;
2908
            if (s->handler[ln])
2909
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2910
            diff &= ~(1 << ln);
2911
        }
2912
        break;
2913

    
2914
    case 0x08:        /* DIRECTION_CONTROL */
2915
        diff = s->outputs & (s->dir ^ value);
2916
        s->dir = value;
2917

    
2918
        value = s->outputs & ~s->dir;
2919
        while ((ln = ffs(diff))) {
2920
            ln --;
2921
            if (s->handler[ln])
2922
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2923
            diff &= ~(1 << ln);
2924
        }
2925
        break;
2926

    
2927
    case 0x0c:        /* INTERRUPT_CONTROL */
2928
        s->edge = value;
2929
        break;
2930

    
2931
    case 0x10:        /* INTERRUPT_MASK */
2932
        s->mask = value;
2933
        break;
2934

    
2935
    case 0x14:        /* INTERRUPT_STATUS */
2936
        s->ints &= ~value;
2937
        if (!s->ints)
2938
            qemu_irq_lower(s->irq);
2939
        break;
2940

    
2941
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
2942
        OMAP_BAD_REG(addr);
2943
        s->pins = value;
2944
        break;
2945

    
2946
    default:
2947
        OMAP_BAD_REG(addr);
2948
        return;
2949
    }
2950
}
2951

    
2952
/* *Some* sources say the memory region is 32-bit.  */
2953
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
2954
    omap_badwidth_read16,
2955
    omap_gpio_read,
2956
    omap_badwidth_read16,
2957
};
2958

    
2959
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
2960
    omap_badwidth_write16,
2961
    omap_gpio_write,
2962
    omap_badwidth_write16,
2963
};
2964

    
2965
static void omap_gpio_reset(struct omap_gpio_s *s)
2966
{
2967
    s->inputs = 0;
2968
    s->outputs = ~0;
2969
    s->dir = ~0;
2970
    s->edge = ~0;
2971
    s->mask = ~0;
2972
    s->ints = 0;
2973
    s->pins = ~0;
2974
}
2975

    
2976
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
2977
                qemu_irq irq, omap_clk clk)
2978
{
2979
    int iomemtype;
2980
    struct omap_gpio_s *s = (struct omap_gpio_s *)
2981
            qemu_mallocz(sizeof(struct omap_gpio_s));
2982

    
2983
    s->base = base;
2984
    s->irq = irq;
2985
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
2986
    omap_gpio_reset(s);
2987

    
2988
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
2989
                    omap_gpio_writefn, s);
2990
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
2991

    
2992
    return s;
2993
}
2994

    
2995
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
2996
{
2997
    return s->in;
2998
}
2999

    
3000
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3001
{
3002
    if (line >= 16 || line < 0)
3003
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
3004
    s->handler[line] = handler;
3005
}
3006

    
3007
/* MicroWire Interface */
3008
struct omap_uwire_s {
3009
    target_phys_addr_t base;
3010
    qemu_irq txirq;
3011
    qemu_irq rxirq;
3012
    qemu_irq txdrq;
3013

    
3014
    uint16_t txbuf;
3015
    uint16_t rxbuf;
3016
    uint16_t control;
3017
    uint16_t setup[5];
3018

    
3019
    struct uwire_slave_s *chip[4];
3020
};
3021

    
3022
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3023
{
3024
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3025
    struct uwire_slave_s *slave = s->chip[chipselect];
3026

    
3027
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
3028
        if (s->control & (1 << 12))                        /* CS_CMD */
3029
            if (slave && slave->send)
3030
                slave->send(slave->opaque,
3031
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3032
        s->control &= ~(1 << 14);                        /* CSRB */
3033
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3034
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3035
    }
3036

    
3037
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
3038
        if (s->control & (1 << 12))                        /* CS_CMD */
3039
            if (slave && slave->receive)
3040
                s->rxbuf = slave->receive(slave->opaque);
3041
        s->control |= 1 << 15;                                /* RDRB */
3042
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3043
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3044
    }
3045
}
3046

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

    
3052
    switch (offset) {
3053
    case 0x00:        /* RDR */
3054
        s->control &= ~(1 << 15);                        /* RDRB */
3055
        return s->rxbuf;
3056

    
3057
    case 0x04:        /* CSR */
3058
        return s->control;
3059

    
3060
    case 0x08:        /* SR1 */
3061
        return s->setup[0];
3062
    case 0x0c:        /* SR2 */
3063
        return s->setup[1];
3064
    case 0x10:        /* SR3 */
3065
        return s->setup[2];
3066
    case 0x14:        /* SR4 */
3067
        return s->setup[3];
3068
    case 0x18:        /* SR5 */
3069
        return s->setup[4];
3070
    }
3071

    
3072
    OMAP_BAD_REG(addr);
3073
    return 0;
3074
}
3075

    
3076
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3077
                uint32_t value)
3078
{
3079
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3080
    int offset = addr & OMAP_MPUI_REG_MASK;
3081

    
3082
    switch (offset) {
3083
    case 0x00:        /* TDR */
3084
        s->txbuf = value;                                /* TD */
3085
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3086
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3087
                         (s->control & (1 << 12)))) {        /* CS_CMD */
3088
            s->control |= 1 << 14;                        /* CSRB */
3089
            omap_uwire_transfer_start(s);
3090
        }
3091
        break;
3092

    
3093
    case 0x04:        /* CSR */
3094
        s->control = value & 0x1fff;
3095
        if (value & (1 << 13))                                /* START */
3096
            omap_uwire_transfer_start(s);
3097
        break;
3098

    
3099
    case 0x08:        /* SR1 */
3100
        s->setup[0] = value & 0x003f;
3101
        break;
3102

    
3103
    case 0x0c:        /* SR2 */
3104
        s->setup[1] = value & 0x0fc0;
3105
        break;
3106

    
3107
    case 0x10:        /* SR3 */
3108
        s->setup[2] = value & 0x0003;
3109
        break;
3110

    
3111
    case 0x14:        /* SR4 */
3112
        s->setup[3] = value & 0x0001;
3113
        break;
3114

    
3115
    case 0x18:        /* SR5 */
3116
        s->setup[4] = value & 0x000f;
3117
        break;
3118

    
3119
    default:
3120
        OMAP_BAD_REG(addr);
3121
        return;
3122
    }
3123
}
3124

    
3125
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3126
    omap_badwidth_read16,
3127
    omap_uwire_read,
3128
    omap_badwidth_read16,
3129
};
3130

    
3131
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3132
    omap_badwidth_write16,
3133
    omap_uwire_write,
3134
    omap_badwidth_write16,
3135
};
3136

    
3137
static void omap_uwire_reset(struct omap_uwire_s *s)
3138
{
3139
    s->control = 0;
3140
    s->setup[0] = 0;
3141
    s->setup[1] = 0;
3142
    s->setup[2] = 0;
3143
    s->setup[3] = 0;
3144
    s->setup[4] = 0;
3145
}
3146

    
3147
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3148
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3149
{
3150
    int iomemtype;
3151
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3152
            qemu_mallocz(sizeof(struct omap_uwire_s));
3153

    
3154
    s->base = base;
3155
    s->txirq = irq[0];
3156
    s->rxirq = irq[1];
3157
    s->txdrq = dma;
3158
    omap_uwire_reset(s);
3159

    
3160
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3161
                    omap_uwire_writefn, s);
3162
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3163

    
3164
    return s;
3165
}
3166

    
3167
void omap_uwire_attach(struct omap_uwire_s *s,
3168
                struct uwire_slave_s *slave, int chipselect)
3169
{
3170
    if (chipselect < 0 || chipselect > 3) {
3171
        fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
3172
        exit(-1);
3173
    }
3174

    
3175
    s->chip[chipselect] = slave;
3176
}
3177

    
3178
/* Pseudonoise Pulse-Width Light Modulator */
3179
static void omap_pwl_update(struct omap_mpu_state_s *s)
3180
{
3181
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3182

    
3183
    if (output != s->pwl.output) {
3184
        s->pwl.output = output;
3185
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3186
    }
3187
}
3188

    
3189
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3190
{
3191
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3192
    int offset = addr & OMAP_MPUI_REG_MASK;
3193

    
3194
    switch (offset) {
3195
    case 0x00:        /* PWL_LEVEL */
3196
        return s->pwl.level;
3197
    case 0x04:        /* PWL_CTRL */
3198
        return s->pwl.enable;
3199
    }
3200
    OMAP_BAD_REG(addr);
3201
    return 0;
3202
}
3203

    
3204
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3205
                uint32_t value)
3206
{
3207
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3208
    int offset = addr & OMAP_MPUI_REG_MASK;
3209

    
3210
    switch (offset) {
3211
    case 0x00:        /* PWL_LEVEL */
3212
        s->pwl.level = value;
3213
        omap_pwl_update(s);
3214
        break;
3215
    case 0x04:        /* PWL_CTRL */
3216
        s->pwl.enable = value & 1;
3217
        omap_pwl_update(s);
3218
        break;
3219
    default:
3220
        OMAP_BAD_REG(addr);
3221
        return;
3222
    }
3223
}
3224

    
3225
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3226
    omap_pwl_read,
3227
    omap_badwidth_read8,
3228
    omap_badwidth_read8,
3229
};
3230

    
3231
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3232
    omap_pwl_write,
3233
    omap_badwidth_write8,
3234
    omap_badwidth_write8,
3235
};
3236

    
3237
static void omap_pwl_reset(struct omap_mpu_state_s *s)
3238
{
3239
    s->pwl.output = 0;
3240
    s->pwl.level = 0;
3241
    s->pwl.enable = 0;
3242
    s->pwl.clk = 1;
3243
    omap_pwl_update(s);
3244
}
3245

    
3246
static void omap_pwl_clk_update(void *opaque, int line, int on)
3247
{
3248
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3249

    
3250
    s->pwl.clk = on;
3251
    omap_pwl_update(s);
3252
}
3253

    
3254
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3255
                omap_clk clk)
3256
{
3257
    int iomemtype;
3258

    
3259
    omap_pwl_reset(s);
3260

    
3261
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3262
                    omap_pwl_writefn, s);
3263
    cpu_register_physical_memory(base, 0x800, iomemtype);
3264

    
3265
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3266
}
3267

    
3268
/* Pulse-Width Tone module */
3269
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3270
{
3271
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3272
    int offset = addr & OMAP_MPUI_REG_MASK;
3273

    
3274
    switch (offset) {
3275
    case 0x00:        /* FRC */
3276
        return s->pwt.frc;
3277
    case 0x04:        /* VCR */
3278
        return s->pwt.vrc;
3279
    case 0x08:        /* GCR */
3280
        return s->pwt.gcr;
3281
    }
3282
    OMAP_BAD_REG(addr);
3283
    return 0;
3284
}
3285

    
3286
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3287
                uint32_t value)
3288
{
3289
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3290
    int offset = addr & OMAP_MPUI_REG_MASK;
3291

    
3292
    switch (offset) {
3293
    case 0x00:        /* FRC */
3294
        s->pwt.frc = value & 0x3f;
3295
        break;
3296
    case 0x04:        /* VRC */
3297
        if ((value ^ s->pwt.vrc) & 1) {
3298
            if (value & 1)
3299
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
3300
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
3301
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
3302
                                 /* Pre-multiplexer divider */
3303
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
3304
                                 /* Octave multiplexer */
3305
                                 (2 << (value & 3)) *
3306
                                 /* 101/107 divider */
3307
                                 ((value & (1 << 2)) ? 101 : 107) *
3308
                                 /*  49/55 divider */
3309
                                 ((value & (1 << 3)) ?  49 : 55) *
3310
                                 /*  50/63 divider */
3311
                                 ((value & (1 << 4)) ?  50 : 63) *
3312
                                 /*  80/127 divider */
3313
                                 ((value & (1 << 5)) ?  80 : 127) /
3314
                                 (107 * 55 * 63 * 127)));
3315
            else
3316
                printf("%s: silence!\n", __FUNCTION__);
3317
        }
3318
        s->pwt.vrc = value & 0x7f;
3319
        break;
3320
    case 0x08:        /* GCR */
3321
        s->pwt.gcr = value & 3;
3322
        break;
3323
    default:
3324
        OMAP_BAD_REG(addr);
3325
        return;
3326
    }
3327
}
3328

    
3329
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3330
    omap_pwt_read,
3331
    omap_badwidth_read8,
3332
    omap_badwidth_read8,
3333
};
3334

    
3335
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3336
    omap_pwt_write,
3337
    omap_badwidth_write8,
3338
    omap_badwidth_write8,
3339
};
3340

    
3341
static void omap_pwt_reset(struct omap_mpu_state_s *s)
3342
{
3343
    s->pwt.frc = 0;
3344
    s->pwt.vrc = 0;
3345
    s->pwt.gcr = 0;
3346
}
3347

    
3348
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3349
                omap_clk clk)
3350
{
3351
    int iomemtype;
3352

    
3353
    s->pwt.clk = clk;
3354
    omap_pwt_reset(s);
3355

    
3356
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3357
                    omap_pwt_writefn, s);
3358
    cpu_register_physical_memory(base, 0x800, iomemtype);
3359
}
3360

    
3361
/* Real-time Clock module */
3362
struct omap_rtc_s {
3363
    target_phys_addr_t base;
3364
    qemu_irq irq;
3365
    qemu_irq alarm;
3366
    QEMUTimer *clk;
3367

    
3368
    uint8_t interrupts;
3369
    uint8_t status;
3370
    int16_t comp_reg;
3371
    int running;
3372
    int pm_am;
3373
    int auto_comp;
3374
    int round;
3375
    struct tm alarm_tm;
3376
    time_t alarm_ti;
3377

    
3378
    struct tm current_tm;
3379
    time_t ti;
3380
    uint64_t tick;
3381
};
3382

    
3383
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3384
{
3385
    /* s->alarm is level-triggered */
3386
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3387
}
3388

    
3389
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3390
{
3391
    s->alarm_ti = mktime(&s->alarm_tm);
3392
    if (s->alarm_ti == -1)
3393
        printf("%s: conversion failed\n", __FUNCTION__);
3394
}
3395

    
3396
static inline uint8_t omap_rtc_bcd(int num)
3397
{
3398
    return ((num / 10) << 4) | (num % 10);
3399
}
3400

    
3401
static inline int omap_rtc_bin(uint8_t num)
3402
{
3403
    return (num & 15) + 10 * (num >> 4);
3404
}
3405

    
3406
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3407
{
3408
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3409
    int offset = addr & OMAP_MPUI_REG_MASK;
3410
    uint8_t i;
3411

    
3412
    switch (offset) {
3413
    case 0x00:        /* SECONDS_REG */
3414
        return omap_rtc_bcd(s->current_tm.tm_sec);
3415

    
3416
    case 0x04:        /* MINUTES_REG */
3417
        return omap_rtc_bcd(s->current_tm.tm_min);
3418

    
3419
    case 0x08:        /* HOURS_REG */
3420
        if (s->pm_am)
3421
            return ((s->current_tm.tm_hour > 11) << 7) |
3422
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3423
        else
3424
            return omap_rtc_bcd(s->current_tm.tm_hour);
3425

    
3426
    case 0x0c:        /* DAYS_REG */
3427
        return omap_rtc_bcd(s->current_tm.tm_mday);
3428

    
3429
    case 0x10:        /* MONTHS_REG */
3430
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3431

    
3432
    case 0x14:        /* YEARS_REG */
3433
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3434

    
3435
    case 0x18:        /* WEEK_REG */
3436
        return s->current_tm.tm_wday;
3437

    
3438
    case 0x20:        /* ALARM_SECONDS_REG */
3439
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3440

    
3441
    case 0x24:        /* ALARM_MINUTES_REG */
3442
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3443

    
3444
    case 0x28:        /* ALARM_HOURS_REG */
3445
        if (s->pm_am)
3446
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3447
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3448
        else
3449
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
3450

    
3451
    case 0x2c:        /* ALARM_DAYS_REG */
3452
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3453

    
3454
    case 0x30:        /* ALARM_MONTHS_REG */
3455
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3456

    
3457
    case 0x34:        /* ALARM_YEARS_REG */
3458
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3459

    
3460
    case 0x40:        /* RTC_CTRL_REG */
3461
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3462
                (s->round << 1) | s->running;
3463

    
3464
    case 0x44:        /* RTC_STATUS_REG */
3465
        i = s->status;
3466
        s->status &= ~0x3d;
3467
        return i;
3468

    
3469
    case 0x48:        /* RTC_INTERRUPTS_REG */
3470
        return s->interrupts;
3471

    
3472
    case 0x4c:        /* RTC_COMP_LSB_REG */
3473
        return ((uint16_t) s->comp_reg) & 0xff;
3474

    
3475
    case 0x50:        /* RTC_COMP_MSB_REG */
3476
        return ((uint16_t) s->comp_reg) >> 8;
3477
    }
3478

    
3479
    OMAP_BAD_REG(addr);
3480
    return 0;
3481
}
3482

    
3483
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3484
                uint32_t value)
3485
{
3486
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3487
    int offset = addr & OMAP_MPUI_REG_MASK;
3488
    struct tm new_tm;
3489
    time_t ti[2];
3490

    
3491
    switch (offset) {
3492
    case 0x00:        /* SECONDS_REG */
3493
#ifdef ALMDEBUG
3494
        printf("RTC SEC_REG <-- %02x\n", value);
3495
#endif
3496
        s->ti -= s->current_tm.tm_sec;
3497
        s->ti += omap_rtc_bin(value);
3498
        return;
3499

    
3500
    case 0x04:        /* MINUTES_REG */
3501
#ifdef ALMDEBUG
3502
        printf("RTC MIN_REG <-- %02x\n", value);
3503
#endif
3504
        s->ti -= s->current_tm.tm_min * 60;
3505
        s->ti += omap_rtc_bin(value) * 60;
3506
        return;
3507

    
3508
    case 0x08:        /* HOURS_REG */
3509
#ifdef ALMDEBUG
3510
        printf("RTC HRS_REG <-- %02x\n", value);
3511
#endif
3512
        s->ti -= s->current_tm.tm_hour * 3600;
3513
        if (s->pm_am) {
3514
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3515
            s->ti += ((value >> 7) & 1) * 43200;
3516
        } else
3517
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3518
        return;
3519

    
3520
    case 0x0c:        /* DAYS_REG */
3521
#ifdef ALMDEBUG
3522
        printf("RTC DAY_REG <-- %02x\n", value);
3523
#endif
3524
        s->ti -= s->current_tm.tm_mday * 86400;
3525
        s->ti += omap_rtc_bin(value) * 86400;
3526
        return;
3527

    
3528
    case 0x10:        /* MONTHS_REG */
3529
#ifdef ALMDEBUG
3530
        printf("RTC MTH_REG <-- %02x\n", value);
3531
#endif
3532
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3533
        new_tm.tm_mon = omap_rtc_bin(value);
3534
        ti[0] = mktime(&s->current_tm);
3535
        ti[1] = mktime(&new_tm);
3536

    
3537
        if (ti[0] != -1 && ti[1] != -1) {
3538
            s->ti -= ti[0];
3539
            s->ti += ti[1];
3540
        } else {
3541
            /* A less accurate version */
3542
            s->ti -= s->current_tm.tm_mon * 2592000;
3543
            s->ti += omap_rtc_bin(value) * 2592000;
3544
        }
3545
        return;
3546

    
3547
    case 0x14:        /* YEARS_REG */
3548
#ifdef ALMDEBUG
3549
        printf("RTC YRS_REG <-- %02x\n", value);
3550
#endif
3551
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3552
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3553
        ti[0] = mktime(&s->current_tm);
3554
        ti[1] = mktime(&new_tm);
3555

    
3556
        if (ti[0] != -1 && ti[1] != -1) {
3557
            s->ti -= ti[0];
3558
            s->ti += ti[1];
3559
        } else {
3560
            /* A less accurate version */
3561
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3562
            s->ti += omap_rtc_bin(value) * 31536000;
3563
        }
3564
        return;
3565

    
3566
    case 0x18:        /* WEEK_REG */
3567
        return;        /* Ignored */
3568

    
3569
    case 0x20:        /* ALARM_SECONDS_REG */
3570
#ifdef ALMDEBUG
3571
        printf("ALM SEC_REG <-- %02x\n", value);
3572
#endif
3573
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3574
        omap_rtc_alarm_update(s);
3575
        return;
3576

    
3577
    case 0x24:        /* ALARM_MINUTES_REG */
3578
#ifdef ALMDEBUG
3579
        printf("ALM MIN_REG <-- %02x\n", value);
3580
#endif
3581
        s->alarm_tm.tm_min = omap_rtc_bin(value);
3582
        omap_rtc_alarm_update(s);
3583
        return;
3584

    
3585
    case 0x28:        /* ALARM_HOURS_REG */
3586
#ifdef ALMDEBUG
3587
        printf("ALM HRS_REG <-- %02x\n", value);
3588
#endif
3589
        if (s->pm_am)
3590
            s->alarm_tm.tm_hour =
3591
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
3592
                    ((value >> 7) & 1) * 12;
3593
        else
3594
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
3595
        omap_rtc_alarm_update(s);
3596
        return;
3597

    
3598
    case 0x2c:        /* ALARM_DAYS_REG */
3599
#ifdef ALMDEBUG
3600
        printf("ALM DAY_REG <-- %02x\n", value);
3601
#endif
3602
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3603
        omap_rtc_alarm_update(s);
3604
        return;
3605

    
3606
    case 0x30:        /* ALARM_MONTHS_REG */
3607
#ifdef ALMDEBUG
3608
        printf("ALM MON_REG <-- %02x\n", value);
3609
#endif
3610
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3611
        omap_rtc_alarm_update(s);
3612
        return;
3613

    
3614
    case 0x34:        /* ALARM_YEARS_REG */
3615
#ifdef ALMDEBUG
3616
        printf("ALM YRS_REG <-- %02x\n", value);
3617
#endif
3618
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3619
        omap_rtc_alarm_update(s);
3620
        return;
3621

    
3622
    case 0x40:        /* RTC_CTRL_REG */
3623
#ifdef ALMDEBUG
3624
        printf("RTC CONTROL <-- %02x\n", value);
3625
#endif
3626
        s->pm_am = (value >> 3) & 1;
3627
        s->auto_comp = (value >> 2) & 1;
3628
        s->round = (value >> 1) & 1;
3629
        s->running = value & 1;
3630
        s->status &= 0xfd;
3631
        s->status |= s->running << 1;
3632
        return;
3633

    
3634
    case 0x44:        /* RTC_STATUS_REG */
3635
#ifdef ALMDEBUG
3636
        printf("RTC STATUSL <-- %02x\n", value);
3637
#endif
3638
        s->status &= ~((value & 0xc0) ^ 0x80);
3639
        omap_rtc_interrupts_update(s);
3640
        return;
3641

    
3642
    case 0x48:        /* RTC_INTERRUPTS_REG */
3643
#ifdef ALMDEBUG
3644
        printf("RTC INTRS <-- %02x\n", value);
3645
#endif
3646
        s->interrupts = value;
3647
        return;
3648

    
3649
    case 0x4c:        /* RTC_COMP_LSB_REG */
3650
#ifdef ALMDEBUG
3651
        printf("RTC COMPLSB <-- %02x\n", value);
3652
#endif
3653
        s->comp_reg &= 0xff00;
3654
        s->comp_reg |= 0x00ff & value;
3655
        return;
3656

    
3657
    case 0x50:        /* RTC_COMP_MSB_REG */
3658
#ifdef ALMDEBUG
3659
        printf("RTC COMPMSB <-- %02x\n", value);
3660
#endif
3661
        s->comp_reg &= 0x00ff;
3662
        s->comp_reg |= 0xff00 & (value << 8);
3663
        return;
3664

    
3665
    default:
3666
        OMAP_BAD_REG(addr);
3667
        return;
3668
    }
3669
}
3670

    
3671
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3672
    omap_rtc_read,
3673
    omap_badwidth_read8,
3674
    omap_badwidth_read8,
3675
};
3676

    
3677
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3678
    omap_rtc_write,
3679
    omap_badwidth_write8,
3680
    omap_badwidth_write8,
3681
};
3682

    
3683
static void omap_rtc_tick(void *opaque)
3684
{
3685
    struct omap_rtc_s *s = opaque;
3686

    
3687
    if (s->round) {
3688
        /* Round to nearest full minute.  */
3689
        if (s->current_tm.tm_sec < 30)
3690
            s->ti -= s->current_tm.tm_sec;
3691
        else
3692
            s->ti += 60 - s->current_tm.tm_sec;
3693

    
3694
        s->round = 0;
3695
    }
3696

    
3697
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
3698

    
3699
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3700
        s->status |= 0x40;
3701
        omap_rtc_interrupts_update(s);
3702
    }
3703

    
3704
    if (s->interrupts & 0x04)
3705
        switch (s->interrupts & 3) {
3706
        case 0:
3707
            s->status |= 0x04;
3708
            qemu_irq_pulse(s->irq);
3709
            break;
3710
        case 1:
3711
            if (s->current_tm.tm_sec)
3712
                break;
3713
            s->status |= 0x08;
3714
            qemu_irq_pulse(s->irq);
3715
            break;
3716
        case 2:
3717
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
3718
                break;
3719
            s->status |= 0x10;
3720
            qemu_irq_pulse(s->irq);
3721
            break;
3722
        case 3:
3723
            if (s->current_tm.tm_sec ||
3724
                            s->current_tm.tm_min || s->current_tm.tm_hour)
3725
                break;
3726
            s->status |= 0x20;
3727
            qemu_irq_pulse(s->irq);
3728
            break;
3729
        }
3730

    
3731
    /* Move on */
3732
    if (s->running)
3733
        s->ti ++;
3734
    s->tick += 1000;
3735

    
3736
    /*
3737
     * Every full hour add a rough approximation of the compensation
3738
     * register to the 32kHz Timer (which drives the RTC) value. 
3739
     */
3740
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
3741
        s->tick += s->comp_reg * 1000 / 32768;
3742

    
3743
    qemu_mod_timer(s->clk, s->tick);
3744
}
3745

    
3746
static void omap_rtc_reset(struct omap_rtc_s *s)
3747
{
3748
    struct tm tm;
3749

    
3750
    s->interrupts = 0;
3751
    s->comp_reg = 0;
3752
    s->running = 0;
3753
    s->pm_am = 0;
3754
    s->auto_comp = 0;
3755
    s->round = 0;
3756
    s->tick = qemu_get_clock(rt_clock);
3757
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
3758
    s->alarm_tm.tm_mday = 0x01;
3759
    s->status = 1 << 7;
3760
    qemu_get_timedate(&tm, 0);
3761
    s->ti = mktime(&tm);
3762

    
3763
    omap_rtc_alarm_update(s);
3764
    omap_rtc_tick(s);
3765
}
3766

    
3767
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
3768
                qemu_irq *irq, omap_clk clk)
3769
{
3770
    int iomemtype;
3771
    struct omap_rtc_s *s = (struct omap_rtc_s *)
3772
            qemu_mallocz(sizeof(struct omap_rtc_s));
3773

    
3774
    s->base = base;
3775
    s->irq = irq[0];
3776
    s->alarm = irq[1];
3777
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
3778

    
3779
    omap_rtc_reset(s);
3780

    
3781
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
3782
                    omap_rtc_writefn, s);
3783
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3784

    
3785
    return s;
3786
}
3787

    
3788
/* Multi-channel Buffered Serial Port interfaces */
3789
struct omap_mcbsp_s {
3790
    target_phys_addr_t base;
3791
    qemu_irq txirq;
3792
    qemu_irq rxirq;
3793
    qemu_irq txdrq;
3794
    qemu_irq rxdrq;
3795

    
3796
    uint16_t spcr[2];
3797
    uint16_t rcr[2];
3798
    uint16_t xcr[2];
3799
    uint16_t srgr[2];
3800
    uint16_t mcr[2];
3801
    uint16_t pcr;
3802
    uint16_t rcer[8];
3803
    uint16_t xcer[8];
3804
    int tx_rate;
3805
    int rx_rate;
3806
    int tx_req;
3807
    int rx_req;
3808

    
3809
    struct i2s_codec_s *codec;
3810
    QEMUTimer *source_timer;
3811
    QEMUTimer *sink_timer;
3812
};
3813

    
3814
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
3815
{
3816
    int irq;
3817

    
3818
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
3819
    case 0:
3820
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
3821
        break;
3822
    case 3:
3823
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
3824
        break;
3825
    default:
3826
        irq = 0;
3827
        break;
3828
    }
3829

    
3830
    if (irq)
3831
        qemu_irq_pulse(s->rxirq);
3832

    
3833
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
3834
    case 0:
3835
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
3836
        break;
3837
    case 3:
3838
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
3839
        break;
3840
    default:
3841
        irq = 0;
3842
        break;
3843
    }
3844

    
3845
    if (irq)
3846
        qemu_irq_pulse(s->txirq);
3847
}
3848

    
3849
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
3850
{
3851
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
3852
        s->spcr[0] |= 1 << 2;                                /* RFULL */
3853
    s->spcr[0] |= 1 << 1;                                /* RRDY */
3854
    qemu_irq_raise(s->rxdrq);
3855
    omap_mcbsp_intr_update(s);
3856
}
3857

    
3858
static void omap_mcbsp_source_tick(void *opaque)
3859
{
3860
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3861
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3862

    
3863
    if (!s->rx_rate)
3864
        return;
3865
    if (s->rx_req)
3866
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
3867

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

    
3870
    omap_mcbsp_rx_newdata(s);
3871
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
3872
}
3873

    
3874
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3875
{
3876
    if (!s->codec || !s->codec->rts)
3877
        omap_mcbsp_source_tick(s);
3878
    else if (s->codec->in.len) {
3879
        s->rx_req = s->codec->in.len;
3880
        omap_mcbsp_rx_newdata(s);
3881
    }
3882
}
3883

    
3884
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3885
{
3886
    qemu_del_timer(s->source_timer);
3887
}
3888

    
3889
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3890
{
3891
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
3892
    qemu_irq_lower(s->rxdrq);
3893
    omap_mcbsp_intr_update(s);
3894
}
3895

    
3896
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3897
{
3898
    s->spcr[1] |= 1 << 1;                                /* XRDY */
3899
    qemu_irq_raise(s->txdrq);
3900
    omap_mcbsp_intr_update(s);
3901
}
3902

    
3903
static void omap_mcbsp_sink_tick(void *opaque)
3904
{
3905
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3906
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3907

    
3908
    if (!s->tx_rate)
3909
        return;
3910
    if (s->tx_req)
3911
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
3912

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

    
3915
    omap_mcbsp_tx_newdata(s);
3916
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
3917
}
3918

    
3919
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3920
{
3921
    if (!s->codec || !s->codec->cts)
3922
        omap_mcbsp_sink_tick(s);
3923
    else if (s->codec->out.size) {
3924
        s->tx_req = s->codec->out.size;
3925
        omap_mcbsp_tx_newdata(s);
3926
    }
3927
}
3928

    
3929
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3930
{
3931
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
3932
    qemu_irq_lower(s->txdrq);
3933
    omap_mcbsp_intr_update(s);
3934
    if (s->codec && s->codec->cts)
3935
        s->codec->tx_swallow(s->codec->opaque);
3936
}
3937

    
3938
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3939
{
3940
    s->tx_req = 0;
3941
    omap_mcbsp_tx_done(s);
3942
    qemu_del_timer(s->sink_timer);
3943
}
3944

    
3945
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3946
{
3947
    int prev_rx_rate, prev_tx_rate;
3948
    int rx_rate = 0, tx_rate = 0;
3949
    int cpu_rate = 1500000;        /* XXX */
3950

    
3951
    /* TODO: check CLKSTP bit */
3952
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
3953
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
3954
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3955
                            (s->pcr & (1 << 8))) {        /* CLKRM */
3956
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3957
                    rx_rate = cpu_rate /
3958
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3959
            } else
3960
                if (s->codec)
3961
                    rx_rate = s->codec->rx_rate;
3962
        }
3963

    
3964
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
3965
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3966
                            (s->pcr & (1 << 9))) {        /* CLKXM */
3967
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3968
                    tx_rate = cpu_rate /
3969
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3970
            } else
3971
                if (s->codec)
3972
                    tx_rate = s->codec->tx_rate;
3973
        }
3974
    }
3975
    prev_tx_rate = s->tx_rate;
3976
    prev_rx_rate = s->rx_rate;
3977
    s->tx_rate = tx_rate;
3978
    s->rx_rate = rx_rate;
3979

    
3980
    if (s->codec)
3981
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3982

    
3983
    if (!prev_tx_rate && tx_rate)
3984
        omap_mcbsp_tx_start(s);
3985
    else if (s->tx_rate && !tx_rate)
3986
        omap_mcbsp_tx_stop(s);
3987

    
3988
    if (!prev_rx_rate && rx_rate)
3989
        omap_mcbsp_rx_start(s);
3990
    else if (prev_tx_rate && !tx_rate)
3991
        omap_mcbsp_rx_stop(s);
3992
}
3993

    
3994
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
3995
{
3996
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3997
    int offset = addr & OMAP_MPUI_REG_MASK;
3998
    uint16_t ret;
3999

    
4000
    switch (offset) {
4001
    case 0x00:        /* DRR2 */
4002
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
4003
            return 0x0000;
4004
        /* Fall through.  */
4005
    case 0x02:        /* DRR1 */
4006
        if (s->rx_req < 2) {
4007
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
4008
            omap_mcbsp_rx_done(s);
4009
        } else {
4010
            s->tx_req -= 2;
4011
            if (s->codec && s->codec->in.len >= 2) {
4012
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
4013
                ret |= s->codec->in.fifo[s->codec->in.start ++];
4014
                s->codec->in.len -= 2;
4015
            } else
4016
                ret = 0x0000;
4017
            if (!s->tx_req)
4018
                omap_mcbsp_rx_done(s);
4019
            return ret;
4020
        }
4021
        return 0x0000;
4022

    
4023
    case 0x04:        /* DXR2 */
4024
    case 0x06:        /* DXR1 */
4025
        return 0x0000;
4026

    
4027
    case 0x08:        /* SPCR2 */
4028
        return s->spcr[1];
4029
    case 0x0a:        /* SPCR1 */
4030
        return s->spcr[0];
4031
    case 0x0c:        /* RCR2 */
4032
        return s->rcr[1];
4033
    case 0x0e:        /* RCR1 */
4034
        return s->rcr[0];
4035
    case 0x10:        /* XCR2 */
4036
        return s->xcr[1];
4037
    case 0x12:        /* XCR1 */
4038
        return s->xcr[0];
4039
    case 0x14:        /* SRGR2 */
4040
        return s->srgr[1];
4041
    case 0x16:        /* SRGR1 */
4042
        return s->srgr[0];
4043
    case 0x18:        /* MCR2 */
4044
        return s->mcr[1];
4045
    case 0x1a:        /* MCR1 */
4046
        return s->mcr[0];
4047
    case 0x1c:        /* RCERA */
4048
        return s->rcer[0];
4049
    case 0x1e:        /* RCERB */
4050
        return s->rcer[1];
4051
    case 0x20:        /* XCERA */
4052
        return s->xcer[0];
4053
    case 0x22:        /* XCERB */
4054
        return s->xcer[1];
4055
    case 0x24:        /* PCR0 */
4056
        return s->pcr;
4057
    case 0x26:        /* RCERC */
4058
        return s->rcer[2];
4059
    case 0x28:        /* RCERD */
4060
        return s->rcer[3];
4061
    case 0x2a:        /* XCERC */
4062
        return s->xcer[2];
4063
    case 0x2c:        /* XCERD */
4064
        return s->xcer[3];
4065
    case 0x2e:        /* RCERE */
4066
        return s->rcer[4];
4067
    case 0x30:        /* RCERF */
4068
        return s->rcer[5];
4069
    case 0x32:        /* XCERE */
4070
        return s->xcer[4];
4071
    case 0x34:        /* XCERF */
4072
        return s->xcer[5];
4073
    case 0x36:        /* RCERG */
4074
        return s->rcer[6];
4075
    case 0x38:        /* RCERH */
4076
        return s->rcer[7];
4077
    case 0x3a:        /* XCERG */
4078
        return s->xcer[6];
4079
    case 0x3c:        /* XCERH */
4080
        return s->xcer[7];
4081
    }
4082

    
4083
    OMAP_BAD_REG(addr);
4084
    return 0;
4085
}
4086

    
4087
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
4088
                uint32_t value)
4089
{
4090
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4091
    int offset = addr & OMAP_MPUI_REG_MASK;
4092

    
4093
    switch (offset) {
4094
    case 0x00:        /* DRR2 */
4095
    case 0x02:        /* DRR1 */
4096
        OMAP_RO_REG(addr);
4097
        return;
4098

    
4099
    case 0x04:        /* DXR2 */
4100
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4101
            return;
4102
        /* Fall through.  */
4103
    case 0x06:        /* DXR1 */
4104
        if (s->tx_req > 1) {
4105
            s->tx_req -= 2;
4106
            if (s->codec && s->codec->cts) {
4107
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
4108
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
4109
            }
4110
            if (s->tx_req < 2)
4111
                omap_mcbsp_tx_done(s);
4112
        } else
4113
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4114
        return;
4115

    
4116
    case 0x08:        /* SPCR2 */
4117
        s->spcr[1] &= 0x0002;
4118
        s->spcr[1] |= 0x03f9 & value;
4119
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
4120
        if (~value & 1)                                        /* XRST */
4121
            s->spcr[1] &= ~6;
4122
        omap_mcbsp_req_update(s);
4123
        return;
4124
    case 0x0a:        /* SPCR1 */
4125
        s->spcr[0] &= 0x0006;
4126
        s->spcr[0] |= 0xf8f9 & value;
4127
        if (value & (1 << 15))                                /* DLB */
4128
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
4129
        if (~value & 1) {                                /* RRST */
4130
            s->spcr[0] &= ~6;
4131
            s->rx_req = 0;
4132
            omap_mcbsp_rx_done(s);
4133
        }
4134
        omap_mcbsp_req_update(s);
4135
        return;
4136

    
4137
    case 0x0c:        /* RCR2 */
4138
        s->rcr[1] = value & 0xffff;
4139
        return;
4140
    case 0x0e:        /* RCR1 */
4141
        s->rcr[0] = value & 0x7fe0;
4142
        return;
4143
    case 0x10:        /* XCR2 */
4144
        s->xcr[1] = value & 0xffff;
4145
        return;
4146
    case 0x12:        /* XCR1 */
4147
        s->xcr[0] = value & 0x7fe0;
4148
        return;
4149
    case 0x14:        /* SRGR2 */
4150
        s->srgr[1] = value & 0xffff;
4151
        omap_mcbsp_req_update(s);
4152
        return;
4153
    case 0x16:        /* SRGR1 */
4154
        s->srgr[0] = value & 0xffff;
4155
        omap_mcbsp_req_update(s);
4156
        return;
4157
    case 0x18:        /* MCR2 */
4158
        s->mcr[1] = value & 0x03e3;
4159
        if (value & 3)                                        /* XMCM */
4160
            printf("%s: Tx channel selection mode enable attempt\n",
4161
                            __FUNCTION__);
4162
        return;
4163
    case 0x1a:        /* MCR1 */
4164
        s->mcr[0] = value & 0x03e1;
4165
        if (value & 1)                                        /* RMCM */
4166
            printf("%s: Rx channel selection mode enable attempt\n",
4167
                            __FUNCTION__);
4168
        return;
4169
    case 0x1c:        /* RCERA */
4170
        s->rcer[0] = value & 0xffff;
4171
        return;
4172
    case 0x1e:        /* RCERB */
4173
        s->rcer[1] = value & 0xffff;
4174
        return;
4175
    case 0x20:        /* XCERA */
4176
        s->xcer[0] = value & 0xffff;
4177
        return;
4178
    case 0x22:        /* XCERB */
4179
        s->xcer[1] = value & 0xffff;
4180
        return;
4181
    case 0x24:        /* PCR0 */
4182
        s->pcr = value & 0x7faf;
4183
        return;
4184
    case 0x26:        /* RCERC */
4185
        s->rcer[2] = value & 0xffff;
4186
        return;
4187
    case 0x28:        /* RCERD */
4188
        s->rcer[3] = value & 0xffff;
4189
        return;
4190
    case 0x2a:        /* XCERC */
4191
        s->xcer[2] = value & 0xffff;
4192
        return;
4193
    case 0x2c:        /* XCERD */
4194
        s->xcer[3] = value & 0xffff;
4195
        return;
4196
    case 0x2e:        /* RCERE */
4197
        s->rcer[4] = value & 0xffff;
4198
        return;
4199
    case 0x30:        /* RCERF */
4200
        s->rcer[5] = value & 0xffff;
4201
        return;
4202
    case 0x32:        /* XCERE */
4203
        s->xcer[4] = value & 0xffff;
4204
        return;
4205
    case 0x34:        /* XCERF */
4206
        s->xcer[5] = value & 0xffff;
4207
        return;
4208
    case 0x36:        /* RCERG */
4209
        s->rcer[6] = value & 0xffff;
4210
        return;
4211
    case 0x38:        /* RCERH */
4212
        s->rcer[7] = value & 0xffff;
4213
        return;
4214
    case 0x3a:        /* XCERG */
4215
        s->xcer[6] = value & 0xffff;
4216
        return;
4217
    case 0x3c:        /* XCERH */
4218
        s->xcer[7] = value & 0xffff;
4219
        return;
4220
    }
4221

    
4222
    OMAP_BAD_REG(addr);
4223
}
4224

    
4225
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
4226
                uint32_t value)
4227
{
4228
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4229
    int offset = addr & OMAP_MPUI_REG_MASK;
4230

    
4231
    if (offset == 0x04) {                                /* DXR */
4232
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4233
            return;
4234
        if (s->tx_req > 3) {
4235
            s->tx_req -= 4;
4236
            if (s->codec && s->codec->cts) {
4237
                s->codec->out.fifo[s->codec->out.len ++] =
4238
                        (value >> 24) & 0xff;
4239
                s->codec->out.fifo[s->codec->out.len ++] =
4240
                        (value >> 16) & 0xff;
4241
                s->codec->out.fifo[s->codec->out.len ++] =
4242
                        (value >> 8) & 0xff;
4243
                s->codec->out.fifo[s->codec->out.len ++] =
4244
                        (value >> 0) & 0xff;
4245
            }
4246
            if (s->tx_req < 4)
4247
                omap_mcbsp_tx_done(s);
4248
        } else
4249
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4250
        return;
4251
    }
4252

    
4253
    omap_badwidth_write16(opaque, addr, value);
4254
}
4255

    
4256
static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
4257
    omap_badwidth_read16,
4258
    omap_mcbsp_read,
4259
    omap_badwidth_read16,
4260
};
4261

    
4262
static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
4263
    omap_badwidth_write16,
4264
    omap_mcbsp_writeh,
4265
    omap_mcbsp_writew,
4266
};
4267

    
4268
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
4269
{
4270
    memset(&s->spcr, 0, sizeof(s->spcr));
4271
    memset(&s->rcr, 0, sizeof(s->rcr));
4272
    memset(&s->xcr, 0, sizeof(s->xcr));
4273
    s->srgr[0] = 0x0001;
4274
    s->srgr[1] = 0x2000;
4275
    memset(&s->mcr, 0, sizeof(s->mcr));
4276
    memset(&s->pcr, 0, sizeof(s->pcr));
4277
    memset(&s->rcer, 0, sizeof(s->rcer));
4278
    memset(&s->xcer, 0, sizeof(s->xcer));
4279
    s->tx_req = 0;
4280
    s->rx_req = 0;
4281
    s->tx_rate = 0;
4282
    s->rx_rate = 0;
4283
    qemu_del_timer(s->source_timer);
4284
    qemu_del_timer(s->sink_timer);
4285
}
4286

    
4287
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
4288
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
4289
{
4290
    int iomemtype;
4291
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
4292
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
4293

    
4294
    s->base = base;
4295
    s->txirq = irq[0];
4296
    s->rxirq = irq[1];
4297
    s->txdrq = dma[0];
4298
    s->rxdrq = dma[1];
4299
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
4300
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
4301
    omap_mcbsp_reset(s);
4302

    
4303
    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
4304
                    omap_mcbsp_writefn, s);
4305
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4306

    
4307
    return s;
4308
}
4309

    
4310
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4311
{
4312
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4313

    
4314
    if (s->rx_rate) {
4315
        s->rx_req = s->codec->in.len;
4316
        omap_mcbsp_rx_newdata(s);
4317
    }
4318
}
4319

    
4320
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
4321
{
4322
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4323

    
4324
    if (s->tx_rate) {
4325
        s->tx_req = s->codec->out.size;
4326
        omap_mcbsp_tx_newdata(s);
4327
    }
4328
}
4329

    
4330
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
4331
{
4332
    s->codec = slave;
4333
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4334
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4335
}
4336

    
4337
/* LED Pulse Generators */
4338
struct omap_lpg_s {
4339
    target_phys_addr_t base;
4340
    QEMUTimer *tm;
4341

    
4342
    uint8_t control;
4343
    uint8_t power;
4344
    int64_t on;
4345
    int64_t period;
4346
    int clk;
4347
    int cycle;
4348
};
4349

    
4350
static void omap_lpg_tick(void *opaque)
4351
{
4352
    struct omap_lpg_s *s = opaque;
4353

    
4354
    if (s->cycle)
4355
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
4356
    else
4357
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
4358

    
4359
    s->cycle = !s->cycle;
4360
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
4361
}
4362

    
4363
static void omap_lpg_update(struct omap_lpg_s *s)
4364
{
4365
    int64_t on, period = 1, ticks = 1000;
4366
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
4367

    
4368
    if (~s->control & (1 << 6))                                        /* LPGRES */
4369
        on = 0;
4370
    else if (s->control & (1 << 7))                                /* PERM_ON */
4371
        on = period;
4372
    else {
4373
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
4374
                        256 / 32);
4375
        on = (s->clk && s->power) ? muldiv64(ticks,
4376
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
4377
    }
4378

    
4379
    qemu_del_timer(s->tm);
4380
    if (on == period && s->on < s->period)
4381
        printf("%s: LED is on\n", __FUNCTION__);
4382
    else if (on == 0 && s->on)
4383
        printf("%s: LED is off\n", __FUNCTION__);
4384
    else if (on && (on != s->on || period != s->period)) {
4385
        s->cycle = 0;
4386
        s->on = on;
4387
        s->period = period;
4388
        omap_lpg_tick(s);
4389
        return;
4390
    }
4391

    
4392
    s->on = on;
4393
    s->period = period;
4394
}
4395

    
4396
static void omap_lpg_reset(struct omap_lpg_s *s)
4397
{
4398
    s->control = 0x00;
4399
    s->power = 0x00;
4400
    s->clk = 1;
4401
    omap_lpg_update(s);
4402
}
4403

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

    
4409
    switch (offset) {
4410
    case 0x00:        /* LCR */
4411
        return s->control;
4412

    
4413
    case 0x04:        /* PMR */
4414
        return s->power;
4415
    }
4416

    
4417
    OMAP_BAD_REG(addr);
4418
    return 0;
4419
}
4420

    
4421
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
4422
                uint32_t value)
4423
{
4424
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4425
    int offset = addr & OMAP_MPUI_REG_MASK;
4426

    
4427
    switch (offset) {
4428
    case 0x00:        /* LCR */
4429
        if (~value & (1 << 6))                                        /* LPGRES */
4430
            omap_lpg_reset(s);
4431
        s->control = value & 0xff;
4432
        omap_lpg_update(s);
4433
        return;
4434

    
4435
    case 0x04:        /* PMR */
4436
        s->power = value & 0x01;
4437
        omap_lpg_update(s);
4438
        return;
4439

    
4440
    default:
4441
        OMAP_BAD_REG(addr);
4442
        return;
4443
    }
4444
}
4445

    
4446
static CPUReadMemoryFunc *omap_lpg_readfn[] = {
4447
    omap_lpg_read,
4448
    omap_badwidth_read8,
4449
    omap_badwidth_read8,
4450
};
4451

    
4452
static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
4453
    omap_lpg_write,
4454
    omap_badwidth_write8,
4455
    omap_badwidth_write8,
4456
};
4457

    
4458
static void omap_lpg_clk_update(void *opaque, int line, int on)
4459
{
4460
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4461

    
4462
    s->clk = on;
4463
    omap_lpg_update(s);
4464
}
4465

    
4466
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4467
{
4468
    int iomemtype;
4469
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4470
            qemu_mallocz(sizeof(struct omap_lpg_s));
4471

    
4472
    s->base = base;
4473
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4474

    
4475
    omap_lpg_reset(s);
4476

    
4477
    iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
4478
                    omap_lpg_writefn, s);
4479
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4480

    
4481
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4482

    
4483
    return s;
4484
}
4485

    
4486
/* MPUI Peripheral Bridge configuration */
4487
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
4488
{
4489
    if (addr == OMAP_MPUI_BASE)        /* CMR */
4490
        return 0xfe4d;
4491

    
4492
    OMAP_BAD_REG(addr);
4493
    return 0;
4494
}
4495

    
4496
static CPUReadMemoryFunc *omap_mpui_io_readfn[] = {
4497
    omap_badwidth_read16,
4498
    omap_mpui_io_read,
4499
    omap_badwidth_read16,
4500
};
4501

    
4502
static CPUWriteMemoryFunc *omap_mpui_io_writefn[] = {
4503
    omap_badwidth_write16,
4504
    omap_badwidth_write16,
4505
    omap_badwidth_write16,
4506
};
4507

    
4508
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4509
{
4510
    int iomemtype = cpu_register_io_memory(0, omap_mpui_io_readfn,
4511
                    omap_mpui_io_writefn, mpu);
4512
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
4513
}
4514

    
4515
/* General chip reset */
4516
static void omap1_mpu_reset(void *opaque)
4517
{
4518
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4519

    
4520
    omap_inth_reset(mpu->ih[0]);
4521
    omap_inth_reset(mpu->ih[1]);
4522
    omap_dma_reset(mpu->dma);
4523
    omap_mpu_timer_reset(mpu->timer[0]);
4524
    omap_mpu_timer_reset(mpu->timer[1]);
4525
    omap_mpu_timer_reset(mpu->timer[2]);
4526
    omap_wd_timer_reset(mpu->wdt);
4527
    omap_os_timer_reset(mpu->os_timer);
4528
    omap_lcdc_reset(mpu->lcd);
4529
    omap_ulpd_pm_reset(mpu);
4530
    omap_pin_cfg_reset(mpu);
4531
    omap_mpui_reset(mpu);
4532
    omap_tipb_bridge_reset(mpu->private_tipb);
4533
    omap_tipb_bridge_reset(mpu->public_tipb);
4534
    omap_dpll_reset(&mpu->dpll[0]);
4535
    omap_dpll_reset(&mpu->dpll[1]);
4536
    omap_dpll_reset(&mpu->dpll[2]);
4537
    omap_uart_reset(mpu->uart[0]);
4538
    omap_uart_reset(mpu->uart[1]);
4539
    omap_uart_reset(mpu->uart[2]);
4540
    omap_mmc_reset(mpu->mmc);
4541
    omap_mpuio_reset(mpu->mpuio);
4542
    omap_gpio_reset(mpu->gpio);
4543
    omap_uwire_reset(mpu->microwire);
4544
    omap_pwl_reset(mpu);
4545
    omap_pwt_reset(mpu);
4546
    omap_i2c_reset(mpu->i2c[0]);
4547
    omap_rtc_reset(mpu->rtc);
4548
    omap_mcbsp_reset(mpu->mcbsp1);
4549
    omap_mcbsp_reset(mpu->mcbsp2);
4550
    omap_mcbsp_reset(mpu->mcbsp3);
4551
    omap_lpg_reset(mpu->led[0]);
4552
    omap_lpg_reset(mpu->led[1]);
4553
    omap_clkm_reset(mpu);
4554
    cpu_reset(mpu->env);
4555
}
4556

    
4557
static const struct omap_map_s {
4558
    target_phys_addr_t phys_dsp;
4559
    target_phys_addr_t phys_mpu;
4560
    uint32_t size;
4561
    const char *name;
4562
} omap15xx_dsp_mm[] = {
4563
    /* Strobe 0 */
4564
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
4565
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
4566
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
4567
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
4568
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
4569
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
4570
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
4571
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
4572
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
4573
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
4574
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
4575
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
4576
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
4577
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
4578
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
4579
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
4580
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
4581
    /* Strobe 1 */
4582
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
4583

    
4584
    { 0 }
4585
};
4586

    
4587
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4588
{
4589
    int io;
4590

    
4591
    for (; map->phys_dsp; map ++) {
4592
        io = cpu_get_physical_page_desc(map->phys_mpu);
4593

    
4594
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4595
    }
4596
}
4597

    
4598
void omap_mpu_wakeup(void *opaque, int irq, int req)
4599
{
4600
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4601

    
4602
    if (mpu->env->halted)
4603
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4604
}
4605

    
4606
static const struct dma_irq_map omap1_dma_irq_map[] = {
4607
    { 0, OMAP_INT_DMA_CH0_6 },
4608
    { 0, OMAP_INT_DMA_CH1_7 },
4609
    { 0, OMAP_INT_DMA_CH2_8 },
4610
    { 0, OMAP_INT_DMA_CH3 },
4611
    { 0, OMAP_INT_DMA_CH4 },
4612
    { 0, OMAP_INT_DMA_CH5 },
4613
    { 1, OMAP_INT_1610_DMA_CH6 },
4614
    { 1, OMAP_INT_1610_DMA_CH7 },
4615
    { 1, OMAP_INT_1610_DMA_CH8 },
4616
    { 1, OMAP_INT_1610_DMA_CH9 },
4617
    { 1, OMAP_INT_1610_DMA_CH10 },
4618
    { 1, OMAP_INT_1610_DMA_CH11 },
4619
    { 1, OMAP_INT_1610_DMA_CH12 },
4620
    { 1, OMAP_INT_1610_DMA_CH13 },
4621
    { 1, OMAP_INT_1610_DMA_CH14 },
4622
    { 1, OMAP_INT_1610_DMA_CH15 }
4623
};
4624

    
4625
/* DMA ports for OMAP1 */
4626
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
4627
                target_phys_addr_t addr)
4628
{
4629
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
4630
}
4631

    
4632
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
4633
                target_phys_addr_t addr)
4634
{
4635
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
4636
}
4637

    
4638
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
4639
                target_phys_addr_t addr)
4640
{
4641
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
4642
}
4643

    
4644
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
4645
                target_phys_addr_t addr)
4646
{
4647
    return addr >= 0xfffb0000 && addr < 0xffff0000;
4648
}
4649

    
4650
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
4651
                target_phys_addr_t addr)
4652
{
4653
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
4654
}
4655

    
4656
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
4657
                target_phys_addr_t addr)
4658
{
4659
    return addr >= 0xe1010000 && addr < 0xe1020004;
4660
}
4661

    
4662
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4663
                DisplayState *ds, const char *core)
4664
{
4665
    int i;
4666
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4667
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4668
    ram_addr_t imif_base, emiff_base;
4669
    qemu_irq *cpu_irq;
4670
    qemu_irq dma_irqs[6];
4671
    int sdindex;
4672

    
4673
    if (!core)
4674
        core = "ti925t";
4675

    
4676
    /* Core */
4677
    s->mpu_model = omap310;
4678
    s->env = cpu_init(core);
4679
    if (!s->env) {
4680
        fprintf(stderr, "Unable to find CPU definition\n");
4681
        exit(1);
4682
    }
4683
    s->sdram_size = sdram_size;
4684
    s->sram_size = OMAP15XX_SRAM_SIZE;
4685

    
4686
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4687

    
4688
    /* Clocks */
4689
    omap_clk_init(s);
4690

    
4691
    /* Memory-mapped stuff */
4692
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4693
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4694
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4695
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4696

    
4697
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4698

    
4699
    cpu_irq = arm_pic_init_cpu(s->env);
4700
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
4701
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4702
                    omap_findclk(s, "arminth_ck"));
4703
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1],
4704
                    s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
4705
                    omap_findclk(s, "arminth_ck"));
4706

    
4707
    for (i = 0; i < 6; i ++)
4708
        dma_irqs[i] =
4709
                s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr];
4710
    s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
4711
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
4712

    
4713
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4714
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4715
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4716
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4717
    s->port[local    ].addr_valid = omap_validate_local_addr;
4718
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4719

    
4720
    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
4721
    soc_dma_port_add_mem_ram(s->dma,
4722
                    emiff_base, OMAP_EMIFF_BASE, s->sdram_size);
4723
    soc_dma_port_add_mem_ram(s->dma,
4724
                    imif_base, OMAP_IMIF_BASE, s->sram_size);
4725

    
4726
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4727
                    s->irq[0][OMAP_INT_TIMER1],
4728
                    omap_findclk(s, "mputim_ck"));
4729
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4730
                    s->irq[0][OMAP_INT_TIMER2],
4731
                    omap_findclk(s, "mputim_ck"));
4732
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4733
                    s->irq[0][OMAP_INT_TIMER3],
4734
                    omap_findclk(s, "mputim_ck"));
4735

    
4736
    s->wdt = omap_wd_timer_init(0xfffec800,
4737
                    s->irq[0][OMAP_INT_WD_TIMER],
4738
                    omap_findclk(s, "armwdt_ck"));
4739

    
4740
    s->os_timer = omap_os_timer_init(0xfffb9000,
4741
                    s->irq[1][OMAP_INT_OS_TIMER],
4742
                    omap_findclk(s, "clk32-kHz"));
4743

    
4744
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4745
                    omap_dma_get_lcdch(s->dma), ds, imif_base, emiff_base,
4746
                    omap_findclk(s, "lcd_ck"));
4747

    
4748
    omap_ulpd_pm_init(0xfffe0800, s);
4749
    omap_pin_cfg_init(0xfffe1000, s);
4750
    omap_id_init(s);
4751

    
4752
    omap_mpui_init(0xfffec900, s);
4753

    
4754
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4755
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4756
                    omap_findclk(s, "tipb_ck"));
4757
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4758
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4759
                    omap_findclk(s, "tipb_ck"));
4760

    
4761
    omap_tcmi_init(0xfffecc00, s);
4762

    
4763
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4764
                    omap_findclk(s, "uart1_ck"),
4765
                    omap_findclk(s, "uart1_ck"),
4766
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
4767
                    serial_hds[0]);
4768
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4769
                    omap_findclk(s, "uart2_ck"),
4770
                    omap_findclk(s, "uart2_ck"),
4771
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
4772
                    serial_hds[0] ? serial_hds[1] : 0);
4773
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4774
                    omap_findclk(s, "uart3_ck"),
4775
                    omap_findclk(s, "uart3_ck"),
4776
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
4777
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4778

    
4779
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4780
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4781
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4782

    
4783
    sdindex = drive_get_index(IF_SD, 0, 0);
4784
    if (sdindex == -1) {
4785
        fprintf(stderr, "qemu: missing SecureDigital device\n");
4786
        exit(1);
4787
    }
4788
    s->mmc = omap_mmc_init(0xfffb7800, drives_table[sdindex].bdrv,
4789
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
4790
                    omap_findclk(s, "mmc_ck"));
4791

    
4792
    s->mpuio = omap_mpuio_init(0xfffb5000,
4793
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4794
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
4795

    
4796
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4797
                    omap_findclk(s, "arm_gpio_ck"));
4798

    
4799
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4800
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4801

    
4802
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4803
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4804

    
4805
    s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4806
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4807

    
4808
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4809
                    omap_findclk(s, "clk32-kHz"));
4810

    
4811
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
4812
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4813
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
4814
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4815
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
4816
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4817

    
4818
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
4819
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
4820

    
4821
    /* Register mappings not currenlty implemented:
4822
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4823
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4824
     * USB W2FC                fffb4000 - fffb47ff
4825
     * Camera Interface        fffb6800 - fffb6fff
4826
     * USB Host                fffba000 - fffba7ff
4827
     * FAC                fffba800 - fffbafff
4828
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4829
     * TIPB switches        fffbc800 - fffbcfff
4830
     * Mailbox                fffcf000 - fffcf7ff
4831
     * Local bus IF        fffec100 - fffec1ff
4832
     * Local bus MMU        fffec200 - fffec2ff
4833
     * DSP MMU                fffed200 - fffed2ff
4834
     */
4835

    
4836
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
4837
    omap_setup_mpui_io(s);
4838

    
4839
    qemu_register_reset(omap1_mpu_reset, s);
4840

    
4841
    return s;
4842
}