summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-08-02 12:01:02 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-08-03 19:32:07 +0200
commit5a693051df54d9c690d141095089449346e748e5 (patch)
tree419d9864d4d8feb76309aa25ac1f995d1892da60 /arch
parent67809258fa29a6022281437c08e4ceb7b10e7667 (diff)
downloadbarebox-5a693051df54d9c690d141095089449346e748e5.tar.gz
barebox-5a693051df54d9c690d141095089449346e748e5.tar.xz
mtd OMAP NAND: Use prefetch engine
Use the prefetch engine to improve NAND performance. The howto is derived from the Kernel. Unlike the kernel we do not make the access mode configurable. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap/gpmc.c61
-rw-r--r--arch/arm/mach-omap/include/mach/gpmc.h16
2 files changed, 74 insertions, 3 deletions
diff --git a/arch/arm/mach-omap/gpmc.c b/arch/arm/mach-omap/gpmc.c
index 92a8ae043d..5b4daaf031 100644
--- a/arch/arm/mach-omap/gpmc.c
+++ b/arch/arm/mach-omap/gpmc.c
@@ -31,6 +31,7 @@
#include <clock.h>
#include <init.h>
#include <io.h>
+#include <errno.h>
#include <mach/silicon.h>
#include <mach/gpmc.h>
#include <mach/sys_info.h>
@@ -125,3 +126,63 @@ void gpmc_cs_config(char cs, struct gpmc_config *config)
mdelay(1); /* Settling time */
}
EXPORT_SYMBOL(gpmc_cs_config);
+
+#define CS_NUM_SHIFT 24
+#define ENABLE_PREFETCH (0x1 << 7)
+#define DMA_MPU_MODE 2
+
+/**
+ * gpmc_prefetch_enable - configures and starts prefetch transfer
+ * @cs: cs (chip select) number
+ * @fifo_th: fifo threshold to be used for read/ write
+ * @dma_mode: dma mode enable (1) or disable (0)
+ * @u32_count: number of bytes to be transferred
+ * @is_write: prefetch read(0) or write post(1) mode
+ */
+int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
+ unsigned int u32_count, int is_write)
+{
+ if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) {
+ pr_err("gpmc: fifo threshold is not supported\n");
+ return -EINVAL;
+ }
+
+ /* Set the amount of bytes to be prefetched */
+ writel(u32_count, GPMC_REG(PREFETCH_CONFIG2));
+
+ /* Set dma/mpu mode, the prefetch read / post write and
+ * enable the engine. Set which cs is has requested for.
+ */
+ writel(((cs << CS_NUM_SHIFT) | PREFETCH_FIFOTHRESHOLD(fifo_th) |
+ ENABLE_PREFETCH | (dma_mode << DMA_MPU_MODE) |
+ (0x1 & is_write)),
+ GPMC_REG(PREFETCH_CONFIG1));
+
+ /* Start the prefetch engine */
+ writel(0x1, GPMC_REG(PREFETCH_CONTROL));
+
+ return 0;
+}
+EXPORT_SYMBOL(gpmc_prefetch_enable);
+
+/**
+ * gpmc_prefetch_reset - disables and stops the prefetch engine
+ */
+int gpmc_prefetch_reset(int cs)
+{
+ u32 config1;
+
+ /* check if the same module/cs is trying to reset */
+ config1 = readl(GPMC_REG(PREFETCH_CONFIG1));
+ if (((config1 >> CS_NUM_SHIFT) & 0x7) != cs)
+ return -EINVAL;
+
+ /* Stop the PFPW engine */
+ writel(0x0, GPMC_REG(PREFETCH_CONTROL));
+
+ /* Reset/disable the PFPW engine */
+ writel(0x0, GPMC_REG(PREFETCH_CONFIG1));
+
+ return 0;
+}
+EXPORT_SYMBOL(gpmc_prefetch_reset);
diff --git a/arch/arm/mach-omap/include/mach/gpmc.h b/arch/arm/mach-omap/include/mach/gpmc.h
index 3ddc5f5b87..ed4e82df7c 100644
--- a/arch/arm/mach-omap/include/mach/gpmc.h
+++ b/arch/arm/mach-omap/include/mach/gpmc.h
@@ -51,9 +51,10 @@
#define GPMC_TIMEOUT_CONTROL (0x40)
#define GPMC_CFG (0x50)
#define GPMC_STATUS (0x54)
-#define GPMC_PREFETCH_CONFIG_1 (0x1E0)
-#define GPMC_PREFETCH_CONFIG_2 (0x1E4)
-#define GPMC_PREFETCH_CTRL (0x1EC)
+#define GPMC_PREFETCH_CONFIG1 (0x1E0)
+#define GPMC_PREFETCH_CONFIG2 (0x1E4)
+#define GPMC_PREFETCH_CONTROL (0x1EC)
+#define GPMC_PREFETCH_STATUS (0x1f0)
#define GPMC_ECC_CONFIG (0x1F4)
#define GPMC_ECC_CONTROL (0x1F8)
#define GPMC_ECC_SIZE_CONFIG (0x1FC)
@@ -138,6 +139,15 @@
#define GPMC_SIZE_32M 0x0E
#define GPMC_SIZE_16M 0x0F
+#define PREFETCH_FIFOTHRESHOLD_MAX 0x40
+#define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8)
+#define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F)
+#define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff)
+
+int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
+ unsigned int u32_count, int is_write);
+int gpmc_prefetch_reset(int cs);
+
#define NAND_WP_BIT 0x00000010
#ifndef __ASSEMBLY__