u-boot/board/keymile/kmp204x/pci.c
Valentin Longchamp af47faf650 kmp204x: complete the reset sequence and PRST configuration
This adds the reset support for the following devices that was until
then not implemented:
- BFTIC4
- QSFPs

This also fixes the configuration of the prst behaviour for the other
resets: Only the u-boot and kernel relevant subsystems are taken out of
reset (pcie, ZL30158, and front eth phy).

Most of the prst config move to misc_init_f(), except for the PCIe
related ones that are in pci_init_board and the bftic and ZL30158 ones
that should be done as soon as possible.

Only the behavior of the Hooper reset is changed according to the
documentation as the application is not able to not configure the switch
when it is not reset.

Signed-off-by: Valentin Longchamp <valentin.longchamp@keymile.com>
2014-05-13 08:26:55 -07:00

123 lines
2.6 KiB
C

/*
* (C) Copyright 2013 Keymile AG
* Valentin Longchamp <valentin.longchamp@keymile.com>
*
* Copyright 2007-2011 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <pci.h>
#include <asm/fsl_pci.h>
#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_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;
}