Statistics
| Branch: | Revision:

root / hw / omap1.c @ abd0c6bd

History | View | Annotate | Download (131.6 kB)

1
/*
2
 * TI OMAP processors emulation.
3
 *
4
 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as
8
 * published by the Free Software Foundation; either version 2 or
9
 * (at your option) version 3 of the License.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along
17
 * with this program; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include "hw.h"
20
#include "arm-misc.h"
21
#include "omap.h"
22
#include "sysemu.h"
23
#include "qemu-timer.h"
24
#include "qemu-char.h"
25
#include "soc_dma.h"
26
/* We use pc-style serial ports.  */
27
#include "pc.h"
28

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
150
#define INT_FALLING_EDGE        0
151
#define INT_LOW_LEVEL                1
152

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
425
    omap_inth_reset(s);
426

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

    
431
    return s;
432
}
433

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
645
    omap_inth_reset(s);
646

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

    
651
    return s;
652
}
653

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
840
    return s;
841
}
842

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
963
    return s;
964
}
965

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1065
    return s;
1066
}
1067

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1661
    omap_mpui_reset(mpu);
1662
}
1663

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1769
    return s;
1770
}
1771

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1992
    return s;
1993
}
1994

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

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

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

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

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

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

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

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

    
2094
    s->ta = ta;
2095

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

    
2098
    return s;
2099
}
2100

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2766
    return s;
2767
}
2768

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

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

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

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

    
2791
    omap_mpuio_kbd_update(s);
2792
}
2793

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2960
    return s;
2961
}
2962

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

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

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

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

    
2986
    uWireSlave *chip[4];
2987
};
2988

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3130
    return s;
3131
}
3132

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3225
    omap_pwl_reset(s);
3226

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3361
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3362
{
3363
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3364
    int offset = addr & OMAP_MPUI_REG_MASK;
3365
    uint8_t i;
3366

    
3367
    switch (offset) {
3368
    case 0x00:        /* SECONDS_REG */
3369
        return to_bcd(s->current_tm.tm_sec);
3370

    
3371
    case 0x04:        /* MINUTES_REG */
3372
        return to_bcd(s->current_tm.tm_min);
3373

    
3374
    case 0x08:        /* HOURS_REG */
3375
        if (s->pm_am)
3376
            return ((s->current_tm.tm_hour > 11) << 7) |
3377
                    to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3378
        else
3379
            return to_bcd(s->current_tm.tm_hour);
3380

    
3381
    case 0x0c:        /* DAYS_REG */
3382
        return to_bcd(s->current_tm.tm_mday);
3383

    
3384
    case 0x10:        /* MONTHS_REG */
3385
        return to_bcd(s->current_tm.tm_mon + 1);
3386

    
3387
    case 0x14:        /* YEARS_REG */
3388
        return to_bcd(s->current_tm.tm_year % 100);
3389

    
3390
    case 0x18:        /* WEEK_REG */
3391
        return s->current_tm.tm_wday;
3392

    
3393
    case 0x20:        /* ALARM_SECONDS_REG */
3394
        return to_bcd(s->alarm_tm.tm_sec);
3395

    
3396
    case 0x24:        /* ALARM_MINUTES_REG */
3397
        return to_bcd(s->alarm_tm.tm_min);
3398

    
3399
    case 0x28:        /* ALARM_HOURS_REG */
3400
        if (s->pm_am)
3401
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3402
                    to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3403
        else
3404
            return to_bcd(s->alarm_tm.tm_hour);
3405

    
3406
    case 0x2c:        /* ALARM_DAYS_REG */
3407
        return to_bcd(s->alarm_tm.tm_mday);
3408

    
3409
    case 0x30:        /* ALARM_MONTHS_REG */
3410
        return to_bcd(s->alarm_tm.tm_mon + 1);
3411

    
3412
    case 0x34:        /* ALARM_YEARS_REG */
3413
        return to_bcd(s->alarm_tm.tm_year % 100);
3414

    
3415
    case 0x40:        /* RTC_CTRL_REG */
3416
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3417
                (s->round << 1) | s->running;
3418

    
3419
    case 0x44:        /* RTC_STATUS_REG */
3420
        i = s->status;
3421
        s->status &= ~0x3d;
3422
        return i;
3423

    
3424
    case 0x48:        /* RTC_INTERRUPTS_REG */
3425
        return s->interrupts;
3426

    
3427
    case 0x4c:        /* RTC_COMP_LSB_REG */
3428
        return ((uint16_t) s->comp_reg) & 0xff;
3429

    
3430
    case 0x50:        /* RTC_COMP_MSB_REG */
3431
        return ((uint16_t) s->comp_reg) >> 8;
3432
    }
3433

    
3434
    OMAP_BAD_REG(addr);
3435
    return 0;
3436
}
3437

    
3438
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3439
                uint32_t value)
