aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Wegner2009-10-30 16:55:02 +0100
committerTsiChung Liew2010-03-24 11:08:43 -0500
commit89083346d0627a5e6e271e61bd34ab5121f9462b (patch)
tree6a46d3fe57befe0d6d0097bbf5f57c7d2bad95c5
parent9d79e5758c3a6776be9a86856823d28e7154a481 (diff)
add block write function to spartan3 slave serial load
Using seperate function calls for each bit-bang of slave serial load can be painfully slow. This patch adds the possibility to supply a block write function that loads the complete block of data in one call (like it can already be done with Altera FPGAs). On an MCF5373L (240 MHz) loading an XC3S4000 this reduces the load time from around 15 seconds to around 3 seconds Signed-off-by: Wolfgang Wegner <w.wegner at astro-kom.de>
-rw-r--r--drivers/fpga/spartan3.c54
-rw-r--r--include/spartan3.h1
-rw-r--r--include/xilinx.h1
3 files changed, 31 insertions, 25 deletions
diff --git a/drivers/fpga/spartan3.c b/drivers/fpga/spartan3.c
index 0fe30410a6f..7a89b5692cb 100644
--- a/drivers/fpga/spartan3.c
+++ b/drivers/fpga/spartan3.c
@@ -385,34 +385,38 @@ static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
} while ((*fn->init) (cookie));
/* Load the data */
- while (bytecount < bsize) {
-
- /* Xilinx detects an error if INIT goes low (active)
- while DONE is low (inactive) */
- if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
- puts ("** CRC error during FPGA load.\n");
- return (FPGA_FAIL);
- }
- val = data [bytecount ++];
- i = 8;
- do {
- /* Deassert the clock */
- (*fn->clk) (FALSE, TRUE, cookie);
- CONFIG_FPGA_DELAY ();
- /* Write data */
- (*fn->wr) ((val & 0x80), TRUE, cookie);
- CONFIG_FPGA_DELAY ();
- /* Assert the clock */
- (*fn->clk) (TRUE, TRUE, cookie);
- CONFIG_FPGA_DELAY ();
- val <<= 1;
- i --;
- } while (i > 0);
+ if(*fn->bwr)
+ (*fn->bwr) (data, bsize, TRUE, cookie);
+ else {
+ while (bytecount < bsize) {
+
+ /* Xilinx detects an error if INIT goes low (active)
+ while DONE is low (inactive) */
+ if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
+ puts ("** CRC error during FPGA load.\n");
+ return (FPGA_FAIL);
+ }
+ val = data [bytecount ++];
+ i = 8;
+ do {
+ /* Deassert the clock */
+ (*fn->clk) (FALSE, TRUE, cookie);
+ CONFIG_FPGA_DELAY ();
+ /* Write data */
+ (*fn->wr) ((val & 0x80), TRUE, cookie);
+ CONFIG_FPGA_DELAY ();
+ /* Assert the clock */
+ (*fn->clk) (TRUE, TRUE, cookie);
+ CONFIG_FPGA_DELAY ();
+ val <<= 1;
+ i --;
+ } while (i > 0);
#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
- if (bytecount % (bsize / 40) == 0)
- putc ('.'); /* let them know we are alive */
+ if (bytecount % (bsize / 40) == 0)
+ putc ('.'); /* let them know we are alive */
#endif
+ }
}
CONFIG_FPGA_DELAY ();
diff --git a/include/spartan3.h b/include/spartan3.h
index 30b1c2d62db..d5a589d0995 100644
--- a/include/spartan3.h
+++ b/include/spartan3.h
@@ -57,6 +57,7 @@ typedef struct {
Xilinx_done_fn done;
Xilinx_wr_fn wr;
Xilinx_post_fn post;
+ Xilinx_bwr_fn bwr; /* block write function */
} Xilinx_Spartan3_Slave_Serial_fns;
/* Device Image Sizes
diff --git a/include/xilinx.h b/include/xilinx.h
index d0799bc572b..2cb2e5b6aad 100644
--- a/include/xilinx.h
+++ b/include/xilinx.h
@@ -100,5 +100,6 @@ typedef int (*Xilinx_busy_fn)( int cookie );
typedef int (*Xilinx_abort_fn)( int cookie );
typedef int (*Xilinx_pre_fn)( int cookie );
typedef int (*Xilinx_post_fn)( int cookie );
+typedef int (*Xilinx_bwr_fn)( void *buf, size_t len, int flush, int cookie );
#endif /* _XILINX_H_ */