~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/ubuntu/linaro/0033-omap_uart-updates.patch/hw/arm/omap1.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-04 12:13:08 UTC
  • mfrom: (10.1.45 sid)
  • Revision ID: package-import@ubuntu.com-20140204121308-1xq92lrfs75agw2g
Tags: 1.7.0+dfsg-3ubuntu1~ppa1
* Merge 1.7.0+dfsg-3 from debian.  Remaining changes:
  - debian/patches/ubuntu:
    * expose-vmx_qemu64cpu.patch
    * linaro (omap3) and arm64 patches
    * ubuntu/target-ppc-add-stubs-for-kvm-breakpoints: fix FTBFS
      on ppc
    * ubuntu/CVE-2013-4377.patch: fix denial of service via virtio
  - debian/qemu-system-x86.modprobe: set kvm_intel nested=1 options
  - debian/control:
    * add arm64 to Architectures
    * add qemu-common and qemu-system-aarch64 packages
  - debian/qemu-system-common.install: add debian/tmp/usr/lib
  - debian/qemu-system-common.preinst: add kvm group
  - debian/qemu-system-common.postinst: remove acl placed by udev,
    and add udevadm trigger.
  - qemu-system-x86.links: add eepro100.rom, remove pxe-virtio,
    pxe-e1000 and pxe-rtl8139.
  - add qemu-system-x86.qemu-kvm.upstart and .default
  - qemu-user-static.postinst-in: remove arm64 binfmt
  - debian/rules:
    * allow parallel build
    * add aarch64 to system_targets and sys_systems
    * add qemu-kvm-spice links
    * install qemu-system-x86.modprobe
  - add debian/qemu-system-common.links for OVMF.fd link
* Remove kvm-img, kvm-nbd, kvm-ifup and kvm-ifdown symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * TI OMAP processors emulation.
 
3
 *
 
4
 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License as
 
8
 * published by the Free Software Foundation; either version 2 or
 
9
 * (at your option) version 3 of the License.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License along
 
17
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
#include "hw/hw.h"
 
20
#include "hw/arm/arm.h"
 
21
#include "hw/arm/omap.h"
 
22
#include "sysemu/sysemu.h"
 
23
#include "hw/arm/soc_dma.h"
 
24
#include "sysemu/blockdev.h"
 
25
#include "qemu/range.h"
 
26
#include "hw/sysbus.h"
 
27
 
 
28
/* Should signal the TCMI/GPMC */
 
29
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
 
30
{
 
31
    uint8_t ret;
 
32
 
 
33
    OMAP_8B_REG(addr);
 
34
    cpu_physical_memory_read(addr, &ret, 1);
 
35
    return ret;
 
36
}
 
37
 
 
38
void omap_badwidth_write8(void *opaque, hwaddr addr,
 
39
                uint32_t value)
 
40
{
 
41
    uint8_t val8 = value;
 
42
 
 
43
    OMAP_8B_REG(addr);
 
44
    cpu_physical_memory_write(addr, &val8, 1);
 
45
}
 
46
 
 
47
uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
 
48
{
 
49
    uint16_t ret;
 
50
 
 
51
    OMAP_16B_REG(addr);
 
52
    cpu_physical_memory_read(addr, &ret, 2);
 
53
    return ret;
 
54
}
 
55
 
 
56
void omap_badwidth_write16(void *opaque, hwaddr addr,
 
57
                uint32_t value)
 
58
{
 
59
    uint16_t val16 = value;
 
60
 
 
61
    OMAP_16B_REG(addr);
 
62
    cpu_physical_memory_write(addr, &val16, 2);
 
63
}
 
64
 
 
65
uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
 
66
{
 
67
    uint32_t ret;
 
68
 
 
69
    OMAP_32B_REG(addr);
 
70
    cpu_physical_memory_read(addr, &ret, 4);
 
71
    return ret;
 
72
}
 
73
 
 
74
void omap_badwidth_write32(void *opaque, hwaddr addr,
 
75
                uint32_t value)
 
76
{
 
77
    OMAP_32B_REG(addr);
 
78
    cpu_physical_memory_write(addr, &value, 4);
 
79
}
 
80
 
 
81
/* MPU OS timers */
 
82
struct omap_mpu_timer_s {
 
83
    MemoryRegion iomem;
 
84
    qemu_irq irq;
 
85
    omap_clk clk;
 
86
    uint32_t val;
 
87
    int64_t time;
 
88
    QEMUTimer *timer;
 
89
    QEMUBH *tick;
 
90
    int64_t rate;
 
91
    int it_ena;
 
92
 
 
93
    int enable;
 
94
    int ptv;
 
95
    int ar;
 
96
    int st;
 
97
    uint32_t reset_val;
 
98
};
 
99
 
 
100
static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
 
101
{
 
102
    uint64_t distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
 
103
 
 
104
    if (timer->st && timer->enable && timer->rate)
 
105
        return timer->val - muldiv64(distance >> (timer->ptv + 1),
 
106
                                     timer->rate, get_ticks_per_sec());
 
107
    else
 
108
        return timer->val;
 
109
}
 
110
 
 
111
static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
 
112
{
 
113
    timer->val = omap_timer_read(timer);
 
114
    timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
115
}
 
116
 
 
117
static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
 
118
{
 
119
    int64_t expires;
 
120
 
 
121
    if (timer->enable && timer->st && timer->rate) {
 
122
        timer->val = timer->reset_val;  /* Should skip this on clk enable */
 
123
        expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
 
124
                           get_ticks_per_sec(), timer->rate);
 
125
 
 
126
        /* If timer expiry would be sooner than in about 1 ms and
 
127
         * auto-reload isn't set, then fire immediately.  This is a hack
 
128
         * to make systems like PalmOS run in acceptable time.  PalmOS
 
129
         * sets the interval to a very low value and polls the status bit
 
130
         * in a busy loop when it wants to sleep just a couple of CPU
 
131
         * ticks.  */
 
132
        if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
 
133
            timer_mod(timer->timer, timer->time + expires);
 
134
        else
 
135
            qemu_bh_schedule(timer->tick);
 
136
    } else
 
137
        timer_del(timer->timer);
 
138
}
 
139
 
 
140
static void omap_timer_fire(void *opaque)
 
141
{
 
142
    struct omap_mpu_timer_s *timer = opaque;
 
143
 
 
144
    if (!timer->ar) {
 
145
        timer->val = 0;
 
146
        timer->st = 0;
 
147
    }
 
148
 
 
149
    if (timer->it_ena)
 
150
        /* Edge-triggered irq */
 
151
        qemu_irq_pulse(timer->irq);
 
152
}
 
153
 
 
154
static void omap_timer_tick(void *opaque)
 
155
{
 
156
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
 
157
 
 
158
    omap_timer_sync(timer);
 
159
    omap_timer_fire(timer);
 
160
    omap_timer_update(timer);
 
161
}
 
162
 
 
163
static void omap_timer_clk_update(void *opaque, int line, int on)
 
164
{
 
165
    struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
 
166
 
 
167
    omap_timer_sync(timer);
 
168
    timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
 
169
    omap_timer_update(timer);
 
170
}
 
171
 
 
172
static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
 
173
{
 
174
    omap_clk_adduser(timer->clk,
 
175
                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
 
176
    timer->rate = omap_clk_getrate(timer->clk);
 
177
}
 
178
 
 
179
static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
 
180
                                    unsigned size)
 
181
{
 
182
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
 
183
 
 
184
    if (size != 4) {
 
185
        return omap_badwidth_read32(opaque, addr);
 
186
    }
 
187
 
 
188
    switch (addr) {
 
189
    case 0x00:  /* CNTL_TIMER */
 
190
        return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
 
191
 
 
192
    case 0x04:  /* LOAD_TIM */
 
193
        break;
 
194
 
 
195
    case 0x08:  /* READ_TIM */
 
196
        return omap_timer_read(s);
 
197
    }
 
198
 
 
199
    OMAP_BAD_REG(addr);
 
200
    return 0;
 
201
}
 
202
 
 
203
static void omap_mpu_timer_write(void *opaque, hwaddr addr,
 
204
                                 uint64_t value, unsigned size)
 
205
{
 
206
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
 
207
 
 
208
    if (size != 4) {
 
209
        return omap_badwidth_write32(opaque, addr, value);
 
210
    }
 
211
 
 
212
    switch (addr) {
 
213
    case 0x00:  /* CNTL_TIMER */
 
214
        omap_timer_sync(s);
 
215
        s->enable = (value >> 5) & 1;
 
216
        s->ptv = (value >> 2) & 7;
 
217
        s->ar = (value >> 1) & 1;
 
218
        s->st = value & 1;
 
219
        omap_timer_update(s);
 
220
        return;
 
221
 
 
222
    case 0x04:  /* LOAD_TIM */
 
223
        s->reset_val = value;
 
224
        return;
 
225
 
 
226
    case 0x08:  /* READ_TIM */
 
227
        OMAP_RO_REG(addr);
 
228
        break;
 
229
 
 
230
    default:
 
231
        OMAP_BAD_REG(addr);
 
232
    }
 
233
}
 
234
 
 
235
static const MemoryRegionOps omap_mpu_timer_ops = {
 
236
    .read = omap_mpu_timer_read,
 
237
    .write = omap_mpu_timer_write,
 
238
    .endianness = DEVICE_LITTLE_ENDIAN,
 
239
};
 
240
 
 
241
static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
 
242
{
 
243
    timer_del(s->timer);
 
244
    s->enable = 0;
 
245
    s->reset_val = 31337;
 
246
    s->val = 0;
 
247
    s->ptv = 0;
 
248
    s->ar = 0;
 
249
    s->st = 0;
 
250
    s->it_ena = 1;
 
251
}
 
252
 
 
253
static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
 
254
                hwaddr base,
 
255
                qemu_irq irq, omap_clk clk)
 
256
{
 
257
    struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
 
258
            g_malloc0(sizeof(struct omap_mpu_timer_s));
 
259
 
 
260
    s->irq = irq;
 
261
    s->clk = clk;
 
262
    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, s);
 
263
    s->tick = qemu_bh_new(omap_timer_fire, s);
 
264
    omap_mpu_timer_reset(s);
 
265
    omap_timer_clk_setup(s);
 
266
 
 
267
    memory_region_init_io(&s->iomem, NULL, &omap_mpu_timer_ops, s,
 
268
                          "omap-mpu-timer", 0x100);
 
269
 
 
270
    memory_region_add_subregion(system_memory, base, &s->iomem);
 
271
 
 
272
    return s;
 
273
}
 
274
 
 
275
/* Watchdog timer */
 
276
struct omap_watchdog_timer_s {
 
277
    struct omap_mpu_timer_s timer;
 
278
    MemoryRegion iomem;
 
279
    uint8_t last_wr;
 
280
    int mode;
 
281
    int free;
 
282
    int reset;
 
283
};
 
284
 
 
285
static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
 
286
                                   unsigned size)
 
287
{
 
288
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
 
289
 
 
290
    if (size != 2) {
 
291
        return omap_badwidth_read16(opaque, addr);
 
292
    }
 
293
 
 
294
    switch (addr) {
 
295
    case 0x00:  /* CNTL_TIMER */
 
296
        return (s->timer.ptv << 9) | (s->timer.ar << 8) |
 
297
                (s->timer.st << 7) | (s->free << 1);
 
298
 
 
299
    case 0x04:  /* READ_TIMER */
 
300
        return omap_timer_read(&s->timer);
 
301
 
 
302
    case 0x08:  /* TIMER_MODE */
 
303
        return s->mode << 15;
 
304
    }
 
305
 
 
306
    OMAP_BAD_REG(addr);
 
307
    return 0;
 
308
}
 
309
 
 
310
static void omap_wd_timer_write(void *opaque, hwaddr addr,
 
311
                                uint64_t value, unsigned size)
 
312
{
 
313
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
 
314
 
 
315
    if (size != 2) {
 
316
        return omap_badwidth_write16(opaque, addr, value);
 
317
    }
 
318
 
 
319
    switch (addr) {
 
320
    case 0x00:  /* CNTL_TIMER */
 
321
        omap_timer_sync(&s->timer);
 
322
        s->timer.ptv = (value >> 9) & 7;
 
323
        s->timer.ar = (value >> 8) & 1;
 
324
        s->timer.st = (value >> 7) & 1;
 
325
        s->free = (value >> 1) & 1;
 
326
        omap_timer_update(&s->timer);
 
327
        break;
 
328
 
 
329
    case 0x04:  /* LOAD_TIMER */
 
330
        s->timer.reset_val = value & 0xffff;
 
331
        break;
 
332
 
 
333
    case 0x08:  /* TIMER_MODE */
 
334
        if (!s->mode && ((value >> 15) & 1))
 
335
            omap_clk_get(s->timer.clk);
 
336
        s->mode |= (value >> 15) & 1;
 
337
        if (s->last_wr == 0xf5) {
 
338
            if ((value & 0xff) == 0xa0) {
 
339
                if (s->mode) {
 
340
                    s->mode = 0;
 
341
                    omap_clk_put(s->timer.clk);
 
342
                }
 
343
            } else {
 
344
                /* XXX: on T|E hardware somehow this has no effect,
 
345
                 * on Zire 71 it works as specified.  */
 
346
                s->reset = 1;
 
347
                qemu_system_reset_request();
 
348
            }
 
349
        }
 
350
        s->last_wr = value & 0xff;
 
351
        break;
 
352
 
 
353
    default:
 
354
        OMAP_BAD_REG(addr);
 
355
    }
 
356
}
 
357
 
 
358
static const MemoryRegionOps omap_wd_timer_ops = {
 
359
    .read = omap_wd_timer_read,
 
360
    .write = omap_wd_timer_write,
 
361
    .endianness = DEVICE_NATIVE_ENDIAN,
 
362
};
 
363
 
 
364
static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
 
365
{
 
366
    timer_del(s->timer.timer);
 
367
    if (!s->mode)
 
368
        omap_clk_get(s->timer.clk);
 
369
    s->mode = 1;
 
370
    s->free = 1;
 
371
    s->reset = 0;
 
372
    s->timer.enable = 1;
 
373
    s->timer.it_ena = 1;
 
374
    s->timer.reset_val = 0xffff;
 
375
    s->timer.val = 0;
 
376
    s->timer.st = 0;
 
377
    s->timer.ptv = 0;
 
378
    s->timer.ar = 0;
 
379
    omap_timer_update(&s->timer);
 
380
}
 
381
 
 
382
static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
 
383
                hwaddr base,
 
384
                qemu_irq irq, omap_clk clk)
 
385
{
 
386
    struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
 
387
            g_malloc0(sizeof(struct omap_watchdog_timer_s));
 
388
 
 
389
    s->timer.irq = irq;
 
390
    s->timer.clk = clk;
 
391
    s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
 
392
    omap_wd_timer_reset(s);
 
393
    omap_timer_clk_setup(&s->timer);
 
394
 
 
395
    memory_region_init_io(&s->iomem, NULL, &omap_wd_timer_ops, s,
 
396
                          "omap-wd-timer", 0x100);
 
397
    memory_region_add_subregion(memory, base, &s->iomem);
 
398
 
 
399
    return s;
 
400
}
 
401
 
 
402
/* 32-kHz timer */
 
403
struct omap_32khz_timer_s {
 
404
    struct omap_mpu_timer_s timer;
 
405
    MemoryRegion iomem;
 
406
};
 
407
 
 
408
static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
 
409
                                   unsigned size)
 
410
{
 
411
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
 
412
    int offset = addr & OMAP_MPUI_REG_MASK;
 
413
 
 
414
    if (size != 4) {
 
415
        return omap_badwidth_read32(opaque, addr);
 
416
    }
 
417
 
 
418
    switch (offset) {
 
419
    case 0x00:  /* TVR */
 
420
        return s->timer.reset_val;
 
421
 
 
422
    case 0x04:  /* TCR */
 
423
        return omap_timer_read(&s->timer);
 
424
 
 
425
    case 0x08:  /* CR */
 
426
        return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
 
427
 
 
428
    default:
 
429
        break;
 
430
    }
 
431
    OMAP_BAD_REG(addr);
 
432
    return 0;
 
433
}
 
434
 
 
435
static void omap_os_timer_write(void *opaque, hwaddr addr,
 
436
                                uint64_t value, unsigned size)
 
437
{
 
438
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
 
439
    int offset = addr & OMAP_MPUI_REG_MASK;
 
440
 
 
441
    if (size != 4) {
 
442
        return omap_badwidth_write32(opaque, addr, value);
 
443
    }
 
444
 
 
445
    switch (offset) {
 
446
    case 0x00:  /* TVR */
 
447
        s->timer.reset_val = value & 0x00ffffff;
 
448
        break;
 
449
 
 
450
    case 0x04:  /* TCR */
 
451
        OMAP_RO_REG(addr);
 
452
        break;
 
453
 
 
454
    case 0x08:  /* CR */
 
455
        s->timer.ar = (value >> 3) & 1;
 
456
        s->timer.it_ena = (value >> 2) & 1;
 
457
        if (s->timer.st != (value & 1) || (value & 2)) {
 
458
            omap_timer_sync(&s->timer);
 
459
            s->timer.enable = value & 1;
 
460
            s->timer.st = value & 1;
 
461
            omap_timer_update(&s->timer);
 
462
        }
 
463
        break;
 
464
 
 
465
    default:
 
466
        OMAP_BAD_REG(addr);
 
467
    }
 
468
}
 
469
 
 
470
static const MemoryRegionOps omap_os_timer_ops = {
 
471
    .read = omap_os_timer_read,
 
472
    .write = omap_os_timer_write,
 
473
    .endianness = DEVICE_NATIVE_ENDIAN,
 
474
};
 
475
 
 
476
static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
 
477
{
 
478
    timer_del(s->timer.timer);
 
479
    s->timer.enable = 0;
 
480
    s->timer.it_ena = 0;
 
481
    s->timer.reset_val = 0x00ffffff;
 
482
    s->timer.val = 0;
 
483
    s->timer.st = 0;
 
484
    s->timer.ptv = 0;
 
485
    s->timer.ar = 1;
 
486
}
 
487
 
 
488
static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
 
489
                hwaddr base,
 
490
                qemu_irq irq, omap_clk clk)
 
491
{
 
492
    struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
 
493
            g_malloc0(sizeof(struct omap_32khz_timer_s));
 
494
 
 
495
    s->timer.irq = irq;
 
496
    s->timer.clk = clk;
 
497
    s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
 
498
    omap_os_timer_reset(s);
 
499
    omap_timer_clk_setup(&s->timer);
 
500
 
 
501
    memory_region_init_io(&s->iomem, NULL, &omap_os_timer_ops, s,
 
502
                          "omap-os-timer", 0x800);
 
503
    memory_region_add_subregion(memory, base, &s->iomem);
 
504
 
 
505
    return s;
 
506
}
 
507
 
 
508
/* Ultra Low-Power Device Module */
 
509
static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
 
510
                                  unsigned size)
 
511
{
 
512
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
513
    uint16_t ret;
 
514
 
 
515
    if (size != 2) {
 
516
        return omap_badwidth_read16(opaque, addr);
 
517
    }
 
518
 
 
519
    switch (addr) {
 
520
    case 0x14:  /* IT_STATUS */
 
521
        ret = s->ulpd_pm_regs[addr >> 2];
 
522
        s->ulpd_pm_regs[addr >> 2] = 0;
 
523
        qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
 
524
        return ret;
 
525
 
 
526
    case 0x18:  /* Reserved */
 
527
    case 0x1c:  /* Reserved */
 
528
    case 0x20:  /* Reserved */
 
529
    case 0x28:  /* Reserved */
 
530
    case 0x2c:  /* Reserved */
 
531
        OMAP_BAD_REG(addr);
 
532
        /* fall through */
 
533
    case 0x00:  /* COUNTER_32_LSB */
 
534
    case 0x04:  /* COUNTER_32_MSB */
 
535
    case 0x08:  /* COUNTER_HIGH_FREQ_LSB */
 
536
    case 0x0c:  /* COUNTER_HIGH_FREQ_MSB */
 
537
    case 0x10:  /* GAUGING_CTRL */
 
538
    case 0x24:  /* SETUP_ANALOG_CELL3_ULPD1 */
 
539
    case 0x30:  /* CLOCK_CTRL */
 
540
    case 0x34:  /* SOFT_REQ */
 
541
    case 0x38:  /* COUNTER_32_FIQ */
 
542
    case 0x3c:  /* DPLL_CTRL */
 
543
    case 0x40:  /* STATUS_REQ */
 
544
        /* XXX: check clk::usecount state for every clock */
 
545
    case 0x48:  /* LOCL_TIME */
 
546
    case 0x4c:  /* APLL_CTRL */
 
547
    case 0x50:  /* POWER_CTRL */
 
548
        return s->ulpd_pm_regs[addr >> 2];
 
549
    }
 
550
 
 
551
    OMAP_BAD_REG(addr);
 
552
    return 0;
 
553
}
 
