summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap
diff options
context:
space:
mode:
authorNishanth Menon <menon.nishanth@gmail.com>2008-09-11 10:22:44 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2008-09-15 10:11:05 +0200
commite9976b7268bd8a9aed45c989bff1aba4f01e338f (patch)
tree328395f98e8c08c4cde4c66c1896e5e12bf72ca2 /arch/arm/mach-omap
parentaec8bdd7e5dafeb29a56de799b798072bcf3d339 (diff)
downloadbarebox-e9976b7268bd8a9aed45c989bff1aba4f01e338f.tar.gz
barebox-e9976b7268bd8a9aed45c989bff1aba4f01e338f.tar.xz
OMAP: Add GPMC NAND support
This patch adds support for a generic GPMC driver also a GPMC controller driver to allow platforms to add NAND devices generically. Signed-off-by: Nishanth Menon <x0nishan@ti.com>
Diffstat (limited to 'arch/arm/mach-omap')
-rw-r--r--arch/arm/mach-omap/Kconfig10
-rw-r--r--arch/arm/mach-omap/Makefile1
-rw-r--r--arch/arm/mach-omap/gpmc.c117
3 files changed, 128 insertions, 0 deletions
diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
index e740de55e4..69f6370a8e 100644
--- a/arch/arm/mach-omap/Kconfig
+++ b/arch/arm/mach-omap/Kconfig
@@ -83,6 +83,16 @@ config OMAP_MALLOC_LEN
help
Say Y here if you like to have initial OMAP3 Clock configuration done from SRAM.
+config GPMC
+ prompt "Support for GPMC configuration"
+ bool
+ depends on (ARCH_OMAP2 || ARCH_OMAP3)
+ default y
+ help
+ Enable this if you use Texas Instrument's General purpose Memory
+ Controller(GPMC). GPMC allows you to configure devices such as NOR,
+ NAND, OneNAND etc.
+
# Get the board specific configurations
source board/omap/Kconfig
diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile
index 174410d9a4..f672dce3e0 100644
--- a/arch/arm/mach-omap/Makefile
+++ b/arch/arm/mach-omap/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_ARCH_OMAP) += syslib.o
obj-$(CONFIG_OMAP_CLOCK_SOURCE_S32K) += s32k_clksource.o
obj-$(CONFIG_ARCH_OMAP3) += omap3_core.o omap3_generic.o
obj-$(CONFIG_OMAP3_CLOCK_CONFIG) += omap3_clock_core.o omap3_clock.o
+obj-$(CONFIG_GPMC) += gpmc.o
diff --git a/arch/arm/mach-omap/gpmc.c b/arch/arm/mach-omap/gpmc.c
new file mode 100644
index 0000000000..22b5014f19
--- /dev/null
+++ b/arch/arm/mach-omap/gpmc.c
@@ -0,0 +1,117 @@
+/**
+ * @file
+ * @brief Provide Generic GPMC configuration option
+ *
+ * FileName: arch/arm/mach-omap/gpmc.c
+ *
+ * This file contains the generic GPMC implementation
+ *
+ */
+/*
+ * (C) Copyright 2008
+ * Texas Instruments, <www.ti.com>
+ * Nishanth Menon <x0nishan@ti.com>
+ *
+ * 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 of
+ * the License, or (at your option) any later version.
+ *
+ * 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 <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch/silicon.h>
+#include <asm/arch/gpmc.h>
+#include <asm/arch/sys_info.h>
+#include <asm/arch/syslib.h>
+
+/**
+ * @brief Do a Generic initialization of GPMC. if you choose otherwise,
+ * Use gpmc registers to modify the values. The defaults configured are:
+ * No idle, L3 free running, no timeout and no IRQs.
+ * we allow for gpmc_config data to be programmed, and will also disable
+ * ALL CS configurations
+ *
+ * @param cfg - GPMC_CFG register value
+ *
+ * @return void
+ */
+void gpmc_generic_init(unsigned int cfg)
+{
+ unsigned int reg = GPMC_REG(CONFIG7_0);
+ char x = 0;
+
+ debug("gpmccfg=%x\n", cfg);
+ /* Generic Configurations */
+ /* No idle, L3 clock free running */
+ __raw_writel(0x10, GPMC_REG(SYS_CONFIG));
+ /* No Timeout */
+ __raw_writel(0x00, GPMC_REG(TIMEOUT_CONTROL));
+ /* No IRQs */
+ __raw_writel(0x00, GPMC_REG(IRQ_ENABLE));
+ /* Write the gpmc_config value */
+ __raw_writel(cfg, GPMC_REG(CFG));
+
+ /* Disable all CS - prevents remaps
+ * But NEVER run me in XIP mode! I will Die!
+ */
+ while (x < GPMC_NUM_CS) {
+ debug("gpmccs=%d Reg:%x <-0x0\n", x, reg);
+ __raw_writel(0x0, reg);
+ reg += GPMC_CONFIG_CS_SIZE;
+ x++;
+ }
+ /* Give me a while to settle things down */
+ mdelay(1);
+}
+EXPORT_SYMBOL(gpmc_generic_init);
+
+/**
+ * @brief Configure the registers and enable a single CS.
+ *
+ * @param cs chip select index
+ * @param config gpmc_config structure describing the CS params
+ *
+ * @return void
+ */
+void gpmc_cs_config(char cs, struct gpmc_config *config)
+{
+ unsigned int reg = GPMC_REG(CONFIG1_0) + (cs * GPMC_CONFIG_CS_SIZE);
+ unsigned char x = 0;
+ debug("gpmccs=%x cfg=%x\n", cs, (unsigned int)config);
+
+ /* Disable the CS before reconfiguring */
+ __raw_writel(0x0, GPMC_REG(CONFIG7_0) + (cs * GPMC_CONFIG_CS_SIZE));
+ mdelay(1); /* Settling time */
+
+ /* Write the CFG1-6 regs */
+ while (x < 6) {
+ debug("gpmccfg=%d Reg:%x <-0x%x\n",
+ x, reg, config->cfg[x]);
+ __raw_writel(config->cfg[x], reg);
+ reg += GPMC_CONFIG_REG_OFF;
+ x++;
+ }
+ /* reg now points to CFG7 */
+ debug("gpmccfg=%d Reg:%x <-0x%x\n",
+ x, reg, (0x1 << 6) | /* CS enable */
+ ((config->size & 0xF) << 8) | /* Size */
+ ((config->base >> 24) & 0x3F));
+
+ __raw_writel((0x1 << 6) | /* CS enable */
+ ((config->size & 0xF) << 8) | /* Size */
+ ((config->base >> 24) & 0x3F), /* Address */
+ reg);
+ mdelay(1); /* Settling time */
+}
+EXPORT_SYMBOL(gpmc_cs_config);