Statistics
| Branch: | Revision:

root / hw / arm / omap1.c @ bd2be150

History | View | Annotate | Download (115.8 kB)

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

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

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

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

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

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

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

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

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

    
65
uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
66
{
67
    uint32_t ret;
68

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

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

    
81
/* MPU OS timers */
82
struct omap_mpu_timer_s {
83
    MemoryRegion iomem;
84
    qemu_irq irq;
85
    omap_clk clk;
86
    uint32_t val;
87
    int64_t time;
88
    QEMUTimer *timer;
89
    QEMUBH *tick;
90
    int64_t rate;
91
    int it_ena;
92

    
93
    int enable;
94
    int ptv;
95
    int ar;
96
    int st;
97
    uint32_t reset_val;
98
};
99

    
100
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
101
{
102
    uint64_t distance = qemu_get_clock_ns(vm_clock) - timer->time;
103

    
104
    if (timer->st && timer->enable && timer->rate)
105
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
106
                                     timer->rate, get_ticks_per_sec());
107
    else
108
        return timer->val;
109
}
110

    
111
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
112
{
113
    timer->val = omap_timer_read(timer);
114
    timer->time = qemu_get_clock_ns(vm_clock);
115
}
116

    
117
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
118
{
119
    int64_t expires;
120

    
121
    if (timer->enable && timer->st && timer->rate) {
122
        timer->val = timer->reset_val;        /* Should skip this on clk enable */
123
        expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
124
                           get_ticks_per_sec(), timer->rate);
125

    
126
        /* If timer expiry would be sooner than in about 1 ms and
127
         * auto-reload isn't set, then fire immediately.  This is a hack
128
         * to make systems like PalmOS run in acceptable time.  PalmOS
129
         * sets the interval to a very low value and polls the status bit
130
         * in a busy loop when it wants to sleep just a couple of CPU
131
         * ticks.  */
132
        if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
133
            qemu_mod_timer(timer->timer, timer->time + expires);
134
        else
135
            qemu_bh_schedule(timer->tick);
136
    } else
137
        qemu_del_timer(timer->timer);
138
}
139

    
140
static void omap_timer_fire(void *opaque)
141
{
142
    struct omap_mpu_timer_s *timer = opaque;
143

    
144
    if (!timer->ar) {
145
        timer->val = 0;
146
        timer->st = 0;
147
    }
148

    
149
    if (timer->it_ena)
150
        /* Edge-triggered irq */
151
        qemu_irq_pulse(timer->irq);
152
}
153

    
154
static void omap_timer_tick(void *opaque)
155
{
156
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
157

    
158
    omap_timer_sync(timer);
159
    omap_timer_fire(timer);
160
    omap_timer_update(timer);
161
}
162

    
163
static void omap_timer_clk_update(void *opaque, int line, int on)
164
{
165
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
166

    
167
    omap_timer_sync(timer);
168
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
169
    omap_timer_update(timer);
170
}
171

    
172
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
173
{
174
    omap_clk_adduser(timer->clk,
175
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
176
    timer->rate = omap_clk_getrate(timer->clk);
177
}
178

    
179
static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
180
                                    unsigned size)
181
{
182
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
183

    
184
    if (size != 4) {
185
        return omap_badwidth_read32(opaque, addr);
186
    }
187

    
188
    switch (addr) {
189
    case 0x00:        /* CNTL_TIMER */
190
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
191

    
192
    case 0x04:        /* LOAD_TIM */
193
        break;
194

    
195
    case 0x08:        /* READ_TIM */
196
        return omap_timer_read(s);
197
    }
198

    
199
    OMAP_BAD_REG(addr);
200
    return 0;
201
}
202

    
203
static void omap_mpu_timer_write(void *opaque, hwaddr addr,
204
                                 uint64_t value, unsigned size)
205
{
206
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
207

    
208
    if (size != 4) {
209
        return omap_badwidth_write32(opaque, addr, value);
210
    }
211

    
212
    switch (addr) {
213
    case 0x00:        /* CNTL_TIMER */
214
        omap_timer_sync(s);
215
        s->enable = (value >> 5) & 1;
216
        s->ptv = (value >> 2) & 7;
217
        s->ar = (value >> 1) & 1;
218
        s->st = value & 1;
219
        omap_timer_update(s);
220
        return;
221

    
222
    case 0x04:        /* LOAD_TIM */
223
        s->reset_val = value;
224
        return;
225

    
226
    case 0x08:        /* READ_TIM */
227
        OMAP_RO_REG(addr);
228
        break;
229

    
230
    default:
231
        OMAP_BAD_REG(addr);
232
    }
233
}
234

    
235
static const MemoryRegionOps omap_mpu_timer_ops = {
236
    .read = omap_mpu_timer_read,
237
    .write = omap_mpu_timer_write,
238
    .endianness = DEVICE_LITTLE_ENDIAN,
239
};
240

    
241
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
242
{
243
    qemu_del_timer(s->timer);
244
    s->enable = 0;
245
    s->reset_val = 31337;
246
    s->val = 0;
247
    s->ptv = 0;
248
    s->ar = 0;
249
    s->st = 0;
250
    s->it_ena = 1;
251
}
252

    
253
static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
254
                hwaddr base,
255
                qemu_irq irq, omap_clk clk)
256
{
257
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
258
            g_malloc0(sizeof(struct omap_mpu_timer_s));
259

    
260
    s->irq = irq;
261
    s->clk = clk;
262
    s->timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, s);
263
    s->tick = qemu_bh_new(omap_timer_fire, s);
264
    omap_mpu_timer_reset(s);
265
    omap_timer_clk_setup(s);
266

    
267
    memory_region_init_io(&s->iomem, &omap_mpu_timer_ops, s,
268
                          "omap-mpu-timer", 0x100);
269

    
270
    memory_region_add_subregion(system_memory, base, &s->iomem);
271

    
272
    return s;
273
}
274

    
275
/* Watchdog timer */
276
struct omap_watchdog_timer_s {
277
    struct omap_mpu_timer_s timer;
278
    MemoryRegion iomem;
279
    uint8_t last_wr;
280
    int mode;
281
    int free;
282
    int reset;
283
};
284

    
285
static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
286
                                   unsigned size)
287
{
288
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
289

    
290
    if (size != 2) {
291
        return omap_badwidth_read16(opaque, addr);
292
    }
293

    
294
    switch (addr) {
295
    case 0x00:        /* CNTL_TIMER */
296
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
297
                (s->timer.st << 7) | (s->free << 1);
298

    
299
    case 0x04:        /* READ_TIMER */
300
        return omap_timer_read(&s->timer);
301

    
302
    case 0x08:        /* TIMER_MODE */
303
        return s->mode << 15;
304
    }
305

    
306
    OMAP_BAD_REG(addr);
307
    return 0;
308
}
309

    
310
static void omap_wd_timer_write(void *opaque, hwaddr addr,
311
                                uint64_t value, unsigned size)
312
{
313
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
314

    
315
    if (size != 2) {
316
        return omap_badwidth_write16(opaque, addr, value);
317
    }
318

    
319
    switch (addr) {
320
    case 0x00:        /* CNTL_TIMER */
321
        omap_timer_sync(&s->timer);
322
        s->timer.ptv = (value >> 9) & 7;
323
        s->timer.ar = (value >> 8) & 1;
324
        s->timer.st = (value >> 7) & 1;
325
        s->free = (value >> 1) & 1;
326
        omap_timer_update(&s->timer);
327
        break;
328

    
329
    case 0x04:        /* LOAD_TIMER */
330
        s->timer.reset_val = value & 0xffff;
331
        break;
332

    
333
    case 0x08:        /* TIMER_MODE */
334
        if (!s->mode && ((value >> 15) & 1))
335
            omap_clk_get(s->timer.clk);
336
        s->mode |= (value >> 15) & 1;
337
        if (s->last_wr == 0xf5) {
338
            if ((value & 0xff) == 0xa0) {
339
                if (s->mode) {
340
                    s->mode = 0;
341
                    omap_clk_put(s->timer.clk);
342
                }
343
            } else {
344
                /* XXX: on T|E hardware somehow this has no effect,
345
                 * on Zire 71 it works as specified.  */
346
                s->reset = 1;
347
                qemu_system_reset_request();
348
            }
349
        }
350
        s->last_wr = value & 0xff;
351
        break;
352

    
353
    default:
354
        OMAP_BAD_REG(addr);
355
    }
356
}
357

    
358
static const MemoryRegionOps omap_wd_timer_ops = {
359
    .read = omap_wd_timer_read,
360
    .write = omap_wd_timer_write,
361
    .endianness = DEVICE_NATIVE_ENDIAN,
362
};
363

    
364
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
365
{
366
    qemu_del_timer(s->timer.timer);
367
    if (!s->mode)
368
        omap_clk_get(s->timer.clk);
369
    s->mode = 1;
370
    s->free = 1;
371
    s->reset = 0;
372
    s->timer.enable = 1;
373
    s->timer.it_ena = 1;
374
    s->timer.reset_val = 0xffff;
375
    s->timer.val = 0;
376
    s->timer.st = 0;
377
    s->timer.ptv = 0;
378
    s->timer.ar = 0;
379
    omap_timer_update(&s->timer);
380
}
381

    
382
static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
383
                hwaddr base,
384
                qemu_irq irq, omap_clk clk)
385
{
386
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
387
            g_malloc0(sizeof(struct omap_watchdog_timer_s));
388

    
389
    s->timer.irq = irq;
390
    s->timer.clk = clk;
391
    s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
392
    omap_wd_timer_reset(s);
393
    omap_timer_clk_setup(&s->timer);
394

    
395
    memory_region_init_io(&s->iomem, &omap_wd_timer_ops, s,
396
                          "omap-wd-timer", 0x100);
397
    memory_region_add_subregion(memory, base, &s->iomem);
398

    
399
    return s;
400
}
401

    
402
/* 32-kHz timer */
403
struct omap_32khz_timer_s {
404
    struct omap_mpu_timer_s timer;
405
    MemoryRegion iomem;
406
};
407

    
408
static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
409
                                   unsigned size)
410
{
411
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
412
    int offset = addr & OMAP_MPUI_REG_MASK;
413

    
414
    if (size != 4) {
415
        return omap_badwidth_read32(opaque, addr);
416
    }
417

    
418
    switch (offset) {
419
    case 0x00:        /* TVR */
420
        return s->timer.reset_val;
421

    
422
    case 0x04:        /* TCR */
423
        return omap_timer_read(&s->timer);
424

    
425
    case 0x08:        /* CR */
426
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
427

    
428
    default:
429
        break;
430
    }
431
    OMAP_BAD_REG(addr);
432
    return 0;
433
}
434

    
435
static void omap_os_timer_write(void *opaque, hwaddr addr,
436
                                uint64_t value, unsigned size)
437
{
438
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
439
    int offset = addr & OMAP_MPUI_REG_MASK;
440

    
441
    if (size != 4) {
442
        return omap_badwidth_write32(opaque, addr, value);
443
    }
444

    
445
    switch (offset) {
446
    case 0x00:        /* TVR */
447
        s->timer.reset_val = value & 0x00ffffff;
448
        break;
449

    
450
    case 0x04:        /* TCR */
451
        OMAP_RO_REG(addr);
452
        break;
453

    
454
    case 0x08:        /* CR */
455
        s->timer.ar = (value >> 3) & 1;
456
        s->timer.it_ena = (value >> 2) & 1;
457
        if (s->timer.st != (value & 1) || (value & 2)) {
458
            omap_timer_sync(&s->timer);
459
            s->timer.enable = value & 1;
460
            s->timer.st = value & 1;
461
            omap_timer_update(&s->timer);
462
        }
463
        break;
464

    
465
    default:
466
        OMAP_BAD_REG(addr);
467
    }
468
}
469

    
470
static const MemoryRegionOps omap_os_timer_ops = {
471
    .read = omap_os_timer_read,
472
    .write = omap_os_timer_write,
473
    .endianness = DEVICE_NATIVE_ENDIAN,
474
};
475

    
476
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
477
{
478
    qemu_del_timer(s->timer.timer);
479
    s->timer.enable = 0;
480
    s->timer.it_ena = 0;
481
    s->timer.reset_val = 0x00ffffff;
482
    s->timer.val = 0;
483
    s->timer.st = 0;
484
    s->timer.ptv = 0;
485
    s->timer.ar = 1;
486
}
487

    
488
static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
489
                hwaddr base,
490
                qemu_irq irq, omap_clk clk)
491
{
492
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
493
            g_malloc0(sizeof(struct omap_32khz_timer_s));
494

    
495
    s->timer.irq = irq;
496
    s->timer.clk = clk;
497
    s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
498
    omap_os_timer_reset(s);
499
    omap_timer_clk_setup(&s->timer);
500

    
501
    memory_region_init_io(&s->iomem, &omap_os_timer_ops, s,
502
                          "omap-os-timer", 0x800);
503
    memory_region_add_subregion(memory, base, &s->iomem);
504

    
505
    return s;
506
}
507

    
508
/* Ultra Low-Power Device Module */
509
static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
510
                                  unsigned size)
511
{
512
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
513
    uint16_t ret;
514

    
515
    if (size != 2) {
516
        return omap_badwidth_read16(opaque, addr);
517
    }
518

    
519
    switch (addr) {
520
    case 0x14:        /* IT_STATUS */
521
        ret = s->ulpd_pm_regs[addr >> 2];
522
        s->ulpd_pm_regs[addr >> 2] = 0;
523
        qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
524
        return ret;
525

    
526
    case 0x18:        /* Reserved */
527
    case 0x1c:        /* Reserved */
528
    case 0x20:        /* Reserved */
529
    case 0x28:        /* Reserved */
530
    case 0x2c:        /* Reserved */
531
        OMAP_BAD_REG(addr);
532
        /* fall through */
533
    case 0x00:        /* COUNTER_32_LSB */
534
    case 0x04:        /* COUNTER_32_MSB */
535
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
536
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
537
    case 0x10:        /* GAUGING_CTRL */
538
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
539
    case 0x30:        /* CLOCK_CTRL */
540
    case 0x34:        /* SOFT_REQ */
541
    case 0x38:        /* COUNTER_32_FIQ */
542
    case 0x3c:        /* DPLL_CTRL */
543
    case 0x40:        /* STATUS_REQ */
544
        /* XXX: check clk::usecount state for every clock */
545
    case 0x48:        /* LOCL_TIME */
546
    case 0x4c:        /* APLL_CTRL */
547
    case 0x50:        /* POWER_CTRL */
548
        return s->ulpd_pm_regs[addr >> 2];
549
    }
550

    
551
    OMAP_BAD_REG(addr);
552
    return 0;
553
}
554

    
555
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
556
                uint16_t diff, uint16_t value)
557
{
558
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
559
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
560
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
561
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
562
}
563

    
564
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
565
                uint16_t diff, uint16_t value)
566
{
567
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
568
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
569
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
570
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
571
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
572
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
573
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
574
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
575
}
576

    
577
static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
578
                               uint64_t value, unsigned size)
579
{
580
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
581
    int64_t now, ticks;
582
    int div, mult;
583
    static const int bypass_div[4] = { 1, 2, 4, 4 };
584
    uint16_t diff;
585

    
586
    if (size != 2) {
587
        return omap_badwidth_write16(opaque, addr, value);
588
    }
589

    
590
    switch (addr) {
591
    case 0x00:        /* COUNTER_32_LSB */
592
    case 0x04:        /* COUNTER_32_MSB */
593
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
594
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
595
    case 0x14:        /* IT_STATUS */
596
    case 0x40:        /* STATUS_REQ */
597
        OMAP_RO_REG(addr);
598
        break;
599

    
600
    case 0x10:        /* GAUGING_CTRL */
601
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
602
        if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
603
            now = qemu_get_clock_ns(vm_clock);
604

    
605
            if (value & 1)
606
                s->ulpd_gauge_start = now;
607
            else {
608
                now -= s->ulpd_gauge_start;
609

    
610
                /* 32-kHz ticks */
611
                ticks = muldiv64(now, 32768, get_ticks_per_sec());
612
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
613
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
614
                if (ticks >> 32)        /* OVERFLOW_32K */
615
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
616

    
617
                /* High frequency ticks */
618
                ticks = muldiv64(now, 12000000, get_ticks_per_sec());
619
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
620
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
621
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
622
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
623

    
624
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;        /* IT_GAUGING */
625
                qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
626
            }
627
        }
628
        s->ulpd_pm_regs[addr >> 2] = value;
629
        break;
630

    
631
    case 0x18:        /* Reserved */
632
    case 0x1c:        /* Reserved */
633
    case 0x20:        /* Reserved */
634
    case 0x28:        /* Reserved */
635
    case 0x2c:        /* Reserved */
636
        OMAP_BAD_REG(addr);
637
        /* fall through */
638
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
639
    case 0x38:        /* COUNTER_32_FIQ */
640
    case 0x48:        /* LOCL_TIME */
641
    case 0x50:        /* POWER_CTRL */
642
        s->ulpd_pm_regs[addr >> 2] = value;
643
        break;
644

    
645
    case 0x30:        /* CLOCK_CTRL */
646
        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
647
        s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
648
        omap_ulpd_clk_update(s, diff, value);
649
        break;
650

    
651
    case 0x34:        /* SOFT_REQ */
652
        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
653
        s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
654
        omap_ulpd_req_update(s, diff, value);
655
        break;
656

    
657
    case 0x3c:        /* DPLL_CTRL */
658
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
659
         * omitted altogether, probably a typo.  */
660
        /* This register has identical semantics with DPLL(1:3) control
661
         * registers, see omap_dpll_write() */
662
        diff = s->ulpd_pm_regs[addr >> 2] & value;
663
        s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
664
        if (diff & (0x3ff << 2)) {
665
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
666
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
667
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
668
            } else {
669
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
670
                mult = 1;
671
            }
672
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
673
        }
