Statistics
| Branch: | Revision:

root / hw / omap1.c @ b4e3104b

History | View | Annotate | Download (122.3 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 of
9
 * the License, or (at your option) any later version.
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
/* We use pc-style serial ports.  */
27
#include "pc.h"
28

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

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

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

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

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

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

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

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

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

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

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

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

    
92
struct omap_intr_handler_s {
93
    qemu_irq *pins;
94
    qemu_irq parent_intr[2];
95
    target_phys_addr_t base;
96
    unsigned char nbanks;
97

    
98
    /* state */
99
    uint32_t new_agr[2];
100
    int sir_intr[2];
101
    struct omap_intr_handler_bank_s banks[];
102
};
103

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

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

    
131
static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
132
{
133
    int i;
134
    uint32_t has_intr = 0;
135

    
136
    for (i = 0; i < s->nbanks; ++i)
137
        has_intr |= s->banks[i].irqs & ~s->banks[i].mask &
138
                (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq);
139

    
140
    if (s->new_agr[is_fiq] && has_intr) {
141
        s->new_agr[is_fiq] = 0;
142
        omap_inth_sir_update(s, is_fiq);
143
        qemu_set_irq(s->parent_intr[is_fiq], 1);
144
    }
145
}
146

    
147
#define INT_FALLING_EDGE        0
148
#define INT_LOW_LEVEL                1
149

    
150
static void omap_set_intr(void *opaque, int irq, int req)
151
{
152
    struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
153
    uint32_t rise;
154

    
155
    struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5];
156
    int n = irq & 31;
157

    
158
    if (req) {
159
        rise = ~bank->irqs & (1 << n);
160
        if (~bank->sens_edge & (1 << n))
161
            rise &= ~bank->inputs & (1 << n);
162

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

    
176
static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
177
{
178
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
179
    int i, offset = addr - s->base;
180
    int bank_no = offset >> 8;
181
    int line_no;
182
    struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
183
    offset &= 0xff;
184

    
185
    switch (offset) {
186
    case 0x00:        /* ITR */
187
        return bank->irqs;
188

    
189
    case 0x04:        /* MIR */
190
        return bank->mask;
191

    
192
    case 0x10:        /* SIR_IRQ_CODE */
193
    case 0x14:  /* SIR_FIQ_CODE */
194
        if (bank_no != 0)
195
            break;
196
        line_no = s->sir_intr[(offset - 0x10) >> 2];
197
        bank = &s->banks[line_no >> 5];
198
        i = line_no & 31;
199
        if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
200
            bank->irqs &= ~(1 << i);
201
        return line_no;
202

    
203
    case 0x18:        /* CONTROL_REG */
204
        if (bank_no != 0)
205
            break;
206
        return 0;
207

    
208
    case 0x1c:        /* ILR0 */
209
    case 0x20:        /* ILR1 */
210
    case 0x24:        /* ILR2 */
211
    case 0x28:        /* ILR3 */
212
    case 0x2c:        /* ILR4 */
213
    case 0x30:        /* ILR5 */
214
    case 0x34:        /* ILR6 */
215
    case 0x38:        /* ILR7 */
216
    case 0x3c:        /* ILR8 */
217
    case 0x40:        /* ILR9 */
218
    case 0x44:        /* ILR10 */
219
    case 0x48:        /* ILR11 */
220
    case 0x4c:        /* ILR12 */
221
    case 0x50:        /* ILR13 */
222
    case 0x54:        /* ILR14 */
223
    case 0x58:        /* ILR15 */
224
    case 0x5c:        /* ILR16 */
225
    case 0x60:        /* ILR17 */
226
    case 0x64:        /* ILR18 */
227
    case 0x68:        /* ILR19 */
228
    case 0x6c:        /* ILR20 */
229
    case 0x70:        /* ILR21 */
230
    case 0x74:        /* ILR22 */
231
    case 0x78:        /* ILR23 */
232
    case 0x7c:        /* ILR24 */
233
    case 0x80:        /* ILR25 */
234
    case 0x84:        /* ILR26 */
235
    case 0x88:        /* ILR27 */
236
    case 0x8c:        /* ILR28 */
237
    case 0x90:        /* ILR29 */
238
    case 0x94:        /* ILR30 */
239
    case 0x98:        /* ILR31 */
240
        i = (offset - 0x1c) >> 2;
241
        return (bank->priority[i] << 2) |
242
                (((bank->sens_edge >> i) & 1) << 1) |
243
                ((bank->fiq >> i) & 1);
244

    
245
    case 0x9c:        /* ISR */
246
        return 0x00000000;
247

    
248
    }
249
    OMAP_BAD_REG(addr);
250
    return 0;
251
}
252

    
253
static void omap_inth_write(void *opaque, target_phys_addr_t addr,
254
                uint32_t value)
255
{
256
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
257
    int i, offset = addr - s->base;
258
    int bank_no = offset >> 8;
259
    struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
260
    offset &= 0xff;
261

    
262
    switch (offset) {
263
    case 0x00:        /* ITR */
264
        /* Important: ignore the clearing if the IRQ is level-triggered and
265
           the input bit is 1 */
266
        bank->irqs &= value | (bank->inputs & bank->sens_edge);
267
        return;
268

    
269
    case 0x04:        /* MIR */
270
        bank->mask = value;
271
        omap_inth_update(s, 0);
272
        omap_inth_update(s, 1);
273
        return;
274

    
275
    case 0x10:        /* SIR_IRQ_CODE */
276
    case 0x14:        /* SIR_FIQ_CODE */
277
        OMAP_RO_REG(addr);
278
        break;
279

    
280
    case 0x18:        /* CONTROL_REG */
281
        if (bank_no != 0)
282
            break;
283
        if (value & 2) {
284
            qemu_set_irq(s->parent_intr[1], 0);
285
            s->new_agr[1] = ~0;
286
            omap_inth_update(s, 1);
287
        }
288
        if (value & 1) {
289
            qemu_set_irq(s->parent_intr[0], 0);
290
            s->new_agr[0] = ~0;
291
            omap_inth_update(s, 0);
292
        }
293
        return;
294

    
295
    case 0x1c:        /* ILR0 */
296
    case 0x20:        /* ILR1 */
297
    case 0x24:        /* ILR2 */
298
    case 0x28:        /* ILR3 */
299
    case 0x2c:        /* ILR4 */
300
    case 0x30:        /* ILR5 */
301
    case 0x34:        /* ILR6 */
302
    case 0x38:        /* ILR7 */
303
    case 0x3c:        /* ILR8 */
304
    case 0x40:        /* ILR9 */
305
    case 0x44:        /* ILR10 */
306
    case 0x48:        /* ILR11 */
307
    case 0x4c:        /* ILR12 */
308
    case 0x50:        /* ILR13 */
309
    case 0x54:        /* ILR14 */
310
    case 0x58:        /* ILR15 */
311
    case 0x5c:        /* ILR16 */
312
    case 0x60:        /* ILR17 */
313
    case 0x64:        /* ILR18 */
314
    case 0x68:        /* ILR19 */
315
    case 0x6c:        /* ILR20 */
316
    case 0x70:        /* ILR21 */
317
    case 0x74:        /* ILR22 */
318
    case 0x78:        /* ILR23 */
319
    case 0x7c:        /* ILR24 */
320
    case 0x80:        /* ILR25 */
321
    case 0x84:        /* ILR26 */
322
    case 0x88:        /* ILR27 */
323
    case 0x8c:        /* ILR28 */
324
    case 0x90:        /* ILR29 */
325
    case 0x94:        /* ILR30 */
326
    case 0x98:        /* ILR31 */
327
        i = (offset - 0x1c) >> 2;
328
        bank->priority[i] = (value >> 2) & 0x1f;
329
        bank->sens_edge &= ~(1 << i);
330
        bank->sens_edge |= ((value >> 1) & 1) << i;
331
        bank->fiq &= ~(1 << i);
332
        bank->fiq |= (value & 1) << i;
333
        return;
334

    
335
    case 0x9c:        /* ISR */
336
        for (i = 0; i < 32; i ++)
337
            if (value & (1 << i)) {
338
                omap_set_intr(s, 32 * bank_no + i, 1);
339
                return;
340
            }
341
        return;
342
    }
343
    OMAP_BAD_REG(addr);
344
}
345

    
346
static CPUReadMemoryFunc *omap_inth_readfn[] = {
347
    omap_badwidth_read32,
348
    omap_badwidth_read32,
349
    omap_inth_read,
350
};
351

    
352
static CPUWriteMemoryFunc *omap_inth_writefn[] = {
353
    omap_inth_write,
354
    omap_inth_write,
355
    omap_inth_write,
356
};
357

    
358
void omap_inth_reset(struct omap_intr_handler_s *s)
359
{
360
    int i;
361

    
362
    for (i = 0; i < s->nbanks; ++i){
363
        s->banks[i].irqs = 0x00000000;
364
        s->banks[i].mask = 0xffffffff;
365
        s->banks[i].sens_edge = 0x00000000;
366
        s->banks[i].fiq = 0x00000000;
367
        s->banks[i].inputs = 0x00000000;
368
        memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority));
369
    }
370

    
371
    s->new_agr[0] = ~0;
372
    s->new_agr[1] = ~0;
373
    s->sir_intr[0] = 0;
374
    s->sir_intr[1] = 0;
375

    
376
    qemu_set_irq(s->parent_intr[0], 0);
377
    qemu_set_irq(s->parent_intr[1], 0);
378
}
379

    
380
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
381
                unsigned long size, unsigned char nbanks,
382
                qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk)
383
{
384
    int iomemtype;
385
    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
386
            qemu_mallocz(sizeof(struct omap_intr_handler_s) +
387
                            sizeof(struct omap_intr_handler_bank_s) * nbanks);
388

    
389
    s->parent_intr[0] = parent_irq;
390
    s->parent_intr[1] = parent_fiq;
391
    s->base = base;
392
    s->nbanks = nbanks;
393
    s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
394

    
395
    omap_inth_reset(s);
396

    
397
    iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
398
                    omap_inth_writefn, s);
399
    cpu_register_physical_memory(s->base, size, iomemtype);
400

    
401
    return s;
402
}
403

    
404
/* MPU OS timers */
405
struct omap_mpu_timer_s {
406
    qemu_irq irq;
407
    omap_clk clk;
408
    target_phys_addr_t base;
409
    uint32_t val;
410
    int64_t time;
411
    QEMUTimer *timer;
412
    int64_t rate;
413
    int it_ena;
414

    
415
    int enable;
416
    int ptv;
417
    int ar;
418
    int st;
419
    uint32_t reset_val;
420
};
421

    
422
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
423
{
424
    uint64_t distance = qemu_get_clock(vm_clock) - timer->time;
425

    
426
    if (timer->st && timer->enable && timer->rate)
427
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
428
                        timer->rate, ticks_per_sec);
429
    else
430
        return timer->val;
431
}
432

    
433
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
434
{
435
    timer->val = omap_timer_read(timer);
436
    timer->time = qemu_get_clock(vm_clock);
437
}
438

    
439
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
440
{
441
    int64_t expires;
442

    
443
    if (timer->enable && timer->st && timer->rate) {
444
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
445
        expires = muldiv64(timer->val << (timer->ptv + 1),
446
                        ticks_per_sec, timer->rate);
447

    
448
        /* If timer expiry would be sooner than in about 1 ms and
449
         * auto-reload isn't set, then fire immediately.  This is a hack
450
         * to make systems like PalmOS run in acceptable time.  PalmOS
451
         * sets the interval to a very low value and polls the status bit
452
         * in a busy loop when it wants to sleep just a couple of CPU
453
         * ticks.  */
454
        if (expires > (ticks_per_sec >> 10) || timer->ar)
455
            qemu_mod_timer(timer->timer, timer->time + expires);
456
        else {
457
            timer->val = 0;
458
            timer->st = 0;
459
            if (timer->it_ena)
460
                /* Edge-triggered irq */
461
                qemu_irq_pulse(timer->irq);
462
        }
463
    } else
464
        qemu_del_timer(timer->timer);
465
}
466

    
467
static void omap_timer_tick(void *opaque)
468
{
469
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
470
    omap_timer_sync(timer);
471

    
472
    if (!timer->ar) {
473
        timer->val = 0;
474
        timer->st = 0;
475
    }
476

    
477
    if (timer->it_ena)
478
        /* Edge-triggered irq */
479
        qemu_irq_pulse(timer->irq);
480
    omap_timer_update(timer);
481
}
482

    
483
static void omap_timer_clk_update(void *opaque, int line, int on)
484
{
485
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
486

    
487
    omap_timer_sync(timer);
488
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
489
    omap_timer_update(timer);
490
}
491

    
492
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
493
{
494
    omap_clk_adduser(timer->clk,
495
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
496
    timer->rate = omap_clk_getrate(timer->clk);
497
}
498

    
499
static uint32_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr)
500
{
501
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
502
    int offset = addr - s->base;
503

    
504
    switch (offset) {
505
    case 0x00:        /* CNTL_TIMER */
506
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
507

    
508
    case 0x04:        /* LOAD_TIM */
509
        break;
510

    
511
    case 0x08:        /* READ_TIM */
512
        return omap_timer_read(s);
513
    }
514

    
515
    OMAP_BAD_REG(addr);
516
    return 0;
517
}
518

    
519
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
520
                uint32_t value)
521
{
522
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
523
    int offset = addr - s->base;
524

    
525
    switch (offset) {
526
    case 0x00:        /* CNTL_TIMER */
527
        omap_timer_sync(s);
528
        s->enable = (value >> 5) & 1;
529
        s->ptv = (value >> 2) & 7;
530
        s->ar = (value >> 1) & 1;
531
        s->st = value & 1;
532
        omap_timer_update(s);
533
        return;
534

    
535
    case 0x04:        /* LOAD_TIM */
536
        s->reset_val = value;
537
        return;
538

    
539
    case 0x08:        /* READ_TIM */
540
        OMAP_RO_REG(addr);
541
        break;
542

    
543
    default:
544
        OMAP_BAD_REG(addr);
545
    }
546
}
547

    
548
static CPUReadMemoryFunc *omap_mpu_timer_readfn[] = {
549
    omap_badwidth_read32,
550
    omap_badwidth_read32,
551
    omap_mpu_timer_read,
552
};
553

    
554
static CPUWriteMemoryFunc *omap_mpu_timer_writefn[] = {
555
    omap_badwidth_write32,
556
    omap_badwidth_write32,
557
    omap_mpu_timer_write,
558
};
559

    
560
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
561
{
562
    qemu_del_timer(s->timer);
563
    s->enable = 0;
564
    s->reset_val = 31337;
565
    s->val = 0;
566
    s->ptv = 0;
567
    s->ar = 0;
568
    s->st = 0;
569
    s->it_ena = 1;
570
}
571

    
572
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
573
                qemu_irq irq, omap_clk clk)
574
{
575
    int iomemtype;
576
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
577
            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
578

    
579
    s->irq = irq;
580
    s->clk = clk;
581
    s->base = base;
582
    s->timer = qemu_new_timer(vm_clock, omap_timer_tick, s);
583
    omap_mpu_timer_reset(s);
584
    omap_timer_clk_setup(s);
585

    
586
    iomemtype = cpu_register_io_memory(0, omap_mpu_timer_readfn,
587
                    omap_mpu_timer_writefn, s);
588
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
589

    
590
    return s;
591
}
592

    
593
/* Watchdog timer */
594
struct omap_watchdog_timer_s {
595
    struct omap_mpu_timer_s timer;
596
    uint8_t last_wr;
597
    int mode;
598
    int free;
599
    int reset;
600
};
601

    
602
static uint32_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr)
603
{
604
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
605
    int offset = addr - s->timer.base;
606

    
607
    switch (offset) {
608
    case 0x00:        /* CNTL_TIMER */
609
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
610
                (s->timer.st << 7) | (s->free << 1);
611

    
612
    case 0x04:        /* READ_TIMER */
613
        return omap_timer_read(&s->timer);
614

    
615
    case 0x08:        /* TIMER_MODE */
616
        return s->mode << 15;
617
    }
618

    
619
    OMAP_BAD_REG(addr);
620
    return 0;
621
}
622

    
623
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
624
                uint32_t value)
625
{
626
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
627
    int offset = addr - s->timer.base;
628

    
629
    switch (offset) {
630
    case 0x00:        /* CNTL_TIMER */
631
        omap_timer_sync(&s->timer);
632
        s->timer.ptv = (value >> 9) & 7;
633
        s->timer.ar = (value >> 8) & 1;
634
        s->timer.st = (value >> 7) & 1;
635
        s->free = (value >> 1) & 1;
636
        omap_timer_update(&s->timer);
637
        break;
638

    
639
    case 0x04:        /* LOAD_TIMER */
640
        s->timer.reset_val = value & 0xffff;
641
        break;
642

    
643
    case 0x08:        /* TIMER_MODE */
644
        if (!s->mode && ((value >> 15) & 1))
645
            omap_clk_get(s->timer.clk);
646
        s->mode |= (value >> 15) & 1;
647
        if (s->last_wr == 0xf5) {
648
            if ((value & 0xff) == 0xa0) {
649
                if (s->mode) {
650
                    s->mode = 0;
651
                    omap_clk_put(s->timer.clk);
652
                }
653
            } else {
654
                /* XXX: on T|E hardware somehow this has no effect,
655
                 * on Zire 71 it works as specified.  */
656
                s->reset = 1;
657
                qemu_system_reset_request();
658
            }
659
        }
660
        s->last_wr = value & 0xff;
661
        break;
662

    
663
    default:
664
        OMAP_BAD_REG(addr);
665
    }
666
}
667

    
668
static CPUReadMemoryFunc *omap_wd_timer_readfn[] = {
669
    omap_badwidth_read16,
670
    omap_wd_timer_read,
671
    omap_badwidth_read16,
672
};
673

    
674
static CPUWriteMemoryFunc *omap_wd_timer_writefn[] = {
675
    omap_badwidth_write16,
676
    omap_wd_timer_write,
677
    omap_badwidth_write16,
678
};
679

    
680
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
681
{
682
    qemu_del_timer(s->timer.timer);
683
    if (!s->mode)
684
        omap_clk_get(s->timer.clk);
685
    s->mode = 1;
686
    s->free = 1;
687
    s->reset = 0;
688
    s->timer.enable = 1;
689
    s->timer.it_ena = 1;
690
    s->timer.reset_val = 0xffff;
691
    s->timer.val = 0;
692
    s->timer.st = 0;
693
    s->timer.ptv = 0;
694
    s->timer.ar = 0;
695
    omap_timer_update(&s->timer);
696
}
697

    
698
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
699
                qemu_irq irq, omap_clk clk)
