~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/linaro/0051-hw-nseries.c-Add-support-for-n900-MIPID.patch/hw/arm/nseries.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-04 12:13:08 UTC
  • mfrom: (10.1.45 sid)
  • Revision ID: package-import@ubuntu.com-20140204121308-1xq92lrfs75agw2g
Tags: 1.7.0+dfsg-3ubuntu1~ppa1
* Merge 1.7.0+dfsg-3 from debian.  Remaining changes:
  - debian/patches/ubuntu:
    * expose-vmx_qemu64cpu.patch
    * linaro (omap3) and arm64 patches
    * ubuntu/target-ppc-add-stubs-for-kvm-breakpoints: fix FTBFS
      on ppc
    * ubuntu/CVE-2013-4377.patch: fix denial of service via virtio
  - debian/qemu-system-x86.modprobe: set kvm_intel nested=1 options
  - debian/control:
    * add arm64 to Architectures
    * add qemu-common and qemu-system-aarch64 packages
  - debian/qemu-system-common.install: add debian/tmp/usr/lib
  - debian/qemu-system-common.preinst: add kvm group
  - debian/qemu-system-common.postinst: remove acl placed by udev,
    and add udevadm trigger.
  - qemu-system-x86.links: add eepro100.rom, remove pxe-virtio,
    pxe-e1000 and pxe-rtl8139.
  - add qemu-system-x86.qemu-kvm.upstart and .default
  - qemu-user-static.postinst-in: remove arm64 binfmt
  - debian/rules:
    * allow parallel build
    * add aarch64 to system_targets and sys_systems
    * add qemu-kvm-spice links
    * install qemu-system-x86.modprobe
  - add debian/qemu-system-common.links for OVMF.fd link
* Remove kvm-img, kvm-nbd, kvm-ifup and kvm-ifdown symlinks.

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
 
 
432
 
static void mipid_reset(DeviceState *qdev)
433
 
{
434
 
    struct mipid_s *s = FROM_SPI_DEVICE(struct mipid_s,
435
 
                                        SPI_DEVICE_FROM_QDEV(qdev));
436
 
 
437
 
    s->pm = 0;
438
 
    s->cmd = 0;
439
 
 
440
 
    s->sleep = 1;
441
 
    s->booster = 0;
442
 
    s->selfcheck =
443
 
            (1 << 7) |  /* Register loading OK.  */
444
 
            (1 << 5) |  /* The chip is attached.  */
445
 
            (1 << 4);   /* Display glass still in one piece.  */
446
 
    s->te = 0;
447
 
    s->partial = 0;
448
 
    s->normal = 1;
449
 
    s->vscr = 0;
450
 
    s->invert = 0;
451
 
    s->onoff = 1;
452
 
    s->gamma = 0;
453
 
}
454
 
 
455
 
static uint32_t mipid_txrx(SPIDevice *spidev, uint32_t cmd, int len)
456
 
