1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2013 Keymile AG 4 * Valentin Longchamp <valentin.longchamp@keymile.com> 5 * 6 * Copyright 2007-2011 Freescale Semiconductor, Inc. 7 */ 8 9 #include <common.h> 10 #include <command.h> 11 #include <pci.h> 12 #include <asm/fsl_pci.h> 13 #include <linux/libfdt.h> 14 #include <fdt_support.h> 15 #include <asm/fsl_serdes.h> 16 #include <linux/errno.h> 17 18 #include "kmp204x.h" 19 20 #define PROM_SEL_L 11 21 /* control the PROM_SEL_L signal*/ 22 static void toggle_fpga_eeprom_bus(bool cpu_own) 23 { 24 qrio_gpio_direction_output(GPIO_A, PROM_SEL_L, !cpu_own); 25 } 26 27 #define CONF_SEL_L 10 28 #define FPGA_PROG_L 19 29 #define FPGA_DONE 18 30 #define FPGA_INIT_L 17 31 32 int trigger_fpga_config(void) 33 { 34 int ret = 0, init_l; 35 /* approx 10ms */ 36 u32 timeout = 10000; 37 38 /* make sure the FPGA_can access the EEPROM */ 39 toggle_fpga_eeprom_bus(false); 40 41 /* assert CONF_SEL_L to be able to drive FPGA_PROG_L */ 42 qrio_gpio_direction_output(GPIO_A, CONF_SEL_L, 0); 43 44 /* trigger the config start */ 45 qrio_gpio_direction_output(GPIO_A, FPGA_PROG_L, 0); 46 47 /* small delay for INIT_L line */ 48 udelay(10); 49 50 /* wait for FPGA_INIT to be asserted */ 51 do { 52 init_l = qrio_get_gpio(GPIO_A, FPGA_INIT_L); 53 if (timeout-- == 0) { 54 printf("FPGA_INIT timeout\n"); 55 ret = -EFAULT; 56 break; 57 } 58 udelay(10); 59 } while (init_l); 60 61 /* deassert FPGA_PROG, config should start */ 62 qrio_set_gpio(GPIO_A, FPGA_PROG_L, 1); 63 64 return ret; 65 } 66 67 /* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */ 68 static int wait_for_fpga_config(void) 69 { 70 int ret = 0, done; 71 /* approx 5 s */ 72 u32 timeout = 500000; 73 74 printf("PCIe FPGA config:"); 75 do { 76 done = qrio_get_gpio(GPIO_A, FPGA_DONE); 77 if (timeout-- == 0) { 78 printf(" FPGA_DONE timeout\n"); 79 ret = -EFAULT; 80 goto err_out; 81 } 82 udelay(10); 83 } while (!done); 84 85 printf(" done\n"); 86 87 err_out: 88 /* deactive CONF_SEL and give the CPU conf EEPROM access */ 89 qrio_set_gpio(GPIO_A, CONF_SEL_L, 1); 90 toggle_fpga_eeprom_bus(true); 91 92 return ret; 93 } 94 95 #define PCIE_SW_RST 14 96 #define PEXHC_RST 13 97 #define HOOPER_RST 12 98 99 void pci_init_board(void) 100 { 101 qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST); 102 qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST); 103 qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST); 104 105 /* wait for the PCIe FPGA to be configured 106 * it has been triggered earlier in board_early_init_r */ 107 if (wait_for_fpga_config()) 108 printf("error finishing PCIe FPGA config\n"); 109 110 qrio_prst(PCIE_SW_RST, false, false); 111 qrio_prst(PEXHC_RST, false, false); 112 qrio_prst(HOOPER_RST, false, false); 113 /* Hooper is not direcly PCIe capable */ 114 mdelay(50); 115 116 fsl_pcie_init_board(0); 117 } 118 119 void pci_of_setup(void *blob, bd_t *bd) 120 { 121 FT_FSL_PCI_SETUP; 122 } 123