Statistics
| Branch: | Revision:

root / hw / omap1.c @ 879c2813

History | View | Annotate | Download (132.1 kB)

1
/*
2
 * TI OMAP processors emulation.
3
 *
4
 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as
8
 * published by the Free Software Foundation; either version 2 or
9
 * (at your option) version 3 of the License.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License 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
#ifdef TARGET_WORDS_BIGENDIAN
1990
    s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
1991
                               chr ?: qemu_chr_open("null", "null", NULL), 1,
1992
                               1);
1993
#else
1994
    s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
1995
                               chr ?: qemu_chr_open("null", "null", NULL), 1,
1996
                               0);
1997
#endif
1998
    return s;
1999
}
2000

    
2001
static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr)
2002
{
2003
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
2004

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

    
2031
    OMAP_BAD_REG(addr);
2032
    return 0;
2033
}
2034

    
2035
static void omap_uart_write(void *opaque, target_phys_addr_t addr,
2036
                uint32_t value)
2037
{
2038
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
2039

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

    
2078
static CPUReadMemoryFunc * const omap_uart_readfn[] = {
2079
    omap_uart_read,
2080
    omap_uart_read,
2081
    omap_badwidth_read8,
2082
};
2083

    
2084
static CPUWriteMemoryFunc * const omap_uart_writefn[] = {
2085
    omap_uart_write,
2086
    omap_uart_write,
2087
    omap_badwidth_write8,
2088
};
2089

    
2090
struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta,
2091
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
2092
                qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr)
2093
{
2094
    target_phys_addr_t base = omap_l4_attach(ta, 0, 0);
2095
    struct omap_uart_s *s = omap_uart_init(base, irq,
2096
                    fclk, iclk, txdma, rxdma, chr);
2097
    int iomemtype = cpu_register_io_memory(omap_uart_readfn,
2098
                    omap_uart_writefn, s);
2099

    
2100
    s->ta = ta;
2101

    
2102
    cpu_register_physical_memory(base + 0x20, 0x100, iomemtype);
2103

    
2104
    return s;
2105
}
2106

    
2107
void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
2108
{
2109
    /* TODO: Should reuse or destroy current s->serial */
2110
#ifdef TARGET_WORDS_BIGENDIAN
2111
    s->serial = serial_mm_init(s->base, 2, s->irq,
2112
                               omap_clk_getrate(s->fclk) / 16,
2113
                               chr ?: qemu_chr_open("null", "null", NULL), 1,
2114
                               1);
2115
#else
2116
    s->serial = serial_mm_init(s->base, 2, s->irq,
2117
                               omap_clk_getrate(s->fclk) / 16,
2118
                               chr ?: qemu_chr_open("null", "null", NULL), 1,
2119
                               0);
2120
#endif
2121
}
2122

    
2123
/* MPU Clock/Reset/Power Mode Control */
2124
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2125
{
2126
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2127

    
2128
    switch (addr) {
2129
    case 0x00:        /* ARM_CKCTL */
2130
        return s->clkm.arm_ckctl;
2131

    
2132
    case 0x04:        /* ARM_IDLECT1 */
2133
        return s->clkm.arm_idlect1;
2134

    
2135
    case 0x08:        /* ARM_IDLECT2 */
2136
        return s->clkm.arm_idlect2;
2137

    
2138
    case 0x0c:        /* ARM_EWUPCT */
2139
        return s->clkm.arm_ewupct;
2140

    
2141
    case 0x10:        /* ARM_RSTCT1 */
2142
        return s->clkm.arm_rstct1;
2143

    
2144
    case 0x14:        /* ARM_RSTCT2 */
2145
        return s->clkm.arm_rstct2;
2146

    
2147
    case 0x18:        /* ARM_SYSST */
2148
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
2149

    
2150
    case 0x1c:        /* ARM_CKOUT1 */
2151
        return s->clkm.arm_ckout1;
2152

    
2153
    case 0x20:        /* ARM_CKOUT2 */
2154
        break;
2155
    }
2156

    
2157
    OMAP_BAD_REG(addr);
2158
    return 0;
2159
}
2160

    
2161
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2162
                uint16_t diff, uint16_t value)
2163
{
2164
    omap_clk clk;
2165

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

    
2208
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2209
                uint16_t diff, uint16_t value)
2210
{
2211
    omap_clk clk;
2212

    
2213
    if (value & (1 << 11))                                /* SETARM_IDLE */
2214
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2215
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2216
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2217

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

    
2239
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2240
                uint16_t diff, uint16_t value)
2241
{
2242
    omap_clk clk;
2243

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

    
2262
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2263
                uint16_t diff, uint16_t value)
2264
{
2265
    omap_clk clk;
2266

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

    
2320
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2321
                uint32_t value)
