3296598cce5ca1465e0a19af59e5c6e73937ce0f
[qemu] / hw / beagle.c
1 /*
2  * Beagle board emulation. http://beagleboard.org/
3  * 
4  * Copyright (C) 2008 yajin(yajin@vm-kernel.org)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 or
9  * (at your option) version 3 of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19  * MA 02111-1307 USA
20  */
21
22 #include "qemu-common.h"
23 #include "sysemu.h"
24 #include "omap.h"
25 #include "arm-misc.h"
26 #include "irq.h"
27 #include "console.h"
28 #include "boards.h"
29 #include "i2c.h"
30 #include "devices.h"
31 #include "flash.h"
32 #include "hw.h"
33 #include "block.h"
34
35 #define BEAGLE_NAND_CS       0
36 #define BEAGLE_NAND_PAGESIZE 0x800
37
38 #define GPMC_NOR             0
39 #define GPMC_NAND           1
40 #define GPMC_MDOC           2
41 #define GPMC_ONENAND    3
42 #define MMC_NAND            4
43 #define MMC_ONENAND     5
44
45
46 #define TST_DEVICE              0x0
47 #define EMU_DEVICE              0x1
48 #define HS_DEVICE               0x2
49 #define GP_DEVICE               0x3
50
51 /* Beagle board support */
52 struct beagle_s {
53     struct omap_mpu_state_s *cpu;
54     
55     struct nand_flash_s *nand;
56     struct omap3_lcd_panel_s *lcd_panel;
57     i2c_bus *i2c;
58     struct twl4030_s *twl4030;
59 };
60
61 static struct arm_boot_info beagle_binfo = {
62     .ram_size = 0x08000000,
63 };
64
65 static void beagle_nand_pread(struct nand_flash_s *nand,
66                               uint64_t addr,
67                               uint8_t *data,
68                               uint32_t len)
69 {
70     uint16_t x;
71     uint32_t i;
72     
73     if ((len&1) || (addr&1)) {
74         fprintf(stderr, "%s: read byte length and address must be even (x16 device!)\n",
75                 __FUNCTION__);
76         exit(-1);
77     }
78     /* send command: reset */
79     nand_setpins(nand, 1, 0, 0, 1, 0);
80     nand_setio(nand, 0xff);
81     while (len) {
82         /* send command: read page (cycle1) */
83         nand_setpins(nand, 1, 0, 0, 1, 0);
84         nand_setio(nand, 0);
85         /* send address */
86         nand_setpins(nand, 0, 1, 0, 1, 0);
87         nand_setio(nand, (uint32_t)((addr >> 1) & 0xff));
88         nand_setio(nand, (uint32_t)((addr >> 9) & 0x3));
89         nand_setio(nand, (uint32_t)((addr >> 11) & 0xff));
90         nand_setio(nand, (uint32_t)((addr >> 19) & 0xff));
91         nand_setio(nand, (uint32_t)((addr >> 27) & 0x1));
92         /* send command: read page (cycle2) */
93         nand_setpins(nand, 1, 0, 0, 1, 0);
94         nand_setio(nand, 0x30);
95         /* read page data */
96         nand_setpins(nand, 0, 0, 0, 1, 0);
97         for (i = (BEAGLE_NAND_PAGESIZE / 2) - (addr & 0x3ff); i && len; i--) {
98             x = nand_getio(nand);
99             *(data++) = (uint8_t)(x & 0xff);
100             *(data++) = (uint8_t)((x >> 8) & 0xff);
101             len -= 2;
102             addr += 2;
103         }
104     }
105 }
106
107 static void beagle_init(ram_addr_t ram_size, int vga_ram_size,
108                 const char *boot_device,
109                 const char *kernel_filename, const char *kernel_cmdline,
110                 const char *initrd_filename, const char *cpu_model)
111 {
112     struct beagle_s *s = (struct beagle_s *) qemu_mallocz(sizeof(*s));
113     int sdram_size = beagle_binfo.ram_size;
114     int sdindex = drive_get_index(IF_SD, 0, 0);
115     
116     if (sdindex == -1) {
117         fprintf(stderr, "qemu: missing SecureDigital device\n");
118         exit(1);
119     }
120     
121         if (ram_size < sdram_size +  OMAP3530_SRAM_SIZE) {
122         fprintf(stderr, "This architecture uses %i bytes of memory\n",
123                         sdram_size + OMAP3530_SRAM_SIZE);
124         exit(1);
125     }
126         s->cpu = omap3530_mpu_init(sdram_size, NULL);
127     
128     if (serial_hds[0])
129         omap_uart_attach(s->cpu->uart[2], serial_hds[0]);
130
131         s->nand = nand_init(NAND_MFR_MICRON, 0xba); /* MT29F2G16ABC */
132         nand_setpins(s->nand, 0, 0, 0, 1, 0); /* no write-protect */
133     omap_gpmc_attach(s->cpu->gpmc, BEAGLE_NAND_CS, 0, NULL, NULL, s, s->nand);
134     omap3_mmc_attach(s->cpu->omap3_mmc[0], drives_table[sdindex].bdrv);
135
136     s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
137     s->twl4030 = twl4030_init(s->i2c, s->cpu->irq[0][OMAP_INT_35XX_SYS_NIRQ]);
138
139         s->lcd_panel = omap3_lcd_panel_init();
140         omap3_lcd_panel_attach(s->cpu->dss, 0, s->lcd_panel);
141
142     omap3_set_mem_type(s->cpu, GPMC_NAND);
143         omap3_set_device_type(s->cpu,GP_DEVICE);
144     if (!omap3_mmc_boot(s->cpu) 
145         && !omap3_nand_boot(s->cpu, s->nand, beagle_nand_pread)) {
146         fprintf(stderr, "%s: boot from MMC and NAND failed\n",
147                 __FUNCTION__);
148         exit(-1);
149     }
150 }
151
152 QEMUMachine beagle_machine = {
153     .name = "beagle",
154     .desc =     "Beagle board (OMAP3530)",
155     .init =     beagle_init,
156     .ram_require =     (0x08000000 +  OMAP3530_SRAM_SIZE) | RAMSIZE_FIXED,
157 };
158