summaryrefslogtreecommitdiff
path: root/board/keymile
diff options
context:
space:
mode:
authorValentin Longchamp <valentin.longchamp@keymile.com>2012-07-05 05:05:08 +0000
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2012-07-07 14:07:37 +0200
commitbcac5b1b2c4f5f44a512dee7b0ac9ed64fd0bed0 (patch)
tree501ae50ae005f779b4ad2e82120057ea8a6f9168 /board/keymile
parentc1b8514a7a94b6b7e4e2bd779ecda16c86248299 (diff)
arm/km: skip FPGA config when already configured
In order to be able to perform board resets without interrupting the traffic, the configuration of an already properly configured FPGA is skipped. This is because some PCIe FPGAs embed some other function that must continue to work over reset. It is then the responsibility of the application to trigger a reconfiguration when needed. This is done by lowering the FPGA_INIT_B pin for delaying the configuration to u-boot @ next reboot, and then lower the FPGA_PROGRAM_B signal. Signed-off-by: Valentin Longchamp <valentin.longchamp@keymile.com>
Diffstat (limited to 'board/keymile')
-rw-r--r--board/keymile/km_arm/fpga_config.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/board/keymile/km_arm/fpga_config.c b/board/keymile/km_arm/fpga_config.c
index 4356b9a64e..8ac63931ec 100644
--- a/board/keymile/km_arm/fpga_config.c
+++ b/board/keymile/km_arm/fpga_config.c
@@ -96,12 +96,43 @@ static int boco_set_bits(u8 reg, u8 flags)
#define SPI_REG 0x06
#define CFG_EEPROM 0x02
#define FPGA_PROG 0x04
+#define FPGA_INIT_B 0x10
#define FPGA_DONE 0x20
+static int fpga_done()
+{
+ int ret = 0;
+ u8 regval;
+
+ /* this is only supported with the boco2 design */
+ if (!check_boco2())
+ return 0;
+
+ ret = i2c_read(BOCO_ADDR, SPI_REG, 1, &regval, 1);
+ if (ret) {
+ printf("%s: error reading the BOCO @%#x !!\n",
+ __func__, SPI_REG);
+ return 0;
+ }
+
+ return regval & FPGA_DONE ? 1 : 0;
+}
+
+int skip;
+
int trigger_fpga_config(void)
{
int ret = 0;
+ /* if the FPGA is already configured, we do not want to
+ * reconfigure it */
+ skip = 0;
+ if (fpga_done()) {
+ printf("PCIe FPGA config: skipped\n");
+ skip = 1;
+ return 0;
+ }
+
if (check_boco2()) {
/* we have a BOCO2, this has to be triggered here */
@@ -111,7 +142,7 @@ int trigger_fpga_config(void)
return ret;
/* trigger the config start */
- ret = boco_clear_bits(SPI_REG, FPGA_PROG);
+ ret = boco_clear_bits(SPI_REG, FPGA_PROG | FPGA_INIT_B);
if (ret)
return ret;
@@ -123,6 +154,11 @@ int trigger_fpga_config(void)
if (ret)
return ret;
+ /* finally, raise INIT_B to remove the config delay */
+ ret = boco_set_bits(SPI_REG, FPGA_INIT_B);
+ if (ret)
+ return ret;
+
} else {
/* we do it the old way, with the gpio pin */
kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1);
@@ -141,6 +177,9 @@ int wait_for_fpga_config(void)
u8 spictrl;
u32 timeout = 20000;
+ if (skip)
+ return 0;
+
if (!check_boco2()) {
/* we do not have BOCO2, this is not really used */
return 0;