3440
{
3441
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3442
    int offset = addr & OMAP_MPUI_REG_MASK;
3443
    struct tm new_tm;
3444
    time_t ti[2];
3445

    
3446
    switch (offset) {
3447
    case 0x00:        /* SECONDS_REG */
3448
#ifdef ALMDEBUG
3449
        printf("RTC SEC_REG <-- %02x\n", value);
3450
#endif
3451
        s->ti -= s->current_tm.tm_sec;
3452
        s->ti += from_bcd(value);
3453
        return;
3454

    
3455
    case 0x04:        /* MINUTES_REG */
3456
#ifdef ALMDEBUG
3457
        printf("RTC MIN_REG <-- %02x\n", value);
3458
#endif
3459
        s->ti -= s->current_tm.tm_min * 60;
3460
        s->ti += from_bcd(value) * 60;
3461
        return;
3462

    
3463
    case 0x08:        /* HOURS_REG */
3464
#ifdef ALMDEBUG
3465
        printf("RTC HRS_REG <-- %02x\n", value);
3466
#endif
3467
        s->ti -= s->current_tm.tm_hour * 3600;
3468
        if (s->pm_am) {
3469
            s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
3470
            s->ti += ((value >> 7) & 1) * 43200;
3471
        } else
3472
            s->ti += from_bcd(value & 0x3f) * 3600;
3473
        return;
3474

    
3475
    case 0x0c:        /* DAYS_REG */
3476
#ifdef ALMDEBUG
3477
        printf("RTC DAY_REG <-- %02x\n", value);
3478
#endif
3479
        s->ti -= s->current_tm.tm_mday * 86400;
3480
        s->ti += from_bcd(value) * 86400;
3481
        return;
3482

    
3483
    case 0x10:        /* MONTHS_REG */
3484
#ifdef ALMDEBUG
3485
        printf("RTC MTH_REG <-- %02x\n", value);
3486
#endif
3487
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3488
        new_tm.tm_mon = from_bcd(value);
3489
        ti[0] = mktimegm(&s->current_tm);
3490
        ti[1] = mktimegm(&new_tm);
3491

    
3492
        if (ti[0] != -1 && ti[1] != -1) {
3493
            s->ti -= ti[0];
3494
            s->ti += ti[1];
3495
        } else {
3496
            /* A less accurate version */
3497
            s->ti -= s->current_tm.tm_mon * 2592000;
3498
            s->ti += from_bcd(value) * 2592000;
3499
        }
3500
        return;
3501

    
3502
    case 0x14:        /* YEARS_REG */
3503
#ifdef ALMDEBUG
3504
        printf("RTC YRS_REG <-- %02x\n", value);
3505
#endif
3506
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3507
        new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
3508
        ti[0] = mktimegm(&s->current_tm);
3509
        ti[1] = mktimegm(&new_tm);
3510

    
3511
        if (ti[0] != -1 && ti[1] != -1) {
3512
            s->ti -= ti[0];
3513
            s->ti += ti[1];
3514
        } else {
3515
            /* A less accurate version */
3516
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3517
            s->ti += from_bcd(value) * 31536000;
3518
        }
3519
        return;
3520

    
3521
    case 0x18:        /* WEEK_REG */
3522
        return;        /* Ignored */
3523

    
3524
    case 0x20:        /* ALARM_SECONDS_REG */
3525
#ifdef ALMDEBUG
3526
        printf("ALM SEC_REG <-- %02x\n", value);
3527
#endif
3528
        s->alarm_tm.tm_sec = from_bcd(value);
3529
        omap_rtc_alarm_update(s);
3530
        return;
3531

    
3532
    case 0x24:        /* ALARM_MINUTES_REG */
3533
#ifdef ALMDEBUG
3534
        printf("ALM MIN_REG <-- %02x\n", value);
3535
#endif
3536
        s->alarm_tm.tm_min = from_bcd(value);
3537
        omap_rtc_alarm_update(s);
3538
        return;
3539

    
3540
    case 0x28:        /* ALARM_HOURS_REG */
3541
#ifdef ALMDEBUG
3542
        printf("ALM HRS_REG <-- %02x\n", value);
3543
#endif
3544
        if (s->pm_am)
3545
            s->alarm_tm.tm_hour =
3546
                    ((from_bcd(value & 0x3f)) % 12) +
3547
                    ((value >> 7) & 1) * 12;
3548
        else
3549
            s->alarm_tm.tm_hour = from_bcd(value);
3550
        omap_rtc_alarm_update(s);
3551
        return;
3552

    
3553
    case 0x2c:        /* ALARM_DAYS_REG */
3554
#ifdef ALMDEBUG
3555
        printf("ALM DAY_REG <-- %02x\n", value);
3556
#endif
3557
        s->alarm_tm.tm_mday = from_bcd(value);
3558
        omap_rtc_alarm_update(s);
3559
        return;
3560

    
3561
    case 0x30:        /* ALARM_MONTHS_REG */
3562
#ifdef ALMDEBUG
3563
        printf("ALM MON_REG <-- %02x\n", value);
3564
#endif
3565
        s->alarm_tm.tm_mon = from_bcd(value);
3566
        omap_rtc_alarm_update(s);
3567
        return;
3568

    
3569
    case 0x34:        /* ALARM_YEARS_REG */
3570
#ifdef ALMDEBUG
3571
        printf("ALM YRS_REG <-- %02x\n", value);
3572
#endif
3573
        s->alarm_tm.tm_year = from_bcd(value);
3574
        omap_rtc_alarm_update(s);
3575
        return;
3576

    
3577
    case 0x40:        /* RTC_CTRL_REG */
3578
#ifdef ALMDEBUG
3579
        printf("RTC CONTROL <-- %02x\n", value);
3580
#endif
3581
        s->pm_am = (value >> 3) & 1;
3582
        s->auto_comp = (value >> 2) & 1;
3583
        s->round = (value >> 1) & 1;
3584
        s->running = value & 1;
3585
        s->status &= 0xfd;
3586
        s->status |= s->running << 1;
3587
        return;
3588

    
3589
    case 0x44:        /* RTC_STATUS_REG */
3590
#ifdef ALMDEBUG
3591
        printf("RTC STATUSL <-- %02x\n", value);
3592
#endif
3593
        s->status &= ~((value & 0xc0) ^ 0x80);
3594
        omap_rtc_interrupts_update(s);
3595
        return;
3596

    
3597
    case 0x48:        /* RTC_INTERRUPTS_REG */
3598
#ifdef ALMDEBUG
3599
        printf("RTC INTRS <-- %02x\n", value);
3600
#endif
3601
        s->interrupts = value;
3602
        return;
3603

    
3604
    case 0x4c:        /* RTC_COMP_LSB_REG */
3605
#ifdef ALMDEBUG
3606
        printf("RTC COMPLSB <-- %02x\n", value);
3607
#endif
3608
        s->comp_reg &= 0xff00;
3609
        s->comp_reg |= 0x00ff & value;
3610
        return;
3611

    
3612
    case 0x50:        /* RTC_COMP_MSB_REG */
3613
#ifdef ALMDEBUG
3614
        printf("RTC COMPMSB <-- %02x\n", value);
3615
#endif
3616
        s->comp_reg &= 0x00ff;
3617
        s->comp_reg |= 0xff00 & (value << 8);
3618
        return;
3619

    
3620
    default:
3621
        OMAP_BAD_REG(addr);
3622
        return;
3623
    }
3624
}
3625

    
3626
static CPUReadMemoryFunc * const omap_rtc_readfn[] = {
3627
    omap_rtc_read,
3628
    omap_badwidth_read8,
3629
    omap_badwidth_read8,
3630
};
3631

    
3632
static CPUWriteMemoryFunc * const omap_rtc_writefn[] = {
3633
    omap_rtc_write,
3634
    omap_badwidth_write8,
3635
    omap_badwidth_write8,
3636
};
3637

    
3638
static void omap_rtc_tick(void *opaque)
3639
{
3640
    struct omap_rtc_s *s = opaque;
3641

    
3642
    if (s->round) {
3643
        /* Round to nearest full minute.  */
3644
        if (s->current_tm.tm_sec < 30)
3645
            s->ti -= s->current_tm.tm_sec;
3646
        else
3647
            s->ti += 60 - s->current_tm.tm_sec;
3648

    
3649
        s->round = 0;
3650
    }
3651

    
3652
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
3653

    
3654
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3655
        s->status |= 0x40;
3656
        omap_rtc_interrupts_update(s);
3657
    }
