Statistics
| Branch: | Revision:

root / hw / omap1.c @ 731ba0ce

History | View | Annotate | Download (132.4 kB)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
152
#define INT_FALLING_EDGE        0
153
#define INT_LOW_LEVEL                1
154

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
428
    omap_inth_reset(s);
429

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

    
434
    return s;
435
}
436

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
649
    omap_inth_reset(s);
650

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

    
655
    return s;
656
}
657

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
844
    return s;
845
}
846

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
970
    return s;
971
}
972

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1073
    return s;
1074
}
1075

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1678
    omap_mpui_reset(mpu);
1679
}
1680

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1790
    return s;
1791
}
1792

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1980
/* UARTs */
1981
struct omap_uart_s {
1982
    SerialState *serial; /* TODO */
1983
    struct omap_target_agent_s *ta;
1984
    target_phys_addr_t base;
1985

    
1986
    uint8_t eblr;
1987
    uint8_t syscontrol;
1988
    uint8_t wkup;
1989
    uint8_t cfps;
1990
    uint8_t mdr[2];
1991
    uint8_t scr;
1992
};
1993

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

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

    
2009
    s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
2010
                               chr ?: qemu_chr_open("null"), 1);
2011

    
2012
    return s;
2013
}
2014

    
2015
static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr)
2016
{
2017
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
2018
    int offset = addr - s->base;
2019

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

    
2043
    OMAP_BAD_REG(addr);
2044
    return 0;
2045
}
2046

    
2047
static void omap_uart_write(void *opaque, target_phys_addr_t addr,
2048
                uint32_t value)
2049
{
2050
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;
2051
    int offset = addr - s->base;
2052

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

    
2087
static CPUReadMemoryFunc *omap_uart_readfn[] = {
2088
    omap_uart_read,
2089
    omap_uart_read,
2090
    omap_badwidth_read8,
2091
};
2092

    
2093
static CPUWriteMemoryFunc *omap_uart_writefn[] = {
2094
    omap_uart_write,
2095
    omap_uart_write,
2096
    omap_badwidth_write8,
2097
};
2098

    
2099
struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta,
2100
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
2101
                qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr)
2102
{
2103
    target_phys_addr_t base = omap_l4_attach(ta, 0, 0);
2104
    struct omap_uart_s *s = omap_uart_init(base, irq,
2105
                    fclk, iclk, txdma, rxdma, chr);
2106
    int iomemtype = cpu_register_io_memory(0, omap_uart_readfn,
2107
                    omap_uart_writefn, s);
2108

    
2109
    s->ta = ta;
2110
    s->base = base;
2111

    
2112
    cpu_register_physical_memory(s->base + 0x20, 0x100, iomemtype);
2113

    
2114
    return s;
2115
}
2116

    
2117
/* MPU Clock/Reset/Power Mode Control */
2118
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
2119
{
2120
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2121
    int offset = addr - s->clkm.mpu_base;
2122

    
2123
    switch (offset) {
2124
    case 0x00:        /* ARM_CKCTL */
2125
        return s->clkm.arm_ckctl;
2126

    
2127
    case 0x04:        /* ARM_IDLECT1 */
2128
        return s->clkm.arm_idlect1;
2129

    
2130
    case 0x08:        /* ARM_IDLECT2 */
2131
        return s->clkm.arm_idlect2;
2132

    
2133
    case 0x0c:        /* ARM_EWUPCT */
2134
        return s->clkm.arm_ewupct;
2135

    
2136
    case 0x10:        /* ARM_RSTCT1 */
2137
        return s->clkm.arm_rstct1;
2138

    
2139
    case 0x14:        /* ARM_RSTCT2 */
2140
        return s->clkm.arm_rstct2;
2141

    
2142
    case 0x18:        /* ARM_SYSST */
2143
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
2144

    
2145
    case 0x1c:        /* ARM_CKOUT1 */
2146
        return s->clkm.arm_ckout1;
2147

    
2148
    case 0x20:        /* ARM_CKOUT2 */
2149
        break;
2150
    }
2151

    
2152
    OMAP_BAD_REG(addr);
2153
    return 0;
2154
}
2155

    
2156
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
2157
                uint16_t diff, uint16_t value)
2158
{
2159
    omap_clk clk;
2160

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

    
2203
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
2204
                uint16_t diff, uint16_t value)
2205
{
2206
    omap_clk clk;
2207

    
2208
    if (value & (1 << 11))                                /* SETARM_IDLE */
2209
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
2210
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
2211
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
2212

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

    
2234
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
2235
                uint16_t diff, uint16_t value)
2236
{
2237
    omap_clk clk;
2238

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

    
2257
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
2258
                uint16_t diff, uint16_t value)
2259
{
2260
    omap_clk clk;
2261

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

    
2315
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
2316
                uint32_t value)
2317
{
2318
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2319
    int offset = addr - s->clkm.mpu_base;
2320
    uint16_t diff;
2321
    omap_clk clk;
2322
    static const char *clkschemename[8] = {
2323
        "fully synchronous", "fully asynchronous", "synchronous scalable",
2324
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
2325
    };
2326

    
2327
    switch (offset) {
2328
    case 0x00:        /* ARM_CKCTL */
2329
        diff = s->clkm.arm_ckctl ^ value;
2330
        s->clkm.arm_ckctl = value & 0x7fff;
2331
        omap_clkm_ckctl_update(s, diff, value);
2332
        return;
2333

    
2334
    case 0x04:        /* ARM_IDLECT1 */
2335
        diff = s->clkm.arm_idlect1 ^ value;
2336
        s->clkm.arm_idlect1 = value & 0x0fff;
2337
        omap_clkm_idlect1_update(s, diff, value);
2338
        return;
2339

    
2340
    case 0x08:        /* ARM_IDLECT2 */
2341
        diff = s->clkm.arm_idlect2 ^ value;
2342
        s->clkm.arm_idlect2 = value & 0x07ff;
2343
        omap_clkm_idlect2_update(s, diff, value);
2344
        return;
2345

    
2346
    case 0x0c:        /* ARM_EWUPCT */
2347
        diff = s->clkm.arm_ewupct ^ value;
2348
        s->clkm.arm_ewupct = value & 0x003f;
2349
        return;
2350

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

    
2369
    case 0x14:        /* ARM_RSTCT2 */
2370
        s->clkm.arm_rstct2 = value & 0x0001;
2371
        return;
2372

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

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

    
2388
    case 0x20:        /* ARM_CKOUT2 */
2389
    default:
2390
        OMAP_BAD_REG(addr);
2391
    }
2392
}
2393

    
2394
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2395
    omap_badwidth_read16,
2396
    omap_clkm_read,
2397
    omap_badwidth_read16,
2398
};
2399

    
2400
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2401
    omap_badwidth_write16,
2402
    omap_clkm_write,
2403
    omap_badwidth_write16,
2404
};
2405

    
2406
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2407
{
2408
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2409
    int offset = addr - s->clkm.dsp_base;
2410

    
2411
    switch (offset) {
2412
    case 0x04:        /* DSP_IDLECT1 */
2413
        return s->clkm.dsp_idlect1;
2414

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

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

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

    
2426
    OMAP_BAD_REG(addr);
2427
    return 0;
2428
}
2429

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

    
2435
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2436
}
2437

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

    
2443
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2444
}
2445

    
2446
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2447
                uint32_t value)
2448
{
2449
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2450
    int offset = addr - s->clkm.dsp_base;
2451
    uint16_t diff;
2452

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

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

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

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

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

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

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

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

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

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

    
2530
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2531
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2532
}
2533

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

    
2543
    uint16_t inputs;
2544
    uint16_t outputs;
2545
    uint16_t dir;
2546
    uint16_t edge;
2547
    uint16_t mask;
2548
    uint16_t ints;
2549

    
2550
    uint16_t debounce;
2551
    uint16_t latch;
2552
    uint8_t event;
2553

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

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

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

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

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

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

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

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

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

    
2606
    case 0x04:        /* OUTPUT_REG */
2607
        return s->outputs;
2608

    
2609
    case 0x08:        /* IO_CNTL */
2610
        return s->dir;
2611

    
2612
    case 0x10:        /* KBR_LATCH */
2613
        return s->row_latch;
2614

    
2615
    case 0x14:        /* KBC_REG */
2616
        return s->cols;
2617

    
2618
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2619
        return s->event;