674

    
675
        /* Enter the desired mode.  */
676
        s->ulpd_pm_regs[addr >> 2] =
677
                (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
678
                ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
679

    
680
        /* Act as if the lock is restored.  */
681
        s->ulpd_pm_regs[addr >> 2] |= 2;
682
        break;
683

    
684
    case 0x4c:        /* APLL_CTRL */
685
        diff = s->ulpd_pm_regs[addr >> 2] & value;
686
        s->ulpd_pm_regs[addr >> 2] = value & 0xf;
687
        if (diff & (1 << 0))                                /* APLL_NDPLL_SWITCH */
688
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
689
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
690
        break;
691

    
692
    default:
693
        OMAP_BAD_REG(addr);
694
    }
695
}
696

    
697
static const MemoryRegionOps omap_ulpd_pm_ops = {
698
    .read = omap_ulpd_pm_read,
699
    .write = omap_ulpd_pm_write,
700
    .endianness = DEVICE_NATIVE_ENDIAN,
701
};
702

    
703
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
704
{
705
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
706
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
707
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
708
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
709
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
710
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
711
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
712
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
713
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
714
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
715
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
716
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
717
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
718
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
719
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
720
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
721
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
722
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
723
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
724
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
725
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
726
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
727
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
728
}
729

    
730
static void omap_ulpd_pm_init(MemoryRegion *system_memory,
731
                hwaddr base,
732
                struct omap_mpu_state_s *mpu)
733
{
734
    memory_region_init_io(&mpu->ulpd_pm_iomem, &omap_ulpd_pm_ops, mpu,
735
                          "omap-ulpd-pm", 0x800);
736
    memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
737
    omap_ulpd_pm_reset(mpu);
738
}
739

    
740
/* OMAP Pin Configuration */
741
static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
742
                                  unsigned size)
743
{
744
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
745

    
746
    if (size != 4) {
747
        return omap_badwidth_read32(opaque, addr);
748
    }
749

    
750
    switch (addr) {
751
    case 0x00:        /* FUNC_MUX_CTRL_0 */
752
    case 0x04:        /* FUNC_MUX_CTRL_1 */
753
    case 0x08:        /* FUNC_MUX_CTRL_2 */
754
        return s->func_mux_ctrl[addr >> 2];
755

    
756
    case 0x0c:        /* COMP_MODE_CTRL_0 */
757
        return s->comp_mode_ctrl[0];
758

    
759
    case 0x10:        /* FUNC_MUX_CTRL_3 */
760
    case 0x14:        /* FUNC_MUX_CTRL_4 */
761
    case 0x18:        /* FUNC_MUX_CTRL_5 */
762
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
763
    case 0x20:        /* FUNC_MUX_CTRL_7 */
764
    case 0x24:        /* FUNC_MUX_CTRL_8 */
765
    case 0x28:        /* FUNC_MUX_CTRL_9 */
766
    case 0x2c:        /* FUNC_MUX_CTRL_A */
767
    case 0x30:        /* FUNC_MUX_CTRL_B */
768
    case 0x34:        /* FUNC_MUX_CTRL_C */
769
    case 0x38:        /* FUNC_MUX_CTRL_D */
770
        return s->func_mux_ctrl[(addr >> 2) - 1];
771

    
772
    case 0x40:        /* PULL_DWN_CTRL_0 */
773
    case 0x44:        /* PULL_DWN_CTRL_1 */
774
    case 0x48:        /* PULL_DWN_CTRL_2 */
775
    case 0x4c:        /* PULL_DWN_CTRL_3 */
776
        return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
777

    
778
    case 0x50:        /* GATE_INH_CTRL_0 */
779
        return s->gate_inh_ctrl[0];
780

    
781
    case 0x60:        /* VOLTAGE_CTRL_0 */
782
        return s->voltage_ctrl[0];
783

    
784
    case 0x70:        /* TEST_DBG_CTRL_0 */
785
        return s->test_dbg_ctrl[0];
786

    
787
    case 0x80:        /* MOD_CONF_CTRL_0 */
788
        return s->mod_conf_ctrl[0];
789
    }
790

    
791
    OMAP_BAD_REG(addr);
792
    return 0;
793
}
794

    
795
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
796
                uint32_t diff, uint32_t value)
797
{
798
    if (s->compat1509) {
799
        if (diff & (1 << 9))                        /* BLUETOOTH */
800
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
801
                            (~value >> 9) & 1);
802
        if (diff & (1 << 7))                        /* USB.CLKO */
803
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
804
                            (value >> 7) & 1);
805
    }
806
}
807

    
808
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
809
                uint32_t diff, uint32_t value)
810
{
811
    if (s->compat1509) {
812
        if (diff & (1 << 31))                        /* MCBSP3_CLK_HIZ_DI */
813
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
814
                            (value >> 31) & 1);
815
        if (diff & (1 << 1))                        /* CLK32K */
816
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
817
                            (~value >> 1) & 1);
818
    }
819
}
820

    
821
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
822
                uint32_t diff, uint32_t value)
823
{
824
    if (diff & (1 << 31))                        /* CONF_MOD_UART3_CLK_MODE_R */
825
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
826
                         omap_findclk(s, ((value >> 31) & 1) ?
827
                                 "ck_48m" : "armper_ck"));
828
    if (diff & (1 << 30))                        /* CONF_MOD_UART2_CLK_MODE_R */
829
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
830
                         omap_findclk(s, ((value >> 30) & 1) ?
831
                                 "ck_48m" : "armper_ck"));
832
    if (diff & (1 << 29))                        /* CONF_MOD_UART1_CLK_MODE_R */
833
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
834
                         omap_findclk(s, ((value >> 29) & 1) ?
835
                                 "ck_48m" : "armper_ck"));
836
    if (diff & (1 << 23))                        /* CONF_MOD_MMC_SD_CLK_REQ_R */
837
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
838
                         omap_findclk(s, ((value >> 23) & 1) ?
839
                                 "ck_48m" : "armper_ck"));
840
    if (diff & (1 << 12))                        /* CONF_MOD_COM_MCLK_12_48_S */
841
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
842
                         omap_findclk(s, ((value >> 12) & 1) ?
843
                                 "ck_48m" : "armper_ck"));
844
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
845
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
846
}
847

    
848
static void omap_pin_cfg_write(void *opaque, hwaddr addr,
849
                               uint64_t value, unsigned size)
850
{
851
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
852
    uint32_t diff;
853

    
854
    if (size != 4) {
855
        return omap_badwidth_write32(opaque, addr, value);
856
    }
857

    
858
    switch (addr) {
859
    case 0x00:        /* FUNC_MUX_CTRL_0 */
860
        diff = s->func_mux_ctrl[addr >> 2] ^ value;
861
        s->func_mux_ctrl[addr >> 2] = value;
862
        omap_pin_funcmux0_update(s, diff, value);
863
        return;
864

    
865
    case 0x04:        /* FUNC_MUX_CTRL_1 */
866
        diff = s->func_mux_ctrl[addr >> 2] ^ value;
867
        s->func_mux_ctrl[addr >> 2] = value;
868
        omap_pin_funcmux1_update(s, diff, value);
869
        return;
870

    
871
    case 0x08:        /* FUNC_MUX_CTRL_2 */
872
        s->func_mux_ctrl[addr >> 2] = value;
873
        return;
874

    
875
    case 0x0c:        /* COMP_MODE_CTRL_0 */
876
        s->comp_mode_ctrl[0] = value;
877
        s->compat1509 = (value != 0x0000eaef);
878
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
879
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
880
        return;
881

    
882
    case 0x10:        /* FUNC_MUX_CTRL_3 */
883
    case 0x14:        /* FUNC_MUX_CTRL_4 */
884
    case 0x18:        /* FUNC_MUX_CTRL_5 */
885
    case 0x1c:        /* FUNC_MUX_CTRL_6 */
886
    case 0x20:        /* FUNC_MUX_CTRL_7 */
887
    case 0x24:        /* FUNC_MUX_CTRL_8 */
888
    case 0x28:        /* FUNC_MUX_CTRL_9 */
889
    case 0x2c:        /* FUNC_MUX_CTRL_A */
890
    case 0x30:        /* FUNC_MUX_CTRL_B */
891
    case 0x34:        /* FUNC_MUX_CTRL_C */
892
    case 0x38:        /* FUNC_MUX_CTRL_D */
893
        s->func_mux_ctrl[(addr >> 2) - 1] = value;
894
        return;
895

    
896
    case 0x40:        /* PULL_DWN_CTRL_0 */
897
    case 0x44:        /* PULL_DWN_CTRL_1 */
898
    case 0x48:        /* PULL_DWN_CTRL_2 */
899
    case 0x4c:        /* PULL_DWN_CTRL_3 */
900
        s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
901
        return;
902

    
903
    case 0x50:        /* GATE_INH_CTRL_0 */
904
        s->gate_inh_ctrl[0] = value;
905
        return;
906

    
907
    case 0x60:        /* VOLTAGE_CTRL_0 */
908
        s->voltage_ctrl[0] = value;
909
        return;
910

    
911
    case 0x70:        /* TEST_DBG_CTRL_0 */
912
        s->test_dbg_ctrl[0] = value;
913
        return;
914

    
915
    case 0x80:        /* MOD_CONF_CTRL_0 */
916
        diff = s->mod_conf_ctrl[0] ^ value;
917
        s->mod_conf_ctrl[0] = value;
918
        omap_pin_modconf1_update(s, diff, value);
919
        return;
920

    
921
    default:
922
        OMAP_BAD_REG(addr);
923
    }
924
}
925

    
926
static const MemoryRegionOps omap_pin_cfg_ops = {
927
    .read = omap_pin_cfg_read,
928
    .write = omap_pin_cfg_write,
929
    .endianness = DEVICE_NATIVE_ENDIAN,
930
};
931

    
932
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
933
{
934
    /* Start in Compatibility Mode.  */
935
    mpu->compat1509 = 1;
936
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
937
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
938
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
939
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
940
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
941
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
942
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
943
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
944
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
945
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
946
}
947

    
948
static void omap_pin_cfg_init(MemoryRegion *system_memory,
949
                hwaddr base,
950
                struct omap_mpu_state_s *mpu)
951
{
952
    memory_region_init_io(&mpu->pin_cfg_iomem, &omap_pin_cfg_ops, mpu,
953
                          "omap-pin-cfg", 0x800);
954
    memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
955
    omap_pin_cfg_reset(mpu);
956
}
957

    
958
/* Device Identification, Die Identification */
959
static uint64_t omap_id_read(void *opaque, hwaddr addr,
960
                             unsigned size)
961
{
962
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
963

    
964
    if (size != 4) {
965
        return omap_badwidth_read32(opaque, addr);
966
    }
967

    
968
    switch (addr) {
969
    case 0xfffe1800:        /* DIE_ID_LSB */
970
        return 0xc9581f0e;
971
    case 0xfffe1804:        /* DIE_ID_MSB */
972
        return 0xa8858bfa;
973

    
974
    case 0xfffe2000:        /* PRODUCT_ID_LSB */
975
        return 0x00aaaafc;
976
    case 0xfffe2004:        /* PRODUCT_ID_MSB */
977
        return 0xcafeb574;
978

    
979
    case 0xfffed400:        /* JTAG_ID_LSB */
980
        switch (s->mpu_model) {
981
        case omap310:
982
            return 0x03310315;
983
        case omap1510:
984
            return 0x03310115;
985
        default:
986
            hw_error("%s: bad mpu model\n", __FUNCTION__);
987
        }
988
        break;
989

    
990
    case 0xfffed404:        /* JTAG_ID_MSB */
991
        switch (s->mpu_model) {
992
        case omap310:
993
            return 0xfb57402f;
994
        case omap1510:
995
            return 0xfb47002f;
996
        default:
997
            hw_error("%s: bad mpu model\n", __FUNCTION__);
998
        }
999
        break;
1000
    }
1001

    
1002
    OMAP_BAD_REG(addr);
1003
    return 0;
1004
}
1005

    
1006
static void omap_id_write(void *opaque, hwaddr addr,
1007
                          uint64_t value, unsigned size)
1008
{
1009
    if (size != 4) {
1010
        return omap_badwidth_write32(opaque, addr, value);
1011
    }
1012

    
1013
    OMAP_BAD_REG(addr);
1014
}
1015

    
1016
static const MemoryRegionOps omap_id_ops = {
1017
    .read = omap_id_read,
1018
    .write = omap_id_write,
1019
    .endianness = DEVICE_NATIVE_ENDIAN,
1020
};
1021

    
1022
static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
1023
{
1024
    memory_region_init_io(&mpu->id_iomem, &omap_id_ops, mpu,
1025
                          "omap-id", 0x100000000ULL);
1026
    memory_region_init_alias(&mpu->id_iomem_e18, "omap-id-e18", &mpu->id_iomem,
1027
                             0xfffe1800, 0x800);
1028
    memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
1029
    memory_region_init_alias(&mpu->id_iomem_ed4, "omap-id-ed4", &mpu->id_iomem,
1030
                             0xfffed400, 0x100);
1031
    memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
1032
    if (!cpu_is_omap15xx(mpu)) {
1033
        memory_region_init_alias(&mpu->id_iomem_ed4, "omap-id-e20",
1034
                                 &mpu->id_iomem, 0xfffe2000, 0x800);
1035
        memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
1036
    }
1037
}
1038

    
1039
/* MPUI Control (Dummy) */
1040
static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
1041
                               unsigned size)
1042
{
1043
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1044

    
1045
    if (size != 4) {
1046
        return omap_badwidth_read32(opaque, addr);
1047
    }
1048

    
1049
    switch (addr) {
1050
    case 0x00:        /* CTRL */
1051
        return s->mpui_ctrl;
1052
    case 0x04:        /* DEBUG_ADDR */
1053
        return 0x01ffffff;
1054
    case 0x08:        /* DEBUG_DATA */
1055
        return 0xffffffff;
1056
    case 0x0c:        /* DEBUG_FLAG */
1057
        return 0x00000800;
1058
    case 0x10:        /* STATUS */
1059
        return 0x00000000;
1060

    
1061
    /* Not in OMAP310 */
1062
    case 0x14:        /* DSP_STATUS */
1063
    case 0x18:        /* DSP_BOOT_CONFIG */
1064
        return 0x00000000;
1065
    case 0x1c:        /* DSP_MPUI_CONFIG */
1066
        return 0x0000ffff;
1067
    }
1068

    
1069
    OMAP_BAD_REG(addr);
1070
    return 0;
1071
}
1072

    
1073
static void omap_mpui_write(void *opaque, hwaddr addr,
1074
                            uint64_t value, unsigned size)
1075
{
1076
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1077

    
1078
    if (size != 4) {
1079
        return omap_badwidth_write32(opaque, addr, value);
1080
    }
1081

    
1082
    switch (addr) {
1083
    case 0x00:        /* CTRL */
1084
        s->mpui_ctrl = value & 0x007fffff;
1085
        break;
1086

    
1087
    case 0x04:        /* DEBUG_ADDR */
1088
    case 0x08:        /* DEBUG_DATA */
1089
    case 0x0c:        /* DEBUG_FLAG */
1090
    case 0x10:        /* STATUS */
1091
    /* Not in OMAP310 */
1092
    case 0x14:        /* DSP_STATUS */
1093
        OMAP_RO_REG(addr);
1094
        break;
1095
    case 0x18:        /* DSP_BOOT_CONFIG */
1096
    case 0x1c:        /* DSP_MPUI_CONFIG */
1097
        break;
1098

    
1099
    default:
1100
        OMAP_BAD_REG(addr);
1101
    }
1102
}
1103

    
1104
static const MemoryRegionOps omap_mpui_ops = {
1105
    .read = omap_mpui_read,
1106
    .write = omap_mpui_write,
1107
    .endianness = DEVICE_NATIVE_ENDIAN,
1108
};
1109

    
1110
static void omap_mpui_reset(struct omap_mpu_state_s *s)
1111
{
1112
    s->mpui_ctrl = 0x0003ff1b;
1113
}
1114

    
1115
static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
1116
                struct omap_mpu_state_s *mpu)