{
457
 
    struct mipid_s *s = FROM_SPI_DEVICE(struct mipid_s, spidev);
458
 
    uint8_t ret;
459
 
 
460
 
    if (len > 9)
461
 
        hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
462
 
 
463
 
    if (s->p >= ARRAY_SIZE(s->resp))
464
 
        ret = 0;
465
 
    else
466
 
        ret = s->resp[s->p ++];
467
 
    if (s->pm --> 0)
468
 
        s->param[s->pm] = cmd;
469
 
    else
470
 
        s->cmd = cmd;
471
 
 
472
 
    switch (s->cmd) {
473
 
    case 0x00:  /* NOP */
474
 
        TRACE_MIPID("NOP");
475
 
        break;
476
 
 
477
 
    case 0x01:  /* SWRESET */
478
 
        TRACE_MIPID("SWRESET");
479
 
        mipid_reset(&s->spi.qdev);
480
 
        break;
481
 
 
482
 
    case 0x02:  /* BSTROFF */
483
 
        TRACE_MIPID("BSTROFF");
484
 
        s->booster = 0;
485
 
        break;
486
 
    case 0x03:  /* BSTRON */
487
 
        TRACE_MIPID("BSTRON");
488
 
        s->booster = 1;
489
 
        break;
490
 
 
491
 
    case 0x04:  /* RDDID */
492
 
        s->p = 0;
493
 
        s->resp[0] = (s->id >> 16) & 0xff;
494
 
        s->resp[1] = (s->id >>  8) & 0xff;
495
 
        s->resp[2] = (s->id >>  0) & 0xff;
496
 
        TRACE_MIPID("RDDID 0x%02x 0x%02x 0x%02x",
497
 
                    s->resp[0], s->resp[1], s->resp[2]);
498
 
        break;
499
 
 
500
 
    case 0x06:  /* RD_RED */
501
 
    case 0x07:  /* RD_GREEN */
502
 
        /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so
503
 
         * for the bootloader one needs to change this.  */
504
 
    case 0x08:  /* RD_BLUE */
505
 
        TRACE_MIPID("RD_RED/GREEN_BLUE 0x01");
506
 
        s->p = 0;
507
 
        /* TODO: return first pixel components */
508
 
        s->resp[0] = 0x01;
509
 
        break;
510
 
 
511
 
    case 0x09:  /* RDDST */
512
 
        s->p = 0;
513
 
        s->resp[0] = s->booster << 7;
514
 
        s->resp[1] = (5 << 4) | (s->partial << 2) |
515
 
                (s->sleep << 1) | s->normal;
516
 
        s->resp[2] = (s->vscr << 7) | (s->invert << 5) |
517
 
                (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);
518
 
        s->resp[3] = s->gamma << 6;
519
 
        TRACE_MIPID("RDDST 0x%02x 0x%02x 0x%02x 0x%02x",
520
 
                    s->resp[0], s->resp[1], s->resp[2], s->resp[3]);
521
 
        break;
522
 
 
523
 
    case 0x0a:  /* RDDPM */
524
 
        s->p = 0;
525
 
        s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |
526
 
                (s->partial << 5) | (s->sleep << 6) | (s->booster << 7);
527
 
        TRACE_MIPID("RDDPM 0x%02x", s->resp[0]);
528
 
        break;
529
 
    case 0x0b:  /* RDDMADCTR */
530
 
        s->p = 0;
531
 
        s->resp[0] = 0;
532
 
        TRACE_MIPID("RDDMACTR 0x%02x", s->resp[0]);
533
 
        break;
534
 
    case 0x0c:  /* RDDCOLMOD */
535
 
        s->p = 0;
536
 
        s->resp[0] = 5; /* 65K colours */
537
 
        TRACE_MIPID("RDDCOLMOD 0x%02x", s->resp[0]);
538
 
        break;
539
 
    case 0x0d:  /* RDDIM */
540
 
        s->p = 0;
541
 
        s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;
542
 
        TRACE_MIPID("RDDIM 0x%02x", s->resp[0]);
543
 
        break;
544
 
    case 0x0e:  /* RDDSM */
545
 
        s->p = 0;
546
 
        s->resp[0] = s->te << 7;
547
 
        TRACE_MIPID("RDDSM 0x%02x", s->resp[0]);
548
 
        break;
549
 
    case 0x0f:  /* RDDSDR */
550
 
        s->p = 0;
551
 
        s->resp[0] = s->selfcheck;
552
 
        TRACE_MIPID("RDDSDR 0x%02x", s->resp[0]);
553
 
        break;
554
 
 
555
 
    case 0x10:  /* SLPIN */
556
 
        TRACE_MIPID("SLPIN");
557
 
        s->sleep = 1;
558
 
        break;
559
 
    case 0x11:  /* SLPOUT */
560
 
        TRACE_MIPID("SLPOUT");
561
 
        s->sleep = 0;
562
 
        s->selfcheck ^= 1 << 6; /* POFF self-diagnosis Ok */
563
 
        break;
564
 
 
565
 
    case 0x12:  /* PTLON */
566
 
        TRACE_MIPID("PTLON");
567
 
        s->partial = 1;
568
 
        s->normal = 0;
569
 
        s->vscr = 0;
570
 
        break;
571
 
    case 0x13:  /* NORON */
572
 
        TRACE_MIPID("NORON");
573
 
        s->partial = 0;
574
 
        s->normal = 1;
575
 
        s->vscr = 0;
576
 
        break;
577
 
 
578
 
    case 0x20:  /* INVOFF */
579
 
        TRACE_MIPID("INVOFF");
580
 
        s->invert = 0;
581
 
        break;
582
 
    case 0x21:  /* INVON */
583
 
        TRACE_MIPID("INVON");
584
 
        s->invert = 1;
585
 
        break;
586
 
 
587
 
    case 0x22:  /* APOFF */
588
 
    case 0x23:  /* APON */
589
 
        TRACE_MIPID("APON/OFF");
590
 
        goto bad_cmd;
591
 
 
592
 
    case 0x25:  /* WRCNTR */
593
 
        TRACE_MIPID("WRCNTR");
594
 
        if (s->pm < 0)
595
 
            s->pm = 1;
596
 
        goto bad_cmd;
597
 
 
598
 
    case 0x26:  /* GAMSET */
599
 
        if (!s->pm) {
600
 
            s->gamma = ffs(s->param[0] & 0xf) - 1;
601
 
            TRACE_MIPID("GAMSET 0x%02x", s->gamma);
602
 
        } else if (s->pm < 0) {
603
 
            s->pm = 1;
604
 
        }
605
 
        break;
606
 
 
607
 
    case 0x28:  /* DISPOFF */
608
 
        TRACE_MIPID("DISPOFF");
609
 
        s->onoff = 0;
610
 
        break;
611
 
    case 0x29:  /* DISPON */
612
 
        TRACE_MIPID("DISPON");
613
 
        s->onoff = 1;
614
 
        break;
615
 
 
616
 
    case 0x2a:  /* CASET */
617
 
    case 0x2b:  /* RASET */
618
 
    case 0x2c:  /* RAMWR */
619
 
    case 0x2d:  /* RGBSET */
620
 
    case 0x2e:  /* RAMRD */
621
 
    case 0x30:  /* PTLAR */
622
 
    case 0x33:  /* SCRLAR */
623
 
        goto bad_cmd;
624
 
 
625
 
    case 0x34:  /* TEOFF */
626
 
        TRACE_MIPID("TEOFF");
627
 
        s->te = 0;
628
 
        break;
629
 
    case 0x35:  /* TEON */
630
 
        if (!s->pm) {
631
 
            s->te = 1;
632
 
            TRACE_MIPID("TEON 0x%02x", s->param[0] & 0xff);
633
 
        } else if (s->pm < 0) {
634
 
            s->pm = 1;
635
 
        }
636
 
        break;
637
 
 
638
 
    case 0x36:  /* MADCTR */
639
 
        TRACE_MIPID("MADCTR");
640
 
        goto bad_cmd;
641
 
 
642
 
    case 0x37:  /* VSCSAD */
643
 
        TRACE_MIPID("VSCSAD");
644
 
        s->partial = 0;
645
 
        s->normal = 0;
646
 
        s->vscr = 1;
647
 
        break;
648
 
 
649
 
    case 0x38:  /* IDMOFF */
650
 
    case 0x39:  /* IDMON */
651
 
    case 0x3a:  /* COLMOD */
652
 
        goto bad_cmd;
653
 
 
654
 
    case 0xb0:  /* CLKINT / DISCTL */
655
 
    case 0xb1:  /* CLKEXT */
656
 
        if (s->pm < 0)
657
 
            s->pm = 2;
658
 
        break;
659
 
 
660
 
    case 0xb4:  /* FRMSEL */
661
 
        TRACE_MIPID("FRMSEL");
662
 
        break;
663
 
 
664
 
    case 0xb5:  /* FRM8SEL */
665
 
    case 0xb6:  /* TMPRNG / INIESC */
666
 
    case 0xb7:  /* TMPHIS / NOP2 */
667
 
    case 0xb8:  /* TMPREAD / MADCTL */
668
 
    case 0xba:  /* DISTCTR */
669
 
    case 0xbb:  /* EPVOL */
670
 
        goto bad_cmd;
671
 
 
672
 
    case 0xbd:  /* Unknown */
673
 
        s->p = 0;
674
 
        s->resp[0] = 0;
675
 
        s->resp[1] = 1;
676
 
        TRACE_MIPID("??? 0x%02x 0x%02x", s->resp[0], s->resp[1]);
677
 
        break;
678
 
 
679
 
    case 0xc2:  /* IFMOD */
680
 
        if (s->pm < 0)
681
 
            s->pm = 2;
682
 
        break;
683
 
 
684
 
    case 0xc6:  /* PWRCTL */
685
 
    case 0xc7:  /* PPWRCTL */
686
 
    case 0xd0:  /* EPWROUT */
687
 
    case 0xd1:  /* EPWRIN */
688
 
    case 0xd4:  /* RDEV */
689
 
    case 0xd5:  /* RDRR */
690
 
        goto bad_cmd;
691
 
 
692
 
    case 0xda:  /* RDID1 */
693
 
        s->p = 0;
694
 
        s->resp[0] = (s->id >> 16) & 0xff;
695
 
        TRACE_MIPID("RDID1 0x%02x", s->resp[0]);
696
 
        break;
697
 
    case 0xdb:  /* RDID2 */
698
 
        s->p = 0;
699
 
        s->resp[0] = (s->id >>  8) & 0xff;
700
 
        TRACE_MIPID("RDID2 0x%02x", s->resp[0]);
701
 
        break;
702
 
    case 0xdc:  /* RDID3 */
703
 
        s->p = 0;
704
 
        s->resp[0] = (s->id >>  0) & 0xff;
705
 
        TRACE_MIPID("RDID3 0x%02x", s->resp[0]);
706
 
        break;
707
 
 
708
 
    default:
709
 
    bad_cmd:
710
 
        qemu_log_mask(LOG_GUEST_ERROR,
711
 
                      "%s: unknown command %02x\n", __func__, s->cmd);
712
 
        break;
713
 
    }
714
 
 
715
 
    return ret;
716
 
}
717
 
 
718
 
static int mipid_init(SPIDevice *spidev)
719
 
{
720
 
    return 0;
721
 
}
722
 
 
723
 