2322
{
2323
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2324
    uint16_t diff;
2325
    omap_clk clk;
2326
    static const char *clkschemename[8] = {
2327
        "fully synchronous", "fully asynchronous", "synchronous scalable",
2328
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2329
    };
2330

    
2331
    switch (addr) {
2332
    case 0x00:        /* ARM_CKCTL */
2333
        diff = s->clkm.arm_ckctl ^ value;
2334
        s->clkm.arm_ckctl = value & 0x7fff;
2335
        omap_clkm_ckctl_update(s, diff, value);
2336
        return;
2337

    
2338
    case 0x04:        /* ARM_IDLECT1 */
2339
        diff = s->clkm.arm_idlect1 ^ value;
2340
        s->clkm.arm_idlect1 = value & 0x0fff;
2341
        omap_clkm_idlect1_update(s, diff, value);
2342
        return;
2343

    
2344
    case 0x08:        /* ARM_IDLECT2 */
2345
        diff = s->clkm.arm_idlect2 ^ value;
2346
        s->clkm.arm_idlect2 = value & 0x07ff;
2347
        omap_clkm_idlect2_update(s, diff, value);
2348
        return;
2349

    
2350
    case 0x0c:        /* ARM_EWUPCT */
2351
        s->clkm.arm_ewupct = value & 0x003f;
2352
        return;
2353

    
2354
    case 0x10:        /* ARM_RSTCT1 */
2355
        diff = s->clkm.arm_rstct1 ^ value;
2356
        s->clkm.arm_rstct1 = value & 0x0007;
2357
        if (value & 9) {
2358
            qemu_system_reset_request();
2359
            s->clkm.cold_start = 0xa;
2360
        }
2361
        if (diff & ~value & 4) {                                /* DSP_RST */
2362
            omap_mpui_reset(s);
2363
            omap_tipb_bridge_reset(s->private_tipb);
2364
            omap_tipb_bridge_reset(s->public_tipb);
2365
        }
2366
        if (diff & 2) {                                                /* DSP_EN */
2367
            clk = omap_findclk(s, "dsp_ck");
2368
            omap_clk_canidle(clk, (~value >> 1) & 1);
2369
        }
2370
        return;
2371

    
2372
    case 0x14:        /* ARM_RSTCT2 */
2373
        s->clkm.arm_rstct2 = value & 0x0001;
2374
        return;
2375

    
2376
    case 0x18:        /* ARM_SYSST */
2377
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
2378
            s->clkm.clocking_scheme = (value >> 11) & 7;
2379
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2380
                            clkschemename[s->clkm.clocking_scheme]);
2381
        }
2382
        s->clkm.cold_start &= value & 0x3f;
2383
        return;
2384

    
2385
    case 0x1c:        /* ARM_CKOUT1 */
2386
        diff = s->clkm.arm_ckout1 ^ value;
2387
        s->clkm.arm_ckout1 = value & 0x003f;
2388
        omap_clkm_ckout1_update(s, diff, value);
2389
        return;
2390

    
2391
    case 0x20:        /* ARM_CKOUT2 */
2392
    default:
2393
        OMAP_BAD_REG(addr);
2394
    }
2395
}
2396

    
2397
static CPUReadMemoryFunc * const omap_clkm_readfn[] = {
2398
    omap_badwidth_read16,
2399
    omap_clkm_read,
2400
    omap_badwidth_read16,
2401
};
2402

    
2403
static CPUWriteMemoryFunc * const omap_clkm_writefn[] = {
2404
    omap_badwidth_write16,
2405
    omap_clkm_write,
2406
    omap_badwidth_write16,
2407
};
2408

    
2409
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2410
{
2411
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2412

    
2413
    switch (addr) {
2414
    case 0x04:        /* DSP_IDLECT1 */
2415
        return s->clkm.dsp_idlect1;
2416

    
2417
    case 0x08:        /* DSP_IDLECT2 */
2418
        return s->clkm.dsp_idlect2;
2419

    
2420
    case 0x14:        /* DSP_RSTCT2 */
2421
        return s->clkm.dsp_rstct2;
2422

    
2423
    case 0x18:        /* DSP_SYSST */
2424
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
2425
                (s->env->halted << 6);        /* Quite useless... */
2426
    }
2427

    
2428
    OMAP_BAD_REG(addr);
2429
    return 0;
2430
}
2431

    
2432
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2433
                uint16_t diff, uint16_t value)
2434
{
2435
    omap_clk clk;
2436

    
2437
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2438
}
2439

    
2440
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2441
                uint16_t diff, uint16_t value)
2442
{
2443
    omap_clk clk;
2444

    
2445
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2446
}
2447

    
2448
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2449
                uint32_t value)
