[1/2] PCI: cadence: Advertise ARI Forwarding Supported
Commit Message
J7 PCIe Root Complex has ARI Forwarding Support (advertised by
PCI_EXP_DEVCAP2_ARI bit) which means support for forwarding of TLPs
addressed to functions with function number greater than 7 but for some
PCIe instances on J7, PCI_EXP_DEVCAP2_ARI bit is cleared which prevents
accessing functions with function number > 7.
Setting the PCI_EXP_DEVCAP2_ARI explicitly, resolves the issue.
Signed-off-by: Achal Verma <a-verma1@ti.com>
---
drivers/pci/controller/cadence/pci-j721e.c | 4 ++++
drivers/pci/controller/cadence/pcie-cadence-host.c | 7 +++++++
drivers/pci/controller/cadence/pcie-cadence.h | 12 ++++++++++++
3 files changed, 23 insertions(+)
@@ -73,6 +73,7 @@ struct j721e_pcie_data {
unsigned int quirk_disable_flr:1;
u32 linkdown_irq_regfield;
unsigned int byte_access_allowed:1;
+ unsigned int set_afs_bit:1;
};
static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
@@ -292,6 +293,7 @@ static const struct j721e_pcie_data j721e_pcie_rc_data = {
.quirk_retrain_flag = true,
.byte_access_allowed = false,
.linkdown_irq_regfield = LINK_DOWN,
+ .set_afs_bit = true,
};
static const struct j721e_pcie_data j721e_pcie_ep_data = {
@@ -304,6 +306,7 @@ static const struct j721e_pcie_data j7200_pcie_rc_data = {
.quirk_detect_quiet_flag = true,
.linkdown_irq_regfield = J7200_LINK_DOWN,
.byte_access_allowed = true,
+ .set_afs_bit = true,
};
static const struct j721e_pcie_data j7200_pcie_ep_data = {
@@ -393,6 +396,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
rc = pci_host_bridge_priv(bridge);
rc->quirk_retrain_flag = data->quirk_retrain_flag;
rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
+ rc->set_afs_bit = data->set_afs_bit;
cdns_pcie = &rc->pcie;
cdns_pcie->dev = dev;
@@ -507,6 +507,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
struct cdns_pcie *pcie;
struct resource *res;
int ret;
+ u32 pcie_cap2;
bridge = pci_host_bridge_from_priv(rc);
if (!bridge)
@@ -536,6 +537,12 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
if (rc->quirk_detect_quiet_flag)
cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
+ if (rc->set_afs_bit) {
+ pcie_cap2 = cdns_pcie_rp_readl(pcie, CDNS_PCIE_RP_CAP_OFFSET + PCI_EXP_DEVCAP2);
+ pcie_cap2 |= PCI_EXP_DEVCAP2_ARI;
+ cdns_pcie_rp_writel(pcie, CDNS_PCIE_RP_CAP_OFFSET + PCI_EXP_DEVCAP2, pcie_cap2);
+ }
+
cdns_pcie_host_enable_ptm_response(pcie);
ret = cdns_pcie_start_link(pcie);
@@ -329,6 +329,7 @@ struct cdns_pcie_rc {
bool avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
unsigned int quirk_retrain_flag:1;
unsigned int quirk_detect_quiet_flag:1;
+ unsigned int set_afs_bit:1;
};
/**
@@ -457,6 +458,17 @@ static inline u16 cdns_pcie_rp_readw(struct cdns_pcie *pcie, u32 reg)
return cdns_pcie_read_sz(addr, 0x2);
}
+static inline void cdns_pcie_rp_writel(struct cdns_pcie *pcie,
+ u32 reg, u32 value)
+{
+ writel(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
+static inline u32 cdns_pcie_rp_readl(struct cdns_pcie *pcie, u32 reg)
+{
+ return readl(pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
/* Endpoint Function register access */
static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
u32 reg, u8 value)