2620

    
2621
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2622
        return s->edge;
2623

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

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

    
2634
    case 0x28:        /* KBD_MASKIT */
2635
        return s->kbd_mask;
2636

    
2637
    case 0x2c:        /* GPIO_MASKIT */
2638
        return s->mask;
2639

    
2640
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2641
        return s->debounce;
2642

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

    
2647
    OMAP_BAD_REG(addr);
2648
    return 0;
2649
}
2650

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

    
2659
    switch (offset) {
2660
    case 0x04:        /* OUTPUT_REG */
2661
        diff = (s->outputs ^ value) & ~s->dir;
2662
        s->outputs = value;
2663
        while ((ln = ffs(diff))) {
2664
            ln --;
2665
            if (s->handler[ln])
2666
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2667
            diff &= ~(1 << ln);
2668
        }
2669
        break;
2670

    
2671
    case 0x08:        /* IO_CNTL */
2672
        diff = s->outputs & (s->dir ^ value);
2673
        s->dir = value;
2674

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

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

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

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

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

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

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

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

    
2718
    default:
2719
        OMAP_BAD_REG(addr);
2720
        return;
2721
    }
2722
}
2723

    
2724
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
2725
    omap_badwidth_read16,
2726
    omap_mpuio_read,
2727
    omap_badwidth_read16,
2728
};
2729

    
2730
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
2731
    omap_badwidth_write16,
2732
    omap_mpuio_write,
2733
    omap_badwidth_write16,
2734
};
2735

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

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

    
2756
    s->clk = on;
2757
    if (on)
2758
        omap_mpuio_kbd_update(s);
2759
}
2760

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

    
2769
    s->base = base;
2770
    s->irq = gpio_int;
2771
    s->kbd_irq = kbd_int;
2772
    s->wakeup = wakeup;
2773
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2774
    omap_mpuio_reset(s);
2775

    
2776
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
2777
                    omap_mpuio_writefn, s);
2778
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
2779

    
2780
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2781

    
2782
    return s;
2783
}
2784

    
2785
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2786
{
2787
    return s->in;
2788
}
2789

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

    
2797
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2798
{
2799
    if (row >= 5 || row < 0)
2800
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
2801
                        __FUNCTION__, col, row);
2802

    
2803
    if (down)
2804
        s->buttons[row] |= 1 << col;
2805
    else
2806
        s->buttons[row] &= ~(1 << col);
2807

    
2808
    omap_mpuio_kbd_update(s);
2809
}
2810

    
2811
/* General-Purpose I/O */
2812
struct omap_gpio_s {
2813
    target_phys_addr_t base;
2814
    qemu_irq irq;
2815
    qemu_irq *in;
2816
    qemu_irq handler[16];
2817

    
2818
    uint16_t inputs;
2819
    uint16_t outputs;
2820
    uint16_t dir;
2821
    uint16_t edge;
2822
    uint16_t mask;
2823
    uint16_t ints;
2824
    uint16_t pins;
2825
};
2826

    
2827
static void omap_gpio_set(void *opaque, int line, int level)
2828
{
2829
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2830
    uint16_t prev = s->inputs;
2831

    
2832
    if (level)
2833
        s->inputs |= 1 << line;
2834
    else
2835
        s->inputs &= ~(1 << line);
2836

    
2837
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
2838
                    (1 << line) & s->dir & ~s->mask) {
2839
        s->ints |= 1 << line;
2840
        qemu_irq_raise(s->irq);
2841
    }
2842
}
2843

    
2844
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
2845
{
2846
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2847
    int offset = addr & OMAP_MPUI_REG_MASK;
2848

    
2849
    switch (offset) {
2850
    case 0x00:        /* DATA_INPUT */
2851
        return s->inputs & s->pins;
2852

    
2853
    case 0x04:        /* DATA_OUTPUT */
2854
        return s->outputs;
2855

    
2856
    case 0x08:        /* DIRECTION_CONTROL */
2857
        return s->dir;
2858

    
2859
    case 0x0c:        /* INTERRUPT_CONTROL */
2860
        return s->edge;
2861

    
2862
    case 0x10:        /* INTERRUPT_MASK */
2863
        return s->mask;
2864

    
2865
    case 0x14:        /* INTERRUPT_STATUS */
2866
        return s->ints;
2867

    
2868
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
2869
        OMAP_BAD_REG(addr);
2870
        return s->pins;
2871
    }
2872

    
2873
    OMAP_BAD_REG(addr);
2874
    return 0;
2875
}
2876

    
2877
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
2878
                uint32_t value)
2879
{
2880
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2881
    int offset = addr & OMAP_MPUI_REG_MASK;
2882
    uint16_t diff;
2883
    int ln;
2884

    
2885
    switch (offset) {
2886
    case 0x00:        /* DATA_INPUT */
2887
        OMAP_RO_REG(addr);
2888
        return;
2889

    
2890
    case 0x04:        /* DATA_OUTPUT */
2891
        diff = (s->outputs ^ value) & ~s->dir;
2892
        s->outputs = value;
2893
        while ((ln = ffs(diff))) {
2894
            ln --;
2895
            if (s->handler[ln])
2896
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2897
            diff &= ~(1 << ln);
2898
        }
2899
        break;
2900

    
2901
    case 0x08:        /* DIRECTION_CONTROL */
2902
        diff = s->outputs & (s->dir ^ value);
2903
        s->dir = value;
2904

    
2905
        value = s->outputs & ~s->dir;
2906
        while ((ln = ffs(diff))) {
2907
            ln --;
2908
            if (s->handler[ln])
2909
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2910
            diff &= ~(1 << ln);
2911
        }
2912
        break;
2913

    
2914
    case 0x0c:        /* INTERRUPT_CONTROL */
2915
        s->edge = value;
2916
        break;
2917

    
2918
    case 0x10:        /* INTERRUPT_MASK */
2919
        s->mask = value;
2920
        break;
2921

    
2922
    case 0x14:        /* INTERRUPT_STATUS */
2923
        s->ints &= ~value;
2924
        if (!s->ints)
2925
            qemu_irq_lower(s->irq);
2926
        break;
2927

    
2928
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
2929
        OMAP_BAD_REG(addr);
2930
        s->pins = value;
2931
        break;
2932

    
2933
    default:
2934
        OMAP_BAD_REG(addr);
2935
        return;
2936
    }
2937
}
2938

    
2939
/* *Some* sources say the memory region is 32-bit.  */
2940
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
2941
    omap_badwidth_read16,
2942
    omap_gpio_read,
2943
    omap_badwidth_read16,
2944
};
2945

    
2946
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
2947
    omap_badwidth_write16,
2948
    omap_gpio_write,
2949
    omap_badwidth_write16,
2950
};
2951

    
2952
static void omap_gpio_reset(struct omap_gpio_s *s)
2953
{
2954
    s->inputs = 0;
2955
    s->outputs = ~0;
2956
    s->dir = ~0;
2957
    s->edge = ~0;
2958
    s->mask = ~0;
2959
    s->ints = 0;
2960
    s->pins = ~0;
2961
}
2962

    
2963
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
2964
                qemu_irq irq, omap_clk clk)
2965
{
2966
    int iomemtype;
2967
    struct omap_gpio_s *s = (struct omap_gpio_s *)
2968
            qemu_mallocz(sizeof(struct omap_gpio_s));
2969

    
2970
    s->base = base;
2971
    s->irq = irq;
2972
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
2973
    omap_gpio_reset(s);
2974

    
2975
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
2976
                    omap_gpio_writefn, s);
2977
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
2978

    
2979
    return s;
