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