3658

    
3659
    if (s->interrupts & 0x04)
3660
        switch (s->interrupts & 3) {
3661
        case 0:
3662
            s->status |= 0x04;
3663
            qemu_irq_pulse(s->irq);
3664
            break;
3665
        case 1:
3666
            if (s->current_tm.tm_sec)
3667
                break;
3668
            s->status |= 0x08;
3669
            qemu_irq_pulse(s->irq);
3670
            break;
3671
        case 2:
3672
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
3673
                break;
3674
            s->status |= 0x10;
3675
            qemu_irq_pulse(s->irq);
3676
            break;
3677
        case 3:
3678
            if (s->current_tm.tm_sec ||
3679
                            s->current_tm.tm_min || s->current_tm.tm_hour)
3680
                break;
3681
            s->status |= 0x20;
3682
            qemu_irq_pulse(s->irq);
3683
            break;
3684
        }
3685

    
3686
    /* Move on */
3687
    if (s->running)
3688
        s->ti ++;
3689
    s->tick += 1000;
3690

    
3691
    /*
3692
     * Every full hour add a rough approximation of the compensation
3693
     * register to the 32kHz Timer (which drives the RTC) value. 
3694
     */
3695
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
3696
        s->tick += s->comp_reg * 1000 / 32768;
3697

    
3698
    qemu_mod_timer(s->clk, s->tick);
3699
}
3700

    
3701
static void omap_rtc_reset(struct omap_rtc_s *s)
3702
{
3703
    struct tm tm;
3704

    
3705
    s->interrupts = 0;
3706
    s->comp_reg = 0;
3707
    s->running = 0;
3708
    s->pm_am = 0;
3709
    s->auto_comp = 0;
3710
    s->round = 0;
3711
    s->tick = qemu_get_clock(rt_clock);
3712
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
3713
    s->alarm_tm.tm_mday = 0x01;
3714
    s->status = 1 << 7;
3715
    qemu_get_timedate(&tm, 0);
3716
    s->ti = mktimegm(&tm);
3717

    
3718
    omap_rtc_alarm_update(s);
3719
    omap_rtc_tick(s);
3720
}
3721

    
3722
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
3723
                qemu_irq *irq, omap_clk clk)