1117
{
1118
    memory_region_init_io(&mpu->mpui_iomem, &omap_mpui_ops, mpu,
1119
                          "omap-mpui", 0x100);
1120
    memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
1121

    
1122
    omap_mpui_reset(mpu);
1123
}
1124

    
1125
/* TIPB Bridges */
1126
struct omap_tipb_bridge_s {
1127
    qemu_irq abort;
1128
    MemoryRegion iomem;
1129

    
1130
    int width_intr;
1131
    uint16_t control;
1132
    uint16_t alloc;
1133
    uint16_t buffer;
1134
    uint16_t enh_control;
1135
};
1136

    
1137
static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
1138
                                      unsigned size)
1139
{
1140
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1141

    
1142
    if (size < 2) {
1143
        return omap_badwidth_read16(opaque, addr);
1144
    }
1145

    
1146
    switch (addr) {
1147
    case 0x00:        /* TIPB_CNTL */
1148
        return s->control;
1149
    case 0x04:        /* TIPB_BUS_ALLOC */
1150
        return s->alloc;
1151
    case 0x08:        /* MPU_TIPB_CNTL */
1152
        return s->buffer;
1153
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1154
        return s->enh_control;
1155
    case 0x10:        /* ADDRESS_DBG */
1156
    case 0x14:        /* DATA_DEBUG_LOW */
1157
    case 0x18:        /* DATA_DEBUG_HIGH */
1158
        return 0xffff;
1159
    case 0x1c:        /* DEBUG_CNTR_SIG */
1160
        return 0x00f8;
1161
    }
1162

    
1163
    OMAP_BAD_REG(addr);
1164
    return 0;
1165
}
1166

    
1167
static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
1168
                                   uint64_t value, unsigned size)
1169
{
1170
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1171

    
1172
    if (size < 2) {
1173
        return omap_badwidth_write16(opaque, addr, value);
1174
    }
1175

    
1176
    switch (addr) {
1177
    case 0x00:        /* TIPB_CNTL */
1178
        s->control = value & 0xffff;
1179
        break;
1180

    
1181
    case 0x04:        /* TIPB_BUS_ALLOC */
1182
        s->alloc = value & 0x003f;
1183
        break;
1184

    
1185
    case 0x08:        /* MPU_TIPB_CNTL */
1186
        s->buffer = value & 0x0003;
1187
        break;
1188

    
1189
    case 0x0c:        /* ENHANCED_TIPB_CNTL */
1190
        s->width_intr = !(value & 2);
1191
        s->enh_control = value & 0x000f;
1192
        break;
1193

    
1194
    case 0x10:        /* ADDRESS_DBG */
1195
    case 0x14:        /* DATA_DEBUG_LOW */
1196
    case 0x18:        /* DATA_DEBUG_HIGH */
1197
    case 0x1c:        /* DEBUG_CNTR_SIG */
1198
        OMAP_RO_REG(addr);
1199
        break;
1200

    
1201
    default:
1202
        OMAP_BAD_REG(addr);
1203
    }
1204
}
1205

    
1206
static const MemoryRegionOps omap_tipb_bridge_ops = {
1207
    .read = omap_tipb_bridge_read,
1208
    .write = omap_tipb_bridge_write,
1209
    .endianness = DEVICE_NATIVE_ENDIAN,
1210
};
1211

    
1212
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
1213
{
1214
    s->control = 0xffff;
1215
    s->alloc = 0x0009;
1216
    s->buffer = 0x0000;
1217
    s->enh_control = 0x000f;
1218
}
1219

    
1220
static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
1221
    MemoryRegion *memory, hwaddr base,
1222
    qemu_irq abort_irq, omap_clk clk)
1223
{
1224
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
1225
            g_malloc0(sizeof(struct omap_tipb_bridge_s));
1226

    
1227
    s->abort = abort_irq;
1228
    omap_tipb_bridge_reset(s);
1229

    
1230
    memory_region_init_io(&s->iomem, &omap_tipb_bridge_ops, s,
1231
                          "omap-tipb-bridge", 0x100);
1232
    memory_region_add_subregion(memory, base, &s->iomem);
1233

    
1234
    return s;
1235
}
1236

    
1237
/* Dummy Traffic Controller's Memory Interface */
1238
static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
1239
                               unsigned size)
1240
{
1241
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1242
    uint32_t ret;
1243

    
1244
    if (size != 4) {
1245
        return omap_badwidth_read32(opaque, addr);
1246
    }
1247

    
1248
    switch (addr) {
1249
    case 0x00:        /* IMIF_PRIO */
1250
    case 0x04:        /* EMIFS_PRIO */
1251
    case 0x08:        /* EMIFF_PRIO */
1252
    case 0x0c:        /* EMIFS_CONFIG */
1253
    case 0x10:        /* EMIFS_CS0_CONFIG */
1254
    case 0x14:        /* EMIFS_CS1_CONFIG */
1255
    case 0x18:        /* EMIFS_CS2_CONFIG */
1256
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1257
    case 0x24:        /* EMIFF_MRS */
1258
    case 0x28:        /* TIMEOUT1 */
1259
    case 0x2c:        /* TIMEOUT2 */
1260
    case 0x30:        /* TIMEOUT3 */
1261
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1262
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1263
        return s->tcmi_regs[addr >> 2];
1264

    
1265
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1266
        ret = s->tcmi_regs[addr >> 2];
1267
        s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
1268
        /* XXX: We can try using the VGA_DIRTY flag for this */
1269
        return ret;
1270
    }
1271

    
1272
    OMAP_BAD_REG(addr);
1273
    return 0;
1274
}
1275

    
1276
static void omap_tcmi_write(void *opaque, hwaddr addr,
1277
                            uint64_t value, unsigned size)
1278
{
1279
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1280

    
1281
    if (size != 4) {
1282
        return omap_badwidth_write32(opaque, addr, value);
1283
    }
1284

    
1285
    switch (addr) {
1286
    case 0x00:        /* IMIF_PRIO */
1287
    case 0x04:        /* EMIFS_PRIO */
1288
    case 0x08:        /* EMIFF_PRIO */
1289
    case 0x10:        /* EMIFS_CS0_CONFIG */
1290
    case 0x14:        /* EMIFS_CS1_CONFIG */
1291
    case 0x18:        /* EMIFS_CS2_CONFIG */
1292
    case 0x1c:        /* EMIFS_CS3_CONFIG */
1293
    case 0x20:        /* EMIFF_SDRAM_CONFIG */
1294
    case 0x24:        /* EMIFF_MRS */
1295
    case 0x28:        /* TIMEOUT1 */
1296
    case 0x2c:        /* TIMEOUT2 */
1297
    case 0x30:        /* TIMEOUT3 */
1298
    case 0x3c:        /* EMIFF_SDRAM_CONFIG_2 */
1299
    case 0x40:        /* EMIFS_CFG_DYN_WAIT */
1300
        s->tcmi_regs[addr >> 2] = value;
1301
        break;
1302
    case 0x0c:        /* EMIFS_CONFIG */
1303
        s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
1304
        break;
1305

    
1306
    default:
1307
        OMAP_BAD_REG(addr);
1308
    }
1309
}
1310

    
1311
static const MemoryRegionOps omap_tcmi_ops = {
1312
    .read = omap_tcmi_read,
1313
    .write = omap_tcmi_write,
1314
    .endianness = DEVICE_NATIVE_ENDIAN,
1315
};
1316

    
1317
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
1318
{
1319
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
1320
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
1321
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
1322
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
1323
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
1324
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
1325
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
1326
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
1327
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
1328
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
1329
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
1330
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
1331
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
1332
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
1333
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
1334
}
1335

    
1336
static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
1337
                struct omap_mpu_state_s *mpu)
1338
{
1339
    memory_region_init_io(&mpu->tcmi_iomem, &omap_tcmi_ops, mpu,
1340
                          "omap-tcmi", 0x100);
1341
    memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
1342
    omap_tcmi_reset(mpu);
1343
}
1344

    
1345
/* Digital phase-locked loops control */
1346
struct dpll_ctl_s {
1347
    MemoryRegion iomem;
1348
    uint16_t mode;
1349
    omap_clk dpll;
1350
};
1351

    
1352
static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
1353
                               unsigned size)
1354
{
1355
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1356

    
1357
    if (size != 2) {
1358
        return omap_badwidth_read16(opaque, addr);
1359
    }
1360

    
1361
    if (addr == 0x00)        /* CTL_REG */
1362
        return s->mode;
1363

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

    
1368
static void omap_dpll_write(void *opaque, hwaddr addr,
1369
                            uint64_t value, unsigned size)
1370
{
1371
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1372
    uint16_t diff;
1373
    static const int bypass_div[4] = { 1, 2, 4, 4 };
1374
    int div, mult;
1375

    
1376
    if (size != 2) {
1377
        return omap_badwidth_write16(opaque, addr, value);
1378
    }
1379

    
1380
    if (addr == 0x00) {        /* CTL_REG */
1381
        /* See omap_ulpd_pm_write() too */
1382
        diff = s->mode & value;
1383
        s->mode = value & 0x2fff;
1384
        if (diff & (0x3ff << 2)) {
1385
            if (value & (1 << 4)) {                        /* PLL_ENABLE */
1386
                div = ((value >> 5) & 3) + 1;                /* PLL_DIV */
1387
                mult = MIN((value >> 7) & 0x1f, 1);        /* PLL_MULT */
1388
            } else {
1389
                div = bypass_div[((value >> 2) & 3)];        /* BYPASS_DIV */
1390
                mult = 1;
1391
            }
1392
            omap_clk_setrate(s->dpll, div, mult);
1393
        }
1394

    
1395
        /* Enter the desired mode.  */
1396
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1397

    
1398
        /* Act as if the lock is restored.  */
1399
        s->mode |= 2;
1400
    } else {
1401
        OMAP_BAD_REG(addr);
1402
    }
1403
}
1404

    
1405
static const MemoryRegionOps omap_dpll_ops = {
1406
    .read = omap_dpll_read,
1407
    .write = omap_dpll_write,
1408
    .endianness = DEVICE_NATIVE_ENDIAN,
1409
};
1410

    
1411
static void omap_dpll_reset(struct dpll_ctl_s *s)
1412
{
1413
    s->mode = 0x2002;
1414
    omap_clk_setrate(s->dpll, 1, 1);
1415
}
1416

    
1417
static struct dpll_ctl_s  *omap_dpll_init(MemoryRegion *memory,
1418
                           hwaddr base, omap_clk clk)
1419
{
1420
    struct dpll_ctl_s *s = g_malloc0(sizeof(*s));
1421
    memory_region_init_io(&s->iomem, &omap_dpll_ops, s, "omap-dpll", 0x100);
1422

    
1423
    s->dpll = clk;
1424
    omap_dpll_reset(s);
1425

    
1426
    memory_region_add_subregion(memory, base, &s->iomem);
1427
    return s;
1428
}
1429

    
1430
/* MPU Clock/Reset/Power Mode Control */
1431
static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
1432
                               unsigned size)
1433
{
1434
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1435

    
1436
    if (size != 2) {
1437
        return omap_badwidth_read16(opaque, addr);
1438
    }
1439

    
1440
    switch (addr) {
1441
    case 0x00:        /* ARM_CKCTL */
1442
        return s->clkm.arm_ckctl;
1443

    
1444
    case 0x04:        /* ARM_IDLECT1 */
1445
        return s->clkm.arm_idlect1;
1446

    
1447
    case 0x08:        /* ARM_IDLECT2 */
1448
        return s->clkm.arm_idlect2;
1449

    
1450
    case 0x0c:        /* ARM_EWUPCT */
1451
        return s->clkm.arm_ewupct;
1452

    
1453
    case 0x10:        /* ARM_RSTCT1 */
1454
        return s->clkm.arm_rstct1;
1455

    
1456
    case 0x14:        /* ARM_RSTCT2 */
1457
        return s->clkm.arm_rstct2;
1458

    
1459
    case 0x18:        /* ARM_SYSST */
1460
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1461

    
1462
    case 0x1c:        /* ARM_CKOUT1 */
1463
        return s->clkm.arm_ckout1;
1464

    
1465
    case 0x20:        /* ARM_CKOUT2 */
1466
        break;
1467
    }
1468

    
1469
    OMAP_BAD_REG(addr);
1470
    return 0;
1471
}
1472

    
1473
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1474
                uint16_t diff, uint16_t value)
1475
{
1476
    omap_clk clk;
1477

    
1478
    if (diff & (1 << 14)) {                                /* ARM_INTHCK_SEL */
1479
        if (value & (1 << 14))
1480
            /* Reserved */;
1481
        else {
1482
            clk = omap_findclk(s, "arminth_ck");
1483
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1484
        }
1485
    }
1486
    if (diff & (1 << 12)) {                                /* ARM_TIMXO */
1487
        clk = omap_findclk(s, "armtim_ck");
1488
        if (value & (1 << 12))
1489
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
1490
        else
1491
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1492
    }
1493
    /* XXX: en_dspck */
1494
    if (diff & (3 << 10)) {                                /* DSPMMUDIV */
1495
        clk = omap_findclk(s, "dspmmu_ck");
1496
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
1497
    }
1498
    if (diff & (3 << 8)) {                                /* TCDIV */
1499
        clk = omap_findclk(s, "tc_ck");
1500
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
1501
    }
1502
    if (diff & (3 << 6)) {                                /* DSPDIV */
1503
        clk = omap_findclk(s, "dsp_ck");
1504
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
1505
    }
1506
    if (diff & (3 << 4)) {                                /* ARMDIV */
1507
        clk = omap_findclk(s, "arm_ck");
1508
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
1509
    }
1510
    if (diff & (3 << 2)) {                                /* LCDDIV */
1511
        clk = omap_findclk(s, "lcd_ck");
1512
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
1513
    }
1514
    if (diff & (3 << 0)) {                                /* PERDIV */
1515
        clk = omap_findclk(s, "armper_ck");
1516
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
1517
    }
1518
}
1519

    
1520
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1521
                uint16_t diff, uint16_t value)
1522
{
1523
    omap_clk clk;
1524

    
1525
    if (value & (1 << 11)) {                            /* SETARM_IDLE */
1526
        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
1527
    }
1528
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
1529
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
1530

    
1531
#define SET_CANIDLE(clock, bit)                                \
1532
    if (diff & (1 << bit)) {                                \
1533
        clk = omap_findclk(s, clock);                        \
1534
        omap_clk_canidle(clk, (value >> bit) & 1);        \
1535
    }
1536
    SET_CANIDLE("mpuwd_ck", 0)                                /* IDLWDT_ARM */
1537
    SET_CANIDLE("armxor_ck", 1)                                /* IDLXORP_ARM */
1538
    SET_CANIDLE("mpuper_ck", 2)                                /* IDLPER_ARM */
1539
    SET_CANIDLE("lcd_ck", 3)                                /* IDLLCD_ARM */
1540
    SET_CANIDLE("lb_ck", 4)                                /* IDLLB_ARM */
1541
    SET_CANIDLE("hsab_ck", 5)                                /* IDLHSAB_ARM */
1542
    SET_CANIDLE("tipb_ck", 6)                                /* IDLIF_ARM */
1543
    SET_CANIDLE("dma_ck", 6)                                /* IDLIF_ARM */
1544
    SET_CANIDLE("tc_ck", 6)                                /* IDLIF_ARM */
1545
    SET_CANIDLE("dpll1", 7)                                /* IDLDPLL_ARM */
1546
    SET_CANIDLE("dpll2", 7)                                /* IDLDPLL_ARM */
1547
    SET_CANIDLE("dpll3", 7)                                /* IDLDPLL_ARM */
1548
    SET_CANIDLE("mpui_ck", 8)                                /* IDLAPI_ARM */
1549
    SET_CANIDLE("armtim_ck", 9)                                /* IDLTIM_ARM */
1550
}
1551

    
1552
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1553
                uint16_t diff, uint16_t value)
1554
{
1555
    omap_clk clk;
1556

    
1557
#define SET_ONOFF(clock, bit)                                \
1558
    if (diff & (1 << bit)) {                                \
1559
        clk = omap_findclk(s, clock);                        \
1560
        omap_clk_onoff(clk, (value >> bit) & 1);        \
1561
    }
1562
    SET_ONOFF("mpuwd_ck", 0)                                /* EN_WDTCK */
1563
    SET_ONOFF("armxor_ck", 1)                                /* EN_XORPCK */
1564
    SET_ONOFF("mpuper_ck", 2)                                /* EN_PERCK */
1565
    SET_ONOFF("lcd_ck", 3)                                /* EN_LCDCK */
1566
    SET_ONOFF("lb_ck", 4)                                /* EN_LBCK */
1567
    SET_ONOFF("hsab_ck", 5)                                /* EN_HSABCK */
1568
    SET_ONOFF("mpui_ck", 6)                                /* EN_APICK */
1569
    SET_ONOFF("armtim_ck", 7)                                /* EN_TIMCK */
1570
    SET_CANIDLE("dma_ck", 8)                                /* DMACK_REQ */
1571
    SET_ONOFF("arm_gpio_ck", 9)                                /* EN_GPIOCK */
1572
    SET_ONOFF("lbfree_ck", 10)                                /* EN_LBFREECK */
1573
}
1574

    
1575
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1576
                uint16_t diff, uint16_t value)
1577
{
1578
    omap_clk clk;
1579

    
1580
    if (diff & (3 << 4)) {                                /* TCLKOUT */
1581
        clk = omap_findclk(s, "tclk_out");
1582
        switch ((value >> 4) & 3) {
1583
        case 1:
1584
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
1585
            omap_clk_onoff(clk, 1);
1586
            break;
1587
        case 2:
1588
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
1589
            omap_clk_onoff(clk, 1);
1590
            break;
1591
        default:
1592
            omap_clk_onoff(clk, 0);
1593
        }
1594
    }
1595
    if (diff & (3 << 2)) {                                /* DCLKOUT */
1596
        clk = omap_findclk(s, "dclk_out");
1597
        switch ((value >> 2) & 3) {
1598
        case 0:
1599
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
1600
            break;
1601
        case 1:
1602
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
1603
            break;
1604
        case 2:
1605
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
1606
            break;
1607
        case 3:
1608
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1609
            break;
1610
        }
1611
    }
1612
    if (diff & (3 << 0)) {                                /* ACLKOUT */
1613
        clk = omap_findclk(s, "aclk_out");
1614
        switch ((value >> 0) & 3) {
1615
        case 1:
1616
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
1617
            omap_clk_onoff(clk, 1);
1618
            break;
1619
        case 2:
1620
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
1621
            omap_clk_onoff(clk, 1);
1622
            break;
1623
        case 3:
1624
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
1625
            omap_clk_onoff(clk, 1);
1626
            break;
1627
        default:
1628
            omap_clk_onoff(clk, 0);
1629
        }
1630
    }
1631
}
1632

    
1633
static void omap_clkm_write(void *opaque, hwaddr addr,
1634
                            uint64_t value, unsigned size)
1635
{
1636
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1637
    uint16_t diff;
1638
    omap_clk clk;
1639
    static const char *clkschemename[8] = {
1640
        "fully synchronous", "fully asynchronous", "synchronous scalable",
1641
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
1642
    };
1643

    
1644
    if (size != 2) {
1645
        return omap_badwidth_write16(opaque, addr, value);
1646
    }
1647

    
1648
    switch (addr) {
1649
    case 0x00:        /* ARM_CKCTL */
1650
        diff = s->clkm.arm_ckctl ^ value;
1651
        s->clkm.arm_ckctl = value & 0x7fff;
1652
        omap_clkm_ckctl_update(s, diff, value);
1653
        return;
1654

    
1655
    case 0x04:        /* ARM_IDLECT1 */
1656
        diff = s->clkm.arm_idlect1 ^ value;
1657
        s->clkm.arm_idlect1 = value & 0x0fff;
1658
        omap_clkm_idlect1_update(s, diff, value);
1659
        return;
1660

    
1661
    case 0x08:        /* ARM_IDLECT2 */
1662
        diff = s->clkm.arm_idlect2 ^ value;
1663
        s->clkm.arm_idlect2 = value & 0x07ff;
1664
        omap_clkm_idlect2_update(s, diff, value);
1665
        return;
1666

    
1667
    case 0x0c:        /* ARM_EWUPCT */
1668
        s->clkm.arm_ewupct = value & 0x003f;
1669
        return;
1670

    
1671
    case 0x10:        /* ARM_RSTCT1 */
1672
        diff = s->clkm.arm_rstct1 ^ value;
1673
        s->clkm.arm_rstct1 = value & 0x0007;
1674
        if (value & 9) {
1675
            qemu_system_reset_request();
1676
            s->clkm.cold_start = 0xa;
1677
        }
1678
        if (diff & ~value & 4) {                                /* DSP_RST */
1679
            omap_mpui_reset(s);
1680
            omap_tipb_bridge_reset(s->private_tipb);
1681
            omap_tipb_bridge_reset(s->public_tipb);
1682
        }
1683
        if (diff & 2) {                                                /* DSP_EN */
1684
            clk = omap_findclk(s, "dsp_ck");
1685
            omap_clk_canidle(clk, (~value >> 1) & 1);
1686
        }
1687
        return;
1688

    
1689
    case 0x14:        /* ARM_RSTCT2 */
1690
        s->clkm.arm_rstct2 = value & 0x0001;
1691
        return;
1692

    
1693
    case 0x18:        /* ARM_SYSST */
1694
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
1695
            s->clkm.clocking_scheme = (value >> 11) & 7;
1696
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
1697
                            clkschemename[s->clkm.clocking_scheme]);
1698
        }
1699
        s->clkm.cold_start &= value & 0x3f;
1700
        return;
1701

    
1702
    case 0x1c:        /* ARM_CKOUT1 */
1703
        diff = s->clkm.arm_ckout1 ^ value;
1704
        s->clkm.arm_ckout1 = value & 0x003f;
1705
        omap_clkm_ckout1_update(s, diff, value);
1706
        return;
1707

    
1708
    case 0x20:        /* ARM_CKOUT2 */
1709
    default:
1710
        OMAP_BAD_REG(addr);
1711
    }
1712
}
1713

    
1714
static const MemoryRegionOps omap_clkm_ops = {
1715
    .read = omap_clkm_read,
1716
    .write = omap_clkm_write,
1717
    .endianness = DEVICE_NATIVE_ENDIAN,
1718
};
1719

    
1720
static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
1721
                                 unsigned size)
1722
{
1723
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1724
    CPUState *cpu = CPU(s->cpu);
1725

    
1726
    if (size != 2) {
1727
        return omap_badwidth_read16(opaque, addr);
1728
    }
1729

    
1730
    switch (addr) {
1731
    case 0x04:        /* DSP_IDLECT1 */
1732
        return s->clkm.dsp_idlect1;
1733

    
1734
    case 0x08:        /* DSP_IDLECT2 */
1735
        return s->clkm.dsp_idlect2;
1736

    
1737
    case 0x14:        /* DSP_RSTCT2 */
1738
        return s->clkm.dsp_rstct2;
1739

    
1740
    case 0x18:        /* DSP_SYSST */
1741
        cpu = CPU(s->cpu);
1742
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
1743
                (cpu->halted << 6);      /* Quite useless... */
1744
    }
1745

    
1746
    OMAP_BAD_REG(addr);
1747
    return 0;
1748
}
1749

    
1750
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
1751
                uint16_t diff, uint16_t value)
1752
{
1753
    omap_clk clk;
1754

    
1755
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
1756
}
1757

    
1758
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
1759
                uint16_t diff, uint16_t value)
1760
{
1761
    omap_clk clk;
1762

    
1763
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
1764
}
1765

    
1766
static void omap_clkdsp_write(void *opaque, hwaddr addr,
1767
                              uint64_t value, unsigned size)
1768
{
1769
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1770
    uint16_t diff;
1771

    
1772
    if (size != 2) {
1773
        return omap_badwidth_write16(opaque, addr, value);
1774
    }
1775

    
1776
    switch (addr) {
1777
    case 0x04:        /* DSP_IDLECT1 */
1778
        diff = s->clkm.dsp_idlect1 ^ value;
1779
        s->clkm.dsp_idlect1 = value & 0x01f7;
1780
        omap_clkdsp_idlect1_update(s, diff, value);
1781
        break;
1782

    
1783
    case 0x08:        /* DSP_IDLECT2 */
1784
        s->clkm.dsp_idlect2 = value & 0x0037;
1785
        diff = s->clkm.dsp_idlect1 ^ value;
1786
        omap_clkdsp_idlect2_update(s, diff, value);
1787
        break;
1788

    
1789
    case 0x14:        /* DSP_RSTCT2 */
1790
        s->clkm.dsp_rstct2 = value & 0x0001;
1791
        break;
1792

    
1793
    case 0x18:        /* DSP_SYSST */
1794
        s->clkm.cold_start &= value & 0x3f;
1795
        break;
1796

    
1797
    default:
1798
        OMAP_BAD_REG(addr);
1799
    }
1800
}
1801

    
1802
static const MemoryRegionOps omap_clkdsp_ops = {
1803
    .read = omap_clkdsp_read,
1804
    .write = omap_clkdsp_write,
1805
    .endianness = DEVICE_NATIVE_ENDIAN,
1806
};
1807

    
1808
static void omap_clkm_reset(struct omap_mpu_state_s *s)
1809
{
1810
    if (s->wdt && s->wdt->reset)
1811
        s->clkm.cold_start = 0x6;
1812
    s->clkm.clocking_scheme = 0;
1813
    omap_clkm_ckctl_update(s, ~0, 0x3000);
1814
    s->clkm.arm_ckctl = 0x3000;
1815
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
1816
    s->clkm.arm_idlect1 = 0x0400;
1817
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
1818
    s->clkm.arm_idlect2 = 0x0100;
1819
    s->clkm.arm_ewupct = 0x003f;
1820
    s->clkm.arm_rstct1 = 0x0000;
1821
    s->clkm.arm_rstct2 = 0x0000;
1822
    s->clkm.arm_ckout1 = 0x0015;
1823
    s->clkm.dpll1_mode = 0x2002;
1824
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
1825
    s->clkm.dsp_idlect1 = 0x0040;
1826
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
1827
    s->clkm.dsp_idlect2 = 0x0000;
1828
    s->clkm.dsp_rstct2 = 0x0000;
1829
}
1830

    
1831
static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
1832
                hwaddr dsp_base, struct omap_mpu_state_s *s)
1833
{
1834
    memory_region_init_io(&s->clkm_iomem, &omap_clkm_ops, s,
1835
                          "omap-clkm", 0x100);
1836
    memory_region_init_io(&s->clkdsp_iomem, &omap_clkdsp_ops, s,
1837
                          "omap-clkdsp", 0x1000);
1838

    
1839
    s->clkm.arm_idlect1 = 0x03ff;
1840
    s->clkm.arm_idlect2 = 0x0100;
1841
    s->clkm.dsp_idlect1 = 0x0002;
1842
    omap_clkm_reset(s);
1843
    s->clkm.cold_start = 0x3a;
1844

    
1845
    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
1846
    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
1847
}
1848

    
1849
/* MPU I/O */
1850
struct omap_mpuio_s {
1851
    qemu_irq irq;
1852
    qemu_irq kbd_irq;
1853
    qemu_irq *in;
1854
    qemu_irq handler[16];
1855
    qemu_irq wakeup;
1856
    MemoryRegion iomem;
1857

    
1858
    uint16_t inputs;
1859
    uint16_t outputs;
1860
    uint16_t dir;
1861
    uint16_t edge;
1862
    uint16_t mask;
1863
    uint16_t ints;
1864

    
1865
    uint16_t debounce;
1866
    uint16_t latch;
1867
    uint8_t event;
1868

    
1869
    uint8_t buttons[5];
1870
    uint8_t row_latch;
1871
    uint8_t cols;
1872
    int kbd_mask;
1873
    int clk;
1874
};
1875

    
1876
static void omap_mpuio_set(void *opaque, int line, int level)
1877
{
1878
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1879
    uint16_t prev = s->inputs;
1880

    
1881
    if (level)
1882
        s->inputs |= 1 << line;
1883
    else
1884
        s->inputs &= ~(1 << line);
1885

    
1886
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
1887
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
1888
            s->ints |= 1 << line;
1889
            qemu_irq_raise(s->irq);
1890
            /* TODO: wakeup */
1891
        }
1892
        if ((s->event & (1 << 0)) &&                /* SET_GPIO_EVENT_MODE */
1893
                (s->event >> 1) == line)        /* PIN_SELECT */
1894
            s->latch = s->inputs;
1895
    }
1896
}
1897

    
1898
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
1899
{
1900
    int i;
1901
    uint8_t *row, rows = 0, cols = ~s->cols;
1902

    
1903
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1904
        if (*row & cols)
1905
            rows |= i;
1906

    
1907
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1908
    s->row_latch = ~rows;
1909
}
1910

    
1911
static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
1912
                                unsigned size)
1913
{
1914
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1915
    int offset = addr & OMAP_MPUI_REG_MASK;
1916
    uint16_t ret;
1917

    
1918
    if (size != 2) {
1919
        return omap_badwidth_read16(opaque, addr);
1920
    }
1921

    
1922
    switch (offset) {
1923
    case 0x00:        /* INPUT_LATCH */
1924
        return s->inputs;
1925

    
1926
    case 0x04:        /* OUTPUT_REG */
1927
        return s->outputs;
1928

    
1929
    case 0x08:        /* IO_CNTL */
1930
        return s->dir;
1931

    
1932
    case 0x10:        /* KBR_LATCH */
1933
        return s->row_latch;
1934

    
1935
    case 0x14:        /* KBC_REG */
1936
        return s->cols;
1937

    
1938
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1939
        return s->event;
1940

    
1941
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1942
        return s->edge;
1943

    
1944
    case 0x20:        /* KBD_INT */
1945
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
1946

    
1947
    case 0x24:        /* GPIO_INT */
1948
        ret = s->ints;
1949
        s->ints &= s->mask;
1950
        if (ret)
1951
            qemu_irq_lower(s->irq);
1952
        return ret;
1953

    
1954
    case 0x28:        /* KBD_MASKIT */
1955
        return s->kbd_mask;
1956

    
1957
    case 0x2c:        /* GPIO_MASKIT */
1958
        return s->mask;
1959

    
1960
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1961
        return s->debounce;
1962

    
1963
    case 0x34:        /* GPIO_LATCH_REG */
1964
        return s->latch;
1965
    }
1966

    
1967
    OMAP_BAD_REG(addr);
1968
    return 0;
1969
}
1970

    
1971
static void omap_mpuio_write(void *opaque, hwaddr addr,
1972
                             uint64_t value, unsigned size)
1973
{
1974
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1975
    int offset = addr & OMAP_MPUI_REG_MASK;
1976
    uint16_t diff;
1977
    int ln;
1978

    
1979
    if (size != 2) {
1980
        return omap_badwidth_write16(opaque, addr, value);
1981
    }
1982

    
1983
    switch (offset) {
1984
    case 0x04:        /* OUTPUT_REG */
1985
        diff = (s->outputs ^ value) & ~s->dir;
1986
        s->outputs = value;
1987
        while ((ln = ffs(diff))) {
1988
            ln --;
1989
            if (s->handler[ln])
1990
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
1991
            diff &= ~(1 << ln);
1992
        }
1993
        break;
1994

    
1995
    case 0x08:        /* IO_CNTL */
1996
        diff = s->outputs & (s->dir ^ value);
1997
        s->dir = value;
1998

    
1999
        value = s->outputs & ~s->dir;
2000
        while ((ln = ffs(diff))) {
2001
            ln --;
2002
            if (s->handler[ln])
2003
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
2004
            diff &= ~(1 << ln);
2005
        }
2006
        break;
2007

    
2008
    case 0x14:        /* KBC_REG */
2009
        s->cols = value;
2010
        omap_mpuio_kbd_update(s);
2011
        break;
2012

    
2013
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2014
        s->event = value & 0x1f;
2015
        break;
2016

    
2017
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2018
        s->edge = value;
2019
        break;
2020

    
2021
    case 0x28:        /* KBD_MASKIT */
2022
        s->kbd_mask = value & 1;
2023
        omap_mpuio_kbd_update(s);
2024
        break;
2025

    
2026
    case 0x2c:        /* GPIO_MASKIT */
2027
        s->mask = value;
2028
        break;
2029

    
2030
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2031
        s->debounce = value & 0x1ff;
2032
        break;
2033

    
2034
    case 0x00:        /* INPUT_LATCH */
2035
    case 0x10:        /* KBR_LATCH */
2036
    case 0x20:        /* KBD_INT */
2037
    case 0x24:        /* GPIO_INT */
2038
    case 0x34:        /* GPIO_LATCH_REG */
2039
        OMAP_RO_REG(addr);
2040
        return;
2041

    
2042
    default:
2043
        OMAP_BAD_REG(addr);
2044
        return;
2045
    }
2046
}
2047

    
2048
static const MemoryRegionOps omap_mpuio_ops  = {
2049
    .read = omap_mpuio_read,
2050
    .write = omap_mpuio_write,
2051
    .endianness = DEVICE_NATIVE_ENDIAN,
2052
};
2053

    
2054
static void omap_mpuio_reset(struct omap_mpuio_s *s)
2055
{
2056
    s->inputs = 0;
2057
    s->outputs = 0;
2058
    s->dir = ~0;
2059
    s->event = 0;
2060
    s->edge = 0;
2061
    s->kbd_mask = 0;
2062
    s->mask = 0;
2063
    s->debounce = 0;
2064
    s->latch = 0;
2065
    s->ints = 0;
2066
    s->row_latch = 0x1f;
2067
    s->clk = 1;
2068
}
2069

    
2070
static void omap_mpuio_onoff(void *opaque, int line, int on)
2071
{
2072
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2073

    
2074
    s->clk = on;
2075
    if (on)
2076
        omap_mpuio_kbd_update(s);
2077
}
2078

    
2079
static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
2080
                hwaddr base,
2081
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2082
                omap_clk clk)