700
{
701
    int iomemtype;
702
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
703
            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
704

    
705
    s->timer.irq = irq;
706
    s->timer.clk = clk;
707
    s->timer.base = base;
708
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
709
    omap_wd_timer_reset(s);
710
    omap_timer_clk_setup(&s->timer);
711

    
712
    iomemtype = cpu_register_io_memory(0, omap_wd_timer_readfn,
713
                    omap_wd_timer_writefn, s);
714
    cpu_register_physical_memory(s->timer.base, 0x100, iomemtype);
715

    
716
    return s;
717
}
718

    
719
/* 32-kHz timer */
720
struct omap_32khz_timer_s {
721
    struct omap_mpu_timer_s timer;
722
};
723

    
724
static uint32_t omap_os_timer_read(void *opaque, target_phys_addr_t addr)
725
{
726
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
727
    int offset = addr & OMAP_MPUI_REG_MASK;
728

    
729
    switch (offset) {
730
    case 0x00:        /* TVR */
731
        return s->timer.reset_val;
732

    
733
    case 0x04:        /* TCR */
734
        return omap_timer_read(&s->timer);
735

    
736
    case 0x08:        /* CR */
737
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
738

    
739
    default:
740
        break;
741
    }
742
    OMAP_BAD_REG(addr);
743
    return 0;
744
}
745

    
746
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
747
                uint32_t value)
748
{
749
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
750
    int offset = addr & OMAP_MPUI_REG_MASK;
751

    
752
    switch (offset) {
753
    case 0x00:        /* TVR */
754
        s->timer.reset_val = value & 0x00ffffff;
755
        break;
756

    
757
    case 0x04:        /* TCR */
758
        OMAP_RO_REG(addr);
759
        break;
760

    
761
    case 0x08:        /* CR */
762
        s->timer.ar = (value >> 3) & 1;
763
        s->timer.it_ena = (value >> 2) & 1;
764
        if (s->timer.st != (value & 1) || (value & 2)) {
765
            omap_timer_sync(&s->timer);
766
            s->timer.enable = value & 1;
767
            s->timer.st = value & 1;
768
            omap_timer_update(&s->timer);
769
        }
770
        break;
771

    
772
    default:
773
        OMAP_BAD_REG(addr);
774
    }
775
}
776

    
777
static CPUReadMemoryFunc *omap_os_timer_readfn[] = {
778
    omap_badwidth_read32,
779
    omap_badwidth_read32,
780
    omap_os_timer_read,
781
};
782

    
783
static CPUWriteMemoryFunc *omap_os_timer_writefn[] = {
784
    omap_badwidth_write32,
785
    omap_badwidth_write32,
786
    omap_os_timer_write,
787
};
788

    
789
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
790
{
791
    qemu_del_timer(s->timer.timer);
792
    s->timer.enable = 0;
793
    s->timer.it_ena = 0;
794
    s->timer.reset_val = 0x00ffffff;
795
    s->timer.val = 0;
796
    s->timer.st = 0;
797
    s->timer.ptv = 0;
798
    s->timer.ar = 1;
799
}
800

    
801
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
802
                qemu_irq irq, omap_clk clk)
803
{
804
    int iomemtype;
805
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
806
            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
807

    
808
    s->timer.irq = irq;
809
    s->timer.clk = clk;
810
    s->timer.base = base;
811
    s->timer.timer = qemu_new_timer(vm_clock, omap_timer_tick, &s->timer);
812
    omap_os_timer_reset(s);
813
    omap_timer_clk_setup(&s->timer);
814

    
815
    iomemtype = cpu_register_io_memory(0, omap_os_timer_readfn,
816
                    omap_os_timer_writefn, s);
817
    cpu_register_physical_memory(s->timer.base, 0x800, iomemtype);
818

    
819
    return s;
820
}
821

    
822
/* Ultra Low-Power Device Module */
823
static uint32_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr)
824
{
825
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
826
    int offset = addr - s->ulpd_pm_base;
827
    uint16_t ret;
828

    
829
    switch (offset) {
830
    case 0x14:        /* IT_STATUS */
831
        ret = s->ulpd_pm_regs[offset >> 2];
832
        s->ulpd_pm_regs[offset >> 2] = 0;
833
        qemu_irq_lower(s->irq[1][OMAP_INT_GAUGE_32K]);
834
        return ret;
835

    
836
    case 0x18:        /* Reserved */
837
    case 0x1c:        /* Reserved */
838
    case 0x20:        /* Reserved */
839
    case 0x28:        /* Reserved */
840
    case 0x2c:        /* Reserved */
841
        OMAP_BAD_REG(addr);
842
    case 0x00:        /* COUNTER_32_LSB */
843
    case 0x04:        /* COUNTER_32_MSB */
844
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
845
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
846
    case 0x10:        /* GAUGING_CTRL */
847
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
848
    case 0x30:        /* CLOCK_CTRL */
849
    case 0x34:        /* SOFT_REQ */
850
    case 0x38:        /* COUNTER_32_FIQ */
851
    case 0x3c:        /* DPLL_CTRL */
852
    case 0x40:        /* STATUS_REQ */
853
        /* XXX: check clk::usecount state for every clock */
854
    case 0x48:        /* LOCL_TIME */
855
    case 0x4c:        /* APLL_CTRL */
856
    case 0x50:        /* POWER_CTRL */
857
        return s->ulpd_pm_regs[offset >> 2];
858
    }
859

    
860
    OMAP_BAD_REG(addr);
861
    return 0;
862
}
863

    
864
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
865
                uint16_t diff, uint16_t value)
866
{
867
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
868
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
869
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
870
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
871
}
872

    
873
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
874
                uint16_t diff, uint16_t value)
875
{
876
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
877
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
878
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
879
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
880
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
881
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
882
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
883
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
884
}
885

    
886
static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
887
                uint32_t value)
888
{
889
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
890
    int offset = addr - s->ulpd_pm_base;
891
    int64_t now, ticks;
892
    int div, mult;
893
    static const int bypass_div[4] = { 1, 2, 4, 4 };
894
    uint16_t diff;
895

    
896
    switch (offset) {
897
    case 0x00:        /* COUNTER_32_LSB */
898
    case 0x04:        /* COUNTER_32_MSB */
899
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
900
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
901
    case 0x14:        /* IT_STATUS */
902
    case 0x40:        /* STATUS_REQ */
903
        OMAP_RO_REG(addr);
904
        break;
905

    
906
    case 0x10:        /* GAUGING_CTRL */
907
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
908
        if ((s->ulpd_pm_regs[offset >> 2] ^ value) & 1) {
909
            now = qemu_get_clock(vm_clock);
910

    
911
            if (value & 1)
912
                s->ulpd_gauge_start = now;
913
            else {
914
                now -= s->ulpd_gauge_start;
915

    
916
                /* 32-kHz ticks */
917
                ticks = muldiv64(now, 32768, ticks_per_sec);
918
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
919
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
920
                if (ticks >> 32)        /* OVERFLOW_32K */
921
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
922

    
923
                /* High frequency ticks */
924
                ticks = muldiv64(now, 12000000, ticks_per_sec);
925
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
926
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
927
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
928
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
929

    
930
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
931
                qemu_irq_raise(s->irq[1][OMAP_INT_GAUGE_32K]);
932
            }
933
        }
934
        s->ulpd_pm_regs[offset >> 2] = value;
935
        break;
936

    
937
    case 0x18:        /* Reserved */
938
    case 0x1c:        /* Reserved */
939
    case 0x20:        /* Reserved */
940
    case 0x28:        /* Reserved */
941
    case 0x2c:        /* Reserved */
942
        OMAP_BAD_REG(addr);
943
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
944
    case 0x38:        /* COUNTER_32_FIQ */
945
    case 0x48:        /* LOCL_TIME */
946
    case 0x50:        /* POWER_CTRL */
947
        s->ulpd_pm_regs[offset >> 2] = value;
948
        break;
949

    
950
    case 0x30:        /* CLOCK_CTRL */
951
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
952
        s->ulpd_pm_regs[offset >> 2] = value & 0x3f;
953
        omap_ulpd_clk_update(s, diff, value);
954
        break;
955

    
956
    case 0x34:        /* SOFT_REQ */
957
        diff = s->ulpd_pm_regs[offset >> 2] ^ value;
958
        s->ulpd_pm_regs[offset >> 2] = value & 0x1f;
959
        omap_ulpd_req_update(s, diff, value);
960
        break;
961

    
962
    case 0x3c:        /* DPLL_CTRL */
963
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
964
         * omitted altogether, probably a typo.  */
965
        /* This register has identical semantics with DPLL(1:3) control
966
         * registers, see omap_dpll_write() */
967
        diff = s->ulpd_pm_regs[offset >> 2] & value;
968
        s->ulpd_pm_regs[offset >> 2] = value & 0x2fff;
969
        if (diff & (0x3ff << 2)) {
970
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
971
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
972
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
973
            } else {
974
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
975
                mult = 1;
976
            }
977
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
978
        }
979

    
980
        /* Enter the desired mode.  */
981
        s->ulpd_pm_regs[offset >> 2] =
982
                (s->ulpd_pm_regs[offset >> 2] & 0xfffe) |
983
                ((s->ulpd_pm_regs[offset >> 2] >> 4) & 1);
984

    
985
        /* Act as if the lock is restored.  */
986
        s->ulpd_pm_regs[offset >> 2] |= 2;
987
        break;
988

    
989
    case 0x4c:        /* APLL_CTRL */
990
        diff = s->ulpd_pm_regs[offset >> 2] & value;
991
        s->ulpd_pm_regs[offset >> 2] = value & 0xf;
992
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
993
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
994
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
995
        break;
996

    
997
    default:
998
        OMAP_BAD_REG(addr);
999
    }
1000
}
1001

    
1002
static CPUReadMemoryFunc *omap_ulpd_pm_readfn[] = {
1003
    omap_badwidth_read16,
1004
    omap_ulpd_pm_read,
1005
    omap_badwidth_read16,
1006
};
1007

    
1008
static CPUWriteMemoryFunc *omap_ulpd_pm_writefn[] = {
1009
    omap_badwidth_write16,
1010
    omap_ulpd_pm_write,
1011
    omap_badwidth_write16,
1012
};
1013

    
1014
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
1015
{
1016
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
1017
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
1018
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
1019
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
1020
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
1021
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
1022
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
1023
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
1024
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
1025
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
1026
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
1027
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
1028
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
1029
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
1030
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
1031
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
1032
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
1033
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
1034
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
1035
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
1036
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
1037
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
1038
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
1039
}
1040

    
1041
static void omap_ulpd_pm_init(target_phys_addr_t base,
1042
                struct omap_mpu_state_s *mpu)
1043
{
1044
    int iomemtype = cpu_register_io_memory(0, omap_ulpd_pm_readfn,
1045
                    omap_ulpd_pm_writefn, mpu);
1046

    
1047
    mpu->ulpd_pm_base = base;
1048
    cpu_register_physical_memory(mpu->ulpd_pm_base, 0x800, iomemtype);
1049
    omap_ulpd_pm_reset(mpu);
1050
}
1051

    
1052
/* OMAP Pin Configuration */
1053
static uint32_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr)
1054
{
1055
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1056
    int offset = addr - s->pin_cfg_base;
1057

    
1058
    switch (offset) {
1059
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1060
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1061
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1062
        return s->func_mux_ctrl[offset >> 2];
1063

    
1064
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1065
        return s->comp_mode_ctrl[0];
1066

    
1067
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1068
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1069
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1070
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1071
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1072
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1073
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1074
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1075
    case 0x30:        /* FUNC_MUX_CTRL_B */
1076
    case 0x34:        /* FUNC_MUX_CTRL_C */
1077
    case 0x38:        /* FUNC_MUX_CTRL_D */
1078
        return s->func_mux_ctrl[(offset >> 2) - 1];
1079

    
1080
    case 0x40:        /* PULL_DWN_CTRL_0 */
1081
    case 0x44:        /* PULL_DWN_CTRL_1 */
1082
    case 0x48:        /* PULL_DWN_CTRL_2 */
1083
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1084
        return s->pull_dwn_ctrl[(offset & 0xf) >> 2];
1085

    
1086
    case 0x50:        /* GATE_INH_CTRL_0 */
1087
        return s->gate_inh_ctrl[0];
1088

    
1089
    case 0x60:        /* VOLTAGE_CTRL_0 */
1090
        return s->voltage_ctrl[0];
1091

    
1092
    case 0x70:        /* TEST_DBG_CTRL_0 */
1093
        return s->test_dbg_ctrl[0];
1094

    
1095
    case 0x80:        /* MOD_CONF_CTRL_0 */
1096
        return s->mod_conf_ctrl[0];
1097
    }
1098

    
1099
    OMAP_BAD_REG(addr);
1100
    return 0;
1101
}
1102

    
1103
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
1104
                uint32_t diff, uint32_t value)
1105
{
1106
    if (s->compat1509) {
1107
        if (diff & (1 << 9))                        /* BLUETOOTH */
1108
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
1109
                            (~value >> 9) & 1);
1110
        if (diff & (1 << 7))                        /* USB.CLKO */
1111
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
1112
                            (value >> 7) & 1);
1113
    }
1114
}
1115

    
1116
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
1117
                uint32_t diff, uint32_t value)
1118
{
1119
    if (s->compat1509) {
1120
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
1121
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
1122
                            (value >> 31) & 1);
1123
        if (diff & (1 << 1))                        /* CLK32K */
1124
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
1125
                            (~value >> 1) & 1);
1126
    }
1127
}
1128

    
1129
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
1130
                uint32_t diff, uint32_t value)
1131
{
1132
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
1133
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
1134
                         omap_findclk(s, ((value >> 31) & 1) ?
1135
                                 "ck_48m" : "armper_ck"));
1136
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
1137
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
1138
                         omap_findclk(s, ((value >> 30) & 1) ?
1139
                                 "ck_48m" : "armper_ck"));
1140
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
1141
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
1142
                         omap_findclk(s, ((value >> 29) & 1) ?
1143
                                 "ck_48m" : "armper_ck"));
1144
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
1145
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
1146
                         omap_findclk(s, ((value >> 23) & 1) ?
1147
                                 "ck_48m" : "armper_ck"));
1148
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
1149
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
1150
                         omap_findclk(s, ((value >> 12) & 1) ?
1151
                                 "ck_48m" : "armper_ck"));
1152
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
1153
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
1154
}
1155

    
1156
static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
1157
                uint32_t value)
1158
{
1159
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1160
    int offset = addr - s->pin_cfg_base;
1161
    uint32_t diff;
1162

    
1163
    switch (offset) {
1164
    case 0x00:        /* FUNC_MUX_CTRL_0 */
1165
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1166
        s->func_mux_ctrl[offset >> 2] = value;
1167
        omap_pin_funcmux0_update(s, diff, value);
1168
        return;
1169

    
1170
    case 0x04:        /* FUNC_MUX_CTRL_1 */
1171
        diff = s->func_mux_ctrl[offset >> 2] ^ value;
1172
        s->func_mux_ctrl[offset >> 2] = value;
1173
        omap_pin_funcmux1_update(s, diff, value);
1174
        return;
1175

    
1176
    case 0x08:        /* FUNC_MUX_CTRL_2 */
1177
        s->func_mux_ctrl[offset >> 2] = value;
1178
        return;
1179

    
1180
    case 0x0c:        /* COMP_MODE_CTRL_0 */
1181
        s->comp_mode_ctrl[0] = value;
1182
        s->compat1509 = (value != 0x0000eaef);
1183
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
1184
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
1185
        return;
1186

    
1187
    case 0x10:        /* FUNC_MUX_CTRL_3 */
1188
    case 0x14:        /* FUNC_MUX_CTRL_4 */
1189
    case 0x18:        /* FUNC_MUX_CTRL_5 */
1190
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
1191
    case 0x20:        /* FUNC_MUX_CTRL_7 */
1192
    case 0x24:        /* FUNC_MUX_CTRL_8 */
1193
    case 0x28:        /* FUNC_MUX_CTRL_9 */
1194
    case 0x2c:        /* FUNC_MUX_CTRL_A */
1195
    case 0x30:        /* FUNC_MUX_CTRL_B */
1196
    case 0x34:        /* FUNC_MUX_CTRL_C */
1197
    case 0x38:        /* FUNC_MUX_CTRL_D */
1198
        s->func_mux_ctrl[(offset >> 2) - 1] = value;
1199
        return;
1200

    
1201
    case 0x40:        /* PULL_DWN_CTRL_0 */
1202
    case 0x44:        /* PULL_DWN_CTRL_1 */
1203
    case 0x48:        /* PULL_DWN_CTRL_2 */
1204
    case 0x4c:        /* PULL_DWN_CTRL_3 */
1205
        s->pull_dwn_ctrl[(offset & 0xf) >> 2] = value;
1206
        return;
1207

    
1208
    case 0x50:        /* GATE_INH_CTRL_0 */
1209
        s->gate_inh_ctrl[0] = value;
1210
        return;
1211

    
1212
    case 0x60:        /* VOLTAGE_CTRL_0 */
1213
        s->voltage_ctrl[0] = value;
1214
        return;
1215

    
1216
    case 0x70:        /* TEST_DBG_CTRL_0 */
1217
        s->test_dbg_ctrl[0] = value;
1218
        return;
1219

    
1220
    case 0x80:        /* MOD_CONF_CTRL_0 */
1221
        diff = s->mod_conf_ctrl[0] ^ value;
1222
        s->mod_conf_ctrl[0] = value;
1223
        omap_pin_modconf1_update(s, diff, value);
1224
        return;
1225

    
1226
    default:
1227
        OMAP_BAD_REG(addr);
1228
    }
1229
}
1230

    
1231
static CPUReadMemoryFunc *omap_pin_cfg_readfn[] = {
1232
    omap_badwidth_read32,
1233
    omap_badwidth_read32,
1234
    omap_pin_cfg_read,
1235
};
1236

    
1237
static CPUWriteMemoryFunc *omap_pin_cfg_writefn[] = {
1238
    omap_badwidth_write32,
1239
    omap_badwidth_write32,
1240
    omap_pin_cfg_write,
1241
};
1242

    
1243
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
1244
{
1245
    /* Start in Compatibility Mode.  */
1246
    mpu->compat1509 = 1;
1247
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
1248
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
1249
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
1250
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
1251
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
1252
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
1253
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
1254
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
1255
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
1256
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
1257
}
1258

    
1259
static void omap_pin_cfg_init(target_phys_addr_t base,
1260
                struct omap_mpu_state_s *mpu)