554
 
 
555
static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
 
556
                uint16_t diff, uint16_t value)
 
557
{
 
558
    if (diff & (1 << 4))                                /* USB_MCLK_EN */
 
559
        omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
 
560
    if (diff & (1 << 5))                                /* DIS_USB_PVCI_CLK */
 
561
        omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
 
562
}
 
563
 
 
564
static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
 
565
                uint16_t diff, uint16_t value)
 
566
{
 
567
    if (diff & (1 << 0))                                /* SOFT_DPLL_REQ */
 
568
        omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
 
569
    if (diff & (1 << 1))                                /* SOFT_COM_REQ */
 
570
        omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
 
571
    if (diff & (1 << 2))                                /* SOFT_SDW_REQ */
 
572
        omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
 
573
    if (diff & (1 << 3))                                /* SOFT_USB_REQ */
 
574
        omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
 
575
}
 
576
 
 
577
static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
 
578
                               uint64_t value, unsigned size)
 
579
{
 
580
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
581
    int64_t now, ticks;
 
582
    int div, mult;
 
583
    static const int bypass_div[4] = { 1, 2, 4, 4 };
 
584
    uint16_t diff;
 
585
 
 
586
    if (size != 2) {
 
587
        return omap_badwidth_write16(opaque, addr, value);
 
588
    }
 
589
 
 
590
    switch (addr) {
 
591
    case 0x00:  /* COUNTER_32_LSB */
 
592
    case 0x04:  /* COUNTER_32_MSB */
 
593
    case 0x08:  /* COUNTER_HIGH_FREQ_LSB */
 
594
    case 0x0c:  /* COUNTER_HIGH_FREQ_MSB */
 
595
    case 0x14:  /* IT_STATUS */
 
596
    case 0x40:  /* STATUS_REQ */
 
597
        OMAP_RO_REG(addr);
 
598
        break;
 
599
 
 
600
    case 0x10:  /* GAUGING_CTRL */
 
601
        /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
 
602
        if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
 
603
            now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
604
 
 
605
            if (value & 1)
 
606
                s->ulpd_gauge_start = now;
 
607
            else {
 
608
                now -= s->ulpd_gauge_start;
 
609
 
 
610
                /* 32-kHz ticks */
 
611
                ticks = muldiv64(now, 32768, get_ticks_per_sec());
 
612
                s->ulpd_pm_regs[0x00 >> 2] = (ticks >>  0) & 0xffff;
 
613
                s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
 
614
                if (ticks >> 32)        /* OVERFLOW_32K */
 
615
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
 
616
 
 
617
                /* High frequency ticks */
 
618
                ticks = muldiv64(now, 12000000, get_ticks_per_sec());
 
619
                s->ulpd_pm_regs[0x08 >> 2] = (ticks >>  0) & 0xffff;
 
620
                s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
 
621
                if (ticks >> 32)        /* OVERFLOW_HI_FREQ */
 
622
                    s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
 
623
 
 
624
                s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0;   /* IT_GAUGING */
 
625
                qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
 
626
            }
 
627
        }
 
628
        s->ulpd_pm_regs[addr >> 2] = value;
 
629
        break;
 
630
 
 
631
    case 0x18:  /* Reserved */
 
632
    case 0x1c:  /* Reserved */
 
633
    case 0x20:  /* Reserved */
 
634
    case 0x28:  /* Reserved */
 
635
    case 0x2c:  /* Reserved */
 
636
        OMAP_BAD_REG(addr);
 
637
        /* fall through */
 
638
    case 0x24:  /* SETUP_ANALOG_CELL3_ULPD1 */
 
639
    case 0x38:  /* COUNTER_32_FIQ */
 
640
    case 0x48:  /* LOCL_TIME */
 
641
    case 0x50:  /* POWER_CTRL */
 
642
        s->ulpd_pm_regs[addr >> 2] = value;
 
643
        break;
 
644
 
 
645
    case 0x30:  /* CLOCK_CTRL */
 
646
        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
 
647
        s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
 
648
        omap_ulpd_clk_update(s, diff, value);
 
649
        break;
 
650
 
 
651
    case 0x34:  /* SOFT_REQ */
 
652
        diff = s->ulpd_pm_regs[addr >> 2] ^ value;
 
653
        s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
 
654
        omap_ulpd_req_update(s, diff, value);
 
655
        break;
 
656
 
 
657
    case 0x3c:  /* DPLL_CTRL */
 
658
        /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
 
659
         * omitted altogether, probably a typo.  */
 
660
        /* This register has identical semantics with DPLL(1:3) control
 
661
         * registers, see omap_dpll_write() */
 
662
        diff = s->ulpd_pm_regs[addr >> 2] & value;
 
663
        s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
 
664
        if (diff & (0x3ff << 2)) {
 
665
            if (value & (1 << 4)) {                     /* PLL_ENABLE */
 
666
                div = ((value >> 5) & 3) + 1;           /* PLL_DIV */
 
667
                mult = MIN((value >> 7) & 0x1f, 1);     /* PLL_MULT */
 
668
            } else {
 
669
                div = bypass_div[((value >> 2) & 3)];   /* BYPASS_DIV */
 
670
                mult = 1;
 
671
            }
 
672
            omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
 
673
        }
 
674
 
 
675
        /* Enter the desired mode.  */
 
676
        s->ulpd_pm_regs[addr >> 2] =
 
677
                (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
 
678
                ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
 
679
 
 
680
        /* Act as if the lock is restored.  */
 
681
        s->ulpd_pm_regs[addr >> 2] |= 2;
 
682
        break;
 
683
 
 
684
    case 0x4c:  /* APLL_CTRL */
 
685
        diff = s->ulpd_pm_regs[addr >> 2] & value;
 
686
        s->ulpd_pm_regs[addr >> 2] = value & 0xf;
 
687
        if (diff & (1 << 0))                            /* APLL_NDPLL_SWITCH */
 
688
            omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
 
689
                                    (value & (1 << 0)) ? "apll" : "dpll4"));
 
690
        break;
 
691
 
 
692
    default:
 
693
        OMAP_BAD_REG(addr);
 
694
    }
 
695
}
 
696
 
 
697
static const MemoryRegionOps omap_ulpd_pm_ops = {
 
698
    .read = omap_ulpd_pm_read,
 
699
    .write = omap_ulpd_pm_write,
 
700
    .endianness = DEVICE_NATIVE_ENDIAN,
 
701
};
 
702
 
 
703
static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
 
704
{
 
705
    mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
 
706
    mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
 
707
    mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
 
708
    mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
 
709
    mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
 
710
    mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
 
711
    mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
 
712
    mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
 
713
    mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
 
714
    mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
 
715
    mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
 
716
    omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
 
717
    mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
 
718
    omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
 
719
    mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
 
720
    mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
 
721
    mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
 
722
    mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
 
723
    mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
 
724
    mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
 
725
    mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
 
726
    omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
 
727
    omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
 
728
}
 
729
 
 
730
static void omap_ulpd_pm_init(MemoryRegion *system_memory,
 
731
                hwaddr base,
 
732
                struct omap_mpu_state_s *mpu)
 
733
{
 
734
    memory_region_init_io(&mpu->ulpd_pm_iomem, NULL, &omap_ulpd_pm_ops, mpu,
 
735
                          "omap-ulpd-pm", 0x800);
 
736
    memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
 
737
    omap_ulpd_pm_reset(mpu);
 
738
}
 
739
 
 
740
/* OMAP Pin Configuration */
 
741
static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
 
742
                                  unsigned size)
 
743
{
 
744
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
745
 
 
746
    if (size != 4) {
 
747
        return omap_badwidth_read32(opaque, addr);
 
748
    }
 
749
 
 
750
    switch (addr) {
 
751
    case 0x00:  /* FUNC_MUX_CTRL_0 */
 
752
    case 0x04:  /* FUNC_MUX_CTRL_1 */
 
753
    case 0x08:  /* FUNC_MUX_CTRL_2 */
 
754
        return s->func_mux_ctrl[addr >> 2];
 
755
 
 
756
    case 0x0c:  /* COMP_MODE_CTRL_0 */
 
757
        return s->comp_mode_ctrl[0];
 
758
 
 
759
    case 0x10:  /* FUNC_MUX_CTRL_3 */
 
760
    case 0x14:  /* FUNC_MUX_CTRL_4 */
 
761
    case 0x18:  /* FUNC_MUX_CTRL_5 */
 
762
    case 0x1c:  /* FUNC_MUX_CTRL_6 */
 
763
    case 0x20:  /* FUNC_MUX_CTRL_7 */
 
764
    case 0x24:  /* FUNC_MUX_CTRL_8 */
 
765
    case 0x28:  /* FUNC_MUX_CTRL_9 */
 
766
    case 0x2c:  /* FUNC_MUX_CTRL_A */
 
767
    case 0x30:  /* FUNC_MUX_CTRL_B */
 
768
    case 0x34:  /* FUNC_MUX_CTRL_C */
 
769
    case 0x38:  /* FUNC_MUX_CTRL_D */
 
770
        return s->func_mux_ctrl[(addr >> 2) - 1];
 
771
 
 
772
    case 0x40:  /* PULL_DWN_CTRL_0 */
 
773
    case 0x44:  /* PULL_DWN_CTRL_1 */
 
774
    case 0x48:  /* PULL_DWN_CTRL_2 */
 
775
    case 0x4c:  /* PULL_DWN_CTRL_3 */
 
776
        return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
 
777
 
 
778
    case 0x50:  /* GATE_INH_CTRL_0 */
 
779
        return s->gate_inh_ctrl[0];
 
780
 
 
781
    case 0x60:  /* VOLTAGE_CTRL_0 */
 
782
        return s->voltage_ctrl[0];
 
783
 
 
784
    case 0x70:  /* TEST_DBG_CTRL_0 */
 
785
        return s->test_dbg_ctrl[0];
 
786
 
 
787
    case 0x80:  /* MOD_CONF_CTRL_0 */
 
788
        return s->mod_conf_ctrl[0];
 
789
    }
 
790
 
 
791
    OMAP_BAD_REG(addr);
 
792
    return 0;
 
793
}
 
794
 
 
795
static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
 
796
                uint32_t diff, uint32_t value)
 
797
{
 
798
    if (s->compat1509) {
 
799
        if (diff & (1 << 9))                    /* BLUETOOTH */
 
800
            omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
 
801
                            (~value >> 9) & 1);
 
802
        if (diff & (1 << 7))                    /* USB.CLKO */
 
803
            omap_clk_onoff(omap_findclk(s, "usb.clko"),
 
804
                            (value >> 7) & 1);
 
805
    }
 
806
}
 
807
 
 
808
static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
 
809
                uint32_t diff, uint32_t value)
 
810
{
 
811
    if (s->compat1509) {
 
812
        if (diff & (1 << 31))                   /* MCBSP3_CLK_HIZ_DI */
 
813
            omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
 
814
                            (value >> 31) & 1);
 
815
        if (diff & (1 << 1))                    /* CLK32K */
 
816
            omap_clk_onoff(omap_findclk(s, "clk32k_out"),
 
817
                            (~value >> 1) & 1);
 
818
    }
 
819
}
 
820
 
 
821
static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
 
822
                uint32_t diff, uint32_t value)
 
823
{
 
824
    if (diff & (1 << 31))                       /* CONF_MOD_UART3_CLK_MODE_R */
 
825
         omap_clk_reparent(omap_findclk(s, "uart3_ck"),
 
826
                         omap_findclk(s, ((value >> 31) & 1) ?
 
827
                                 "ck_48m" : "armper_ck"));
 
828
    if (diff & (1 << 30))                       /* CONF_MOD_UART2_CLK_MODE_R */
 
829
         omap_clk_reparent(omap_findclk(s, "uart2_ck"),
 
830
                         omap_findclk(s, ((value >> 30) & 1) ?
 
831
                                 "ck_48m" : "armper_ck"));
 
832
    if (diff & (1 << 29))                       /* CONF_MOD_UART1_CLK_MODE_R */
 
833
         omap_clk_reparent(omap_findclk(s, "uart1_ck"),
 
834
                         omap_findclk(s, ((value >> 29) & 1) ?
 
835
                                 "ck_48m" : "armper_ck"));
 
836
    if (diff & (1 << 23))                       /* CONF_MOD_MMC_SD_CLK_REQ_R */
 
837
         omap_clk_reparent(omap_findclk(s, "mmc_ck"),
 
838
                         omap_findclk(s, ((value >> 23) & 1) ?
 
839
                                 "ck_48m" : "armper_ck"));
 
840
    if (diff & (1 << 12))                       /* CONF_MOD_COM_MCLK_12_48_S */
 
841
         omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
 
842
                         omap_findclk(s, ((value >> 12) & 1) ?
 
843
                                 "ck_48m" : "armper_ck"));
 
844
    if (diff & (1 << 9))                        /* CONF_MOD_USB_HOST_HHC_UHO */
 
845
         omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
 
846
}
 
847
 
 
848
static void omap_pin_cfg_write(void *opaque, hwaddr addr,
 
849
                               uint64_t value, unsigned size)
 
850
{
 
851
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
852
    uint32_t diff;
 
853
 
 
854
    if (size != 4) {
 
855
        return omap_badwidth_write32(opaque, addr, value);
 
856
    }
 
857
 
 
858
    switch (addr) {
 
859
    case 0x00:  /* FUNC_MUX_CTRL_0 */
 
860
        diff = s->func_mux_ctrl[addr >> 2] ^ value;
 
861
        s->func_mux_ctrl[addr >> 2] = value;
 
862
        omap_pin_funcmux0_update(s, diff, value);
 
863
        return;
 
864
 
 
865
    case 0x04:  /* FUNC_MUX_CTRL_1 */
 
866
        diff = s->func_mux_ctrl[addr >> 2] ^ value;
 
867
        s->func_mux_ctrl[addr >> 2] = value;
 
868
        omap_pin_funcmux1_update(s, diff, value);
 
869
        return;
 
870
 
 
871
    case 0x08:  /* FUNC_MUX_CTRL_2 */
 
872
        s->func_mux_ctrl[addr >> 2] = value;
 
873
        return;
 
874
 
 
875
    case 0x0c:  /* COMP_MODE_CTRL_0 */
 
876
        s->comp_mode_ctrl[0] = value;
 
877
        s->compat1509 = (value != 0x0000eaef);
 
878
        omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
 
879
        omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
 
880
        return;
 
881
 
 
882
    case 0x10:  /* FUNC_MUX_CTRL_3 */
 
883
    case 0x14:  /* FUNC_MUX_CTRL_4 */
 
884
    case 0x18:  /* FUNC_MUX_CTRL_5 */
 
885
    case 0x1c:  /* FUNC_MUX_CTRL_6 */
 
886
    case 0x20:  /* FUNC_MUX_CTRL_7 */
 
887
    case 0x24:  /* FUNC_MUX_CTRL_8 */
 
888
    case 0x28:  /* FUNC_MUX_CTRL_9 */
 
889
    case 0x2c:  /* FUNC_MUX_CTRL_A */
 
890
    case 0x30:  /* FUNC_MUX_CTRL_B */
 
891
    case 0x34:  /* FUNC_MUX_CTRL_C */
 
892
    case 0x38:  /* FUNC_MUX_CTRL_D */
 
893
        s->func_mux_ctrl[(addr >> 2) - 1] = value;
 
894
        return;
 
895
 
 
896
    case 0x40:  /* PULL_DWN_CTRL_0 */
 
897
    case 0x44:  /* PULL_DWN_CTRL_1 */
 
898
    case 0x48:  /* PULL_DWN_CTRL_2 */
 
899
    case 0x4c:  /* PULL_DWN_CTRL_3 */
 
900
        s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
 
901
        return;
 
902
 
 
903
    case 0x50:  /* GATE_INH_CTRL_0 */
 
904
        s->gate_inh_ctrl[0] = value;
 
905
        return;
 
906
 
 
907
    case 0x60:  /* VOLTAGE_CTRL_0 */
 
908
        s->voltage_ctrl[0] = value;
 
909
        return;
 
910
 
 
911
    case 0x70:  /* TEST_DBG_CTRL_0 */
 
912
        s->test_dbg_ctrl[0] = value;
 
913
        return;
 
914
 
 
915
    case 0x80:  /* MOD_CONF_CTRL_0 */
 
916
        diff = s->mod_conf_ctrl[0] ^ value;
 
917
        s->mod_conf_ctrl[0] = value;
 
918
        omap_pin_modconf1_update(s, diff, value);
 
919
        return;
 
920
 
 
921
    default:
 
922
        OMAP_BAD_REG(addr);
 
923
    }
 
924
}
 
925
 
 
926
static const MemoryRegionOps omap_pin_cfg_ops = {
 
927
    .read = omap_pin_cfg_read,
 
928
    .write = omap_pin_cfg_write,
 
929
    .endianness = DEVICE_NATIVE_ENDIAN,
 
930
};
 
931
 
 
932
static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
 
933
{
 
934
    /* Start in Compatibility Mode.  */
 
935
    mpu->compat1509 = 1;
 
936
    omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
 
937
    omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
 
938
    omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
 
939
    memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
 
940
    memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
 
941
    memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
 
942
    memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
 
943
    memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
 
944
    memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
 
945
    memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
 
946
}
 
947
 
 
948
static void omap_pin_cfg_init(MemoryRegion *system_memory,
 
949
                hwaddr base,
 
950
                struct omap_mpu_state_s *mpu)
 
951
{
 
952
    memory_region_init_io(&mpu->pin_cfg_iomem, NULL, &omap_pin_cfg_ops, mpu,
 
953
                          "omap-pin-cfg", 0x800);
 
954
    memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
 
955
    omap_pin_cfg_reset(mpu);
 
956
}
 
957
 
 
958
/* Device Identification, Die Identification */
 
959
static uint64_t omap_id_read(void *opaque, hwaddr addr,
 
960
                             unsigned size)
 
961
{
 
962
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
963
 
 
964
    if (size != 4) {
 
965
        return omap_badwidth_read32(opaque, addr);
 
966
    }
 
967
 
 
968
    switch (addr) {
 
969
    case 0xfffe1800:    /* DIE_ID_LSB */
 
970
        return 0xc9581f0e;
 
971
    case 0xfffe1804:    /* DIE_ID_MSB */
 
972
        return 0xa8858bfa;
 
973
 
 
974
    case 0xfffe2000:    /* PRODUCT_ID_LSB */
 
975
        return 0x00aaaafc;
 
976
    case 0xfffe2004:    /* PRODUCT_ID_MSB */
 
977
        return 0xcafeb574;
 
978
 
 
979
    case 0xfffed400:    /* JTAG_ID_LSB */
 
980
        switch (s->mpu_model) {
 
981
        case omap310:
 
982
            return 0x03310315;
 
983
        case omap1510:
 
984
            return 0x03310115;
 
985
        default:
 
986
            hw_error("%s: bad mpu model\n", __FUNCTION__);
 
987
        }
 
988
        break;
 
989
 
 
990
    case 0xfffed404:    /* JTAG_ID_MSB */
 
991
        switch (s->mpu_model) {
 
992
        case omap310:
 
993
            return 0xfb57402f;
 
994
        case omap1510:
 
995
            return 0xfb47002f;
 
996
        default:
 
997
            hw_error("%s: bad mpu model\n", __FUNCTION__);
 
998
        }
 
999
        break;
 
1000
    }
 
1001
 
 
1002
    OMAP_BAD_REG(addr);
 
1003
    return 0;
 
1004
}
 
1005
 
 
1006
static void omap_id_write(void *opaque, hwaddr addr,
 
1007
                          uint64_t value, unsigned size)
 
1008
{
 
1009
    if (size != 4) {
 
1010
        return omap_badwidth_write32(opaque, addr, value);
 
1011
    }
 
1012
 
 
1013
    OMAP_BAD_REG(addr);
 
1014
}
 
1015
 
 
1016
static const MemoryRegionOps omap_id_ops = {
 
1017
    .read = omap_id_read,
 
1018
    .write = omap_id_write,
 
1019
    .endianness = DEVICE_NATIVE_ENDIAN,
 
1020
};
 
1021
 
 
1022
static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
 
1023
{
 
1024
    memory_region_init_io(&mpu->id_iomem, NULL, &omap_id_ops, mpu,
 
1025
                          "omap-id", 0x100000000ULL);
 
1026
    memory_region_init_alias(&mpu->id_iomem_e18, NULL, "omap-id-e18", &mpu->id_iomem,
 
1027
                             0xfffe1800, 0x800);
 
1028
    memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
 
1029
    memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-ed4", &mpu->id_iomem,
 
1030
                             0xfffed400, 0x100);
 
1031
    memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
 
1032
    if (!cpu_is_omap15xx(mpu)) {
 
1033
        memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-e20",
 
1034
                                 &mpu->id_iomem, 0xfffe2000, 0x800);
 
