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