blob: a484eb574955ad6afc1de8f9c66ed292a12f46ed [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>
Valentin Longchampdc146da2014-01-27 11:49:12 +010017#include <asm/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 Longchampdc146da2014-01-27 11:49:12 +010097#define PEXHC_SW_RST 13
Valentin Longchampc98bf292013-10-18 11:47:24 +020098#define HOOPER_SW_RST 12
99
100void pci_init_board(void)
101{
Valentin Longchampdc146da2014-01-27 11:49:12 +0100102 /* first wait for the PCIe FPGA to be configured
103 * it has been triggered earlier in board_early_init_r */
104 int ret = wait_for_fpga_config();
105 if (ret)
106 printf("error finishing PCIe FPGA config\n");
107
Valentin Longchampc98bf292013-10-18 11:47:24 +0200108 qrio_prst(PCIE_SW_RST, false, false);
Valentin Longchampdc146da2014-01-27 11:49:12 +0100109 qrio_prst(PEXHC_SW_RST, false, false);
Valentin Longchampc98bf292013-10-18 11:47:24 +0200110 qrio_prst(HOOPER_SW_RST, false, false);
111 /* Hooper is not direcly PCIe capable */
112 mdelay(50);
Valentin Longchampdc146da2014-01-27 11:49:12 +0100113
Valentin Longchampc98bf292013-10-18 11:47:24 +0200114 fsl_pcie_init_board(0);
115}
116
117void pci_of_setup(void *blob, bd_t *bd)
118{
119 FT_FSL_PCI_SETUP;
120}