omap3: nand: configurable fifo threshold to gain the throughput
authorSukumar Ghorai <s-ghorai@ti.com>
Fri, 28 Jan 2011 10:12:07 +0000 (15:42 +0530)
committerTony Lindgren <tony@atomide.com>
Thu, 17 Feb 2011 23:32:54 +0000 (15:32 -0800)
Configure the FIFO THREASHOLD value different for read and write to keep busy
both filling and to drain out of FIFO at reading and writing.

Signed-off-by: Vimal Singh <vimalsingh@ti.com>
Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/gpmc.c
arch/arm/plat-omap/include/plat/gpmc.h
drivers/mtd/nand/omap2.c

index 382dea83e4f038a74f0677418f5212ab8e2b76aa..674174365f787ccb3f5139a1a1afff2defefc82f 100644 (file)
@@ -60,7 +60,6 @@
 #define GPMC_CHUNK_SHIFT       24              /* 16 MB */
 #define GPMC_SECTION_SHIFT     28              /* 128 MB */
 
-#define PREFETCH_FIFOTHRESHOLD (0x40 << 8)
 #define CS_NUM_SHIFT           24
 #define ENABLE_PREFETCH                (0x1 << 7)
 #define DMA_MPU_MODE           2
@@ -606,15 +605,19 @@ EXPORT_SYMBOL(gpmc_nand_write);
 /**
  * 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 dma_mode,
+int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
                                unsigned int u32_count, int is_write)
 {
 
-       if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) {
+       if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) {
+               pr_err("gpmc: fifo threshold is not supported\n");
+               return -1;
+       } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) {
                /* Set the amount of bytes to be prefetched */
                gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count);
 
@@ -622,7 +625,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode,
                 * enable the engine. Set which cs is has requested for.
                 */
                gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) |
-                                       PREFETCH_FIFOTHRESHOLD |
+                                       PREFETCH_FIFOTHRESHOLD(fifo_th) |
                                        ENABLE_PREFETCH |
                                        (dma_mode << DMA_MPU_MODE) |
                                        (0x1 & is_write)));
index 9c060da0a873db3c475d311c86b9a1c3bf9d4819..a2434639063d6b02275bbcac17bf0a4f88f201ef 100644 (file)
@@ -83,6 +83,9 @@
 #define GPMC_IRQ_FIFOEVENTENABLE       0x01
 #define GPMC_IRQ_COUNT_EVENT           0x02
 
+#define PREFETCH_FIFOTHRESHOLD_MAX     0x40
+#define PREFETCH_FIFOTHRESHOLD(val)    ((val) << 8)
+
 /*
  * Note that all values in this struct are in nanoseconds except sync_clk
  * (which is in picoseconds), while the register values are in gpmc_fck cycles.
@@ -134,7 +137,7 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
 extern void gpmc_cs_free(int cs);
 extern int gpmc_cs_set_reserved(int cs, int reserved);
 extern int gpmc_cs_reserved(int cs);
-extern int gpmc_prefetch_enable(int cs, int dma_mode,
+extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
                                        unsigned int u32_count, int is_write);
 extern int gpmc_prefetch_reset(int cs);
 extern void omap3_gpmc_save_context(void);
index fbe841467175949456dd31aff4df968c060f2291..f1648fd5924afced6c90ed7da9e7a2cd031c9c8e 100644 (file)
@@ -244,7 +244,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
        }
 
        /* configure and start prefetch transfer */
-       ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);
+       ret = gpmc_prefetch_enable(info->gpmc_cs,
+                       PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0);
        if (ret) {
                /* PFPW engine is busy, use cpu copy method */
                if (info->nand.options & NAND_BUSWIDTH_16)
@@ -289,7 +290,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
        }
 
        /*  configure and start prefetch transfer */
-       ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1);
+       ret = gpmc_prefetch_enable(info->gpmc_cs,
+                       PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1);
        if (ret) {
                /* PFPW engine is busy, use cpu copy method */
                if (info->nand.options & NAND_BUSWIDTH_16)
@@ -345,8 +347,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
        int ret;
        unsigned long tim, limit;
 
-       /* The fifo depth is 64 bytes. We have a sync at each frame and frame
-        * length is 64 bytes.
+       /* The fifo depth is 64 bytes max.
+        * But configure the FIFO-threahold to 32 to get a sync at each frame
+        * and frame length is 32 bytes.
         */
        int buf_len = len >> 6;
 
@@ -387,7 +390,8 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
                                        OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC);
        }
        /*  configure and start prefetch transfer */
-       ret = gpmc_prefetch_enable(info->gpmc_cs, 0x1, len, is_write);
+       ret = gpmc_prefetch_enable(info->gpmc_cs,
+                       PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write);
        if (ret)
                /* PFPW engine is busy, use cpu copy method */
                goto out_copy;
@@ -522,7 +526,8 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
        init_completion(&info->comp);
 
        /*  configure and start prefetch transfer */
-       ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0);
+       ret = gpmc_prefetch_enable(info->gpmc_cs,
+                       PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0);
        if (ret)
                /* PFPW engine is busy, use cpu copy method */
                goto out_copy;
@@ -569,8 +574,9 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
        info->buf = (u_char *) buf;
        init_completion(&info->comp);
 
-       /*  configure and start prefetch transfer */
-       ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1);
+       /* configure and start prefetch transfer : size=24 */
+       ret = gpmc_prefetch_enable(info->gpmc_cs,
+                       (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1);
        if (ret)
                /* PFPW engine is busy, use cpu copy method */
                goto out_copy;