Statistics
| Branch: | Revision:

root / hw / omap1.c @ 83c9f4ca

History | View | Annotate | Download (115.7 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-misc.h"
21
#include "hw/omap.h"
22
#include "sysemu/sysemu.h"
23
#include "hw/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(&s->cpu->env, 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

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

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

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

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

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

    
1744
    OMAP_BAD_REG(addr);
1745
    return 0;
1746
}
1747

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

    
1753
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
1754
}
1755

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

    
1761
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
1762
}
1763

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

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

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

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

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

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

    
1795
    default:
1796
        OMAP_BAD_REG(addr);
1797
    }
1798
}
1799

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

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

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

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

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

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

    
1856
    uint16_t inputs;
1857
    uint16_t outputs;
1858
    uint16_t dir;
1859
    uint16_t edge;
1860
    uint16_t mask;
1861
    uint16_t ints;
1862

    
1863
    uint16_t debounce;
1864
    uint16_t latch;
1865
    uint8_t event;
1866

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

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

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

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

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

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

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

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

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

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

    
1924
    case 0x04:        /* OUTPUT_REG */
1925
        return s->outputs;
1926

    
1927
    case 0x08:        /* IO_CNTL */
1928
        return s->dir;
1929

    
1930
    case 0x10:        /* KBR_LATCH */
1931
        return s->row_latch;
1932

    
1933
    case 0x14:        /* KBC_REG */
1934
        return s->cols;
1935

    
1936
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1937
        return s->event;
1938

    
1939
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1940
        return s->edge;
1941

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

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

    
1952
    case 0x28:        /* KBD_MASKIT */
1953
        return s->kbd_mask;
1954

    
1955
    case 0x2c:        /* GPIO_MASKIT */
1956
        return s->mask;
1957

    
1958
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1959
        return s->debounce;
1960

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

    
1965
    OMAP_BAD_REG(addr);
1966
    return 0;
1967
}
1968

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

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

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

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

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

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

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

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

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

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

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

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

    
2040
    default:
2041
        OMAP_BAD_REG(addr);
2042
        return;
2043
    }
2044
}
2045

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

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

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

    
2072
    s->clk = on;
2073
    if (on)
2074
        omap_mpuio_kbd_update(s);
2075
}
2076

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

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

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

    
2095
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2096

    
2097
    return s;
2098
}
2099

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

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

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

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

    
2122
    omap_mpuio_kbd_update(s);
2123
}
2124

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

    
2132
    uint16_t txbuf;
2133
    uint16_t rxbuf;
2134
    uint16_t control;
2135
    uint16_t setup[5];
2136

    
2137
    uWireSlave *chip[4];
2138
};
2139

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

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

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

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

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

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

    
2180
    case 0x04:        /* CSR */
2181
        return s->control;
2182

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

    
2195
    OMAP_BAD_REG(addr);
2196
    return 0;
2197
}
2198

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

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

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

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

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

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

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

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

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

    
2246
    default:
2247
        OMAP_BAD_REG(addr);
2248
        return;
2249
    }
2250
}
2251

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

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

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

    
2277
    s->txirq = txirq;
2278
    s->rxirq = rxirq;
2279
    s->txdrq = dma;
2280
    omap_uwire_reset(s);
2281

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

    
2285
    return s;
2286
}
2287

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

    
2296
    s->chip[chipselect] = slave;
2297
}
2298

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

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

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

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

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

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

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

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

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

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

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

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

    
2382
    s->clk = on;
2383
    omap_pwl_update(s);
2384
}
2385

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

    
2392
    omap_pwl_reset(s);
2393

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2524
    struct tm current_tm;
2525
    time_t ti;
2526
    uint64_t tick;
2527
};
2528

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2610
    case 0x48:        /* RTC_INTERRUPTS_REG */
2611
        return s->interrupts;
2612

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

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

    
2620
    OMAP_BAD_REG(addr);
2621
    return 0;
2622
}
2623

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

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

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

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

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

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

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

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

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

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

    
2711
    case 0x18:        /* WEEK_REG */
2712
        return;        /* Ignored */
2713

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

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

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

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

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

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

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

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

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

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

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

    
2810
    default:
2811
        OMAP_BAD_REG(addr);
2812
        return;
2813
    }
2814
}
2815

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

    
2822
static void omap_rtc_tick(void *opaque)
2823
{
2824
    struct omap_rtc_s *s = opaque;
2825

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

    
2833
        s->round = 0;
2834
    }
2835

    
2836
    localtime_r(&s->ti, &s->current_tm);
