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

« back to all changes in this revision

Viewing changes to .pc/ubuntu/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);