]> git.ipfire.org Git - thirdparty/u-boot.git/blob - board/keymile/kmp204x/pci.c
libfdt: move headers to <linux/libfdt.h> and <linux/libfdt_env.h>
[thirdparty/u-boot.git] / board / keymile / kmp204x / pci.c
1 /*
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 <linux/libfdt.h>
15 #include <fdt_support.h>
16 #include <asm/fsl_serdes.h>
17 #include <linux/errno.h>
18
19 #include "kmp204x.h"
20
21 #define PROM_SEL_L 11
22 /* control the PROM_SEL_L signal*/
23 static 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
33 int 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 */
69 static 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
88 err_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
96 #define PCIE_SW_RST 14
97 #define PEXHC_RST 13
98 #define HOOPER_RST 12
99
100 void pci_init_board(void)
101 {
102 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
107 * it has been triggered earlier in board_early_init_r */
108 if (wait_for_fpga_config())
109 printf("error finishing PCIe FPGA config\n");
110
111 qrio_prst(PCIE_SW_RST, false, false);
112 qrio_prst(PEXHC_RST, false, false);
113 qrio_prst(HOOPER_RST, false, false);
114 /* Hooper is not direcly PCIe capable */
115 mdelay(50);
116
117 fsl_pcie_init_board(0);
118 }
119
120 void pci_of_setup(void *blob, bd_t *bd)
121 {
122 FT_FSL_PCI_SETUP;
123 }