1261
{
1262
    int iomemtype = cpu_register_io_memory(0, omap_pin_cfg_readfn,
1263
                    omap_pin_cfg_writefn, mpu);
1264

    
1265
    mpu->pin_cfg_base = base;
1266
    cpu_register_physical_memory(mpu->pin_cfg_base, 0x800, iomemtype);
1267
    omap_pin_cfg_reset(mpu);
1268
}
1269

    
1270
/* Device Identification, Die Identification */
1271
static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1272
{
1273
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1274

    
1275
    switch (addr) {
1276
    case 0xfffe1800:        /* DIE_ID_LSB */
1277
        return 0xc9581f0e;
1278
    case 0xfffe1804:        /* DIE_ID_MSB */
1279
        return 0xa8858bfa;
1280

    
1281
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
1282
        return 0x00aaaafc;
1283
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
1284
        return 0xcafeb574;
1285

    
1286
    case 0xfffed400:        /* JTAG_ID_LSB */
1287
        switch (s->mpu_model) {
1288
        case omap310:
1289
            return 0x03310315;
1290
        case omap1510:
1291
            return 0x03310115;
1292
        }
1293
        break;
1294

    
1295
    case 0xfffed404:        /* JTAG_ID_MSB */
1296
        switch (s->mpu_model) {
1297
        case omap310:
1298
            return 0xfb57402f;
1299
        case omap1510:
1300
            return 0xfb47002f;
1301
        }
1302
        break;
1303
    }
1304

    
1305
    OMAP_BAD_REG(addr);
1306
    return 0;
1307
}
1308

    
1309
static void omap_id_write(void *opaque, target_phys_addr_t addr,
1310
                uint32_t value)
1311
{
1312
    OMAP_BAD_REG(addr);
1313
}
1314

    
1315
static CPUReadMemoryFunc *omap_id_readfn[] = {
1316
    omap_badwidth_read32,
1317
    omap_badwidth_read32,
1318
    omap_id_read,
1319
};
1320

    
1321
static CPUWriteMemoryFunc *omap_id_writefn[] = {
1322
    omap_badwidth_write32,
1323
    omap_badwidth_write32,
1324
    omap_id_write,
1325
};
1326

    
1327
static void omap_id_init(struct omap_mpu_state_s *mpu)
1328
{
1329
    int iomemtype = cpu_register_io_memory(0, omap_id_readfn,
1330
                    omap_id_writefn, mpu);
1331
    cpu_register_physical_memory(0xfffe1800, 0x800, iomemtype);
1332
    cpu_register_physical_memory(0xfffed400, 0x100, iomemtype);
1333
    if (!cpu_is_omap15xx(mpu))
1334
        cpu_register_physical_memory(0xfffe2000, 0x800, iomemtype);
1335
}
1336

    
1337
/* MPUI Control (Dummy) */
1338
static uint32_t omap_mpui_read(void *opaque, target_phys_addr_t addr)
1339
{
1340
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1341
    int offset = addr - s->mpui_base;
1342

    
1343
    switch (offset) {
1344
    case 0x00:        /* CTRL */
1345
        return s->mpui_ctrl;
1346
    case 0x04:        /* DEBUG_ADDR */
1347
        return 0x01ffffff;
1348
    case 0x08:        /* DEBUG_DATA */
1349
        return 0xffffffff;
1350
    case 0x0c:        /* DEBUG_FLAG */
1351
        return 0x00000800;
1352
    case 0x10:        /* STATUS */
1353
        return 0x00000000;
1354

    
1355
    /* Not in OMAP310 */
1356
    case 0x14:        /* DSP_STATUS */
1357
    case 0x18:        /* DSP_BOOT_CONFIG */
1358
        return 0x00000000;
1359
    case 0x1c:        /* DSP_MPUI_CONFIG */
1360
        return 0x0000ffff;
1361
    }
1362

    
1363
    OMAP_BAD_REG(addr);
1364
    return 0;
1365
}
1366

    
1367
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
1368
                uint32_t value)
1369
{
1370
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1371
    int offset = addr - s->mpui_base;
1372

    
1373
    switch (offset) {
1374
    case 0x00:        /* CTRL */
1375
        s->mpui_ctrl = value & 0x007fffff;
1376
        break;
1377

    
1378
    case 0x04:        /* DEBUG_ADDR */
1379
    case 0x08:        /* DEBUG_DATA */
1380
    case 0x0c:        /* DEBUG_FLAG */
1381
    case 0x10:        /* STATUS */
1382
    /* Not in OMAP310 */
1383
    case 0x14:        /* DSP_STATUS */
1384
        OMAP_RO_REG(addr);
1385
    case 0x18:        /* DSP_BOOT_CONFIG */
1386
    case 0x1c:        /* DSP_MPUI_CONFIG */
1387
        break;
1388

    
1389
    default:
1390
        OMAP_BAD_REG(addr);
1391
    }
1392
}
1393

    
1394
static CPUReadMemoryFunc *omap_mpui_readfn[] = {
1395
    omap_badwidth_read32,
1396
    omap_badwidth_read32,
1397
    omap_mpui_read,
1398
};
1399

    
1400
static CPUWriteMemoryFunc *omap_mpui_writefn[] = {
1401
    omap_badwidth_write32,
1402
    omap_badwidth_write32,
1403
    omap_mpui_write,
1404
};
1405

    
1406
static void omap_mpui_reset(struct omap_mpu_state_s *s)
1407
{
1408
    s->mpui_ctrl = 0x0003ff1b;
1409
}
1410

    
1411
static void omap_mpui_init(target_phys_addr_t base,
1412
                struct omap_mpu_state_s *mpu)
1413
{
1414
    int iomemtype = cpu_register_io_memory(0, omap_mpui_readfn,
1415
                    omap_mpui_writefn, mpu);
1416

    
1417
    mpu->mpui_base = base;
1418
    cpu_register_physical_memory(mpu->mpui_base, 0x100, iomemtype);
1419

    
1420
    omap_mpui_reset(mpu);
1421
}
1422

    
1423
/* TIPB Bridges */
1424
struct omap_tipb_bridge_s {
1425
    target_phys_addr_t base;
1426
    qemu_irq abort;
1427

    
1428
    int width_intr;
1429
    uint16_t control;
1430
    uint16_t alloc;
1431
    uint16_t buffer;
1432
    uint16_t enh_control;
1433
};
1434

    
1435
static uint32_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr)
1436
{
1437
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1438
    int offset = addr - s->base;
1439

    
1440
    switch (offset) {
1441
    case 0x00:        /* TIPB_CNTL */
1442
        return s->control;
1443
    case 0x04:        /* TIPB_BUS_ALLOC */
1444
        return s->alloc;
1445
    case 0x08:        /* MPU_TIPB_CNTL */
1446
        return s->buffer;
1447
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1448
        return s->enh_control;
1449
    case 0x10:        /* ADDRESS_DBG */
1450
    case 0x14:        /* DATA_DEBUG_LOW */
1451
    case 0x18:        /* DATA_DEBUG_HIGH */
1452
        return 0xffff;
1453
    case 0x1c:        /* DEBUG_CNTR_SIG */
1454
        return 0x00f8;
1455
    }
1456

    
1457
    OMAP_BAD_REG(addr);
1458
    return 0;
1459
}
1460

    
1461
static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
1462
                uint32_t value)
1463
{
1464
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1465
    int offset = addr - s->base;
1466

    
1467
    switch (offset) {
1468
    case 0x00:        /* TIPB_CNTL */
1469
        s->control = value & 0xffff;
1470
        break;
1471

    
1472
    case 0x04:        /* TIPB_BUS_ALLOC */
1473
        s->alloc = value & 0x003f;
1474
        break;
1475

    
1476
    case 0x08:        /* MPU_TIPB_CNTL */
1477
        s->buffer = value & 0x0003;
1478
        break;
1479

    
1480
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1481
        s->width_intr = !(value & 2);
1482
        s->enh_control = value & 0x000f;
1483
        break;
1484

    
1485
    case 0x10:        /* ADDRESS_DBG */
1486
    case 0x14:        /* DATA_DEBUG_LOW */
1487
    case 0x18:        /* DATA_DEBUG_HIGH */
1488
    case 0x1c:        /* DEBUG_CNTR_SIG */
1489
        OMAP_RO_REG(addr);
1490
        break;
1491

    
1492
    default:
1493
        OMAP_BAD_REG(addr);
1494
    }
1495
}
1496

    
1497
static CPUReadMemoryFunc *omap_tipb_bridge_readfn[] = {
1498
    omap_badwidth_read16,
1499
    omap_tipb_bridge_read,
1500
    omap_tipb_bridge_read,
1501
};
1502

    
1503
static CPUWriteMemoryFunc *omap_tipb_bridge_writefn[] = {
1504
    omap_badwidth_write16,
1505
    omap_tipb_bridge_write,
1506
    omap_tipb_bridge_write,
1507
};
1508

    
1509
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1510
{
1511
    s->control = 0xffff;
1512
    s->alloc = 0x0009;
1513
    s->buffer = 0x0000;
1514
    s->enh_control = 0x000f;
1515
}
1516

    
1517
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
1518
                qemu_irq abort_irq, omap_clk clk)
1519
{
1520
    int iomemtype;
1521
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
1522
            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
1523

    
1524
    s->abort = abort_irq;
1525
    s->base = base;
1526
    omap_tipb_bridge_reset(s);
1527

    
1528
    iomemtype = cpu_register_io_memory(0, omap_tipb_bridge_readfn,
1529
                    omap_tipb_bridge_writefn, s);
1530
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1531

    
1532
    return s;
1533
}
1534

    
1535
/* Dummy Traffic Controller's Memory Interface */
1536
static uint32_t omap_tcmi_read(void *opaque, target_phys_addr_t addr)
1537
{
1538
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1539
    int offset = addr - s->tcmi_base;
1540
    uint32_t ret;
1541

    
1542
    switch (offset) {
1543
    case 0x00:        /* IMIF_PRIO */
1544
    case 0x04:        /* EMIFS_PRIO */
1545
    case 0x08:        /* EMIFF_PRIO */
1546
    case 0x0c:        /* EMIFS_CONFIG */
1547
    case 0x10:        /* EMIFS_CS0_CONFIG */
1548
    case 0x14:        /* EMIFS_CS1_CONFIG */
1549
    case 0x18:        /* EMIFS_CS2_CONFIG */
1550
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1551
    case 0x24:        /* EMIFF_MRS */
1552
    case 0x28:        /* TIMEOUT1 */
1553
    case 0x2c:        /* TIMEOUT2 */
1554
    case 0x30:        /* TIMEOUT3 */
1555
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1556
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1557
        return s->tcmi_regs[offset >> 2];
1558

    
1559
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1560
        ret = s->tcmi_regs[offset >> 2];
1561
        s->tcmi_regs[offset >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1562
        /* XXX: We can try using the VGA_DIRTY flag for this */
1563
        return ret;
1564
    }
1565

    
1566
    OMAP_BAD_REG(addr);
1567
    return 0;
1568
}
1569

    
1570
static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
1571
                uint32_t value)
1572
{
1573
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1574
    int offset = addr - s->tcmi_base;
1575

    
1576
    switch (offset) {
1577
    case 0x00:        /* IMIF_PRIO */
1578
    case 0x04:        /* EMIFS_PRIO */
1579
    case 0x08:        /* EMIFF_PRIO */
1580
    case 0x10:        /* EMIFS_CS0_CONFIG */
1581
    case 0x14:        /* EMIFS_CS1_CONFIG */
1582
    case 0x18:        /* EMIFS_CS2_CONFIG */
1583
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1584
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1585
    case 0x24:        /* EMIFF_MRS */
1586
    case 0x28:        /* TIMEOUT1 */
1587
    case 0x2c:        /* TIMEOUT2 */
1588
    case 0x30:        /* TIMEOUT3 */
1589
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1590
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1591
        s->tcmi_regs[offset >> 2] = value;
1592
        break;
1593
    case 0x0c:        /* EMIFS_CONFIG */
1594
        s->tcmi_regs[offset >> 2] = (value & 0xf) | (1 << 4);
1595
        break;
1596

    
1597
    default:
1598
        OMAP_BAD_REG(addr);
1599
    }
1600
}
1601

    
1602
static CPUReadMemoryFunc *omap_tcmi_readfn[] = {
1603
    omap_badwidth_read32,
1604
    omap_badwidth_read32,
1605
    omap_tcmi_read,
1606
};
1607

    
1608
static CPUWriteMemoryFunc *omap_tcmi_writefn[] = {
1609
    omap_badwidth_write32,
1610
    omap_badwidth_write32,
1611
    omap_tcmi_write,
1612
};
1613

    
1614
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1615
{
1616
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1617
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1618
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1619
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1620
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1621
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1622
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1623
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1624
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1625
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1626
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1627
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1628
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1629
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1630
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1631
}
1632

    
1633
static void omap_tcmi_init(target_phys_addr_t base,
1634
                struct omap_mpu_state_s *mpu)
1635
{
1636
    int iomemtype = cpu_register_io_memory(0, omap_tcmi_readfn,
1637
                    omap_tcmi_writefn, mpu);
1638

    
1639
    mpu->tcmi_base = base;
1640
    cpu_register_physical_memory(mpu->tcmi_base, 0x100, iomemtype);
1641
    omap_tcmi_reset(mpu);
1642
}
1643

    
1644
/* Digital phase-locked loops control */
1645
static uint32_t omap_dpll_read(void *opaque, target_phys_addr_t addr)
1646
{
1647
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1648
    int offset = addr - s->base;
1649

    
1650
    if (offset == 0x00)        /* CTL_REG */
1651
        return s->mode;
1652

    
1653
    OMAP_BAD_REG(addr);
1654
    return 0;
1655
}
1656

    
1657
static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
1658
                uint32_t value)
1659
{
1660
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1661
    uint16_t diff;
1662
    int offset = addr - s->base;
1663
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1664
    int div, mult;
1665

    
1666
    if (offset == 0x00) {        /* CTL_REG */
1667
        /* See omap_ulpd_pm_write() too */
1668
        diff = s->mode & value;
1669
        s->mode = value & 0x2fff;
1670
        if (diff & (0x3ff << 2)) {
1671
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1672
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1673
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1674
            } else {
1675
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1676
                mult = 1;
1677
            }
1678
            omap_clk_setrate(s->dpll, div, mult);
1679
        }
1680

    
1681
        /* Enter the desired mode.  */
1682
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1683

    
1684
        /* Act as if the lock is restored.  */
1685
        s->mode |= 2;
1686
    } else {
1687
        OMAP_BAD_REG(addr);
1688
    }
1689
}
1690

    
1691
static CPUReadMemoryFunc *omap_dpll_readfn[] = {
1692
    omap_badwidth_read16,
1693
    omap_dpll_read,
1694
    omap_badwidth_read16,
1695
};
1696

    
1697
static CPUWriteMemoryFunc *omap_dpll_writefn[] = {
1698
    omap_badwidth_write16,
1699
    omap_dpll_write,
1700
    omap_badwidth_write16,
1701
};
1702

    
1703
static void omap_dpll_reset(struct dpll_ctl_s *s)
1704
{
1705
    s->mode = 0x2002;
1706
    omap_clk_setrate(s->dpll, 1, 1);
1707
}
1708

    
1709
static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
1710
                omap_clk clk)
1711
{
1712
    int iomemtype = cpu_register_io_memory(0, omap_dpll_readfn,
1713
                    omap_dpll_writefn, s);
1714

    
1715
    s->base = base;
1716
    s->dpll = clk;
1717
    omap_dpll_reset(s);
1718

    
1719
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
1720
}
1721

    
1722
/* UARTs */
1723
struct omap_uart_s {
1724
    SerialState *serial; /* TODO */
1725
};
1726

    
1727
static void omap_uart_reset(struct omap_uart_s *s)
1728
{
1729
}
1730

    
1731
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
1732
                qemu_irq irq, omap_clk clk, CharDriverState *chr)
