qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Add Apollon (OMAP24xx) board support (take #2)
@ 2008-07-28  7:24 Kyungmin Park
  2008-08-01 21:04 ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 5+ messages in thread
From: Kyungmin Park @ 2008-07-28  7:24 UTC (permalink / raw)
  To: qemu-devel

Add apollon (OMAP24xx) board initial support
with board descriptions

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
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 <kyungmin.park@samsung.com>
+ *
+ * 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)
+@item 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:
+@itemize @minus
+@item
+Texas Instruments OMAP2420 System-on-chip (ARM 1136 core)
+@item
+RAM and non-volatile OneNAND Flash memories
+@item
+LAN91C96 Ethernet
+@item
+(TODO) Display connected to internal framebuffer chip and OMAP on-chip
+display controller and a Samsung LCD controller
+@item
+(TODO) TI TSC2101 touchscreen controllers driven through SPI bus
+@item
+Secure Digital card connected to OMAP MMC/SD host
+@item
+One OMAP on-chip UARTs
+@item
+(TODO) External USB transceiver chip connected to USB controller embedded in a TI
+@item
+(TODO) Three GPIO switches and GPIO indicate LEDs
+@end 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);

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-08-02 14:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-28  7:24 [Qemu-devel] [PATCH] Add Apollon (OMAP24xx) board support (take #2) Kyungmin Park
2008-08-01 21:04 ` Jean-Christophe PLAGNIOL-VILLARD
2008-08-02  1:49   ` Kyungmin Park
2008-08-02 13:38     ` Jean-Christophe PLAGNIOL-VILLARD
2008-08-02 14:53       ` Kyungmin Park

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).