Statistics
| Branch: | Revision:

root / hw / omap1.c @ a8170e5e

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.h"
20
#include "arm-misc.h"
21
#include "omap.h"
22
#include "sysemu.h"
23
#include "soc_dma.h"
24
#include "blockdev.h"
25
#include "range.h"
26
#include "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
    case 0x00:        /* COUNTER_32_LSB */
533
    case 0x04:        /* COUNTER_32_MSB */
534
    case 0x08:        /* COUNTER_HIGH_FREQ_LSB */
535
    case 0x0c:        /* COUNTER_HIGH_FREQ_MSB */
536
    case 0x10:        /* GAUGING_CTRL */
537
    case 0x24:        /* SETUP_ANALOG_CELL3_ULPD1 */
538
    case 0x30:        /* CLOCK_CTRL */
539
    case 0x34:        /* SOFT_REQ */
540
    case 0x38:        /* COUNTER_32_FIQ */
541
    case 0x3c:        /* DPLL_CTRL */
542
    case 0x40:        /* STATUS_REQ */
543
        /* XXX: check clk::usecount state for every clock */
544
    case 0x48:        /* LOCL_TIME */
545
    case 0x4c:        /* APLL_CTRL */
546
    case 0x50:        /* POWER_CTRL */
547
        return s->ulpd_pm_regs[addr >> 2];
548
    }
549

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
690
    default:
691
        OMAP_BAD_REG(addr);
692
    }
693
}
694

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

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

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

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

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

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

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

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

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

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

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

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

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

    
789
    OMAP_BAD_REG(addr);
790
    return 0;
791
}
792

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
919
    default:
920
        OMAP_BAD_REG(addr);
921
    }
922
}
923

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

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

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

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

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

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

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

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

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

    
1000
    OMAP_BAD_REG(addr);
1001
    return 0;
1002
}
1003

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

    
1011
    OMAP_BAD_REG(addr);
1012
}
1013

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

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

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

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

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

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

    
1067
    OMAP_BAD_REG(addr);
1068
    return 0;
1069
}
1070

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

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

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

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

    
1096
    default:
1097
        OMAP_BAD_REG(addr);
1098
    }
1099
}
1100

    
1101
static const MemoryRegionOps omap_mpui_ops = {
1102
    .read = omap_mpui_read,
1103
    .write = omap_mpui_write,
1104
    .endianness = DEVICE_NATIVE_ENDIAN,
1105
};
1106

    
1107
static void omap_mpui_reset(struct omap_mpu_state_s *s)
1108
{
1109
    s->mpui_ctrl = 0x0003ff1b;
1110
}
1111

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

    
1119
    omap_mpui_reset(mpu);
1120
}
1121

    
1122
/* TIPB Bridges */
1123
struct omap_tipb_bridge_s {
1124
    qemu_irq abort;
1125
    MemoryRegion iomem;
1126

    
1127
    int width_intr;
1128
    uint16_t control;
1129
    uint16_t alloc;
1130
    uint16_t buffer;
1131
    uint16_t enh_control;
1132
};
1133

    
1134
static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
1135
                                      unsigned size)
1136
{
1137
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1138

    
1139
    if (size < 2) {
1140
        return omap_badwidth_read16(opaque, addr);
1141
    }
1142

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

    
1160
    OMAP_BAD_REG(addr);
1161
    return 0;
1162
}
1163

    
1164
static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
1165
                                   uint64_t value, unsigned size)
1166
{
1167
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
1168

    
1169
    if (size < 2) {
1170
        return omap_badwidth_write16(opaque, addr, value);
1171
    }
1172

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

    
1178
    case 0x04:        /* TIPB_BUS_ALLOC */
1179
        s->alloc = value & 0x003f;
1180
        break;
1181

    
1182
    case 0x08:        /* MPU_TIPB_CNTL */
1183
        s->buffer = value & 0x0003;
1184
        break;
1185

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

    
1191
    case 0x10:        /* ADDRESS_DBG */
1192
    case 0x14:        /* DATA_DEBUG_LOW */
1193
    case 0x18:        /* DATA_DEBUG_HIGH */
1194
    case 0x1c:        /* DEBUG_CNTR_SIG */
1195
        OMAP_RO_REG(addr);
1196
        break;
1197

    
1198
    default:
1199
        OMAP_BAD_REG(addr);
1200
    }
