Revert "Use correct types to enable > 2G support" (r4238), it is
[qemu] / hw / nseries.c
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  *
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,
20  * MA 02111-1307 USA
21  */
22
23 #include "qemu-common.h"
24 #include "sysemu.h"
25 #include "omap.h"
26 #include "arm-misc.h"
27 #include "irq.h"
28 #include "console.h"
29 #include "boards.h"
30 #include "i2c.h"
31 #include "devices.h"
32 #include "flash.h"
33 #include "hw.h"
34
35 /* Nokia N8x0 support */
36 struct n800_s {
37     struct omap_mpu_state_s *cpu;
38
39     struct rfbi_chip_s blizzard;
40     struct uwire_slave_s *ts;
41     i2c_bus *i2c;
42
43     int keymap[0x80];
44
45     struct tusb_s *usb;
46     void *retu;
47     void *tahvo;
48 };
49
50 /* GPIO pins */
51 #define N800_TUSB_ENABLE_GPIO           0
52 #define N800_MMC2_WP_GPIO               8
53 #define N800_UNKNOWN_GPIO0              9       /* out */
54 #define N800_UNKNOWN_GPIO1              10      /* out */
55 #define N800_CAM_TURN_GPIO              12
56 #define N800_BLIZZARD_POWERDOWN_GPIO    15
57 #define N800_MMC1_WP_GPIO               23
58 #define N8X0_ONENAND_GPIO               26
59 #define N800_UNKNOWN_GPIO2              53      /* out */
60 #define N8X0_TUSB_INT_GPIO              58
61 #define N800_BT_WKUP_GPIO               61
62 #define N800_STI_GPIO                   62
63 #define N8X0_CBUS_SEL_GPIO              64
64 #define N8X0_CBUS_CLK_GPIO              65      /* sure? */
65 #define N8X0_CBUS_DAT_GPIO              66
66 #define N800_WLAN_IRQ_GPIO              87
67 #define N800_BT_RESET_GPIO              92
68 #define N800_TEA5761_CS_GPIO            93
69 #define N800_UNKNOWN_GPIO               94
70 #define N800_CAM_ACT_GPIO               95
71 #define N800_MMC_CS_GPIO                96
72 #define N800_WLAN_PWR_GPIO              97
73 #define N8X0_BT_HOST_WKUP_GPIO          98
74 #define N800_UNKNOWN_GPIO3              101     /* out */
75 #define N810_KB_LOCK_GPIO               102
76 #define N800_TSC_TS_GPIO                103
77 #define N810_TSC2005_GPIO               106
78 #define N800_HEADPHONE_GPIO             107
79 #define N8X0_RETU_GPIO                  108
80 #define N800_TSC_KP_IRQ_GPIO            109
81 #define N810_KEYBOARD_GPIO              109
82 #define N800_BAT_COVER_GPIO             110
83 #define N810_SLIDE_GPIO                 110
84 #define N8X0_TAHVO_GPIO                 111
85 #define N800_UNKNOWN_GPIO4              112     /* out */
86 #define N810_TSC_RESET_GPIO             118
87 #define N800_TSC_RESET_GPIO             119     /* ? */
88 #define N8X0_TMP105_GPIO                125
89
90 /* Config */
91 #define XLDR_LL_UART                    1
92
93 /* Addresses on the I2C bus */
94 #define N8X0_TMP105_ADDR                0x48
95 #define N8X0_MENELAUS_ADDR              0x72
96
97 /* Chipselects on GPMC NOR interface */
98 #define N8X0_ONENAND_CS                 0
99 #define N8X0_USB_ASYNC_CS               1
100 #define N8X0_USB_SYNC_CS                4
101
102 static void n800_mmc_cs_cb(void *opaque, int line, int level)
103 {
104     /* TODO: this seems to actually be connected to the menelaus, to
105      * which also both MMC slots connect.  */
106     omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
107
108     printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
109 }
110
111 static void n800_gpio_setup(struct n800_s *s)
112 {
113     qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1);
114     omap2_gpio_out_set(s->cpu->gpif, N800_MMC_CS_GPIO, mmc_cs[0]);
115
116     qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]);
117 }
118
119 static void n8x0_nand_setup(struct n800_s *s)
120 {
121     /* Either ec40xx or ec48xx are OK for the ID */
122     omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
123                     onenand_base_unmap,
124                     onenand_init(0xec4800, 1,
125                             omap2_gpio_in_get(s->cpu->gpif,
126                                     N8X0_ONENAND_GPIO)[0]));
127 }
128
129 static void n800_i2c_setup(struct n800_s *s)
130 {
131     qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0];
132
133     /* Attach the CPU on one end of our I2C bus.  */
134     s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
135
136     /* Attach a menelaus PM chip */
137     i2c_set_slave_address(
138                     twl92230_init(s->i2c,
139                             s->cpu->irq[0][OMAP_INT_24XX_SYS_NIRQ]),
140                     N8X0_MENELAUS_ADDR);
141
142     /* Attach a TMP105 PM chip (A0 wired to ground) */
143     i2c_set_slave_address(tmp105_init(s->i2c, tmp_irq), N8X0_TMP105_ADDR);
144 }
145
146 /* Touchscreen and keypad controller */
147 #define RETU_KEYCODE    61      /* F3 */
148
149 static void n800_key_event(void *opaque, int keycode)
150 {
151     struct n800_s *s = (struct n800_s *) opaque;
152     int code = s->keymap[keycode & 0x7f];
153
154     if (code == -1) {
155         if ((keycode & 0x7f) == RETU_KEYCODE)
156             retu_key_event(s->retu, !(keycode & 0x80));
157         return;
158     }
159
160     tsc210x_key_event(s->ts, code, !(keycode & 0x80));
161 }
162
163 static const int n800_keys[16] = {
164     -1,
165     72, /* Up */
166     63, /* Home (F5) */
167     -1,
168     75, /* Left */
169     28, /* Enter */
170     77, /* Right */
171     -1,
172     1,  /* Cycle (ESC) */
173     80, /* Down */
174     62, /* Menu (F4) */
175     -1,
176     66, /* Zoom- (F8) */
177     64, /* FS (F6) */
178     65, /* Zoom+ (F7) */
179     -1,
180 };
181
182 static struct mouse_transform_info_s n800_pointercal = {
183     .x = 800,
184     .y = 480,
185     .a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
186 };
187
188 static void n800_tsc_setup(struct n800_s *s)
189 {
190     int i;
191
192     /* XXX: are the three pins inverted inside the chip between the
193      * tsc and the cpu (N4111)?  */
194     qemu_irq penirq = 0;        /* NC */
195     qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0];
196     qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0];
197
198     s->ts = tsc2301_init(penirq, kbirq, dav, 0);
199
200     for (i = 0; i < 0x80; i ++)
201         s->keymap[i] = -1;
202     for (i = 0; i < 0x10; i ++)
203         if (n800_keys[i] >= 0)
204             s->keymap[n800_keys[i]] = i;
205
206     qemu_add_kbd_event_handler(n800_key_event, s);
207
208     tsc210x_set_transform(s->ts, &n800_pointercal);
209 }
210
211 /* LCD MIPI DBI-C controller (URAL) */
212 struct mipid_s {
213     int resp[4];
214     int param[4];
215     int p;
216     int pm;
217     int cmd;
218
219     int sleep;
220     int booster;
221     int te;
222     int selfcheck;
223     int partial;
224     int normal;
225     int vscr;
226     int invert;
227     int onoff;
228     int gamma;
229     uint32_t id;
230 };
231
232 static void mipid_reset(struct mipid_s *s)
233 {
234     if (!s->sleep)
235         fprintf(stderr, "%s: Display off\n", __FUNCTION__);
236
237     s->pm = 0;
238     s->cmd = 0;
239
240     s->sleep = 1;
241     s->booster = 0;
242     s->selfcheck =
243             (1 << 7) |  /* Register loading OK.  */
244             (1 << 5) |  /* The chip is attached.  */
245             (1 << 4);   /* Display glass still in one piece.  */
246     s->te = 0;
247     s->partial = 0;
248     s->normal = 1;
249     s->vscr = 0;
250     s->invert = 0;
251     s->onoff = 1;
252     s->gamma = 0;
253 }
254
255 static uint32_t mipid_txrx(void *opaque, uint32_t cmd)
256 {
257     struct mipid_s *s = (struct mipid_s *) opaque;
258     uint8_t ret;
259
260     if (s->p >= sizeof(s->resp) / sizeof(*s->resp))
261         ret = 0;
262     else
263         ret = s->resp[s->p ++];
264     if (s->pm --> 0)
265         s->param[s->pm] = cmd;
266     else
267         s->cmd = cmd;
268
269     switch (s->cmd) {
270     case 0x00:  /* NOP */
271         break;
272
273     case 0x01:  /* SWRESET */
274         mipid_reset(s);
275         break;
276
277     case 0x02:  /* BSTROFF */
278         s->booster = 0;
279         break;
280     case 0x03:  /* BSTRON */
281         s->booster = 1;
282         break;
283
284     case 0x04:  /* RDDID */
285         s->p = 0;
286         s->resp[0] = (s->id >> 16) & 0xff;
287         s->resp[1] = (s->id >>  8) & 0xff;
288         s->resp[2] = (s->id >>  0) & 0xff;
289         break;
290
291     case 0x06:  /* RD_RED */
292     case 0x07:  /* RD_GREEN */
293         /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so
294          * for the bootloader one needs to change this.  */
295     case 0x08:  /* RD_BLUE */
296         s->p = 0;
297         /* TODO: return first pixel components */
298         s->resp[0] = 0x01;
299         break;
300
301     case 0x09:  /* RDDST */
302         s->p = 0;
303         s->resp[0] = s->booster << 7;
304         s->resp[1] = (5 << 4) | (s->partial << 2) |
305                 (s->sleep << 1) | s->normal;
306         s->resp[2] = (s->vscr << 7) | (s->invert << 5) |
307                 (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);
308         s->resp[3] = s->gamma << 6;
309         break;
310
311     case 0x0a:  /* RDDPM */
312         s->p = 0;
313         s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |
314                 (s->partial << 5) | (s->sleep << 6) | (s->booster << 7);
315         break;
316     case 0x0b:  /* RDDMADCTR */
317         s->p = 0;
318         s->resp[0] = 0;
319         break;
320     case 0x0c:  /* RDDCOLMOD */
321         s->p = 0;
322         s->resp[0] = 5; /* 65K colours */
323         break;
324     case 0x0d:  /* RDDIM */
325         s->p = 0;
326         s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;
327         break;
328     case 0x0e:  /* RDDSM */
329         s->p = 0;
330         s->resp[0] = s->te << 7;
331         break;
332     case 0x0f:  /* RDDSDR */
333         s->p = 0;
334         s->resp[0] = s->selfcheck;
335         break;
336
337     case 0x10:  /* SLPIN */
338         s->sleep = 1;
339         break;
340     case 0x11:  /* SLPOUT */
341         s->sleep = 0;
342         s->selfcheck ^= 1 << 6; /* POFF self-diagnosis Ok */
343         break;
344
345     case 0x12:  /* PTLON */
346         s->partial = 1;
347         s->normal = 0;
348         s->vscr = 0;
349         break;
350     case 0x13:  /* NORON */
351         s->partial = 0;
352         s->normal = 1;
353         s->vscr = 0;
354         break;
355
356     case 0x20:  /* INVOFF */
357         s->invert = 0;
358         break;
359     case 0x21:  /* INVON */
360         s->invert = 1;
361         break;
362
363     case 0x22:  /* APOFF */
364     case 0x23:  /* APON */
365         goto bad_cmd;
366
367     case 0x25:  /* WRCNTR */
368         if (s->pm < 0)
369             s->pm = 1;
370         goto bad_cmd;
371
372     case 0x26:  /* GAMSET */
373         if (!s->pm)
374             s->gamma = ffs(s->param[0] & 0xf) - 1;
375         else if (s->pm < 0)
376             s->pm = 1;
377         break;
378
379     case 0x28:  /* DISPOFF */
380         s->onoff = 0;
381         fprintf(stderr, "%s: Display off\n", __FUNCTION__);
382         break;
383     case 0x29:  /* DISPON */
384         s->onoff = 1;
385         fprintf(stderr, "%s: Display on\n", __FUNCTION__);
386         break;
387
388     case 0x2a:  /* CASET */
389     case 0x2b:  /* RASET */
390     case 0x2c:  /* RAMWR */
391     case 0x2d:  /* RGBSET */
392     case 0x2e:  /* RAMRD */
393     case 0x30:  /* PTLAR */
394     case 0x33:  /* SCRLAR */
395         goto bad_cmd;
396
397     case 0x34:  /* TEOFF */
398         s->te = 0;
399         break;
400     case 0x35:  /* TEON */
401         if (!s->pm)
402             s->te = 1;
403         else if (s->pm < 0)
404             s->pm = 1;
405         break;
406
407     case 0x36:  /* MADCTR */
408         goto bad_cmd;
409
410     case 0x37:  /* VSCSAD */
411         s->partial = 0;
412         s->normal = 0;
413         s->vscr = 1;
414         break;
415
416     case 0x38:  /* IDMOFF */
417     case 0x39:  /* IDMON */
418     case 0x3a:  /* COLMOD */
419         goto bad_cmd;
420
421     case 0xb0:  /* CLKINT / DISCTL */
422     case 0xb1:  /* CLKEXT */
423         if (s->pm < 0)
424             s->pm = 2;
425         break;
426
427     case 0xb4:  /* FRMSEL */
428         break;
429
430     case 0xb5:  /* FRM8SEL */
431     case 0xb6:  /* TMPRNG / INIESC */
432     case 0xb7:  /* TMPHIS / NOP2 */
433     case 0xb8:  /* TMPREAD / MADCTL */
434     case 0xba:  /* DISTCTR */
435     case 0xbb:  /* EPVOL */
436         goto bad_cmd;
437
438     case 0xbd:  /* Unknown */
439         s->p = 0;
440         s->resp[0] = 0;
441         s->resp[1] = 1;
442         break;
443
444     case 0xc2:  /* IFMOD */
445         if (s->pm < 0)
446             s->pm = 2;
447         break;
448
449     case 0xc6:  /* PWRCTL */
450     case 0xc7:  /* PPWRCTL */
451     case 0xd0:  /* EPWROUT */
452     case 0xd1:  /* EPWRIN */
453     case 0xd4:  /* RDEV */
454     case 0xd5:  /* RDRR */
455         goto bad_cmd;
456
457     case 0xda:  /* RDID1 */
458         s->p = 0;
459         s->resp[0] = (s->id >> 16) & 0xff;
460         break;
461     case 0xdb:  /* RDID2 */
462         s->p = 0;
463         s->resp[0] = (s->id >>  8) & 0xff;
464         break;
465     case 0xdc:  /* RDID3 */
466         s->p = 0;
467         s->resp[0] = (s->id >>  0) & 0xff;
468         break;
469
470     default:
471     bad_cmd:
472         fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, s->cmd);
473         break;
474     }
475
476     return ret;
477 }
478
479 static void *mipid_init(void)
480 {
481     struct mipid_s *s = (struct mipid_s *) qemu_mallocz(sizeof(*s));
482
483     s->id = 0x838f03;
484     mipid_reset(s);
485
486     return s;
487 }
488
489 static void n800_spi_setup(struct n800_s *s)
490 {
491     void *tsc2301 = s->ts->opaque;
492     void *mipid = mipid_init();
493
494     omap_mcspi_attach(s->cpu->mcspi[0], tsc210x_txrx, tsc2301, 0);
495     omap_mcspi_attach(s->cpu->mcspi[0], mipid_txrx, mipid, 1);
496 }
497
498 /* This task is normally performed by the bootloader.  If we're loading
499  * a kernel directly, we need to enable the Blizzard ourselves.  */
500 static void n800_dss_init(struct rfbi_chip_s *chip)
501 {
502     uint8_t *fb_blank;
503
504     chip->write(chip->opaque, 0, 0x2a);         /* LCD Width register */
505     chip->write(chip->opaque, 1, 0x64);
506     chip->write(chip->opaque, 0, 0x2c);         /* LCD HNDP register */
507     chip->write(chip->opaque, 1, 0x1e);
508     chip->write(chip->opaque, 0, 0x2e);         /* LCD Height 0 register */
509     chip->write(chip->opaque, 1, 0xe0);
510     chip->write(chip->opaque, 0, 0x30);         /* LCD Height 1 register */
511     chip->write(chip->opaque, 1, 0x01);
512     chip->write(chip->opaque, 0, 0x32);         /* LCD VNDP register */
513     chip->write(chip->opaque, 1, 0x06);
514     chip->write(chip->opaque, 0, 0x68);         /* Display Mode register */
515     chip->write(chip->opaque, 1, 1);            /* Enable bit */
516
517     chip->write(chip->opaque, 0, 0x6c); 
518     chip->write(chip->opaque, 1, 0x00);         /* Input X Start Position */
519     chip->write(chip->opaque, 1, 0x00);         /* Input X Start Position */
520     chip->write(chip->opaque, 1, 0x00);         /* Input Y Start Position */
521     chip->write(chip->opaque, 1, 0x00);         /* Input Y Start Position */
522     chip->write(chip->opaque, 1, 0x1f);         /* Input X End Position */
523     chip->write(chip->opaque, 1, 0x03);         /* Input X End Position */
524     chip->write(chip->opaque, 1, 0xdf);         /* Input Y End Position */
525     chip->write(chip->opaque, 1, 0x01);         /* Input Y End Position */
526     chip->write(chip->opaque, 1, 0x00);         /* Output X Start Position */
527     chip->write(chip->opaque, 1, 0x00);         /* Output X Start Position */
528     chip->write(chip->opaque, 1, 0x00);         /* Output Y Start Position */
529     chip->write(chip->opaque, 1, 0x00);         /* Output Y Start Position */
530     chip->write(chip->opaque, 1, 0x1f);         /* Output X End Position */
531     chip->write(chip->opaque, 1, 0x03);         /* Output X End Position */
532     chip->write(chip->opaque, 1, 0xdf);         /* Output Y End Position */
533     chip->write(chip->opaque, 1, 0x01);         /* Output Y End Position */
534     chip->write(chip->opaque, 1, 0x01);         /* Input Data Format */
535     chip->write(chip->opaque, 1, 0x01);         /* Data Source Select */
536
537     fb_blank = memset(qemu_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
538     /* Display Memory Data Port */
539     chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
540     free(fb_blank);
541 }
542
543 static void n800_dss_setup(struct n800_s *s, DisplayState *ds)
544 {
545     s->blizzard.opaque = s1d13745_init(0, ds);
546     s->blizzard.block = s1d13745_write_block;
547     s->blizzard.write = s1d13745_write;
548     s->blizzard.read = s1d13745_read;
549
550     omap_rfbi_attach(s->cpu->dss, 0, &s->blizzard);
551 }
552
553 static void n800_cbus_setup(struct n800_s *s)
554 {
555     qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N8X0_CBUS_DAT_GPIO)[0];
556     qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_RETU_GPIO)[0];
557     qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TAHVO_GPIO)[0];
558
559     struct cbus_s *cbus = cbus_init(dat_out);
560
561     omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_CLK_GPIO, cbus->clk);
562     omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_DAT_GPIO, cbus->dat);
563     omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_SEL_GPIO, cbus->sel);
564
565     cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
566     cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
567 }
568
569 static void n800_usb_power_cb(void *opaque, int line, int level)
570 {
571     struct n800_s *s = opaque;
572
573     tusb6010_power(s->usb, level);
574 }
575
576 static void n800_usb_setup(struct n800_s *s)
577 {
578     qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0];
579     qemu_irq tusb_pwr = qemu_allocate_irqs(n800_usb_power_cb, s, 1)[0];
580     struct tusb_s *tusb = tusb6010_init(tusb_irq);
581
582     /* Using the NOR interface */
583     omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
584                     tusb6010_async_io(tusb), 0, 0, tusb);
585     omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
586                     tusb6010_sync_io(tusb), 0, 0, tusb);
587
588     s->usb = tusb;
589     omap2_gpio_out_set(s->cpu->gpif, N800_TUSB_ENABLE_GPIO, tusb_pwr);
590 }
591
592 /* This task is normally performed by the bootloader.  If we're loading
593  * a kernel directly, we need to set up GPMC mappings ourselves.  */
594 static void n800_gpmc_init(struct n800_s *s)
595 {
596     uint32_t config7 =
597             (0xf << 8) |        /* MASKADDRESS */
598             (1 << 6) |          /* CSVALID */
599             (4 << 0);           /* BASEADDRESS */
600
601     cpu_physical_memory_write(0x6800a078,               /* GPMC_CONFIG7_0 */
602                     (void *) &config7, sizeof(config7));
603 }
604
605 /* Setup sequence done by the bootloader */
606 static void n800_boot_init(void *opaque)
607 {
608     struct n800_s *s = (struct n800_s *) opaque;
609     uint32_t buf;
610
611     /* PRCM setup */
612 #define omap_writel(addr, val)  \
613     buf = (val);                        \
614     cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf))
615
616     omap_writel(0x48008060, 0x41);              /* PRCM_CLKSRC_CTRL */
617     omap_writel(0x48008070, 1);                 /* PRCM_CLKOUT_CTRL */
618     omap_writel(0x48008078, 0);                 /* PRCM_CLKEMUL_CTRL */
619     omap_writel(0x48008090, 0);                 /* PRCM_VOLTSETUP */
620     omap_writel(0x48008094, 0);                 /* PRCM_CLKSSETUP */
621     omap_writel(0x48008098, 0);                 /* PRCM_POLCTRL */
622     omap_writel(0x48008140, 2);                 /* CM_CLKSEL_MPU */
623     omap_writel(0x48008148, 0);                 /* CM_CLKSTCTRL_MPU */
624     omap_writel(0x48008158, 1);                 /* RM_RSTST_MPU */
625     omap_writel(0x480081c8, 0x15);              /* PM_WKDEP_MPU */
626     omap_writel(0x480081d4, 0x1d4);             /* PM_EVGENCTRL_MPU */
627     omap_writel(0x480081d8, 0);                 /* PM_EVEGENONTIM_MPU */
628     omap_writel(0x480081dc, 0);                 /* PM_EVEGENOFFTIM_MPU */
629     omap_writel(0x480081e0, 0xc);               /* PM_PWSTCTRL_MPU */
630     omap_writel(0x48008200, 0x047e7ff7);        /* CM_FCLKEN1_CORE */
631     omap_writel(0x48008204, 0x00000004);        /* CM_FCLKEN2_CORE */
632     omap_writel(0x48008210, 0x047e7ff1);        /* CM_ICLKEN1_CORE */
633     omap_writel(0x48008214, 0x00000004);        /* CM_ICLKEN2_CORE */
634     omap_writel(0x4800821c, 0x00000000);        /* CM_ICLKEN4_CORE */
635     omap_writel(0x48008230, 0);                 /* CM_AUTOIDLE1_CORE */
636     omap_writel(0x48008234, 0);                 /* CM_AUTOIDLE2_CORE */
637     omap_writel(0x48008238, 7);                 /* CM_AUTOIDLE3_CORE */
638     omap_writel(0x4800823c, 0);                 /* CM_AUTOIDLE4_CORE */
639     omap_writel(0x48008240, 0x04360626);        /* CM_CLKSEL1_CORE */
640     omap_writel(0x48008244, 0x00000014);        /* CM_CLKSEL2_CORE */
641     omap_writel(0x48008248, 0);                 /* CM_CLKSTCTRL_CORE */
642     omap_writel(0x48008300, 0x00000000);        /* CM_FCLKEN_GFX */
643     omap_writel(0x48008310, 0x00000000);        /* CM_ICLKEN_GFX */
644     omap_writel(0x48008340, 0x00000001);        /* CM_CLKSEL_GFX */
645     omap_writel(0x48008400, 0x00000004);        /* CM_FCLKEN_WKUP */
646     omap_writel(0x48008410, 0x00000004);        /* CM_ICLKEN_WKUP */
647     omap_writel(0x48008440, 0x00000000);        /* CM_CLKSEL_WKUP */
648     omap_writel(0x48008500, 0x000000cf);        /* CM_CLKEN_PLL */
649     omap_writel(0x48008530, 0x0000000c);        /* CM_AUTOIDLE_PLL */
650     omap_writel(0x48008540,                     /* CM_CLKSEL1_PLL */
651                     (0x78 << 12) | (6 << 8));
652     omap_writel(0x48008544, 2);                 /* CM_CLKSEL2_PLL */
653
654     /* GPMC setup */
655     n800_gpmc_init(s);
656
657     /* Video setup */
658     n800_dss_init(&s->blizzard);
659
660     /* CPU setup */
661     s->cpu->env->regs[15] = s->cpu->env->boot_info->loader_start;
662     s->cpu->env->GE = 0x5;
663 }
664
665 #define OMAP_TAG_NOKIA_BT       0x4e01
666 #define OMAP_TAG_WLAN_CX3110X   0x4e02
667 #define OMAP_TAG_CBUS           0x4e03
668 #define OMAP_TAG_EM_ASIC_BB5    0x4e04
669
670 static int n800_atag_setup(struct arm_boot_info *info, void *p)
671 {
672     uint8_t *b;
673     uint16_t *w;
674     uint32_t *l;
675
676     w = p;
677
678     stw_raw(w ++, OMAP_TAG_UART);               /* u16 tag */
679     stw_raw(w ++, 4);                           /* u16 len */
680     stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
681     w ++;
682
683     stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5);        /* u16 tag */
684     stw_raw(w ++, 4);                           /* u16 len */
685     stw_raw(w ++, N8X0_RETU_GPIO);              /* s16 retu_irq_gpio */
686     stw_raw(w ++, N8X0_TAHVO_GPIO);             /* s16 tahvo_irq_gpio */
687
688     stw_raw(w ++, OMAP_TAG_CBUS);               /* u16 tag */
689     stw_raw(w ++, 8);                           /* u16 len */
690     stw_raw(w ++, N8X0_CBUS_CLK_GPIO);          /* s16 clk_gpio */
691     stw_raw(w ++, N8X0_CBUS_DAT_GPIO);          /* s16 dat_gpio */
692     stw_raw(w ++, N8X0_CBUS_SEL_GPIO);          /* s16 sel_gpio */
693     w ++;
694
695     stw_raw(w ++, OMAP_TAG_GPIO_SWITCH);        /* u16 tag */
696     stw_raw(w ++, 20);                          /* u16 len */
697     strcpy((void *) w, "bat_cover");            /* char name[12] */
698     w += 6;
699     stw_raw(w ++, N800_BAT_COVER_GPIO);         /* u16 gpio */
700     stw_raw(w ++, 0x01);
701     stw_raw(w ++, 0);
702     stw_raw(w ++, 0);
703
704     stw_raw(w ++, OMAP_TAG_GPIO_SWITCH);        /* u16 tag */
705     stw_raw(w ++, 20);                          /* u16 len */
706     strcpy((void *) w, "cam_act");              /* char name[12] */
707     w += 6;
708     stw_raw(w ++, N800_CAM_ACT_GPIO);           /* u16 gpio */
709     stw_raw(w ++, 0x20);
710     stw_raw(w ++, 0);
711     stw_raw(w ++, 0);
712
713     stw_raw(w ++, OMAP_TAG_GPIO_SWITCH);        /* u16 tag */
714     stw_raw(w ++, 20);                          /* u16 len */
715     strcpy((void *) w, "cam_turn");             /* char name[12] */
716     w += 6;
717     stw_raw(w ++, N800_CAM_TURN_GPIO);          /* u16 gpio */
718     stw_raw(w ++, 0x21);
719     stw_raw(w ++, 0);
720     stw_raw(w ++, 0);
721
722     stw_raw(w ++, OMAP_TAG_GPIO_SWITCH);        /* u16 tag */
723     stw_raw(w ++, 20);                          /* u16 len */
724     strcpy((void *) w, "headphone");            /* char name[12] */
725     w += 6;
726     stw_raw(w ++, N800_HEADPHONE_GPIO);         /* u16 gpio */
727     stw_raw(w ++, 0x11);
728     stw_raw(w ++, 0);
729     stw_raw(w ++, 0);
730
731     stw_raw(w ++, OMAP_TAG_NOKIA_BT);           /* u16 tag */
732     stw_raw(w ++, 12);                          /* u16 len */
733     b = (void *) w;
734     stb_raw(b ++, 0x01);                        /* u8 chip_type (CSR) */
735     stb_raw(b ++, N800_BT_WKUP_GPIO);           /* u8 bt_wakeup_gpio */
736     stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO);      /* u8 host_wakeup_gpio */
737     stb_raw(b ++, N800_BT_RESET_GPIO);          /* u8 reset_gpio */
738     stb_raw(b ++, 1);                           /* u8 bt_uart */
739     memset(b, 0, 6);                            /* u8 bd_addr[6] */
740     b += 6;
741     stb_raw(b ++, 0x02);                        /* u8 bt_sysclk (38.4) */
742     w = (void *) b;
743
744     stw_raw(w ++, OMAP_TAG_WLAN_CX3110X);       /* u16 tag */
745     stw_raw(w ++, 8);                           /* u16 len */
746     stw_raw(w ++, 0x25);                        /* u8 chip_type */
747     stw_raw(w ++, N800_WLAN_PWR_GPIO);          /* s16 power_gpio */
748     stw_raw(w ++, N800_WLAN_IRQ_GPIO);          /* s16 irq_gpio */
749     stw_raw(w ++, -1);                          /* s16 spi_cs_gpio */
750
751     stw_raw(w ++, OMAP_TAG_MMC);                /* u16 tag */
752     stw_raw(w ++, 16);                          /* u16 len */
753     stw_raw(w ++, 0xf);                         /* unsigned flags */
754     stw_raw(w ++, -1);                          /* s16 power_pin */
755     stw_raw(w ++, -1);                          /* s16 switch_pin */
756     stw_raw(w ++, -1);                          /* s16 wp_pin */
757     stw_raw(w ++, 0);                           /* unsigned flags */
758     stw_raw(w ++, 0);                           /* s16 power_pin */
759     stw_raw(w ++, 0);                           /* s16 switch_pin */
760     stw_raw(w ++, 0);                           /* s16 wp_pin */
761
762     stw_raw(w ++, OMAP_TAG_TEA5761);            /* u16 tag */
763     stw_raw(w ++, 4);                           /* u16 len */
764     stw_raw(w ++, N800_TEA5761_CS_GPIO);        /* u16 enable_gpio */
765     w ++;
766
767     stw_raw(w ++, OMAP_TAG_PARTITION);          /* u16 tag */
768     stw_raw(w ++, 28);                          /* u16 len */
769     strcpy((void *) w, "bootloader");           /* char name[16] */
770     l = (void *) (w + 8);
771     stl_raw(l ++, 0x00020000);                  /* unsigned int size */
772     stl_raw(l ++, 0x00000000);                  /* unsigned int offset */
773     stl_raw(l ++, 0x3);                         /* unsigned int mask_flags */
774     w = (void *) l;
775
776     stw_raw(w ++, OMAP_TAG_PARTITION);          /* u16 tag */
777     stw_raw(w ++, 28);                          /* u16 len */
778     strcpy((void *) w, "config");               /* char name[16] */
779     l = (void *) (w + 8);
780     stl_raw(l ++, 0x00060000);                  /* unsigned int size */
781     stl_raw(l ++, 0x00020000);                  /* unsigned int offset */
782     stl_raw(l ++, 0x0);                         /* unsigned int mask_flags */
783     w = (void *) l;
784
785     stw_raw(w ++, OMAP_TAG_PARTITION);          /* u16 tag */
786     stw_raw(w ++, 28);                          /* u16 len */
787     strcpy((void *) w, "kernel");               /* char name[16] */
788     l = (void *) (w + 8);
789     stl_raw(l ++, 0x00200000);                  /* unsigned int size */
790     stl_raw(l ++, 0x00080000);                  /* unsigned int offset */
791     stl_raw(l ++, 0x0);                         /* unsigned int mask_flags */
792     w = (void *) l;
793
794     stw_raw(w ++, OMAP_TAG_PARTITION);          /* u16 tag */
795     stw_raw(w ++, 28);                          /* u16 len */
796     strcpy((void *) w, "initfs");               /* char name[16] */
797     l = (void *) (w + 8);
798     stl_raw(l ++, 0x00200000);                  /* unsigned int size */
799     stl_raw(l ++, 0x00280000);                  /* unsigned int offset */
800     stl_raw(l ++, 0x3);                         /* unsigned int mask_flags */
801     w = (void *) l;
802
803     stw_raw(w ++, OMAP_TAG_PARTITION);          /* u16 tag */
804     stw_raw(w ++, 28);                          /* u16 len */
805     strcpy((void *) w, "rootfs");               /* char name[16] */
806     l = (void *) (w + 8);
807     stl_raw(l ++, 0x0fb80000);                  /* unsigned int size */
808     stl_raw(l ++, 0x00480000);                  /* unsigned int offset */
809     stl_raw(l ++, 0x3);                         /* unsigned int mask_flags */
810     w = (void *) l;
811
812     stw_raw(w ++, OMAP_TAG_BOOT_REASON);        /* u16 tag */
813     stw_raw(w ++, 12);                          /* u16 len */
814 #if 0
815     strcpy((void *) w, "por");                  /* char reason_str[12] */
816     strcpy((void *) w, "charger");              /* char reason_str[12] */
817     strcpy((void *) w, "32wd_to");              /* char reason_str[12] */
818     strcpy((void *) w, "sw_rst");               /* char reason_str[12] */
819     strcpy((void *) w, "mbus");                 /* char reason_str[12] */
820     strcpy((void *) w, "unknown");              /* char reason_str[12] */
821     strcpy((void *) w, "swdg_to");              /* char reason_str[12] */
822     strcpy((void *) w, "sec_vio");              /* char reason_str[12] */
823     strcpy((void *) w, "pwr_key");              /* char reason_str[12] */
824     strcpy((void *) w, "rtc_alarm");            /* char reason_str[12] */
825 #else
826     strcpy((void *) w, "pwr_key");              /* char reason_str[12] */
827 #endif
828     w += 6;
829
830 #if 0   /* N810 */
831     stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
832     stw_raw(w ++, 24);                          /* u16 len */
833     strcpy((void *) w, "product");              /* char component[12] */
834     w += 6;
835     strcpy((void *) w, "RX-44");                /* char version[12] */
836     w += 6;
837
838     stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
839     stw_raw(w ++, 24);                          /* u16 len */
840     strcpy((void *) w, "hw-build");             /* char component[12] */
841     w += 6;
842     strcpy((void *) w, "QEMU");                 /* char version[12] */
843     w += 6;
844
845     stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
846     stw_raw(w ++, 24);                          /* u16 len */
847     strcpy((void *) w, "nolo");                 /* char component[12] */
848     w += 6;
849     strcpy((void *) w, "1.1.10-qemu");          /* char version[12] */
850     w += 6;
851 #else
852     stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
853     stw_raw(w ++, 24);                          /* u16 len */
854     strcpy((void *) w, "product");              /* char component[12] */
855     w += 6;
856     strcpy((void *) w, "RX-34");                /* char version[12] */
857     w += 6;
858
859     stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
860     stw_raw(w ++, 24);                          /* u16 len */
861     strcpy((void *) w, "hw-build");             /* char component[12] */
862     w += 6;
863     strcpy((void *) w, "QEMU");                 /* char version[12] */
864     w += 6;
865
866     stw_raw(w ++, OMAP_TAG_VERSION_STR);        /* u16 tag */
867     stw_raw(w ++, 24);                          /* u16 len */
868     strcpy((void *) w, "nolo");                 /* char component[12] */
869     w += 6;
870     strcpy((void *) w, "1.1.6-qemu");           /* char version[12] */
871     w += 6;
872 #endif
873
874     stw_raw(w ++, OMAP_TAG_LCD);                /* u16 tag */
875     stw_raw(w ++, 36);                          /* u16 len */
876     strcpy((void *) w, "QEMU LCD panel");       /* char panel_name[16] */
877     w += 8;
878     strcpy((void *) w, "blizzard");             /* char ctrl_name[16] */
879     w += 8;
880     stw_raw(w ++, 5);                           /* TODO s16 nreset_gpio */
881     stw_raw(w ++, 16);                          /* u8 data_lines */
882
883     return (void *) w - p;
884 }
885
886 static struct arm_boot_info n800_binfo = {
887     .loader_start = OMAP2_Q2_BASE,
888     /* Actually two chips of 0x4000000 bytes each */
889     .ram_size = 0x08000000,
890     .board_id = 0x4f7,
891     .atag_board = n800_atag_setup,
892 };
893
894 static void n800_init(int ram_size, int vga_ram_size,
895                 const char *boot_device, DisplayState *ds,
896                 const char *kernel_filename, const char *kernel_cmdline,
897                 const char *initrd_filename, const char *cpu_model)
898 {
899     struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s));
900     int sdram_size = n800_binfo.ram_size;
901     int onenandram_size = 0x00010000;
902
903     if (ram_size < sdram_size + onenandram_size + OMAP242X_SRAM_SIZE) {
904         fprintf(stderr, "This architecture uses %i bytes of memory\n",
905                         sdram_size + onenandram_size + OMAP242X_SRAM_SIZE);
906         exit(1);
907     }
908
909     s->cpu = omap2420_mpu_init(sdram_size, NULL, cpu_model);
910
911     n800_gpio_setup(s);
912     n8x0_nand_setup(s);
913     n800_i2c_setup(s);
914     n800_tsc_setup(s);
915     n800_spi_setup(s);
916     n800_dss_setup(s, ds);
917     n800_cbus_setup(s);
918     if (usb_enabled)
919         n800_usb_setup(s);
920
921     /* Setup initial (reset) machine state */
922
923     /* Start at the OneNAND bootloader.  */
924     s->cpu->env->regs[15] = 0;
925
926     if (kernel_filename) {
927         /* Or at the linux loader.  */
928         n800_binfo.kernel_filename = kernel_filename;
929         n800_binfo.kernel_cmdline = kernel_cmdline;
930         n800_binfo.initrd_filename = initrd_filename;
931         arm_load_kernel(s->cpu->env, &n800_binfo);
932
933         qemu_register_reset(n800_boot_init, s);
934         n800_boot_init(s);
935     }
936
937     dpy_resize(ds, 800, 480);
938 }
939
940 QEMUMachine n800_machine = {
941     "n800",
942     "Nokia N800 aka. RX-34 tablet (OMAP2420)",
943     n800_init,
944 };