diff options
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 11 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/gpmc.h | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/omap2.c | 22 |
3 files changed, 25 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 382dea83e4f0..674174365f78 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -60,7 +60,6 @@ | |||
60 | #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ | 60 | #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ |
61 | #define GPMC_SECTION_SHIFT 28 /* 128 MB */ | 61 | #define GPMC_SECTION_SHIFT 28 /* 128 MB */ |
62 | 62 | ||
63 | #define PREFETCH_FIFOTHRESHOLD (0x40 << 8) | ||
64 | #define CS_NUM_SHIFT 24 | 63 | #define CS_NUM_SHIFT 24 |
65 | #define ENABLE_PREFETCH (0x1 << 7) | 64 | #define ENABLE_PREFETCH (0x1 << 7) |
66 | #define DMA_MPU_MODE 2 | 65 | #define DMA_MPU_MODE 2 |
@@ -606,15 +605,19 @@ EXPORT_SYMBOL(gpmc_nand_write); | |||
606 | /** | 605 | /** |
607 | * gpmc_prefetch_enable - configures and starts prefetch transfer | 606 | * gpmc_prefetch_enable - configures and starts prefetch transfer |
608 | * @cs: cs (chip select) number | 607 | * @cs: cs (chip select) number |
608 | * @fifo_th: fifo threshold to be used for read/ write | ||
609 | * @dma_mode: dma mode enable (1) or disable (0) | 609 | * @dma_mode: dma mode enable (1) or disable (0) |
610 | * @u32_count: number of bytes to be transferred | 610 | * @u32_count: number of bytes to be transferred |
611 | * @is_write: prefetch read(0) or write post(1) mode | 611 | * @is_write: prefetch read(0) or write post(1) mode |
612 | */ | 612 | */ |
613 | int gpmc_prefetch_enable(int cs, int dma_mode, | 613 | int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, |
614 | unsigned int u32_count, int is_write) | 614 | unsigned int u32_count, int is_write) |
615 | { | 615 | { |
616 | 616 | ||
617 | if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { | 617 | if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { |
618 | pr_err("gpmc: fifo threshold is not supported\n"); | ||
619 | return -1; | ||
620 | } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { | ||
618 | /* Set the amount of bytes to be prefetched */ | 621 | /* Set the amount of bytes to be prefetched */ |
619 | gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); | 622 | gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); |
620 | 623 | ||
@@ -622,7 +625,7 @@ int gpmc_prefetch_enable(int cs, int dma_mode, | |||
622 | * enable the engine. Set which cs is has requested for. | 625 | * enable the engine. Set which cs is has requested for. |
623 | */ | 626 | */ |
624 | gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | | 627 | gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | |
625 | PREFETCH_FIFOTHRESHOLD | | 628 | PREFETCH_FIFOTHRESHOLD(fifo_th) | |
626 | ENABLE_PREFETCH | | 629 | ENABLE_PREFETCH | |
627 | (dma_mode << DMA_MPU_MODE) | | 630 | (dma_mode << DMA_MPU_MODE) | |
628 | (0x1 & is_write))); | 631 | (0x1 & is_write))); |
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 9c060da0a873..a2434639063d 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h | |||
@@ -83,6 +83,9 @@ | |||
83 | #define GPMC_IRQ_FIFOEVENTENABLE 0x01 | 83 | #define GPMC_IRQ_FIFOEVENTENABLE 0x01 |
84 | #define GPMC_IRQ_COUNT_EVENT 0x02 | 84 | #define GPMC_IRQ_COUNT_EVENT 0x02 |
85 | 85 | ||
86 | #define PREFETCH_FIFOTHRESHOLD_MAX 0x40 | ||
87 | #define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8) | ||
88 | |||
86 | /* | 89 | /* |
87 | * Note that all values in this struct are in nanoseconds except sync_clk | 90 | * Note that all values in this struct are in nanoseconds except sync_clk |
88 | * (which is in picoseconds), while the register values are in gpmc_fck cycles. | 91 | * (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 | extern void gpmc_cs_free(int cs); | 137 | extern void gpmc_cs_free(int cs); |
135 | extern int gpmc_cs_set_reserved(int cs, int reserved); | 138 | extern int gpmc_cs_set_reserved(int cs, int reserved); |
136 | extern int gpmc_cs_reserved(int cs); | 139 | extern int gpmc_cs_reserved(int cs); |
137 | extern int gpmc_prefetch_enable(int cs, int dma_mode, | 140 | extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, |
138 | unsigned int u32_count, int is_write); | 141 | unsigned int u32_count, int is_write); |
139 | extern int gpmc_prefetch_reset(int cs); | 142 | extern int gpmc_prefetch_reset(int cs); |
140 | extern void omap3_gpmc_save_context(void); | 143 | extern void omap3_gpmc_save_context(void); |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index fbe841467175..f1648fd5924a 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -244,7 +244,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) | |||
244 | } | 244 | } |
245 | 245 | ||
246 | /* configure and start prefetch transfer */ | 246 | /* configure and start prefetch transfer */ |
247 | ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); | 247 | ret = gpmc_prefetch_enable(info->gpmc_cs, |
248 | PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); | ||
248 | if (ret) { | 249 | if (ret) { |
249 | /* PFPW engine is busy, use cpu copy method */ | 250 | /* PFPW engine is busy, use cpu copy method */ |
250 | if (info->nand.options & NAND_BUSWIDTH_16) | 251 | if (info->nand.options & NAND_BUSWIDTH_16) |
@@ -289,7 +290,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, | |||
289 | } | 290 | } |
290 | 291 | ||
291 | /* configure and start prefetch transfer */ | 292 | /* configure and start prefetch transfer */ |
292 | ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); | 293 | ret = gpmc_prefetch_enable(info->gpmc_cs, |
294 | PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); | ||
293 | if (ret) { | 295 | if (ret) { |
294 | /* PFPW engine is busy, use cpu copy method */ | 296 | /* PFPW engine is busy, use cpu copy method */ |
295 | if (info->nand.options & NAND_BUSWIDTH_16) | 297 | 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 | int ret; | 347 | int ret; |
346 | unsigned long tim, limit; | 348 | unsigned long tim, limit; |
347 | 349 | ||
348 | /* The fifo depth is 64 bytes. We have a sync at each frame and frame | 350 | /* The fifo depth is 64 bytes max. |
349 | * length is 64 bytes. | 351 | * But configure the FIFO-threahold to 32 to get a sync at each frame |
352 | * and frame length is 32 bytes. | ||
350 | */ | 353 | */ |
351 | int buf_len = len >> 6; | 354 | int buf_len = len >> 6; |
352 | 355 | ||
@@ -387,7 +390,8 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | |||
387 | OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC); | 390 | OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC); |
388 | } | 391 | } |
389 | /* configure and start prefetch transfer */ | 392 | /* configure and start prefetch transfer */ |
390 | ret = gpmc_prefetch_enable(info->gpmc_cs, 0x1, len, is_write); | 393 | ret = gpmc_prefetch_enable(info->gpmc_cs, |
394 | PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); | ||
391 | if (ret) | 395 | if (ret) |
392 | /* PFPW engine is busy, use cpu copy method */ | 396 | /* PFPW engine is busy, use cpu copy method */ |
393 | goto out_copy; | 397 | goto out_copy; |
@@ -522,7 +526,8 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) | |||
522 | init_completion(&info->comp); | 526 | init_completion(&info->comp); |
523 | 527 | ||
524 | /* configure and start prefetch transfer */ | 528 | /* configure and start prefetch transfer */ |
525 | ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); | 529 | ret = gpmc_prefetch_enable(info->gpmc_cs, |
530 | PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0); | ||
526 | if (ret) | 531 | if (ret) |
527 | /* PFPW engine is busy, use cpu copy method */ | 532 | /* PFPW engine is busy, use cpu copy method */ |
528 | goto out_copy; | 533 | goto out_copy; |
@@ -569,8 +574,9 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, | |||
569 | info->buf = (u_char *) buf; | 574 | info->buf = (u_char *) buf; |
570 | init_completion(&info->comp); | 575 | init_completion(&info->comp); |
571 | 576 | ||
572 | /* configure and start prefetch transfer */ | 577 | /* configure and start prefetch transfer : size=24 */ |
573 | ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); | 578 | ret = gpmc_prefetch_enable(info->gpmc_cs, |
579 | (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1); | ||
574 | if (ret) | 580 | if (ret) |
575 | /* PFPW engine is busy, use cpu copy method */ | 581 | /* PFPW engine is busy, use cpu copy method */ |
576 | goto out_copy; | 582 | goto out_copy; |