2083
{
2084
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2085
            g_malloc0(sizeof(struct omap_mpuio_s));
2086

    
2087
    s->irq = gpio_int;
2088
    s->kbd_irq = kbd_int;
2089
    s->wakeup = wakeup;
2090
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2091
    omap_mpuio_reset(s);
2092

    
2093
    memory_region_init_io(&s->iomem, &omap_mpuio_ops, s,
2094
                          "omap-mpuio", 0x800);
2095
    memory_region_add_subregion(memory, base, &s->iomem);
2096

    
2097
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2098

    
2099
    return s;
2100
}
2101

    
2102
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2103
{
2104
    return s->in;
2105
}
2106

    
2107
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
2108
{
2109
    if (line >= 16 || line < 0)
2110
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
2111
    s->handler[line] = handler;
2112
}
2113

    
2114
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
2115
{
2116
    if (row >= 5 || row < 0)
2117
        hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
2118

    
2119
    if (down)
2120
        s->buttons[row] |= 1 << col;
2121
    else
2122
        s->buttons[row] &= ~(1 << col);
2123

    
2124
    omap_mpuio_kbd_update(s);
2125
}
2126

    
2127
/* MicroWire Interface */
2128
struct omap_uwire_s {
2129
    MemoryRegion iomem;
2130
    qemu_irq txirq;
2131
    qemu_irq rxirq;
2132
    qemu_irq txdrq;
2133

    
2134
    uint16_t txbuf;
2135
    uint16_t rxbuf;
2136
    uint16_t control;
2137
    uint16_t setup[5];
2138

    
2139
    uWireSlave *chip[4];
2140
};
2141

    
2142
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2143
{
2144
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
2145
    uWireSlave *slave = s->chip[chipselect];
2146

    
2147
    if ((s->control >> 5) & 0x1f) {                        /* NB_BITS_WR */
2148
        if (s->control & (1 << 12))                        /* CS_CMD */
2149
            if (slave && slave->send)
2150
                slave->send(slave->opaque,
2151
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
2152
        s->control &= ~(1 << 14);                        /* CSRB */
2153
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2154
         * a DRQ.  When is the level IRQ supposed to be reset?  */
2155
    }
2156

    
2157
    if ((s->control >> 0) & 0x1f) {                        /* NB_BITS_RD */
2158
        if (s->control & (1 << 12))                        /* CS_CMD */
2159
            if (slave && slave->receive)
2160
                s->rxbuf = slave->receive(slave->opaque);
2161
        s->control |= 1 << 15;                                /* RDRB */
2162
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
2163
         * a DRQ.  When is the level IRQ supposed to be reset?  */
2164
    }
2165
}
2166

    
2167
static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
2168
                                unsigned size)
2169
{
2170
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2171
    int offset = addr & OMAP_MPUI_REG_MASK;
2172

    
2173
    if (size != 2) {
2174
        return omap_badwidth_read16(opaque, addr);
2175
    }
2176

    
2177
    switch (offset) {
2178
    case 0x00:        /* RDR */
2179
        s->control &= ~(1 << 15);                        /* RDRB */
2180
        return s->rxbuf;
2181

    
2182
    case 0x04:        /* CSR */
2183
        return s->control;
2184

    
2185
    case 0x08:        /* SR1 */
2186
        return s->setup[0];
2187
    case 0x0c:        /* SR2 */
2188
        return s->setup[1];
2189
    case 0x10:        /* SR3 */
2190
        return s->setup[2];
2191
    case 0x14:        /* SR4 */
2192
        return s->setup[3];
2193
    case 0x18:        /* SR5 */
2194
        return s->setup[4];
2195
    }
2196

    
2197
    OMAP_BAD_REG(addr);
2198
    return 0;
2199
}
2200

    
2201
static void omap_uwire_write(void *opaque, hwaddr addr,
2202
                             uint64_t value, unsigned size)
2203
{
2204
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2205
    int offset = addr & OMAP_MPUI_REG_MASK;
2206

    
2207
    if (size != 2) {
2208
        return omap_badwidth_write16(opaque, addr, value);
2209
    }
2210

    
2211
    switch (offset) {
2212
    case 0x00:        /* TDR */
2213
        s->txbuf = value;                                /* TD */
2214
        if ((s->setup[4] & (1 << 2)) &&                        /* AUTO_TX_EN */
2215
                        ((s->setup[4] & (1 << 3)) ||        /* CS_TOGGLE_TX_EN */
2216
                         (s->control & (1 << 12)))) {        /* CS_CMD */
2217
            s->control |= 1 << 14;                        /* CSRB */
2218
            omap_uwire_transfer_start(s);
2219
        }
2220
        break;
2221

    
2222
    case 0x04:        /* CSR */
2223
        s->control = value & 0x1fff;
2224
        if (value & (1 << 13))                                /* START */
2225
            omap_uwire_transfer_start(s);
2226
        break;
2227

    
2228
    case 0x08:        /* SR1 */
2229
        s->setup[0] = value & 0x003f;
2230
        break;
2231

    
2232
    case 0x0c:        /* SR2 */
2233
        s->setup[1] = value & 0x0fc0;
2234
        break;
2235

    
2236
    case 0x10:        /* SR3 */
2237
        s->setup[2] = value & 0x0003;
2238
        break;
2239

    
2240
    case 0x14:        /* SR4 */
2241
        s->setup[3] = value & 0x0001;
2242
        break;
2243

    
2244
    case 0x18:        /* SR5 */
2245
        s->setup[4] = value & 0x000f;
2246
        break;
2247

    
2248
    default:
2249
        OMAP_BAD_REG(addr);
2250
        return;
2251
    }
2252
}
2253

    
2254
static const MemoryRegionOps omap_uwire_ops = {
2255
    .read = omap_uwire_read,
2256
    .write = omap_uwire_write,
2257
    .endianness = DEVICE_NATIVE_ENDIAN,
2258
};
2259

    
2260
static void omap_uwire_reset(struct omap_uwire_s *s)
2261
{
2262
    s->control = 0;
2263
    s->setup[0] = 0;
2264
    s->setup[1] = 0;
2265
    s->setup[2] = 0;
2266
    s->setup[3] = 0;
2267
    s->setup[4] = 0;
2268
}
2269

    
2270
static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
2271
                                            hwaddr base,
2272
                                            qemu_irq txirq, qemu_irq rxirq,
2273
                                            qemu_irq dma,
2274
                                            omap_clk clk)
2275
{
2276
    struct omap_uwire_s *s = (struct omap_uwire_s *)
2277
            g_malloc0(sizeof(struct omap_uwire_s));
2278

    
2279
    s->txirq = txirq;
2280
    s->rxirq = rxirq;
2281
    s->txdrq = dma;
2282
    omap_uwire_reset(s);
2283

    
2284
    memory_region_init_io(&s->iomem, &omap_uwire_ops, s, "omap-uwire", 0x800);
2285
    memory_region_add_subregion(system_memory, base, &s->iomem);
2286

    
2287
    return s;
2288
}
2289

    
2290
void omap_uwire_attach(struct omap_uwire_s *s,
2291
                uWireSlave *slave, int chipselect)
2292
{
2293
    if (chipselect < 0 || chipselect > 3) {
2294
        fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
2295
        exit(-1);
2296
    }
2297

    
2298
    s->chip[chipselect] = slave;
2299
}
2300

    
2301
/* Pseudonoise Pulse-Width Light Modulator */
2302
struct omap_pwl_s {
2303
    MemoryRegion iomem;
2304
    uint8_t output;
2305
    uint8_t level;
2306
    uint8_t enable;
2307
    int clk;
2308
};
2309

    
2310
static void omap_pwl_update(struct omap_pwl_s *s)
2311
{
2312
    int output = (s->clk && s->enable) ? s->level : 0;
2313

    
2314
    if (output != s->output) {
2315
        s->output = output;
2316
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
2317
    }
2318
}
2319

    
2320
static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
2321
                              unsigned size)
2322
{
2323
    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2324
    int offset = addr & OMAP_MPUI_REG_MASK;
2325

    
2326
    if (size != 1) {
2327
        return omap_badwidth_read8(opaque, addr);
2328
    }
2329

    
2330
    switch (offset) {
2331
    case 0x00:        /* PWL_LEVEL */
2332
        return s->level;
2333
    case 0x04:        /* PWL_CTRL */
2334
        return s->enable;
2335
    }
2336
    OMAP_BAD_REG(addr);
2337
    return 0;
2338
}
2339

    
2340
static void omap_pwl_write(void *opaque, hwaddr addr,
2341
                           uint64_t value, unsigned size)
2342
{
2343
    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2344
    int offset = addr & OMAP_MPUI_REG_MASK;
2345

    
2346
    if (size != 1) {
2347
        return omap_badwidth_write8(opaque, addr, value);
2348
    }
2349

    
2350
    switch (offset) {
2351
    case 0x00:        /* PWL_LEVEL */
2352
        s->level = value;
2353
        omap_pwl_update(s);
2354
        break;
2355
    case 0x04:        /* PWL_CTRL */
2356
        s->enable = value & 1;
2357
        omap_pwl_update(s);
2358
        break;
2359
    default:
2360
        OMAP_BAD_REG(addr);
2361
        return;
2362
    }
2363
}
2364

    
2365
static const MemoryRegionOps omap_pwl_ops = {
2366
    .read = omap_pwl_read,
2367
    .write = omap_pwl_write,
2368
    .endianness = DEVICE_NATIVE_ENDIAN,
2369
};
2370

    
2371
static void omap_pwl_reset(struct omap_pwl_s *s)
2372
{
2373
    s->output = 0;
2374
    s->level = 0;
2375
    s->enable = 0;
2376
    s->clk = 1;
2377
    omap_pwl_update(s);
2378
}
2379

    
2380
static void omap_pwl_clk_update(void *opaque, int line, int on)
2381
{
2382
    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2383

    
2384
    s->clk = on;
2385
    omap_pwl_update(s);
2386
}
2387

    
2388
static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
2389
                                        hwaddr base,
2390
                                        omap_clk clk)
2391
{
2392
    struct omap_pwl_s *s = g_malloc0(sizeof(*s));
2393

    
2394
    omap_pwl_reset(s);
2395

    
2396
    memory_region_init_io(&s->iomem, &omap_pwl_ops, s,
2397
                          "omap-pwl", 0x800);
2398
    memory_region_add_subregion(system_memory, base, &s->iomem);
2399

    
2400
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
2401
    return s;
2402
}
2403

    
2404
/* Pulse-Width Tone module */
2405
struct omap_pwt_s {
2406
    MemoryRegion iomem;
2407
    uint8_t frc;
2408
    uint8_t vrc;
2409
    uint8_t gcr;
2410
    omap_clk clk;
2411
};
2412

    
2413
static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
2414
                              unsigned size)
2415
{
2416
    struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
2417
    int offset = addr & OMAP_MPUI_REG_MASK;
2418

    
2419
    if (size != 1) {
2420
        return omap_badwidth_read8(opaque, addr);
2421
    }
2422

    
2423
    switch (offset) {
2424
    case 0x00:        /* FRC */
2425
        return s->frc;
2426
    case 0x04:        /* VCR */
2427
        return s->vrc;
2428
    case 0x08:        /* GCR */
2429
        return s->gcr;
2430
    }
2431
    OMAP_BAD_REG(addr);
2432
    return 0;
2433
}
2434

    
2435
static void omap_pwt_write(void *opaque, hwaddr addr,
2436
                           uint64_t value, unsigned size)
2437
{
2438
    struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
2439
    int offset = addr & OMAP_MPUI_REG_MASK;
2440

    
2441
    if (size != 1) {
2442
        return omap_badwidth_write8(opaque, addr, value);
2443
    }
2444

    
2445
    switch (offset) {
2446
    case 0x00:        /* FRC */
2447
        s->frc = value & 0x3f;
2448
        break;
2449
    case 0x04:        /* VRC */
2450
        if ((value ^ s->vrc) & 1) {
2451
            if (value & 1)
2452
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
2453
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
2454
                                ((omap_clk_getrate(s->clk) >> 3) /
2455
                                 /* Pre-multiplexer divider */
2456
                                 ((s->gcr & 2) ? 1 : 154) /
2457
                                 /* Octave multiplexer */
2458
                                 (2 << (value & 3)) *
2459
                                 /* 101/107 divider */
2460
                                 ((value & (1 << 2)) ? 101 : 107) *
2461
                                 /*  49/55 divider */
2462
                                 ((value & (1 << 3)) ?  49 : 55) *
2463
                                 /*  50/63 divider */
2464
                                 ((value & (1 << 4)) ?  50 : 63) *
2465
                                 /*  80/127 divider */
2466
                                 ((value & (1 << 5)) ?  80 : 127) /
2467
                                 (107 * 55 * 63 * 127)));
2468
            else
2469
                printf("%s: silence!\n", __FUNCTION__);
2470
        }
2471
        s->vrc = value & 0x7f;
2472
        break;
2473
    case 0x08:        /* GCR */
2474
        s->gcr = value & 3;
2475
        break;
2476
    default:
2477
        OMAP_BAD_REG(addr);
2478
        return;
2479
    }
2480
}
2481

    
2482
static const MemoryRegionOps omap_pwt_ops = {
2483
    .read =omap_pwt_read,
2484
    .write = omap_pwt_write,
2485
    .endianness = DEVICE_NATIVE_ENDIAN,
2486
};
2487

    
2488
static void omap_pwt_reset(struct omap_pwt_s *s)
2489
{
2490
    s->frc = 0;
2491
    s->vrc = 0;
2492
    s->gcr = 0;
2493
}
2494

    
2495
static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
2496
                                        hwaddr base,
2497
                                        omap_clk clk)
2498
{
2499
    struct omap_pwt_s *s = g_malloc0(sizeof(*s));
2500
    s->clk = clk;
2501
    omap_pwt_reset(s);
2502

    
2503
    memory_region_init_io(&s->iomem, &omap_pwt_ops, s,
2504
                          "omap-pwt", 0x800);
2505
    memory_region_add_subregion(system_memory, base, &s->iomem);
2506
    return s;
2507
}
2508

    
2509
/* Real-time Clock module */
2510
struct omap_rtc_s {
2511
    MemoryRegion iomem;
2512
    qemu_irq irq;
2513
    qemu_irq alarm;
2514
    QEMUTimer *clk;
2515

    
2516
    uint8_t interrupts;
2517
    uint8_t status;
2518
    int16_t comp_reg;
2519
    int running;
2520
    int pm_am;
2521
    int auto_comp;
2522
    int round;
2523
    struct tm alarm_tm;
2524
    time_t alarm_ti;
2525

    
2526
    struct tm current_tm;
2527
    time_t ti;
2528
    uint64_t tick;
2529
};
2530

    
2531
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2532
{
2533
    /* s->alarm is level-triggered */
2534
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2535
}
2536

    
2537
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
2538
{
2539
    s->alarm_ti = mktimegm(&s->alarm_tm);
2540
    if (s->alarm_ti == -1)
2541
        printf("%s: conversion failed\n", __FUNCTION__);
2542
}
2543

    
2544
static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
2545
                              unsigned size)
2546
{
2547
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2548
    int offset = addr & OMAP_MPUI_REG_MASK;
2549
    uint8_t i;
2550

    
2551
    if (size != 1) {
2552
        return omap_badwidth_read8(opaque, addr);
2553
    }
2554

    
2555
    switch (offset) {
2556
    case 0x00:        /* SECONDS_REG */
2557
        return to_bcd(s->current_tm.tm_sec);
2558

    
2559
    case 0x04:        /* MINUTES_REG */
2560
        return to_bcd(s->current_tm.tm_min);
2561

    
2562
    case 0x08:        /* HOURS_REG */
2563
        if (s->pm_am)
2564
            return ((s->current_tm.tm_hour > 11) << 7) |
2565
                    to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
2566
        else
2567
            return to_bcd(s->current_tm.tm_hour);
2568

    
2569
    case 0x0c:        /* DAYS_REG */
2570
        return to_bcd(s->current_tm.tm_mday);
2571

    
2572
    case 0x10:        /* MONTHS_REG */
2573
        return to_bcd(s->current_tm.tm_mon + 1);
2574

    
2575
    case 0x14:        /* YEARS_REG */
2576
        return to_bcd(s->current_tm.tm_year % 100);
2577

    
2578
    case 0x18:        /* WEEK_REG */
2579
        return s->current_tm.tm_wday;
2580

    
2581
    case 0x20:        /* ALARM_SECONDS_REG */
2582
        return to_bcd(s->alarm_tm.tm_sec);
2583

    
2584
    case 0x24:        /* ALARM_MINUTES_REG */
2585
        return to_bcd(s->alarm_tm.tm_min);
2586

    
2587
    case 0x28:        /* ALARM_HOURS_REG */
2588
        if (s->pm_am)
2589
            return ((s->alarm_tm.tm_hour > 11) << 7) |
2590
                    to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
2591
        else
2592
            return to_bcd(s->alarm_tm.tm_hour);
2593

    
2594
    case 0x2c:        /* ALARM_DAYS_REG */
2595
        return to_bcd(s->alarm_tm.tm_mday);
2596

    
2597
    case 0x30:        /* ALARM_MONTHS_REG */
2598
        return to_bcd(s->alarm_tm.tm_mon + 1);
2599

    
2600
    case 0x34:        /* ALARM_YEARS_REG */
2601
        return to_bcd(s->alarm_tm.tm_year % 100);
2602

    
2603
    case 0x40:        /* RTC_CTRL_REG */
2604
        return (s->pm_am << 3) | (s->auto_comp << 2) |
2605
                (s->round << 1) | s->running;
2606

    
2607
    case 0x44:        /* RTC_STATUS_REG */
2608
        i = s->status;
2609
        s->status &= ~0x3d;
2610
        return i;
2611

    
2612
    case 0x48:        /* RTC_INTERRUPTS_REG */
2613
        return s->interrupts;
2614

    
2615
    case 0x4c:        /* RTC_COMP_LSB_REG */
2616
        return ((uint16_t) s->comp_reg) & 0xff;
2617

    
2618
    case 0x50:        /* RTC_COMP_MSB_REG */
2619
        return ((uint16_t) s->comp_reg) >> 8;
2620
    }
2621

    
2622
    OMAP_BAD_REG(addr);
2623
    return 0;
2624
}
2625

    
2626
static void omap_rtc_write(void *opaque, hwaddr addr,
2627
                           uint64_t value, unsigned size)
