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_bflash_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 uint32_t beagle_nand_read16(void *opaque, target_phys_addr_t addr)
77 struct beagle_s *s = (struct beagle_s *) opaque;
78 //BEAGLE_DEBUG("beagle_nand_read16 offset %x\n",addr);
82 case 0x7C: /*NAND_COMMAND*/
83 case 0x80: /*NAND_ADDRESS*/
86 case 0x84: /*NAND_DATA*/
87 return nandb_read_data16(s->nand);
96 static void beagle_nand_write16(void *opaque, target_phys_addr_t addr,
99 struct beagle_s *s = (struct beagle_s *) opaque;
102 case 0x7C: /*NAND_COMMAND*/
103 nandb_write_command(s->nand,value);
105 case 0x80: /*NAND_ADDRESS*/
106 nandb_write_address(s->nand,value);
108 case 0x84: /*NAND_DATA*/
109 nandb_write_data16(s->nand,value);
118 static CPUReadMemoryFunc *beagle_nand_readfn[] = {
121 omap_badwidth_read32,
124 static CPUWriteMemoryFunc *beagle_nand_writefn[] = {
127 omap_badwidth_write32,
130 static void beagle_nand_setup(struct beagle_s *s)
135 s->nand = nandb_init(NAND_MFR_MICRON,0xba);
136 /*wp=1, no write protect!!! */
137 //nand_set_wp(s->nand, 1);
139 /* iomemtype = cpu_register_io_memory(0, beagle_nand_readfn,
140 beagle_nand_writefn, s);
141 cpu_register_physical_memory(0x6e00007c, 0xc, iomemtype);*/
142 omap_gpmc_attach(s->cpu->gpmc, 0, 0, NULL, NULL, s, beagle_nand_readfn, beagle_nand_writefn);
145 omap3_set_mem_type(s->cpu,GPMC_NAND);
149 static int beagle_nand_read_page(struct beagle_s *s,uint8_t *buf, uint16_t page_addr)
157 beagle_nand_write16(s,0x7C,0);
158 /*send page address */
159 beagle_nand_write16(s,0x80,page_addr&0xff);
160 beagle_nand_write16(s,0x80,(page_addr>>8)&0x7);
161 beagle_nand_write16(s,0x80,(page_addr>>11)&0xff);
162 beagle_nand_write16(s,0x80,(page_addr>>19)&0xff);
163 beagle_nand_write16(s,0x80,(page_addr>>27)&0xff);
164 /*send command 0x30*/
165 beagle_nand_write16(s,0x7C,0x30);
167 for (i=0;i<0x800/2;i++)
169 *p++ = beagle_nand_read16(s,0x84);
174 /*read the xloader from NAND Flash into internal RAM*/
175 static int beagle_boot_from_nand(struct beagle_s *s)
177 uint32_t loadaddr, len;
178 uint8_t nand_page[0x800],*load_dest;
179 uint32_t nand_pages,i;
181 /* The first two words(8 bytes) in first nand flash page have special meaning.
182 First word:x-loader len
183 Second word: x-load address in internal ram */
184 beagle_nand_read_page(s,nand_page,0);
185 len = *((uint32_t*)nand_page);
186 loadaddr = *((uint32_t*)(nand_page+4));
187 if ((len==0)||(loadaddr==0)||(len==0xffffffff)||(loadaddr==0xffffffff))
190 /*put the first page into internal ram*/
191 load_dest = phys_ram_base +beagle_binfo.ram_size;
192 load_dest += loadaddr-OMAP3_SRAM_BASE;
194 BEAGLE_DEBUG("load_dest %x phys_ram_base %x \n",(unsigned)load_dest,(unsigned)phys_ram_base);
196 memcpy(load_dest,nand_page+8,0x800-8);
197 load_dest += 0x800-8;
199 nand_pages = len/0x800;
203 for (i=1;i<nand_pages;i++)
205 beagle_nand_read_page(s,nand_page,i*0x800);
206 memcpy(load_dest,nand_page,0x800);
209 s->cpu->env->regs[15] = loadaddr;
214 static int beagle_rom_emu(struct beagle_s *s)
216 if (!omap3_mmc_boot(s->cpu))
217 if (beagle_boot_from_nand(s) < 0)
222 static void beagle_dss_setup(struct beagle_s *s)
224 s->lcd_panel = omap3_lcd_panel_init();
225 omap3_lcd_panel_attach(s->cpu->dss, 0, s->lcd_panel);
226 s->lcd_panel->dss = s->cpu->dss;
229 static void beagle_mmc_cs_cb(void *opaque, int line, int level)
231 /* TODO: this seems to actually be connected to the menelaus, to
232 * which also both MMC slots connect. */
233 omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
235 printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
238 static void beagle_i2c_setup(struct beagle_s *s)
240 /* Attach the CPU on one end of our I2C bus. */
241 s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
243 s->twl4030 = twl4030_init(s->i2c, s->cpu->irq[0][OMAP_INT_35XX_SYS_NIRQ]);
247 static void beagle_init(ram_addr_t ram_size, int vga_ram_size,
248 const char *boot_device,
249 const char *kernel_filename, const char *kernel_cmdline,
250 const char *initrd_filename, const char *cpu_model)
252 struct beagle_s *s = (struct beagle_s *) qemu_mallocz(sizeof(*s));
253 int sdram_size = beagle_binfo.ram_size;
255 if (ram_size < sdram_size + OMAP3530_SRAM_SIZE) {
256 fprintf(stderr, "This architecture uses %i bytes of memory\n",
257 sdram_size + OMAP3530_SRAM_SIZE);
260 s->cpu = omap3530_mpu_init(sdram_size, NULL);
261 beagle_nand_setup(s);
264 omap3_set_device_type(s->cpu,GP_DEVICE);
265 if (beagle_rom_emu(s) < 0) {
266 fprintf(stderr,"boot from MMC and nand failed \n");
273 QEMUMachine beagle_machine = {
275 .desc = "Beagle board (OMAP3530)",
277 .ram_require = (0x08000000 + OMAP3530_SRAM_SIZE) | RAMSIZE_FIXED,