2980
}
2981

    
2982
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
2983
{
2984
    return s->in;
2985
}
2986

    
2987
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
2988
{
2989
    if (line >= 16 || line < 0)
2990
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
2991
    s->handler[line] = handler;
2992
}
2993

    
2994
/* MicroWire Interface */
2995
struct omap_uwire_s {
2996
    target_phys_addr_t base;
2997
    qemu_irq txirq;
2998
    qemu_irq rxirq;
2999
    qemu_irq txdrq;
3000

    
3001
    uint16_t txbuf;
3002
    uint16_t rxbuf;
3003
    uint16_t control;
3004
    uint16_t setup[5];
3005

    
3006
    struct uwire_slave_s *chip[4];
3007
};
3008

    
3009
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
3010
{
3011
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
3012
    struct uwire_slave_s *slave = s->chip[chipselect];
3013

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

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

    
3034
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
3035
{
3036
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3037
    int offset = addr & OMAP_MPUI_REG_MASK;
3038

    
3039
    switch (offset) {
3040
    case 0x00:        /* RDR */
3041
        s->control &= ~(1 << 15);                        /* RDRB */
3042
        return s->rxbuf;
3043

    
3044
    case 0x04:        /* CSR */
3045
        return s->control;
3046

    
3047
    case 0x08:        /* SR1 */
3048
        return s->setup[0];
3049
    case 0x0c:        /* SR2 */
3050
        return s->setup[1];
3051
    case 0x10:        /* SR3 */
3052
        return s->setup[2];
3053
    case 0x14:        /* SR4 */
3054
        return s->setup[3];
3055
    case 0x18:        /* SR5 */
3056
        return s->setup[4];
3057
    }
3058

    
3059
    OMAP_BAD_REG(addr);
3060
    return 0;
3061
}
3062

    
3063
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
3064
                uint32_t value)
3065
{
3066
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
3067
    int offset = addr & OMAP_MPUI_REG_MASK;
3068

    
3069
    switch (offset) {
3070
    case 0x00:        /* TDR */
3071
        s->txbuf = value;                                /* TD */
3072
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
3073
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
3074
                         (s->control & (1 << 12)))) {        /* CS_CMD */
3075
            s->control |= 1 << 14;                        /* CSRB */
3076
            omap_uwire_transfer_start(s);
3077
        }
3078
        break;
3079

    
3080
    case 0x04:        /* CSR */
3081
        s->control = value & 0x1fff;
3082
        if (value & (1 << 13))                                /* START */
3083
            omap_uwire_transfer_start(s);
3084
        break;
3085

    
3086
    case 0x08:        /* SR1 */
3087
        s->setup[0] = value & 0x003f;
3088
        break;
3089

    
3090
    case 0x0c:        /* SR2 */
3091
        s->setup[1] = value & 0x0fc0;
3092
        break;
3093

    
3094
    case 0x10:        /* SR3 */
3095
        s->setup[2] = value & 0x0003;
3096
        break;
3097

    
3098
    case 0x14:        /* SR4 */
3099
        s->setup[3] = value & 0x0001;
3100
        break;
3101

    
3102
    case 0x18:        /* SR5 */
3103
        s->setup[4] = value & 0x000f;
3104
        break;
3105

    
3106
    default:
3107
        OMAP_BAD_REG(addr);
3108
        return;
3109
    }
3110
}
3111

    
3112
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
3113
    omap_badwidth_read16,
3114
    omap_uwire_read,
3115
    omap_badwidth_read16,
3116
};
3117

    
3118
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
3119
    omap_badwidth_write16,
3120
    omap_uwire_write,
3121
    omap_badwidth_write16,
3122
};
3123

    
3124
static void omap_uwire_reset(struct omap_uwire_s *s)
3125
{
3126
    s->control = 0;
3127
    s->setup[0] = 0;
3128
    s->setup[1] = 0;
3129
    s->setup[2] = 0;
3130
    s->setup[3] = 0;
3131
    s->setup[4] = 0;
3132
}
3133

    
3134
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
3135
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
3136
{
3137
    int iomemtype;
3138
    struct omap_uwire_s *s = (struct omap_uwire_s *)
3139
            qemu_mallocz(sizeof(struct omap_uwire_s));
3140

    
3141
    s->base = base;
3142
    s->txirq = irq[0];
3143
    s->rxirq = irq[1];
3144
    s->txdrq = dma;
3145
    omap_uwire_reset(s);
3146

    
3147
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
3148
                    omap_uwire_writefn, s);
3149
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3150

    
3151
    return s;
3152
}
3153

    
3154
void omap_uwire_attach(struct omap_uwire_s *s,
3155
                struct uwire_slave_s *slave, int chipselect)
3156
{
3157
    if (chipselect < 0 || chipselect > 3) {
3158
        fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
3159
        exit(-1);
3160
    }
3161

    
3162
    s->chip[chipselect] = slave;
3163
}
3164

    
3165
/* Pseudonoise Pulse-Width Light Modulator */
3166
static void omap_pwl_update(struct omap_mpu_state_s *s)
3167
{
3168
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
3169

    
3170
    if (output != s->pwl.output) {
3171
        s->pwl.output = output;
3172
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
3173
    }
3174
}
3175

    
3176
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
3177
{
3178
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3179
    int offset = addr & OMAP_MPUI_REG_MASK;
3180

    
3181
    switch (offset) {
3182
    case 0x00:        /* PWL_LEVEL */
3183
        return s->pwl.level;
3184
    case 0x04:        /* PWL_CTRL */
3185
        return s->pwl.enable;
3186
    }
3187
    OMAP_BAD_REG(addr);
3188
    return 0;
3189
}
3190

    
3191
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
3192
                uint32_t value)
3193
{
3194
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3195
    int offset = addr & OMAP_MPUI_REG_MASK;
3196

    
3197
    switch (offset) {
3198
    case 0x00:        /* PWL_LEVEL */
3199
        s->pwl.level = value;
3200
        omap_pwl_update(s);
3201
        break;
3202
    case 0x04:        /* PWL_CTRL */
3203
        s->pwl.enable = value & 1;
3204
        omap_pwl_update(s);
3205
        break;
3206
    default:
3207
        OMAP_BAD_REG(addr);
3208
        return;
3209
    }
3210
}
3211

    
3212
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
3213
    omap_pwl_read,
3214
    omap_badwidth_read8,
3215
    omap_badwidth_read8,
3216
};
3217

    
3218
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
3219
    omap_pwl_write,
3220
    omap_badwidth_write8,
3221
    omap_badwidth_write8,
3222
};
3223

    
3224
static void omap_pwl_reset(struct omap_mpu_state_s *s)
3225
{
3226
    s->pwl.output = 0;
3227
    s->pwl.level = 0;
3228
    s->pwl.enable = 0;
3229
    s->pwl.clk = 1;
3230
    omap_pwl_update(s);
3231
}
3232

    
3233
static void omap_pwl_clk_update(void *opaque, int line, int on)
3234
{
3235
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3236

    
3237
    s->pwl.clk = on;
3238
    omap_pwl_update(s);
3239
}
3240

    
3241
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3242
                omap_clk clk)
3243
{
3244
    int iomemtype;
3245

    
3246
    omap_pwl_reset(s);
3247

    
3248
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
3249
                    omap_pwl_writefn, s);
3250
    cpu_register_physical_memory(base, 0x800, iomemtype);
3251

    
3252
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
3253
}
3254

    
3255
/* Pulse-Width Tone module */
3256
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
3257
{
3258
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3259
    int offset = addr & OMAP_MPUI_REG_MASK;
3260

    
3261
    switch (offset) {
3262
    case 0x00:        /* FRC */
3263
        return s->pwt.frc;
3264
    case 0x04:        /* VCR */
3265
        return s->pwt.vrc;
3266
    case 0x08:        /* GCR */
3267
        return s->pwt.gcr;
3268
    }
3269
    OMAP_BAD_REG(addr);
3270
    return 0;
3271
}
3272

    
3273
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
3274
                uint32_t value)
3275
{
3276
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
3277
    int offset = addr & OMAP_MPUI_REG_MASK;
3278

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

    
3316
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
3317
    omap_pwt_read,
3318
    omap_badwidth_read8,
3319
    omap_badwidth_read8,
3320
};
3321

    
3322
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
3323
    omap_pwt_write,
3324
    omap_badwidth_write8,
3325
    omap_badwidth_write8,
3326
};
3327

    
3328
static void omap_pwt_reset(struct omap_mpu_state_s *s)
3329
{
3330
    s->pwt.frc = 0;
3331
    s->pwt.vrc = 0;
3332
    s->pwt.gcr = 0;
3333
}
3334

    
3335
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
3336
                omap_clk clk)
3337
{
3338
    int iomemtype;
3339

    
3340
    s->pwt.clk = clk;
3341
    omap_pwt_reset(s);
3342

    
3343
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
3344
                    omap_pwt_writefn, s);
3345
    cpu_register_physical_memory(base, 0x800, iomemtype);