1733
{
1734
    struct omap_uart_s *s = (struct omap_uart_s *)
1735
            qemu_mallocz(sizeof(struct omap_uart_s));
1736
    if (chr)
1737
        s->serial = serial_mm_init(base, 2, irq, chr, 1);
1738
    return s;
1739
}
1740

    
1741
/* MPU Clock/Reset/Power Mode Control */
1742
static uint32_t omap_clkm_read(void *opaque, target_phys_addr_t addr)
1743
{
1744
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1745
    int offset = addr - s->clkm.mpu_base;
1746

    
1747
    switch (offset) {
1748
    case 0x00:        /* ARM_CKCTL */
1749
        return s->clkm.arm_ckctl;
1750

    
1751
    case 0x04:        /* ARM_IDLECT1 */
1752
        return s->clkm.arm_idlect1;
1753

    
1754
    case 0x08:        /* ARM_IDLECT2 */
1755
        return s->clkm.arm_idlect2;
1756

    
1757
    case 0x0c:        /* ARM_EWUPCT */
1758
        return s->clkm.arm_ewupct;
1759

    
1760
    case 0x10:        /* ARM_RSTCT1 */
1761
        return s->clkm.arm_rstct1;
1762

    
1763
    case 0x14:        /* ARM_RSTCT2 */
1764
        return s->clkm.arm_rstct2;
1765

    
1766
    case 0x18:        /* ARM_SYSST */
1767
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1768

    
1769
    case 0x1c:        /* ARM_CKOUT1 */
1770
        return s->clkm.arm_ckout1;
1771

    
1772
    case 0x20:        /* ARM_CKOUT2 */
1773
        break;
1774
    }
1775

    
1776
    OMAP_BAD_REG(addr);
1777
    return 0;
1778
}
1779

    
1780
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1781
                uint16_t diff, uint16_t value)
1782
{
1783
    omap_clk clk;
1784

    
1785
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
1786
        if (value & (1 << 14))
1787
            /* Reserved */;
1788
        else {
1789
            clk = omap_findclk(s, "arminth_ck");
1790
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1791
        }
1792
    }
1793
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
1794
        clk = omap_findclk(s, "armtim_ck");
1795
        if (value & (1 << 12))
1796
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
1797
        else
1798
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1799
    }
1800
    /* XXX: en_dspck */
1801
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
1802
        clk = omap_findclk(s, "dspmmu_ck");
1803
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
1804
    }
1805
    if (diff & (3 << 8)) {                                /* TCDIV */
1806
        clk = omap_findclk(s, "tc_ck");
1807
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
1808
    }
1809
    if (diff & (3 << 6)) {                                /* DSPDIV */
1810
        clk = omap_findclk(s, "dsp_ck");
1811
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
1812
    }
1813
    if (diff & (3 << 4)) {                                /* ARMDIV */
1814
        clk = omap_findclk(s, "arm_ck");
1815
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
1816
    }
1817
    if (diff & (3 << 2)) {                                /* LCDDIV */
1818
        clk = omap_findclk(s, "lcd_ck");
1819
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
1820
    }
1821
    if (diff & (3 << 0)) {                                /* PERDIV */
1822
        clk = omap_findclk(s, "armper_ck");
1823
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
1824
    }
1825
}
1826

    
1827
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1828
                uint16_t diff, uint16_t value)
1829
{
1830
    omap_clk clk;
1831

    
1832
    if (value & (1 << 11))                                /* SETARM_IDLE */
1833
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
1834
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
1835
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
1836

    
1837
#define SET_CANIDLE(clock, bit)                                \
1838
    if (diff & (1 << bit)) {                                \
1839
        clk = omap_findclk(s, clock);                        \
1840
        omap_clk_canidle(clk, (value >> bit) & 1);        \
1841
    }
1842
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
1843
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
1844
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
1845
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
1846
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
1847
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
1848
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
1849
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
1850
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
1851
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
1852
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
1853
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
1854
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
1855
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
1856
}
1857

    
1858
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1859
                uint16_t diff, uint16_t value)
1860
{
1861
    omap_clk clk;
1862

    
1863
#define SET_ONOFF(clock, bit)                                \
1864
    if (diff & (1 << bit)) {                                \
1865
        clk = omap_findclk(s, clock);                        \
1866
        omap_clk_onoff(clk, (value >> bit) & 1);        \
1867
    }
1868
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
1869
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
1870
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
1871
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
1872
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
1873
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
1874
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
1875
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
1876
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
1877
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
1878
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
1879
}
1880

    
1881
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1882
                uint16_t diff, uint16_t value)
1883
{
1884
    omap_clk clk;
1885

    
1886
    if (diff & (3 << 4)) {                                /* TCLKOUT */
1887
        clk = omap_findclk(s, "tclk_out");
1888
        switch ((value >> 4) & 3) {
1889
        case 1:
1890
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
1891
            omap_clk_onoff(clk, 1);
1892
            break;
1893
        case 2:
1894
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1895
            omap_clk_onoff(clk, 1);
1896
            break;
1897
        default:
1898
            omap_clk_onoff(clk, 0);
1899
        }
1900
    }
1901
    if (diff & (3 << 2)) {                                /* DCLKOUT */
1902
        clk = omap_findclk(s, "dclk_out");
1903
        switch ((value >> 2) & 3) {
1904
        case 0:
1905
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
1906
            break;
1907
        case 1:
1908
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
1909
            break;
1910
        case 2:
1911
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
1912
            break;
1913
        case 3:
1914
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1915
            break;
1916
        }
1917
    }
1918
    if (diff & (3 << 0)) {                                /* ACLKOUT */
1919
        clk = omap_findclk(s, "aclk_out");
1920
        switch ((value >> 0) & 3) {
1921
        case 1:
1922
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1923
            omap_clk_onoff(clk, 1);
1924
            break;
1925
        case 2:
1926
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
1927
            omap_clk_onoff(clk, 1);
1928
            break;
1929
        case 3:
1930
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1931
            omap_clk_onoff(clk, 1);
1932
            break;
1933
        default:
1934
            omap_clk_onoff(clk, 0);
1935
        }
1936
    }
1937
}
1938

    
1939
static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
1940
                uint32_t value)
1941
{
1942
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1943
    int offset = addr - s->clkm.mpu_base;
1944
    uint16_t diff;
1945
    omap_clk clk;
1946
    static const char *clkschemename[8] = {
1947
        "fully synchronous", "fully asynchronous", "synchronous scalable",
1948
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
1949
    };
1950

    
1951
    switch (offset) {
1952
    case 0x00:        /* ARM_CKCTL */
1953
        diff = s->clkm.arm_ckctl ^ value;
1954
        s->clkm.arm_ckctl = value & 0x7fff;
1955
        omap_clkm_ckctl_update(s, diff, value);
1956
        return;
1957

    
1958
    case 0x04:        /* ARM_IDLECT1 */
1959
        diff = s->clkm.arm_idlect1 ^ value;
1960
        s->clkm.arm_idlect1 = value & 0x0fff;
1961
        omap_clkm_idlect1_update(s, diff, value);
1962
        return;
1963

    
1964
    case 0x08:        /* ARM_IDLECT2 */
1965
        diff = s->clkm.arm_idlect2 ^ value;
1966
        s->clkm.arm_idlect2 = value & 0x07ff;
1967
        omap_clkm_idlect2_update(s, diff, value);
1968
        return;
1969

    
1970
    case 0x0c:        /* ARM_EWUPCT */
1971
        diff = s->clkm.arm_ewupct ^ value;
1972
        s->clkm.arm_ewupct = value & 0x003f;
1973
        return;
1974

    
1975
    case 0x10:        /* ARM_RSTCT1 */
1976
        diff = s->clkm.arm_rstct1 ^ value;
1977
        s->clkm.arm_rstct1 = value & 0x0007;
1978
        if (value & 9) {
1979
            qemu_system_reset_request();
1980
            s->clkm.cold_start = 0xa;
1981
        }
1982
        if (diff & ~value & 4) {                                /* DSP_RST */
1983
            omap_mpui_reset(s);
1984
            omap_tipb_bridge_reset(s->private_tipb);
1985
            omap_tipb_bridge_reset(s->public_tipb);
1986
        }
1987
        if (diff & 2) {                                                /* DSP_EN */
1988
            clk = omap_findclk(s, "dsp_ck");
1989
            omap_clk_canidle(clk, (~value >> 1) & 1);
1990
        }
1991
        return;
1992

    
1993
    case 0x14:        /* ARM_RSTCT2 */
1994
        s->clkm.arm_rstct2 = value & 0x0001;
1995
        return;
1996

    
1997
    case 0x18:        /* ARM_SYSST */
1998
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
1999
            s->clkm.clocking_scheme = (value >> 11) & 7;
2000
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
2001
                            clkschemename[s->clkm.clocking_scheme]);
2002
        }
2003
        s->clkm.cold_start &= value & 0x3f;
2004
        return;
2005

    
2006
    case 0x1c:        /* ARM_CKOUT1 */
2007
        diff = s->clkm.arm_ckout1 ^ value;
2008
        s->clkm.arm_ckout1 = value & 0x003f;
2009
        omap_clkm_ckout1_update(s, diff, value);
2010
        return;
2011

    
2012
    case 0x20:        /* ARM_CKOUT2 */
2013
    default:
2014
        OMAP_BAD_REG(addr);
2015
    }
2016
}
2017

    
2018
static CPUReadMemoryFunc *omap_clkm_readfn[] = {
2019
    omap_badwidth_read16,
2020
    omap_clkm_read,
2021
    omap_badwidth_read16,
2022
};
2023

    
2024
static CPUWriteMemoryFunc *omap_clkm_writefn[] = {
2025
    omap_badwidth_write16,
2026
    omap_clkm_write,
2027
    omap_badwidth_write16,
2028
};
2029

    
2030
static uint32_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr)
2031
{
2032
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2033
    int offset = addr - s->clkm.dsp_base;
2034

    
2035
    switch (offset) {
2036
    case 0x04:        /* DSP_IDLECT1 */
2037
        return s->clkm.dsp_idlect1;
2038

    
2039
    case 0x08:        /* DSP_IDLECT2 */
2040
        return s->clkm.dsp_idlect2;
2041

    
2042
    case 0x14:        /* DSP_RSTCT2 */
2043
        return s->clkm.dsp_rstct2;
2044

    
2045
    case 0x18:        /* DSP_SYSST */
2046
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
2047
                (s->env->halted << 6);        /* Quite useless... */
2048
    }
2049

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

    
2054
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
2055
                uint16_t diff, uint16_t value)
2056
{
2057
    omap_clk clk;
2058

    
2059
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
2060
}
2061

    
2062
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
2063
                uint16_t diff, uint16_t value)
2064
{
2065
    omap_clk clk;
2066

    
2067
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
2068
}
2069

    
2070
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
2071
                uint32_t value)
2072
{
2073
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2074
    int offset = addr - s->clkm.dsp_base;
2075
    uint16_t diff;
2076

    
2077
    switch (offset) {
2078
    case 0x04:        /* DSP_IDLECT1 */
2079
        diff = s->clkm.dsp_idlect1 ^ value;
2080
        s->clkm.dsp_idlect1 = value & 0x01f7;
2081
        omap_clkdsp_idlect1_update(s, diff, value);
2082
        break;
2083

    
2084
    case 0x08:        /* DSP_IDLECT2 */
2085
        s->clkm.dsp_idlect2 = value & 0x0037;
2086
        diff = s->clkm.dsp_idlect1 ^ value;
2087
        omap_clkdsp_idlect2_update(s, diff, value);
2088
        break;
2089

    
2090
    case 0x14:        /* DSP_RSTCT2 */
2091
        s->clkm.dsp_rstct2 = value & 0x0001;
2092
        break;
2093

    
2094
    case 0x18:        /* DSP_SYSST */
2095
        s->clkm.cold_start &= value & 0x3f;
2096
        break;
2097

    
2098
    default:
2099
        OMAP_BAD_REG(addr);
2100
    }
2101
}
2102

    
2103
static CPUReadMemoryFunc *omap_clkdsp_readfn[] = {
2104
    omap_badwidth_read16,
2105
    omap_clkdsp_read,
2106
    omap_badwidth_read16,
2107
};
2108

    
2109
static CPUWriteMemoryFunc *omap_clkdsp_writefn[] = {
2110
    omap_badwidth_write16,
2111
    omap_clkdsp_write,
2112
    omap_badwidth_write16,
2113
};
2114

    
2115
static void omap_clkm_reset(struct omap_mpu_state_s *s)
2116
{
2117
    if (s->wdt && s->wdt->reset)
2118
        s->clkm.cold_start = 0x6;
2119
    s->clkm.clocking_scheme = 0;
2120
    omap_clkm_ckctl_update(s, ~0, 0x3000);
2121
    s->clkm.arm_ckctl = 0x3000;
2122
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
2123
    s->clkm.arm_idlect1 = 0x0400;
2124
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
2125
    s->clkm.arm_idlect2 = 0x0100;
2126
    s->clkm.arm_ewupct = 0x003f;
2127
    s->clkm.arm_rstct1 = 0x0000;
2128
    s->clkm.arm_rstct2 = 0x0000;
2129
    s->clkm.arm_ckout1 = 0x0015;
2130
    s->clkm.dpll1_mode = 0x2002;
2131
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
2132
    s->clkm.dsp_idlect1 = 0x0040;
2133
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
2134
    s->clkm.dsp_idlect2 = 0x0000;
2135
    s->clkm.dsp_rstct2 = 0x0000;
2136
}
2137

    
2138
static void omap_clkm_init(target_phys_addr_t mpu_base,
2139
                target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
2140
{
2141
    int iomemtype[2] = {
2142
        cpu_register_io_memory(0, omap_clkm_readfn, omap_clkm_writefn, s),
2143
        cpu_register_io_memory(0, omap_clkdsp_readfn, omap_clkdsp_writefn, s),
2144
    };
2145

    
2146
    s->clkm.mpu_base = mpu_base;
2147
    s->clkm.dsp_base = dsp_base;
2148
    s->clkm.arm_idlect1 = 0x03ff;
2149
    s->clkm.arm_idlect2 = 0x0100;
2150
    s->clkm.dsp_idlect1 = 0x0002;
2151
    omap_clkm_reset(s);
2152
    s->clkm.cold_start = 0x3a;
2153

    
2154
    cpu_register_physical_memory(s->clkm.mpu_base, 0x100, iomemtype[0]);
2155
    cpu_register_physical_memory(s->clkm.dsp_base, 0x1000, iomemtype[1]);
2156
}
2157

    
2158
/* MPU I/O */
2159
struct omap_mpuio_s {
2160
    target_phys_addr_t base;
2161
    qemu_irq irq;
2162
    qemu_irq kbd_irq;
2163
    qemu_irq *in;
2164
    qemu_irq handler[16];
2165
    qemu_irq wakeup;
2166

    
2167
    uint16_t inputs;
2168
    uint16_t outputs;
2169
    uint16_t dir;
2170
    uint16_t edge;
2171
    uint16_t mask;
2172
    uint16_t ints;
2173

    
2174
    uint16_t debounce;
2175
    uint16_t latch;
2176
    uint8_t event;
2177

    
2178
    uint8_t buttons[5];
2179
    uint8_t row_latch;
2180
    uint8_t cols;
2181
    int kbd_mask;
2182
    int clk;
2183
};
2184

    
2185
static void omap_mpuio_set(void *opaque, int line, int level)
2186
{
2187
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2188
    uint16_t prev = s->inputs;
2189

    
2190
    if (level)
2191
        s->inputs |= 1 << line;
2192
    else
2193
        s->inputs &= ~(1 << line);
2194

    
2195
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
2196
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
2197
            s->ints |= 1 << line;
2198
            qemu_irq_raise(s->irq);
2199
            /* TODO: wakeup */
2200
        }
2201
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
2202
                (s->event >> 1) == line)        /* PIN_SELECT */
2203
            s->latch = s->inputs;
2204
    }
2205
}
2206

    
2207
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
2208
{
2209
    int i;
2210
    uint8_t *row, rows = 0, cols = ~s->cols;
2211

    
2212
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
2213
        if (*row & cols)
2214
            rows |= i;
2215

    
2216
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
2217
    s->row_latch = ~rows;
2218
}
2219

    
2220
static uint32_t omap_mpuio_read(void *opaque, target_phys_addr_t addr)
2221
{
2222
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2223
    int offset = addr & OMAP_MPUI_REG_MASK;
2224
    uint16_t ret;
2225

    
2226
    switch (offset) {
2227
    case 0x00:        /* INPUT_LATCH */
2228
        return s->inputs;
2229

    
2230
    case 0x04:        /* OUTPUT_REG */
2231
        return s->outputs;
2232

    
2233
    case 0x08:        /* IO_CNTL */
2234
        return s->dir;
2235

    
2236
    case 0x10:        /* KBR_LATCH */
2237
        return s->row_latch;
2238

    
2239
    case 0x14:        /* KBC_REG */
2240
        return s->cols;
2241

    
2242
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2243
        return s->event;
2244

    
2245
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2246
        return s->edge;
2247

    
2248
    case 0x20:        /* KBD_INT */
2249
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
2250

    
2251
    case 0x24:        /* GPIO_INT */
2252
        ret = s->ints;
2253
        s->ints &= s->mask;
2254
        if (ret)
2255
            qemu_irq_lower(s->irq);
2256
        return ret;
2257

    
2258
    case 0x28:        /* KBD_MASKIT */
2259
        return s->kbd_mask;
2260

    
2261
    case 0x2c:        /* GPIO_MASKIT */
2262
        return s->mask;
2263

    
2264
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2265
        return s->debounce;
2266

    
2267
    case 0x34:        /* GPIO_LATCH_REG */
2268
        return s->latch;
2269
    }
2270

    
2271
    OMAP_BAD_REG(addr);
2272
    return 0;
2273
}
2274

    
2275
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
2276
                uint32_t value)
