[U-Boot-Users] Some RFCs about U-Boot's the generic FPGA support
Matthias Fuchs
matthias.fuchs at esd-electronics.com
Mon Aug 20 15:13:02 CEST 2007
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_ */
More information about the U-Boot
mailing list