3724
{
3725
    int iomemtype;
3726
    struct omap_rtc_s *s = (struct omap_rtc_s *)
3727
            qemu_mallocz(sizeof(struct omap_rtc_s));
3728

    
3729
    s->irq = irq[0];
3730
    s->alarm = irq[1];
3731
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
3732

    
3733
    omap_rtc_reset(s);
3734

    
3735
    iomemtype = cpu_register_io_memory(omap_rtc_readfn,
3736
                    omap_rtc_writefn, s);
3737
    cpu_register_physical_memory(base, 0x800, iomemtype);
3738

    
3739
    return s;
3740
}
3741

    
3742
/* Multi-channel Buffered Serial Port interfaces */
3743
struct omap_mcbsp_s {
3744
    qemu_irq txirq;
3745
    qemu_irq rxirq;
3746
    qemu_irq txdrq;
3747
    qemu_irq rxdrq;
3748

    
3749
    uint16_t spcr[2];
3750
    uint16_t rcr[2];
3751
    uint16_t xcr[2];
3752
    uint16_t srgr[2];
3753
    uint16_t mcr[2];
3754
    uint16_t pcr;
3755
    uint16_t rcer[8];
3756
    uint16_t xcer[8];
3757
    int tx_rate;
3758
    int rx_rate;
3759
    int tx_req;
3760
    int rx_req;
3761

    
3762
    I2SCodec *codec;
3763
    QEMUTimer *source_timer;
3764
    QEMUTimer *sink_timer;
3765
};
3766

    
3767
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
3768
{
3769
    int irq;
3770

    
3771
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
3772
    case 0:
3773
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
3774
        break;
3775
    case 3:
3776
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
3777
        break;
3778
    default:
3779
        irq = 0;
3780
        break;
3781
    }
3782

    
3783
    if (irq)
3784
        qemu_irq_pulse(s->rxirq);
3785

    
3786
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
3787
    case 0:
3788
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
3789
        break;
3790
    case 3:
3791
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
3792
        break;
3793
    default:
3794
        irq = 0;
3795
        break;
3796
    }
3797

    
3798
    if (irq)
3799
        qemu_irq_pulse(s->txirq);
3800
}
3801

    
3802
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
3803
{
3804
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
3805
        s->spcr[0] |= 1 << 2;                                /* RFULL */
3806
    s->spcr[0] |= 1 << 1;                                /* RRDY */
3807
    qemu_irq_raise(s->rxdrq);
3808
    omap_mcbsp_intr_update(s);
3809
}
3810

    
3811
static void omap_mcbsp_source_tick(void *opaque)
3812
{
3813
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3814
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3815

    
3816
    if (!s->rx_rate)
3817
        return;
3818
    if (s->rx_req)
3819
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
3820

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

    
3823
    omap_mcbsp_rx_newdata(s);
3824
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) +
3825
                   get_ticks_per_sec());
3826
}
3827

    
3828
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3829
{
3830
    if (!s->codec || !s->codec->rts)
3831
        omap_mcbsp_source_tick(s);
3832
    else if (s->codec->in.len) {
3833
        s->rx_req = s->codec->in.len;
3834
        omap_mcbsp_rx_newdata(s);
3835
    }
3836
}
3837

    
3838
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3839
{
3840
    qemu_del_timer(s->source_timer);
3841
}
3842

    
3843
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3844
{
3845
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
3846
    qemu_irq_lower(s->rxdrq);
3847
    omap_mcbsp_intr_update(s);
3848
}
3849

    
3850
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3851
{
3852
    s->spcr[1] |= 1 << 1;                                /* XRDY */
3853
    qemu_irq_raise(s->txdrq);
3854
    omap_mcbsp_intr_update(s);
3855
}
3856

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

    
3862
    if (!s->tx_rate)
3863
        return;
3864
    if (s->tx_req)
3865
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
3866

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

    
3869
    omap_mcbsp_tx_newdata(s);
3870
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) +
3871
                   get_ticks_per_sec());
3872
}
3873

    
3874
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3875
{
3876
    if (!s->codec || !s->codec->cts)
3877
        omap_mcbsp_sink_tick(s);
3878
    else if (s->codec->out.size) {
3879
        s->tx_req = s->codec->out.size;
3880
        omap_mcbsp_tx_newdata(s);
3881
    }
3882
}
3883

    
3884
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3885
{
3886
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
3887
    qemu_irq_lower(s->txdrq);
3888
    omap_mcbsp_intr_update(s);
3889
    if (s->codec && s->codec->cts)
3890
        s->codec->tx_swallow(s->codec->opaque);
3891
}
3892

    
3893
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3894
{
3895
    s->tx_req = 0;
3896
    omap_mcbsp_tx_done(s);
3897
    qemu_del_timer(s->sink_timer);
3898
}
3899

    
3900
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3901
{
3902
    int prev_rx_rate, prev_tx_rate;
3903
    int rx_rate = 0, tx_rate = 0;
3904
    int cpu_rate = 1500000;        /* XXX */
3905

    
3906
    /* TODO: check CLKSTP bit */
3907
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
3908
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
3909
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3910
                            (s->pcr & (1 << 8))) {        /* CLKRM */
3911
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3912
                    rx_rate = cpu_rate /
3913
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3914
            } else