2277
{
2278
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2279
    int offset = addr & OMAP_MPUI_REG_MASK;
2280
    uint16_t diff;
2281
    int ln;
2282

    
2283
    switch (offset) {
2284
    case 0x04:        /* OUTPUT_REG */
2285
        diff = (s->outputs ^ value) & ~s->dir;
2286
        s->outputs = value;
2287
        while ((ln = ffs(diff))) {
2288
            ln --;
2289
            if (s->handler[ln])
2290
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2291
            diff &= ~(1 << ln);
2292
        }
2293
        break;
2294

    
2295
    case 0x08:        /* IO_CNTL */
2296
        diff = s->outputs & (s->dir ^ value);
2297
        s->dir = value;
2298

    
2299
        value = s->outputs & ~s->dir;
2300
        while ((ln = ffs(diff))) {
2301
            ln --;
2302
            if (s->handler[ln])
2303
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2304
            diff &= ~(1 << ln);
2305
        }
2306
        break;
2307

    
2308
    case 0x14:        /* KBC_REG */
2309
        s->cols = value;
2310
        omap_mpuio_kbd_update(s);
2311
        break;
2312

    
2313
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2314
        s->event = value & 0x1f;
2315
        break;
2316

    
2317
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2318
        s->edge = value;
2319
        break;
2320

    
2321
    case 0x28:        /* KBD_MASKIT */
2322
        s->kbd_mask = value & 1;
2323
        omap_mpuio_kbd_update(s);
2324
        break;
2325

    
2326
    case 0x2c:        /* GPIO_MASKIT */
2327
        s->mask = value;
2328
        break;
2329

    
2330
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2331
        s->debounce = value & 0x1ff;
2332
        break;
2333

    
2334
    case 0x00:        /* INPUT_LATCH */
2335
    case 0x10:        /* KBR_LATCH */
2336
    case 0x20:        /* KBD_INT */
2337
    case 0x24:        /* GPIO_INT */
2338
    case 0x34:        /* GPIO_LATCH_REG */
2339
        OMAP_RO_REG(addr);
2340
        return;
2341

    
2342
    default:
2343
        OMAP_BAD_REG(addr);
2344
        return;
2345
    }
2346
}
2347

    
2348
static CPUReadMemoryFunc *omap_mpuio_readfn[] = {
2349
    omap_badwidth_read16,
2350
    omap_mpuio_read,
2351
    omap_badwidth_read16,
2352
};
2353

    
2354
static CPUWriteMemoryFunc *omap_mpuio_writefn[] = {
2355
    omap_badwidth_write16,
2356
    omap_mpuio_write,
2357
    omap_badwidth_write16,
2358
};
2359

    
2360
static void omap_mpuio_reset(struct omap_mpuio_s *s)
2361
{
2362
    s->inputs = 0;
2363
    s->outputs = 0;
2364
    s->dir = ~0;
2365
    s->event = 0;
2366
    s->edge = 0;
2367
    s->kbd_mask = 0;
2368
    s->mask = 0;
2369
    s->debounce = 0;
2370
    s->latch = 0;
2371
    s->ints = 0;
2372
    s->row_latch = 0x1f;
2373
    s->clk = 1;
2374
}
2375

    
2376
static void omap_mpuio_onoff(void *opaque, int line, int on)
2377
{
2378
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2379

    
2380
    s->clk = on;
2381
    if (on)
2382
        omap_mpuio_kbd_update(s);
2383
}
2384

    
2385
struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
2386
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2387
                omap_clk clk)
2388
{
2389
    int iomemtype;
2390
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2391
            qemu_mallocz(sizeof(struct omap_mpuio_s));
2392

    
2393
    s->base = base;
2394
    s->irq = gpio_int;
2395
    s->kbd_irq = kbd_int;
2396
    s->wakeup = wakeup;
2397
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2398
    omap_mpuio_reset(s);
2399

    
2400
    iomemtype = cpu_register_io_memory(0, omap_mpuio_readfn,
2401
                    omap_mpuio_writefn, s);
2402
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
2403

    
2404
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2405

    
2406
    return s;
2407
}
2408

    
2409
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2410
{
2411
    return s->in;
2412
}
2413

    
2414
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2415
{
2416
    if (line >= 16 || line < 0)
2417
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
2418
    s->handler[line] = handler;
2419
}
2420

    
2421
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2422
{
2423
    if (row >= 5 || row < 0)
2424
        cpu_abort(cpu_single_env, "%s: No key %i-%i\n",
2425
                        __FUNCTION__, col, row);
2426

    
2427
    if (down)
2428
        s->buttons[row] |= 1 << col;
2429
    else
2430
        s->buttons[row] &= ~(1 << col);
2431

    
2432
    omap_mpuio_kbd_update(s);
2433
}
2434

    
2435
/* General-Purpose I/O */
2436
struct omap_gpio_s {
2437
    target_phys_addr_t base;
2438
    qemu_irq irq;
2439
    qemu_irq *in;
2440
    qemu_irq handler[16];
2441

    
2442
    uint16_t inputs;
2443
    uint16_t outputs;
2444
    uint16_t dir;
2445
    uint16_t edge;
2446
    uint16_t mask;
2447
    uint16_t ints;
2448
    uint16_t pins;
2449
};
2450

    
2451
static void omap_gpio_set(void *opaque, int line, int level)
2452
{
2453
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2454
    uint16_t prev = s->inputs;
2455

    
2456
    if (level)
2457
        s->inputs |= 1 << line;
2458
    else
2459
        s->inputs &= ~(1 << line);
2460

    
2461
    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
2462
                    (1 << line) & s->dir & ~s->mask) {
2463
        s->ints |= 1 << line;
2464
        qemu_irq_raise(s->irq);
2465
    }
2466
}
2467

    
2468
static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
2469
{
2470
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2471
    int offset = addr & OMAP_MPUI_REG_MASK;
2472

    
2473
    switch (offset) {
2474
    case 0x00:        /* DATA_INPUT */
2475
        return s->inputs & s->pins;
2476

    
2477
    case 0x04:        /* DATA_OUTPUT */
2478
        return s->outputs;
2479

    
2480
    case 0x08:        /* DIRECTION_CONTROL */
2481
        return s->dir;
2482

    
2483
    case 0x0c:        /* INTERRUPT_CONTROL */
2484
        return s->edge;
2485

    
2486
    case 0x10:        /* INTERRUPT_MASK */
2487
        return s->mask;
2488

    
2489
    case 0x14:        /* INTERRUPT_STATUS */
2490
        return s->ints;
2491

    
2492
    case 0x18:        /* PIN_CONTROL (not in OMAP310) */
2493
        OMAP_BAD_REG(addr);
2494
        return s->pins;
2495
    }
2496

    
2497
    OMAP_BAD_REG(addr);
2498
    return 0;
2499
}
2500

    
2501
static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
2502
                uint32_t value)
2503
{
2504
    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
2505
    int offset = addr & OMAP_MPUI_REG_MASK;
2506
    uint16_t diff;
2507
    int ln;
2508

    
2509
    switch (offset) {
2510
    case 0x00:        /* DATA_INPUT */
2511
        OMAP_RO_REG(addr);
2512
        return;
2513

    
2514
    case 0x04:        /* DATA_OUTPUT */
2515
        diff = (s->outputs ^ value) & ~s->dir;
2516
        s->outputs = value;
2517
        while ((ln = ffs(diff))) {
2518
            ln --;
2519
            if (s->handler[ln])
2520
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2521
            diff &= ~(1 << ln);
2522
        }
2523
        break;
2524

    
2525
    case 0x08:        /* DIRECTION_CONTROL */
2526
        diff = s->outputs & (s->dir ^ value);
2527
        s->dir = value;
2528

    
2529
        value = s->outputs & ~s->dir;
2530
        while ((ln = ffs(diff))) {
2531
            ln --;
2532
            if (s->handler[ln])
2533
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2534
            diff &= ~(1 << ln);
2535
        }
2536
        break;
2537

    
2538
    case 0x0c:        /* INTERRUPT_CONTROL */
2539
        s->edge = value;
2540
        break;
2541

    
2542
    case 0x10:        /* INTERRUPT_MASK */
2543
        s->mask = value;
2544
        break;
2545

    
2546
    case 0x14:        /* INTERRUPT_STATUS */
2547
        s->ints &= ~value;
2548
        if (!s->ints)
2549
            qemu_irq_lower(s->irq);
2550
        break;
2551

    
2552
    case 0x18:        /* PIN_CONTROL (not in OMAP310 TRM) */
2553
        OMAP_BAD_REG(addr);
2554
        s->pins = value;
2555
        break;
2556

    
2557
    default:
2558
        OMAP_BAD_REG(addr);
2559
        return;
2560
    }
2561
}
2562

    
2563
/* *Some* sources say the memory region is 32-bit.  */
2564
static CPUReadMemoryFunc *omap_gpio_readfn[] = {
2565
    omap_badwidth_read16,
2566
    omap_gpio_read,
2567
    omap_badwidth_read16,
2568
};
2569

    
2570
static CPUWriteMemoryFunc *omap_gpio_writefn[] = {
2571
    omap_badwidth_write16,
2572
    omap_gpio_write,
2573
    omap_badwidth_write16,
2574
};
2575

    
2576
static void omap_gpio_reset(struct omap_gpio_s *s)
2577
{
2578
    s->inputs = 0;
2579
    s->outputs = ~0;
2580
    s->dir = ~0;
2581
    s->edge = ~0;
2582
    s->mask = ~0;
2583
    s->ints = 0;
2584
    s->pins = ~0;
2585
}
2586

    
2587
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
2588
                qemu_irq irq, omap_clk clk)
2589
{
2590
    int iomemtype;
2591
    struct omap_gpio_s *s = (struct omap_gpio_s *)
2592
            qemu_mallocz(sizeof(struct omap_gpio_s));
2593

    
2594
    s->base = base;
2595
    s->irq = irq;
2596
    s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
2597
    omap_gpio_reset(s);
2598

    
2599
    iomemtype = cpu_register_io_memory(0, omap_gpio_readfn,
2600
                    omap_gpio_writefn, s);
2601
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
2602

    
2603
    return s;
2604
}
2605

    
2606
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
2607
{
2608
    return s->in;
2609
}
2610

    
2611
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
2612
{
2613
    if (line >= 16 || line < 0)
2614
        cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
2615
    s->handler[line] = handler;
2616
}
2617

    
2618
/* MicroWire Interface */
2619
struct omap_uwire_s {
2620
    target_phys_addr_t base;
2621
    qemu_irq txirq;
2622
    qemu_irq rxirq;
2623
    qemu_irq txdrq;
2624

    
2625
    uint16_t txbuf;
2626
    uint16_t rxbuf;
2627
    uint16_t control;
2628
    uint16_t setup[5];
2629

    
2630
    struct uwire_slave_s *chip[4];
2631
};
2632

    
2633
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2634
{
2635
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
2636
    struct uwire_slave_s *slave = s->chip[chipselect];
2637

    
2638
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
2639
        if (s->control & (1 << 12))                        /* CS_CMD */
2640
            if (slave && slave->send)
2641
                slave->send(slave->opaque,
2642
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
2643
        s->control &= ~(1 << 14);                        /* CSRB */
2644
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2645
         * a DRQ.  When is the level IRQ supposed to be reset?  */
2646
    }
2647

    
2648
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
2649
        if (s->control & (1 << 12))                        /* CS_CMD */
2650
            if (slave && slave->receive)
2651
                s->rxbuf = slave->receive(slave->opaque);
2652
        s->control |= 1 << 15;                                /* RDRB */
2653
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2654
         * a DRQ.  When is the level IRQ supposed to be reset?  */
2655
    }
2656
}
2657

    
2658
static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
2659
{
2660
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2661
    int offset = addr & OMAP_MPUI_REG_MASK;
2662

    
2663
    switch (offset) {
2664
    case 0x00:        /* RDR */
2665
        s->control &= ~(1 << 15);                        /* RDRB */
2666
        return s->rxbuf;
2667

    
2668
    case 0x04:        /* CSR */
2669
        return s->control;
2670

    
2671
    case 0x08:        /* SR1 */
2672
        return s->setup[0];
2673
    case 0x0c:        /* SR2 */
2674
        return s->setup[1];
2675
    case 0x10:        /* SR3 */
2676
        return s->setup[2];
2677
    case 0x14:        /* SR4 */
2678
        return s->setup[3];
2679
    case 0x18:        /* SR5 */
2680
        return s->setup[4];
2681
    }
2682

    
2683
    OMAP_BAD_REG(addr);
2684
    return 0;
2685
}
2686

    
2687
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
2688
                uint32_t value)
2689
{
2690
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2691
    int offset = addr & OMAP_MPUI_REG_MASK;
2692

    
2693
    switch (offset) {
2694
    case 0x00:        /* TDR */
2695
        s->txbuf = value;                                /* TD */
2696
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
2697
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
2698
                         (s->control & (1 << 12)))) {        /* CS_CMD */
2699
            s->control |= 1 << 14;                        /* CSRB */
2700
            omap_uwire_transfer_start(s);
2701
        }
2702
        break;
2703

    
2704
    case 0x04:        /* CSR */
2705
        s->control = value & 0x1fff;
2706
        if (value & (1 << 13))                                /* START */
2707
            omap_uwire_transfer_start(s);
2708
        break;
2709

    
2710
    case 0x08:        /* SR1 */
2711
        s->setup[0] = value & 0x003f;
2712
        break;
2713

    
2714
    case 0x0c:        /* SR2 */
2715
        s->setup[1] = value & 0x0fc0;
2716
        break;
2717

    
2718
    case 0x10:        /* SR3 */
2719
        s->setup[2] = value & 0x0003;
2720
        break;
2721

    
2722
    case 0x14:        /* SR4 */
2723
        s->setup[3] = value & 0x0001;
2724
        break;
2725

    
2726
    case 0x18:        /* SR5 */
2727
        s->setup[4] = value & 0x000f;
2728
        break;
2729

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

    
2736
static CPUReadMemoryFunc *omap_uwire_readfn[] = {
2737
    omap_badwidth_read16,
2738
    omap_uwire_read,
2739
    omap_badwidth_read16,
2740
};
2741

    
2742
static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
2743
    omap_badwidth_write16,
2744
    omap_uwire_write,
2745
    omap_badwidth_write16,
2746
};
2747

    
2748
static void omap_uwire_reset(struct omap_uwire_s *s)
2749
{
2750
    s->control = 0;
2751
    s->setup[0] = 0;
2752
    s->setup[1] = 0;
2753
    s->setup[2] = 0;
2754
    s->setup[3] = 0;
2755
    s->setup[4] = 0;
2756
}
2757

    
2758
struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
2759
                qemu_irq *irq, qemu_irq dma, omap_clk clk)
2760
{
2761
    int iomemtype;
2762
    struct omap_uwire_s *s = (struct omap_uwire_s *)
2763
            qemu_mallocz(sizeof(struct omap_uwire_s));
2764

    
2765
    s->base = base;
2766
    s->txirq = irq[0];
2767
    s->rxirq = irq[1];
2768
    s->txdrq = dma;
2769
    omap_uwire_reset(s);
2770

    
2771
    iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
2772
                    omap_uwire_writefn, s);
2773
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
2774

    
2775
    return s;
2776
}
2777

    
2778
void omap_uwire_attach(struct omap_uwire_s *s,
2779
                struct uwire_slave_s *slave, int chipselect)
2780
{
2781
    if (chipselect < 0 || chipselect > 3)
2782
        cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
2783
                        chipselect);
2784

    
2785
    s->chip[chipselect] = slave;
2786
}
2787

    
2788
/* Pseudonoise Pulse-Width Light Modulator */
2789
static void omap_pwl_update(struct omap_mpu_state_s *s)
2790
{
2791
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
2792

    
2793
    if (output != s->pwl.output) {
2794
        s->pwl.output = output;
2795
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
2796
    }
2797
}
2798

    
2799
static uint32_t omap_pwl_read(void *opaque, target_phys_addr_t addr)
2800
{
2801
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2802
    int offset = addr & OMAP_MPUI_REG_MASK;
2803

    
2804
    switch (offset) {
2805
    case 0x00:        /* PWL_LEVEL */
2806
        return s->pwl.level;
2807
    case 0x04:        /* PWL_CTRL */
2808
        return s->pwl.enable;
2809
    }
2810
    OMAP_BAD_REG(addr);
2811
    return 0;
2812
}
2813

    
2814
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
2815
                uint32_t value)
2816
{
2817
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2818
    int offset = addr & OMAP_MPUI_REG_MASK;
2819

    
2820
    switch (offset) {
2821
    case 0x00:        /* PWL_LEVEL */
2822
        s->pwl.level = value;
2823
        omap_pwl_update(s);
2824
        break;
2825
    case 0x04:        /* PWL_CTRL */
2826
        s->pwl.enable = value & 1;
2827
        omap_pwl_update(s);
2828
        break;
2829
    default:
2830
        OMAP_BAD_REG(addr);
2831
        return;
2832
    }
2833
}
2834

    
2835
static CPUReadMemoryFunc *omap_pwl_readfn[] = {
2836
    omap_pwl_read,
2837
    omap_badwidth_read8,
2838
    omap_badwidth_read8,
2839
};
2840

    
2841
static CPUWriteMemoryFunc *omap_pwl_writefn[] = {
2842
    omap_pwl_write,
2843
    omap_badwidth_write8,
2844
    omap_badwidth_write8,
2845
};
2846

    
2847
static void omap_pwl_reset(struct omap_mpu_state_s *s)
2848
{
2849
    s->pwl.output = 0;
2850
    s->pwl.level = 0;
2851
    s->pwl.enable = 0;
2852
    s->pwl.clk = 1;
2853
    omap_pwl_update(s);
2854
}
2855

    
2856
static void omap_pwl_clk_update(void *opaque, int line, int on)
2857
{
2858
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2859

    
2860
    s->pwl.clk = on;
2861
    omap_pwl_update(s);
2862
}
2863

    
2864
static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
2865
                omap_clk clk)
2866
{
2867
    int iomemtype;
2868

    
2869
    omap_pwl_reset(s);
2870

    
2871
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
2872
                    omap_pwl_writefn, s);
2873
    cpu_register_physical_memory(base, 0x800, iomemtype);
2874

    
2875
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
2876
}
2877

    
2878
/* Pulse-Width Tone module */
2879
static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr)
2880
{
2881
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2882
    int offset = addr & OMAP_MPUI_REG_MASK;
2883

    
2884
    switch (offset) {
2885
    case 0x00:        /* FRC */
2886
        return s->pwt.frc;
2887
    case 0x04:        /* VCR */
2888
        return s->pwt.vrc;
2889
    case 0x08:        /* GCR */
2890
        return s->pwt.gcr;
2891
    }
2892
    OMAP_BAD_REG(addr);
2893
    return 0;
2894
}
2895

    
2896
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
2897
                uint32_t value)
