xref: /rk3399_rockchip-uboot/board/keymile/kmp204x/pci.c (revision 0e00a84cdedf7a1949486746225b35984b351eca)
1877bfe37SValentin Longchamp /*
2877bfe37SValentin Longchamp  * (C) Copyright 2013 Keymile AG
3877bfe37SValentin Longchamp  * Valentin Longchamp <valentin.longchamp@keymile.com>
4877bfe37SValentin Longchamp  *
5877bfe37SValentin Longchamp  * Copyright 2007-2011 Freescale Semiconductor, Inc.
6877bfe37SValentin Longchamp  *
7877bfe37SValentin Longchamp  * SPDX-License-Identifier:	GPL-2.0+
8877bfe37SValentin Longchamp  */
9877bfe37SValentin Longchamp 
10877bfe37SValentin Longchamp #include <common.h>
11877bfe37SValentin Longchamp #include <command.h>
12877bfe37SValentin Longchamp #include <pci.h>
13877bfe37SValentin Longchamp #include <asm/fsl_pci.h>
14*0e00a84cSMasahiro Yamada #include <linux/libfdt.h>
15877bfe37SValentin Longchamp #include <fdt_support.h>
16877bfe37SValentin Longchamp #include <asm/fsl_serdes.h>
171221ce45SMasahiro Yamada #include <linux/errno.h>
18877bfe37SValentin Longchamp 
19877bfe37SValentin Longchamp #include "kmp204x.h"
20877bfe37SValentin Longchamp 
2127c78e06SValentin Longchamp #define PROM_SEL_L	11
2227c78e06SValentin Longchamp /* control the PROM_SEL_L signal*/
toggle_fpga_eeprom_bus(bool cpu_own)2327c78e06SValentin Longchamp static void toggle_fpga_eeprom_bus(bool cpu_own)
2427c78e06SValentin Longchamp {
2527c78e06SValentin Longchamp 	qrio_gpio_direction_output(GPIO_A, PROM_SEL_L, !cpu_own);
2627c78e06SValentin Longchamp }
2727c78e06SValentin Longchamp 
2827c78e06SValentin Longchamp #define CONF_SEL_L	10
2927c78e06SValentin Longchamp #define FPGA_PROG_L	19
3027c78e06SValentin Longchamp #define FPGA_DONE	18
3127c78e06SValentin Longchamp #define FPGA_INIT_L	17
3227c78e06SValentin Longchamp 
trigger_fpga_config(void)3327c78e06SValentin Longchamp int trigger_fpga_config(void)
3427c78e06SValentin Longchamp {
3527c78e06SValentin Longchamp 	int ret = 0, init_l;
3627c78e06SValentin Longchamp 	/* approx 10ms */
3727c78e06SValentin Longchamp 	u32 timeout = 10000;
3827c78e06SValentin Longchamp 
3927c78e06SValentin Longchamp 	/* make sure the FPGA_can access the EEPROM */
4027c78e06SValentin Longchamp 	toggle_fpga_eeprom_bus(false);
4127c78e06SValentin Longchamp 
4227c78e06SValentin Longchamp 	/* assert CONF_SEL_L to be able to drive FPGA_PROG_L */
4327c78e06SValentin Longchamp 	qrio_gpio_direction_output(GPIO_A, CONF_SEL_L, 0);
4427c78e06SValentin Longchamp 
4527c78e06SValentin Longchamp 	/* trigger the config start */
4627c78e06SValentin Longchamp 	qrio_gpio_direction_output(GPIO_A, FPGA_PROG_L, 0);
4727c78e06SValentin Longchamp 
4827c78e06SValentin Longchamp 	/* small delay for INIT_L line */
4927c78e06SValentin Longchamp 	udelay(10);
5027c78e06SValentin Longchamp 
5127c78e06SValentin Longchamp 	/* wait for FPGA_INIT to be asserted */
5227c78e06SValentin Longchamp 	do {
5327c78e06SValentin Longchamp 		init_l = qrio_get_gpio(GPIO_A, FPGA_INIT_L);
5427c78e06SValentin Longchamp 		if (timeout-- == 0) {
5527c78e06SValentin Longchamp 			printf("FPGA_INIT timeout\n");
5627c78e06SValentin Longchamp 			ret = -EFAULT;
5727c78e06SValentin Longchamp 			break;
5827c78e06SValentin Longchamp 		}
5927c78e06SValentin Longchamp 		udelay(10);
6027c78e06SValentin Longchamp 	} while (init_l);
6127c78e06SValentin Longchamp 
6227c78e06SValentin Longchamp 	/* deassert FPGA_PROG, config should start */
6327c78e06SValentin Longchamp 	qrio_set_gpio(GPIO_A, FPGA_PROG_L, 1);
6427c78e06SValentin Longchamp 
6527c78e06SValentin Longchamp 	return ret;
6627c78e06SValentin Longchamp }
6727c78e06SValentin Longchamp 
6827c78e06SValentin Longchamp /* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */
wait_for_fpga_config(void)6927c78e06SValentin Longchamp static int wait_for_fpga_config(void)
7027c78e06SValentin Longchamp {
7127c78e06SValentin Longchamp 	int ret = 0, done;
7227c78e06SValentin Longchamp 	/* approx 5 s */
7327c78e06SValentin Longchamp 	u32 timeout = 500000;
7427c78e06SValentin Longchamp 
7527c78e06SValentin Longchamp 	printf("PCIe FPGA config:");
7627c78e06SValentin Longchamp 	do {
7727c78e06SValentin Longchamp 		done = qrio_get_gpio(GPIO_A, FPGA_DONE);
7827c78e06SValentin Longchamp 		if (timeout-- == 0) {
7927c78e06SValentin Longchamp 			printf(" FPGA_DONE timeout\n");
8027c78e06SValentin Longchamp 			ret = -EFAULT;
8127c78e06SValentin Longchamp 			goto err_out;
8227c78e06SValentin Longchamp 		}
8327c78e06SValentin Longchamp 		udelay(10);
8427c78e06SValentin Longchamp 	} while (!done);
8527c78e06SValentin Longchamp 
8627c78e06SValentin Longchamp 	printf(" done\n");
8727c78e06SValentin Longchamp 
8827c78e06SValentin Longchamp err_out:
8927c78e06SValentin Longchamp 	/* deactive CONF_SEL and give the CPU conf EEPROM access */
9027c78e06SValentin Longchamp 	qrio_set_gpio(GPIO_A, CONF_SEL_L, 1);
9127c78e06SValentin Longchamp 	toggle_fpga_eeprom_bus(true);
9227c78e06SValentin Longchamp 
9327c78e06SValentin Longchamp 	return ret;
9427c78e06SValentin Longchamp }
9527c78e06SValentin Longchamp 
96877bfe37SValentin Longchamp #define PCIE_SW_RST	14
97af47faf6SValentin Longchamp #define PEXHC_RST	13
98af47faf6SValentin Longchamp #define HOOPER_RST	12
99877bfe37SValentin Longchamp 
pci_init_board(void)100877bfe37SValentin Longchamp void pci_init_board(void)
101877bfe37SValentin Longchamp {
102af47faf6SValentin Longchamp 	qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
103af47faf6SValentin Longchamp 	qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
104af47faf6SValentin Longchamp 	qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
105af47faf6SValentin Longchamp 
106af47faf6SValentin Longchamp 	/* wait for the PCIe FPGA to be configured
10727c78e06SValentin Longchamp 	 * it has been triggered earlier in board_early_init_r */
108af47faf6SValentin Longchamp 	if (wait_for_fpga_config())
10927c78e06SValentin Longchamp 		printf("error finishing PCIe FPGA config\n");
11027c78e06SValentin Longchamp 
111877bfe37SValentin Longchamp 	qrio_prst(PCIE_SW_RST, false, false);
112af47faf6SValentin Longchamp 	qrio_prst(PEXHC_RST, false, false);
113af47faf6SValentin Longchamp 	qrio_prst(HOOPER_RST, false, false);
114877bfe37SValentin Longchamp 	/* Hooper is not direcly PCIe capable */
115877bfe37SValentin Longchamp 	mdelay(50);
11627c78e06SValentin Longchamp 
117877bfe37SValentin Longchamp 	fsl_pcie_init_board(0);
118877bfe37SValentin Longchamp }
119877bfe37SValentin Longchamp 
pci_of_setup(void * blob,bd_t * bd)120877bfe37SValentin Longchamp void pci_of_setup(void *blob, bd_t *bd)
121877bfe37SValentin Longchamp {
122877bfe37SValentin Longchamp 	FT_FSL_PCI_SETUP;
123877bfe37SValentin Longchamp }
124