orion5x: accelerate NAND on the TS-78xx
Subsystems (4)
Alexander Clouter
maintainerPATCH 1/1 orion5x: accelerate NAND on the TS-78xx
The NAND supports 32bit reads and writes so lets stop shunting 8bit chunks across the bus.
Doing a dumb 'dd' benchmark, this increases performance roughly like so:
* read: 1.3MB/s to 3.4MB/s
* write: 614kB/s to 882kB/s
--- arch/arm/mach-orion5x/ts78xx-setup.c | 42 ++++++++++++++++++++++++++++++++++ 1 files changed, 42 insertions(+), 0 deletions(-)
arch/arm/mach-orion5x/ts78xx-setup.c +42 -0
@@ -191,6 +191,46 @@ static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)return readb (TS_NAND_CTRL ) &0x20 ; } +static void ts78xx_ts_nand_write_buf (struct mtd_info *mtd, +const uint8_t *buf,int len) +{ +struct nand_chip *chip = mtd->priv; +void __iomem *io_base = chip->IO_ADDR_W; +uint32_t *buf32; +int i =0 ; + +while (len && (unsigned int )buf &3 ) { +writeb (*buf++, io_base); + len--; + } + buf32 = (uint32_t *)buf; +while (i < len/4 ) +writel (buf32[i++], io_base); + i *=4 ; +while (i < len) +writeb (buf[i++], io_base); +} + +static void ts78xx_ts_nand_read_buf (struct mtd_info *mtd, +uint8_t *buf,int len) +{ +struct nand_chip *chip = mtd->priv; +void __iomem *io_base = chip->IO_ADDR_R; +uint32_t *buf32; +int i =0 ; + +while (len && (unsigned int )buf &3 ) { + *buf++ =readb (io_base); + len--; + } + buf32 = (uint32_t *)buf; +while (i < len/4 ) + buf32[i++] =readl (io_base); + i *=4 ; +while (i < len) + buf[i++] =readb (io_base); +} +const char *ts_nand_part_probes[] = {"cmdlinepart" ,NULL };static struct mtd_partition ts78xx_ts_nand_parts[] = {
@@ -233,6 +273,8 @@ static struct platform_nand_data ts78xx_ts_nand_data = {*/ .cmd_ctrl = ts78xx_ts_nand_cmd_ctrl, .dev_ready = ts78xx_ts_nand_dev_ready, + .write_buf = ts78xx_ts_nand_write_buf, + .read_buf = ts78xx_ts_nand_read_buf, }, };
Signature · 1 line
1.7.2.3
PATCH 1/1 orion5x: accelerate NAND on the TS-78xx
Quoted 6 lines · Alexander Clouter
The NAND supports 32bit reads and writes so lets stop shunting 8bit chunks across the bus.
Doing a dumb 'dd' benchmark, this increases performance roughly like so:
* read: 1.3MB/s to 3.4MB/s
* write: 614kB/s to 882kB/s
Try something like the below. It's slightly more typing, but the underlying string IO functions should improve your transfer speed. Note that they won't do endian conversions.
Quoted 22 lines
Signed-off-by Alexander Clouter <[email protected]>--- arch/arm/mach-orion5x/ts78xx-setup.c | 42 ++++++++++++++++++++++++++++++++++ 1 files changed, 42 insertions(+), 0 deletions(-)arch/arm/mach-orion5x/ts78xx-setup.c +8
-0@@ -191,6 +191,46 @@ static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)return readb (TS_NAND_CTRL ) &0x20 ; } +static void ts78xx_ts_nand_write_buf (struct mtd_info *mtd, +const uint8_t *buf,int len) +{ +struct nand_chip *chip = mtd->priv; +void __iomem *io_base = chip->IO_ADDR_W; +uint32_t *buf32; +int i =0 ; +
arch/arm/mach-orion5x/ts78xx-setup.c static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd) · line 211
Quoted 10 lines
arch/arm/mach-orion5x/ts78xx-setup.c +10
-0+while (len && (unsigned int )buf &3 ) { +writeb (*buf++, io_base); + len--; + } + buf32 = (uint32_t *)buf; +while (i < len/4 ) +writel (buf32[i++], io_base); + i *=4 ; +while (i < len) +writeb (buf[i++], io_base);
unsigned long off = ((unsigned long)buf & 3);
int sz;
if (off) {
sz = min(4 - off, len);
writesb(io_base, buf, sz);
buf += sz;
len -= sz;
}
sz = len >> 2;
if (sz) {
u32 *buf32 = (u32 *)buf;
writesl(io_base, buf32, sz);
buf += sz << 2;
len -= sz << 2;
}
if (len)
writesb(io_base, buf, len);Quoted 10 lines
arch/arm/mach-orion5x/ts78xx-setup.c +10
-0+} + +static void ts78xx_ts_nand_read_buf (struct mtd_info *mtd, +uint8_t *buf,int len) +{ +struct nand_chip *chip = mtd->priv; +void __iomem *io_base = chip->IO_ADDR_R; +uint32_t *buf32; +int i =0 ; +
arch/arm/mach-orion5x/ts78xx-setup.c static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd) · line 231
Quoted 10 lines
arch/arm/mach-orion5x/ts78xx-setup.c +10
-0+while (len && (unsigned int )buf &3 ) { + *buf++ =readb (io_base); + len--; + } + buf32 = (uint32_t *)buf; +while (i < len/4 ) + buf32[i++] =readl (io_base); + i *=4 ; +while (i < len) + buf[i++] =readb (io_base);
unsigned long off = ((unsigned long)buf & 3);
int sz;
if (off) {
sz = min(4 - off, len);
readsb(io_base, buf, sz);
buf += sz;
len -= sz;
}
sz = len >> 2;
if (sz) {
u32 *buf32 = (u32 *)buf;
readsl(io_base, buf32, sz);
buf += sz << 2;
len -= sz << 2;
}
if (len)
readsb(io_base, buf, len);Quoted 21 lines
arch/arm/mach-orion5x/ts78xx-setup.c +4
-0+} +const char *ts_nand_part_probes[] = {"cmdlinepart" ,NULL };static struct mtd_partition ts78xx_ts_nand_parts[] = {@@ -233,6 +273,8 @@ static struct platform_nand_data ts78xx_ts_nand_data = {*/ .cmd_ctrl = ts78xx_ts_nand_cmd_ctrl, .dev_ready = ts78xx_ts_nand_dev_ready, + .write_buf = ts78xx_ts_nand_write_buf, + .read_buf = ts78xx_ts_nand_read_buf, }, };Signature · 6 lines
1.7.2.3 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Alexander Clouter
maintainerPATCH 1/1 orion5x: accelerate NAND on the TS-78xx
Quoted 5 lines · Russell King - ARM Linux
Quoted 3 lines · Alexander Clouter
The NAND supports 32bit reads and writes so lets stop shunting 8bit chunks across the bus.
Quoted 8 lines
Quoted 3 lines
Doing a dumb 'dd' benchmark, this increases performance roughly like so:
* read: 1.3MB/s to 3.4MB/s
* write: 614kB/s to 882kB/sTry something like the below. It's slightly more typing, but the underlying string IO functions should improve your transfer speed. Note that they won't do endian conversions.
I get roughly the same speeds with your approach...I am happy to swing either your way or my original implementation; well actually it was stolen from Nico's orion_nand implementation :)
What should I submit? These functions will at somestage get DMA support added.
Cheers
Signature · 2 lines
Alexander Clouter .sigmonster says: Live Free or Live in Massachusetts.
Alexander Clouter
maintainerPATCH 1/1 orion5x: accelerate NAND on the TS-78xx
Quoted 13 lines · Alexander Clouter
Quoted 13 lines · Alexander Clouter
Quoted 6 lines
The NAND supports 32bit reads and writes so lets stop shunting 8bit chunks across the bus.
Doing a dumb 'dd' benchmark, this increases performance roughly like so:
* read: 1.3MB/s to 3.4MB/s
* write: 614kB/s to 882kB/sTry something like the below. It's slightly more typing, but the underlying string IO functions should improve your transfer speed. Note that they won't do endian conversions.
Quoted 7 lines
I get roughly the same speeds with your approach...I am happy to swing either your way or my original implementation; well actually it was stolen from Nico's
orion_nandimplementation :)What should I submit? These functions will at somestage get DMA support added.
I decided I prefer your version and it 'hides' the while loops and is easier to read.
Cheers
Signature · 3 lines
Alexander Clouter
.sigmonster says: What!? Me worry?
-- Alfred E. Newman