3346
}
3347

    
3348
/* Real-time Clock module */
3349
struct omap_rtc_s {
3350
    target_phys_addr_t base;
3351
    qemu_irq irq;
3352
    qemu_irq alarm;
3353
    QEMUTimer *clk;
3354

    
3355
    uint8_t interrupts;
3356
    uint8_t status;
3357
    int16_t comp_reg;
3358
    int running;
3359
    int pm_am;
3360
    int auto_comp;
3361
    int round;
3362
    struct tm alarm_tm;
3363
    time_t alarm_ti;
3364

    
3365
    struct tm current_tm;
3366
    time_t ti;
3367
    uint64_t tick;
3368
};
3369

    
3370
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3371
{
3372
    /* s->alarm is level-triggered */
3373
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3374
}
3375

    
3376
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3377
{
3378
    s->alarm_ti = mktime(&s->alarm_tm);
3379
    if (s->alarm_ti == -1)
3380
        printf("%s: conversion failed\n", __FUNCTION__);
3381
}
3382

    
3383
static inline uint8_t omap_rtc_bcd(int num)
3384
{
3385
    return ((num / 10) << 4) | (num % 10);
3386
}
3387

    
3388
static inline int omap_rtc_bin(uint8_t num)
3389
{
3390
    return (num & 15) + 10 * (num >> 4);
3391
}
3392

    
3393
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3394
{
3395
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3396
    int offset = addr & OMAP_MPUI_REG_MASK;
3397
    uint8_t i;
3398

    
3399
    switch (offset) {
3400
    case 0x00:        /* SECONDS_REG */
3401
        return omap_rtc_bcd(s->current_tm.tm_sec);
3402

    
3403
    case 0x04:        /* MINUTES_REG */
3404
        return omap_rtc_bcd(s->current_tm.tm_min);
3405

    
3406
    case 0x08:        /* HOURS_REG */
3407
        if (s->pm_am)
3408
            return ((s->current_tm.tm_hour > 11) << 7) |
3409
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3410
        else
3411
            return omap_rtc_bcd(s->current_tm.tm_hour);
3412

    
3413
    case 0x0c:        /* DAYS_REG */
3414
        return omap_rtc_bcd(s->current_tm.tm_mday);
3415

    
3416
    case 0x10:        /* MONTHS_REG */
3417
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3418

    
3419
    case 0x14:        /* YEARS_REG */
3420
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3421

    
3422
    case 0x18:        /* WEEK_REG */
3423
        return s->current_tm.tm_wday;
3424

    
3425
    case 0x20:        /* ALARM_SECONDS_REG */
3426
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3427

    
3428
    case 0x24:        /* ALARM_MINUTES_REG */
3429
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3430

    
3431
    case 0x28:        /* ALARM_HOURS_REG */
3432
        if (s->pm_am)
3433
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3434
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3435
        else
3436
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
3437

    
3438
    case 0x2c:        /* ALARM_DAYS_REG */
3439
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3440

    
3441
    case 0x30:        /* ALARM_MONTHS_REG */
3442
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3443

    
3444
    case 0x34:        /* ALARM_YEARS_REG */
3445
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3446

    
3447
    case 0x40:        /* RTC_CTRL_REG */
3448
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3449
                (s->round << 1) | s->running;
3450

    
3451
    case 0x44:        /* RTC_STATUS_REG */
3452
        i = s->status;
3453
        s->status &= ~0x3d;
3454
        return i;
3455

    
3456
    case 0x48:        /* RTC_INTERRUPTS_REG */
3457
        return s->interrupts;
3458

    
3459
    case 0x4c:        /* RTC_COMP_LSB_REG */
3460
        return ((uint16_t) s->comp_reg) & 0xff;
3461

    
3462
    case 0x50:        /* RTC_COMP_MSB_REG */
3463
        return ((uint16_t) s->comp_reg) >> 8;
3464
    }
3465

    
3466
    OMAP_BAD_REG(addr);
3467
    return 0;
3468
}
3469

    
3470
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3471
                uint32_t value)
3472
{
3473
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3474
    int offset = addr & OMAP_MPUI_REG_MASK;
3475
    struct tm new_tm;
3476
    time_t ti[2];
3477

    
3478
    switch (offset) {
3479
    case 0x00:        /* SECONDS_REG */
3480
#if ALMDEBUG
3481
        printf("RTC SEC_REG <-- %02x\n", value);
3482
#endif
3483
        s->ti -= s->current_tm.tm_sec;
3484
        s->ti += omap_rtc_bin(value);
3485
        return;
3486

    
3487
    case 0x04:        /* MINUTES_REG */
3488
#if ALMDEBUG
3489
        printf("RTC MIN_REG <-- %02x\n", value);
3490
#endif
3491
        s->ti -= s->current_tm.tm_min * 60;
3492
        s->ti += omap_rtc_bin(value) * 60;
3493
        return;
3494

    
3495
    case 0x08:        /* HOURS_REG */
3496
#if ALMDEBUG
3497
        printf("RTC HRS_REG <-- %02x\n", value);
3498
#endif
3499
        s->ti -= s->current_tm.tm_hour * 3600;
3500
        if (s->pm_am) {
3501
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3502
            s->ti += ((value >> 7) & 1) * 43200;
3503
        } else
3504
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3505
        return;
3506

    
3507
    case 0x0c:        /* DAYS_REG */
3508
#if ALMDEBUG
3509
        printf("RTC DAY_REG <-- %02x\n", value);
3510
#endif
3511
        s->ti -= s->current_tm.tm_mday * 86400;
3512
        s->ti += omap_rtc_bin(value) * 86400;
3513
        return;
3514

    
3515
    case 0x10:        /* MONTHS_REG */
3516
#if ALMDEBUG
3517
        printf("RTC MTH_REG <-- %02x\n", value);
3518
#endif
3519
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3520
        new_tm.tm_mon = omap_rtc_bin(value);
3521
        ti[0] = mktime(&s->current_tm);
3522
        ti[1] = mktime(&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_mon * 2592000;
3530
            s->ti += omap_rtc_bin(value) * 2592000;
3531
        }
3532
        return;
3533

    
3534
    case 0x14:        /* YEARS_REG */
3535
#if ALMDEBUG
3536
        printf("RTC YRS_REG <-- %02x\n", value);
3537
#endif
3538
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3539
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3540
        ti[0] = mktime(&s->current_tm);
3541
        ti[1] = mktime(&new_tm);
3542

    
3543
        if (ti[0] != -1 && ti[1] != -1) {
3544
            s->ti -= ti[0];
3545
            s->ti += ti[1];
3546
        } else {
3547
            /* A less accurate version */
3548
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3549
            s->ti += omap_rtc_bin(value) * 31536000;
3550
        }
3551
        return;
3552

    
3553
    case 0x18:        /* WEEK_REG */
3554
        return;        /* Ignored */
3555

    
3556
    case 0x20:        /* ALARM_SECONDS_REG */
3557
#if ALMDEBUG
3558
        printf("ALM SEC_REG <-- %02x\n", value);
3559
#endif
3560
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3561
        omap_rtc_alarm_update(s);
3562
        return;
3563

    
3564
    case 0x24:        /* ALARM_MINUTES_REG */
3565
#if ALMDEBUG
3566
        printf("ALM MIN_REG <-- %02x\n", value);
3567
#endif
3568
        s->alarm_tm.tm_min = omap_rtc_bin(value);
3569
        omap_rtc_alarm_update(s);
3570
        return;
3571

    
3572
    case 0x28:        /* ALARM_HOURS_REG */
3573
#if ALMDEBUG
3574
        printf("ALM HRS_REG <-- %02x\n", value);
3575
#endif
3576
        if (s->pm_am)
3577
            s->alarm_tm.tm_hour =
3578
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
3579
                    ((value >> 7) & 1) * 12;
3580
        else
3581
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
3582
        omap_rtc_alarm_update(s);
3583
        return;
3584

    
3585
    case 0x2c:        /* ALARM_DAYS_REG */
3586
#if ALMDEBUG
3587
        printf("ALM DAY_REG <-- %02x\n", value);
3588
#endif
3589
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3590
        omap_rtc_alarm_update(s);
3591
        return;
3592

    
3593
    case 0x30:        /* ALARM_MONTHS_REG */
3594
#if ALMDEBUG
3595
        printf("ALM MON_REG <-- %02x\n", value);
3596
#endif
3597
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3598
        omap_rtc_alarm_update(s);
3599
        return;
3600

    
3601
    case 0x34:        /* ALARM_YEARS_REG */
3602
#if ALMDEBUG
3603
        printf("ALM YRS_REG <-- %02x\n", value);
3604
#endif
3605
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3606
        omap_rtc_alarm_update(s);
3607
        return;
3608

    
3609
    case 0x40:        /* RTC_CTRL_REG */
3610
#if ALMDEBUG
3611
        printf("RTC CONTROL <-- %02x\n", value);
3612
#endif
3613
        s->pm_am = (value >> 3) & 1;
3614
        s->auto_comp = (value >> 2) & 1;
3615
        s->round = (value >> 1) & 1;
3616
        s->running = value & 1;
3617
        s->status &= 0xfd;
3618
        s->status |= s->running << 1;
3619
        return;
3620

    
3621
    case 0x44:        /* RTC_STATUS_REG */
3622
#if ALMDEBUG
3623
        printf("RTC STATUSL <-- %02x\n", value);
3624
#endif
3625
        s->status &= ~((value & 0xc0) ^ 0x80);
3626
        omap_rtc_interrupts_update(s);
3627
        return;
3628

    
3629
    case 0x48:        /* RTC_INTERRUPTS_REG */
3630
#if ALMDEBUG
3631
        printf("RTC INTRS <-- %02x\n", value);
3632
#endif
3633
        s->interrupts = value;
3634
        return;
3635

    
3636
    case 0x4c:        /* RTC_COMP_LSB_REG */
3637
#if ALMDEBUG
3638
        printf("RTC COMPLSB <-- %02x\n", value);
3639
#endif
3640
        s->comp_reg &= 0xff00;
3641
        s->comp_reg |= 0x00ff & value;
3642
        return;
3643

    
3644
    case 0x50:        /* RTC_COMP_MSB_REG */
3645
#if ALMDEBUG
3646
        printf("RTC COMPMSB <-- %02x\n", value);
3647
#endif
3648
        s->comp_reg &= 0x00ff;
3649
        s->comp_reg |= 0xff00 & (value << 8);
3650
        return;
3651

    
3652
    default:
3653
        OMAP_BAD_REG(addr);
3654
        return;
3655
    }
3656
}
3657

    
3658
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3659
    omap_rtc_read,