3915
                if (s->codec)
3916
                    rx_rate = s->codec->rx_rate;
3917
        }
3918

    
3919
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
3920
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3921
                            (s->pcr & (1 << 9))) {        /* CLKXM */
3922
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3923
                    tx_rate = cpu_rate /
3924
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3925
            } else
3926
                if (s->codec)
3927
                    tx_rate = s->codec->tx_rate;
3928
        }
3929
    }
3930
    prev_tx_rate = s->tx_rate;
3931
    prev_rx_rate = s->rx_rate;
3932
    s->tx_rate = tx_rate;
3933
    s->rx_rate = rx_rate;
3934

    
3935
    if (s->codec)
3936
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3937

    
3938
    if (!prev_tx_rate && tx_rate)
3939
        omap_mcbsp_tx_start(s);
3940
    else if (s->tx_rate && !tx_rate)
3941
        omap_mcbsp_tx_stop(s);
3942

    
3943
    if (!prev_rx_rate && rx_rate)
3944
        omap_mcbsp_rx_start(s);
3945
    else if (prev_tx_rate && !tx_rate)
3946
        omap_mcbsp_rx_stop(s);
3947
}
3948

    
3949
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
3950
{
3951
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3952
    int offset = addr & OMAP_MPUI_REG_MASK;
3953
    uint16_t ret;
3954

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

    
3978
    case 0x04:        /* DXR2 */
3979
    case 0x06:        /* DXR1 */
3980
        return 0x0000;
3981

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

    
4038
    OMAP_BAD_REG(addr);
4039
    return 0;
4040
}
4041

    
4042
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
4043
                uint32_t value)
4044
{
4045
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4046
    int offset = addr & OMAP_MPUI_REG_MASK;
4047

    
4048
    switch (offset) {
4049
    case 0x00:        /* DRR2 */
4050
    case 0x02:        /* DRR1 */
4051
        OMAP_RO_REG(addr);
4052
        return;
4053

    
4054
    case 0x04:        /* DXR2 */
4055
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4056
            return;
4057
        /* Fall through.  */
4058
    case 0x06:        /* DXR1 */
4059
        if (s->tx_req > 1) {
4060
            s->tx_req -= 2;
4061
            if (s->codec && s->codec->cts) {
4062
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
4063
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
4064
            }
4065
            if (s->tx_req < 2)
4066
                omap_mcbsp_tx_done(s);
4067
        } else
4068
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4069
        return;
4070

    
4071
    case 0x08:        /* SPCR2 */
4072
        s->spcr[1] &= 0x0002;
4073
        s->spcr[1] |= 0x03f9 & value;
4074
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
4075
        if (~value & 1)                                        /* XRST */
4076
            s->spcr[1] &= ~6;
4077
        omap_mcbsp_req_update(s);
4078
        return;
4079
    case 0x0a:        /* SPCR1 */
4080
        s->spcr[0] &= 0x0006;
4081
        s->spcr[0] |= 0xf8f9 & value;
4082
        if (value & (1 << 15))                                /* DLB */
4083
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
4084
        if (~value & 1) {                                /* RRST */
4085
            s->spcr[0] &= ~6;
4086
            s->rx_req = 0;
4087
            omap_mcbsp_rx_done(s);
4088
        }
4089
        omap_mcbsp_req_update(s);
4090
        return;
4091

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

    
4177
    OMAP_BAD_REG(addr);
4178
}
4179

    
4180
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
4181
                uint32_t value)
4182
{
4183
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4184
    int offset = addr & OMAP_MPUI_REG_MASK;
4185

    
4186
    if (offset == 0x04) {                                /* DXR */
4187
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4188
            return;
4189
        if (s->tx_req > 3) {
4190
            s->tx_req -= 4;
4191
            if (s->codec && s->codec->cts) {
4192
                s->codec->out.fifo[s->codec->out.len ++] =
4193
                        (value >> 24) & 0xff;
4194
                s->codec->out.fifo[s->codec->out.len ++] =
4195
                        (value >> 16) & 0xff;
4196
                s->codec->out.fifo[s->codec->out.len ++] =
4197
                        (value >> 8) & 0xff;
4198
                s->codec->out.fifo[s->codec->out.len ++] =
4199
                        (value >> 0) & 0xff;
4200
            }
4201
            if (s->tx_req < 4)
4202
                omap_mcbsp_tx_done(s);
4203
        } else
4204
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4205
        return;
4206
    }
4207

    
4208
    omap_badwidth_write16(opaque, addr, value);
4209
}
4210

    
4211
static CPUReadMemoryFunc * const omap_mcbsp_readfn[] = {
4212
    omap_badwidth_read16,
4213
    omap_mcbsp_read,
4214
    omap_badwidth_read16,
4215
};
4216

    
4217
static CPUWriteMemoryFunc * const omap_mcbsp_writefn[] = {
4218
    omap_badwidth_write16,
4219
    omap_mcbsp_writeh,
4220
    omap_mcbsp_writew,
4221
};
4222

    
4223
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
4224
{
4225
    memset(&s->spcr, 0, sizeof(s->spcr));
4226
    memset(&s->rcr, 0, sizeof(s->rcr));
4227
    memset(&s->xcr, 0, sizeof(s->xcr));
4228
    s->srgr[0] = 0x0001;
4229
    s->srgr[1] = 0x2000;
4230
    memset(&s->mcr, 0, sizeof(s->mcr));
4231
    memset(&s->pcr, 0, sizeof(s->pcr));
4232
    memset(&s->rcer, 0, sizeof(s->rcer));
4233
    memset(&s->xcer, 0, sizeof(s->xcer));
4234
    s->tx_req = 0;
4235
    s->rx_req = 0;
4236
    s->tx_rate = 0;
4237
    s->rx_rate = 0;
4238
    qemu_del_timer(s->source_timer);
4239
    qemu_del_timer(s->sink_timer);
4240
}
4241

    
4242
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
4243
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
4244
{
4245
    int iomemtype;
4246
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
4247
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
4248

    
4249
    s->txirq = irq[0];
4250
    s->rxirq = irq[1];
4251
    s->txdrq = dma[0];
4252
    s->rxdrq = dma[1];
4253
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
4254
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
4255
    omap_mcbsp_reset(s);
4256

    
4257
    iomemtype = cpu_register_io_memory(omap_mcbsp_readfn,
4258
                    omap_mcbsp_writefn, s);
4259
    cpu_register_physical_memory(base, 0x800, iomemtype);
4260

    
4261
    return s;
4262
}
4263

    
4264
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4265
{
4266
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4267

    
4268
    if (s->rx_rate) {
4269
        s->rx_req = s->codec->in.len;
4270
        omap_mcbsp_rx_newdata(s);
4271
    }
4272
}
4273

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

    
4278
    if (s->tx_rate) {
4279
        s->tx_req = s->codec->out.size;
4280
        omap_mcbsp_tx_newdata(s);
4281
    }
