2 * Beagle board emulation. http://beagleboard.org/
4 * Copyright (C) 2008 yajin(yajin@vm-kernel.org)
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.
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.
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,
22 #include "qemu-common.h"
35 #define BEAGLE_NAND_CS 0
40 #define GPMC_ONENAND 3
45 #define TST_DEVICE 0x0
46 #define EMU_DEVICE 0x1
53 #define BEAGLE_DEBUG(...) do { fprintf(stderr, __VA_ARGS__); } while(0)
55 #define BEAGLE_DEBUG(x)
58 /* Beagle board support */
60 struct omap_mpu_state_s *cpu;
62 struct nand_flash_s *nand;
63 struct omap3_lcd_panel_s *lcd_panel;
65 struct twl4030_s *twl4030;
70 static struct arm_boot_info beagle_binfo = {
71 .ram_size = 0x08000000,
75 static void beagle_nand_setup(struct beagle_s *s)
77 s->nand = nand_init(NAND_MFR_MICRON, 0xba); /* MT29F2G16ABC */
78 nand_setpins(s->nand, 0, 0, 0, 1, 0); /* no write-protect */
79 omap_gpmc_attach(s->cpu->gpmc, BEAGLE_NAND_CS, 0, NULL, NULL, s, s->nand);
80 omap3_set_mem_type(s->cpu, GPMC_NAND);
83 static int beagle_nand_read_page(struct beagle_s *s,uint8_t *buf, uint32_t addr)
85 uint16_t *p = (uint16_t *)buf;
88 /* send command: reset */
89 nand_setpins(s->nand, 1, 0, 0, 1, 0);
90 nand_setio(s->nand, 0xff);
91 /* send command: read page (cycle1) */
92 nand_setpins(s->nand, 1, 0, 0, 1, 0);
93 nand_setio(s->nand, 0);
94 /* send page address (x16 device):
95 bits 0-11 define cache address in words (bit11 set only for OOB access)
96 bits 16-33 define page and block address */
97 nand_setpins(s->nand, 0, 1, 0, 1, 0);
98 nand_setio(s->nand, (addr >> 1) & 0xff);
99 nand_setio(s->nand, (addr >> 9) & 0x3);
100 nand_setio(s->nand, (addr >> 11) & 0xff);
101 nand_setio(s->nand, (addr >> 19) & 0xff);
102 nand_setio(s->nand, (addr >> 27) & 0x1);
103 /* send command: read page (cycle2) */
104 nand_setpins(s->nand, 1, 0, 0, 1, 0);
105 nand_setio(s->nand, 0x30);
107 nand_setpins(s->nand, 0, 0, 0, 1, 0);
108 for (i = 0; i < 0x800 / 2; i++)
109 *(p++) = nand_getio(s->nand);
113 /*read the xloader from NAND Flash into internal RAM*/
114 static int beagle_boot_from_nand(struct beagle_s *s)
116 uint32_t loadaddr, len;
117 uint8_t nand_page[0x800],*load_dest;
118 uint32_t nand_pages,i;
120 /* The first two words(8 bytes) in first nand flash page have special meaning.
121 First word:x-loader len
122 Second word: x-load address in internal ram */
123 beagle_nand_read_page(s,nand_page,0);
124 len = *((uint32_t*)nand_page);
125 loadaddr = *((uint32_t*)(nand_page+4));
126 fprintf(stderr, "%s: len = 0x%08x, addr = 0x%08x\n", __FUNCTION__, len, loadaddr);
127 if ((len==0)||(loadaddr==0)||(len==0xffffffff)||(loadaddr==0xffffffff))
130 /*put the first page into internal ram*/
131 load_dest = phys_ram_base + beagle_binfo.ram_size;
132 load_dest += loadaddr-OMAP3_SRAM_BASE;
134 memcpy(load_dest,nand_page+8,0x800-8);
135 load_dest += 0x800-8;
137 nand_pages = len/0x800;
141 for (i=1;i<nand_pages;i++)
143 beagle_nand_read_page(s,nand_page,i*0x800);
144 memcpy(load_dest,nand_page,0x800);
147 s->cpu->env->regs[15] = loadaddr;
152 static int beagle_rom_emu(struct beagle_s *s)
154 if (!omap3_mmc_boot(s->cpu))
155 if (beagle_boot_from_nand(s) < 0)
160 static void beagle_dss_setup(struct beagle_s *s)
162 s->lcd_panel = omap3_lcd_panel_init();
163 omap3_lcd_panel_attach(s->cpu->dss, 0, s->lcd_panel);
166 //static void beagle_mmc_cs_cb(void *opaque, int line, int level)
168 // /* TODO: this seems to actually be connected to the menelaus, to
169 // * which also both MMC slots connect. */
170 // omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
172 // printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
175 static void beagle_i2c_setup(struct beagle_s *s)
177 /* Attach the CPU on one end of our I2C bus. */
178 s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
180 s->twl4030 = twl4030_init(s->i2c, s->cpu->irq[0][OMAP_INT_35XX_SYS_NIRQ]);
184 static void beagle_init(ram_addr_t ram_size, int vga_ram_size,
185 const char *boot_device,
186 const char *kernel_filename, const char *kernel_cmdline,
187 const char *initrd_filename, const char *cpu_model)
189 struct beagle_s *s = (struct beagle_s *) qemu_mallocz(sizeof(*s));
190 int sdram_size = beagle_binfo.ram_size;
192 if (ram_size < sdram_size + OMAP3530_SRAM_SIZE) {
193 fprintf(stderr, "This architecture uses %i bytes of memory\n",
194 sdram_size + OMAP3530_SRAM_SIZE);
197 s->cpu = omap3530_mpu_init(sdram_size, NULL);
198 beagle_nand_setup(s);
201 omap3_set_device_type(s->cpu,GP_DEVICE);
202 if (beagle_rom_emu(s) < 0) {
203 fprintf(stderr,"boot from MMC and nand failed \n");
210 QEMUMachine beagle_machine = {
212 .desc = "Beagle board (OMAP3530)",
214 .ram_require = (0x08000000 + OMAP3530_SRAM_SIZE) | RAMSIZE_FIXED,