[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Add Apollon (OMAP24xx) board support (take #2)
From: |
Kyungmin Park |
Subject: |
[Qemu-devel] [PATCH] Add Apollon (OMAP24xx) board support (take #2) |
Date: |
Mon, 28 Jul 2008 16:24:03 +0900 |
User-agent: |
Mutt/1.5.14 (2007-02-12) |
Add apollon (OMAP24xx) board initial support
with board descriptions
Signed-off-by: Kyungmin Park <address@hidden>
---
diff --git a/Makefile.target b/Makefile.target
index ff105c1..2d124e4 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -603,6 +603,7 @@ OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o
omap_i2c.o
OBJS+= omap2.o omap_dss.o soc_dma.o
OBJS+= palm.o tsc210x.o
OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o
+OBJS+= apollon.o
OBJS+= tsc2005.o
OBJS+= mst_fpga.o mainstone.o
OBJS+= musicpal.o pflash_cfi02.o
diff --git a/hw/apollon.c b/hw/apollon.c
new file mode 100644
index 0000000..f3719b0
--- /dev/null
+++ b/hw/apollon.c
@@ -0,0 +1,299 @@
+/*
+ * Samsung Apollon OneNAND board
+ *
+ * Copyright (C) 2008 Samsung Electronics
+ * Written by Kyungmin Park <address@hidden>
+ *
+ * Derived from nseries.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "qemu-common.h"
+#include "sysemu.h"
+#include "omap.h"
+#include "arm-misc.h"
+#include "irq.h"
+#include "console.h"
+#include "boards.h"
+#include "devices.h"
+#include "flash.h"
+#include "hw.h"
+#include "net.h"
+
+/* Samsung apollon support */
+struct apollon_s {
+ struct omap_mpu_state_s *cpu;
+
+ struct {
+ void *opaque;
+ uint32_t (*txrx)(void *opaque, uint32_t value, int len);
+ struct uwire_slave_s *chip;
+ } ts;
+};
+
+/* GPIO pins */
+#define APOLLON_BLIZZARD_RESET_GPIO 30
+#define APOLLON_MMC_CS_GPIO 37
+#define APOLLON_ONENAND_GPIO 72
+#define APOLLON_ETHERNET_GPIO 74
+
+/* Chipselects on GPMC OneNAND interface */
+#define APOLLON_ONENAND_CS 0
+
+static void apollon_mmc_cs_cb(void *opaque, int line, int level)
+{
+ /* TODO: this seems to actually be connected to the menelaus, to
+ * which also both MMC slots connect. */
+ omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
+
+ printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);
+}
+
+static void apollon_gpio_setup(struct apollon_s *s)
+{
+ qemu_irq *mmc_cs = qemu_allocate_irqs(apollon_mmc_cs_cb, s->cpu->mmc, 1);
+ omap2_gpio_out_set(s->cpu->gpif, APOLLON_MMC_CS_GPIO, mmc_cs[0]);
+}
+
+static void apollon_onenand_setup(struct apollon_s *s)
+{
+ /* Either ec40xx or ec48xx are OK for the ID */
+ omap_gpmc_attach(s->cpu->gpmc, APOLLON_ONENAND_CS, 0, onenand_base_update,
+ onenand_base_unmap,
+ onenand_init(0xec4800, 1,
+ omap2_gpio_in_get(s->cpu->gpif,
+ APOLLON_ONENAND_GPIO)[0]));
+}
+
+/* This task is normally performed by the bootloader. If we're loading
+ * a kernel directly, we need to set up GPMC mappings ourselves. */
+static void apollon_gpmc_init(struct apollon_s *s)
+{
+ uint32_t config7 =
+ (0xf << 8) | /* MASKADDRESS */
+ (1 << 6) | /* CSVALID */
+ (4 << 0); /* BASEADDRESS */
+
+ cpu_physical_memory_write(0x6800a078, /* GPMC_CONFIG7_0 */
+ (void *) &config7, sizeof(config7));
+
+ /* Set GPMC1 for ethernet at apollon */
+ config7 = 0x00000F40 | (0x08000000 >> 24);
+ cpu_physical_memory_write(0x6800a0a8, /* GPMC_CONFIG7_1 */
+ (void *) &config7, sizeof(config7));
+}
+
+/* Setup sequence done by the bootloader */
+static void apollon_boot_init(void *opaque)
+{
+ struct apollon_s *s = (struct apollon_s *) opaque;
+ uint32_t buf;
+
+ /* PRCM setup */
+#define omap_writel(addr, val) \
+ buf = (val); \
+ cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf))
+
+ omap_writel(0x48008060, 0x41); /* PRCM_CLKSRC_CTRL */
+ omap_writel(0x48008070, 1); /* PRCM_CLKOUT_CTRL */
+ omap_writel(0x48008078, 0); /* PRCM_CLKEMUL_CTRL */
+ omap_writel(0x48008090, 0); /* PRCM_VOLTSETUP */
+ omap_writel(0x48008094, 0); /* PRCM_CLKSSETUP */
+ omap_writel(0x48008098, 0); /* PRCM_POLCTRL */
+ omap_writel(0x48008140, 2); /* CM_CLKSEL_MPU */
+ omap_writel(0x48008148, 0); /* CM_CLKSTCTRL_MPU */
+ omap_writel(0x48008158, 1); /* RM_RSTST_MPU */
+ omap_writel(0x480081c8, 0x15); /* PM_WKDEP_MPU */
+ omap_writel(0x480081d4, 0x1d4); /* PM_EVGENCTRL_MPU */
+ omap_writel(0x480081d8, 0); /* PM_EVEGENONTIM_MPU */
+ omap_writel(0x480081dc, 0); /* PM_EVEGENOFFTIM_MPU
*/
+ omap_writel(0x480081e0, 0xc); /* PM_PWSTCTRL_MPU */
+ omap_writel(0x48008200, 0x047e7ff7); /* CM_FCLKEN1_CORE */
+ omap_writel(0x48008204, 0x00000004); /* CM_FCLKEN2_CORE */
+ omap_writel(0x48008210, 0x047e7ff1); /* CM_ICLKEN1_CORE */
+ omap_writel(0x48008214, 0x00000004); /* CM_ICLKEN2_CORE */
+ omap_writel(0x4800821c, 0x00000000); /* CM_ICLKEN4_CORE */
+ omap_writel(0x48008230, 0); /* CM_AUTOIDLE1_CORE */
+ omap_writel(0x48008234, 0); /* CM_AUTOIDLE2_CORE */
+ omap_writel(0x48008238, 7); /* CM_AUTOIDLE3_CORE */
+ omap_writel(0x4800823c, 0); /* CM_AUTOIDLE4_CORE */
+ omap_writel(0x48008240, 0x04360626); /* CM_CLKSEL1_CORE */
+ omap_writel(0x48008244, 0x00000014); /* CM_CLKSEL2_CORE */
+ omap_writel(0x48008248, 0); /* CM_CLKSTCTRL_CORE */
+ omap_writel(0x48008300, 0x00000000); /* CM_FCLKEN_GFX */
+ omap_writel(0x48008310, 0x00000000); /* CM_ICLKEN_GFX */
+ omap_writel(0x48008340, 0x00000001); /* CM_CLKSEL_GFX */
+ omap_writel(0x48008400, 0x00000004); /* CM_FCLKEN_WKUP */
+ omap_writel(0x48008410, 0x00000004); /* CM_ICLKEN_WKUP */
+ omap_writel(0x48008440, 0x00000000); /* CM_CLKSEL_WKUP */
+ omap_writel(0x48008500, 0x000000cf); /* CM_CLKEN_PLL */
+ omap_writel(0x48008530, 0x0000000c); /* CM_AUTOIDLE_PLL */
+ omap_writel(0x48008540, /* CM_CLKSEL1_PLL */
+ (0x78 << 12) | (6 << 8));
+ omap_writel(0x48008544, 2); /* CM_CLKSEL2_PLL */
+
+ /* GPMC setup */
+ apollon_gpmc_init(s);
+
+ /* CPU setup */
+ s->cpu->env->regs[15] = s->cpu->env->boot_info->loader_start;
+ s->cpu->env->GE = 0x5;
+}
+
+static struct omap_partition_info_s {
+ uint32_t offset;
+ uint32_t size;
+ int mask;
+ const char *name;
+} apollon_part_info[] = {
+ { 0x00000000, 0x00020000, 0x3, "bootloader" },
+ { 0x00020000, 0x00020000, 0x0, "params" },
+ { 0x00040000, 0x00200000, 0x0, "kernel" },
+ { 0x00240000, 0x01000000, 0x3, "rootfs" },
+ { 0x01240000, 0x0f000000, 0x3, "fs" },
+
+ { 0, 0, 0, 0 }
+};
+
+static int apollon_atag_setup(struct arm_boot_info *info, void *p)
+{
+ uint16_t *w;
+ uint32_t *l;
+ struct omap_partition_info_s *partition;
+
+ w = p;
+
+ stw_raw(w ++, OMAP_TAG_UART); /* u16 tag */
+ stw_raw(w ++, 4); /* u16 len */
+ stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
+ w ++;
+
+ stw_raw(w ++, OMAP_TAG_MMC); /* u16 tag */
+ stw_raw(w ++, 16); /* u16 len */
+ stw_raw(w ++, 0xf); /* unsigned flags */
+ stw_raw(w ++, -1); /* s16 power_pin */
+ stw_raw(w ++, -1); /* s16 switch_pin */
+ stw_raw(w ++, -1); /* s16 wp_pin */
+ stw_raw(w ++, 0); /* unsigned flags */
+ stw_raw(w ++, 0); /* s16 power_pin */
+ stw_raw(w ++, 0); /* s16 switch_pin */
+ stw_raw(w ++, 0); /* s16 wp_pin */
+
+ w ++;
+
+ partition = apollon_part_info;
+ for (; partition->name; partition ++) {
+ stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */
+ stw_raw(w ++, 28); /* u16 len */
+ strcpy((void *) w, partition->name); /* char name[16] */
+ l = (void *) (w + 8);
+ stl_raw(l ++, partition->size); /* unsigned int size */
+ stl_raw(l ++, partition->offset); /* unsigned int offset */
+ stl_raw(l ++, partition->mask); /* unsigned int
mask_flags */
+ w = (void *) l;
+ }
+
+ stw_raw(w ++, OMAP_TAG_BOOT_REASON); /* u16 tag */
+ stw_raw(w ++, 12); /* u16 len */
+#if 0
+ strcpy((void *) w, "por"); /* char reason_str[12] */
+ strcpy((void *) w, "charger"); /* char reason_str[12] */
+ strcpy((void *) w, "32wd_to"); /* char reason_str[12] */
+ strcpy((void *) w, "sw_rst"); /* char reason_str[12] */
+ strcpy((void *) w, "mbus"); /* char reason_str[12]
*/
+ strcpy((void *) w, "unknown"); /* char reason_str[12] */
+ strcpy((void *) w, "swdg_to"); /* char reason_str[12] */
+ strcpy((void *) w, "sec_vio"); /* char reason_str[12] */
+ strcpy((void *) w, "pwr_key"); /* char reason_str[12] */
+ strcpy((void *) w, "rtc_alarm"); /* char reason_str[12] */
+#else
+ strcpy((void *) w, "pwr_key"); /* char reason_str[12] */
+#endif
+ w += 6;
+
+ return (void *) w - p;
+}
+
+static struct arm_boot_info apollon_binfo = {
+ .loader_start = OMAP2_Q2_BASE,
+ /* Actually two chips of 0x4000000 bytes each */
+ .ram_size = 0x08000000,
+ .board_id = 0x397,
+ .atag_board = apollon_atag_setup,
+};
+
+static void apollon_init(ram_addr_t ram_size, int vga_ram_size,
+ const char *boot_device, DisplayState *ds,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+ struct apollon_s *s = (struct apollon_s *) qemu_mallocz(sizeof(*s));
+ struct arm_boot_info *binfo = &apollon_binfo;
+ int sdram_size = binfo->ram_size;
+ int onenandram_size = 0x00010000;
+
+ if (ram_size < sdram_size + onenandram_size + OMAP242X_SRAM_SIZE) {
+ fprintf(stderr, "This architecture uses %i bytes of memory\n",
+ sdram_size + onenandram_size + OMAP242X_SRAM_SIZE);
+ exit(1);
+ }
+
+ s->cpu = omap2420_mpu_init(sdram_size, NULL, cpu_model);
+
+ /* Setup peripherals
+ *
+ * Believed external peripherals layout in the apollon:
+ * (spi bus 1)
+ * tsc2101
+ */
+ apollon_gpio_setup(s);
+ apollon_onenand_setup(s);
+
+ /* Setup initial (reset) machine state */
+
+ /* Start at the OneNAND bootloader. */
+ s->cpu->env->regs[15] = 0;
+
+ if (kernel_filename) {
+ /* Or at the linux loader. */
+ binfo->kernel_filename = kernel_filename;
+ binfo->kernel_cmdline = kernel_cmdline;
+ binfo->initrd_filename = initrd_filename;
+ arm_load_kernel(s->cpu->env, binfo);
+
+ qemu_register_reset(apollon_boot_init, s);
+ apollon_boot_init(s);
+ }
+
+#if 0
+ /* FIXME: We shouldn't really be doing this here. The LCD controller
+ will set the size once configured, so this just sets an initial
+ size until the guest activates the display. */
+ dpy_resize(ds, 800, 480);
+#endif
+
+ /* Interrupt line of NIC is connected to GPIO line 74 */
+ smc91c111_init(&nd_table[0], 0x08000300,
+ omap2_gpio_in_get(s->cpu->gpif, APOLLON_ETHERNET_GPIO)[0]);
+}
+
+QEMUMachine apollon_machine = {
+ "apollon",
+ "Samsung Apollon (OMAP2420)",
+ apollon_init,
+ (0x08000000 + 0x00010000 + OMAP242X_SRAM_SIZE) | RAMSIZE_FIXED,
+};
diff --git a/hw/boards.h b/hw/boards.h
index 22ac332..64c7ae6 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -89,6 +89,9 @@ extern QEMUMachine palmte_machine;
extern QEMUMachine n800_machine;
extern QEMUMachine n810_machine;
+/* apollon.c */
+extern QEMUMachine apollon_machine;
+
/* gumstix.c */
extern QEMUMachine connex_machine;
extern QEMUMachine verdex_machine;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index eb29a9f..2bb30d6 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -88,6 +88,7 @@ For system emulation, the following hardware targets are
supported:
@item Arnewsh MCF5206 evaluation board (ColdFire V2).
@item Palm Tungsten|E PDA (OMAP310 processor)
@item N800 and N810 tablets (OMAP2420 processor)
address@hidden Samsung apollon OneNAND board (OMAP2420 processor)
@item MusicPal (MV88W8618 ARM processor)
@end itemize
@@ -2604,6 +2605,29 @@ Nokia RETU and TAHVO multi-purpose chips with an RTC,
connected
through CBUS
@end itemize
+Samsung Apollon OneNAND development board emulation supports the following
elements:
address@hidden @minus
address@hidden
+Texas Instruments OMAP2420 System-on-chip (ARM 1136 core)
address@hidden
+RAM and non-volatile OneNAND Flash memories
address@hidden
+LAN91C96 Ethernet
address@hidden
+(TODO) Display connected to internal framebuffer chip and OMAP on-chip
+display controller and a Samsung LCD controller
address@hidden
+(TODO) TI TSC2101 touchscreen controllers driven through SPI bus
address@hidden
+Secure Digital card connected to OMAP MMC/SD host
address@hidden
+One OMAP on-chip UARTs
address@hidden
+(TODO) External USB transceiver chip connected to USB controller embedded in a
TI
address@hidden
+(TODO) Three GPIO switches and GPIO indicate LEDs
address@hidden itemize
+
The Luminary Micro Stellaris LM3S811EVB emulation includes the following
devices:
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 42ff584..c92bb15 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -14,6 +14,7 @@ void register_machines(void)
qemu_register_machine(&palmte_machine);
qemu_register_machine(&n800_machine);
qemu_register_machine(&n810_machine);
+ qemu_register_machine(&apollon_machine);
qemu_register_machine(&lm3s811evb_machine);
qemu_register_machine(&lm3s6965evb_machine);
qemu_register_machine(&connex_machine);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH] Add Apollon (OMAP24xx) board support (take #2),
Kyungmin Park <=