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