3660
    omap_badwidth_read8,
3661
    omap_badwidth_read8,
3662
};
3663

    
3664
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3665
    omap_rtc_write,
3666
    omap_badwidth_write8,
3667
    omap_badwidth_write8,
3668
};
3669

    
3670
static void omap_rtc_tick(void *opaque)
3671
{
3672
    struct omap_rtc_s *s = opaque;
3673

    
3674
    if (s->round) {
3675
        /* Round to nearest full minute.  */
3676
        if (s->current_tm.tm_sec < 30)
3677
            s->ti -= s->current_tm.tm_sec;
3678
        else
3679
            s->ti += 60 - s->current_tm.tm_sec;
3680

    
3681
        s->round = 0;
3682
    }
3683

    
3684
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
3685

    
3686
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3687
        s->status |= 0x40;
3688
        omap_rtc_interrupts_update(s);
3689
    }
3690

    
3691
    if (s->interrupts & 0x04)
3692
        switch (s->interrupts & 3) {
3693
        case 0:
3694
            s->status |= 0x04;
3695
            qemu_irq_pulse(s->irq);
3696
            break;
3697
        case 1:
3698
            if (s->current_tm.tm_sec)
3699
                break;
3700
            s->status |= 0x08;
3701
            qemu_irq_pulse(s->irq);
3702
            break;
3703
        case 2:
3704
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
3705
                break;
3706
            s->status |= 0x10;
3707
            qemu_irq_pulse(s->irq);
3708
            break;
3709
        case 3:
3710
            if (s->current_tm.tm_sec ||
3711
                            s->current_tm.tm_min || s->current_tm.tm_hour)
3712
                break;
3713
            s->status |= 0x20;
3714
            qemu_irq_pulse(s->irq);
3715
            break;
3716
        }
3717

    
3718
    /* Move on */
3719
    if (s->running)
3720
        s->ti ++;
3721
    s->tick += 1000;
3722

    
3723
    /*
3724
     * Every full hour add a rough approximation of the compensation
3725
     * register to the 32kHz Timer (which drives the RTC) value. 
3726
     */
3727
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
3728
        s->tick += s->comp_reg * 1000 / 32768;
3729

    
3730
    qemu_mod_timer(s->clk, s->tick);
3731
}
3732

    
3733
static void omap_rtc_reset(struct omap_rtc_s *s)
3734
{
3735
    struct tm tm;
3736

    
3737
    s->interrupts = 0;
3738
    s->comp_reg = 0;
3739
    s->running = 0;
3740
    s->pm_am = 0;
3741
    s->auto_comp = 0;
3742
    s->round = 0;
3743
    s->tick = qemu_get_clock(rt_clock);
3744
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
3745
    s->alarm_tm.tm_mday = 0x01;
3746
    s->status = 1 << 7;
3747
    qemu_get_timedate(&tm, 0);
3748
    s->ti = mktime(&tm);
3749

    
3750
    omap_rtc_alarm_update(s);
3751
    omap_rtc_tick(s);
3752
}
3753

    
3754
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
3755
                qemu_irq *irq, omap_clk clk)
3756
{
3757
    int iomemtype;
3758
    struct omap_rtc_s *s = (struct omap_rtc_s *)
3759
            qemu_mallocz(sizeof(struct omap_rtc_s));
3760

    
3761
    s->base = base;
3762
    s->irq = irq[0];
3763
    s->alarm = irq[1];
3764
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
3765

    
3766
    omap_rtc_reset(s);
3767

    
3768
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
3769
                    omap_rtc_writefn, s);
3770
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3771

    
3772
    return s;
3773
}
3774

    
3775
/* Multi-channel Buffered Serial Port interfaces */
3776
struct omap_mcbsp_s {
3777
    target_phys_addr_t base;
3778
    qemu_irq txirq;
3779
    qemu_irq rxirq;
3780
    qemu_irq txdrq;
3781
    qemu_irq rxdrq;
3782

    
3783
    uint16_t spcr[2];
3784
    uint16_t rcr[2];
3785
    uint16_t xcr[2];
3786
    uint16_t srgr[2];
3787
    uint16_t mcr[2];
3788
    uint16_t pcr;
3789
    uint16_t rcer[8];
3790
    uint16_t xcer[8];
3791
    int tx_rate;
3792
    int rx_rate;
3793
    int tx_req;
3794
    int rx_req;
3795

    
3796
    struct i2s_codec_s *codec;
3797
    QEMUTimer *source_timer;
3798
    QEMUTimer *sink_timer;
3799
};
3800

    
3801
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
3802
{
3803
    int irq;
3804

    
3805
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
3806
    case 0:
3807
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
3808
        break;
3809
    case 3:
3810
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
3811
        break;
3812
    default:
3813
        irq = 0;
3814
        break;
3815
    }
3816

    
3817
    if (irq)
3818
        qemu_irq_pulse(s->rxirq);
3819

    
3820
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
3821
    case 0:
3822
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
3823
        break;
3824
    case 3:
3825
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
3826
        break;
3827
    default:
3828
        irq = 0;
3829
        break;
3830
    }
3831

    
3832
    if (irq)
3833
        qemu_irq_pulse(s->txirq);
