~ubuntu-branches/ubuntu/saucy/qemu/saucy

« back to all changes in this revision

Viewing changes to .pc/linaro-patches-1.5.0/0054-hw-nseries.c-Add-n900-machine.patch/hw/arm/nseries.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-05-28 08:18:30 UTC
  • mfrom: (1.8.2) (10.1.37 sid)
  • Revision ID: package-import@ubuntu.com-20130528081830-87xl2z9fq516a814
Tags: 1.5.0+dfsg-2ubuntu1
* Merge 1.5.0+dfs-2 from debian unstable.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - Dropped patches:
    * 0001-fix-wrong-output-with-info-chardev-for-tcp-socket.patch
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * gridcentric patch - updated
    * linaro arm patches from qemu-linaro rebasing branch

Show diffs side-by-side

added added

removed removed

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