1201
}
1202

    
1203
static const MemoryRegionOps omap_tipb_bridge_ops = {
1204
    .read = omap_tipb_bridge_read,
1205
    .write = omap_tipb_bridge_write,
1206
    .endianness = DEVICE_NATIVE_ENDIAN,
1207
};
1208

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

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

    
1224
    s->abort = abort_irq;
1225
    omap_tipb_bridge_reset(s);
1226

    
1227
    memory_region_init_io(&s->iomem, &omap_tipb_bridge_ops, s,
1228
                          "omap-tipb-bridge", 0x100);
1229
    memory_region_add_subregion(memory, base, &s->iomem);
1230

    
1231
    return s;
1232
}
1233

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

    
1241
    if (size != 4) {
1242
        return omap_badwidth_read32(opaque, addr);
1243
    }
1244

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

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

    
1269
    OMAP_BAD_REG(addr);
1270
    return 0;
1271
}
1272

    
1273
static void omap_tcmi_write(void *opaque, hwaddr addr,
1274
                            uint64_t value, unsigned size)
1275
{
1276
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1277

    
1278
    if (size != 4) {
1279
        return omap_badwidth_write32(opaque, addr, value);
1280
    }
1281

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

    
1303
    default:
1304
        OMAP_BAD_REG(addr);
1305
    }
1306
}
1307

    
1308
static const MemoryRegionOps omap_tcmi_ops = {
1309
    .read = omap_tcmi_read,
1310
    .write = omap_tcmi_write,
1311
    .endianness = DEVICE_NATIVE_ENDIAN,
1312
};
1313

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

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

    
1342
/* Digital phase-locked loops control */
1343
struct dpll_ctl_s {
1344
    MemoryRegion iomem;
1345
    uint16_t mode;
1346
    omap_clk dpll;
1347
};
1348

    
1349
static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
1350
                               unsigned size)
1351
{
1352
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1353

    
1354
    if (size != 2) {
1355
        return omap_badwidth_read16(opaque, addr);
1356
    }
1357

    
1358
    if (addr == 0x00)        /* CTL_REG */
1359
        return s->mode;
1360

    
1361
    OMAP_BAD_REG(addr);
1362
    return 0;
1363
}
1364

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

    
1373
    if (size != 2) {
1374
        return omap_badwidth_write16(opaque, addr, value);
1375
    }
1376

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

    
1392
        /* Enter the desired mode.  */
1393
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
1394

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

    
1402
static const MemoryRegionOps omap_dpll_ops = {
1403
    .read = omap_dpll_read,
1404
    .write = omap_dpll_write,
1405
    .endianness = DEVICE_NATIVE_ENDIAN,
1406
};
1407

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

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

    
1420
    s->dpll = clk;
1421
    omap_dpll_reset(s);
1422

    
1423
    memory_region_add_subregion(memory, base, &s->iomem);
1424
    return s;
1425
}
1426

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

    
1433
    if (size != 2) {
1434
        return omap_badwidth_read16(opaque, addr);
1435
    }
1436

    
1437
    switch (addr) {
1438
    case 0x00:        /* ARM_CKCTL */
1439
        return s->clkm.arm_ckctl;
1440

    
1441
    case 0x04:        /* ARM_IDLECT1 */
1442
        return s->clkm.arm_idlect1;
1443

    
1444
    case 0x08:        /* ARM_IDLECT2 */
1445
        return s->clkm.arm_idlect2;
1446

    
1447
    case 0x0c:        /* ARM_EWUPCT */
1448
        return s->clkm.arm_ewupct;
1449

    
1450
    case 0x10:        /* ARM_RSTCT1 */
1451
        return s->clkm.arm_rstct1;
1452

    
1453
    case 0x14:        /* ARM_RSTCT2 */
1454
        return s->clkm.arm_rstct2;
1455

    
1456
    case 0x18:        /* ARM_SYSST */
1457
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1458

    
1459
    case 0x1c:        /* ARM_CKOUT1 */
1460
        return s->clkm.arm_ckout1;
1461

    
1462
    case 0x20:        /* ARM_CKOUT2 */
1463
        break;
1464
    }
1465

    
1466
    OMAP_BAD_REG(addr);
1467
    return 0;
1468
}
1469

    
1470
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1471
                uint16_t diff, uint16_t value)
1472
{
1473
    omap_clk clk;
1474

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

    
1517
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1518
                uint16_t diff, uint16_t value)
1519
{
1520
    omap_clk clk;
1521

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

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

    
1549
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1550
                uint16_t diff, uint16_t value)