2898
{
2899
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2900
    int offset = addr & OMAP_MPUI_REG_MASK;
2901

    
2902
    switch (offset) {
2903
    case 0x00:        /* FRC */
2904
        s->pwt.frc = value & 0x3f;
2905
        break;
2906
    case 0x04:        /* VRC */
2907
        if ((value ^ s->pwt.vrc) & 1) {
2908
            if (value & 1)
2909
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
2910
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
2911
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
2912
                                 /* Pre-multiplexer divider */
2913
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
2914
                                 /* Octave multiplexer */
2915
                                 (2 << (value & 3)) *
2916
                                 /* 101/107 divider */
2917
                                 ((value & (1 << 2)) ? 101 : 107) *
2918
                                 /*  49/55 divider */
2919
                                 ((value & (1 << 3)) ?  49 : 55) *
2920
                                 /*  50/63 divider */
2921
                                 ((value & (1 << 4)) ?  50 : 63) *
2922
                                 /*  80/127 divider */
2923
                                 ((value & (1 << 5)) ?  80 : 127) /
2924
                                 (107 * 55 * 63 * 127)));
2925
            else
2926
                printf("%s: silence!\n", __FUNCTION__);
2927
        }
2928
        s->pwt.vrc = value & 0x7f;
2929
        break;
2930
    case 0x08:        /* GCR */
2931
        s->pwt.gcr = value & 3;
2932
        break;
2933
    default:
2934
        OMAP_BAD_REG(addr);
2935
        return;
2936
    }
2937
}
2938

    
2939
static CPUReadMemoryFunc *omap_pwt_readfn[] = {
2940
    omap_pwt_read,
2941
    omap_badwidth_read8,
2942
    omap_badwidth_read8,
2943
};
2944

    
2945
static CPUWriteMemoryFunc *omap_pwt_writefn[] = {
2946
    omap_pwt_write,
2947
    omap_badwidth_write8,
2948
    omap_badwidth_write8,
2949
};
2950

    
2951
static void omap_pwt_reset(struct omap_mpu_state_s *s)
2952
{
2953
    s->pwt.frc = 0;
2954
    s->pwt.vrc = 0;
2955
    s->pwt.gcr = 0;
2956
}
2957

    
2958
static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
2959
                omap_clk clk)
2960
{
2961
    int iomemtype;
2962

    
2963
    s->pwt.clk = clk;
2964
    omap_pwt_reset(s);
2965

    
2966
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
2967
                    omap_pwt_writefn, s);
2968
    cpu_register_physical_memory(base, 0x800, iomemtype);
2969
}
2970

    
2971
/* Real-time Clock module */
2972
struct omap_rtc_s {
2973
    target_phys_addr_t base;
2974
    qemu_irq irq;
2975
    qemu_irq alarm;
2976
    QEMUTimer *clk;
2977

    
2978
    uint8_t interrupts;
2979
    uint8_t status;
2980
    int16_t comp_reg;
2981
    int running;
2982
    int pm_am;
2983
    int auto_comp;
2984
    int round;
2985
    struct tm alarm_tm;
2986
    time_t alarm_ti;
2987

    
2988
    struct tm current_tm;
2989
    time_t ti;
2990
    uint64_t tick;
2991
};
2992

    
2993
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2994
{
2995
    /* s->alarm is level-triggered */
2996
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2997
}
2998

    
2999
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
3000
{
3001
    s->alarm_ti = mktime(&s->alarm_tm);
3002
    if (s->alarm_ti == -1)
3003
        printf("%s: conversion failed\n", __FUNCTION__);
3004
}
3005

    
3006
static inline uint8_t omap_rtc_bcd(int num)
3007
{
3008
    return ((num / 10) << 4) | (num % 10);
3009
}
3010

    
3011
static inline int omap_rtc_bin(uint8_t num)
3012
{
3013
    return (num & 15) + 10 * (num >> 4);
3014
}
3015

    
3016
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
3017
{
3018
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3019
    int offset = addr & OMAP_MPUI_REG_MASK;
3020
    uint8_t i;
3021

    
3022
    switch (offset) {
3023
    case 0x00:        /* SECONDS_REG */
3024
        return omap_rtc_bcd(s->current_tm.tm_sec);
3025

    
3026
    case 0x04:        /* MINUTES_REG */
3027
        return omap_rtc_bcd(s->current_tm.tm_min);
3028

    
3029
    case 0x08:        /* HOURS_REG */
3030
        if (s->pm_am)
3031
            return ((s->current_tm.tm_hour > 11) << 7) |
3032
                    omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
3033
        else
3034
            return omap_rtc_bcd(s->current_tm.tm_hour);
3035

    
3036
    case 0x0c:        /* DAYS_REG */
3037
        return omap_rtc_bcd(s->current_tm.tm_mday);
3038

    
3039
    case 0x10:        /* MONTHS_REG */
3040
        return omap_rtc_bcd(s->current_tm.tm_mon + 1);
3041

    
3042
    case 0x14:        /* YEARS_REG */
3043
        return omap_rtc_bcd(s->current_tm.tm_year % 100);
3044

    
3045
    case 0x18:        /* WEEK_REG */
3046
        return s->current_tm.tm_wday;
3047

    
3048
    case 0x20:        /* ALARM_SECONDS_REG */
3049
        return omap_rtc_bcd(s->alarm_tm.tm_sec);
3050

    
3051
    case 0x24:        /* ALARM_MINUTES_REG */
3052
        return omap_rtc_bcd(s->alarm_tm.tm_min);
3053

    
3054
    case 0x28:        /* ALARM_HOURS_REG */
3055
        if (s->pm_am)
3056
            return ((s->alarm_tm.tm_hour > 11) << 7) |
3057
                    omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
3058
        else
3059
            return omap_rtc_bcd(s->alarm_tm.tm_hour);
3060

    
3061
    case 0x2c:        /* ALARM_DAYS_REG */
3062
        return omap_rtc_bcd(s->alarm_tm.tm_mday);
3063

    
3064
    case 0x30:        /* ALARM_MONTHS_REG */
3065
        return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
3066

    
3067
    case 0x34:        /* ALARM_YEARS_REG */
3068
        return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
3069

    
3070
    case 0x40:        /* RTC_CTRL_REG */
3071
        return (s->pm_am << 3) | (s->auto_comp << 2) |
3072
                (s->round << 1) | s->running;
3073

    
3074
    case 0x44:        /* RTC_STATUS_REG */
3075
        i = s->status;
3076
        s->status &= ~0x3d;
3077
        return i;
3078

    
3079
    case 0x48:        /* RTC_INTERRUPTS_REG */
3080
        return s->interrupts;
3081

    
3082
    case 0x4c:        /* RTC_COMP_LSB_REG */
3083
        return ((uint16_t) s->comp_reg) & 0xff;
3084

    
3085
    case 0x50:        /* RTC_COMP_MSB_REG */
3086
        return ((uint16_t) s->comp_reg) >> 8;
3087
    }
3088

    
3089
    OMAP_BAD_REG(addr);
3090
    return 0;
3091
}
3092

    
3093
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
3094
                uint32_t value)
3095
{
3096
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
3097
    int offset = addr & OMAP_MPUI_REG_MASK;
3098
    struct tm new_tm;
3099
    time_t ti[2];
3100

    
3101
    switch (offset) {
3102
    case 0x00:        /* SECONDS_REG */
3103
#if ALMDEBUG
3104
        printf("RTC SEC_REG <-- %02x\n", value);
3105
#endif
3106
        s->ti -= s->current_tm.tm_sec;
3107
        s->ti += omap_rtc_bin(value);
3108
        return;
3109

    
3110
    case 0x04:        /* MINUTES_REG */
3111
#if ALMDEBUG
3112
        printf("RTC MIN_REG <-- %02x\n", value);
3113
#endif
3114
        s->ti -= s->current_tm.tm_min * 60;
3115
        s->ti += omap_rtc_bin(value) * 60;
3116
        return;
3117

    
3118
    case 0x08:        /* HOURS_REG */
3119
#if ALMDEBUG
3120
        printf("RTC HRS_REG <-- %02x\n", value);
3121
#endif
3122
        s->ti -= s->current_tm.tm_hour * 3600;
3123
        if (s->pm_am) {
3124
            s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
3125
            s->ti += ((value >> 7) & 1) * 43200;
3126
        } else
3127
            s->ti += omap_rtc_bin(value & 0x3f) * 3600;
3128
        return;
3129

    
3130
    case 0x0c:        /* DAYS_REG */
3131
#if ALMDEBUG
3132
        printf("RTC DAY_REG <-- %02x\n", value);
3133
#endif
3134
        s->ti -= s->current_tm.tm_mday * 86400;
3135
        s->ti += omap_rtc_bin(value) * 86400;
3136
        return;
3137

    
3138
    case 0x10:        /* MONTHS_REG */
3139
#if ALMDEBUG
3140
        printf("RTC MTH_REG <-- %02x\n", value);
3141
#endif
3142
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3143
        new_tm.tm_mon = omap_rtc_bin(value);
3144
        ti[0] = mktime(&s->current_tm);
3145
        ti[1] = mktime(&new_tm);
3146

    
3147
        if (ti[0] != -1 && ti[1] != -1) {
3148
            s->ti -= ti[0];
3149
            s->ti += ti[1];
3150
        } else {
3151
            /* A less accurate version */
3152
            s->ti -= s->current_tm.tm_mon * 2592000;
3153
            s->ti += omap_rtc_bin(value) * 2592000;
3154
        }
3155
        return;
3156

    
3157
    case 0x14:        /* YEARS_REG */
3158
#if ALMDEBUG
3159
        printf("RTC YRS_REG <-- %02x\n", value);
3160
#endif
3161
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
3162
        new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
3163
        ti[0] = mktime(&s->current_tm);
3164
        ti[1] = mktime(&new_tm);
3165

    
3166
        if (ti[0] != -1 && ti[1] != -1) {
3167
            s->ti -= ti[0];
3168
            s->ti += ti[1];
3169
        } else {
3170
            /* A less accurate version */
3171
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
3172
            s->ti += omap_rtc_bin(value) * 31536000;
3173
        }
3174
        return;
3175

    
3176
    case 0x18:        /* WEEK_REG */
3177
        return;        /* Ignored */
3178

    
3179
    case 0x20:        /* ALARM_SECONDS_REG */
3180
#if ALMDEBUG
3181
        printf("ALM SEC_REG <-- %02x\n", value);
3182
#endif
3183
        s->alarm_tm.tm_sec = omap_rtc_bin(value);
3184
        omap_rtc_alarm_update(s);
3185
        return;
3186

    
3187
    case 0x24:        /* ALARM_MINUTES_REG */
3188
#if ALMDEBUG
3189
        printf("ALM MIN_REG <-- %02x\n", value);
3190
#endif
3191
        s->alarm_tm.tm_min = omap_rtc_bin(value);
3192
        omap_rtc_alarm_update(s);
3193
        return;
3194

    
3195
    case 0x28:        /* ALARM_HOURS_REG */
3196
#if ALMDEBUG
3197
        printf("ALM HRS_REG <-- %02x\n", value);
3198
#endif
3199
        if (s->pm_am)
3200
            s->alarm_tm.tm_hour =
3201
                    ((omap_rtc_bin(value & 0x3f)) % 12) +
3202
                    ((value >> 7) & 1) * 12;
3203
        else
3204
            s->alarm_tm.tm_hour = omap_rtc_bin(value);
3205
        omap_rtc_alarm_update(s);
3206
        return;
3207

    
3208
    case 0x2c:        /* ALARM_DAYS_REG */
3209
#if ALMDEBUG
3210
        printf("ALM DAY_REG <-- %02x\n", value);
3211
#endif
3212
        s->alarm_tm.tm_mday = omap_rtc_bin(value);
3213
        omap_rtc_alarm_update(s);
3214
        return;
3215

    
3216
    case 0x30:        /* ALARM_MONTHS_REG */
3217
#if ALMDEBUG
3218
        printf("ALM MON_REG <-- %02x\n", value);
3219
#endif
3220
        s->alarm_tm.tm_mon = omap_rtc_bin(value);
3221
        omap_rtc_alarm_update(s);
3222
        return;
3223

    
3224
    case 0x34:        /* ALARM_YEARS_REG */
3225
#if ALMDEBUG
3226
        printf("ALM YRS_REG <-- %02x\n", value);
3227
#endif
3228
        s->alarm_tm.tm_year = omap_rtc_bin(value);
3229
        omap_rtc_alarm_update(s);
3230
        return;
3231

    
3232
    case 0x40:        /* RTC_CTRL_REG */
3233
#if ALMDEBUG
3234
        printf("RTC CONTROL <-- %02x\n", value);
3235
#endif
3236
        s->pm_am = (value >> 3) & 1;
3237
        s->auto_comp = (value >> 2) & 1;
3238
        s->round = (value >> 1) & 1;
3239
        s->running = value & 1;
3240
        s->status &= 0xfd;
3241
        s->status |= s->running << 1;
3242
        return;
3243

    
3244
    case 0x44:        /* RTC_STATUS_REG */
3245
#if ALMDEBUG
3246
        printf("RTC STATUSL <-- %02x\n", value);
3247
#endif
3248
        s->status &= ~((value & 0xc0) ^ 0x80);
3249
        omap_rtc_interrupts_update(s);
3250
        return;
3251

    
3252
    case 0x48:        /* RTC_INTERRUPTS_REG */
3253
#if ALMDEBUG
3254
        printf("RTC INTRS <-- %02x\n", value);
3255
#endif
3256
        s->interrupts = value;
3257
        return;
3258

    
3259
    case 0x4c:        /* RTC_COMP_LSB_REG */
3260
#if ALMDEBUG
3261
        printf("RTC COMPLSB <-- %02x\n", value);
3262
#endif
3263
        s->comp_reg &= 0xff00;
3264
        s->comp_reg |= 0x00ff & value;
3265
        return;
3266

    
3267
    case 0x50:        /* RTC_COMP_MSB_REG */
3268
#if ALMDEBUG
3269
        printf("RTC COMPMSB <-- %02x\n", value);
3270
#endif
3271
        s->comp_reg &= 0x00ff;
3272
        s->comp_reg |= 0xff00 & (value << 8);
3273
        return;
3274

    
3275
    default:
3276
        OMAP_BAD_REG(addr);
3277
        return;
3278
    }
3279
}
3280

    
3281
static CPUReadMemoryFunc *omap_rtc_readfn[] = {
3282
    omap_rtc_read,
3283
    omap_badwidth_read8,
3284
    omap_badwidth_read8,
3285
};
3286

    
3287
static CPUWriteMemoryFunc *omap_rtc_writefn[] = {
3288
    omap_rtc_write,
3289
    omap_badwidth_write8,
3290
    omap_badwidth_write8,
3291
};
3292

    
3293
static void omap_rtc_tick(void *opaque)
3294
{
3295
    struct omap_rtc_s *s = opaque;
3296

    
3297
    if (s->round) {
3298
        /* Round to nearest full minute.  */
3299
        if (s->current_tm.tm_sec < 30)
3300
            s->ti -= s->current_tm.tm_sec;
3301
        else
3302
            s->ti += 60 - s->current_tm.tm_sec;
3303

    
3304
        s->round = 0;
3305
    }
3306

    
3307
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
3308

    
3309
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
3310
        s->status |= 0x40;
3311
        omap_rtc_interrupts_update(s);
3312
    }
3313

    
3314
    if (s->interrupts & 0x04)
3315
        switch (s->interrupts & 3) {
3316
        case 0:
3317
            s->status |= 0x04;
3318
            qemu_irq_pulse(s->irq);
3319
            break;
3320
        case 1:
3321
            if (s->current_tm.tm_sec)
3322
                break;
3323
            s->status |= 0x08;
3324
            qemu_irq_pulse(s->irq);
3325
            break;
3326
        case 2:
3327
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
3328
                break;
3329
            s->status |= 0x10;
3330
            qemu_irq_pulse(s->irq);
3331
            break;
3332
        case 3:
3333
            if (s->current_tm.tm_sec ||
3334
                            s->current_tm.tm_min || s->current_tm.tm_hour)
3335
                break;
3336
            s->status |= 0x20;
3337
            qemu_irq_pulse(s->irq);
3338
            break;
3339
        }
3340

    
3341
    /* Move on */
3342
    if (s->running)
3343
        s->ti ++;
3344
    s->tick += 1000;
3345

    
3346
    /*
3347
     * Every full hour add a rough approximation of the compensation
3348
     * register to the 32kHz Timer (which drives the RTC) value. 
3349
     */
3350
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
3351
        s->tick += s->comp_reg * 1000 / 32768;
3352

    
3353
    qemu_mod_timer(s->clk, s->tick);
3354
}
3355

    
3356
static void omap_rtc_reset(struct omap_rtc_s *s)
3357
{
3358
    struct tm tm;
3359

    
3360
    s->interrupts = 0;
3361
    s->comp_reg = 0;
3362
    s->running = 0;
3363
    s->pm_am = 0;
3364
    s->auto_comp = 0;
3365
    s->round = 0;
3366
    s->tick = qemu_get_clock(rt_clock);
3367
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
3368
    s->alarm_tm.tm_mday = 0x01;
3369
    s->status = 1 << 7;
3370
    qemu_get_timedate(&tm, 0);
3371
    s->ti = mktime(&tm);
3372

    
3373
    omap_rtc_alarm_update(s);
3374
    omap_rtc_tick(s);
3375
}
3376

    
3377
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
3378
                qemu_irq *irq, omap_clk clk)
