Statistics
| Branch: | Revision:

root / hw / omap1.c @ 3204db98

History | View | Annotate | Download (115.7 kB)

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

    
32
/* Should signal the TCMI/GPMC */
33
uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
34
{
35
    uint8_t ret;
36

    
37
    OMAP_8B_REG(addr);
38
    cpu_physical_memory_read(addr, (void *) &ret, 1);
39
    return ret;
40
}
41

    
42
void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
43
                uint32_t value)
44
{
45
    uint8_t val8 = value;
46

    
47
    OMAP_8B_REG(addr);
48
    cpu_physical_memory_write(addr, (void *) &val8, 1);
49
}
50

    
51
uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
52
{
53
    uint16_t ret;
54

    
55
    OMAP_16B_REG(addr);
56
    cpu_physical_memory_read(addr, (void *) &ret, 2);
57
    return ret;
58
}
59

    
60
void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
61
                uint32_t value)
62
{
63
    uint16_t val16 = value;
64

    
65
    OMAP_16B_REG(addr);
66
    cpu_physical_memory_write(addr, (void *) &val16, 2);
67
}
68

    
69
uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
70
{
71
    uint32_t ret;
72

    
73
    OMAP_32B_REG(addr);
74
    cpu_physical_memory_read(addr, (void *) &ret, 4);
75
    return ret;
76
}
77

    
78
void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
79
                uint32_t value)
80
{
81
    OMAP_32B_REG(addr);
82
    cpu_physical_memory_write(addr, (void *) &value, 4);
83
}
84

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

    
97
    int enable;
98
    int ptv;
99
    int ar;
100
    int st;
101
    uint32_t reset_val;
102
};
103

    
104
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
105
{
106
    uint64_t distance = qemu_get_clock_ns(vm_clock) - timer->time;
107

    
108
    if (timer->st && timer->enable && timer->rate)
109
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
110
                                     timer->rate, get_ticks_per_sec());
111
    else
112
        return timer->val;
113
}
114

    
115
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
116
{
117
    timer->val = omap_timer_read(timer);
118
    timer->time = qemu_get_clock_ns(vm_clock);
119
}
120

    
121
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
122
{
123
    int64_t expires;
124

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

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

    
144
static void omap_timer_fire(void *opaque)
145
{
146
    struct omap_mpu_timer_s *timer = opaque;
147

    
148
    if (!timer->ar) {
149
        timer->val = 0;
150
        timer->st = 0;
151
    }
152

    
153
    if (timer->it_ena)
154
        /* Edge-triggered irq */
155
        qemu_irq_pulse(timer->irq);
156
}
157

    
158
static void omap_timer_tick(void *opaque)
159
{
160
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
161

    
162
    omap_timer_sync(timer);
163
    omap_timer_fire(timer);
164
    omap_timer_update(timer);
165
}
166

    
167
static void omap_timer_clk_update(void *opaque, int line, int on)
168
{
169
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
170

    
171
    omap_timer_sync(timer);
172
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
173
    omap_timer_update(timer);
174
}
175

    
176
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
177
{
178
    omap_clk_adduser(timer->clk,
179
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
180
    timer->rate = omap_clk_getrate(timer->clk);
181
}
182

    
183
static uint64_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr,
184
                                    unsigned size)
185
{
186
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
187

    
188
    if (size != 4) {
189
        return omap_badwidth_read32(opaque, addr);
190
    }
191

    
192
    switch (addr) {
193
    case 0x00:        /* CNTL_TIMER */
194
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
195

    
196
    case 0x04:        /* LOAD_TIM */
197
        break;
198

    
199
    case 0x08:        /* READ_TIM */
200
        return omap_timer_read(s);
201
    }
202

    
203
    OMAP_BAD_REG(addr);
204
    return 0;
205
}
206

    
207
static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
208
                                 uint64_t value, unsigned size)
209
{
210
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
211

    
212
    if (size != 4) {
213
        return omap_badwidth_write32(opaque, addr, value);
214
    }
215

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

    
226
    case 0x04:        /* LOAD_TIM */
227
        s->reset_val = value;
228
        return;
229

    
230
    case 0x08:        /* READ_TIM */
231
        OMAP_RO_REG(addr);
232
        break;
233

    
234
    default:
235
        OMAP_BAD_REG(addr);
236
    }
237
}
238

    
239
static const MemoryRegionOps omap_mpu_timer_ops = {
240
    .read = omap_mpu_timer_read,
241
    .write = omap_mpu_timer_write,
242
    .endianness = DEVICE_LITTLE_ENDIAN,
243
};
244

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

    
257
static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
258
                target_phys_addr_t base,
259
                qemu_irq irq, omap_clk clk)
260
{
261
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
262
            g_malloc0(sizeof(struct omap_mpu_timer_s));
263

    
264
    s->irq = irq;
265
    s->clk = clk;
266
    s->timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, s);
267
    s->tick = qemu_bh_new(omap_timer_fire, s);
268
    omap_mpu_timer_reset(s);
269
    omap_timer_clk_setup(s);
270

    
271
    memory_region_init_io(&s->iomem, &omap_mpu_timer_ops, s,
272
                          "omap-mpu-timer", 0x100);
273

    
274
    memory_region_add_subregion(system_memory, base, &s->iomem);
275

    
276
    return s;
277
}
278

    
279
/* Watchdog timer */
280
struct omap_watchdog_timer_s {
281
    struct omap_mpu_timer_s timer;
282
    MemoryRegion iomem;
283
    uint8_t last_wr;
284
    int mode;
285
    int free;
286
    int reset;
287
};
288

    
289
static uint64_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr,
290
                                   unsigned size)
291
{
292
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
293

    
294
    if (size != 2) {
295
        return omap_badwidth_read16(opaque, addr);
296
    }
297

    
298
    switch (addr) {
299
    case 0x00:        /* CNTL_TIMER */
300
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
301
                (s->timer.st << 7) | (s->free << 1);
302

    
303
    case 0x04:        /* READ_TIMER */
304
        return omap_timer_read(&s->timer);
305

    
306
    case 0x08:        /* TIMER_MODE */
307
        return s->mode << 15;
308
    }
309

    
310
    OMAP_BAD_REG(addr);
311
    return 0;
312
}
313

    
314
static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
315
                                uint64_t value, unsigned size)
316
{
317
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
318

    
319
    if (size != 2) {
320
        return omap_badwidth_write16(opaque, addr, value);
321
    }
322

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

    
333
    case 0x04:        /* LOAD_TIMER */
334
        s->timer.reset_val = value & 0xffff;
335
        break;
336

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

    
357
    default:
358
        OMAP_BAD_REG(addr);
359
    }
360
}
361

    
362
static const MemoryRegionOps omap_wd_timer_ops = {
363
    .read = omap_wd_timer_read,
364
    .write = omap_wd_timer_write,
365
    .endianness = DEVICE_NATIVE_ENDIAN,
366
};
367

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

    
386
static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
387
                target_phys_addr_t base,
388
                qemu_irq irq, omap_clk clk)
389
{
390
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
391
            g_malloc0(sizeof(struct omap_watchdog_timer_s));
392

    
393
    s->timer.irq = irq;
394
    s->timer.clk = clk;
395
    s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
396
    omap_wd_timer_reset(s);
397
    omap_timer_clk_setup(&s->timer);
398

    
399
    memory_region_init_io(&s->iomem, &omap_wd_timer_ops, s,
400
                          "omap-wd-timer", 0x100);
401
    memory_region_add_subregion(memory, base, &s->iomem);
402

    
403
    return s;
404
}
405

    
406
/* 32-kHz timer */
407
struct omap_32khz_timer_s {
408
    struct omap_mpu_timer_s timer;
409
    MemoryRegion iomem;
410
};
411

    
412
static uint64_t omap_os_timer_read(void *opaque, target_phys_addr_t addr,
413
                                   unsigned size)
414
{
415
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
416
    int offset = addr & OMAP_MPUI_REG_MASK;
417

    
418
    if (size != 4) {
419
        return omap_badwidth_read32(opaque, addr);
420
    }
421

    
422
    switch (offset) {
423
    case 0x00:        /* TVR */
424
        return s->timer.reset_val;
425

    
426
    case 0x04:        /* TCR */
427
        return omap_timer_read(&s->timer);
428

    
429
    case 0x08:        /* CR */
430
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
431

    
432
    default:
433
        break;
434
    }
435
    OMAP_BAD_REG(addr);
436
    return 0;
437
}
438

    
439
static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
440
                                uint64_t value, unsigned size)
441
{
442
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
443
    int offset = addr & OMAP_MPUI_REG_MASK;
444

    
445
    if (size != 4) {
446
        return omap_badwidth_write32(opaque, addr, value);
447
    }
448

    
449
    switch (offset) {
450
    case 0x00:        /* TVR */
451
        s->timer.reset_val = value & 0x00ffffff;
452
        break;
453

    
454
    case 0x04:        /* TCR */
455
        OMAP_RO_REG(addr);
456
        break;
457

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

    
469
    default:
470
        OMAP_BAD_REG(addr);
471
    }
472
}
473

    
474
static const MemoryRegionOps omap_os_timer_ops = {
475
    .read = omap_os_timer_read,
476
    .write = omap_os_timer_write,
477
    .endianness = DEVICE_NATIVE_ENDIAN,
478
};
479

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

    
492
static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
493
                target_phys_addr_t base,
494
                qemu_irq irq, omap_clk clk)
495
{
496
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
497
            g_malloc0(sizeof(struct omap_32khz_timer_s));
498

    
499
    s->timer.irq = irq;
500
    s->timer.clk = clk;
501
    s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
502
    omap_os_timer_reset(s);
503
    omap_timer_clk_setup(&s->timer);
504

    
505
    memory_region_init_io(&s->iomem, &omap_os_timer_ops, s,
506
                          "omap-os-timer", 0x800);
507
    memory_region_add_subregion(memory, base, &s->iomem);
508

    
509
    return s;
510
}
511

    
512
/* Ultra Low-Power Device Module */
513
static uint64_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr,
514
                                  unsigned size)
515
{
516
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
517
    uint16_t ret;
518

    
519
    if (size != 2) {
520
        return omap_badwidth_read16(opaque, addr);
521
    }
522

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

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

    
554
    OMAP_BAD_REG(addr);
555
    return 0;
556
}
557

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

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

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

    
589
    if (size != 2) {
590
        return omap_badwidth_write16(opaque, addr, value);
591
    }
592

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

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

    
608
            if (value & 1)
609
                s->ulpd_gauge_start = now;
610
            else {
611
                now -= s->ulpd_gauge_start;
612

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

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

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

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

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

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

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

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

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

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

    
694
    default:
695
        OMAP_BAD_REG(addr);
696
    }
697
}
698

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

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

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

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

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

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

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

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

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

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

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

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

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

    
793
    OMAP_BAD_REG(addr);
794
    return 0;
795
}
796

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
923
    default:
924
        OMAP_BAD_REG(addr);
925
    }
926
}
927

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

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

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

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

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

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

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

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

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

    
1004
    OMAP_BAD_REG(addr);
1005
    return 0;
1006
}
1007

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

    
1015
    OMAP_BAD_REG(addr);
1016
}
1017

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

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

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

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

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

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

    
1071
    OMAP_BAD_REG(addr);
1072
    return 0;
1073
}
1074

    
1075
static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
1076
                            uint64_t value, unsigned size)
1077
{
1078
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1079

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

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

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

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

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

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

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

    
1123
    omap_mpui_reset(mpu);
1124
}
1125

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1235
    return s;
1236
}
1237

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

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

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

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

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

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

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

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

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

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

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

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

    
1346
/* Digital phase-locked loops control */
1347
static uint64_t omap_dpll_read(void *opaque, target_phys_addr_t addr,
1348
                               unsigned size)