3834
}
3835

    
3836
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
3837
{
3838
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
3839
        s->spcr[0] |= 1 << 2;                                /* RFULL */
3840
    s->spcr[0] |= 1 << 1;                                /* RRDY */
3841
    qemu_irq_raise(s->rxdrq);
3842
    omap_mcbsp_intr_update(s);
3843
}
3844

    
3845
static void omap_mcbsp_source_tick(void *opaque)
3846
{
3847
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3848
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3849

    
3850
    if (!s->rx_rate)
3851
        return;
3852
    if (s->rx_req)
3853
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
3854

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

    
3857
    omap_mcbsp_rx_newdata(s);
3858
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
3859
}
3860

    
3861
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3862
{
3863
    if (!s->codec || !s->codec->rts)
3864
        omap_mcbsp_source_tick(s);
3865
    else if (s->codec->in.len) {
3866
        s->rx_req = s->codec->in.len;
3867
        omap_mcbsp_rx_newdata(s);
3868
    }
3869
}
3870

    
3871
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3872
{
3873
    qemu_del_timer(s->source_timer);
3874
}
3875

    
3876
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3877
{
3878
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
3879
    qemu_irq_lower(s->rxdrq);
3880
    omap_mcbsp_intr_update(s);
3881
}
3882

    
3883
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3884
{
3885
    s->spcr[1] |= 1 << 1;                                /* XRDY */
3886
    qemu_irq_raise(s->txdrq);
3887
    omap_mcbsp_intr_update(s);
3888
}
3889

    
3890
static void omap_mcbsp_sink_tick(void *opaque)
3891
{
3892
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3893
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3894

    
3895
    if (!s->tx_rate)
3896
        return;
3897
    if (s->tx_req)
3898
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
3899

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

    
3902
    omap_mcbsp_tx_newdata(s);
3903
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
3904
}
3905

    
3906
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3907
{
3908
    if (!s->codec || !s->codec->cts)
3909
        omap_mcbsp_sink_tick(s);
3910
    else if (s->codec->out.size) {
3911
        s->tx_req = s->codec->out.size;
3912
        omap_mcbsp_tx_newdata(s);
3913
    }
3914
}
3915

    
3916
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3917
{
3918
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
3919
    qemu_irq_lower(s->txdrq);
3920
    omap_mcbsp_intr_update(s);
3921
    if (s->codec && s->codec->cts)
3922
        s->codec->tx_swallow(s->codec->opaque);
3923
}
3924

    
3925
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3926
{
3927
    s->tx_req = 0;
3928
    omap_mcbsp_tx_done(s);
3929
    qemu_del_timer(s->sink_timer);
3930
}
3931

    
3932
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3933
{
3934
    int prev_rx_rate, prev_tx_rate;
3935
    int rx_rate = 0, tx_rate = 0;
3936
    int cpu_rate = 1500000;        /* XXX */
3937

    
3938
    /* TODO: check CLKSTP bit */
3939
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
3940
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
3941
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3942
                            (s->pcr & (1 << 8))) {        /* CLKRM */
3943
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3944
                    rx_rate = cpu_rate /
3945
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3946
            } else
3947
                if (s->codec)
3948
                    rx_rate = s->codec->rx_rate;
3949
        }
3950

    
3951
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
3952
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3953
                            (s->pcr & (1 << 9))) {        /* CLKXM */
3954
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3955
                    tx_rate = cpu_rate /
3956
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3957
            } else
3958
                if (s->codec)
3959
                    tx_rate = s->codec->tx_rate;
3960
        }
3961
    }
3962
    prev_tx_rate = s->tx_rate;
3963
    prev_rx_rate = s->rx_rate;
3964
    s->tx_rate = tx_rate;
3965
    s->rx_rate = rx_rate;
3966

    
3967
    if (s->codec)
3968
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3969

    
3970
    if (!prev_tx_rate && tx_rate)
3971
        omap_mcbsp_tx_start(s);
3972
    else if (s->tx_rate && !tx_rate)
3973
        omap_mcbsp_tx_stop(s);
3974

    
3975
    if (!prev_rx_rate && rx_rate)
3976
        omap_mcbsp_rx_start(s);
3977
    else if (prev_tx_rate && !tx_rate)
3978
        omap_mcbsp_rx_stop(s);
3979
}
3980

    
3981
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
3982
{
3983
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3984
    int offset = addr & OMAP_MPUI_REG_MASK;
3985
    uint16_t ret;
3986

    
3987
    switch (offset) {
3988
    case 0x00:        /* DRR2 */
3989
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
3990
            return 0x0000;
3991
        /* Fall through.  */
3992
    case 0x02:        /* DRR1 */
3993
        if (s->rx_req < 2) {
3994
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
3995
            omap_mcbsp_rx_done(s);
3996
        } else {
3997
            s->tx_req -= 2;
3998
            if (s->codec && s->codec->in.len >= 2) {
3999
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
4000
                ret |= s->codec->in.fifo[s->codec->in.start ++];
4001
                s->codec->in.len -= 2;
4002
            } else
4003
                ret = 0x0000;
4004
            if (!s->tx_req)
4005
                omap_mcbsp_rx_done(s);
4006
            return ret;
4007
        }
4008
        return 0x0000;
4009

    
4010
    case 0x04:        /* DXR2 */
4011
    case 0x06:        /* DXR1 */
4012
        return 0x0000;
4013

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

    
4070
    OMAP_BAD_REG(addr);
4071
    return 0;
4072
}
4073

    
4074
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
4075
                uint32_t value)
4076
{
4077
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4078
    int offset = addr & OMAP_MPUI_REG_MASK;
4079

    
4080
    switch (offset) {
4081
    case 0x00:        /* DRR2 */
4082
    case 0x02:        /* DRR1 */
4083
        OMAP_RO_REG(addr);
4084
        return;
4085

    
4086
    case 0x04:        /* DXR2 */
4087
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4088
            return;
4089
        /* Fall through.  */
4090
    case 0x06:        /* DXR1 */
4091
        if (s->tx_req > 1) {
4092
            s->tx_req -= 2;
4093
            if (s->codec && s->codec->cts) {
4094
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
4095
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
4096
            }
4097
            if (s->tx_req < 2)
4098
                omap_mcbsp_tx_done(s);
4099
        } else
4100
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4101
        return;
4102

    
4103
    case 0x08:        /* SPCR2 */
4104
        s->spcr[1] &= 0x0002;
4105
        s->spcr[1] |= 0x03f9 & value;
4106
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
4107
        if (~value & 1)                                        /* XRST */
4108
            s->spcr[1] &= ~6;
4109
        omap_mcbsp_req_update(s);
4110
        return;
4111
    case 0x0a:        /* SPCR1 */
4112
        s->spcr[0] &= 0x0006;
4113
        s->spcr[0] |= 0xf8f9 & value;
4114
        if (value & (1 << 15))                                /* DLB */
4115
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
4116
        if (~value & 1) {                                /* RRST */
4117
            s->spcr[0] &= ~6;
4118
            s->rx_req = 0;
4119
            omap_mcbsp_rx_done(s);
4120
        }
4121
        omap_mcbsp_req_update(s);
4122
        return;
4123

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

    
4209
    OMAP_BAD_REG(addr);
4210
}
4211

    
4212
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
4213
                uint32_t value)
4214
{
4215
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4216
    int offset = addr & OMAP_MPUI_REG_MASK;
4217

    
4218
    if (offset == 0x04) {                                /* DXR */
4219
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
4220
            return;
4221
        if (s->tx_req > 3) {
4222
            s->tx_req -= 4;
4223
            if (s->codec && s->codec->cts) {
4224
                s->codec->out.fifo[s->codec->out.len ++] =
4225
                        (value >> 24) & 0xff;
4226
                s->codec->out.fifo[s->codec->out.len ++] =
4227
                        (value >> 16) & 0xff;
4228
                s->codec->out.fifo[s->codec->out.len ++] =
4229
                        (value >> 8) & 0xff;
4230
                s->codec->out.fifo[s->codec->out.len ++] =
4231
                        (value >> 0) & 0xff;
4232
            }
4233
            if (s->tx_req < 4)
4234
                omap_mcbsp_tx_done(s);
4235
        } else
4236
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
4237
        return;
4238
    }
4239

    
4240
    omap_badwidth_write16(opaque, addr, value);
4241
}
4242

    
4243
static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
4244
    omap_badwidth_read16,
4245
    omap_mcbsp_read,
4246
    omap_badwidth_read16,
4247
};
4248

    
4249
static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
4250
    omap_badwidth_write16,
4251
    omap_mcbsp_writeh,
4252
    omap_mcbsp_writew,