2450
{
2451
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2452
    uint16_t diff;
2453

    
2454
    switch (addr) {
2455
    case 0x04:        /* DSP_IDLECT1 */
2456
        diff = s->clkm.dsp_idlect1 ^ value;
2457
        s->clkm.dsp_idlect1 = value & 0x01f7;
2458
        omap_clkdsp_idlect1_update(s, diff, value);
2459
        break;
2460

    
2461
    case 0x08:        /* DSP_IDLECT2 */
2462
        s->clkm.dsp_idlect2 = value & 0x0037;
2463
        diff = s->clkm.dsp_idlect1 ^ value;
2464
        omap_clkdsp_idlect2_update(s, diff, value);
2465
        break;
2466

    
2467
    case 0x14:        /* DSP_RSTCT2 */
2468
        s->clkm.dsp_rstct2 = value & 0x0001;
2469
        break;
2470

    
2471
    case 0x18:        /* DSP_SYSST */
2472
        s->clkm.cold_start &= value & 0x3f;
2473
        break;
2474

    
2475
    default:
2476
        OMAP_BAD_REG(addr);
2477
    }
2478
}
2479

    
2480
static CPUReadMemoryFunc * const omap_clkdsp_readfn[] = {
2481
    omap_badwidth_read16,
2482
    omap_clkdsp_read,
2483
    omap_badwidth_read16,
2484
};
2485

    
2486
static CPUWriteMemoryFunc * const omap_clkdsp_writefn[] = {
2487
    omap_badwidth_write16,
2488
    omap_clkdsp_write,
2489
    omap_badwidth_write16,
2490
};
2491

    
2492
static void omap_clkm_reset(struct omap_mpu_state_s *s)
2493
{
2494
    if (s->wdt && s->wdt->reset)
2495
        s->clkm.cold_start = 0x6;
2496
    s->clkm.clocking_scheme = 0;
2497
    omap_clkm_ckctl_update(s, ~0, 0x3000);
2498
    s->clkm.arm_ckctl = 0x3000;
2499
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
2500
    s->clkm.arm_idlect1 = 0x0400;
2501
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
2502
    s->clkm.arm_idlect2 = 0x0100;
2503
    s->clkm.arm_ewupct = 0x003f;
2504
    s->clkm.arm_rstct1 = 0x0000;
2505
    s->clkm.arm_rstct2 = 0x0000;
2506
    s->clkm.arm_ckout1 = 0x0015;
2507
    s->clkm.dpll1_mode = 0x2002;
2508
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2509
    s->clkm.dsp_idlect1 = 0x0040;
2510
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2511
    s->clkm.dsp_idlect2 = 0x0000;
2512
    s->clkm.dsp_rstct2 = 0x0000;
2513
}
2514

    
2515
static void omap_clkm_init(target_phys_addr_t mpu_base,
2516
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2517
{
2518
    int iomemtype[2] = {
2519
        cpu_register_io_memory(omap_clkm_readfn, omap_clkm_writefn, s),
2520
        cpu_register_io_memory(omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2521
    };
2522

    
2523
    s->clkm.arm_idlect1 = 0x03ff;
2524
    s->clkm.arm_idlect2 = 0x0100;
2525
    s->clkm.dsp_idlect1 = 0x0002;
2526
    omap_clkm_reset(s);
2527
    s->clkm.cold_start = 0x3a;
2528

    
2529
    cpu_register_physical_memory(mpu_base, 0x100, iomemtype[0]);
2530
    cpu_register_physical_memory(dsp_base, 0x1000, iomemtype[1]);
2531
}
2532

    
2533
/* MPU I/O */
2534
struct omap_mpuio_s {
2535
    qemu_irq irq;
2536
    qemu_irq kbd_irq;
2537
    qemu_irq *in;
2538
    qemu_irq handler[16];
2539
    qemu_irq wakeup;
2540

    
2541
    uint16_t inputs;
2542
    uint16_t outputs;
2543
    uint16_t dir;
2544
    uint16_t edge;
2545
    uint16_t mask;
2546
    uint16_t ints;
2547

    
2548
    uint16_t debounce;
2549
    uint16_t latch;
2550
    uint8_t event;
2551

    
2552
    uint8_t buttons[5];
2553
    uint8_t row_latch;
2554
    uint8_t cols;
2555
    int kbd_mask;
2556
    int clk;
2557
};
2558

    
2559
static void omap_mpuio_set(void *opaque, int line, int level)
2560
{
2561
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2562
    uint16_t prev = s->inputs;
2563

    
2564
    if (level)
2565
        s->inputs |= 1 << line;
2566
    else
2567
        s->inputs &= ~(1 << line);
2568

    
2569
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2570
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2571
            s->ints |= 1 << line;
2572
            qemu_irq_raise(s->irq);
2573
            /* TODO: wakeup */
2574
        }
2575
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
2576
                (s->event >> 1) == line)        /* PIN_SELECT */
2577
            s->latch = s->inputs;
2578
    }
2579
}
2580

    
2581
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2582
{
2583
    int i;
2584
    uint8_t *row, rows = 0, cols = ~s->cols;
2585

    
2586
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2587
        if (*row & cols)
2588
            rows |= i;
2589

    
2590
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
2591
    s->row_latch = ~rows;
2592
}
2593

    
2594
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2595
{
2596
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2597
    int offset = addr & OMAP_MPUI_REG_MASK;
2598
    uint16_t ret;
2599

    
2600
    switch (offset) {
2601
    case 0x00:        /* INPUT_LATCH */
2602
        return s->inputs;
2603

    
2604
    case 0x04:        /* OUTPUT_REG */
2605
        return s->outputs;
2606

    
2607
    case 0x08:        /* IO_CNTL */
2608
        return s->dir;
2609

    
2610
    case 0x10:        /* KBR_LATCH */
2611
        return s->row_latch;
2612

    
2613
    case 0x14:        /* KBC_REG */
2614
        return s->cols;
2615

    
2616
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2617
        return s->event;
2618

    
2619
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2620
        return s->edge;
2621

    
2622
    case 0x20:        /* KBD_INT */
2623
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
2624

    
2625
    case 0x24:        /* GPIO_INT */
2626
        ret = s->ints;
2627
        s->ints &= s->mask;
2628
        if (ret)
2629
            qemu_irq_lower(s->irq);
2630
        return ret;
2631

    
2632
    case 0x28:        /* KBD_MASKIT */
2633
        return s->kbd_mask;
2634

    
2635
    case 0x2c:        /* GPIO_MASKIT */
2636
        return s->mask;
2637

    
2638
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2639
        return s->debounce;
2640

    
2641
    case 0x34:        /* GPIO_LATCH_REG */
2642
        return s->latch;
2643
    }
2644

    
2645
    OMAP_BAD_REG(addr);
2646
    return 0;
2647
}
2648

    
2649
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2650
                uint32_t value)
