qemu/hw/nseries.c
<<
>>
Prefs
   1/*
   2 * Nokia N-series internet tablets.
   3 *
   4 * Copyright (C) 2007 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 "qemu-common.h"
  22#include "sysemu.h"
  23#include "omap.h"
  24#include "arm-misc.h"
  25#include "irq.h"
  26#include "console.h"
  27#include "boards.h"
  28#include "i2c.h"
  29#include "devices.h"
  30#include "flash.h"
  31#include "hw.h"
  32#include "bt.h"
  33#include "loader.h"
  34
  35/* Nokia N8x0 support */
  36struct n800_s {
  37    struct omap_mpu_state_s *cpu;
  38
  39    struct rfbi_chip_s blizzard;
  40    struct {
  41        void *opaque;
  42        uint32_t (*txrx)(void *opaque, uint32_t value, int len);
  43        uWireSlave *chip;
  44    } ts;
  45    i2c_bus *i2c;
  46
  47    int keymap[0x80];
  48    i2c_slave *kbd;
  49
  50    TUSBState *usb;
  51    void *retu;
  52    void *tahvo;
  53    void *nand;
  54};
  55
  56/* GPIO pins */
  57#define N8X0_TUSB_ENABLE_GPIO           0
  58#define N800_MMC2_WP_GPIO               8
  59#define N800_UNKNOWN_GPIO0              9       /* out */
  60#define N810_MMC2_VIOSD_GPIO            9
  61#define N810_HEADSET_AMP_GPIO           10
  62#define N800_CAM_TURN_GPIO              12
  63#define N810_GPS_RESET_GPIO             12
  64#define N800_BLIZZARD_POWERDOWN_GPIO    15
  65#define N800_MMC1_WP_GPIO               23
  66#define N810_MMC2_VSD_GPIO              23
  67#define N8X0_ONENAND_GPIO               26
  68#define N810_BLIZZARD_RESET_GPIO        30
  69#define N800_UNKNOWN_GPIO2              53      /* out */
  70#define N8X0_TUSB_INT_GPIO              58
  71#define N8X0_BT_WKUP_GPIO               61
  72#define N8X0_STI_GPIO                   62
  73#define N8X0_CBUS_SEL_GPIO              64
  74#define N8X0_CBUS_DAT_GPIO              65
  75#define N8X0_CBUS_CLK_GPIO              66
  76#define N8X0_WLAN_IRQ_GPIO              87
  77#define N8X0_BT_RESET_GPIO              92
  78#define N8X0_TEA5761_CS_GPIO            93
  79#define N800_UNKNOWN_GPIO               94
  80#define N810_TSC_RESET_GPIO             94
  81#define N800_CAM_ACT_GPIO               95
  82#define N810_GPS_WAKEUP_GPIO            95
  83#define N8X0_MMC_CS_GPIO                96
  84#define N8X0_WLAN_PWR_GPIO              97
  85#define N8X0_BT_HOST_WKUP_GPIO          98
  86#define N810_SPEAKER_AMP_GPIO           101
  87#define N810_KB_LOCK_GPIO               102
  88#define N800_TSC_TS_GPIO                103
  89#define N810_TSC_TS_GPIO                106
  90#define N8X0_HEADPHONE_GPIO             107
  91#define N8X0_RETU_GPIO                  108
  92#define N800_TSC_KP_IRQ_GPIO            109
  93#define N810_KEYBOARD_GPIO              109
  94#define N800_BAT_COVER_GPIO             110
  95#define N810_SLIDE_GPIO                 110
  96#define N8X0_TAHVO_GPIO                 111
  97#define N800_UNKNOWN_GPIO4              112     /* out */
  98#define N810_SLEEPX_LED_GPIO            112
  99#define N800_TSC_RESET_GPIO             118     /* ? */
 100#define N810_AIC33_RESET_GPIO           118
 101#define N800_TSC_UNKNOWN_GPIO           119     /* out */
 102#define N8X0_TMP105_GPIO                125
 103
 104/* Config */
 105#define BT_UART                         0
 106#define XLDR_LL_UART                    1
 107
 108/* Addresses on the I2C bus 0 */
 109#define N810_TLV320AIC33_ADDR           0x18    /* Audio CODEC */
 110#define N8X0_TCM825x_ADDR               0x29    /* Camera */
 111#define N810_LP5521_ADDR                0x32    /* LEDs */
 112#define N810_TSL2563_ADDR               0x3d    /* Light sensor */
 113#define N810_LM8323_ADDR                0x45    /* Keyboard */
 114/* Addresses on the I2C bus 1 */
 115#define N8X0_TMP105_ADDR                0x48    /* Temperature sensor */
 116#define N8X0_MENELAUS_ADDR              0x72    /* Power management */
 117
 118/* Chipselects on GPMC NOR interface */
 119#define N8X0_ONENAND_CS                 0
 120#define N8X0_USB_ASYNC_CS               1
 121#define N8X0_USB_SYNC_CS                4
 122
 123#define N8X0_BD_ADDR                    0x00, 0x1a, 0x89, 0x9e, 0x3e, 0x81
 124
 125static void n800_mmc_cs_cb(void *opaque, int line, int level)
 126{
 127    /* TODO: this seems to actually be connected to the menelaus, to
 128     * which also both MMC slots connect.  */
 129    omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
 130
 131    printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
 132}
 133
 134static void n8x0_gpio_setup(struct n800_s *s)
 135{
 136    qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1);
 137    omap2_gpio_out_set(s->cpu->gpif, N8X0_MMC_CS_GPIO, mmc_cs[0]);
 138
 139    qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]);
 140}
 141
 142#define MAEMO_CAL_HEADER(...)                           \
 143    'C',  'o',  'n',  'F',  0x02, 0x00, 0x04, 0x00,     \
 144    __VA_ARGS__,                                        \
 145    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 146
 147static const uint8_t n8x0_cal_wlan_mac[] = {
 148    MAEMO_CAL_HEADER('w', 'l', 'a', 'n', '-', 'm', 'a', 'c')
 149    0x1c, 0x00, 0x00, 0x00, 0x47, 0xd6, 0x69, 0xb3,
 150    0x30, 0x08, 0xa0, 0x83, 0x00, 0x00, 0x00, 0x00,
 151    0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
 152    0x89, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
 153    0x5d, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
 154};
 155
 156static const uint8_t n8x0_cal_bt_id[] = {
 157    MAEMO_CAL_HEADER('b', 't', '-', 'i', 'd', 0, 0, 0)
 158    0x0a, 0x00, 0x00, 0x00, 0xa3, 0x4b, 0xf6, 0x96,
 159    0xa8, 0xeb, 0xb2, 0x41, 0x00, 0x00, 0x00, 0x00,
 160    N8X0_BD_ADDR,
 161};
 162
 163static void n8x0_nand_setup(struct n800_s *s)
 164{
 165    char *otp_region;
 166
 167    /* Either ec40xx or ec48xx are OK for the ID */
 168    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
 169                    onenand_base_unmap,
 170                    (s->nand = onenand_init(0xec4800, 1,
 171                                            omap2_gpio_in_get(s->cpu->gpif,
 172                                                    N8X0_ONENAND_GPIO)[0])));
 173    otp_region = onenand_raw_otp(s->nand);
 174
 175    memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
 176    memcpy(otp_region + 0x800, n8x0_cal_bt_id, sizeof(n8x0_cal_bt_id));
 177    /* XXX: in theory should also update the OOB for both pages */
 178}
 179
 180static void n8x0_i2c_setup(struct n800_s *s)
 181{
 182    DeviceState *dev;
 183    qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0];
 184
 185    /* Attach the CPU on one end of our I2C bus.  */
 186    s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
 187
 188    /* Attach a menelaus PM chip */
 189    dev = i2c_create_slave(s->i2c, "twl92230", N8X0_MENELAUS_ADDR);
 190    qdev_connect_gpio_out(dev, 3, s->cpu->irq[0][OMAP_INT_24XX_SYS_NIRQ]);
 191
 192    /* Attach a TMP105 PM chip (A0 wired to ground) */
 193    dev = i2c_create_slave(s->i2c, "tmp105", N8X0_TMP105_ADDR);
 194    qdev_connect_gpio_out(dev, 0, tmp_irq);
 195}
 196
 197/* Touchscreen and keypad controller */
 198static MouseTransformInfo n800_pointercal = {
 199    .x = 800,
 200    .y = 480,
 201    .a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
 202};
 203
 204static MouseTransformInfo n810_pointercal = {
 205    .x = 800,
 206    .y = 480,
 207    .a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
 208};
 209
 210#define RETU_KEYCODE    61      /* F3 */
 211
 212static void n800_key_event(void *opaque, int keycode)
 213{
 214    struct n800_s *s = (struct n800_s *) opaque;
 215    int code = s->keymap[keycode & 0x7f];
 216
 217    if (code == -1) {
 218        if ((keycode & 0x7f) == RETU_KEYCODE)
 219            retu_key_event(s->retu, !(keycode & 0x80));
 220        return;
 221    }
 222
 223    tsc210x_key_event(s->ts.chip, code, !(keycode & 0x80));
 224}
 225
 226static const int n800_keys[16] = {
 227    -1,
 228    72, /* Up */
 229    63, /* Home (F5) */
 230    -1,
 231    75, /* Left */
 232    28, /* Enter */
 233    77, /* Right */
 234    -1,
 235     1, /* Cycle (ESC) */
 236    80, /* Down */
 237    62, /* Menu (F4) */
 238    -1,
 239    66, /* Zoom- (F8) */
 240    64, /* FullScreen (F6) */
 241    65, /* Zoom+ (F7) */
 242    -1,
 243};
 244
 245static void n800_tsc_kbd_setup(struct n800_s *s)
 246{
 247    int i;
 248
 249    /* XXX: are the three pins inverted inside the chip between the
 250     * tsc and the cpu (N4111)?  */
 251    qemu_irq penirq = NULL;     /* NC */
 252    qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0];
 253    qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0];
 254
 255    s->ts.chip = tsc2301_init(penirq, kbirq, dav);
 256    s->ts.opaque = s->ts.chip->opaque;
 257    s->ts.txrx = tsc210x_txrx;
 258
 259    for (i = 0; i < 0x80; i ++)
 260        s->keymap[i] = -1;
 261    for (i = 0; i < 0x10; i ++)
 262        if (n800_keys[i] >= 0)
 263            s->keymap[n800_keys[i]] = i;
 264
 265    qemu_add_kbd_event_handler(n800_key_event, s);
 266
 267    tsc210x_set_transform(s->ts.chip, &n800_pointercal);
 268}
 269
 270static void n810_tsc_setup(struct n800_s *s)
 271{
 272    qemu_irq pintdav = omap2_gpio_in_get(s->cpu->gpif, N810_TSC_TS_GPIO)[0];
 273
 274    s->ts.opaque = tsc2005_init(pintdav);
 275    s->ts.txrx = tsc2005_txrx;
 276
 277    tsc2005_set_transform(s->ts.opaque, &n810_pointercal);
 278}
 279
 280/* N810 Keyboard controller */
 281static void n810_key_event(void *opaque, int keycode)
 282{
 283    struct n800_s *s = (struct n800_s *) opaque;
 284    int code = s->keymap[keycode & 0x7f];
 285
 286    if (code == -1) {
 287        if ((keycode & 0x7f) == RETU_KEYCODE)
 288            retu_key_event(s->retu, !(keycode & 0x80));
 289        return;
 290    }
 291
 292    lm832x_key_event(s->kbd, code, !(keycode & 0x80));
 293}
 294
 295#define M       0
 296
 297static int n810_keys[0x80] = {
 298    [0x01] = 16,        /* Q */
 299    [0x02] = 37,        /* K */
 300    [0x03] = 24,        /* O */
 301    [0x04] = 25,        /* P */
 302    [0x05] = 14,        /* Backspace */
 303    [0x06] = 30,        /* A */
 304    [0x07] = 31,        /* S */
 305    [0x08] = 32,        /* D */
 306    [0x09] = 33,        /* F */
 307    [0x0a] = 34,        /* G */
 308    [0x0b] = 35,        /* H */
 309    [0x0c] = 36,        /* J */
 310
 311    [0x11] = 17,        /* W */
 312    [0x12] = 62,        /* Menu (F4) */
 313    [0x13] = 38,        /* L */
 314    [0x14] = 40,        /* ' (Apostrophe) */
 315    [0x16] = 44,        /* Z */
 316    [0x17] = 45,        /* X */
 317    [0x18] = 46,        /* C */
 318    [0x19] = 47,        /* V */
 319    [0x1a] = 48,        /* B */
 320    [0x1b] = 49,        /* N */
 321    [0x1c] = 42,        /* Shift (Left shift) */
 322    [0x1f] = 65,        /* Zoom+ (F7) */
 323
 324    [0x21] = 18,        /* E */
 325    [0x22] = 39,        /* ; (Semicolon) */
 326    [0x23] = 12,        /* - (Minus) */
 327    [0x24] = 13,        /* = (Equal) */
 328    [0x2b] = 56,        /* Fn (Left Alt) */
 329    [0x2c] = 50,        /* M */
 330    [0x2f] = 66,        /* Zoom- (F8) */
 331
 332    [0x31] = 19,        /* R */
 333    [0x32] = 29 | M,    /* Right Ctrl */
 334    [0x34] = 57,        /* Space */
 335    [0x35] = 51,        /* , (Comma) */
 336    [0x37] = 72 | M,    /* Up */
 337    [0x3c] = 82 | M,    /* Compose (Insert) */
 338    [0x3f] = 64,        /* FullScreen (F6) */
 339
 340    [0x41] = 20,        /* T */
 341    [0x44] = 52,        /* . (Dot) */
 342    [0x46] = 77 | M,    /* Right */
 343    [0x4f] = 63,        /* Home (F5) */
 344    [0x51] = 21,        /* Y */
 345    [0x53] = 80 | M,    /* Down */
 346    [0x55] = 28,        /* Enter */
 347    [0x5f] =  1,        /* Cycle (ESC) */
 348
 349    [0x61] = 22,        /* U */
 350    [0x64] = 75 | M,    /* Left */
 351
 352    [0x71] = 23,        /* I */
 353#if 0
 354    [0x75] = 28 | M,    /* KP Enter (KP Enter) */
 355#else
 356    [0x75] = 15,        /* KP Enter (Tab) */
 357#endif
 358};
 359
 360#undef M
 361
 362static void n810_kbd_setup(struct n800_s *s)
 363{
 364    qemu_irq kbd_irq = omap2_gpio_in_get(s->cpu->gpif, N810_KEYBOARD_GPIO)[0];
 365    DeviceState *dev;
 366    int i;
 367
 368    for (i = 0; i < 0x80; i ++)
 369        s->keymap[i] = -1;
 370    for (i = 0; i < 0x80; i ++)
 371        if (n810_keys[i] > 0)
 372            s->keymap[n810_keys[i]] = i;
 373
 374    qemu_add_kbd_event_handler(n810_key_event, s);
 375
 376    /* Attach the LM8322 keyboard to the I2C bus,
 377     * should happen in n8x0_i2c_setup and s->kbd be initialised here.  */
 378    dev = i2c_create_slave(s->i2c, "lm8323", N810_LM8323_ADDR);
 379    qdev_connect_gpio_out(dev, 0, kbd_irq);
 380}
 381
 382/* LCD MIPI DBI-C controller (URAL) */
 383struct mipid_s {
 384    int resp[4];
 385    int param[4];
 386    int p;
 387    int pm;
 388    int cmd;
 389
 390    int sleep;
 391    int booster;
 392    int te;
 393    int selfcheck;
 394    int partial;
 395    int normal;
 396    int vscr;
 397    int invert;
 398    int onoff;
 399    int gamma;
 400    uint32_t id;
 401};
 402
 403static void mipid_reset(struct mipid_s *s)
 404{
 405    if (!s->sleep)
 406        fprintf(stderr, "%s: Display off\n", __FUNCTION__);
 407
 408    s->pm = 0;
 409    s->cmd = 0;
 410
 411    s->sleep = 1;
 412    s->booster = 0;
 413    s->selfcheck =
 414            (1 << 7) |  /* Register loading OK.  */
 415            (1 << 5) |  /* The chip is attached.  */
 416            (1 << 4);   /* Display glass still in one piece.  */
 417    s->te = 0;
 418    s->partial = 0;
 419    s->normal = 1;
 420    s->vscr = 0;
 421    s->invert = 0;
 422    s->onoff = 1;
 423    s->gamma = 0;
 424}
 425
 426static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
 427{
 428    struct mipid_s *s = (struct mipid_s *) opaque;
 429    uint8_t ret;
 430
 431    if (len > 9)
 432        hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
 433
 434    if (s->p >= ARRAY_SIZE(s->resp))
 435        ret = 0;
 436    else
 437        ret = s->resp[s->p ++];
 438    if (s->pm --> 0)
 439        s->param[s->pm] = cmd;
 440    else
 441        s->cmd = cmd;
 442
 443    switch (s->cmd) {
 444    case 0x00:  /* NOP */
 445        break;
 446
 447    case 0x01:  /* SWRESET */
 448        mipid_reset(s);
 449        break;
 450
 451    case 0x02:  /* BSTROFF */
 452        s->booster = 0;
 453        break;
 454    case 0x03:  /* BSTRON */
 455        s->booster = 1;
 456        break;
 457
 458    case 0x04:  /* RDDID */
 459        s->p = 0;
 460        s->resp[0] = (s->id >> 16) & 0xff;
 461        s->resp[1] = (s->id >>  8) & 0xff;
 462        s->resp[2] = (s->id >>  0) & 0xff;
 463        break;
 464
 465    case 0x06:  /* RD_RED */
 466    case 0x07:  /* RD_GREEN */
 467        /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so
 468         * for the bootloader one needs to change this.  */
 469    case 0x08:  /* RD_BLUE */
 470        s->p = 0;
 471        /* TODO: return first pixel components */
 472        s->resp[0] = 0x01;
 473        break;
 474
 475    case 0x09:  /* RDDST */
 476        s->p = 0;
 477        s->resp[0] = s->booster << 7;
 478        s->resp[1] = (5 << 4) | (s->partial << 2) |
 479                (s->sleep << 1) | s->normal;
 480        s->resp[2] = (s->vscr << 7) | (s->invert << 5) |
 481                (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);
 482        s->resp[3] = s->gamma << 6;
 483        break;
 484
 485    case 0x0a:  /* RDDPM */
 486        s->p = 0;
 487        s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |
 488                (s->partial << 5) | (s->sleep << 6) | (s->booster << 7);
 489        break;
 490    case 0x0b:  /* RDDMADCTR */
 491        s->p = 0;
 492        s->resp[0] = 0;
 493        break;
 494    case 0x0c:  /* RDDCOLMOD */
 495        s->p = 0;
 496        s->resp[0] = 5; /* 65K colours */
 497        break;
 498    case 0x0d:  /* RDDIM */
 499        s->p = 0;
 500        s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;
 501        break;
 502    case 0x0e:  /* RDDSM */
 503        s->p = 0;
 504        s->resp[0] = s->te << 7;
 505        break;
 506    case 0x0f:  /* RDDSDR */
 507        s->p = 0;
 508        s->resp[0] = s->selfcheck;
 509        break;
 510
 511    case 0x10:  /* SLPIN */
 512        s->sleep = 1;
 513        break;
 514    case 0x11:  /* SLPOUT */
 515        s->sleep = 0;
 516        s->selfcheck ^= 1 << 6; /* POFF self-diagnosis Ok */
 517        break;
 518
 519    case 0x12:  /* PTLON */
 520        s->partial = 1;
 521        s->normal = 0;
 522        s->vscr = 0;
 523        break;
 524    case 0x13:  /* NORON */
 525        s->partial = 0;
 526        s->normal = 1;
 527        s->vscr = 0;
 528        break;
 529
 530    case 0x20:  /* INVOFF */
 531        s->invert = 0;
 532        break;
 533    case 0x21:  /* INVON */
 534        s->invert = 1;
 535        break;
 536
 537    case 0x22:  /* APOFF */
 538    case 0x23:  /* APON */
 539        goto bad_cmd;
 540
 541    case 0x25:  /* WRCNTR */
 542        if (s->pm < 0)
 543            s->pm = 1;
 544        goto bad_cmd;
 545
 546    case 0x26:  /* GAMSET */
 547        if (!s->pm)
 548            s->gamma = ffs(s->param[0] & 0xf) - 1;
 549        else if (s->pm < 0)
 550            s->pm = 1;
 551        break;
 552
 553    case 0x28:  /* DISPOFF */
 554        s->onoff = 0;
 555        fprintf(stderr, "%s: Display off\n", __FUNCTION__);
 556        break;
 557    case 0x29:  /* DISPON */
 558        s->onoff = 1;
 559        fprintf(stderr, "%s: Display on\n", __FUNCTION__);
 560        break;
 561
 562    case 0x2a:  /* CASET */
 563    case 0x2b:  /* RASET */
 564    case 0x2c:  /* RAMWR */
 565    case 0x2d:  /* RGBSET */
 566    case 0x2e:  /* RAMRD */
 567    case 0x30:  /* PTLAR */
 568    case 0x33:  /* SCRLAR */
 569        goto bad_cmd;
 570
 571    case 0x34:  /* TEOFF */
 572        s->te = 0;
 573        break;
 574    case 0x35:  /* TEON */
 575        if (!s->pm)
 576            s->te = 1;
 577        else if (s->pm < 0)
 578            s->pm = 1;
 579        break;
 580
 581    case 0x36:  /* MADCTR */
 582        goto bad_cmd;
 583
 584    case 0x37:  /* VSCSAD */
 585        s->partial = 0;
 586        s->normal = 0;
 587        s->vscr = 1;
 588        break;
 589
 590    case 0x38:  /* IDMOFF */
 591    case 0x39:  /* IDMON */
 592    case 0x3a:  /* COLMOD */
 593        goto bad_cmd;
 594
 595    case 0xb0:  /* CLKINT / DISCTL */
 596    case 0xb1:  /* CLKEXT */
 597        if (s->pm < 0)
 598            s->pm = 2;
 599        break;
 600
 601    case 0xb4:  /* FRMSEL */
 602        break;
 603
 604    case 0xb5:  /* FRM8SEL */
 605    case 0xb6:  /* TMPRNG / INIESC */
 606    case 0xb7:  /* TMPHIS / NOP2 */
 607    case 0xb8:  /* TMPREAD / MADCTL */
 608    case 0xba:  /* DISTCTR */
 609    case 0xbb:  /* EPVOL */
 610        goto bad_cmd;
 611
 612    case 0xbd:  /* Unknown */
 613        s->p = 0;
 614        s->resp[0] = 0;
 615        s->resp[1] = 1;
 616        break;
 617
 618    case 0xc2:  /* IFMOD */
 619        if (s->pm < 0)
 620            s->pm = 2;
 621        break;
 622
 623    case 0xc6:  /* PWRCTL */
 624    case 0xc7:  /* PPWRCTL */
 625    case 0xd0:  /* EPWROUT */
 626    case 0xd1:  /* EPWRIN */
 627    case 0xd4:  /* RDEV */
 628    case 0xd5:  /* RDRR */
 629        goto bad_cmd;
 630
 631    case 0xda:  /* RDID1 */
 632        s->p = 0;
 633        s->resp[0] = (s->id >> 16) & 0xff;
 634        break;
 635    case 0xdb:  /* RDID2 */
 636        s->p = 0;
 637        s->resp[0] = (s->id >>  8) & 0xff;
 638        break;
 639    case 0xdc:  /* RDID3 */
 640        s->p = 0;
 641        s->resp[0] = (s->id >>  0) & 0xff;
 642        break;
 643
 644    default:
 645    bad_cmd:
 646        fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, s->cmd);
 647        break;
 648    }
 649
 650    return ret;
 651}
 652
 653static void *mipid_init(void)
 654{
 655    struct mipid_s *s = (struct mipid_s *) qemu_mallocz(sizeof(*s));
 656
 657    s->id = 0x838f03;
 658    mipid_reset(s);
 659
 660    return s;
 661}
 662
 663static void n8x0_spi_setup(struct n800_s *s)
 664{
 665    void *tsc = s->ts.opaque;
 666    void *mipid = mipid_init();
 667
 668    omap_mcspi_attach(s->cpu->mcspi[0], s->ts.txrx, tsc, 0);
 669    omap_mcspi_attach(s->cpu->mcspi[0], mipid_txrx, mipid, 1);
 670}
 671
 672/* This task is normally performed by the bootloader.  If we're loading
 673 * a kernel directly, we need to enable the Blizzard ourselves.  */
 674static void n800_dss_init(struct rfbi_chip_s *chip)
 675{
 676    uint8_t *fb_blank;
 677
 678    chip->write(chip->opaque, 0, 0x2a);         /* LCD Width register */
 679    chip->write(chip->opaque, 1, 0x64);
 680    chip->write(chip->opaque, 0, 0x2c);         /* LCD HNDP register */
 681    chip->write(chip->opaque, 1, 0x1e);
 682    chip->write(chip->opaque, 0, 0x2e);         /* LCD Height 0 register */
 683    chip->write(chip->opaque, 1, 0xe0);
 684    chip->write(chip->opaque, 0, 0x30);         /* LCD Height 1 register */
 685    chip->write(chip->opaque, 1, 0x01);
 686    chip->write(chip->opaque, 0, 0x32);         /* LCD VNDP register */
 687    chip->write(chip->opaque, 1, 0x06);
 688    chip->write(chip->opaque, 0, 0x68);         /* Display Mode register */
 689    chip->write(chip->opaque, 1, 1);            /* Enable bit */
 690
 691    chip->write(chip->opaque, 0, 0x6c); 
 692    chip->write(chip->opaque, 1, 0x00);         /* Input X Start Position */
 693    chip->write(chip->opaque, 1, 0x00);         /* Input X Start Position */
 694    chip->write(chip->opaque, 1, 0x00);         /* Input Y Start Position */
 695    chip->write(chip->opaque, 1, 0x00);         /* Input Y Start Position */
 696    chip->write(chip->opaque, 1, 0x1f);         /* Input X End Position */
 697    chip->write(chip->opaque, 1, 0x03);         /* Input X End Position */
 698    chip->write(chip->opaque, 1, 0xdf);         /* Input Y End Position */
 699    chip->write(chip->opaque, 1, 0x01);         /* Input Y End Position */
 700    chip->write(chip->opaque, 1, 0x00);         /* Output X Start Position */
 701    chip->write(chip->opaque, 1, 0x00);         /* Output X Start Position */
 702    chip->write(chip->opaque, 1, 0x00);         /* Output Y Start Position */
 703    chip->write(chip->opaque, 1, 0x00);         /* Output Y Start Position */
 704    chip->write(chip->opaque, 1, 0x1f);         /* Output X End Position */
 705    chip->write(chip->opaque, 1, 0x03);         /* Output X End Position */
 706    chip->write(chip->opaque, 1, 0xdf);         /* Output Y End Position */
 707    chip->write(chip->opaque, 1, 0x01);         /* Output Y End Position */
 708    chip->write(chip->opaque, 1, 0x01);         /* Input Data Format */
 709    chip->write(chip->opaque, 1, 0x01);         /* Data Source Select */
 710
 711    fb_blank = memset(qemu_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
 712    /* Display Memory Data Port */
 713    chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
 714    qemu_free(fb_blank);
 715}
 716
 717static void n8x0_dss_setup(struct n800_s *s)
 718{
 719    s->blizzard.opaque = s1d13745_init(NULL);
 720    s->blizzard.block = s1d13745_write_block;
 721    s->blizzard.write = s1d13745_write;
 722    s->blizzard.read = s1d13745_read;
 723
 724    omap_rfbi_attach(s->cpu->dss, 0, &s->blizzard);
 725}
 726
 727static void n8x0_cbus_setup(struct n800_s *s)
 728{
 729    qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N8X0_CBUS_DAT_GPIO)[0];
 730    qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_RETU_GPIO)[0];
 731    qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TAHVO_GPIO)[0];
 732
 733    CBus *cbus = cbus_init(dat_out);
 734
 735    omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_CLK_GPIO, cbus->clk);
 736    omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_DAT_GPIO, cbus->dat);
 737    omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_SEL_GPIO, cbus->sel);
 738
 739    cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
 740    cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
 741}
 742
 743static void n8x0_uart_setup(struct n800_s *s)
 744{
 745    CharDriverState *radio = uart_hci_init(
 746                    omap2_gpio_in_get(s->cpu->gpif,
 747                            N8X0_BT_HOST_WKUP_GPIO)[0]);
 748
 749    omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_RESET_GPIO,
 750                    csrhci_pins_get(radio)[csrhci_pin_reset]);
 751    omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_WKUP_GPIO,
 752                    csrhci_pins_get(radio)[csrhci_pin_wakeup]);
 753
 754    omap_uart_attach(s->cpu->uart[BT_UART], radio);
 755}
 756
 757static void n8x0_usb_power_cb(void *opaque, int line, int level)
 758{
 759    struct n800_s *s = opaque;
 760
 761    tusb6010_power(s->usb, level);
 762}
 763
 764static void n8x0_usb_setup(struct n800_s *s)
 765{
 766    qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0];
 767    qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
 768    TUSBState *tusb = tusb6010_init(tusb_irq);
 769
 770    /* Using the NOR interface */
 771    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
 772                    tusb6010_async_io(tusb), NULL, NULL, tusb);
 773    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
 774                    tusb6010_sync_io(tusb), NULL, NULL, tusb);
 775
 776    s->usb = tusb;
 777    omap2_gpio_out_set(s->cpu->gpif, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
 778}
 779
 780/* Setup done before the main bootloader starts by some early setup code
 781 * - used when we want to run the main bootloader in emulation.  This
 782 * isn't documented.  */
 783static uint32_t n800_pinout[104] = {
 784    0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
 785    0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
 786    0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
 787    0x080800bc, 0x00cc0808, 0x08081818, 0x18180128,
 788    0x01241800, 0x18181818, 0x000000f0, 0x01300000,
 789    0x00001b0b, 0x1b0f0138, 0x00e0181b, 0x1b031b0b,
 790    0x180f0078, 0x00740018, 0x0f0f0f1a, 0x00000080,
 791    0x007c0000, 0x00000000, 0x00000088, 0x00840000,
 792    0x00000000, 0x00000094, 0x00980300, 0x0f180003,
 793    0x0000008c, 0x00900f0f, 0x0f0f1b00, 0x0f00009c,
 794    0x01140000, 0x1b1b0f18, 0x0818013c, 0x01400008,
 795    0x00001818, 0x000b0110, 0x010c1800, 0x0b030b0f,
 796    0x181800f4, 0x00f81818, 0x00000018, 0x000000fc,
 797    0x00401808, 0x00000000, 0x0f1b0030, 0x003c0008,
 798    0x00000000, 0x00000038, 0x00340000, 0x00000000,
 799    0x1a080070, 0x00641a1a, 0x08080808, 0x08080060,
 800    0x005c0808, 0x08080808, 0x08080058, 0x00540808,
 801    0x08080808, 0x0808006c, 0x00680808, 0x08080808,
 802    0x000000a8, 0x00b00000, 0x08080808, 0x000000a0,
 803    0x00a40000, 0x00000000, 0x08ff0050, 0x004c0808,
 804    0xffffffff, 0xffff0048, 0x0044ffff, 0xffffffff,
 805    0x000000ac, 0x01040800, 0x08080b0f, 0x18180100,
 806    0x01081818, 0x0b0b1808, 0x1a0300e4, 0x012c0b1a,
 807    0x02020018, 0x0b000134, 0x011c0800, 0x0b1b1b00,
 808    0x0f0000c8, 0x00ec181b, 0x000f0f02, 0x00180118,
 809    0x01200000, 0x0f0b1b1b, 0x0f0200e8, 0x0000020b,
 810};
 811
 812static void n800_setup_nolo_tags(void *sram_base)
 813{
 814    int i;
 815    uint32_t *p = sram_base + 0x8000;
 816    uint32_t *v = sram_base + 0xa000;
 817
 818    memset(p, 0, 0x3000);
 819
 820    strcpy((void *) (p + 0), "QEMU N800");
 821
 822    strcpy((void *) (p + 8), "F5");
 823
 824    stl_raw(p + 10, 0x04f70000);
 825    strcpy((void *) (p + 9), "RX-34");
 826
 827    /* RAM size in MB? */
 828    stl_raw(p + 12, 0x80);
 829
 830    /* Pointer to the list of tags */
 831    stl_raw(p + 13, OMAP2_SRAM_BASE + 0x9000);
 832
 833    /* The NOLO tags start here */
 834    p = sram_base + 0x9000;
 835#define ADD_TAG(tag, len)                               \
 836    stw_raw((uint16_t *) p + 0, tag);                   \
 837    stw_raw((uint16_t *) p + 1, len); p ++;             \
 838    stl_raw(p ++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
 839
 840    /* OMAP STI console? Pin out settings? */
 841    ADD_TAG(0x6e01, 414);
 842    for (i = 0; i < ARRAY_SIZE(n800_pinout); i ++)
 843        stl_raw(v ++, n800_pinout[i]);
 844
 845    /* Kernel memsize? */
 846    ADD_TAG(0x6e05, 1);
 847    stl_raw(v ++, 2);
 848
 849    /* NOLO serial console */
 850    ADD_TAG(0x6e02, 4);
 851    stl_raw(v ++, XLDR_LL_UART);        /* UART number (1 - 3) */
 852
 853#if 0
 854    /* CBUS settings (Retu/AVilma) */
 855    ADD_TAG(0x6e03, 6);
 856    stw_raw((uint16_t *) v + 0, 65);    /* CBUS GPIO0 */
 857    stw_raw((uint16_t *) v + 1, 66);    /* CBUS GPIO1 */
 858    stw_raw((uint16_t *) v + 2, 64);    /* CBUS GPIO2 */
 859    v += 2;
 860#endif
 861
 862    /* Nokia ASIC BB5 (Retu/Tahvo) */
 863    ADD_TAG(0x6e0a, 4);
 864    stw_raw((uint16_t *) v + 0, 111);   /* "Retu" interrupt GPIO */
 865    stw_raw((uint16_t *) v + 1, 108);   /* "Tahvo" interrupt GPIO */
 866    v ++;
 867
 868    /* LCD console? */
 869    ADD_TAG(0x6e04, 4);
 870    stw_raw((uint16_t *) v + 0, 30);    /* ??? */
 871    stw_raw((uint16_t *) v + 1, 24);    /* ??? */
 872    v ++;
 873
 874#if 0
 875    /* LCD settings */
 876    ADD_TAG(0x6e06, 2);
 877    stw_raw((uint16_t *) (v ++), 15);   /* ??? */
 878#endif
 879
 880    /* I^2C (Menelaus) */
 881    ADD_TAG(0x6e07, 4);
 882    stl_raw(v ++, 0x00720000);          /* ??? */
 883
 884    /* Unknown */
 885    ADD_TAG(0x6e0b, 6);
 886    stw_raw((uint16_t *) v + 0, 94);    /* ??? */
 887    stw_raw((uint16_t *) v + 1, 23);    /* ??? */
 888    stw_raw((uint16_t *) v + 2, 0);     /* ??? */
 889    v += 2;
 890
 891    /* OMAP gpio switch info */
 892    ADD_TAG(0x6e0c, 80);
 893    strcpy((void *) v, "bat_cover");    v += 3;
 894    stw_raw((uint16_t *) v + 0, 110);   /* GPIO num ??? */
 895    stw_raw((uint16_t *) v + 1, 1);     /* GPIO num ??? */
 896    v += 2;
 897    strcpy((void *) v, "cam_act");      v += 3;
 898    stw_raw((uint16_t *) v + 0, 95);    /* GPIO num ??? */
 899    stw_raw((uint16_t *) v + 1, 32);    /* GPIO num ??? */
 900    v += 2;
 901    strcpy((void *) v, "cam_turn");     v += 3;
 902    stw_raw((uint16_t *) v + 0, 12);    /* GPIO num ??? */
 903    stw_raw((uint16_t *) v + 1, 33);    /* GPIO num ??? */
 904    v += 2;
 905    strcpy((void *) v, "headphone");    v += 3;
 906    stw_raw((uint16_t *) v + 0, 107);   /* GPIO num ??? */
 907    stw_raw((uint16_t *) v + 1, 17);    /* GPIO num ??? */
 908    v += 2;
 909
 910    /* Bluetooth */
 911    ADD_TAG(0x6e0e, 12);
 912    stl_raw(v ++, 0x5c623d01);          /* ??? */
 913    stl_raw(v ++, 0x00000201);          /* ??? */
 914    stl_raw(v ++, 0x00000000);          /* ??? */
 915
 916    /* CX3110x WLAN settings */
 917    ADD_TAG(0x6e0f, 8);
 918    stl_raw(v ++, 0x00610025);          /* ??? */
 919    stl_raw(v ++, 0xffff0057);          /* ??? */
 920
 921    /* MMC host settings */
 922    ADD_TAG(0x6e10, 12);
 923    stl_raw(v ++, 0xffff000f);          /* ??? */
 924    stl_raw(v ++, 0xffffffff);          /* ??? */
 925    stl_raw(v ++, 0x00000060);          /* ??? */
 926
 927    /* OneNAND chip select */
 928    ADD_TAG(0x6e11, 10);
 929    stl_raw(v ++, 0x00000401);          /* ??? */
 930    stl_raw(v ++, 0x0002003a);          /* ??? */
 931    stl_raw(v ++, 0x00000002);          /* ??? */
 932
 933    /* TEA5761 sensor settings */
 934    ADD_TAG(0x6e12, 2);
 935    stl_raw(v ++, 93);                  /* GPIO num ??? */
 936
 937#if 0
 938    /* Unknown tag */
 939    ADD_TAG(6e09, 0);
 940
 941    /* Kernel UART / console */
 942    ADD_TAG(6e12, 0);
 943#endif
 944
 945    /* End of the list */
 946    stl_raw(p ++, 0x00000000);
 947    stl_raw(p ++, 0x00000000);
 948}
 949
 950/* This task is normally performed by the bootloader.  If we're loading
 951 * a kernel directly, we need to set up GPMC mappings ourselves.  */
 952static void n800_gpmc_init(struct n800_s *s)
 953{
 954    uint32_t config7 =
 955            (0xf << 8) |        /* MASKADDRESS */
 956            (1 << 6) |          /* CSVALID */
 957            (4 << 0);           /* BASEADDRESS */
 958
 959    cpu_physical_memory_write(0x6800a078,               /* GPMC_CONFIG7_0 */
 960                    (void *) &config7, sizeof(config7));
 961}
 962
 963/* Setup sequence done by the bootloader */
 964static void n8x0_boot_init(void *opaque)
 965{
 966    struct n800_s *s = (struct n800_s *) opaque;
 967    uint32_t buf;
 968
 969    /* PRCM setup */
 970#define omap_writel(addr, val)  \
 971    buf = (val);                        \
 972    cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf))
 973
 974    omap_writel(0x48008060, 0x41);              /* PRCM_CLKSRC_CTRL */
 975    omap_writel(0x48008070, 1);                 /* PRCM_CLKOUT_CTRL */
 976    omap_writel(0x48008078, 0);                 /* PRCM_CLKEMUL_CTRL */
 977    omap_writel(0x48008090, 0);                 /* PRCM_VOLTSETUP */
 978    omap_writel(0x48008094, 0);                 /* PRCM_CLKSSETUP */
 979    omap_writel(0x48008098, 0);                 /* PRCM_POLCTRL */
 980    omap_writel(0x48008140, 2);                 /* CM_CLKSEL_MPU */
 981    omap_writel(0x48008148, 0);                 /* CM_CLKSTCTRL_MPU */
 982    omap_writel(0x48008158, 1);                 /* RM_RSTST_MPU */
 983    omap_writel(0x480081c8, 0x15);              /* PM_WKDEP_MPU */
 984    omap_writel(0x480081d4, 0x1d4);             /* PM_EVGENCTRL_MPU */
 985    omap_writel(0x480081d8, 0);                 /* PM_EVEGENONTIM_MPU */
 986    omap_writel(0x480081dc, 0);                 /* PM_EVEGENOFFTIM_MPU */
 987    omap_writel(0x480081e0, 0xc);               /* PM_PWSTCTRL_MPU */
 988    omap_writel(0x48008200, 0x047e7ff7);        /* CM_FCLKEN1_CORE */
 989    omap_writel(0x48008204, 0x00000004);        /* CM_FCLKEN2_CORE */
 990    omap_writel(0x48008210, 0x047e7ff1);        /* CM_ICLKEN1_CORE */
 991    omap_writel(0x48008214, 0x00000004);        /* CM_ICLKEN2_CORE */
 992    omap_writel(0x4800821c, 0x00000000);        /* CM_ICLKEN4_CORE */
 993    omap_writel(0x48008230, 0);                 /* CM_AUTOIDLE1_CORE */
 994    omap_writel(0x48008234, 0);                 /* CM_AUTOIDLE2_CORE */
 995    omap_writel(0x48008238, 7);                 /* CM_AUTOIDLE3_CORE */
 996    omap_writel(0x4800823c, 0);                 /* CM_AUTOIDLE4_CORE */
 997    omap_writel(0x48008240, 0x04360626);        /* CM_CLKSEL1_CORE */
 998    omap_writel(0x48008244, 0x00000014);        /* CM_CLKSEL2_CORE */
 999    omap_writel(0x48008248, 0);                 /* CM_CLKSTCTRL_CORE */