4282
}
4283

    
4284
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
4285
{
4286
    s->codec = slave;
4287
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4288
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4289
}
4290

    
4291
/* LED Pulse Generators */
4292
struct omap_lpg_s {
4293
    QEMUTimer *tm;
4294

    
4295
    uint8_t control;
4296
    uint8_t power;
4297
    int64_t on;
4298
    int64_t period;
4299
    int clk;
4300
    int cycle;
4301
};
4302

    
4303
static void omap_lpg_tick(void *opaque)
4304
{
4305
    struct omap_lpg_s *s = opaque;
4306

    
4307
    if (s->cycle)
4308
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
4309
    else
4310
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
4311

    
4312
    s->cycle = !s->cycle;
4313
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
4314
}
4315

    
4316
static void omap_lpg_update(struct omap_lpg_s *s)
4317
{
4318
    int64_t on, period = 1, ticks = 1000;
4319
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
4320

    
4321
    if (~s->control & (1 << 6))                                        /* LPGRES */
4322
        on = 0;
4323
    else if (s->control & (1 << 7))                                /* PERM_ON */
4324
        on = period;
4325
    else {
4326
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
4327
                        256 / 32);
4328
        on = (s->clk && s->power) ? muldiv64(ticks,
4329
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
4330
    }
4331

    
4332
    qemu_del_timer(s->tm);
4333
    if (on == period && s->on < s->period)
4334
        printf("%s: LED is on\n", __FUNCTION__);
4335
    else if (on == 0 && s->on)
4336
        printf("%s: LED is off\n", __FUNCTION__);
4337
    else if (on && (on != s->on || period != s->period)) {
4338
        s->cycle = 0;
4339
        s->on = on;
4340
        s->period = period;
4341
        omap_lpg_tick(s);
4342
        return;
4343
    }
4344

    
4345
    s->on = on;
4346
    s->period = period;
4347
}
4348

    
4349
static void omap_lpg_reset(struct omap_lpg_s *s)
4350
{
4351
    s->control = 0x00;
4352
    s->power = 0x00;
4353
    s->clk = 1;
4354
    omap_lpg_update(s);
4355
}
4356

    
4357
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
4358
{
4359
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4360
    int offset = addr & OMAP_MPUI_REG_MASK;
4361

    
4362
    switch (offset) {
4363
    case 0x00:        /* LCR */
4364
        return s->control;
4365

    
4366
    case 0x04:        /* PMR */
4367
        return s->power;
4368
    }
4369

    
4370
    OMAP_BAD_REG(addr);
4371
    return 0;
4372
}
4373

    
4374
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
4375
                uint32_t value)