2628
{
2629
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2630
    int offset = addr & OMAP_MPUI_REG_MASK;
2631
    struct tm new_tm;
2632
    time_t ti[2];
2633

    
2634
    if (size != 1) {
2635
        return omap_badwidth_write8(opaque, addr, value);
2636
    }
2637

    
2638
    switch (offset) {
2639
    case 0x00:        /* SECONDS_REG */
2640
#ifdef ALMDEBUG
2641
        printf("RTC SEC_REG <-- %02x\n", value);
2642
#endif
2643
        s->ti -= s->current_tm.tm_sec;
2644
        s->ti += from_bcd(value);
2645
        return;
2646

    
2647
    case 0x04:        /* MINUTES_REG */
2648
#ifdef ALMDEBUG
2649
        printf("RTC MIN_REG <-- %02x\n", value);
2650
#endif
2651
        s->ti -= s->current_tm.tm_min * 60;
2652
        s->ti += from_bcd(value) * 60;
2653
        return;
2654

    
2655
    case 0x08:        /* HOURS_REG */
2656
#ifdef ALMDEBUG
2657
        printf("RTC HRS_REG <-- %02x\n", value);
2658
#endif
2659
        s->ti -= s->current_tm.tm_hour * 3600;
2660
        if (s->pm_am) {
2661
            s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
2662
            s->ti += ((value >> 7) & 1) * 43200;
2663
        } else
2664
            s->ti += from_bcd(value & 0x3f) * 3600;
2665
        return;
2666

    
2667
    case 0x0c:        /* DAYS_REG */
2668
#ifdef ALMDEBUG
2669
        printf("RTC DAY_REG <-- %02x\n", value);
2670
#endif
2671
        s->ti -= s->current_tm.tm_mday * 86400;
2672
        s->ti += from_bcd(value) * 86400;
2673
        return;
2674

    
2675
    case 0x10:        /* MONTHS_REG */
2676
#ifdef ALMDEBUG
2677
        printf("RTC MTH_REG <-- %02x\n", value);
2678
#endif
2679
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2680
        new_tm.tm_mon = from_bcd(value);
2681
        ti[0] = mktimegm(&s->current_tm);
2682
        ti[1] = mktimegm(&new_tm);
2683

    
2684
        if (ti[0] != -1 && ti[1] != -1) {
2685
            s->ti -= ti[0];
2686
            s->ti += ti[1];
2687
        } else {
2688
            /* A less accurate version */
2689
            s->ti -= s->current_tm.tm_mon * 2592000;
2690
            s->ti += from_bcd(value) * 2592000;
2691
        }
2692
        return;
2693

    
2694
    case 0x14:        /* YEARS_REG */
2695
#ifdef ALMDEBUG
2696
        printf("RTC YRS_REG <-- %02x\n", value);
2697
#endif
2698
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2699
        new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
2700
        ti[0] = mktimegm(&s->current_tm);
2701
        ti[1] = mktimegm(&new_tm);
2702

    
2703
        if (ti[0] != -1 && ti[1] != -1) {
2704
            s->ti -= ti[0];
2705
            s->ti += ti[1];
2706
        } else {
2707
            /* A less accurate version */
2708
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
2709
            s->ti += from_bcd(value) * 31536000;
2710
        }
2711
        return;
2712

    
2713
    case 0x18:        /* WEEK_REG */
2714
        return;        /* Ignored */
2715

    
2716
    case 0x20:        /* ALARM_SECONDS_REG */
2717
#ifdef ALMDEBUG
2718
        printf("ALM SEC_REG <-- %02x\n", value);
2719
#endif
2720
        s->alarm_tm.tm_sec = from_bcd(value);
2721
        omap_rtc_alarm_update(s);
2722
        return;
2723

    
2724
    case 0x24:        /* ALARM_MINUTES_REG */
2725
#ifdef ALMDEBUG
2726
        printf("ALM MIN_REG <-- %02x\n", value);
2727
#endif
2728
        s->alarm_tm.tm_min = from_bcd(value);
2729
        omap_rtc_alarm_update(s);
2730
        return;
2731

    
2732
    case 0x28:        /* ALARM_HOURS_REG */
2733
#ifdef ALMDEBUG
2734
        printf("ALM HRS_REG <-- %02x\n", value);
2735
#endif
2736
        if (s->pm_am)
2737
            s->alarm_tm.tm_hour =
2738
                    ((from_bcd(value & 0x3f)) % 12) +
2739
                    ((value >> 7) & 1) * 12;
2740
        else
2741
            s->alarm_tm.tm_hour = from_bcd(value);
2742
        omap_rtc_alarm_update(s);
2743
        return;
2744

    
2745
    case 0x2c:        /* ALARM_DAYS_REG */
2746
#ifdef ALMDEBUG
2747
        printf("ALM DAY_REG <-- %02x\n", value);
2748
#endif
2749
        s->alarm_tm.tm_mday = from_bcd(value);
2750
        omap_rtc_alarm_update(s);
2751
        return;
2752

    
2753
    case 0x30:        /* ALARM_MONTHS_REG */
2754
#ifdef ALMDEBUG
2755
        printf("ALM MON_REG <-- %02x\n", value);
2756
#endif
2757
        s->alarm_tm.tm_mon = from_bcd(value);
2758
        omap_rtc_alarm_update(s);
2759
        return;
2760

    
2761
    case 0x34:        /* ALARM_YEARS_REG */
2762
#ifdef ALMDEBUG
2763
        printf("ALM YRS_REG <-- %02x\n", value);
2764
#endif
2765
        s->alarm_tm.tm_year = from_bcd(value);
2766
        omap_rtc_alarm_update(s);
2767
        return;
2768

    
2769
    case 0x40:        /* RTC_CTRL_REG */
2770
#ifdef ALMDEBUG
2771
        printf("RTC CONTROL <-- %02x\n", value);
2772
#endif
2773
        s->pm_am = (value >> 3) & 1;
2774
        s->auto_comp = (value >> 2) & 1;
2775
        s->round = (value >> 1) & 1;
2776
        s->running = value & 1;
2777
        s->status &= 0xfd;
2778
        s->status |= s->running << 1;
2779
        return;
2780

    
2781
    case 0x44:        /* RTC_STATUS_REG */
2782
#ifdef ALMDEBUG
2783
        printf("RTC STATUSL <-- %02x\n", value);
2784
#endif
2785
        s->status &= ~((value & 0xc0) ^ 0x80);
2786
        omap_rtc_interrupts_update(s);
2787
        return;
2788

    
2789
    case 0x48:        /* RTC_INTERRUPTS_REG */
2790
#ifdef ALMDEBUG
2791
        printf("RTC INTRS <-- %02x\n", value);
2792
#endif
2793
        s->interrupts = value;
2794
        return;
2795

    
2796
    case 0x4c:        /* RTC_COMP_LSB_REG */
2797
#ifdef ALMDEBUG
2798
        printf("RTC COMPLSB <-- %02x\n", value);
2799
#endif
2800
        s->comp_reg &= 0xff00;
2801
        s->comp_reg |= 0x00ff & value;
2802
        return;
2803

    
2804
    case 0x50:        /* RTC_COMP_MSB_REG */
2805
#ifdef ALMDEBUG
2806
        printf("RTC COMPMSB <-- %02x\n", value);
2807
#endif
2808
        s->comp_reg &= 0x00ff;
2809
        s->comp_reg |= 0xff00 & (value << 8);
2810
        return;
2811

    
2812
    default:
2813
        OMAP_BAD_REG(addr);
2814
        return;
2815
    }
2816
}
2817

    
2818
static const MemoryRegionOps omap_rtc_ops = {
2819
    .read = omap_rtc_read,
2820
    .write = omap_rtc_write,
2821
    .endianness = DEVICE_NATIVE_ENDIAN,
2822
};
2823

    
2824
static void omap_rtc_tick(void *opaque)
2825
{
2826
    struct omap_rtc_s *s = opaque;
2827

    
2828
    if (s->round) {
2829
        /* Round to nearest full minute.  */
2830
        if (s->current_tm.tm_sec < 30)
2831
            s->ti -= s->current_tm.tm_sec;
2832
        else
2833
            s->ti += 60 - s->current_tm.tm_sec;
2834

    
2835
        s->round = 0;
2836
    }
2837

    
2838
    localtime_r(&s->ti, &s->current_tm);
2839

    
2840
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2841
        s->status |= 0x40;
2842
        omap_rtc_interrupts_update(s);
2843
    }
2844

    
2845
    if (s->interrupts & 0x04)
2846
        switch (s->interrupts & 3) {
2847
        case 0:
2848
            s->status |= 0x04;
2849
            qemu_irq_pulse(s->irq);
2850
            break;
2851
        case 1:
2852
            if (s->current_tm.tm_sec)
2853
                break;
2854
            s->status |= 0x08;
2855
            qemu_irq_pulse(s->irq);
2856
            break;
2857
        case 2:
2858
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
2859
                break;
2860
            s->status |= 0x10;
2861
            qemu_irq_pulse(s->irq);
2862
            break;
2863
        case 3:
2864
            if (s->current_tm.tm_sec ||
2865
                            s->current_tm.tm_min || s->current_tm.tm_hour)
2866
                break;
2867
            s->status |= 0x20;
2868
            qemu_irq_pulse(s->irq);
2869
            break;
2870
        }
2871

    
2872
    /* Move on */
2873
    if (s->running)
2874
        s->ti ++;
2875
    s->tick += 1000;
2876

    
2877
    /*
2878
     * Every full hour add a rough approximation of the compensation
2879
     * register to the 32kHz Timer (which drives the RTC) value. 
2880
     */
2881
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
2882
        s->tick += s->comp_reg * 1000 / 32768;
2883

    
2884
    qemu_mod_timer(s->clk, s->tick);
2885
}
2886

    
2887
static void omap_rtc_reset(struct omap_rtc_s *s)
2888
{
2889
    struct tm tm;
2890

    
2891
    s->interrupts = 0;
2892
    s->comp_reg = 0;
2893
    s->running = 0;
2894
    s->pm_am = 0;
2895
    s->auto_comp = 0;
2896
    s->round = 0;
2897
    s->tick = qemu_get_clock_ms(rtc_clock);
2898
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
2899
    s->alarm_tm.tm_mday = 0x01;
2900
    s->status = 1 << 7;
2901
    qemu_get_timedate(&tm, 0);
2902
    s->ti = mktimegm(&tm);
2903

    
2904
    omap_rtc_alarm_update(s);
2905
    omap_rtc_tick(s);
2906
}
2907

    
2908
static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
2909
                                        hwaddr base,
2910
                                        qemu_irq timerirq, qemu_irq alarmirq,
2911
                                        omap_clk clk)
2912
{
2913
    struct omap_rtc_s *s = (struct omap_rtc_s *)
2914
            g_malloc0(sizeof(struct omap_rtc_s));
2915

    
2916
    s->irq = timerirq;
2917
    s->alarm = alarmirq;
2918
    s->clk = qemu_new_timer_ms(rtc_clock, omap_rtc_tick, s);
2919

    
2920
    omap_rtc_reset(s);
2921

    
2922
    memory_region_init_io(&s->iomem, &omap_rtc_ops, s,
2923
                          "omap-rtc", 0x800);
2924
    memory_region_add_subregion(system_memory, base, &s->iomem);
2925

    
2926
    return s;
2927
}
2928

    
2929
/* Multi-channel Buffered Serial Port interfaces */
2930
struct omap_mcbsp_s {
2931
    MemoryRegion iomem;
2932
    qemu_irq txirq;
2933
    qemu_irq rxirq;
2934
    qemu_irq txdrq;
2935
    qemu_irq rxdrq;
2936

    
2937
    uint16_t spcr[2];
2938
    uint16_t rcr[2];
2939
    uint16_t xcr[2];
2940
    uint16_t srgr[2];
2941
    uint16_t mcr[2];
2942
    uint16_t pcr;
2943
    uint16_t rcer[8];
2944
    uint16_t xcer[8];
2945
    int tx_rate;
2946
    int rx_rate;
2947
    int tx_req;
2948
    int rx_req;
2949

    
2950
    I2SCodec *codec;
2951
    QEMUTimer *source_timer;
2952
    QEMUTimer *sink_timer;
2953
};
2954

    
2955
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2956
{
2957
    int irq;
2958

    
2959
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
2960
    case 0:
2961
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
2962
        break;
2963
    case 3:
2964
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
2965
        break;
2966
    default:
2967
        irq = 0;
2968
        break;
2969
    }
2970

    
2971
    if (irq)
2972
        qemu_irq_pulse(s->rxirq);
2973

    
2974
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
2975
    case 0:
2976
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
2977
        break;
2978
    case 3:
2979
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
2980
        break;
2981
    default:
2982
        irq = 0;
2983
        break;
2984
    }
2985

    
2986
    if (irq)
2987
        qemu_irq_pulse(s->txirq);
2988
}
2989

    
2990
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
2991
{
2992
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
2993
        s->spcr[0] |= 1 << 2;                                /* RFULL */
2994
    s->spcr[0] |= 1 << 1;                                /* RRDY */
2995
    qemu_irq_raise(s->rxdrq);
2996
    omap_mcbsp_intr_update(s);
2997
}
2998

    
2999
static void omap_mcbsp_source_tick(void *opaque)
3000
{
3001
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3002
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3003

    
3004
    if (!s->rx_rate)
3005
        return;
3006
    if (s->rx_req)
3007
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
3008

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

    
3011
    omap_mcbsp_rx_newdata(s);
3012
    qemu_mod_timer(s->source_timer, qemu_get_clock_ns(vm_clock) +
3013
                   get_ticks_per_sec());
3014
}
3015

    
3016
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
3017
{
3018
    if (!s->codec || !s->codec->rts)
3019
        omap_mcbsp_source_tick(s);
3020
    else if (s->codec->in.len) {
3021
        s->rx_req = s->codec->in.len;
3022
        omap_mcbsp_rx_newdata(s);
3023
    }
3024
}
3025

    
3026
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3027
{
3028
    qemu_del_timer(s->source_timer);
3029
}
3030

    
3031
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3032
{
3033
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
3034
    qemu_irq_lower(s->rxdrq);
3035
    omap_mcbsp_intr_update(s);
3036
}
3037

    
3038
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3039
{
3040
    s->spcr[1] |= 1 << 1;                                /* XRDY */
3041
    qemu_irq_raise(s->txdrq);
3042
    omap_mcbsp_intr_update(s);
3043
}
3044

    
3045
static void omap_mcbsp_sink_tick(void *opaque)
3046
{
3047
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3048
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3049

    
3050
    if (!s->tx_rate)
3051
        return;
3052
    if (s->tx_req)
3053
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
3054

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

    
3057
    omap_mcbsp_tx_newdata(s);
3058
    qemu_mod_timer(s->sink_timer, qemu_get_clock_ns(vm_clock) +
3059
                   get_ticks_per_sec());
3060
}
3061

    
3062
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3063
{
3064
    if (!s->codec || !s->codec->cts)
3065
        omap_mcbsp_sink_tick(s);
3066
    else if (s->codec->out.size) {
3067
        s->tx_req = s->codec->out.size;
3068
        omap_mcbsp_tx_newdata(s);
3069
    }
3070
}
3071

    
3072
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3073
{
3074
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
3075
    qemu_irq_lower(s->txdrq);
3076
    omap_mcbsp_intr_update(s);
3077
    if (s->codec && s->codec->cts)
3078
        s->codec->tx_swallow(s->codec->opaque);
3079
}
3080

    
3081
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3082
{
3083
    s->tx_req = 0;
3084
    omap_mcbsp_tx_done(s);
3085
    qemu_del_timer(s->sink_timer);
3086
}
3087

    
3088
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3089
{
3090
    int prev_rx_rate, prev_tx_rate;
3091
    int rx_rate = 0, tx_rate = 0;
3092
    int cpu_rate = 1500000;        /* XXX */
3093

    
3094
    /* TODO: check CLKSTP bit */
3095
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
3096
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
3097
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3098
                            (s->pcr & (1 << 8))) {        /* CLKRM */
3099
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3100
                    rx_rate = cpu_rate /
3101
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3102
            } else