static Property mipid_properties[] = {
724
 
    DEFINE_PROP_UINT32("id", struct mipid_s, id, 0),
725
 
    DEFINE_PROP_END_OF_LIST()
726
 
};
727
 
 
728
 
static void mipid_class_init(ObjectClass *klass, void *data)
729
 
{
730
 
    DeviceClass *dc = DEVICE_CLASS(klass);
731
 
    SPIDeviceClass *k = SPI_DEVICE_CLASS(klass);
732
 
 
733
 
    k->init = mipid_init;
734
 
    k->txrx = mipid_txrx;
735
 
    dc->reset = mipid_reset;
736
 
    dc->props = mipid_properties;
737
 
}
738
 
 
739
 
static TypeInfo mipid_info = {
740
 
    .name = "lcd_mipid",
741
 
    .parent = TYPE_SPI_DEVICE,
742
 
    .instance_size = sizeof(struct mipid_s),
743
 
    .class_init = mipid_class_init,
744
 
};
745
 
 
746
 
static void n8x0_spi_setup(struct n800_s *s)
747
 
{
748
 
    s->mipid = spi_create_device_noinit(omap_mcspi_bus(s->mpu->mcspi, 0),
749
 
                                        "lcd_mipid", 1);
750
 
    qdev_prop_set_uint32(s->mipid, "id", 0x838f03);
751
 
    qdev_init_nofail(s->mipid);
752
 
}
753
 
 
754
 
/* This task is normally performed by the bootloader.  If we're loading
755
 
 * a kernel directly, we need to enable the Blizzard ourselves.  */
756
 
static void n800_dss_init(struct rfbi_chip_s *chip)
757
 
{
758
 
    uint8_t *fb_blank;
759
 
 
760
 
    chip->write(chip->opaque, 0, 0x2a);         /* LCD Width register */
761
 
    chip->write(chip->opaque, 1, 0x64);
762
 
    chip->write(chip->opaque, 0, 0x2c);         /* LCD HNDP register */
763
 
    chip->write(chip->opaque, 1, 0x1e);
764
 
    chip->write(chip->opaque, 0, 0x2e);         /* LCD Height 0 register */
765
 
    chip->write(chip->opaque, 1, 0xe0);
766
 
    chip->write(chip->opaque, 0, 0x30);         /* LCD Height 1 register */
767
 
    chip->write(chip->opaque, 1, 0x01);
768
 
    chip->write(chip->opaque, 0, 0x32);         /* LCD VNDP register */
769
 
    chip->write(chip->opaque, 1, 0x06);
770
 
    chip->write(chip->opaque, 0, 0x68);         /* Display Mode register */
771
 
    chip->write(chip->opaque, 1, 1);            /* Enable bit */
772
 
 
773
 
    chip->write(chip->opaque, 0, 0x6c); 
774
 
    chip->write(chip->opaque, 1, 0x00);         /* Input X Start Position */
775
 
    chip->write(chip->opaque, 1, 0x00);         /* Input X Start Position */
776
 
    chip->write(chip->opaque, 1, 0x00);         /* Input Y Start Position */
777
 
    chip->write(chip->opaque, 1, 0x00);         /* Input Y Start Position */
778
 
    chip->write(chip->opaque, 1, 0x1f);         /* Input X End Position */
779
 
    chip->write(chip->opaque, 1, 0x03);         /* Input X End Position */
780
 
    chip->write(chip->opaque, 1, 0xdf);         /* Input Y End Position */
781
 
    chip->write(chip->opaque, 1, 0x01);         /* Input Y End Position */
782
 
    chip->write(chip->opaque, 1, 0x00);         /* Output X Start Position */
783
 
    chip->write(chip->opaque, 1, 0x00);         /* Output X Start Position */
784
 
    chip->write(chip->opaque, 1, 0x00);         /* Output Y Start Position */
785
 
    chip->write(chip->opaque, 1, 0x00);         /* Output Y Start Position */
786
 
    chip->write(chip->opaque, 1, 0x1f);         /* Output X End Position */
787
 
    chip->write(chip->opaque, 1, 0x03);         /* Output X End Position */
788
 
    chip->write(chip->opaque, 1, 0xdf);         /* Output Y End Position */
789
 
    chip->write(chip->opaque, 1, 0x01);         /* Output Y End Position */
790
 
    chip->write(chip->opaque, 1, 0x01);         /* Input Data Format */
791
 
    chip->write(chip->opaque, 1, 0x01);         /* Data Source Select */
792
 
 
793
 
    fb_blank = memset(g_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
794
 
    /* Display Memory Data Port */
795
 
    chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
796
 
    g_free(fb_blank);
797
 
}
798
 
 
799
 
static void n8x0_dss_setup(struct n800_s *s)
800
 
{
801
 
    s->blizzard.opaque = s1d13745_init(NULL);
802
 
    s->blizzard.block = s1d13745_write_block;
803
 
    s->blizzard.write = s1d13745_write;
804
 
    s->blizzard.read = s1d13745_read;
805
 
 
806
 
    omap_rfbi_attach(s->mpu->dss, 0, &s->blizzard);
807
 
}
808
 
 
809
 
static void n8x0_cbus_setup(struct n800_s *s)
810
 
{
811
 
    qemu_irq dat_out = qdev_get_gpio_in(s->mpu->gpio, N8X0_CBUS_DAT_GPIO);
812
 
    qemu_irq retu_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_RETU_GPIO);
813
 
    qemu_irq tahvo_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TAHVO_GPIO);
814
 
 
815
 
    CBus *cbus = cbus_init(dat_out);
816
 
 
817
 
    qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_CLK_GPIO, cbus->clk);
818
 
    qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_DAT_GPIO, cbus->dat);
819
 
    qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_SEL_GPIO, cbus->sel);
820
 
 
821
 
    cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
822
 
    cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
823
 
}
824
 
 
825
 
static void n8x0_uart_setup(struct n800_s *s)
826
 
{
827
 
    CharDriverState *radio = uart_hci_init(
828
 
                    qdev_get_gpio_in(s->mpu->gpio, N8X0_BT_HOST_WKUP_GPIO));
829
 
 
830
 
    qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_RESET_GPIO,
831
 
                    csrhci_pins_get(radio)[csrhci_pin_reset]);
832
 
    qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_WKUP_GPIO,
833
 
                    csrhci_pins_get(radio)[csrhci_pin_wakeup]);
834
 
 
835
 
    omap_uart_attach(s->mpu->uart[BT_UART], radio, "bt-uart");
836
 
}
837
 
 
838
 
static void n8x0_usb_setup(struct n800_s *s)
839
 
{
840
 
    SysBusDevice *dev;
841
 
    s->usb = qdev_create(NULL, "tusb6010");
842
 
    dev = SYS_BUS_DEVICE(s->usb);
843
 
    qdev_init_nofail(s->usb);
844
 
    sysbus_connect_irq(dev, 0,
845
 
                       qdev_get_gpio_in(s->mpu->gpio, N8X0_TUSB_INT_GPIO));
846
 
    /* Using the NOR interface */
847
 
    omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_ASYNC_CS,
848
 
                     sysbus_mmio_get_region(dev, 0));
849
 
    omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_SYNC_CS,
850
 
                     sysbus_mmio_get_region(dev, 1));