4253
};
4254

    
4255
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
4256
{
4257
    memset(&s->spcr, 0, sizeof(s->spcr));
4258
    memset(&s->rcr, 0, sizeof(s->rcr));
4259
    memset(&s->xcr, 0, sizeof(s->xcr));
4260
    s->srgr[0] = 0x0001;
4261
    s->srgr[1] = 0x2000;
4262
    memset(&s->mcr, 0, sizeof(s->mcr));
4263
    memset(&s->pcr, 0, sizeof(s->pcr));
4264
    memset(&s->rcer, 0, sizeof(s->rcer));
4265
    memset(&s->xcer, 0, sizeof(s->xcer));
4266
    s->tx_req = 0;
4267
    s->rx_req = 0;
4268
    s->tx_rate = 0;
4269
    s->rx_rate = 0;
4270
    qemu_del_timer(s->source_timer);
4271
    qemu_del_timer(s->sink_timer);
4272
}
4273

    
4274
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
4275
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
4276
{
4277
    int iomemtype;
4278
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
4279
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
4280

    
4281
    s->base = base;
4282
    s->txirq = irq[0];
4283
    s->rxirq = irq[1];
4284
    s->txdrq = dma[0];
4285
    s->rxdrq = dma[1];
4286
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
4287
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
4288
    omap_mcbsp_reset(s);
4289

    
4290
    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
4291
                    omap_mcbsp_writefn, s);
4292
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4293

    
4294
    return s;
4295
}
4296

    
4297
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
4298
{
4299
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4300

    
4301
    if (s->rx_rate) {
4302
        s->rx_req = s->codec->in.len;
4303
        omap_mcbsp_rx_newdata(s);
4304
    }
4305
}
4306

    
4307
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
4308
{
4309
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
4310

    
4311
    if (s->tx_rate) {
4312
        s->tx_req = s->codec->out.size;
4313
        omap_mcbsp_tx_newdata(s);
4314
    }
4315
}
4316

    
4317
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
4318
{
4319
    s->codec = slave;
4320
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
4321
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4322
}
4323

    
4324
/* LED Pulse Generators */
4325
struct omap_lpg_s {
4326
    target_phys_addr_t base;
4327
    QEMUTimer *tm;
4328

    
4329
    uint8_t control;
4330
    uint8_t power;
4331
    int64_t on;
4332
    int64_t period;
4333
    int clk;
4334
    int cycle;
4335
};
4336

    
4337
static void omap_lpg_tick(void *opaque)
4338
{
4339
    struct omap_lpg_s *s = opaque;
4340

    
4341
    if (s->cycle)
4342
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
4343
    else
4344
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
4345

    
4346
    s->cycle = !s->cycle;
4347
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
4348
}
4349

    
4350
static void omap_lpg_update(struct omap_lpg_s *s)
4351
{
4352
    int64_t on, period = 1, ticks = 1000;
4353
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
4354

    
4355
    if (~s->control & (1 << 6))                                        /* LPGRES */
4356
        on = 0;
4357
    else if (s->control & (1 << 7))                                /* PERM_ON */
4358
        on = period;
4359
    else {
4360
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
4361
                        256 / 32);
4362
        on = (s->clk && s->power) ? muldiv64(ticks,
4363
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
4364
    }
4365

    
4366
    qemu_del_timer(s->tm);
4367
    if (on == period && s->on < s->period)
4368
        printf("%s: LED is on\n", __FUNCTION__);
4369
    else if (on == 0 && s->on)
4370
        printf("%s: LED is off\n", __FUNCTION__);
4371
    else if (on && (on != s->on || period != s->period)) {
4372
        s->cycle = 0;
4373
        s->on = on;
4374
        s->period = period;
4375
        omap_lpg_tick(s);
4376
        return;
4377
    }
4378

    
4379
    s->on = on;
4380
    s->period = period;
4381
}
4382

    
4383
static void omap_lpg_reset(struct omap_lpg_s *s)
4384
{
4385
    s->control = 0x00;
4386
    s->power = 0x00;
4387
    s->clk = 1;
4388
    omap_lpg_update(s);
4389
}
4390

    
4391
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
4392
{
4393
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4394
    int offset = addr & OMAP_MPUI_REG_MASK;
4395

    
4396
    switch (offset) {
4397
    case 0x00:        /* LCR */
4398
        return s->control;
4399

    
4400
    case 0x04:        /* PMR */
4401
        return s->power;
4402
    }
4403

    
4404
    OMAP_BAD_REG(addr);
4405
    return 0;
4406
}
4407

    
4408
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
4409
                uint32_t value)
4410
{
4411
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4412
    int offset = addr & OMAP_MPUI_REG_MASK;
4413

    
4414
    switch (offset) {
4415
    case 0x00:        /* LCR */
4416
        if (~value & (1 << 6))                                        /* LPGRES */
4417
            omap_lpg_reset(s);
4418
        s->control = value & 0xff;
4419
        omap_lpg_update(s);
4420
        return;
4421

    
4422
    case 0x04:        /* PMR */
4423
        s->power = value & 0x01;
4424
        omap_lpg_update(s);
4425
        return;
4426

    
4427
    default:
4428
        OMAP_BAD_REG(addr);
4429
        return;
4430
    }
4431
}
4432

    
4433
static CPUReadMemoryFunc *omap_lpg_readfn[] = {
4434
    omap_lpg_read,
4435
    omap_badwidth_read8,
4436
    omap_badwidth_read8,
4437
};
4438

    
4439
static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
4440
    omap_lpg_write,
4441
    omap_badwidth_write8,
4442
    omap_badwidth_write8,
4443
};
4444

    
4445
static void omap_lpg_clk_update(void *opaque, int line, int on)
4446
{
4447
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4448

    
4449
    s->clk = on;
4450
    omap_lpg_update(s);
4451
}
4452

    
4453
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4454
{
4455
    int iomemtype;
4456
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4457
            qemu_mallocz(sizeof(struct omap_lpg_s));
4458

    
4459
    s->base = base;
4460
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4461

    
4462
    omap_lpg_reset(s);
4463

    
4464
    iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
4465
                    omap_lpg_writefn, s);
4466
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4467

    
4468
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4469

    
4470
    return s;
4471
}
4472

    
4473
/* MPUI Peripheral Bridge configuration */
4474
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
4475
{
4476
    if (addr == OMAP_MPUI_BASE)        /* CMR */
4477
        return 0xfe4d;
4478

    
4479
    OMAP_BAD_REG(addr);
4480
    return 0;
4481
}
4482

    
4483
static CPUReadMemoryFunc *omap_mpui_io_readfn[] = {
4484
    omap_badwidth_read16,
4485
    omap_mpui_io_read,
4486
    omap_badwidth_read16,
4487
};
4488

    
4489
static CPUWriteMemoryFunc *omap_mpui_io_writefn[] = {
4490
    omap_badwidth_write16,
4491
    omap_badwidth_write16,
4492
    omap_badwidth_write16,
4493
};
4494

    
4495
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4496
{
4497
    int iomemtype = cpu_register_io_memory(0, omap_mpui_io_readfn,
4498
                    omap_mpui_io_writefn, mpu);
4499
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
4500
}
4501

    
4502
/* General chip reset */
4503
static void omap1_mpu_reset(void *opaque)
4504
{
4505
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4506

    
4507
    omap_inth_reset(mpu->ih[0]);
4508
    omap_inth_reset(mpu->ih[1]);
4509
    omap_dma_reset(mpu->dma);
4510
    omap_mpu_timer_reset(mpu->timer[0]);
4511
    omap_mpu_timer_reset(mpu->timer[1]);
4512
    omap_mpu_timer_reset(mpu->timer[2]);
4513
    omap_wd_timer_reset(mpu->wdt);
4514
    omap_os_timer_reset(mpu->os_timer);
4515
    omap_lcdc_reset(mpu->lcd);
4516
    omap_ulpd_pm_reset(mpu);
4517
    omap_pin_cfg_reset(mpu);
4518
    omap_mpui_reset(mpu);
4519
    omap_tipb_bridge_reset(mpu->private_tipb);
4520
    omap_tipb_bridge_reset(mpu->public_tipb);
4521
    omap_dpll_reset(&mpu->dpll[0]);
4522
    omap_dpll_reset(&mpu->dpll[1]);
4523
    omap_dpll_reset(&mpu->dpll[2]);
4524
    omap_uart_reset(mpu->uart[0]);
4525
    omap_uart_reset(mpu->uart[1]);
4526
    omap_uart_reset(mpu->uart[2]);
4527
    omap_mmc_reset(mpu->mmc);
4528
    omap_mpuio_reset(mpu->mpuio);
4529
    omap_gpio_reset(mpu->gpio);
4530
    omap_uwire_reset(mpu->microwire);
4531
    omap_pwl_reset(mpu);
4532
    omap_pwt_reset(mpu);
4533
    omap_i2c_reset(mpu->i2c[0]);
4534
    omap_rtc_reset(mpu->rtc);
4535
    omap_mcbsp_reset(mpu->mcbsp1);
4536
    omap_mcbsp_reset(mpu->mcbsp2);
4537
    omap_mcbsp_reset(mpu->mcbsp3);
4538
    omap_lpg_reset(mpu->led[0]);
4539
    omap_lpg_reset(mpu->led[1]);
4540
    omap_clkm_reset(mpu);
4541
    cpu_reset(mpu->env);
4542
}
4543

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

    
4571
    { 0 }
