* Patch by Gleb Natapov, 07 Sep 2004:
authorwdenk <wdenk>
Sun, 9 Jan 2005 18:12:51 +0000 (18:12 +0000)
committerwdenk <wdenk>
Sun, 9 Jan 2005 18:12:51 +0000 (18:12 +0000)
  mpc824x: set PCI latency timer to a sane value
  (is 0 after reset).

* Patch by Kurt Stremerch, 03 Sep 2004:
  Add bitstream configuration option for fpga command (Xilinx only).

CHANGELOG
common/cmd_fpga.c
cpu/mpc824x/cpu_init.c

index b6f3c89..4dd8038 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,13 @@
 Changes for U-Boot 1.1.3:
 ======================================================================
 
+* Patch by Gleb Natapov, 07 Sep 2004:
+  mpc824x: set PCI latency timer to a sane value
+  (is 0 after reset).
+
+* Patch by Kurt Stremerch, 03 Sep 2004:
+  Add bitstream configuration option for fpga command (Xilinx only).
+
 * Patch by Kurt Stremerch, 03 Sep 2004:
   Add Xilinx Spartan2E family FPGA support
 
index 325fdd1..7c762ba 100644 (file)
@@ -52,8 +52,122 @@ static int fpga_get_op (char *opstr);
 #define FPGA_NONE   -1
 #define FPGA_INFO   0
 #define FPGA_LOAD   1
+#define FPGA_LOADB  2
 #define FPGA_DUMP   3
 
+/* Convert bitstream data and load into the fpga */
+int fpga_loadbitstream(unsigned long dev, char* fpgadata, size_t size)
+{
+       int length;
+       char* swapdata;
+       int swapsize;
+       char buffer[80];
+       char *ptr;
+       char *dataptr;
+       int data;
+       int i;
+       int rc;
+
+       dataptr = fpgadata;
+
+#if CFG_FPGA_XILINX
+       /* skip the first 13 bytes of the bitsteam, their meaning is unknown */
+       dataptr+=13;
+
+       /* get design name (identifier, length, string) */
+       if (*dataptr++ != 0x61) {
+               PRINTF(__FUNCTION__ ": Design name identifier not recognized in bitstream.\n");
+               return FPGA_FAIL;
+       }
+
+       length = (*dataptr << 8) + *(dataptr+1); 
+       dataptr+=2;
+       for(i=0;i<length;i++)
+               buffer[i]=*dataptr++;
+       
+       buffer[length-5]='\0'; /* remove filename extension */
+       PRINTF(__FUNCTION__ ": design name = \"%s\".\n",buffer);
+
+       /* get part number (identifier, length, string) */
+       if (*dataptr++ != 0x62) {
+               printf(__FUNCTION__ ": Part number identifier not recognized in bitstream.\n");
+               return FPGA_FAIL;
+       }
+       
+       length = (*dataptr << 8) + *(dataptr+1); dataptr+=2;
+       for(i=0;i<length;i++) 
+               buffer[i]=*dataptr++;
+       PRINTF(__FUNCTION__ ": part number = \"%s\".\n",buffer);
+       
+       /* get date (identifier, length, string) */
+       if (*dataptr++ != 0x63) {
+               printf(__FUNCTION__ ": Date identifier not recognized in bitstream.\n");
+               return FPGA_FAIL;
+       }
+       
+       length = (*dataptr << 8) + *(dataptr+1); dataptr+=2;
+       for(i=0;i<length;i++)
+               buffer[i]=*dataptr++;
+       PRINTF(__FUNCTION__ ": date = \"%s\".\n",buffer);
+
+       /* get time (identifier, length, string) */
+       if (*dataptr++ != 0x64) {
+               printf(__FUNCTION__ ": Time identifier not recognized in bitstream.\n");
+               return FPGA_FAIL;
+       }
+       
+       length = (*dataptr << 8) + *(dataptr+1); dataptr+=2;
+       for(i=0;i<length;i++)
+               buffer[i]=*dataptr++;
+       PRINTF(__FUNCTION__ ": time = \"%s\".\n",buffer);
+       
+       /* get fpga data length (identifier, length) */
+       if (*dataptr++ != 0x65) {
+               printf(__FUNCTION__ ": Data length identifier not recognized in bitstream.\n");
+               return FPGA_FAIL;
+       }
+       swapsize = ((long)*dataptr<<24) + ((long)*(dataptr+1)<<16) + ((long)*(dataptr+2)<<8) + (long)*(dataptr+3);
+       dataptr+=4;
+       PRINTF(__FUNCTION__ ": bytes in bitstream = %d.\n",swapsize);
+       
+       /* check consistency of length obtained */
+       if (swapsize >= size) {
+               printf(__FUNCTION__ ": Could not find right length of data in bitstream.\n");
+               return FPGA_FAIL;
+       }
+       
+       /* allocate memory */
+       swapdata = (char *)malloc(swapsize);
+       if (swapdata == NULL) {
+               printf(__FUNCTION__ ": Could not allocate %d bytes memory !\n",swapsize);
+               return FPGA_FAIL;
+       }
+       
+       /* read data into memory and swap bits */
+       ptr = swapdata;
+       for (i = 0; i < swapsize; i++) {
+               data = 0x00;
+               data |= (*dataptr & 0x01) << 7;
+               data |= (*dataptr & 0x02) << 5;
+               data |= (*dataptr & 0x04) << 3;
+               data |= (*dataptr & 0x08) << 1;
+               data |= (*dataptr & 0x10) >> 1;
+               data |= (*dataptr & 0x20) >> 3;
+               data |= (*dataptr & 0x40) >> 5;
+               data |= (*dataptr & 0x80) >> 7;
+               *ptr++ = data;
+               dataptr++;
+       }
+
+       rc = fpga_load(dev, swapdata, swapsize);
+       free(swapdata);
+       return rc;
+#else
+       printf("Bitstream support only for Xilinx devices.\n");
+       return FPGA_FAIL;
+#endif
+}
+
 /* ------------------------------------------------------------------------- */
 /* command form:
  *   fpga <op> <device number> <data addr> <datasize>
@@ -118,6 +232,10 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
                rc = fpga_load (dev, fpga_data, data_size);
                break;
 
+       case FPGA_LOADB:
+               rc = fpga_loadbitstream(dev, fpga_data, data_size);
+               break;
+
        case FPGA_DUMP:
                rc = fpga_dump (dev, fpga_data, data_size);
                break;
@@ -145,6 +263,8 @@ static int fpga_get_op (char *opstr)
 
        if (!strcmp ("info", opstr)) {
                op = FPGA_INFO;
+       } else if (!strcmp ("loadb", opstr)) {
+               op = FPGA_LOADB;
        } else if (!strcmp ("load", opstr)) {
                op = FPGA_LOAD;
        } else if (!strcmp ("dump", opstr)) {
@@ -163,5 +283,6 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
            "fpga operations:\n"
            "\tinfo\tlist known device information.\n"
            "\tload\tLoad device from memory buffer.\n"
+           "\tloadb\tLoad device from bitstream buffer (Xilinx devices only).\n"
            "\tdump\tLoad device to memory buffer.\n");
 #endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */
index d0c7a3b..965f4fd 100644 (file)
@@ -90,7 +90,7 @@ cpu_init_f (void)
 #endif
 
        CONFIG_WRITE_BYTE(PCLSR, 0x8);  /* set PCI cache line size */
-
+       CONFIG_WRITE_BYTE (PLTR, 0x40); /* set PCI latency timer */
        /*
        * Note that although this bit is cleared after a hard reset, it
        * must be explicitly set and then cleared by software during