2651
{
2652
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2653
    int offset = addr & OMAP_MPUI_REG_MASK;
2654
    uint16_t diff;
2655
    int ln;
2656

    
2657
    switch (offset) {
2658
    case 0x04:        /* OUTPUT_REG */
2659
        diff = (s->outputs ^ value) & ~s->dir;
2660
        s->outputs = value;
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 0x08:        /* IO_CNTL */
2670
        diff = s->outputs & (s->dir ^ value);
2671
        s->dir = value;
2672

    
2673
        value = s->outputs & ~s->dir;
2674
        while ((ln = ffs(diff))) {
2675
            ln --;
2676
            if (s->handler[ln])
2677
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2678
            diff &= ~(1 << ln);
2679
        }
2680
        break;
2681

    
2682
    case 0x14:        /* KBC_REG */
2683
        s->cols = value;
2684
        omap_mpuio_kbd_update(s);
2685
        break;
2686

    
2687
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2688
        s->event = value & 0x1f;
2689
        break;
2690

    
2691
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2692
        s->edge = value;
2693
        break;
2694

    
2695
    case 0x28:        /* KBD_MASKIT */
2696
        s->kbd_mask = value & 1;
2697
        omap_mpuio_kbd_update(s);
2698
        break;
2699

    
2700
    case 0x2c:        /* GPIO_MASKIT */
2701
        s->mask = value;
2702
        break;
2703

    
2704
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2705
        s->debounce = value & 0x1ff;
2706
        break;
2707

    
2708
    case 0x00:        /* INPUT_LATCH */
2709
    case 0x10:        /* KBR_LATCH */
2710
    case 0x20:        /* KBD_INT */
2711
    case 0x24:        /* GPIO_INT */
2712
    case 0x34:        /* GPIO_LATCH_REG */
2713
        OMAP_RO_REG(addr);
2714
        return;
2715

    
2716
    default:
2717
        OMAP_BAD_REG(addr);
2718
        return;
2719
    }
2720
}
2721

    
2722
static CPUReadMemoryFunc * const omap_mpuio_readfn[] = {
2723
    omap_badwidth_read16,
2724
    omap_mpuio_read,
2725
    omap_badwidth_read16,
2726
};
2727

    
2728
static CPUWriteMemoryFunc * const omap_mpuio_writefn[] = {
2729
    omap_badwidth_write16,
2730
    omap_mpuio_write,
2731
    omap_badwidth_write16,
2732
};
2733

    
2734
static void omap_mpuio_reset(struct omap_mpuio_s *s)
2735
{
2736
    s->inputs = 0;
2737
    s->outputs = 0;
2738
    s->dir = ~0;
2739
    s->event = 0;
2740
    s->edge = 0;
2741
    s->kbd_mask = 0;
2742
    s->mask = 0;
2743
    s->debounce = 0;
2744
    s->latch = 0;
2745
    s->ints = 0;
2746
    s->row_latch = 0x1f;
2747
    s->clk = 1;
2748
}
2749

    
2750
static void omap_mpuio_onoff(void *opaque, int line, int on)
2751
{
2752
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2753

    
2754
    s->clk = on;
2755
    if (on)
2756
        omap_mpuio_kbd_update(s);
2757
}
2758

    
2759
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
2760
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2761
                omap_clk clk)
2762
{
2763
    int iomemtype;
2764
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2765
            qemu_mallocz(sizeof(struct omap_mpuio_s));
2766

    
2767
    s->irq = gpio_int;
2768
    s->kbd_irq = kbd_int;
2769
    s->wakeup = wakeup;
2770
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2771
    omap_mpuio_reset(s);
2772

    
2773
    iomemtype = cpu_register_io_memory(omap_mpuio_readfn,
2774
                    omap_mpuio_writefn, s);
2775
    cpu_register_physical_memory(base, 0x800, iomemtype);
2776

    
2777
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2778

    
2779
    return s;
2780
}
2781

    
2782
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2783
{
2784
    return s->in;
2785
}
2786

    
2787
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2788
{
2789
    if (line >= 16 || line < 0)
2790
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
2791
    s->handler[line] = handler;
2792
}
2793

    
2794
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2795
{
2796
    if (row >= 5 || row < 0)
2797
        hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
2798

    
2799
    if (down)
2800
        s->buttons[row] |= 1 << col;
2801
    else
2802
        s->buttons[row] &= ~(1 << col);
2803

    
2804
    omap_mpuio_kbd_update(s);
2805
}
2806

    
2807
/* General-Purpose I/O */
2808
struct omap_gpio_s {
2809
    qemu_irq irq;
2810
    qemu_irq *in;
2811
    qemu_irq handler[16];
2812

    
2813
    uint16_t inputs;
2814
    uint16_t outputs;
2815
    uint16_t dir;
2816
    uint16_t edge;
2817
    uint16_t mask;
2818
    uint16_t ints;
2819
    uint16_t pins;
2820
};
2821

    
2822
static void omap_gpio_set(void *opaque, int line, int level)
2823
{
2824
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2825
    uint16_t prev = s->inputs;
2826

    
2827
    if (level)
2828
        s->inputs |= 1 << line;
2829
    else
2830
        s->inputs &= ~(1 << line);
2831

    
2832
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
2833
                    (1 << line) & s->dir & ~s->mask) {
2834
        s->ints |= 1 << line;
2835
        qemu_irq_raise(s->irq);
2836
    }
2837
}
2838

    
2839
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
2840
{
2841
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2842
    int offset = addr & OMAP_MPUI_REG_MASK;
2843

    
2844
    switch (offset) {
2845
    case 0x00:        /* DATA_INPUT */
2846
        return s->inputs & s->pins;
2847

    
2848
    case 0x04:        /* DATA_OUTPUT */
2849
        return s->outputs;
2850

    
2851
    case 0x08:        /* DIRECTION_CONTROL */
2852
        return s->dir;
2853

    
2854
    case 0x0c:        /* INTERRUPT_CONTROL */
2855
        return s->edge;
2856

    
2857
    case 0x10:        /* INTERRUPT_MASK */
2858
        return s->mask;
2859

    
2860
    case 0x14:        /* INTERRUPT_STATUS */
2861
        return s->ints;
2862

    
2863
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
2864
        OMAP_BAD_REG(addr);
2865
        return s->pins;
2866
    }
2867

    
2868
    OMAP_BAD_REG(addr);
2869
    return 0;
2870
}
2871

    
2872
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
2873
                uint32_t value)