1035
        memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
 
1036
    }
 
1037
}
 
1038
 
 
1039
/* MPUI Control (Dummy) */
 
1040
static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
 
1041
                               unsigned size)
 
1042
{
 
1043
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
1044
 
 
1045
    if (size != 4) {
 
1046
        return omap_badwidth_read32(opaque, addr);
 
1047
    }
 
1048
 
 
1049
    switch (addr) {
 
1050
    case 0x00:  /* CTRL */
 
1051
        return s->mpui_ctrl;
 
1052
    case 0x04:  /* DEBUG_ADDR */
 
1053
        return 0x01ffffff;
 
1054
    case 0x08:  /* DEBUG_DATA */
 
1055
        return 0xffffffff;
 
1056
    case 0x0c:  /* DEBUG_FLAG */
 
1057
        return 0x00000800;
 
1058
    case 0x10:  /* STATUS */
 
1059
        return 0x00000000;
 
1060
 
 
1061
    /* Not in OMAP310 */
 
1062
    case 0x14:  /* DSP_STATUS */
 
1063
    case 0x18:  /* DSP_BOOT_CONFIG */
 
1064
        return 0x00000000;
 
1065
    case 0x1c:  /* DSP_MPUI_CONFIG */
 
1066
        return 0x0000ffff;
 
1067
    }
 
1068
 
 
1069
    OMAP_BAD_REG(addr);
 
1070
    return 0;
 
1071
}
 
1072
 
 
1073
static void omap_mpui_write(void *opaque, hwaddr addr,
 
1074
                            uint64_t value, unsigned size)
 
1075
{
 
1076
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
1077
 
 
1078
    if (size != 4) {
 
1079
        return omap_badwidth_write32(opaque, addr, value);
 
1080
    }
 
1081
 
 
1082
    switch (addr) {
 
1083
    case 0x00:  /* CTRL */
 
1084
        s->mpui_ctrl = value & 0x007fffff;
 
1085
        break;
 
1086
 
 
1087
    case 0x04:  /* DEBUG_ADDR */
 
1088
    case 0x08:  /* DEBUG_DATA */
 
1089
    case 0x0c:  /* DEBUG_FLAG */
 
1090
    case 0x10:  /* STATUS */
 
1091
    /* Not in OMAP310 */
 
1092
    case 0x14:  /* DSP_STATUS */
 
1093
        OMAP_RO_REG(addr);
 
1094
        break;
 
1095
    case 0x18:  /* DSP_BOOT_CONFIG */
 
1096
    case 0x1c:  /* DSP_MPUI_CONFIG */
 
1097
        break;
 
1098
 
 
1099
    default:
 
1100
        OMAP_BAD_REG(addr);
 
1101
    }
 
1102
}
 
1103
 
 
1104
static const MemoryRegionOps omap_mpui_ops = {
 
1105
    .read = omap_mpui_read,
 
1106
    .write = omap_mpui_write,
 
1107
    .endianness = DEVICE_NATIVE_ENDIAN,
 
1108
};
 
1109
 
 
1110
static void omap_mpui_reset(struct omap_mpu_state_s *s)
 
1111
{
 
1112
    s->mpui_ctrl = 0x0003ff1b;
 
1113
}
 
1114
 
 
1115
static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
 
1116
                struct omap_mpu_state_s *mpu)
 
1117
{
 
1118
    memory_region_init_io(&mpu->mpui_iomem, NULL, &omap_mpui_ops, mpu,
 
1119
                          "omap-mpui", 0x100);
 
1120
    memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
 
1121
 
 
1122
    omap_mpui_reset(mpu);
 
1123
}
 
1124
 
 
1125
/* TIPB Bridges */
 
1126
struct omap_tipb_bridge_s {
 
1127
    qemu_irq abort;
 
1128
    MemoryRegion iomem;
 
1129
 
 
1130
    int width_intr;
 
1131
    uint16_t control;
 
1132
    uint16_t alloc;
 
1133
    uint16_t buffer;
 
1134
    uint16_t enh_control;
 
1135
};
 
1136
 
 
1137
static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
 
1138
                                      unsigned size)
 
1139
{
 
1140
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
 
1141
 
 
1142
    if (size < 2) {
 
1143
        return omap_badwidth_read16(opaque, addr);
 
1144
    }
 
1145
 
 
1146
    switch (addr) {
 
1147
    case 0x00:  /* TIPB_CNTL */
 
1148
        return s->control;
 
1149
    case 0x04:  /* TIPB_BUS_ALLOC */
 
1150
        return s->alloc;
 
1151
    case 0x08:  /* MPU_TIPB_CNTL */
 
1152
        return s->buffer;
 
1153
    case 0x0c:  /* ENHANCED_TIPB_CNTL */
 
1154
        return s->enh_control;
 
1155
    case 0x10:  /* ADDRESS_DBG */
 
1156
    case 0x14:  /* DATA_DEBUG_LOW */
 
1157
    case 0x18:  /* DATA_DEBUG_HIGH */
 
1158
        return 0xffff;
 
1159
    case 0x1c:  /* DEBUG_CNTR_SIG */
 
1160
        return 0x00f8;
 
1161
    }
 
1162
 
 
1163
    OMAP_BAD_REG(addr);
 
1164
    return 0;
 
1165
}
 
1166
 
 
1167
static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
 
1168
                                   uint64_t value, unsigned size)
 
1169
{
 
1170
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
 
1171
 
 
1172
    if (size < 2) {
 
1173
        return omap_badwidth_write16(opaque, addr, value);
 
1174
    }
 
1175
 
 
1176
    switch (addr) {
 
1177
    case 0x00:  /* TIPB_CNTL */
 
1178
        s->control = value & 0xffff;
 
1179
        break;
 
1180
 
 
1181
    case 0x04:  /* TIPB_BUS_ALLOC */
 
1182
        s->alloc = value & 0x003f;
 
1183
        break;
 
1184
 
 
1185
    case 0x08:  /* MPU_TIPB_CNTL */
 
1186
        s->buffer = value & 0x0003;
 
1187
        break;
 
1188
 
 
1189
    case 0x0c:  /* ENHANCED_TIPB_CNTL */
 
1190
        s->width_intr = !(value & 2);
 
1191
        s->enh_control = value & 0x000f;
 
1192
        break;
 
1193
 
 
1194
    case 0x10:  /* ADDRESS_DBG */
 
1195
    case 0x14:  /* DATA_DEBUG_LOW */
 
1196
    case 0x18:  /* DATA_DEBUG_HIGH */
 
1197
    case 0x1c:  /* DEBUG_CNTR_SIG */
 
1198
        OMAP_RO_REG(addr);
 
1199
        break;
 
1200
 
 
1201
    default:
 
1202
        OMAP_BAD_REG(addr);
 
1203
    }
 
1204
}
 
1205
 
 
1206
static const MemoryRegionOps omap_tipb_bridge_ops = {
 
1207
    .read = omap_tipb_bridge_read,
 
1208
    .write = omap_tipb_bridge_write,
 
1209
    .endianness = DEVICE_NATIVE_ENDIAN,
 
1210
};
 
1211
 
 
1212
static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
 
1213
{
 
1214
    s->control = 0xffff;
 
1215
    s->alloc = 0x0009;
 
1216
    s->buffer = 0x0000;
 
1217
    s->enh_control = 0x000f;
 
1218
}
 
1219
 
 
1220
static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
 
1221
    MemoryRegion *memory, hwaddr base,
 
1222
    qemu_irq abort_irq, omap_clk clk)
 
1223
{
 
1224
    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
 
1225
            g_malloc0(sizeof(struct omap_tipb_bridge_s));
 
1226
 
 
1227
    s->abort = abort_irq;
 
1228
    omap_tipb_bridge_reset(s);
 
1229
 
 
1230
    memory_region_init_io(&s->iomem, NULL, &omap_tipb_bridge_ops, s,
 
1231
                          "omap-tipb-bridge", 0x100);
 
1232
    memory_region_add_subregion(memory, base, &s->iomem);
 
1233
 
 
1234
    return s;
 
1235
}
 
1236
 
 
1237
/* Dummy Traffic Controller's Memory Interface */
 
1238
static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
 
1239
                               unsigned size)
 
1240
{
 
1241
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
1242
    uint32_t ret;
 
1243
 
 
1244
    if (size != 4) {
 
1245
        return omap_badwidth_read32(opaque, addr);
 
1246
    }
 
1247
 
 
1248
    switch (addr) {
 
1249
    case 0x00:  /* IMIF_PRIO */
 
1250
    case 0x04:  /* EMIFS_PRIO */
 
1251
    case 0x08:  /* EMIFF_PRIO */
 
1252
    case 0x0c:  /* EMIFS_CONFIG */
 
1253
    case 0x10:  /* EMIFS_CS0_CONFIG */
 
1254
    case 0x14:  /* EMIFS_CS1_CONFIG */
 
1255
    case 0x18:  /* EMIFS_CS2_CONFIG */
 
1256
    case 0x1c:  /* EMIFS_CS3_CONFIG */
 
1257
    case 0x24:  /* EMIFF_MRS */
 
1258
    case 0x28:  /* TIMEOUT1 */
 
1259
    case 0x2c:  /* TIMEOUT2 */
 
1260
    case 0x30:  /* TIMEOUT3 */
 
1261
    case 0x3c:  /* EMIFF_SDRAM_CONFIG_2 */
 
1262
    case 0x40:  /* EMIFS_CFG_DYN_WAIT */
 
1263
        return s->tcmi_regs[addr >> 2];
 
1264
 
 
1265
    case 0x20:  /* EMIFF_SDRAM_CONFIG */
 
1266
        ret = s->tcmi_regs[addr >> 2];
 
1267
        s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
 
1268
        /* XXX: We can try using the VGA_DIRTY flag for this */
 
1269
        return ret;
 
1270
    }
 
1271
 
 
1272
    OMAP_BAD_REG(addr);
 
1273
    return 0;
 
1274
}
 
1275
 
 
1276
static void omap_tcmi_write(void *opaque, hwaddr addr,
 
1277
                            uint64_t value, unsigned size)
 
1278
{
 
1279
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
1280
 
 
1281
    if (size != 4) {
 
1282
        return omap_badwidth_write32(opaque, addr, value);
 
1283
    }
 
1284
 
 
1285
    switch (addr) {
 
1286
    case 0x00:  /* IMIF_PRIO */
 
1287
    case 0x04:  /* EMIFS_PRIO */
 
1288
    case 0x08:  /* EMIFF_PRIO */
 
1289
    case 0x10:  /* EMIFS_CS0_CONFIG */
 
1290
    case 0x14:  /* EMIFS_CS1_CONFIG */
 
1291
    case 0x18:  /* EMIFS_CS2_CONFIG */
 
1292
    case 0x1c:  /* EMIFS_CS3_CONFIG */
 
1293
    case 0x20:  /* EMIFF_SDRAM_CONFIG */
 
1294
    case 0x24:  /* EMIFF_MRS */
 
1295
    case 0x28:  /* TIMEOUT1 */
 
1296
    case 0x2c:  /* TIMEOUT2 */
 
1297
    case 0x30:  /* TIMEOUT3 */
 
1298
    case 0x3c:  /* EMIFF_SDRAM_CONFIG_2 */
 
1299
    case 0x40:  /* EMIFS_CFG_DYN_WAIT */
 
1300
        s->tcmi_regs[addr >> 2] = value;
 
1301
        break;
 
1302
    case 0x0c:  /* EMIFS_CONFIG */
 
1303
        s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
 
1304
        break;
 
1305
 
 
1306
    default:
 
1307
        OMAP_BAD_REG(addr);
 
1308
    }
 
1309
}
 
1310
 
 
1311
static const MemoryRegionOps omap_tcmi_ops = {
 
1312
    .read = omap_tcmi_read,
 
1313
    .write = omap_tcmi_write,
 
1314
    .endianness = DEVICE_NATIVE_ENDIAN,
 
1315
};
 
1316
 
 
1317
static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
 
1318
{
 
1319
    mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
 
1320
    mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
 
1321
    mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
 
1322
    mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
 
1323
    mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
 
1324
    mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
 
1325
    mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
 
1326
    mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
 
1327
    mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
 
1328
    mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
 
1329
    mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
 
1330
    mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
 
1331
    mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
 
1332
    mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
 
1333
    mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
 
1334
}
 
1335
 
 
1336
static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
 
1337
                struct omap_mpu_state_s *mpu)
 
1338
{
 
1339
    memory_region_init_io(&mpu->tcmi_iomem, NULL, &omap_tcmi_ops, mpu,
 
1340
                          "omap-tcmi", 0x100);
 
1341
    memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
 
1342
    omap_tcmi_reset(mpu);
 
1343
}
 
1344
 
 
1345
/* Digital phase-locked loops control */
 
1346
struct dpll_ctl_s {
 
1347
    MemoryRegion iomem;
 
1348
    uint16_t mode;
 
1349
    omap_clk dpll;
 
1350
};
 
1351
 
 
1352
static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
 
1353
                               unsigned size)
 
1354
{
 
1355
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
 
1356
 
 
1357
    if (size != 2) {
 
1358
        return omap_badwidth_read16(opaque, addr);
 
1359
    }
 
1360
 
 
1361
    if (addr == 0x00)   /* CTL_REG */
 
1362
        return s->mode;
 
1363
 
 
1364
    OMAP_BAD_REG(addr);
 
1365
    return 0;
 
1366
}
 
1367
 
 
1368
static void omap_dpll_write(void *opaque, hwaddr addr,
 
1369
                            uint64_t value, unsigned size)
 
1370
{
 
1371
    struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
 
1372
    uint16_t diff;
 
1373
    static const int bypass_div[4] = { 1, 2, 4, 4 };
 
1374
    int div, mult;
 
1375
 
 
1376
    if (size != 2) {
 
1377
        return omap_badwidth_write16(opaque, addr, value);
 
1378
    }
 
1379
 
 
1380
    if (addr == 0x00) { /* CTL_REG */
 
1381
        /* See omap_ulpd_pm_write() too */
 
1382
        diff = s->mode & value;
 
1383
        s->mode = value & 0x2fff;
 
1384
        if (diff & (0x3ff << 2)) {
 
1385
            if (value & (1 << 4)) {                     /* PLL_ENABLE */
 
1386
                div = ((value >> 5) & 3) + 1;           /* PLL_DIV */
 
1387
                mult = MIN((value >> 7) & 0x1f, 1);     /* PLL_MULT */
 
1388
            } else {
 
1389
                div = bypass_div[((value >> 2) & 3)];   /* BYPASS_DIV */
 
1390
                mult = 1;
 
1391
            }
 
1392
            omap_clk_setrate(s->dpll, div, mult);
 
1393
        }
 
1394
 
 
1395
        /* Enter the desired mode.  */
 
1396
        s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
 
1397
 
 
1398
        /* Act as if the lock is restored.  */
 
1399
        s->mode |= 2;
 
1400
    } else {
 
1401
        OMAP_BAD_REG(addr);
 
1402
    }
 
1403
}
 
1404
 
 
1405
static const MemoryRegionOps omap_dpll_ops = {
 
1406
    .read = omap_dpll_read,
 
1407
    .write = omap_dpll_write,
 
1408
    .endianness = DEVICE_NATIVE_ENDIAN,
 
1409
};
 
1410
 
 
1411
static void omap_dpll_reset(struct dpll_ctl_s *s)
 
1412
{
 
1413
    s->mode = 0x2002;
 
1414
    omap_clk_setrate(s->dpll, 1, 1);
 
1415
}
 
1416
 
 
1417
static struct dpll_ctl_s  *omap_dpll_init(MemoryRegion *memory,
 
1418
                           hwaddr base, omap_clk clk)
 
1419
{
 
1420
    struct dpll_ctl_s *s = g_malloc0(sizeof(*s));
 
1421
    memory_region_init_io(&s->iomem, NULL, &omap_dpll_ops, s, "omap-dpll", 0x100);
 
1422
 
 
1423
    s->dpll = clk;
 
1424
    omap_dpll_reset(s);
 
1425
 
 
1426
    memory_region_add_subregion(memory, base, &s->iomem);
 
1427
    return s;
 
1428
}
 
1429
 
 
1430
/* MPU Clock/Reset/Power Mode Control */
 
1431
static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
 
1432
                               unsigned size)
 
1433
{
 
1434
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
1435
 
 
1436
    if (size != 2) {
 
1437
        return omap_badwidth_read16(opaque, addr);
 
1438
    }
 
1439
 
 
1440
    switch (addr) {
 
1441
    case 0x00:  /* ARM_CKCTL */
 
1442
        return s->clkm.arm_ckctl;
 
1443
 
 
1444
    case 0x04:  /* ARM_IDLECT1 */
 
1445
        return s->clkm.arm_idlect1;
 
1446
 
 
1447
    case 0x08:  /* ARM_IDLECT2 */
 
1448
        return s->clkm.arm_idlect2;
 
1449
 
 
1450
    case 0x0c:  /* ARM_EWUPCT */
 
1451
        return s->clkm.arm_ewupct;
 
1452
 
 
1453
    case 0x10:  /* ARM_RSTCT1 */
 
1454
        return s->clkm.arm_rstct1;
 
1455
 
 
1456
    case 0x14:  /* ARM_RSTCT2 */
 
1457
        return s->clkm.arm_rstct2;
 
1458
 
 
1459
    case 0x18:  /* ARM_SYSST */
 
1460
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
 
1461
 
 
1462
    case 0x1c:  /* ARM_CKOUT1 */
 
1463
        return s->clkm.arm_ckout1;
 
1464
 
 
1465
    case 0x20:  /* ARM_CKOUT2 */
 
1466
        break;
 
1467
    }
 
1468
 
 
1469
    OMAP_BAD_REG(addr);
 
1470
    return 0;
 
1471
}
 
1472
 
 
1473
static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
 
1474
                uint16_t diff, uint16_t value)
 
1475
{
 
1476
    omap_clk clk;
 
1477
 
 
1478
    if (diff & (1 << 14)) {                             /* ARM_INTHCK_SEL */
 
1479
        if (value & (1 << 14))
 
1480
            /* Reserved */;
 
1481
        else {
 
1482
            clk = omap_findclk(s, "arminth_ck");
 
1483
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
 
1484
        }
 
1485
    }
 
1486
    if (diff & (1 << 12)) {                             /* ARM_TIMXO */
 
1487
        clk = omap_findclk(s, "armtim_ck");
 
1488
        if (value & (1 << 12))
 
1489
            omap_clk_reparent(clk, omap_findclk(s, "clkin"));
 
1490
        else
 
1491
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
 
1492
    }
 
1493
    /* XXX: en_dspck */
 
1494
    if (diff & (3 << 10)) {                             /* DSPMMUDIV */
 
1495
        clk = omap_findclk(s, "dspmmu_ck");
 
1496
        omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
 
1497
    }
 
1498
    if (diff & (3 << 8)) {                              /* TCDIV */
 
1499
        clk = omap_findclk(s, "tc_ck");
 
1500
        omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
 
1501
    }
 
1502
    if (diff & (3 << 6)) {                              /* DSPDIV */
 
1503
        clk = omap_findclk(s, "dsp_ck");
 
1504
        omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
 
1505
    }
 
1506
    if (diff & (3 << 4)) {                              /* ARMDIV */
 
1507
        clk = omap_findclk(s, "arm_ck");
 
1508
        omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
 
1509
    }
 
1510
    if (diff & (3 << 2)) {                              /* LCDDIV */
 
1511
        clk = omap_findclk(s, "lcd_ck");
 
1512
        omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
 
1513
    }
 
1514
    if (diff & (3 << 0)) {                              /* PERDIV */
 
1515
        clk = omap_findclk(s, "armper_ck");
 
1516
        omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
 
1517
    }
 
1518
}
 
1519
 
 
1520
static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
 
1521
                uint16_t diff, uint16_t value)
 
1522
{
 
1523
    omap_clk clk;
 
1524
 
 
1525
    if (value & (1 << 11)) {                            /* SETARM_IDLE */
 
1526
        cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
 
1527
    }
 
1528
    if (!(value & (1 << 10)))                           /* WKUP_MODE */
 
1529
        qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */
 
1530
 
 
1531
#define SET_CANIDLE(clock, bit)                         \
 
1532
    if (diff & (1 << bit)) {                            \
 
1533
        clk = omap_findclk(s, clock);                   \
 
1534
        omap_clk_canidle(clk, (value >> bit) & 1);      \
 
1535
    }
 
1536
    SET_CANIDLE("mpuwd_ck", 0)                          /* IDLWDT_ARM */
 
1537
    SET_CANIDLE("armxor_ck", 1)                         /* IDLXORP_ARM */
 
1538
    SET_CANIDLE("mpuper_ck", 2)                         /* IDLPER_ARM */
 
1539
    SET_CANIDLE("lcd_ck", 3)                            /* IDLLCD_ARM */
 
1540
    SET_CANIDLE("lb_ck", 4)                             /* IDLLB_ARM */
 
1541
    SET_CANIDLE("hsab_ck", 5)                           /* IDLHSAB_ARM */
 
1542
    SET_CANIDLE("tipb_ck", 6)                           /* IDLIF_ARM */
 
1543
    SET_CANIDLE("dma_ck", 6)                            /* IDLIF_ARM */
 
1544
    SET_CANIDLE("tc_ck", 6)                             /* IDLIF_ARM */
 
1545
    SET_CANIDLE("dpll1", 7)                             /* IDLDPLL_ARM */
 
1546
    SET_CANIDLE("dpll2", 7)                             /* IDLDPLL_ARM */
 
1547
    SET_CANIDLE("dpll3", 7)                             /* IDLDPLL_ARM */
 
1548
    SET_CANIDLE("mpui_ck", 8)                           /* IDLAPI_ARM */
 
1549
    SET_CANIDLE("armtim_ck", 9)                         /* IDLTIM_ARM */
 
1550
}
 
