Commit 27c78e06f2b42bd6285ed104ece23f6c69e42e6f

Authored by Valentin Longchamp
Committed by York Sun
1 parent 47c1180c02

kmp204x: initial support for PCIe FPGA configuration

The PEXHC PCIe configuration mechanism ensures that the FPGA get
configured at power-up. Since all the PCIe devices should be configured
when the kernel start, u-boot has to take care that the FPGA gets
configured also in other reset scenarios, mostly because of possible
configuration change.

The used mechanism is taken from the km_kirkwood design and adapted to
the kmp204x case (slightly different HW and PCIe configuration).

Signed-off-by: Valentin Longchamp <valentin.longchamp@keymile.com>
Reviewed-by: York Sun <yorksun@freescale.com>

Showing 2 changed files with 91 additions and 1 deletions Side-by-side Diff

board/keymile/kmp204x/kmp204x.c
... ... @@ -101,6 +101,7 @@
101 101  
102 102 int board_early_init_r(void)
103 103 {
  104 + int ret = 0;
104 105 /* Flush d-cache and invalidate i-cache of any FLASH data */
105 106 flush_dcache();
106 107 invalidate_icache();
... ... @@ -108,7 +109,11 @@
108 109 set_liodns();
109 110 setup_portals();
110 111  
111   - return 0;
  112 + ret = trigger_fpga_config();
  113 + if (ret)
  114 + printf("error triggering PCIe FPGA config\n");
  115 +
  116 + return ret;
112 117 }
113 118  
114 119 unsigned long get_board_sys_clk(unsigned long dummy)
board/keymile/kmp204x/pci.c
... ... @@ -14,18 +14,103 @@
14 14 #include <libfdt.h>
15 15 #include <fdt_support.h>
16 16 #include <asm/fsl_serdes.h>
  17 +#include <asm/errno.h>
17 18  
18 19 #include "kmp204x.h"
19 20  
  21 +#define PROM_SEL_L 11
  22 +/* control the PROM_SEL_L signal*/
  23 +static void toggle_fpga_eeprom_bus(bool cpu_own)
  24 +{
  25 + qrio_gpio_direction_output(GPIO_A, PROM_SEL_L, !cpu_own);
  26 +}
  27 +
  28 +#define CONF_SEL_L 10
  29 +#define FPGA_PROG_L 19
  30 +#define FPGA_DONE 18
  31 +#define FPGA_INIT_L 17
  32 +
  33 +int trigger_fpga_config(void)
  34 +{
  35 + int ret = 0, init_l;
  36 + /* approx 10ms */
  37 + u32 timeout = 10000;
  38 +
  39 + /* make sure the FPGA_can access the EEPROM */
  40 + toggle_fpga_eeprom_bus(false);
  41 +
  42 + /* assert CONF_SEL_L to be able to drive FPGA_PROG_L */
  43 + qrio_gpio_direction_output(GPIO_A, CONF_SEL_L, 0);
  44 +
  45 + /* trigger the config start */
  46 + qrio_gpio_direction_output(GPIO_A, FPGA_PROG_L, 0);
  47 +
  48 + /* small delay for INIT_L line */
  49 + udelay(10);
  50 +
  51 + /* wait for FPGA_INIT to be asserted */
  52 + do {
  53 + init_l = qrio_get_gpio(GPIO_A, FPGA_INIT_L);
  54 + if (timeout-- == 0) {
  55 + printf("FPGA_INIT timeout\n");
  56 + ret = -EFAULT;
  57 + break;
  58 + }
  59 + udelay(10);
  60 + } while (init_l);
  61 +
  62 + /* deassert FPGA_PROG, config should start */
  63 + qrio_set_gpio(GPIO_A, FPGA_PROG_L, 1);
  64 +
  65 + return ret;
  66 +}
  67 +
  68 +/* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */
  69 +static int wait_for_fpga_config(void)
  70 +{
  71 + int ret = 0, done;
  72 + /* approx 5 s */
  73 + u32 timeout = 500000;
  74 +
  75 + printf("PCIe FPGA config:");
  76 + do {
  77 + done = qrio_get_gpio(GPIO_A, FPGA_DONE);
  78 + if (timeout-- == 0) {
  79 + printf(" FPGA_DONE timeout\n");
  80 + ret = -EFAULT;
  81 + goto err_out;
  82 + }
  83 + udelay(10);
  84 + } while (!done);
  85 +
  86 + printf(" done\n");
  87 +
  88 +err_out:
  89 + /* deactive CONF_SEL and give the CPU conf EEPROM access */
  90 + qrio_set_gpio(GPIO_A, CONF_SEL_L, 1);
  91 + toggle_fpga_eeprom_bus(true);
  92 +
  93 + return ret;
  94 +}
  95 +
20 96 #define PCIE_SW_RST 14
  97 +#define PEXHC_SW_RST 13
21 98 #define HOOPER_SW_RST 12
22 99  
23 100 void pci_init_board(void)
24 101 {
  102 + /* first wait for the PCIe FPGA to be configured
  103 + * it has been triggered earlier in board_early_init_r */
  104 + int ret = wait_for_fpga_config();
  105 + if (ret)
  106 + printf("error finishing PCIe FPGA config\n");
  107 +
25 108 qrio_prst(PCIE_SW_RST, false, false);
  109 + qrio_prst(PEXHC_SW_RST, false, false);
26 110 qrio_prst(HOOPER_SW_RST, false, false);
27 111 /* Hooper is not direcly PCIe capable */
28 112 mdelay(50);
  113 +
29 114 fsl_pcie_init_board(0);
30 115 }
31 116