1349
{
1350
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
1351

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

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

    
1359
    OMAP_BAD_REG(addr);
1360
    return 0;
1361
}
1362

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

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

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

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

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

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

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

    
1412
static void omap_dpll_init(MemoryRegion *memory, struct dpll_ctl_s *s,
1413
                           target_phys_addr_t base, omap_clk clk)
1414
{
1415
    memory_region_init_io(&s->iomem, &omap_dpll_ops, s, "omap-dpll", 0x100);
1416

    
1417
    s->dpll = clk;
1418
    omap_dpll_reset(s);
1419

    
1420
    memory_region_add_subregion(memory, base, &s->iomem);
1421
}
1422

    
1423
/* MPU Clock/Reset/Power Mode Control */
1424
static uint64_t omap_clkm_read(void *opaque, target_phys_addr_t addr,
1425
                               unsigned size)
1426
{
1427
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1428

    
1429
    if (size != 2) {
1430
        return omap_badwidth_read16(opaque, addr);
1431
    }
1432

    
1433
    switch (addr) {
1434
    case 0x00:        /* ARM_CKCTL */
1435
        return s->clkm.arm_ckctl;
1436

    
1437
    case 0x04:        /* ARM_IDLECT1 */
1438
        return s->clkm.arm_idlect1;
1439

    
1440
    case 0x08:        /* ARM_IDLECT2 */
1441
        return s->clkm.arm_idlect2;
1442

    
1443
    case 0x0c:        /* ARM_EWUPCT */
1444
        return s->clkm.arm_ewupct;
1445

    
1446
    case 0x10:        /* ARM_RSTCT1 */
1447
        return s->clkm.arm_rstct1;
1448

    
1449
    case 0x14:        /* ARM_RSTCT2 */
1450
        return s->clkm.arm_rstct2;
1451

    
1452
    case 0x18:        /* ARM_SYSST */
1453
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
1454

    
1455
    case 0x1c:        /* ARM_CKOUT1 */
1456
        return s->clkm.arm_ckout1;
1457

    
1458
    case 0x20:        /* ARM_CKOUT2 */
1459
        break;
1460
    }
1461

    
1462
    OMAP_BAD_REG(addr);
1463
    return 0;
1464
}
1465

    
1466
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
1467
                uint16_t diff, uint16_t value)
1468
{
1469
    omap_clk clk;
1470

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

    
1513
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
1514
                uint16_t diff, uint16_t value)
1515
{
1516
    omap_clk clk;
1517

    
1518
    if (value & (1 << 11))                                /* SETARM_IDLE */
1519
        cpu_interrupt(s->env, CPU_INTERRUPT_HALT);
1520
    if (!(value & (1 << 10)))                                /* WKUP_MODE */
1521
        qemu_system_shutdown_request();        /* XXX: disable wakeup from IRQ */
1522

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

    
1544
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
1545
                uint16_t diff, uint16_t value)
1546
{
1547
    omap_clk clk;
1548

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

    
1567
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
1568
                uint16_t diff, uint16_t value)
1569
{
1570
    omap_clk clk;
1571

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

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

    
1636
    if (size != 2) {
1637
        return omap_badwidth_write16(opaque, addr, value);
1638
    }
1639

    
1640
    switch (addr) {
1641
    case 0x00:        /* ARM_CKCTL */
1642
        diff = s->clkm.arm_ckctl ^ value;
1643
        s->clkm.arm_ckctl = value & 0x7fff;
1644
        omap_clkm_ckctl_update(s, diff, value);
1645
        return;
1646

    
1647
    case 0x04:        /* ARM_IDLECT1 */
1648
        diff = s->clkm.arm_idlect1 ^ value;
1649
        s->clkm.arm_idlect1 = value & 0x0fff;
1650
        omap_clkm_idlect1_update(s, diff, value);
1651
        return;
1652

    
1653
    case 0x08:        /* ARM_IDLECT2 */
1654
        diff = s->clkm.arm_idlect2 ^ value;
1655
        s->clkm.arm_idlect2 = value & 0x07ff;
1656
        omap_clkm_idlect2_update(s, diff, value);
1657
        return;
1658

    
1659
    case 0x0c:        /* ARM_EWUPCT */
1660
        s->clkm.arm_ewupct = value & 0x003f;
1661
        return;
1662

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

    
1681
    case 0x14:        /* ARM_RSTCT2 */
1682
        s->clkm.arm_rstct2 = value & 0x0001;
1683
        return;
1684

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

    
1694
    case 0x1c:        /* ARM_CKOUT1 */
1695
        diff = s->clkm.arm_ckout1 ^ value;
1696
        s->clkm.arm_ckout1 = value & 0x003f;
1697
        omap_clkm_ckout1_update(s, diff, value);
1698
        return;
1699

    
1700
    case 0x20:        /* ARM_CKOUT2 */
1701
    default:
1702
        OMAP_BAD_REG(addr);
1703
    }
1704
}
1705

    
1706
static const MemoryRegionOps omap_clkm_ops = {
1707
    .read = omap_clkm_read,
1708
    .write = omap_clkm_write,
1709
    .endianness = DEVICE_NATIVE_ENDIAN,
1710
};
1711

    
1712
static uint64_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr,
1713
                                 unsigned size)
1714
{
1715
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1716

    
1717
    if (size != 2) {
1718
        return omap_badwidth_read16(opaque, addr);
1719
    }
1720

    
1721
    switch (addr) {
1722
    case 0x04:        /* DSP_IDLECT1 */
1723
        return s->clkm.dsp_idlect1;
1724

    
1725
    case 0x08:        /* DSP_IDLECT2 */
1726
        return s->clkm.dsp_idlect2;
1727

    
1728
    case 0x14:        /* DSP_RSTCT2 */
1729
        return s->clkm.dsp_rstct2;
1730

    
1731
    case 0x18:        /* DSP_SYSST */
1732
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
1733
                (s->env->halted << 6);        /* Quite useless... */
1734
    }
1735

    
1736
    OMAP_BAD_REG(addr);
1737
    return 0;
1738
}
1739

    
1740
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
1741
                uint16_t diff, uint16_t value)
1742
{
1743
    omap_clk clk;
1744

    
1745
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
1746
}
1747

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

    
1753
    SET_ONOFF("dspxor_ck", 1);                                /* EN_XORPCK */
1754
}
1755

    
1756
static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
1757
                              uint64_t value, unsigned size)
1758
{
1759
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1760
    uint16_t diff;
1761

    
1762
    if (size != 2) {
1763
        return omap_badwidth_write16(opaque, addr, value);
1764
    }
1765

    
1766
    switch (addr) {
1767
    case 0x04:        /* DSP_IDLECT1 */
1768
        diff = s->clkm.dsp_idlect1 ^ value;
1769
        s->clkm.dsp_idlect1 = value & 0x01f7;
1770
        omap_clkdsp_idlect1_update(s, diff, value);
1771
        break;
1772

    
1773
    case 0x08:        /* DSP_IDLECT2 */
1774
        s->clkm.dsp_idlect2 = value & 0x0037;
1775
        diff = s->clkm.dsp_idlect1 ^ value;
1776
        omap_clkdsp_idlect2_update(s, diff, value);
1777
        break;
1778

    
1779
    case 0x14:        /* DSP_RSTCT2 */
1780
        s->clkm.dsp_rstct2 = value & 0x0001;
1781
        break;
1782

    
1783
    case 0x18:        /* DSP_SYSST */
1784
        s->clkm.cold_start &= value & 0x3f;
1785
        break;
1786

    
1787
    default:
1788
        OMAP_BAD_REG(addr);
1789
    }
1790
}
1791

    
1792
static const MemoryRegionOps omap_clkdsp_ops = {
1793
    .read = omap_clkdsp_read,
1794
    .write = omap_clkdsp_write,
1795
    .endianness = DEVICE_NATIVE_ENDIAN,
1796
};
1797

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

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

    
1829
    s->clkm.arm_idlect1 = 0x03ff;
1830
    s->clkm.arm_idlect2 = 0x0100;
1831
    s->clkm.dsp_idlect1 = 0x0002;
1832
    omap_clkm_reset(s);
1833
    s->clkm.cold_start = 0x3a;
1834

    
1835
    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
1836
    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
1837
}
1838

    
1839
/* MPU I/O */
1840
struct omap_mpuio_s {
1841
    qemu_irq irq;
1842
    qemu_irq kbd_irq;
1843
    qemu_irq *in;
1844
    qemu_irq handler[16];
1845
    qemu_irq wakeup;
1846
    MemoryRegion iomem;
1847

    
1848
    uint16_t inputs;
1849
    uint16_t outputs;
1850
    uint16_t dir;
1851
    uint16_t edge;
1852
    uint16_t mask;
1853
    uint16_t ints;
1854

    
1855
    uint16_t debounce;
1856
    uint16_t latch;
1857
    uint8_t event;
1858

    
1859
    uint8_t buttons[5];
1860
    uint8_t row_latch;
1861
    uint8_t cols;
1862
    int kbd_mask;
1863
    int clk;
1864
};
1865

    
1866
static void omap_mpuio_set(void *opaque, int line, int level)
1867
{
1868
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1869
    uint16_t prev = s->inputs;
1870

    
1871
    if (level)
1872
        s->inputs |= 1 << line;
1873
    else
1874
        s->inputs &= ~(1 << line);
1875

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

    
1888
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
1889
{
1890
    int i;
1891
    uint8_t *row, rows = 0, cols = ~s->cols;
1892

    
1893
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
1894
        if (*row & cols)
1895
            rows |= i;
1896

    
1897
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
1898
    s->row_latch = ~rows;
1899
}
1900

    
1901
static uint64_t omap_mpuio_read(void *opaque, target_phys_addr_t addr,
1902
                                unsigned size)
1903
{
1904
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1905
    int offset = addr & OMAP_MPUI_REG_MASK;
1906
    uint16_t ret;
1907

    
1908
    if (size != 2) {
1909
        return omap_badwidth_read16(opaque, addr);
1910
    }
1911

    
1912
    switch (offset) {
1913
    case 0x00:        /* INPUT_LATCH */
1914
        return s->inputs;
1915

    
1916
    case 0x04:        /* OUTPUT_REG */
1917
        return s->outputs;
1918

    
1919
    case 0x08:        /* IO_CNTL */
1920
        return s->dir;
1921

    
1922
    case 0x10:        /* KBR_LATCH */
1923
        return s->row_latch;
1924

    
1925
    case 0x14:        /* KBC_REG */
1926
        return s->cols;
1927

    
1928
    case 0x18:        /* GPIO_EVENT_MODE_REG */
1929
        return s->event;
1930

    
1931
    case 0x1c:        /* GPIO_INT_EDGE_REG */
1932
        return s->edge;
1933

    
1934
    case 0x20:        /* KBD_INT */
1935
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
1936

    
1937
    case 0x24:        /* GPIO_INT */
1938
        ret = s->ints;
1939
        s->ints &= s->mask;
1940
        if (ret)
1941
            qemu_irq_lower(s->irq);
1942
        return ret;
1943

    
1944
    case 0x28:        /* KBD_MASKIT */
1945
        return s->kbd_mask;
1946

    
1947
    case 0x2c:        /* GPIO_MASKIT */
1948
        return s->mask;
1949

    
1950
    case 0x30:        /* GPIO_DEBOUNCING_REG */
1951
        return s->debounce;
1952

    
1953
    case 0x34:        /* GPIO_LATCH_REG */
1954
        return s->latch;
1955
    }
1956

    
1957
    OMAP_BAD_REG(addr);
1958
    return 0;
1959
}
1960

    
1961
static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
1962
                             uint64_t value, unsigned size)
