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