2874
{
2875
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2876
    int offset = addr & OMAP_MPUI_REG_MASK;
2877
    uint16_t diff;
2878
    int ln;
2879

    
2880
    switch (offset) {
2881
    case 0x00:        /* DATA_INPUT */
2882
        OMAP_RO_REG(addr);
2883
        return;
2884

    
2885
    case 0x04:        /* DATA_OUTPUT */
2886
        diff = (s->outputs ^ value) & ~s->dir;
2887
        s->outputs = value;
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 0x08:        /* DIRECTION_CONTROL */
2897
        diff = s->outputs & (s->dir ^ value);
2898
        s->dir = value;
2899

    
2900
        value = s->outputs & ~s->dir;
2901
        while ((ln = ffs(diff))) {
2902
            ln --;
2903
            if (s->handler[ln])
2904
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2905
            diff &= ~(1 << ln);
2906
        }
2907
        break;
2908

    
2909
    case 0x0c:        /* INTERRUPT_CONTROL */
2910
        s->edge = value;
2911
        break;
2912

    
2913
    case 0x10:        /* INTERRUPT_MASK */
2914
        s->mask = value;
2915
        break;
2916

    
2917
    case 0x14:        /* INTERRUPT_STATUS */
2918
        s->ints &= ~value;
2919
        if (!s->ints)
2920
            qemu_irq_lower(s->irq);
2921
        break;
2922

    
2923
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
2924
        OMAP_BAD_REG(addr);
2925
        s->pins = value;
2926
        break;
2927

    
2928
    default:
2929
        OMAP_BAD_REG(addr);
2930
        return;
2931
    }
2932
}
2933

    
2934
/* *Some* sources say the memory region is 32-bit.  */
2935
static CPUReadMemoryFunc * const omap_gpio_readfn[] = {
2936
    omap_badwidth_read16,
2937
    omap_gpio_read,
2938
    omap_badwidth_read16,
2939
};
2940

    
2941
static CPUWriteMemoryFunc * const omap_gpio_writefn[] = {
2942
    omap_badwidth_write16,
2943
    omap_gpio_write,
2944
    omap_badwidth_write16,
2945
};
2946

    
2947
static void omap_gpio_reset(struct omap_gpio_s *s)
2948
{
2949
    s->inputs = 0;
2950
    s->outputs = ~0;
2951
    s->dir = ~0;
2952
    s->edge = ~0;
2953
    s->mask = ~0;
2954
    s->ints = 0;
2955
    s->pins = ~0;
2956
}
2957

    
2958
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
2959
                qemu_irq irq, omap_clk clk)
2960
{
2961
    int iomemtype;
2962
    struct omap_gpio_s *s = (struct omap_gpio_s *)
2963
            qemu_mallocz(sizeof(struct omap_gpio_s));
2964

    
2965
    s->irq = irq;
2966
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
2967
    omap_gpio_reset(s);
2968

    
2969
    iomemtype = cpu_register_io_memory(omap_gpio_readfn,
2970
                    omap_gpio_writefn, s);
2971
    cpu_register_physical_memory(base, 0x1000, iomemtype);
2972

    
2973
    return s;
2974
}
2975

    
2976
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
2977
{
2978
    return s->in;
2979
}
2980

    
2981
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
2982
{
2983
    if (line >= 16 || line < 0)
2984
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
2985
    s->handler[line] = handler;
2986
}
2987

    
2988
/* MicroWire Interface */
2989
struct omap_uwire_s {
2990
    qemu_irq txirq;
2991
    qemu_irq rxirq;
2992
    qemu_irq txdrq;
2993

    
2994
    uint16_t txbuf;
2995
    uint16_t rxbuf;
2996
    uint16_t control;
2997
    uint16_t setup[5];
2998

    
2999
    uWireSlave *chip[4];
3000
};
3001

    
3002
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3003
{
3004
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3005
    uWireSlave *slave = s->chip[chipselect];
3006

    
3007
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
3008
        if (s->control & (1 << 12))                        /* CS_CMD */
3009
            if (slave && slave->send)
3010
                slave->send(slave->opaque,
3011
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
3012
        s->control &= ~(1 << 14);                        /* CSRB */
3013
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3014
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3015
    }
3016

    
3017
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
3018
        if (s->control & (1 << 12))                        /* CS_CMD */
3019
            if (slave && slave->receive)
3020
                s->rxbuf = slave->receive(slave->opaque);
3021
        s->control |= 1 << 15;                                /* RDRB */
3022
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
3023
         * a DRQ.  When is the level IRQ supposed to be reset?  */
3024
    }
3025
}
3026

    
3027
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3028
{
3029
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3030
    int offset = addr & OMAP_MPUI_REG_MASK;
3031

    
3032
    switch (offset) {
3033
    case 0x00:        /* RDR */
3034
        s->control &= ~(1 << 15);                        /* RDRB */
3035
        return s->rxbuf;
3036

    
3037
    case 0x04:        /* CSR */
3038
        return s->control;
3039

    
3040
    case 0x08:        /* SR1 */
3041
        return s->setup[0];
3042
    case 0x0c:        /* SR2 */
3043
        return s->setup[1];
3044
    case 0x10:        /* SR3 */
3045
        return s->setup[2];
3046
    case 0x14:        /* SR4 */
3047
        return s->setup[3];
3048
    case 0x18:        /* SR5 */
3049
        return s->setup[4];
3050
    }
3051

    
3052
    OMAP_BAD_REG(addr);
3053
    return 0;
3054
}
3055

    
3056
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3057
                uint32_t value)
3058
{
3059
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3060
    int offset = addr & OMAP_MPUI_REG_MASK;
3061

    
3062
    switch (offset) {
3063
    case 0x00:        /* TDR */
3064
        s->txbuf = value;                                /* TD */
3065
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3066
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3067
                         (s->control & (1 << 12)))) {        /* CS_CMD */
3068
            s->control |= 1 << 14;                        /* CSRB */
3069
            omap_uwire_transfer_start(s);
3070
        }
3071
        break;
3072

    
3073
    case 0x04:        /* CSR */
3074
        s->control = value & 0x1fff;
3075
        if (value & (1 << 13))                                /* START */
3076
            omap_uwire_transfer_start(s);
3077
        break;
3078

    
3079
    case 0x08:        /* SR1 */