851
 
    qdev_connect_gpio_out(s->mpu->gpio, N8X0_TUSB_ENABLE_GPIO,
852
 
                          qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */
853
 
}
854
 
 
855
 
/* Setup done before the main bootloader starts by some early setup code
856
 
 * - used when we want to run the main bootloader in emulation.  This
857
 
 * isn't documented.  */
858
 
static uint32_t n800_pinout[104] = {
859
 
    0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
860
 
    0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
861
 
    0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
862
 
    0x080800bc, 0x00cc0808, 0x08081818, 0x18180128,
863
 
    0x01241800, 0x18181818, 0x000000f0, 0x01300000,
864
 
    0x00001b0b, 0x1b0f0138, 0x00e0181b, 0x1b031b0b,
865
 
    0x180f0078, 0x00740018, 0x0f0f0f1a, 0x00000080,
866
 
    0x007c0000, 0x00000000, 0x00000088, 0x00840000,
867
 
    0x00000000, 0x00000094, 0x00980300, 0x0f180003,
868
 
    0x0000008c, 0x00900f0f, 0x0f0f1b00, 0x0f00009c,
869
 
    0x01140000, 0x1b1b0f18, 0x0818013c, 0x01400008,
870
 
    0x00001818, 0x000b0110, 0x010c1800, 0x0b030b0f,
871
 
    0x181800f4, 0x00f81818, 0x00000018, 0x000000fc,
872
 
    0x00401808, 0x00000000, 0x0f1b0030, 0x003c0008,
873
 
    0x00000000, 0x00000038, 0x00340000, 0x00000000,
874
 
    0x1a080070, 0x00641a1a, 0x08080808, 0x08080060,
875
 
    0x005c0808, 0x08080808, 0x08080058, 0x00540808,
876
 
    0x08080808, 0x0808006c, 0x00680808, 0x08080808,
877
 
    0x000000a8, 0x00b00000, 0x08080808, 0x000000a0,
878
 
    0x00a40000, 0x00000000, 0x08ff0050, 0x004c0808,
879
 
    0xffffffff, 0xffff0048, 0x0044ffff, 0xffffffff,
880
 
    0x000000ac, 0x01040800, 0x08080b0f, 0x18180100,
881
 
    0x01081818, 0x0b0b1808, 0x1a0300e4, 0x012c0b1a,
882
 
    0x02020018, 0x0b000134, 0x011c0800, 0x0b1b1b00,
883
 
    0x0f0000c8, 0x00ec181b, 0x000f0f02, 0x00180118,
884
 
    0x01200000, 0x0f0b1b1b, 0x0f0200e8, 0x0000020b,
885
 
};
886
 
 
887
 
static void n800_setup_nolo_tags(void *sram_base)
888
 