1963
{
1964
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
1965
    int offset = addr & OMAP_MPUI_REG_MASK;
1966
    uint16_t diff;
1967
    int ln;
1968

    
1969
    if (size != 2) {
1970
        return omap_badwidth_write16(opaque, addr, value);
1971
    }
1972

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

    
1985
    case 0x08:        /* IO_CNTL */
1986
        diff = s->outputs & (s->dir ^ value);
1987
        s->dir = value;
1988

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

    
1998
    case 0x14:        /* KBC_REG */
1999
        s->cols = value;
2000
        omap_mpuio_kbd_update(s);
2001
        break;
2002

    
2003
    case 0x18:        /* GPIO_EVENT_MODE_REG */
2004
        s->event = value & 0x1f;
2005
        break;
2006

    
2007
    case 0x1c:        /* GPIO_INT_EDGE_REG */
2008
        s->edge = value;
2009
        break;
2010

    
2011
    case 0x28:        /* KBD_MASKIT */
2012
        s->kbd_mask = value & 1;
2013
        omap_mpuio_kbd_update(s);
2014
        break;
2015

    
2016
    case 0x2c:        /* GPIO_MASKIT */
2017
        s->mask = value;
2018
        break;
2019

    
2020
    case 0x30:        /* GPIO_DEBOUNCING_REG */
2021
        s->debounce = value & 0x1ff;
2022
        break;
2023

    
2024
    case 0x00:        /* INPUT_LATCH */
2025
    case 0x10:        /* KBR_LATCH */
2026
    case 0x20:        /* KBD_INT */
2027
    case 0x24:        /* GPIO_INT */
2028
    case 0x34:        /* GPIO_LATCH_REG */
2029
        OMAP_RO_REG(addr);
2030
        return;
2031

    
2032
    default:
2033
        OMAP_BAD_REG(addr);
2034
        return;
2035
    }
2036
}
2037

    
2038
static const MemoryRegionOps omap_mpuio_ops  = {
2039
    .read = omap_mpuio_read,
2040
    .write = omap_mpuio_write,
2041
    .endianness = DEVICE_NATIVE_ENDIAN,
2042
};
2043

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

    
2060
static void omap_mpuio_onoff(void *opaque, int line, int on)
2061
{
2062
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
2063

    
2064
    s->clk = on;
2065
    if (on)
2066
        omap_mpuio_kbd_update(s);
2067
}
2068

    
2069
struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
2070
                target_phys_addr_t base,
2071
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
2072
                omap_clk clk)
2073
{
2074
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
2075
            g_malloc0(sizeof(struct omap_mpuio_s));
2076

    
2077
    s->irq = gpio_int;
2078
    s->kbd_irq = kbd_int;
2079
    s->wakeup = wakeup;
2080
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
2081
    omap_mpuio_reset(s);
2082

    
2083
    memory_region_init_io(&s->iomem, &omap_mpuio_ops, s,
2084
                          "omap-mpuio", 0x800);
2085
    memory_region_add_subregion(memory, base, &s->iomem);
2086

    
2087
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
2088

    
2089
    return s;
2090
}
2091

    
2092
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
2093
{
2094
    return s->in;
2095
}
2096

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

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

    
2109
    if (down)
2110
        s->buttons[row] |= 1 << col;
2111
    else
2112
        s->buttons[row] &= ~(1 << col);
2113

    
2114
    omap_mpuio_kbd_update(s);
2115
}
2116

    
2117
/* MicroWire Interface */
2118
struct omap_uwire_s {
2119
    MemoryRegion iomem;
2120
    qemu_irq txirq;
2121
    qemu_irq rxirq;
2122
    qemu_irq txdrq;
2123

    
2124
    uint16_t txbuf;
2125
    uint16_t rxbuf;
2126
    uint16_t control;
2127
    uint16_t setup[5];
2128

    
2129
    uWireSlave *chip[4];
2130
};
2131

    
2132
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
2133
{
2134
    int chipselect = (s->control >> 10) & 3;                /* INDEX */
2135
    uWireSlave *slave = s->chip[chipselect];
2136

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

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

    
2157
static uint64_t omap_uwire_read(void *opaque, target_phys_addr_t addr,
2158
                                unsigned size)
2159
{
2160
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2161
    int offset = addr & OMAP_MPUI_REG_MASK;
2162

    
2163
    if (size != 2) {
2164
        return omap_badwidth_read16(opaque, addr);
2165
    }
2166

    
2167
    switch (offset) {
2168
    case 0x00:        /* RDR */
2169
        s->control &= ~(1 << 15);                        /* RDRB */
2170
        return s->rxbuf;
2171

    
2172
    case 0x04:        /* CSR */
2173
        return s->control;
2174

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

    
2187
    OMAP_BAD_REG(addr);
2188
    return 0;
2189
}
2190

    
2191
static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
2192
                             uint64_t value, unsigned size)
2193
{
2194
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
2195
    int offset = addr & OMAP_MPUI_REG_MASK;
2196

    
2197
    if (size != 2) {
2198
        return omap_badwidth_write16(opaque, addr, value);
2199
    }
2200

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

    
2212
    case 0x04:        /* CSR */
2213
        s->control = value & 0x1fff;
2214
        if (value & (1 << 13))                                /* START */
2215
            omap_uwire_transfer_start(s);
2216
        break;
2217

    
2218
    case 0x08:        /* SR1 */
2219
        s->setup[0] = value & 0x003f;
2220
        break;
2221

    
2222
    case 0x0c:        /* SR2 */
2223
        s->setup[1] = value & 0x0fc0;
2224
        break;
2225

    
2226
    case 0x10:        /* SR3 */
2227
        s->setup[2] = value & 0x0003;
2228
        break;
2229

    
2230
    case 0x14:        /* SR4 */
2231
        s->setup[3] = value & 0x0001;
2232
        break;
2233

    
2234
    case 0x18:        /* SR5 */
2235
        s->setup[4] = value & 0x000f;
2236
        break;
2237

    
2238
    default:
2239
        OMAP_BAD_REG(addr);
2240
        return;
2241
    }
2242
}
2243

    
2244
static const MemoryRegionOps omap_uwire_ops = {
2245
    .read = omap_uwire_read,
2246
    .write = omap_uwire_write,
2247
    .endianness = DEVICE_NATIVE_ENDIAN,
2248
};
2249

    
2250
static void omap_uwire_reset(struct omap_uwire_s *s)
2251
{
2252
    s->control = 0;
2253
    s->setup[0] = 0;
2254
    s->setup[1] = 0;
2255
    s->setup[2] = 0;
2256
    s->setup[3] = 0;
2257
    s->setup[4] = 0;
2258
}
2259

    
2260
static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
2261
                                            target_phys_addr_t base,
2262
                                            qemu_irq txirq, qemu_irq rxirq,
2263
                                            qemu_irq dma,
2264
                                            omap_clk clk)
2265
{
2266
    struct omap_uwire_s *s = (struct omap_uwire_s *)
2267
            g_malloc0(sizeof(struct omap_uwire_s));
2268

    
2269
    s->txirq = txirq;
2270
    s->rxirq = rxirq;
2271
    s->txdrq = dma;
2272
    omap_uwire_reset(s);
2273

    
2274
    memory_region_init_io(&s->iomem, &omap_uwire_ops, s, "omap-uwire", 0x800);
2275
    memory_region_add_subregion(system_memory, base, &s->iomem);
2276

    
2277
    return s;
2278
}
2279

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

    
2288
    s->chip[chipselect] = slave;
2289
}
2290

    
2291
/* Pseudonoise Pulse-Width Light Modulator */
2292
static void omap_pwl_update(struct omap_mpu_state_s *s)
2293
{
2294
    int output = (s->pwl.clk && s->pwl.enable) ? s->pwl.level : 0;
2295

    
2296
    if (output != s->pwl.output) {
2297
        s->pwl.output = output;
2298
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
2299
    }
2300
}
2301

    
2302
static uint64_t omap_pwl_read(void *opaque, target_phys_addr_t addr,
2303
                              unsigned size)
2304
{
2305
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2306
    int offset = addr & OMAP_MPUI_REG_MASK;
2307

    
2308
    if (size != 1) {
2309
        return omap_badwidth_read8(opaque, addr);
2310
    }
2311

    
2312
    switch (offset) {
2313
    case 0x00:        /* PWL_LEVEL */
2314
        return s->pwl.level;
2315
    case 0x04:        /* PWL_CTRL */
2316
        return s->pwl.enable;
2317
    }
2318
    OMAP_BAD_REG(addr);
2319
    return 0;
2320
}
2321

    
2322
static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
2323
                           uint64_t value, unsigned size)
2324
{
2325
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2326
    int offset = addr & OMAP_MPUI_REG_MASK;
2327

    
2328
    if (size != 1) {
2329
        return omap_badwidth_write8(opaque, addr, value);
2330
    }
2331

    
2332
    switch (offset) {
2333
    case 0x00:        /* PWL_LEVEL */
2334
        s->pwl.level = value;
2335
        omap_pwl_update(s);
2336
        break;
2337
    case 0x04:        /* PWL_CTRL */
2338
        s->pwl.enable = value & 1;
2339
        omap_pwl_update(s);
2340
        break;
2341
    default:
2342
        OMAP_BAD_REG(addr);
2343
        return;
2344
    }
2345
}
2346

    
2347
static const MemoryRegionOps omap_pwl_ops = {
2348
    .read = omap_pwl_read,
2349
    .write = omap_pwl_write,
2350
    .endianness = DEVICE_NATIVE_ENDIAN,
2351
};
2352

    
2353
static void omap_pwl_reset(struct omap_mpu_state_s *s)
2354
{
2355
    s->pwl.output = 0;
2356
    s->pwl.level = 0;
2357
    s->pwl.enable = 0;
2358
    s->pwl.clk = 1;
2359
    omap_pwl_update(s);
2360
}
2361

    
2362
static void omap_pwl_clk_update(void *opaque, int line, int on)
2363
{
2364
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2365

    
2366
    s->pwl.clk = on;
2367
    omap_pwl_update(s);
2368
}
2369

    
2370
static void omap_pwl_init(MemoryRegion *system_memory,
2371
                target_phys_addr_t base, struct omap_mpu_state_s *s,
2372
                omap_clk clk)
2373
{
2374
    omap_pwl_reset(s);
2375

    
2376
    memory_region_init_io(&s->pwl_iomem, &omap_pwl_ops, s,
2377
                          "omap-pwl", 0x800);
2378
    memory_region_add_subregion(system_memory, base, &s->pwl_iomem);
2379

    
2380
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
2381
}
2382

    
2383
/* Pulse-Width Tone module */
2384
static uint64_t omap_pwt_read(void *opaque, target_phys_addr_t addr,
2385
                              unsigned size)
2386
{
2387
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2388
    int offset = addr & OMAP_MPUI_REG_MASK;
2389

    
2390
    if (size != 1) {
2391
        return omap_badwidth_read8(opaque, addr);
2392
    }
2393

    
2394
    switch (offset) {
2395
    case 0x00:        /* FRC */
2396
        return s->pwt.frc;
2397
    case 0x04:        /* VCR */
2398
        return s->pwt.vrc;
2399
    case 0x08:        /* GCR */
2400
        return s->pwt.gcr;
2401
    }
2402
    OMAP_BAD_REG(addr);
2403
    return 0;
2404
}
2405

    
2406
static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
2407
                           uint64_t value, unsigned size)
