// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2013 Keymile AG * Valentin Longchamp <valentin.longchamp@keymile.com> * * Copyright 2007-2011 Freescale Semiconductor, Inc. */ #include <common.h> #include <command.h> #include <pci.h> #include <asm/fsl_pci.h> #include <linux/libfdt.h> #include <fdt_support.h> #include <asm/fsl_serdes.h> #include <linux/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_RST 13 #define HOOPER_RST 12 void pci_init_board(void) { qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST); qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST); qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST); /* wait for the PCIe FPGA to be configured * it has been triggered earlier in board_early_init_r */ if (wait_for_fpga_config()) printf("error finishing PCIe FPGA config\n"); qrio_prst(PCIE_SW_RST, false, false); qrio_prst(PEXHC_RST, false, false); qrio_prst(HOOPER_RST, false, false); /* Hooper is not direcly PCIe capable */ mdelay(50); fsl_pcie_init_board(0); } void pci_of_setup(void *blob, bd_t *bd) { FT_FSL_PCI_SETUP; }