{
889
 
    int i;
890
 
    uint32_t *p = sram_base + 0x8000;
891
 
    uint32_t *v = sram_base + 0xa000;
892
 
 
893
 
    memset(p, 0, 0x3000);
894
 
 
895
 
    strcpy((void *) (p + 0), "QEMU N800");
896
 
 
897
 
    strcpy((void *) (p + 8), "F5");
898
 
 
899
 
    stl_raw(p + 10, 0x04f70000);
900
 
    strcpy((void *) (p + 9), "RX-34");
901
 
 
902
 
    /* RAM size in MB? */
903
 
    stl_raw(p + 12, 0x80);
904
 
 
905
 
    /* Pointer to the list of tags */
906
 
    stl_raw(p + 13, OMAP2_SRAM_BASE + 0x9000);
907
 
 
908
 
    /* The NOLO tags start here */
909
 
    p = sram_base + 0x9000;
910
 
#define ADD_TAG(tag, len)                               \
911
 
    stw_raw((uint16_t *) p + 0, tag);                   \
912
 
    stw_raw((uint16_t *) p + 1, len); p ++;             \
913
 
    stl_raw(p ++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
914
 
 
915
 
    /* OMAP STI console? Pin out settings? */
916
 
    ADD_TAG(0x6e01, 414);
917
 
    for (i = 0; i < ARRAY_SIZE(n800_pinout); i ++)
918
 
        stl_raw(v ++, n800_pinout[i]);
919
 
 
920
 
    /* Kernel memsize? */
921
 
    ADD_TAG(0x6e05, 1);
922
 
    stl_raw(v ++, 2);
923
 
 
924
 
    /* NOLO serial console */
925
 
    ADD_TAG(0x6e02, 4);
926
 
    stl_raw(v ++, XLDR_LL_UART);        /* UART number (1 - 3) */
927
 
 
928
 
#if 0
929
 
    /* CBUS settings (Retu/AVilma) */
930
 
    ADD_TAG(0x6e03, 6);
931
 
    stw_raw((uint16_t *) v + 0, 65);    /* CBUS GPIO0 */
932
 
    stw_raw((uint16_t *) v + 1, 66);    /* CBUS GPIO1 */
933
 
    stw_raw((uint16_t *) v + 2, 64);    /* CBUS GPIO2 */
934
 
    v += 2;
935
 
#endif
936
 
 
937
 
    /* Nokia ASIC BB5 (Retu/Tahvo) */
938
 
    ADD_TAG(0x6e0a, 4);
939
 
    stw_raw((uint16_t *) v + 0, 111);   /* "Retu" interrupt GPIO */
940
 
    stw_raw((uint16_t *) v + 1, 108);   /* "Tahvo" interrupt GPIO */
941
 
    v ++;
942
 
 
943
 
    /* LCD console? */
944
 
    ADD_TAG(0x6e04, 4);
945
 
    stw_raw((uint16_t *) v + 0, 30);    /* ??? */
946
 
    stw_raw((uint16_t *) v + 1, 24);    /* ??? */
947
 
    v ++;
948
 
 
949
 
#if 0
950
 
    /* LCD settings */
951
 
    ADD_TAG(0x6e06, 2);
952
 
    stw_raw((uint16_t *) (v ++), 15);   /* ??? */
953
 
#endif
954
 
 
955
 
    /* I^2C (Menelaus) */
956
 
    ADD_TAG(0x6e07, 4);
957
 
    stl_raw(v ++, 0x00720000);          /* ??? */
958
 
 
959
 
    /* Unknown */
960
 
    ADD_TAG(0x6e0b, 6);
961
 
    stw_raw((uint16_t *) v + 0, 94);    /* ??? */
962
 
    stw_raw((uint16_t *) v + 1, 23);    /* ??? */
963
 
    stw_raw((uint16_t *) v + 2, 0);     /* ??? */
964
 
    v += 2;
965
 
 
966
 
    /* OMAP gpio switch info */
967
 
    ADD_TAG(0x6e0c, 80);
968
 
    strcpy((void *) v, "bat_cover");    v += 3;
969
 
    stw_raw((uint16_t *) v + 0, 110);   /* GPIO num ??? */
970
 
    stw_raw((uint16_t *) v + 1, 1);     /* GPIO num ??? */
971
 
    v += 2;
972
 
    strcpy((void *) v, "cam_act");      v += 3;
973
 
    stw_raw((uint16_t *) v + 0, 95);    /* GPIO num ??? */
974
 
    stw_raw((uint16_t *) v + 1, 32);    /* GPIO num ??? */
975
 
    v += 2;
976
 
    strcpy((void *) v, "cam_turn");     v += 3;
977
 
    stw_raw((uint16_t *) v + 0, 12);    /* GPIO num ??? */
978
 
    stw_raw((uint16_t *) v + 1, 33);    /* GPIO num ??? */
979
 
    v += 2;
980
 
    strcpy((void *) v, "headphone");    v += 3;
981
 
    stw_raw((uint16_t *) v + 0, 107);   /* GPIO num ??? */
982
 
    stw_raw((uint16_t *) v + 1, 17);    /* GPIO num ??? */
983
 
    v += 2;
984
 
 
985
 
    /* Bluetooth */
986
 
    ADD_TAG(0x6e0e, 12);
987
 
    stl_raw(v ++, 0x5c623d01);          /* ??? */
988
 
    stl_raw(v ++, 0x00000201);          /* ??? */
989
 
    stl_raw(v ++, 0x00000000);          /* ??? */
990
 
 
991
 
    /* CX3110x WLAN settings */
992
 
    ADD_TAG(0x6e0f, 8);
993
 
    stl_raw(v ++, 0x00610025);          /* ??? */
994
 
    stl_raw(v ++, 0xffff0057);          /* ??? */
995
 
 
996
 
    /* MMC host settings */
997
 
    ADD_TAG(0x6e10, 12);
998
 
    stl_raw(v ++, 0xffff000f);          /* ??? */
999
 
    stl_raw(v ++, 0xffffffff);          /* ??? */
1000
 
    stl_raw(v ++, 0x00000060);          /* ??? */
1001
 
 
1002
 
    /* OneNAND chip select */
1003
 
    ADD_TAG(0x6e11, 10);
1004
 
    stl_raw(v ++, 0x00000401);          /* ??? */
1005
 
    stl_raw(v ++, 0x0002003a);          /* ??? */
1006
 
    stl_raw(v ++, 0x00000002);          /* ??? */
1007
 
 
1008
 
    /* TEA5761 sensor settings */
1009
 
    ADD_TAG(0x6e12, 2);
1010
 
    stl_raw(v ++, 93);                  /* GPIO num ??? */
1011
 
 
1012
 
#if 0
1013
 
    /* Unknown tag */
1014
 
    ADD_TAG(6e09, 0);
1015
 
 
1016
 
    /* Kernel UART / console */
1017
 
    ADD_TAG(6e12, 0);
1018
 
#endif
1019
 
 
1020
 
    /* End of the list */
1021
 
    stl_raw(p ++, 0x00000000);
1022
 
    stl_raw(p ++, 0x00000000);
1023
 
}
1024
 
 
1025
 
/* This task is normally performed by the bootloader.  If we're loading
1026
 
 * a kernel directly, we need to set up GPMC mappings ourselves.  */
1027
 
static void n800_gpmc_init(struct n800_s *s)
1028
 
{
1029
 
    uint32_t config7 =
1030
 
            (0xf << 8) |        /* MASKADDRESS */
1031
 
            (1 << 6) |          /* CSVALID */
1032
 
            (4 << 0);           /* BASEADDRESS */
1033
 
 
1034
 
    cpu_physical_memory_write(0x6800a078,               /* GPMC_CONFIG7_0 */
1035
 
                              &config7, sizeof(config7));
1036
 
}
1037
 
 
1038
 
/* Setup sequence done by the bootloader */
1039
 
static void n8x0_boot_init(void *opaque)
1040
 
{
1041
 
    struct n800_s *s = (struct n800_s *) opaque;
1042
 
    uint32_t buf;
1043
 
 
1044
 
    /* PRCM setup */
1045
 
#define omap_writel(addr, val)  \
1046
 
    buf = (val);                        \
1047
 
    cpu_physical_memory_write(addr, &buf, sizeof(buf))
1048
 
 
1049
 
    omap_writel(0x48008060, 0x41);              /* PRCM_CLKSRC_CTRL */
1050
 
    omap_writel(0x48008070, 1);                 /* PRCM_CLKOUT_CTRL */
1051
 
    omap_writel(0x48008078, 0);                 /* PRCM_CLKEMUL_CTRL */
1052
 
    omap_writel(0x48008090, 0);                 /* PRCM_VOLTSETUP */
1053
 
    omap_writel(0x48008094, 0);                 /* PRCM_CLKSSETUP */
1054
 
    omap_writel(0x48008098, 0);                 /* PRCM_POLCTRL */
1055
 
    omap_writel(0x48008140, 2);                 /* CM_CLKSEL_MPU */
1056
 
    omap_writel(0x48008148, 0);                 /* CM_CLKSTCTRL_MPU */
1057
 
    omap_writel(0x48008158, 1);                 /* RM_RSTST_MPU */
1058
 
    omap_writel(0x480081c8, 0x15);              /* PM_WKDEP_MPU */
1059
 
    omap_writel(0x480081d4, 0x1d4);             /* PM_EVGENCTRL_MPU */
1060
 
    omap_writel(0x480081d8, 0);                 /* PM_EVEGENONTIM_MPU */
1061
 
    omap_writel(0x480081dc, 0);                 /* PM_EVEGENOFFTIM_MPU */
1062
 
    omap_writel(0x480081e0, 0xc);               /* PM_PWSTCTRL_MPU */
1063
 
    omap_writel(0x48008200, 0x047e7ff7);        /* CM_FCLKEN1_CORE */
1064
 
    omap_writel(0x48008204, 0x00000004);        /* CM_FCLKEN2_CORE */
1065
 
    omap_writel(0x48008210, 0x047e7ff1);        /* CM_ICLKEN1_CORE */
1066
 
    omap_writel(0x48008214, 0x00000004);        /* CM_ICLKEN2_CORE */
1067
 
    omap_writel(0x4800821c, 0x00000000);        /* CM_ICLKEN4_CORE */
1068
 
    omap_writel(0x48008230, 0);                 /* CM_AUTOIDLE1_CORE */
1069
 
    omap_writel(0x48008234, 0);                 /* CM_AUTOIDLE2_CORE */
1070
 
    omap_writel(0x48008238, 7);                 /* CM_AUTOIDLE3_CORE */
1071
 
    omap_writel(0x4800823c, 0);                 /* CM_AUTOIDLE4_CORE */
1072
 
    omap_writel(0x48008240, 0x04360626);        /* CM_CLKSEL1_CORE */
1073
 
    omap_writel(0x48008244, 0x00000014);        /* CM_CLKSEL2_CORE */
1074
 
    omap_writel(0x48008248, 0);                 /* CM_CLKSTCTRL_CORE */
1075
 
    omap_writel(0x48008300, 0x00000000);        /* CM_FCLKEN_GFX */
1076
 
    omap_writel(0x48008310, 0x00000000);        /* CM_ICLKEN_GFX */
1077
 
    omap_writel(0x48008340, 0x00000001);        /* CM_CLKSEL_GFX */
1078
 
    omap_writel(0x48008400, 0x00000004);        /* CM_FCLKEN_WKUP */
1079
 
    omap_writel(0x48008410, 0x00000004);        /* CM_ICLKEN_WKUP */
1080
 
    omap_writel(0x48008440, 0x00000000);        /* CM_CLKSEL_WKUP */
1081
 
    omap_writel(0x48008500, 0x000000cf);        /* CM_CLKEN_PLL */
1082
 
    omap_writel(0x48008530, 0x0000000c);        /* CM_AUTOIDLE_PLL */
1083
 
    omap_writel(0x48008540,                     /* CM_CLKSEL1_PLL */
1084
 
                    (0x78 << 12) | (6 << 8));
1085
 
    omap_writel(0x48008544, 2);                 /* CM_CLKSEL2_PLL */
1086
 
 
1087
 
    /* GPMC setup */
1088
 
    n800_gpmc_init(s);
1089
 
 
1090
 
    /* Video setup */
1091
 
    n800_dss_init(&s->blizzard);
1092
 
 
1093
 
    /* CPU setup */
1094
 
    s->mpu->cpu->env.GE = 0x5;
1095
 
 
1096
 
    /* If the machine has a slided keyboard, open it */
1097
 
    if (s->kbd)
1098
 
        qemu_irq_raise(qdev_get_gpio_in(s->mpu->gpio, N810_SLIDE_GPIO));
1099
 
}
1100
 
 
1101
 
#define OMAP_TAG_NOKIA_BT       0x4e01
1102
 
#define OMAP_TAG_WLAN_CX3110X   0x4e02
1103
 
#define OMAP_TAG_CBUS           0x4e03
1104
 
#define OMAP_TAG_EM_ASIC_BB5    0x4e04
1105
 
 
1106
 
static struct omap_gpiosw_info_s {
1107
 
    const char *name;
1108
 
    int line;
1109
 
    int type;
1110
 
} n800_gpiosw_info[] = {
1111
 
    {
1112
 
        "bat_cover", N800_BAT_COVER_GPIO,
1113
 
        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1114
 
    }, {
1115
 
        "cam_act", N800_CAM_ACT_GPIO,
1116
 
        OMAP_GPIOSW_TYPE_ACTIVITY,
1117
 
    }, {
1118
 
        "cam_turn", N800_CAM_TURN_GPIO,
1119
 
        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED,
1120
 
    }, {
1121
 
        "headphone", N8X0_HEADPHONE_GPIO,
1122
 
        OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1123
 
    },
1124
 
    { NULL }
1125
 
}, n810_gpiosw_info[] = {
1126
 
    {
1127
 
        "gps_reset", N810_GPS_RESET_GPIO,
1128
 
        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1129
 
    }, {
1130
 
        "gps_wakeup", N810_GPS_WAKEUP_GPIO,
1131
 
        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1132
 
    }, {
1133
 
        "headphone", N8X0_HEADPHONE_GPIO,
1134
 
        OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1135
 
    }, {
1136
 
        "kb_lock", N810_KB_LOCK_GPIO,
1137
 
        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1138
 
    }, {
1139
 
        "sleepx_led", N810_SLEEPX_LED_GPIO,
1140
 
        OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED | OMAP_GPIOSW_OUTPUT,
1141
 
    }, {
1142
 
        "slide", N810_SLIDE_GPIO,
1143
 
        OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1144
 
    },
1145
 
    { NULL }
1146
 
};
1147
 
 
1148
 
static struct omap_partition_info_s {
1149
 
    uint32_t offset;
1150
 
    uint32_t size;
1151
 
    int mask;
1152
 
    const char *name;
1153
 
} n800_part_info[] = {
1154
 
    { 0x00000000, 0x00020000, 0x3, "bootloader" },
1155
 
    { 0x00020000, 0x00060000, 0x0, "config" },
1156
 
    { 0x00080000, 0x00200000, 0x0, "kernel" },
1157
 
    { 0x00280000, 0x00200000, 0x3, "initfs" },
1158
 
    { 0x00480000, 0x0fb80000, 0x3, "rootfs" },
1159
 
 
1160
 
    { 0, 0, 0, NULL }
1161
 
}, n810_part_info[] = {
1162
 
    { 0x00000000, 0x00020000, 0x3, "bootloader" },
1163
 
    { 0x00020000, 0x00060000, 0x0, "config" },
1164
 
    { 0x00080000, 0x00220000, 0x0, "kernel" },
1165
 
    { 0x002a0000, 0x00400000, 0x0, "initfs" },
1166
 
    { 0x006a0000, 0x0f960000, 0x0, "rootfs" },
1167
 
 
1168
 
    { 0, 0, 0, NULL }
1169
 
};
1170
 
 
1171
 
static bdaddr_t n8x0_bd_addr = {{ N8X0_BD_ADDR }};
1172
 
 
1173
 
static int n8x0_atag_setup(void *p, int model)
1174
 
{
1175
 
    uint8_t *b;
1176
 
    uint16_t *w;
1177
 
    uint32_t *l;
1178
 
    struct omap_gpiosw_info_s *gpiosw;
1179
 
    struct omap_partition_info_s *partition;
1180
 
    const char *tag;
1181
 
 
1182
 
    w = p;
1183
 
 
1184
 
    stw_raw(w ++, OMAP_TAG_UART);               /* u16 tag */
1185
 
    stw_raw(w ++, 4);                           /* u16 len */
1186
 
    stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
1187
 
    w ++;
1188
 
 
1189
 
#if 0
1190
 
    stw_raw(w ++, OMAP_TAG_SERIAL_CONSOLE);     /* u16 tag */
1191
 
    stw_raw(w ++, 4);                           /* u16 len */
1192
 
    stw_raw(w ++, XLDR_LL_UART + 1);            /* u8 console_uart */
1193
 
    stw_raw(w ++, 115200);                      /* u32 console_speed */
1194
 
#endif
1195
 
 
1196
 
    stw_raw(w ++, OMAP_TAG_LCD);                /* u16 tag */
1197
 
    stw_raw(w ++, 36);                          /* u16 len */
1198
 
    strcpy((void *) w, "QEMU LCD panel");       /* char panel_name[16] */
1199
 
    w += 8;
1200
 
    strcpy((void *) w, "blizzard");             /* char ctrl_name[16] */
1201
 
    w += 8;
1202
 
    stw_raw(w ++, N810_BLIZZARD_RESET_GPIO);    /* TODO: n800 s16 nreset_gpio */
1203
 
    stw_raw(w ++, 24);                          /* u8 data_lines */
1204
 
 
1205
 
    stw_raw(w ++, OMAP_TAG_CBUS);               /* u16 tag */
1206
 
    stw_raw(w ++, 8);                           /* u16 len */
1207
 
    stw_raw(w ++, N8X0_CBUS_CLK_GPIO);          /* s16 clk_gpio */
1208
 
    stw_raw(w ++, N8X0_CBUS_DAT_GPIO);          /* s16 dat_gpio */
1209
 
    stw_raw(w ++, N8X0_CBUS_SEL_GPIO);          /* s16 sel_gpio */
1210
 
    w ++;
1211
 
 
1212
 
    stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5);        /* u16 tag */
1213
 
    stw_raw(w ++, 4);                           /* u16 len */
1214
 
    stw_raw(w ++, N8X0_RETU_GPIO);              /* s16 retu_irq_gpio */
1215
 
    stw_raw(w ++, N8X0_TAHVO_GPIO);             /* s16 tahvo_irq_gpio */
1216
 
 
1217
 
    gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
1218
 
    for (; gpiosw->name; gpiosw ++) {
1219
 
        stw_raw(w ++, OMAP_TAG_GPIO_SWITCH);    /* u16 tag */
1220
 
        stw_raw(w ++, 20);                      /* u16 len */
1221
 
        strcpy((void *) w, gpiosw->name);       /* char name[12] */
1222
 
        w += 6;
1223
 
        stw_raw(w ++, gpiosw->line);            /* u16 gpio */
1224
 
        stw_raw(w ++, gpiosw->type);
1225
 
        stw_raw(w ++, 0);
1226
 
        stw_raw(w ++, 0);
1227
 
    }
1228
 
 
1229
 
    stw_raw(w ++, OMAP_TAG_NOKIA_BT);           /* u16 tag */
1230
 
    stw_raw(w ++, 12);                          /* u16 len */
1231
 
    b = (void *) w;
1232
 
    stb_raw(b ++, 0x01);                        /* u8 chip_type (CSR) */
1233
 
    stb_raw(b ++, N8X0_BT_WKUP_GPIO);           /* u8 bt_wakeup_gpio */
1234
 
    stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO);      /* u8 host_wakeup_gpio */