1551
{
1552
    omap_clk clk;
1553

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

    
1572
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1573
                uint16_t diff, uint16_t value)
1574
{
1575
    omap_clk clk;
1576

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

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

    
1641
    if (size != 2) {
1642
        return omap_badwidth_write16(opaque, addr, value);
1643
    }
1644

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

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

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

    
1664
    case 0x0c:        /* ARM_EWUPCT */
1665
        s->clkm.arm_ewupct = value & 0x003f;
1666
        return;
1667

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

    
1686
    case 0x14:        /* ARM_RSTCT2 */
1687
        s->clkm.arm_rstct2 = value & 0x0001;
1688
        return;
1689

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

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

    
1705
    case 0x20:        /* ARM_CKOUT2 */
1706
    default:
1707
        OMAP_BAD_REG(addr);
1708
    }
1709
}
1710

    
1711
static const MemoryRegionOps omap_clkm_ops = {
1712
    .read = omap_clkm_read,
1713
    .write = omap_clkm_write,
1714
    .endianness = DEVICE_NATIVE_ENDIAN,
1715
};
1716

    
1717
static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
1718
                                 unsigned size)
1719
{
1720
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1721

    
1722
    if (size != 2) {
1723
        return omap_badwidth_read16(opaque, addr);
1724
    }
1725

    
1726
    switch (addr) {
1727
    case 0x04:        /* DSP_IDLECT1 */
1728
        return s->clkm.dsp_idlect1;
1729

    
1730
    case 0x08:        /* DSP_IDLECT2 */
1731
        return s->clkm.dsp_idlect2;
1732

    
1733
    case 0x14:        /* DSP_RSTCT2 */
1734
        return s->clkm.dsp_rstct2;
1735

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

    
1741
    OMAP_BAD_REG(addr);
1742
    return 0;
1743
}
1744

    
1745
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
1746
                uint16_t diff, uint16_t value)
1747
{
1748
    omap_clk clk;
1749

    
1750
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
1751
}
1752

    
1753
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
1754
                uint16_t diff, uint16_t value)
1755
{
1756
    omap_clk clk;
1757

    
1758
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
1759
}
1760

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

    
1767
    if (size != 2) {
1768
        return omap_badwidth_write16(opaque, addr, value);
1769
    }
1770

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

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

    
1784
    case 0x14:        /* DSP_RSTCT2 */
1785
        s->clkm.dsp_rstct2 = value & 0x0001;
1786
        break;
1787

    
1788
    case 0x18:        /* DSP_SYSST */
1789
        s->clkm.cold_start &= value & 0x3f;
1790
        break;
1791

    
1792
    default:
1793
        OMAP_BAD_REG(addr);
1794
    }
1795
}
1796

    
1797
static const MemoryRegionOps omap_clkdsp_ops = {
1798
    .read = omap_clkdsp_read,
1799
    .write = omap_clkdsp_write,
1800
    .endianness = DEVICE_NATIVE_ENDIAN,
1801
};
1802

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

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

    
1834
    s->clkm.arm_idlect1 = 0x03ff;
1835
    s->clkm.arm_idlect2 = 0x0100;
1836
    s->clkm.dsp_idlect1 = 0x0002;
1837
    omap_clkm_reset(s);
1838
    s->clkm.cold_start = 0x3a;
1839

    
1840
    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
1841
    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
1842
}
1843

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

    
1853
    uint16_t inputs;
1854
    uint16_t outputs;
1855
    uint16_t dir;
1856
    uint16_t edge;
1857
    uint16_t mask;
1858
    uint16_t ints;
1859

    
1860
    uint16_t debounce;
1861
    uint16_t latch;
1862
    uint8_t event;
1863

    
1864
    uint8_t buttons[5];
1865
    uint8_t row_latch;
1866
    uint8_t cols;
1867
    int kbd_mask;
1868
    int clk;
1869
};
1870

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

    
1876
    if (level)
1877
        s->inputs |= 1 << line;
1878
    else
1879
        s->inputs &= ~(1 << line);
1880

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

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

    
1898
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1899
        if (*row & cols)
1900
            rows |= i;
1901

    
1902
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1903
    s->row_latch = ~rows;
1904
}
1905

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

    
1913
    if (size != 2) {
1914
        return omap_badwidth_read16(opaque, addr);
1915
    }