2408
{
2409
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2410
    int offset = addr & OMAP_MPUI_REG_MASK;
2411

    
2412
    if (size != 1) {
2413
        return omap_badwidth_write8(opaque, addr, value);
2414
    }
2415

    
2416
    switch (offset) {
2417
    case 0x00:        /* FRC */
2418
        s->pwt.frc = value & 0x3f;
2419
        break;
2420
    case 0x04:        /* VRC */
2421
        if ((value ^ s->pwt.vrc) & 1) {
2422
            if (value & 1)
2423
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
2424
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
2425
                                ((omap_clk_getrate(s->pwt.clk) >> 3) /
2426
                                 /* Pre-multiplexer divider */
2427
                                 ((s->pwt.gcr & 2) ? 1 : 154) /
2428
                                 /* Octave multiplexer */
2429
                                 (2 << (value & 3)) *
2430
                                 /* 101/107 divider */
2431
                                 ((value & (1 << 2)) ? 101 : 107) *
2432
                                 /*  49/55 divider */
2433
                                 ((value & (1 << 3)) ?  49 : 55) *
2434
                                 /*  50/63 divider */
2435
                                 ((value & (1 << 4)) ?  50 : 63) *
2436
                                 /*  80/127 divider */
2437
                                 ((value & (1 << 5)) ?  80 : 127) /
2438
                                 (107 * 55 * 63 * 127)));
2439
            else
2440
                printf("%s: silence!\n", __FUNCTION__);
2441
        }
2442
        s->pwt.vrc = value & 0x7f;
2443
        break;
2444
    case 0x08:        /* GCR */
2445
        s->pwt.gcr = value & 3;
2446
        break;
2447
    default:
2448
        OMAP_BAD_REG(addr);
2449
        return;
2450
    }
2451
}
2452

    
2453
static const MemoryRegionOps omap_pwt_ops = {
2454
    .read =omap_pwt_read,
2455
    .write = omap_pwt_write,
2456
    .endianness = DEVICE_NATIVE_ENDIAN,
2457
};
2458

    
2459
static void omap_pwt_reset(struct omap_mpu_state_s *s)
2460
{
2461
    s->pwt.frc = 0;
2462
    s->pwt.vrc = 0;
2463
    s->pwt.gcr = 0;
2464
}
2465

    
2466
static void omap_pwt_init(MemoryRegion *system_memory,
2467
                target_phys_addr_t base, struct omap_mpu_state_s *s,
2468
                omap_clk clk)
2469
{
2470
    s->pwt.clk = clk;
2471
    omap_pwt_reset(s);
2472

    
2473
    memory_region_init_io(&s->pwt_iomem, &omap_pwt_ops, s,
2474
                          "omap-pwt", 0x800);
2475
    memory_region_add_subregion(system_memory, base, &s->pwt_iomem);
2476
}
2477

    
2478
/* Real-time Clock module */
2479
struct omap_rtc_s {
2480
    MemoryRegion iomem;
2481
    qemu_irq irq;
2482
    qemu_irq alarm;
2483
    QEMUTimer *clk;
2484

    
2485
    uint8_t interrupts;
2486
    uint8_t status;
2487
    int16_t comp_reg;
2488
    int running;
2489
    int pm_am;
2490
    int auto_comp;
2491
    int round;
2492
    struct tm alarm_tm;
2493
    time_t alarm_ti;
2494

    
2495
    struct tm current_tm;
2496
    time_t ti;
2497
    uint64_t tick;
2498
};
2499

    
2500
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
2501
{
2502
    /* s->alarm is level-triggered */
2503
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
2504
}
2505

    
2506
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
2507
{
2508
    s->alarm_ti = mktimegm(&s->alarm_tm);
2509
    if (s->alarm_ti == -1)
2510
        printf("%s: conversion failed\n", __FUNCTION__);
2511
}
2512

    
2513
static uint64_t omap_rtc_read(void *opaque, target_phys_addr_t addr,
2514
                              unsigned size)
2515
{
2516
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2517
    int offset = addr & OMAP_MPUI_REG_MASK;
2518
    uint8_t i;
2519

    
2520
    if (size != 1) {
2521
        return omap_badwidth_read8(opaque, addr);
2522
    }
2523

    
2524
    switch (offset) {
2525
    case 0x00:        /* SECONDS_REG */
2526
        return to_bcd(s->current_tm.tm_sec);
2527

    
2528
    case 0x04:        /* MINUTES_REG */
2529
        return to_bcd(s->current_tm.tm_min);
2530

    
2531
    case 0x08:        /* HOURS_REG */
2532
        if (s->pm_am)
2533
            return ((s->current_tm.tm_hour > 11) << 7) |
2534
                    to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
2535
        else
2536
            return to_bcd(s->current_tm.tm_hour);
2537

    
2538
    case 0x0c:        /* DAYS_REG */
2539
        return to_bcd(s->current_tm.tm_mday);
2540

    
2541
    case 0x10:        /* MONTHS_REG */
2542
        return to_bcd(s->current_tm.tm_mon + 1);
2543

    
2544
    case 0x14:        /* YEARS_REG */
2545
        return to_bcd(s->current_tm.tm_year % 100);
2546

    
2547
    case 0x18:        /* WEEK_REG */
2548
        return s->current_tm.tm_wday;
2549

    
2550
    case 0x20:        /* ALARM_SECONDS_REG */
2551
        return to_bcd(s->alarm_tm.tm_sec);
2552

    
2553
    case 0x24:        /* ALARM_MINUTES_REG */
2554
        return to_bcd(s->alarm_tm.tm_min);
2555

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

    
2563
    case 0x2c:        /* ALARM_DAYS_REG */
2564
        return to_bcd(s->alarm_tm.tm_mday);
2565

    
2566
    case 0x30:        /* ALARM_MONTHS_REG */
2567
        return to_bcd(s->alarm_tm.tm_mon + 1);
2568

    
2569
    case 0x34:        /* ALARM_YEARS_REG */
2570
        return to_bcd(s->alarm_tm.tm_year % 100);
2571

    
2572
    case 0x40:        /* RTC_CTRL_REG */
2573
        return (s->pm_am << 3) | (s->auto_comp << 2) |
2574
                (s->round << 1) | s->running;
2575

    
2576
    case 0x44:        /* RTC_STATUS_REG */
2577
        i = s->status;
2578
        s->status &= ~0x3d;
2579
        return i;
2580

    
2581
    case 0x48:        /* RTC_INTERRUPTS_REG */
2582
        return s->interrupts;
2583

    
2584
    case 0x4c:        /* RTC_COMP_LSB_REG */
2585
        return ((uint16_t) s->comp_reg) & 0xff;
2586

    
2587
    case 0x50:        /* RTC_COMP_MSB_REG */
2588
        return ((uint16_t) s->comp_reg) >> 8;
2589
    }
2590

    
2591
    OMAP_BAD_REG(addr);
2592
    return 0;
2593
}
2594

    
2595
static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
2596
                           uint64_t value, unsigned size)
2597
{
2598
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
2599
    int offset = addr & OMAP_MPUI_REG_MASK;
2600
    struct tm new_tm;
2601
    time_t ti[2];
2602

    
2603
    if (size != 1) {
2604
        return omap_badwidth_write8(opaque, addr, value);
2605
    }
2606

    
2607
    switch (offset) {
2608
    case 0x00:        /* SECONDS_REG */
2609
#ifdef ALMDEBUG
2610
        printf("RTC SEC_REG <-- %02x\n", value);
2611
#endif
2612
        s->ti -= s->current_tm.tm_sec;
2613
        s->ti += from_bcd(value);
2614
        return;
2615

    
2616
    case 0x04:        /* MINUTES_REG */
2617
#ifdef ALMDEBUG
2618
        printf("RTC MIN_REG <-- %02x\n", value);
2619
#endif
2620
        s->ti -= s->current_tm.tm_min * 60;
2621
        s->ti += from_bcd(value) * 60;
2622
        return;
2623

    
2624
    case 0x08:        /* HOURS_REG */
2625
#ifdef ALMDEBUG
2626
        printf("RTC HRS_REG <-- %02x\n", value);
2627
#endif
2628
        s->ti -= s->current_tm.tm_hour * 3600;
2629
        if (s->pm_am) {
2630
            s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
2631
            s->ti += ((value >> 7) & 1) * 43200;
2632
        } else
2633
            s->ti += from_bcd(value & 0x3f) * 3600;
2634
        return;
2635

    
2636
    case 0x0c:        /* DAYS_REG */
2637
#ifdef ALMDEBUG
2638
        printf("RTC DAY_REG <-- %02x\n", value);
2639
#endif
2640
        s->ti -= s->current_tm.tm_mday * 86400;
2641
        s->ti += from_bcd(value) * 86400;
2642
        return;
2643

    
2644
    case 0x10:        /* MONTHS_REG */
2645
#ifdef ALMDEBUG
2646
        printf("RTC MTH_REG <-- %02x\n", value);
2647
#endif
2648
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2649
        new_tm.tm_mon = from_bcd(value);
2650
        ti[0] = mktimegm(&s->current_tm);
2651
        ti[1] = mktimegm(&new_tm);
2652

    
2653
        if (ti[0] != -1 && ti[1] != -1) {
2654
            s->ti -= ti[0];
2655
            s->ti += ti[1];
2656
        } else {
2657
            /* A less accurate version */
2658
            s->ti -= s->current_tm.tm_mon * 2592000;
2659
            s->ti += from_bcd(value) * 2592000;
2660
        }
2661
        return;
2662

    
2663
    case 0x14:        /* YEARS_REG */
2664
#ifdef ALMDEBUG
2665
        printf("RTC YRS_REG <-- %02x\n", value);
2666
#endif
2667
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
2668
        new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
2669
        ti[0] = mktimegm(&s->current_tm);
2670
        ti[1] = mktimegm(&new_tm);
2671

    
2672
        if (ti[0] != -1 && ti[1] != -1) {
2673
            s->ti -= ti[0];
2674
            s->ti += ti[1];
2675
        } else {
2676
            /* A less accurate version */
2677
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
2678
            s->ti += from_bcd(value) * 31536000;
2679
        }
2680
        return;
2681

    
2682
    case 0x18:        /* WEEK_REG */
2683
        return;        /* Ignored */
2684

    
2685
    case 0x20:        /* ALARM_SECONDS_REG */
2686
#ifdef ALMDEBUG
2687
        printf("ALM SEC_REG <-- %02x\n", value);
2688
#endif
2689
        s->alarm_tm.tm_sec = from_bcd(value);
2690
        omap_rtc_alarm_update(s);
2691
        return;
2692

    
2693
    case 0x24:        /* ALARM_MINUTES_REG */
2694
#ifdef ALMDEBUG
2695
        printf("ALM MIN_REG <-- %02x\n", value);
2696
#endif
2697
        s->alarm_tm.tm_min = from_bcd(value);
2698
        omap_rtc_alarm_update(s);
2699
        return;
2700

    
2701
    case 0x28:        /* ALARM_HOURS_REG */
2702
#ifdef ALMDEBUG
2703
        printf("ALM HRS_REG <-- %02x\n", value);
2704
#endif
2705
        if (s->pm_am)
2706
            s->alarm_tm.tm_hour =
2707
                    ((from_bcd(value & 0x3f)) % 12) +
2708
                    ((value >> 7) & 1) * 12;
2709
        else
2710
            s->alarm_tm.tm_hour = from_bcd(value);
2711
        omap_rtc_alarm_update(s);
2712
        return;
2713

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

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

    
2730
    case 0x34:        /* ALARM_YEARS_REG */
2731
#ifdef ALMDEBUG
2732
        printf("ALM YRS_REG <-- %02x\n", value);
2733
#endif
2734
        s->alarm_tm.tm_year = from_bcd(value);
2735
        omap_rtc_alarm_update(s);
2736
        return;
2737

    
2738
    case 0x40:        /* RTC_CTRL_REG */
2739
#ifdef ALMDEBUG
2740
        printf("RTC CONTROL <-- %02x\n", value);
2741
#endif
2742
        s->pm_am = (value >> 3) & 1;
2743
        s->auto_comp = (value >> 2) & 1;
2744
        s->round = (value >> 1) & 1;
2745
        s->running = value & 1;
2746
        s->status &= 0xfd;
2747
        s->status |= s->running << 1;
2748
        return;
2749

    
2750
    case 0x44:        /* RTC_STATUS_REG */
2751
#ifdef ALMDEBUG
2752
        printf("RTC STATUSL <-- %02x\n", value);
2753
#endif
2754
        s->status &= ~((value & 0xc0) ^ 0x80);
2755
        omap_rtc_interrupts_update(s);
2756
        return;
2757

    
2758
    case 0x48:        /* RTC_INTERRUPTS_REG */
2759
#ifdef ALMDEBUG
2760
        printf("RTC INTRS <-- %02x\n", value);
2761
#endif
2762
        s->interrupts = value;
2763
        return;
2764

    
2765
    case 0x4c:        /* RTC_COMP_LSB_REG */
2766
#ifdef ALMDEBUG
2767
        printf("RTC COMPLSB <-- %02x\n", value);
2768
#endif
2769
        s->comp_reg &= 0xff00;
2770
        s->comp_reg |= 0x00ff & value;
2771
        return;
2772

    
2773
    case 0x50:        /* RTC_COMP_MSB_REG */
2774
#ifdef ALMDEBUG
2775
        printf("RTC COMPMSB <-- %02x\n", value);
2776
#endif
2777
        s->comp_reg &= 0x00ff;
2778
        s->comp_reg |= 0xff00 & (value << 8);
2779
        return;
2780

    
2781
    default:
2782
        OMAP_BAD_REG(addr);
2783
        return;
2784
    }
2785
}
2786

    
2787
static const MemoryRegionOps omap_rtc_ops = {
2788
    .read = omap_rtc_read,
2789
    .write = omap_rtc_write,
2790
    .endianness = DEVICE_NATIVE_ENDIAN,
2791
};
2792

    
2793
static void omap_rtc_tick(void *opaque)
2794
{
2795
    struct omap_rtc_s *s = opaque;
2796

    
2797
    if (s->round) {
2798
        /* Round to nearest full minute.  */
2799
        if (s->current_tm.tm_sec < 30)
2800
            s->ti -= s->current_tm.tm_sec;
2801
        else
2802
            s->ti += 60 - s->current_tm.tm_sec;
2803

    
2804
        s->round = 0;
2805
    }
2806

    
2807
    memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
2808

    
2809
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
2810
        s->status |= 0x40;
2811
        omap_rtc_interrupts_update(s);
2812
    }
