qemu/hw/omap2.c
<<
>>
Prefs
   1/*
   2 * TI OMAP processors emulation.
   3 *
   4 * Copyright (C) 2007-2008 Nokia Corporation
   5 * Written by Andrzej Zaborowski <andrew@openedhand.com>
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 or
  10 * (at your option) version 3 of the License.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License along
  18 * with this program; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "blockdev.h"
  22#include "hw.h"
  23#include "arm-misc.h"
  24#include "omap.h"
  25#include "sysemu.h"
  26#include "qemu-timer.h"
  27#include "qemu-char.h"
  28#include "flash.h"
  29#include "soc_dma.h"
  30#include "audio/audio.h"
  31
  32/* Enhanced Audio Controller (CODEC only) */
  33struct omap_eac_s {
  34    qemu_irq irq;
  35
  36    uint16_t sysconfig;
  37    uint8_t config[4];
  38    uint8_t control;
  39    uint8_t address;
  40    uint16_t data;
  41    uint8_t vtol;
  42    uint8_t vtsl;
  43    uint16_t mixer;
  44    uint16_t gain[4];
  45    uint8_t att;
  46    uint16_t max[7];
  47
  48    struct {
  49        qemu_irq txdrq;
  50        qemu_irq rxdrq;
  51        uint32_t (*txrx)(void *opaque, uint32_t, int);
  52        void *opaque;
  53
  54#define EAC_BUF_LEN 1024
  55        uint32_t rxbuf[EAC_BUF_LEN];
  56        int rxoff;
  57        int rxlen;
  58        int rxavail;
  59        uint32_t txbuf[EAC_BUF_LEN];
  60        int txlen;
  61        int txavail;
  62
  63        int enable;
  64        int rate;
  65
  66        uint16_t config[4];
  67
  68        /* These need to be moved to the actual codec */
  69        QEMUSoundCard card;
  70        SWVoiceIn *in_voice;
  71        SWVoiceOut *out_voice;
  72        int hw_enable;
  73    } codec;
  74
  75    struct {
  76        uint8_t control;
  77        uint16_t config;
  78    } modem, bt;
  79};
  80
  81static inline void omap_eac_interrupt_update(struct omap_eac_s *s)
  82{
  83    qemu_set_irq(s->irq, (s->codec.config[1] >> 14) & 1);       /* AURDI */
  84}
  85
  86static inline void omap_eac_in_dmarequest_update(struct omap_eac_s *s)
  87{
  88    qemu_set_irq(s->codec.rxdrq, (s->codec.rxavail || s->codec.rxlen) &&
  89                    ((s->codec.config[1] >> 12) & 1));          /* DMAREN */
  90}
  91
  92static inline void omap_eac_out_dmarequest_update(struct omap_eac_s *s)
  93{
  94    qemu_set_irq(s->codec.txdrq, s->codec.txlen < s->codec.txavail &&
  95                    ((s->codec.config[1] >> 11) & 1));          /* DMAWEN */
  96}
  97
  98static inline void omap_eac_in_refill(struct omap_eac_s *s)
  99{
 100    int left = MIN(EAC_BUF_LEN - s->codec.rxlen, s->codec.rxavail) << 2;
 101    int start = ((s->codec.rxoff + s->codec.rxlen) & (EAC_BUF_LEN - 1)) << 2;
 102    int leftwrap = MIN(left, (EAC_BUF_LEN << 2) - start);
 103    int recv = 1;
 104    uint8_t *buf = (uint8_t *) s->codec.rxbuf + start;
 105
 106    left -= leftwrap;
 107    start = 0;
 108    while (leftwrap && (recv = AUD_read(s->codec.in_voice, buf + start,
 109                                    leftwrap)) > 0) {   /* Be defensive */
 110        start += recv;
 111        leftwrap -= recv;
 112    }
 113    if (recv <= 0)
 114        s->codec.rxavail = 0;
 115    else
 116        s->codec.rxavail -= start >> 2;
 117    s->codec.rxlen += start >> 2;
 118
 119    if (recv > 0 && left > 0) {
 120        start = 0;
 121        while (left && (recv = AUD_read(s->codec.in_voice,
 122                                        (uint8_t *) s->codec.rxbuf + start,
 123                                        left)) > 0) {   /* Be defensive */
 124            start += recv;
 125            left -= recv;
 126        }
 127        if (recv <= 0)
 128            s->codec.rxavail = 0;
 129        else
 130            s->codec.rxavail -= start >> 2;
 131        s->codec.rxlen += start >> 2;
 132    }
 133}
 134
 135static inline void omap_eac_out_empty(struct omap_eac_s *s)
 136{
 137    int left = s->codec.txlen << 2;
 138    int start = 0;
 139    int sent = 1;
 140
 141    while (left && (sent = AUD_write(s->codec.out_voice,
 142                                    (uint8_t *) s->codec.txbuf + start,
 143                                    left)) > 0) {       /* Be defensive */
 144        start += sent;
 145        left -= sent;
 146    }
 147
 148    if (!sent) {
 149        s->codec.txavail = 0;
 150        omap_eac_out_dmarequest_update(s);
 151    }
 152
 153    if (start)
 154        s->codec.txlen = 0;
 155}
 156
 157static void omap_eac_in_cb(void *opaque, int avail_b)
 158{
 159    struct omap_eac_s *s = (struct omap_eac_s *) opaque;
 160
 161    s->codec.rxavail = avail_b >> 2;
 162    omap_eac_in_refill(s);
 163    /* TODO: possibly discard current buffer if overrun */
 164    omap_eac_in_dmarequest_update(s);
 165}
 166
 167static void omap_eac_out_cb(void *opaque, int free_b)
 168{
 169    struct omap_eac_s *s = (struct omap_eac_s *) opaque;
 170
 171    s->codec.txavail = free_b >> 2;
 172    if (s->codec.txlen)
 173        omap_eac_out_empty(s);
 174    else
 175        omap_eac_out_dmarequest_update(s);
 176}
 177
 178static void omap_eac_enable_update(struct omap_eac_s *s)
 179{
 180    s->codec.enable = !(s->codec.config[1] & 1) &&              /* EACPWD */
 181            (s->codec.config[1] & 2) &&                         /* AUDEN */
 182            s->codec.hw_enable;
 183}
 184
 185static const int omap_eac_fsint[4] = {
 186    8000,
 187    11025,
 188    22050,
 189    44100,
 190};
 191
 192static const int omap_eac_fsint2[8] = {
 193    8000,
 194    11025,
 195    22050,
 196    44100,
 197    48000,
 198    0, 0, 0,
 199};
 200
 201static const int omap_eac_fsint3[16] = {
 202    8000,
 203    11025,
 204    16000,
 205    22050,
 206    24000,
 207    32000,
 208    44100,
 209    48000,
 210    0, 0, 0, 0, 0, 0, 0, 0,
 211};
 212
 213static void omap_eac_rate_update(struct omap_eac_s *s)
 214{
 215    int fsint[3];
 216
 217    fsint[2] = (s->codec.config[3] >> 9) & 0xf;
 218    fsint[1] = (s->codec.config[2] >> 0) & 0x7;
 219    fsint[0] = (s->codec.config[0] >> 6) & 0x3;
 220    if (fsint[2] < 0xf)
 221        s->codec.rate = omap_eac_fsint3[fsint[2]];
 222    else if (fsint[1] < 0x7)
 223        s->codec.rate = omap_eac_fsint2[fsint[1]];
 224    else
 225        s->codec.rate = omap_eac_fsint[fsint[0]];
 226}
 227
 228static void omap_eac_volume_update(struct omap_eac_s *s)
 229{
 230    /* TODO */
 231}
 232
 233static void omap_eac_format_update(struct omap_eac_s *s)
 234{
 235    struct audsettings fmt;
 236
 237    /* The hardware buffers at most one sample */
 238    if (s->codec.rxlen)
 239        s->codec.rxlen = 1;
 240
 241    if (s->codec.in_voice) {
 242        AUD_set_active_in(s->codec.in_voice, 0);
 243        AUD_close_in(&s->codec.card, s->codec.in_voice);
 244        s->codec.in_voice = NULL;
 245    }
 246    if (s->codec.out_voice) {
 247        omap_eac_out_empty(s);
 248        AUD_set_active_out(s->codec.out_voice, 0);
 249        AUD_close_out(&s->codec.card, s->codec.out_voice);
 250        s->codec.out_voice = NULL;
 251        s->codec.txavail = 0;
 252    }
 253    /* Discard what couldn't be written */
 254    s->codec.txlen = 0;
 255
 256    omap_eac_enable_update(s);
 257    if (!s->codec.enable)
 258        return;
 259
 260    omap_eac_rate_update(s);
 261    fmt.endianness = ((s->codec.config[0] >> 8) & 1);           /* LI_BI */
 262    fmt.nchannels = ((s->codec.config[0] >> 10) & 1) ? 2 : 1;   /* MN_ST */
 263    fmt.freq = s->codec.rate;
 264    /* TODO: signedness possibly depends on the CODEC hardware - or
 265     * does I2S specify it?  */
 266    /* All register writes are 16 bits so we we store 16-bit samples
 267     * in the buffers regardless of AGCFR[B8_16] value.  */
 268    fmt.fmt = AUD_FMT_U16;
 269
 270    s->codec.in_voice = AUD_open_in(&s->codec.card, s->codec.in_voice,
 271                    "eac.codec.in", s, omap_eac_in_cb, &fmt);
 272    s->codec.out_voice = AUD_open_out(&s->codec.card, s->codec.out_voice,
 273                    "eac.codec.out", s, omap_eac_out_cb, &fmt);
 274
 275    omap_eac_volume_update(s);
 276
 277    AUD_set_active_in(s->codec.in_voice, 1);
 278    AUD_set_active_out(s->codec.out_voice, 1);
 279}
 280
 281static void omap_eac_reset(struct omap_eac_s *s)
 282{
 283    s->sysconfig = 0;
 284    s->config[0] = 0x0c;
 285    s->config[1] = 0x09;
 286    s->config[2] = 0xab;
 287    s->config[3] = 0x03;
 288    s->control = 0x00;
 289    s->address = 0x00;
 290    s->data = 0x0000;
 291    s->vtol = 0x00;
 292    s->vtsl = 0x00;
 293    s->mixer = 0x0000;
 294    s->gain[0] = 0xe7e7;
 295    s->gain[1] = 0x6767;
 296    s->gain[2] = 0x6767;
 297    s->gain[3] = 0x6767;
 298    s->att = 0xce;
 299    s->max[0] = 0;
 300    s->max[1] = 0;
 301    s->max[2] = 0;
 302    s->max[3] = 0;
 303    s->max[4] = 0;
 304    s->max[5] = 0;
 305    s->max[6] = 0;
 306
 307    s->modem.control = 0x00;
 308    s->modem.config = 0x0000;
 309    s->bt.control = 0x00;
 310    s->bt.config = 0x0000;
 311    s->codec.config[0] = 0x0649;
 312    s->codec.config[1] = 0x0000;
 313    s->codec.config[2] = 0x0007;
 314    s->codec.config[3] = 0x1ffc;
 315    s->codec.rxoff = 0;
 316    s->codec.rxlen = 0;
 317    s->codec.txlen = 0;
 318    s->codec.rxavail = 0;
 319    s->codec.txavail = 0;
 320
 321    omap_eac_format_update(s);
 322    omap_eac_interrupt_update(s);
 323}
 324
 325static uint32_t omap_eac_read(void *opaque, target_phys_addr_t addr)
 326{
 327    struct omap_eac_s *s = (struct omap_eac_s *) opaque;
 328    uint32_t ret;
 329
 330    switch (addr) {
 331    case 0x000: /* CPCFR1 */
 332        return s->config[0];
 333    case 0x004: /* CPCFR2 */
 334        return s->config[1];
 335    case 0x008: /* CPCFR3 */
 336        return s->config[2];
 337    case 0x00c: /* CPCFR4 */
 338        return s->config[3];
 339
 340    case 0x010: /* CPTCTL */
 341        return s->control | ((s->codec.rxavail + s->codec.rxlen > 0) << 7) |
 342                ((s->codec.txlen < s->codec.txavail) << 5);
 343
 344    case 0x014: /* CPTTADR */
 345        return s->address;
 346    case 0x018: /* CPTDATL */
 347        return s->data & 0xff;
 348    case 0x01c: /* CPTDATH */
 349        return s->data >> 8;
 350    case 0x020: /* CPTVSLL */
 351        return s->vtol;
 352    case 0x024: /* CPTVSLH */
 353        return s->vtsl | (3 << 5);      /* CRDY1 | CRDY2 */
 354    case 0x040: /* MPCTR */
 355        return s->modem.control;
 356    case 0x044: /* MPMCCFR */
 357        return s->modem.config;
 358    case 0x060: /* BPCTR */
 359        return s->bt.control;
 360    case 0x064: /* BPMCCFR */
 361        return s->bt.config;
 362    case 0x080: /* AMSCFR */
 363        return s->mixer;
 364    case 0x084: /* AMVCTR */
 365        return s->gain[0];
 366    case 0x088: /* AM1VCTR */
 367        return s->gain[1];
 368    case 0x08c: /* AM2VCTR */
 369        return s->gain[2];
 370    case 0x090: /* AM3VCTR */
 371        return s->gain[3];
 372    case 0x094: /* ASTCTR */
 373        return s->att;
 374    case 0x098: /* APD1LCR */
 375        return s->max[0];
 376    case 0x09c: /* APD1RCR */
 377        return s->max[1];
 378    case 0x0a0: /* APD2LCR */
 379        return s->max[2];
 380    case 0x0a4: /* APD2RCR */
 381        return s->max[3];
 382    case 0x0a8: /* APD3LCR */
 383        return s->max[4];
 384    case 0x0ac: /* APD3RCR */
 385        return s->max[5];
 386    case 0x0b0: /* APD4R */
 387        return s->max[6];
 388    case 0x0b4: /* ADWR */
 389        /* This should be write-only?  Docs list it as read-only.  */
 390        return 0x0000;
 391    case 0x0b8: /* ADRDR */
 392        if (likely(s->codec.rxlen > 1)) {
 393            ret = s->codec.rxbuf[s->codec.rxoff ++];
 394            s->codec.rxlen --;
 395            s->codec.rxoff &= EAC_BUF_LEN - 1;
 396            return ret;
 397        } else if (s->codec.rxlen) {
 398            ret = s->codec.rxbuf[s->codec.rxoff ++];
 399            s->codec.rxlen --;
 400            s->codec.rxoff &= EAC_BUF_LEN - 1;
 401            if (s->codec.rxavail)
 402                omap_eac_in_refill(s);
 403            omap_eac_in_dmarequest_update(s);
 404            return ret;
 405        }
 406        return 0x0000;
 407    case 0x0bc: /* AGCFR */
 408        return s->codec.config[0];
 409    case 0x0c0: /* AGCTR */
 410        return s->codec.config[1] | ((s->codec.config[1] & 2) << 14);
 411    case 0x0c4: /* AGCFR2 */
 412        return s->codec.config[2];
 413    case 0x0c8: /* AGCFR3 */
 414        return s->codec.config[3];
 415    case 0x0cc: /* MBPDMACTR */
 416    case 0x0d0: /* MPDDMARR */
 417    case 0x0d8: /* MPUDMARR */
 418    case 0x0e4: /* BPDDMARR */
 419    case 0x0ec: /* BPUDMARR */
 420        return 0x0000;
 421
 422    case 0x100: /* VERSION_NUMBER */
 423        return 0x0010;
 424
 425    case 0x104: /* SYSCONFIG */
 426        return s->sysconfig;
 427
 428    case 0x108: /* SYSSTATUS */
 429        return 1 | 0xe;                                 /* RESETDONE | stuff */
 430    }
 431
 432    OMAP_BAD_REG(addr);
 433    return 0;
 434}
 435
 436static void omap_eac_write(void *opaque, target_phys_addr_t addr,
 437                uint32_t value)
 438{
 439    struct omap_eac_s *s = (struct omap_eac_s *) opaque;
 440
 441    switch (addr) {
 442    case 0x098: /* APD1LCR */
 443    case 0x09c: /* APD1RCR */
 444    case 0x0a0: /* APD2LCR */
 445    case 0x0a4: /* APD2RCR */
 446    case 0x0a8: /* APD3LCR */
 447    case 0x0ac: /* APD3RCR */
 448    case 0x0b0: /* APD4R */
 449    case 0x0b8: /* ADRDR */
 450    case 0x0d0: /* MPDDMARR */
 451    case 0x0d8: /* MPUDMARR */
 452    case 0x0e4: /* BPDDMARR */
 453    case 0x0ec: /* BPUDMARR */
 454    case 0x100: /* VERSION_NUMBER */
 455    case 0x108: /* SYSSTATUS */
 456        OMAP_RO_REG(addr);
 457        return;
 458
 459    case 0x000: /* CPCFR1 */
 460        s->config[0] = value & 0xff;
 461        omap_eac_format_update(s);
 462        break;
 463    case 0x004: /* CPCFR2 */
 464        s->config[1] = value & 0xff;
 465        omap_eac_format_update(s);
 466        break;
 467    case 0x008: /* CPCFR3 */
 468        s->config[2] = value & 0xff;
 469        omap_eac_format_update(s);
 470        break;
 471    case 0x00c: /* CPCFR4 */
 472        s->config[3] = value & 0xff;
 473        omap_eac_format_update(s);
 474        break;
 475
 476    case 0x010: /* CPTCTL */
 477        /* Assuming TXF and TXE bits are read-only... */
 478        s->control = value & 0x5f;
 479        omap_eac_interrupt_update(s);
 480        break;
 481
 482    case 0x014: /* CPTTADR */
 483        s->address = value & 0xff;
 484        break;
 485    case 0x018: /* CPTDATL */
 486        s->data &= 0xff00;
 487        s->data |= value & 0xff;
 488        break;
 489    case 0x01c: /* CPTDATH */
 490        s->data &= 0x00ff;
 491        s->data |= value << 8;
 492        break;
 493    case 0x020: /* CPTVSLL */
 494        s->vtol = value & 0xf8;
 495        break;
 496    case 0x024: /* CPTVSLH */
 497        s->vtsl = value & 0x9f;
 498        break;
 499    case 0x040: /* MPCTR */
 500        s->modem.control = value & 0x8f;
 501        break;
 502    case 0x044: /* MPMCCFR */
 503        s->modem.config = value & 0x7fff;
 504        break;
 505    case 0x060: /* BPCTR */
 506        s->bt.control = value & 0x8f;
 507        break;
 508    case 0x064: /* BPMCCFR */
 509        s->bt.config = value & 0x7fff;
 510        break;
 511    case 0x080: /* AMSCFR */
 512        s->mixer = value & 0x0fff;
 513        break;
 514    case 0x084: /* AMVCTR */
 515        s->gain[0] = value & 0xffff;
 516        break;
 517    case 0x088: /* AM1VCTR */
 518        s->gain[1] = value & 0xff7f;
 519        break;
 520    case 0x08c: /* AM2VCTR */
 521        s->gain[2] = value & 0xff7f;
 522        break;
 523    case 0x090: /* AM3VCTR */
 524        s->gain[3] = value & 0xff7f;
 525        break;
 526    case 0x094: /* ASTCTR */
 527        s->att = value & 0xff;
 528        break;
 529
 530    case 0x0b4: /* ADWR */
 531        s->codec.txbuf[s->codec.txlen ++] = value;
 532        if (unlikely(s->codec.txlen == EAC_BUF_LEN ||
 533                                s->codec.txlen == s->codec.txavail)) {
 534            if (s->codec.txavail)
 535                omap_eac_out_empty(s);
 536            /* Discard what couldn't be written */
 537            s->codec.txlen = 0;
 538        }
 539        break;
 540
 541    case 0x0bc: /* AGCFR */
 542        s->codec.config[0] = value & 0x07ff;
 543        omap_eac_format_update(s);
 544        break;
 545    case 0x0c0: /* AGCTR */
 546        s->codec.config[1] = value & 0x780f;
 547        omap_eac_format_update(s);
 548        break;
 549    case 0x0c4: /* AGCFR2 */
 550        s->codec.config[2] = value & 0x003f;
 551        omap_eac_format_update(s);
 552        break;
 553    case 0x0c8: /* AGCFR3 */
 554        s->codec.config[3] = value & 0xffff;
 555        omap_eac_format_update(s);
 556        break;
 557    case 0x0cc: /* MBPDMACTR */
 558    case 0x0d4: /* MPDDMAWR */
 559    case 0x0e0: /* MPUDMAWR */
 560    case 0x0e8: /* BPDDMAWR */
 561    case 0x0f0: /* BPUDMAWR */
 562        break;
 563
 564    case 0x104: /* SYSCONFIG */
 565        if (value & (1 << 1))                           /* SOFTRESET */
 566            omap_eac_reset(s);
 567        s->sysconfig = value & 0x31d;
 568        break;
 569
 570    default:
 571        OMAP_BAD_REG(addr);
 572        return;
 573    }
 574}
 575
 576static CPUReadMemoryFunc * const omap_eac_readfn[] = {
 577    omap_badwidth_read16,
 578    omap_eac_read,
 579    omap_badwidth_read16,
 580};
 581
 582static CPUWriteMemoryFunc * const omap_eac_writefn[] = {
 583    omap_badwidth_write16,
 584    omap_eac_write,
 585    omap_badwidth_write16,
 586};
 587
 588static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
 589                qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
 590{
 591    int iomemtype;
 592    struct omap_eac_s *s = (struct omap_eac_s *)
 593            qemu_mallocz(sizeof(struct omap_eac_s));
 594
 595    s->irq = irq;
 596    s->codec.rxdrq = *drq ++;
 597    s->codec.txdrq = *drq;
 598    omap_eac_reset(s);
 599
 600    AUD_register_card("OMAP EAC", &s->codec.card);
 601
 602    iomemtype = cpu_register_io_memory(omap_eac_readfn,
 603                    omap_eac_writefn, s, DEVICE_NATIVE_ENDIAN);
 604    omap_l4_attach(ta, 0, iomemtype);
 605
 606    return s;
 607}
 608
 609/* STI/XTI (emulation interface) console - reverse engineered only */
 610struct omap_sti_s {
 611    qemu_irq irq;
 612    CharDriverState *chr;
 613
 614    uint32_t sysconfig;
 615    uint32_t systest;
 616    uint32_t irqst;
 617    uint32_t irqen;
 618    uint32_t clkcontrol;
 619    uint32_t serial_config;
 620};
 621
 622#define STI_TRACE_CONSOLE_CHANNEL       239
 623#define STI_TRACE_CONTROL_CHANNEL       253
 624
 625static inline void omap_sti_interrupt_update(struct omap_sti_s *s)
 626{
 627    qemu_set_irq(s->irq, s->irqst & s->irqen);
 628}
 629
 630static void omap_sti_reset(struct omap_sti_s *s)
 631{
 632    s->sysconfig = 0;
 633    s->irqst = 0;
 634    s->irqen = 0;
 635    s->clkcontrol = 0;
 636    s->serial_config = 0;
 637
 638    omap_sti_interrupt_update(s);
 639}
 640
 641static uint32_t omap_sti_read(void *opaque, target_phys_addr_t addr)
 642{
 643    struct omap_sti_s *s = (struct omap_sti_s *) opaque;
 644
 645    switch (addr) {
 646    case 0x00:  /* STI_REVISION */
 647        return 0x10;
 648
 649    case 0x10:  /* STI_SYSCONFIG */
 650        return s->sysconfig;
 651
 652    case 0x14:  /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
 653        return 0x00;
 654
 655    case 0x18:  /* STI_IRQSTATUS */
 656        return s->irqst;
 657
 658    case 0x1c:  /* STI_IRQSETEN / STI_IRQCLREN */
 659        return s->irqen;
 660
 661    case 0x24:  /* STI_ER / STI_DR / XTI_TRACESELECT */
 662    case 0x28:  /* STI_RX_DR / XTI_RXDATA */
 663        /* TODO */
 664        return 0;
 665
 666    case 0x2c:  /* STI_CLK_CTRL / XTI_SCLKCRTL */
 667        return s->clkcontrol;
 668
 669    case 0x30:  /* STI_SERIAL_CFG / XTI_SCONFIG */
 670        return s->serial_config;
 671    }
 672
 673    OMAP_BAD_REG(addr);
 674    return 0;
 675}
 676
 677static void omap_sti_write(void *opaque, target_phys_addr_t addr,
 678                uint32_t value)
 679{
 680    struct omap_sti_s *s = (struct omap_sti_s *) opaque;
 681
 682    switch (addr) {
 683    case 0x00:  /* STI_REVISION */
 684    case 0x14:  /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
 685        OMAP_RO_REG(addr);
 686        return;
 687
 688    case 0x10:  /* STI_SYSCONFIG */
 689        if (value & (1 << 1))                           /* SOFTRESET */
 690            omap_sti_reset(s);
 691        s->sysconfig = value & 0xfe;
 692        break;
 693
 694    case 0x18:  /* STI_IRQSTATUS */
 695        s->irqst &= ~value;
 696        omap_sti_interrupt_update(s);
 697        break;
 698
 699    case 0x1c:  /* STI_IRQSETEN / STI_IRQCLREN */
 700        s->irqen = value & 0xffff;
 701        omap_sti_interrupt_update(s);
 702        break;
 703
 704    case 0x2c:  /* STI_CLK_CTRL / XTI_SCLKCRTL */
 705        s->clkcontrol = value & 0xff;
 706        break;
 707
 708    case 0x30:  /* STI_SERIAL_CFG / XTI_SCONFIG */
 709        s->serial_config = value & 0xff;
 710        break;
 711
 712    case 0x24:  /* STI_ER / STI_DR / XTI_TRACESELECT */
 713    case 0x28:  /* STI_RX_DR / XTI_RXDATA */
 714        /* TODO */
 715        return;
 716
 717    default:
 718        OMAP_BAD_REG(addr);
 719        return;
 720    }
 721}
 722
 723static CPUReadMemoryFunc * const omap_sti_readfn[] = {
 724    omap_badwidth_read32,
 725    omap_badwidth_read32,
 726    omap_sti_read,
 727};
 728
 729static CPUWriteMemoryFunc * const omap_sti_writefn[] = {
 730    omap_badwidth_write32,
 731    omap_badwidth_write32,
 732    omap_sti_write,
 733};
 734
 735static uint32_t omap_sti_fifo_read(void *opaque, target_phys_addr_t addr)
 736{
 737    OMAP_BAD_REG(addr);
 738    return 0;
 739}
 740
 741static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr,
 742                uint32_t value)
 743{
 744    struct omap_sti_s *s = (struct omap_sti_s *) opaque;
 745    int ch = addr >> 6;
 746    uint8_t byte = value;
 747
 748    if (ch == STI_TRACE_CONTROL_CHANNEL) {
 749        /* Flush channel <i>value</i>.  */
 750        qemu_chr_write(s->chr, (const uint8_t *) "\r", 1);
 751    } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
 752        if (value == 0xc0 || value == 0xc3) {
 753            /* Open channel <i>ch</i>.  */
 754        } else if (value == 0x00)
 755            qemu_chr_write(s->chr, (const uint8_t *) "\n", 1);
 756        else
 757            qemu_chr_write(s->chr, &byte, 1);
 758    }
 759}
 760
 761static CPUReadMemoryFunc * const omap_sti_fifo_readfn[] = {
 762    omap_sti_fifo_read,
 763    omap_badwidth_read8,
 764    omap_badwidth_read8,
 765};
 766
 767static CPUWriteMemoryFunc * const omap_sti_fifo_writefn[] = {
 768    omap_sti_fifo_write,
 769    omap_badwidth_write8,
 770    omap_badwidth_write8,
 771};
 772
 773static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
 774                target_phys_addr_t channel_base, qemu_irq irq, omap_clk clk,
 775                CharDriverState *chr)
 776{
 777    int iomemtype;
 778    struct omap_sti_s *s = (struct omap_sti_s *)
 779            qemu_mallocz(sizeof(struct omap_sti_s));
 780
 781    s->irq = irq;
 782    omap_sti_reset(s);
 783
 784    s->chr = chr ?: qemu_chr_open("null", "null", NULL);
 785
 786    iomemtype = l4_register_io_memory(omap_sti_readfn,
 787                    omap_sti_writefn, s);
 788    omap_l4_attach(ta, 0, iomemtype);
 789
 790    iomemtype = cpu_register_io_memory(omap_sti_fifo_readfn,
 791                    omap_sti_fifo_writefn, s, DEVICE_NATIVE_ENDIAN);
 792    cpu_register_physical_memory(channel_base, 0x10000, iomemtype);
 793
 794    return s;
 795}
 796
 797/* L4 Interconnect */
 798#define L4TA(n)         (n)
 799#define L4TAO(n)        ((n) + 39)
 800
 801static const struct omap_l4_region_s omap_l4_region[125] = {
 802    [  1] = { 0x40800,  0x800, 32          }, /* Initiator agent */
 803    [  2] = { 0x41000, 0x1000, 32          }, /* Link agent */
 804    [  0] = { 0x40000,  0x800, 32          }, /* Address and protection */
 805    [  3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
 806    [  4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
 807    [  5] = { 0x04000, 0x1000, 32 | 16     }, /* 32K Timer */
 808    [  6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
 809    [  7] = { 0x08000,  0x800, 32          }, /* PRCM Region A */
 810    [  8] = { 0x08800,  0x800, 32          }, /* PRCM Region B */
 811    [  9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
 812    [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
 813    [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
 814    [ 12] = { 0x14000, 0x1000, 32          }, /* Test/emulation (TAP) */
 815    [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
 816    [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
 817    [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
 818    [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
 819    [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
 820    [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
 821    [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
 822    [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
 823    [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
 824    [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
 825    [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
 826    [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
 827    [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
 828    [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
 829    [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
 830    [ 28] = { 0x50000,  0x400, 32 | 16 | 8 }, /* Display top */
 831    [ 29] = { 0x50400,  0x400, 32 | 16 | 8 }, /* Display control */
 832    [ 30] = { 0x50800,  0x400, 32 | 16 | 8 }, /* Display RFBI */
 833    [ 31] = { 0x50c00,  0x400, 32 | 16 | 8 }, /* Display encoder */
 834    [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
 835    [ 33] = { 0x52000,  0x400, 32 | 16 | 8 }, /* Camera top */
 836    [ 34] = { 0x52400,  0x400, 32 | 16 | 8 }, /* Camera core */
 837    [ 35] = { 0x52800,  0x400, 32 | 16 | 8 }, /* Camera DMA */
 838    [ 36] = { 0x52c00,  0x400, 32 | 16 | 8 }, /* Camera MMU */
 839    [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
 840    [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
 841    [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
 842    [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
 843    [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
 844    [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
 845    [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
 846    [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
 847    [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
 848    [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
 849    [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
 850    [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
 851    [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
 852    [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
 853    [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
 854    [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
 855    [ 53] = { 0x66000,  0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
 856    [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
 857    [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
 858    [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
 859    [ 57] = { 0x6a000, 0x1000,      16 | 8 }, /* UART1 */
 860    [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
 861    [ 59] = { 0x6c000, 0x1000,      16 | 8 }, /* UART2 */
 862    [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
 863    [ 61] = { 0x6e000, 0x1000,      16 | 8 }, /* UART3 */
 864    [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
 865    [ 63] = { 0x70000, 0x1000,      16     }, /* I2C1 */
 866    [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
 867    [ 65] = { 0x72000, 0x1000,      16     }, /* I2C2 */
 868    [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
 869    [ 67] = { 0x74000, 0x1000,      16     }, /* McBSP1 */
 870    [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
 871    [ 69] = { 0x76000, 0x1000,      16     }, /* McBSP2 */
 872    [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
 873    [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
 874    [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
 875    [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
 876    [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
 877    [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
 878    [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
 879    [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
 880    [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
 881    [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
 882    [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
 883    [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
 884    [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
 885    [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
 886    [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
 887    [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
 888    [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
 889    [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
 890    [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
 891    [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
 892    [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
 893    [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
 894    [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
 895    [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
 896    [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
 897    [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
 898    [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
 899    [ 97] = { 0x90000, 0x1000,      16     }, /* EAC */
 900    [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
 901    [ 99] = { 0x92000, 0x1000,      16     }, /* FAC */
 902    [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
 903    [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
 904    [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
 905    [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
 906    [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
 907    [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
 908    [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
 909    [107] = { 0x9c000, 0x1000,      16 | 8 }, /* MMC SDIO */
 910    [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
 911    [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
 912    [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
 913    [111] = { 0xa0000, 0x1000, 32          }, /* RNG */
 914    [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
 915    [113] = { 0xa2000, 0x1000, 32          }, /* DES3DES */
 916    [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
 917    [115] = { 0xa4000, 0x1000, 32          }, /* SHA1MD5 */
 918    [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
 919    [117] = { 0xa6000, 0x1000, 32          }, /* AES */
 920    [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
 921    [119] = { 0xa8000, 0x2000, 32          }, /* PKA */
 922    [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
 923    [121] = { 0xb0000, 0x1000, 32          }, /* MG */
 924    [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
 925    [123] = { 0xb2000, 0x1000, 32          }, /* HDQ/1-Wire */
 926    [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
 927};
 928
 929static const struct omap_l4_agent_info_s omap_l4_agent_info[54] = {
 930    { 0,           0, 3, 2 }, /* L4IA initiatior agent */
 931    { L4TAO(1),    3, 2, 1 }, /* Control and pinout module */
 932    { L4TAO(2),    5, 2, 1 }, /* 32K timer */
 933    { L4TAO(3),    7, 3, 2 }, /* PRCM */
 934    { L4TA(1),    10, 2, 1 }, /* BCM */
 935    { L4TA(2),    12, 2, 1 }, /* Test JTAG */
 936    { L4TA(3),    14, 6, 3 }, /* Quad GPIO */
 937    { L4TA(4),    20, 4, 3 }, /* WD timer 1/2 */
 938    { L4TA(7),    24, 2, 1 }, /* GP timer 1 */
 939    { L4TA(9),    26, 2, 1 }, /* ATM11 ETB */
 940    { L4TA(10),   28, 5, 4 }, /* Display subsystem */
 941    { L4TA(11),   33, 5, 4 }, /* Camera subsystem */
 942    { L4TA(12),   38, 2, 1 }, /* sDMA */
 943    { L4TA(13),   40, 5, 4 }, /* SSI */
 944    { L4TAO(4),   45, 2, 1 }, /* USB */
 945    { L4TA(14),   47, 2, 1 }, /* Win Tracer1 */
 946    { L4TA(15),   49, 2, 1 }, /* Win Tracer2 */
 947    { L4TA(16),   51, 2, 1 }, /* Win Tracer3 */
 948    { L4TA(17),   53, 2, 1 }, /* Win Tracer4 */
 949    { L4TA(18),   55, 2, 1 }, /* XTI */
 950    { L4TA(19),   57, 2, 1 }, /* UART1 */
 951    { L4TA(20),   59, 2, 1 }, /* UART2 */
 952    { L4TA(21),   61, 2, 1 }, /* UART3 */
 953    { L4TAO(5),   63, 2, 1 }, /* I2C1 */
 954    { L4TAO(6),   65, 2, 1 }, /* I2C2 */
 955    { L4TAO(7),   67, 2, 1 }, /* McBSP1 */
 956    { L4TAO(8),   69, 2, 1 }, /* McBSP2 */
 957    { L4TA(5),    71, 2, 1 }, /* WD Timer 3 (DSP) */
 958    { L4TA(6),    73, 2, 1 }, /* WD Timer 4 (IVA) */
 959    { L4TA(8),    75, 2, 1 }, /* GP Timer 2 */
 960    { L4TA(22),   77, 2, 1 }, /* GP Timer 3 */
 961    { L4TA(23),   79, 2, 1 }, /* GP Timer 4 */
 962    { L4TA(24),   81, 2, 1 }, /* GP Timer 5 */
 963    { L4TA(25),   83, 2, 1 }, /* GP Timer 6 */
 964    { L4TA(26),   85, 2, 1 }, /* GP Timer 7 */
 965    { L4TA(27),   87, 2, 1 }, /* GP Timer 8 */
 966    { L4TA(28),   89, 2, 1 }, /* GP Timer 9 */
 967    { L4TA(29),   91, 2, 1 }, /* GP Timer 10 */
 968    { L4TA(30),   93, 2, 1 }, /* GP Timer 11 */
 969    { L4TA(31),   95, 2, 1 }, /* GP Timer 12 */
 970    { L4TA(32),   97, 2, 1 }, /* EAC */
 971    { L4TA(33),   99, 2, 1 }, /* FAC */
 972    { L4TA(34),  101, 2, 1 }, /* IPC */
 973    { L4TA(35),  103, 2, 1 }, /* SPI1 */
 974    { L4TA(36),  105, 2, 1 }, /* SPI2 */
 975    { L4TAO(9),  107, 2, 1 }, /* MMC SDIO */
 976    { L4TAO(10), 109, 2, 1 },
 977    { L4TAO(11), 111, 2, 1 }, /* RNG */
 978    { L4TAO(12), 113, 2, 1 }, /* DES3DES */
 979    { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
 980    { L4TA(37),  117, 2, 1 }, /* AES */
 981    { L4TA(38),  119, 2, 1 }, /* PKA */
 982    { -1,        121, 2, 1 },
 983    { L4TA(39),  123, 2, 1 }, /* HDQ/1-Wire */
 984};
 985
 986#define omap_l4ta(bus, cs)      \
 987    omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TA(cs))
 988#define omap_l4tao(bus, cs)     \
 989    omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TAO(cs))
 990
 991/* Power, Reset, and Clock Management */
 992struct omap_prcm_s {
 993    qemu_irq irq[3];
 994    struct omap_mpu_state_s *mpu;
 995
 996    uint32_t irqst[3];
 997    uint32_t irqen[3];
 998
 999    uint32_t sysconfig;
1000    uint32_t voltctrl;
1001    uint32_t scratch[20];
1002
1003    uint32_t clksrc[1];
1004    uint32_t clkout[1];
1005    uint32_t clkemul[1];
1006    uint32_t clkpol[1];
1007    uint32_t clksel[8];
1008    uint32_t clken[12];
1009    uint32_t clkctrl[4];
1010    uint32_t clkidle[7];
1011    uint32_t setuptime[2];
1012
1013    uint32_t wkup[3];
1014    uint32_t wken[3];
1015    uint32_t wkst[3];
1016    uint32_t rst[4];
1017    uint32_t rstctrl[1];
1018    uint32_t power[4];
1019    uint32_t rsttime_wkup;
1020
1021    uint32_t ev;
1022    uint32_t evtime[2];
1023
1024    int dpll_lock, apll_lock[2];
1025};
1026
1027static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
1028{
1029    qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
1030    /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
1031}
1032
1033static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr)
1034{
1035    struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
1036    uint32_t ret;
1037
1038    switch (addr) {
1039    case 0x000: /* PRCM_REVISION */
1040        return 0x10;
1041
1042    case 0x010: /* PRCM_SYSCONFIG */
1043        return s->sysconfig;
1044
1045    case 0x018: /* PRCM_IRQSTATUS_MPU */
1046        return s->irqst[0];
1047
1048    case 0x01c: /* PRCM_IRQENABLE_MPU */
1049        return s->irqen[0];
1050
1051    case 0x050: /* PRCM_VOLTCTRL */
1052        return s->voltctrl;
1053    case 0x054: /* PRCM_VOLTST */
1054        return s->voltctrl & 3;
1055
1056    case 0x060: /* PRCM_CLKSRC_CTRL */
1057        return s->clksrc[0];
1058    case 0x070: /* PRCM_CLKOUT_CTRL */
1059        return s->clkout[0];
1060    case 0x078: /* PRCM_CLKEMUL_CTRL */
1061        return s->clkemul[0];
1062    case 0x080: /* PRCM_CLKCFG_CTRL */
1063    case 0x084: /* PRCM_CLKCFG_STATUS */
1064        return 0;
1065
1066    case 0x090: /* PRCM_VOLTSETUP */
1067        return s->setuptime[0];
1068
1069    case 0x094: /* PRCM_CLKSSETUP */
1070        return s->setuptime[1];
1071
1072    case 0x098: /* PRCM_POLCTRL */
1073        return s->clkpol[0];
1074
1075    case 0x0b0: /* GENERAL_PURPOSE1 */
1076    case 0x0b4: /* GENERAL_PURPOSE2 */
1077    case 0x0b8: /* GENERAL_PURPOSE3 */
1078    case 0x0bc: /* GENERAL_PURPOSE4 */
1079    case 0x0c0: /* GENERAL_PURPOSE5 */
1080    case 0x0c4: /* GENERAL_PURPOSE6 */
1081    case 0x0c8: /* GENERAL_PURPOSE7 */
1082    case 0x0cc: /* GENERAL_PURPOSE8 */
1083    case 0x0d0: /* GENERAL_PURPOSE9 */
1084    case 0x0d4: /* GENERAL_PURPOSE10 */
1085    case 0x0d8: /* GENERAL_PURPOSE11 */
1086    case 0x0dc: /* GENERAL_PURPOSE12 */
1087    case 0x0e0: /* GENERAL_PURPOSE13 */
1088    case 0x0e4: /* GENERAL_PURPOSE14 */
1089    case 0x0e8: /* GENERAL_PURPOSE15 */
1090    case 0x0ec: /* GENERAL_PURPOSE16 */
1091    case 0x0f0: /* GENERAL_PURPOSE17 */
1092    case 0x0f4: /* GENERAL_PURPOSE18 */
1093    case 0x0f8: /* GENERAL_PURPOSE19 */
1094    case 0x0fc: /* GENERAL_PURPOSE20 */
1095        return s->scratch[(addr - 0xb0) >> 2];
1096
1097    case 0x140: /* CM_CLKSEL_MPU */
1098        return s->clksel[0];
1099    case 0x148: /* CM_CLKSTCTRL_MPU */
1100        return s->clkctrl[0];
1101
1102    case 0x158: /* RM_RSTST_MPU */
1103        return s->rst[0];
1104    case 0x1c8: /* PM_WKDEP_MPU */
1105        return s->wkup[0];
1106    case 0x1d4: /* PM_EVGENCTRL_MPU */
1107        return s->ev;
1108    case 0x1d8: /* PM_EVEGENONTIM_MPU */
1109        return s->evtime[0];
1110    case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
1111        return s->evtime[1];
1112    case 0x1e0: /* PM_PWSTCTRL_MPU */
1113        return s->power[0];
1114    case 0x1e4: /* PM_PWSTST_MPU */
1115        return 0;
1116
1117    case 0x200: /* CM_FCLKEN1_CORE */
1118        return s->clken[0];
1119    case 0x204: /* CM_FCLKEN2_CORE */
1120        return s->clken[1];
1121    case 0x210: /* CM_ICLKEN1_CORE */
1122        return s->clken[2];
1123    case 0x214: /* CM_ICLKEN2_CORE */
1124        return s->clken[3];
1125    case 0x21c: /* CM_ICLKEN4_CORE */
1126        return s->clken[4];
1127
1128    case 0x220: /* CM_IDLEST1_CORE */
1129        /* TODO: check the actual iclk status */
1130        return 0x7ffffff9;
1131    case 0x224: /* CM_IDLEST2_CORE */
1132        /* TODO: check the actual iclk status */
1133        return 0x00000007;
1134    case 0x22c: /* CM_IDLEST4_CORE */
1135        /* TODO: check the actual iclk status */
1136        return 0x0000001f;
1137
1138    case 0x230: /* CM_AUTOIDLE1_CORE */
1139        return s->clkidle[0];
1140    case 0x234: /* CM_AUTOIDLE2_CORE */
1141        return s->clkidle[1];
1142    case 0x238: /* CM_AUTOIDLE3_CORE */
1143        return s->clkidle[2];
1144    case 0x23c: /* CM_AUTOIDLE4_CORE */
1145        return s->clkidle[3];
1146
1147    case 0x240: /* CM_CLKSEL1_CORE */
1148        return s->clksel[1];
1149    case 0x244: /* CM_CLKSEL2_CORE */
1150        return s->clksel[2];
1151
1152    case 0x248: /* CM_CLKSTCTRL_CORE */
1153        return s->clkctrl[1];
1154
1155    case 0x2a0: /* PM_WKEN1_CORE */
1156        return s->wken[0];
1157    case 0x2a4: /* PM_WKEN2_CORE */
1158        return s->wken[1];
1159
1160    case 0x2b0: /* PM_WKST1_CORE */
1161        return s->wkst[0];
1162    case 0x2b4: /* PM_WKST2_CORE */
1163        return s->wkst[1];
1164    case 0x2c8: /* PM_WKDEP_CORE */
1165        return 0x1e;
1166
1167    case 0x2e0: /* PM_PWSTCTRL_CORE */
1168        return s->power[1];
1169    case 0x2e4: /* PM_PWSTST_CORE */
1170        return 0x000030 | (s->power[1] & 0xfc00);
1171
1172    case 0x300: /* CM_FCLKEN_GFX */
1173        return s->clken[5];
1174    case 0x310: /* CM_ICLKEN_GFX */
1175        return s->clken[6];
1176    case 0x320: /* CM_IDLEST_GFX */
1177        /* TODO: check the actual iclk status */
1178        return 0x00000001;
1179    case 0x340: /* CM_CLKSEL_GFX */
1180        return s->clksel[3];
1181    case 0x348: /* CM_CLKSTCTRL_GFX */
1182        return s->clkctrl[2];
1183    case 0x350: /* RM_RSTCTRL_GFX */
1184        return s->rstctrl[0];
1185    case 0x358: /* RM_RSTST_GFX */
1186        return s->rst[1];
1187    case 0x3c8: /* PM_WKDEP_GFX */
1188        return s->wkup[1];
1189
1190    case 0x3e0: /* PM_PWSTCTRL_GFX */
1191        return s->power[2];
1192    case 0x3e4: /* PM_PWSTST_GFX */
1193        return s->power[2] & 3;
1194
1195    case 0x400: /* CM_FCLKEN_WKUP */
1196        return s->clken[7];
1197    case 0x410: /* CM_ICLKEN_WKUP */
1198        return s->clken[8];
1199    case 0x420: /* CM_IDLEST_WKUP */
1200        /* TODO: check the actual iclk status */
1201        return 0x0000003f;
1202    case 0x430: /* CM_AUTOIDLE_WKUP */
1203        return s->clkidle[4];
1204    case 0x440: /* CM_CLKSEL_WKUP */
1205        return s->clksel[4];
1206    case 0x450: /* RM_RSTCTRL_WKUP */
1207        return 0;
1208    case 0x454: /* RM_RSTTIME_WKUP */
1209        return s->rsttime_wkup;
1210    case 0x458: /* RM_RSTST_WKUP */
1211        return s->rst[2];
1212    case 0x4a0: /* PM_WKEN_WKUP */
1213        return s->wken[2];
1214    case 0x4b0: /* PM_WKST_WKUP */
1215        return s->wkst[2];
1216
1217    case 0x500: /* CM_CLKEN_PLL */
1218        return s->clken[9];
1219    case 0x520: /* CM_IDLEST_CKGEN */
1220        ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8);
1221        if (!(s->clksel[6] & 3))
1222            /* Core uses 32-kHz clock */
1223            ret |= 3 << 0;
1224        else if (!s->dpll_lock)
1225            /* DPLL not locked, core uses ref_clk */
1226            ret |= 1 << 0;
1227        else
1228            /* Core uses DPLL */
1229            ret |= 2 << 0;
1230        return ret;
1231    case 0x530: /* CM_AUTOIDLE_PLL */
1232        return s->clkidle[5];
1233    case 0x540: /* CM_CLKSEL1_PLL */
1234        return s->clksel[5];
1235    case 0x544: /* CM_CLKSEL2_PLL */
1236        return s->clksel[6];
1237
1238    case 0x800: /* CM_FCLKEN_DSP */
1239        return s->clken[10];
1240    case 0x810: /* CM_ICLKEN_DSP */
1241        return s->clken[11];
1242    case 0x820: /* CM_IDLEST_DSP */
1243        /* TODO: check the actual iclk status */
1244        return 0x00000103;
1245    case 0x830: /* CM_AUTOIDLE_DSP */
1246        return s->clkidle[6];
1247    case 0x840: /* CM_CLKSEL_DSP */
1248        return s->clksel[7];
1249    case 0x848: /* CM_CLKSTCTRL_DSP */
1250        return s->clkctrl[3];
1251    case 0x850: /* RM_RSTCTRL_DSP */
1252        return 0;
1253    case 0x858: /* RM_RSTST_DSP */
1254        return s->rst[3];
1255    case 0x8c8: /* PM_WKDEP_DSP */
1256        return s->wkup[2];
1257    case 0x8e0: /* PM_PWSTCTRL_DSP */
1258        return s->power[3];
1259    case 0x8e4: /* PM_PWSTST_DSP */
1260        return 0x008030 | (s->power[3] & 0x3003);
1261
1262    case 0x8f0: /* PRCM_IRQSTATUS_DSP */
1263        return s->irqst[1];
1264    case 0x8f4: /* PRCM_IRQENABLE_DSP */
1265        return s->irqen[1];
1266
1267    case 0x8f8: /* PRCM_IRQSTATUS_IVA */
1268        return s->irqst[2];
1269    case 0x8fc: /* PRCM_IRQENABLE_IVA */
1270        return s->irqen[2];
1271    }
1272
1273    OMAP_BAD_REG(addr);
1274    return 0;
1275}
1276
1277static void omap_prcm_apll_update(struct omap_prcm_s *s)
1278{
1279    int mode[2];
1280
1281    mode[0] = (s->clken[9] >> 6) & 3;
1282    s->apll_lock[0] = (mode[0] == 3);
1283    mode[1] = (s->clken[9] >> 2) & 3;
1284    s->apll_lock[1] = (mode[1] == 3);
1285    /* TODO: update clocks */
1286
1287    if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[1] == 2)
1288        fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
1289                        __FUNCTION__);
1290}
1291
1292static void omap_prcm_dpll_update(struct omap_prcm_s *s)
1293{
1294    omap_clk dpll = omap_findclk(s->mpu, "dpll");
1295    omap_clk dpll_x2 = omap_findclk(s->mpu, "dpll");
1296    omap_clk core = omap_findclk(s->mpu, "core_clk");
1297    int mode = (s->clken[9] >> 0) & 3;
1298    int mult, div;
1299
1300    mult = (s->clksel[5] >> 12) & 0x3ff;
1301    div = (s->clksel[5] >> 8) & 0xf;
1302    if (mult == 0 || mult == 1)
1303        mode = 1;       /* Bypass */
1304
1305    s->dpll_lock = 0;
1306    switch (mode) {
1307    case 0:
1308        fprintf(stderr, "%s: bad EN_DPLL\n", __FUNCTION__);
1309        break;
1310    case 1:     /* Low-power bypass mode (Default) */
1311    case 2:     /* Fast-relock bypass mode */
1312        omap_clk_setrate(dpll, 1, 1);
1313        omap_clk_setrate(dpll_x2, 1, 1);
1314        break;
1315    case 3:     /* Lock mode */
1316        s->dpll_lock = 1; /* After 20 FINT cycles (ref_clk / (div + 1)).  */
1317
1318        omap_clk_setrate(dpll, div + 1, mult);
1319        omap_clk_setrate(dpll_x2, div + 1, mult * 2);
1320        break;
1321    }
1322
1323    switch ((s->clksel[6] >> 0) & 3) {
1324    case 0:
1325        omap_clk_reparent(core, omap_findclk(s->mpu, "clk32-kHz"));
1326        break;
1327    case 1:
1328        omap_clk_reparent(core, dpll);
1329        break;
1330    case 2:
1331        /* Default */
1332        omap_clk_reparent(core, dpll_x2);
1333        break;
1334    case 3:
1335        fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __FUNCTION__);
1336        break;
1337    }
1338}
1339
1340static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
1341                uint32_t value)
1342{
1343    struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
1344
1345    switch (addr) {
1346    case 0x000: /* PRCM_REVISION */
1347    case 0x054: /* PRCM_VOLTST */
1348    case 0x084: /* PRCM_CLKCFG_STATUS */
1349    case 0x1e4: /* PM_PWSTST_MPU */
1350    case 0x220: /* CM_IDLEST1_CORE */
1351    case 0x224: /* CM_IDLEST2_CORE */
1352    case 0x22c: /* CM_IDLEST4_CORE */
1353    case 0x2c8: /* PM_WKDEP_CORE */
1354    case 0x2e4: /* PM_PWSTST_CORE */
1355    case 0x320: /* CM_IDLEST_GFX */
1356    case 0x3e4: /* PM_PWSTST_GFX */
1357    case 0x420: /* CM_IDLEST_WKUP */
1358    case 0x520: /* CM_IDLEST_CKGEN */
1359    case 0x820: /* CM_IDLEST_DSP */
1360    case 0x8e4: /* PM_PWSTST_DSP */
1361        OMAP_RO_REG(addr);
1362        return;
1363
1364    case 0x010: /* PRCM_SYSCONFIG */
1365        s->sysconfig = value & 1;
1366        break;
1367
1368    case 0x018: /* PRCM_IRQSTATUS_MPU */
1369        s->irqst[0] &= ~value;
1370        omap_prcm_int_update(s, 0);
1371        break;
1372    case 0x01c: /* PRCM_IRQENABLE_MPU */
1373        s->irqen[0] = value & 0x3f;
1374        omap_prcm_int_update(s, 0);
1375        break;
1376
1377    case 0x050: /* PRCM_VOLTCTRL */
1378        s->voltctrl = value & 0xf1c3;
1379        break;
1380
1381    case 0x060: /* PRCM_CLKSRC_CTRL */
1382        s->clksrc[0] = value & 0xdb;
1383        /* TODO update clocks */
1384        break;
1385
1386    case 0x070: /* PRCM_CLKOUT_CTRL */
1387        s->clkout[0] = value & 0xbbbb;
1388        /* TODO update clocks */
1389        break;
1390
1391    case 0x078: /* PRCM_CLKEMUL_CTRL */
1392        s->clkemul[0] = value & 1;
1393        /* TODO update clocks */
1394        break;
1395
1396    case 0x080: /* PRCM_CLKCFG_CTRL */
1397        break;
1398
1399    case 0x090: /* PRCM_VOLTSETUP */
1400        s->setuptime[0] = value & 0xffff;
1401        break;
1402    case 0x094: /* PRCM_CLKSSETUP */
1403        s->setuptime[1] = value & 0xffff;
1404        break;
1405
1406    case 0x098: /* PRCM_POLCTRL */
1407        s->clkpol[0] = value & 0x701;
1408        break;
1409
1410    case 0x0b0: /* GENERAL_PURPOSE1 */
1411    case 0x0b4: /* GENERAL_PURPOSE2 */
1412    case 0x0b8: /* GENERAL_PURPOSE3 */
1413    case 0x0bc: /* GENERAL_PURPOSE4 */
1414    case 0x0c0: /* GENERAL_PURPOSE5 */
1415    case 0x0c4: /* GENERAL_PURPOSE6 */
1416    case 0x0c8: /* GENERAL_PURPOSE7 */
1417    case 0x0cc: /* GENERAL_PURPOSE8 */
1418    case 0x0d0: /* GENERAL_PURPOSE9 */
1419    case 0x0d4: /* GENERAL_PURPOSE10 */
1420    case 0x0d8: /* GENERAL_PURPOSE11 */
1421    case 0x0dc: /* GENERAL_PURPOSE12 */
1422    case 0x0e0: /* GENERAL_PURPOSE13 */
1423    case 0x0e4: /* GENERAL_PURPOSE14 */
1424    case 0x0e8: /* GENERAL_PURPOSE15 */
1425    case 0x0ec: /* GENERAL_PURPOSE16 */
1426    case 0x0f0: /* GENERAL_PURPOSE17 */
1427    case 0x0f4: /* GENERAL_PURPOSE18 */
1428    case 0x0f8: /* GENERAL_PURPOSE19 */
1429    case 0x0fc: /* GENERAL_PURPOSE20 */
1430        s->scratch[(addr - 0xb0) >> 2] = value;
1431        break;
1432
1433    case 0x140: /* CM_CLKSEL_MPU */
1434        s->clksel[0] = value & 0x1f;
1435        /* TODO update clocks */
1436        break;
1437    case 0x148: /* CM_CLKSTCTRL_MPU */
1438        s->clkctrl[0] = value & 0x1f;
1439        break;
1440
1441    case 0x158: /* RM_RSTST_MPU */
1442        s->rst[0] &= ~value;
1443        break;
1444    case 0x1c8: /* PM_WKDEP_MPU */
1445        s->wkup[0] = value & 0x15;
1446        break;
1447
1448    case 0x1d4: /* PM_EVGENCTRL_MPU */
1449        s->ev = value & 0x1f;
1450        break;
1451    case 0x1d8: /* PM_EVEGENONTIM_MPU */
1452        s->evtime[0] = value;
1453        break;
1454    case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
1455        s->evtime[1] = value;
1456        break;
1457
1458    case 0x1e0: /* PM_PWSTCTRL_MPU */
1459        s->power[0] = value & 0xc0f;
1460        break;
1461
1462    case 0x200: /* CM_FCLKEN1_CORE */
1463        s->clken[0] = value & 0xbfffffff;
1464        /* TODO update clocks */
1465        /* The EN_EAC bit only gets/puts func_96m_clk.  */
1466        break;
1467    case 0x204: /* CM_FCLKEN2_CORE */
1468        s->clken[1] = value & 0x00000007;
1469        /* TODO update clocks */
1470        break;
1471    case 0x210: /* CM_ICLKEN1_CORE */
1472        s->clken[2] = value & 0xfffffff9;
1473        /* TODO update clocks */
1474        /* The EN_EAC bit only gets/puts core_l4_iclk.  */
1475        break;
1476    case 0x214: /* CM_ICLKEN2_CORE */
1477        s->clken[3] = value & 0x00000007;
1478        /* TODO update clocks */
1479        break;
1480    case 0x21c: /* CM_ICLKEN4_CORE */
1481        s->clken[4] = value & 0x0000001f;
1482        /* TODO update clocks */
1483        break;
1484
1485    case 0x230: /* CM_AUTOIDLE1_CORE */
1486        s->clkidle[0] = value & 0xfffffff9;
1487        /* TODO update clocks */
1488        break;
1489    case 0x234: /* CM_AUTOIDLE2_CORE */
1490        s->clkidle[1] = value & 0x00000007;
1491        /* TODO update clocks */
1492        break;
1493    case 0x238: /* CM_AUTOIDLE3_CORE */
1494        s->clkidle[2] = value & 0x00000007;
1495        /* TODO update clocks */
1496        break;
1497    case 0x23c: /* CM_AUTOIDLE4_CORE */
1498        s->clkidle[3] = value & 0x0000001f;
1499        /* TODO update clocks */
1500        break;
1501
1502    case 0x240: /* CM_CLKSEL1_CORE */
1503        s->clksel[1] = value & 0x0fffbf7f;
1504        /* TODO update clocks */
1505        break;
1506
1507    case 0x244: /* CM_CLKSEL2_CORE */
1508        s->clksel[2] = value & 0x00fffffc;
1509        /* TODO update clocks */
1510        break;
1511
1512    case 0x248: /* CM_CLKSTCTRL_CORE */
1513        s->clkctrl[1] = value & 0x7;
1514        break;
1515
1516    case 0x2a0: /* PM_WKEN1_CORE */
1517        s->wken[0] = value & 0x04667ff8;
1518        break;
1519    case 0x2a4: /* PM_WKEN2_CORE */
1520        s->wken[1] = value & 0x00000005;
1521        break;
1522
1523    case 0x2b0: /* PM_WKST1_CORE */
1524        s->wkst[0] &= ~value;
1525        break;
1526    case 0x2b4: /* PM_WKST2_CORE */
1527        s->wkst[1] &= ~value;
1528        break;
1529
1530    case 0x2e0: /* PM_PWSTCTRL_CORE */
1531        s->power[1] = (value & 0x00fc3f) | (1 << 2);
1532        break;
1533
1534    case 0x300: /* CM_FCLKEN_GFX */
1535        s->clken[5] = value & 6;
1536        /* TODO update clocks */
1537        break;
1538    case 0x310: /* CM_ICLKEN_GFX */
1539        s->clken[6] = value & 1;
1540        /* TODO update clocks */
1541        break;
1542    case 0x340: /* CM_CLKSEL_GFX */
1543        s->clksel[3] = value & 7;
1544        /* TODO update clocks */
1545        break;
1546    case 0x348: /* CM_CLKSTCTRL_GFX */
1547        s->clkctrl[2] = value & 1;
1548        break;
1549    case 0x350: /* RM_RSTCTRL_GFX */
1550        s->rstctrl[0] = value & 1;
1551        /* TODO: reset */
1552        break;
1553    case 0x358: /* RM_RSTST_GFX */
1554        s->rst[1] &= ~value;
1555        break;
1556    case 0x3c8: /* PM_WKDEP_GFX */
1557        s->wkup[1] = value & 0x13;
1558        break;
1559    case 0x3e0: /* PM_PWSTCTRL_GFX */
1560        s->power[2] = (value & 0x00c0f) | (3 << 2);
1561        break;
1562
1563    case 0x400: /* CM_FCLKEN_WKUP */
1564        s->clken[7] = value & 0xd;
1565        /* TODO update clocks */
1566        break;
1567    case 0x410: /* CM_ICLKEN_WKUP */
1568        s->clken[8] = value & 0x3f;
1569        /* TODO update clocks */
1570        break;
1571    case 0x430: /* CM_AUTOIDLE_WKUP */
1572        s->clkidle[4] = value & 0x0000003f;
1573        /* TODO update clocks */
1574        break;
1575    case 0x440: /* CM_CLKSEL_WKUP */
1576        s->clksel[4] = value & 3;
1577        /* TODO update clocks */
1578        break;
1579    case 0x450: /* RM_RSTCTRL_WKUP */
1580        /* TODO: reset */
1581        if (value & 2)
1582            qemu_system_reset_request();
1583        break;
1584    case 0x454: /* RM_RSTTIME_WKUP */
1585        s->rsttime_wkup = value & 0x1fff;
1586        break;
1587    case 0x458: /* RM_RSTST_WKUP */
1588        s->rst[2] &= ~value;
1589        break;
1590    case 0x4a0: /* PM_WKEN_WKUP */
1591        s->wken[2] = value & 0x00000005;
1592        break;
1593    case 0x4b0: /* PM_WKST_WKUP */
1594        s->wkst[2] &= ~value;
1595        break;
1596
1597    case 0x500: /* CM_CLKEN_PLL */
1598        if (value & 0xffffff30)
1599            fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
1600                            "future compatiblity\n", __FUNCTION__);
1601        if ((s->clken[9] ^ value) & 0xcc) {
1602            s->clken[9] &= ~0xcc;
1603            s->clken[9] |= value & 0xcc;
1604            omap_prcm_apll_update(s);
1605        }
1606        if ((s->clken[9] ^ value) & 3) {
1607            s->clken[9] &= ~3;
1608            s->clken[9] |= value & 3;
1609            omap_prcm_dpll_update(s);
1610        }
1611        break;
1612    case 0x530: /* CM_AUTOIDLE_PLL */
1613        s->clkidle[5] = value & 0x000000cf;
1614        /* TODO update clocks */
1615        break;
1616    case 0x540: /* CM_CLKSEL1_PLL */
1617        if (value & 0xfc4000d7)
1618            fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
1619                            "future compatiblity\n", __FUNCTION__);
1620        if ((s->clksel[5] ^ value) & 0x003fff00) {
1621            s->clksel[5] = value & 0x03bfff28;
1622            omap_prcm_dpll_update(s);
1623        }
1624        /* TODO update the other clocks */
1625
1626        s->clksel[5] = value & 0x03bfff28;
1627        break;
1628    case 0x544: /* CM_CLKSEL2_PLL */
1629        if (value & ~3)
1630            fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
1631                            "future compatiblity\n", __FUNCTION__);
1632        if (s->clksel[6] != (value & 3)) {
1633            s->clksel[6] = value & 3;
1634            omap_prcm_dpll_update(s);
1635        }
1636        break;
1637
1638    case 0x800: /* CM_FCLKEN_DSP */
1639        s->clken[10] = value & 0x501;
1640        /* TODO update clocks */
1641        break;
1642    case 0x810: /* CM_ICLKEN_DSP */
1643        s->clken[11] = value & 0x2;
1644        /* TODO update clocks */
1645        break;
1646    case 0x830: /* CM_AUTOIDLE_DSP */
1647        s->clkidle[6] = value & 0x2;
1648        /* TODO update clocks */
1649        break;
1650    case 0x840: /* CM_CLKSEL_DSP */
1651        s->clksel[7] = value & 0x3fff;
1652        /* TODO update clocks */
1653        break;
1654    case 0x848: /* CM_CLKSTCTRL_DSP */
1655        s->clkctrl[3] = value & 0x101;
1656        break;
1657    case 0x850: /* RM_RSTCTRL_DSP */
1658        /* TODO: reset */
1659        break;
1660    case 0x858: /* RM_RSTST_DSP */
1661        s->rst[3] &= ~value;
1662        break;
1663    case 0x8c8: /* PM_WKDEP_DSP */
1664        s->wkup[2] = value & 0x13;
1665        break;
1666    case 0x8e0: /* PM_PWSTCTRL_DSP */
1667        s->power[3] = (value & 0x03017) | (3 << 2);
1668        break;
1669
1670    case 0x8f0: /* PRCM_IRQSTATUS_DSP */
1671        s->irqst[1] &= ~value;
1672        omap_prcm_int_update(s, 1);
1673        break;
1674    case 0x8f4: /* PRCM_IRQENABLE_DSP */
1675        s->irqen[1] = value & 0x7;
1676        omap_prcm_int_update(s, 1);
1677        break;
1678
1679    case 0x8f8: /* PRCM_IRQSTATUS_IVA */
1680        s->irqst[2] &= ~value;
1681        omap_prcm_int_update(s, 2);
1682        break;
1683    case 0x8fc: /* PRCM_IRQENABLE_IVA */
1684        s->irqen[2] = value & 0x7;
1685        omap_prcm_int_update(s, 2);
1686        break;
1687
1688    default:
1689        OMAP_BAD_REG(addr);
1690        return;
1691    }
1692}
1693
1694static CPUReadMemoryFunc * const omap_prcm_readfn[] = {
1695    omap_badwidth_read32,
1696    omap_badwidth_read32,
1697    omap_prcm_read,
1698};
1699
1700static CPUWriteMemoryFunc * const omap_prcm_writefn[] = {
1701    omap_badwidth_write32,
1702    omap_badwidth_write32,
1703    omap_prcm_write,
1704};
1705
1706static void omap_prcm_reset(struct omap_prcm_s *s)
1707{
1708    s->sysconfig = 0;
1709    s->irqst[0] = 0;
1710    s->irqst[1] = 0;
1711    s->irqst[2] = 0;
1712    s->irqen[0] = 0;
1713    s->irqen[1] = 0;
1714    s->irqen[2] = 0;
1715    s->voltctrl = 0x1040;
1716    s->ev = 0x14;
1717    s->evtime[0] = 0;
1718    s->evtime[1] = 0;
1719    s->clkctrl[0] = 0;
1720    s->clkctrl[1] = 0;
1721    s->clkctrl[2] = 0;
1722    s->clkctrl[3] = 0;
1723    s->clken[1] = 7;
1724    s->clken[3] = 7;
1725    s->clken[4] = 0;
1726    s->clken[5] = 0;
1727    s->clken[6] = 0;
1728    s->clken[7] = 0xc;
1729    s->clken[8] = 0x3e;
1730    s->clken[9] = 0x0d;
1731    s->clken[10] = 0;
1732    s->clken[11] = 0;
1733    s->clkidle[0] = 0;
1734    s->clkidle[2] = 7;
1735    s->clkidle[3] = 0;
1736    s->clkidle[4] = 0;
1737    s->clkidle[5] = 0x0c;
1738    s->clkidle[6] = 0;
1739    s->clksel[0] = 0x01;
1740    s->clksel[1] = 0x02100121;
1741    s->clksel[2] = 0x00000000;
1742    s->clksel[3] = 0x01;
1743    s->clksel[4] = 0;
1744    s->clksel[7] = 0x0121;
1745    s->wkup[0] = 0x15;
1746    s->wkup[1] = 0x13;
1747    s->wkup[2] = 0x13;
1748    s->wken[0] = 0x04667ff8;
1749    s->wken[1] = 0x00000005;
1750    s->wken[2] = 5;
1751    s->wkst[0] = 0;
1752    s->wkst[1] = 0;
1753    s->wkst[2] = 0;
1754    s->power[0] = 0x00c;
1755    s->power[1] = 4;
1756    s->power[2] = 0x0000c;
1757    s->power[3] = 0x14;
1758    s->rstctrl[0] = 1;
1759    s->rst[3] = 1;
1760    omap_prcm_apll_update(s);
1761    omap_prcm_dpll_update(s);
1762}
1763
1764static void omap_prcm_coldreset(struct omap_prcm_s *s)
1765{
1766    s->setuptime[0] = 0;
1767    s->setuptime[1] = 0;
1768    memset(&s->scratch, 0, sizeof(s->scratch));
1769    s->rst[0] = 0x01;
1770    s->rst[1] = 0x00;
1771    s->rst[2] = 0x01;
1772    s->clken[0] = 0;
1773    s->clken[2] = 0;
1774    s->clkidle[1] = 0;
1775    s->clksel[5] = 0;
1776    s->clksel[6] = 2;
1777    s->clksrc[0] = 0x43;
1778    s->clkout[0] = 0x0303;
1779    s->clkemul[0] = 0;
1780    s->clkpol[0] = 0x100;
1781    s->rsttime_wkup = 0x1002;
1782
1783    omap_prcm_reset(s);
1784}
1785
1786static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
1787                qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
1788                struct omap_mpu_state_s *mpu)
1789{
1790    int iomemtype;
1791    struct omap_prcm_s *s = (struct omap_prcm_s *)
1792            qemu_mallocz(sizeof(struct omap_prcm_s));
1793
1794    s->irq[0] = mpu_int;
1795    s->irq[1] = dsp_int;
1796    s->irq[2] = iva_int;
1797    s->mpu = mpu;
1798    omap_prcm_coldreset(s);
1799
1800    iomemtype = l4_register_io_memory(omap_prcm_readfn,
1801                    omap_prcm_writefn, s);
1802    omap_l4_attach(ta, 0, iomemtype);
1803    omap_l4_attach(ta, 1, iomemtype);
1804
1805    return s;
1806}
1807
1808/* System and Pinout control */
1809struct omap_sysctl_s {
1810    struct omap_mpu_state_s *mpu;
1811
1812    uint32_t sysconfig;
1813    uint32_t devconfig;
1814    uint32_t psaconfig;
1815    uint32_t padconf[0x45];
1816    uint8_t obs;
1817    uint32_t msuspendmux[5];
1818};
1819
1820static uint32_t omap_sysctl_read8(void *opaque, target_phys_addr_t addr)
1821{
1822
1823    struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
1824    int pad_offset, byte_offset;
1825    int value;
1826
1827    switch (addr) {
1828    case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
1829        pad_offset = (addr - 0x30) >> 2;
1830        byte_offset = (addr - 0x30) & (4 - 1);
1831
1832        value = s->padconf[pad_offset];
1833        value = (value >> (byte_offset * 8)) & 0xff;
1834
1835        return value;
1836
1837    default:
1838        break;
1839    }
1840
1841    OMAP_BAD_REG(addr);
1842    return 0;
1843}
1844
1845static uint32_t omap_sysctl_read(void *opaque, target_phys_addr_t addr)
1846{
1847    struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
1848
1849    switch (addr) {
1850    case 0x000: /* CONTROL_REVISION */
1851        return 0x20;
1852
1853    case 0x010: /* CONTROL_SYSCONFIG */
1854        return s->sysconfig;
1855
1856    case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
1857        return s->padconf[(addr - 0x30) >> 2];
1858
1859    case 0x270: /* CONTROL_DEBOBS */
1860        return s->obs;
1861
1862    case 0x274: /* CONTROL_DEVCONF */
1863        return s->devconfig;
1864
1865    case 0x28c: /* CONTROL_EMU_SUPPORT */
1866        return 0;
1867
1868    case 0x290: /* CONTROL_MSUSPENDMUX_0 */
1869        return s->msuspendmux[0];
1870    case 0x294: /* CONTROL_MSUSPENDMUX_1 */
1871        return s->msuspendmux[1];
1872    case 0x298: /* CONTROL_MSUSPENDMUX_2 */
1873        return s->msuspendmux[2];
1874    case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
1875        return s->msuspendmux[3];
1876    case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
1877        return s->msuspendmux[4];
1878    case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
1879        return 0;
1880
1881    case 0x2b8: /* CONTROL_PSA_CTRL */
1882        return s->psaconfig;
1883    case 0x2bc: /* CONTROL_PSA_CMD */
1884    case 0x2c0: /* CONTROL_PSA_VALUE */
1885        return 0;
1886
1887    case 0x2b0: /* CONTROL_SEC_CTRL */
1888        return 0x800000f1;
1889    case 0x2d0: /* CONTROL_SEC_EMU */
1890        return 0x80000015;
1891    case 0x2d4: /* CONTROL_SEC_TAP */
1892        return 0x8000007f;
1893    case 0x2b4: /* CONTROL_SEC_TEST */
1894    case 0x2f0: /* CONTROL_SEC_STATUS */
1895    case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
1896        /* Secure mode is not present on general-pusrpose device.  Outside
1897         * secure mode these values cannot be read or written.  */
1898        return 0;
1899
1900    case 0x2d8: /* CONTROL_OCM_RAM_PERM */
1901        return 0xff;
1902    case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
1903    case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
1904    case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
1905        /* No secure mode so no Extended Secure RAM present.  */
1906        return 0;
1907
1908    case 0x2f8: /* CONTROL_STATUS */
1909        /* Device Type => General-purpose */
1910        return 0x0300;
1911    case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
1912
1913    case 0x300: /* CONTROL_RPUB_KEY_H_0 */
1914    case 0x304: /* CONTROL_RPUB_KEY_H_1 */
1915    case 0x308: /* CONTROL_RPUB_KEY_H_2 */
1916    case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
1917        return 0xdecafbad;
1918
1919    case 0x310: /* CONTROL_RAND_KEY_0 */
1920    case 0x314: /* CONTROL_RAND_KEY_1 */
1921    case 0x318: /* CONTROL_RAND_KEY_2 */
1922    case 0x31c: /* CONTROL_RAND_KEY_3 */
1923    case 0x320: /* CONTROL_CUST_KEY_0 */
1924    case 0x324: /* CONTROL_CUST_KEY_1 */
1925    case 0x330: /* CONTROL_TEST_KEY_0 */
1926    case 0x334: /* CONTROL_TEST_KEY_1 */
1927    case 0x338: /* CONTROL_TEST_KEY_2 */
1928    case 0x33c: /* CONTROL_TEST_KEY_3 */
1929    case 0x340: /* CONTROL_TEST_KEY_4 */
1930    case 0x344: /* CONTROL_TEST_KEY_5 */
1931    case 0x348: /* CONTROL_TEST_KEY_6 */
1932    case 0x34c: /* CONTROL_TEST_KEY_7 */
1933    case 0x350: /* CONTROL_TEST_KEY_8 */
1934    case 0x354: /* CONTROL_TEST_KEY_9 */
1935        /* Can only be accessed in secure mode and when C_FieldAccEnable
1936         * bit is set in CONTROL_SEC_CTRL.
1937         * TODO: otherwise an interconnect access error is generated.  */
1938        return 0;
1939    }
1940
1941    OMAP_BAD_REG(addr);
1942    return 0;
1943}
1944
1945static void omap_sysctl_write8(void *opaque, target_phys_addr_t addr,
1946                uint32_t value)
1947{
1948    struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
1949    int pad_offset, byte_offset;
1950    int prev_value;
1951
1952    switch (addr) {
1953    case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
1954        pad_offset = (addr - 0x30) >> 2;
1955        byte_offset = (addr - 0x30) & (4 - 1);
1956
1957        prev_value = s->padconf[pad_offset];
1958        prev_value &= ~(0xff << (byte_offset * 8));
1959        prev_value |= ((value & 0x1f1f1f1f) << (byte_offset * 8)) & 0x1f1f1f1f;
1960        s->padconf[pad_offset] = prev_value;
1961        break;
1962
1963    default:
1964        OMAP_BAD_REG(addr);
1965        break;
1966    }
1967}
1968
1969static void omap_sysctl_write(void *opaque, target_phys_addr_t addr,
1970                uint32_t value)
1971{
1972    struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
1973
1974    switch (addr) {
1975    case 0x000: /* CONTROL_REVISION */
1976    case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
1977    case 0x2c0: /* CONTROL_PSA_VALUE */
1978    case 0x2f8: /* CONTROL_STATUS */
1979    case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
1980    case 0x300: /* CONTROL_RPUB_KEY_H_0 */
1981    case 0x304: /* CONTROL_RPUB_KEY_H_1 */
1982    case 0x308: /* CONTROL_RPUB_KEY_H_2 */
1983    case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
1984    case 0x310: /* CONTROL_RAND_KEY_0 */
1985    case 0x314: /* CONTROL_RAND_KEY_1 */
1986    case 0x318: /* CONTROL_RAND_KEY_2 */
1987    case 0x31c: /* CONTROL_RAND_KEY_3 */
1988    case 0x320: /* CONTROL_CUST_KEY_0 */
1989    case 0x324: /* CONTROL_CUST_KEY_1 */
1990    case 0x330: /* CONTROL_TEST_KEY_0 */
1991    case 0x334: /* CONTROL_TEST_KEY_1 */
1992    case 0x338: /* CONTROL_TEST_KEY_2 */
1993    case 0x33c: /* CONTROL_TEST_KEY_3 */
1994    case 0x340: /* CONTROL_TEST_KEY_4 */
1995    case 0x344: /* CONTROL_TEST_KEY_5 */
1996    case 0x348: /* CONTROL_TEST_KEY_6 */
1997    case 0x34c: /* CONTROL_TEST_KEY_7 */
1998    case 0x350: /* CONTROL_TEST_KEY_8 */
1999    case 0x354: /* CONTROL_TEST_KEY_9 */
2000        OMAP_RO_REG(addr);
2001        return;
2002
2003    case 0x010: /* CONTROL_SYSCONFIG */
2004        s->sysconfig = value & 0x1e;
2005        break;
2006
2007    case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
2008        /* XXX: should check constant bits */
2009        s->padconf[(addr - 0x30) >> 2] = value & 0x1f1f1f1f;
2010        break;
2011
2012    case 0x270: /* CONTROL_DEBOBS */
2013        s->obs = value & 0xff;
2014        break;
2015
2016    case 0x274: /* CONTROL_DEVCONF */
2017        s->devconfig = value & 0xffffc7ff;
2018        break;
2019
2020    case 0x28c: /* CONTROL_EMU_SUPPORT */
2021        break;
2022
2023    case 0x290: /* CONTROL_MSUSPENDMUX_0 */
2024        s->msuspendmux[0] = value & 0x3fffffff;
2025        break;
2026    case 0x294: /* CONTROL_MSUSPENDMUX_1 */
2027        s->msuspendmux[1] = value & 0x3fffffff;
2028        break;
2029    case 0x298: /* CONTROL_MSUSPENDMUX_2 */
2030        s->msuspendmux[2] = value & 0x3fffffff;
2031        break;
2032    case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
2033        s->msuspendmux[3] = value & 0x3fffffff;
2034        break;
2035    case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
2036        s->msuspendmux[4] = value & 0x3fffffff;
2037        break;
2038
2039    case 0x2b8: /* CONTROL_PSA_CTRL */
2040        s->psaconfig = value & 0x1c;
2041        s->psaconfig |= (value & 0x20) ? 2 : 1;
2042        break;
2043    case 0x2bc: /* CONTROL_PSA_CMD */
2044        break;
2045
2046    case 0x2b0: /* CONTROL_SEC_CTRL */
2047    case 0x2b4: /* CONTROL_SEC_TEST */
2048    case 0x2d0: /* CONTROL_SEC_EMU */
2049    case 0x2d4: /* CONTROL_SEC_TAP */
2050    case 0x2d8: /* CONTROL_OCM_RAM_PERM */
2051    case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
2052    case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
2053    case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
2054    case 0x2f0: /* CONTROL_SEC_STATUS */
2055    case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
2056        break;
2057
2058    default:
2059        OMAP_BAD_REG(addr);
2060        return;
2061    }
2062}
2063
2064static CPUReadMemoryFunc * const omap_sysctl_readfn[] = {
2065    omap_sysctl_read8,
2066    omap_badwidth_read32,       /* TODO */
2067    omap_sysctl_read,
2068};
2069
2070static CPUWriteMemoryFunc * const omap_sysctl_writefn[] = {
2071    omap_sysctl_write8,
2072    omap_badwidth_write32,      /* TODO */
2073    omap_sysctl_write,
2074};
2075
2076static void omap_sysctl_reset(struct omap_sysctl_s *s)
2077{
2078    /* (power-on reset) */
2079    s->sysconfig = 0;
2080    s->obs = 0;
2081    s->devconfig = 0x0c000000;
2082    s->msuspendmux[0] = 0x00000000;
2083    s->msuspendmux[1] = 0x00000000;
2084    s->msuspendmux[2] = 0x00000000;
2085    s->msuspendmux[3] = 0x00000000;
2086    s->msuspendmux[4] = 0x00000000;
2087    s->psaconfig = 1;
2088
2089    s->padconf[0x00] = 0x000f0f0f;
2090    s->padconf[0x01] = 0x00000000;
2091    s->padconf[0x02] = 0x00000000;
2092    s->padconf[0x03] = 0x00000000;
2093    s->padconf[0x04] = 0x00000000;
2094    s->padconf[0x05] = 0x00000000;
2095    s->padconf[0x06] = 0x00000000;
2096    s->padconf[0x07] = 0x00000000;
2097    s->padconf[0x08] = 0x08080800;
2098    s->padconf[0x09] = 0x08080808;
2099    s->padconf[0x0a] = 0x08080808;
2100    s->padconf[0x0b] = 0x08080808;
2101    s->padconf[0x0c] = 0x08080808;
2102    s->padconf[0x0d] = 0x08080800;
2103    s->padconf[0x0e] = 0x08080808;
2104    s->padconf[0x0f] = 0x08080808;
2105    s->padconf[0x10] = 0x18181808;      /* | 0x07070700 if SBoot3 */
2106    s->padconf[0x11] = 0x18181818;      /* | 0x07070707 if SBoot3 */
2107    s->padconf[0x12] = 0x18181818;      /* | 0x07070707 if SBoot3 */
2108    s->padconf[0x13] = 0x18181818;      /* | 0x07070707 if SBoot3 */
2109    s->padconf[0x14] = 0x18181818;      /* | 0x00070707 if SBoot3 */
2110    s->padconf[0x15] = 0x18181818;
2111    s->padconf[0x16] = 0x18181818;      /* | 0x07000000 if SBoot3 */
2112    s->padconf[0x17] = 0x1f001f00;
2113    s->padconf[0x18] = 0x1f1f1f1f;
2114    s->padconf[0x19] = 0x00000000;
2115    s->padconf[0x1a] = 0x1f180000;
2116    s->padconf[0x1b] = 0x00001f1f;
2117    s->padconf[0x1c] = 0x1f001f00;
2118    s->padconf[0x1d] = 0x00000000;
2119    s->padconf[0x1e] = 0x00000000;
2120    s->padconf[0x1f] = 0x08000000;
2121    s->padconf[0x20] = 0x08080808;
2122    s->padconf[0x21] = 0x08080808;
2123    s->padconf[0x22] = 0x0f080808;
2124    s->padconf[0x23] = 0x0f0f0f0f;
2125    s->padconf[0x24] = 0x000f0f0f;
2126    s->padconf[0x25] = 0x1f1f1f0f;
2127    s->padconf[0x26] = 0x080f0f1f;
2128    s->padconf[0x27] = 0x070f1808;
2129    s->padconf[0x28] = 0x0f070707;
2130    s->padconf[0x29] = 0x000f0f1f;
2131    s->padconf[0x2a] = 0x0f0f0f1f;
2132    s->padconf[0x2b] = 0x08000000;
2133    s->padconf[0x2c] = 0x0000001f;
2134    s->padconf[0x2d] = 0x0f0f1f00;
2135    s->padconf[0x2e] = 0x1f1f0f0f;
2136    s->padconf[0x2f] = 0x0f1f1f1f;
2137    s->padconf[0x30] = 0x0f0f0f0f;
2138    s->padconf[0x31] = 0x0f1f0f1f;
2139    s->padconf[0x32] = 0x0f0f0f0f;
2140    s->padconf[0x33] = 0x0f1f0f1f;
2141    s->padconf[0x34] = 0x1f1f0f0f;
2142    s->padconf[0x35] = 0x0f0f1f1f;
2143    s->padconf[0x36] = 0x0f0f1f0f;
2144    s->padconf[0x37] = 0x0f0f0f0f;
2145    s->padconf[0x38] = 0x1f18180f;
2146    s->padconf[0x39] = 0x1f1f1f1f;
2147    s->padconf[0x3a] = 0x00001f1f;
2148    s->padconf[0x3b] = 0x00000000;
2149    s->padconf[0x3c] = 0x00000000;
2150    s->padconf[0x3d] = 0x0f0f0f0f;
2151    s->padconf[0x3e] = 0x18000f0f;
2152    s->padconf[0x3f] = 0x00070000;
2153    s->padconf[0x40] = 0x00000707;
2154    s->padconf[0x41] = 0x0f1f0700;
2155    s->padconf[0x42] = 0x1f1f070f;
2156    s->padconf[0x43] = 0x0008081f;
2157    s->padconf[0x44] = 0x00000800;
2158}
2159
2160static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
2161                omap_clk iclk, struct omap_mpu_state_s *mpu)
2162{
2163    int iomemtype;
2164    struct omap_sysctl_s *s = (struct omap_sysctl_s *)
2165            qemu_mallocz(sizeof(struct omap_sysctl_s));
2166
2167    s->mpu = mpu;
2168    omap_sysctl_reset(s);
2169
2170    iomemtype = l4_register_io_memory(omap_sysctl_readfn,
2171                    omap_sysctl_writefn, s);
2172    omap_l4_attach(ta, 0, iomemtype);
2173
2174    return s;
2175}
2176
2177/* General chip reset */
2178static void omap2_mpu_reset(void *opaque)
2179{
2180    struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
2181
2182    omap_inth_reset(mpu->ih[0]);
2183    omap_dma_reset(mpu->dma);
2184    omap_prcm_reset(mpu->prcm);
2185    omap_sysctl_reset(mpu->sysc);
2186    omap_gp_timer_reset(mpu->gptimer[0]);
2187    omap_gp_timer_reset(mpu->gptimer[1]);
2188    omap_gp_timer_reset(mpu->gptimer[2]);
2189    omap_gp_timer_reset(mpu->gptimer[3]);
2190    omap_gp_timer_reset(mpu->gptimer[4]);
2191    omap_gp_timer_reset(mpu->gptimer[5]);
2192    omap_gp_timer_reset(mpu->gptimer[6]);
2193    omap_gp_timer_reset(mpu->gptimer[7]);
2194    omap_gp_timer_reset(mpu->gptimer[8]);
2195    omap_gp_timer_reset(mpu->gptimer[9]);
2196    omap_gp_timer_reset(mpu->gptimer[10]);
2197    omap_gp_timer_reset(mpu->gptimer[11]);
2198    omap_synctimer_reset(mpu->synctimer);
2199    omap_sdrc_reset(mpu->sdrc);
2200    omap_gpmc_reset(mpu->gpmc);
2201    omap_dss_reset(mpu->dss);
2202    omap_uart_reset(mpu->uart[0]);
2203    omap_uart_reset(mpu->uart[1]);
2204    omap_uart_reset(mpu->uart[2]);
2205    omap_mmc_reset(mpu->mmc);
2206    omap_gpif_reset(mpu->gpif);
2207    omap_mcspi_reset(mpu->mcspi[0]);
2208    omap_mcspi_reset(mpu->mcspi[1]);
2209    omap_i2c_reset(mpu->i2c[0]);
2210    omap_i2c_reset(mpu->i2c[1]);
2211    cpu_reset(mpu->env);
2212}
2213
2214static int omap2_validate_addr(struct omap_mpu_state_s *s,
2215                target_phys_addr_t addr)
2216{
2217    return 1;
2218}
2219
2220static const struct dma_irq_map omap2_dma_irq_map[] = {
2221    { 0, OMAP_INT_24XX_SDMA_IRQ0 },
2222    { 0, OMAP_INT_24XX_SDMA_IRQ1 },
2223    { 0, OMAP_INT_24XX_SDMA_IRQ2 },
2224    { 0, OMAP_INT_24XX_SDMA_IRQ3 },
2225};
2226
2227struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
2228                const char *core)
2229{
2230    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
2231            qemu_mallocz(sizeof(struct omap_mpu_state_s));
2232    ram_addr_t sram_base, q2_base;
2233    qemu_irq *cpu_irq;
2234    qemu_irq dma_irqs[4];
2235    omap_clk gpio_clks[4];
2236    DriveInfo *dinfo;
2237    int i;
2238
2239    /* Core */
2240    s->mpu_model = omap2420;
2241    s->env = cpu_init(core ?: "arm1136-r2");
2242    if (!s->env) {
2243        fprintf(stderr, "Unable to find CPU definition\n");
2244        exit(1);
2245    }
2246    s->sdram_size = sdram_size;
2247    s->sram_size = OMAP242X_SRAM_SIZE;
2248
2249    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
2250
2251    /* Clocks */
2252    omap_clk_init(s);
2253
2254    /* Memory-mapped stuff */
2255    cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
2256                    (q2_base = qemu_ram_alloc(NULL, "omap2.dram",
2257                                              s->sdram_size)) | IO_MEM_RAM);
2258    cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
2259                    (sram_base = qemu_ram_alloc(NULL, "omap2.sram",
2260                                                s->sram_size)) | IO_MEM_RAM);
2261
2262    s->l4 = omap_l4_init(OMAP2_L4_BASE, 54);
2263
2264    /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
2265    cpu_irq = arm_pic_init_cpu(s->env);
2266    s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0],
2267                    cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
2268                    omap_findclk(s, "mpu_intc_fclk"),
2269                    omap_findclk(s, "mpu_intc_iclk"));
2270
2271    s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
2272                    s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s);
2273
2274    s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
2275                    omap_findclk(s, "omapctrl_iclk"), s);
2276
2277    for (i = 0; i < 4; i ++)
2278        dma_irqs[i] =
2279                s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr];
2280    s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
2281                    omap_findclk(s, "sdma_iclk"),
2282                    omap_findclk(s, "sdma_fclk"));
2283    s->port->addr_valid = omap2_validate_addr;
2284
2285    /* Register SDRAM and SRAM ports for fast DMA transfers.  */
2286    soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
2287    soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
2288
2289    s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
2290                    s->irq[0][OMAP_INT_24XX_UART1_IRQ],
2291                    omap_findclk(s, "uart1_fclk"),
2292                    omap_findclk(s, "uart1_iclk"),
2293                    s->drq[OMAP24XX_DMA_UART1_TX],
2294                    s->drq[OMAP24XX_DMA_UART1_RX],
2295                    "uart1",
2296                    serial_hds[0]);
2297    s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20),
2298                    s->irq[0][OMAP_INT_24XX_UART2_IRQ],
2299                    omap_findclk(s, "uart2_fclk"),
2300                    omap_findclk(s, "uart2_iclk"),
2301                    s->drq[OMAP24XX_DMA_UART2_TX],
2302                    s->drq[OMAP24XX_DMA_UART2_RX],
2303                    "uart2",
2304                    serial_hds[0] ? serial_hds[1] : NULL);
2305    s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21),
2306                    s->irq[0][OMAP_INT_24XX_UART3_IRQ],
2307                    omap_findclk(s, "uart3_fclk"),
2308                    omap_findclk(s, "uart3_iclk"),
2309                    s->drq[OMAP24XX_DMA_UART3_TX],
2310                    s->drq[OMAP24XX_DMA_UART3_RX],
2311                    "uart3",
2312                    serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
2313
2314    s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
2315                    s->irq[0][OMAP_INT_24XX_GPTIMER1],
2316                    omap_findclk(s, "wu_gpt1_clk"),
2317                    omap_findclk(s, "wu_l4_iclk"));
2318    s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
2319                    s->irq[0][OMAP_INT_24XX_GPTIMER2],
2320                    omap_findclk(s, "core_gpt2_clk"),
2321                    omap_findclk(s, "core_l4_iclk"));
2322    s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
2323                    s->irq[0][OMAP_INT_24XX_GPTIMER3],
2324                    omap_findclk(s, "core_gpt3_clk"),
2325                    omap_findclk(s, "core_l4_iclk"));
2326    s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
2327                    s->irq[0][OMAP_INT_24XX_GPTIMER4],
2328                    omap_findclk(s, "core_gpt4_clk"),
2329                    omap_findclk(s, "core_l4_iclk"));
2330    s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
2331                    s->irq[0][OMAP_INT_24XX_GPTIMER5],
2332                    omap_findclk(s, "core_gpt5_clk"),
2333                    omap_findclk(s, "core_l4_iclk"));
2334    s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
2335                    s->irq[0][OMAP_INT_24XX_GPTIMER6],
2336                    omap_findclk(s, "core_gpt6_clk"),
2337                    omap_findclk(s, "core_l4_iclk"));
2338    s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
2339                    s->irq[0][OMAP_INT_24XX_GPTIMER7],
2340                    omap_findclk(s, "core_gpt7_clk"),
2341                    omap_findclk(s, "core_l4_iclk"));
2342    s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
2343                    s->irq[0][OMAP_INT_24XX_GPTIMER8],
2344                    omap_findclk(s, "core_gpt8_clk"),
2345                    omap_findclk(s, "core_l4_iclk"));
2346    s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
2347                    s->irq[0][OMAP_INT_24XX_GPTIMER9],
2348                    omap_findclk(s, "core_gpt9_clk"),
2349                    omap_findclk(s, "core_l4_iclk"));
2350    s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
2351                    s->irq[0][OMAP_INT_24XX_GPTIMER10],
2352                    omap_findclk(s, "core_gpt10_clk"),
2353                    omap_findclk(s, "core_l4_iclk"));
2354    s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
2355                    s->irq[0][OMAP_INT_24XX_GPTIMER11],
2356                    omap_findclk(s, "core_gpt11_clk"),
2357                    omap_findclk(s, "core_l4_iclk"));
2358    s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
2359                    s->irq[0][OMAP_INT_24XX_GPTIMER12],
2360                    omap_findclk(s, "core_gpt12_clk"),
2361                    omap_findclk(s, "core_l4_iclk"));
2362
2363    omap_tap_init(omap_l4ta(s->l4, 2), s);
2364
2365    s->synctimer = omap_synctimer_init(omap_l4tao(s->l4, 2), s,
2366                    omap_findclk(s, "clk32-kHz"),
2367                    omap_findclk(s, "core_l4_iclk"));
2368
2369    s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
2370                    s->irq[0][OMAP_INT_24XX_I2C1_IRQ],
2371                    &s->drq[OMAP24XX_DMA_I2C1_TX],
2372                    omap_findclk(s, "i2c1.fclk"),
2373                    omap_findclk(s, "i2c1.iclk"));
2374    s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
2375                    s->irq[0][OMAP_INT_24XX_I2C2_IRQ],
2376                    &s->drq[OMAP24XX_DMA_I2C2_TX],
2377                    omap_findclk(s, "i2c2.fclk"),
2378                    omap_findclk(s, "i2c2.iclk"));
2379
2380    gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
2381    gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
2382    gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
2383    gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
2384    s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
2385                    &s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
2386                    gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
2387
2388    s->sdrc = omap_sdrc_init(0x68009000);
2389    s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
2390
2391    dinfo = drive_get(IF_SD, 0, 0);
2392    if (!dinfo) {
2393        fprintf(stderr, "qemu: missing SecureDigital device\n");
2394        exit(1);
2395    }
2396    s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv,
2397                    s->irq[0][OMAP_INT_24XX_MMC_IRQ],
2398                    &s->drq[OMAP24XX_DMA_MMC1_TX],
2399                    omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
2400
2401    s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
2402                    s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ],
2403                    &s->drq[OMAP24XX_DMA_SPI1_TX0],
2404                    omap_findclk(s, "spi1_fclk"),
2405                    omap_findclk(s, "spi1_iclk"));
2406    s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
2407                    s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ],
2408                    &s->drq[OMAP24XX_DMA_SPI2_TX0],
2409                    omap_findclk(s, "spi2_fclk"),
2410                    omap_findclk(s, "spi2_iclk"));
2411
2412    s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800,
2413                    /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
2414                    s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
2415                    omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
2416                    omap_findclk(s, "dss_54m_clk"),
2417                    omap_findclk(s, "dss_l3_iclk"),
2418                    omap_findclk(s, "dss_l4_iclk"));
2419
2420    omap_sti_init(omap_l4ta(s->l4, 18), 0x54000000,
2421                    s->irq[0][OMAP_INT_24XX_STI], omap_findclk(s, "emul_ck"),
2422                    serial_hds[0] && serial_hds[1] && serial_hds[2] ?
2423                    serial_hds[3] : NULL);
2424
2425    s->eac = omap_eac_init(omap_l4ta(s->l4, 32),
2426                    s->irq[0][OMAP_INT_24XX_EAC_IRQ],
2427                    /* Ten consecutive lines */
2428                    &s->drq[OMAP24XX_DMA_EAC_AC_RD],
2429                    omap_findclk(s, "func_96m_clk"),
2430                    omap_findclk(s, "core_l4_iclk"));
2431
2432    /* All register mappings (includin those not currenlty implemented):
2433     * SystemControlMod 48000000 - 48000fff
2434     * SystemControlL4  48001000 - 48001fff
2435     * 32kHz Timer Mod  48004000 - 48004fff
2436     * 32kHz Timer L4   48005000 - 48005fff
2437     * PRCM ModA        48008000 - 480087ff
2438     * PRCM ModB        48008800 - 48008fff
2439     * PRCM L4          48009000 - 48009fff
2440     * TEST-BCM Mod     48012000 - 48012fff
2441     * TEST-BCM L4      48013000 - 48013fff
2442     * TEST-TAP Mod     48014000 - 48014fff
2443     * TEST-TAP L4      48015000 - 48015fff
2444     * GPIO1 Mod        48018000 - 48018fff
2445     * GPIO Top         48019000 - 48019fff
2446     * GPIO2 Mod        4801a000 - 4801afff
2447     * GPIO L4          4801b000 - 4801bfff
2448     * GPIO3 Mod        4801c000 - 4801cfff
2449     * GPIO4 Mod        4801e000 - 4801efff
2450     * WDTIMER1 Mod     48020000 - 48010fff
2451     * WDTIMER Top      48021000 - 48011fff
2452     * WDTIMER2 Mod     48022000 - 48012fff
2453     * WDTIMER L4       48023000 - 48013fff
2454     * WDTIMER3 Mod     48024000 - 48014fff
2455     * WDTIMER3 L4      48025000 - 48015fff
2456     * WDTIMER4 Mod     48026000 - 48016fff
2457     * WDTIMER4 L4      48027000 - 48017fff
2458     * GPTIMER1 Mod     48028000 - 48018fff
2459     * GPTIMER1 L4      48029000 - 48019fff
2460     * GPTIMER2 Mod     4802a000 - 4801afff
2461     * GPTIMER2 L4      4802b000 - 4801bfff
2462     * L4-Config AP     48040000 - 480407ff
2463     * L4-Config IP     48040800 - 48040fff
2464     * L4-Config LA     48041000 - 48041fff
2465     * ARM11ETB Mod     48048000 - 48049fff
2466     * ARM11ETB L4      4804a000 - 4804afff
2467     * DISPLAY Top      48050000 - 480503ff
2468     * DISPLAY DISPC    48050400 - 480507ff
2469     * DISPLAY RFBI     48050800 - 48050bff
2470     * DISPLAY VENC     48050c00 - 48050fff
2471     * DISPLAY L4       48051000 - 48051fff
2472     * CAMERA Top       48052000 - 480523ff
2473     * CAMERA core      48052400 - 480527ff
2474     * CAMERA DMA       48052800 - 48052bff
2475     * CAMERA MMU       48052c00 - 48052fff
2476     * CAMERA L4        48053000 - 48053fff
2477     * SDMA Mod         48056000 - 48056fff
2478     * SDMA L4          48057000 - 48057fff
2479     * SSI Top          48058000 - 48058fff
2480     * SSI GDD          48059000 - 48059fff
2481     * SSI Port1        4805a000 - 4805afff
2482     * SSI Port2        4805b000 - 4805bfff
2483     * SSI L4           4805c000 - 4805cfff
2484     * USB Mod          4805e000 - 480fefff
2485     * USB L4           4805f000 - 480fffff
2486     * WIN_TRACER1 Mod  48060000 - 48060fff
2487     * WIN_TRACER1 L4   48061000 - 48061fff
2488     * WIN_TRACER2 Mod  48062000 - 48062fff
2489     * WIN_TRACER2 L4   48063000 - 48063fff
2490     * WIN_TRACER3 Mod  48064000 - 48064fff
2491     * WIN_TRACER3 L4   48065000 - 48065fff
2492     * WIN_TRACER4 Top  48066000 - 480660ff
2493     * WIN_TRACER4 ETT  48066100 - 480661ff
2494     * WIN_TRACER4 WT   48066200 - 480662ff
2495     * WIN_TRACER4 L4   48067000 - 48067fff
2496     * XTI Mod          48068000 - 48068fff
2497     * XTI L4           48069000 - 48069fff
2498     * UART1 Mod        4806a000 - 4806afff
2499     * UART1 L4         4806b000 - 4806bfff
2500     * UART2 Mod        4806c000 - 4806cfff
2501     * UART2 L4         4806d000 - 4806dfff
2502     * UART3 Mod        4806e000 - 4806efff
2503     * UART3 L4         4806f000 - 4806ffff
2504     * I2C1 Mod         48070000 - 48070fff
2505     * I2C1 L4          48071000 - 48071fff
2506     * I2C2 Mod         48072000 - 48072fff
2507     * I2C2 L4          48073000 - 48073fff
2508     * McBSP1 Mod       48074000 - 48074fff
2509     * McBSP1 L4        48075000 - 48075fff
2510     * McBSP2 Mod       48076000 - 48076fff
2511     * McBSP2 L4        48077000 - 48077fff
2512     * GPTIMER3 Mod     48078000 - 48078fff
2513     * GPTIMER3 L4      48079000 - 48079fff
2514     * GPTIMER4 Mod     4807a000 - 4807afff
2515     * GPTIMER4 L4      4807b000 - 4807bfff
2516     * GPTIMER5 Mod     4807c000 - 4807cfff
2517     * GPTIMER5 L4      4807d000 - 4807dfff
2518     * GPTIMER6 Mod     4807e000 - 4807efff
2519     * GPTIMER6 L4      4807f000 - 4807ffff
2520     * GPTIMER7 Mod     48080000 - 48080fff
2521     * GPTIMER7 L4      48081000 - 48081fff
2522     * GPTIMER8 Mod     48082000 - 48082fff
2523     * GPTIMER8 L4      48083000 - 48083fff
2524     * GPTIMER9 Mod     48084000 - 48084fff
2525     * GPTIMER9 L4      48085000 - 48085fff
2526     * GPTIMER10 Mod    48086000 - 48086fff
2527     * GPTIMER10 L4     48087000 - 48087fff
2528     * GPTIMER11 Mod    48088000 - 48088fff
2529     * GPTIMER11 L4     48089000 - 48089fff
2530     * GPTIMER12 Mod    4808a000 - 4808afff
2531     * GPTIMER12 L4     4808b000 - 4808bfff
2532     * EAC Mod          48090000 - 48090fff
2533     * EAC L4           48091000 - 48091fff
2534     * FAC Mod          48092000 - 48092fff
2535     * FAC L4           48093000 - 48093fff
2536     * MAILBOX Mod      48094000 - 48094fff
2537     * MAILBOX L4       48095000 - 48095fff
2538     * SPI1 Mod         48098000 - 48098fff
2539     * SPI1 L4          48099000 - 48099fff
2540     * SPI2 Mod         4809a000 - 4809afff
2541     * SPI2 L4          4809b000 - 4809bfff
2542     * MMC/SDIO Mod     4809c000 - 4809cfff
2543     * MMC/SDIO L4      4809d000 - 4809dfff
2544     * MS_PRO Mod       4809e000 - 4809efff
2545     * MS_PRO L4        4809f000 - 4809ffff
2546     * RNG Mod          480a0000 - 480a0fff
2547     * RNG L4           480a1000 - 480a1fff
2548     * DES3DES Mod      480a2000 - 480a2fff
2549     * DES3DES L4       480a3000 - 480a3fff
2550     * SHA1MD5 Mod      480a4000 - 480a4fff
2551     * SHA1MD5 L4       480a5000 - 480a5fff
2552     * AES Mod          480a6000 - 480a6fff
2553     * AES L4           480a7000 - 480a7fff
2554     * PKA Mod          480a8000 - 480a9fff
2555     * PKA L4           480aa000 - 480aafff
2556     * MG Mod           480b0000 - 480b0fff
2557     * MG L4            480b1000 - 480b1fff
2558     * HDQ/1-wire Mod   480b2000 - 480b2fff
2559     * HDQ/1-wire L4    480b3000 - 480b3fff
2560     * MPU interrupt    480fe000 - 480fefff
2561     * STI channel base 54000000 - 5400ffff
2562     * IVA RAM          5c000000 - 5c01ffff
2563     * IVA ROM          5c020000 - 5c027fff
2564     * IMG_BUF_A        5c040000 - 5c040fff
2565     * IMG_BUF_B        5c042000 - 5c042fff
2566     * VLCDS            5c048000 - 5c0487ff
2567     * IMX_COEF         5c049000 - 5c04afff
2568     * IMX_CMD          5c051000 - 5c051fff
2569     * VLCDQ            5c053000 - 5c0533ff
2570     * VLCDH            5c054000 - 5c054fff
2571     * SEQ_CMD          5c055000 - 5c055fff
2572     * IMX_REG          5c056000 - 5c0560ff
2573     * VLCD_REG         5c056100 - 5c0561ff
2574     * SEQ_REG          5c056200 - 5c0562ff
2575     * IMG_BUF_REG      5c056300 - 5c0563ff
2576     * SEQIRQ_REG       5c056400 - 5c0564ff
2577     * OCP_REG          5c060000 - 5c060fff
2578     * SYSC_REG         5c070000 - 5c070fff
2579     * MMU_REG          5d000000 - 5d000fff
2580     * sDMA R           68000400 - 680005ff
2581     * sDMA W           68000600 - 680007ff
2582     * Display Control  68000800 - 680009ff
2583     * DSP subsystem    68000a00 - 68000bff
2584     * MPU subsystem    68000c00 - 68000dff
2585     * IVA subsystem    68001000 - 680011ff
2586     * USB              68001200 - 680013ff
2587     * Camera           68001400 - 680015ff
2588     * VLYNQ (firewall) 68001800 - 68001bff
2589     * VLYNQ            68001e00 - 68001fff
2590     * SSI              68002000 - 680021ff
2591     * L4               68002400 - 680025ff
2592     * DSP (firewall)   68002800 - 68002bff
2593     * DSP subsystem    68002e00 - 68002fff
2594     * IVA (firewall)   68003000 - 680033ff
2595     * IVA              68003600 - 680037ff
2596     * GFX              68003a00 - 68003bff
2597     * CMDWR emulation  68003c00 - 68003dff
2598     * SMS              68004000 - 680041ff
2599     * OCM              68004200 - 680043ff
2600     * GPMC             68004400 - 680045ff
2601     * RAM (firewall)   68005000 - 680053ff
2602     * RAM (err login)  68005400 - 680057ff
2603     * ROM (firewall)   68005800 - 68005bff
2604     * ROM (err login)  68005c00 - 68005fff
2605     * GPMC (firewall)  68006000 - 680063ff
2606     * GPMC (err login) 68006400 - 680067ff
2607     * SMS (err login)  68006c00 - 68006fff
2608     * SMS registers    68008000 - 68008fff
2609     * SDRC registers   68009000 - 68009fff
2610     * GPMC registers   6800a000   6800afff
2611     */
2612
2613    qemu_register_reset(omap2_mpu_reset, s);
2614
2615    return s;
2616}
2617