1916

    
1917
    switch (offset) {
1918
    case 0x00:        /* INPUT_LATCH */
1919
        return s->inputs;
1920

    
1921
    case 0x04:        /* OUTPUT_REG */
1922
        return s->outputs;
1923

    
1924
    case 0x08:        /* IO_CNTL */
1925
        return s->dir;
1926

    
1927
    case 0x10:        /* KBR_LATCH */
1928
        return s->row_latch;
1929

    
1930
    case 0x14:        /* KBC_REG */
1931
        return s->cols;
1932

    
1933
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1934
        return s->event;
1935

    
1936
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1937
        return s->edge;
1938

    
1939
    case 0x20:        /* KBD_INT */
1940
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
1941

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

    
1949
    case 0x28:        /* KBD_MASKIT */
1950
        return s->kbd_mask;
1951

    
1952
    case 0x2c:        /* GPIO_MASKIT */
1953
        return s->mask;
1954

    
1955
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1956
        return s->debounce;
1957

    
1958
    case 0x34:        /* GPIO_LATCH_REG */
1959
        return s->latch;
1960
    }
1961

    
1962
    OMAP_BAD_REG(addr);
1963
    return 0;
1964
}
1965

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

    
1974
    if (size != 2) {
1975
        return omap_badwidth_write16(opaque, addr, value);
1976
    }
1977

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

    
1990
    case 0x08:        /* IO_CNTL */
1991
        diff = s->outputs & (s->dir ^ value);
1992
        s->dir = value;
1993

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

    
2003
    case 0x14:        /* KBC_REG */
2004
        s->cols = value;
2005
        omap_mpuio_kbd_update(s);
2006
        break;
2007

    
2008
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2009
        s->event = value & 0x1f;
2010
        break;
2011

    
2012
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2013
        s->edge = value;
2014
        break;
2015

    
2016
    case 0x28:        /* KBD_MASKIT */
2017
        s->kbd_mask = value & 1;
2018
        omap_mpuio_kbd_update(s);
2019
        break;
2020

    
2021
    case 0x2c:        /* GPIO_MASKIT */
2022
        s->mask = value;
2023
        break;
2024

    
2025
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2026
        s->debounce = value & 0x1ff;
2027
        break;
2028

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

    
2037
    default:
2038
        OMAP_BAD_REG(addr);
2039
        return;
2040
    }
2041
}
2042

    
2043
static const MemoryRegionOps omap_mpuio_ops  = {
2044
    .read = omap_mpuio_read,
2045
    .write = omap_mpuio_write,
2046
    .endianness = DEVICE_NATIVE_ENDIAN,
2047
};
2048

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

    
2065
static void omap_mpuio_onoff(void *opaque, int line, int on)
2066
{
2067
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2068

    
2069
    s->clk = on;
2070
    if (on)
2071
        omap_mpuio_kbd_update(s);
2072
}
2073

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

    
2082
    s->irq = gpio_int;
2083
    s->kbd_irq = kbd_int;
2084
    s->wakeup = wakeup;
2085
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2086
    omap_mpuio_reset(s);
2087

    
2088
    memory_region_init_io(&s->iomem, &omap_mpuio_ops, s,
2089
                          "omap-mpuio", 0x800);
2090
    memory_region_add_subregion(memory, base, &s->iomem);
2091

    
2092
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2093

    
2094
    return s;
2095
}
2096

    
2097
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2098
{
2099
    return s->in;
2100
}
2101

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

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

    
2114
    if (down)
2115
        s->buttons[row] |= 1 << col;
2116
    else
2117
        s->buttons[row] &= ~(1 << col);
2118

    
2119
    omap_mpuio_kbd_update(s);
2120
}
2121

    
2122
/* MicroWire Interface */
2123
struct omap_uwire_s {
2124
    MemoryRegion iomem;
2125
    qemu_irq txirq;
2126
    qemu_irq rxirq;
2127
    qemu_irq txdrq;
2128

    
2129
    uint16_t txbuf;
2130
    uint16_t rxbuf;
2131
    uint16_t control;
2132
    uint16_t setup[5];
2133

    
2134
    uWireSlave *chip[4];
2135
};
2136

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

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

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

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

    
2168
    if (size != 2) {
2169
        return omap_badwidth_read16(opaque, addr);
2170
    }
2171

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

    
2177
    case 0x04:        /* CSR */
2178
        return s->control;
2179

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

    
2192
    OMAP_BAD_REG(addr);
2193
    return 0;