3080
        s->setup[0] = value & 0x003f;
3081
        break;
3082

    
3083
    case 0x0c:        /* SR2 */
3084
        s->setup[1] = value & 0x0fc0;
3085
        break;
3086

    
3087
    case 0x10:        /* SR3 */
3088
        s->setup[2] = value & 0x0003;
3089
        break;
3090

    
3091
    case 0x14:        /* SR4 */
3092
        s->setup[3] = value & 0x0001;
3093
        break;
3094

    
3095
    case 0x18:        /* SR5 */
3096
        s->setup[4] = value & 0x000f;
3097
        break;
3098

    
3099
    default:
3100
        OMAP_BAD_REG(addr);
3101
        return;
3102
    }
3103
}
3104

    
3105
static CPUReadMemoryFunc * const omap_uwire_readfn[] = {
3106
    omap_badwidth_read16,
3107
    omap_uwire_read,
3108
    omap_badwidth_read16,
3109
};
3110

    
3111
static CPUWriteMemoryFunc * const omap_uwire_writefn[] = {
3112
    omap_badwidth_write16,
3113
    omap_uwire_write,
3114
    omap_badwidth_write16,
3115
};
3116

    
3117
static void omap_uwire_reset(struct omap_uwire_s *s)
3118
{
3119
    s->control = 0;
3120
    s->setup[0] = 0;
3121
    s->setup[1] = 0;
3122
    s->setup[2] = 0;
3123
    s->setup[3] = 0;
3124
    s->setup[4] = 0;
3125
}
3126

    
3127
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3128
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3129
{
3130
    int iomemtype;
3131
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3132
            qemu_mallocz(sizeof(struct omap_uwire_s));
3133

    
3134
    s->txirq = irq[0];
3135
    s->rxirq = irq[1];
3136
    s->txdrq = dma;
3137
    omap_uwire_reset(s);
3138

    
3139
    iomemtype = cpu_register_io_memory(omap_uwire_readfn,
3140
                    omap_uwire_writefn, s);
3141
    cpu_register_physical_memory(base, 0x800, iomemtype);
3142

    
3143
    return s;
3144
}
3145

    
3146
void omap_uwire_attach(struct omap_uwire_s *s,
3147
                uWireSlave *slave, int chipselect)
3148
{
3149
    if (chipselect < 0 || chipselect > 3) {
3150
        fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
3151
        exit(-1);
3152
    }
3153

    
3154
    s->chip[chipselect] = slave;
3155
}
3156

    
3157
/* Pseudonoise Pulse-Width Light Modulator */
3158
static void omap_pwl_update(struct omap_mpu_state_s *s)
3159
{
3160
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3161

    
3162
    if (output != s->pwl.output) {
3163
        s->pwl.output = output;
3164
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3165
    }
3166
}
3167

    
3168
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3169
{
3170
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3171
    int offset = addr & OMAP_MPUI_REG_MASK;
3172

    
3173
    switch (offset) {
3174
    case 0x00:        /* PWL_LEVEL */
3175
        return s->pwl.level;
3176
    case 0x04:        /* PWL_CTRL */
3177
        return s->pwl.enable;
3178
    }
3179
    OMAP_BAD_REG(addr);
3180
    return 0;
3181
}
3182

    
3183
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3184
                uint32_t value)
3185
{
3186
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3187
    int offset = addr & OMAP_MPUI_REG_MASK;
3188

    
3189
    switch (offset) {
3190
    case 0x00:        /* PWL_LEVEL */
3191
        s->pwl.level = value;
3192
        omap_pwl_update(s);
3193
        break;
3194
    case 0x04:        /* PWL_CTRL */
3195
        s->pwl.enable = value & 1;
3196
        omap_pwl_update(s);
3197
        break;
3198
    default:
3199
        OMAP_BAD_REG(addr);
3200
        return;
3201
    }
3202
}
3203

    
3204
static CPUReadMemoryFunc * const omap_pwl_readfn[] = {
3205
    omap_pwl_read,
3206
    omap_badwidth_read8,
3207
    omap_badwidth_read8,
3208
};
3209

    
3210
static CPUWriteMemoryFunc * const omap_pwl_writefn[] = {
3211
    omap_pwl_write,
3212
    omap_badwidth_write8,
3213
    omap_badwidth_write8,
3214
};
3215

    
3216
static void omap_pwl_reset(struct omap_mpu_state_s *s)
3217
{
3218
    s->pwl.output = 0;
3219
    s->pwl.level = 0;
3220
    s->pwl.enable = 0;
3221
    s->pwl.clk = 1;
3222
    omap_pwl_update(s);
3223
}
3224

    
3225
static void omap_pwl_clk_update(void *opaque, int line, int on)
3226
{
3227
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3228

    
3229
    s->pwl.clk = on;
3230
    omap_pwl_update(s);
3231
}
3232

    
3233
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3234
                omap_clk clk)
3235
{
3236
    int iomemtype;
3237

    
3238
    omap_pwl_reset(s);
3239

    
3240
    iomemtype = cpu_register_io_memory(omap_pwl_readfn,
3241
                    omap_pwl_writefn, s);
3242
    cpu_register_physical_memory(base, 0x800, iomemtype);
3243

    
3244
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3245
}
3246

    
3247
/* Pulse-Width Tone module */
3248
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3249
{
3250
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3251
    int offset = addr & OMAP_MPUI_REG_MASK;
3252

    
3253
    switch (offset) {
3254
    case 0x00:        /* FRC */
3255
        return s->pwt.frc;
3256
    case 0x04:        /* VCR */
3257
        return s->pwt.vrc;
3258
    case 0x08:        /* GCR */
3259
        return s->pwt.gcr;
3260
    }
3261
    OMAP_BAD_REG(addr);
3262
    return 0;
3263
}
3264

    
3265
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3266
                uint32_t value)
