Commit 317379a9 authored by Sukumar Ghorai's avatar Sukumar Ghorai Committed by Tony Lindgren

omap3: nand: configurable fifo threshold to gain the throughput

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: default avatarVimal Singh <vimalsingh@ti.com>
Signed-off-by: default avatarSukumar Ghorai <s-ghorai@ti.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 4e070376
...@@ -60,7 +60,6 @@ ...@@ -60,7 +60,6 @@
#define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */
#define GPMC_SECTION_SHIFT 28 /* 128 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */
#define PREFETCH_FIFOTHRESHOLD (0x40 << 8)
#define CS_NUM_SHIFT 24 #define CS_NUM_SHIFT 24
#define ENABLE_PREFETCH (0x1 << 7) #define ENABLE_PREFETCH (0x1 << 7)
#define DMA_MPU_MODE 2 #define DMA_MPU_MODE 2
...@@ -606,15 +605,19 @@ EXPORT_SYMBOL(gpmc_nand_write); ...@@ -606,15 +605,19 @@ EXPORT_SYMBOL(gpmc_nand_write);
/** /**
* gpmc_prefetch_enable - configures and starts prefetch transfer * gpmc_prefetch_enable - configures and starts prefetch transfer
* @cs: cs (chip select) number * @cs: cs (chip select) number
* @fifo_th: fifo threshold to be used for read/ write
* @dma_mode: dma mode enable (1) or disable (0) * @dma_mode: dma mode enable (1) or disable (0)
* @u32_count: number of bytes to be transferred * @u32_count: number of bytes to be transferred
* @is_write: prefetch read(0) or write post(1) mode * @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) 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 */ /* Set the amount of bytes to be prefetched */
gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count);
...@@ -622,7 +625,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, ...@@ -622,7 +625,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode,
* enable the engine. Set which cs is has requested for. * enable the engine. Set which cs is has requested for.
*/ */
gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) |
PREFETCH_FIFOTHRESHOLD | PREFETCH_FIFOTHRESHOLD(fifo_th) |
ENABLE_PREFETCH | ENABLE_PREFETCH |
(dma_mode << DMA_MPU_MODE) | (dma_mode << DMA_MPU_MODE) |
(0x1 & is_write))); (0x1 & is_write)));
......
...@@ -83,6 +83,9 @@ ...@@ -83,6 +83,9 @@
#define GPMC_IRQ_FIFOEVENTENABLE 0x01 #define GPMC_IRQ_FIFOEVENTENABLE 0x01
#define GPMC_IRQ_COUNT_EVENT 0x02 #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 * 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. * (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); ...@@ -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 void gpmc_cs_free(int cs);
extern int gpmc_cs_set_reserved(int cs, int reserved); extern int gpmc_cs_set_reserved(int cs, int reserved);
extern int gpmc_cs_reserved(int cs); 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); unsigned int u32_count, int is_write);
extern int gpmc_prefetch_reset(int cs); extern int gpmc_prefetch_reset(int cs);
extern void omap3_gpmc_save_context(void); extern void omap3_gpmc_save_context(void);
......
...@@ -244,7 +244,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) ...@@ -244,7 +244,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
} }
/* configure and start prefetch transfer */ /* 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) { if (ret) {
/* PFPW engine is busy, use cpu copy method */ /* PFPW engine is busy, use cpu copy method */
if (info->nand.options & NAND_BUSWIDTH_16) if (info->nand.options & NAND_BUSWIDTH_16)
...@@ -289,7 +290,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, ...@@ -289,7 +290,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
} }
/* configure and start prefetch transfer */ /* 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) { if (ret) {
/* PFPW engine is busy, use cpu copy method */ /* PFPW engine is busy, use cpu copy method */
if (info->nand.options & NAND_BUSWIDTH_16) if (info->nand.options & NAND_BUSWIDTH_16)
...@@ -345,8 +347,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, ...@@ -345,8 +347,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
int ret; int ret;
unsigned long tim, limit; unsigned long tim, limit;
/* The fifo depth is 64 bytes. We have a sync at each frame and frame /* The fifo depth is 64 bytes max.
* length is 64 bytes. * 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; int buf_len = len >> 6;
...@@ -387,7 +390,8 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, ...@@ -387,7 +390,8 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC); OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC);
} }
/* configure and start prefetch transfer */ /* 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) if (ret)
/* PFPW engine is busy, use cpu copy method */ /* PFPW engine is busy, use cpu copy method */
goto out_copy; goto out_copy;
...@@ -522,7 +526,8 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) ...@@ -522,7 +526,8 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)
init_completion(&info->comp); init_completion(&info->comp);
/* configure and start prefetch transfer */ /* 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) if (ret)
/* PFPW engine is busy, use cpu copy method */ /* PFPW engine is busy, use cpu copy method */
goto out_copy; goto out_copy;
...@@ -569,8 +574,9 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, ...@@ -569,8 +574,9 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd,
info->buf = (u_char *) buf; info->buf = (u_char *) buf;
init_completion(&info->comp); init_completion(&info->comp);
/* configure and start prefetch transfer */ /* configure and start prefetch transfer : size=24 */
ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); ret = gpmc_prefetch_enable(info->gpmc_cs,
(PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1);
if (ret) if (ret)
/* PFPW engine is busy, use cpu copy method */ /* PFPW engine is busy, use cpu copy method */
goto out_copy; goto out_copy;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment