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