* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
* Keith Outwater, keith_outwater@mvis.com
+ *
+ * Copyright (c) 2019 SED Systems, a division of Calian Ltd.
*/
/*
}
/*
- * Virtex-II Slave SelectMap configuration loader. Configuration via
- * SelectMap is as follows:
+ * Virtex-II Slave SelectMap or Serial configuration loader. Configuration
+ * is as follows:
* 1. Set the FPGA's PROG_B line low.
* 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high.
* 3. Write data to the SelectMap port. If INIT_B goes low at any time
* INIT_B and DONE lines. If both are high, configuration has
* succeeded. Congratulations!
*/
-static int virtex2_slave_pre(xilinx_virtex2_slave_selectmap_fns *fn, int cookie)
+static int virtex2_slave_pre(xilinx_virtex2_slave_fns *fn, int cookie)
{
unsigned long ts;
return FPGA_SUCCESS;
}
-static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn,
+static int virtex2_slave_post(xilinx_virtex2_slave_fns *fn,
int cookie)
{
int ret_val = FPGA_SUCCESS;
ret_val = FPGA_FAIL;
break;
}
- (*fn->wdata) (0xff, true, cookie);
- CONFIG_FPGA_DELAY();
- (*fn->clk) (false, true, cookie);
- CONFIG_FPGA_DELAY();
- (*fn->clk) (true, true, cookie);
+ if (fn->wbulkdata) {
+ unsigned char dummy = 0xff;
+ (*fn->wbulkdata)(&dummy, 1, true, cookie);
+ } else {
+ (*fn->wdata)(0xff, true, cookie);
+ CONFIG_FPGA_DELAY();
+ (*fn->clk)(false, true, cookie);
+ CONFIG_FPGA_DELAY();
+ (*fn->clk)(true, true, cookie);
+ }
}
if (ret_val == FPGA_SUCCESS) {
static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
- xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns;
+ xilinx_virtex2_slave_fns *fn = desc->iface_fns;
size_t bytecount = 0;
unsigned char *data = (unsigned char *)buf;
int cookie = desc->cookie;
static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
- xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns;
+ xilinx_virtex2_slave_fns *fn = desc->iface_fns;
if (fn) {
unsigned char *data = (unsigned char *)buf;
static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
{
- printf("%s: Slave Serial Loading is unsupported\n", __func__);
- return FPGA_FAIL;
+ int ret_val = FPGA_FAIL;
+ xilinx_virtex2_slave_fns *fn = desc->iface_fns;
+ unsigned char *data = (unsigned char *)buf;
+ int cookie = desc->cookie;
+
+ ret_val = virtex2_slave_pre(fn, cookie);
+ if (ret_val != FPGA_SUCCESS)
+ return ret_val;
+
+ if (fn->wbulkdata) {
+ /* Load the data in a single chunk */
+ (*fn->wbulkdata)(data, bsize, true, cookie);
+ } else {
+ size_t bytecount = 0;
+
+ /*
+ * Load the data bit by bit
+ */
+ while (bytecount < bsize) {
+ unsigned char curr_data = data[bytecount++];
+ int bit;
+
+#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
+ if (ctrlc()) {
+ (*fn->abort) (cookie);
+ return FPGA_FAIL;
+ }
+#endif
+
+ if ((*fn->done)(cookie) == FPGA_SUCCESS) {
+ PRINTF("%s:%d:done went active early, bytecount = %d\n",
+ __func__, __LINE__, bytecount);
+ break;
+ }
+
+#ifdef CONFIG_SYS_FPGA_CHECK_ERROR
+ if ((*fn->init)(cookie)) {
+ printf("\n%s:%d: ** Error: INIT asserted during configuration\n",
+ __func__, __LINE__);
+ printf("%zu = buffer offset, %zu = buffer size\n",
+ bytecount, bsize);
+ (*fn->abort)(cookie);
+ return FPGA_FAIL;
+ }
+#endif
+
+ for (bit = 7; bit >= 0; --bit) {
+ unsigned char curr_bit = (curr_data >> bit) & 1;
+ (*fn->wdata)(curr_bit, true, cookie);
+ CONFIG_FPGA_DELAY();
+ (*fn->clk)(false, true, cookie);
+ CONFIG_FPGA_DELAY();
+ (*fn->clk)(true, true, cookie);
+ }
+
+ /* Slave serial never uses a busy pin */
+
+#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
+ if (bytecount % (bsize / 40) == 0)
+ putc('.');
+#endif
+ }
+ }
+
+ return virtex2_slave_post(fn, cookie);
}
static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)