1235
 
    stb_raw(b ++, N8X0_BT_RESET_GPIO);          /* u8 reset_gpio */
1236
 
    stb_raw(b ++, BT_UART + 1);                 /* u8 bt_uart */
1237
 
    memcpy(b, &n8x0_bd_addr, 6);                /* u8 bd_addr[6] */
1238
 
    b += 6;
1239
 
    stb_raw(b ++, 0x02);                        /* u8 bt_sysclk (38.4) */
1240
 
    w = (void *) b;
1241
 
 
1242
 
    stw_raw(w ++, OMAP_TAG_WLAN_CX3110X);       /* u16 tag */
1243
 
    stw_raw(w ++, 8);                           /* u16 len */
1244
 
    stw_raw(w ++, 0x25);                        /* u8 chip_type */
1245
 
    stw_raw(w ++, N8X0_WLAN_PWR_GPIO);          /* s16 power_gpio */
1246
 
    stw_raw(w ++, N8X0_WLAN_IRQ_GPIO);          /* s16 irq_gpio */
1247
 
    stw_raw(w ++, -1);                          /* s16 spi_cs_gpio */
1248
 
 
1249
 
    stw_raw(w ++, OMAP_TAG_MMC);                /* u16 tag */
1250
 
    stw_raw(w ++, 16);                          /* u16 len */