3379
{
3380
    int iomemtype;
3381
    struct omap_rtc_s *s = (struct omap_rtc_s *)
3382
            qemu_mallocz(sizeof(struct omap_rtc_s));
3383

    
3384
    s->base = base;
3385
    s->irq = irq[0];
3386
    s->alarm = irq[1];
3387
    s->clk = qemu_new_timer(rt_clock, omap_rtc_tick, s);
3388

    
3389
    omap_rtc_reset(s);
3390

    
3391
    iomemtype = cpu_register_io_memory(0, omap_rtc_readfn,
3392
                    omap_rtc_writefn, s);
3393
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3394

    
3395
    return s;
3396
}
3397

    
3398
/* Multi-channel Buffered Serial Port interfaces */
3399
struct omap_mcbsp_s {
3400
    target_phys_addr_t base;
3401
    qemu_irq txirq;
3402
    qemu_irq rxirq;
3403
    qemu_irq txdrq;
3404
    qemu_irq rxdrq;
3405

    
3406
    uint16_t spcr[2];
3407
    uint16_t rcr[2];
3408
    uint16_t xcr[2];
3409
    uint16_t srgr[2];
3410
    uint16_t mcr[2];
3411
    uint16_t pcr;
3412
    uint16_t rcer[8];
3413
    uint16_t xcer[8];
3414
    int tx_rate;
3415
    int rx_rate;
3416
    int tx_req;
3417
    int rx_req;
3418

    
3419
    struct i2s_codec_s *codec;
3420
    QEMUTimer *source_timer;
3421
    QEMUTimer *sink_timer;
3422
};
3423

    
3424
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
3425
{
3426
    int irq;
3427

    
3428
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
3429
    case 0:
3430
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
3431
        break;
3432
    case 3:
3433
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
3434
        break;
3435
    default:
3436
        irq = 0;
3437
        break;
3438
    }
3439

    
3440
    if (irq)
3441
        qemu_irq_pulse(s->rxirq);
3442

    
3443
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
3444
    case 0:
3445
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
3446
        break;
3447
    case 3:
3448
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
3449
        break;
3450
    default:
3451
        irq = 0;
3452
        break;
3453
    }
3454

    
3455
    if (irq)
3456
        qemu_irq_pulse(s->txirq);
3457
}
3458

    
3459
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
3460
{
3461
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
3462
        s->spcr[0] |= 1 << 2;                                /* RFULL */
3463
    s->spcr[0] |= 1 << 1;                                /* RRDY */
3464
    qemu_irq_raise(s->rxdrq);
3465
    omap_mcbsp_intr_update(s);
3466
}
3467

    
3468
static void omap_mcbsp_source_tick(void *opaque)
3469
{
3470
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3471
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3472

    
3473
    if (!s->rx_rate)
3474
        return;
3475
    if (s->rx_req)
3476
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
3477

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

    
3480
    omap_mcbsp_rx_newdata(s);
3481
    qemu_mod_timer(s->source_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
3482
}
3483

    
3484
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3485
{
3486
    if (!s->codec || !s->codec->rts)
3487
        omap_mcbsp_source_tick(s);
3488
    else if (s->codec->in.len) {
3489
        s->rx_req = s->codec->in.len;
3490
        omap_mcbsp_rx_newdata(s);
3491
    }
3492
}
3493

    
3494
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3495
{
3496
    qemu_del_timer(s->source_timer);
3497
}
3498

    
3499
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3500
{
3501
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
3502
    qemu_irq_lower(s->rxdrq);
3503
    omap_mcbsp_intr_update(s);
3504
}
3505

    
3506
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3507
{
3508
    s->spcr[1] |= 1 << 1;                                /* XRDY */
3509
    qemu_irq_raise(s->txdrq);
3510
    omap_mcbsp_intr_update(s);
3511
}
3512

    
3513
static void omap_mcbsp_sink_tick(void *opaque)
3514
{
3515
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3516
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3517

    
3518
    if (!s->tx_rate)
3519
        return;
3520
    if (s->tx_req)
3521
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
3522

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

    
3525
    omap_mcbsp_tx_newdata(s);
3526
    qemu_mod_timer(s->sink_timer, qemu_get_clock(vm_clock) + ticks_per_sec);
3527
}
3528

    
3529
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3530
{
3531
    if (!s->codec || !s->codec->cts)
3532
        omap_mcbsp_sink_tick(s);
3533
    else if (s->codec->out.size) {
3534
        s->tx_req = s->codec->out.size;
3535
        omap_mcbsp_tx_newdata(s);
3536
    }
3537
}
3538

    
3539
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3540
{
3541
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
3542
    qemu_irq_lower(s->txdrq);
3543
    omap_mcbsp_intr_update(s);
3544
    if (s->codec && s->codec->cts)
3545
        s->codec->tx_swallow(s->codec->opaque);
3546
}
3547

    
3548
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3549
{
3550
    s->tx_req = 0;
3551
    omap_mcbsp_tx_done(s);
3552
    qemu_del_timer(s->sink_timer);
3553
}
3554

    
3555
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3556
{
3557
    int prev_rx_rate, prev_tx_rate;
3558
    int rx_rate = 0, tx_rate = 0;
3559
    int cpu_rate = 1500000;        /* XXX */
3560

    
3561
    /* TODO: check CLKSTP bit */
3562
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
3563
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
3564
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3565
                            (s->pcr & (1 << 8))) {        /* CLKRM */
3566
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3567
                    rx_rate = cpu_rate /
3568
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3569
            } else
3570
                if (s->codec)
3571
                    rx_rate = s->codec->rx_rate;
3572
        }
3573

    
3574
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
3575
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3576
                            (s->pcr & (1 << 9))) {        /* CLKXM */
3577
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3578
                    tx_rate = cpu_rate /
3579
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3580
            } else
3581
                if (s->codec)
3582
                    tx_rate = s->codec->tx_rate;
3583
        }
3584
    }
3585
    prev_tx_rate = s->tx_rate;
3586
    prev_rx_rate = s->rx_rate;
3587
    s->tx_rate = tx_rate;
3588
    s->rx_rate = rx_rate;
3589

    
3590
    if (s->codec)
3591
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3592

    
3593
    if (!prev_tx_rate && tx_rate)
3594
        omap_mcbsp_tx_start(s);
3595
    else if (s->tx_rate && !tx_rate)
3596
        omap_mcbsp_tx_stop(s);
3597

    
3598
    if (!prev_rx_rate && rx_rate)
3599
        omap_mcbsp_rx_start(s);
3600
    else if (prev_tx_rate && !tx_rate)
3601
        omap_mcbsp_rx_stop(s);
3602
}
3603

    
3604
static uint32_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr)
3605
{
3606
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3607
    int offset = addr & OMAP_MPUI_REG_MASK;
3608
    uint16_t ret;
3609

    
3610
    switch (offset) {
3611
    case 0x00:        /* DRR2 */
3612
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
3613
            return 0x0000;
3614
        /* Fall through.  */
3615
    case 0x02:        /* DRR1 */
3616
        if (s->rx_req < 2) {
3617
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
3618
            omap_mcbsp_rx_done(s);
3619
        } else {
3620
            s->tx_req -= 2;
3621
            if (s->codec && s->codec->in.len >= 2) {
3622
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3623
                ret |= s->codec->in.fifo[s->codec->in.start ++];
3624
                s->codec->in.len -= 2;
3625
            } else
3626
                ret = 0x0000;
3627
            if (!s->tx_req)
3628
                omap_mcbsp_rx_done(s);
3629
            return ret;
3630
        }
3631
        return 0x0000;
3632

    
3633
    case 0x04:        /* DXR2 */
3634
    case 0x06:        /* DXR1 */
3635
        return 0x0000;
3636

    
3637
    case 0x08:        /* SPCR2 */
3638
        return s->spcr[1];
3639
    case 0x0a:        /* SPCR1 */
3640
        return s->spcr[0];
3641
    case 0x0c:        /* RCR2 */
3642
        return s->rcr[1];
3643
    case 0x0e:        /* RCR1 */
3644
        return s->rcr[0];
3645
    case 0x10:        /* XCR2 */
3646
        return s->xcr[1];
3647
    case 0x12:        /* XCR1 */
3648
        return s->xcr[0];
3649
    case 0x14:        /* SRGR2 */
3650
        return s->srgr[1];
3651
    case 0x16:        /* SRGR1 */
3652
        return s->srgr[0];
3653
    case 0x18:        /* MCR2 */
3654
        return s->mcr[1];
3655
    case 0x1a:        /* MCR1 */
3656
        return s->mcr[0];
3657
    case 0x1c:        /* RCERA */
3658
        return s->rcer[0];
3659
    case 0x1e:        /* RCERB */
3660
        return s->rcer[1];
3661
    case 0x20:        /* XCERA */
3662
        return s->xcer[0];
3663
    case 0x22:        /* XCERB */
3664
        return s->xcer[1];
3665
    case 0x24:        /* PCR0 */
3666
        return s->pcr;
3667
    case 0x26:        /* RCERC */
3668
        return s->rcer[2];
3669
    case 0x28:        /* RCERD */
3670
        return s->rcer[3];
3671
    case 0x2a:        /* XCERC */
3672
        return s->xcer[2];
3673
    case 0x2c:        /* XCERD */
3674
        return s->xcer[3];
3675
    case 0x2e:        /* RCERE */
3676
        return s->rcer[4];
3677
    case 0x30:        /* RCERF */
3678
        return s->rcer[5];
3679
    case 0x32:        /* XCERE */
3680
        return s->xcer[4];
3681
    case 0x34:        /* XCERF */
3682
        return s->xcer[5];
3683
    case 0x36:        /* RCERG */
3684
        return s->rcer[6];
3685
    case 0x38:        /* RCERH */
3686
        return s->rcer[7];
3687
    case 0x3a:        /* XCERG */
3688
        return s->xcer[6];
3689
    case 0x3c:        /* XCERH */
3690
        return s->xcer[7];
3691
    }
3692

    
3693
    OMAP_BAD_REG(addr);
3694
    return 0;
3695
}
3696

    
3697
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
3698
                uint32_t value)
3699
{
3700
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3701
    int offset = addr & OMAP_MPUI_REG_MASK;
3702

    
3703
    switch (offset) {
3704
    case 0x00:        /* DRR2 */
3705
    case 0x02:        /* DRR1 */
3706
        OMAP_RO_REG(addr);
3707
        return;
3708

    
3709
    case 0x04:        /* DXR2 */
3710
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
3711
            return;
3712
        /* Fall through.  */
3713
    case 0x06:        /* DXR1 */
3714
        if (s->tx_req > 1) {
3715
            s->tx_req -= 2;
3716
            if (s->codec && s->codec->cts) {
3717
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
3718
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
3719
            }
3720
            if (s->tx_req < 2)
3721
                omap_mcbsp_tx_done(s);
3722
        } else
3723
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3724
        return;
3725

    
3726
    case 0x08:        /* SPCR2 */
3727
        s->spcr[1] &= 0x0002;
3728
        s->spcr[1] |= 0x03f9 & value;
3729
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
3730
        if (~value & 1)                                        /* XRST */
3731
            s->spcr[1] &= ~6;
3732
        omap_mcbsp_req_update(s);
3733
        return;
3734
    case 0x0a:        /* SPCR1 */
3735
        s->spcr[0] &= 0x0006;
3736
        s->spcr[0] |= 0xf8f9 & value;
3737
        if (value & (1 << 15))                                /* DLB */
3738
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
3739
        if (~value & 1) {                                /* RRST */
3740
            s->spcr[0] &= ~6;
3741
            s->rx_req = 0;
3742
            omap_mcbsp_rx_done(s);
3743
        }
3744
        omap_mcbsp_req_update(s);
3745
        return;
3746

    
3747
    case 0x0c:        /* RCR2 */
3748
        s->rcr[1] = value & 0xffff;
3749
        return;
3750
    case 0x0e:        /* RCR1 */
3751
        s->rcr[0] = value & 0x7fe0;
3752
        return;
3753
    case 0x10:        /* XCR2 */
3754
        s->xcr[1] = value & 0xffff;
3755
        return;
3756
    case 0x12:        /* XCR1 */
3757
        s->xcr[0] = value & 0x7fe0;
3758
        return;
3759
    case 0x14:        /* SRGR2 */
3760
        s->srgr[1] = value & 0xffff;
3761
        omap_mcbsp_req_update(s);
3762
        return;
3763
    case 0x16:        /* SRGR1 */
3764
        s->srgr[0] = value & 0xffff;
3765
        omap_mcbsp_req_update(s);
3766
        return;
3767
    case 0x18:        /* MCR2 */
3768
        s->mcr[1] = value & 0x03e3;
3769
        if (value & 3)                                        /* XMCM */
3770
            printf("%s: Tx channel selection mode enable attempt\n",
3771
                            __FUNCTION__);
3772
        return;
3773
    case 0x1a:        /* MCR1 */
3774
        s->mcr[0] = value & 0x03e1;
3775
        if (value & 1)                                        /* RMCM */
3776
            printf("%s: Rx channel selection mode enable attempt\n",
3777
                            __FUNCTION__);
3778
        return;
3779
    case 0x1c:        /* RCERA */
3780
        s->rcer[0] = value & 0xffff;
3781
        return;
3782
    case 0x1e:        /* RCERB */
3783
        s->rcer[1] = value & 0xffff;
3784
        return;
3785
    case 0x20:        /* XCERA */
3786
        s->xcer[0] = value & 0xffff;
3787
        return;
3788
    case 0x22:        /* XCERB */
3789
        s->xcer[1] = value & 0xffff;
3790
        return;
3791
    case 0x24:        /* PCR0 */
3792
        s->pcr = value & 0x7faf;
3793
        return;
3794
    case 0x26:        /* RCERC */
3795
        s->rcer[2] = value & 0xffff;
3796
        return;
3797
    case 0x28:        /* RCERD */
3798
        s->rcer[3] = value & 0xffff;
3799
        return;
3800
    case 0x2a:        /* XCERC */
3801
        s->xcer[2] = value & 0xffff;
3802
        return;
3803
    case 0x2c:        /* XCERD */
3804
        s->xcer[3] = value & 0xffff;
3805
        return;
3806
    case 0x2e:        /* RCERE */
3807
        s->rcer[4] = value & 0xffff;
3808
        return;
3809
    case 0x30:        /* RCERF */
3810
        s->rcer[5] = value & 0xffff;
3811
        return;
3812
    case 0x32:        /* XCERE */
3813
        s->xcer[4] = value & 0xffff;
3814
        return;
3815
    case 0x34:        /* XCERF */
3816
        s->xcer[5] = value & 0xffff;
3817
        return;
3818
    case 0x36:        /* RCERG */
3819
        s->rcer[6] = value & 0xffff;
3820
        return;
3821
    case 0x38:        /* RCERH */
3822
        s->rcer[7] = value & 0xffff;
3823
        return;
3824
    case 0x3a:        /* XCERG */
3825
        s->xcer[6] = value & 0xffff;
3826
        return;
3827
    case 0x3c:        /* XCERH */
3828
        s->xcer[7] = value & 0xffff;
3829
        return;
3830
    }
3831

    
3832
    OMAP_BAD_REG(addr);
3833
}
3834

    
3835
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
3836
                uint32_t value)
3837
{
3838
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3839
    int offset = addr & OMAP_MPUI_REG_MASK;
3840

    
3841
    if (offset == 0x04) {                                /* DXR */
3842
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
3843
            return;
3844
        if (s->tx_req > 3) {
3845
            s->tx_req -= 4;
3846
            if (s->codec && s->codec->cts) {
3847
                s->codec->out.fifo[s->codec->out.len ++] =
3848
                        (value >> 24) & 0xff;
3849
                s->codec->out.fifo[s->codec->out.len ++] =
3850
                        (value >> 16) & 0xff;
3851
                s->codec->out.fifo[s->codec->out.len ++] =
3852
                        (value >> 8) & 0xff;
3853
                s->codec->out.fifo[s->codec->out.len ++] =
3854
                        (value >> 0) & 0xff;
3855
            }
3856
            if (s->tx_req < 4)
3857
                omap_mcbsp_tx_done(s);
3858
        } else
3859
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3860
        return;
3861
    }
3862

    
3863
    omap_badwidth_write16(opaque, addr, value);
3864
}
3865

    
3866
static CPUReadMemoryFunc *omap_mcbsp_readfn[] = {
3867
    omap_badwidth_read16,
3868
    omap_mcbsp_read,
3869
    omap_badwidth_read16,
3870
};
3871

    
3872
static CPUWriteMemoryFunc *omap_mcbsp_writefn[] = {
3873
    omap_badwidth_write16,
3874
    omap_mcbsp_writeh,
3875
    omap_mcbsp_writew,
3876
};
3877

    
3878
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
3879
{
3880
    memset(&s->spcr, 0, sizeof(s->spcr));
3881
    memset(&s->rcr, 0, sizeof(s->rcr));
3882
    memset(&s->xcr, 0, sizeof(s->xcr));
3883
    s->srgr[0] = 0x0001;
3884
    s->srgr[1] = 0x2000;
3885
    memset(&s->mcr, 0, sizeof(s->mcr));
3886
    memset(&s->pcr, 0, sizeof(s->pcr));
3887
    memset(&s->rcer, 0, sizeof(s->rcer));
3888
    memset(&s->xcer, 0, sizeof(s->xcer));
3889
    s->tx_req = 0;
3890
    s->rx_req = 0;
3891
    s->tx_rate = 0;
3892
    s->rx_rate = 0;
3893
    qemu_del_timer(s->source_timer);
3894
    qemu_del_timer(s->sink_timer);
3895
}
3896

    
3897
struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
3898
                qemu_irq *irq, qemu_irq *dma, omap_clk clk)