1551
 
 
1552
static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
 
1553
                uint16_t diff, uint16_t value)
 
1554
{
 
1555
    omap_clk clk;
 
1556
 
 
1557
#define SET_ONOFF(clock, bit)                           \
 
1558
    if (diff & (1 << bit)) {                            \
 
1559
        clk = omap_findclk(s, clock);                   \
 
1560
        omap_clk_onoff(clk, (value >> bit) & 1);        \
 
1561
    }
 
1562
    SET_ONOFF("mpuwd_ck", 0)                            /* EN_WDTCK */
 
1563
    SET_ONOFF("armxor_ck", 1)                           /* EN_XORPCK */
 
1564
    SET_ONOFF("mpuper_ck", 2)                           /* EN_PERCK */
 
1565
    SET_ONOFF("lcd_ck", 3)                              /* EN_LCDCK */
 
1566
    SET_ONOFF("lb_ck", 4)                               /* EN_LBCK */
 
1567
    SET_ONOFF("hsab_ck", 5)                             /* EN_HSABCK */
 
1568
    SET_ONOFF("mpui_ck", 6)                             /* EN_APICK */
 
1569
    SET_ONOFF("armtim_ck", 7)                           /* EN_TIMCK */
 
1570
    SET_CANIDLE("dma_ck", 8)                            /* DMACK_REQ */
 
1571
    SET_ONOFF("arm_gpio_ck", 9)                         /* EN_GPIOCK */
 
1572
    SET_ONOFF("lbfree_ck", 10)                          /* EN_LBFREECK */
 
1573
}
 
1574
 
 
1575
static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
 
1576
                uint16_t diff, uint16_t value)
 
1577
{
 
1578
    omap_clk clk;
 
1579
 
 
1580
    if (diff & (3 << 4)) {                              /* TCLKOUT */
 
1581
        clk = omap_findclk(s, "tclk_out");
 
1582
        switch ((value >> 4) & 3) {
 
1583
        case 1:
 
1584
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
 
1585
            omap_clk_onoff(clk, 1);
 
1586
            break;
 
1587
        case 2:
 
1588
            omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
 
1589
            omap_clk_onoff(clk, 1);
 
1590
            break;
 
1591
        default:
 
1592
            omap_clk_onoff(clk, 0);
 
1593
        }
 
1594
    }
 
1595
    if (diff & (3 << 2)) {                              /* DCLKOUT */
 
1596
        clk = omap_findclk(s, "dclk_out");
 
1597
        switch ((value >> 2) & 3) {
 
1598
        case 0:
 
1599
            omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
 
1600
            break;
 
1601
        case 1:
 
1602
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
 
1603
            break;
 
1604
        case 2:
 
1605
            omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
 
1606
            break;
 
1607
        case 3:
 
1608
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
 
1609
            break;
 
1610
        }
 
1611
    }
 
1612
    if (diff & (3 << 0)) {                              /* ACLKOUT */
 
1613
        clk = omap_findclk(s, "aclk_out");
 
1614
        switch ((value >> 0) & 3) {
 
1615
        case 1:
 
1616
            omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
 
1617
            omap_clk_onoff(clk, 1);
 
1618
            break;
 
1619
        case 2:
 
1620
            omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
 
1621
            omap_clk_onoff(clk, 1);
 
1622
            break;
 
1623
        case 3:
 
1624
            omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
 
1625
            omap_clk_onoff(clk, 1);
 
1626
            break;
 
1627
        default:
 
1628
            omap_clk_onoff(clk, 0);
 
1629
        }
 
1630
    }
 
1631
}
 
1632
 
 
1633
static void omap_clkm_write(void *opaque, hwaddr addr,
 
1634
                            uint64_t value, unsigned size)
 
1635
{
 
1636
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
1637
    uint16_t diff;
 
1638
    omap_clk clk;
 
1639
    static const char *clkschemename[8] = {
 
1640
        "fully synchronous", "fully asynchronous", "synchronous scalable",
 
1641
        "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
 
1642
    };
 
1643
 
 
1644
    if (size != 2) {
 
1645
        return omap_badwidth_write16(opaque, addr, value);
 
1646
    }
 
1647
 
 
1648
    switch (addr) {
 
1649
    case 0x00:  /* ARM_CKCTL */
 
1650
        diff = s->clkm.arm_ckctl ^ value;
 
1651
        s->clkm.arm_ckctl = value & 0x7fff;
 
1652
        omap_clkm_ckctl_update(s, diff, value);
 
1653
        return;
 
1654
 
 
1655
    case 0x04:  /* ARM_IDLECT1 */
 
1656
        diff = s->clkm.arm_idlect1 ^ value;
 
1657
        s->clkm.arm_idlect1 = value & 0x0fff;
 
1658
        omap_clkm_idlect1_update(s, diff, value);
 
1659
        return;
 
1660
 
 
1661
    case 0x08:  /* ARM_IDLECT2 */
 
1662
        diff = s->clkm.arm_idlect2 ^ value;
 
1663
        s->clkm.arm_idlect2 = value & 0x07ff;
 
1664
        omap_clkm_idlect2_update(s, diff, value);
 
1665
        return;
 
1666
 
 
1667
    case 0x0c:  /* ARM_EWUPCT */
 
1668
        s->clkm.arm_ewupct = value & 0x003f;
 
1669
        return;
 
1670
 
 
1671
    case 0x10:  /* ARM_RSTCT1 */
 
1672
        diff = s->clkm.arm_rstct1 ^ value;
 
1673
        s->clkm.arm_rstct1 = value & 0x0007;
 
1674
        if (value & 9) {
 
1675
            qemu_system_reset_request();
 
1676
            s->clkm.cold_start = 0xa;
 
1677
        }
 
1678
        if (diff & ~value & 4) {                                /* DSP_RST */
 
1679
            omap_mpui_reset(s);
 
1680
            omap_tipb_bridge_reset(s->private_tipb);
 
1681
            omap_tipb_bridge_reset(s->public_tipb);
 
1682
        }
 
1683
        if (diff & 2) {                                         /* DSP_EN */
 
1684
            clk = omap_findclk(s, "dsp_ck");
 
1685
            omap_clk_canidle(clk, (~value >> 1) & 1);
 
1686
        }
 
1687
        return;
 
1688
 
 
1689
    case 0x14:  /* ARM_RSTCT2 */
 
1690
        s->clkm.arm_rstct2 = value & 0x0001;
 
1691
        return;
 
1692
 
 
1693
    case 0x18:  /* ARM_SYSST */
 
1694
        if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
 
1695
            s->clkm.clocking_scheme = (value >> 11) & 7;
 
1696
            printf("%s: clocking scheme set to %s\n", __FUNCTION__,
 
1697
                            clkschemename[s->clkm.clocking_scheme]);
 
1698
        }
 
1699
        s->clkm.cold_start &= value & 0x3f;
 
1700
        return;
 
1701
 
 
1702
    case 0x1c:  /* ARM_CKOUT1 */
 
1703
        diff = s->clkm.arm_ckout1 ^ value;
 
1704
        s->clkm.arm_ckout1 = value & 0x003f;
 
1705
        omap_clkm_ckout1_update(s, diff, value);
 
1706
        return;
 
1707
 
 
1708
    case 0x20:  /* ARM_CKOUT2 */
 
1709
    default:
 
1710
        OMAP_BAD_REG(addr);
 
1711
    }
 
1712
}
 
1713
 
 
1714
static const MemoryRegionOps omap_clkm_ops = {
 
1715
    .read = omap_clkm_read,
 
1716
    .write = omap_clkm_write,
 
1717
    .endianness = DEVICE_NATIVE_ENDIAN,
 
1718
};
 
1719
 
 
1720
static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
 
1721
                                 unsigned size)
 
1722
{
 
1723
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
1724
    CPUState *cpu = CPU(s->cpu);
 
1725
 
 
1726
    if (size != 2) {
 
1727
        return omap_badwidth_read16(opaque, addr);
 
1728
    }
 
1729
 
 
1730
    switch (addr) {
 
1731
    case 0x04:  /* DSP_IDLECT1 */
 
1732
        return s->clkm.dsp_idlect1;
 
1733
 
 
1734
    case 0x08:  /* DSP_IDLECT2 */
 
1735
        return s->clkm.dsp_idlect2;
 
1736
 
 
1737
    case 0x14:  /* DSP_RSTCT2 */
 
1738
        return s->clkm.dsp_rstct2;
 
1739
 
 
1740
    case 0x18:  /* DSP_SYSST */
 
1741
        cpu = CPU(s->cpu);
 
1742
        return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
 
1743
                (cpu->halted << 6);      /* Quite useless... */
 
1744
    }
 
1745
 
 
1746
    OMAP_BAD_REG(addr);
 
1747
    return 0;
 
1748
}
 
1749
 
 
1750
static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
 
1751
                uint16_t diff, uint16_t value)
 
1752
{
 
1753
    omap_clk clk;
 
1754
 
 
1755
    SET_CANIDLE("dspxor_ck", 1);                        /* IDLXORP_DSP */
 
1756
}
 
1757
 
 
1758
static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
 
1759
                uint16_t diff, uint16_t value)
 
1760
{
 
1761
    omap_clk clk;
 
1762
 
 
1763
    SET_ONOFF("dspxor_ck", 1);                          /* EN_XORPCK */
 
1764
}
 
1765
 
 
1766
static void omap_clkdsp_write(void *opaque, hwaddr addr,
 
1767
                              uint64_t value, unsigned size)
 
1768
{
 
1769
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
 
1770
    uint16_t diff;
 
1771
 
 
1772
    if (size != 2) {
 
1773
        return omap_badwidth_write16(opaque, addr, value);
 
1774
    }
 
1775
 
 
1776
    switch (addr) {
 
1777
    case 0x04:  /* DSP_IDLECT1 */
 
1778
        diff = s->clkm.dsp_idlect1 ^ value;
 
1779
        s->clkm.dsp_idlect1 = value & 0x01f7;
 
1780
        omap_clkdsp_idlect1_update(s, diff, value);
 
1781
        break;
 
1782
 
 
1783
    case 0x08:  /* DSP_IDLECT2 */
 
1784
        s->clkm.dsp_idlect2 = value & 0x0037;
 
1785
        diff = s->clkm.dsp_idlect1 ^ value;
 
1786
        omap_clkdsp_idlect2_update(s, diff, value);
 
1787
        break;
 
1788
 
 
1789
    case 0x14:  /* DSP_RSTCT2 */
 
1790
        s->clkm.dsp_rstct2 = value & 0x0001;
 
1791
        break;
 
1792
 
 
1793
    case 0x18:  /* DSP_SYSST */
 
1794
        s->clkm.cold_start &= value & 0x3f;
 
1795
        break;
 
1796
 
 
1797
    default:
 
1798
        OMAP_BAD_REG(addr);
 
1799
    }
 
1800
}
 
1801
 
 
1802
static const MemoryRegionOps omap_clkdsp_ops = {
 
1803
    .read = omap_clkdsp_read,
 
1804
    .write = omap_clkdsp_write,
 
1805
    .endianness = DEVICE_NATIVE_ENDIAN,
 
1806
};
 
1807
 
 
1808
static void omap_clkm_reset(struct omap_mpu_state_s *s)
 
1809
{
 
1810
    if (s->wdt && s->wdt->reset)
 
1811
        s->clkm.cold_start = 0x6;
 
1812
    s->clkm.clocking_scheme = 0;
 
1813
    omap_clkm_ckctl_update(s, ~0, 0x3000);
 
1814
    s->clkm.arm_ckctl = 0x3000;
 
1815
    omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
 
1816
    s->clkm.arm_idlect1 = 0x0400;
 
1817
    omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
 
1818
    s->clkm.arm_idlect2 = 0x0100;
 
1819
    s->clkm.arm_ewupct = 0x003f;
 
1820
    s->clkm.arm_rstct1 = 0x0000;
 
1821
    s->clkm.arm_rstct2 = 0x0000;
 
1822
    s->clkm.arm_ckout1 = 0x0015;
 
1823
    s->clkm.dpll1_mode = 0x2002;
 
1824
    omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
 
1825
    s->clkm.dsp_idlect1 = 0x0040;
 
1826
    omap_clkdsp_idlect2_update(s, ~0, 0x0000);
 
1827
    s->clkm.dsp_idlect2 = 0x0000;
 
1828
    s->clkm.dsp_rstct2 = 0x0000;
 
1829
}
 
1830
 
 
1831
static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
 
1832
                hwaddr dsp_base, struct omap_mpu_state_s *s)
 
1833
{
 
1834
    memory_region_init_io(&s->clkm_iomem, NULL, &omap_clkm_ops, s,
 
1835
                          "omap-clkm", 0x100);
 
1836
    memory_region_init_io(&s->clkdsp_iomem, NULL, &omap_clkdsp_ops, s,
 
1837
                          "omap-clkdsp", 0x1000);
 
1838
 
 
1839
    s->clkm.arm_idlect1 = 0x03ff;
 
1840
    s->clkm.arm_idlect2 = 0x0100;
 
1841
    s->clkm.dsp_idlect1 = 0x0002;
 
1842
    omap_clkm_reset(s);
 
1843
    s->clkm.cold_start = 0x3a;
 
1844
 
 
1845
    memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
 
1846
    memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
 
1847
}
 
1848
 
 
1849
/* MPU I/O */
 
1850
struct omap_mpuio_s {
 
1851
    qemu_irq irq;
 
1852
    qemu_irq kbd_irq;
 
1853
    qemu_irq *in;
 
1854
    qemu_irq handler[16];
 
1855
    qemu_irq wakeup;
 
1856
    MemoryRegion iomem;
 
1857
 
 
1858
    uint16_t inputs;
 
1859
    uint16_t outputs;
 
1860
    uint16_t dir;
 
1861
    uint16_t edge;
 
1862
    uint16_t mask;
 
1863
    uint16_t ints;
 
1864
 
 
1865
    uint16_t debounce;
 
1866
    uint16_t latch;
 
1867
    uint8_t event;
 
1868
 
 
1869
    uint8_t buttons[5];
 
1870
    uint8_t row_latch;
 
1871
    uint8_t cols;
 
1872
    int kbd_mask;
 
1873
    int clk;
 
1874
};
 
1875
 
 
1876
static void omap_mpuio_set(void *opaque, int line, int level)
 
1877
{
 
1878
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
 
1879
    uint16_t prev = s->inputs;
 
1880
 
 
1881
    if (level)
 
1882
        s->inputs |= 1 << line;
 
1883
    else
 
1884
        s->inputs &= ~(1 << line);
 
1885
 
 
1886
    if (((1 << line) & s->dir & ~s->mask) && s->clk) {
 
1887
        if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
 
1888
            s->ints |= 1 << line;
 
1889
            qemu_irq_raise(s->irq);
 
1890
            /* TODO: wakeup */
 
1891
        }
 
1892
        if ((s->event & (1 << 0)) &&            /* SET_GPIO_EVENT_MODE */
 
1893
                (s->event >> 1) == line)        /* PIN_SELECT */
 
1894
            s->latch = s->inputs;
 
1895
    }
 
1896
}
 
1897
 
 
1898
static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
 
1899
{
 
1900
    int i;
 
1901
    uint8_t *row, rows = 0, cols = ~s->cols;
 
1902
 
 
1903
    for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
 
1904
        if (*row & cols)
 
1905
            rows |= i;
 
1906
 
 
1907
    qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
 
1908
    s->row_latch = ~rows;
 
1909
}
 
1910
 
 
1911
static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
 
1912
                                unsigned size)
 
1913
{
 
1914
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
 
1915
    int offset = addr & OMAP_MPUI_REG_MASK;
 
1916
    uint16_t ret;
 
1917
 
 
1918
    if (size != 2) {
 
1919
        return omap_badwidth_read16(opaque, addr);
 
1920
    }
 
1921
 
 
1922
    switch (offset) {
 
1923
    case 0x00:  /* INPUT_LATCH */
 
1924
        return s->inputs;
 
1925
 
 
1926
    case 0x04:  /* OUTPUT_REG */
 
1927
        return s->outputs;
 
1928
 
 
1929
    case 0x08:  /* IO_CNTL */
 
1930
        return s->dir;
 
1931
 
 
1932
    case 0x10:  /* KBR_LATCH */
 
1933
        return s->row_latch;
 
1934
 
 
1935
    case 0x14:  /* KBC_REG */
 
1936
        return s->cols;
 
1937
 
 
1938
    case 0x18:  /* GPIO_EVENT_MODE_REG */
 
1939
        return s->event;
 
1940
 
 
1941
    case 0x1c:  /* GPIO_INT_EDGE_REG */
 
1942
        return s->edge;
 
1943
 
 
1944
    case 0x20:  /* KBD_INT */
 
1945
        return (~s->row_latch & 0x1f) && !s->kbd_mask;
 
1946
 
 
1947
    case 0x24:  /* GPIO_INT */
 
1948
        ret = s->ints;
 
1949
        s->ints &= s->mask;
 
1950
        if (ret)
 
1951
            qemu_irq_lower(s->irq);
 
1952
        return ret;
 
1953
 
 
1954
    case 0x28:  /* KBD_MASKIT */
 
1955
        return s->kbd_mask;
 
1956
 
 
1957
    case 0x2c:  /* GPIO_MASKIT */
 
1958
        return s->mask;
 
1959
 
 
1960
    case 0x30:  /* GPIO_DEBOUNCING_REG */
 
1961
        return s->debounce;
 
1962
 
 
1963
    case 0x34:  /* GPIO_LATCH_REG */
 
1964
        return s->latch;
 
1965
    }
 
1966
 
 
1967
    OMAP_BAD_REG(addr);
 
1968
    return 0;
 
1969
}
 
1970
 
 
1971
static void omap_mpuio_write(void *opaque, hwaddr addr,
 
1972
                             uint64_t value, unsigned size)
 
1973
{
 
1974
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
 
1975
    int offset = addr & OMAP_MPUI_REG_MASK;
 
1976
    uint16_t diff;
 
1977
    int ln;
 
1978
 
 
1979
    if (size != 2) {
 
1980
        return omap_badwidth_write16(opaque, addr, value);
 
1981
    }
 
1982
 
 
1983
    switch (offset) {
 
1984
    case 0x04:  /* OUTPUT_REG */
 
1985
        diff = (s->outputs ^ value) & ~s->dir;
 
1986
        s->outputs = value;
 
1987
        while ((ln = ffs(diff))) {
 
1988
            ln --;
 
1989
            if (s->handler[ln])
 
1990
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
 
1991
            diff &= ~(1 << ln);
 
1992
        }
 
1993
        break;
 
1994
 
 
1995
    case 0x08:  /* IO_CNTL */
 
1996
        diff = s->outputs & (s->dir ^ value);
 
1997
        s->dir = value;
 
1998
 
 
1999
        value = s->outputs & ~s->dir;
 
2000
        while ((ln = ffs(diff))) {
 
2001
            ln --;
 
2002
            if (s->handler[ln])
 
2003
                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
 
2004
            diff &= ~(1 << ln);
 
2005
        }
 
2006
        break;
 
2007
 
 
2008
    case 0x14:  /* KBC_REG */
 
2009
        s->cols = value;
 
2010
        omap_mpuio_kbd_update(s);
 
2011
        break;
 
2012
 
 
2013
    case 0x18:  /* GPIO_EVENT_MODE_REG */
 
2014
        s->event = value & 0x1f;
 
2015
        break;
 
2016
 
 
2017
    case 0x1c:  /* GPIO_INT_EDGE_REG */
 
2018
        s->edge = value;
 
2019
        break;
 
2020
 
 
2021
    case 0x28:  /* KBD_MASKIT */
 
2022
        s->kbd_mask = value & 1;
 
2023
        omap_mpuio_kbd_update(s);
 
2024
        break;
 
2025
 
 
2026
    case 0x2c:  /* GPIO_MASKIT */
 
2027
        s->mask = value;
 
2028
        break;
 
2029
 
 
2030
    case 0x30:  /* GPIO_DEBOUNCING_REG */
 
2031
        s->debounce = value & 0x1ff;
 
2032
        break;
 
2033
 
 
2034
    case 0x00:  /* INPUT_LATCH */
 
2035
    case 0x10:  /* KBR_LATCH */
 
2036
    case 0x20:  /* KBD_INT */
 
2037
    case 0x24:  /* GPIO_INT */
 
2038
    case 0x34:  /* GPIO_LATCH_REG */
 
2039
        OMAP_RO_REG(addr);
 
2040
        return;
 
2041
 
 
2042
    default:
 
2043
        OMAP_BAD_REG(addr);
 
2044
        return;
 
2045
    }
 
2046
}
 
