OMAP3 clock adjustments & cleanups
[qemu] / hw / beagle.c
1 /*
2  * Beagle board emulation. http://beagleboard.org/
3  * 
4  * Original code Copyright (C) 2008 yajin(yajin@vm-kernel.org)
5  * Rewrite Copyright (C) 2009 Nokia Corporation
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 "boards.h"
28 #include "i2c.h"
29 #include "devices.h"
30 #include "flash.h"
31
32 #define BEAGLE_NAND_CS       0
33 #define BEAGLE_NAND_PAGESIZE 0x800
34 #define BEAGLE_SDRAM_SIZE    (128 * 1024 * 1024) /* 128MB */
35
36 /* Beagle board support */
37 struct beagle_s {
38     struct omap_mpu_state_s *cpu;
39     
40     struct nand_flash_s *nand;
41     struct omap3_lcd_panel_s *lcd_panel;
42     i2c_bus *i2c;
43     struct twl4030_s *twl4030;
44 };
45
46 static void beagle_nand_pread(struct nand_flash_s *nand,
47                               uint64_t addr,
48                               uint8_t *data,
49                               uint32_t len)
50 {
51     uint16_t x;
52     uint32_t i;
53     
54     if ((len&1) || (addr&1)) {
55         fprintf(stderr, "%s: read byte length and address must be even (x16 device!)\n",
56                 __FUNCTION__);
57         exit(-1);
58     }
59     /* send command: reset */
60     nand_setpins(nand, 1, 0, 0, 1, 0);
61     nand_setio(nand, 0xff);
62     while (len) {
63         /* send command: read page (cycle1) */
64         nand_setpins(nand, 1, 0, 0, 1, 0);
65         nand_setio(nand, 0);
66         /* send address */
67         nand_setpins(nand, 0, 1, 0, 1, 0);
68         nand_setio(nand, (uint32_t)((addr >> 1) & 0xff));
69         nand_setio(nand, (uint32_t)((addr >> 9) & 0x3));
70         nand_setio(nand, (uint32_t)((addr >> 11) & 0xff));
71         nand_setio(nand, (uint32_t)((addr >> 19) & 0xff));
72         nand_setio(nand, (uint32_t)((addr >> 27) & 0x1));
73         /* send command: read page (cycle2) */
74         nand_setpins(nand, 1, 0, 0, 1, 0);
75         nand_setio(nand, 0x30);
76         /* read page data */
77         nand_setpins(nand, 0, 0, 0, 1, 0);
78         for (i = (BEAGLE_NAND_PAGESIZE / 2) - (addr & 0x3ff); i && len; i--) {
79             x = nand_getio(nand);
80             *(data++) = (uint8_t)(x & 0xff);
81             *(data++) = (uint8_t)((x >> 8) & 0xff);
82             len -= 2;
83             addr += 2;
84         }
85     }
86 }
87
88 static void beagle_init(ram_addr_t ram_size, int vga_ram_size,
89                 const char *boot_device,
90                 const char *kernel_filename, const char *kernel_cmdline,
91                 const char *initrd_filename, const char *cpu_model)
92 {
93     struct beagle_s *s = (struct beagle_s *) qemu_mallocz(sizeof(*s));
94     int sdindex = drive_get_index(IF_SD, 0, 0);
95     
96     if (sdindex == -1) {
97         fprintf(stderr, "%s: missing SecureDigital device\n", __FUNCTION__);
98         exit(1);
99     }
100         if (ram_size < (beagle_machine.ram_require & ~RAMSIZE_FIXED)) {
101         fprintf(stderr, "%s: This architecture uses %lu bytes of memory\n",
102                 __FUNCTION__, (beagle_machine.ram_require & ~RAMSIZE_FIXED));
103         exit(1);
104     }
105         s->cpu = omap3530_mpu_init(BEAGLE_SDRAM_SIZE, NULL);
106     
107     if (serial_hds[0])
108         omap_uart_attach(s->cpu->uart[2], serial_hds[0]);
109
110         s->nand = nand_init(NAND_MFR_MICRON, 0xba); /* MT29F2G16ABC */
111         nand_setpins(s->nand, 0, 0, 0, 1, 0); /* no write-protect */
112     omap_gpmc_attach(s->cpu->gpmc, BEAGLE_NAND_CS, 0, NULL, NULL, s, s->nand);
113     omap3_mmc_attach(s->cpu->omap3_mmc[0], drives_table[sdindex].bdrv);
114
115     s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
116     s->twl4030 = twl4030_init(s->i2c, s->cpu->irq[0][OMAP_INT_3XXX_SYS_NIRQ]);
117
118         s->lcd_panel = omap3_lcd_panel_init();
119         omap3_lcd_panel_attach(s->cpu->dss, 0, s->lcd_panel);
120     
121     if (!omap3_mmc_boot(s->cpu) 
122         && !omap3_nand_boot(s->cpu, s->nand, beagle_nand_pread)) {
123         fprintf(stderr, "%s: boot from MMC and NAND failed\n",
124                 __FUNCTION__);
125         exit(-1);
126     }
127 }
128
129 QEMUMachine beagle_machine = {
130     .name =        "beagle",
131     .desc =        "Beagle board (OMAP3530)",
132     .init =        beagle_init,
133     .ram_require = (BEAGLE_SDRAM_SIZE
134                     + OMAP3XXX_SRAM_SIZE
135                     + OMAP3XXX_BOOTROM_SIZE) | RAMSIZE_FIXED,
136 };
137