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