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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 #include "qemu-common.h"
35 /* Nokia N8x0 support */
37 struct omap_mpu_state_s *cpu;
39 struct rfbi_chip_s blizzard;
42 uint32_t (*txrx)(void *opaque, uint32_t value, int len);
43 struct uwire_slave_s *chip;
56 #define N8X0_TUSB_ENABLE_GPIO 0
57 #define N800_MMC2_WP_GPIO 8
58 #define N800_UNKNOWN_GPIO0 9 /* out */
59 #define N800_UNKNOWN_GPIO1 10 /* out */
60 #define N800_CAM_TURN_GPIO 12
61 #define N810_GPS_RESET_GPIO 12
62 #define N800_BLIZZARD_POWERDOWN_GPIO 15
63 #define N800_MMC1_WP_GPIO 23
64 #define N8X0_ONENAND_GPIO 26
65 #define N810_BLIZZARD_RESET_GPIO 30
66 #define N800_UNKNOWN_GPIO2 53 /* out */
67 #define N8X0_TUSB_INT_GPIO 58
68 #define N8X0_BT_WKUP_GPIO 61
69 #define N8X0_STI_GPIO 62
70 #define N8X0_CBUS_SEL_GPIO 64
71 #define N8X0_CBUS_DAT_GPIO 65
72 #define N8X0_CBUS_CLK_GPIO 66
73 #define N8X0_WLAN_IRQ_GPIO 87
74 #define N8X0_BT_RESET_GPIO 92
75 #define N8X0_TEA5761_CS_GPIO 93
76 #define N800_UNKNOWN_GPIO 94
77 #define N810_TSC_RESET_GPIO 94
78 #define N800_CAM_ACT_GPIO 95
79 #define N810_GPS_WAKEUP_GPIO 95
80 #define N8X0_MMC_CS_GPIO 96
81 #define N8X0_WLAN_PWR_GPIO 97
82 #define N8X0_BT_HOST_WKUP_GPIO 98
83 #define N800_UNKNOWN_GPIO3 101 /* out */
84 #define N810_KB_LOCK_GPIO 102
85 #define N800_TSC_TS_GPIO 103
86 #define N810_TSC_TS_GPIO 106
87 #define N8X0_HEADPHONE_GPIO 107
88 #define N8X0_RETU_GPIO 108
89 #define N800_TSC_KP_IRQ_GPIO 109
90 #define N810_KEYBOARD_GPIO 109
91 #define N800_BAT_COVER_GPIO 110
92 #define N810_SLIDE_GPIO 110
93 #define N8X0_TAHVO_GPIO 111
94 #define N800_UNKNOWN_GPIO4 112 /* out */
95 #define N810_SLEEPX_LED_GPIO 112
96 #define N800_TSC_RESET_GPIO 118 /* ? */
97 #define N800_TSC_UNKNOWN_GPIO 119 /* out */
98 #define N8X0_TMP105_GPIO 125
101 #define XLDR_LL_UART 1
103 /* Addresses on the I2C bus 0 */
104 #define N810_TLV320AIC33_ADDR 0x18 /* Audio CODEC */
105 #define N8X0_TCM825x_ADDR 0x29 /* Camera */
106 #define N810_LP5521_ADDR 0x32 /* LEDs */
107 #define N810_TSL2563_ADDR 0x3d /* Light sensor */
108 #define N810_LM8323_ADDR 0x45 /* Keyboard */
109 /* Addresses on the I2C bus 1 */
110 #define N8X0_TMP105_ADDR 0x48 /* Temperature sensor */
111 #define N8X0_MENELAUS_ADDR 0x72 /* Power management */
113 /* Chipselects on GPMC NOR interface */
114 #define N8X0_ONENAND_CS 0
115 #define N8X0_USB_ASYNC_CS 1
116 #define N8X0_USB_SYNC_CS 4
118 static void n800_mmc_cs_cb(void *opaque, int line, int level)
120 /* TODO: this seems to actually be connected to the menelaus, to
121 * which also both MMC slots connect. */
122 omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
124 printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
127 static void n8x0_gpio_setup(struct n800_s *s)
129 qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1);
130 omap2_gpio_out_set(s->cpu->gpif, N8X0_MMC_CS_GPIO, mmc_cs[0]);
132 qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]);
135 static void n8x0_nand_setup(struct n800_s *s)
137 /* Either ec40xx or ec48xx are OK for the ID */
138 omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
140 onenand_init(0xec4800, 1,
141 omap2_gpio_in_get(s->cpu->gpif,
142 N8X0_ONENAND_GPIO)[0]));
145 static void n8x0_i2c_setup(struct n800_s *s)
147 qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0];
149 /* Attach the CPU on one end of our I2C bus. */
150 s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
152 /* Attach a menelaus PM chip */
153 i2c_set_slave_address(
154 twl92230_init(s->i2c,
155 s->cpu->irq[0][OMAP_INT_24XX_SYS_NIRQ]),
158 /* Attach a TMP105 PM chip (A0 wired to ground) */
159 i2c_set_slave_address(tmp105_init(s->i2c, tmp_irq), N8X0_TMP105_ADDR);
162 /* Touchscreen and keypad controller */
163 static struct mouse_transform_info_s n800_pointercal = {
166 .a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
169 static struct mouse_transform_info_s n810_pointercal = {
172 .a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
175 #define RETU_KEYCODE 61 /* F3 */
177 static void n800_key_event(void *opaque, int keycode)
179 struct n800_s *s = (struct n800_s *) opaque;
180 int code = s->keymap[keycode & 0x7f];
183 if ((keycode & 0x7f) == RETU_KEYCODE)
184 retu_key_event(s->retu, !(keycode & 0x80));
188 tsc210x_key_event(s->ts.chip, code, !(keycode & 0x80));
191 static const int n800_keys[16] = {
205 64, /* FullScreen (F6) */
210 static void n800_tsc_kbd_setup(struct n800_s *s)
214 /* XXX: are the three pins inverted inside the chip between the
215 * tsc and the cpu (N4111)? */
216 qemu_irq penirq = 0; /* NC */
217 qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0];
218 qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0];
220 s->ts.chip = tsc2301_init(penirq, kbirq, dav, 0);
221 s->ts.opaque = s->ts.chip->opaque;
222 s->ts.txrx = tsc210x_txrx;
224 for (i = 0; i < 0x80; i ++)
226 for (i = 0; i < 0x10; i ++)
227 if (n800_keys[i] >= 0)
228 s->keymap[n800_keys[i]] = i;
230 qemu_add_kbd_event_handler(n800_key_event, s);
232 tsc210x_set_transform(s->ts.chip, &n800_pointercal);
235 static void n810_tsc_setup(struct n800_s *s)
237 qemu_irq pintdav = omap2_gpio_in_get(s->cpu->gpif, N810_TSC_TS_GPIO)[0];
239 s->ts.opaque = tsc2005_init(pintdav);
240 s->ts.txrx = tsc2005_txrx;
242 tsc2005_set_transform(s->ts.opaque, &n810_pointercal);
245 /* N810 Keyboard controller */
246 static void n810_key_event(void *opaque, int keycode)
248 struct n800_s *s = (struct n800_s *) opaque;
249 int code = s->keymap[keycode & 0x7f];
252 if ((keycode & 0x7f) == RETU_KEYCODE)
253 retu_key_event(s->retu, !(keycode & 0x80));
257 lm832x_key_event(s->kbd, code, !(keycode & 0x80));
262 static int n810_keys[0x80] = {
267 [0x05] = 14, /* Backspace */
277 [0x12] = 62, /* Menu (F4) */
279 [0x14] = 40, /* ' (Apostrophe) */
286 [0x1c] = 42, /* Shift (Left shift) */
287 [0x1f] = 65, /* Zoom+ (F7) */
290 [0x22] = 39, /* ; (Semicolon) */
291 [0x23] = 12, /* - (Minus) */
292 [0x24] = 13, /* = (Equal) */
293 [0x2b] = 56, /* Fn (Left Alt) */
295 [0x2f] = 66, /* Zoom- (F8) */
298 [0x32] = 29 | M, /* Right Ctrl */
299 [0x34] = 57, /* Space */
300 [0x35] = 51, /* , (Comma) */
301 [0x37] = 72 | M, /* Up */
302 [0x3c] = 82 | M, /* Compose (Insert) */
303 [0x3f] = 64, /* FullScreen (F6) */
306 [0x44] = 52, /* . (Dot) */
307 [0x46] = 77 | M, /* Right */
308 [0x4f] = 63, /* Home (F5) */
310 [0x53] = 80 | M, /* Down */
311 [0x55] = 28, /* Enter */
312 [0x5f] = 1, /* Cycle (ESC) */
315 [0x64] = 75 | M, /* Left */
319 [0x75] = 28 | M, /* KP Enter (KP Enter) */
321 [0x75] = 15, /* KP Enter (Tab) */
327 static void n810_kbd_setup(struct n800_s *s)
329 qemu_irq kbd_irq = omap2_gpio_in_get(s->cpu->gpif, N810_KEYBOARD_GPIO)[0];
332 for (i = 0; i < 0x80; i ++)
334 for (i = 0; i < 0x80; i ++)
335 if (n810_keys[i] > 0)
336 s->keymap[n810_keys[i]] = i;
338 qemu_add_kbd_event_handler(n810_key_event, s);
340 /* Attach the LM8322 keyboard to the I2C bus,
341 * should happen in n8x0_i2c_setup and s->kbd be initialised here. */
342 s->kbd = lm8323_init(s->i2c, kbd_irq);
343 i2c_set_slave_address(s->kbd, N810_LM8323_ADDR);
346 /* LCD MIPI DBI-C controller (URAL) */
367 static void mipid_reset(struct mipid_s *s)
370 fprintf(stderr, "%s: Display off\n", __FUNCTION__);
378 (1 << 7) | /* Register loading OK. */
379 (1 << 5) | /* The chip is attached. */
380 (1 << 4); /* Display glass still in one piece. */
390 static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
392 struct mipid_s *s = (struct mipid_s *) opaque;
396 cpu_abort(cpu_single_env, "%s: FIXME: bad SPI word width %i\n",
399 if (s->p >= sizeof(s->resp) / sizeof(*s->resp))
402 ret = s->resp[s->p ++];
404 s->param[s->pm] = cmd;
412 case 0x01: /* SWRESET */
416 case 0x02: /* BSTROFF */
419 case 0x03: /* BSTRON */
423 case 0x04: /* RDDID */
425 s->resp[0] = (s->id >> 16) & 0xff;
426 s->resp[1] = (s->id >> 8) & 0xff;
427 s->resp[2] = (s->id >> 0) & 0xff;
430 case 0x06: /* RD_RED */
431 case 0x07: /* RD_GREEN */
432 /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so
433 * for the bootloader one needs to change this. */
434 case 0x08: /* RD_BLUE */
436 /* TODO: return first pixel components */
440 case 0x09: /* RDDST */
442 s->resp[0] = s->booster << 7;
443 s->resp[1] = (5 << 4) | (s->partial << 2) |
444 (s->sleep << 1) | s->normal;
445 s->resp[2] = (s->vscr << 7) | (s->invert << 5) |
446 (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);
447 s->resp[3] = s->gamma << 6;
450 case 0x0a: /* RDDPM */
452 s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |
453 (s->partial << 5) | (s->sleep << 6) | (s->booster << 7);
455 case 0x0b: /* RDDMADCTR */
459 case 0x0c: /* RDDCOLMOD */
461 s->resp[0] = 5; /* 65K colours */
463 case 0x0d: /* RDDIM */
465 s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;
467 case 0x0e: /* RDDSM */
469 s->resp[0] = s->te << 7;
471 case 0x0f: /* RDDSDR */
473 s->resp[0] = s->selfcheck;
476 case 0x10: /* SLPIN */
479 case 0x11: /* SLPOUT */
481 s->selfcheck ^= 1 << 6; /* POFF self-diagnosis Ok */
484 case 0x12: /* PTLON */
489 case 0x13: /* NORON */
495 case 0x20: /* INVOFF */
498 case 0x21: /* INVON */
502 case 0x22: /* APOFF */
503 case 0x23: /* APON */
506 case 0x25: /* WRCNTR */
511 case 0x26: /* GAMSET */
513 s->gamma = ffs(s->param[0] & 0xf) - 1;
518 case 0x28: /* DISPOFF */
520 fprintf(stderr, "%s: Display off\n", __FUNCTION__);
522 case 0x29: /* DISPON */
524 fprintf(stderr, "%s: Display on\n", __FUNCTION__);
527 case 0x2a: /* CASET */
528 case 0x2b: /* RASET */
529 case 0x2c: /* RAMWR */
530 case 0x2d: /* RGBSET */
531 case 0x2e: /* RAMRD */
532 case 0x30: /* PTLAR */
533 case 0x33: /* SCRLAR */
536 case 0x34: /* TEOFF */
539 case 0x35: /* TEON */
546 case 0x36: /* MADCTR */
549 case 0x37: /* VSCSAD */
555 case 0x38: /* IDMOFF */
556 case 0x39: /* IDMON */
557 case 0x3a: /* COLMOD */
560 case 0xb0: /* CLKINT / DISCTL */
561 case 0xb1: /* CLKEXT */
566 case 0xb4: /* FRMSEL */
569 case 0xb5: /* FRM8SEL */
570 case 0xb6: /* TMPRNG / INIESC */
571 case 0xb7: /* TMPHIS / NOP2 */
572 case 0xb8: /* TMPREAD / MADCTL */
573 case 0xba: /* DISTCTR */
574 case 0xbb: /* EPVOL */
577 case 0xbd: /* Unknown */
583 case 0xc2: /* IFMOD */
588 case 0xc6: /* PWRCTL */
589 case 0xc7: /* PPWRCTL */
590 case 0xd0: /* EPWROUT */
591 case 0xd1: /* EPWRIN */
592 case 0xd4: /* RDEV */
593 case 0xd5: /* RDRR */
596 case 0xda: /* RDID1 */
598 s->resp[0] = (s->id >> 16) & 0xff;
600 case 0xdb: /* RDID2 */
602 s->resp[0] = (s->id >> 8) & 0xff;
604 case 0xdc: /* RDID3 */
606 s->resp[0] = (s->id >> 0) & 0xff;
611 fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, s->cmd);
618 static void *mipid_init(void)
620 struct mipid_s *s = (struct mipid_s *) qemu_mallocz(sizeof(*s));
628 static void n8x0_spi_setup(struct n800_s *s)
630 void *tsc = s->ts.opaque;
631 void *mipid = mipid_init();
633 omap_mcspi_attach(s->cpu->mcspi[0], s->ts.txrx, tsc, 0);
634 omap_mcspi_attach(s->cpu->mcspi[0], mipid_txrx, mipid, 1);
637 /* This task is normally performed by the bootloader. If we're loading
638 * a kernel directly, we need to enable the Blizzard ourselves. */
639 static void n800_dss_init(struct rfbi_chip_s *chip)
643 chip->write(chip->opaque, 0, 0x2a); /* LCD Width register */
644 chip->write(chip->opaque, 1, 0x64);
645 chip->write(chip->opaque, 0, 0x2c); /* LCD HNDP register */
646 chip->write(chip->opaque, 1, 0x1e);
647 chip->write(chip->opaque, 0, 0x2e); /* LCD Height 0 register */
648 chip->write(chip->opaque, 1, 0xe0);
649 chip->write(chip->opaque, 0, 0x30); /* LCD Height 1 register */
650 chip->write(chip->opaque, 1, 0x01);
651 chip->write(chip->opaque, 0, 0x32); /* LCD VNDP register */
652 chip->write(chip->opaque, 1, 0x06);
653 chip->write(chip->opaque, 0, 0x68); /* Display Mode register */
654 chip->write(chip->opaque, 1, 1); /* Enable bit */
656 chip->write(chip->opaque, 0, 0x6c);
657 chip->write(chip->opaque, 1, 0x00); /* Input X Start Position */
658 chip->write(chip->opaque, 1, 0x00); /* Input X Start Position */
659 chip->write(chip->opaque, 1, 0x00); /* Input Y Start Position */
660 chip->write(chip->opaque, 1, 0x00); /* Input Y Start Position */
661 chip->write(chip->opaque, 1, 0x1f); /* Input X End Position */
662 chip->write(chip->opaque, 1, 0x03); /* Input X End Position */
663 chip->write(chip->opaque, 1, 0xdf); /* Input Y End Position */
664 chip->write(chip->opaque, 1, 0x01); /* Input Y End Position */
665 chip->write(chip->opaque, 1, 0x00); /* Output X Start Position */
666 chip->write(chip->opaque, 1, 0x00); /* Output X Start Position */
667 chip->write(chip->opaque, 1, 0x00); /* Output Y Start Position */
668 chip->write(chip->opaque, 1, 0x00); /* Output Y Start Position */
669 chip->write(chip->opaque, 1, 0x1f); /* Output X End Position */
670 chip->write(chip->opaque, 1, 0x03); /* Output X End Position */
671 chip->write(chip->opaque, 1, 0xdf); /* Output Y End Position */
672 chip->write(chip->opaque, 1, 0x01); /* Output Y End Position */
673 chip->write(chip->opaque, 1, 0x01); /* Input Data Format */
674 chip->write(chip->opaque, 1, 0x01); /* Data Source Select */
676 fb_blank = memset(qemu_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
677 /* Display Memory Data Port */
678 chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
682 static void n8x0_dss_setup(struct n800_s *s, DisplayState *ds)
684 s->blizzard.opaque = s1d13745_init(0, ds);
685 s->blizzard.block = s1d13745_write_block;
686 s->blizzard.write = s1d13745_write;
687 s->blizzard.read = s1d13745_read;
689 omap_rfbi_attach(s->cpu->dss, 0, &s->blizzard);
692 static void n8x0_cbus_setup(struct n800_s *s)
694 qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N8X0_CBUS_DAT_GPIO)[0];
695 qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_RETU_GPIO)[0];
696 qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TAHVO_GPIO)[0];
698 struct cbus_s *cbus = cbus_init(dat_out);
700 omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_CLK_GPIO, cbus->clk);
701 omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_DAT_GPIO, cbus->dat);
702 omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_SEL_GPIO, cbus->sel);
704 cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
705 cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
708 static void n8x0_usb_power_cb(void *opaque, int line, int level)
710 struct n800_s *s = opaque;
712 tusb6010_power(s->usb, level);
715 static void n8x0_usb_setup(struct n800_s *s)
717 qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0];
718 qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
719 struct tusb_s *tusb = tusb6010_init(tusb_irq);
721 /* Using the NOR interface */
722 omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
723 tusb6010_async_io(tusb), 0, 0, tusb);
724 omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
725 tusb6010_sync_io(tusb), 0, 0, tusb);
728 omap2_gpio_out_set(s->cpu->gpif, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
731 /* This task is normally performed by the bootloader. If we're loading
732 * a kernel directly, we need to set up GPMC mappings ourselves. */
733 static void n800_gpmc_init(struct n800_s *s)
736 (0xf << 8) | /* MASKADDRESS */
737 (1 << 6) | /* CSVALID */
738 (4 << 0); /* BASEADDRESS */
740 cpu_physical_memory_write(0x6800a078, /* GPMC_CONFIG7_0 */
741 (void *) &config7, sizeof(config7));
744 /* Setup sequence done by the bootloader */
745 static void n8x0_boot_init(void *opaque)
747 struct n800_s *s = (struct n800_s *) opaque;
751 #define omap_writel(addr, val) \
753 cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf))
755 omap_writel(0x48008060, 0x41); /* PRCM_CLKSRC_CTRL */
756 omap_writel(0x48008070, 1); /* PRCM_CLKOUT_CTRL */
757 omap_writel(0x48008078, 0); /* PRCM_CLKEMUL_CTRL */
758 omap_writel(0x48008090, 0); /* PRCM_VOLTSETUP */
759 omap_writel(0x48008094, 0); /* PRCM_CLKSSETUP */
760 omap_writel(0x48008098, 0); /* PRCM_POLCTRL */
761 omap_writel(0x48008140, 2); /* CM_CLKSEL_MPU */
762 omap_writel(0x48008148, 0); /* CM_CLKSTCTRL_MPU */
763 omap_writel(0x48008158, 1); /* RM_RSTST_MPU */
764 omap_writel(0x480081c8, 0x15); /* PM_WKDEP_MPU */
765 omap_writel(0x480081d4, 0x1d4); /* PM_EVGENCTRL_MPU */
766 omap_writel(0x480081d8, 0); /* PM_EVEGENONTIM_MPU */
767 omap_writel(0x480081dc, 0); /* PM_EVEGENOFFTIM_MPU */
768 omap_writel(0x480081e0, 0xc); /* PM_PWSTCTRL_MPU */
769 omap_writel(0x48008200, 0x047e7ff7); /* CM_FCLKEN1_CORE */
770 omap_writel(0x48008204, 0x00000004); /* CM_FCLKEN2_CORE */
771 omap_writel(0x48008210, 0x047e7ff1); /* CM_ICLKEN1_CORE */
772 omap_writel(0x48008214, 0x00000004); /* CM_ICLKEN2_CORE */
773 omap_writel(0x4800821c, 0x00000000); /* CM_ICLKEN4_CORE */
774 omap_writel(0x48008230, 0); /* CM_AUTOIDLE1_CORE */
775 omap_writel(0x48008234, 0); /* CM_AUTOIDLE2_CORE */
776 omap_writel(0x48008238, 7); /* CM_AUTOIDLE3_CORE */
777 omap_writel(0x4800823c, 0); /* CM_AUTOIDLE4_CORE */
778 omap_writel(0x48008240, 0x04360626); /* CM_CLKSEL1_CORE */
779 omap_writel(0x48008244, 0x00000014); /* CM_CLKSEL2_CORE */
780 omap_writel(0x48008248, 0); /* CM_CLKSTCTRL_CORE */
781 omap_writel(0x48008300, 0x00000000); /* CM_FCLKEN_GFX */
782 omap_writel(0x48008310, 0x00000000); /* CM_ICLKEN_GFX */
783 omap_writel(0x48008340, 0x00000001); /* CM_CLKSEL_GFX */
784 omap_writel(0x48008400, 0x00000004); /* CM_FCLKEN_WKUP */
785 omap_writel(0x48008410, 0x00000004); /* CM_ICLKEN_WKUP */
786 omap_writel(0x48008440, 0x00000000); /* CM_CLKSEL_WKUP */
787 omap_writel(0x48008500, 0x000000cf); /* CM_CLKEN_PLL */
788 omap_writel(0x48008530, 0x0000000c); /* CM_AUTOIDLE_PLL */
789 omap_writel(0x48008540, /* CM_CLKSEL1_PLL */
790 (0x78 << 12) | (6 << 8));
791 omap_writel(0x48008544, 2); /* CM_CLKSEL2_PLL */
797 n800_dss_init(&s->blizzard);
800 s->cpu->env->regs[15] = s->cpu->env->boot_info->loader_start;
801 s->cpu->env->GE = 0x5;
804 #define OMAP_TAG_NOKIA_BT 0x4e01
805 #define OMAP_TAG_WLAN_CX3110X 0x4e02
806 #define OMAP_TAG_CBUS 0x4e03
807 #define OMAP_TAG_EM_ASIC_BB5 0x4e04
809 static struct omap_gpiosw_info_s {
813 } n800_gpiosw_info[] = {
815 "bat_cover", N800_BAT_COVER_GPIO,
816 OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
818 "cam_act", N800_CAM_ACT_GPIO,
819 OMAP_GPIOSW_TYPE_ACTIVITY,
821 "cam_turn", N800_CAM_TURN_GPIO,
822 OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED,
824 "headphone", N8X0_HEADPHONE_GPIO,
825 OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
828 }, n810_gpiosw_info[] = {
830 "gps_reset", N810_GPS_RESET_GPIO,
831 OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
833 "gps_wakeup", N810_GPS_WAKEUP_GPIO,
834 OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
836 "headphone", N8X0_HEADPHONE_GPIO,
837 OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
839 "kb_lock", N810_KB_LOCK_GPIO,
840 OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
842 "sleepx_led", N810_SLEEPX_LED_GPIO,
843 OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED | OMAP_GPIOSW_OUTPUT,
845 "slide", N810_SLIDE_GPIO,
846 OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
851 static struct omap_partition_info_s {
856 } n800_part_info[] = {
857 { 0x00000000, 0x00020000, 0x3, "bootloader" },
858 { 0x00020000, 0x00060000, 0x0, "config" },
859 { 0x00080000, 0x00200000, 0x0, "kernel" },
860 { 0x00280000, 0x00200000, 0x3, "initfs" },
861 { 0x00480000, 0x0fb80000, 0x3, "rootfs" },
864 }, n810_part_info[] = {
865 { 0x00000000, 0x00020000, 0x3, "bootloader" },
866 { 0x00020000, 0x00060000, 0x0, "config" },
867 { 0x00080000, 0x00220000, 0x0, "kernel" },
868 { 0x002a0000, 0x00400000, 0x0, "initfs" },
869 { 0x006a0000, 0x0f960000, 0x0, "rootfs" },
874 static int n8x0_atag_setup(void *p, int model)
879 struct omap_gpiosw_info_s *gpiosw;
880 struct omap_partition_info_s *partition;
885 stw_raw(w ++, OMAP_TAG_UART); /* u16 tag */
886 stw_raw(w ++, 4); /* u16 len */
887 stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
891 stw_raw(w ++, OMAP_TAG_SERIAL_CONSOLE); /* u16 tag */
892 stw_raw(w ++, 4); /* u16 len */
893 stw_raw(w ++, XLDR_LL_UART); /* u8 console_uart */
894 stw_raw(w ++, 115200); /* u32 console_speed */
897 stw_raw(w ++, OMAP_TAG_LCD); /* u16 tag */
898 stw_raw(w ++, 36); /* u16 len */
899 strcpy((void *) w, "QEMU LCD panel"); /* char panel_name[16] */
901 strcpy((void *) w, "blizzard"); /* char ctrl_name[16] */
903 stw_raw(w ++, N810_BLIZZARD_RESET_GPIO); /* TODO: n800 s16 nreset_gpio */
904 stw_raw(w ++, 24); /* u8 data_lines */
906 stw_raw(w ++, OMAP_TAG_CBUS); /* u16 tag */
907 stw_raw(w ++, 8); /* u16 len */
908 stw_raw(w ++, N8X0_CBUS_CLK_GPIO); /* s16 clk_gpio */
909 stw_raw(w ++, N8X0_CBUS_DAT_GPIO); /* s16 dat_gpio */
910 stw_raw(w ++, N8X0_CBUS_SEL_GPIO); /* s16 sel_gpio */
913 stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5); /* u16 tag */
914 stw_raw(w ++, 4); /* u16 len */
915 stw_raw(w ++, N8X0_RETU_GPIO); /* s16 retu_irq_gpio */
916 stw_raw(w ++, N8X0_TAHVO_GPIO); /* s16 tahvo_irq_gpio */
918 gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
919 for (; gpiosw->name; gpiosw ++) {
920 stw_raw(w ++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */
921 stw_raw(w ++, 20); /* u16 len */
922 strcpy((void *) w, gpiosw->name); /* char name[12] */
924 stw_raw(w ++, gpiosw->line); /* u16 gpio */
925 stw_raw(w ++, gpiosw->type);
930 stw_raw(w ++, OMAP_TAG_NOKIA_BT); /* u16 tag */
931 stw_raw(w ++, 12); /* u16 len */
933 stb_raw(b ++, 0x01); /* u8 chip_type (CSR) */
934 stb_raw(b ++, N8X0_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */
935 stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */
936 stb_raw(b ++, N8X0_BT_RESET_GPIO); /* u8 reset_gpio */
937 stb_raw(b ++, 1); /* u8 bt_uart */
938 memset(b, 0, 6); /* u8 bd_addr[6] */
940 stb_raw(b ++, 0x02); /* u8 bt_sysclk (38.4) */
943 stw_raw(w ++, OMAP_TAG_WLAN_CX3110X); /* u16 tag */
944 stw_raw(w ++, 8); /* u16 len */
945 stw_raw(w ++, 0x25); /* u8 chip_type */
946 stw_raw(w ++, N8X0_WLAN_PWR_GPIO); /* s16 power_gpio */
947 stw_raw(w ++, N8X0_WLAN_IRQ_GPIO); /* s16 irq_gpio */
948 stw_raw(w ++, -1); /* s16 spi_cs_gpio */
950 stw_raw(w ++, OMAP_TAG_MMC); /* u16 tag */
951 stw_raw(w ++, 16); /* u16 len */
953 stw_raw(w ++, 0x23f); /* unsigned flags */
954 stw_raw(w ++, -1); /* s16 power_pin */
955 stw_raw(w ++, -1); /* s16 switch_pin */
956 stw_raw(w ++, -1); /* s16 wp_pin */
957 stw_raw(w ++, 0x240); /* unsigned flags */
958 stw_raw(w ++, 0xc000); /* s16 power_pin */
959 stw_raw(w ++, 0x0248); /* s16 switch_pin */
960 stw_raw(w ++, 0xc000); /* s16 wp_pin */
962 stw_raw(w ++, 0xf); /* unsigned flags */
963 stw_raw(w ++, -1); /* s16 power_pin */
964 stw_raw(w ++, -1); /* s16 switch_pin */
965 stw_raw(w ++, -1); /* s16 wp_pin */
966 stw_raw(w ++, 0); /* unsigned flags */
967 stw_raw(w ++, 0); /* s16 power_pin */
968 stw_raw(w ++, 0); /* s16 switch_pin */
969 stw_raw(w ++, 0); /* s16 wp_pin */
972 stw_raw(w ++, OMAP_TAG_TEA5761); /* u16 tag */
973 stw_raw(w ++, 4); /* u16 len */
974 stw_raw(w ++, N8X0_TEA5761_CS_GPIO); /* u16 enable_gpio */
977 partition = (model == 810) ? n810_part_info : n800_part_info;
978 for (; partition->name; partition ++) {
979 stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */
980 stw_raw(w ++, 28); /* u16 len */
981 strcpy((void *) w, partition->name); /* char name[16] */
982 l = (void *) (w + 8);
983 stl_raw(l ++, partition->size); /* unsigned int size */
984 stl_raw(l ++, partition->offset); /* unsigned int offset */
985 stl_raw(l ++, partition->mask); /* unsigned int mask_flags */
989 stw_raw(w ++, OMAP_TAG_BOOT_REASON); /* u16 tag */
990 stw_raw(w ++, 12); /* u16 len */
992 strcpy((void *) w, "por"); /* char reason_str[12] */
993 strcpy((void *) w, "charger"); /* char reason_str[12] */
994 strcpy((void *) w, "32wd_to"); /* char reason_str[12] */
995 strcpy((void *) w, "sw_rst"); /* char reason_str[12] */
996 strcpy((void *) w, "mbus"); /* char reason_str[12] */
997 strcpy((void *) w, "unknown"); /* char reason_str[12] */
998 strcpy((void *) w, "swdg_to"); /* char reason_str[12] */
999 strcpy((void *) w, "sec_vio"); /* char reason_str[12] */
1000 strcpy((void *) w, "pwr_key"); /* char reason_str[12] */
1001 strcpy((void *) w, "rtc_alarm"); /* char reason_str[12] */
1003 strcpy((void *) w, "pwr_key"); /* char reason_str[12] */
1007 tag = (model == 810) ? "RX-44" : "RX-34";
1008 stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
1009 stw_raw(w ++, 24); /* u16 len */
1010 strcpy((void *) w, "product"); /* char component[12] */
1012 strcpy((void *) w, tag); /* char version[12] */
1015 stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
1016 stw_raw(w ++, 24); /* u16 len */
1017 strcpy((void *) w, "hw-build"); /* char component[12] */
1019 strcpy((void *) w, "QEMU " QEMU_VERSION); /* char version[12] */
1022 tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
1023 stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
1024 stw_raw(w ++, 24); /* u16 len */
1025 strcpy((void *) w, "nolo"); /* char component[12] */
1027 strcpy((void *) w, tag); /* char version[12] */
1030 return (void *) w - p;
1033 static int n800_atag_setup(struct arm_boot_info *info, void *p)
1035 return n8x0_atag_setup(p, 800);
1038 static int n810_atag_setup(struct arm_boot_info *info, void *p)
1040 return n8x0_atag_setup(p, 810);
1043 static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
1044 DisplayState *ds, const char *kernel_filename,
1045 const char *kernel_cmdline, const char *initrd_filename,
1046 const char *cpu_model, struct arm_boot_info *binfo, int model)
1048 struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s));
1049 int sdram_size = binfo->ram_size;
1050 int onenandram_size = 0x00010000;
1052 if (ram_size < sdram_size + onenandram_size + OMAP242X_SRAM_SIZE) {
1053 fprintf(stderr, "This architecture uses %i bytes of memory\n",
1054 sdram_size + onenandram_size + OMAP242X_SRAM_SIZE);
1058 s->cpu = omap2420_mpu_init(sdram_size, NULL, cpu_model);
1064 n800_tsc_kbd_setup(s);
1065 else if (model == 810) {
1070 n8x0_dss_setup(s, ds);
1075 /* Setup initial (reset) machine state */
1077 /* Start at the OneNAND bootloader. */
1078 s->cpu->env->regs[15] = 0;
1080 if (kernel_filename) {
1081 /* Or at the linux loader. */
1082 binfo->kernel_filename = kernel_filename;
1083 binfo->kernel_cmdline = kernel_cmdline;
1084 binfo->initrd_filename = initrd_filename;
1085 arm_load_kernel(s->cpu->env, binfo);
1087 qemu_register_reset(n8x0_boot_init, s);
1091 dpy_resize(ds, 800, 480);
1094 static struct arm_boot_info n800_binfo = {
1095 .loader_start = OMAP2_Q2_BASE,
1096 /* Actually two chips of 0x4000000 bytes each */
1097 .ram_size = 0x08000000,
1099 .atag_board = n800_atag_setup,
1102 static struct arm_boot_info n810_binfo = {
1103 .loader_start = OMAP2_Q2_BASE,
1104 /* Actually two chips of 0x4000000 bytes each */
1105 .ram_size = 0x08000000,
1106 /* 0x60c and 0x6bf (WiMAX Edition) have been assigned but are not
1107 * used by some older versions of the bootloader and 5555 is used
1108 * instead (including versions that shipped with many devices). */
1110 .atag_board = n810_atag_setup,
1113 static void n800_init(ram_addr_t ram_size, int vga_ram_size,
1114 const char *boot_device, DisplayState *ds,
1115 const char *kernel_filename, const char *kernel_cmdline,
1116 const char *initrd_filename, const char *cpu_model)
1118 return n8x0_init(ram_size, boot_device, ds,
1119 kernel_filename, kernel_cmdline, initrd_filename,
1120 cpu_model, &n800_binfo, 800);
1123 static void n810_init(ram_addr_t ram_size, int vga_ram_size,
1124 const char *boot_device, DisplayState *ds,
1125 const char *kernel_filename, const char *kernel_cmdline,
1126 const char *initrd_filename, const char *cpu_model)
1128 return n8x0_init(ram_size, boot_device, ds,
1129 kernel_filename, kernel_cmdline, initrd_filename,
1130 cpu_model, &n810_binfo, 810);
1133 QEMUMachine n800_machine = {
1135 "Nokia N800 tablet aka. RX-34 (OMAP2420)",
1137 (0x08000000 + 0x00010000 + OMAP242X_SRAM_SIZE) | RAMSIZE_FIXED,
1140 QEMUMachine n810_machine = {
1142 "Nokia N810 tablet aka. RX-44 (OMAP2420)",
1144 (0x08000000 + 0x00010000 + OMAP242X_SRAM_SIZE) | RAMSIZE_FIXED,