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
34 #define BEAGLE_NAND_CS 0
\r
35 #define BEAGLE_TWL4030_ADDR 0x4b /* Power management */
\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
51 #define BEAGLE_DEBUG(x) do { printf x ; } while(0)
\r
53 #define BEAGLE_DEBUG(x) do { } while(0)
\r
56 /* Beagle board support */
\r
58 struct omap_mpu_state_s *cpu;
\r
60 struct nand_bflash_s *nand;
\r
61 struct omap3_lcd_panel_s *lcd_panel;
\r
67 static struct arm_boot_info beagle_binfo = {
\r
68 .ram_size = 0x08000000,
\r
72 static uint32_t beagle_nand_read16(void *opaque, target_phys_addr_t addr)
\r
74 struct beagle_s *s = (struct beagle_s *) opaque;
\r
75 BEAGLE_DEBUG(("beagle_nand_read16 offset %x\n",addr));
\r
79 case 0x7C: /*NAND_COMMAND*/
\r
80 case 0x80: /*NAND_ADDRESS*/
\r
83 case 0x84: /*NAND_DATA*/
\r
84 return nandb_read_data16(s->nand);
\r
93 static void beagle_nand_write16(void *opaque, target_phys_addr_t addr,
\r
96 struct beagle_s *s = (struct beagle_s *) opaque;
\r
99 case 0x7C: /*NAND_COMMAND*/
\r
100 nandb_write_command(s->nand,value);
\r
102 case 0x80: /*NAND_ADDRESS*/
\r
103 nandb_write_address(s->nand,value);
\r
105 case 0x84: /*NAND_DATA*/
\r
106 nandb_write_data16(s->nand,value);
\r
109 OMAP_BAD_REG(addr);
\r
115 static CPUReadMemoryFunc *beagle_nand_readfn[] = {
\r
116 beagle_nand_read16,
\r
117 beagle_nand_read16,
\r
118 omap_badwidth_read32,
\r
121 static CPUWriteMemoryFunc *beagle_nand_writefn[] = {
\r
122 beagle_nand_write16,
\r
123 beagle_nand_write16,
\r
124 omap_badwidth_write32,
\r
127 static void beagle_nand_setup(struct beagle_s *s)
\r
132 s->nand = nandb_init(NAND_MFR_MICRON,0xba);
\r
133 /*wp=1, no write protect!!! */
\r
134 //nand_set_wp(s->nand, 1);
\r
136 /* iomemtype = cpu_register_io_memory(0, beagle_nand_readfn,
\r
137 beagle_nand_writefn, s);
\r
138 cpu_register_physical_memory(0x6e00007c, 0xc, iomemtype);*/
\r
139 omap_gpmc_attach(s->cpu->gpmc, 0, 0, NULL, NULL, s, beagle_nand_readfn, beagle_nand_writefn);
\r
142 omap3_set_mem_type(s->cpu,GPMC_NAND);
\r
146 static int beagle_nand_read_page(struct beagle_s *s,uint8_t *buf, uint16_t page_addr)
\r
153 /*send command 0x0*/
\r
154 beagle_nand_write16(s,0x7C,0);
\r
155 /*send page address */
\r
156 beagle_nand_write16(s,0x80,page_addr&0xff);
\r
157 beagle_nand_write16(s,0x80,(page_addr>>8)&0x7);
\r
158 beagle_nand_write16(s,0x80,(page_addr>>11)&0xff);
\r
159 beagle_nand_write16(s,0x80,(page_addr>>19)&0xff);
\r
160 beagle_nand_write16(s,0x80,(page_addr>>27)&0xff);
\r
161 /*send command 0x30*/
\r
162 beagle_nand_write16(s,0x7C,0x30);
\r
164 for (i=0;i<0x800/2;i++)
\r
166 *p++ = beagle_nand_read16(s,0x84);
\r
171 static int beagle_boot_from_mmc(struct beagle_s *s)
\r
176 /*read the xloader from NAND Flash into internal RAM*/
\r
177 static int beagle_boot_from_nand(struct beagle_s *s)
\r
179 uint32_t loadaddr, len;
\r
180 uint8_t nand_page[0x800],*load_dest;
\r
181 uint32_t nand_pages,i;
\r
183 /* The first two words(8 bytes) in first nand flash page have special meaning.
\r
184 First word:x-loader len
\r
185 Second word: x-load address in internal ram */
\r
186 beagle_nand_read_page(s,nand_page,0);
\r
187 len = *((uint32_t*)nand_page);
\r
188 loadaddr = *((uint32_t*)(nand_page+4));
\r
189 if ((len==0)||(loadaddr==0)||(len==0xffffffff)||(loadaddr==0xffffffff))
\r
192 /*put the first page into internal ram*/
\r
193 load_dest = phys_ram_base +beagle_binfo.ram_size;
\r
194 load_dest += loadaddr-OMAP3_SRAM_BASE;
\r
196 BEAGLE_DEBUG(("load_dest %x phys_ram_base %x \n",(unsigned)load_dest,(unsigned)phys_ram_base));
\r
198 memcpy(load_dest,nand_page+8,0x800-8);
\r
199 load_dest += 0x800-8;
\r
201 nand_pages = len/0x800;
\r
205 for (i=1;i<nand_pages;i++)
\r
207 beagle_nand_read_page(s,nand_page,i*0x800);
\r
208 memcpy(load_dest,nand_page,0x800);
\r
209 load_dest += 0x800;
\r
211 s->cpu->env->regs[15] = loadaddr;
\r
215 static int beagle_rom_emu(struct beagle_s *s)
\r
217 if (beagle_boot_from_mmc(s)<0)
\r
219 if (beagle_boot_from_nand(s)<0)
\r
225 static void beagle_dss_setup(struct beagle_s *s, DisplayState *ds)
\r
227 s->lcd_panel = omap3_lcd_panel_init(ds);
\r
228 omap3_lcd_panel_attach(s->cpu->dss, 0, s->lcd_panel);
\r
229 s->lcd_panel->dss = s->cpu->dss;
\r
232 static void beagle_mmc_cs_cb(void *opaque, int line, int level)
\r
234 /* TODO: this seems to actually be connected to the menelaus, to
\r
235 * which also both MMC slots connect. */
\r
236 omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
\r
238 printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
\r
241 static void beagle_i2c_setup(struct beagle_s *s)
\r
244 /* Attach the CPU on one end of our I2C bus. */
\r
245 s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
\r
247 /* Attach a menelaus PM chip */
\r
248 i2c_set_slave_address(
\r
249 twl4030_init(s->i2c,
\r
250 s->cpu->irq[0][OMAP_INT_35XX_SYS_NIRQ]),
\r
251 BEAGLE_TWL4030_ADDR);
\r
255 static void beagle_init(ram_addr_t ram_size, int vga_ram_size,
\r
256 const char *boot_device, DisplayState *ds,
\r
257 const char *kernel_filename, const char *kernel_cmdline,
\r
258 const char *initrd_filename, const char *cpu_model)
\r
260 struct beagle_s *s = (struct beagle_s *) qemu_mallocz(sizeof(*s));
\r
261 int sdram_size = beagle_binfo.ram_size;
\r
263 if (ram_size < sdram_size + OMAP3530_SRAM_SIZE) {
\r
264 fprintf(stderr, "This architecture uses %i bytes of memory\n",
\r
265 sdram_size + OMAP3530_SRAM_SIZE);
\r
268 s->cpu = omap3530_mpu_init(sdram_size, NULL, NULL);
\r
269 beagle_nand_setup(s);
\r
270 beagle_i2c_setup(s);
\r
271 beagle_dss_setup(s,ds);
\r
272 omap3_set_device_type(s->cpu,GP_DEVICE);
\r
273 if (beagle_rom_emu(s)<0)
\r
275 fprintf(stderr,"boot from MMC and nand failed \n");
\r
284 QEMUMachine beagle_machine = {
\r
286 .desc = "Beagle board (OMAP3530)",
\r
287 .init = beagle_init,
\r
288 .ram_require = (0x08000000 + OMAP3530_SRAM_SIZE) | RAMSIZE_FIXED,
\r