3267
{
3268
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3269
    int offset = addr & OMAP_MPUI_REG_MASK;
3270

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

    
3308
static CPUReadMemoryFunc * const omap_pwt_readfn[] = {
3309
    omap_pwt_read,
3310
    omap_badwidth_read8,
3311
    omap_badwidth_read8,
3312
};
3313

    
3314
static CPUWriteMemoryFunc * const omap_pwt_writefn[] = {
3315
    omap_pwt_write,
3316
    omap_badwidth_write8,
3317
    omap_badwidth_write8,
3318
};
3319

    
3320
static void omap_pwt_reset(struct omap_mpu_state_s *s)
3321
{
3322
    s->pwt.frc = 0;
3323
    s->pwt.vrc = 0;
3324
    s->pwt.gcr = 0;
3325
}
3326

    
3327
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3328
                omap_clk clk)
3329
{
3330
    int iomemtype;
3331

    
3332
    s->pwt.clk = clk;
3333
    omap_pwt_reset(s);
3334

    
3335
    iomemtype = cpu_register_io_memory(omap_pwt_readfn,
3336
                    omap_pwt_writefn, s);
3337
    cpu_register_physical_memory(base, 0x800, iomemtype);
3338
}
3339

    
3340
/* Real-time Clock module */
3341
struct omap_rtc_s {
3342
    qemu_irq irq;
3343
    qemu_irq alarm;
3344
    QEMUTimer *clk;
3345

    
3346
    uint8_t interrupts;
3347
    uint8_t status;
3348
    int16_t comp_reg;
3349
    int running;
3350
    int pm_am;
3351
    int auto_comp;
3352
    int round;
3353
    struct tm alarm_tm;
3354
    time_t alarm_ti;
3355

    
3356
    struct tm current_tm;
3357
    time_t ti;
3358
    uint64_t tick;
3359
};
3360

    
3361
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3362
{
3363
    /* s->alarm is level-triggered */
3364
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3365
}
3366

    
3367
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3368
{
3369
    s->alarm_ti = mktimegm(&s->alarm_tm);
3370
    if (s->alarm_ti == -1)
3371
        printf("%s: conversion failed\n", __FUNCTION__);
3372
}
3373

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3662
        s->round = 0;
3663
    }
3664

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

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

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

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

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

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

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

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

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

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

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

    
3746
    omap_rtc_reset(s);
3747

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

    
3752
    return s;
3753
}
3754

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

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

    
3775
    I2SCodec *codec;
3776
    QEMUTimer *source_timer;
3777
    QEMUTimer *sink_timer;
3778
};
3779

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

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

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

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

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

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

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

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

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

    
3836
    omap_mcbsp_rx_newdata(s);
3837
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) +
3838
                   get_ticks_per_sec());
3839
}
3840

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

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

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

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

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

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

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

    
3882
    omap_mcbsp_tx_newdata(s);
3883
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) +
3884
                   get_ticks_per_sec());
3885
}
3886

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

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

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

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

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

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

    
3948
    if (s->codec)
3949
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3950

    
3951
    if (!prev_tx_rate && tx_rate)
3952
        omap_mcbsp_tx_start(s);
3953
    else if (s->tx_rate && !tx_rate)
3954
        omap_mcbsp_tx_stop(s);
3955

    
3956
    if (!prev_rx_rate && rx_rate)
3957
        omap_mcbsp_rx_start(s);
3958
    else if (prev_tx_rate && !tx_rate)
3959
        omap_mcbsp_rx_stop(s);
3960
}
3961

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

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

    
3991
    case 0x04:        /* DXR2 */
3992
    case 0x06:        /* DXR1 */
3993
        return 0x0000;
3994

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

    
4051
    OMAP_BAD_REG(addr);
4052
    return 0;
4053
}
4054

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

    
4061
    switch (offset) {
4062
    case 0x00:        /* DRR2 */
4063
    case 0x02:        /* DRR1 */
4064
        OMAP_RO_REG(addr);
4065
        return;
4066

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

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

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

    
4190
    OMAP_BAD_REG(addr);
4191
}
4192

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

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

    
4221
    omap_badwidth_write16(opaque, addr, value);
4222
}
4223

    
4224
static CPUReadMemoryFunc * const omap_mcbsp_readfn[] = {
4225
    omap_badwidth_read16,
4226
    omap_mcbsp_read,
4227
    omap_badwidth_read16,
4228
};
4229

    
4230
static CPUWriteMemoryFunc * const omap_mcbsp_writefn[] = {
4231
    omap_badwidth_write16,
4232
    omap_mcbsp_writeh,
4233
    omap_mcbsp_writew,
4234
};
4235

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

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

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

    
4270
    iomemtype = cpu_register_io_memory(omap_mcbsp_readfn,
4271
                    omap_mcbsp_writefn, s);
4272
    cpu_register_physical_memory(base, 0x800, iomemtype);
4273

    
4274
    return s;
4275
}
4276

    
4277
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4278
{
4279
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4280

    
4281
    if (s->rx_rate) {
4282
        s->rx_req = s->codec->in.len;
4283
        omap_mcbsp_rx_newdata(s);
4284
    }
4285
}
4286

    
4287
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
4288
{
4289
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4290

    
4291
    if (s->tx_rate) {
4292
        s->tx_req = s->codec->out.size;
4293
        omap_mcbsp_tx_newdata(s);
4294
    }
4295
}
4296

    
4297
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
4298
{
4299
    s->codec = slave;
4300
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4301
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4302
}
4303

    
4304
/* LED Pulse Generators */
4305
struct omap_lpg_s {
4306
    QEMUTimer *tm;
4307

    
4308
    uint8_t control;
4309
    uint8_t power;
4310
    int64_t on;
4311
    int64_t period;
4312
    int clk;
4313
    int cycle;
4314
};
4315

    
4316
static void omap_lpg_tick(void *opaque)
4317
{
4318
    struct omap_lpg_s *s = opaque;
4319

    
4320
    if (s->cycle)
4321
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
4322
    else
4323
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
4324

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

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

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

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

    
4358
    s->on = on;
4359
    s->period = period;
4360
}
4361

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

    
4370
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
4371
{
4372
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4373
    int offset = addr & OMAP_MPUI_REG_MASK;
4374

    
4375
    switch (offset) {
4376
    case 0x00:        /* LCR */
4377
        return s->control;
4378

    
4379
    case 0x04:        /* PMR */
4380
        return s->power;
4381
    }
4382

    
4383
    OMAP_BAD_REG(addr);
4384
    return 0;
4385
}
4386

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

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

    
4401
    case 0x04:        /* PMR */