4376
{
4377
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4378
    int offset = addr & OMAP_MPUI_REG_MASK;
4379

    
4380
    switch (offset) {
4381
    case 0x00:        /* LCR */
4382
        if (~value & (1 << 6))                                        /* LPGRES */
4383
            omap_lpg_reset(s);
4384
        s->control = value & 0xff;
4385
        omap_lpg_update(s);
4386
        return;
4387

    
4388
    case 0x04:        /* PMR */
4389
        s->power = value & 0x01;
4390
        omap_lpg_update(s);
4391
        return;
4392

    
4393
    default:
4394
        OMAP_BAD_REG(addr);
4395
        return;
4396
    }
4397
}
4398

    
4399
static CPUReadMemoryFunc * const omap_lpg_readfn[] = {
4400
    omap_lpg_read,
4401
    omap_badwidth_read8,
4402
    omap_badwidth_read8,
4403
};
4404

    
4405
static CPUWriteMemoryFunc * const omap_lpg_writefn[] = {
4406
    omap_lpg_write,
4407
    omap_badwidth_write8,
4408
    omap_badwidth_write8,
4409
};
4410

    
4411
static void omap_lpg_clk_update(void *opaque, int line, int on)
4412
{
4413
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4414

    
4415
    s->clk = on;
4416
    omap_lpg_update(s);
4417
}
4418

    
4419
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4420
{
4421
    int iomemtype;
4422
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4423
            qemu_mallocz(sizeof(struct omap_lpg_s));
4424

    
4425
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4426

    
4427
    omap_lpg_reset(s);
4428

    
4429
    iomemtype = cpu_register_io_memory(omap_lpg_readfn,
4430
                    omap_lpg_writefn, s);
4431
    cpu_register_physical_memory(base, 0x800, iomemtype);
4432

    
4433
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4434

    
4435
    return s;
4436
}
4437

    
4438
/* MPUI Peripheral Bridge configuration */
4439
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
4440
{
4441
    if (addr == OMAP_MPUI_BASE)        /* CMR */
4442
        return 0xfe4d;
4443

    
4444
    OMAP_BAD_REG(addr);
4445
    return 0;
4446
}
4447

    
4448
static CPUReadMemoryFunc * const omap_mpui_io_readfn[] = {
4449
    omap_badwidth_read16,
4450
    omap_mpui_io_read,
4451
    omap_badwidth_read16,
4452
};
4453

    
4454
static CPUWriteMemoryFunc * const omap_mpui_io_writefn[] = {
4455
    omap_badwidth_write16,
4456
    omap_badwidth_write16,
4457
    omap_badwidth_write16,
4458
};
4459

    
4460
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4461
{
4462
    int iomemtype = cpu_register_io_memory(omap_mpui_io_readfn,
4463
                    omap_mpui_io_writefn, mpu);
4464
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
4465
}
4466

    
4467
/* General chip reset */
4468
static void omap1_mpu_reset(void *opaque)
4469
{
4470
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4471

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

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

    
4536
    { 0 }
4537
};
4538

    
4539
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4540
{
4541
    int io;
4542

    
4543
    for (; map->phys_dsp; map ++) {
4544
        io = cpu_get_physical_page_desc(map->phys_mpu);
4545

    
4546
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4547
    }
4548
}
4549

    
4550
void omap_mpu_wakeup(void *opaque, int irq, int req)
4551
{
4552
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4553

    
4554
    if (mpu->env->halted)
4555
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4556
}
4557

    
4558
static const struct dma_irq_map omap1_dma_irq_map[] = {
4559
    { 0, OMAP_INT_DMA_CH0_6 },
4560
    { 0, OMAP_INT_DMA_CH1_7 },
4561
    { 0, OMAP_INT_DMA_CH2_8 },
4562
    { 0, OMAP_INT_DMA_CH3 },
4563
    { 0, OMAP_INT_DMA_CH4 },
4564
    { 0, OMAP_INT_DMA_CH5 },
4565
    { 1, OMAP_INT_1610_DMA_CH6 },
4566
    { 1, OMAP_INT_1610_DMA_CH7 },
4567
    { 1, OMAP_INT_1610_DMA_CH8 },
4568
    { 1, OMAP_INT_1610_DMA_CH9 },
4569
    { 1, OMAP_INT_1610_DMA_CH10 },
4570
    { 1, OMAP_INT_1610_DMA_CH11 },
4571
    { 1, OMAP_INT_1610_DMA_CH12 },
4572
    { 1, OMAP_INT_1610_DMA_CH13 },
4573
    { 1, OMAP_INT_1610_DMA_CH14 },
4574
    { 1, OMAP_INT_1610_DMA_CH15 }
4575
};
4576

    
4577
/* DMA ports for OMAP1 */
4578
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
4579
                target_phys_addr_t addr)
4580
{
4581
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
4582
}
4583

    
4584
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
4585
                target_phys_addr_t addr)
4586
{
4587
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
4588
}
4589

    
4590
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
4591
                target_phys_addr_t addr)
4592
{
4593
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
4594
}
4595

    
4596
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
4597
                target_phys_addr_t addr)
4598
{
4599
    return addr >= 0xfffb0000 && addr < 0xffff0000;
4600
}
4601

    
4602
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
4603
                target_phys_addr_t addr)
4604
{
4605
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
4606
}
4607

    
4608
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
4609
                target_phys_addr_t addr)
4610
{
4611
    return addr >= 0xe1010000 && addr < 0xe1020004;
4612
}
4613

    
4614
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4615
                const char *core)
4616
{
4617
    int i;
4618
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4619
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4620
    ram_addr_t imif_base, emiff_base;
4621
    qemu_irq *cpu_irq;
4622
    qemu_irq dma_irqs[6];
4623
    DriveInfo *dinfo;
4624

    
4625
    if (!core)
4626
        core = "ti925t";
4627

    
4628
    /* Core */
4629
    s->mpu_model = omap310;
4630
    s->env = cpu_init(core);
4631
    if (!s->env) {
4632
        fprintf(stderr, "Unable to find CPU definition\n");
4633
        exit(1);
4634
    }
4635
    s->sdram_size = sdram_size;
4636
    s->sram_size = OMAP15XX_SRAM_SIZE;
4637

    
4638
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4639

    
4640
    /* Clocks */
4641
    omap_clk_init(s);
4642

    
4643
    /* Memory-mapped stuff */
4644
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4645
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4646
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4647
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4648

    
4649
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4650

    
4651
    cpu_irq = arm_pic_init_cpu(s->env);
4652
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
4653
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4654
                    omap_findclk(s, "arminth_ck"));
