2
* Nokia N-series internet tablets.
4
* Copyright (C) 2007 Nokia Corporation
5
* Written by Andrzej Zaborowski <andrew@openedhand.com>
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.
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.
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/>.
21
#include "qemu-common.h"
22
#include "sysemu/sysemu.h"
23
#include "hw/arm/omap.h"
24
#include "hw/arm/arm.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"
34
#include "hw/loader.h"
35
#include "sysemu/blockdev.h"
36
#include "hw/sysbus.h"
37
#include "exec/address-spaces.h"
42
#define TRACE_MIPID(fmt, ...) \
43
fprintf(stderr, "%s@%d: " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
45
#define TRACE_MIPID(...)
48
/* Nokia N8x0 support */
50
struct omap_mpu_state_s *mpu;
52
struct rfbi_chip_s blizzard;
66
#define N8X0_TUSB_ENABLE_GPIO 0
67
#define N800_MMC2_WP_GPIO 8
68
#define N800_UNKNOWN_GPIO0 9 /* out */
69
#define N810_MMC2_VIOSD_GPIO 9
70
#define N810_HEADSET_AMP_GPIO 10
71
#define N800_CAM_TURN_GPIO 12
72
#define N810_GPS_RESET_GPIO 12
73
#define N800_BLIZZARD_POWERDOWN_GPIO 15
74
#define N800_MMC1_WP_GPIO 23
75
#define N810_MMC2_VSD_GPIO 23
76
#define N8X0_ONENAND_GPIO 26
77
#define N810_BLIZZARD_RESET_GPIO 30
78
#define N800_UNKNOWN_GPIO2 53 /* out */
79
#define N8X0_TUSB_INT_GPIO 58
80
#define N8X0_BT_WKUP_GPIO 61
81
#define N8X0_STI_GPIO 62
82
#define N8X0_CBUS_SEL_GPIO 64
83
#define N8X0_CBUS_DAT_GPIO 65
84
#define N8X0_CBUS_CLK_GPIO 66
85
#define N8X0_WLAN_IRQ_GPIO 87
86
#define N8X0_BT_RESET_GPIO 92
87
#define N8X0_TEA5761_CS_GPIO 93
88
#define N800_UNKNOWN_GPIO 94
89
#define N810_TSC_RESET_GPIO 94
90
#define N800_CAM_ACT_GPIO 95
91
#define N810_GPS_WAKEUP_GPIO 95
92
#define N8X0_MMC_CS_GPIO 96
93
#define N8X0_WLAN_PWR_GPIO 97
94
#define N8X0_BT_HOST_WKUP_GPIO 98
95
#define N810_SPEAKER_AMP_GPIO 101
96
#define N810_KB_LOCK_GPIO 102
97
#define N800_TSC_TS_GPIO 103
98
#define N810_TSC_TS_GPIO 106
99
#define N8X0_HEADPHONE_GPIO 107
100
#define N8X0_RETU_GPIO 108
101
#define N800_TSC_KP_IRQ_GPIO 109
102
#define N810_KEYBOARD_GPIO 109
103
#define N800_BAT_COVER_GPIO 110
104
#define N810_SLIDE_GPIO 110
105
#define N8X0_TAHVO_GPIO 111
106
#define N800_UNKNOWN_GPIO4 112 /* out */
107
#define N810_SLEEPX_LED_GPIO 112
108
#define N800_TSC_RESET_GPIO 118 /* ? */
109
#define N810_AIC33_RESET_GPIO 118
110
#define N800_TSC_UNKNOWN_GPIO 119 /* out */
111
#define N8X0_TMP105_GPIO 125
115
#define XLDR_LL_UART 1
117
/* Addresses on the I2C bus 0 */
118
#define N810_TLV320AIC33_ADDR 0x18 /* Audio CODEC */
119
#define N8X0_TCM825x_ADDR 0x29 /* Camera */
120
#define N810_LP5521_ADDR 0x32 /* LEDs */
121
#define N810_TSL2563_ADDR 0x3d /* Light sensor */
122
#define N810_LM8323_ADDR 0x45 /* Keyboard */
123
/* Addresses on the I2C bus 1 */
124
#define N8X0_TMP105_ADDR 0x48 /* Temperature sensor */
125
#define N8X0_MENELAUS_ADDR 0x72 /* Power management */
127
/* Chipselects on GPMC NOR interface */
128
#define N8X0_ONENAND_CS 0
129
#define N8X0_USB_ASYNC_CS 1
130
#define N8X0_USB_SYNC_CS 4
132
#define N8X0_BD_ADDR 0x00, 0x1a, 0x89, 0x9e, 0x3e, 0x81
134
static void n800_mmc_cs_cb(void *opaque, int line, int level)
136
/* TODO: this seems to actually be connected to the menelaus, to
137
* which also both MMC slots connect. */
138
omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
141
static void n8x0_gpio_setup(struct n800_s *s)
143
qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->mpu->mmc, 1);
144
qdev_connect_gpio_out(s->mpu->gpio, N8X0_MMC_CS_GPIO, mmc_cs[0]);
146
qemu_irq_lower(qdev_get_gpio_in(s->mpu->gpio, N800_BAT_COVER_GPIO));
149
#define MAEMO_CAL_HEADER(...) \
150
'C', 'o', 'n', 'F', 0x02, 0x00, 0x04, 0x00, \
152
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154
static const uint8_t n8x0_cal_wlan_mac[] = {
155
MAEMO_CAL_HEADER('w', 'l', 'a', 'n', '-', 'm', 'a', 'c')
156
0x1c, 0x00, 0x00, 0x00, 0x47, 0xd6, 0x69, 0xb3,
157
0x30, 0x08, 0xa0, 0x83, 0x00, 0x00, 0x00, 0x00,
158
0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
159
0x89, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
160
0x5d, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
163
static const uint8_t n8x0_cal_bt_id[] = {
164
MAEMO_CAL_HEADER('b', 't', '-', 'i', 'd', 0, 0, 0)
165
0x0a, 0x00, 0x00, 0x00, 0xa3, 0x4b, 0xf6, 0x96,
166
0xa8, 0xeb, 0xb2, 0x41, 0x00, 0x00, 0x00, 0x00,
170
static void n8x0_nand_setup(struct n800_s *s)
175
s->nand = qdev_create(NULL, "onenand");
176
qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);
177
/* Either 0x40 or 0x48 are OK for the device ID */
178
qdev_prop_set_uint16(s->nand, "device_id", 0x48);
179
qdev_prop_set_uint16(s->nand, "version_id", 0);
180
qdev_prop_set_int32(s->nand, "shift", 1);
181
dinfo = drive_get(IF_MTD, 0, 0);
182
if (dinfo && dinfo->bdrv) {
183
qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv);
185
qdev_init_nofail(s->nand);
186
sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,
187
qdev_get_gpio_in(s->mpu->gpio, N8X0_ONENAND_GPIO));
188
omap_gpmc_attach(s->mpu->gpmc, N8X0_ONENAND_CS,
189
sysbus_mmio_get_region(SYS_BUS_DEVICE(s->nand), 0));
190
otp_region = onenand_raw_otp(s->nand);
192
memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
193
memcpy(otp_region + 0x800, n8x0_cal_bt_id, sizeof(n8x0_cal_bt_id));
194
/* XXX: in theory should also update the OOB for both pages */
197
static qemu_irq n8x0_system_powerdown;
199
static void n8x0_powerdown_req(Notifier *n, void *opaque)
201
qemu_irq_raise(n8x0_system_powerdown);
204
static Notifier n8x0_system_powerdown_notifier = {
205
.notify = n8x0_powerdown_req
208
static void n8x0_i2c_setup(struct n800_s *s)
211
qemu_irq tmp_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TMP105_GPIO);
212
i2c_bus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
214
/* Attach a menelaus PM chip */
215
dev = i2c_create_slave(i2c, "twl92230", N8X0_MENELAUS_ADDR);
216
qdev_connect_gpio_out(dev, 3,
217
qdev_get_gpio_in(s->mpu->ih[0],
218
OMAP_INT_24XX_SYS_NIRQ));
220
n8x0_system_powerdown = qdev_get_gpio_in(dev, 3);
221
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
223
/* Attach a TMP105 PM chip (A0 wired to ground) */
224
dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
225
qdev_connect_gpio_out(dev, 0, tmp_irq);
228
/* Touchscreen and keypad controller */
229
static MouseTransformInfo n800_pointercal = {
232
.a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
235
static MouseTransformInfo n810_pointercal = {
238
.a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
241
#define RETU_KEYCODE 61 /* F3 */
243
static void n800_key_event(void *opaque, int keycode)
245
struct n800_s *s = (struct n800_s *) opaque;
246
int code = s->keymap[keycode & 0x7f];
249
if ((keycode & 0x7f) == RETU_KEYCODE)
250
retu_key_event(s->retu, !(keycode & 0x80));
254
tsc2301_key_event(s->tsc, code, !(keycode & 0x80));
257
static const int n800_keys[16] = {
271
64, /* FullScreen (F6) */
276
static void n800_tsc_kbd_setup(struct n800_s *s)
280
/* XXX: are the three pins inverted inside the chip between the
281
* tsc and the cpu (N4111)? */
282
s->tsc = spi_create_device(omap_mcspi_bus(s->mpu->mcspi, 0), "tsc2301", 0);
284
qdev_connect_gpio_out(s->tsc, 1, qdev_get_gpio_in(s->mpu->gpio,
285
N800_TSC_KP_IRQ_GPIO));
286
qdev_connect_gpio_out(s->tsc, 2, qdev_get_gpio_in(s->mpu->gpio,
289
for (i = 0; i < 0x80; i ++)
291
for (i = 0; i < 0x10; i ++)
292
if (n800_keys[i] >= 0)
293
s->keymap[n800_keys[i]] = i;
295
qemu_add_kbd_event_handler(n800_key_event, s);
297
tsc2301_set_transform(s->tsc, &n800_pointercal);
300
static void n810_tsc_setup(struct n800_s *s)
302
s->tsc = spi_create_device(omap_mcspi_bus(s->mpu->mcspi, 0), "tsc2005", 0);
303
qdev_connect_gpio_out(s->tsc, 0, qdev_get_gpio_in(s->mpu->gpio,
305
tsc2005_set_transform(s->tsc, &n810_pointercal, 400, 4000);
308
/* N810 Keyboard controller */
309
static void n810_key_event(void *opaque, int keycode)
311
struct n800_s *s = (struct n800_s *) opaque;
312
int code = s->keymap[keycode & 0x7f];
315
if ((keycode & 0x7f) == RETU_KEYCODE)
316
retu_key_event(s->retu, !(keycode & 0x80));
320
lm832x_key_event(s->kbd, code, !(keycode & 0x80));
325
static int n810_keys[0x80] = {
330
[0x05] = 14, /* Backspace */
340
[0x12] = 62, /* Menu (F4) */
342
[0x14] = 40, /* ' (Apostrophe) */
349
[0x1c] = 42, /* Shift (Left shift) */
350
[0x1f] = 65, /* Zoom+ (F7) */
353
[0x22] = 39, /* ; (Semicolon) */
354
[0x23] = 12, /* - (Minus) */
355
[0x24] = 13, /* = (Equal) */
356
[0x2b] = 56, /* Fn (Left Alt) */
358
[0x2f] = 66, /* Zoom- (F8) */
361
[0x32] = 29 | M, /* Right Ctrl */
362
[0x34] = 57, /* Space */
363
[0x35] = 51, /* , (Comma) */
364
[0x37] = 72 | M, /* Up */
365
[0x3c] = 82 | M, /* Compose (Insert) */
366
[0x3f] = 64, /* FullScreen (F6) */
369
[0x44] = 52, /* . (Dot) */
370
[0x46] = 77 | M, /* Right */
371
[0x4f] = 63, /* Home (F5) */
373
[0x53] = 80 | M, /* Down */
374
[0x55] = 28, /* Enter */
375
[0x5f] = 1, /* Cycle (ESC) */
378
[0x64] = 75 | M, /* Left */
382
[0x75] = 28 | M, /* KP Enter (KP Enter) */
384
[0x75] = 15, /* KP Enter (Tab) */
390
static void n810_kbd_setup(struct n800_s *s)
392
qemu_irq kbd_irq = qdev_get_gpio_in(s->mpu->gpio, N810_KEYBOARD_GPIO);
395
for (i = 0; i < 0x80; i ++)
397
for (i = 0; i < 0x80; i ++)
398
if (n810_keys[i] > 0)
399
s->keymap[n810_keys[i]] = i;
401
qemu_add_kbd_event_handler(n810_key_event, s);
403
/* Attach the LM8322 keyboard to the I2C bus,
404
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
405
s->kbd = i2c_create_slave(omap_i2c_bus(s->mpu->i2c[0]),
406
"lm8323", N810_LM8323_ADDR);
407
qdev_connect_gpio_out(s->kbd, 0, kbd_irq);
410
/* LCD MIPI DBI-C controller (URAL) */
437
static void mipid_reset(DeviceState *qdev)
439
struct mipid_s *s = FROM_SPI_DEVICE(struct mipid_s,
440
SPI_DEVICE_FROM_QDEV(qdev));
448
(1 << 7) | /* Register loading OK. */
449
(1 << 5) | /* The chip is attached. */
450
(1 << 4); /* Display glass still in one piece. */
460
static uint32_t mipid_txrx(SPIDevice *spidev, uint32_t cmd, int len)
462
struct mipid_s *s = FROM_SPI_DEVICE(struct mipid_s, spidev);
465
if (s->n900 && len == 10) {
471
hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
473
if (s->p >= ARRAY_SIZE(s->resp))
476
ret = s->resp[s->p ++];
478
s->param[s->pm] = cmd;
487
case 0x01: /* SWRESET */
488
TRACE_MIPID("SWRESET");
489
mipid_reset(&s->spi.qdev);
492
case 0x02: /* BSTROFF */
493
TRACE_MIPID("BSTROFF");
496
case 0x03: /* BSTRON */
497
TRACE_MIPID("BSTRON");
501
case 0x04: /* RDDID */
503
s->resp[0] = (s->id >> 16) & 0xff;
504
s->resp[1] = (s->id >> 8) & 0xff;
505
s->resp[2] = (s->id >> 0) & 0xff;
506
TRACE_MIPID("RDDID 0x%02x 0x%02x 0x%02x",
507
s->resp[0], s->resp[1], s->resp[2]);
510
case 0x06: /* RD_RED */
511
case 0x07: /* RD_GREEN */
512
/* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so
513
* for the bootloader one needs to change this. */
514
case 0x08: /* RD_BLUE */
515
TRACE_MIPID("RD_RED/GREEN_BLUE 0x01");
517
/* TODO: return first pixel components */
521
case 0x09: /* RDDST */
523
s->resp[0] = s->booster << 7;
524
s->resp[1] = (5 << 4) | (s->partial << 2) |
525
(s->sleep << 1) | s->normal;
526
s->resp[2] = (s->vscr << 7) | (s->invert << 5) |
527
(s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);
528
s->resp[3] = s->gamma << 6;
529
TRACE_MIPID("RDDST 0x%02x 0x%02x 0x%02x 0x%02x",
530
s->resp[0], s->resp[1], s->resp[2], s->resp[3]);
533
case 0x0a: /* RDDPM */
535
s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |
536
(s->partial << 5) | (s->sleep << 6) | (s->booster << 7);
537
TRACE_MIPID("RDDPM 0x%02x", s->resp[0]);
539
case 0x0b: /* RDDMADCTR */
542
TRACE_MIPID("RDDMACTR 0x%02x", s->resp[0]);
544
case 0x0c: /* RDDCOLMOD */
546
s->resp[0] = 5; /* 65K colours */
547
TRACE_MIPID("RDDCOLMOD 0x%02x", s->resp[0]);
549
case 0x0d: /* RDDIM */
551
s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;
552
TRACE_MIPID("RDDIM 0x%02x", s->resp[0]);
554
case 0x0e: /* RDDSM */
556
s->resp[0] = s->te << 7;
557
TRACE_MIPID("RDDSM 0x%02x", s->resp[0]);
559
case 0x0f: /* RDDSDR */
561
s->resp[0] = s->selfcheck;
562
TRACE_MIPID("RDDSDR 0x%02x", s->resp[0]);
565
case 0x10: /* SLPIN */
566
TRACE_MIPID("SLPIN");
569
case 0x11: /* SLPOUT */
570
TRACE_MIPID("SLPOUT");
572
s->selfcheck ^= 1 << 6; /* POFF self-diagnosis Ok */
575
case 0x12: /* PTLON */
576
TRACE_MIPID("PTLON");
581
case 0x13: /* NORON */
582
TRACE_MIPID("NORON");
588
case 0x20: /* INVOFF */
589
TRACE_MIPID("INVOFF");
592
case 0x21: /* INVON */
593
TRACE_MIPID("INVON");
597
case 0x22: /* APOFF */
598
case 0x23: /* APON */
599
TRACE_MIPID("APON/OFF");
602
case 0x25: /* WRCNTR */
603
TRACE_MIPID("WRCNTR");
608
case 0x26: /* GAMSET */
610
s->gamma = ffs(s->param[0] & 0xf) - 1;
611
TRACE_MIPID("GAMSET 0x%02x", s->gamma);
612
} else if (s->pm < 0) {
617
case 0x28: /* DISPOFF */
618
TRACE_MIPID("DISPOFF");
621
case 0x29: /* DISPON */
622
TRACE_MIPID("DISPON");
626
case 0x2a: /* CASET */
627
case 0x2b: /* RASET */
628
case 0x2c: /* RAMWR */
629
case 0x2d: /* RGBSET */
630
case 0x2e: /* RAMRD */
631
case 0x30: /* PTLAR */
632
case 0x33: /* SCRLAR */
635
case 0x34: /* TEOFF */
636
TRACE_MIPID("TEOFF");
639
case 0x35: /* TEON */
642
TRACE_MIPID("TEON 0x%02x", s->param[0] & 0xff);
643
} else if (s->pm < 0) {
648
case 0x36: /* MADCTR */
649
TRACE_MIPID("MADCTR");
652
case 0x37: /* VSCSAD */
653
TRACE_MIPID("VSCSAD");
659
case 0x38: /* IDMOFF */
660
case 0x39: /* IDMON */
661
TRACE_MIPID("IDMON/OFF");
663
case 0x3a: /* COLMOD */
665
TRACE_MIPID("COLMOD 0x%02x", s->param[0] & 0xff);
666
} else if (s->pm < 0) {
671
case 0x51: /* WRITE_BRIGHTNESS */
674
s->brightness = s->param[0] & 0xff;
675
TRACE_MIPID("WRITE_BRIGHTNESS 0x%02x", s->brightness);
676
} else if (s->pm < 0) {
683
case 0x52: /* READ_BRIGHTNESS */
686
s->resp[0] = s->brightness;
687
TRACE_MIPID("READ_BRIGHTNESS 0x%02x", s->resp[0]);
692
case 0x53: /* WRITE_CTRL */
695
s->ctrl = s->param[0] & 0xff;
696
TRACE_MIPID("WRITE_CTRL 0x%02x", s->ctrl);
697
} else if (s->pm < 0) {
704
case 0x54: /* READ_CTRL */
707
s->resp[0] = s->ctrl;
708
TRACE_MIPID("READ_CTRL 0x%02x", s->resp[0]);
713
case 0x55: /* WRITE_CABC */
716
s->cabc = s->param[0] & 0xff;
717
TRACE_MIPID("WRITE_CABC 0x%02x", s->cabc);
718
} else if (s->pm < 0) {
725
case 0x56: /* READ_CABC */
728
s->resp[0] = s->cabc;
729
TRACE_MIPID("READ_CABC 0x%02x", s->resp[0]);
735
case 0xb0: /* CLKINT / DISCTL */
736
case 0xb1: /* CLKEXT */
738
TRACE_MIPID("CLKINT/EXT");
739
} else if (s->pm < 0) {
744
case 0xb4: /* FRMSEL */
745
TRACE_MIPID("FRMSEL");
748
case 0xb5: /* FRM8SEL */
749
case 0xb6: /* TMPRNG / INIESC */
750
case 0xb7: /* TMPHIS / NOP2 */
751
case 0xb8: /* TMPREAD / MADCTL */
752
case 0xba: /* DISTCTR */
753
case 0xbb: /* EPVOL */
756
case 0xbd: /* Unknown */
760
TRACE_MIPID("??? 0x%02x 0x%02x", s->resp[0], s->resp[1]);
763
case 0xc2: /* IFMOD */
765
TRACE_MIPID("IFMOD");
766
} else if (s->pm < 0) {
767
s->pm = (s->n900) ? 3 : 2;
771
case 0xc6: /* PWRCTL */
772
case 0xc7: /* PPWRCTL */
773
case 0xd0: /* EPWROUT */
774
case 0xd1: /* EPWRIN */
775
case 0xd4: /* RDEV */
776
case 0xd5: /* RDRR */
779
case 0xda: /* RDID1 */
781
s->resp[0] = (s->id >> 16) & 0xff;
782
TRACE_MIPID("RDID1 0x%02x", s->resp[0]);
784
case 0xdb: /* RDID2 */
786
s->resp[0] = (s->id >> 8) & 0xff;
787
TRACE_MIPID("RDID2 0x%02x", s->resp[0]);
789
case 0xdc: /* RDID3 */
791
s->resp[0] = (s->id >> 0) & 0xff;
792
TRACE_MIPID("RDID3 0x%02x", s->resp[0]);
797
qemu_log_mask(LOG_GUEST_ERROR,
798
"%s: unknown command %02x\n", __func__, s->cmd);
805
static int mipid_init(SPIDevice *spidev)
810
static Property mipid_properties[] = {
811
DEFINE_PROP_UINT32("id", struct mipid_s, id, 0),
812
DEFINE_PROP_UINT8("n900", struct mipid_s, n900, 0),
813
DEFINE_PROP_END_OF_LIST()
816
static void mipid_class_init(ObjectClass *klass, void *data)
818
DeviceClass *dc = DEVICE_CLASS(klass);
819
SPIDeviceClass *k = SPI_DEVICE_CLASS(klass);
821
k->init = mipid_init;
822
k->txrx = mipid_txrx;
823
dc->reset = mipid_reset;
824
dc->props = mipid_properties;
827
static TypeInfo mipid_info = {
829
.parent = TYPE_SPI_DEVICE,
830
.instance_size = sizeof(struct mipid_s),
831
.class_init = mipid_class_init,
834
static void n8x0_spi_setup(struct n800_s *s)
836
s->mipid = spi_create_device_noinit(omap_mcspi_bus(s->mpu->mcspi, 0),
838
qdev_prop_set_uint32(s->mipid, "id", 0x838f03);
839
qdev_init_nofail(s->mipid);
842
/* This task is normally performed by the bootloader. If we're loading
843
* a kernel directly, we need to enable the Blizzard ourselves. */
844
static void n800_dss_init(struct rfbi_chip_s *chip)
848
chip->write(chip->opaque, 0, 0x2a); /* LCD Width register */
849
chip->write(chip->opaque, 1, 0x64);
850
chip->write(chip->opaque, 0, 0x2c); /* LCD HNDP register */
851
chip->write(chip->opaque, 1, 0x1e);
852
chip->write(chip->opaque, 0, 0x2e); /* LCD Height 0 register */
853
chip->write(chip->opaque, 1, 0xe0);
854
chip->write(chip->opaque, 0, 0x30); /* LCD Height 1 register */
855
chip->write(chip->opaque, 1, 0x01);
856
chip->write(chip->opaque, 0, 0x32); /* LCD VNDP register */
857
chip->write(chip->opaque, 1, 0x06);
858
chip->write(chip->opaque, 0, 0x68); /* Display Mode register */
859
chip->write(chip->opaque, 1, 1); /* Enable bit */
861
chip->write(chip->opaque, 0, 0x6c);
862
chip->write(chip->opaque, 1, 0x00); /* Input X Start Position */
863
chip->write(chip->opaque, 1, 0x00); /* Input X Start Position */
864
chip->write(chip->opaque, 1, 0x00); /* Input Y Start Position */
865
chip->write(chip->opaque, 1, 0x00); /* Input Y Start Position */
866
chip->write(chip->opaque, 1, 0x1f); /* Input X End Position */
867
chip->write(chip->opaque, 1, 0x03); /* Input X End Position */
868
chip->write(chip->opaque, 1, 0xdf); /* Input Y End Position */
869
chip->write(chip->opaque, 1, 0x01); /* Input Y End Position */
870
chip->write(chip->opaque, 1, 0x00); /* Output X Start Position */
871
chip->write(chip->opaque, 1, 0x00); /* Output X Start Position */
872
chip->write(chip->opaque, 1, 0x00); /* Output Y Start Position */
873
chip->write(chip->opaque, 1, 0x00); /* Output Y Start Position */
874
chip->write(chip->opaque, 1, 0x1f); /* Output X End Position */
875
chip->write(chip->opaque, 1, 0x03); /* Output X End Position */
876
chip->write(chip->opaque, 1, 0xdf); /* Output Y End Position */
877
chip->write(chip->opaque, 1, 0x01); /* Output Y End Position */
878
chip->write(chip->opaque, 1, 0x01); /* Input Data Format */
879
chip->write(chip->opaque, 1, 0x01); /* Data Source Select */
881
fb_blank = memset(g_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
882
/* Display Memory Data Port */
883
chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
887
static void n8x0_dss_setup(struct n800_s *s)
889
s->blizzard.opaque = s1d13745_init(NULL);
890
s->blizzard.block = s1d13745_write_block;
891
s->blizzard.write = s1d13745_write;
892
s->blizzard.read = s1d13745_read;
894
omap_rfbi_attach(s->mpu->dss, 0, &s->blizzard);
897
static void n8x0_cbus_setup(struct n800_s *s)
899
qemu_irq dat_out = qdev_get_gpio_in(s->mpu->gpio, N8X0_CBUS_DAT_GPIO);
900
qemu_irq retu_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_RETU_GPIO);
901
qemu_irq tahvo_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TAHVO_GPIO);
903
CBus *cbus = cbus_init(dat_out);
905
qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_CLK_GPIO, cbus->clk);
906
qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_DAT_GPIO, cbus->dat);
907
qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_SEL_GPIO, cbus->sel);
909
cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
910
cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
913
static void n8x0_uart_setup(struct n800_s *s)
915
CharDriverState *radio = uart_hci_init(
916
qdev_get_gpio_in(s->mpu->gpio, N8X0_BT_HOST_WKUP_GPIO));
918
qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_RESET_GPIO,
919
csrhci_pins_get(radio)[csrhci_pin_reset]);
920
qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_WKUP_GPIO,
921
csrhci_pins_get(radio)[csrhci_pin_wakeup]);
923
omap_uart_attach(s->mpu->uart[BT_UART], radio, "bt-uart");
926
static void n8x0_usb_setup(struct n800_s *s)
929
s->usb = qdev_create(NULL, "tusb6010");
930
dev = SYS_BUS_DEVICE(s->usb);
931
qdev_init_nofail(s->usb);
932
sysbus_connect_irq(dev, 0,
933
qdev_get_gpio_in(s->mpu->gpio, N8X0_TUSB_INT_GPIO));
934
/* Using the NOR interface */
935
omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_ASYNC_CS,
936
sysbus_mmio_get_region(dev, 0));
937
omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_SYNC_CS,
938
sysbus_mmio_get_region(dev, 1));
939
qdev_connect_gpio_out(s->mpu->gpio, N8X0_TUSB_ENABLE_GPIO,
940
qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */
943
/* Setup done before the main bootloader starts by some early setup code
944
* - used when we want to run the main bootloader in emulation. This
945
* isn't documented. */
946
static uint32_t n800_pinout[104] = {
947
0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
948
0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
949
0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
950
0x080800bc, 0x00cc0808, 0x08081818, 0x18180128,
951
0x01241800, 0x18181818, 0x000000f0, 0x01300000,
952
0x00001b0b, 0x1b0f0138, 0x00e0181b, 0x1b031b0b,
953
0x180f0078, 0x00740018, 0x0f0f0f1a, 0x00000080,
954
0x007c0000, 0x00000000, 0x00000088, 0x00840000,
955
0x00000000, 0x00000094, 0x00980300, 0x0f180003,
956
0x0000008c, 0x00900f0f, 0x0f0f1b00, 0x0f00009c,
957
0x01140000, 0x1b1b0f18, 0x0818013c, 0x01400008,
958
0x00001818, 0x000b0110, 0x010c1800, 0x0b030b0f,
959
0x181800f4, 0x00f81818, 0x00000018, 0x000000fc,
960
0x00401808, 0x00000000, 0x0f1b0030, 0x003c0008,
961
0x00000000, 0x00000038, 0x00340000, 0x00000000,
962
0x1a080070, 0x00641a1a, 0x08080808, 0x08080060,
963
0x005c0808, 0x08080808, 0x08080058, 0x00540808,
964
0x08080808, 0x0808006c, 0x00680808, 0x08080808,
965
0x000000a8, 0x00b00000, 0x08080808, 0x000000a0,
966
0x00a40000, 0x00000000, 0x08ff0050, 0x004c0808,
967
0xffffffff, 0xffff0048, 0x0044ffff, 0xffffffff,
968
0x000000ac, 0x01040800, 0x08080b0f, 0x18180100,
969
0x01081818, 0x0b0b1808, 0x1a0300e4, 0x012c0b1a,
970
0x02020018, 0x0b000134, 0x011c0800, 0x0b1b1b00,
971
0x0f0000c8, 0x00ec181b, 0x000f0f02, 0x00180118,
972
0x01200000, 0x0f0b1b1b, 0x0f0200e8, 0x0000020b,
975
static void n800_setup_nolo_tags(void *sram_base)
978
uint32_t *p = sram_base + 0x8000;
979
uint32_t *v = sram_base + 0xa000;
981
memset(p, 0, 0x3000);
983
strcpy((void *) (p + 0), "QEMU N800");
985
strcpy((void *) (p + 8), "F5");
987
stl_raw(p + 10, 0x04f70000);
988
strcpy((void *) (p + 9), "RX-34");
990
/* RAM size in MB? */
991
stl_raw(p + 12, 0x80);
993
/* Pointer to the list of tags */
994
stl_raw(p + 13, OMAP2_SRAM_BASE + 0x9000);
996
/* The NOLO tags start here */
997
p = sram_base + 0x9000;
998
#define ADD_TAG(tag, len) \
999
stw_raw((uint16_t *) p + 0, tag); \
1000
stw_raw((uint16_t *) p + 1, len); p ++; \
1001
stl_raw(p ++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
1003
/* OMAP STI console? Pin out settings? */
1004
ADD_TAG(0x6e01, 414);
1005
for (i = 0; i < ARRAY_SIZE(n800_pinout); i ++)
1006
stl_raw(v ++, n800_pinout[i]);
1008
/* Kernel memsize? */
1012
/* NOLO serial console */
1014
stl_raw(v ++, XLDR_LL_UART); /* UART number (1 - 3) */
1017
/* CBUS settings (Retu/AVilma) */
1019
stw_raw((uint16_t *) v + 0, 65); /* CBUS GPIO0 */
1020
stw_raw((uint16_t *) v + 1, 66); /* CBUS GPIO1 */
1021
stw_raw((uint16_t *) v + 2, 64); /* CBUS GPIO2 */
1025
/* Nokia ASIC BB5 (Retu/Tahvo) */
1027
stw_raw((uint16_t *) v + 0, 111); /* "Retu" interrupt GPIO */
1028
stw_raw((uint16_t *) v + 1, 108); /* "Tahvo" interrupt GPIO */
1033
stw_raw((uint16_t *) v + 0, 30); /* ??? */
1034
stw_raw((uint16_t *) v + 1, 24); /* ??? */
1040
stw_raw((uint16_t *) (v ++), 15); /* ??? */
1043
/* I^2C (Menelaus) */
1045
stl_raw(v ++, 0x00720000); /* ??? */
1049
stw_raw((uint16_t *) v + 0, 94); /* ??? */
1050
stw_raw((uint16_t *) v + 1, 23); /* ??? */
1051
stw_raw((uint16_t *) v + 2, 0); /* ??? */
1054
/* OMAP gpio switch info */
1055
ADD_TAG(0x6e0c, 80);
1056
strcpy((void *) v, "bat_cover"); v += 3;
1057
stw_raw((uint16_t *) v + 0, 110); /* GPIO num ??? */
1058
stw_raw((uint16_t *) v + 1, 1); /* GPIO num ??? */
1060
strcpy((void *) v, "cam_act"); v += 3;
1061
stw_raw((uint16_t *) v + 0, 95); /* GPIO num ??? */
1062
stw_raw((uint16_t *) v + 1, 32); /* GPIO num ??? */
1064
strcpy((void *) v, "cam_turn"); v += 3;
1065
stw_raw((uint16_t *) v + 0, 12); /* GPIO num ??? */
1066
stw_raw((uint16_t *) v + 1, 33); /* GPIO num ??? */
1068
strcpy((void *) v, "headphone"); v += 3;
1069
stw_raw((uint16_t *) v + 0, 107); /* GPIO num ??? */
1070
stw_raw((uint16_t *) v + 1, 17); /* GPIO num ??? */
1074
ADD_TAG(0x6e0e, 12);
1075
stl_raw(v ++, 0x5c623d01); /* ??? */
1076
stl_raw(v ++, 0x00000201); /* ??? */
1077
stl_raw(v ++, 0x00000000); /* ??? */
1079
/* CX3110x WLAN settings */
1081
stl_raw(v ++, 0x00610025); /* ??? */
1082
stl_raw(v ++, 0xffff0057); /* ??? */
1084
/* MMC host settings */
1085
ADD_TAG(0x6e10, 12);
1086
stl_raw(v ++, 0xffff000f); /* ??? */
1087
stl_raw(v ++, 0xffffffff); /* ??? */
1088
stl_raw(v ++, 0x00000060); /* ??? */
1090
/* OneNAND chip select */
1091
ADD_TAG(0x6e11, 10);
1092
stl_raw(v ++, 0x00000401); /* ??? */
1093
stl_raw(v ++, 0x0002003a); /* ??? */
1094
stl_raw(v ++, 0x00000002); /* ??? */
1096
/* TEA5761 sensor settings */
1098
stl_raw(v ++, 93); /* GPIO num ??? */
1104
/* Kernel UART / console */
1108
/* End of the list */
1109
stl_raw(p ++, 0x00000000);
1110
stl_raw(p ++, 0x00000000);
1113
/* This task is normally performed by the bootloader. If we're loading
1114
* a kernel directly, we need to set up GPMC mappings ourselves. */
1115
static void n800_gpmc_init(struct n800_s *s)
1118
(0xf << 8) | /* MASKADDRESS */
1119
(1 << 6) | /* CSVALID */
1120
(4 << 0); /* BASEADDRESS */
1122
cpu_physical_memory_write(0x6800a078, /* GPMC_CONFIG7_0 */
1123
&config7, sizeof(config7));
1126
/* Setup sequence done by the bootloader */
1127
static void n8x0_boot_init(void *opaque)
1129
struct n800_s *s = (struct n800_s *) opaque;
1133
#define omap_writel(addr, val) \
1135
cpu_physical_memory_write(addr, &buf, sizeof(buf))
1137
omap_writel(0x48008060, 0x41); /* PRCM_CLKSRC_CTRL */
1138
omap_writel(0x48008070, 1); /* PRCM_CLKOUT_CTRL */
1139
omap_writel(0x48008078, 0); /* PRCM_CLKEMUL_CTRL */
1140
omap_writel(0x48008090, 0); /* PRCM_VOLTSETUP */
1141
omap_writel(0x48008094, 0); /* PRCM_CLKSSETUP */
1142
omap_writel(0x48008098, 0); /* PRCM_POLCTRL */
1143
omap_writel(0x48008140, 2); /* CM_CLKSEL_MPU */
1144
omap_writel(0x48008148, 0); /* CM_CLKSTCTRL_MPU */
1145
omap_writel(0x48008158, 1); /* RM_RSTST_MPU */
1146
omap_writel(0x480081c8, 0x15); /* PM_WKDEP_MPU */
1147
omap_writel(0x480081d4, 0x1d4); /* PM_EVGENCTRL_MPU */
1148
omap_writel(0x480081d8, 0); /* PM_EVEGENONTIM_MPU */
1149
omap_writel(0x480081dc, 0); /* PM_EVEGENOFFTIM_MPU */
1150
omap_writel(0x480081e0, 0xc); /* PM_PWSTCTRL_MPU */
1151
omap_writel(0x48008200, 0x047e7ff7); /* CM_FCLKEN1_CORE */
1152
omap_writel(0x48008204, 0x00000004); /* CM_FCLKEN2_CORE */
1153
omap_writel(0x48008210, 0x047e7ff1); /* CM_ICLKEN1_CORE */
1154
omap_writel(0x48008214, 0x00000004); /* CM_ICLKEN2_CORE */
1155
omap_writel(0x4800821c, 0x00000000); /* CM_ICLKEN4_CORE */
1156
omap_writel(0x48008230, 0); /* CM_AUTOIDLE1_CORE */
1157
omap_writel(0x48008234, 0); /* CM_AUTOIDLE2_CORE */
1158
omap_writel(0x48008238, 7); /* CM_AUTOIDLE3_CORE */
1159
omap_writel(0x4800823c, 0); /* CM_AUTOIDLE4_CORE */
1160
omap_writel(0x48008240, 0x04360626); /* CM_CLKSEL1_CORE */
1161
omap_writel(0x48008244, 0x00000014); /* CM_CLKSEL2_CORE */
1162
omap_writel(0x48008248, 0); /* CM_CLKSTCTRL_CORE */
1163
omap_writel(0x48008300, 0x00000000); /* CM_FCLKEN_GFX */
1164
omap_writel(0x48008310, 0x00000000); /* CM_ICLKEN_GFX */
1165
omap_writel(0x48008340, 0x00000001); /* CM_CLKSEL_GFX */
1166
omap_writel(0x48008400, 0x00000004); /* CM_FCLKEN_WKUP */
1167
omap_writel(0x48008410, 0x00000004); /* CM_ICLKEN_WKUP */
1168
omap_writel(0x48008440, 0x00000000); /* CM_CLKSEL_WKUP */
1169
omap_writel(0x48008500, 0x000000cf); /* CM_CLKEN_PLL */
1170
omap_writel(0x48008530, 0x0000000c); /* CM_AUTOIDLE_PLL */
1171
omap_writel(0x48008540, /* CM_CLKSEL1_PLL */
1172
(0x78 << 12) | (6 << 8));
1173
omap_writel(0x48008544, 2); /* CM_CLKSEL2_PLL */
1179
n800_dss_init(&s->blizzard);
1182
s->mpu->cpu->env.GE = 0x5;
1184
/* If the machine has a slided keyboard, open it */
1186
qemu_irq_raise(qdev_get_gpio_in(s->mpu->gpio, N810_SLIDE_GPIO));
1189
#define OMAP_TAG_NOKIA_BT 0x4e01
1190
#define OMAP_TAG_WLAN_CX3110X 0x4e02
1191
#define OMAP_TAG_CBUS 0x4e03
1192
#define OMAP_TAG_EM_ASIC_BB5 0x4e04
1194
static struct omap_gpiosw_info_s {
1198
} n800_gpiosw_info[] = {
1200
"bat_cover", N800_BAT_COVER_GPIO,
1201
OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1203
"cam_act", N800_CAM_ACT_GPIO,
1204
OMAP_GPIOSW_TYPE_ACTIVITY,
1206
"cam_turn", N800_CAM_TURN_GPIO,
1207
OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED,
1209
"headphone", N8X0_HEADPHONE_GPIO,
1210
OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1213
}, n810_gpiosw_info[] = {
1215
"gps_reset", N810_GPS_RESET_GPIO,
1216
OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1218
"gps_wakeup", N810_GPS_WAKEUP_GPIO,
1219
OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
1221
"headphone", N8X0_HEADPHONE_GPIO,
1222
OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
1224
"kb_lock", N810_KB_LOCK_GPIO,
1225
OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1227
"sleepx_led", N810_SLEEPX_LED_GPIO,
1228
OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED | OMAP_GPIOSW_OUTPUT,
1230
"slide", N810_SLIDE_GPIO,
1231
OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
1236
static struct omap_partition_info_s {
1241
} n800_part_info[] = {
1242
{ 0x00000000, 0x00020000, 0x3, "bootloader" },
1243
{ 0x00020000, 0x00060000, 0x0, "config" },
1244
{ 0x00080000, 0x00200000, 0x0, "kernel" },
1245
{ 0x00280000, 0x00200000, 0x3, "initfs" },
1246
{ 0x00480000, 0x0fb80000, 0x3, "rootfs" },
1249
}, n810_part_info[] = {
1250
{ 0x00000000, 0x00020000, 0x3, "bootloader" },
1251
{ 0x00020000, 0x00060000, 0x0, "config" },
1252
{ 0x00080000, 0x00220000, 0x0, "kernel" },
1253
{ 0x002a0000, 0x00400000, 0x0, "initfs" },
1254
{ 0x006a0000, 0x0f960000, 0x0, "rootfs" },
1259
static bdaddr_t n8x0_bd_addr = {{ N8X0_BD_ADDR }};
1261
static int n8x0_atag_setup(void *p, int model)
1266
struct omap_gpiosw_info_s *gpiosw;
1267
struct omap_partition_info_s *partition;
1272
stw_raw(w ++, OMAP_TAG_UART); /* u16 tag */
1273
stw_raw(w ++, 4); /* u16 len */
1274
stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
1278
stw_raw(w ++, OMAP_TAG_SERIAL_CONSOLE); /* u16 tag */
1279
stw_raw(w ++, 4); /* u16 len */
1280
stw_raw(w ++, XLDR_LL_UART + 1); /* u8 console_uart */
1281
stw_raw(w ++, 115200); /* u32 console_speed */
1284
stw_raw(w ++, OMAP_TAG_LCD); /* u16 tag */
1285
stw_raw(w ++, 36); /* u16 len */
1286
strcpy((void *) w, "QEMU LCD panel"); /* char panel_name[16] */
1288
strcpy((void *) w, "blizzard"); /* char ctrl_name[16] */
1290
stw_raw(w ++, N810_BLIZZARD_RESET_GPIO); /* TODO: n800 s16 nreset_gpio */
1291
stw_raw(w ++, 24); /* u8 data_lines */
1293
stw_raw(w ++, OMAP_TAG_CBUS); /* u16 tag */
1294
stw_raw(w ++, 8); /* u16 len */
1295
stw_raw(w ++, N8X0_CBUS_CLK_GPIO); /* s16 clk_gpio */
1296
stw_raw(w ++, N8X0_CBUS_DAT_GPIO); /* s16 dat_gpio */
1297
stw_raw(w ++, N8X0_CBUS_SEL_GPIO); /* s16 sel_gpio */
1300
stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5); /* u16 tag */
1301
stw_raw(w ++, 4); /* u16 len */
1302
stw_raw(w ++, N8X0_RETU_GPIO); /* s16 retu_irq_gpio */
1303
stw_raw(w ++, N8X0_TAHVO_GPIO); /* s16 tahvo_irq_gpio */
1305
gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
1306
for (; gpiosw->name; gpiosw ++) {
1307
stw_raw(w ++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */
1308
stw_raw(w ++, 20); /* u16 len */
1309
strcpy((void *) w, gpiosw->name); /* char name[12] */
1311
stw_raw(w ++, gpiosw->line); /* u16 gpio */
1312
stw_raw(w ++, gpiosw->type);
1317
stw_raw(w ++, OMAP_TAG_NOKIA_BT); /* u16 tag */
1318
stw_raw(w ++, 12); /* u16 len */
1320
stb_raw(b ++, 0x01); /* u8 chip_type (CSR) */
1321
stb_raw(b ++, N8X0_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */
1322
stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */
1323
stb_raw(b ++, N8X0_BT_RESET_GPIO); /* u8 reset_gpio */
1324
stb_raw(b ++, BT_UART + 1); /* u8 bt_uart */
1325
memcpy(b, &n8x0_bd_addr, 6); /* u8 bd_addr[6] */
1327
stb_raw(b ++, 0x02); /* u8 bt_sysclk (38.4) */
1330
stw_raw(w ++, OMAP_TAG_WLAN_CX3110X); /* u16 tag */
1331
stw_raw(w ++, 8); /* u16 len */
1332
stw_raw(w ++, 0x25); /* u8 chip_type */
1333
stw_raw(w ++, N8X0_WLAN_PWR_GPIO); /* s16 power_gpio */
1334
stw_raw(w ++, N8X0_WLAN_IRQ_GPIO); /* s16 irq_gpio */
1335
stw_raw(w ++, -1); /* s16 spi_cs_gpio */
1337
stw_raw(w ++, OMAP_TAG_MMC); /* u16 tag */
1338
stw_raw(w ++, 16); /* u16 len */
1340
stw_raw(w ++, 0x23f); /* unsigned flags */
1341
stw_raw(w ++, -1); /* s16 power_pin */
1342
stw_raw(w ++, -1); /* s16 switch_pin */
1343
stw_raw(w ++, -1); /* s16 wp_pin */
1344
stw_raw(w ++, 0x240); /* unsigned flags */
1345
stw_raw(w ++, 0xc000); /* s16 power_pin */
1346
stw_raw(w ++, 0x0248); /* s16 switch_pin */
1347
stw_raw(w ++, 0xc000); /* s16 wp_pin */
1349
stw_raw(w ++, 0xf); /* unsigned flags */
1350
stw_raw(w ++, -1); /* s16 power_pin */
1351
stw_raw(w ++, -1); /* s16 switch_pin */
1352
stw_raw(w ++, -1); /* s16 wp_pin */
1353
stw_raw(w ++, 0); /* unsigned flags */
1354
stw_raw(w ++, 0); /* s16 power_pin */
1355
stw_raw(w ++, 0); /* s16 switch_pin */
1356
stw_raw(w ++, 0); /* s16 wp_pin */
1359
stw_raw(w ++, OMAP_TAG_TEA5761); /* u16 tag */
1360
stw_raw(w ++, 4); /* u16 len */
1361
stw_raw(w ++, N8X0_TEA5761_CS_GPIO); /* u16 enable_gpio */
1364
partition = (model == 810) ? n810_part_info : n800_part_info;
1365
for (; partition->name; partition ++) {
1366
stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */
1367
stw_raw(w ++, 28); /* u16 len */
1368
strcpy((void *) w, partition->name); /* char name[16] */
1369
l = (void *) (w + 8);
1370
stl_raw(l ++, partition->size); /* unsigned int size */
1371
stl_raw(l ++, partition->offset); /* unsigned int offset */
1372
stl_raw(l ++, partition->mask); /* unsigned int mask_flags */
1376
stw_raw(w ++, OMAP_TAG_BOOT_REASON); /* u16 tag */
1377
stw_raw(w ++, 12); /* u16 len */
1379
strcpy((void *) w, "por"); /* char reason_str[12] */
1380
strcpy((void *) w, "charger"); /* char reason_str[12] */
1381
strcpy((void *) w, "32wd_to"); /* char reason_str[12] */
1382
strcpy((void *) w, "sw_rst"); /* char reason_str[12] */
1383
strcpy((void *) w, "mbus"); /* char reason_str[12] */
1384
strcpy((void *) w, "unknown"); /* char reason_str[12] */
1385
strcpy((void *) w, "swdg_to"); /* char reason_str[12] */
1386
strcpy((void *) w, "sec_vio"); /* char reason_str[12] */
1387
strcpy((void *) w, "pwr_key"); /* char reason_str[12] */
1388
strcpy((void *) w, "rtc_alarm"); /* char reason_str[12] */
1390
strcpy((void *) w, "pwr_key"); /* char reason_str[12] */
1394
tag = (model == 810) ? "RX-44" : "RX-34";
1395
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
1396
stw_raw(w ++, 24); /* u16 len */
1397
strcpy((void *) w, "product"); /* char component[12] */
1399
strcpy((void *) w, tag); /* char version[12] */
1402
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
1403
stw_raw(w ++, 24); /* u16 len */
1404
strcpy((void *) w, "hw-build"); /* char component[12] */
1406
strcpy((void *) w, "QEMU"); /* char version[12] */
1409
tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
1410
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
1411
stw_raw(w ++, 24); /* u16 len */
1412
strcpy((void *) w, "nolo"); /* char component[12] */
1414
strcpy((void *) w, tag); /* char version[12] */
1417
return (void *) w - p;
1420
static int n800_atag_setup(const struct arm_boot_info *info, void *p)
1422
return n8x0_atag_setup(p, 800);
1425
static int n810_atag_setup(const struct arm_boot_info *info, void *p)
1427
return n8x0_atag_setup(p, 810);
1430
static void n8x0_init(QEMUMachineInitArgs *args,
1431
struct arm_boot_info *binfo, int model)
1433
MemoryRegion *sysmem = get_system_memory();
1434
struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));
1435
int sdram_size = binfo->ram_size;
1437
s->mpu = omap2420_mpu_init(sysmem, sdram_size, args->cpu_model);
1439
/* Setup peripherals
1441
* Believed external peripherals layout in the N810:
1446
* Conexant cx3110x (WLAN)
1447
* optional: pc2400m (WiMAX)
1449
* TLV320AIC33 (audio codec)
1450
* TCM825x (camera by Toshiba)
1451
* lp5521 (clever LEDs)
1452
* tsl2563 (light sensor, hwmon, model 7, rev. 0)
1453
* lm8323 (keypad, manf 00, rev 04)
1455
* tmp105 (temperature sensor, hwmon)
1457
* (somewhere on i2c - maybe N800-only)
1458
* tea5761 (FM tuner)
1461
* (some serial port)
1462
* csr41814 (Bluetooth)
1468
n800_tsc_kbd_setup(s);
1469
else if (model == 810) {
1473
cursor_hide = 0; // who wants to use touchscreen without a pointer?
1478
if (usb_enabled(false)) {
1482
if (args->kernel_filename) {
1483
/* Or at the linux loader. */
1484
binfo->kernel_filename = args->kernel_filename;
1485
binfo->kernel_cmdline = args->kernel_cmdline;
1486
binfo->initrd_filename = args->initrd_filename;
1487
arm_load_kernel(s->mpu->cpu, binfo);
1489
qemu_register_reset(n8x0_boot_init, s);
1492
if (option_rom[0].name &&
1493
(args->boot_device[0] == 'n' || !args->kernel_filename)) {
1494
uint8_t nolo_tags[0x10000];
1495
/* No, wait, better start at the ROM. */
1496
s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
1498
/* This is intended for loading the `secondary.bin' program from
1499
* Nokia images (the NOLO bootloader). The entry point seems
1500
* to be at OMAP2_Q2_BASE + 0x400000.
1502
* The `2nd.bin' files contain some kind of earlier boot code and
1503
* for them the entry point needs to be set to OMAP2_SRAM_BASE.
1505
* The code above is for loading the `zImage' file from Nokia
1507
load_image_targphys(option_rom[0].name,
1508
OMAP2_Q2_BASE + 0x400000,
1509
sdram_size - 0x400000);
1511
n800_setup_nolo_tags(nolo_tags);
1512
cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
1516
static struct arm_boot_info n800_binfo = {
1517
.loader_start = OMAP2_Q2_BASE,
1518
/* Actually two chips of 0x4000000 bytes each */
1519
.ram_size = 0x08000000,
1521
.atag_board = n800_atag_setup,
1524
static struct arm_boot_info n810_binfo = {
1525
.loader_start = OMAP2_Q2_BASE,
1526
/* Actually two chips of 0x4000000 bytes each */
1527
.ram_size = 0x08000000,
1528
/* 0x60c and 0x6bf (WiMAX Edition) have been assigned but are not
1529
* used by some older versions of the bootloader and 5555 is used
1530
* instead (including versions that shipped with many devices). */
1532
.atag_board = n810_atag_setup,
1535
static void n800_init(QEMUMachineInitArgs *args)
1537
return n8x0_init(args, &n800_binfo, 800);
1540
static void n810_init(QEMUMachineInitArgs *args)
1542
return n8x0_init(args, &n810_binfo, 810);
1545
static QEMUMachine n800_machine = {
1547
.desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
1549
DEFAULT_MACHINE_OPTIONS,
1552
static QEMUMachine n810_machine = {
1554
.desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
1556
DEFAULT_MACHINE_OPTIONS,
1559
static void nseries_register_types(void)
1561
type_register_static(&mipid_info);
1564
static void nseries_machine_init(void)
1566
qemu_register_machine(&n800_machine);
1567
qemu_register_machine(&n810_machine);
1570
type_init(nseries_register_types);
1571
machine_init(nseries_machine_init);