2018-01-27 02:50:27 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2015-04-09 02:21:35 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2014-2015 Broadcom Corporation
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _PCIE_IPROC_H
|
|
|
|
#define _PCIE_IPROC_H
|
|
|
|
|
2015-12-05 01:34:59 +08:00
|
|
|
/**
|
|
|
|
* iProc PCIe interface type
|
|
|
|
*
|
|
|
|
* PAXB is the wrapper used in root complex that can be connected to an
|
|
|
|
* external endpoint device.
|
|
|
|
*
|
|
|
|
* PAXC is the wrapper used in root complex dedicated for internal emulated
|
|
|
|
* endpoint devices.
|
|
|
|
*/
|
|
|
|
enum iproc_pcie_type {
|
2016-11-01 08:38:32 +08:00
|
|
|
IPROC_PCIE_PAXB_BCMA = 0,
|
|
|
|
IPROC_PCIE_PAXB,
|
2016-11-01 08:38:41 +08:00
|
|
|
IPROC_PCIE_PAXB_V2,
|
2015-12-05 01:34:59 +08:00
|
|
|
IPROC_PCIE_PAXC,
|
2016-11-01 08:38:35 +08:00
|
|
|
IPROC_PCIE_PAXC_V2,
|
2015-12-05 01:34:59 +08:00
|
|
|
};
|
|
|
|
|
2015-10-16 21:18:24 +08:00
|
|
|
/**
|
|
|
|
* iProc PCIe outbound mapping
|
|
|
|
* @axi_offset: offset from the AXI address to the internal address used by
|
|
|
|
* the iProc PCIe core
|
2016-11-01 08:38:37 +08:00
|
|
|
* @nr_windows: total number of supported outbound mapping windows
|
2015-10-16 21:18:24 +08:00
|
|
|
*/
|
|
|
|
struct iproc_pcie_ob {
|
|
|
|
resource_size_t axi_offset;
|
2016-11-01 08:38:37 +08:00
|
|
|
unsigned int nr_windows;
|
2015-10-16 21:18:24 +08:00
|
|
|
};
|
|
|
|
|
2016-11-01 08:38:39 +08:00
|
|
|
/**
|
|
|
|
* iProc PCIe inbound mapping
|
|
|
|
* @nr_regions: total number of supported inbound mapping regions
|
|
|
|
*/
|
|
|
|
struct iproc_pcie_ib {
|
|
|
|
unsigned int nr_regions;
|
|
|
|
};
|
|
|
|
|
2016-11-01 08:38:37 +08:00
|
|
|
struct iproc_pcie_ob_map;
|
2016-11-01 08:38:39 +08:00
|
|
|
struct iproc_pcie_ib_map;
|
2016-01-07 08:04:35 +08:00
|
|
|
struct iproc_msi;
|
|
|
|
|
2015-04-09 02:21:35 +08:00
|
|
|
/**
|
|
|
|
* iProc PCIe device
|
2015-12-05 01:34:59 +08:00
|
|
|
*
|
2015-04-09 02:21:35 +08:00
|
|
|
* @dev: pointer to device data structure
|
2015-12-05 01:34:59 +08:00
|
|
|
* @type: iProc PCIe interface type
|
|
|
|
* @reg_offsets: register offsets
|
2015-04-09 02:21:35 +08:00
|
|
|
* @base: PCIe host controller I/O register base
|
2016-01-07 08:04:35 +08:00
|
|
|
* @base_addr: PCIe host controller register base physical address
|
2015-04-09 02:21:35 +08:00
|
|
|
* @root_bus: pointer to root bus
|
|
|
|
* @phy: optional PHY device that controls the Serdes
|
2015-09-16 08:39:15 +08:00
|
|
|
* @map_irq: function callback to map interrupts
|
2016-11-01 08:38:30 +08:00
|
|
|
* @ep_is_internal: indicates an internal emulated endpoint device is connected
|
2018-06-12 08:21:06 +08:00
|
|
|
* @iproc_cfg_read: indicates the iProc config read function should be used
|
|
|
|
* @rej_unconfig_pf: indicates the root complex needs to detect and reject
|
|
|
|
* enumeration against unconfigured physical functions emulated in the ASIC
|
2016-11-01 08:38:33 +08:00
|
|
|
* @has_apb_err_disable: indicates the controller can be configured to prevent
|
|
|
|
* unsupported request from being forwarded as an APB bus error
|
2018-06-12 08:21:04 +08:00
|
|
|
* @fix_paxc_cap: indicates the controller has corrupted capability list in its
|
|
|
|
* config space registers and requires SW based fixup
|
2016-11-01 08:38:37 +08:00
|
|
|
*
|
2016-01-07 08:04:35 +08:00
|
|
|
* @need_ob_cfg: indicates SW needs to configure the outbound mapping window
|
2016-11-01 08:38:37 +08:00
|
|
|
* @ob: outbound mapping related parameters
|
|
|
|
* @ob_map: outbound mapping related parameters specific to the controller
|
|
|
|
*
|
2018-01-12 04:36:16 +08:00
|
|
|
* @need_ib_cfg: indicates SW needs to configure the inbound mapping window
|
2016-11-01 08:38:39 +08:00
|
|
|
* @ib: inbound mapping related parameters
|
|
|
|
* @ib_map: outbound mapping region related parameters
|
|
|
|
*
|
2016-11-01 08:38:35 +08:00
|
|
|
* @need_msi_steer: indicates additional configuration of the iProc PCIe
|
|
|
|
* controller is required to steer MSI writes to external interrupt controller
|
2016-01-07 08:04:35 +08:00
|
|
|
* @msi: MSI data
|
2015-04-09 02:21:35 +08:00
|
|
|
*/
|
|
|
|
struct iproc_pcie {
|
|
|
|
struct device *dev;
|
2015-12-05 01:34:59 +08:00
|
|
|
enum iproc_pcie_type type;
|
2016-11-01 08:38:30 +08:00
|
|
|
u16 *reg_offsets;
|
2015-04-09 02:21:35 +08:00
|
|
|
void __iomem *base;
|
2016-01-07 08:04:35 +08:00
|
|
|
phys_addr_t base_addr;
|
2017-03-10 01:27:07 +08:00
|
|
|
struct resource mem;
|
2015-04-09 02:21:35 +08:00
|
|
|
struct pci_bus *root_bus;
|
|
|
|
struct phy *phy;
|
2015-05-13 05:23:00 +08:00
|
|
|
int (*map_irq)(const struct pci_dev *, u8, u8);
|
2016-11-01 08:38:30 +08:00
|
|
|
bool ep_is_internal;
|
2018-06-12 08:21:06 +08:00
|
|
|
bool iproc_cfg_read;
|
|
|
|
bool rej_unconfig_pf;
|
2016-11-01 08:38:33 +08:00
|
|
|
bool has_apb_err_disable;
|
2018-06-12 08:21:04 +08:00
|
|
|
bool fix_paxc_cap;
|
2016-11-01 08:38:37 +08:00
|
|
|
|
2015-10-16 21:18:24 +08:00
|
|
|
bool need_ob_cfg;
|
|
|
|
struct iproc_pcie_ob ob;
|
2016-11-01 08:38:37 +08:00
|
|
|
const struct iproc_pcie_ob_map *ob_map;
|
|
|
|
|
2018-01-12 04:36:16 +08:00
|
|
|
bool need_ib_cfg;
|
2016-11-01 08:38:39 +08:00
|
|
|
struct iproc_pcie_ib ib;
|
|
|
|
const struct iproc_pcie_ib_map *ib_map;
|
|
|
|
|
2016-11-01 08:38:35 +08:00
|
|
|
bool need_msi_steer;
|
2016-01-07 08:04:35 +08:00
|
|
|
struct iproc_msi *msi;
|
2015-04-09 02:21:35 +08:00
|
|
|
};
|
|
|
|
|
2015-05-25 04:37:02 +08:00
|
|
|
int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res);
|
2015-04-09 02:21:35 +08:00
|
|
|
int iproc_pcie_remove(struct iproc_pcie *pcie);
|
PCI: iproc: Add 500ms delay during device shutdown
During soft reset (e.g., "reboot" from Linux) on some iProc-based SOCs, the
LCPLL clock and PERST both go off simultaneously. This seems in accordance
with the PCIe Card Electromechanical spec, r2.0, sec 2.2.3, which says the
clock goes inactive after PERST# goes active, but doesn't specify how long
the clock should be valid after PERST#.
However, we have observed that with the iProc Stingray, some Intel NVMe
endpoints, e.g., the P3700 400GB series, are not detected correctly upon
the next boot sequence unless the clock remains valid for some time after
PERST# is asserted.
Delay 500ms after asserting PERST# before performing a reboot. The 500ms
is experimentally determined.
Signed-off-by: Oza Pawandeep <oza.oza@broadcom.com>
[bhelgaas: changelog, add spec reference, fold in iproc_pcie_shutdown()
export from Arnd Bergmann <arnd@arndb.de>]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ray Jui <ray.jui@broadcom.com>
Reviewed-by: Scott Branden <scott.branden@broadcom.com>
2017-08-29 05:43:35 +08:00
|
|
|
int iproc_pcie_shutdown(struct iproc_pcie *pcie);
|
2015-04-09 02:21:35 +08:00
|
|
|
|
2016-01-07 08:04:35 +08:00
|
|
|
#ifdef CONFIG_PCIE_IPROC_MSI
|
|
|
|
int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node);
|
|
|
|
void iproc_msi_exit(struct iproc_pcie *pcie);
|
|
|
|
#else
|
|
|
|
static inline int iproc_msi_init(struct iproc_pcie *pcie,
|
|
|
|
struct device_node *node)
|
|
|
|
{
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
static inline void iproc_msi_exit(struct iproc_pcie *pcie)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-04-09 02:21:35 +08:00
|
|
|
#endif /* _PCIE_IPROC_H */
|