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