2047
 
 
2048
static const MemoryRegionOps omap_mpuio_ops  = {
 
2049
    .read = omap_mpuio_read,
 
2050
    .write = omap_mpuio_write,
 
2051
    .endianness = DEVICE_NATIVE_ENDIAN,
 
2052
};
 
2053
 
 
2054
static void omap_mpuio_reset(struct omap_mpuio_s *s)
 
2055
{
 
2056
    s->inputs = 0;
 
2057
    s->outputs = 0;
 
2058
    s->dir = ~0;
 
2059
    s->event = 0;
 
2060
    s->edge = 0;
 
2061
    s->kbd_mask = 0;
 
2062
    s->mask = 0;
 
2063
    s->debounce = 0;
 
2064
    s->latch = 0;
 
2065
    s->ints = 0;
 
2066
    s->row_latch = 0x1f;
 
2067
    s->clk = 1;
 
2068
}
 
2069
 
 
2070
static void omap_mpuio_onoff(void *opaque, int line, int on)
 
2071
{
 
2072
    struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
 
2073
 
 
2074
    s->clk = on;
 
2075
    if (on)
 
2076
        omap_mpuio_kbd_update(s);
 
2077
}
 
2078
 
 
2079
static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
 
2080
                hwaddr base,
 
2081
                qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
 
2082
                omap_clk clk)
 
2083
{
 
2084
    struct omap_mpuio_s *s = (struct omap_mpuio_s *)
 
2085
            g_malloc0(sizeof(struct omap_mpuio_s));
 
2086
 
 
2087
    s->irq = gpio_int;
 
2088
    s->kbd_irq = kbd_int;
 
2089
    s->wakeup = wakeup;
 
2090
    s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
 
2091
    omap_mpuio_reset(s);
 
2092
 
 
2093
    memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s,
 
2094
                          "omap-mpuio", 0x800);
 
2095
    memory_region_add_subregion(memory, base, &s->iomem);
 
2096
 
 
2097
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
 
2098
 
 
2099
    return s;
 
2100
}
 
2101
 
 
2102
qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
 
2103
{
 
2104
    return s->in;
 
2105
}
 
2106
 
 
2107
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
 
2108
{
 
2109
    if (line >= 16 || line < 0)
 
2110
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
 
2111
    s->handler[line] = handler;
 
2112
}
 
2113
 
 
2114
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
 
2115
{
 
2116
    if (row >= 5 || row < 0)
 
2117
        hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
 
2118
 
 
2119
    if (down)
 
2120
        s->buttons[row] |= 1 << col;
 
2121
    else
 
2122
        s->buttons[row] &= ~(1 << col);
 
2123
 
 
2124
    omap_mpuio_kbd_update(s);
 
2125
}
 
2126
 
 
2127
/* MicroWire Interface */
 
2128
struct omap_uwire_s {
 
2129
    MemoryRegion iomem;
 
2130
    qemu_irq txirq;
 
2131
    qemu_irq rxirq;
 
2132
    qemu_irq txdrq;
 
2133
 
 
2134
    uint16_t txbuf;
 
2135
    uint16_t rxbuf;
 
2136
    uint16_t control;
 
2137
    uint16_t setup[5];
 
2138
 
 
2139
    uWireSlave *chip[4];
 
2140
};
 
2141
 
 
2142
static void omap_uwire_transfer_start(struct omap_uwire_s *s)
 
2143
{
 
2144
    int chipselect = (s->control >> 10) & 3;            /* INDEX */
 
2145
    uWireSlave *slave = s->chip[chipselect];
 
2146
 
 
2147
    if ((s->control >> 5) & 0x1f) {                     /* NB_BITS_WR */
 
2148
        if (s->control & (1 << 12))                     /* CS_CMD */
 
2149
            if (slave && slave->send)
 
2150
                slave->send(slave->opaque,
 
2151
                                s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
 
2152
        s->control &= ~(1 << 14);                       /* CSRB */
 
2153
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
 
2154
         * a DRQ.  When is the level IRQ supposed to be reset?  */
 
2155
    }
 
2156
 
 
2157
    if ((s->control >> 0) & 0x1f) {                     /* NB_BITS_RD */
 
2158
        if (s->control & (1 << 12))                     /* CS_CMD */
 
2159
            if (slave && slave->receive)
 
2160
                s->rxbuf = slave->receive(slave->opaque);
 
2161
        s->control |= 1 << 15;                          /* RDRB */
 
2162
        /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
 
2163
         * a DRQ.  When is the level IRQ supposed to be reset?  */
 
2164
    }
 
2165
}
 
2166
 
 
2167
static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
 
2168
                                unsigned size)
 
2169
{
 
2170
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
 
2171
    int offset = addr & OMAP_MPUI_REG_MASK;
 
2172
 
 
2173
    if (size != 2) {
 
2174
        return omap_badwidth_read16(opaque, addr);
 
2175
    }
 
2176
 
 
2177
    switch (offset) {
 
2178
    case 0x00:  /* RDR */
 
2179
        s->control &= ~(1 << 15);                       /* RDRB */
 
2180
        return s->rxbuf;
 
2181
 
 
2182
    case 0x04:  /* CSR */
 
2183
        return s->control;
 
2184
 
 
2185
    case 0x08:  /* SR1 */
 
2186
        return s->setup[0];
 
2187
    case 0x0c:  /* SR2 */
 
2188
        return s->setup[1];
 
2189
    case 0x10:  /* SR3 */
 
2190
        return s->setup[2];
 
2191
    case 0x14:  /* SR4 */
 
2192
        return s->setup[3];
 
2193
    case 0x18:  /* SR5 */
 
2194
        return s->setup[4];
 
2195
    }
 
2196
 
 
2197
    OMAP_BAD_REG(addr);
 
2198
    return 0;
 
2199
}
 
2200
 
 
2201
static void omap_uwire_write(void *opaque, hwaddr addr,
 
2202
                             uint64_t value, unsigned size)
 
2203
{
 
2204
    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
 
2205
    int offset = addr & OMAP_MPUI_REG_MASK;
 
2206
 
 
2207
    if (size != 2) {
 
2208
        return omap_badwidth_write16(opaque, addr, value);
 
2209
    }
 
2210
 
 
2211
    switch (offset) {
 
2212
    case 0x00:  /* TDR */
 
2213
        s->txbuf = value;                               /* TD */
 
2214
        if ((s->setup[4] & (1 << 2)) &&                 /* AUTO_TX_EN */
 
2215
                        ((s->setup[4] & (1 << 3)) ||    /* CS_TOGGLE_TX_EN */
 
2216
                         (s->control & (1 << 12)))) {   /* CS_CMD */
 
2217
            s->control |= 1 << 14;                      /* CSRB */
 
2218
            omap_uwire_transfer_start(s);
 
2219
        }
 
2220
        break;
 
2221
 
 
2222
    case 0x04:  /* CSR */
 
2223
        s->control = value & 0x1fff;
 
2224
        if (value & (1 << 13))                          /* START */
 
2225
            omap_uwire_transfer_start(s);
 
2226
        break;
 
2227
 
 
2228
    case 0x08:  /* SR1 */
 
2229
        s->setup[0] = value & 0x003f;
 
2230
        break;
 
2231
 
 
2232
    case 0x0c:  /* SR2 */
 
2233
        s->setup[1] = value & 0x0fc0;
 
2234
        break;
 
2235
 
 
2236
    case 0x10:  /* SR3 */
 
2237
        s->setup[2] = value & 0x0003;
 
2238
        break;
 
2239
 
 
2240
    case 0x14:  /* SR4 */
 
2241
        s->setup[3] = value & 0x0001;
 
2242
        break;
 
2243
 
 
2244
    case 0x18:  /* SR5 */
 
2245
        s->setup[4] = value & 0x000f;
 
2246
        break;
 
2247
 
 
2248
    default:
 
2249
        OMAP_BAD_REG(addr);
 
2250
        return;
 
2251
    }
 
2252
}
 
2253
 
 
2254
static const MemoryRegionOps omap_uwire_ops = {
 
2255
    .read = omap_uwire_read,
 
2256
    .write = omap_uwire_write,
 
2257
    .endianness = DEVICE_NATIVE_ENDIAN,
 
2258
};
 
2259
 
 
2260
static void omap_uwire_reset(struct omap_uwire_s *s)
 
2261
{
 
2262
    s->control = 0;
 
2263
    s->setup[0] = 0;
 
2264
    s->setup[1] = 0;
 
2265
    s->setup[2] = 0;
 
2266
    s->setup[3] = 0;
 
2267
    s->setup[4] = 0;
 
2268
}
 
2269
 
 
2270
static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
 
2271
                                            hwaddr base,
 
2272
                                            qemu_irq txirq, qemu_irq rxirq,
 
2273
                                            qemu_irq dma,
 
2274
                                            omap_clk clk)
 
2275
{
 
2276
    struct omap_uwire_s *s = (struct omap_uwire_s *)
 
2277
            g_malloc0(sizeof(struct omap_uwire_s));
 
2278
 
 
2279
    s->txirq = txirq;
 
2280
    s->rxirq = rxirq;
 
2281
    s->txdrq = dma;
 
2282
    omap_uwire_reset(s);
 
2283
 
 
2284
    memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800);
 
2285
    memory_region_add_subregion(system_memory, base, &s->iomem);
 
2286
 
 
2287
    return s;
 
2288
}
 
2289
 
 
2290
void omap_uwire_attach(struct omap_uwire_s *s,
 
2291
                uWireSlave *slave, int chipselect)
 
2292
{
 
2293
    if (chipselect < 0 || chipselect > 3) {
 
2294
        fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
 
2295
        exit(-1);
 
2296
    }
 
2297
 
 
2298
    s->chip[chipselect] = slave;
 
2299
}
 
2300
 
 
2301
/* Pseudonoise Pulse-Width Light Modulator */
 
2302
struct omap_pwl_s {
 
2303
    MemoryRegion iomem;
 
2304
    uint8_t output;
 
2305
    uint8_t level;
 
2306
    uint8_t enable;
 
2307
    int clk;
 
2308
};
 
2309
 
 
2310
static void omap_pwl_update(struct omap_pwl_s *s)
 
2311
{
 
2312
    int output = (s->clk && s->enable) ? s->level : 0;
 
2313
 
 
2314
    if (output != s->output) {
 
2315
        s->output = output;
 
2316
        printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
 
2317
    }
 
2318
}
 
2319
 
 
2320
static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
 
2321
                              unsigned size)
 
2322
{
 
2323
    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
 
2324
    int offset = addr & OMAP_MPUI_REG_MASK;
 
2325
 
 
2326
    if (size != 1) {
 
2327
        return omap_badwidth_read8(opaque, addr);
 
2328
    }
 
2329
 
 
2330
    switch (offset) {
 
2331
    case 0x00:  /* PWL_LEVEL */
 
2332
        return s->level;
 
2333
    case 0x04:  /* PWL_CTRL */
 
2334
        return s->enable;
 
2335
    }
 
2336
    OMAP_BAD_REG(addr);
 
2337
    return 0;
 
2338
}
 
2339
 
 
2340
static void omap_pwl_write(void *opaque, hwaddr addr,
 
2341
                           uint64_t value, unsigned size)
 
2342
{
 
2343
    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
 
2344
    int offset = addr & OMAP_MPUI_REG_MASK;
 
2345
 
 
2346
    if (size != 1) {
 
2347
        return omap_badwidth_write8(opaque, addr, value);
 
2348
    }
 
2349
 
 
2350
    switch (offset) {
 
2351
    case 0x00:  /* PWL_LEVEL */
 
2352
        s->level = value;
 
2353
        omap_pwl_update(s);
 
2354
        break;
 
2355
    case 0x04:  /* PWL_CTRL */
 
2356
        s->enable = value & 1;
 
2357
        omap_pwl_update(s);
 
2358
        break;
 
2359
    default:
 
2360
        OMAP_BAD_REG(addr);
 
2361
        return;
 
2362
    }
 
2363
}
 
2364
 
 
2365
static const MemoryRegionOps omap_pwl_ops = {
 
2366
    .read = omap_pwl_read,
 
2367
    .write = omap_pwl_write,
 
2368
    .endianness = DEVICE_NATIVE_ENDIAN,
 
2369
};
 
2370
 
 
2371
static void omap_pwl_reset(struct omap_pwl_s *s)
 
2372
{
 
2373
    s->output = 0;
 
2374
    s->level = 0;
 
2375
    s->enable = 0;
 
2376
    s->clk = 1;
 
2377
    omap_pwl_update(s);
 
2378
}
 
2379
 
 
2380
static void omap_pwl_clk_update(void *opaque, int line, int on)
 
2381
{
 
2382
    struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
 
2383
 
 
2384
    s->clk = on;
 
2385
    omap_pwl_update(s);
 
2386
}
 
2387
 
 
2388
static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
 
2389
                                        hwaddr base,
 
2390
                                        omap_clk clk)
 
2391
{
 
2392
    struct omap_pwl_s *s = g_malloc0(sizeof(*s));
 
2393
 
 
2394
    omap_pwl_reset(s);
 
2395
 
 
2396
    memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s,
 
2397
                          "omap-pwl", 0x800);
 
2398
    memory_region_add_subregion(system_memory, base, &s->iomem);
 
2399
 
 
2400
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
 
2401
    return s;
 
2402
}
 
2403
 
 
2404
/* Pulse-Width Tone module */
 
2405
struct omap_pwt_s {
 
2406
    MemoryRegion iomem;
 
2407
    uint8_t frc;
 
2408
    uint8_t vrc;
 
2409
    uint8_t gcr;
 
2410
    omap_clk clk;
 
2411
};
 
2412
 
 
2413
static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
 
2414
                              unsigned size)
 
2415
{
 
2416
    struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
 
2417
    int offset = addr & OMAP_MPUI_REG_MASK;
 
2418
 
 
2419
    if (size != 1) {
 
2420
        return omap_badwidth_read8(opaque, addr);
 
2421
    }
 
2422
 
 
2423
    switch (offset) {
 
2424
    case 0x00:  /* FRC */
 
2425
        return s->frc;
 
2426
    case 0x04:  /* VCR */
 
2427
        return s->vrc;
 
2428
    case 0x08:  /* GCR */
 
2429
        return s->gcr;
 
2430
    }
 
2431
    OMAP_BAD_REG(addr);
 
2432
    return 0;
 
2433
}
 
2434
 
 
2435
static void omap_pwt_write(void *opaque, hwaddr addr,
 
2436
                           uint64_t value, unsigned size)
 
2437
{
 
2438
    struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
 
2439
    int offset = addr & OMAP_MPUI_REG_MASK;
 
2440
 
 
2441
    if (size != 1) {
 
2442
        return omap_badwidth_write8(opaque, addr, value);
 
2443
    }
 
2444
 
 
2445
    switch (offset) {
 
2446
    case 0x00:  /* FRC */
 
2447
        s->frc = value & 0x3f;
 
2448
        break;
 
2449
    case 0x04:  /* VRC */
 
2450
        if ((value ^ s->vrc) & 1) {
 
2451
            if (value & 1)
 
2452
                printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
 
2453
                                /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
 
2454
                                ((omap_clk_getrate(s->clk) >> 3) /
 
2455
                                 /* Pre-multiplexer divider */
 
2456
                                 ((s->gcr & 2) ? 1 : 154) /
 
2457
                                 /* Octave multiplexer */
 
2458
                                 (2 << (value & 3)) *
 
2459
                                 /* 101/107 divider */
 
2460
                                 ((value & (1 << 2)) ? 101 : 107) *
 
2461
                                 /*  49/55 divider */
 
2462
                                 ((value & (1 << 3)) ?  49 : 55) *
 
2463
                                 /*  50/63 divider */
 
2464
                                 ((value & (1 << 4)) ?  50 : 63) *
 
2465
                                 /*  80/127 divider */
 
2466
                                 ((value & (1 << 5)) ?  80 : 127) /
 
2467
                                 (107 * 55 * 63 * 127)));
 
2468
            else
 
2469
                printf("%s: silence!\n", __FUNCTION__);
 
2470
        }
 
2471
        s->vrc = value & 0x7f;
 
2472
        break;
 
2473
    case 0x08:  /* GCR */
 
2474
        s->gcr = value & 3;
 
2475
        break;
 
2476
    default:
 
2477
        OMAP_BAD_REG(addr);
 
2478
        return;
 
2479
    }
 
2480
}
 
2481
 
 
2482
static const MemoryRegionOps omap_pwt_ops = {
 
2483
    .read =omap_pwt_read,
 
2484
    .write = omap_pwt_write,
 
2485
    .endianness = DEVICE_NATIVE_ENDIAN,
 
2486
};
 
2487
 
 
2488
static void omap_pwt_reset(struct omap_pwt_s *s)
 
2489
{
 
2490
    s->frc = 0;
 
2491
    s->vrc = 0;
 
2492
    s->gcr = 0;
 
2493
}
 
2494
 
 
2495
static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
 
2496
                                        hwaddr base,
 
2497
                                        omap_clk clk)
 
2498
{
 
2499
    struct omap_pwt_s *s = g_malloc0(sizeof(*s));
 
2500
    s->clk = clk;
 
2501
    omap_pwt_reset(s);
 
2502
 
 
2503
    memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s,
 
2504
                          "omap-pwt", 0x800);
 
2505
    memory_region_add_subregion(system_memory, base, &s->iomem);
 
2506
    return s;
 
2507
}
 
2508
 
 
2509
/* Real-time Clock module */
 
2510
struct omap_rtc_s {
 
2511
    MemoryRegion iomem;
 
2512
    qemu_irq irq;
 
2513
    qemu_irq alarm;
 
2514
    QEMUTimer *clk;
 
2515
 
 
2516
    uint8_t interrupts;
 
2517
    uint8_t status;
 
2518
    int16_t comp_reg;
 
2519
    int running;
 
2520
    int pm_am;
 
2521
    int auto_comp;
 
2522
    int round;
 
2523
    struct tm alarm_tm;
 
2524
    time_t alarm_ti;
 
2525
 
 
2526
    struct tm current_tm;
 
2527
    time_t ti;
 
2528
    uint64_t tick;
 
2529
};
 
2530
 
 
2531
static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
 
2532
{
 
2533
    /* s->alarm is level-triggered */
 
2534
    qemu_set_irq(s->alarm, (s->status >> 6) & 1);
 
2535
}
 
2536
 
 
2537
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
 
2538
{
 
2539
    s->alarm_ti = mktimegm(&s->alarm_tm);
 
2540
    if (s->alarm_ti == -1)
 
2541
        printf("%s: conversion failed\n", __FUNCTION__);
 
2542
}
 
2543
 
 
2544
static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
 
2545
                              unsigned size)
 
