2 * Beagle board emulation. http://beagleboard.org/
\r
4 * Copyright (C) 2008 yajin(yajin@vm-kernel.org)
\r
6 * This program is free software; you can redistribute it and/or
\r
7 * modify it under the terms of the GNU General Public License as
\r
8 * published by the Free Software Foundation; either version 2 or
\r
9 * (at your option) version 3 of the License.
\r
11 * This program is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with this program; if not, write to the Free Software
\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
\r
22 #include "qemu-common.h"
\r
25 #include "arm-misc.h"
\r
27 #include "console.h"
\r
30 #include "devices.h"
\r
35 #define BEAGLE_NAND_CS 0
\r
40 #define GPMC_ONENAND 3
\r
42 #define MMC_ONENAND 5
\r
45 #define TST_DEVICE 0x0
\r
46 #define EMU_DEVICE 0x1
\r
47 #define HS_DEVICE 0x2
\r
48 #define GP_DEVICE 0x3
\r
50 #define DEBUG_BEAGLE
\r
53 #define BEAGLE_DEBUG(...) do { fprintf(stderr, __VA_ARGS__); } while(0)
\r
55 #define BEAGLE_DEBUG(x)
\r
58 /* Beagle board support */
\r
60 struct omap_mpu_state_s *cpu;
\r
62 struct nand_bflash_s *nand;
\r
63 struct omap3_lcd_panel_s *lcd_panel;
\r
65 struct twl4030_s *twl4030;
\r
70 static struct arm_boot_info beagle_binfo = {
\r
71 .ram_size = 0x08000000,
\r
75 static uint32_t beagle_nand_read16(void *opaque, target_phys_addr_t addr)
\r
77 struct beagle_s *s = (struct beagle_s *) opaque;
\r
78 //BEAGLE_DEBUG("beagle_nand_read16 offset %x\n",addr);
\r
82 case 0x7C: /*NAND_COMMAND*/
\r
83 case 0x80: /*NAND_ADDRESS*/
\r
86 case 0x84: /*NAND_DATA*/
\r
87 return nandb_read_data16(s->nand);
\r
96 static void beagle_nand_write16(void *opaque, target_phys_addr_t addr,
\r
99 struct beagle_s *s = (struct beagle_s *) opaque;
\r
102 case 0x7C: /*NAND_COMMAND*/
\r
103 nandb_write_command(s->nand,value);
\r
105 case 0x80: /*NAND_ADDRESS*/
\r
106 nandb_write_address(s->nand,value);
\r
108 case 0x84: /*NAND_DATA*/
\r
109 nandb_write_data16(s->nand,value);
\r
112 OMAP_BAD_REG(addr);
\r
118 static CPUReadMemoryFunc *beagle_nand_readfn[] = {
\r
119 beagle_nand_read16,
\r
120 beagle_nand_read16,
\r
121 omap_badwidth_read32,
\r
124 static CPUWriteMemoryFunc *beagle_nand_writefn[] = {
\r
125 beagle_nand_write16,
\r
126 beagle_nand_write16,
\r
127 omap_badwidth_write32,
\r
130 static void beagle_nand_setup(struct beagle_s *s)
\r
135 s->nand = nandb_init(NAND_MFR_MICRON,0xba);
\r
136 /*wp=1, no write protect!!! */
\r
137 //nand_set_wp(s->nand, 1);
\r
139 /* iomemtype = cpu_register_io_memory(0, beagle_nand_readfn,
\r
140 beagle_nand_writefn, s);
\r
141 cpu_register_physical_memory(0x6e00007c, 0xc, iomemtype);*/
\r
142 omap_gpmc_attach(s->cpu->gpmc, 0, 0, NULL, NULL, s, beagle_nand_readfn, beagle_nand_writefn);
\r
145 omap3_set_mem_type(s->cpu,GPMC_NAND);
\r
149 static int beagle_nand_read_page(struct beagle_s *s,uint8_t *buf, uint16_t page_addr)
\r
156 /*send command 0x0*/
\r
157 beagle_nand_write16(s,0x7C,0);
\r
158 /*send page address */
\r
159 beagle_nand_write16(s,0x80,page_addr&0xff);
\r
160 beagle_nand_write16(s,0x80,(page_addr>>8)&0x7);
\r
161 beagle_nand_write16(s,0x80,(page_addr>>11)&0xff);
\r
162 beagle_nand_write16(s,0x80,(page_addr>>19)&0xff);
\r
163 beagle_nand_write16(s,0x80,(page_addr>>27)&0xff);
\r
164 /*send command 0x30*/
\r
165 beagle_nand_write16(s,0x7C,0x30);
\r
167 for (i=0;i<0x800/2;i++)
\r
169 *p++ = beagle_nand_read16(s,0x84);
\r
174 /*read the xloader from NAND Flash into internal RAM*/
\r
175 static int beagle_boot_from_nand(struct beagle_s *s)
\r
177 uint32_t loadaddr, len;
\r
178 uint8_t nand_page[0x800],*load_dest;
\r
179 uint32_t nand_pages,i;
\r
181 /* The first two words(8 bytes) in first nand flash page have special meaning.
\r
182 First word:x-loader len
\r
183 Second word: x-load address in internal ram */
\r
184 beagle_nand_read_page(s,nand_page,0);
\r
185 len = *((uint32_t*)nand_page);
\r
186 loadaddr = *((uint32_t*)(nand_page+4));
\r
187 if ((len==0)||(loadaddr==0)||(len==0xffffffff)||(loadaddr==0xffffffff))
\r
190 /*put the first page into internal ram*/
\r
191 load_dest = phys_ram_base +beagle_binfo.ram_size;
\r
192 load_dest += loadaddr-OMAP3_SRAM_BASE;
\r
194 BEAGLE_DEBUG("load_dest %x phys_ram_base %x \n",(unsigned)load_dest,(unsigned)phys_ram_base);
\r
196 memcpy(load_dest,nand_page+8,0x800-8);
\r
197 load_dest += 0x800-8;
\r
199 nand_pages = len/0x800;
\r
203 for (i=1;i<nand_pages;i++)
\r
205 beagle_nand_read_page(s,nand_page,i*0x800);
\r
206 memcpy(load_dest,nand_page,0x800);
\r
207 load_dest += 0x800;
\r
209 s->cpu->env->regs[15] = loadaddr;
\r
214 static int beagle_rom_emu(struct beagle_s *s)
\r
216 if (!omap3_mmc_boot(s->cpu))
\r
217 if (beagle_boot_from_nand(s) < 0)
\r
222 static void beagle_dss_setup(struct beagle_s *s)
\r
224 s->lcd_panel = omap3_lcd_panel_init();
\r
225 omap3_lcd_panel_attach(s->cpu->dss, 0, s->lcd_panel);
\r
226 s->lcd_panel->dss = s->cpu->dss;
\r
229 static void beagle_mmc_cs_cb(void *opaque, int line, int level)
\r
231 /* TODO: this seems to actually be connected to the menelaus, to
\r
232 * which also both MMC slots connect. */
\r
233 omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
\r
235 printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
\r
238 static void beagle_i2c_setup(struct beagle_s *s)
\r
240 /* Attach the CPU on one end of our I2C bus. */
\r
241 s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
\r
243 s->twl4030 = twl4030_init(s->i2c, s->cpu->irq[0][OMAP_INT_35XX_SYS_NIRQ]);
\r
247 static void beagle_init(ram_addr_t ram_size, int vga_ram_size,
\r
248 const char *boot_device,
\r
249 const char *kernel_filename, const char *kernel_cmdline,
\r
250 const char *initrd_filename, const char *cpu_model)
\r
252 struct beagle_s *s = (struct beagle_s *) qemu_mallocz(sizeof(*s));
\r
253 int sdram_size = beagle_binfo.ram_size;
\r
255 if (ram_size < sdram_size + OMAP3530_SRAM_SIZE) {
\r
256 fprintf(stderr, "This architecture uses %i bytes of memory\n",
\r
257 sdram_size + OMAP3530_SRAM_SIZE);
\r
260 s->cpu = omap3530_mpu_init(sdram_size, NULL);
\r
261 beagle_nand_setup(s);
\r
262 beagle_i2c_setup(s);
\r
263 beagle_dss_setup(s);
\r
264 omap3_set_device_type(s->cpu,GP_DEVICE);
\r
265 if (beagle_rom_emu(s) < 0) {
\r
266 fprintf(stderr,"boot from MMC and nand failed \n");
\r
273 QEMUMachine beagle_machine = {
\r
275 .desc = "Beagle board (OMAP3530)",
\r
276 .init = beagle_init,
\r
277 .ram_require = (0x08000000 + OMAP3530_SRAM_SIZE) | RAMSIZE_FIXED,
\r