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