2546
{
 
2547
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
 
2548
    int offset = addr & OMAP_MPUI_REG_MASK;
 
2549
    uint8_t i;
 
2550
 
 
2551
    if (size != 1) {
 
2552
        return omap_badwidth_read8(opaque, addr);
 
2553
    }
 
2554
 
 
2555
    switch (offset) {
 
2556
    case 0x00:  /* SECONDS_REG */
 
2557
        return to_bcd(s->current_tm.tm_sec);
 
2558
 
 
2559
    case 0x04:  /* MINUTES_REG */
 
2560
        return to_bcd(s->current_tm.tm_min);
 
2561
 
 
2562
    case 0x08:  /* HOURS_REG */
 
2563
        if (s->pm_am)
 
2564
            return ((s->current_tm.tm_hour > 11) << 7) |
 
2565
                    to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
 
2566
        else
 
2567
            return to_bcd(s->current_tm.tm_hour);
 
2568
 
 
2569
    case 0x0c:  /* DAYS_REG */
 
2570
        return to_bcd(s->current_tm.tm_mday);
 
2571
 
 
2572
    case 0x10:  /* MONTHS_REG */
 
2573
        return to_bcd(s->current_tm.tm_mon + 1);
 
2574
 
 
2575
    case 0x14:  /* YEARS_REG */
 
2576
        return to_bcd(s->current_tm.tm_year % 100);
 
2577
 
 
2578
    case 0x18:  /* WEEK_REG */
 
2579
        return s->current_tm.tm_wday;
 
2580
 
 
2581
    case 0x20:  /* ALARM_SECONDS_REG */
 
2582
        return to_bcd(s->alarm_tm.tm_sec);
 
2583
 
 
2584
    case 0x24:  /* ALARM_MINUTES_REG */
 
2585
        return to_bcd(s->alarm_tm.tm_min);
 
2586
 
 
2587
    case 0x28:  /* ALARM_HOURS_REG */
 
2588
        if (s->pm_am)
 
2589
            return ((s->alarm_tm.tm_hour > 11) << 7) |
 
2590
                    to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
 
2591
        else
 
2592
            return to_bcd(s->alarm_tm.tm_hour);
 
2593
 
 
2594
    case 0x2c:  /* ALARM_DAYS_REG */
 
2595
        return to_bcd(s->alarm_tm.tm_mday);
 
2596
 
 
2597
    case 0x30:  /* ALARM_MONTHS_REG */
 
2598
        return to_bcd(s->alarm_tm.tm_mon + 1);
 
2599
 
 
2600
    case 0x34:  /* ALARM_YEARS_REG */
 
2601
        return to_bcd(s->alarm_tm.tm_year % 100);
 
2602
 
 
2603
    case 0x40:  /* RTC_CTRL_REG */
 
2604
        return (s->pm_am << 3) | (s->auto_comp << 2) |
 
2605
                (s->round << 1) | s->running;
 
2606
 
 
2607
    case 0x44:  /* RTC_STATUS_REG */
 
2608
        i = s->status;
 
2609
        s->status &= ~0x3d;
 
2610
        return i;
 
2611
 
 
2612
    case 0x48:  /* RTC_INTERRUPTS_REG */
 
2613
        return s->interrupts;
 
2614
 
 
2615
    case 0x4c:  /* RTC_COMP_LSB_REG */
 
2616
        return ((uint16_t) s->comp_reg) & 0xff;
 
2617
 
 
2618
    case 0x50:  /* RTC_COMP_MSB_REG */
 
2619
        return ((uint16_t) s->comp_reg) >> 8;
 
2620
    }
 
2621
 
 
2622
    OMAP_BAD_REG(addr);
 
2623
    return 0;
 
2624
}
 
2625
 
 
2626
static void omap_rtc_write(void *opaque, hwaddr addr,
 
2627
                           uint64_t value, unsigned size)
 
2628
{
 
2629
    struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
 
2630
    int offset = addr & OMAP_MPUI_REG_MASK;
 
2631
    struct tm new_tm;
 
2632
    time_t ti[2];
 
2633
 
 
2634
    if (size != 1) {
 
2635
        return omap_badwidth_write8(opaque, addr, value);
 
2636
    }
 
2637
 
 
2638
    switch (offset) {
 
2639
    case 0x00:  /* SECONDS_REG */
 
2640
#ifdef ALMDEBUG
 
2641
        printf("RTC SEC_REG <-- %02x\n", value);
 
2642
#endif
 
2643
        s->ti -= s->current_tm.tm_sec;
 
2644
        s->ti += from_bcd(value);
 
2645
        return;
 
2646
 
 
2647
    case 0x04:  /* MINUTES_REG */
 
2648
#ifdef ALMDEBUG
 
2649
        printf("RTC MIN_REG <-- %02x\n", value);
 
2650
#endif
 
2651
        s->ti -= s->current_tm.tm_min * 60;
 
2652
        s->ti += from_bcd(value) * 60;
 
2653
        return;
 
2654
 
 
2655
    case 0x08:  /* HOURS_REG */
 
2656
#ifdef ALMDEBUG
 
2657
        printf("RTC HRS_REG <-- %02x\n", value);
 
2658
#endif
 
2659
        s->ti -= s->current_tm.tm_hour * 3600;
 
2660
        if (s->pm_am) {
 
2661
            s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
 
2662
            s->ti += ((value >> 7) & 1) * 43200;
 
2663
        } else
 
2664
            s->ti += from_bcd(value & 0x3f) * 3600;
 
2665
        return;
 
2666
 
 
2667
    case 0x0c:  /* DAYS_REG */
 
2668
#ifdef ALMDEBUG
 
2669
        printf("RTC DAY_REG <-- %02x\n", value);
 
2670
#endif
 
2671
        s->ti -= s->current_tm.tm_mday * 86400;
 
2672
        s->ti += from_bcd(value) * 86400;
 
2673
        return;
 
2674
 
 
2675
    case 0x10:  /* MONTHS_REG */
 
2676
#ifdef ALMDEBUG
 
2677
        printf("RTC MTH_REG <-- %02x\n", value);
 
2678
#endif
 
2679
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
 
2680
        new_tm.tm_mon = from_bcd(value);
 
2681
        ti[0] = mktimegm(&s->current_tm);
 
2682
        ti[1] = mktimegm(&new_tm);
 
2683
 
 
2684
        if (ti[0] != -1 && ti[1] != -1) {
 
2685
            s->ti -= ti[0];
 
2686
            s->ti += ti[1];
 
2687
        } else {
 
2688
            /* A less accurate version */
 
2689
            s->ti -= s->current_tm.tm_mon * 2592000;
 
2690
            s->ti += from_bcd(value) * 2592000;
 
2691
        }
 
2692
        return;
 
2693
 
 
2694
    case 0x14:  /* YEARS_REG */
 
2695
#ifdef ALMDEBUG
 
2696
        printf("RTC YRS_REG <-- %02x\n", value);
 
2697
#endif
 
2698
        memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
 
2699
        new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
 
2700
        ti[0] = mktimegm(&s->current_tm);
 
2701
        ti[1] = mktimegm(&new_tm);
 
2702
 
 
2703
        if (ti[0] != -1 && ti[1] != -1) {
 
2704
            s->ti -= ti[0];
 
2705
            s->ti += ti[1];
 
2706
        } else {
 
2707
            /* A less accurate version */
 
2708
            s->ti -= (s->current_tm.tm_year % 100) * 31536000;
 
2709
            s->ti += from_bcd(value) * 31536000;
 
2710
        }
 
2711
        return;
 
2712
 
 
2713
    case 0x18:  /* WEEK_REG */
 
2714
        return; /* Ignored */
 
2715
 
 
2716
    case 0x20:  /* ALARM_SECONDS_REG */
 
2717
#ifdef ALMDEBUG
 
2718
        printf("ALM SEC_REG <-- %02x\n", value);
 
2719
#endif
 
2720
        s->alarm_tm.tm_sec = from_bcd(value);
 
2721
        omap_rtc_alarm_update(s);
 
2722
        return;
 
2723
 
 
2724
    case 0x24:  /* ALARM_MINUTES_REG */
 
2725
#ifdef ALMDEBUG
 
2726
        printf("ALM MIN_REG <-- %02x\n", value);
 
2727
#endif
 
2728
        s->alarm_tm.tm_min = from_bcd(value);
 
2729
        omap_rtc_alarm_update(s);
 
2730
        return;
 
2731
 
 
2732
    case 0x28:  /* ALARM_HOURS_REG */
 
2733
#ifdef ALMDEBUG
 
2734
        printf("ALM HRS_REG <-- %02x\n", value);
 
2735
#endif
 
2736
        if (s->pm_am)
 
2737
            s->alarm_tm.tm_hour =
 
2738
                    ((from_bcd(value & 0x3f)) % 12) +
 
2739
                    ((value >> 7) & 1) * 12;
 
2740
        else
 
2741
            s->alarm_tm.tm_hour = from_bcd(value);
 
2742
        omap_rtc_alarm_update(s);
 
2743
        return;
 
2744
 
 
2745
    case 0x2c:  /* ALARM_DAYS_REG */
 
2746
#ifdef ALMDEBUG
 
2747
        printf("ALM DAY_REG <-- %02x\n", value);
 
2748
#endif
 
2749
        s->alarm_tm.tm_mday = from_bcd(value);
 
2750
        omap_rtc_alarm_update(s);
 
2751
        return;
 
2752
 
 
2753
    case 0x30:  /* ALARM_MONTHS_REG */
 
2754
#ifdef ALMDEBUG
 
2755
        printf("ALM MON_REG <-- %02x\n", value);
 
2756
#endif
 
2757
        s->alarm_tm.tm_mon = from_bcd(value);
 
2758
        omap_rtc_alarm_update(s);
 
2759
        return;
 
2760
 
 
2761
    case 0x34:  /* ALARM_YEARS_REG */
 
2762
#ifdef ALMDEBUG
 
2763
        printf("ALM YRS_REG <-- %02x\n", value);
 
2764
#endif
 
2765
        s->alarm_tm.tm_year = from_bcd(value);
 
2766
        omap_rtc_alarm_update(s);
 
2767
        return;
 
2768
 
 
2769
    case 0x40:  /* RTC_CTRL_REG */
 
2770
#ifdef ALMDEBUG
 
2771
        printf("RTC CONTROL <-- %02x\n", value);
 
2772
#endif
 
2773
        s->pm_am = (value >> 3) & 1;
 
2774
        s->auto_comp = (value >> 2) & 1;
 
2775
        s->round = (value >> 1) & 1;
 
2776
        s->running = value & 1;
 
2777
        s->status &= 0xfd;
 
2778
        s->status |= s->running << 1;
 
2779
        return;
 
2780
 
 
2781
    case 0x44:  /* RTC_STATUS_REG */
 
2782
#ifdef ALMDEBUG
 
2783
        printf("RTC STATUSL <-- %02x\n", value);
 
2784
#endif
 
2785
        s->status &= ~((value & 0xc0) ^ 0x80);
 
2786
        omap_rtc_interrupts_update(s);
 
2787
        return;
 
2788
 
 
2789
    case 0x48:  /* RTC_INTERRUPTS_REG */
 
2790
#ifdef ALMDEBUG
 
2791
        printf("RTC INTRS <-- %02x\n", value);
 
2792
#endif
 
2793
        s->interrupts = value;
 
2794
        return;
 
2795
 
 
2796
    case 0x4c:  /* RTC_COMP_LSB_REG */
 
2797
#ifdef ALMDEBUG
 
2798
        printf("RTC COMPLSB <-- %02x\n", value);
 
2799
#endif
 
2800
        s->comp_reg &= 0xff00;
 
2801
        s->comp_reg |= 0x00ff & value;
 
2802
        return;
 
2803
 
 
2804
    case 0x50:  /* RTC_COMP_MSB_REG */
 
2805
#ifdef ALMDEBUG
 
2806
        printf("RTC COMPMSB <-- %02x\n", value);
 
2807
#endif
 
2808
        s->comp_reg &= 0x00ff;
 
2809
        s->comp_reg |= 0xff00 & (value << 8);
 
2810
        return;
 
2811
 
 
2812
    default:
 
2813
        OMAP_BAD_REG(addr);
 
2814
        return;
 
2815
    }
 
2816
}
 
2817
 
 
2818
static const MemoryRegionOps omap_rtc_ops = {
 
2819
    .read = omap_rtc_read,
 
2820
    .write = omap_rtc_write,
 
2821
    .endianness = DEVICE_NATIVE_ENDIAN,
 
2822
};
 
2823
 
 
2824
static void omap_rtc_tick(void *opaque)
 
2825
{
 
2826
    struct omap_rtc_s *s = opaque;
 
2827
 
 
2828
    if (s->round) {
 
2829
        /* Round to nearest full minute.  */
 
2830
        if (s->current_tm.tm_sec < 30)
 
2831
            s->ti -= s->current_tm.tm_sec;
 
2832
        else
 
2833
            s->ti += 60 - s->current_tm.tm_sec;
 
2834
 
 
2835
        s->round = 0;
 
2836
    }
 
2837
 
 
2838
    localtime_r(&s->ti, &s->current_tm);
 
2839
 
 
2840
    if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
 
2841
        s->status |= 0x40;
 
2842
        omap_rtc_interrupts_update(s);
 
2843
    }
 
2844
 
 
2845
    if (s->interrupts & 0x04)
 
2846
        switch (s->interrupts & 3) {
 
2847
        case 0:
 
2848
            s->status |= 0x04;
 
2849
            qemu_irq_pulse(s->irq);
 
2850
            break;
 
2851
        case 1:
 
2852
            if (s->current_tm.tm_sec)
 
2853
                break;
 
2854
            s->status |= 0x08;
 
2855
            qemu_irq_pulse(s->irq);
 
2856
            break;
 
2857
        case 2:
 
2858
            if (s->current_tm.tm_sec || s->current_tm.tm_min)
 
2859
                break;
 
2860
            s->status |= 0x10;
 
2861
            qemu_irq_pulse(s->irq);
 
2862
            break;
 
2863
        case 3:
 
2864
            if (s->current_tm.tm_sec ||
 
2865
                            s->current_tm.tm_min || s->current_tm.tm_hour)
 
2866
                break;
 
2867
            s->status |= 0x20;
 
2868
            qemu_irq_pulse(s->irq);
 
2869
            break;
 
2870
        }
 
2871
 
 
2872
    /* Move on */
 
2873
    if (s->running)
 
2874
        s->ti ++;
 
2875
    s->tick += 1000;
 
2876
 
 
2877
    /*
 
2878
     * Every full hour add a rough approximation of the compensation
 
2879
     * register to the 32kHz Timer (which drives the RTC) value. 
 
2880
     */
 
2881
    if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
 
2882
        s->tick += s->comp_reg * 1000 / 32768;
 
2883
 
 
2884
    timer_mod(s->clk, s->tick);
 
2885
}
 
2886
 
 
2887
static void omap_rtc_reset(struct omap_rtc_s *s)
 
2888
{
 
2889
    struct tm tm;
 
2890
 
 
2891
    s->interrupts = 0;
 
2892
    s->comp_reg = 0;
 
2893
    s->running = 0;
 
2894
    s->pm_am = 0;
 
2895
    s->auto_comp = 0;
 
2896
    s->round = 0;
 
2897
    s->tick = qemu_clock_get_ms(rtc_clock);
 
2898
    memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
 
2899
    s->alarm_tm.tm_mday = 0x01;
 
2900
    s->status = 1 << 7;
 
2901
    qemu_get_timedate(&tm, 0);
 
2902
    s->ti = mktimegm(&tm);
 
2903
 
 
2904
    omap_rtc_alarm_update(s);
 
2905
    omap_rtc_tick(s);
 
2906
}
 
2907
 
 
2908
static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
 
2909
                                        hwaddr base,
 
2910
                                        qemu_irq timerirq, qemu_irq alarmirq,
 
2911
                                        omap_clk clk)
 
2912
{
 
2913
    struct omap_rtc_s *s = (struct omap_rtc_s *)
 
2914
            g_malloc0(sizeof(struct omap_rtc_s));
 
2915
 
 
2916
    s->irq = timerirq;
 
2917
    s->alarm = alarmirq;
 
2918
    s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);
 
2919
 
 
2920
    omap_rtc_reset(s);
 
2921
 
 
2922
    memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,
 
2923
                          "omap-rtc", 0x800);
 
2924
    memory_region_add_subregion(system_memory, base, &s->iomem);
 
2925
 
 
2926
    return s;
 
2927
}
 
2928
 
 
2929
/* Multi-channel Buffered Serial Port interfaces */
 
2930
struct omap_mcbsp_s {
 
2931
    MemoryRegion iomem;
 
2932
    qemu_irq txirq;
 
2933
    qemu_irq rxirq;
 
2934
    qemu_irq txdrq;
 
2935
    qemu_irq rxdrq;
 
2936
 
 
2937
    uint16_t spcr[2];
 
2938
    uint16_t rcr[2];
 
2939
    uint16_t xcr[2];
 
2940
    uint16_t srgr[2];
 
2941
    uint16_t mcr[2];
 
2942
    uint16_t pcr;
 
2943
    uint16_t rcer[8];
 
2944
    uint16_t xcer[8];
 
2945
    int tx_rate;
 
2946
    int rx_rate;
 
2947
    int tx_req;
 
2948
    int rx_req;
 
2949
 
 
2950
    I2SCodec *codec;
 
2951
    QEMUTimer *source_timer;
 
2952
    QEMUTimer *sink_timer;
 
2953
};
 
2954
 
 
2955
static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
 
2956
{
 
2957
    int irq;
 
2958
 
 
2959
    switch ((s->spcr[0] >> 4) & 3) {                    /* RINTM */
 
2960
    case 0:
 
2961
        irq = (s->spcr[0] >> 1) & 1;                    /* RRDY */
 
2962
        break;
 
2963
    case 3:
 
2964
        irq = (s->spcr[0] >> 3) & 1;                    /* RSYNCERR */
 
2965
        break;
 
2966
    default:
 
2967
        irq = 0;
 
2968
        break;
 
2969
    }
 
2970
 
 
2971
    if (irq)
 
2972
        qemu_irq_pulse(s->rxirq);
 
2973
 
 
2974
    switch ((s->spcr[1] >> 4) & 3) {                    /* XINTM */
 
2975
    case 0:
 
2976
        irq = (s->spcr[1] >> 1) & 1;                    /* XRDY */
 
2977
        break;
 
2978
    case 3:
 
2979
        irq = (s->spcr[1] >> 3) & 1;                    /* XSYNCERR */
 
2980
        break;
 
2981
    default:
 
2982
        irq = 0;
 
2983
        break;
 
2984
    }
 
2985
 
 
2986
    if (irq)
 
2987
        qemu_irq_pulse(s->txirq);
 
2988
}
 
2989
 
 
2990
static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
 
2991
{
 
2992
    if ((s->spcr[0] >> 1) & 1)                          /* RRDY */
 
2993
        s->spcr[0] |= 1 << 2;                           /* RFULL */
 
2994
    s->spcr[0] |= 1 << 1;                               /* RRDY */
 
2995
    qemu_irq_raise(s->rxdrq);
 
2996
    omap_mcbsp_intr_update(s);
 
2997
}
 
2998
 
 
2999
static void omap_mcbsp_source_tick(void *opaque)
 
3000
{
 
3001
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
3002
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
 
3003
 
 
3004
    if (!s->rx_rate)
 
3005
        return;
 
3006
    if (s->rx_req)
 
3007
        printf("%s: Rx FIFO overrun\n", __FUNCTION__);
 
3008
 
 
3009
    s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
 
3010
 
 
3011
    omap_mcbsp_rx_newdata(s);
 
3012
    timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
 
3013
                   get_ticks_per_sec());
 
3014
}
 
3015
 
 
3016
static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
 
3017
{
 
3018
    if (!s->codec || !s->codec->rts)
 
3019
        omap_mcbsp_source_tick(s);
 
3020
    else if (s->codec->in.len) {
 
3021
        s->rx_req = s->codec->in.len;
 
3022
        omap_mcbsp_rx_newdata(s);
 
3023
    }
 
3024
}
 
3025
 
 
3026
static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
 
3027
{
 
3028
    timer_del(s->source_timer);
 
3029
}
 
3030
 
 
3031
static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
 
3032
{
 
3033
    s->spcr[0] &= ~(1 << 1);                            /* RRDY */
 
3034
    qemu_irq_lower(s->rxdrq);
 
3035
    omap_mcbsp_intr_update(s);
 
3036
}
 
3037
 
 
3038
static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
 
3039
{
 
3040
    s->spcr[1] |= 1 << 1;                               /* XRDY */
 
3041
    qemu_irq_raise(s->txdrq);
 
3042
    omap_mcbsp_intr_update(s);
 
3043
}
 
3044
 
 
3045
static void omap_mcbsp_sink_tick(void *opaque)
 
3046
{
 
3047
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
3048
    static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
 
3049
 
 
3050
    if (!s->tx_rate)
 
3051
        return;
 
3052
    if (s->tx_req)
 
3053
        printf("%s: Tx FIFO underrun\n", __FUNCTION__);
 
3054
 
 
3055
    s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
 
3056
 
 
3057
    omap_mcbsp_tx_newdata(s);
 
3058
    timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
 
3059
                   get_ticks_per_sec());
 
3060
}
 
3061
 
 
3062
static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
 
3063
{
 
3064
    if (!s->codec || !s->codec->cts)
 
3065
        omap_mcbsp_sink_tick(s);
 
3066
    else if (s->codec->out.size) {
 
3067
        s->tx_req = s->codec->out.size;
 
3068
        omap_mcbsp_tx_newdata(s);
 
3069
    }
 
3070
}
 
3071
 
 
3072
static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
 
3073
{
 
3074
    s->spcr[1] &= ~(1 << 1);                            /* XRDY */
 
3075
    qemu_irq_lower(s->txdrq);
 
3076
    omap_mcbsp_intr_update(s);
 
3077
    if (s->codec && s->codec->cts)
 
3078
        s->codec->tx_swallow(s->codec->opaque);
 
3079
}
 
3080
 
 
3081
static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
 
3082
{
 
3083
    s->tx_req = 0;
 
3084
    omap_mcbsp_tx_done(s);
 
3085
    timer_del(s->sink_timer);
 
3086
}
 
