1 /* 2 * (C) Copyright 2013 Keymile AG 3 * Valentin Longchamp <valentin.longchamp@keymile.com> 4 * 5 * Copyright 2007-2011 Freescale Semiconductor, Inc. 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <command.h> 12 #include <pci.h> 13 #include <asm/fsl_pci.h> 14 #include <linux/libfdt.h> 15 #include <fdt_support.h> 16 #include <asm/fsl_serdes.h> 17 #include <linux/errno.h> 18 19 #include "kmp204x.h" 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 96 #define PCIE_SW_RST 14 97 #define PEXHC_RST 13 98 #define HOOPER_RST 12 99 100 void pci_init_board(void) 101 { 102 qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST); 103 qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST); 104 qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST); 105 106 /* wait for the PCIe FPGA to be configured 107 * it has been triggered earlier in board_early_init_r */ 108 if (wait_for_fpga_config()) 109 printf("error finishing PCIe FPGA config\n"); 110 111 qrio_prst(PCIE_SW_RST, false, false); 112 qrio_prst(PEXHC_RST, false, false); 113 qrio_prst(HOOPER_RST, false, false); 114 /* Hooper is not direcly PCIe capable */ 115 mdelay(50); 116 117 fsl_pcie_init_board(0); 118 } 119 120 void pci_of_setup(void *blob, bd_t *bd) 121 { 122 FT_FSL_PCI_SETUP; 123 } 124