1251
 
    if (model == 810) {
1252
 
        stw_raw(w ++, 0x23f);                   /* unsigned flags */
1253
 
        stw_raw(w ++, -1);                      /* s16 power_pin */
1254
 
        stw_raw(w ++, -1);                      /* s16 switch_pin */
1255
 
        stw_raw(w ++, -1);                      /* s16 wp_pin */
1256
 
        stw_raw(w ++, 0x240);                   /* unsigned flags */
1257
 
        stw_raw(w ++, 0xc000);                  /* s16 power_pin */
1258
 
        stw_raw(w ++, 0x0248);                  /* s16 switch_pin */
1259
 
        stw_raw(w ++, 0xc000);                  /* s16 wp_pin */
1260
 
    } else {
1261
 
        stw_raw(w ++, 0xf);                     /* unsigned flags */
1262
 
        stw_raw(w ++, -1);                      /* s16 power_pin */
1263
 
        stw_raw(w ++, -1);                      /* s16 switch_pin */
1264
 
        stw_raw(w ++, -1);                      /* s16 wp_pin */
1265
 
        stw_raw(w ++, 0);                       /* unsigned flags */
1266
 
        stw_raw(w ++, 0);                       /* s16 power_pin */
1267
 
        stw_raw(w ++, 0);                       /* s16 switch_pin */
1268
 
        stw_raw(w ++, 0);                       /* s16 wp_pin */
1269
 
    }
1270
 
 
1271
 
    stw_raw(w ++, OMAP_TAG_TEA5761);            /* u16 tag */
1272
 
    stw_raw(w ++, 4);                           /* u16 len */
1273
 
    stw_raw(w ++, N8X0_TEA5761_CS_GPIO);        /* u16 enable_gpio */
1274
 
    w ++;
1275
 
 
1276
 
    partition = (model == 810) ? n810_part_info : n800_part_info;
1277
 
    for (; partition->name; partition ++) {
1278
 
        stw_raw(w ++, OMAP_TAG_PARTITION);      /* u16 tag */
1279
 
        stw_raw(w ++, 28);                      /* u16 len */
1280
 
        strcpy((void *) w, partition->name);    /* char name[16] */
1281
 
        l = (void *) (w + 8);
1282
 
        stl_raw(l ++, partition->size);         /* unsigned int size */
1283
 
        stl_raw(l ++, partition->offset);       /* unsigned int offset */
1284
 
        stl_raw(l ++, partition->mask);         /* unsigned int mask_flags */
1285
 
        w = (void *) l;
1286
 
    }
1287
 
 
1288
 
    stw_raw(w ++, OMAP_TAG_BOOT_REASON);        /* u16 tag */
1289
 
    stw_raw(w ++, 12);                          /* u16 len */
1290
 
#if 0
1291
 
    strcpy((void *) w, "por");                  /* char reason_str[12] */
1292
 
    strcpy((void *) w, "charger");              /* char reason_str[12] */
1293
 
    strcpy((void *) w, "32wd_to");              /* char reason_str[12] */
1294
 
    strcpy((void *) w, "sw_rst");               /* char reason_str[12] */
1295
 
    strcpy((void *) w, "mbus");                 /* char reason_str[12] */
1296
 
    strcpy((void *) w, "unknown");              /* char reason_str[12] */
1297
 
    strcpy((void *) w, "swdg_to");              /* char reason_str[12] */
1298
 
    strcpy((void *) w, "sec_vio");              /* char reason_str[12] */
1299
 
    strcpy((void *) w, "pwr_key");              /* char reason_str[12] */
1300
 
    strcpy((void *) w, "rtc_alarm");            /* char reason_str[12] */
1301
 
#else
1302
 
    strcpy((void *) w, "pwr_key");              /* char reason_str[12] */
1303
 
#endif
1304
 
    w += 6;
1305
 
 
1306
 
    tag = (model == 810) ? "RX-44" : "RX-34";
1307
 
    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1308
 
    stw_raw(w ++, 24);                          /* u16 len */
1309
 
    strcpy((void *) w, "product");              /* char component[12] */
1310
 
    w += 6;
1311
 
    strcpy((void *) w, tag);                    /* char version[12] */
1312
 
    w += 6;
1313
 
 
1314
 
    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1315
 
    stw_raw(w ++, 24);                          /* u16 len */
1316
 
    strcpy((void *) w, "hw-build");             /* char component[12] */
1317
 
    w += 6;
1318
 
    strcpy((void *) w, "QEMU ");
1319
 
    pstrcat((void *) w, 12, qemu_get_version()); /* char version[12] */
1320
 
    w += 6;
