123 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// 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;
 | 
						|
}
 |