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