
Hi,
I am currently setting up a new board that will use U-Boot's generic FPGA support to boot zwi different Xilinx FPGA in slave serial mode. While grep'ing through the U-Boot board config files I noticed that nearly nobody uses this code.
I made a couple of changes to the code. Some of them changes the current behavior a little bit, so I like to request for comments before submitting a final patch.
Since nobody uses this code I see nothing that speaks against these changes:
1) Make the 'size' parameter obsolete for the 'fpga loadb' command. The actual bitstream size is taken from the bitstream.
2) Do not bit-swap the bytes in the xilinx bitstream. When using the slave serial code the bits may not be swapped. I can imagine that this swapping requirement comes from a special board layout. So is should be done in board specific code. When removing the swapping code, we can get rid of the complete malloc/free stuff in fpga_loadbitstream().
3) Fix a signed/unsigned issue in slave serial download code.
4) Make post() and pre() callback optional in relocation. So do not relocate NULL-pointers. This has been discussed a short time ago on the list.
5) Add a post() configuration callback for Spartan II devices in slave serial mode.
6) Add some more devices.
7) Minor typo fixes.
Any comments?
BTW: Are there any boards that use the FPGA stuff and that are not made public ?:-)
Matthias
diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 3444091..2e1cf26 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -145,13 +145,14 @@ int fpga_loadbitstream(unsigned long dev dataptr+=4; printf(" bytes in bitstream = %d\n", swapsize);
- /* check consistency of length obtained */ - if (swapsize >= size) { + /* check consistency of length obtained when length parameter is non-0 */ + if (size && (swapsize >= size)) { printf("%s: Could not find right length of data in bitstream\n", __FUNCTION__); return FPGA_FAIL; }
+#if 0 /* mf test-only */ /* allocate memory */ swapdata = (unsigned char *)malloc(swapsize); if (swapdata == NULL) { @@ -178,6 +179,9 @@ int fpga_loadbitstream(unsigned long dev
rc = fpga_load(dev, swapdata, swapsize); free(swapdata); +#else + rc = fpga_load(dev, dataptr, swapsize); +#endif return rc; #else printf("Bitstream support only for Xilinx devices\n"); diff --git a/common/fpga.c b/common/fpga.c index 2eff239..2c231c2 100644 --- a/common/fpga.c +++ b/common/fpga.c @@ -112,11 +112,15 @@ static __attribute__((__const__)) fpga_d printf( "%s: Null buffer.\n", fn ); return (fpga_desc * const)NULL; } +#if 0 /* mf test-only + * bsize might be obsolete so do not check it. + * also bsize=3 is not better than 0 :-) + */ if ( !bsize ) { printf( "%s: Null buffer size.\n", fn ); return (fpga_desc * const)NULL; } - +#endif return desc; }
diff --git a/common/spartan2.c b/common/spartan2.c index 0fb23b6..bcb67ba 100644 --- a/common/spartan2.c +++ b/common/spartan2.c @@ -516,7 +516,7 @@ static int Spartan2_ss_load (Xilinx_desc (*fn->clk) (FALSE, TRUE, cookie); CONFIG_FPGA_DELAY (); /* Write data */ - (*fn->wr) ((val < 0), TRUE, cookie); + (*fn->wr) ((val & 0x80), TRUE, cookie); CONFIG_FPGA_DELAY (); /* Assert the clock */ (*fn->clk) (TRUE, TRUE, cookie); @@ -561,6 +561,13 @@ static int Spartan2_ss_load (Xilinx_desc } putc ('\n'); /* terminate the dotted line */
+ /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + #ifdef CFG_FPGA_PROG_FEEDBACK if (ret_val == FPGA_SUCCESS) { puts ("Done.\n"); @@ -615,8 +622,10 @@ static int Spartan2_ss_reloc (Xilinx_des PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, desc);
- addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; + if (fn->pre) { + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + }
addr = (ulong) (fn->pgm) + reloc_offset; fn_r->pgm = (Xilinx_pgm_fn) addr; @@ -633,6 +642,11 @@ static int Spartan2_ss_reloc (Xilinx_des addr = (ulong) (fn->wr) + reloc_offset; fn_r->wr = (Xilinx_wr_fn) addr;
+ if (fn->post) { + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + } + fn_r->relocated = TRUE;
} else { diff --git a/common/spartan3.c b/common/spartan3.c index c0f2b05..1435d1f 100644 --- a/common/spartan3.c +++ b/common/spartan3.c @@ -446,7 +446,7 @@ static int Spartan3_ss_load (Xilinx_desc int ret_val = FPGA_FAIL; /* assume the worst */ Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns; int i; - char val; + char val;
PRINTF ("%s: start with interface functions @ 0x%p\n", __FUNCTION__, fn); @@ -521,7 +521,7 @@ static int Spartan3_ss_load (Xilinx_desc (*fn->clk) (FALSE, TRUE, cookie); CONFIG_FPGA_DELAY (); /* Write data */ - (*fn->wr) ((val < 0), TRUE, cookie); + (*fn->wr) ((val & 0x80), TRUE, cookie); CONFIG_FPGA_DELAY (); /* Assert the clock */ (*fn->clk) (TRUE, TRUE, cookie); @@ -566,6 +566,13 @@ static int Spartan3_ss_load (Xilinx_desc } putc ('\n'); /* terminate the dotted line */
+ /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + #ifdef CFG_FPGA_PROG_FEEDBACK if (ret_val == FPGA_SUCCESS) { puts ("Done.\n"); @@ -620,8 +627,10 @@ static int Spartan3_ss_reloc (Xilinx_des PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, desc);
- addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; + if (fn->pre) { + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + }
addr = (ulong) (fn->pgm) + reloc_offset; fn_r->pgm = (Xilinx_pgm_fn) addr; @@ -638,6 +647,11 @@ static int Spartan3_ss_reloc (Xilinx_des addr = (ulong) (fn->wr) + reloc_offset; fn_r->wr = (Xilinx_wr_fn) addr;
+ if (fn->post) { + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + } + fn_r->relocated = TRUE;
} else { diff --git a/include/spartan2.h b/include/spartan2.h index d2e81e3..bd159e1 100644 --- a/include/spartan2.h +++ b/include/spartan2.h @@ -58,6 +58,7 @@ typedef struct { Xilinx_init_fn init; Xilinx_done_fn done; Xilinx_wr_fn wr; + Xilinx_post_fn post; int relocated; } Xilinx_Spartan2_Slave_Serial_fns;
@@ -69,6 +70,7 @@ typedef struct { #define XILINX_XC2S50_SIZE 559232/8 #define XILINX_XC2S100_SIZE 781248/8 #define XILINX_XC2S150_SIZE 1040128/8 +#define XILINX_XC2S200_SIZE 1335872/8
/* Spartan-IIE (1.8V) */ #define XILINX_XC2S50E_SIZE 630048/8 @@ -95,6 +97,9 @@ typedef struct { #define XILINX_XC2S150_DESC(iface, fn_table, cookie) \ { Xilinx_Spartan2, iface, XILINX_XC2S150_SIZE, fn_table, cookie }
+#define XILINX_XC2S200_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan2, iface, XILINX_XC2S200_SIZE, fn_table, cookie } + #define XILINX_XC2S50E_DESC(iface, fn_table, cookie) \ { Xilinx_Spartan2, iface, XILINX_XC2S50E_SIZE, fn_table, cookie }
diff --git a/include/spartan3.h b/include/spartan3.h index b14db03..95f62bc 100644 --- a/include/spartan3.h +++ b/include/spartan3.h @@ -58,6 +58,7 @@ typedef struct { Xilinx_init_fn init; Xilinx_done_fn done; Xilinx_wr_fn wr; + Xilinx_post_fn post; int relocated; } Xilinx_Spartan3_Slave_Serial_fns;
@@ -73,9 +74,12 @@ typedef struct { #define XILINX_XC3S4000_SIZE 11316864/8 #define XILINX_XC3S5000_SIZE 13271936/8
+/* Spartan-IIIE (1.2V) */ +#define XILINX_XC3S1200E_SIZE 3841184/8 + /* Descriptor Macros *********************************************************************/ -/* Spartan-II devices */ +/* Spartan-III devices */ #define XILINX_XC3S50_DESC(iface, fn_table, cookie) \ { Xilinx_Spartan3, iface, XILINX_XC3S50_SIZE, fn_table, cookie }
@@ -100,4 +104,9 @@ typedef struct { #define XILINX_XC3S5000_DESC(iface, fn_table, cookie) \ { Xilinx_Spartan3, iface, XILINX_XC3S5000E_SIZE, fn_table, cookie }
+ +/* Spartan-IIIE devices */ +#define XILINX_XC3S1200E_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan3, iface, XILINX_XC3S1200E_SIZE, fn_table, cookie } + #endif /* _SPARTAN3_H_ */