Statistics
| Branch: | Revision:

root / hw / omap1.c @ 1f51470d

History | View | Annotate | Download (116.2 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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
                target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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
                target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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
                target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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
                target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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
                target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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, target_phys_addr_t 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
                           target_phys_addr_t 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, target_phys_addr_t 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->env, CPU_INTERRUPT_HALT);
1524
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
1525
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
1526

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2093
    return s;
2094
}
2095

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

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

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

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

    
2118
    omap_mpuio_kbd_update(s);
2119
}
2120

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2281
    return s;
2282
}
2283

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2388
    omap_pwl_reset(s);
2389

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2829
        s->round = 0;
2830
    }
2831

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

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

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

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

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

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

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

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

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

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

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

    
2914
    omap_rtc_reset(s);
2915

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

    
2920
    return s;
2921
}
2922

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3364
    OMAP_BAD_REG(addr);
3365
}
3366

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

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

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

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

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

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

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

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

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

    
3452
    return s;
3453
}
3454

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3620
    s->tm = qemu_new_timer_ms(rt_clock, omap_lpg_tick, s);
3621

    
3622
    omap_lpg_reset(s);
3623

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

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

    
3629
    return s;
3630
}
3631

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

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

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

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

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

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

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

    
3674
    omap_dma_reset(mpu->dma);
3675
    omap_mpu_timer_reset(mpu->timer[0]);
3676
    omap_mpu_timer_reset(mpu->timer[1]);
3677
    omap_mpu_timer_reset(mpu->timer[2]);
3678
    omap_wd_timer_reset(mpu->wdt);
3679
    omap_os_timer_reset(mpu->os_timer);
3680
    omap_lcdc_reset(mpu->lcd);
3681
    omap_ulpd_pm_reset(mpu);
3682
    omap_pin_cfg_reset(mpu);
3683
    omap_mpui_reset(mpu);
3684
    omap_tipb_bridge_reset(mpu->private_tipb);
3685
    omap_tipb_bridge_reset(mpu->public_tipb);
3686
    omap_dpll_reset(mpu->dpll[0]);
3687
    omap_dpll_reset(mpu->dpll[1]);
3688
    omap_dpll_reset(mpu->dpll[2]);
3689
    omap_uart_reset(mpu->uart[0]);
3690
    omap_uart_reset(mpu->uart[1]);
3691
    omap_uart_reset(mpu->uart[2]);
3692
    omap_mmc_reset(mpu->mmc);
3693
    omap_mpuio_reset(mpu->mpuio);
3694
    omap_uwire_reset(mpu->microwire);
3695
    omap_pwl_reset(mpu->pwl);
3696
    omap_pwt_reset(mpu->pwt);
3697
    omap_i2c_reset(mpu->i2c[0]);
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(mpu->env);
3706
}
3707

    
3708
static const struct omap_map_s {
3709
    target_phys_addr_t phys_dsp;
3710
    target_phys_addr_t 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->env->halted)
3756
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
3757
}
3758

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3996
    s->i2c[0] = omap_i2c_init(system_memory, 0xfffb3800,
3997
                              qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C),
3998
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
3999

    
4000
    s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
4001
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
4002
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
4003
                    omap_findclk(s, "clk32-kHz"));
4004

    
4005
    s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
4006
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
4007
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
4008
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
4009
    s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
4010
                                qdev_get_gpio_in(s->ih[0],
4011
                                                 OMAP_INT_310_McBSP2_TX),
4012
                                qdev_get_gpio_in(s->ih[0],
4013
                                                 OMAP_INT_310_McBSP2_RX),
4014
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
4015
    s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
4016
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
4017
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
4018
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4019

    
4020
    s->led[0] = omap_lpg_init(system_memory,
4021
                              0xfffbd000, omap_findclk(s, "clk32-kHz"));
4022
    s->led[1] = omap_lpg_init(system_memory,
4023
                              0xfffbd800, omap_findclk(s, "clk32-kHz"));
4024

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

    
4040
    omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
4041
    omap_setup_mpui_io(system_memory, s);
4042

    
4043
    qemu_register_reset(omap1_mpu_reset, s);
4044

    
4045
    return s;
4046
}