2194
}
2195

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

    
2202
    if (size != 2) {
2203
        return omap_badwidth_write16(opaque, addr, value);
2204
    }
2205

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

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

    
2223
    case 0x08:        /* SR1 */
2224
        s->setup[0] = value & 0x003f;
2225
        break;
2226

    
2227
    case 0x0c:        /* SR2 */
2228
        s->setup[1] = value & 0x0fc0;
2229
        break;
2230

    
2231
    case 0x10:        /* SR3 */
2232
        s->setup[2] = value & 0x0003;
2233
        break;
2234

    
2235
    case 0x14:        /* SR4 */
2236
        s->setup[3] = value & 0x0001;
2237
        break;
2238

    
2239
    case 0x18:        /* SR5 */
2240
        s->setup[4] = value & 0x000f;
2241
        break;
2242

    
2243
    default:
2244
        OMAP_BAD_REG(addr);
2245
        return;
2246
    }
2247
}
2248

    
2249
static const MemoryRegionOps omap_uwire_ops = {
2250
    .read = omap_uwire_read,
2251
    .write = omap_uwire_write,
2252
    .endianness = DEVICE_NATIVE_ENDIAN,
2253
};
2254

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

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

    
2274
    s->txirq = txirq;
2275
    s->rxirq = rxirq;
2276
    s->txdrq = dma;
2277
    omap_uwire_reset(s);
2278

    
2279
    memory_region_init_io(&s->iomem, &omap_uwire_ops, s, "omap-uwire", 0x800);
2280
    memory_region_add_subregion(system_memory, base, &s->iomem);
2281

    
2282
    return s;
2283
}
2284

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

    
2293
    s->chip[chipselect] = slave;
2294
}
2295

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

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

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

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

    
2321
    if (size != 1) {
2322
        return omap_badwidth_read8(opaque, addr);
2323
    }
2324

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

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

    
2341
    if (size != 1) {
2342
        return omap_badwidth_write8(opaque, addr, value);
2343
    }
2344

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

    
2360
static const MemoryRegionOps omap_pwl_ops = {
2361
    .read = omap_pwl_read,
2362
    .write = omap_pwl_write,
2363
    .endianness = DEVICE_NATIVE_ENDIAN,
2364
};
2365

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

    
2375
static void omap_pwl_clk_update(void *opaque, int line, int on)
2376
{
2377
    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
2378

    
2379
    s->clk = on;
2380
    omap_pwl_update(s);
2381
}
2382

    
2383
static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
2384
                                        hwaddr base,
2385
                                        omap_clk clk)
2386
{
2387
    struct omap_pwl_s *s = g_malloc0(sizeof(*s));
2388

    
2389
    omap_pwl_reset(s);
2390

    
2391
    memory_region_init_io(&s->iomem, &omap_pwl_ops, s,
2392
                          "omap-pwl", 0x800);
2393
    memory_region_add_subregion(system_memory, base, &s->iomem);
2394

    
2395
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
2396
    return s;
2397
}
2398

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

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

    
2414
    if (size != 1) {
2415
        return omap_badwidth_read8(opaque, addr);
2416
    }
2417

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

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

    
2436
    if (size != 1) {
2437
        return omap_badwidth_write8(opaque, addr, value);
2438
    }
2439

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

    
2477
static const MemoryRegionOps omap_pwt_ops = {
2478
    .read =omap_pwt_read,
2479
    .write = omap_pwt_write,
2480
    .endianness = DEVICE_NATIVE_ENDIAN,
2481
};
2482

    
2483
static void omap_pwt_reset(struct omap_pwt_s *s)
2484
{
2485
    s->frc = 0;
2486
    s->vrc = 0;
2487
    s->gcr = 0;
2488
}
2489

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

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

    
2504
/* Real-time Clock module */
2505
struct omap_rtc_s {
2506
    MemoryRegion iomem;
2507
    qemu_irq irq;
2508
    qemu_irq alarm;
2509
    QEMUTimer *clk;
2510

    
2511
    uint8_t interrupts;
2512
    uint8_t status;
2513
    int16_t comp_reg;
2514
    int running;
2515
    int pm_am;
2516
    int auto_comp;
2517
    int round;
2518
    struct tm alarm_tm;
2519
    time_t alarm_ti;
2520

    
2521
    struct tm current_tm;
2522
    time_t ti;
2523
    uint64_t tick;
2524
};
2525

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

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

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

    
2546
    if (size != 1) {
2547
        return omap_badwidth_read8(opaque, addr);
2548
    }