3899
{
3900
    int iomemtype;
3901
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
3902
            qemu_mallocz(sizeof(struct omap_mcbsp_s));
3903

    
3904
    s->base = base;
3905
    s->txirq = irq[0];
3906
    s->rxirq = irq[1];
3907
    s->txdrq = dma[0];
3908
    s->rxdrq = dma[1];
3909
    s->sink_timer = qemu_new_timer(vm_clock, omap_mcbsp_sink_tick, s);
3910
    s->source_timer = qemu_new_timer(vm_clock, omap_mcbsp_source_tick, s);
3911
    omap_mcbsp_reset(s);
3912

    
3913
    iomemtype = cpu_register_io_memory(0, omap_mcbsp_readfn,
3914
                    omap_mcbsp_writefn, s);
3915
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
3916

    
3917
    return s;
3918
}
3919

    
3920
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3921
{
3922
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3923

    
3924
    if (s->rx_rate) {
3925
        s->rx_req = s->codec->in.len;
3926
        omap_mcbsp_rx_newdata(s);
3927
    }
3928
}
3929

    
3930
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3931
{
3932
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3933

    
3934
    if (s->tx_rate) {
3935
        s->tx_req = s->codec->out.size;
3936
        omap_mcbsp_tx_newdata(s);
3937
    }
3938
}
3939

    
3940
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave)
3941
{
3942
    s->codec = slave;
3943
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
3944
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
3945
}
3946

    
3947
/* LED Pulse Generators */
3948
struct omap_lpg_s {
3949
    target_phys_addr_t base;
3950
    QEMUTimer *tm;
3951

    
3952
    uint8_t control;
3953
    uint8_t power;
3954
    int64_t on;
3955
    int64_t period;
3956
    int clk;
3957
    int cycle;
3958
};
3959

    
3960
static void omap_lpg_tick(void *opaque)
3961
{
3962
    struct omap_lpg_s *s = opaque;
3963

    
3964
    if (s->cycle)
3965
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
3966
    else
3967
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
3968

    
3969
    s->cycle = !s->cycle;
3970
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
3971
}
3972

    
3973
static void omap_lpg_update(struct omap_lpg_s *s)
3974
{
3975
    int64_t on, period = 1, ticks = 1000;
3976
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
3977

    
3978
    if (~s->control & (1 << 6))                                        /* LPGRES */
3979
        on = 0;
3980
    else if (s->control & (1 << 7))                                /* PERM_ON */
3981
        on = period;
3982
    else {
3983
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
3984
                        256 / 32);
3985
        on = (s->clk && s->power) ? muldiv64(ticks,
3986
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
3987
    }
3988

    
3989
    qemu_del_timer(s->tm);
3990
    if (on == period && s->on < s->period)
3991
        printf("%s: LED is on\n", __FUNCTION__);
3992
    else if (on == 0 && s->on)
3993
        printf("%s: LED is off\n", __FUNCTION__);
3994
    else if (on && (on != s->on || period != s->period)) {
3995
        s->cycle = 0;
3996
        s->on = on;
3997
        s->period = period;
3998
        omap_lpg_tick(s);
3999
        return;
4000
    }
4001

    
4002
    s->on = on;
4003
    s->period = period;
4004
}
4005

    
4006
static void omap_lpg_reset(struct omap_lpg_s *s)
4007
{
4008
    s->control = 0x00;
4009
    s->power = 0x00;
4010
    s->clk = 1;
4011
    omap_lpg_update(s);
4012
}
4013

    
4014
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
4015
{
4016
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4017
    int offset = addr & OMAP_MPUI_REG_MASK;
4018

    
4019
    switch (offset) {
4020
    case 0x00:        /* LCR */
4021
        return s->control;
4022

    
4023
    case 0x04:        /* PMR */
4024
        return s->power;
4025
    }
4026

    
4027
    OMAP_BAD_REG(addr);
4028
    return 0;
4029
}
4030

    
4031
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
4032
                uint32_t value)
4033
{
4034
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4035
    int offset = addr & OMAP_MPUI_REG_MASK;
4036

    
4037
    switch (offset) {
4038
    case 0x00:        /* LCR */
4039
        if (~value & (1 << 6))                                        /* LPGRES */
4040
            omap_lpg_reset(s);
4041
        s->control = value & 0xff;
4042
        omap_lpg_update(s);
4043
        return;
4044

    
4045
    case 0x04:        /* PMR */
4046
        s->power = value & 0x01;
4047
        omap_lpg_update(s);
4048
        return;
4049

    
4050
    default:
4051
        OMAP_BAD_REG(addr);
4052
        return;
4053
    }
4054
}
4055

    
4056
static CPUReadMemoryFunc *omap_lpg_readfn[] = {
4057
    omap_lpg_read,
4058
    omap_badwidth_read8,
4059
    omap_badwidth_read8,
4060
};
4061

    
4062
static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
4063
    omap_lpg_write,
4064
    omap_badwidth_write8,
4065
    omap_badwidth_write8,
4066
};
4067

    
4068
static void omap_lpg_clk_update(void *opaque, int line, int on)
4069
{
4070
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4071

    
4072
    s->clk = on;
4073
    omap_lpg_update(s);
4074
}
4075

    
4076
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4077
{
4078
    int iomemtype;
4079
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4080
            qemu_mallocz(sizeof(struct omap_lpg_s));
4081

    
4082
    s->base = base;
4083
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4084

    
4085
    omap_lpg_reset(s);
4086

    
4087
    iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
4088
                    omap_lpg_writefn, s);
4089
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4090

    
4091
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4092

    
4093
    return s;
4094
}
4095

    
4096
/* MPUI Peripheral Bridge configuration */
4097
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
4098
{
4099
    if (addr == OMAP_MPUI_BASE)        /* CMR */
4100
        return 0xfe4d;
4101

    
4102
    OMAP_BAD_REG(addr);
4103
    return 0;
4104
}
4105

    
4106
static CPUReadMemoryFunc *omap_mpui_io_readfn[] = {
4107
    omap_badwidth_read16,
4108
    omap_mpui_io_read,
4109
    omap_badwidth_read16,
4110
};
4111

    
4112
static CPUWriteMemoryFunc *omap_mpui_io_writefn[] = {
4113
    omap_badwidth_write16,
4114
    omap_badwidth_write16,
4115
    omap_badwidth_write16,
4116
};
4117

    
4118
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4119
{
4120
    int iomemtype = cpu_register_io_memory(0, omap_mpui_io_readfn,
4121
                    omap_mpui_io_writefn, mpu);
4122
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
4123
}
4124

    
4125
/* General chip reset */
4126
static void omap_mpu_reset(void *opaque)
4127
{
4128
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4129

    
4130
    omap_inth_reset(mpu->ih[0]);
4131
    omap_inth_reset(mpu->ih[1]);
4132
    omap_dma_reset(mpu->dma);
4133
    omap_mpu_timer_reset(mpu->timer[0]);
4134
    omap_mpu_timer_reset(mpu->timer[1]);
4135
    omap_mpu_timer_reset(mpu->timer[2]);
4136
    omap_wd_timer_reset(mpu->wdt);
4137
    omap_os_timer_reset(mpu->os_timer);
4138
    omap_lcdc_reset(mpu->lcd);
4139
    omap_ulpd_pm_reset(mpu);
4140
    omap_pin_cfg_reset(mpu);
4141
    omap_mpui_reset(mpu);
4142
    omap_tipb_bridge_reset(mpu->private_tipb);
4143
    omap_tipb_bridge_reset(mpu->public_tipb);
4144
    omap_dpll_reset(&mpu->dpll[0]);
4145
    omap_dpll_reset(&mpu->dpll[1]);
4146
    omap_dpll_reset(&mpu->dpll[2]);
4147
    omap_uart_reset(mpu->uart[0]);
4148
    omap_uart_reset(mpu->uart[1]);
4149
    omap_uart_reset(mpu->uart[2]);
4150
    omap_mmc_reset(mpu->mmc);
4151
    omap_mpuio_reset(mpu->mpuio);
4152
    omap_gpio_reset(mpu->gpio);
4153
    omap_uwire_reset(mpu->microwire);
4154
    omap_pwl_reset(mpu);
4155
    omap_pwt_reset(mpu);
4156
    omap_i2c_reset(mpu->i2c);
4157
    omap_rtc_reset(mpu->rtc);
4158
    omap_mcbsp_reset(mpu->mcbsp1);
4159
    omap_mcbsp_reset(mpu->mcbsp2);
4160
    omap_mcbsp_reset(mpu->mcbsp3);
4161
    omap_lpg_reset(mpu->led[0]);
4162
    omap_lpg_reset(mpu->led[1]);
4163
    omap_clkm_reset(mpu);
4164
    cpu_reset(mpu->env);
4165
}
4166

    
4167
static const struct omap_map_s {
4168
    target_phys_addr_t phys_dsp;
4169
    target_phys_addr_t phys_mpu;
4170
    uint32_t size;
4171
    const char *name;
4172
} omap15xx_dsp_mm[] = {
4173
    /* Strobe 0 */
4174
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
4175
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
4176
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
4177
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
4178
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
4179
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
4180
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
4181
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
4182
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
4183
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
4184
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
4185
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
4186
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
4187
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
4188
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
4189
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
4190
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
4191
    /* Strobe 1 */
4192
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
4193

    
4194
    { 0 }
4195
};
4196

    
4197
static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4198
{
4199
    int io;
4200

    
4201
    for (; map->phys_dsp; map ++) {
4202
        io = cpu_get_physical_page_desc(map->phys_mpu);
4203

    
4204
        cpu_register_physical_memory(map->phys_dsp, map->size, io);
4205
    }
4206
}
4207

    
4208
static void omap_mpu_wakeup(void *opaque, int irq, int req)
4209
{
4210
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4211

    
4212
    if (mpu->env->halted)
4213
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4214
}
4215

    
4216
static const struct dma_irq_map omap_dma_irq_map[] = {
4217
    { 0, OMAP_INT_DMA_CH0_6 },
4218
    { 0, OMAP_INT_DMA_CH1_7 },
4219
    { 0, OMAP_INT_DMA_CH2_8 },
4220
    { 0, OMAP_INT_DMA_CH3 },
4221
    { 0, OMAP_INT_DMA_CH4 },
4222
    { 0, OMAP_INT_DMA_CH5 },
4223
    { 1, OMAP_INT_1610_DMA_CH6 },
4224
    { 1, OMAP_INT_1610_DMA_CH7 },
4225
    { 1, OMAP_INT_1610_DMA_CH8 },
4226
    { 1, OMAP_INT_1610_DMA_CH9 },
4227
    { 1, OMAP_INT_1610_DMA_CH10 },
4228
    { 1, OMAP_INT_1610_DMA_CH11 },
4229
    { 1, OMAP_INT_1610_DMA_CH12 },
4230
    { 1, OMAP_INT_1610_DMA_CH13 },
4231
    { 1, OMAP_INT_1610_DMA_CH14 },
4232
    { 1, OMAP_INT_1610_DMA_CH15 }
4233
};
4234

    
4235
/* DMA ports for OMAP1 */
4236
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
4237
                target_phys_addr_t addr)
4238
{
4239
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
4240
}
4241

    
4242
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
4243
                target_phys_addr_t addr)
4244
{
4245
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
4246
}
4247

    
4248
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
4249
                target_phys_addr_t addr)
4250
{
4251
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
4252
}
4253

    
4254
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
4255
                target_phys_addr_t addr)
4256
{
4257
    return addr >= 0xfffb0000 && addr < 0xffff0000;
4258
}
4259

    
4260
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
4261
                target_phys_addr_t addr)
4262
{
4263
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
4264
}
4265

    
4266
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
4267
                target_phys_addr_t addr)
4268
{
4269
    return addr >= 0xe1010000 && addr < 0xe1020004;
4270
}
4271

    
4272
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4273
                DisplayState *ds, const char *core)
4274
{
4275
    int i;
4276
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4277
            qemu_mallocz(sizeof(struct omap_mpu_state_s));
4278
    ram_addr_t imif_base, emiff_base;
4279
    qemu_irq *cpu_irq;
4280
    qemu_irq dma_irqs[6];
4281
    int sdindex;
4282

    
4283
    if (!core)
4284
        core = "ti925t";
4285

    
4286
    /* Core */
4287
    s->mpu_model = omap310;
4288
    s->env = cpu_init(core);
4289
    if (!s->env) {
4290
        fprintf(stderr, "Unable to find CPU definition\n");
4291
        exit(1);
4292
    }
4293
    s->sdram_size = sdram_size;
4294
    s->sram_size = OMAP15XX_SRAM_SIZE;
4295

    
4296
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
4297

    
4298
    /* Clocks */
4299
    omap_clk_init(s);
4300

    
4301
    /* Memory-mapped stuff */
4302
    cpu_register_physical_memory(OMAP_EMIFF_BASE, s->sdram_size,
4303
                    (emiff_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
4304
    cpu_register_physical_memory(OMAP_IMIF_BASE, s->sram_size,
4305
                    (imif_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
4306

    
4307
    omap_clkm_init(0xfffece00, 0xe1008000, s);
4308

    
4309
    cpu_irq = arm_pic_init_cpu(s->env);
4310
    s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1,
4311
                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4312
                    omap_findclk(s, "arminth_ck"));
4313
    s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1,
4314
                    s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
4315
                    omap_findclk(s, "arminth_ck"));
4316
    s->irq[0] = s->ih[0]->pins;
4317
    s->irq[1] = s->ih[1]->pins;
4318

    
4319
    for (i = 0; i < 6; i ++)
4320
        dma_irqs[i] = s->irq[omap_dma_irq_map[i].ih][omap_dma_irq_map[i].intr];
4321
    s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
4322
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
4323

    
4324
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
4325
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
4326
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
4327
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
4328
    s->port[local    ].addr_valid = omap_validate_local_addr;
4329
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
4330

    
4331
    s->timer[0] = omap_mpu_timer_init(0xfffec500,
4332
                    s->irq[0][OMAP_INT_TIMER1],
4333
                    omap_findclk(s, "mputim_ck"));
4334
    s->timer[1] = omap_mpu_timer_init(0xfffec600,
4335
                    s->irq[0][OMAP_INT_TIMER2],
4336
                    omap_findclk(s, "mputim_ck"));
4337
    s->timer[2] = omap_mpu_timer_init(0xfffec700,
4338
                    s->irq[0][OMAP_INT_TIMER3],
4339
                    omap_findclk(s, "mputim_ck"));
4340

    
4341
    s->wdt = omap_wd_timer_init(0xfffec800,
4342
                    s->irq[0][OMAP_INT_WD_TIMER],
4343
                    omap_findclk(s, "armwdt_ck"));
4344

    
4345
    s->os_timer = omap_os_timer_init(0xfffb9000,
4346
                    s->irq[1][OMAP_INT_OS_TIMER],
4347
                    omap_findclk(s, "clk32-kHz"));
4348

    
4349
    s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
4350
                    omap_dma_get_lcdch(s->dma), ds, imif_base, emiff_base,
4351
                    omap_findclk(s, "lcd_ck"));
4352

    
4353
    omap_ulpd_pm_init(0xfffe0800, s);
4354
    omap_pin_cfg_init(0xfffe1000, s);
4355
    omap_id_init(s);
4356

    
4357
    omap_mpui_init(0xfffec900, s);
4358

    
4359
    s->private_tipb = omap_tipb_bridge_init(0xfffeca00,
4360
                    s->irq[0][OMAP_INT_BRIDGE_PRIV],
4361
                    omap_findclk(s, "tipb_ck"));
4362
    s->public_tipb = omap_tipb_bridge_init(0xfffed300,
4363
                    s->irq[0][OMAP_INT_BRIDGE_PUB],
4364
                    omap_findclk(s, "tipb_ck"));
4365

    
4366
    omap_tcmi_init(0xfffecc00, s);
4367

    
4368
    s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4369
                    omap_findclk(s, "uart1_ck"),
4370
                    serial_hds[0]);
4371
    s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4372
                    omap_findclk(s, "uart2_ck"),
4373
                    serial_hds[0] ? serial_hds[1] : 0);
4374
    s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4375
                    omap_findclk(s, "uart3_ck"),
4376
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4377

    
4378
    omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
4379
    omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
4380
    omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
4381

    
4382
    sdindex = drive_get_index(IF_SD, 0, 0);
4383
    if (sdindex == -1) {
4384
        fprintf(stderr, "qemu: missing SecureDigital device\n");
4385
        exit(1);
4386
    }
4387
    s->mmc = omap_mmc_init(0xfffb7800, drives_table[sdindex].bdrv,
4388
                    s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
4389
                    omap_findclk(s, "mmc_ck"));
4390

    
4391
    s->mpuio = omap_mpuio_init(0xfffb5000,
4392
                    s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
4393
                    s->wakeup, omap_findclk(s, "clk32-kHz"));
4394

    
4395
    s->gpio = omap_gpio_init(0xfffce000, s->irq[0][OMAP_INT_GPIO_BANK1],
4396
                    omap_findclk(s, "arm_gpio_ck"));
4397

    
4398
    s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
4399
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
4400

    
4401
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4402
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4403

    
4404
    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4405
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4406

    
4407
    s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
4408
                    omap_findclk(s, "clk32-kHz"));
4409

    
4410
    s->mcbsp1 = omap_mcbsp_init(0xfffb1800, &s->irq[1][OMAP_INT_McBSP1TX],
4411
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4412
    s->mcbsp2 = omap_mcbsp_init(0xfffb1000, &s->irq[0][OMAP_INT_310_McBSP2_TX],
4413
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4414
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
4415
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4416

    
4417
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
4418
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
4419

    
4420
    /* Register mappings not currenlty implemented:
4421
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4422
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4423
     * USB W2FC                fffb4000 - fffb47ff
4424
     * Camera Interface        fffb6800 - fffb6fff
4425
     * USB Host                fffba000 - fffba7ff
4426
     * FAC                fffba800 - fffbafff
4427
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4428
     * TIPB switches        fffbc800 - fffbcfff
4429
     * Mailbox                fffcf000 - fffcf7ff
4430
     * Local bus IF        fffec100 - fffec1ff
4431
     * Local bus MMU        fffec200 - fffec2ff
4432
     * DSP MMU                fffed200 - fffed2ff
4433
     */
4434

    
4435
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
4436
    omap_setup_mpui_io(s);
4437

    
4438
    qemu_register_reset(omap_mpu_reset, s);
4439

    
4440
    return s;
4441
}