From: Kishon Vijay Abraham I kishon@ti.com
stable inclusion from stable-5.10.68 commit 81381b72f40ca6632402f5cc6dda789b1b6f6310 bugzilla: 182671 https://gitee.com/openeuler/kernel/issues/I4EWUH
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
[ Upstream commit f1de58802f0fff364cf49f5e47d1be744baa434f ]
J7200 has the same PCIe IP as in J721E with minor changes in the wrapper. J7200 allows byte access of bridge configuration space registers and the register field for LINK_DOWN interrupt is different. J7200 also requires "quirk_detect_quiet_flag" to be set. Configure these changes as part of driver data applicable only to J7200.
Link: https://lore.kernel.org/r/20210811123336.31357-4-kishon@ti.com Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org Signed-off-by: Chen Jun chenjun102@huawei.com Acked-by: Weilong Chen chenweilong@huawei.com
Signed-off-by: Chen Jun chenjun102@huawei.com --- drivers/pci/controller/cadence/pci-j721e.c | 40 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index 973b309ac9ba..2f5a49c77074 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -25,6 +25,7 @@ #define STATUS_REG_SYS_2 0x508 #define STATUS_CLR_REG_SYS_2 0x708 #define LINK_DOWN BIT(1) +#define J7200_LINK_DOWN BIT(10)
#define J721E_PCIE_USER_CMD_STATUS 0x4 #define LINK_TRAINING_ENABLE BIT(0) @@ -54,6 +55,7 @@ struct j721e_pcie { struct cdns_pcie *cdns_pcie; void __iomem *user_cfg_base; void __iomem *intd_cfg_base; + u32 linkdown_irq_regfield; };
enum j721e_pcie_mode { @@ -64,6 +66,9 @@ enum j721e_pcie_mode { struct j721e_pcie_data { enum j721e_pcie_mode mode; unsigned int quirk_retrain_flag:1; + unsigned int quirk_detect_quiet_flag:1; + u32 linkdown_irq_regfield; + unsigned int byte_access_allowed:1; };
static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset) @@ -95,12 +100,12 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv) u32 reg;
reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2); - if (!(reg & LINK_DOWN)) + if (!(reg & pcie->linkdown_irq_regfield)) return IRQ_NONE;
dev_err(dev, "LINK DOWN!\n");
- j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN); + j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, pcie->linkdown_irq_regfield); return IRQ_HANDLED; }
@@ -109,7 +114,7 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie) u32 reg;
reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2); - reg |= LINK_DOWN; + reg |= pcie->linkdown_irq_regfield; j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg); }
@@ -272,10 +277,25 @@ static struct pci_ops cdns_ti_pcie_host_ops = { static const struct j721e_pcie_data j721e_pcie_rc_data = { .mode = PCI_MODE_RC, .quirk_retrain_flag = true, + .byte_access_allowed = false, + .linkdown_irq_regfield = LINK_DOWN, };
static const struct j721e_pcie_data j721e_pcie_ep_data = { .mode = PCI_MODE_EP, + .linkdown_irq_regfield = LINK_DOWN, +}; + +static const struct j721e_pcie_data j7200_pcie_rc_data = { + .mode = PCI_MODE_RC, + .quirk_detect_quiet_flag = true, + .linkdown_irq_regfield = J7200_LINK_DOWN, + .byte_access_allowed = true, +}; + +static const struct j721e_pcie_data j7200_pcie_ep_data = { + .mode = PCI_MODE_EP, + .quirk_detect_quiet_flag = true, };
static const struct of_device_id of_j721e_pcie_match[] = { @@ -287,6 +307,14 @@ static const struct of_device_id of_j721e_pcie_match[] = { .compatible = "ti,j721e-pcie-ep", .data = &j721e_pcie_ep_data, }, + { + .compatible = "ti,j7200-pcie-host", + .data = &j7200_pcie_rc_data, + }, + { + .compatible = "ti,j7200-pcie-ep", + .data = &j7200_pcie_ep_data, + }, {}, };
@@ -319,6 +347,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
pcie->dev = dev; pcie->mode = mode; + pcie->linkdown_irq_regfield = data->linkdown_irq_regfield;
base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg"); if (IS_ERR(base)) @@ -378,9 +407,11 @@ static int j721e_pcie_probe(struct platform_device *pdev) goto err_get_sync; }
- bridge->ops = &cdns_ti_pcie_host_ops; + if (!data->byte_access_allowed) + bridge->ops = &cdns_ti_pcie_host_ops; rc = pci_host_bridge_priv(bridge); rc->quirk_retrain_flag = data->quirk_retrain_flag; + rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
cdns_pcie = &rc->pcie; cdns_pcie->dev = dev; @@ -430,6 +461,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) ret = -ENOMEM; goto err_get_sync; } + ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
cdns_pcie = &ep->pcie; cdns_pcie->dev = dev;