diff options
Diffstat (limited to 'board/keymile/kmp204x/pci.c')
-rw-r--r-- | board/keymile/kmp204x/pci.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/board/keymile/kmp204x/pci.c b/board/keymile/kmp204x/pci.c index ec20c8afb4..a484eb5749 100644 --- a/board/keymile/kmp204x/pci.c +++ b/board/keymile/kmp204x/pci.c @@ -14,18 +14,103 @@ #include <libfdt.h> #include <fdt_support.h> #include <asm/fsl_serdes.h> +#include <asm/errno.h> #include "kmp204x.h" +#define PROM_SEL_L 11 +/* control the PROM_SEL_L signal*/ +static void toggle_fpga_eeprom_bus(bool cpu_own) +{ + qrio_gpio_direction_output(GPIO_A, PROM_SEL_L, !cpu_own); +} + +#define CONF_SEL_L 10 +#define FPGA_PROG_L 19 +#define FPGA_DONE 18 +#define FPGA_INIT_L 17 + +int trigger_fpga_config(void) +{ + int ret = 0, init_l; + /* approx 10ms */ + u32 timeout = 10000; + + /* make sure the FPGA_can access the EEPROM */ + toggle_fpga_eeprom_bus(false); + + /* assert CONF_SEL_L to be able to drive FPGA_PROG_L */ + qrio_gpio_direction_output(GPIO_A, CONF_SEL_L, 0); + + /* trigger the config start */ + qrio_gpio_direction_output(GPIO_A, FPGA_PROG_L, 0); + + /* small delay for INIT_L line */ + udelay(10); + + /* wait for FPGA_INIT to be asserted */ + do { + init_l = qrio_get_gpio(GPIO_A, FPGA_INIT_L); + if (timeout-- == 0) { + printf("FPGA_INIT timeout\n"); + ret = -EFAULT; + break; + } + udelay(10); + } while (init_l); + + /* deassert FPGA_PROG, config should start */ + qrio_set_gpio(GPIO_A, FPGA_PROG_L, 1); + + return ret; +} + +/* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */ +static int wait_for_fpga_config(void) +{ + int ret = 0, done; + /* approx 5 s */ + u32 timeout = 500000; + + printf("PCIe FPGA config:"); + do { + done = qrio_get_gpio(GPIO_A, FPGA_DONE); + if (timeout-- == 0) { + printf(" FPGA_DONE timeout\n"); + ret = -EFAULT; + goto err_out; + } + udelay(10); + } while (!done); + + printf(" done\n"); + +err_out: + /* deactive CONF_SEL and give the CPU conf EEPROM access */ + qrio_set_gpio(GPIO_A, CONF_SEL_L, 1); + toggle_fpga_eeprom_bus(true); + + return ret; +} + #define PCIE_SW_RST 14 +#define PEXHC_SW_RST 13 #define HOOPER_SW_RST 12 void pci_init_board(void) { + /* first wait for the PCIe FPGA to be configured + * it has been triggered earlier in board_early_init_r */ + int ret = wait_for_fpga_config(); + if (ret) + printf("error finishing PCIe FPGA config\n"); + qrio_prst(PCIE_SW_RST, false, false); + qrio_prst(PEXHC_SW_RST, false, false); qrio_prst(HOOPER_SW_RST, false, false); /* Hooper is not direcly PCIe capable */ mdelay(50); + fsl_pcie_init_board(0); } |