changeset 2980:b54e7bc232f0

ea lpc2468 nand: Add heuristic to improve i/o throughput
author Ross Younger <wry@ecoscentric.com>
date Tue, 10 Nov 2009 18:12:16 +0000
parents 013b321ed7df
children 868c53050a8b
files packages/hal/arm/lpc24xx/ea2468/current/ChangeLog packages/hal/arm/lpc24xx/ea2468/current/src/ea_lpc2468_nand.c
diffstat 2 files changed, 39 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/arm/lpc24xx/ea2468/current/ChangeLog
+++ b/packages/hal/arm/lpc24xx/ea2468/current/ChangeLog
@@ -2,6 +2,7 @@ 2009-11-10  Ross Younger <wry@ecoscentri
 
 	* ea_lpc2468_nand.c: Fix interrupt-mode brokenness when the debug
 	  level was low.
+	  Add heuristic to improve I/O throughput.
 
 2009-11-06  Ross Younger <wry@ecoscentric.com>
 
--- a/packages/hal/arm/lpc24xx/ea2468/current/src/ea_lpc2468_nand.c
+++ b/packages/hal/arm/lpc24xx/ea2468/current/src/ea_lpc2468_nand.c
@@ -118,7 +118,26 @@ static inline unsigned char read_data_1(
 
 static inline void read_data_bulk(cyg_nand_device *ctx, unsigned char *dp, size_t n)
 {
-    HAL_READ_UINT8_VECTOR(NAND_BASE, dp, n, 0);
+    // Most of the time, we expect to be dealing with word-aligned
+    // multiples of 4 bytes, so optimise for that case.
+    if ( ((CYG_ADDRWORD)dp&3)==0 && (n%4)==0) {
+        volatile cyg_uint8 const *a = (cyg_uint8*) NAND_BASE;
+        cyg_uint32 *ip = (cyg_uint32*) dp;
+        cyg_uint32 r;
+        n /= 4;
+#ifdef CYGHWR_HAL_ARM_BIGENDIAN
+#define ONEWORD do { r  = (*a) << 24; r |= (*a) << 16; r |= (*a) << 8; r |= *a; } while(0)
+#else
+#define ONEWORD do { r  = *a; r |= (*a) << 8; r |= (*a) << 16; r |= (*a) << 24; } while(0)
+#endif
+        while (n) {
+            ONEWORD;
+            *(ip++) = r;
+            --n;
+        }
+#undef ONEWORD
+    } else
+        HAL_READ_UINT8_VECTOR(NAND_BASE, dp, n, 0);
 }
 
 static inline void write_data_1(cyg_nand_device *ctx, unsigned char b)
@@ -128,7 +147,24 @@ static inline void write_data_1(cyg_nand
 
 static inline void write_data_bulk(cyg_nand_device *ctx, const unsigned char *dp, size_t n)
 {
-    HAL_WRITE_UINT8_VECTOR(NAND_BASE, dp, n, 0);
+    if ( ((CYG_ADDRWORD)dp&3)==0 && (n%4)==0) {
+        volatile cyg_uint8 *a = (cyg_uint8*) NAND_BASE;
+        cyg_uint32 *ip = (cyg_uint32*) dp;
+        cyg_uint32 r;
+        n /= 4;
+#ifdef CYGHWR_HAL_ARM_BIGENDIAN
+#define ONEWORD do { *a = (r>>24)&0xff; *a = (r>>16)&0xff; (*a) = (r>>8) & 0xff; (*a) = r & 0xff; } while(0)
+#else
+#define ONEWORD do { *a = r & 0xff; *a = (r>>8) & 0xff; *a = (r>>16)&0xff; *a = (r>>24)&0xff; } while(0)
+#endif
+        while (n) {
+            r = *(ip++);
+            ONEWORD;
+            --n;
+        }
+#undef ONEWORD
+    } else
+        HAL_WRITE_UINT8_VECTOR(NAND_BASE, dp, n, 0);
 }