3087
 
 
3088
static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
 
3089
{
 
3090
    int prev_rx_rate, prev_tx_rate;
 
3091
    int rx_rate = 0, tx_rate = 0;
 
3092
    int cpu_rate = 1500000;     /* XXX */
 
3093
 
 
3094
    /* TODO: check CLKSTP bit */
 
3095
    if (s->spcr[1] & (1 << 6)) {                        /* GRST */
 
3096
        if (s->spcr[0] & (1 << 0)) {                    /* RRST */
 
3097
            if ((s->srgr[1] & (1 << 13)) &&             /* CLKSM */
 
3098
                            (s->pcr & (1 << 8))) {      /* CLKRM */
 
3099
                if (~s->pcr & (1 << 7))                 /* SCLKME */
 
3100
                    rx_rate = cpu_rate /
 
3101
                            ((s->srgr[0] & 0xff) + 1);  /* CLKGDV */
 
3102
            } else
 
3103
                if (s->codec)
 
3104
                    rx_rate = s->codec->rx_rate;
 
3105
        }
 
3106
 
 
3107
        if (s->spcr[1] & (1 << 0)) {                    /* XRST */
 
3108
            if ((s->srgr[1] & (1 << 13)) &&             /* CLKSM */
 
3109
                            (s->pcr & (1 << 9))) {      /* CLKXM */
 
3110
                if (~s->pcr & (1 << 7))                 /* SCLKME */
 
3111
                    tx_rate = cpu_rate /
 
3112
                            ((s->srgr[0] & 0xff) + 1);  /* CLKGDV */
 
3113
            } else
 
3114
                if (s->codec)
 
3115
                    tx_rate = s->codec->tx_rate;
 
3116
        }
 
3117
    }
 
3118
    prev_tx_rate = s->tx_rate;
 
3119
    prev_rx_rate = s->rx_rate;
 
3120
    s->tx_rate = tx_rate;
 
3121
    s->rx_rate = rx_rate;
 
3122
 
 
3123
    if (s->codec)
 
3124
        s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
 
3125
 
 
3126
    if (!prev_tx_rate && tx_rate)
 
3127
        omap_mcbsp_tx_start(s);
 
3128
    else if (s->tx_rate && !tx_rate)
 
3129
        omap_mcbsp_tx_stop(s);
 
3130
 
 
3131
    if (!prev_rx_rate && rx_rate)
 
3132
        omap_mcbsp_rx_start(s);
 
3133
    else if (prev_tx_rate && !tx_rate)
 
3134
        omap_mcbsp_rx_stop(s);
 
3135
}
 
3136
 
 
3137
static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
 
3138
                                unsigned size)
 
3139
{
 
3140
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
3141
    int offset = addr & OMAP_MPUI_REG_MASK;
 
3142
    uint16_t ret;
 
3143
 
 
3144
    if (size != 2) {
 
3145
        return omap_badwidth_read16(opaque, addr);
 
3146
    }
 
3147
 
 
3148
    switch (offset) {
 
3149
    case 0x00:  /* DRR2 */
 
3150
        if (((s->rcr[0] >> 5) & 7) < 3)                 /* RWDLEN1 */
 
3151
            return 0x0000;
 
3152
        /* Fall through.  */
 
3153
    case 0x02:  /* DRR1 */
 
3154
        if (s->rx_req < 2) {
 
3155
            printf("%s: Rx FIFO underrun\n", __FUNCTION__);
 
3156
            omap_mcbsp_rx_done(s);
 
3157
        } else {
 
3158
            s->tx_req -= 2;
 
3159
            if (s->codec && s->codec->in.len >= 2) {
 
3160
                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
 
3161
                ret |= s->codec->in.fifo[s->codec->in.start ++];
 
3162
                s->codec->in.len -= 2;
 
3163
            } else
 
3164
                ret = 0x0000;
 
3165
            if (!s->tx_req)
 
3166
                omap_mcbsp_rx_done(s);
 
3167
            return ret;
 
3168
        }
 
3169
        return 0x0000;
 
3170
 
 
3171
    case 0x04:  /* DXR2 */
 
3172
    case 0x06:  /* DXR1 */
 
3173
        return 0x0000;
 
3174
 
 
3175
    case 0x08:  /* SPCR2 */
 
3176
        return s->spcr[1];
 
3177
    case 0x0a:  /* SPCR1 */
 
3178
        return s->spcr[0];
 
3179
    case 0x0c:  /* RCR2 */
 
3180
        return s->rcr[1];
 
3181
    case 0x0e:  /* RCR1 */
 
3182
        return s->rcr[0];
 
3183
    case 0x10:  /* XCR2 */
 
3184
        return s->xcr[1];
 
3185
    case 0x12:  /* XCR1 */
 
3186
        return s->xcr[0];
 
3187
    case 0x14:  /* SRGR2 */
 
3188
        return s->srgr[1];
 
3189
    case 0x16:  /* SRGR1 */
 
3190
        return s->srgr[0];
 
3191
    case 0x18:  /* MCR2 */
 
3192
        return s->mcr[1];
 
3193
    case 0x1a:  /* MCR1 */
 
3194
        return s->mcr[0];
 
3195
    case 0x1c:  /* RCERA */
 
3196
        return s->rcer[0];
 
3197
    case 0x1e:  /* RCERB */
 
3198
        return s->rcer[1];
 
3199
    case 0x20:  /* XCERA */
 
3200
        return s->xcer[0];
 
3201
    case 0x22:  /* XCERB */
 
3202
        return s->xcer[1];
 
3203
    case 0x24:  /* PCR0 */
 
3204
        return s->pcr;
 
3205
    case 0x26:  /* RCERC */
 
3206
        return s->rcer[2];
 
3207
    case 0x28:  /* RCERD */
 
3208
        return s->rcer[3];
 
3209
    case 0x2a:  /* XCERC */
 
3210
        return s->xcer[2];
 
3211
    case 0x2c:  /* XCERD */
 
3212
        return s->xcer[3];
 
3213
    case 0x2e:  /* RCERE */
 
3214
        return s->rcer[4];
 
3215
    case 0x30:  /* RCERF */
 
3216
        return s->rcer[5];
 
3217
    case 0x32:  /* XCERE */
 
3218
        return s->xcer[4];
 
3219
    case 0x34:  /* XCERF */
 
3220
        return s->xcer[5];
 
3221
    case 0x36:  /* RCERG */
 
3222
        return s->rcer[6];
 
3223
    case 0x38:  /* RCERH */
 
3224
        return s->rcer[7];
 
3225
    case 0x3a:  /* XCERG */
 
3226
        return s->xcer[6];
 
3227
    case 0x3c:  /* XCERH */
 
3228
        return s->xcer[7];
 
3229
    }
 
3230
 
 
3231
    OMAP_BAD_REG(addr);
 
3232
    return 0;
 
3233
}
 
3234
 
 
3235
static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
 
3236
                uint32_t value)
 
3237
{
 
3238
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
3239
    int offset = addr & OMAP_MPUI_REG_MASK;
 
3240
 
 
3241
    switch (offset) {
 
3242
    case 0x00:  /* DRR2 */
 
3243
    case 0x02:  /* DRR1 */
 
3244
        OMAP_RO_REG(addr);
 
3245
        return;
 
3246
 
 
3247
    case 0x04:  /* DXR2 */
 
3248
        if (((s->xcr[0] >> 5) & 7) < 3)                 /* XWDLEN1 */
 
3249
            return;
 
3250
        /* Fall through.  */
 
3251
    case 0x06:  /* DXR1 */
 
3252
        if (s->tx_req > 1) {
 
3253
            s->tx_req -= 2;
 
3254
            if (s->codec && s->codec->cts) {
 
3255
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
 
3256
                s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
 
3257
            }
 
3258
            if (s->tx_req < 2)
 
3259
                omap_mcbsp_tx_done(s);
 
3260
        } else
 
3261
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
 
3262
        return;
 
3263
 
 
3264
    case 0x08:  /* SPCR2 */
 
3265
        s->spcr[1] &= 0x0002;
 
3266
        s->spcr[1] |= 0x03f9 & value;
 
3267
        s->spcr[1] |= 0x0004 & (value << 2);            /* XEMPTY := XRST */
 
3268
        if (~value & 1)                                 /* XRST */
 
3269
            s->spcr[1] &= ~6;
 
3270
        omap_mcbsp_req_update(s);
 
3271
        return;
 
3272
    case 0x0a:  /* SPCR1 */
 
3273
        s->spcr[0] &= 0x0006;
 
3274
        s->spcr[0] |= 0xf8f9 & value;
 
3275
        if (value & (1 << 15))                          /* DLB */
 
3276
            printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
 
3277
        if (~value & 1) {                               /* RRST */
 
3278
            s->spcr[0] &= ~6;
 
3279
            s->rx_req = 0;
 
3280
            omap_mcbsp_rx_done(s);
 
3281
        }
 
3282
        omap_mcbsp_req_update(s);
 
3283
        return;
 
3284
 
 
3285
    case 0x0c:  /* RCR2 */
 
3286
        s->rcr[1] = value & 0xffff;
 
3287
        return;
 
3288
    case 0x0e:  /* RCR1 */
 
3289
        s->rcr[0] = value & 0x7fe0;
 
3290
        return;
 
3291
    case 0x10:  /* XCR2 */
 
3292
        s->xcr[1] = value & 0xffff;
 
3293
        return;
 
3294
    case 0x12:  /* XCR1 */
 
3295
        s->xcr[0] = value & 0x7fe0;
 
3296
        return;
 
3297
    case 0x14:  /* SRGR2 */
 
3298
        s->srgr[1] = value & 0xffff;
 
3299
        omap_mcbsp_req_update(s);
 
3300
        return;
 
3301
    case 0x16:  /* SRGR1 */
 
3302
        s->srgr[0] = value & 0xffff;
 
3303
        omap_mcbsp_req_update(s);
 
3304
        return;
 
3305
    case 0x18:  /* MCR2 */
 
3306
        s->mcr[1] = value & 0x03e3;
 
3307
        if (value & 3)                                  /* XMCM */
 
3308
            printf("%s: Tx channel selection mode enable attempt\n",
 
3309
                            __FUNCTION__);
 
3310
        return;
 
3311
    case 0x1a:  /* MCR1 */
 
3312
        s->mcr[0] = value & 0x03e1;
 
3313
        if (value & 1)                                  /* RMCM */
 
3314
            printf("%s: Rx channel selection mode enable attempt\n",
 
3315
                            __FUNCTION__);
 
3316
        return;
 
3317
    case 0x1c:  /* RCERA */
 
3318
        s->rcer[0] = value & 0xffff;
 
3319
        return;
 
3320
    case 0x1e:  /* RCERB */
 
3321
        s->rcer[1] = value & 0xffff;
 
3322
        return;
 
3323
    case 0x20:  /* XCERA */
 
3324
        s->xcer[0] = value & 0xffff;
 
3325
        return;
 
3326
    case 0x22:  /* XCERB */
 
3327
        s->xcer[1] = value & 0xffff;
 
3328
        return;
 
3329
    case 0x24:  /* PCR0 */
 
3330
        s->pcr = value & 0x7faf;
 
3331
        return;
 
3332
    case 0x26:  /* RCERC */
 
3333
        s->rcer[2] = value & 0xffff;
 
3334
        return;
 
3335
    case 0x28:  /* RCERD */
 
3336
        s->rcer[3] = value & 0xffff;
 
3337
        return;
 
3338
    case 0x2a:  /* XCERC */
 
3339
        s->xcer[2] = value & 0xffff;
 
3340
        return;
 
3341
    case 0x2c:  /* XCERD */
 
3342
        s->xcer[3] = value & 0xffff;
 
3343
        return;
 
3344
    case 0x2e:  /* RCERE */
 
3345
        s->rcer[4] = value & 0xffff;
 
3346
        return;
 
3347
    case 0x30:  /* RCERF */
 
3348
        s->rcer[5] = value & 0xffff;
 
3349
        return;
 
3350
    case 0x32:  /* XCERE */
 
3351
        s->xcer[4] = value & 0xffff;
 
3352
        return;
 
3353
    case 0x34:  /* XCERF */
 
3354
        s->xcer[5] = value & 0xffff;
 
3355
        return;
 
3356
    case 0x36:  /* RCERG */
 
3357
        s->rcer[6] = value & 0xffff;
 
3358
        return;
 
3359
    case 0x38:  /* RCERH */
 
3360
        s->rcer[7] = value & 0xffff;
 
3361
        return;
 
3362
    case 0x3a:  /* XCERG */
 
3363
        s->xcer[6] = value & 0xffff;
 
3364
        return;
 
3365
    case 0x3c:  /* XCERH */
 
3366
        s->xcer[7] = value & 0xffff;
 
3367
        return;
 
3368
    }
 
3369
 
 
3370
    OMAP_BAD_REG(addr);
 
3371
}
 
3372
 
 
3373
static void omap_mcbsp_writew(void *opaque, hwaddr addr,
 
3374
                uint32_t value)
 
3375
{
 
3376
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
3377
    int offset = addr & OMAP_MPUI_REG_MASK;
 
3378
 
 
3379
    if (offset == 0x04) {                               /* DXR */
 
3380
        if (((s->xcr[0] >> 5) & 7) < 3)                 /* XWDLEN1 */
 
3381
            return;
 
3382
        if (s->tx_req > 3) {
 
3383
            s->tx_req -= 4;
 
3384
            if (s->codec && s->codec->cts) {
 
3385
                s->codec->out.fifo[s->codec->out.len ++] =
 
3386
                        (value >> 24) & 0xff;
 
3387
                s->codec->out.fifo[s->codec->out.len ++] =
 
3388
                        (value >> 16) & 0xff;
 
3389
                s->codec->out.fifo[s->codec->out.len ++] =
 
3390
                        (value >> 8) & 0xff;
 
3391
                s->codec->out.fifo[s->codec->out.len ++] =
 
3392
                        (value >> 0) & 0xff;
 
3393
            }
 
3394
            if (s->tx_req < 4)
 
3395
                omap_mcbsp_tx_done(s);
 
3396
        } else
 
3397
            printf("%s: Tx FIFO overrun\n", __FUNCTION__);
 
3398
        return;
 
3399
    }
 
3400
 
 
3401
    omap_badwidth_write16(opaque, addr, value);
 
3402
}
 
3403
 
 
3404
static void omap_mcbsp_write(void *opaque, hwaddr addr,
 
3405
                             uint64_t value, unsigned size)
 
3406
{
 
3407
    switch (size) {
 
3408
    case 2: return omap_mcbsp_writeh(opaque, addr, value);
 
3409
    case 4: return omap_mcbsp_writew(opaque, addr, value);
 
3410
    default: return omap_badwidth_write16(opaque, addr, value);
 
3411
    }
 
3412
}
 
3413
 
 
3414
static const MemoryRegionOps omap_mcbsp_ops = {
 
3415
    .read = omap_mcbsp_read,
 
3416
    .write = omap_mcbsp_write,
 
3417
    .endianness = DEVICE_NATIVE_ENDIAN,
 
3418
};
 
3419
 
 
3420
static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
 
3421
{
 
3422
    memset(&s->spcr, 0, sizeof(s->spcr));
 
3423
    memset(&s->rcr, 0, sizeof(s->rcr));
 
3424
    memset(&s->xcr, 0, sizeof(s->xcr));
 
3425
    s->srgr[0] = 0x0001;
 
3426
    s->srgr[1] = 0x2000;
 
3427
    memset(&s->mcr, 0, sizeof(s->mcr));
 
3428
    memset(&s->pcr, 0, sizeof(s->pcr));
 
3429
    memset(&s->rcer, 0, sizeof(s->rcer));
 
3430
    memset(&s->xcer, 0, sizeof(s->xcer));
 
3431
    s->tx_req = 0;
 
3432
    s->rx_req = 0;
 
3433
    s->tx_rate = 0;
 
3434
    s->rx_rate = 0;
 
3435
    timer_del(s->source_timer);
 
3436
    timer_del(s->sink_timer);
 
3437
}
 
3438
 
 
3439
static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
 
3440
                                            hwaddr base,
 
3441
                                            qemu_irq txirq, qemu_irq rxirq,
 
3442
                                            qemu_irq *dma, omap_clk clk)
 
3443
{
 
3444
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
 
3445
            g_malloc0(sizeof(struct omap_mcbsp_s));
 
3446
 
 
3447
    s->txirq = txirq;
 
3448
    s->rxirq = rxirq;
 
3449
    s->txdrq = dma[0];
 
3450
    s->rxdrq = dma[1];
 
3451
    s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);
 
3452
    s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);
 
3453
    omap_mcbsp_reset(s);
 
3454
 
 
3455
    memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
 
3456
    memory_region_add_subregion(system_memory, base, &s->iomem);
 
3457
 
 
3458
    return s;
 
3459
}
 
3460
 
 
3461
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
 
3462
{
 
3463
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
3464
 
 
3465
    if (s->rx_rate) {
 
3466
        s->rx_req = s->codec->in.len;
 
3467
        omap_mcbsp_rx_newdata(s);
 
3468
    }
 
3469
}
 
3470
 
 
3471
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
 
3472
{
 
3473
    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
 
3474
 
 
3475
    if (s->tx_rate) {
 
3476
        s->tx_req = s->codec->out.size;
 
3477
        omap_mcbsp_tx_newdata(s);
 
3478
    }
 
3479
}
 
3480
 
 
3481
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
 
3482
{
 
3483
    s->codec = slave;
 
3484
    slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
 
3485
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
 
3486
}
 
3487
 
 
3488
/* LED Pulse Generators */
 
3489
struct omap_lpg_s {
 
3490
    MemoryRegion iomem;
 
3491
    QEMUTimer *tm;
 
3492
 
 
3493
    uint8_t control;
 
3494
    uint8_t power;
 
3495
    int64_t on;
 
3496
    int64_t period;
 
3497
    int clk;
 
3498
    int cycle;
 
3499
};
 
3500
 
 
3501
static void omap_lpg_tick(void *opaque)
 
3502
{
 
3503
    struct omap_lpg_s *s = opaque;
 
3504
 
 
3505
    if (s->cycle)
 
3506
        timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on);
 
3507
    else
 
3508
        timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
 
3509
 
 
3510
    s->cycle = !s->cycle;
 
3511
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
 
3512
}
 
3513
 
 
3514
static void omap_lpg_update(struct omap_lpg_s *s)
 
3515
{
 
3516
    int64_t on, period = 1, ticks = 1000;
 
3517
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
 
3518
 
 
3519
    if (~s->control & (1 << 6))                                 /* LPGRES */
 
3520
        on = 0;
 
3521
    else if (s->control & (1 << 7))                             /* PERM_ON */
 
3522
        on = period;
 
3523
    else {
 
3524
        period = muldiv64(ticks, per[s->control & 7],           /* PERCTRL */
 
3525
                        256 / 32);
 
3526
        on = (s->clk && s->power) ? muldiv64(ticks,
 
3527
                        per[(s->control >> 3) & 7], 256) : 0;   /* ONCTRL */
 
3528
    }
 
3529
 
 
3530
    timer_del(s->tm);
 
3531
    if (on == period && s->on < s->period)
 
3532
        printf("%s: LED is on\n", __FUNCTION__);
 
3533
    else if (on == 0 && s->on)
 
3534
        printf("%s: LED is off\n", __FUNCTION__);
 
3535
    else if (on && (on != s->on || period != s->period)) {
 
3536
        s->cycle = 0;
 
3537
        s->on = on;
 
3538
        s->period = period;
 
3539
        omap_lpg_tick(s);
 
3540
        return;
 
3541
    }
 
3542
 
 
3543
    s->on = on;
 
3544
    s->period = period;
 
3545
}
 
3546
 
 
3547
static void omap_lpg_reset(struct omap_lpg_s *s)
 
3548
{
 
3549
    s->control = 0x00;
 
3550
    s->power = 0x00;
 
3551
    s->clk = 1;
 
3552
    omap_lpg_update(s);
 
3553
}
 
3554
 
 
3555
static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
 
3556
                              unsigned size)
 
3557
{
 
3558
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
 
3559
    int offset = addr & OMAP_MPUI_REG_MASK;
 
3560
 
 
3561
    if (size != 1) {
 
3562
        return omap_badwidth_read8(opaque, addr);
 
3563
    }
 
3564
 
 
3565
    switch (offset) {
 
3566
    case 0x00:  /* LCR */
 
3567
        return s->control;
 
3568
 
 
3569
    case 0x04:  /* PMR */
 
3570
        return s->power;
 
3571
    }
 
3572
 
 
3573
    OMAP_BAD_REG(addr);
 
3574
    return 0;
 
3575
}
 
3576
 
 
3577
static void omap_lpg_write(void *opaque, hwaddr addr,
 
3578
                           uint64_t value, unsigned size)
 