3103
                if (s->codec)
3104
                    rx_rate = s->codec->rx_rate;
3105
        }
3106

    
3107
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
3108
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3109
                            (s->pcr & (1 << 9))) {        /* CLKXM */
3110
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3111
                    tx_rate = cpu_rate /
3112
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3113
            } else
3114
                if (s->codec)
3115
                    tx_rate = s->codec->tx_rate;
3116
        }
3117
    }
3118
    prev_tx_rate = s->tx_rate;
3119
    prev_rx_rate = s->rx_rate;
3120
    s->tx_rate = tx_rate;
3121
    s->rx_rate = rx_rate;
3122

    
3123
    if (s->codec)
3124
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3125

    
3126
    if (!prev_tx_rate && tx_rate)
3127
        omap_mcbsp_tx_start(s);
3128
    else if (s->tx_rate && !tx_rate)
3129
        omap_mcbsp_tx_stop(s);
3130

    
3131
    if (!prev_rx_rate && rx_rate)
3132
        omap_mcbsp_rx_start(s);
3133
    else if (prev_tx_rate && !tx_rate)
3134
        omap_mcbsp_rx_stop(s);
3135
}
3136

    
3137
static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
3138
                                unsigned size)
3139
{
3140
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3141
    int offset = addr & OMAP_MPUI_REG_MASK;
3142
    uint16_t ret;
3143

    
3144
    if (size != 2) {
3145
        return omap_badwidth_read16(opaque, addr);
3146
    }
3147

    
3148
    switch (offset) {
3149
    case 0x00:        /* DRR2 */
3150
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
3151
            return 0x0000;
3152
        /* Fall through.  */
3153
    case 0x02:        /* DRR1 */
3154
        if (s->rx_req < 2) {
3155
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
3156
            omap_mcbsp_rx_done(s);
3157
        } else {
3158
            s->tx_req -= 2;
3159
            if (s->codec && s->codec->in.len >= 2) {
3160
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3161
                ret |= s->codec->in.fifo[s->codec->in.start ++];
3162
                s->codec->in.len -= 2;
3163
            } else
3164
                ret = 0x0000;
3165
            if (!s->tx_req)
3166
                omap_mcbsp_rx_done(s);
3167
            return ret;
3168
        }
3169
        return 0x0000;
3170

    
3171
    case 0x04:        /* DXR2 */
3172
    case 0x06:        /* DXR1 */
3173
        return 0x0000;
3174

    
3175
    case 0x08:        /* SPCR2 */
3176
        return s->spcr[1];
3177
    case 0x0a:        /* SPCR1 */
3178
        return s->spcr[0];
3179
    case 0x0c:        /* RCR2 */
3180
        return s->rcr[1];
3181
    case 0x0e:        /* RCR1 */
3182
        return s->rcr[0];
3183
    case 0x10:        /* XCR2 */
3184
        return s->xcr[1];
3185
    case 0x12:        /* XCR1 */
3186
        return s->xcr[0];
3187
    case 0x14:        /* SRGR2 */
3188
        return s->srgr[1];
3189
    case 0x16:        /* SRGR1 */
3190
        return s->srgr[0];
3191
    case 0x18:        /* MCR2 */
3192
        return s->mcr[1];
3193
    case 0x1a:        /* MCR1 */
3194
        return s->mcr[0];
3195
    case 0x1c:        /* RCERA */
3196
        return s->rcer[0];
3197
    case 0x1e:        /* RCERB */
3198
        return s->rcer[1];
3199
    case 0x20:        /* XCERA */
3200
        return s->xcer[0];
3201
    case 0x22:        /* XCERB */
3202
        return s->xcer[1];
3203
    case 0x24:        /* PCR0 */
3204
        return s->pcr;
3205
    case 0x26:        /* RCERC */
3206
        return s->rcer[2];
3207
    case 0x28:        /* RCERD */
3208
        return s->rcer[3];
3209
    case 0x2a:        /* XCERC */
3210
        return s->xcer[2];
3211
    case 0x2c:        /* XCERD */
3212
        return s->xcer[3];
3213
    case 0x2e:        /* RCERE */
3214
        return s->rcer[4];
3215
    case 0x30:        /* RCERF */
3216
        return s->rcer[5];
3217
    case 0x32:        /* XCERE */
3218
        return s->xcer[4];
3219
    case 0x34:        /* XCERF */
3220
        return s->xcer[5];
3221
    case 0x36:        /* RCERG */
3222
        return s->rcer[6];
3223
    case 0x38:        /* RCERH */
3224
        return s->rcer[7];
3225
    case 0x3a:        /* XCERG */
3226
        return s->xcer[6];
3227
    case 0x3c:        /* XCERH */
3228
        return s->xcer[7];
3229
    }
3230

    
3231
    OMAP_BAD_REG(addr);
3232
    return 0;
3233
}
3234

    
3235
static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
3236
                uint32_t value)
3237
{
3238
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3239
    int offset = addr & OMAP_MPUI_REG_MASK;
3240

    
3241
    switch (offset) {
3242
    case 0x00:        /* DRR2 */
3243
    case 0x02:        /* DRR1 */
3244
        OMAP_RO_REG(addr);
3245
        return;
3246

    
3247
    case 0x04:        /* DXR2 */
3248
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
3249
            return;
3250
        /* Fall through.  */
3251
    case 0x06:        /* DXR1 */
3252
        if (s->tx_req > 1) {
3253
            s->tx_req -= 2;
3254
            if (s->codec && s->codec->cts) {
3255
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
3256
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
3257
            }
3258
            if (s->tx_req < 2)
3259
                omap_mcbsp_tx_done(s);
3260
        } else
3261
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3262
        return;
3263

    
3264
    case 0x08:        /* SPCR2 */
3265
        s->spcr[1] &= 0x0002;
3266
        s->spcr[1] |= 0x03f9 & value;
3267
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
3268
        if (~value & 1)                                        /* XRST */
3269
            s->spcr[1] &= ~6;
3270
        omap_mcbsp_req_update(s);
3271
        return;
3272
    case 0x0a:        /* SPCR1 */
3273
        s->spcr[0] &= 0x0006;
3274
        s->spcr[0] |= 0xf8f9 & value;
3275
        if (value & (1 << 15))                                /* DLB */
3276
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
3277
        if (~value & 1) {                                /* RRST */
3278
            s->spcr[0] &= ~6;
3279
            s->rx_req = 0;
3280
            omap_mcbsp_rx_done(s);
3281
        }
3282
        omap_mcbsp_req_update(s);
3283
        return;
3284

    
3285
    case 0x0c:        /* RCR2 */
3286
        s->rcr[1] = value & 0xffff;
3287
        return;
3288
    case 0x0e:        /* RCR1 */
3289
        s->rcr[0] = value & 0x7fe0;
3290
        return;
3291
    case 0x10:        /* XCR2 */
3292
        s->xcr[1] = value & 0xffff;
3293
        return;
3294
    case 0x12:        /* XCR1 */
3295
        s->xcr[0] = value & 0x7fe0;
3296
        return;
3297
    case 0x14:        /* SRGR2 */
3298
        s->srgr[1] = value & 0xffff;
3299
        omap_mcbsp_req_update(s);
3300
        return;
3301
    case 0x16:        /* SRGR1 */
3302
        s->srgr[0] = value & 0xffff;
3303
        omap_mcbsp_req_update(s);
3304
        return;
3305
    case 0x18:        /* MCR2 */
3306
        s->mcr[1] = value & 0x03e3;
3307
        if (value & 3)                                        /* XMCM */
3308
            printf("%s: Tx channel selection mode enable attempt\n",
3309
                            __FUNCTION__);
3310
        return;
3311
    case 0x1a:        /* MCR1 */
3312
        s->mcr[0] = value & 0x03e1;
3313
        if (value & 1)                                        /* RMCM */
3314
            printf("%s: Rx channel selection mode enable attempt\n",
3315
                            __FUNCTION__);
3316
        return;
3317
    case 0x1c:        /* RCERA */
3318
        s->rcer[0] = value & 0xffff;
3319
        return;
3320
    case 0x1e:        /* RCERB */
3321
        s->rcer[1] = value & 0xffff;
3322
        return;
3323
    case 0x20:        /* XCERA */
3324
        s->xcer[0] = value & 0xffff;
3325
        return;
3326
    case 0x22:        /* XCERB */
3327
        s->xcer[1] = value & 0xffff;
3328
        return;
3329
    case 0x24:        /* PCR0 */
3330
        s->pcr = value & 0x7faf;
3331
        return;
3332
    case 0x26:        /* RCERC */
3333
        s->rcer[2] = value & 0xffff;
3334
        return;
3335
    case 0x28:        /* RCERD */
3336
        s->rcer[3] = value & 0xffff;
3337
        return;
3338
    case 0x2a:        /* XCERC */
3339
        s->xcer[2] = value & 0xffff;
3340
        return;
3341
    case 0x2c:        /* XCERD */
3342
        s->xcer[3] = value & 0xffff;
3343
        return;
3344
    case 0x2e:        /* RCERE */
3345
        s->rcer[4] = value & 0xffff;
3346
        return;
3347
    case 0x30:        /* RCERF */
3348
        s->rcer[5] = value & 0xffff;
3349
        return;
3350
    case 0x32:        /* XCERE */
3351
        s->xcer[4] = value & 0xffff;
3352
        return;
3353
    case 0x34:        /* XCERF */
3354
        s->xcer[5] = value & 0xffff;
3355
        return;
3356
    case 0x36:        /* RCERG */
3357
        s->rcer[6] = value & 0xffff;
3358
        return;
3359
    case 0x38:        /* RCERH */
3360
        s->rcer[7] = value & 0xffff;
3361
        return;
3362
    case 0x3a:        /* XCERG */
3363
        s->xcer[6] = value & 0xffff;
3364
        return;
3365
    case 0x3c:        /* XCERH */
3366
        s->xcer[7] = value & 0xffff;
3367
        return;
3368
    }
3369

    
3370
    OMAP_BAD_REG(addr);
3371
}
3372

    
3373
static void omap_mcbsp_writew(void *opaque, hwaddr addr,
3374
                uint32_t value)
3375
{
3376
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3377
    int offset = addr & OMAP_MPUI_REG_MASK;
3378

    
3379
    if (offset == 0x04) {                                /* DXR */
3380
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
3381
            return;
3382
        if (s->tx_req > 3) {
3383
            s->tx_req -= 4;
3384
            if (s->codec && s->codec->cts) {
3385
                s->codec->out.fifo[s->codec->out.len ++] =
3386
                        (value >> 24) & 0xff;
3387
                s->codec->out.fifo[s->codec->out.len ++] =
3388
                        (value >> 16) & 0xff;
3389
                s->codec->out.fifo[s->codec->out.len ++] =
3390
                        (value >> 8) & 0xff;
3391
                s->codec->out.fifo[s->codec->out.len ++] =
3392
                        (value >> 0) & 0xff;
3393
            }
3394
            if (s->tx_req < 4)
3395
                omap_mcbsp_tx_done(s);
3396
        } else
3397
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3398
        return;
3399
    }
3400

    
3401
    omap_badwidth_write16(opaque, addr, value);
3402
}
3403

    
3404
static void omap_mcbsp_write(void *opaque, hwaddr addr,
3405
                             uint64_t value, unsigned size)
3406
{
3407
    switch (size) {
3408
    case 2: return omap_mcbsp_writeh(opaque, addr, value);
3409
    case 4: return omap_mcbsp_writew(opaque, addr, value);
3410
    default: return omap_badwidth_write16(opaque, addr, value);
3411
    }
3412
}
3413

    
3414
static const MemoryRegionOps omap_mcbsp_ops = {
3415
    .read = omap_mcbsp_read,
3416
    .write = omap_mcbsp_write,
3417
    .endianness = DEVICE_NATIVE_ENDIAN,
3418
};
3419

    
3420
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
3421
{
3422
    memset(&s->spcr, 0, sizeof(s->spcr));
3423
    memset(&s->rcr, 0, sizeof(s->rcr));
3424
    memset(&s->xcr, 0, sizeof(s->xcr));
3425
    s->srgr[0] = 0x0001;
3426
    s->srgr[1] = 0x2000;
3427
    memset(&s->mcr, 0, sizeof(s->mcr));
3428
    memset(&s->pcr, 0, sizeof(s->pcr));
3429
    memset(&s->rcer, 0, sizeof(s->rcer));
3430
    memset(&s->xcer, 0, sizeof(s->xcer));
3431
    s->tx_req = 0;
3432
    s->rx_req = 0;
3433
    s->tx_rate = 0;
3434
    s->rx_rate = 0;
3435
    qemu_del_timer(s->source_timer);
3436
    qemu_del_timer(s->sink_timer);
3437
}
3438

    
3439
static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
3440
                                            hwaddr base,
3441
                                            qemu_irq txirq, qemu_irq rxirq,
3442
                                            qemu_irq *dma, omap_clk clk)
3443
{
3444
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
3445
            g_malloc0(sizeof(struct omap_mcbsp_s));
3446

    
3447
    s->txirq = txirq;
3448
    s->rxirq = rxirq;
3449
    s->txdrq = dma[0];
3450
    s->rxdrq = dma[1];
3451
    s->sink_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_sink_tick, s);
3452
    s->source_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_source_tick, s);
3453
    omap_mcbsp_reset(s);
3454

    
3455
    memory_region_init_io(&s->iomem, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
3456
    memory_region_add_subregion(system_memory, base, &s->iomem);
3457

    
3458
    return s;
3459
}
3460

    
3461
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3462
{
3463
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3464

    
3465
    if (s->rx_rate) {
3466
        s->rx_req = s->codec->in.len;
3467
        omap_mcbsp_rx_newdata(s);
3468
    }
3469
}
3470

    
3471
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3472
{
3473
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3474

    
3475
    if (s->tx_rate) {
3476
        s->tx_req = s->codec->out.size;
3477
        omap_mcbsp_tx_newdata(s);
3478
    }
3479
}
3480

    
3481
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
3482
{
3483
    s->codec = slave;
3484
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
3485
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
3486
}
3487

    
3488
/* LED Pulse Generators */
3489
struct omap_lpg_s {
3490
    MemoryRegion iomem;
3491
    QEMUTimer *tm;
3492

    
3493
    uint8_t control;
3494
    uint8_t power;
3495
    int64_t on;
3496
    int64_t period;
3497
    int clk;
3498
    int cycle;
3499
};
3500

    
3501
static void omap_lpg_tick(void *opaque)
3502
{
3503
    struct omap_lpg_s *s = opaque;
3504

    
3505
    if (s->cycle)
3506
        qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->period - s->on);
3507
    else
3508
        qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->on);
3509

    
3510
    s->cycle = !s->cycle;
3511
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
3512
}
3513

    
3514
static void omap_lpg_update(struct omap_lpg_s *s)
3515
{
3516
    int64_t on, period = 1, ticks = 1000;
3517
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
3518

    
3519
    if (~s->control & (1 << 6))                                        /* LPGRES */
3520
        on = 0;
3521
    else if (s->control & (1 << 7))                                /* PERM_ON */
3522
        on = period;
3523
    else {
3524
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
3525
                        256 / 32);
3526
        on = (s->clk && s->power) ? muldiv64(ticks,
3527
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
3528
    }
3529

    
3530
    qemu_del_timer(s->tm);
3531
    if (on == period && s->on < s->period)
3532
        printf("%s: LED is on\n", __FUNCTION__);
3533
    else if (on == 0 && s->on)
3534
        printf("%s: LED is off\n", __FUNCTION__);
3535
    else if (on && (on != s->on || period != s->period)) {
3536
        s->cycle = 0;
3537
        s->on = on;
3538
        s->period = period;
3539
        omap_lpg_tick(s);
3540
        return;
3541
    }
3542

    
3543
    s->on = on;
3544
    s->period = period;
3545
}
3546

    
3547
static void omap_lpg_reset(struct omap_lpg_s *s)
3548
{
3549
    s->control = 0x00;
3550
    s->power = 0x00;
3551
    s->clk = 1;
3552
    omap_lpg_update(s);
3553
}
3554

    
3555
static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
3556
                              unsigned size)
3557
{
3558
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3559
    int offset = addr & OMAP_MPUI_REG_MASK;
3560

    
3561
    if (size != 1) {
3562
        return omap_badwidth_read8(opaque, addr);
3563
    }
3564

    
3565
    switch (offset) {
3566
    case 0x00:        /* LCR */
3567
        return s->control;
3568

    
3569
    case 0x04:        /* PMR */
3570
        return s->power;
3571
    }
3572

    
3573
    OMAP_BAD_REG(addr);
3574
    return 0;
3575
}
3576

    
3577
static void omap_lpg_write(void *opaque, hwaddr addr,
3578
                           uint64_t value, unsigned size)
