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