3579
{
 
3580
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
 
3581
    int offset = addr & OMAP_MPUI_REG_MASK;
 
3582
 
 
3583
    if (size != 1) {
 
3584
        return omap_badwidth_write8(opaque, addr, value);
 
3585
    }
 
3586
 
 
3587
    switch (offset) {
 
3588
    case 0x00:  /* LCR */
 
3589
        if (~value & (1 << 6))                                  /* LPGRES */
 
3590
            omap_lpg_reset(s);
 
3591
        s->control = value & 0xff;
 
3592
        omap_lpg_update(s);
 
3593
        return;
 
3594
 
 
3595
    case 0x04:  /* PMR */
 
3596
        s->power = value & 0x01;
 
3597
        omap_lpg_update(s);
 
3598
        return;
 
3599
 
 
3600
    default:
 
3601
        OMAP_BAD_REG(addr);
 
3602
        return;
 
3603
    }
 
3604
}
 
3605
 
 
3606
static const MemoryRegionOps omap_lpg_ops = {
 
3607
    .read = omap_lpg_read,
 
3608
    .write = omap_lpg_write,
 
3609
    .endianness = DEVICE_NATIVE_ENDIAN,
 
3610
};
 
3611
 
 
3612
static void omap_lpg_clk_update(void *opaque, int line, int on)
 
3613
{
 
3614
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
 
3615
 
 
3616
    s->clk = on;
 
3617
    omap_lpg_update(s);
 
3618
}
 
3619
 
 
3620
static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
 
3621
                                        hwaddr base, omap_clk clk)
 
3622
{
 
3623
    struct omap_lpg_s *s = (struct omap_lpg_s *)
 
3624
            g_malloc0(sizeof(struct omap_lpg_s));
 
3625
 
 
3626
    s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s);
 
3627
 
 
3628
    omap_lpg_reset(s);
 
3629
 
 
3630
    memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800);
 
3631
    memory_region_add_subregion(system_memory, base, &s->iomem);
 
3632
 
 
3633
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
 
3634
 
 
3635
    return s;
 
3636
}
 
3637
 
 
3638
/* MPUI Peripheral Bridge configuration */
 
3639
static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr,
 
3640
                                  unsigned size)
 
3641
{
 
3642
    if (size != 2) {
 
3643
        return omap_badwidth_read16(opaque, addr);
 
3644
    }
 
3645
 
 
3646
    if (addr == OMAP_MPUI_BASE) /* CMR */
 
3647
        return 0xfe4d;
 
3648
 
 
3649
    OMAP_BAD_REG(addr);
 
3650
    return 0;
 
3651
}
 
3652
 
 
3653
static void omap_mpui_io_write(void *opaque, hwaddr addr,
 
3654
                               uint64_t value, unsigned size)
 
3655
{
 
3656
    /* FIXME: infinite loop */
 
3657
    omap_badwidth_write16(opaque, addr, value);
 
3658
}
 
3659
 
 
3660
static const MemoryRegionOps omap_mpui_io_ops = {
 
3661
    .read = omap_mpui_io_read,
 
3662
    .write = omap_mpui_io_write,
 
3663
    .endianness = DEVICE_NATIVE_ENDIAN,
 
3664
};
 
3665
 
 
3666
static void omap_setup_mpui_io(MemoryRegion *system_memory,
 
3667
                               struct omap_mpu_state_s *mpu)
 
3668
{
 
3669
    memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu,
 
3670
                          "omap-mpui-io", 0x7fff);
 
3671
    memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
 
3672
                                &mpu->mpui_io_iomem);
 
3673
}
 
3674
 
 
3675
/* General chip reset */
 
3676
static void omap1_mpu_reset(void *opaque)
 
3677
{
 
3678
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
 
3679
 
 
3680
    omap_dma_reset(mpu->dma);
 
3681
    omap_mpu_timer_reset(mpu->timer[0]);
 
3682
    omap_mpu_timer_reset(mpu->timer[1]);
 
3683
    omap_mpu_timer_reset(mpu->timer[2]);
 
3684
    omap_wd_timer_reset(mpu->wdt);
 
3685
    omap_os_timer_reset(mpu->os_timer);
 
3686
    omap_lcdc_reset(mpu->lcd);
 
3687
    omap_ulpd_pm_reset(mpu);
 
3688
    omap_pin_cfg_reset(mpu);
 
3689
    omap_mpui_reset(mpu);
 
3690
    omap_tipb_bridge_reset(mpu->private_tipb);
 
3691
    omap_tipb_bridge_reset(mpu->public_tipb);
 
3692
    omap_dpll_reset(mpu->dpll[0]);
 
3693
    omap_dpll_reset(mpu->dpll[1]);
 
3694
    omap_dpll_reset(mpu->dpll[2]);
 
3695
    omap_uart_reset(mpu->uart[0]);
 
3696
    omap_uart_reset(mpu->uart[1]);
 
3697
    omap_uart_reset(mpu->uart[2]);
 
3698
    omap_mmc_reset(mpu->mmc);
 
3699
    omap_mpuio_reset(mpu->mpuio);
 
3700
    omap_uwire_reset(mpu->microwire);
 
3701
    omap_pwl_reset(mpu->pwl);
 
3702
    omap_pwt_reset(mpu->pwt);
 
3703
    omap_rtc_reset(mpu->rtc);
 
3704
    omap_mcbsp_reset(mpu->mcbsp1);
 
3705
    omap_mcbsp_reset(mpu->mcbsp2);
 
3706
    omap_mcbsp_reset(mpu->mcbsp3);
 
3707
    omap_lpg_reset(mpu->led[0]);
 
3708
    omap_lpg_reset(mpu->led[1]);
 
3709
    omap_clkm_reset(mpu);
 
3710
    cpu_reset(CPU(mpu->cpu));
 
3711
}
 
3712
 
 
3713
static const struct omap_map_s {
 
3714
    hwaddr phys_dsp;
 
3715
    hwaddr phys_mpu;
 
3716
    uint32_t size;
 
3717
    const char *name;
 
3718
} omap15xx_dsp_mm[] = {
 
3719
    /* Strobe 0 */
 
3720
    { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" },              /* CS0 */
 
3721
    { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" },             /* CS1 */
 
3722
    { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" },          /* CS3 */
 
3723
    { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" },   /* CS4 */
 
3724
    { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" },        /* CS5 */
 
3725
    { 0xe1013000, 0xfffb3000, 0x800, "uWire" },                 /* CS6 */
 
3726
    { 0xe1013800, 0xfffb3800, 0x800, "I^2C" },                  /* CS7 */
 
3727
    { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" },              /* CS8 */
 
3728
    { 0xe1014800, 0xfffb4800, 0x800, "RTC" },                   /* CS9 */
 
3729
    { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" },                 /* CS10 */
 
3730
    { 0xe1015800, 0xfffb5800, 0x800, "PWL" },                   /* CS11 */
 
3731
    { 0xe1016000, 0xfffb6000, 0x800, "PWT" },                   /* CS12 */
 
3732
    { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" },                /* CS14 */
 
3733
    { 0xe1017800, 0xfffb7800, 0x800, "MMC" },                   /* CS15 */
 
3734
    { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" },          /* CS18 */
 
3735
    { 0xe1019800, 0xfffb9800, 0x800, "UART3" },                 /* CS19 */
 
3736
    { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" },         /* CS25 */
 
3737
    /* Strobe 1 */
 
3738
    { 0xe101e000, 0xfffce000, 0x800, "GPIOs" },                 /* CS28 */
 
3739
 
 
3740
    { 0 }
 
3741
};
 
3742
 
 
3743
static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
 
3744
                                   const struct omap_map_s *map)
 
3745
{
 
3746
    MemoryRegion *io;
 
3747
 
 
3748
    for (; map->phys_dsp; map ++) {
 
3749
        io = g_new(MemoryRegion, 1);
 
3750
        memory_region_init_alias(io, NULL, map->name,
 
3751
                                 system_memory, map->phys_mpu, map->size);
 
3752
        memory_region_add_subregion(system_memory, map->phys_dsp, io);
 
3753
    }
 
3754
}
 
3755
 
 
3756
void omap_mpu_wakeup(void *opaque, int irq, int req)
 
3757
{
 
3758
    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
 
3759
    CPUState *cpu = CPU(mpu->cpu);
 
3760
 
 
3761
    if (cpu->halted) {
 
3762
        cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
 
3763
    }
 
3764
}
 
3765
 
 
3766
static const struct dma_irq_map omap1_dma_irq_map[] = {
 
3767
    { 0, OMAP_INT_DMA_CH0_6 },
 
3768
    { 0, OMAP_INT_DMA_CH1_7 },
 
3769
    { 0, OMAP_INT_DMA_CH2_8 },
 
3770
    { 0, OMAP_INT_DMA_CH3 },
 
3771
    { 0, OMAP_INT_DMA_CH4 },
 
3772
    { 0, OMAP_INT_DMA_CH5 },
 
3773
    { 1, OMAP_INT_1610_DMA_CH6 },
 
3774
    { 1, OMAP_INT_1610_DMA_CH7 },
 
3775
    { 1, OMAP_INT_1610_DMA_CH8 },
 
3776
    { 1, OMAP_INT_1610_DMA_CH9 },
 
3777
    { 1, OMAP_INT_1610_DMA_CH10 },
 
3778
    { 1, OMAP_INT_1610_DMA_CH11 },
 
3779
    { 1, OMAP_INT_1610_DMA_CH12 },
 
3780
    { 1, OMAP_INT_1610_DMA_CH13 },
 
3781
    { 1, OMAP_INT_1610_DMA_CH14 },
 
3782
    { 1, OMAP_INT_1610_DMA_CH15 }
 
3783
};
 
3784
 
 
3785
/* DMA ports for OMAP1 */
 
3786
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
 
3787
                hwaddr addr)
 
3788
{
 
3789
    return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
 
3790
}
 
3791
 
 
3792
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
 
3793
                hwaddr addr)
 
3794
{
 
3795
    return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
 
3796
                             addr);
 
3797
}
 
3798
 
 
3799
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
 
3800
                hwaddr addr)
 
3801
{
 
3802
    return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
 
3803
}
 
3804
 
 
3805
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
 
3806
                hwaddr addr)
 
3807
{
 
3808
    return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
 
3809
}
 
3810
 
 
3811
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
 
3812
                hwaddr addr)
 
3813
{
 
3814
    return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
 
3815
}
 
3816
 
 
3817
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
 
3818
                hwaddr addr)
 
3819
{
 
3820
    return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
 
3821
}
 
3822
 
 
3823
struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
 
3824
                unsigned long sdram_size,
 
3825
                const char *core)
 
3826
{
 
3827
    int i;
 
3828
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
 
3829
            g_malloc0(sizeof(struct omap_mpu_state_s));
 
3830
    qemu_irq dma_irqs[6];
 
3831
    DriveInfo *dinfo;
 
3832
    SysBusDevice *busdev;
 
3833
 
 
3834
    if (!core)
 
3835
        core = "ti925t";
 
3836
 
 
3837
    /* Core */
 
3838
    s->mpu_model = omap310;
 
3839
    s->cpu = cpu_arm_init(core);
 
3840
    if (s->cpu == NULL) {
 
3841
        fprintf(stderr, "Unable to find CPU definition\n");
 
3842
        exit(1);
 
3843
    }
 
3844
    s->sdram_size = sdram_size;
 
3845
    s->sram_size = OMAP15XX_SRAM_SIZE;
 
3846
 
 
3847
    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
 
3848
 
 
3849
    /* Clocks */
 
3850
    omap_clk_init(s);
 
3851
 
 
3852
    /* Memory-mapped stuff */
 
3853
    memory_region_init_ram(&s->emiff_ram, NULL, "omap1.dram", s->sdram_size);
 
3854
    vmstate_register_ram_global(&s->emiff_ram);
 
3855
    memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
 
3856
    memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size);
 
3857
    vmstate_register_ram_global(&s->imif_ram);
 
3858
    memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
 
3859
 
 
3860
    omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
 
3861
 
 
3862
    s->ih[0] = qdev_create(NULL, "omap-intc");
 
3863
    qdev_prop_set_uint32(s->ih[0], "size", 0x100);
 
3864
    qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
 
3865
    qdev_init_nofail(s->ih[0]);
 
3866
    busdev = SYS_BUS_DEVICE(s->ih[0]);
 
3867
    sysbus_connect_irq(busdev, 0,
 
3868
                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
 
3869
    sysbus_connect_irq(busdev, 1,
 
3870
                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
 
3871
    sysbus_mmio_map(busdev, 0, 0xfffecb00);
 
3872
    s->ih[1] = qdev_create(NULL, "omap-intc");
 
3873
    qdev_prop_set_uint32(s->ih[1], "size", 0x800);
 
3874
    qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
 
3875
    qdev_init_nofail(s->ih[1]);
 
3876
    busdev = SYS_BUS_DEVICE(s->ih[1]);
 
3877
    sysbus_connect_irq(busdev, 0,
 
3878
                       qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
 
3879
    /* The second interrupt controller's FIQ output is not wired up */
 
3880
    sysbus_mmio_map(busdev, 0, 0xfffe0000);
 
3881
 
 
3882
    for (i = 0; i < 6; i++) {
 
3883
        dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
 
3884
                                       omap1_dma_irq_map[i].intr);
 
3885
    }
 
3886
    s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory,
 
3887
                           qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
 
3888
                           s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
 
3889
 
 
3890
    s->port[emiff    ].addr_valid = omap_validate_emiff_addr;
 
3891
    s->port[emifs    ].addr_valid = omap_validate_emifs_addr;
 
3892
    s->port[imif     ].addr_valid = omap_validate_imif_addr;
 
3893
    s->port[tipb     ].addr_valid = omap_validate_tipb_addr;
 
3894
    s->port[local    ].addr_valid = omap_validate_local_addr;
 
3895
    s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
 
3896
 
 
3897
    /* Register SDRAM and SRAM DMA ports for fast transfers.  */
 
3898
    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram),
 
3899
                         OMAP_EMIFF_BASE, s->sdram_size);
 
3900
    soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
 
3901
                         OMAP_IMIF_BASE, s->sram_size);
 
3902
 
 
3903
    s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
 
3904
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
 
3905
                    omap_findclk(s, "mputim_ck"));
 
3906
    s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
 
3907
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
 
3908
                    omap_findclk(s, "mputim_ck"));
 
3909
    s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
 
3910
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
 
3911
                    omap_findclk(s, "mputim_ck"));
 
3912
 
 
3913
    s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
 
3914
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
 
3915
                    omap_findclk(s, "armwdt_ck"));
 
3916
 
 
3917
    s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
 
3918
                    qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
 
3919
                    omap_findclk(s, "clk32-kHz"));
 
3920
 
 
3921
    s->lcd = omap_lcdc_init(system_memory, 0xfffec000,
 
3922
                            qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
 
3923
                            omap_dma_get_lcdch(s->dma),
 
3924
                            omap_findclk(s, "lcd_ck"));
 
3925
 
 
3926
    omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
 
3927
    omap_pin_cfg_init(system_memory, 0xfffe1000, s);
 
3928
    omap_id_init(system_memory, s);
 
3929
 
 
3930
    omap_mpui_init(system_memory, 0xfffec900, s);
 
3931
 
 
3932
    s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
 
3933
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
 
3934
                    omap_findclk(s, "tipb_ck"));
 
3935
    s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
 
3936
                    qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
 
3937
                    omap_findclk(s, "tipb_ck"));
 
3938
 
 
3939
    omap_tcmi_init(system_memory, 0xfffecc00, s);
 
3940
 
 
3941
    s->uart[0] = omap_uart_init(0xfffb0000,
 
3942
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
 
3943
                    omap_findclk(s, "uart1_ck"),
 
3944
                    omap_findclk(s, "uart1_ck"),
 
3945
                    s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
 
3946
                    "uart1",
 
3947
                    serial_hds[0]);
 
3948
    s->uart[1] = omap_uart_init(0xfffb0800,
 
3949
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
 
3950
                    omap_findclk(s, "uart2_ck"),
 
3951
                    omap_findclk(s, "uart2_ck"),
 
3952
                    s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
 
3953
                    "uart2",
 
3954
                    serial_hds[0] ? serial_hds[1] : NULL);
 
3955
    s->uart[2] = omap_uart_init(0xfffb9800,
 
3956
                                qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
 
3957
                    omap_findclk(s, "uart3_ck"),
 
3958
                    omap_findclk(s, "uart3_ck"),
 
3959
                    s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
 
3960
                    "uart3",
 
3961
                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
 
3962
 
 
3963
    s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
 
3964
                                omap_findclk(s, "dpll1"));
 
3965
    s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000,
 
3966
                                omap_findclk(s, "dpll2"));
 
3967
    s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100,
 
3968
                                omap_findclk(s, "dpll3"));
 
3969
 
 
3970
    dinfo = drive_get(IF_SD, 0, 0);
 
3971
    if (!dinfo) {
 
3972
        fprintf(stderr, "qemu: missing SecureDigital device\n");
 
3973
        exit(1);
 
3974
    }
 
3975
    s->mmc = omap_mmc_init(0xfffb7800, system_memory, dinfo->bdrv,
 
3976
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
 
3977
                           &s->drq[OMAP_DMA_MMC_TX],
 
3978
                    omap_findclk(s, "mmc_ck"));
 
3979
 
 
3980
    s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
 
3981
                               qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD),
 
3982
                               qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO),
 
3983
                               s->wakeup, omap_findclk(s, "clk32-kHz"));
 
3984
 
 
3985
    s->gpio = qdev_create(NULL, "omap-gpio");
 
3986
    qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
 
3987
    qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
 
3988
    qdev_init_nofail(s->gpio);
 
3989
    sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio), 0,
 
3990
                       qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
 
3991
    sysbus_mmio_map(SYS_BUS_DEVICE(s->gpio), 0, 0xfffce000);
 
3992
 
 
3993
    s->microwire = omap_uwire_init(system_memory, 0xfffb3000,
 
3994
                                   qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX),
 
3995
                                   qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX),
 
3996
                    s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
 
3997
 
 
3998
    s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
 
3999
                           omap_findclk(s, "armxor_ck"));
 
4000
    s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
 
4001
                           omap_findclk(s, "armxor_ck"));
 
4002
 
 
4003
    s->i2c[0] = qdev_create(NULL, "omap_i2c");
 
4004
    qdev_prop_set_uint8(s->i2c[0], "revision", 0x11);
 
4005
    qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "mpuper_ck"));
 
4006
    qdev_init_nofail(s->i2c[0]);
 
4007
    busdev = SYS_BUS_DEVICE(s->i2c[0]);
 
4008
    sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C));
 
4009
    sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]);
 
4010
    sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]);
 
4011
    sysbus_mmio_map(busdev, 0, 0xfffb3800);
 
4012
 
 
4013
    s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
 
4014
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
 
4015
                           qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
 
4016
                    omap_findclk(s, "clk32-kHz"));
 
4017
 
 
4018
    s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
 
4019
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
 
4020
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
 
4021
                    &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
 
4022
    s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
 
4023
                                qdev_get_gpio_in(s->ih[0],
 
4024
                                                 OMAP_INT_310_McBSP2_TX),
 
4025
                                qdev_get_gpio_in(s->ih[0],
 
4026
                                                 OMAP_INT_310_McBSP2_RX),
 
4027
                    &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
 
4028
    s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
 
4029
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
 
4030
                                qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
 
4031
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
 
4032
 
 
4033
    s->led[0] = omap_lpg_init(system_memory,
 
4034
                              0xfffbd000, omap_findclk(s, "clk32-kHz"));
 
4035
    s->led[1] = omap_lpg_init(system_memory,
 
4036
                              0xfffbd800, omap_findclk(s, "clk32-kHz"));
 
4037
 
 
4038
    /* Register mappings not currenlty implemented:
 
4039
     * MCSI2 Comm       fffb2000 - fffb27ff (not mapped on OMAP310)
 
4040
     * MCSI1 Bluetooth  fffb2800 - fffb2fff (not mapped on OMAP310)
 
4041
     * USB W2FC         fffb4000 - fffb47ff
 
4042
     * Camera Interface fffb6800 - fffb6fff
 
4043
     * USB Host         fffba000 - fffba7ff
 
4044
     * FAC              fffba800 - fffbafff
 
4045
     * HDQ/1-Wire       fffbc000 - fffbc7ff
 
4046
     * TIPB switches    fffbc800 - fffbcfff
 
4047
     * Mailbox          fffcf000 - fffcf7ff
 
4048
     * Local bus IF     fffec100 - fffec1ff
 
4049
     * Local bus MMU    fffec200 - fffec2ff
 
4050
     * DSP MMU          fffed200 - fffed2ff
 
4051
     */
 
4052
 
 
4053
    omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
 
4054
    omap_setup_mpui_io(system_memory, s);
 
4055
 
 
4056
    qemu_register_reset(omap1_mpu_reset, s);
 
4057
 
 
4058
    return s;
 
4059
}