3579
{
3580
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3581
    int offset = addr & OMAP_MPUI_REG_MASK;
3582

    
3583
    if (size != 1) {
3584
        return omap_badwidth_write8(opaque, addr, value);
3585
    }
3586

    
3587
    switch (offset) {
3588
    case 0x00:        /* LCR */
3589
        if (~value & (1 << 6))                                        /* LPGRES */
3590
            omap_lpg_reset(s);
3591
        s->control = value & 0xff;
3592
        omap_lpg_update(s);
3593
        return;
3594

    
3595
    case 0x04:        /* PMR */
3596
        s->power = value & 0x01;
3597
        omap_lpg_update(s);
3598
        return;
3599

    
3600
    default:
3601
        OMAP_BAD_REG(addr);
3602
        return;
3603
    }
3604
}
3605

    
3606
static const MemoryRegionOps omap_lpg_ops = {
3607
    .read = omap_lpg_read,
3608
    .write = omap_lpg_write,
3609
    .endianness = DEVICE_NATIVE_ENDIAN,
3610
};
3611

    
3612
static void omap_lpg_clk_update(void *opaque, int line, int on)
3613
{
3614
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3615

    
3616
    s->clk = on;
3617
    omap_lpg_update(s);
3618
}
3619

    
3620
static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
3621
                                        hwaddr base, omap_clk clk)
3622
{
3623
    struct omap_lpg_s *s = (struct omap_lpg_s *)
3624
            g_malloc0(sizeof(struct omap_lpg_s));
3625

    
3626
    s->tm = qemu_new_timer_ms(vm_clock, omap_lpg_tick, s);
3627

    
3628
    omap_lpg_reset(s);
3629

    
3630
    memory_region_init_io(&s->iomem, &omap_lpg_ops, s, "omap-lpg", 0x800);
3631
    memory_region_add_subregion(system_memory, base, &s->iomem);
3632

    
3633
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
3634

    
3635
    return s;
3636
}
3637

    
3638
/* MPUI Peripheral Bridge configuration */
3639
static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr,
3640
                                  unsigned size)
3641
{
3642
    if (size != 2) {
3643
        return omap_badwidth_read16(opaque, addr);
3644
    }
3645

    
3646
    if (addr == OMAP_MPUI_BASE)        /* CMR */
3647
        return 0xfe4d;
3648

    
3649
    OMAP_BAD_REG(addr);
3650
    return 0;
3651
}
3652

    
3653
static void omap_mpui_io_write(void *opaque, hwaddr addr,
3654
                               uint64_t value, unsigned size)
3655
{
3656
    /* FIXME: infinite loop */
3657
    omap_badwidth_write16(opaque, addr, value);
3658
}
3659

    
3660
static const MemoryRegionOps omap_mpui_io_ops = {
3661
    .read = omap_mpui_io_read,
3662
    .write = omap_mpui_io_write,
3663
    .endianness = DEVICE_NATIVE_ENDIAN,
3664
};
3665

    
3666
static void omap_setup_mpui_io(MemoryRegion *system_memory,
3667
                               struct omap_mpu_state_s *mpu)
3668
{
3669
    memory_region_init_io(&mpu->mpui_io_iomem, &omap_mpui_io_ops, mpu,
3670
                          "omap-mpui-io", 0x7fff);
3671
    memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
3672
                                &mpu->mpui_io_iomem);
3673
}
3674

    
3675
/* General chip reset */
3676
static void omap1_mpu_reset(void *opaque)
3677
{
3678
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3679

    
3680
    omap_dma_reset(mpu->dma);
3681
    omap_mpu_timer_reset(mpu->timer[0]);
3682
    omap_mpu_timer_reset(mpu->timer[1]);
3683
    omap_mpu_timer_reset(mpu->timer[2]);
3684
    omap_wd_timer_reset(mpu->wdt);
3685
    omap_os_timer_reset(mpu->os_timer);
3686
    omap_lcdc_reset(mpu->lcd);
3687
    omap_ulpd_pm_reset(mpu);
3688
    omap_pin_cfg_reset(mpu);
3689
    omap_mpui_reset(mpu);
3690
    omap_tipb_bridge_reset(mpu->private_tipb);
3691
    omap_tipb_bridge_reset(mpu->public_tipb);
3692
    omap_dpll_reset(mpu->dpll[0]);
3693
    omap_dpll_reset(mpu->dpll[1]);
3694
    omap_dpll_reset(mpu->dpll[2]);
3695
    omap_uart_reset(mpu->uart[0]);
3696
    omap_uart_reset(mpu->uart[1]);
3697
    omap_uart_reset(mpu->uart[2]);
3698
    omap_mmc_reset(mpu->mmc);
3699
    omap_mpuio_reset(mpu->mpuio);
3700
    omap_uwire_reset(mpu->microwire);
3701
    omap_pwl_reset(mpu->pwl);
3702
    omap_pwt_reset(mpu->pwt);
3703
    omap_rtc_reset(mpu->rtc);
3704
    omap_mcbsp_reset(mpu->mcbsp1);
3705
    omap_mcbsp_reset(mpu->mcbsp2);
3706
    omap_mcbsp_reset(mpu->mcbsp3);
3707
    omap_lpg_reset(mpu->led[0]);
3708
    omap_lpg_reset(mpu->led[1]);
3709
    omap_clkm_reset(mpu);
3710
    cpu_reset(CPU(mpu->cpu));
3711
}
3712

    
3713
static const struct omap_map_s {
3714
    hwaddr phys_dsp;
3715
    hwaddr phys_mpu;
3716
    uint32_t size;
3717
    const char *name;
3718
} omap15xx_dsp_mm[] = {
3719
    /* Strobe 0 */
3720
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
3721
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
3722
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
3723
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
3724
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
3725
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
3726
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
3727
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
3728
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
3729
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
3730
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
3731
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
3732
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
3733
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
3734
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
3735
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
3736
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
3737
    /* Strobe 1 */
3738
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
3739

    
3740
    { 0 }
3741
};
3742

    
3743
static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
3744
                                   const struct omap_map_s *map)
3745
{
3746
    MemoryRegion *io;
3747

    
3748
    for (; map->phys_dsp; map ++) {
3749
        io = g_new(MemoryRegion, 1);
3750
        memory_region_init_alias(io, map->name,
3751
                                 system_memory, map->phys_mpu, map->size);
3752
        memory_region_add_subregion(system_memory, map->phys_dsp, io);
3753
    }
3754
}
3755

    
3756
void omap_mpu_wakeup(void *opaque, int irq, int req)
3757
{
3758
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3759
    CPUState *cpu = CPU(mpu->cpu);
3760

    
3761
    if (cpu->halted) {
3762
        cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
3763
    }
3764
}
3765

    
3766
static const struct dma_irq_map omap1_dma_irq_map[] = {
3767
    { 0, OMAP_INT_DMA_CH0_6 },
3768
    { 0, OMAP_INT_DMA_CH1_7 },
3769
    { 0, OMAP_INT_DMA_CH2_8 },
3770
    { 0, OMAP_INT_DMA_CH3 },
3771
    { 0, OMAP_INT_DMA_CH4 },
3772
    { 0, OMAP_INT_DMA_CH5 },
3773
    { 1, OMAP_INT_1610_DMA_CH6 },
3774
    { 1, OMAP_INT_1610_DMA_CH7 },
3775
    { 1, OMAP_INT_1610_DMA_CH8 },
3776
    { 1, OMAP_INT_1610_DMA_CH9 },
3777
    { 1, OMAP_INT_1610_DMA_CH10 },
3778
    { 1, OMAP_INT_1610_DMA_CH11 },
3779
    { 1, OMAP_INT_1610_DMA_CH12 },
3780
    { 1, OMAP_INT_1610_DMA_CH13 },
3781
    { 1, OMAP_INT_1610_DMA_CH14 },
3782
    { 1, OMAP_INT_1610_DMA_CH15 }
3783
};
3784

    
3785
/* DMA ports for OMAP1 */
3786
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
3787
                hwaddr addr)
3788
{
3789
    return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
3790
}
3791

    
3792
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
3793
                hwaddr addr)
3794
{
3795
    return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
3796
                             addr);
3797
}
3798

    
3799
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
3800
                hwaddr addr)
3801
{
3802
    return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
3803
}
3804

    
3805
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
3806
                hwaddr addr)
3807
{
3808
    return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
3809
}
3810

    
3811
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3812
                hwaddr addr)
3813
{
3814
    return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
3815
}
3816

    
3817
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
3818
                hwaddr addr)
3819
{
3820
    return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
3821
}
3822

    
3823
struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
3824
                unsigned long sdram_size,
3825
                const char *core)
3826
{
3827
    int i;
3828
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
3829
            g_malloc0(sizeof(struct omap_mpu_state_s));
3830
    qemu_irq *cpu_irq;
3831
    qemu_irq dma_irqs[6];
3832
    DriveInfo *dinfo;
3833
    SysBusDevice *busdev;
3834

    
3835
    if (!core)
3836
        core = "ti925t";
3837

    
3838
    /* Core */
3839
    s->mpu_model = omap310;
3840
    s->cpu = cpu_arm_init(core);
3841
    if (s->cpu == NULL) {
3842
        fprintf(stderr, "Unable to find CPU definition\n");
3843
        exit(1);
3844
    }
3845
    s->sdram_size = sdram_size;
3846
    s->sram_size = OMAP15XX_SRAM_SIZE;
3847

    
3848
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3849

    
3850
    /* Clocks */
3851
    omap_clk_init(s);
3852

    
3853
    /* Memory-mapped stuff */
3854
    memory_region_init_ram(&s->emiff_ram, "omap1.dram", s->sdram_size);
3855
    vmstate_register_ram_global(&s->emiff_ram);
3856
    memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
3857
    memory_region_init_ram(&s->imif_ram, "omap1.sram", s->sram_size);
3858
    vmstate_register_ram_global(&s->imif_ram);
3859
    memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
3860

    
3861
    omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
3862

    
3863
    cpu_irq = arm_pic_init_cpu(s->cpu);
3864
    s->ih[0] = qdev_create(NULL, "omap-intc");
3865
    qdev_prop_set_uint32(s->ih[0], "size", 0x100);
3866
    qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
3867
    qdev_init_nofail(s->ih[0]);
3868
    busdev = SYS_BUS_DEVICE(s->ih[0]);
3869
    sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
3870
    sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
3871
    sysbus_mmio_map(busdev, 0, 0xfffecb00);
3872
    s->ih[1] = qdev_create(NULL, "omap-intc");
3873
    qdev_prop_set_uint32(s->ih[1], "size", 0x800);
3874
    qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
3875
    qdev_init_nofail(s->ih[1]);
3876
    busdev = SYS_BUS_DEVICE(s->ih[1]);
3877
    sysbus_connect_irq(busdev, 0,
3878
                       qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
3879
    /* The second interrupt controller's FIQ output is not wired up */
3880
    sysbus_mmio_map(busdev, 0, 0xfffe0000);
3881

    
3882
    for (i = 0; i < 6; i++) {
3883
        dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
3884
                                       omap1_dma_irq_map[i].intr);
3885
    }
3886
    s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory,
3887
                           qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
3888
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
3889

    
3890
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
3891
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
3892
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
3893
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
3894
    s->port[local    ].addr_valid = omap_validate_local_addr;
3895
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
3896

    
3897
    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
3898
    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram),
3899
                         OMAP_EMIFF_BASE, s->sdram_size);
3900
    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
3901
                         OMAP_IMIF_BASE, s->sram_size);
3902

    
3903
    s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
3904
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
3905
                    omap_findclk(s, "mputim_ck"));
3906
    s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
3907
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
3908
                    omap_findclk(s, "mputim_ck"));
3909
    s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
3910
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
3911
                    omap_findclk(s, "mputim_ck"));
3912

    
3913
    s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
3914
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
3915
                    omap_findclk(s, "armwdt_ck"));
3916

    
3917
    s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
3918
                    qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
3919
                    omap_findclk(s, "clk32-kHz"));
3920

    
3921
    s->lcd = omap_lcdc_init(system_memory, 0xfffec000,
3922
                            qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
3923
                            omap_dma_get_lcdch(s->dma),
3924
                            omap_findclk(s, "lcd_ck"));
3925

    
3926
    omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
3927
    omap_pin_cfg_init(system_memory, 0xfffe1000, s);
3928
    omap_id_init(system_memory, s);
3929

    
3930
    omap_mpui_init(system_memory, 0xfffec900, s);
3931

    
3932
    s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
3933
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
3934
                    omap_findclk(s, "tipb_ck"));
3935
    s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
3936
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
3937
                    omap_findclk(s, "tipb_ck"));
3938

    
3939
    omap_tcmi_init(system_memory, 0xfffecc00, s);
3940

    
3941
    s->uart[0] = omap_uart_init(0xfffb0000,
3942
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
3943
                    omap_findclk(s, "uart1_ck"),
3944
                    omap_findclk(s, "uart1_ck"),
3945
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
3946
                    "uart1",
3947
                    serial_hds[0]);
3948
    s->uart[1] = omap_uart_init(0xfffb0800,
3949
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
3950
                    omap_findclk(s, "uart2_ck"),
3951
                    omap_findclk(s, "uart2_ck"),
3952
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
3953
                    "uart2",
3954
                    serial_hds[0] ? serial_hds[1] : NULL);
3955
    s->uart[2] = omap_uart_init(0xfffb9800,
3956
                                qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
3957
                    omap_findclk(s, "uart3_ck"),
3958
                    omap_findclk(s, "uart3_ck"),
3959
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
3960
                    "uart3",
3961
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
3962

    
3963
    s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
3964
                                omap_findclk(s, "dpll1"));
3965
    s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000,
3966
                                omap_findclk(s, "dpll2"));
3967
    s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100,
3968
                                omap_findclk(s, "dpll3"));
3969

    
3970
    dinfo = drive_get(IF_SD, 0, 0);
3971
    if (!dinfo) {
3972
        fprintf(stderr, "qemu: missing SecureDigital device\n");
3973
        exit(1);
3974
    }
3975
    s->mmc = omap_mmc_init(0xfffb7800, system_memory, dinfo->bdrv,
3976
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
3977
                           &s->drq[OMAP_DMA_MMC_TX],
3978
                    omap_findclk(s, "mmc_ck"));
3979

    
3980
    s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
3981
                               qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD),
3982
                               qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO),
3983
                               s->wakeup, omap_findclk(s, "clk32-kHz"));
3984

    
3985
    s->gpio = qdev_create(NULL, "omap-gpio");
3986
    qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
3987
    qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
3988
    qdev_init_nofail(s->gpio);
3989
    sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio), 0,
3990
                       qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
3991
    sysbus_mmio_map(SYS_BUS_DEVICE(s->gpio), 0, 0xfffce000);
3992

    
3993
    s->microwire = omap_uwire_init(system_memory, 0xfffb3000,
3994
                                   qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX),
3995
                                   qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX),
3996
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
3997

    
3998
    s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
3999
                           omap_findclk(s, "armxor_ck"));
4000
    s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
4001
                           omap_findclk(s, "armxor_ck"));
4002

    
4003
    s->i2c[0] = qdev_create(NULL, "omap_i2c");
4004
    qdev_prop_set_uint8(s->i2c[0], "revision", 0x11);
4005
    qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "mpuper_ck"));
4006
    qdev_init_nofail(s->i2c[0]);
4007
    busdev = SYS_BUS_DEVICE(s->i2c[0]);
4008
    sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C));
4009
    sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]);
4010
    sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]);
4011
    sysbus_mmio_map(busdev, 0, 0xfffb3800);
4012

    
4013
    s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
4014
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
4015
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
4016
                    omap_findclk(s, "clk32-kHz"));
4017

    
4018
    s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
4019
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
4020
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
4021
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4022
    s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
4023
                                qdev_get_gpio_in(s->ih[0],
4024
                                                 OMAP_INT_310_McBSP2_TX),
4025
                                qdev_get_gpio_in(s->ih[0],
4026
                                                 OMAP_INT_310_McBSP2_RX),
4027
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4028
    s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
4029
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
4030
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
4031
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4032

    
4033
    s->led[0] = omap_lpg_init(system_memory,
4034
                              0xfffbd000, omap_findclk(s, "clk32-kHz"));
4035
    s->led[1] = omap_lpg_init(system_memory,
4036
                              0xfffbd800, omap_findclk(s, "clk32-kHz"));
4037

    
4038
    /* Register mappings not currenlty implemented:
4039
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
4040
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
4041
     * USB W2FC                fffb4000 - fffb47ff
4042
     * Camera Interface        fffb6800 - fffb6fff
4043
     * USB Host                fffba000 - fffba7ff
4044
     * FAC                fffba800 - fffbafff
4045
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4046
     * TIPB switches        fffbc800 - fffbcfff
4047
     * Mailbox                fffcf000 - fffcf7ff
4048
     * Local bus IF        fffec100 - fffec1ff
4049
     * Local bus MMU        fffec200 - fffec2ff
4050
     * DSP MMU                fffed200 - fffed2ff
4051
     */
4052

    
4053
    omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
4054
    omap_setup_mpui_io(system_memory, s);
4055

    
4056
    qemu_register_reset(omap1_mpu_reset, s);
4057

    
4058
    return s;
4059
}