1000    omap_writel(0x48008300, 0x00000000);        /* CM_FCLKEN_GFX */
1001    omap_writel(0x48008310, 0x00000000);        /* CM_ICLKEN_GFX */
1002    omap_writel(0x48008340, 0x00000001);        /* CM_CLKSEL_GFX */
1003    omap_writel(0x48008400, 0x00000004);        /* CM_FCLKEN_WKUP */
1004    omap_writel(0x48008410, 0x00000004);        /* CM_ICLKEN_WKUP */
1005    omap_writel(0x48008440, 0x00000000);        /* CM_CLKSEL_WKUP */
1006    omap_writel(0x48008500, 0x000000cf);        /* CM_CLKEN_PLL */
1007    omap_writel(0x48008530, 0x0000000c);        /* CM_AUTOIDLE_PLL */
1008    omap_writel(0x48008540,                     /* CM_CLKSEL1_PLL */
1009                    (0x78 << 12) | (6 << 8));
1010    omap_writel(0x48008544, 2);                 /* CM_CLKSEL2_PLL */
1011
1012    /* GPMC setup */
1013    n800_gpmc_init(s);
1014
1015    /* Video setup */
1016    n800_dss_init(&s->blizzard);
1017
1018    /* CPU setup */
1019    s->cpu->env->GE = 0x5;
1020
1021    /* If the machine has a slided keyboard, open it */
1022    if (s->kbd)
1023        qemu_irq_raise(omap2_gpio_in_get(s->cpu->gpif, N810_SLIDE_GPIO)[0]);
1024}
1025
1026#define OMAP_TAG_NOKIA_BT       0x4e01
1027#define OMAP_TAG_WLAN_CX3110X   0x4e02
1028#define OMAP_TAG_CBUS           0x4e03
1029#define OMAP_TAG_EM_ASIC_BB5    0x4e04
1030
1031static struct omap_gpiosw_info_s {
1032    const char *name;
1033    int line;
1034    int type;
1035} n800_gpiosw_info[] = {
1036    {
1037        "bat_cover", N800_BAT_COVER_GPIO,
1038        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1039    }, {
1040        "cam_act", N800_CAM_ACT_GPIO,
1041        OMAP_GPIOSW_TYPE_ACTIVITY,
1042    }, {
1043        "cam_turn", N800_CAM_TURN_GPIO,
1044        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED,
1045    }, {
1046        "headphone", N8X0_HEADPHONE_GPIO,
1047        OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1048    },
1049    { NULL }
1050}, n810_gpiosw_info[] = {
1051    {
1052        "gps_reset", N810_GPS_RESET_GPIO,
1053        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1054    }, {
1055        "gps_wakeup", N810_GPS_WAKEUP_GPIO,
1056        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1057    }, {
1058        "headphone", N8X0_HEADPHONE_GPIO,
1059        OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1060    }, {
1061        "kb_lock", N810_KB_LOCK_GPIO,
1062        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1063    }, {
1064        "sleepx_led", N810_SLEEPX_LED_GPIO,
1065        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED | OMAP_GPIOSW_OUTPUT,
1066    }, {
1067        "slide", N810_SLIDE_GPIO,
1068        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1069    },
1070    { NULL }
1071};
1072
1073static struct omap_partition_info_s {
1074    uint32_t offset;
1075    uint32_t size;
1076    int mask;
1077    const char *name;
1078} n800_part_info[] = {
1079    { 0x00000000, 0x00020000, 0x3, "bootloader" },
1080    { 0x00020000, 0x00060000, 0x0, "config" },
1081    { 0x00080000, 0x00200000, 0x0, "kernel" },
1082    { 0x00280000, 0x00200000, 0x3, "initfs" },
1083    { 0x00480000, 0x0fb80000, 0x3, "rootfs" },
1084
1085    { 0, 0, 0, NULL }
1086}, n810_part_info[] = {
1087    { 0x00000000, 0x00020000, 0x3, "bootloader" },
1088    { 0x00020000, 0x00060000, 0x0, "config" },
1089    { 0x00080000, 0x00220000, 0x0, "kernel" },
1090    { 0x002a0000, 0x00400000, 0x0, "initfs" },
1091    { 0x006a0000, 0x0f960000, 0x0, "rootfs" },
1092
1093    { 0, 0, 0, NULL }
1094};
1095
1096static bdaddr_t n8x0_bd_addr = {{ N8X0_BD_ADDR }};
1097
1098static int n8x0_atag_setup(void *p, int model)
1099{
1100    uint8_t *b;
1101    uint16_t *w;
1102    uint32_t *l;
1103    struct omap_gpiosw_info_s *gpiosw;
1104    struct omap_partition_info_s *partition;
1105    const char *tag;
1106
1107    w = p;
1108
1109    stw_raw(w ++, OMAP_TAG_UART);               /* u16 tag */
1110    stw_raw(w ++, 4);                           /* u16 len */
1111    stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
1112    w ++;
1113
1114#if 0
1115    stw_raw(w ++, OMAP_TAG_SERIAL_CONSOLE);     /* u16 tag */
1116    stw_raw(w ++, 4);                           /* u16 len */
1117    stw_raw(w ++, XLDR_LL_UART + 1);            /* u8 console_uart */
1118    stw_raw(w ++, 115200);                      /* u32 console_speed */
1119#endif
1120
1121    stw_raw(w ++, OMAP_TAG_LCD);                /* u16 tag */
1122    stw_raw(w ++, 36);                          /* u16 len */
1123    strcpy((void *) w, "QEMU LCD panel");       /* char panel_name[16] */
1124    w += 8;
1125    strcpy((void *) w, "blizzard");             /* char ctrl_name[16] */
1126    w += 8;
1127    stw_raw(w ++, N810_BLIZZARD_RESET_GPIO);    /* TODO: n800 s16 nreset_gpio */
1128    stw_raw(w ++, 24);                          /* u8 data_lines */
1129
1130    stw_raw(w ++, OMAP_TAG_CBUS);               /* u16 tag */
1131    stw_raw(w ++, 8);                           /* u16 len */
1132    stw_raw(w ++, N8X0_CBUS_CLK_GPIO);          /* s16 clk_gpio */
1133    stw_raw(w ++, N8X0_CBUS_DAT_GPIO);          /* s16 dat_gpio */
1134    stw_raw(w ++, N8X0_CBUS_SEL_GPIO);          /* s16 sel_gpio */
1135    w ++;
1136
1137    stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5);        /* u16 tag */
1138    stw_raw(w ++, 4);                           /* u16 len */
1139    stw_raw(w ++, N8X0_RETU_GPIO);              /* s16 retu_irq_gpio */
1140    stw_raw(w ++, N8X0_TAHVO_GPIO);             /* s16 tahvo_irq_gpio */
1141
1142    gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
1143    for (; gpiosw->name; gpiosw ++) {
1144        stw_raw(w ++, OMAP_TAG_GPIO_SWITCH);    /* u16 tag */
1145        stw_raw(w ++, 20);                      /* u16 len */
1146        strcpy((void *) w, gpiosw->name);       /* char name[12] */
1147        w += 6;
1148        stw_raw(w ++, gpiosw->line);            /* u16 gpio */
1149        stw_raw(w ++, gpiosw->type);
1150        stw_raw(w ++, 0);
1151        stw_raw(w ++, 0);
1152    }
1153
1154    stw_raw(w ++, OMAP_TAG_NOKIA_BT);           /* u16 tag */
1155    stw_raw(w ++, 12);                          /* u16 len */
1156    b = (void *) w;
1157    stb_raw(b ++, 0x01);                        /* u8 chip_type (CSR) */
1158    stb_raw(b ++, N8X0_BT_WKUP_GPIO);           /* u8 bt_wakeup_gpio */
1159    stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO);      /* u8 host_wakeup_gpio */
1160    stb_raw(b ++, N8X0_BT_RESET_GPIO);          /* u8 reset_gpio */
1161    stb_raw(b ++, BT_UART + 1);                 /* u8 bt_uart */
1162    memcpy(b, &n8x0_bd_addr, 6);                /* u8 bd_addr[6] */
1163    b += 6;
1164    stb_raw(b ++, 0x02);                        /* u8 bt_sysclk (38.4) */
1165    w = (void *) b;
1166
1167    stw_raw(w ++, OMAP_TAG_WLAN_CX3110X);       /* u16 tag */
1168    stw_raw(w ++, 8);                           /* u16 len */
1169    stw_raw(w ++, 0x25);                        /* u8 chip_type */
1170    stw_raw(w ++, N8X0_WLAN_PWR_GPIO);          /* s16 power_gpio */
1171    stw_raw(w ++, N8X0_WLAN_IRQ_GPIO);          /* s16 irq_gpio */
1172    stw_raw(w ++, -1);                          /* s16 spi_cs_gpio */
1173
1174    stw_raw(w ++, OMAP_TAG_MMC);                /* u16 tag */
1175    stw_raw(w ++, 16);                          /* u16 len */
1176    if (model == 810) {
1177        stw_raw(w ++, 0x23f);                   /* unsigned flags */
1178        stw_raw(w ++, -1);                      /* s16 power_pin */
1179        stw_raw(w ++, -1);                      /* s16 switch_pin */
1180        stw_raw(w ++, -1);                      /* s16 wp_pin */
1181        stw_raw(w ++, 0x240);                   /* unsigned flags */
1182        stw_raw(w ++, 0xc000);                  /* s16 power_pin */
1183        stw_raw(w ++, 0x0248);                  /* s16 switch_pin */
1184        stw_raw(w ++, 0xc000);                  /* s16 wp_pin */
1185    } else {
1186        stw_raw(w ++, 0xf);                     /* unsigned flags */
1187        stw_raw(w ++, -1);                      /* s16 power_pin */
1188        stw_raw(w ++, -1);                      /* s16 switch_pin */
1189        stw_raw(w ++, -1);                      /* s16 wp_pin */
1190        stw_raw(w ++, 0);                       /* unsigned flags */
1191        stw_raw(w ++, 0);                       /* s16 power_pin */
1192        stw_raw(w ++, 0);                       /* s16 switch_pin */
1193        stw_raw(w ++, 0);                       /* s16 wp_pin */
1194    }
1195
1196    stw_raw(w ++, OMAP_TAG_TEA5761);            /* u16 tag */
1197    stw_raw(w ++, 4);                           /* u16 len */
1198    stw_raw(w ++, N8X0_TEA5761_CS_GPIO);        /* u16 enable_gpio */
1199    w ++;
1200
1201    partition = (model == 810) ? n810_part_info : n800_part_info;
1202    for (; partition->name; partition ++) {
1203        stw_raw(w ++, OMAP_TAG_PARTITION);      /* u16 tag */
1204        stw_raw(w ++, 28);                      /* u16 len */
1205        strcpy((void *) w, partition->name);    /* char name[16] */
1206        l = (void *) (w + 8);
1207        stl_raw(l ++, partition->size);         /* unsigned int size */
1208        stl_raw(l ++, partition->offset);       /* unsigned int offset */
1209        stl_raw(l ++, partition->mask);         /* unsigned int mask_flags */
1210        w = (void *) l;
1211    }
1212
1213    stw_raw(w ++, OMAP_TAG_BOOT_REASON);        /* u16 tag */
1214    stw_raw(w ++, 12);                          /* u16 len */
1215#if 0
1216    strcpy((void *) w, "por");                  /* char reason_str[12] */
1217    strcpy((void *) w, "charger");              /* char reason_str[12] */
1218    strcpy((void *) w, "32wd_to");              /* char reason_str[12] */
1219    strcpy((void *) w, "sw_rst");               /* char reason_str[12] */
1220    strcpy((void *) w, "mbus");                 /* char reason_str[12] */
1221    strcpy((void *) w, "unknown");              /* char reason_str[12] */
1222    strcpy((void *) w, "swdg_to");              /* char reason_str[12] */
1223    strcpy((void *) w, "sec_vio");              /* char reason_str[12] */
1224    strcpy((void *) w, "pwr_key");              /* char reason_str[12] */
1225    strcpy((void *) w, "rtc_alarm");            /* char reason_str[12] */
1226#else
1227    strcpy((void *) w, "pwr_key");              /* char reason_str[12] */
1228#endif
1229    w += 6;
1230
1231    tag = (model == 810) ? "RX-44" : "RX-34";
1232    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1233    stw_raw(w ++, 24);                          /* u16 len */
1234    strcpy((void *) w, "product");              /* char component[12] */
1235    w += 6;
1236    strcpy((void *) w, tag);                    /* char version[12] */
1237    w += 6;
1238
1239    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1240    stw_raw(w ++, 24);                          /* u16 len */
1241    strcpy((void *) w, "hw-build");             /* char component[12] */
1242    w += 6;
1243    strcpy((void *) w, "QEMU " QEMU_VERSION);   /* char version[12] */
1244    w += 6;
1245
1246    tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
1247    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1248    stw_raw(w ++, 24);                          /* u16 len */
1249    strcpy((void *) w, "nolo");                 /* char component[12] */
1250    w += 6;
1251    strcpy((void *) w, tag);                    /* char version[12] */
1252    w += 6;
1253
1254    return (void *) w - p;
1255}
1256
1257static int n800_atag_setup(struct arm_boot_info *info, void *p)
1258{
1259    return n8x0_atag_setup(p, 800);
1260}
1261
1262static int n810_atag_setup(struct arm_boot_info *info, void *p)
1263{
1264    return n8x0_atag_setup(p, 810);
1265}
1266
1267static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
1268                const char *kernel_filename,
1269                const char *kernel_cmdline, const char *initrd_filename,
1270                const char *cpu_model, struct arm_boot_info *binfo, int model)
1271{
1272    struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s));
1273    int sdram_size = binfo->ram_size;
1274    DisplayState *ds;
1275
1276    s->cpu = omap2420_mpu_init(sdram_size, cpu_model);
1277
1278    /* Setup peripherals
1279     *
1280     * Believed external peripherals layout in the N810:
1281     * (spi bus 1)
1282     *   tsc2005
1283     *   lcd_mipid
1284     * (spi bus 2)
1285     *   Conexant cx3110x (WLAN)
1286     *   optional: pc2400m (WiMAX)
1287     * (i2c bus 0)
1288     *   TLV320AIC33 (audio codec)
1289     *   TCM825x (camera by Toshiba)
1290     *   lp5521 (clever LEDs)
1291     *   tsl2563 (light sensor, hwmon, model 7, rev. 0)
1292     *   lm8323 (keypad, manf 00, rev 04)
1293     * (i2c bus 1)
1294     *   tmp105 (temperature sensor, hwmon)
1295     *   menelaus (pm)
1296     * (somewhere on i2c - maybe N800-only)
1297     *   tea5761 (FM tuner)
1298     * (serial 0)
1299     *   GPS
1300     * (some serial port)
1301     *   csr41814 (Bluetooth)
1302     */
1303    n8x0_gpio_setup(s);
1304    n8x0_nand_setup(s);
1305    n8x0_i2c_setup(s);
1306    if (model == 800)
1307        n800_tsc_kbd_setup(s);
1308    else if (model == 810) {
1309        n810_tsc_setup(s);
1310        n810_kbd_setup(s);
1311    }
1312    n8x0_spi_setup(s);
1313    n8x0_dss_setup(s);
1314    n8x0_cbus_setup(s);
1315    n8x0_uart_setup(s);
1316    if (usb_enabled)
1317        n8x0_usb_setup(s);
1318
1319    if (kernel_filename) {
1320        /* Or at the linux loader.  */
1321        binfo->kernel_filename = kernel_filename;
1322        binfo->kernel_cmdline = kernel_cmdline;
1323        binfo->initrd_filename = initrd_filename;
1324        arm_load_kernel(s->cpu->env, binfo);
1325
1326        qemu_register_reset(n8x0_boot_init, s);
1327    }
1328
1329    if (option_rom[0] && (boot_device[0] == 'n' || !kernel_filename)) {
1330        int rom_size;
1331        uint8_t nolo_tags[0x10000];
1332        /* No, wait, better start at the ROM.  */
1333        s->cpu->env->regs[15] = OMAP2_Q2_BASE + 0x400000;
1334
1335        /* This is intended for loading the `secondary.bin' program from
1336         * Nokia images (the NOLO bootloader).  The entry point seems
1337         * to be at OMAP2_Q2_BASE + 0x400000.
1338         *
1339         * The `2nd.bin' files contain some kind of earlier boot code and
1340         * for them the entry point needs to be set to OMAP2_SRAM_BASE.
1341         *
1342         * The code above is for loading the `zImage' file from Nokia
1343         * images.  */
1344        rom_size = load_image_targphys(option_rom[0],
1345                                       OMAP2_Q2_BASE + 0x400000,
1346                                       sdram_size - 0x400000);
1347        printf("%i bytes of image loaded\n", rom_size);
1348
1349        n800_setup_nolo_tags(nolo_tags);
1350        cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
1351    }
1352    /* FIXME: We shouldn't really be doing this here.  The LCD controller
1353       will set the size once configured, so this just sets an initial
1354       size until the guest activates the display.  */
1355    ds = get_displaystate();
1356    ds->surface = qemu_resize_displaysurface(ds, 800, 480);
1357    dpy_resize(ds);
1358}
1359
1360static struct arm_boot_info n800_binfo = {
1361    .loader_start = OMAP2_Q2_BASE,
1362    /* Actually two chips of 0x4000000 bytes each */
1363    .ram_size = 0x08000000,
1364    .board_id = 0x4f7,
1365    .atag_board = n800_atag_setup,
1366};
1367
1368static struct arm_boot_info n810_binfo = {
1369    .loader_start = OMAP2_Q2_BASE,
1370    /* Actually two chips of 0x4000000 bytes each */
1371    .ram_size = 0x08000000,
1372    /* 0x60c and 0x6bf (WiMAX Edition) have been assigned but are not
1373     * used by some older versions of the bootloader and 5555 is used
1374     * instead (including versions that shipped with many devices).  */
1375    .board_id = 0x60c,
1376    .atag_board = n810_atag_setup,
1377};
1378
1379static void n800_init(ram_addr_t ram_size,
1380                const char *boot_device,
1381                const char *kernel_filename, const char *kernel_cmdline,
1382                const char *initrd_filename, const char *cpu_model)
1383{
1384    return n8x0_init(ram_size, boot_device,
1385                    kernel_filename, kernel_cmdline, initrd_filename,
1386                    cpu_model, &n800_binfo, 800);
1387}
1388
1389static void n810_init(ram_addr_t ram_size,
1390                const char *boot_device,
1391                const char *kernel_filename, const char *kernel_cmdline,
1392                const char *initrd_filename, const char *cpu_model)
1393{
1394    return n8x0_init(ram_size, boot_device,
1395                    kernel_filename, kernel_cmdline, initrd_filename,
1396                    cpu_model, &n810_binfo, 810);
1397}
1398
1399static QEMUMachine n800_machine = {
1400    .name = "n800",
1401    .desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
1402    .init = n800_init,
1403};
1404
1405static QEMUMachine n810_machine = {
1406    .name = "n810",
1407    .desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
1408    .init = n810_init,
1409};
1410
1411static void nseries_machine_init(void)
1412{
1413    qemu_register_machine(&n800_machine);
1414    qemu_register_machine(&n810_machine);
1415}
1416
1417machine_init(nseries_machine_init);
1418