2813

    
2814
    if (s->interrupts & 0x04)
2815
        switch (s->interrupts & 3) {
2816
        case 0:
2817
            s->status |= 0x04;
2818
            qemu_irq_pulse(s->irq);
2819
            break;
2820
        case 1:
2821
            if (s->current_tm.tm_sec)
2822
                break;
2823
            s->status |= 0x08;
2824
            qemu_irq_pulse(s->irq);
2825
            break;
2826
        case 2:
2827
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
2828
                break;
2829
            s->status |= 0x10;
2830
            qemu_irq_pulse(s->irq);
2831
            break;
2832
        case 3:
2833
            if (s->current_tm.tm_sec ||
2834
                            s->current_tm.tm_min || s->current_tm.tm_hour)
2835
                break;
2836
            s->status |= 0x20;
2837
            qemu_irq_pulse(s->irq);
2838
            break;
2839
        }
2840

    
2841
    /* Move on */
2842
    if (s->running)
2843
        s->ti ++;
2844
    s->tick += 1000;
2845

    
2846
    /*
2847
     * Every full hour add a rough approximation of the compensation
2848
     * register to the 32kHz Timer (which drives the RTC) value. 
2849
     */
2850
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
2851
        s->tick += s->comp_reg * 1000 / 32768;
2852

    
2853
    qemu_mod_timer(s->clk, s->tick);
2854
}
2855

    
2856
static void omap_rtc_reset(struct omap_rtc_s *s)
2857
{
2858
    struct tm tm;
2859

    
2860
    s->interrupts = 0;
2861
    s->comp_reg = 0;
2862
    s->running = 0;
2863
    s->pm_am = 0;
2864
    s->auto_comp = 0;
2865
    s->round = 0;
2866
    s->tick = qemu_get_clock_ms(rt_clock);
2867
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
2868
    s->alarm_tm.tm_mday = 0x01;
2869
    s->status = 1 << 7;
2870
    qemu_get_timedate(&tm, 0);
2871
    s->ti = mktimegm(&tm);
2872

    
2873
    omap_rtc_alarm_update(s);
2874
    omap_rtc_tick(s);
2875
}
2876

    
2877
static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
2878
                                        target_phys_addr_t base,
2879
                                        qemu_irq timerirq, qemu_irq alarmirq,
2880
                                        omap_clk clk)
2881
{
2882
    struct omap_rtc_s *s = (struct omap_rtc_s *)
2883
            g_malloc0(sizeof(struct omap_rtc_s));
2884

    
2885
    s->irq = timerirq;
2886
    s->alarm = alarmirq;
2887
    s->clk = qemu_new_timer_ms(rt_clock, omap_rtc_tick, s);
2888

    
2889
    omap_rtc_reset(s);
2890

    
2891
    memory_region_init_io(&s->iomem, &omap_rtc_ops, s,
2892
                          "omap-rtc", 0x800);
2893
    memory_region_add_subregion(system_memory, base, &s->iomem);
2894

    
2895
    return s;
2896
}
2897

    
2898
/* Multi-channel Buffered Serial Port interfaces */
2899
struct omap_mcbsp_s {
2900
    MemoryRegion iomem;
2901
    qemu_irq txirq;
2902
    qemu_irq rxirq;
2903
    qemu_irq txdrq;
2904
    qemu_irq rxdrq;
2905

    
2906
    uint16_t spcr[2];
2907
    uint16_t rcr[2];
2908
    uint16_t xcr[2];
2909
    uint16_t srgr[2];
2910
    uint16_t mcr[2];
2911
    uint16_t pcr;
2912
    uint16_t rcer[8];
2913
    uint16_t xcer[8];
2914
    int tx_rate;
2915
    int rx_rate;
2916
    int tx_req;
2917
    int rx_req;
2918

    
2919
    I2SCodec *codec;
2920
    QEMUTimer *source_timer;
2921
    QEMUTimer *sink_timer;
2922
};
2923

    
2924
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
2925
{
2926
    int irq;
2927

    
2928
    switch ((s->spcr[0] >> 4) & 3) {                        /* RINTM */
2929
    case 0:
2930
        irq = (s->spcr[0] >> 1) & 1;                        /* RRDY */
2931
        break;
2932
    case 3:
2933
        irq = (s->spcr[0] >> 3) & 1;                        /* RSYNCERR */
2934
        break;
2935
    default:
2936
        irq = 0;
2937
        break;
2938
    }
2939

    
2940
    if (irq)
2941
        qemu_irq_pulse(s->rxirq);
2942

    
2943
    switch ((s->spcr[1] >> 4) & 3) {                        /* XINTM */
2944
    case 0:
2945
        irq = (s->spcr[1] >> 1) & 1;                        /* XRDY */
2946
        break;
2947
    case 3:
2948
        irq = (s->spcr[1] >> 3) & 1;                        /* XSYNCERR */
2949
        break;
2950
    default:
2951
        irq = 0;
2952
        break;
2953
    }
2954

    
2955
    if (irq)
2956
        qemu_irq_pulse(s->txirq);
2957
}
2958

    
2959
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
2960
{
2961
    if ((s->spcr[0] >> 1) & 1)                                /* RRDY */
2962
        s->spcr[0] |= 1 << 2;                                /* RFULL */
2963
    s->spcr[0] |= 1 << 1;                                /* RRDY */
2964
    qemu_irq_raise(s->rxdrq);
2965
    omap_mcbsp_intr_update(s);
2966
}
2967

    
2968
static void omap_mcbsp_source_tick(void *opaque)
2969
{
2970
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
2971
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
2972

    
2973
    if (!s->rx_rate)
2974
        return;
2975
    if (s->rx_req)
2976
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
2977

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

    
2980
    omap_mcbsp_rx_newdata(s);
2981
    qemu_mod_timer(s->source_timer, qemu_get_clock_ns(vm_clock) +
2982
                   get_ticks_per_sec());
2983
}
2984

    
2985
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
2986
{
2987
    if (!s->codec || !s->codec->rts)
2988
        omap_mcbsp_source_tick(s);
2989
    else if (s->codec->in.len) {
2990
        s->rx_req = s->codec->in.len;
2991
        omap_mcbsp_rx_newdata(s);
2992
    }
2993
}
2994

    
2995
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
2996
{
2997
    qemu_del_timer(s->source_timer);
2998
}
2999

    
3000
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
3001
{
3002
    s->spcr[0] &= ~(1 << 1);                                /* RRDY */
3003
    qemu_irq_lower(s->rxdrq);
3004
    omap_mcbsp_intr_update(s);
3005
}
3006

    
3007
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
3008
{
3009
    s->spcr[1] |= 1 << 1;                                /* XRDY */
3010
    qemu_irq_raise(s->txdrq);
3011
    omap_mcbsp_intr_update(s);
3012
}
3013

    
3014
static void omap_mcbsp_sink_tick(void *opaque)
3015
{
3016
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3017
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
3018

    
3019
    if (!s->tx_rate)
3020
        return;
3021
    if (s->tx_req)
3022
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
3023

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

    
3026
    omap_mcbsp_tx_newdata(s);
3027
    qemu_mod_timer(s->sink_timer, qemu_get_clock_ns(vm_clock) +
3028
                   get_ticks_per_sec());
3029
}
3030

    
3031
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
3032
{
3033
    if (!s->codec || !s->codec->cts)
3034
        omap_mcbsp_sink_tick(s);
3035
    else if (s->codec->out.size) {
3036
        s->tx_req = s->codec->out.size;
3037
        omap_mcbsp_tx_newdata(s);
3038
    }
3039
}
3040

    
3041
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
3042
{
3043
    s->spcr[1] &= ~(1 << 1);                                /* XRDY */
3044
    qemu_irq_lower(s->txdrq);
3045
    omap_mcbsp_intr_update(s);
3046
    if (s->codec && s->codec->cts)
3047
        s->codec->tx_swallow(s->codec->opaque);
3048
}
3049

    
3050
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
3051
{
3052
    s->tx_req = 0;
3053
    omap_mcbsp_tx_done(s);
3054
    qemu_del_timer(s->sink_timer);
3055
}
3056

    
3057
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
3058
{
3059
    int prev_rx_rate, prev_tx_rate;
3060
    int rx_rate = 0, tx_rate = 0;
3061
    int cpu_rate = 1500000;        /* XXX */
3062

    
3063
    /* TODO: check CLKSTP bit */
3064
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
3065
        if (s->spcr[0] & (1 << 0)) {                        /* RRST */
3066
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3067
                            (s->pcr & (1 << 8))) {        /* CLKRM */
3068
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3069
                    rx_rate = cpu_rate /
3070
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3071
            } else
3072
                if (s->codec)
3073
                    rx_rate = s->codec->rx_rate;
3074
        }