2549

    
2550
    switch (offset) {
2551
    case 0x00:        /* SECONDS_REG */
2552
        return to_bcd(s->current_tm.tm_sec);
2553

    
2554
    case 0x04:        /* MINUTES_REG */
2555
        return to_bcd(s->current_tm.tm_min);
2556

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

    
2564
    case 0x0c:        /* DAYS_REG */
2565
        return to_bcd(s->current_tm.tm_mday);
2566

    
2567
    case 0x10:        /* MONTHS_REG */
2568
        return to_bcd(s->current_tm.tm_mon + 1);
2569

    
2570
    case 0x14:        /* YEARS_REG */
2571
        return to_bcd(s->current_tm.tm_year % 100);
2572

    
2573
    case 0x18:        /* WEEK_REG */
2574
        return s->current_tm.tm_wday;
2575

    
2576
    case 0x20:        /* ALARM_SECONDS_REG */
2577
        return to_bcd(s->alarm_tm.tm_sec);
2578

    
2579
    case 0x24:        /* ALARM_MINUTES_REG */
2580
        return to_bcd(s->alarm_tm.tm_min);
2581

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

    
2589
    case 0x2c:        /* ALARM_DAYS_REG */
2590
        return to_bcd(s->alarm_tm.tm_mday);
2591

    
2592
    case 0x30:        /* ALARM_MONTHS_REG */
2593
        return to_bcd(s->alarm_tm.tm_mon + 1);
2594

    
2595
    case 0x34:        /* ALARM_YEARS_REG */
2596
        return to_bcd(s->alarm_tm.tm_year % 100);
2597

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

    
2602
    case 0x44:        /* RTC_STATUS_REG */
2603
        i = s->status;
2604
        s->status &= ~0x3d;
2605
        return i;
2606

    
2607
    case 0x48:        /* RTC_INTERRUPTS_REG */
2608
        return s->interrupts;
2609

    
2610
    case 0x4c:        /* RTC_COMP_LSB_REG */
2611
        return ((uint16_t) s->comp_reg) & 0xff;
2612

    
2613
    case 0x50:        /* RTC_COMP_MSB_REG */
2614
        return ((uint16_t) s->comp_reg) >> 8;
2615
    }
2616

    
2617
    OMAP_BAD_REG(addr);
2618
    return 0;
2619
}
2620

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

    
2629
    if (size != 1) {
2630
        return omap_badwidth_write8(opaque, addr, value);
2631
    }
2632

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

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

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

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

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

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

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

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

    
2708
    case 0x18:        /* WEEK_REG */
2709
        return;        /* Ignored */
2710

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

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

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

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

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

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

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

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

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

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

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

    
2807
    default:
2808
        OMAP_BAD_REG(addr);
2809
        return;
2810
    }
2811
}
2812

    
2813
static const MemoryRegionOps omap_rtc_ops = {
2814
    .read = omap_rtc_read,
2815
    .write = omap_rtc_write,
2816
    .endianness = DEVICE_NATIVE_ENDIAN,
2817
};
2818

    
2819
static void omap_rtc_tick(void *opaque)
2820
{
2821
    struct omap_rtc_s *s = opaque;
2822

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

    
2830
        s->round = 0;
2831
    }
2832

    
2833
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
2834

    
2835
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2836
        s->status |= 0x40;
2837
        omap_rtc_interrupts_update(s);
2838
    }
2839

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

    
2867
    /* Move on */
2868
    if (s->running)
2869
        s->ti ++;
2870
    s->tick += 1000;
2871

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

    
2879
    qemu_mod_timer(s->clk, s->tick);
2880
}
2881

    
2882
static void omap_rtc_reset(struct omap_rtc_s *s)
2883
{
2884
    struct tm tm;
2885

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

    
2899
    omap_rtc_alarm_update(s);
2900
    omap_rtc_tick(s);
2901
}
2902

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

    
2911
    s->irq = timerirq;
2912
    s->alarm = alarmirq;
2913
    s->clk = qemu_new_timer_ms(rtc_clock, omap_rtc_tick, s);
2914

    
2915
    omap_rtc_reset(s);
2916

    
2917
    memory_region_init_io(&s->iomem, &omap_rtc_ops, s,
2918
                          "omap-rtc", 0x800);
2919
    memory_region_add_subregion(system_memory, base, &s->iomem);