4402
        s->power = value & 0x01;
4403
        omap_lpg_update(s);
4404
        return;
4405

    
4406
    default:
4407
        OMAP_BAD_REG(addr);
4408
        return;
4409
    }
4410
}
4411

    
4412
static CPUReadMemoryFunc * const omap_lpg_readfn[] = {
4413
    omap_lpg_read,
4414
    omap_badwidth_read8,
4415
    omap_badwidth_read8,
4416
};
4417

    
4418
static CPUWriteMemoryFunc * const omap_lpg_writefn[] = {
4419
    omap_lpg_write,
4420
    omap_badwidth_write8,
4421
    omap_badwidth_write8,
4422
};
4423

    
4424
static void omap_lpg_clk_update(void *opaque, int line, int on)
4425
{
4426
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4427

    
4428
    s->clk = on;
4429
    omap_lpg_update(s);
4430
}
4431

    
4432
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4433
{
4434
    int iomemtype;
4435
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4436
            qemu_mallocz(sizeof(struct omap_lpg_s));
4437

    
4438
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4439

    
4440
    omap_lpg_reset(s);
4441

    
4442
    iomemtype = cpu_register_io_memory(omap_lpg_readfn,
4443
                    omap_lpg_writefn, s);
4444
    cpu_register_physical_memory(base, 0x800, iomemtype);
4445

    
4446
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4447

    
4448
    return s;
4449
}
4450

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

    
4457
    OMAP_BAD_REG(addr);
4458
    return 0;
4459
}
4460

    
4461
static CPUReadMemoryFunc * const omap_mpui_io_readfn[] = {
4462
    omap_badwidth_read16,
4463
    omap_mpui_io_read,
4464
    omap_badwidth_read16,
4465
};
4466

    
4467
static CPUWriteMemoryFunc * const omap_mpui_io_writefn[] = {
4468
    omap_badwidth_write16,
4469
    omap_badwidth_write16,
4470
    omap_badwidth_write16,
4471
};
4472

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

    
4480
/* General chip reset */
4481
static void omap1_mpu_reset(void *opaque)
4482
{
4483
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4484

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

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

    
4549
    { 0 }
4550
};
4551

    
4552
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4553
{
4554
    int io;
4555

    
4556
    for (; map->phys_dsp; map ++) {
4557
        io = cpu_get_physical_page_desc(map->phys_mpu);
4558

    
4559
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4560
    }
4561
}
4562

    
4563
void omap_mpu_wakeup(void *opaque, int irq, int req)
4564
{
4565
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4566

    
4567
    if (mpu->env->halted)
4568
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4569
}
4570

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

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

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

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

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

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

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

    
4627
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4628
                const char *core)
4629
{
4630
    int i;
4631
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4632
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4633
    ram_addr_t imif_base, emiff_base;
4634
    qemu_irq *cpu_irq;
4635
    qemu_irq dma_irqs[6];
4636
    DriveInfo *dinfo;
4637

    
4638
    if (!core)
4639
        core = "ti925t";
4640

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

    
4651
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4652

    
4653
    /* Clocks */
4654
    omap_clk_init(s);
4655

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

    
4662
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4663

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

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

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

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

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

    
4701
    s->wdt = omap_wd_timer_init(0xfffec800,
4702
                    s->irq[0][OMAP_INT_WD_TIMER],
4703
                    omap_findclk(s, "armwdt_ck"));
4704

    
4705
    s->os_timer = omap_os_timer_init(0xfffb9000,
4706
                    s->irq[1][OMAP_INT_OS_TIMER],
4707
                    omap_findclk(s, "clk32-kHz"));
4708

    
4709
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4710
                    omap_dma_get_lcdch(s->dma), imif_base, emiff_base,
4711
                    omap_findclk(s, "lcd_ck"));
4712

    
4713
    omap_ulpd_pm_init(0xfffe0800, s);
4714
    omap_pin_cfg_init(0xfffe1000, s);
4715
    omap_id_init(s);
4716

    
4717
    omap_mpui_init(0xfffec900, s);
4718

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

    
4726
    omap_tcmi_init(0xfffecc00, s);
4727

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

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

    
4748
    dinfo = drive_get(IF_SD, 0, 0);
4749
    if (!dinfo) {
4750
        fprintf(stderr, "qemu: missing SecureDigital device\n");
4751
        exit(1);
4752
    }
4753
    s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv,
4754
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
4755
                    omap_findclk(s, "mmc_ck"));
4756

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

    
4761
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4762
                    omap_findclk(s, "arm_gpio_ck"));
4763

    
4764
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4765
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4766

    
4767
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4768
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4769

    
4770
    s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4771
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4772

    
4773
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4774
                    omap_findclk(s, "clk32-kHz"));
4775

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

    
4783
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
4784
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
4785

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

    
4801
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
4802
    omap_setup_mpui_io(s);
4803

    
4804
    qemu_register_reset(omap1_mpu_reset, s);
4805

    
4806
    return s;
4807
}