blob: b827e43a7a0470eae5e3e5a52ec6e20a19a462c0 [file] [log] [blame]
Valentin Longchampc98bf292013-10-18 11:47:24 +02001/*
2 * (C) Copyright 2013 Keymile AG
3 * Valentin Longchamp <valentin.longchamp@keymile.com>
4 *
5 * Copyright 2007-2011 Freescale Semiconductor, Inc.
6 *
7 * SPDX-License-Identifier: GPL-2.0+
8 */
9
10#include <common.h>
11#include <command.h>
12#include <pci.h>
13#include <asm/fsl_pci.h>
14#include <libfdt.h>
15#include <fdt_support.h>
16#include <asm/fsl_serdes.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090017#include <linux/errno.h>
Valentin Longchampc98bf292013-10-18 11:47:24 +020018
19#include "kmp204x.h"
20
Valentin Longchampdc146da2014-01-27 11:49:12 +010021#define PROM_SEL_L 11
22/* control the PROM_SEL_L signal*/
23static void toggle_fpga_eeprom_bus(bool cpu_own)
24{
25 qrio_gpio_direction_output(GPIO_A, PROM_SEL_L, !cpu_own);
26}
27
28#define CONF_SEL_L 10
29#define FPGA_PROG_L 19
30#define FPGA_DONE 18
31#define FPGA_INIT_L 17
32
33int trigger_fpga_config(void)
34{
35 int ret = 0, init_l;
36 /* approx 10ms */
37 u32 timeout = 10000;
38
39 /* make sure the FPGA_can access the EEPROM */
40 toggle_fpga_eeprom_bus(false);
41
42 /* assert CONF_SEL_L to be able to drive FPGA_PROG_L */
43 qrio_gpio_direction_output(GPIO_A, CONF_SEL_L, 0);
44
45 /* trigger the config start */
46 qrio_gpio_direction_output(GPIO_A, FPGA_PROG_L, 0);
47
48 /* small delay for INIT_L line */
49 udelay(10);
50
51 /* wait for FPGA_INIT to be asserted */
52 do {
53 init_l = qrio_get_gpio(GPIO_A, FPGA_INIT_L);
54 if (timeout-- == 0) {
55 printf("FPGA_INIT timeout\n");
56 ret = -EFAULT;
57 break;
58 }
59 udelay(10);
60 } while (init_l);
61
62 /* deassert FPGA_PROG, config should start */
63 qrio_set_gpio(GPIO_A, FPGA_PROG_L, 1);
64
65 return ret;
66}
67
68/* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */
69static int wait_for_fpga_config(void)
70{
71 int ret = 0, done;
72 /* approx 5 s */
73 u32 timeout = 500000;
74
75 printf("PCIe FPGA config:");
76 do {
77 done = qrio_get_gpio(GPIO_A, FPGA_DONE);
78 if (timeout-- == 0) {
79 printf(" FPGA_DONE timeout\n");
80 ret = -EFAULT;
81 goto err_out;
82 }
83 udelay(10);
84 } while (!done);
85
86 printf(" done\n");
87
88err_out:
89 /* deactive CONF_SEL and give the CPU conf EEPROM access */
90 qrio_set_gpio(GPIO_A, CONF_SEL_L, 1);
91 toggle_fpga_eeprom_bus(true);
92
93 return ret;
94}
95
Valentin Longchampc98bf292013-10-18 11:47:24 +020096#define PCIE_SW_RST 14
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +020097#define PEXHC_RST 13
98#define HOOPER_RST 12
Valentin Longchampc98bf292013-10-18 11:47:24 +020099
100void pci_init_board(void)
101{
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200102 qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
103 qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
104 qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
105
106 /* wait for the PCIe FPGA to be configured
Valentin Longchampdc146da2014-01-27 11:49:12 +0100107 * it has been triggered earlier in board_early_init_r */
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200108 if (wait_for_fpga_config())
Valentin Longchampdc146da2014-01-27 11:49:12 +0100109 printf("error finishing PCIe FPGA config\n");
110
Valentin Longchampc98bf292013-10-18 11:47:24 +0200111 qrio_prst(PCIE_SW_RST, false, false);
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200112 qrio_prst(PEXHC_RST, false, false);
113 qrio_prst(HOOPER_RST, false, false);
Valentin Longchampc98bf292013-10-18 11:47:24 +0200114 /* Hooper is not direcly PCIe capable */
115 mdelay(50);
Valentin Longchampdc146da2014-01-27 11:49:12 +0100116
Valentin Longchampc98bf292013-10-18 11:47:24 +0200117 fsl_pcie_init_board(0);
118}
119
120void pci_of_setup(void *blob, bd_t *bd)
121{
122 FT_FSL_PCI_SETUP;
123}