1321
 
 
1322
 
    tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
1323
 
    stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
1324
 
    stw_raw(w ++, 24);                          /* u16 len */
1325
 
    strcpy((void *) w, "nolo");                 /* char component[12] */
1326
 
    w += 6;
1327
 
    strcpy((void *) w, tag);                    /* char version[12] */
1328
 
    w += 6;
1329
 
 
1330
 
    return (void *) w - p;
1331
 
}
1332
 
 
1333
 
static int n800_atag_setup(const struct arm_boot_info *info, void *p)
1334
 
{
1335
 
    return n8x0_atag_setup(p, 800);
1336
 
}
1337
 
 
1338
 
static int n810_atag_setup(const struct arm_boot_info *info, void *p)
1339
 
{
1340
 
    return n8x0_atag_setup(p, 810);
1341
 
}
1342
 
 
1343
 
static void n8x0_init(QEMUMachineInitArgs *args,
1344
 
                      struct arm_boot_info *binfo, int model)
1345
 
{
1346
 
    MemoryRegion *sysmem = get_system_memory();
1347
 
    struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));
1348
 
    int sdram_size = binfo->ram_size;
1349
 
 
1350
 
    s->mpu = omap2420_mpu_init(sysmem, sdram_size, args->cpu_model);
1351
 
 
1352
 
    /* Setup peripherals
1353
 
     *
1354
 
     * Believed external peripherals layout in the N810:
1355
 
     * (spi bus 1)
1356
 
     *   tsc2005
1357
 
     *   lcd_mipid
1358
 
     * (spi bus 2)
1359
 
     *   Conexant cx3110x (WLAN)
1360
 
     *   optional: pc2400m (WiMAX)
1361
 
     * (i2c bus 0)
1362
 
     *   TLV320AIC33 (audio codec)
1363
 
     *   TCM825x (camera by Toshiba)
1364
 
     *   lp5521 (clever LEDs)
1365
 
     *   tsl2563 (light sensor, hwmon, model 7, rev. 0)
1366
 
     *   lm8323 (keypad, manf 00, rev 04)
1367
 
     * (i2c bus 1)
1368
 
     *   tmp105 (temperature sensor, hwmon)
1369
 
     *   menelaus (pm)
1370
 
     * (somewhere on i2c - maybe N800-only)
1371
 
     *   tea5761 (FM tuner)
1372
 
     * (serial 0)
1373
 
     *   GPS
1374
 
     * (some serial port)
1375
 
     *   csr41814 (Bluetooth)
1376
 
     */
1377
 
    n8x0_gpio_setup(s);
1378
 
    n8x0_nand_setup(s);
1379
 
    n8x0_i2c_setup(s);
1380
 
    if (model == 800)
1381
 
        n800_tsc_kbd_setup(s);
1382
 
    else if (model == 810) {
1383
 
        n810_tsc_setup(s);
1384
 
        n810_kbd_setup(s);
1385
 
    }
1386
 
    n8x0_spi_setup(s);
1387
 
    n8x0_dss_setup(s);
1388
 
    n8x0_cbus_setup(s);
1389
 
    n8x0_uart_setup(s);
1390
 
    if (usb_enabled(false)) {
1391
 
        n8x0_usb_setup(s);
1392
 
    }
1393
 
 
1394
 
    if (args->kernel_filename) {
1395
 
        /* Or at the linux loader.  */
1396
 
        binfo->kernel_filename = args->kernel_filename;
1397
 
        binfo->kernel_cmdline = args->kernel_cmdline;
1398
 
        binfo->initrd_filename = args->initrd_filename;
1399
 
        arm_load_kernel(s->mpu->cpu, binfo);
1400
 
 
1401
 
        qemu_register_reset(n8x0_boot_init, s);
1402
 
    }
1403
 
 
1404
 
    if (option_rom[0].name &&
1405
 
        (args->boot_order[0] == 'n' || !args->kernel_filename)) {
1406
 
        uint8_t nolo_tags[0x10000];
1407
 
        /* No, wait, better start at the ROM.  */
1408
 
        s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
1409
 
 
1410
 
        /* This is intended for loading the `secondary.bin' program from
1411
 
         * Nokia images (the NOLO bootloader).  The entry point seems
1412
 
         * to be at OMAP2_Q2_BASE + 0x400000.
1413
 
         *
1414
 
         * The `2nd.bin' files contain some kind of earlier boot code and
1415
 
         * for them the entry point needs to be set to OMAP2_SRAM_BASE.
1416
 
         *
1417
 
         * The code above is for loading the `zImage' file from Nokia
1418
 
         * images.  */
1419
 
        load_image_targphys(option_rom[0].name,
1420
 
                            OMAP2_Q2_BASE + 0x400000,
1421
 
                            sdram_size - 0x400000);
1422
 
 
1423
 
        n800_setup_nolo_tags(nolo_tags);
1424
 
        cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
1425
 
    }
1426
 
}
1427
 
 
1428
 
static struct arm_boot_info n800_binfo = {
1429
 
    .loader_start = OMAP2_Q2_BASE,
1430
 
    /* Actually two chips of 0x4000000 bytes each */
1431
 
    .ram_size = 0x08000000,
1432
 
    .board_id = 0x4f7,
1433
 
    .atag_board = n800_atag_setup,
1434
 
};
1435
 
 
1436
 
static struct arm_boot_info n810_binfo = {
1437
 
    .loader_start = OMAP2_Q2_BASE,
1438
 
    /* Actually two chips of 0x4000000 bytes each */
1439
 
    .ram_size = 0x08000000,
1440
 
    /* 0x60c and 0x6bf (WiMAX Edition) have been assigned but are not
1441
 
     * used by some older versions of the bootloader and 5555 is used
1442
 
     * instead (including versions that shipped with many devices).  */
1443
 
    .board_id = 0x60c,
1444
 
    .atag_board = n810_atag_setup,
1445
 
};
1446
 
 
1447
 
static void n800_init(QEMUMachineInitArgs *args)
1448
 
{
1449
 
    return n8x0_init(args, &n800_binfo, 800);
1450
 
}
1451
 
 
1452
 
static void n810_init(QEMUMachineInitArgs *args)
1453
 
{
1454
 
    return n8x0_init(args, &n810_binfo, 810);
1455
 
}
1456
 
 
1457
 
static QEMUMachine n800_machine = {
1458
 
    .name = "n800",
1459
 
    .desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
1460
 
    .init = n800_init,
1461
 
    .default_boot_order = "",
1462
 
};
1463
 
 
1464
 
static QEMUMachine n810_machine = {
1465
 
    .name = "n810",
1466
 
    .desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
1467
 
    .init = n810_init,
1468
 
    .default_boot_order = "",
1469
 
};
1470
 
 
1471
 
static void nseries_register_types(void)
1472
 
{
1473
 
    type_register_static(&mipid_info);
1474
 
}
1475
 
 
1476
 
static void nseries_machine_init(void)
1477
 
{
1478
 
    qemu_register_machine(&n800_machine);
1479
 
    qemu_register_machine(&n810_machine);
1480
 
}
1481
 
 
1482
 
type_init(nseries_register_types);
1483
 
machine_init(nseries_machine_init);