3075

    
3076
        if (s->spcr[1] & (1 << 0)) {                        /* XRST */
3077
            if ((s->srgr[1] & (1 << 13)) &&                /* CLKSM */
3078
                            (s->pcr & (1 << 9))) {        /* CLKXM */
3079
                if (~s->pcr & (1 << 7))                        /* SCLKME */
3080
                    tx_rate = cpu_rate /
3081
                            ((s->srgr[0] & 0xff) + 1);        /* CLKGDV */
3082
            } else
3083
                if (s->codec)
3084
                    tx_rate = s->codec->tx_rate;
3085
        }
3086
    }
3087
    prev_tx_rate = s->tx_rate;
3088
    prev_rx_rate = s->rx_rate;
3089
    s->tx_rate = tx_rate;
3090
    s->rx_rate = rx_rate;
3091

    
3092
    if (s->codec)
3093
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
3094

    
3095
    if (!prev_tx_rate && tx_rate)
3096
        omap_mcbsp_tx_start(s);
3097
    else if (s->tx_rate && !tx_rate)
3098
        omap_mcbsp_tx_stop(s);
3099

    
3100
    if (!prev_rx_rate && rx_rate)
3101
        omap_mcbsp_rx_start(s);
3102
    else if (prev_tx_rate && !tx_rate)
3103
        omap_mcbsp_rx_stop(s);
3104
}
3105

    
3106
static uint64_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr,
3107
                                unsigned size)
3108
{
3109
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3110
    int offset = addr & OMAP_MPUI_REG_MASK;
3111
    uint16_t ret;
3112

    
3113
    if (size != 2) {
3114
        return omap_badwidth_read16(opaque, addr);
3115
    }
3116

    
3117
    switch (offset) {
3118
    case 0x00:        /* DRR2 */
3119
        if (((s->rcr[0] >> 5) & 7) < 3)                        /* RWDLEN1 */
3120
            return 0x0000;
3121
        /* Fall through.  */
3122
    case 0x02:        /* DRR1 */
3123
        if (s->rx_req < 2) {
3124
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
3125
            omap_mcbsp_rx_done(s);
3126
        } else {
3127
            s->tx_req -= 2;
3128
            if (s->codec && s->codec->in.len >= 2) {
3129
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
3130
                ret |= s->codec->in.fifo[s->codec->in.start ++];
3131
                s->codec->in.len -= 2;
3132
            } else
3133
                ret = 0x0000;
3134
            if (!s->tx_req)
3135
                omap_mcbsp_rx_done(s);
3136
            return ret;
3137
        }
3138
        return 0x0000;
3139

    
3140
    case 0x04:        /* DXR2 */
3141
    case 0x06:        /* DXR1 */
3142
        return 0x0000;
3143

    
3144
    case 0x08:        /* SPCR2 */
3145
        return s->spcr[1];
3146
    case 0x0a:        /* SPCR1 */
3147
        return s->spcr[0];
3148
    case 0x0c:        /* RCR2 */
3149
        return s->rcr[1];
3150
    case 0x0e:        /* RCR1 */
3151
        return s->rcr[0];
3152
    case 0x10:        /* XCR2 */
3153
        return s->xcr[1];
3154
    case 0x12:        /* XCR1 */
3155
        return s->xcr[0];
3156
    case 0x14:        /* SRGR2 */
3157
        return s->srgr[1];
3158
    case 0x16:        /* SRGR1 */
3159
        return s->srgr[0];
3160
    case 0x18:        /* MCR2 */
3161
        return s->mcr[1];
3162
    case 0x1a:        /* MCR1 */
3163
        return s->mcr[0];
3164
    case 0x1c:        /* RCERA */
3165
        return s->rcer[0];
3166
    case 0x1e:        /* RCERB */
3167
        return s->rcer[1];
3168
    case 0x20:        /* XCERA */
3169
        return s->xcer[0];
3170
    case 0x22:        /* XCERB */
3171
        return s->xcer[1];
3172
    case 0x24:        /* PCR0 */
3173
        return s->pcr;
3174
    case 0x26:        /* RCERC */
3175
        return s->rcer[2];
3176
    case 0x28:        /* RCERD */
3177
        return s->rcer[3];
3178
    case 0x2a:        /* XCERC */
3179
        return s->xcer[2];
3180
    case 0x2c:        /* XCERD */
3181
        return s->xcer[3];
3182
    case 0x2e:        /* RCERE */
3183
        return s->rcer[4];
3184
    case 0x30:        /* RCERF */
3185
        return s->rcer[5];
3186
    case 0x32:        /* XCERE */
3187
        return s->xcer[4];
3188
    case 0x34:        /* XCERF */
3189
        return s->xcer[5];
3190
    case 0x36:        /* RCERG */
3191
        return s->rcer[6];
3192
    case 0x38:        /* RCERH */
3193
        return s->rcer[7];
3194
    case 0x3a:        /* XCERG */
3195
        return s->xcer[6];
3196
    case 0x3c:        /* XCERH */
3197
        return s->xcer[7];
3198
    }
3199

    
3200
    OMAP_BAD_REG(addr);
3201
    return 0;
3202
}
3203

    
3204
static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
3205
                uint32_t value)
3206
{
3207
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3208
    int offset = addr & OMAP_MPUI_REG_MASK;
3209

    
3210
    switch (offset) {
3211
    case 0x00:        /* DRR2 */
3212
    case 0x02:        /* DRR1 */
3213
        OMAP_RO_REG(addr);
3214
        return;
3215

    
3216
    case 0x04:        /* DXR2 */
3217
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
3218
            return;
3219
        /* Fall through.  */
3220
    case 0x06:        /* DXR1 */
3221
        if (s->tx_req > 1) {
3222
            s->tx_req -= 2;
3223
            if (s->codec && s->codec->cts) {
3224
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
3225
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
3226
            }
3227
            if (s->tx_req < 2)
3228
                omap_mcbsp_tx_done(s);
3229
        } else
3230
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3231
        return;
3232

    
3233
    case 0x08:        /* SPCR2 */
3234
        s->spcr[1] &= 0x0002;
3235
        s->spcr[1] |= 0x03f9 & value;
3236
        s->spcr[1] |= 0x0004 & (value << 2);                /* XEMPTY := XRST */
3237
        if (~value & 1)                                        /* XRST */
3238
            s->spcr[1] &= ~6;
3239
        omap_mcbsp_req_update(s);
3240
        return;
3241
    case 0x0a:        /* SPCR1 */
3242
        s->spcr[0] &= 0x0006;
3243
        s->spcr[0] |= 0xf8f9 & value;
3244
        if (value & (1 << 15))                                /* DLB */
3245
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
3246
        if (~value & 1) {                                /* RRST */
3247
            s->spcr[0] &= ~6;
3248
            s->rx_req = 0;
3249
            omap_mcbsp_rx_done(s);
3250
        }
3251
        omap_mcbsp_req_update(s);
3252
        return;
3253

    
3254
    case 0x0c:        /* RCR2 */
3255
        s->rcr[1] = value & 0xffff;
3256
        return;
3257
    case 0x0e:        /* RCR1 */
3258
        s->rcr[0] = value & 0x7fe0;
3259
        return;
3260
    case 0x10:        /* XCR2 */
3261
        s->xcr[1] = value & 0xffff;
3262
        return;
3263
    case 0x12:        /* XCR1 */
3264
        s->xcr[0] = value & 0x7fe0;
3265
        return;
3266
    case 0x14:        /* SRGR2 */
3267
        s->srgr[1] = value & 0xffff;
3268
        omap_mcbsp_req_update(s);
3269
        return;
3270
    case 0x16:        /* SRGR1 */
3271
        s->srgr[0] = value & 0xffff;
3272
        omap_mcbsp_req_update(s);
3273
        return;
3274
    case 0x18:        /* MCR2 */
3275
        s->mcr[1] = value & 0x03e3;
3276
        if (value & 3)                                        /* XMCM */
3277
            printf("%s: Tx channel selection mode enable attempt\n",
3278
                            __FUNCTION__);
3279
        return;
3280
    case 0x1a:        /* MCR1 */
3281
        s->mcr[0] = value & 0x03e1;
3282
        if (value & 1)                                        /* RMCM */
3283
            printf("%s: Rx channel selection mode enable attempt\n",
3284
                            __FUNCTION__);
3285
        return;
3286
    case 0x1c:        /* RCERA */
3287
        s->rcer[0] = value & 0xffff;
3288
        return;
3289
    case 0x1e:        /* RCERB */
3290
        s->rcer[1] = value & 0xffff;
3291
        return;
3292
    case 0x20:        /* XCERA */
3293
        s->xcer[0] = value & 0xffff;
3294
        return;
3295
    case 0x22:        /* XCERB */
3296
        s->xcer[1] = value & 0xffff;
3297
        return;
3298
    case 0x24:        /* PCR0 */
3299
        s->pcr = value & 0x7faf;
3300
        return;
3301
    case 0x26:        /* RCERC */
3302
        s->rcer[2] = value & 0xffff;
3303
        return;
3304
    case 0x28:        /* RCERD */
3305
        s->rcer[3] = value & 0xffff;
3306
        return;
3307
    case 0x2a:        /* XCERC */
3308
        s->xcer[2] = value & 0xffff;
3309
        return;
3310
    case 0x2c:        /* XCERD */
3311
        s->xcer[3] = value & 0xffff;
3312
        return;
3313
    case 0x2e:        /* RCERE */
3314
        s->rcer[4] = value & 0xffff;
3315
        return;
3316
    case 0x30:        /* RCERF */
3317
        s->rcer[5] = value & 0xffff;
3318
        return;
3319
    case 0x32:        /* XCERE */
3320
        s->xcer[4] = value & 0xffff;
3321
        return;
3322
    case 0x34:        /* XCERF */
3323
        s->xcer[5] = value & 0xffff;
3324
        return;
3325
    case 0x36:        /* RCERG */
3326
        s->rcer[6] = value & 0xffff;
3327
        return;
3328
    case 0x38:        /* RCERH */
3329
        s->rcer[7] = value & 0xffff;
3330
        return;
3331
    case 0x3a:        /* XCERG */
3332
        s->xcer[6] = value & 0xffff;
3333
        return;
3334
    case 0x3c:        /* XCERH */
3335
        s->xcer[7] = value & 0xffff;
3336
        return;
3337
    }
3338

    
3339
    OMAP_BAD_REG(addr);
3340
}
3341

    
3342
static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
3343
                uint32_t value)
3344
{
3345
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3346
    int offset = addr & OMAP_MPUI_REG_MASK;
3347

    
3348
    if (offset == 0x04) {                                /* DXR */
3349
        if (((s->xcr[0] >> 5) & 7) < 3)                        /* XWDLEN1 */
3350
            return;
3351
        if (s->tx_req > 3) {
3352
            s->tx_req -= 4;
3353
            if (s->codec && s->codec->cts) {
3354
                s->codec->out.fifo[s->codec->out.len ++] =
3355
                        (value >> 24) & 0xff;
3356
                s->codec->out.fifo[s->codec->out.len ++] =
3357
                        (value >> 16) & 0xff;
3358
                s->codec->out.fifo[s->codec->out.len ++] =
3359
                        (value >> 8) & 0xff;
3360
                s->codec->out.fifo[s->codec->out.len ++] =
3361
                        (value >> 0) & 0xff;
3362
            }
3363
            if (s->tx_req < 4)
3364
                omap_mcbsp_tx_done(s);
3365
        } else
3366
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
3367
        return;
3368
    }
3369

    
3370
    omap_badwidth_write16(opaque, addr, value);
3371
}
3372

    
3373
static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr,
3374
                             uint64_t value, unsigned size)