2920

    
2921
    return s;
2922
}
2923

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

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

    
2945
    I2SCodec *codec;
2946
    QEMUTimer *source_timer;
2947
    QEMUTimer *sink_timer;
2948
};
2949

    
2950
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2951
{
2952
    int irq;
2953

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

    
2966
    if (irq)
2967
        qemu_irq_pulse(s->rxirq);
2968

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

    
2981
    if (irq)
2982
        qemu_irq_pulse(s->txirq);
2983
}
2984

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

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

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

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

    
3006
    omap_mcbsp_rx_newdata(s);
3007
    qemu_mod_timer(s->source_timer, qemu_get_clock_ns(vm_clock) +
3008
                   get_ticks_per_sec());
3009
}
3010

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

    
3021
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
3022
{
3023
    qemu_del_timer(s->source_timer);
3024
}
3025

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

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

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

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

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

    
3052
    omap_mcbsp_tx_newdata(s);
3053
    qemu_mod_timer(s->sink_timer, qemu_get_clock_ns(vm_clock) +
3054
                   get_ticks_per_sec());
3055
}
3056

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

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

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

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

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

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

    
3118
    if (s->codec)
3119
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3120

    
3121
    if (!prev_tx_rate && tx_rate)
3122
        omap_mcbsp_tx_start(s);
3123
    else if (s->tx_rate && !tx_rate)
3124
        omap_mcbsp_tx_stop(s);
3125

    
3126
    if (!prev_rx_rate && rx_rate)
3127
        omap_mcbsp_rx_start(s);
3128
    else if (prev_tx_rate && !tx_rate)
3129
        omap_mcbsp_rx_stop(s);
3130
}
3131

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

    
3139
    if (size != 2) {
3140
        return omap_badwidth_read16(opaque, addr);
3141
    }
3142

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

    
3166
    case 0x04:        /* DXR2 */
3167
    case 0x06:        /* DXR1 */
3168
        return 0x0000;
3169

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

    
3226
    OMAP_BAD_REG(addr);
3227
    return 0;
3228
}
3229

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

    
3236
    switch (offset) {
3237
    case 0x00:        /* DRR2 */
3238
    case 0x02:        /* DRR1 */
3239
        OMAP_RO_REG(addr);
3240
        return;
3241

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

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

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

    
3365
    OMAP_BAD_REG(addr);
3366
}
3367

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

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

    
3396
    omap_badwidth_write16(opaque, addr, value);
3397
}
3398

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

    
3409
static const MemoryRegionOps omap_mcbsp_ops = {
3410
    .read = omap_mcbsp_read,
3411
    .write = omap_mcbsp_write,
3412
    .endianness = DEVICE_NATIVE_ENDIAN,
3413
};
3414

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

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

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

    
3450
    memory_region_init_io(&s->iomem, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
3451
    memory_region_add_subregion(system_memory, base, &s->iomem);
3452

    
3453
    return s;
3454
}
3455

    
3456
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3457
{
3458
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3459

    
3460
    if (s->rx_rate) {
3461
        s->rx_req = s->codec->in.len;
3462
        omap_mcbsp_rx_newdata(s);
3463
    }
3464
}
3465

    
3466
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3467
{
3468
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3469

    
3470
    if (s->tx_rate) {
3471
        s->tx_req = s->codec->out.size;
3472
        omap_mcbsp_tx_newdata(s);
3473
    }
3474
}
3475

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

    
3483
/* LED Pulse Generators */
3484
struct omap_lpg_s {
3485
    MemoryRegion iomem;
3486
    QEMUTimer *tm;
3487

    
3488
    uint8_t control;
3489
    uint8_t power;
3490
    int64_t on;
3491
    int64_t period;
3492
    int clk;
3493
    int cycle;
3494
};
3495

    
3496
static void omap_lpg_tick(void *opaque)
3497
{
3498
    struct omap_lpg_s *s = opaque;
3499

    
3500
    if (s->cycle)
3501
        qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->period - s->on);
3502
    else
3503
        qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->on);
3504

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

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

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

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

    
3538
    s->on = on;
3539
    s->period = period;
3540
}
3541

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

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

    
3556
    if (size != 1) {
3557
        return omap_badwidth_read8(opaque, addr);
3558
    }
3559

    
3560
    switch (offset) {
3561
    case 0x00:        /* LCR */
3562
        return s->control;
3563

    
3564
    case 0x04:        /* PMR */
3565
        return s->power;
3566
    }