4655
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1],
4656
                    s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
4657
                    omap_findclk(s, "arminth_ck"));
4658

    
4659
    for (i = 0; i < 6; i ++)
4660
        dma_irqs[i] =
4661
                s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr];
4662
    s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
4663
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
4664

    
4665
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4666
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4667
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4668
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4669
    s->port[local    ].addr_valid = omap_validate_local_addr;
4670
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4671

    
4672
    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
4673
    soc_dma_port_add_mem_ram(s->dma,
4674
                    emiff_base, OMAP_EMIFF_BASE, s->sdram_size);
4675
    soc_dma_port_add_mem_ram(s->dma,
4676
                    imif_base, OMAP_IMIF_BASE, s->sram_size);
4677

    
4678
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4679
                    s->irq[0][OMAP_INT_TIMER1],
4680
                    omap_findclk(s, "mputim_ck"));
4681
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4682
                    s->irq[0][OMAP_INT_TIMER2],
4683
                    omap_findclk(s, "mputim_ck"));
4684
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4685
                    s->irq[0][OMAP_INT_TIMER3],
4686
                    omap_findclk(s, "mputim_ck"));
4687

    
4688
    s->wdt = omap_wd_timer_init(0xfffec800,
4689
                    s->irq[0][OMAP_INT_WD_TIMER],
4690
                    omap_findclk(s, "armwdt_ck"));
4691

    
4692
    s->os_timer = omap_os_timer_init(0xfffb9000,
4693
                    s->irq[1][OMAP_INT_OS_TIMER],
4694
                    omap_findclk(s, "clk32-kHz"));
4695

    
4696
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4697
                    omap_dma_get_lcdch(s->dma), imif_base, emiff_base,
4698
                    omap_findclk(s, "lcd_ck"));
4699

    
4700
    omap_ulpd_pm_init(0xfffe0800, s);
4701
    omap_pin_cfg_init(0xfffe1000, s);
4702
    omap_id_init(s);
4703

    
4704
    omap_mpui_init(0xfffec900, s);
4705

    
4706
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4707
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4708
                    omap_findclk(s, "tipb_ck"));
4709
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4710
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4711
                    omap_findclk(s, "tipb_ck"));
4712

    
4713
    omap_tcmi_init(0xfffecc00, s);
4714

    
4715
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4716
                    omap_findclk(s, "uart1_ck"),
4717
                    omap_findclk(s, "uart1_ck"),
4718
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
4719
                    serial_hds[0]);
4720
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4721
                    omap_findclk(s, "uart2_ck"),
4722
                    omap_findclk(s, "uart2_ck"),
4723
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
4724
                    serial_hds[0] ? serial_hds[1] : NULL);
4725
    s->uart[2] = omap_uart_init(0xfffb9800, s->irq[0][OMAP_INT_UART3],
4726
                    omap_findclk(s, "uart3_ck"),
4727
                    omap_findclk(s, "uart3_ck"),
4728
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
4729
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
4730

    
4731
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4732
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4733
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4734

    
4735
    dinfo = drive_get(IF_SD, 0, 0);
4736
    if (!dinfo) {
4737
        fprintf(stderr, "qemu: missing SecureDigital device\n");
4738
        exit(1);
4739
    }
4740
    s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv,
4741
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
4742
                    omap_findclk(s, "mmc_ck"));
4743

    
4744
    s->mpuio = omap_mpuio_init(0xfffb5000,
4745
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4746
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
4747

    
4748
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4749
                    omap_findclk(s, "arm_gpio_ck"));
4750

    
4751
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4752
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4753

    
4754
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4755
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4756

    
4757
    s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4758
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4759

    
4760
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4761
                    omap_findclk(s, "clk32-kHz"));
4762

    
4763
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
4764
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4765
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
4766
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4767
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
4768
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4769

    
4770
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
4771
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
4772

    
4773
    /* Register mappings not currenlty implemented:
4774
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4775
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4776
     * USB W2FC                fffb4000 - fffb47ff
4777
     * Camera Interface        fffb6800 - fffb6fff
4778
     * USB Host                fffba000 - fffba7ff
4779
     * FAC                fffba800 - fffbafff
4780
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4781
     * TIPB switches        fffbc800 - fffbcfff
4782
     * Mailbox                fffcf000 - fffcf7ff
4783
     * Local bus IF        fffec100 - fffec1ff
4784
     * Local bus MMU        fffec200 - fffec2ff
4785
     * DSP MMU                fffed200 - fffed2ff
4786
     */
4787

    
4788
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
4789
    omap_setup_mpui_io(s);
4790

    
4791
    qemu_register_reset(omap1_mpu_reset, s);
4792

    
4793
    return s;
4794
}