Takashi Iwai ef0ff1
From 1def82a638920d7d60b7c7f4e11e748cff814a77 Mon Sep 17 00:00:00 2001
Takashi Iwai ef0ff1
From: Kishon Vijay Abraham I <kishon@ti.com>
Takashi Iwai ef0ff1
Date: Wed, 11 Aug 2021 18:03:34 +0530
Takashi Iwai ef0ff1
Subject: [PATCH] PCI: j721e: Add PCIe support for J7200
Takashi Iwai ef0ff1
Git-commit: f1de58802f0fff364cf49f5e47d1be744baa434f
Takashi Iwai ef0ff1
Patch-mainline: v5.15-rc1
Takashi Iwai ef0ff1
References: stable-5.14.7
Takashi Iwai ef0ff1
Takashi Iwai ef0ff1
[ Upstream commit f1de58802f0fff364cf49f5e47d1be744baa434f ]
Takashi Iwai ef0ff1
Takashi Iwai ef0ff1
J7200 has the same PCIe IP as in J721E with minor changes in the
Takashi Iwai ef0ff1
wrapper. J7200 allows byte access of bridge configuration space
Takashi Iwai ef0ff1
registers and the register field for LINK_DOWN interrupt is different.
Takashi Iwai ef0ff1
J7200 also requires "quirk_detect_quiet_flag" to be set. Configure these
Takashi Iwai ef0ff1
changes as part of driver data applicable only to J7200.
Takashi Iwai ef0ff1
Takashi Iwai ef0ff1
Link: https://lore.kernel.org/r/20210811123336.31357-4-kishon@ti.com
Takashi Iwai ef0ff1
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Takashi Iwai ef0ff1
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Takashi Iwai ef0ff1
Signed-off-by: Sasha Levin <sashal@kernel.org>
Takashi Iwai ef0ff1
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai ef0ff1
Takashi Iwai ef0ff1
---
Takashi Iwai ef0ff1
 drivers/pci/controller/cadence/pci-j721e.c | 40 +++++++++++++++++++---
Takashi Iwai ef0ff1
 1 file changed, 36 insertions(+), 4 deletions(-)
Takashi Iwai ef0ff1
Takashi Iwai ef0ff1
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
Takashi Iwai ef0ff1
index 0c5813b230b4..10b13b728284 100644
Takashi Iwai ef0ff1
--- a/drivers/pci/controller/cadence/pci-j721e.c
Takashi Iwai ef0ff1
+++ b/drivers/pci/controller/cadence/pci-j721e.c
Takashi Iwai ef0ff1
@@ -27,6 +27,7 @@
Takashi Iwai ef0ff1
 #define STATUS_REG_SYS_2	0x508
Takashi Iwai ef0ff1
 #define STATUS_CLR_REG_SYS_2	0x708
Takashi Iwai ef0ff1
 #define LINK_DOWN		BIT(1)
Takashi Iwai ef0ff1
+#define J7200_LINK_DOWN		BIT(10)
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 #define J721E_PCIE_USER_CMD_STATUS	0x4
Takashi Iwai ef0ff1
 #define LINK_TRAINING_ENABLE		BIT(0)
Takashi Iwai ef0ff1
@@ -57,6 +58,7 @@ struct j721e_pcie {
Takashi Iwai ef0ff1
 	struct cdns_pcie	*cdns_pcie;
Takashi Iwai ef0ff1
 	void __iomem		*user_cfg_base;
Takashi Iwai ef0ff1
 	void __iomem		*intd_cfg_base;
Takashi Iwai ef0ff1
+	u32			linkdown_irq_regfield;
Takashi Iwai ef0ff1
 };
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 enum j721e_pcie_mode {
Takashi Iwai ef0ff1
@@ -67,6 +69,9 @@ enum j721e_pcie_mode {
Takashi Iwai ef0ff1
 struct j721e_pcie_data {
Takashi Iwai ef0ff1
 	enum j721e_pcie_mode	mode;
Takashi Iwai ef0ff1
 	unsigned int		quirk_retrain_flag:1;
Takashi Iwai ef0ff1
+	unsigned int		quirk_detect_quiet_flag:1;
Takashi Iwai ef0ff1
+	u32			linkdown_irq_regfield;
Takashi Iwai ef0ff1
+	unsigned int		byte_access_allowed:1;
Takashi Iwai ef0ff1
 };
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
Takashi Iwai ef0ff1
@@ -98,12 +103,12 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
Takashi Iwai ef0ff1
 	u32 reg;
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 	reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
Takashi Iwai ef0ff1
-	if (!(reg & LINK_DOWN))
Takashi Iwai ef0ff1
+	if (!(reg & pcie->linkdown_irq_regfield))
Takashi Iwai ef0ff1
 		return IRQ_NONE;
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 	dev_err(dev, "LINK DOWN!\n");
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
-	j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN);
Takashi Iwai ef0ff1
+	j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, pcie->linkdown_irq_regfield);
Takashi Iwai ef0ff1
 	return IRQ_HANDLED;