3375
{
3376
    switch (size) {
3377
    case 2: return omap_mcbsp_writeh(opaque, addr, value);
3378
    case 4: return omap_mcbsp_writew(opaque, addr, value);
3379
    default: return omap_badwidth_write16(opaque, addr, value);
3380
    }
3381
}
3382

    
3383
static const MemoryRegionOps omap_mcbsp_ops = {
3384
    .read = omap_mcbsp_read,
3385
    .write = omap_mcbsp_write,
3386
    .endianness = DEVICE_NATIVE_ENDIAN,
3387
};
3388

    
3389
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
3390
{
3391
    memset(&s->spcr, 0, sizeof(s->spcr));
3392
    memset(&s->rcr, 0, sizeof(s->rcr));
3393
    memset(&s->xcr, 0, sizeof(s->xcr));
3394
    s->srgr[0] = 0x0001;
3395
    s->srgr[1] = 0x2000;
3396
    memset(&s->mcr, 0, sizeof(s->mcr));
3397
    memset(&s->pcr, 0, sizeof(s->pcr));
3398
    memset(&s->rcer, 0, sizeof(s->rcer));
3399
    memset(&s->xcer, 0, sizeof(s->xcer));
3400
    s->tx_req = 0;
3401
    s->rx_req = 0;
3402
    s->tx_rate = 0;
3403
    s->rx_rate = 0;
3404
    qemu_del_timer(s->source_timer);
3405
    qemu_del_timer(s->sink_timer);
3406
}
3407

    
3408
static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
3409
                                            target_phys_addr_t base,
3410
                                            qemu_irq txirq, qemu_irq rxirq,
3411
                                            qemu_irq *dma, omap_clk clk)
3412
{
3413
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
3414
            g_malloc0(sizeof(struct omap_mcbsp_s));
3415

    
3416
    s->txirq = txirq;
3417
    s->rxirq = rxirq;
3418
    s->txdrq = dma[0];
3419
    s->rxdrq = dma[1];
3420
    s->sink_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_sink_tick, s);
3421
    s->source_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_source_tick, s);
3422
    omap_mcbsp_reset(s);
3423

    
3424
    memory_region_init_io(&s->iomem, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
3425
    memory_region_add_subregion(system_memory, base, &s->iomem);
3426

    
3427
    return s;
3428
}
3429

    
3430
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
3431
{
3432
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3433

    
3434
    if (s->rx_rate) {
3435
        s->rx_req = s->codec->in.len;
3436
        omap_mcbsp_rx_newdata(s);
3437
    }
3438
}
3439

    
3440
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
3441
{
3442
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
3443

    
3444
    if (s->tx_rate) {
3445
        s->tx_req = s->codec->out.size;
3446
        omap_mcbsp_tx_newdata(s);
3447
    }
3448
}
3449

    
3450
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
3451
{
3452
    s->codec = slave;
3453
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
3454
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
3455
}
3456

    
3457
/* LED Pulse Generators */
3458
struct omap_lpg_s {
3459
    MemoryRegion iomem;
3460
    QEMUTimer *tm;
3461

    
3462
    uint8_t control;
3463
    uint8_t power;
3464
    int64_t on;
3465
    int64_t period;
3466
    int clk;
3467
    int cycle;
3468
};
3469

    
3470
static void omap_lpg_tick(void *opaque)
3471
{
3472
    struct omap_lpg_s *s = opaque;
3473

    
3474
    if (s->cycle)
3475
        qemu_mod_timer(s->tm, qemu_get_clock_ms(rt_clock) + s->period - s->on);
3476
    else
3477
        qemu_mod_timer(s->tm, qemu_get_clock_ms(rt_clock) + s->on);
3478

    
3479
    s->cycle = !s->cycle;
3480
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
3481
}
3482

    
3483
static void omap_lpg_update(struct omap_lpg_s *s)
3484
{
3485
    int64_t on, period = 1, ticks = 1000;
3486
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
3487

    
3488
    if (~s->control & (1 << 6))                                        /* LPGRES */
3489
        on = 0;
3490
    else if (s->control & (1 << 7))                                /* PERM_ON */
3491
        on = period;
3492
    else {
3493
        period = muldiv64(ticks, per[s->control & 7],                /* PERCTRL */
3494
                        256 / 32);
3495
        on = (s->clk && s->power) ? muldiv64(ticks,
3496
                        per[(s->control >> 3) & 7], 256) : 0;        /* ONCTRL */
3497
    }
3498

    
3499
    qemu_del_timer(s->tm);
3500
    if (on == period && s->on < s->period)
3501
        printf("%s: LED is on\n", __FUNCTION__);
3502
    else if (on == 0 && s->on)
3503
        printf("%s: LED is off\n", __FUNCTION__);
3504
    else if (on && (on != s->on || period != s->period)) {
3505
        s->cycle = 0;
3506
        s->on = on;
3507
        s->period = period;
3508
        omap_lpg_tick(s);
3509
        return;
3510
    }
3511

    
3512
    s->on = on;
3513
    s->period = period;
3514
}
3515

    
3516
static void omap_lpg_reset(struct omap_lpg_s *s)
3517
{
3518
    s->control = 0x00;
3519
    s->power = 0x00;
3520
    s->clk = 1;
3521
    omap_lpg_update(s);
3522
}
3523

    
3524
static uint64_t omap_lpg_read(void *opaque, target_phys_addr_t addr,
3525
                              unsigned size)
3526
{
3527
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3528
    int offset = addr & OMAP_MPUI_REG_MASK;
3529

    
3530
    if (size != 1) {
3531
        return omap_badwidth_read8(opaque, addr);
3532
    }
3533

    
3534
    switch (offset) {
3535
    case 0x00:        /* LCR */
3536
        return s->control;
3537

    
3538
    case 0x04:        /* PMR */
3539
        return s->power;
3540
    }
3541

    
3542
    OMAP_BAD_REG(addr);
3543
    return 0;
3544
}
3545

    
3546
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
3547
                           uint64_t value, unsigned size)
3548
{
3549
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3550
    int offset = addr & OMAP_MPUI_REG_MASK;
3551

    
3552
    if (size != 1) {
3553
        return omap_badwidth_write8(opaque, addr, value);
3554
    }
3555

    
3556
    switch (offset) {
3557
    case 0x00:        /* LCR */
3558
        if (~value & (1 << 6))                                        /* LPGRES */
3559
            omap_lpg_reset(s);
3560
        s->control = value & 0xff;
3561
        omap_lpg_update(s);
3562
        return;
3563

    
3564
    case 0x04:        /* PMR */
3565
        s->power = value & 0x01;
3566
        omap_lpg_update(s);
3567
        return;
3568

    
3569
    default:
3570
        OMAP_BAD_REG(addr);
3571
        return;
3572
    }
3573
}
3574

    
3575
static const MemoryRegionOps omap_lpg_ops = {
3576
    .read = omap_lpg_read,
3577
    .write = omap_lpg_write,
3578
    .endianness = DEVICE_NATIVE_ENDIAN,
3579
};
3580

    
3581
static void omap_lpg_clk_update(void *opaque, int line, int on)
3582
{
3583
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
3584

    
3585
    s->clk = on;
3586
    omap_lpg_update(s);
3587
}
3588

    
3589
static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
3590
                                        target_phys_addr_t base, omap_clk clk)
3591
{
3592
    struct omap_lpg_s *s = (struct omap_lpg_s *)
3593
            g_malloc0(sizeof(struct omap_lpg_s));
3594

    
3595
    s->tm = qemu_new_timer_ms(rt_clock, omap_lpg_tick, s);
3596

    
3597
    omap_lpg_reset(s);
3598

    
3599
    memory_region_init_io(&s->iomem, &omap_lpg_ops, s, "omap-lpg", 0x800);
3600
    memory_region_add_subregion(system_memory, base, &s->iomem);
3601

    
3602
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
3603

    
3604
    return s;
3605
}
3606

    
3607
/* MPUI Peripheral Bridge configuration */
3608
static uint64_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr,
3609
                                  unsigned size)
3610
{
3611
    if (size != 2) {
3612
        return omap_badwidth_read16(opaque, addr);
3613
    }
3614

    
3615
    if (addr == OMAP_MPUI_BASE)        /* CMR */
3616
        return 0xfe4d;
3617

    
3618
    OMAP_BAD_REG(addr);
3619
    return 0;
3620
}
3621

    
3622
static void omap_mpui_io_write(void *opaque, target_phys_addr_t addr,
3623
                               uint64_t value, unsigned size)
3624
{
3625
    /* FIXME: infinite loop */
3626
    omap_badwidth_write16(opaque, addr, value);
3627
}
3628

    
3629
static const MemoryRegionOps omap_mpui_io_ops = {
3630
    .read = omap_mpui_io_read,
3631
    .write = omap_mpui_io_write,
3632
    .endianness = DEVICE_NATIVE_ENDIAN,
3633
};
3634

    
3635
static void omap_setup_mpui_io(MemoryRegion *system_memory,
3636
                               struct omap_mpu_state_s *mpu)
3637
{
3638
    memory_region_init_io(&mpu->mpui_io_iomem, &omap_mpui_io_ops, mpu,
3639
                          "omap-mpui-io", 0x7fff);
3640
    memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
3641
                                &mpu->mpui_io_iomem);
3642
}
3643

    
3644
/* General chip reset */
3645
static void omap1_mpu_reset(void *opaque)
3646
{
3647
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3648

    
3649
    omap_dma_reset(mpu->dma);
3650
    omap_mpu_timer_reset(mpu->timer[0]);
3651
    omap_mpu_timer_reset(mpu->timer[1]);
3652
    omap_mpu_timer_reset(mpu->timer[2]);
3653
    omap_wd_timer_reset(mpu->wdt);
3654
    omap_os_timer_reset(mpu->os_timer);
3655
    omap_lcdc_reset(mpu->lcd);
3656
    omap_ulpd_pm_reset(mpu);
3657
    omap_pin_cfg_reset(mpu);
3658
    omap_mpui_reset(mpu);
3659
    omap_tipb_bridge_reset(mpu->private_tipb);
3660
    omap_tipb_bridge_reset(mpu->public_tipb);
3661
    omap_dpll_reset(&mpu->dpll[0]);
3662
    omap_dpll_reset(&mpu->dpll[1]);
3663
    omap_dpll_reset(&mpu->dpll[2]);
3664
    omap_uart_reset(mpu->uart[0]);
3665
    omap_uart_reset(mpu->uart[1]);
3666
    omap_uart_reset(mpu->uart[2]);
3667
    omap_mmc_reset(mpu->mmc);
3668
    omap_mpuio_reset(mpu->mpuio);
3669
    omap_uwire_reset(mpu->microwire);
3670
    omap_pwl_reset(mpu);
3671
    omap_pwt_reset(mpu);
3672
    omap_i2c_reset(mpu->i2c[0]);
3673
    omap_rtc_reset(mpu->rtc);
3674
    omap_mcbsp_reset(mpu->mcbsp1);
3675
    omap_mcbsp_reset(mpu->mcbsp2);
3676
    omap_mcbsp_reset(mpu->mcbsp3);
3677
    omap_lpg_reset(mpu->led[0]);
3678
    omap_lpg_reset(mpu->led[1]);
3679
    omap_clkm_reset(mpu);
3680
    cpu_reset(mpu->env);
3681
}
3682

    
3683
static const struct omap_map_s {
3684
    target_phys_addr_t phys_dsp;
3685
    target_phys_addr_t phys_mpu;
3686
    uint32_t size;
3687
    const char *name;
3688
} omap15xx_dsp_mm[] = {
3689
    /* Strobe 0 */
3690
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },                /* CS0 */
3691
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },                /* CS1 */
3692
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },                /* CS3 */
3693
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },        /* CS4 */
3694
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
3695
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                        /* CS6 */
3696
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                        /* CS7 */
3697
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },                /* CS8 */
3698
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                        /* CS9 */
3699
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                        /* CS10 */
3700
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                        /* CS11 */
3701
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                        /* CS12 */
3702
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
3703
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                        /* CS15 */
3704
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },                /* CS18 */
3705
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                        /* CS19 */
3706
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },                /* CS25 */
3707
    /* Strobe 1 */
