Skip to contentSkip to conversation

OMAP/GPMC: speed up NAND read access

PATCH Superseded Daniel Mack 1 participant 3 messages Jun 11, 2014

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover OMAP/GPMC: speed up NAND read access

Hi,

I spent some time looking into boot times of AM335x platforms. One big improvement I made came with adding support for GPMC prefetch mode, which gave a speed-up of NAND reads of roughly factor 2. This is what patch #1 does.

Note that this is currently limited to read operations in 8-bit mode, but I believe it could be easily extended to 16-bit operations if anyone has hardware to test it on. Using the engine for write mode speed improvements should also be doable, but I didn't spend time on it yet. That can be added as a separate patch later.

Patch #2 decreases the GPMC memory map window size from 256MiB to 16MiB. Admittedly, I'm not quite sure about the reason, but a read from offset 0 in this memory area will freeze U-Boot instantly if the size is configured to 256MiB. As contents of the FIFO are accessed in a pseudo-mode from offset 0 anyway, it doesn't really matter.

What I also did to further speed up my boot was to tweak the GPMC parameters for the NAND chip on our boards, but that's not part of this patch set, and probably deserves a little more cleanup.

Test results and feedback very welcome.

Thanks,
Daniel

Daniel Mack (2):
mtd: OMAP: Enable GPMC prefetch mode
ARM: omap-common: gpmp: decrease memory region size to 16MiB

 arch/arm/cpu/armv7/omap-common/mem-common.c |   2 +-
 doc/README.nand                             |   5 ++
 drivers/mtd/nand/omap_gpmc.c                | 115 +++++++++++++++++++++++++++-
 include/linux/mtd/omap_gpmc.h               |   6 +-
 4 files changed, 124 insertions(+), 4 deletions(-)
Signature · 1 line
1.9.3
#1 lore raw

PATCH 1/2 mtd: OMAP: Enable GPMC prefetch mode

Enable GPMC's prefetch feature for NAND access. This speeds up NAND read access a lot by pre-fetching contents in the background and reading them through the FIFO address.

The current implementation has two limitations:

a) it only works for 16bit
b) it only supports read access

Both is easily fixable by someone who has hardware to implement it.

Note that U-Boot code uses non word-aligned buffers to read data into, and request read lengths that are not multiples of 4, so both partial buffers (head and tail) have to be addressed.

Tested on AM335x hardware.

---
 doc/README.nand               |   5 ++
 drivers/mtd/nand/omap_gpmc.c  | 115 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/mtd/omap_gpmc.h |   6 ++-
 3 files changed, 123 insertions(+), 3 deletions(-)
doc/README.nand +5 -0
index 70cf768..6459f2a 100644
@@ -292,6 +292,11 @@ Platform specific options
 		Thus BCH16 can be supported on 4K page NAND.
 
 
+    CONFIG_NAND_OMAP_PREFETCH
+	On OMAP platforms that use the GPMC controller (CONFIG_NAND_OMAP_GPMC),
+	this options enables the code that uses the prefetch mode to speed up
+	read operations.
+
 NOTE:
 =====
 
drivers/mtd/nand/omap_gpmc.c +113 -2

130 lines not on this page · raw message

include/linux/mtd/omap_gpmc.h +5 -1
index 9a86582..6cbae45 100644
@@ -66,7 +66,11 @@ struct gpmc {
 	u32 status;		/* 0x54 */
 	u8 res5[0x8];		/* 0x58 */
 	struct gpmc_cs cs[8];	/* 0x60, 0x90, .. */
-	u8 res6[0x14];		/* 0x1E0 */
+	u32 prefetch_config1;	/* 0x1E0 */
+	u32 prefetch_config2;	/* 0x1E4 */
+	u32 res6;		/* 0x1E8 */
+	u32 prefetch_control;	/* 0x1EC */
+	u32 prefetch_status;	/* 0x1F0 */
 	u32 ecc_config;		/* 0x1F4 */
 	u32 ecc_control;	/* 0x1F8 */
 	u32 ecc_size_config;	/* 0x1FC */
Signature · 1 line
1.9.3
#2 lore raw

PATCH 2/2 ARM: omap-common: gpmp: decrease memory region size to 16MiB

In reply to Daniel Mack

That memory area is not used except for the first location, so it doesn't matter. However, with the length configured to 256MiB, U-Boot crased when accessing contents of the map.

---
 arch/arm/cpu/armv7/omap-common/mem-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/cpu/armv7/omap-common/mem-common.c +1 -1
index 944ef84..3595806 100644
@@ -99,7 +99,7 @@ void gpmc_init(void)
 						M_NAND_GPMC_CONFIG6,
 						0
 						};
-	u32 size = GPMC_SIZE_256M;
+	u32 size = GPMC_SIZE_16M;
 	u32 base = CONFIG_SYS_NAND_BASE;
 #elif defined(CONFIG_CMD_ONENAND)
 	const u32 gpmc_regs[GPMC_MAX_REG] = {	ONENAND_GPMC_CONFIG1,
Signature · 1 line
1.9.3