Takashi Iwai ef0ff1
 }
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
@@ -112,7 +117,7 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
Takashi Iwai ef0ff1
 	u32 reg;
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 	reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2);
Takashi Iwai ef0ff1
-	reg |= LINK_DOWN;
Takashi Iwai ef0ff1
+	reg |= pcie->linkdown_irq_regfield;
Takashi Iwai ef0ff1
 	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
Takashi Iwai ef0ff1
 }
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
@@ -284,10 +289,25 @@ static struct pci_ops cdns_ti_pcie_host_ops = {
Takashi Iwai ef0ff1
 static const struct j721e_pcie_data j721e_pcie_rc_data = {
Takashi Iwai ef0ff1
 	.mode = PCI_MODE_RC,
Takashi Iwai ef0ff1
 	.quirk_retrain_flag = true,
Takashi Iwai ef0ff1
+	.byte_access_allowed = false,
Takashi Iwai ef0ff1
+	.linkdown_irq_regfield = LINK_DOWN,
Takashi Iwai ef0ff1
 };
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 static const struct j721e_pcie_data j721e_pcie_ep_data = {
Takashi Iwai ef0ff1
 	.mode = PCI_MODE_EP,
Takashi Iwai ef0ff1
+	.linkdown_irq_regfield = LINK_DOWN,
Takashi Iwai ef0ff1
+};
Takashi Iwai ef0ff1
+
Takashi Iwai ef0ff1
+static const struct j721e_pcie_data j7200_pcie_rc_data = {
Takashi Iwai ef0ff1
+	.mode = PCI_MODE_RC,
Takashi Iwai ef0ff1
+	.quirk_detect_quiet_flag = true,
Takashi Iwai ef0ff1
+	.linkdown_irq_regfield = J7200_LINK_DOWN,
Takashi Iwai ef0ff1
+	.byte_access_allowed = true,
Takashi Iwai ef0ff1
+};
Takashi Iwai ef0ff1
+
Takashi Iwai ef0ff1
+static const struct j721e_pcie_data j7200_pcie_ep_data = {
Takashi Iwai ef0ff1
+	.mode = PCI_MODE_EP,
Takashi Iwai ef0ff1
+	.quirk_detect_quiet_flag = true,
Takashi Iwai ef0ff1
 };
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 static const struct of_device_id of_j721e_pcie_match[] = {
Takashi Iwai ef0ff1
@@ -299,6 +319,14 @@ static const struct of_device_id of_j721e_pcie_match[] = {
Takashi Iwai ef0ff1
 		.compatible = "ti,j721e-pcie-ep",
Takashi Iwai ef0ff1
 		.data = &j721e_pcie_ep_data,
Takashi Iwai ef0ff1
 	},
Takashi Iwai ef0ff1
+	{
Takashi Iwai ef0ff1
+		.compatible = "ti,j7200-pcie-host",
Takashi Iwai ef0ff1
+		.data = &j7200_pcie_rc_data,
Takashi Iwai ef0ff1
+	},
Takashi Iwai ef0ff1
+	{
Takashi Iwai ef0ff1
+		.compatible = "ti,j7200-pcie-ep",
Takashi Iwai ef0ff1
+		.data = &j7200_pcie_ep_data,
Takashi Iwai ef0ff1
+	},
Takashi Iwai ef0ff1
 	{},
Takashi Iwai ef0ff1
 };
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
@@ -332,6 +360,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 	pcie->dev = dev;
Takashi Iwai ef0ff1
 	pcie->mode = mode;
Takashi Iwai ef0ff1
+	pcie->linkdown_irq_regfield = data->linkdown_irq_regfield;
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 	base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg");
Takashi Iwai ef0ff1
 	if (IS_ERR(base))
Takashi Iwai ef0ff1
@@ -391,9 +420,11 @@ static int j721e_pcie_probe(struct platform_device *pdev)
Takashi Iwai ef0ff1
 			goto err_get_sync;
Takashi Iwai ef0ff1
 		}
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
-		bridge->ops = &cdns_ti_pcie_host_ops;
Takashi Iwai ef0ff1
+		if (!data->byte_access_allowed)
Takashi Iwai ef0ff1
+			bridge->ops = &cdns_ti_pcie_host_ops;
Takashi Iwai ef0ff1
 		rc = pci_host_bridge_priv(bridge);
Takashi Iwai ef0ff1
 		rc->quirk_retrain_flag = data->quirk_retrain_flag;
Takashi Iwai ef0ff1
+		rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 		cdns_pcie = &rc->pcie;
Takashi Iwai ef0ff1
 		cdns_pcie->dev = dev;
Takashi Iwai ef0ff1
@@ -459,6 +490,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
Takashi Iwai ef0ff1
 			ret = -ENOMEM;
Takashi Iwai ef0ff1
 			goto err_get_sync;
Takashi Iwai ef0ff1
 		}
Takashi Iwai ef0ff1
+		ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
Takashi Iwai ef0ff1
 
Takashi Iwai ef0ff1
 		cdns_pcie = &ep->pcie;
Takashi Iwai ef0ff1
 		cdns_pcie->dev = dev;
Takashi Iwai ef0ff1
-- 
Takashi Iwai ef0ff1
2.26.2
Takashi Iwai ef0ff1