4572
};
4573

    
4574
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4575
{
4576
    int io;
4577

    
4578
    for (; map->phys_dsp; map ++) {
4579
        io = cpu_get_physical_page_desc(map->phys_mpu);
4580

    
4581
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4582
    }
4583
}
4584

    
4585
void omap_mpu_wakeup(void *opaque, int irq, int req)
4586
{
4587
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4588

    
4589
    if (mpu->env->halted)
4590
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4591
}
4592

    
4593
static const struct dma_irq_map omap1_dma_irq_map[] = {
4594
    { 0, OMAP_INT_DMA_CH0_6 },
4595
    { 0, OMAP_INT_DMA_CH1_7 },
4596
    { 0, OMAP_INT_DMA_CH2_8 },
4597
    { 0, OMAP_INT_DMA_CH3 },
4598
    { 0, OMAP_INT_DMA_CH4 },
4599
    { 0, OMAP_INT_DMA_CH5 },
4600
    { 1, OMAP_INT_1610_DMA_CH6 },
4601
    { 1, OMAP_INT_1610_DMA_CH7 },
4602
    { 1, OMAP_INT_1610_DMA_CH8 },
4603
    { 1, OMAP_INT_1610_DMA_CH9 },
4604
    { 1, OMAP_INT_1610_DMA_CH10 },
4605
    { 1, OMAP_INT_1610_DMA_CH11 },
4606
    { 1, OMAP_INT_1610_DMA_CH12 },
4607
    { 1, OMAP_INT_1610_DMA_CH13 },
4608
    { 1, OMAP_INT_1610_DMA_CH14 },
4609
    { 1, OMAP_INT_1610_DMA_CH15 }
4610
};
4611

    
4612
/* DMA ports for OMAP1 */
4613
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
4614
                target_phys_addr_t addr)
4615
{
4616
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
4617
}
4618

    
4619
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
4620
                target_phys_addr_t addr)
4621
{
4622
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
4623
}
4624

    
4625
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
4626
                target_phys_addr_t addr)
4627
{
4628
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
4629
}
4630

    
4631
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
4632
                target_phys_addr_t addr)
4633
{
4634
    return addr >= 0xfffb0000 && addr < 0xffff0000;
4635
}
4636

    
4637
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
4638
                target_phys_addr_t addr)
4639
{
4640
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
4641
}
4642

    
4643
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
4644
                target_phys_addr_t addr)
4645
{
4646
    return addr >= 0xe1010000 && addr < 0xe1020004;
4647
}
4648

    
4649
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4650
                DisplayState *ds, const char *core)
4651
{
4652
    int i;
4653
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4654
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4655
    ram_addr_t imif_base, emiff_base;
4656
    qemu_irq *cpu_irq;
4657
    qemu_irq dma_irqs[6];
4658
    int sdindex;
4659

    
4660
    if (!core)
4661
        core = "ti925t";
4662

    
4663
    /* Core */
4664
    s->mpu_model = omap310;
4665
    s->env = cpu_init(core);
4666
    if (!s->env) {
4667
        fprintf(stderr, "Unable to find CPU definition\n");
4668
        exit(1);
4669
    }
4670
    s->sdram_size = sdram_size;
4671
    s->sram_size = OMAP15XX_SRAM_SIZE;
4672

    
4673
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4674

    
4675
    /* Clocks */
4676
    omap_clk_init(s);
4677

    
4678
    /* Memory-mapped stuff */
4679
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4680
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4681
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4682
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4683

    
4684
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4685

    
4686
    cpu_irq = arm_pic_init_cpu(s->env);
4687
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
4688
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4689
                    omap_findclk(s, "arminth_ck"));
4690
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1],
4691
                    s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
4692
                    omap_findclk(s, "arminth_ck"));
4693

    
4694
    for (i = 0; i < 6; i ++)
4695
        dma_irqs[i] =
4696
                s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr];
4697
    s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
4698
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
4699

    
4700
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4701
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4702
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4703
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4704
    s->port[local    ].addr_valid = omap_validate_local_addr;
4705
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4706

    
4707
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4708
                    s->irq[0][OMAP_INT_TIMER1],
4709
                    omap_findclk(s, "mputim_ck"));
4710
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4711
                    s->irq[0][OMAP_INT_TIMER2],
4712
                    omap_findclk(s, "mputim_ck"));
4713
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4714
                    s->irq[0][OMAP_INT_TIMER3],
4715
                    omap_findclk(s, "mputim_ck"));
4716

    
4717
    s->wdt = omap_wd_timer_init(0xfffec800,
4718
                    s->irq[0][OMAP_INT_WD_TIMER],
4719
                    omap_findclk(s, "armwdt_ck"));
4720

    
4721
    s->os_timer = omap_os_timer_init(0xfffb9000,
4722
                    s->irq[1][OMAP_INT_OS_TIMER],
4723
                    omap_findclk(s, "clk32-kHz"));
4724

    
4725
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4726
                    omap_dma_get_lcdch(s->dma), ds, imif_base, emiff_base,
4727
                    omap_findclk(s, "lcd_ck"));
4728

    
4729
    omap_ulpd_pm_init(0xfffe0800, s);
4730
    omap_pin_cfg_init(0xfffe1000, s);
4731
    omap_id_init(s);
4732

    
4733
    omap_mpui_init(0xfffec900, s);
4734

    
4735
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4736
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4737
                    omap_findclk(s, "tipb_ck"));
4738
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4739
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4740
                    omap_findclk(s, "tipb_ck"));
4741

    
4742
    omap_tcmi_init(0xfffecc00, s);
4743

    
4744
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4745
                    omap_findclk(s, "uart1_ck"),
4746
                    omap_findclk(s, "uart1_ck"),
4747
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
4748
                    serial_hds[0]);
4749
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4750
                    omap_findclk(s, "uart2_ck"),
4751
                    omap_findclk(s, "uart2_ck"),
4752
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
4753
                    serial_hds[0] ? serial_hds[1] : 0);
4754
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4755
                    omap_findclk(s, "uart3_ck"),
4756
                    omap_findclk(s, "uart3_ck"),
4757
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
4758
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4759

    
4760
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4761
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4762
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4763

    
4764
    sdindex = drive_get_index(IF_SD, 0, 0);
4765
    if (sdindex == -1) {
4766
        fprintf(stderr, "qemu: missing SecureDigital device\n");
4767
        exit(1);
4768
    }
4769
    s->mmc = omap_mmc_init(0xfffb7800, drives_table[sdindex].bdrv,
4770
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
4771
                    omap_findclk(s, "mmc_ck"));
4772

    
4773
    s->mpuio = omap_mpuio_init(0xfffb5000,
4774
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4775
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
4776

    
4777
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4778
                    omap_findclk(s, "arm_gpio_ck"));
4779

    
4780
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4781
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4782

    
4783
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4784
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4785

    
4786
    s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4787
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4788

    
4789
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4790
                    omap_findclk(s, "clk32-kHz"));
4791

    
4792
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
4793
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4794
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
4795
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4796
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
4797
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4798

    
4799
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
4800
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
4801

    
4802
    /* Register mappings not currenlty implemented:
4803
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4804
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4805
     * USB W2FC                fffb4000 - fffb47ff
4806
     * Camera Interface        fffb6800 - fffb6fff
4807
     * USB Host                fffba000 - fffba7ff
4808
     * FAC                fffba800 - fffbafff
4809
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4810
     * TIPB switches        fffbc800 - fffbcfff
4811
     * Mailbox                fffcf000 - fffcf7ff
4812
     * Local bus IF        fffec100 - fffec1ff
4813
     * Local bus MMU        fffec200 - fffec2ff
4814
     * DSP MMU                fffed200 - fffed2ff
4815
     */
4816

    
4817
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
4818
    omap_setup_mpui_io(s);
4819

    
4820
    qemu_register_reset(omap1_mpu_reset, s);
4821

    
4822
    return s;
4823
}