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