blob: 15bbc810a1b650cc64ea1576d8652863469033c6 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Valentin Longchampc98bf292013-10-18 11:47:24 +02002/*
3 * (C) Copyright 2013 Keymile AG
4 * Valentin Longchamp <valentin.longchamp@keymile.com>
5 *
6 * Copyright 2007-2011 Freescale Semiconductor, Inc.
Valentin Longchampc98bf292013-10-18 11:47:24 +02007 */
8
9#include <common.h>
10#include <command.h>
Simon Glass18afe102019-11-14 12:57:47 -070011#include <init.h>
Valentin Longchampc98bf292013-10-18 11:47:24 +020012#include <pci.h>
13#include <asm/fsl_pci.h>
Masahiro Yamada75f82d02018-03-05 01:20:11 +090014#include <linux/libfdt.h>
Valentin Longchampc98bf292013-10-18 11:47:24 +020015#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
Holger Brunck95626872020-01-10 12:47:42 +010019#include "../common/qrio.h"
Valentin Longchampc98bf292013-10-18 11:47:24 +020020#include "kmp204x.h"
21
Valentin Longchampdc146da2014-01-27 11:49:12 +010022#define PROM_SEL_L 11
23/* control the PROM_SEL_L signal*/
24static void toggle_fpga_eeprom_bus(bool cpu_own)
25{
Holger Brunck95626872020-01-10 12:47:42 +010026 qrio_gpio_direction_output(QRIO_GPIO_A, PROM_SEL_L, !cpu_own);
Valentin Longchampdc146da2014-01-27 11:49:12 +010027}
28
29#define CONF_SEL_L 10
30#define FPGA_PROG_L 19
31#define FPGA_DONE 18
32#define FPGA_INIT_L 17
33
34int trigger_fpga_config(void)
35{
36 int ret = 0, init_l;
37 /* approx 10ms */
38 u32 timeout = 10000;
39
40 /* make sure the FPGA_can access the EEPROM */
41 toggle_fpga_eeprom_bus(false);
42
43 /* assert CONF_SEL_L to be able to drive FPGA_PROG_L */
Holger Brunck95626872020-01-10 12:47:42 +010044 qrio_gpio_direction_output(QRIO_GPIO_A, CONF_SEL_L, 0);
Valentin Longchampdc146da2014-01-27 11:49:12 +010045
46 /* trigger the config start */
Holger Brunck95626872020-01-10 12:47:42 +010047 qrio_gpio_direction_output(QRIO_GPIO_A, FPGA_PROG_L, 0);
Valentin Longchampdc146da2014-01-27 11:49:12 +010048
49 /* small delay for INIT_L line */
50 udelay(10);
51
52 /* wait for FPGA_INIT to be asserted */
53 do {
Holger Brunck95626872020-01-10 12:47:42 +010054 init_l = qrio_get_gpio(QRIO_GPIO_A, FPGA_INIT_L);
Valentin Longchampdc146da2014-01-27 11:49:12 +010055 if (timeout-- == 0) {
56 printf("FPGA_INIT timeout\n");
57 ret = -EFAULT;
58 break;
59 }
60 udelay(10);
61 } while (init_l);
62
63 /* deassert FPGA_PROG, config should start */
Holger Brunck95626872020-01-10 12:47:42 +010064 qrio_set_gpio(QRIO_GPIO_A, FPGA_PROG_L, 1);
Valentin Longchampdc146da2014-01-27 11:49:12 +010065
66 return ret;
67}
68
69/* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */
70static int wait_for_fpga_config(void)
71{
72 int ret = 0, done;
73 /* approx 5 s */
74 u32 timeout = 500000;
75
76 printf("PCIe FPGA config:");
77 do {
Holger Brunck95626872020-01-10 12:47:42 +010078 done = qrio_get_gpio(QRIO_GPIO_A, FPGA_DONE);
Valentin Longchampdc146da2014-01-27 11:49:12 +010079 if (timeout-- == 0) {
80 printf(" FPGA_DONE timeout\n");
81 ret = -EFAULT;
82 goto err_out;
83 }
84 udelay(10);
85 } while (!done);
86
87 printf(" done\n");
88
89err_out:
90 /* deactive CONF_SEL and give the CPU conf EEPROM access */
Holger Brunck95626872020-01-10 12:47:42 +010091 qrio_set_gpio(QRIO_GPIO_A, CONF_SEL_L, 1);
Valentin Longchampdc146da2014-01-27 11:49:12 +010092 toggle_fpga_eeprom_bus(true);
93
94 return ret;
95}
96
Valentin Longchampc98bf292013-10-18 11:47:24 +020097#define PCIE_SW_RST 14
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +020098#define PEXHC_RST 13
99#define HOOPER_RST 12
Valentin Longchampc98bf292013-10-18 11:47:24 +0200100
101void pci_init_board(void)
102{
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200103 qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
104 qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
105 qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
106
107 /* wait for the PCIe FPGA to be configured
Valentin Longchampdc146da2014-01-27 11:49:12 +0100108 * it has been triggered earlier in board_early_init_r */
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200109 if (wait_for_fpga_config())
Valentin Longchampdc146da2014-01-27 11:49:12 +0100110 printf("error finishing PCIe FPGA config\n");
111
Valentin Longchampc98bf292013-10-18 11:47:24 +0200112 qrio_prst(PCIE_SW_RST, false, false);
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200113 qrio_prst(PEXHC_RST, false, false);
114 qrio_prst(HOOPER_RST, false, false);
Valentin Longchampc98bf292013-10-18 11:47:24 +0200115 /* Hooper is not direcly PCIe capable */
116 mdelay(50);
Valentin Longchampdc146da2014-01-27 11:49:12 +0100117
Valentin Longchampc98bf292013-10-18 11:47:24 +0200118 fsl_pcie_init_board(0);
119}
120
121void pci_of_setup(void *blob, bd_t *bd)
122{
123 FT_FSL_PCI_SETUP;
124}