2023-08-12 22:06:09

by Achal Verma

[permalink] [raw]
Subject: [PATCH 0/2] Advertise ARI related capabilities.

This series addresses the limitation and flaw which are occurring due to
ARI capability related bits not set correctly.

First patch addresses the issue of PCI_EXP_DEVCAP2_ARI being not set even
when J7 PCIe controller in RC mode supports ARI Forwarding.

Second patch related to the issue when PCIe controller is put in end point
mode, Next function field in ARI capability for last function stores
current_function+1 value, which is supposed to be zero to signal that
current function is the last one.


Achal Verma (1):
PCI: cadence: Advertise ARI Forwarding Supported

Jasko-EXT Wojciech (1):
PCI: cadence: Clear the ARI Capability Next Function Number of the
last function

drivers/pci/controller/cadence/pci-j721e.c | 4 ++++
.../pci/controller/cadence/pcie-cadence-ep.c | 14 +++++++++++++-
.../pci/controller/cadence/pcie-cadence-host.c | 7 +++++++
drivers/pci/controller/cadence/pcie-cadence.h | 18 ++++++++++++++++++
4 files changed, 42 insertions(+), 1 deletion(-)

--
2.25.1



2023-08-12 22:48:13

by Achal Verma

[permalink] [raw]
Subject: [PATCH 2/2] PCI: cadence: Clear the ARI Capability Next Function Number of the last function

From: Jasko-EXT Wojciech <[email protected]>

Next Function Number field in ARI Capability Register for last function
must be zero by default as per the PCIe specification, indicating there
is no next higher number function but that's not happening in our case,
so this patch clears the Next Function Number field for last function used.

Signed-off-by: Jasko-EXT Wojciech <[email protected]>
Signed-off-by: Achal Verma <[email protected]>
Reviewed-by: Vignesh Raghavendra <[email protected]>
---
drivers/pci/controller/cadence/pcie-cadence-ep.c | 14 +++++++++++++-
drivers/pci/controller/cadence/pcie-cadence.h | 6 ++++++
2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index b8b655d4047e..8742b2f594fd 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -565,7 +565,8 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
struct cdns_pcie *pcie = &ep->pcie;
struct device *dev = pcie->dev;
int max_epfs = sizeof(epc->function_num_map) * 8;
- int ret, value, epf;
+ int ret, epf, last_fn;
+ u32 reg, value;

/*
* BIT(0) is hardwired to 1, hence function 0 is always enabled
@@ -573,6 +574,17 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
*/
cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, epc->function_num_map);

+ /*
+ * Next function field in ARI_CAP_AND_CTR register for last function
+ * should be 0.
+ * Clearing Next Function Number field for the last function used.
+ */
+ last_fn = find_last_bit(&epc->function_num_map, BITS_PER_LONG);
+ reg = CDNS_PCIE_CORE_PF_I_ARI_CAP_AND_CTRL(last_fn);
+ value = cdns_pcie_readl(pcie, reg);
+ value &= ~CDNS_PCIE_ARI_CAP_NFN_MASK;
+ cdns_pcie_writel(pcie, reg, value);
+
if (ep->quirk_disable_flr) {
for (epf = 0; epf < max_epfs; epf++) {
if (!(epc->function_num_map & BIT(epf)))
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 7a5d05f3febc..adcab11e62cd 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -130,6 +130,12 @@
#define CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET 0xc0
#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET 0x200

+/*
+ * Endpoint PF Registers
+ */
+#define CDNS_PCIE_CORE_PF_I_ARI_CAP_AND_CTRL(fn) (0x144 + (fn) * 0x1000)
+#define CDNS_PCIE_ARI_CAP_NFN_MASK GENMASK(15, 8)
+
/*
* Root Port Registers (PCI configuration space for the root port function)
*/
--
2.25.1


2023-08-12 23:34:02

by Achal Verma

[permalink] [raw]
Subject: [PATCH 1/2] PCI: cadence: Advertise ARI Forwarding Supported

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 <[email protected]>
---
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(+)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 2c3b3af59271..7e94eb94f29c 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -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;
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 5b14f7ee3c79..fc696d94f7a2 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -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);
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 190786e47df9..7a5d05f3febc 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -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)
--
2.25.1