3567

    
3568
    OMAP_BAD_REG(addr);
3569
    return 0;
3570
}
3571

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

    
3578
    if (size != 1) {
3579
        return omap_badwidth_write8(opaque, addr, value);
3580
    }
3581

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

    
3590
    case 0x04:        /* PMR */
3591
        s->power = value & 0x01;
3592
        omap_lpg_update(s);
3593
        return;
3594

    
3595
    default:
3596
        OMAP_BAD_REG(addr);
3597
        return;
3598
    }
3599
}
3600

    
3601
static const MemoryRegionOps omap_lpg_ops = {
3602
    .read = omap_lpg_read,
3603
    .write = omap_lpg_write,
3604
    .endianness = DEVICE_NATIVE_ENDIAN,
3605
};
3606

    
3607
static void omap_lpg_clk_update(void *opaque, int line, int on)
3608
{
3609
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3610

    
3611
    s->clk = on;
3612
    omap_lpg_update(s);
3613
}
3614

    
3615
static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
3616
                                        hwaddr base, omap_clk clk)
3617
{
3618
    struct omap_lpg_s *s = (struct omap_lpg_s *)
3619
            g_malloc0(sizeof(struct omap_lpg_s));
3620

    
3621
    s->tm = qemu_new_timer_ms(vm_clock, omap_lpg_tick, s);
3622

    
3623
    omap_lpg_reset(s);
3624

    
3625
    memory_region_init_io(&s->iomem, &omap_lpg_ops, s, "omap-lpg", 0x800);
3626
    memory_region_add_subregion(system_memory, base, &s->iomem);
3627

    
3628
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
3629

    
3630
    return s;
3631
}
3632

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

    
3641
    if (addr == OMAP_MPUI_BASE)        /* CMR */
3642
        return 0xfe4d;
3643

    
3644
    OMAP_BAD_REG(addr);
3645
    return 0;
3646
}
3647

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

    
3655
static const MemoryRegionOps omap_mpui_io_ops = {
3656
    .read = omap_mpui_io_read,
3657
    .write = omap_mpui_io_write,
3658
    .endianness = DEVICE_NATIVE_ENDIAN,
3659
};
3660

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

    
3670
/* General chip reset */
3671
static void omap1_mpu_reset(void *opaque)
3672
{
3673
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3674

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

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

    
3735
    { 0 }
3736
};
3737

    
3738
static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
3739
                                   const struct omap_map_s *map)
3740
{
3741
    MemoryRegion *io;
3742

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

    
3751
void omap_mpu_wakeup(void *opaque, int irq, int req)
3752
{
3753
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3754

    
3755
    if (mpu->cpu->env.halted) {
3756
        cpu_interrupt(&mpu->cpu->env, CPU_INTERRUPT_EXITTB);
3757
    }
3758
}
3759

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

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

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

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

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

    
3805
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3806
                hwaddr addr)
3807
{
3808
    return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
3809
}
3810

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

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

    
3829
    if (!core)
3830
        core = "ti925t";
3831

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

    
3842
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3843

    
3844
    /* Clocks */
3845
    omap_clk_init(s);
3846

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

    
3855
    omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
3856

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

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

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

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

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

    
3907
    s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
3908
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
3909
                    omap_findclk(s, "armwdt_ck"));
3910

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

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

    
3920
    omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
3921
    omap_pin_cfg_init(system_memory, 0xfffe1000, s);
3922
    omap_id_init(system_memory, s);
3923

    
3924
    omap_mpui_init(system_memory, 0xfffec900, s);
3925

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

    
3933
    omap_tcmi_init(system_memory, 0xfffecc00, s);
3934

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

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

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

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

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

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

    
3992
    s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
3993
                           omap_findclk(s, "armxor_ck"));
3994
    s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
3995
                           omap_findclk(s, "armxor_ck"));
3996

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

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

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

    
4027
    s->led[0] = omap_lpg_init(system_memory,
4028
                              0xfffbd000, omap_findclk(s, "clk32-kHz"));
4029
    s->led[1] = omap_lpg_init(system_memory,
4030
                              0xfffbd800, omap_findclk(s, "clk32-kHz"));
4031

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

    
4047
    omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
4048
    omap_setup_mpui_io(system_memory, s);
4049

    
4050
    qemu_register_reset(omap1_mpu_reset, s);
4051

    
4052
    return s;
4053
}