blob: cdb498da03b07278d2fc96275c78e6569b7dd593 [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>
Simon Glassdbd79542020-05-10 11:40:11 -060014#include <linux/delay.h>
Masahiro Yamada75f82d02018-03-05 01:20:11 +090015#include <linux/libfdt.h>
Valentin Longchampc98bf292013-10-18 11:47:24 +020016#include <fdt_support.h>
17#include <asm/fsl_serdes.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090018#include <linux/errno.h>
Valentin Longchampc98bf292013-10-18 11:47:24 +020019
Holger Brunck95626872020-01-10 12:47:42 +010020#include "../common/qrio.h"
Valentin Longchampc98bf292013-10-18 11:47:24 +020021#include "kmp204x.h"
22
Valentin Longchampdc146da2014-01-27 11:49:12 +010023#define PROM_SEL_L 11
24/* control the PROM_SEL_L signal*/
25static void toggle_fpga_eeprom_bus(bool cpu_own)
26{
Holger Brunck95626872020-01-10 12:47:42 +010027 qrio_gpio_direction_output(QRIO_GPIO_A, PROM_SEL_L, !cpu_own);
Valentin Longchampdc146da2014-01-27 11:49:12 +010028}
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
35int 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 */
Holger Brunck95626872020-01-10 12:47:42 +010045 qrio_gpio_direction_output(QRIO_GPIO_A, CONF_SEL_L, 0);
Valentin Longchampdc146da2014-01-27 11:49:12 +010046
47 /* trigger the config start */
Holger Brunck95626872020-01-10 12:47:42 +010048 qrio_gpio_direction_output(QRIO_GPIO_A, FPGA_PROG_L, 0);
Valentin Longchampdc146da2014-01-27 11:49:12 +010049
50 /* small delay for INIT_L line */
51 udelay(10);
52
53 /* wait for FPGA_INIT to be asserted */
54 do {
Holger Brunck95626872020-01-10 12:47:42 +010055 init_l = qrio_get_gpio(QRIO_GPIO_A, FPGA_INIT_L);
Valentin Longchampdc146da2014-01-27 11:49:12 +010056 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 */
Holger Brunck95626872020-01-10 12:47:42 +010065 qrio_set_gpio(QRIO_GPIO_A, FPGA_PROG_L, 1);
Valentin Longchampdc146da2014-01-27 11:49:12 +010066
67 return ret;
68}
69
70/* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */
71static 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 {
Holger Brunck95626872020-01-10 12:47:42 +010079 done = qrio_get_gpio(QRIO_GPIO_A, FPGA_DONE);
Valentin Longchampdc146da2014-01-27 11:49:12 +010080 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
90err_out:
91 /* deactive CONF_SEL and give the CPU conf EEPROM access */
Holger Brunck95626872020-01-10 12:47:42 +010092 qrio_set_gpio(QRIO_GPIO_A, CONF_SEL_L, 1);
Valentin Longchampdc146da2014-01-27 11:49:12 +010093 toggle_fpga_eeprom_bus(true);
94
95 return ret;
96}
97
Valentin Longchampc98bf292013-10-18 11:47:24 +020098#define PCIE_SW_RST 14
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +020099#define PEXHC_RST 13
100#define HOOPER_RST 12
Valentin Longchampc98bf292013-10-18 11:47:24 +0200101
102void pci_init_board(void)
103{
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200104 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
Valentin Longchampdc146da2014-01-27 11:49:12 +0100109 * it has been triggered earlier in board_early_init_r */
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200110 if (wait_for_fpga_config())
Valentin Longchampdc146da2014-01-27 11:49:12 +0100111 printf("error finishing PCIe FPGA config\n");
112
Valentin Longchampc98bf292013-10-18 11:47:24 +0200113 qrio_prst(PCIE_SW_RST, false, false);
Valentin Longchamp5eb9dab2014-04-30 15:01:46 +0200114 qrio_prst(PEXHC_RST, false, false);
115 qrio_prst(HOOPER_RST, false, false);
Valentin Longchampc98bf292013-10-18 11:47:24 +0200116 /* Hooper is not direcly PCIe capable */
117 mdelay(50);
Valentin Longchampdc146da2014-01-27 11:49:12 +0100118
Valentin Longchampc98bf292013-10-18 11:47:24 +0200119 fsl_pcie_init_board(0);
120}
121
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900122void pci_of_setup(void *blob, struct bd_info *bd)
Valentin Longchampc98bf292013-10-18 11:47:24 +0200123{
124 FT_FSL_PCI_SETUP;
125}