3708
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                        /* CS28 */
3709

    
3710
    { 0 }
3711
};
3712

    
3713
static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
3714
                                   const struct omap_map_s *map)
3715
{
3716
    MemoryRegion *io;
3717

    
3718
    for (; map->phys_dsp; map ++) {
3719
        io = g_new(MemoryRegion, 1);
3720
        memory_region_init_alias(io, map->name,
3721
                                 system_memory, map->phys_mpu, map->size);
3722
        memory_region_add_subregion(system_memory, map->phys_dsp, io);
3723
    }
3724
}
3725

    
3726
void omap_mpu_wakeup(void *opaque, int irq, int req)
3727
{
3728
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3729

    
3730
    if (mpu->env->halted)
3731
        cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
3732
}
3733

    
3734
static const struct dma_irq_map omap1_dma_irq_map[] = {
3735
    { 0, OMAP_INT_DMA_CH0_6 },
3736
    { 0, OMAP_INT_DMA_CH1_7 },
3737
    { 0, OMAP_INT_DMA_CH2_8 },
3738
    { 0, OMAP_INT_DMA_CH3 },
3739
    { 0, OMAP_INT_DMA_CH4 },
3740
    { 0, OMAP_INT_DMA_CH5 },
3741
    { 1, OMAP_INT_1610_DMA_CH6 },
3742
    { 1, OMAP_INT_1610_DMA_CH7 },
3743
    { 1, OMAP_INT_1610_DMA_CH8 },
3744
    { 1, OMAP_INT_1610_DMA_CH9 },
3745
    { 1, OMAP_INT_1610_DMA_CH10 },
3746
    { 1, OMAP_INT_1610_DMA_CH11 },
3747
    { 1, OMAP_INT_1610_DMA_CH12 },
3748
    { 1, OMAP_INT_1610_DMA_CH13 },
3749
    { 1, OMAP_INT_1610_DMA_CH14 },
3750
    { 1, OMAP_INT_1610_DMA_CH15 }
3751
};
3752

    
3753
/* DMA ports for OMAP1 */
3754
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
3755
                target_phys_addr_t addr)
3756
{
3757
    return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
3758
}
3759

    
3760
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
3761
                target_phys_addr_t addr)
3762
{
3763
    return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
3764
                             addr);
3765
}
3766

    
3767
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
3768
                target_phys_addr_t addr)
3769
{
3770
    return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
3771
}
3772

    
3773
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
3774
                target_phys_addr_t addr)
3775
{
3776
    return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
3777
}
3778

    
3779
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
3780
                target_phys_addr_t addr)
3781
{
3782
    return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
3783
}
3784

    
3785
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
3786
                target_phys_addr_t addr)
3787
{
3788
    return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
3789
}
3790

    
3791
struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
3792
                unsigned long sdram_size,
3793
                const char *core)
3794
{
3795
    int i;
3796
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
3797
            g_malloc0(sizeof(struct omap_mpu_state_s));
3798
    qemu_irq *cpu_irq;
3799
    qemu_irq dma_irqs[6];
3800
    DriveInfo *dinfo;
3801
    SysBusDevice *busdev;
3802

    
3803
    if (!core)
3804
        core = "ti925t";
3805

    
3806
    /* Core */
3807
    s->mpu_model = omap310;
3808
    s->env = cpu_init(core);
3809
    if (!s->env) {
3810
        fprintf(stderr, "Unable to find CPU definition\n");
3811
        exit(1);
3812
    }
3813
    s->sdram_size = sdram_size;
3814
    s->sram_size = OMAP15XX_SRAM_SIZE;
3815

    
3816
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3817

    
3818
    /* Clocks */
3819
    omap_clk_init(s);
3820

    
3821
    /* Memory-mapped stuff */
3822
    memory_region_init_ram(&s->emiff_ram, NULL, "omap1.dram", s->sdram_size);
3823
    memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
3824
    memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size);
3825
    memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
3826

    
3827
    omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
3828

    
3829
    cpu_irq = arm_pic_init_cpu(s->env);
3830
    s->ih[0] = qdev_create(NULL, "omap-intc");
3831
    qdev_prop_set_uint32(s->ih[0], "size", 0x100);
3832
    qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
3833
    qdev_init_nofail(s->ih[0]);
3834
    busdev = sysbus_from_qdev(s->ih[0]);
3835
    sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
3836
    sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
3837
    sysbus_mmio_map(busdev, 0, 0xfffecb00);
3838
    s->ih[1] = qdev_create(NULL, "omap-intc");
3839
    qdev_prop_set_uint32(s->ih[1], "size", 0x800);
3840
    qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
3841
    qdev_init_nofail(s->ih[1]);
3842
    busdev = sysbus_from_qdev(s->ih[1]);
3843
    sysbus_connect_irq(busdev, 0,
3844
                       qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
3845
    /* The second interrupt controller's FIQ output is not wired up */
3846
    sysbus_mmio_map(busdev, 0, 0xfffe0000);
3847

    
3848
    for (i = 0; i < 6; i++) {
3849
        dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
3850
                                       omap1_dma_irq_map[i].intr);
3851
    }
3852
    s->dma = omap_dma_init(0xfffed800, dma_irqs,
3853
                           qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
3854
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
3855

    
3856
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
3857
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
3858
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
3859
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
3860
    s->port[local    ].addr_valid = omap_validate_local_addr;
3861
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
3862

    
3863
    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
3864
    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram),
3865
                         OMAP_EMIFF_BASE, s->sdram_size);
3866
    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
3867
                         OMAP_IMIF_BASE, s->sram_size);
3868

    
3869
    s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
3870
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
3871
                    omap_findclk(s, "mputim_ck"));
3872
    s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
3873
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
3874
                    omap_findclk(s, "mputim_ck"));
3875
    s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
3876
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
3877
                    omap_findclk(s, "mputim_ck"));
3878

    
3879
    s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
3880
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
3881
                    omap_findclk(s, "armwdt_ck"));
3882

    
3883
    s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
3884
                    qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
3885
                    omap_findclk(s, "clk32-kHz"));
3886

    
3887
    s->lcd = omap_lcdc_init(0xfffec000,
3888
                            qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
3889
                            omap_dma_get_lcdch(s->dma),
3890
                            omap_findclk(s, "lcd_ck"));
3891

    
3892
    omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
3893
    omap_pin_cfg_init(system_memory, 0xfffe1000, s);
3894
    omap_id_init(system_memory, s);
3895

    
3896
    omap_mpui_init(system_memory, 0xfffec900, s);
3897

    
3898
    s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
3899
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
3900
                    omap_findclk(s, "tipb_ck"));
3901
    s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
3902
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
3903
                    omap_findclk(s, "tipb_ck"));
3904

    
3905
    omap_tcmi_init(system_memory, 0xfffecc00, s);
3906

    
3907
    s->uart[0] = omap_uart_init(0xfffb0000,
3908
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
3909
                    omap_findclk(s, "uart1_ck"),
3910
                    omap_findclk(s, "uart1_ck"),
3911
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
3912
                    "uart1",
3913
                    serial_hds[0]);
3914
    s->uart[1] = omap_uart_init(0xfffb0800,
3915
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
3916
                    omap_findclk(s, "uart2_ck"),
3917
                    omap_findclk(s, "uart2_ck"),
3918
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
3919
                    "uart2",
3920
                    serial_hds[0] ? serial_hds[1] : NULL);
3921
    s->uart[2] = omap_uart_init(0xfffb9800,
3922
                                qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
3923
                    omap_findclk(s, "uart3_ck"),
3924
                    omap_findclk(s, "uart3_ck"),
3925
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
3926
                    "uart3",
3927
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
3928

    
3929
    omap_dpll_init(system_memory,
3930
                   &s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
3931
    omap_dpll_init(system_memory,
3932
                   &s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
3933
    omap_dpll_init(system_memory,
3934
                   &s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
3935

    
3936
    dinfo = drive_get(IF_SD, 0, 0);
3937
    if (!dinfo) {
3938
        fprintf(stderr, "qemu: missing SecureDigital device\n");
3939
        exit(1);
3940
    }
3941
    s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv,
3942
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
3943
                           &s->drq[OMAP_DMA_MMC_TX],
3944
                    omap_findclk(s, "mmc_ck"));
3945

    
3946
    s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
3947
                               qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD),
3948
                               qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO),
3949
                               s->wakeup, omap_findclk(s, "clk32-kHz"));
3950

    
3951
    s->gpio = qdev_create(NULL, "omap-gpio");
3952
    qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
3953
    qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
3954
    qdev_init_nofail(s->gpio);
3955
    sysbus_connect_irq(sysbus_from_qdev(s->gpio), 0,
3956
                       qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
3957
    sysbus_mmio_map(sysbus_from_qdev(s->gpio), 0, 0xfffce000);
3958

    
3959
    s->microwire = omap_uwire_init(system_memory, 0xfffb3000,
3960
                                   qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX),
3961
                                   qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX),
3962
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
3963

    
3964
    omap_pwl_init(system_memory, 0xfffb5800, s, omap_findclk(s, "armxor_ck"));
3965
    omap_pwt_init(system_memory, 0xfffb6000, s, omap_findclk(s, "armxor_ck"));
3966

    
3967
    s->i2c[0] = omap_i2c_init(0xfffb3800,
3968
                              qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C),
3969
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
3970

    
3971
    s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
3972
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
3973
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
3974
                    omap_findclk(s, "clk32-kHz"));
3975

    
3976
    s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
3977
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
3978
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
3979
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
3980
    s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
3981
                                qdev_get_gpio_in(s->ih[0],
3982
                                                 OMAP_INT_310_McBSP2_TX),
3983
                                qdev_get_gpio_in(s->ih[0],
3984
                                                 OMAP_INT_310_McBSP2_RX),
3985
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
3986
    s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
3987
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
3988
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
3989
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
3990

    
3991
    s->led[0] = omap_lpg_init(system_memory,
3992
                              0xfffbd000, omap_findclk(s, "clk32-kHz"));
3993
    s->led[1] = omap_lpg_init(system_memory,
3994
                              0xfffbd800, omap_findclk(s, "clk32-kHz"));
3995

    
3996
    /* Register mappings not currenlty implemented:
3997
     * MCSI2 Comm        fffb2000 - fffb27ff (not mapped on OMAP310)
3998
     * MCSI1 Bluetooth        fffb2800 - fffb2fff (not mapped on OMAP310)
3999
     * USB W2FC                fffb4000 - fffb47ff
4000
     * Camera Interface        fffb6800 - fffb6fff
4001
     * USB Host                fffba000 - fffba7ff
4002
     * FAC                fffba800 - fffbafff
4003
     * HDQ/1-Wire        fffbc000 - fffbc7ff
4004
     * TIPB switches        fffbc800 - fffbcfff
4005
     * Mailbox                fffcf000 - fffcf7ff
4006
     * Local bus IF        fffec100 - fffec1ff
4007
     * Local bus MMU        fffec200 - fffec2ff
4008
     * DSP MMU                fffed200 - fffed2ff
4009
     */
4010

    
4011
    omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
4012
    omap_setup_mpui_io(system_memory, s);
4013

    
4014
    qemu_register_reset(omap1_mpu_reset, s);
4015

    
4016
    return s;
4017
}