David Brownell
Abstract the orion_nand_fast_block_write() routine into a separate routine -- arm_nandwrite() -- so that other ARM cores can reuse it. Have davinci_nand do so. This faster than byte-at-a-time ops by a factor of three (!), even given the slowish interactions to support hardware ECC (1-bit flavor in that test) each 512 bytes; those could be read more efficiently by on-chip code. NOTE that until there's a generic "ARM algorithm" structure, this can't work on newer ARMv6 (like ARM1136) or ARMv7A (like Cortex-A8) cores, though the downloaded code itself would work just fine there. git-svn-id: svn://svn.berlios.de/openocd/trunk@2663 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "nand.h"
|
||||
#include "arm_nandio.h"
|
||||
|
||||
|
||||
enum ecc {
|
||||
@@ -51,6 +51,9 @@ struct davinci_nand {
|
||||
uint32_t cmd; /* with CLE */
|
||||
uint32_t addr; /* with ALE */
|
||||
|
||||
/* write acceleration */
|
||||
struct arm_nand_data io;
|
||||
|
||||
/* page i/o for the relevant flavor of hardware ECC */
|
||||
int (*read_page)(struct nand_device_s *nand, uint32_t page,
|
||||
uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
|
||||
@@ -181,7 +184,7 @@ static int davinci_read_data(struct nand_device_s *nand, void *data)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* REVISIT a bit of native code should let block I/O be MUCH faster */
|
||||
/* REVISIT a bit of native code should let block reads be MUCH faster */
|
||||
|
||||
static int davinci_read_block_data(struct nand_device_s *nand,
|
||||
uint8_t *data, int data_size)
|
||||
@@ -223,10 +226,17 @@ static int davinci_write_block_data(struct nand_device_s *nand,
|
||||
target_t *target = info->target;
|
||||
uint32_t nfdata = info->data;
|
||||
uint32_t tmp;
|
||||
int status;
|
||||
|
||||
if (!halted(target, "write_block"))
|
||||
return ERROR_NAND_OPERATION_FAILED;
|
||||
|
||||
/* try the fast way first */
|
||||
status = arm_nandwrite(&info->io, data, data_size);
|
||||
if (status != ERROR_NAND_NO_BUFFER)
|
||||
return status;
|
||||
|
||||
/* else do it slowly */
|
||||
while (data_size >= 4) {
|
||||
tmp = le_to_h_u32(data);
|
||||
target_write_u32(target, nfdata, tmp);
|
||||
@@ -285,6 +295,12 @@ static int davinci_write_page(struct nand_device_s *nand, uint32_t page,
|
||||
memset(oob, 0x0ff, oob_size);
|
||||
}
|
||||
|
||||
/* REVISIT avoid wasting SRAM: unless nand->use_raw is set,
|
||||
* use 512 byte chunks. Read side support will often want
|
||||
* to include oob_size ...
|
||||
*/
|
||||
info->io.chunk_size = nand->page_size;
|
||||
|
||||
status = info->write_page(nand, page, data, data_size, oob, oob_size);
|
||||
free(ooballoc);
|
||||
return status;
|
||||
@@ -700,6 +716,9 @@ static int davinci_nand_device_command(struct command_context_s *cmd_ctx,
|
||||
|
||||
nand->controller_priv = info;
|
||||
|
||||
info->io.target = target;
|
||||
info->io.data = info->data;
|
||||
|
||||
/* NOTE: for now we don't do any error correction on read.
|
||||
* Nothing else in OpenOCD currently corrects read errors,
|
||||
* and in any case it's *writing* that we care most about.
|
||||
|
||||
Reference in New Issue
Block a user