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