2837

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

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

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

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

    
2882
    qemu_mod_timer(s->clk, s->tick);
2883
}
2884

    
2885
static void omap_rtc_reset(struct omap_rtc_s *s)
2886
{
2887
    struct tm tm;
2888

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

    
2902
    omap_rtc_alarm_update(s);
2903
    omap_rtc_tick(s);
2904
}
2905

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

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

    
2918
    omap_rtc_reset(s);
2919

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

    
2924
    return s;
2925
}
2926

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

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

    
2948
    I2SCodec *codec;
2949
    QEMUTimer *source_timer;
2950
    QEMUTimer *sink_timer;
2951
};
2952

    
2953
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2954
{
2955
    int irq;
2956

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

    
2969
    if (irq)
2970
        qemu_irq_pulse(s->rxirq);
2971

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

    
2984
    if (irq)
2985
        qemu_irq_pulse(s->txirq);
2986
}
2987

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3121
    if (s->codec)
3122
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3123

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

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

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

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

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

    
3169
    case 0x04:        /* DXR2 */
3170
    case 0x06:        /* DXR1 */
3171
        return 0x0000;
3172

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

    
3229
    OMAP_BAD_REG(addr);
3230
    return 0;
3231
}
3232

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

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

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

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

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

    
3368
    OMAP_BAD_REG(addr);
3369
}
3370

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

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

    
3399
    omap_badwidth_write16(opaque, addr, value);
3400
}
3401

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

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

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

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

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

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

    
3456
    return s;
3457
}
3458

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

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

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

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

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

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

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

    
3499
static void omap_lpg_tick(void *opaque)
3500
{
3501
    struct omap_lpg_s *s = opaque;
3502

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

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

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

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

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

    
3541
    s->on = on;
3542
    s->period = period;
3543
}
3544

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

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

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

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

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

    
3571
    OMAP_BAD_REG(addr);
3572
    return 0;
3573
}
3574

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

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

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

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

    
3598
    default:
3599
        OMAP_BAD_REG(addr);
3600
        return;
3601
    }
3602
}
3603

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

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

    
3614
    s->clk = on;
3615
    omap_lpg_update(s);
3616
}
3617

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

    
3624
    s->tm = qemu_new_timer_ms(vm_clock, omap_lpg_tick, s);
3625

    
3626
    omap_lpg_reset(s);
3627

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

    
3631
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
3632

    
3633
    return s;
3634
}
3635

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

    
3644
    if (addr == OMAP_MPUI_BASE)        /* CMR */
3645
        return 0xfe4d;
3646

    
3647
    OMAP_BAD_REG(addr);
3648
    return 0;
3649
}
3650

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

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

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

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

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

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

    
3738
    { 0 }
3739
};
3740

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

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

    
3754
void omap_mpu_wakeup(void *opaque, int irq, int req)
3755
{
3756
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3757

    
3758
    if (mpu->cpu->env.halted) {
3759
        cpu_interrupt(&mpu->cpu->env, CPU_INTERRUPT_EXITTB);
3760
    }
3761
}
3762

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

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

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

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

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

    
3808
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3809
                hwaddr addr)
3810
{
3811
    return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
3812
}
3813

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

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

    
3832
    if (!core)
3833
        core = "ti925t";
3834

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

    
3845
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3846

    
3847
    /* Clocks */
3848
    omap_clk_init(s);
3849

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

    
3858
    omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
3859

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

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

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

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

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

    
3910
    s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
3911
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
3912
                    omap_findclk(s, "armwdt_ck"));
3913

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

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

    
3923
    omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
3924
    omap_pin_cfg_init(system_memory, 0xfffe1000, s);
3925
    omap_id_init(system_memory, s);
3926

    
3927
    omap_mpui_init(system_memory, 0xfffec900, s);
3928

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

    
3936
    omap_tcmi_init(system_memory, 0xfffecc00, s);
3937

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

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

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

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

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

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

    
3995
    s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
3996
                           omap_findclk(s, "armxor_ck"));
3997
    s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
3998
                           omap_findclk(s, "armxor_ck"));
3999

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

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

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

    
4030
    s->led[0] = omap_lpg_init(system_memory,
4031
                              0xfffbd000, omap_findclk(s, "clk32-kHz"));
4032
    s->led[1] = omap_lpg_init(system_memory,
4033
                              0xfffbd800, omap_findclk(s, "clk32-kHz"));
4034

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

    
4050
    omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
4051
    omap_setup_mpui_io(system_memory, s);
4052

    
4053
    qemu_register_reset(omap1_mpu_reset, s);
4054

    
4055
    return s;
4056
}