Linux-PCI Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 00/30] Enable Tegra PCIe root port features
@ 2019-04-11 17:03 Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 01/30] soc/tegra: pmc: Export tegra_powergate_power_on() Manikanta Maddireddy
                   ` (29 more replies)
  0 siblings, 30 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

This series of patches adds,
- Tegra root port features like Gen2, AER, etc
- Power and perf optimizations
- Fixes like "power up sequence", "dev_err prints", etc

These series of patches are tested on Tegra186 based Jetson-TX2, Tegra210
based Jetson-TX1 and T124 based Jetson-TK1 platforms.

Manikanta Maddireddy (30):
  soc/tegra: pmc: Export tegra_powergate_power_on()
  PCI: tegra: Fix PCIe host power up sequence
  PCI: tegra: Move REFCLK pad settings out of phy_power_on()
  PCI: tegra: Add PCIe Gen2 link speed support
  PCI: tegra: Advertise PCIe Advanced Error Reporting (AER) capability
  PCI: tegra: Program UPHY electrical settings for Tegra210
  PCI: tegra: Enable opportunistic update FC and ACK
  PCI: tegra: Disable AFI dynamic clock gating
  PCI: tegra: Process pending DLL transactions before entering L1 or L2
  PCI: tegra: Enable PCIe xclk clock clamping
  PCI: tegra: Increase the deskew retry time
  PCI: tegra: Add SW fixup for RAW violations
  PCI: tegra: Update flow control threshold in Tegra210
  PCI: tegra: Set target speed as Gen1 before link up
  PCI: tegra: Fix PLLE powerdown issue due to CLKREQ# signal
  PCI: tegra: Program AFI_CACHE* registers only for Tegra20
  PCI: tegra: Use switch statements in tegra_pcie_isr()
  PCI: tegra: Change PRSNT_SENSE irq log to debug
  PCI: tegra: Use legacy irq for port service drivers
  PCI: tegra: Add AFI_PEX2_CTRL reg offset as part of soc struct
  PCI: tegra: Add "pci" type check before parsing child device tree node
  PCI: tegra: Access endpoint config only if PCIe link is up
  dt-bindings: pci: tegra: Document PCIe DPD pinctrl optional prop
  arm64: tegra: Add PEX DPD states as pinctrl properties
  PCI: tegra: Put PEX CLK & BIAS pads in DPD mode
  dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  PCI: tegra: Add support to configure platform GPIOs
  dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop
  PCI: tegra: Add support for GPIO based PCIe reset
  PCI: tegra: Change link retry log level to INFO

 .../bindings/pci/nvidia,tegra20-pcie.txt      |  15 +
 arch/arm64/boot/dts/nvidia/tegra210.dtsi      |  19 +
 drivers/pci/controller/pci-tegra.c            | 696 ++++++++++++++++--
 drivers/soc/tegra/pmc.c                       |   1 +
 4 files changed, 656 insertions(+), 75 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 01/30] soc/tegra: pmc: Export tegra_powergate_power_on()
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence Manikanta Maddireddy
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

tegra_powergate_sequence_power_up() powers up partition and also enables
clock & reset. However if a controller like PCIe have multiple clocks
& resets and they need to be enabled in a sequence, driver has to use
standalone function tegra_powergate_power_on() to power up partition.

Export tegra_powergate_power_on() to allow Tegra controller drivers to
unpower gate partition independent to clock & reset.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 0c5f79528e5f..cb3de81348bd 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -701,6 +701,7 @@ int tegra_powergate_power_on(unsigned int id)
 
 	return tegra_powergate_set(pmc, id, true);
 }
+EXPORT_SYMBOL(tegra_powergate_power_on);
 
 /**
  * tegra_powergate_power_off() - power off partition
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 01/30] soc/tegra: pmc: Export tegra_powergate_power_on() Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:01   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 03/30] PCI: tegra: Move REFCLK pad settings out of phy_power_on() Manikanta Maddireddy
                   ` (27 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

PCIe host power up sequence involves programming AFI(AXI to FPCI bridge)
registers first and then PCIe registers. Otherwise AFI register settings
may not latch to PCIe IP.

PCIe root port starts LTSSM as soon as PCIe xrst is deasserted.
So deassert PCIe xrst after programming PCIe registers.

Modify PCIe power up sequence as follows,
  - Power ungate PCIe partition
  - Enable AFI clock
  - Deassert AFI reset
  - Program AFI registers
  - Enable PCIe clock
  - Deassert PCIe reset
  - Program PCIe registers
  - Deassert PCIe xrst to start LTSSM

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 73 ++++++++++++++++++------------
 1 file changed, 43 insertions(+), 30 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index f4f53d092e00..0bf270bcea34 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -966,9 +966,6 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
 		}
 	}
 
-	/* take the PCIe interface module out of reset */
-	reset_control_deassert(pcie->pcie_xrst);
-
 	/* finally enable PCIe */
 	value = afi_readl(pcie, AFI_CONFIGURATION);
 	value |= AFI_CONFIGURATION_EN_FPCI;
@@ -997,8 +994,6 @@ static void tegra_pcie_disable_controller(struct tegra_pcie *pcie)
 {
 	int err;
 
-	reset_control_assert(pcie->pcie_xrst);
-
 	if (pcie->soc->program_uphy) {
 		err = tegra_pcie_phy_power_off(pcie);
 		if (err < 0)
@@ -1014,13 +1009,11 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
 	int err;
 
 	reset_control_assert(pcie->afi_rst);
-	reset_control_assert(pcie->pex_rst);
 
 	clk_disable_unprepare(pcie->pll_e);
 	if (soc->has_cml_clk)
 		clk_disable_unprepare(pcie->cml_clk);
 	clk_disable_unprepare(pcie->afi_clk);
-	clk_disable_unprepare(pcie->pex_clk);
 
 	if (!dev->pm_domain)
 		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
@@ -1036,58 +1029,59 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
 	const struct tegra_pcie_soc *soc = pcie->soc;
 	int err;
 
-	reset_control_assert(pcie->pcie_xrst);
-	reset_control_assert(pcie->afi_rst);
-	reset_control_assert(pcie->pex_rst);
-
-	if (!dev->pm_domain)
-		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
-
 	/* enable regulators */
 	err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
 	if (err < 0)
 		dev_err(dev, "failed to enable regulators: %d\n", err);
 
-	if (dev->pm_domain) {
-		err = clk_prepare_enable(pcie->pex_clk);
+	if (!dev->pm_domain) {
+		err = tegra_powergate_power_on(TEGRA_POWERGATE_PCIE);
 		if (err) {
-			dev_err(dev, "failed to enable PEX clock: %d\n", err);
-			return err;
+			dev_err(dev, "power ungate failed: %d\n", err);
+			goto regulator_disable;
 		}
-		reset_control_deassert(pcie->pex_rst);
-	} else {
-		err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
-							pcie->pex_clk,
-							pcie->pex_rst);
+		err = tegra_powergate_remove_clamping(TEGRA_POWERGATE_PCIE);
 		if (err) {
-			dev_err(dev, "powerup sequence failed: %d\n", err);
-			return err;
+			dev_err(dev, "remove clamp failed: %d\n", err);
+			goto powergate;
 		}
 	}
 
-	reset_control_deassert(pcie->afi_rst);
-
 	err = clk_prepare_enable(pcie->afi_clk);
 	if (err < 0) {
 		dev_err(dev, "failed to enable AFI clock: %d\n", err);
-		return err;
+		goto powergate;
 	}
 
 	if (soc->has_cml_clk) {
 		err = clk_prepare_enable(pcie->cml_clk);
 		if (err < 0) {
 			dev_err(dev, "failed to enable CML clock: %d\n", err);
-			return err;
+			goto afi_clk_disable;
 		}
 	}
 
 	err = clk_prepare_enable(pcie->pll_e);
 	if (err < 0) {
 		dev_err(dev, "failed to enable PLLE clock: %d\n", err);
-		return err;
+		goto cml_clk_disable;
 	}
 
+	reset_control_deassert(pcie->afi_rst);
+
 	return 0;
+
+cml_clk_disable:
+	if (soc->has_cml_clk)
+		clk_disable_unprepare(pcie->cml_clk);
+afi_clk_disable:
+	clk_disable_unprepare(pcie->afi_clk);
+powergate:
+	if (!dev->pm_domain)
+		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
+regulator_disable:
+	regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
+	return err;
 }
 
 static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
@@ -2108,7 +2102,12 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
 			 port->index, port->lanes);
 
 		tegra_pcie_port_enable(port);
+	}
+
+	/* Start LTSSM from Tegra side */
+	reset_control_deassert(pcie->pcie_xrst);
 
+	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
 		if (tegra_pcie_port_check_link(port))
 			continue;
 
@@ -2123,6 +2122,8 @@ static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
 {
 	struct tegra_pcie_port *port, *tmp;
 
+	reset_control_assert(pcie->pcie_xrst);
+
 	list_for_each_entry_safe(port, tmp, &pcie->ports, list)
 		tegra_pcie_port_disable(port);
 }
@@ -2472,6 +2473,9 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
 
 	tegra_pcie_disable_ports(pcie);
 
+	reset_control_assert(pcie->pex_rst);
+	clk_disable_unprepare(pcie->pex_clk);
+
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		tegra_pcie_disable_msi(pcie);
 
@@ -2501,10 +2505,19 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		tegra_pcie_enable_msi(pcie);
 
+	err = clk_prepare_enable(pcie->pex_clk);
+	if (err) {
+		dev_err(dev, "failed to enable PEX clock: %d\n", err);
+		goto disable_controller;
+	}
+	reset_control_deassert(pcie->pex_rst);
+
 	tegra_pcie_enable_ports(pcie);
 
 	return 0;
 
+disable_controller:
+	tegra_pcie_disable_controller(pcie);
 poweroff:
 	tegra_pcie_power_off(pcie);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 03/30] PCI: tegra: Move REFCLK pad settings out of phy_power_on()
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 01/30] soc/tegra: pmc: Export tegra_powergate_power_on() Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:06   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support Manikanta Maddireddy
                   ` (26 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

In Tegra186 PHY programming is done by BPMP-FW, so PHY calls are skipped
in driver. REFCLK pad settings are independent of PHY and should be
programmed by driver. So move REFCLK pad settings out of phy_power_on().
These pad settings tune REFCLK peak to peak amplitude.

Fixes: cf5d31801278 ("PCI: tegra: Program PADS_REFCLK_CFG* always, not
just on legacy SoCs")

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 0bf270bcea34..a61ce9d475b4 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -852,7 +852,6 @@ static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port)
 static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
 {
 	struct device *dev = pcie->dev;
-	const struct tegra_pcie_soc *soc = pcie->soc;
 	struct tegra_pcie_port *port;
 	int err;
 
@@ -878,12 +877,6 @@ static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
 		}
 	}
 
-	/* Configure the reference clock driver */
-	pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
-
-	if (soc->num_ports > 2)
-		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
-
 	return 0;
 }
 
@@ -2092,11 +2085,24 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
 	return false;
 }
 
+static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
+{
+	const struct tegra_pcie_soc *soc = pcie->soc;
+
+	/* Configure the reference clock driver */
+	pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
+
+	if (soc->num_ports > 2)
+		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
+}
+
 static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
 {
 	struct device *dev = pcie->dev;
 	struct tegra_pcie_port *port, *tmp;
 
+	tegra_pcie_apply_pad_settings(pcie);
+
 	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
 		dev_info(dev, "probing port %u, using %u lanes\n",
 			 port->index, port->lanes);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (2 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 03/30] PCI: tegra: Move REFCLK pad settings out of phy_power_on() Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:21   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 05/30] PCI: tegra: Advertise PCIe Advanced Error Reporting (AER) capability Manikanta Maddireddy
                   ` (25 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Tegra124, 132, 210 and 186 support Gen2 link speed. After PCIe link is up
in Gen1, set target link speed as Gen2 and retrain link. Link switches to
Gen2 speed if Gen2 capable end point is connected, else link stays in Gen1.

Per PCIe 4.0r0.9 sec 7.6.3.7 implementation note, driver need to wait for
PCIe LTSSM to come back from recovery before retraining the link.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 61 ++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index a61ce9d475b4..6ccda82735f8 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -191,6 +191,8 @@
 #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
 #define  RP_LINK_CONTROL_STATUS_LINKSTAT_MASK	0x3fff0000
 
+#define RP_LINK_CONTROL_STATUS_2		0x000000b0
+
 #define PADS_CTL_SEL		0x0000009c
 
 #define PADS_CTL		0x000000a0
@@ -2096,6 +2098,62 @@ static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
 		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
 }
 
+#define LINK_RETRAIN_TIMEOUT 100000
+
+static void tegra_pcie_change_link_speed(struct tegra_pcie *pcie)
+{
+	struct device *dev = pcie->dev;
+	struct tegra_pcie_port *port, *tmp;
+	ktime_t deadline;
+	u32 val;
+
+	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+		/*
+		 * Link Capabilities 2 register is hardwired to 0 in Tegra,
+		 * so no need to read it before setting target speed.
+		 */
+		val = readl(port->base + RP_LINK_CONTROL_STATUS_2);
+		val &= ~PCI_EXP_LNKSTA_CLS;
+		val |= PCI_EXP_LNKSTA_CLS_5_0GB;
+		writel(val, port->base + RP_LINK_CONTROL_STATUS_2);
+
+		/*
+		 * Poll until link comes back from recovery to avoid race
+		 * condition.
+		 */
+		deadline = ktime_add_us(ktime_get(), LINK_RETRAIN_TIMEOUT);
+		for (;;) {
+			val = readl(port->base + RP_LINK_CONTROL_STATUS);
+			if (!(val & PCI_EXP_LNKSTA_LT))
+				break;
+			if (ktime_after(ktime_get(), deadline))
+				break;
+			usleep_range(2000, 3000);
+		}
+		if (val & PCI_EXP_LNKSTA_LT)
+			dev_err(dev, "PCIe port %u link is still in recovery\n",
+				port->index);
+
+		/* Retrain the link */
+		val = readl(port->base + RP_LINK_CONTROL_STATUS);
+		val |= PCI_EXP_LNKCTL_RL;
+		writel(val, port->base + RP_LINK_CONTROL_STATUS);
+
+		deadline = ktime_add_us(ktime_get(), LINK_RETRAIN_TIMEOUT);
+		for (;;) {
+			val = readl(port->base + RP_LINK_CONTROL_STATUS);
+			if (!(val & PCI_EXP_LNKSTA_LT))
+				break;
+			if (ktime_after(ktime_get(), deadline))
+				break;
+			usleep_range(2000, 3000);
+		}
+		if (val & PCI_EXP_LNKSTA_LT)
+			dev_err(dev, "link retrain of PCIe port %u failed\n",
+				port->index);
+	}
+}
+
 static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
 {
 	struct device *dev = pcie->dev;
@@ -2122,6 +2180,9 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
 		tegra_pcie_port_disable(port);
 		tegra_pcie_port_free(port);
 	}
+
+	if (pcie->soc->has_gen2)
+		tegra_pcie_change_link_speed(pcie);
 }
 
 static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 05/30] PCI: tegra: Advertise PCIe Advanced Error Reporting (AER) capability
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (3 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:23   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 06/30] PCI: tegra: Program UPHY electrical settings for Tegra210 Manikanta Maddireddy
                   ` (24 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Default root port setting hides AER capability. This patch enables the
advertisement of AER capability by root port.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 6ccda82735f8..9ff1a0e2797f 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -180,6 +180,9 @@
 #define RP_VEND_XP	0x00000f00
 #define  RP_VEND_XP_DL_UP	(1 << 30)
 
+#define RP_VEND_CTL1	0x00000f48
+#define  RP_VEND_CTL1_ERPT	(1 << 13)
+
 #define RP_VEND_CTL2 0x00000fa8
 #define  RP_VEND_CTL2_PCA_ENABLE (1 << 7)
 
@@ -478,6 +481,16 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
 	afi_writel(port->pcie, value, ctrl);
 }
 
+static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
+{
+	u32 value;
+
+	/* Enable AER capability */
+	value = readl(port->base + RP_VEND_CTL1);
+	value |= RP_VEND_CTL1_ERPT;
+	writel(value, port->base + RP_VEND_CTL1);
+}
+
 static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 {
 	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
@@ -502,6 +515,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 		value |= RP_VEND_CTL2_PCA_ENABLE;
 		writel(value, port->base + RP_VEND_CTL2);
 	}
+
+	tegra_pcie_enable_rp_features(port);
 }
 
 static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 06/30] PCI: tegra: Program UPHY electrical settings for Tegra210
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (4 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 05/30] PCI: tegra: Advertise PCIe Advanced Error Reporting (AER) capability Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:29   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 07/30] PCI: tegra: Enable opportunistic update FC and ACK Manikanta Maddireddy
                   ` (23 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

UPHY electrical programming guidelines are documented in Tegra210 TRM.
Program these electrical settings for proper eye diagram in Gen1 and Gen2
link speeds.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 100 +++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 9ff1a0e2797f..a377245d254d 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -177,6 +177,32 @@
 
 #define AFI_PEXBIAS_CTRL_0		0x168
 
+#define RP_ECTL_2_R1	0x00000e84
+#define  RP_ECTL_2_R1_RX_CTLE_1C_MASK		0xffff
+
+#define RP_ECTL_4_R1	0x00000e8c
+#define  RP_ECTL_4_R1_RX_CDR_CTRL_1C_MASK	(0xffff << 16)
+#define  RP_ECTL_4_R1_RX_CDR_CTRL_1C_SHIFT	16
+
+#define RP_ECTL_5_R1	0x00000e90
+#define  RP_ECTL_5_R1_RX_EQ_CTRL_L_1C_MASK	0xffffffff
+
+#define RP_ECTL_6_R1	0x00000e94
+#define  RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK	0xffffffff
+
+#define RP_ECTL_2_R2	0x00000ea4
+#define  RP_ECTL_2_R2_RX_CTLE_1C_MASK	0xffff
+
+#define RP_ECTL_4_R2	0x00000eac
+#define  RP_ECTL_4_R2_RX_CDR_CTRL_1C_MASK	(0xffff << 16)
+#define  RP_ECTL_4_R2_RX_CDR_CTRL_1C_SHIFT	16
+
+#define RP_ECTL_5_R2	0x00000eb0
+#define  RP_ECTL_5_R2_RX_EQ_CTRL_L_1C_MASK	0xffffffff
+
+#define RP_ECTL_6_R2	0x00000eb4
+#define  RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK	0xffffffff
+
 #define RP_VEND_XP	0x00000f00
 #define  RP_VEND_XP_DL_UP	(1 << 30)
 
@@ -265,6 +291,19 @@ struct tegra_pcie_soc {
 	bool has_gen2;
 	bool force_pca_enable;
 	bool program_uphy;
+	struct {
+		struct {
+			u32 rp_ectl_2_r1;
+			u32 rp_ectl_4_r1;
+			u32 rp_ectl_5_r1;
+			u32 rp_ectl_6_r1;
+			u32 rp_ectl_2_r2;
+			u32 rp_ectl_4_r2;
+			u32 rp_ectl_5_r2;
+			u32 rp_ectl_6_r2;
+		} regs;
+		bool enable;
+	} ectl;
 };
 
 static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
@@ -491,6 +530,52 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
 	writel(value, port->base + RP_VEND_CTL1);
 }
 
+static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
+{
+	const struct tegra_pcie_soc *soc = port->pcie->soc;
+	u32 val;
+
+	val = readl(port->base + RP_ECTL_2_R1);
+	val &= ~RP_ECTL_2_R1_RX_CTLE_1C_MASK;
+	val |= soc->ectl.regs.rp_ectl_2_r1;
+	writel(val, port->base + RP_ECTL_2_R1);
+
+	val = readl(port->base + RP_ECTL_4_R1);
+	val &= ~RP_ECTL_4_R1_RX_CDR_CTRL_1C_MASK;
+	val |= soc->ectl.regs.rp_ectl_4_r1 << RP_ECTL_4_R1_RX_CDR_CTRL_1C_SHIFT;
+	writel(val, port->base + RP_ECTL_4_R1);
+
+	val = readl(port->base + RP_ECTL_5_R1);
+	val &= ~RP_ECTL_5_R1_RX_EQ_CTRL_L_1C_MASK;
+	val |= soc->ectl.regs.rp_ectl_5_r1;
+	writel(val, port->base + RP_ECTL_5_R1);
+
+	val = readl(port->base + RP_ECTL_6_R1);
+	val &= ~RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK;
+	val |= soc->ectl.regs.rp_ectl_6_r1;
+	writel(val, port->base + RP_ECTL_6_R1);
+
+	val = readl(port->base + RP_ECTL_2_R2);
+	val &= ~RP_ECTL_2_R2_RX_CTLE_1C_MASK;
+	val |= soc->ectl.regs.rp_ectl_2_r2;
+	writel(val, port->base + RP_ECTL_2_R2);
+
+	val = readl(port->base + RP_ECTL_4_R2);
+	val &= ~RP_ECTL_4_R2_RX_CDR_CTRL_1C_MASK;
+	val |= soc->ectl.regs.rp_ectl_4_r2 << RP_ECTL_4_R2_RX_CDR_CTRL_1C_SHIFT;
+	writel(val, port->base + RP_ECTL_4_R2);
+
+	val = readl(port->base + RP_ECTL_5_R2);
+	val &= ~RP_ECTL_5_R2_RX_EQ_CTRL_L_1C_MASK;
+	val |= soc->ectl.regs.rp_ectl_5_r2;
+	writel(val, port->base + RP_ECTL_5_R2);
+
+	val = readl(port->base + RP_ECTL_6_R2);
+	val &= ~RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK;
+	val |= soc->ectl.regs.rp_ectl_6_r2;
+	writel(val, port->base + RP_ECTL_6_R2);
+}
+
 static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 {
 	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
@@ -517,6 +602,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 	}
 
 	tegra_pcie_enable_rp_features(port);
+	if (soc->ectl.enable)
+		tegra_pcie_program_ectl_settings(port);
 }
 
 static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
@@ -2229,6 +2316,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
 	.has_gen2 = false,
 	.force_pca_enable = false,
 	.program_uphy = true,
+	.ectl.enable = false,
 };
 
 static const struct tegra_pcie_port_soc tegra30_pcie_ports[] = {
@@ -2252,6 +2340,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
 	.has_gen2 = false,
 	.force_pca_enable = false,
 	.program_uphy = true,
+	.ectl.enable = false,
 };
 
 static const struct tegra_pcie_soc tegra124_pcie = {
@@ -2268,6 +2357,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
 	.has_gen2 = true,
 	.force_pca_enable = false,
 	.program_uphy = true,
+	.ectl.enable = false,
 };
 
 static const struct tegra_pcie_soc tegra210_pcie = {
@@ -2284,6 +2374,15 @@ static const struct tegra_pcie_soc tegra210_pcie = {
 	.has_gen2 = true,
 	.force_pca_enable = true,
 	.program_uphy = true,
+	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
+	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
+	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
+	.ectl.regs.rp_ectl_6_r1 = 0x00000001,
+	.ectl.regs.rp_ectl_2_r2 = 0x0000008f,
+	.ectl.regs.rp_ectl_4_r2 = 0x000000c7,
+	.ectl.regs.rp_ectl_5_r2 = 0x55010000,
+	.ectl.regs.rp_ectl_6_r2 = 0x00000001,
+	.ectl.enable = true,
 };
 
 static const struct tegra_pcie_port_soc tegra186_pcie_ports[] = {
@@ -2307,6 +2406,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
 	.has_gen2 = true,
 	.force_pca_enable = false,
 	.program_uphy = false,
+	.ectl.enable = false,
 };
 
 static const struct of_device_id tegra_pcie_of_match[] = {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 07/30] PCI: tegra: Enable opportunistic update FC and ACK
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (5 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 06/30] PCI: tegra: Program UPHY electrical settings for Tegra210 Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:30   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 08/30] PCI: tegra: Disable AFI dynamic clock gating Manikanta Maddireddy
                   ` (22 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Enable opportunistic update FC and ACK to allow data link layer send
pending ACKs and update FC packets when link is idle instead of waiting
for timers to expire. This improves the PCIe performance due to better
utilization of PCIe bandwidth.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index a377245d254d..fc4369674884 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -204,7 +204,9 @@
 #define  RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK	0xffffffff
 
 #define RP_VEND_XP	0x00000f00
-#define  RP_VEND_XP_DL_UP	(1 << 30)
+#define  RP_VEND_XP_DL_UP			(1 << 30)
+#define  RP_VEND_XP_OPPORTUNISTIC_ACK		(1 << 27)
+#define  RP_VEND_XP_OPPORTUNISTIC_UPDATEFC	(1 << 28)
 
 #define RP_VEND_CTL1	0x00000f48
 #define  RP_VEND_CTL1_ERPT	(1 << 13)
@@ -528,6 +530,12 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
 	value = readl(port->base + RP_VEND_CTL1);
 	value |= RP_VEND_CTL1_ERPT;
 	writel(value, port->base + RP_VEND_CTL1);
+
+	/* Optimal settings to enhance bandwidth */
+	value = readl(port->base + RP_VEND_XP);
+	value |= RP_VEND_XP_OPPORTUNISTIC_ACK;
+	value |= RP_VEND_XP_OPPORTUNISTIC_UPDATEFC;
+	writel(value, port->base + RP_VEND_XP);
 }
 
 static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 08/30] PCI: tegra: Disable AFI dynamic clock gating
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (6 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 07/30] PCI: tegra: Enable opportunistic update FC and ACK Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:32   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 09/30] PCI: tegra: Process pending DLL transactions before entering L1 or L2 Manikanta Maddireddy
                   ` (21 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Outstanding write counter in AFI is used to generate idle signal to
dynamically gate the AFI clock. When there are 32 outstanding writes
from AFI to memory, the outstanding write counter overflows and
indicates that there are "0" outstanding write transactions.

When memory controller is under heavy load, write completions to AFI
gets delayed and AFI write counter overflows. This causes AFI clock gating
even when there are outstanding transactions towards memory controller
resutling in system hang.

Disable dynamic clock gating of AFI clock to avoid system hang.

CLKEN_OVERRIDE bit is not defined in Tegra20 and Tegra30, however
programming this bit doesn't cause any side effects. Program this
bit for all Tegra SoCs to avoid conditional check.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index fc4369674884..ce0282819370 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -95,7 +95,8 @@
 #define AFI_MSI_EN_VEC7		0xa8
 
 #define AFI_CONFIGURATION		0xac
-#define  AFI_CONFIGURATION_EN_FPCI	(1 << 0)
+#define  AFI_CONFIGURATION_EN_FPCI		(1 << 0)
+#define  AFI_CONFIGURATION_CLKEN_OVERRIDE	(1 << 31)
 
 #define AFI_FPCI_ERROR_MASKS	0xb0
 
@@ -1071,9 +1072,10 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
 		}
 	}
 
-	/* finally enable PCIe */
+	/* Disable AFI dynamic clock gating and enable PCIe */
 	value = afi_readl(pcie, AFI_CONFIGURATION);
 	value |= AFI_CONFIGURATION_EN_FPCI;
+	value |= AFI_CONFIGURATION_CLKEN_OVERRIDE;
 	afi_writel(pcie, value, AFI_CONFIGURATION);
 
 	value = AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 09/30] PCI: tegra: Process pending DLL transactions before entering L1 or L2
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (7 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 08/30] PCI: tegra: Disable AFI dynamic clock gating Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:33   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 10/30] PCI: tegra: Enable PCIe xclk clock clamping Manikanta Maddireddy
                   ` (20 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

PM message are truncated while entering L1 or L2, which is resulting in
receiver errors. Set the required bit to finish processing DLLP before
link enter L1 or L2.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index ce0282819370..e40df52e46a7 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -212,6 +212,9 @@
 #define RP_VEND_CTL1	0x00000f48
 #define  RP_VEND_CTL1_ERPT	(1 << 13)
 
+#define RP_VEND_XP_BIST	0x00000f4c
+#define  RP_VEND_XP_BIST_GOTO_L1_L2_AFTER_DLLP_DONE	(1 << 28)
+
 #define RP_VEND_CTL2 0x00000fa8
 #define  RP_VEND_CTL2_PCA_ENABLE (1 << 7)
 
@@ -537,6 +540,14 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
 	value |= RP_VEND_XP_OPPORTUNISTIC_ACK;
 	value |= RP_VEND_XP_OPPORTUNISTIC_UPDATEFC;
 	writel(value, port->base + RP_VEND_XP);
+
+	/*
+	 * LTSSM will wait for DLLP to finish before entering L1 or L2,
+	 * to avoid truncation of PM messages which results in receiver errors
+	 */
+	value = readl(port->base + RP_VEND_XP_BIST);
+	value |= RP_VEND_XP_BIST_GOTO_L1_L2_AFTER_DLLP_DONE;
+	writel(value, port->base + RP_VEND_XP_BIST);
 }
 
 static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 10/30] PCI: tegra: Enable PCIe xclk clock clamping
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (8 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 09/30] PCI: tegra: Process pending DLL transactions before entering L1 or L2 Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:37   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 11/30] PCI: tegra: Increase the deskew retry time Manikanta Maddireddy
                   ` (19 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Enable xclk clock clamping when entering L1. Clamp threshold will
determine the time spent waiting for clock module to turn on xclk after
signalling it. Default threshold value in Tegra124 and 210 is not enough
to turn ON xlck clock. Increase the clamp threshold to meet the clock
module timing in Tegra124 and 210, default threshold value is sufficient
in Tegra186.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index e40df52e46a7..f785ecae2f6b 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -219,8 +219,14 @@
 #define  RP_VEND_CTL2_PCA_ENABLE (1 << 7)
 
 #define RP_PRIV_MISC	0x00000fe0
-#define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0)
-#define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0)
+#define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT		(0xe << 0)
+#define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT		(0xf << 0)
+#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD_MASK	(0x7f << 16)
+#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD		(0xf << 16)
+#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_ENABLE		(1 << 23)
+#define  RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD_MASK	(0x7f << 24)
+#define  RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD		(0xf << 24)
+#define  RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE		(1 << 31)
 
 #define RP_LINK_CONTROL_STATUS			0x00000090
 #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
@@ -297,6 +303,7 @@ struct tegra_pcie_soc {
 	bool has_gen2;
 	bool force_pca_enable;
 	bool program_uphy;
+	bool update_clamp_threshold;
 	struct {
 		struct {
 			u32 rp_ectl_2_r1;
@@ -528,6 +535,7 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
 
 static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
 {
+	const struct tegra_pcie_soc *soc = port->pcie->soc;
 	u32 value;
 
 	/* Enable AER capability */
@@ -548,6 +556,17 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
 	value = readl(port->base + RP_VEND_XP_BIST);
 	value |= RP_VEND_XP_BIST_GOTO_L1_L2_AFTER_DLLP_DONE;
 	writel(value, port->base + RP_VEND_XP_BIST);
+
+	value = readl(port->base + RP_PRIV_MISC);
+	value |= RP_PRIV_MISC_CTLR_CLK_CLAMP_ENABLE;
+	value |= RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE;
+	if (soc->update_clamp_threshold) {
+		value &= ~(RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD_MASK |
+				RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD_MASK);
+		value |= RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD |
+			RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD;
+	}
+	writel(value, port->base + RP_PRIV_MISC);
 }
 
 static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
@@ -2337,6 +2356,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
 	.has_gen2 = false,
 	.force_pca_enable = false,
 	.program_uphy = true,
+	.update_clamp_threshold = false,
 	.ectl.enable = false,
 };
 
@@ -2361,6 +2381,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
 	.has_gen2 = false,
 	.force_pca_enable = false,
 	.program_uphy = true,
+	.update_clamp_threshold = false,
 	.ectl.enable = false,
 };
 
@@ -2378,6 +2399,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
 	.has_gen2 = true,
 	.force_pca_enable = false,
 	.program_uphy = true,
+	.update_clamp_threshold = true,
 	.ectl.enable = false,
 };
 
@@ -2395,6 +2417,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
 	.has_gen2 = true,
 	.force_pca_enable = true,
 	.program_uphy = true,
+	.update_clamp_threshold = true,
 	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
 	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
 	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
@@ -2427,6 +2450,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
 	.has_gen2 = true,
 	.force_pca_enable = false,
 	.program_uphy = false,
+	.update_clamp_threshold = false,
 	.ectl.enable = false,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 11/30] PCI: tegra: Increase the deskew retry time
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (9 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 10/30] PCI: tegra: Enable PCIe xclk clock clamping Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:39   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations Manikanta Maddireddy
                   ` (18 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Some times link speed change from Gen2 to Gen1 fails due to instability
in deskew logic on lane-0 in Tegra210. Increase the deskew retry time
to resolve this issue.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index f785ecae2f6b..9e61da68cfae 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -209,6 +209,10 @@
 #define  RP_VEND_XP_OPPORTUNISTIC_ACK		(1 << 27)
 #define  RP_VEND_XP_OPPORTUNISTIC_UPDATEFC	(1 << 28)
 
+#define RP_VEND_CTL0	0x00000f44
+#define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK	(0xf << 12)
+#define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH	(0x9 << 12)
+
 #define RP_VEND_CTL1	0x00000f48
 #define  RP_VEND_CTL1_ERPT	(1 << 13)
 
@@ -304,6 +308,7 @@ struct tegra_pcie_soc {
 	bool force_pca_enable;
 	bool program_uphy;
 	bool update_clamp_threshold;
+	bool program_deskew_time;
 	struct {
 		struct {
 			u32 rp_ectl_2_r1;
@@ -615,6 +620,23 @@ static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
 	writel(val, port->base + RP_ECTL_6_R2);
 }
 
+static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
+{
+	const struct tegra_pcie_soc *soc = port->pcie->soc;
+	u32 value;
+
+	/*
+	 * Tune deskew retry time to take care of Gen2 -> Gen1
+	 * link speed change error in corner cases
+	 */
+	if (soc->program_deskew_time) {
+		value = readl(port->base + RP_VEND_CTL0);
+		value &= ~RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK;
+		value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH;
+		writel(value, port->base + RP_VEND_CTL0);
+	}
+}
+
 static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 {
 	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
@@ -643,6 +665,7 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
 	tegra_pcie_enable_rp_features(port);
 	if (soc->ectl.enable)
 		tegra_pcie_program_ectl_settings(port);
+	tegra_pcie_apply_sw_fixup(port);
 }
 
 static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
@@ -2357,6 +2380,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
 	.force_pca_enable = false,
 	.program_uphy = true,
 	.update_clamp_threshold = false,
+	.program_deskew_time = false,
 	.ectl.enable = false,
 };
 
@@ -2382,6 +2406,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
 	.force_pca_enable = false,
 	.program_uphy = true,
 	.update_clamp_threshold = false,
+	.program_deskew_time = false,
 	.ectl.enable = false,
 };
 
@@ -2400,6 +2425,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
 	.force_pca_enable = false,
 	.program_uphy = true,
 	.update_clamp_threshold = true,
+	.program_deskew_time = false,
 	.ectl.enable = false,
 };
 
@@ -2418,6 +2444,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
 	.force_pca_enable = true,
 	.program_uphy = true,
 	.update_clamp_threshold = true,
+	.program_deskew_time = true,
 	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
 	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
 	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
@@ -2451,6 +2478,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
 	.force_pca_enable = false,
 	.program_uphy = false,
 	.update_clamp_threshold = false,
+	.program_deskew_time = false,
 	.ectl.enable = false,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (10 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 11/30] PCI: tegra: Increase the deskew retry time Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-11 20:01   ` Bjorn Helgaas
  2019-04-15 11:45   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 13/30] PCI: tegra: Update flow control threshold in Tegra210 Manikanta Maddireddy
                   ` (17 subsequent siblings)
  29 siblings, 2 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

The logic which blocks read requests till AFI gets ACK for all outstanding
MC writes does not behave correctly when number of outstanding write
becomes more than 32 in Tegra124 and 132.

SW fixup to prevent this issue is to limit outstanding posted writes and
tweak updateFC timer threshold.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 34 ++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 9e61da68cfae..b74408eeb367 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -178,6 +178,13 @@
 
 #define AFI_PEXBIAS_CTRL_0		0x168
 
+#define RP_PRIV_XP_DL		0x00000494
+#define  RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD	(0x1ff << 1)
+
+#define RP_RX_HDR_LIMIT		0x00000e00
+#define  RP_RX_HDR_LIMIT_PW_MASK	(0xff << 8)
+#define  RP_RX_HDR_LIMIT_PW		(0x0e << 8)
+
 #define RP_ECTL_2_R1	0x00000e84
 #define  RP_ECTL_2_R1_RX_CTLE_1C_MASK		0xffff
 
@@ -208,6 +215,7 @@
 #define  RP_VEND_XP_DL_UP			(1 << 30)
 #define  RP_VEND_XP_OPPORTUNISTIC_ACK		(1 << 27)
 #define  RP_VEND_XP_OPPORTUNISTIC_UPDATEFC	(1 << 28)
+#define  RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK	(0xff << 18)
 
 #define RP_VEND_CTL0	0x00000f44
 #define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK	(0xf << 12)
@@ -300,6 +308,7 @@ struct tegra_pcie_soc {
 	u32 tx_ref_sel;
 	u32 pads_refclk_cfg0;
 	u32 pads_refclk_cfg1;
+	u32 update_fc_val;
 	bool has_pex_clkreq_en;
 	bool has_pex_bias_ctrl;
 	bool has_intr_prsnt_sense;
@@ -309,6 +318,7 @@ struct tegra_pcie_soc {
 	bool program_uphy;
 	bool update_clamp_threshold;
 	bool program_deskew_time;
+	bool raw_violation_fixup;
 	struct {
 		struct {
 			u32 rp_ectl_2_r1;
@@ -635,6 +645,23 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
 		value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH;
 		writel(value, port->base + RP_VEND_CTL0);
 	}
+
+	/* Fixup for read after write violation in T124 & T132 platforms */
+	if (soc->raw_violation_fixup) {
+		value = readl(port->base + RP_RX_HDR_LIMIT);
+		value &= ~RP_RX_HDR_LIMIT_PW_MASK;
+		value |= RP_RX_HDR_LIMIT_PW;
+		writel(value, port->base + RP_RX_HDR_LIMIT);
+
+		value = readl(port->base + RP_PRIV_XP_DL);
+		value |= RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD;
+		writel(value, port->base + RP_PRIV_XP_DL);
+
+		value = readl(port->base + RP_VEND_XP);
+		value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK;
+		value |= soc->update_fc_val;
+		writel(value, port->base + RP_VEND_XP);
+	}
 }
 
 static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
@@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
 	.program_uphy = true,
 	.update_clamp_threshold = false,
 	.program_deskew_time = false,
+	.raw_violation_fixup = false,
 	.ectl.enable = false,
 };
 
@@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
 	.program_uphy = true,
 	.update_clamp_threshold = false,
 	.program_deskew_time = false,
+	.raw_violation_fixup = false,
 	.ectl.enable = false,
 };
 
@@ -2417,6 +2446,8 @@ static const struct tegra_pcie_soc tegra124_pcie = {
 	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
 	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
 	.pads_refclk_cfg0 = 0x44ac44ac,
+	/* FC threshold is bit[25:18] */
+	.update_fc_val = 0x03fc0000,
 	.has_pex_clkreq_en = true,
 	.has_pex_bias_ctrl = true,
 	.has_intr_prsnt_sense = true,
@@ -2426,6 +2457,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
 	.program_uphy = true,
 	.update_clamp_threshold = true,
 	.program_deskew_time = false,
+	.raw_violation_fixup = true,
 	.ectl.enable = false,
 };
 
@@ -2445,6 +2477,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
 	.program_uphy = true,
 	.update_clamp_threshold = true,
 	.program_deskew_time = true,
+	.raw_violation_fixup = false,
 	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
 	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
 	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
@@ -2479,6 +2512,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
 	.program_uphy = false,
 	.update_clamp_threshold = false,
 	.program_deskew_time = false,
+	.raw_violation_fixup = false,
 	.ectl.enable = false,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 13/30] PCI: tegra: Update flow control threshold in Tegra210
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (11 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 11:47   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up Manikanta Maddireddy
                   ` (16 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Recommended update FC threshold in Tegra210 is 0x60 for best performance
of x1 link. Setting this to 0x60 provides the best balance between number
of UpdateFC and read data sent over the link.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index b74408eeb367..7dc728cc5f51 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -319,6 +319,7 @@ struct tegra_pcie_soc {
 	bool update_clamp_threshold;
 	bool program_deskew_time;
 	bool raw_violation_fixup;
+	bool update_fc_threshold;
 	struct {
 		struct {
 			u32 rp_ectl_2_r1;
@@ -662,6 +663,13 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
 		value |= soc->update_fc_val;
 		writel(value, port->base + RP_VEND_XP);
 	}
+
+	if (soc->update_fc_threshold) {
+		value = readl(port->base + RP_VEND_XP);
+		value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK;
+		value |= soc->update_fc_val;
+		writel(value, port->base + RP_VEND_XP);
+	}
 }
 
 static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
@@ -2409,6 +2417,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
 	.update_clamp_threshold = false,
 	.program_deskew_time = false,
 	.raw_violation_fixup = false,
+	.update_fc_threshold = false,
 	.ectl.enable = false,
 };
 
@@ -2436,6 +2445,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
 	.update_clamp_threshold = false,
 	.program_deskew_time = false,
 	.raw_violation_fixup = false,
+	.update_fc_threshold = false,
 	.ectl.enable = false,
 };
 
@@ -2458,6 +2468,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
 	.update_clamp_threshold = true,
 	.program_deskew_time = false,
 	.raw_violation_fixup = true,
+	.update_fc_threshold = false,
 	.ectl.enable = false,
 };
 
@@ -2468,6 +2479,8 @@ static const struct tegra_pcie_soc tegra210_pcie = {
 	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
 	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
 	.pads_refclk_cfg0 = 0x90b890b8,
+	/* FC threshold is bit[25:18] */
+	.update_fc_val = 0x01800000,
 	.has_pex_clkreq_en = true,
 	.has_pex_bias_ctrl = true,
 	.has_intr_prsnt_sense = true,
@@ -2478,6 +2491,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
 	.update_clamp_threshold = true,
 	.program_deskew_time = true,
 	.raw_violation_fixup = false,
+	.update_fc_threshold = true,
 	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
 	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
 	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
@@ -2513,6 +2527,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
 	.update_clamp_threshold = false,
 	.program_deskew_time = false,
 	.raw_violation_fixup = false,
+	.update_fc_threshold = false,
 	.ectl.enable = false,
 };
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (12 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 13/30] PCI: tegra: Update flow control threshold in Tegra210 Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-11 20:04   ` Bjorn Helgaas
  2019-04-15 11:52   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 15/30] PCI: tegra: Fix PLLE powerdown issue due to CLKREQ# signal Manikanta Maddireddy
                   ` (15 subsequent siblings)
  29 siblings, 2 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Some of the legacy PCIe endpoints doesn't enumerate if root port advertises
both Gen-1 and Gen-2 speeds. Hence, the strategy followed here is to
initially advertise only Gen-1 and after link is up, retrain link to Gen-2
speed.

Following two cards display this behaviour,
  - Fusion HDTV 5 Express card
  - IOGear SIL - PCIE - SATA card

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 7dc728cc5f51..7e24eac12668 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -670,6 +670,17 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
 		value |= soc->update_fc_val;
 		writel(value, port->base + RP_VEND_XP);
 	}
+
+	/*
+	 * PCIe link doesn't come up with few legacy PCIe endpoints
+	 * if root port advertises both Gen-1 and Gen-2 speeds.
+	 * Hence, the strategy followed here is to initially advertise
+	 * only Gen-1 and after link is up, retrain link to Gen-2 speed
+	 */
+	value = readl(port->base + RP_LINK_CONTROL_STATUS_2);
+	value &= ~PCI_EXP_LNKSTA_CLS;
+	value |= PCI_EXP_LNKSTA_CLS_2_5GB;
+	writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
 }
 
 static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 15/30] PCI: tegra: Fix PLLE powerdown issue due to CLKREQ# signal
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (13 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 13:17   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 16/30] PCI: tegra: Program AFI_CACHE* registers only for Tegra20 Manikanta Maddireddy
                   ` (14 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Disable controllers which failed to link up and configure CLKREQ# signals
of these controllers as GPIO. This is required to avoid CLKREQ# signal of
inactive controllers interfering with PLLE powerdown sequence.

PCIE_CLKREQ_GPIO bits are defined only in Tegra186, however programming
these bits in other SoCs doesn't cause any side effects. Program these
bits for all Tegra SoCs to avoid conditional check.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 7e24eac12668..8e5fdc8ce3d6 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -160,6 +160,8 @@
 #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211	(0x1 << 20)
 #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411	(0x2 << 20)
 #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_111	(0x2 << 20)
+#define  AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(x)		(1 << ((x) + 29))
+#define  AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO_ALL		(0x7 << 29)
 
 #define AFI_FUSE			0x104
 #define  AFI_FUSE_PCIE_T0_GEN2_DIS	(1 << 2)
@@ -733,6 +735,15 @@ static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
 
 	value &= ~AFI_PEX_CTRL_REFCLK_EN;
 	afi_writel(port->pcie, value, ctrl);
+
+	/*
+	 * disable PCIe device and set CLKREQ# as gpio
+	 * to allow PLLE power down
+	 */
+	value = afi_readl(port->pcie, AFI_PCIE_CONFIG);
+	value |= AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
+	value |= AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(port->index);
+	afi_writel(port->pcie, value, AFI_PCIE_CONFIG);
 }
 
 static void tegra_pcie_port_free(struct tegra_pcie_port *port)
@@ -1147,9 +1158,12 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
 	value = afi_readl(pcie, AFI_PCIE_CONFIG);
 	value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK;
 	value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config;
+	value |= AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO_ALL;
 
-	list_for_each_entry(port, &pcie->ports, list)
+	list_for_each_entry(port, &pcie->ports, list) {
 		value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
+		value &= ~AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(port->index);
+	}
 
 	afi_writel(pcie, value, AFI_PCIE_CONFIG);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 16/30] PCI: tegra: Program AFI_CACHE* registers only for Tegra20
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (14 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 15/30] PCI: tegra: Fix PLLE powerdown issue due to CLKREQ# signal Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 13:20   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 17/30] PCI: tegra: Use switch statements in tegra_pcie_isr() Manikanta Maddireddy
                   ` (13 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

AFI_CACHE* registers are available only in Tegra20, program them only
for Tegra20.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 8e5fdc8ce3d6..cdaaf13a9fd7 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -887,6 +887,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
  */
 static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 {
+	struct device_node *np = pcie->dev->of_node;
 	u32 fpci_bar, size, axi_address;
 
 	/* Bar 0: type 1 extended configuration space */
@@ -927,11 +928,13 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 	afi_writel(pcie, 0, AFI_AXI_BAR5_SZ);
 	afi_writel(pcie, 0, AFI_FPCI_BAR5);
 
-	/* map all upstream transactions as uncached */
-	afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
-	afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
-	afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
-	afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
+	if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
+		/* map all upstream transactions as uncached */
+		afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
+		afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
+		afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
+		afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
+	}
 
 	/* MSI translations are setup only when needed */
 	afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 17/30] PCI: tegra: Use switch statements in tegra_pcie_isr()
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (15 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 16/30] PCI: tegra: Program AFI_CACHE* registers only for Tegra20 Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 13:25   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 18/30] PCI: tegra: Change PRSNT_SENSE irq log to debug Manikanta Maddireddy
                   ` (12 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Use switch statements in tegra_pcie_isr() for better code readability.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 37 ++++++++++++++++--------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index cdaaf13a9fd7..cf2715065a53 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -842,36 +842,39 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 	};
 	struct tegra_pcie *pcie = arg;
 	struct device *dev = pcie->dev;
-	u32 code, signature;
+	u32 code, signature, fpci;
+	u64 address;
 
 	code = afi_readl(pcie, AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
 	signature = afi_readl(pcie, AFI_INTR_SIGNATURE);
 	afi_writel(pcie, 0, AFI_INTR_CODE);
 
-	if (code == AFI_INTR_LEGACY)
-		return IRQ_NONE;
-
 	if (code >= ARRAY_SIZE(err_msg))
-		code = 0;
+		return IRQ_NONE;
 
+	switch (code) {
+	case AFI_INTR_LEGACY:
+		return IRQ_NONE;
 	/*
 	 * do not pollute kernel log with master abort reports since they
 	 * happen a lot during enumeration
 	 */
-	if (code == AFI_INTR_MASTER_ABORT)
+	case AFI_INTR_MASTER_ABORT:
 		dev_dbg(dev, "%s, signature: %08x\n", err_msg[code], signature);
-	else
+		fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
+		address = (u64)fpci << 32 | (signature & 0xfffffffc);
+		dev_dbg(dev, "  FPCI address: %10llx\n", address);
+		break;
+	case AFI_INTR_TARGET_ABORT:
+	case AFI_INTR_FPCI_DECODE_ERROR:
 		dev_err(dev, "%s, signature: %08x\n", err_msg[code], signature);
-
-	if (code == AFI_INTR_TARGET_ABORT || code == AFI_INTR_MASTER_ABORT ||
-	    code == AFI_INTR_FPCI_DECODE_ERROR) {
-		u32 fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
-		u64 address = (u64)fpci << 32 | (signature & 0xfffffffc);
-
-		if (code == AFI_INTR_MASTER_ABORT)
-			dev_dbg(dev, "  FPCI address: %10llx\n", address);
-		else
-			dev_err(dev, "  FPCI address: %10llx\n", address);
+		fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
+		address = (u64)fpci << 32 | (signature & 0xfffffffc);
+		dev_err(dev, "  FPCI address: %10llx\n", address);
+		break;
+	default:
+		dev_err(dev, "%s, signature: %08x\n", err_msg[code], signature);
+		break;
 	}
 
 	return IRQ_HANDLED;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 18/30] PCI: tegra: Change PRSNT_SENSE irq log to debug
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (16 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 17/30] PCI: tegra: Use switch statements in tegra_pcie_isr() Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 19/30] PCI: tegra: Use legacy irq for port service drivers Manikanta Maddireddy
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

PRSNT_MAP bit field is programmed to update the slot present status.
PRSNT_SENSE irq is triggered when this bit field is programmed, which is
not an error. Add a new switch case to trap RSNT_SENSE code and print it
with debug log level.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index cf2715065a53..dcfe97711cb5 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -855,6 +855,9 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
 	switch (code) {
 	case AFI_INTR_LEGACY:
 		return IRQ_NONE;
+	case AFI_INTR_PE_PRSNT_SENSE:
+		dev_dbg(dev, "%s, signature: %08x\n", err_msg[code], signature);
+		break;
 	/*
 	 * do not pollute kernel log with master abort reports since they
 	 * happen a lot during enumeration
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 19/30] PCI: tegra: Use legacy irq for port service drivers
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (17 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 18/30] PCI: tegra: Change PRSNT_SENSE irq log to debug Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 13:35   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 20/30] PCI: tegra: Add AFI_PEX2_CTRL reg offset as part of soc struct Manikanta Maddireddy
                   ` (10 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Tegra signals PCIe services like AER, PME, etc over legacy IRQ line.
By default service drivers register interrupt routine over MSI IRQ line,
use pcie_pme_disable_msi() function to disable MSI for service drivers.

PME and AER interrupts registered to MSI without this change
cat /proc/interrupts | grep -i pci
36: 21 0 0 0 0 0 GICv2 104 Level       PCIE
37: 35 0 0 0 0 0 GICv2 105 Level       Tegra PCIe MSI
76: 0  0 0 0 0 0 Tegra PCIe MSI 0 Edge PCIe PME, aerdrv, PCIe BW notif

PME and AER interrupts registered to legacy IRQ with this change
cat /proc/interrupts | grep -i pci
36: 33 0 0 0 0 0 GICv2 104 Level      PCIE, PCIe PME, aerdrv, PCIe BW notif
37: 52 0 0 0 0 0 GICv2 105 Level      Tegra PCIe MSI

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index dcfe97711cb5..11be88a394e3 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -41,6 +41,7 @@
 #include <soc/tegra/pmc.h>
 
 #include "../pci.h"
+#include "../pcie/portdrv.h"
 
 #define INT_PCI_MSI_NR (8 * 32)
 
@@ -2724,6 +2725,9 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 		goto put_resources;
 	}
 
+	/* PME events are received over legacy INTR, so disable MSI for PME */
+	pcie_pme_disable_msi();
+
 	pm_runtime_enable(pcie->dev);
 	err = pm_runtime_get_sync(pcie->dev);
 	if (err) {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 20/30] PCI: tegra: Add AFI_PEX2_CTRL reg offset as part of soc struct
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (18 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 19/30] PCI: tegra: Use legacy irq for port service drivers Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 13:31   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 21/30] PCI: tegra: Add "pci" type check before parsing child device tree node Manikanta Maddireddy
                   ` (9 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Tegra186 and Tegra30 have three PCIe root ports. AFI_PEX2_CTRL register
is defined for third root port. Offset of this register in Tegra186 is
different from Tegra30, so add offset as part of soc data structure.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 11be88a394e3..8fdc7934d4c9 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -169,7 +169,6 @@
 
 #define AFI_PEX0_CTRL			0x110
 #define AFI_PEX1_CTRL			0x118
-#define AFI_PEX2_CTRL			0x128
 #define  AFI_PEX_CTRL_RST		(1 << 0)
 #define  AFI_PEX_CTRL_CLKREQ_EN		(1 << 1)
 #define  AFI_PEX_CTRL_REFCLK_EN		(1 << 3)
@@ -307,6 +306,7 @@ struct tegra_pcie_soc {
 	unsigned int num_ports;
 	const struct tegra_pcie_port_soc *ports;
 	unsigned int msi_base_shift;
+	unsigned long afi_pex2_ctrl;
 	u32 pads_pll_ctl;
 	u32 tx_ref_sel;
 	u32 pads_refclk_cfg0;
@@ -516,6 +516,7 @@ static struct pci_ops tegra_pcie_ops = {
 
 static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
 {
+	const struct tegra_pcie_soc *soc = port->pcie->soc;
 	unsigned long ret = 0;
 
 	switch (port->index) {
@@ -528,7 +529,7 @@ static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
 		break;
 
 	case 2:
-		ret = AFI_PEX2_CTRL;
+		ret = soc->afi_pex2_ctrl;
 		break;
 	}
 
@@ -2439,6 +2440,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
 	.num_ports = 2,
 	.ports = tegra20_pcie_ports,
 	.msi_base_shift = 0,
+	.afi_pex2_ctrl = 0x128,
 	.pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
 	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10,
 	.pads_refclk_cfg0 = 0xfa5cfa5c,
@@ -2548,6 +2550,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
 	.num_ports = 3,
 	.ports = tegra186_pcie_ports,
 	.msi_base_shift = 8,
+	.afi_pex2_ctrl = 0x19c,
 	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
 	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
 	.pads_refclk_cfg0 = 0x80b880b8,
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 21/30] PCI: tegra: Add "pci" type check before parsing child device tree node
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (19 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 20/30] PCI: tegra: Add AFI_PEX2_CTRL reg offset as part of soc struct Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 13:37   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up Manikanta Maddireddy
                   ` (8 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Each root port is added as a child device tree node of PCIe controller
node. These child nodes are parsed using open firmware PCI bus accessor
functions. If the child node is not of "pci" type then device tree
parsing fails. Add "pci" type check before parsing child device tree node.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 8fdc7934d4c9..d08a63132c77 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -2197,6 +2197,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 		unsigned int index;
 		u32 value;
 
+		if (!of_node_is_type(port, "pci"))
+			continue;
+
 		err = of_pci_get_devfn(port);
 		if (err < 0) {
 			dev_err(dev, "failed to parse address: %d\n", err);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (20 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 21/30] PCI: tegra: Add "pci" type check before parsing child device tree node Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-11 20:15   ` Bjorn Helgaas
  2019-04-11 17:03 ` [PATCH 23/30] dt-bindings: pci: tegra: Document PCIe DPD pinctrl optional prop Manikanta Maddireddy
                   ` (7 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Add PCIe link up check in config read and write callback functions
before accessing endpoint config registers.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 38 ++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index d08a63132c77..c050687020f0 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -426,6 +426,14 @@ static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
 	return readl(pcie->pads + offset);
 }
 
+static bool tegra_pcie_link_status(struct tegra_pcie_port *port)
+{
+	u32 value;
+
+	value = readl(port->base + RP_LINK_CONTROL_STATUS);
+	return !!(value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE);
+}
+
 /*
  * The configuration space mapping on Tegra is somewhat similar to the ECAM
  * defined by PCIe. However it deviates a bit in how the 4 bits for extended
@@ -491,20 +499,50 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
 static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
 				  int where, int size, u32 *value)
 {
+	struct tegra_pcie *pcie = bus->sysdata;
+	struct pci_dev *bridge;
+	struct tegra_pcie_port *port;
+
 	if (bus->number == 0)
 		return pci_generic_config_read32(bus, devfn, where, size,
 						 value);
 
+	bridge = pcie_find_root_port(bus->self);
+
+	list_for_each_entry(port, &pcie->ports, list)
+		if (port->index + 1 == PCI_SLOT(bridge->devfn))
+			break;
+
+	/* If there is no link, then there is no device */
+	if (!tegra_pcie_link_status(port)) {
+		*value = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
 	return pci_generic_config_read(bus, devfn, where, size, value);
 }
 
 static int tegra_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
 				   int where, int size, u32 value)
 {
+	struct tegra_pcie *pcie = bus->sysdata;
+	struct tegra_pcie_port *port;
+	struct pci_dev *bridge;
+
 	if (bus->number == 0)
 		return pci_generic_config_write32(bus, devfn, where, size,
 						  value);
 
+	bridge = pcie_find_root_port(bus->self);
+
+	list_for_each_entry(port, &pcie->ports, list)
+		if (port->index + 1 == PCI_SLOT(bridge->devfn))
+			break;
+
+	/* If there is no link, then there is no device */
+	if (!tegra_pcie_link_status(port))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
 	return pci_generic_config_write(bus, devfn, where, size, value);
 }
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 23/30] dt-bindings: pci: tegra: Document PCIe DPD pinctrl optional prop
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (21 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 14:07   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 24/30] arm64: tegra: Add PEX DPD states as pinctrl properties Manikanta Maddireddy
                   ` (6 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Document PCIe DPD pinctrl optional property to put PEX clk & BIAS pads
in low power mode.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 .../devicetree/bindings/pci/nvidia,tegra20-pcie.txt      | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
index 145a4f04194f..fbbd3bcb3435 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
@@ -65,6 +65,15 @@ Required properties:
   - afi
   - pcie_x
 
+Optional properties:
+- pinctrl-names : The pin control state names.
+- pinctrl-0: PCIe IO(bias & REFCLK) deep power down(DPD) disable state.
+  In Tegra210 PCIe clamps are not controlling IO signals, so there
+  is leakagae power even after PCIe power partition is off. Pass
+  pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
+- pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
+  Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
+
 Required properties on Tegra124 and later (deprecated):
 - phys: Must contain an entry for each entry in phy-names.
 - phy-names: Must include the following entries:
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 24/30] arm64: tegra: Add PEX DPD states as pinctrl properties
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (22 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 23/30] dt-bindings: pci: tegra: Document PCIe DPD pinctrl optional prop Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 25/30] PCI: tegra: Put PEX CLK & BIAS pads in DPD mode Manikanta Maddireddy
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Add PEX DPD states as pinctrl properties to set in PCIe driver. In Tegra210
BIAS pads are not in power down mode when clamps are applied. So to set the
pads in DPD, pass the PEX DPD states as pinctrl properties to PCIe driver.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index a550c0a4d572..876e32e6d577 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -48,6 +48,11 @@
 			 <&tegra_car 72>,
 			 <&tegra_car 74>;
 		reset-names = "pex", "afi", "pcie_x";
+
+		pinctrl-names = "pex-dpd-disable", "pex-dpd-enable";
+		pinctrl-0 = <&pex_dpd_disable>;
+		pinctrl-1 = <&pex_dpd_enable>;
+
 		status = "disabled";
 
 		pci@1,0 {
@@ -848,6 +853,20 @@
 			pins = "sdmmc3";
 			power-source = <TEGRA_IO_PAD_VOLTAGE_1V8>;
 		};
+
+		pex_dpd_disable: pex_en {
+			pex-dpd-disable {
+				pins = "pex-bias", "pex-clk1", "pex-clk2";
+				low-power-disable;
+			};
+		};
+
+		pex_dpd_enable: pex_dis {
+			pex-dpd-enable {
+				pins = "pex-bias", "pex-clk1", "pex-clk2";
+				low-power-enable;
+			};
+		};
 	};
 
 	fuse@7000f800 {
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 25/30] PCI: tegra: Put PEX CLK & BIAS pads in DPD mode
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (23 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 24/30] arm64: tegra: Add PEX DPD states as pinctrl properties Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 14:11   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop Manikanta Maddireddy
                   ` (4 subsequent siblings)
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

In Tegra210 AFI design has clamp value for the BIAS pad as 0, which keeps
the bias pad in non power down mode. This is leading to power consumption
of 2 mW in BIAS pad, even if the PCIe partition is power gated. To avoid
unnecessary power consumption, put PEX CLK & BIAS pads in deep power down
mode when PCIe partition is power gated.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 65 +++++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index c050687020f0..92c6daa0de84 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -30,6 +30,7 @@
 #include <linux/of_platform.h>
 #include <linux/pci.h>
 #include <linux/phy/phy.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 #include <linux/sizes.h>
@@ -323,6 +324,7 @@ struct tegra_pcie_soc {
 	bool program_deskew_time;
 	bool raw_violation_fixup;
 	bool update_fc_threshold;
+	bool config_pex_io_dpd;
 	struct {
 		struct {
 			u32 rp_ectl_2_r1;
@@ -385,6 +387,10 @@ struct tegra_pcie {
 
 	const struct tegra_pcie_soc *soc;
 	struct dentry *debugfs;
+
+	struct pinctrl *pex_pinctrl;
+	struct pinctrl_state *pex_dpd_enable;
+	struct pinctrl_state *pex_dpd_disable;
 };
 
 struct tegra_pcie_port {
@@ -2154,6 +2160,37 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
 	return tegra_pcie_get_legacy_regulators(pcie);
 }
 
+static int tegra_pcie_parse_pinctrl(struct tegra_pcie *pcie)
+{
+	struct device *dev = pcie->dev;
+	int err = 0;
+
+	pcie->pex_pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR(pcie->pex_pinctrl)) {
+		err = PTR_ERR(pcie->pex_pinctrl);
+		dev_err(dev, "failed to get pinctrl handle: %d\n", err);
+		return err;
+	}
+
+	pcie->pex_dpd_enable = pinctrl_lookup_state(pcie->pex_pinctrl,
+						    "pex-dpd-enable");
+	if (IS_ERR(pcie->pex_dpd_enable)) {
+		err = PTR_ERR(pcie->pex_dpd_enable);
+		dev_err(dev, "missing pex-dpd-enable state: %d\n", err);
+		return err;
+	}
+
+	pcie->pex_dpd_disable = pinctrl_lookup_state(pcie->pex_pinctrl,
+						     "pex-dpd-disable");
+	if (IS_ERR(pcie->pex_dpd_disable)) {
+		err = PTR_ERR(pcie->pex_dpd_disable);
+		dev_err(dev, "missing pex-dpd-disable state: %d\n", err);
+		return err;
+	}
+
+	return err;
+}
+
 static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 {
 	struct device *dev = pcie->dev;
@@ -2496,6 +2533,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
 	.program_deskew_time = false,
 	.raw_violation_fixup = false,
 	.update_fc_threshold = false,
+	.config_pex_io_dpd = false,
 	.ectl.enable = false,
 };
 
@@ -2524,6 +2562,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
 	.program_deskew_time = false,
 	.raw_violation_fixup = false,
 	.update_fc_threshold = false,
+	.config_pex_io_dpd = false,
 	.ectl.enable = false,
 };
 
@@ -2547,6 +2586,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
 	.program_deskew_time = false,
 	.raw_violation_fixup = true,
 	.update_fc_threshold = false,
+	.config_pex_io_dpd = false,
 	.ectl.enable = false,
 };
 
@@ -2570,6 +2610,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
 	.program_deskew_time = true,
 	.raw_violation_fixup = false,
 	.update_fc_threshold = true,
+	.config_pex_io_dpd = true,
 	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
 	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
 	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
@@ -2607,6 +2648,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
 	.program_deskew_time = false,
 	.raw_violation_fixup = false,
 	.update_fc_threshold = false,
+	.config_pex_io_dpd = false,
 	.ectl.enable = false,
 };
 
@@ -2753,6 +2795,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&pcie->ports);
 	pcie->dev = dev;
 
+	if (pcie->soc->config_pex_io_dpd) {
+		err = tegra_pcie_parse_pinctrl(pcie);
+		if (err < 0)
+			return err;
+	}
+
 	err = tegra_pcie_parse_dt(pcie);
 	if (err < 0)
 		return err;
@@ -2866,6 +2914,8 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
 		tegra_pcie_disable_msi(pcie);
 
 	tegra_pcie_disable_controller(pcie);
+	if (pcie->soc->config_pex_io_dpd)
+		pinctrl_select_state(pcie->pex_pinctrl, pcie->pex_dpd_enable);
 	tegra_pcie_power_off(pcie);
 
 	return 0;
@@ -2881,10 +2931,20 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
 		dev_err(dev, "tegra pcie power on fail: %d\n", err);
 		return err;
 	}
+
+	if (pcie->soc->config_pex_io_dpd) {
+		err = pinctrl_select_state(pcie->pex_pinctrl,
+					   pcie->pex_dpd_disable);
+		if (err < 0) {
+			dev_err(dev, "disabling PCIe IO DPD failed: %d\n", err);
+			goto poweroff;
+		}
+	}
+
 	err = tegra_pcie_enable_controller(pcie);
 	if (err) {
 		dev_err(dev, "tegra pcie controller enable fail: %d\n", err);
-		goto poweroff;
+		goto pex_dpd_enable;
 	}
 	tegra_pcie_setup_translations(pcie);
 
@@ -2904,6 +2964,9 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
 
 disable_controller:
 	tegra_pcie_disable_controller(pcie);
+pex_dpd_enable:
+	if (pcie->soc->config_pex_io_dpd)
+		pinctrl_select_state(pcie->pex_pinctrl, pcie->pex_dpd_enable);
 poweroff:
 	tegra_pcie_power_off(pcie);
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (24 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 25/30] PCI: tegra: Put PEX CLK & BIAS pads in DPD mode Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-11 20:18   ` Bjorn Helgaas
  2019-04-15 14:16   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 27/30] PCI: tegra: Add support to configure platform GPIOs Manikanta Maddireddy
                   ` (3 subsequent siblings)
  29 siblings, 2 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Document "nvidia,plat-gpios" optional property which supports configuring
of platform specific gpios.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
index fbbd3bcb3435..dca8393b86d1 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
@@ -73,6 +73,8 @@ Optional properties:
   pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
 - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
   Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
+- nvidia,plat-gpios: A list of platform specific gpios which controls
+  endpoint's internal regulator or PCIe logic.
 
 Required properties on Tegra124 and later (deprecated):
 - phys: Must contain an entry for each entry in phy-names.
@@ -567,6 +569,7 @@ Board DTS:
 		pci@2,0 {
 			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
 			phy-names = "pcie-0";
+			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
 			status = "okay";
 		};
 	};
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 27/30] PCI: tegra: Add support to configure platform GPIOs
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (25 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 28/30] dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop Manikanta Maddireddy
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Few endpoints provides gpio control to its internal regulators or PCIe
interface. For example, few Wi-Fi chips provide gpio control to turn ON
or OFF internal regulators and RTL8111 NIC card provides a gpio control
to stop sampling PCIe Rx lane & driving Tx lane.

Add generic support to configure platform specific GPIOs of both
active high and low types before going for PCIe link up.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 59 ++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 92c6daa0de84..4a91c9fb3a9d 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -403,6 +403,9 @@ struct tegra_pcie_port {
 	unsigned int lanes;
 
 	struct phy **phys;
+
+	int n_gpios;
+	int *gpios;
 };
 
 struct tegra_pcie_bus {
@@ -1359,6 +1362,17 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
 	return err;
 }
 
+static void tegra_pcie_config_plat(struct tegra_pcie *pcie, bool set)
+{
+	struct tegra_pcie_port *port;
+	int count;
+
+	list_for_each_entry(port, &pcie->ports, list) {
+		for (count = 0; count < port->n_gpios; ++count)
+			gpiod_set_value(gpio_to_desc(port->gpios[count]), set);
+	}
+}
+
 static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
 {
 	struct device *dev = pcie->dev;
@@ -2191,6 +2205,45 @@ static int tegra_pcie_parse_pinctrl(struct tegra_pcie *pcie)
 	return err;
 }
 
+static int tegra_pcie_parse_plat_dt(struct tegra_pcie_port *port,
+				    struct device_node *np)
+{
+	struct device *dev = port->pcie->dev;
+	int count, gpio, err;
+	enum of_gpio_flags flags;
+	unsigned long f;
+
+	port->n_gpios = of_gpio_named_count(np, "nvidia,plat-gpios");
+	if (port->n_gpios > 0) {
+		port->gpios = devm_kzalloc(dev, port->n_gpios * sizeof(int),
+					   GFP_KERNEL);
+		if (!port->gpios)
+			return -ENOMEM;
+
+		for (count = 0; count < port->n_gpios; ++count) {
+			gpio = of_get_named_gpio_flags(np, "nvidia,plat-gpios",
+						       count, &flags);
+			if (!gpio_is_valid(gpio)) {
+				dev_err(dev, "invalid gpio: %d\n", gpio);
+				return gpio;
+			}
+
+			f = (flags & OF_GPIO_ACTIVE_LOW) ?
+			    (GPIOF_OUT_INIT_LOW | GPIOF_ACTIVE_LOW) :
+			    GPIOF_OUT_INIT_HIGH;
+
+			err = devm_gpio_request_one(dev, gpio, f, NULL);
+			if (err < 0) {
+				dev_err(dev, "gpio %d request failed\n", gpio);
+				return err;
+			}
+			port->gpios[count] = gpio;
+		}
+	}
+
+	return 0;
+}
+
 static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 {
 	struct device *dev = pcie->dev;
@@ -2332,6 +2385,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 		if (IS_ERR(rp->base))
 			return PTR_ERR(rp->base);
 
+		err = tegra_pcie_parse_plat_dt(rp, port);
+		if (err < 0)
+			return err;
+
 		list_add_tail(&rp->list, &pcie->ports);
 	}
 
@@ -2917,6 +2974,7 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
 	if (pcie->soc->config_pex_io_dpd)
 		pinctrl_select_state(pcie->pex_pinctrl, pcie->pex_dpd_enable);
 	tegra_pcie_power_off(pcie);
+	tegra_pcie_config_plat(pcie, 0);
 
 	return 0;
 }
@@ -2926,6 +2984,7 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
 	struct tegra_pcie *pcie = dev_get_drvdata(dev);
 	int err;
 
+	tegra_pcie_config_plat(pcie, 1);
 	err = tegra_pcie_power_on(pcie);
 	if (err) {
 		dev_err(dev, "tegra pcie power on fail: %d\n", err);
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 28/30] dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (26 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 27/30] PCI: tegra: Add support to configure platform GPIOs Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 14:20   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 29/30] PCI: tegra: Add support for GPIO based PCIe reset Manikanta Maddireddy
  2019-04-11 17:03 ` [PATCH 30/30] PCI: tegra: Change link retry log level to INFO Manikanta Maddireddy
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Document "nvidia,rst-gpio" optional property which supports GPIO based
PERST# signal.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
index dca8393b86d1..23928fd59538 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
@@ -75,6 +75,8 @@ Optional properties:
   Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
 - nvidia,plat-gpios: A list of platform specific gpios which controls
   endpoint's internal regulator or PCIe logic.
+- nvidia,rst-gpio: If GPIO is used as PERST# signal instead of available
+  SFIO, add this property with phandle to GPIO controller and GPIO number.
 
 Required properties on Tegra124 and later (deprecated):
 - phys: Must contain an entry for each entry in phy-names.
@@ -671,6 +673,7 @@ Board DTS:
 
 		pci@1,0 {
 			nvidia,num-lanes = <4>;
+			nvidia,rst-gpio = <&tegra_main_gpio TEGRA_MAIN_GPIO(A, 3) 0>;
 			status = "okay";
 		};
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 29/30] PCI: tegra: Add support for GPIO based PCIe reset
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (27 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 28/30] dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 14:20   ` Thierry Reding
  2019-04-11 17:03 ` [PATCH 30/30] PCI: tegra: Change link retry log level to INFO Manikanta Maddireddy
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Add support for GPIO based PERST# instead of SFIO mode controller by AFI.
GPIO number comes from per port PCIe device tree node.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 37 +++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 4a91c9fb3a9d..75873e6627f9 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -17,6 +17,7 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/iopoll.h>
 #include <linux/irq.h>
@@ -26,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of_address.h>
+#include <linux/of_gpio.h>
 #include <linux/of_pci.h>
 #include <linux/of_platform.h>
 #include <linux/pci.h>
@@ -406,6 +408,7 @@ struct tegra_pcie_port {
 
 	int n_gpios;
 	int *gpios;
+	int rst_gpio;
 };
 
 struct tegra_pcie_bus {
@@ -589,15 +592,23 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
 	unsigned long value;
 
 	/* pulse reset signal */
-	value = afi_readl(port->pcie, ctrl);
-	value &= ~AFI_PEX_CTRL_RST;
-	afi_writel(port->pcie, value, ctrl);
+	if (gpio_is_valid(port->rst_gpio)) {
+		gpio_set_value(port->rst_gpio, 0);
+	} else {
+		value = afi_readl(port->pcie, ctrl);
+		value &= ~AFI_PEX_CTRL_RST;
+		afi_writel(port->pcie, value, ctrl);
+	}
 
 	usleep_range(1000, 2000);
 
-	value = afi_readl(port->pcie, ctrl);
-	value |= AFI_PEX_CTRL_RST;
-	afi_writel(port->pcie, value, ctrl);
+	if (gpio_is_valid(port->rst_gpio)) {
+		gpio_set_value(port->rst_gpio, 1);
+	} else {
+		value = afi_readl(port->pcie, ctrl);
+		value |= AFI_PEX_CTRL_RST;
+		afi_writel(port->pcie, value, ctrl);
+	}
 }
 
 static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
@@ -2241,6 +2252,20 @@ static int tegra_pcie_parse_plat_dt(struct tegra_pcie_port *port,
 		}
 	}
 
+	port->rst_gpio = of_get_named_gpio(np, "nvidia,rst-gpio", 0);
+	if (gpio_is_valid(port->rst_gpio)) {
+		err = devm_gpio_request(dev, port->rst_gpio, "pex_rst_gpio");
+		if (err < 0) {
+			dev_err(dev, "rst_gpio request failed: %d\n", err);
+			return err;
+		}
+		err = gpio_direction_output(port->rst_gpio, 0);
+		if (err < 0) {
+			dev_err(dev, "rst_gpio set o/p failed: %d\n", err);
+			return err;
+		}
+	}
+
 	return 0;
 }
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* [PATCH 30/30] PCI: tegra: Change link retry log level to INFO
  2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
                   ` (28 preceding siblings ...)
  2019-04-11 17:03 ` [PATCH 29/30] PCI: tegra: Add support for GPIO based PCIe reset Manikanta Maddireddy
@ 2019-04-11 17:03 ` Manikanta Maddireddy
  2019-04-15 14:23   ` Thierry Reding
  29 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-11 17:03 UTC (permalink / raw)
  To: thierry.reding, bhelgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas
  Cc: linux-tegra, linux-pci, devicetree, Manikanta Maddireddy

Link retry log is info log not error, so change it to INFO log level.

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
---
 drivers/pci/controller/pci-tegra.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 75873e6627f9..55f8ff4f3e07 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -2461,7 +2461,7 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
 		} while (--timeout);
 
 		if (!timeout) {
-			dev_err(dev, "link %u down, retrying\n", port->index);
+			dev_info(dev, "link %u down, retrying\n", port->index);
 			goto retry;
 		}
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations
  2019-04-11 17:03 ` [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations Manikanta Maddireddy
@ 2019-04-11 20:01   ` Bjorn Helgaas
  2019-04-12  5:59     ` Manikanta Maddireddy
  2019-04-15 11:45   ` Thierry Reding
  1 sibling, 1 reply; 106+ messages in thread
From: Bjorn Helgaas @ 2019-04-11 20:01 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree

On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote:
> The logic which blocks read requests till AFI gets ACK for all outstanding
> MC writes does not behave correctly when number of outstanding write
> becomes more than 32 in Tegra124 and 132.
> 
> SW fixup to prevent this issue is to limit outstanding posted writes and
> tweak updateFC timer threshold.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>

>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>  	.program_uphy = true,
>  	.update_clamp_threshold = false,
>  	.program_deskew_time = false,
> +	.raw_violation_fixup = false,
>  	.ectl.enable = false,

It doesn't really matter either way, but you don't *have* to
initialize all these flags to "false" since that's the default for
uninitialized fields in static structs like these.  If you left them
out, the structs would only contain the "true" items, and it'd be
easier to see what's special about each SoC.

>  };
>  
> @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>  	.program_uphy = true,
>  	.update_clamp_threshold = false,
>  	.program_deskew_time = false,
> +	.raw_violation_fixup = false,
>  	.ectl.enable = false,
>  };

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up
  2019-04-11 17:03 ` [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up Manikanta Maddireddy
@ 2019-04-11 20:04   ` Bjorn Helgaas
  2019-04-12  6:44     ` Manikanta Maddireddy
  2019-04-15 11:52   ` Thierry Reding
  1 sibling, 1 reply; 106+ messages in thread
From: Bjorn Helgaas @ 2019-04-11 20:04 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree

On Thu, Apr 11, 2019 at 10:33:39PM +0530, Manikanta Maddireddy wrote:
> Some of the legacy PCIe endpoints doesn't enumerate if root port advertises
> both Gen-1 and Gen-2 speeds. Hence, the strategy followed here is to
> initially advertise only Gen-1 and after link is up, retrain link to Gen-2
> speed.
> 
> Following two cards display this behaviour,
>   - Fusion HDTV 5 Express card
>   - IOGear SIL - PCIE - SATA card

This sounds like a Tegra erratum.  If you think this is an issue with
the endpoints above, not with Tegra, we should see issues with these
cards in non-Tegra systems.

If that's the case, we might need a more far-reaching solution that
would fix issues with these cards in all systems.

If it really is a Tegra erratum, that's fine; just own up to it in the
commit log and comment so it's not misleading.

> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 7dc728cc5f51..7e24eac12668 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -670,6 +670,17 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>  		value |= soc->update_fc_val;
>  		writel(value, port->base + RP_VEND_XP);
>  	}
> +
> +	/*
> +	 * PCIe link doesn't come up with few legacy PCIe endpoints
> +	 * if root port advertises both Gen-1 and Gen-2 speeds.
> +	 * Hence, the strategy followed here is to initially advertise
> +	 * only Gen-1 and after link is up, retrain link to Gen-2 speed
> +	 */
> +	value = readl(port->base + RP_LINK_CONTROL_STATUS_2);
> +	value &= ~PCI_EXP_LNKSTA_CLS;
> +	value |= PCI_EXP_LNKSTA_CLS_2_5GB;
> +	writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
>  }
>  
>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-11 17:03 ` [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up Manikanta Maddireddy
@ 2019-04-11 20:15   ` Bjorn Helgaas
  2019-04-12  7:00     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Bjorn Helgaas @ 2019-04-11 20:15 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree

On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
> Add PCIe link up check in config read and write callback functions
> before accessing endpoint config registers.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 38 ++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index d08a63132c77..c050687020f0 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -426,6 +426,14 @@ static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
>  	return readl(pcie->pads + offset);
>  }
>  
> +static bool tegra_pcie_link_status(struct tegra_pcie_port *port)

Most drivers call this *_pcie_link_up().  It would be better if tegra
followed that convention.

> +{
> +	u32 value;
> +
> +	value = readl(port->base + RP_LINK_CONTROL_STATUS);
> +	return !!(value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE);
> +}
> +
>  /*
>   * The configuration space mapping on Tegra is somewhat similar to the ECAM
>   * defined by PCIe. However it deviates a bit in how the 4 bits for extended
> @@ -491,20 +499,50 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
>  				  int where, int size, u32 *value)
>  {
> +	struct tegra_pcie *pcie = bus->sysdata;
> +	struct pci_dev *bridge;
> +	struct tegra_pcie_port *port;
> +
>  	if (bus->number == 0)
>  		return pci_generic_config_read32(bus, devfn, where, size,
>  						 value);
>  
> +	bridge = pcie_find_root_port(bus->self);
> +
> +	list_for_each_entry(port, &pcie->ports, list)
> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
> +			break;
> +
> +	/* If there is no link, then there is no device */
> +	if (!tegra_pcie_link_status(port)) {

This is racy and you should avoid it if possible.  The link could go down
between calling tegra_pcie_link_status() and issuing the config read/write.

If your driver is to be reliable, it must be able to handle any bad
consequence of issuing that config read/write anyway, so I think it's
better if it doesn't even bother checking whether the link is up.

> +		*value = 0xffffffff;
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +	}
> +
>  	return pci_generic_config_read(bus, devfn, where, size, value);
>  }
>  
>  static int tegra_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
>  				   int where, int size, u32 value)
>  {
> +	struct tegra_pcie *pcie = bus->sysdata;
> +	struct tegra_pcie_port *port;
> +	struct pci_dev *bridge;
> +
>  	if (bus->number == 0)
>  		return pci_generic_config_write32(bus, devfn, where, size,
>  						  value);
>  
> +	bridge = pcie_find_root_port(bus->self);
> +
> +	list_for_each_entry(port, &pcie->ports, list)
> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
> +			break;
> +
> +	/* If there is no link, then there is no device */
> +	if (!tegra_pcie_link_status(port))
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +
>  	return pci_generic_config_write(bus, devfn, where, size, value);
>  }
>  
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-11 17:03 ` [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop Manikanta Maddireddy
@ 2019-04-11 20:18   ` Bjorn Helgaas
  2019-04-12  7:01     ` Manikanta Maddireddy
  2019-04-15 14:16   ` Thierry Reding
  1 sibling, 1 reply; 106+ messages in thread
From: Bjorn Helgaas @ 2019-04-11 20:18 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree

On Thu, Apr 11, 2019 at 10:33:51PM +0530, Manikanta Maddireddy wrote:
> Document "nvidia,plat-gpios" optional property which supports configuring
> of platform specific gpios.

s/gpios/GPIOs/ (also in the description below)

Acronyms in commit logs, comments, printks, etc should be capitalized.

> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> index fbbd3bcb3435..dca8393b86d1 100644
> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> @@ -73,6 +73,8 @@ Optional properties:
>    pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
>  - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
> +- nvidia,plat-gpios: A list of platform specific gpios which controls
> +  endpoint's internal regulator or PCIe logic.
>  
>  Required properties on Tegra124 and later (deprecated):
>  - phys: Must contain an entry for each entry in phy-names.
> @@ -567,6 +569,7 @@ Board DTS:
>  		pci@2,0 {
>  			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
>  			phy-names = "pcie-0";
> +			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
>  			status = "okay";
>  		};
>  	};
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations
  2019-04-11 20:01   ` Bjorn Helgaas
@ 2019-04-12  5:59     ` Manikanta Maddireddy
  2019-04-15 11:41       ` Thierry Reding
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-12  5:59 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree


On 12-Apr-19 1:31 AM, Bjorn Helgaas wrote:
> On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote:
>> The logic which blocks read requests till AFI gets ACK for all outstanding
>> MC writes does not behave correctly when number of outstanding write
>> becomes more than 32 in Tegra124 and 132.
>>
>> SW fixup to prevent this issue is to limit outstanding posted writes and
>> tweak updateFC timer threshold.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>> @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = false,
>>  	.program_deskew_time = false,
>> +	.raw_violation_fixup = false,
>>  	.ectl.enable = false,
> It doesn't really matter either way, but you don't *have* to
> initialize all these flags to "false" since that's the default for
> uninitialized fields in static structs like these.  If you left them
> out, the structs would only contain the "true" items, and it'd be
> easier to see what's special about each SoC.

SoC flags are explicitly set false if not supported, I am following same existing

coding style in this driver. Maybe the intention here is to convey what is

not supported by a particular SoC without going through soc struct definition.

>>  };
>>  
>> @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = false,
>>  	.program_deskew_time = false,
>> +	.raw_violation_fixup = false,
>>  	.ectl.enable = false,
>>  };

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up
  2019-04-11 20:04   ` Bjorn Helgaas
@ 2019-04-12  6:44     ` Manikanta Maddireddy
  2019-04-12 14:35       ` Bjorn Helgaas
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-12  6:44 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree


On 12-Apr-19 1:34 AM, Bjorn Helgaas wrote:
> On Thu, Apr 11, 2019 at 10:33:39PM +0530, Manikanta Maddireddy wrote:
>> Some of the legacy PCIe endpoints doesn't enumerate if root port advertises
>> both Gen-1 and Gen-2 speeds. Hence, the strategy followed here is to
>> initially advertise only Gen-1 and after link is up, retrain link to Gen-2
>> speed.
>>
>> Following two cards display this behaviour,
>>   - Fusion HDTV 5 Express card
>>   - IOGear SIL - PCIE - SATA card
> This sounds like a Tegra erratum.  If you think this is an issue with
> the endpoints above, not with Tegra, we should see issues with these
> cards in non-Tegra systems.
>
> If that's the case, we might need a more far-reaching solution that
> would fix issues with these cards in all systems.
>
> If it really is a Tegra erratum, that's fine; just own up to it in the
> commit log and comment so it's not misleading.

Based on PCIe LA traces with x86 platform:
 1) x86 initially advertises Gen1, Gen2 & Gen3 speeds. Link number negotiation does not happen
 as end point does not lock down to the advertised link number from RP.
 2) There are multiple entries to detect<->compliance from the both the sides.
 3) After some time (or some counts of detect entry), x86 only advertises Gen1 speed in TS1
 4) This time end point responds to the link number in the TS1 and link comes up

Tegra PCIe IP fails after step-2, it doesn't retry with only Gen1. This is the reason for

setting link speed to Gen1 and then start LTSSM.

I don't see anything mentioned about advertising lower link speed and retrying

link up in "Configuration Substate Machine" figure in PCIe spec. I am not sure

if it is mentioned anywhere in implementation notes or left for implementer to

decide in PCIe spec.

I will update this information in next version of this patch to justify why this is required

only for Tegra.

>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 11 +++++++++++
>>  1 file changed, 11 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 7dc728cc5f51..7e24eac12668 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -670,6 +670,17 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>>  		value |= soc->update_fc_val;
>>  		writel(value, port->base + RP_VEND_XP);
>>  	}
>> +
>> +	/*
>> +	 * PCIe link doesn't come up with few legacy PCIe endpoints
>> +	 * if root port advertises both Gen-1 and Gen-2 speeds.
>> +	 * Hence, the strategy followed here is to initially advertise
>> +	 * only Gen-1 and after link is up, retrain link to Gen-2 speed
>> +	 */
>> +	value = readl(port->base + RP_LINK_CONTROL_STATUS_2);
>> +	value &= ~PCI_EXP_LNKSTA_CLS;
>> +	value |= PCI_EXP_LNKSTA_CLS_2_5GB;
>> +	writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
>>  }
>>  
>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>> -- 
>> 2.17.1
>>

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-11 20:15   ` Bjorn Helgaas
@ 2019-04-12  7:00     ` Manikanta Maddireddy
  2019-04-12 14:50       ` Bjorn Helgaas
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-12  7:00 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree


On 12-Apr-19 1:45 AM, Bjorn Helgaas wrote:
> On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
>> Add PCIe link up check in config read and write callback functions
>> before accessing endpoint config registers.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 38 ++++++++++++++++++++++++++++++
>>  1 file changed, 38 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index d08a63132c77..c050687020f0 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -426,6 +426,14 @@ static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
>>  	return readl(pcie->pads + offset);
>>  }
>>  
>> +static bool tegra_pcie_link_status(struct tegra_pcie_port *port)
> Most drivers call this *_pcie_link_up().  It would be better if tegra
> followed that convention.
OK, I will update it in next version.
>
>> +{
>> +	u32 value;
>> +
>> +	value = readl(port->base + RP_LINK_CONTROL_STATUS);
>> +	return !!(value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE);
>> +}
>> +
>>  /*
>>   * The configuration space mapping on Tegra is somewhat similar to the ECAM
>>   * defined by PCIe. However it deviates a bit in how the 4 bits for extended
>> @@ -491,20 +499,50 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
>>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
>>  				  int where, int size, u32 *value)
>>  {
>> +	struct tegra_pcie *pcie = bus->sysdata;
>> +	struct pci_dev *bridge;
>> +	struct tegra_pcie_port *port;
>> +
>>  	if (bus->number == 0)
>>  		return pci_generic_config_read32(bus, devfn, where, size,
>>  						 value);
>>  
>> +	bridge = pcie_find_root_port(bus->self);
>> +
>> +	list_for_each_entry(port, &pcie->ports, list)
>> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
>> +			break;
>> +
>> +	/* If there is no link, then there is no device */
>> +	if (!tegra_pcie_link_status(port)) {
> This is racy and you should avoid it if possible.  The link could go down
> between calling tegra_pcie_link_status() and issuing the config read/write.
>
> If your driver is to be reliable, it must be able to handle any bad
> consequence of issuing that config read/write anyway, so I think it's
> better if it doesn't even bother checking whether the link is up.
This change is made based on similar check present in dwc driver

dw_pcie_valid_device(), reasons for making this change in Tegra might

differ dwc.

Intention here is to reduce the number of AER errors when device is

falling off the bus or going through hot reset. So racy condition here

is OK

>> +		*value = 0xffffffff;
>> +		return PCIBIOS_DEVICE_NOT_FOUND;
>> +	}
>> +
>>  	return pci_generic_config_read(bus, devfn, where, size, value);
>>  }
>>  
>>  static int tegra_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
>>  				   int where, int size, u32 value)
>>  {
>> +	struct tegra_pcie *pcie = bus->sysdata;
>> +	struct tegra_pcie_port *port;
>> +	struct pci_dev *bridge;
>> +
>>  	if (bus->number == 0)
>>  		return pci_generic_config_write32(bus, devfn, where, size,
>>  						  value);
>>  
>> +	bridge = pcie_find_root_port(bus->self);
>> +
>> +	list_for_each_entry(port, &pcie->ports, list)
>> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
>> +			break;
>> +
>> +	/* If there is no link, then there is no device */
>> +	if (!tegra_pcie_link_status(port))
>> +		return PCIBIOS_DEVICE_NOT_FOUND;
>> +
>>  	return pci_generic_config_write(bus, devfn, where, size, value);
>>  }
>>  
>> -- 
>> 2.17.1
>>

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-11 20:18   ` Bjorn Helgaas
@ 2019-04-12  7:01     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-12  7:01 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree


On 12-Apr-19 1:48 AM, Bjorn Helgaas wrote:
> On Thu, Apr 11, 2019 at 10:33:51PM +0530, Manikanta Maddireddy wrote:
>> Document "nvidia,plat-gpios" optional property which supports configuring
>> of platform specific gpios.
> s/gpios/GPIOs/ (also in the description below)
>
> Acronyms in commit logs, comments, printks, etc should be capitalized.
I will take care of it in next version.
>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> index fbbd3bcb3435..dca8393b86d1 100644
>> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> @@ -73,6 +73,8 @@ Optional properties:
>>    pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
>>  - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
>>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
>> +- nvidia,plat-gpios: A list of platform specific gpios which controls
>> +  endpoint's internal regulator or PCIe logic.
>>  
>>  Required properties on Tegra124 and later (deprecated):
>>  - phys: Must contain an entry for each entry in phy-names.
>> @@ -567,6 +569,7 @@ Board DTS:
>>  		pci@2,0 {
>>  			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
>>  			phy-names = "pcie-0";
>> +			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
>>  			status = "okay";
>>  		};
>>  	};
>> -- 
>> 2.17.1
>>

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up
  2019-04-12  6:44     ` Manikanta Maddireddy
@ 2019-04-12 14:35       ` Bjorn Helgaas
  2019-04-15 10:43         ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Bjorn Helgaas @ 2019-04-12 14:35 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree

On Fri, Apr 12, 2019 at 12:14:20PM +0530, Manikanta Maddireddy wrote:
> On 12-Apr-19 1:34 AM, Bjorn Helgaas wrote:
> > On Thu, Apr 11, 2019 at 10:33:39PM +0530, Manikanta Maddireddy wrote:
> >> Some of the legacy PCIe endpoints doesn't enumerate if root port advertises
> >> both Gen-1 and Gen-2 speeds. Hence, the strategy followed here is to
> >> initially advertise only Gen-1 and after link is up, retrain link to Gen-2
> >> speed.
> >>
> >> Following two cards display this behaviour,
> >>   - Fusion HDTV 5 Express card
> >>   - IOGear SIL - PCIE - SATA card
> > This sounds like a Tegra erratum.  If you think this is an issue with
> > the endpoints above, not with Tegra, we should see issues with these
> > cards in non-Tegra systems.
> >
> > If that's the case, we might need a more far-reaching solution that
> > would fix issues with these cards in all systems.
> >
> > If it really is a Tegra erratum, that's fine; just own up to it in the
> > commit log and comment so it's not misleading.
> 
> Based on PCIe LA traces with x86 platform:
>  1) x86 initially advertises Gen1, Gen2 & Gen3 speeds. Link number negotiation does not happen
>  as end point does not lock down to the advertised link number from RP.
>  2) There are multiple entries to detect<->compliance from the both the sides.
>  3) After some time (or some counts of detect entry), x86 only advertises Gen1 speed in TS1
>  4) This time end point responds to the link number in the TS1 and link comes up
> 
> Tegra PCIe IP fails after step-2, it doesn't retry with only Gen1.
> This is the reason for setting link speed to Gen1 and then start
> LTSSM.
> 
> I don't see anything mentioned about advertising lower link speed
> and retrying link up in "Configuration Substate Machine" figure in
> PCIe spec. I am not sure if it is mentioned anywhere in
> implementation notes or left for implementer to decide in PCIe spec.

There's a note in PCIe r4.0, sec 1.2 that says

  Initialization – During hardware initialization, each PCI Express
  Link is set up following a negotiation of Lane widths and frequency
  of operation by the two agents at each end of the Link. No firmware
  or operating system software is involved.

I interpret that as meaning the hardware at each end of the link
should be able to initialize the link without any help from software.

I think the hardware pretty much *has* to be able to do that.
Consider the native PCIe hotplug case: the OS has the generic pciehp
driver, but no knowledge of any device-specific behavior of the
Downstream Port leading to a hot-added device.  I don't *think*
there's anything in the spec about software having to be involved in
initializing the link in that case (correct me if I'm wrong), so the
link has to come up correctly without any OS or firmware intervention.

I'd argue that the same applies to this Tegra root port situation.  If
some issue requires a workaround to bring the link up, you do have the
opportunity to apply the fixup at probe-time.  But if you ever hope to
support hotplug for the root port, I think you'll have trouble because
I don't think there's a hook that lets you apply this fixup at hot-add
time.

> I will update this information in next version of this patch to
> justify why this is required only for Tegra.

> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >> ---
> >>  drivers/pci/controller/pci-tegra.c | 11 +++++++++++
> >>  1 file changed, 11 insertions(+)
> >>
> >> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> >> index 7dc728cc5f51..7e24eac12668 100644
> >> --- a/drivers/pci/controller/pci-tegra.c
> >> +++ b/drivers/pci/controller/pci-tegra.c
> >> @@ -670,6 +670,17 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
> >>  		value |= soc->update_fc_val;
> >>  		writel(value, port->base + RP_VEND_XP);
> >>  	}
> >> +
> >> +	/*
> >> +	 * PCIe link doesn't come up with few legacy PCIe endpoints
> >> +	 * if root port advertises both Gen-1 and Gen-2 speeds.
> >> +	 * Hence, the strategy followed here is to initially advertise
> >> +	 * only Gen-1 and after link is up, retrain link to Gen-2 speed
> >> +	 */
> >> +	value = readl(port->base + RP_LINK_CONTROL_STATUS_2);
> >> +	value &= ~PCI_EXP_LNKSTA_CLS;
> >> +	value |= PCI_EXP_LNKSTA_CLS_2_5GB;
> >> +	writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
> >>  }
> >>  
> >>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> >> -- 
> >> 2.17.1
> >>

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-12  7:00     ` Manikanta Maddireddy
@ 2019-04-12 14:50       ` Bjorn Helgaas
  2019-04-15 11:36         ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Bjorn Helgaas @ 2019-04-12 14:50 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree,
	Jingoo Han, Gustavo Pimentel, Ley Foon Tan, Michal Simek

[+cc Jingoo, Gustavo (dwc maintainers), Ley (altera), Michal (xilinx)]

On Fri, Apr 12, 2019 at 12:30:22PM +0530, Manikanta Maddireddy wrote:
> On 12-Apr-19 1:45 AM, Bjorn Helgaas wrote:
> > On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
> >> Add PCIe link up check in config read and write callback functions
> >> before accessing endpoint config registers.

> >>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
> >>  				  int where, int size, u32 *value)
> >>  {
> >> +	struct tegra_pcie *pcie = bus->sysdata;
> >> +	struct pci_dev *bridge;
> >> +	struct tegra_pcie_port *port;
> >> +
> >>  	if (bus->number == 0)
> >>  		return pci_generic_config_read32(bus, devfn, where, size,
> >>  						 value);
> >>  
> >> +	bridge = pcie_find_root_port(bus->self);
> >> +
> >> +	list_for_each_entry(port, &pcie->ports, list)
> >> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
> >> +			break;
> >> +
> >> +	/* If there is no link, then there is no device */
> >> +	if (!tegra_pcie_link_status(port)) {
> >
> > This is racy and you should avoid it if possible.  The link could go down
> > between calling tegra_pcie_link_status() and issuing the config read/write.
> >
> > If your driver is to be reliable, it must be able to handle any bad
> > consequence of issuing that config read/write anyway, so I think it's
> > better if it doesn't even bother checking whether the link is up.
>
> This change is made based on similar check present in dwc driver
> dw_pcie_valid_device(), reasons for making this change in Tegra might
> differ dwc.

Yes, you won't be surprised to learn that I don't like the similar
checks in dwc, altera, xilinx, and xilinx-nwl either :)  I raise this
issue every time I see it, but I can't remember if I've mentioned dwc
specifically.

We need to either eradicate this pattern of checking for link up, or
include a comment about why it is absolutely necessary.

> Intention here is to reduce the number of AER errors when device is
> falling off the bus or going through hot reset. So racy condition here is
> OK

I'm not convinced about this.  The issues you mention need to be
solved in a generic way, not a tegra-specific way.

We don't want to end up with code that silently avoids the config
access 99.99% of the time, but once in a blue moon, we lose the race
(the device stops responding after we've determined the link is up)
and the access causes a mysterious AER error that we have no way to
debug.

> >> +		*value = 0xffffffff;
> >> +		return PCIBIOS_DEVICE_NOT_FOUND;
> >> +	}
> >> +
> >>  	return pci_generic_config_read(bus, devfn, where, size, value);
> >>  }

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up
  2019-04-12 14:35       ` Bjorn Helgaas
@ 2019-04-15 10:43         ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 10:43 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree


On 12-Apr-19 8:05 PM, Bjorn Helgaas wrote:
> On Fri, Apr 12, 2019 at 12:14:20PM +0530, Manikanta Maddireddy wrote:
>> On 12-Apr-19 1:34 AM, Bjorn Helgaas wrote:
>>> On Thu, Apr 11, 2019 at 10:33:39PM +0530, Manikanta Maddireddy wrote:
>>>> Some of the legacy PCIe endpoints doesn't enumerate if root port advertises
>>>> both Gen-1 and Gen-2 speeds. Hence, the strategy followed here is to
>>>> initially advertise only Gen-1 and after link is up, retrain link to Gen-2
>>>> speed.
>>>>
>>>> Following two cards display this behaviour,
>>>>   - Fusion HDTV 5 Express card
>>>>   - IOGear SIL - PCIE - SATA card
>>> This sounds like a Tegra erratum.  If you think this is an issue with
>>> the endpoints above, not with Tegra, we should see issues with these
>>> cards in non-Tegra systems.
>>>
>>> If that's the case, we might need a more far-reaching solution that
>>> would fix issues with these cards in all systems.
>>>
>>> If it really is a Tegra erratum, that's fine; just own up to it in the
>>> commit log and comment so it's not misleading.
>> Based on PCIe LA traces with x86 platform:
>>  1) x86 initially advertises Gen1, Gen2 & Gen3 speeds. Link number negotiation does not happen
>>  as end point does not lock down to the advertised link number from RP.
>>  2) There are multiple entries to detect<->compliance from the both the sides.
>>  3) After some time (or some counts of detect entry), x86 only advertises Gen1 speed in TS1
>>  4) This time end point responds to the link number in the TS1 and link comes up
>>
>> Tegra PCIe IP fails after step-2, it doesn't retry with only Gen1.
>> This is the reason for setting link speed to Gen1 and then start
>> LTSSM.
>>
>> I don't see anything mentioned about advertising lower link speed
>> and retrying link up in "Configuration Substate Machine" figure in
>> PCIe spec. I am not sure if it is mentioned anywhere in
>> implementation notes or left for implementer to decide in PCIe spec.
> There's a note in PCIe r4.0, sec 1.2 that says
>
>   Initialization – During hardware initialization, each PCI Express
>   Link is set up following a negotiation of Lane widths and frequency
>   of operation by the two agents at each end of the Link. No firmware
>   or operating system software is involved.
>
> I interpret that as meaning the hardware at each end of the link
> should be able to initialize the link without any help from software.
>
> I think the hardware pretty much *has* to be able to do that.
> Consider the native PCIe hotplug case: the OS has the generic pciehp
> driver, but no knowledge of any device-specific behavior of the
> Downstream Port leading to a hot-added device.  I don't *think*
> there's anything in the spec about software having to be involved in
> initializing the link in that case (correct me if I'm wrong), so the
> link has to come up correctly without any OS or firmware intervention.
>
> I'd argue that the same applies to this Tegra root port situation.  If
> some issue requires a workaround to bring the link up, you do have the
> opportunity to apply the fixup at probe-time.  But if you ever hope to
> support hotplug for the root port, I think you'll have trouble because
> I don't think there's a hook that lets you apply this fixup at hot-add
> time.

When you said "link initialization should happen without SW/firmware

intervention", it is after LTSSM is started, right? This patch programs

the target link speed before LTSSM is started.

As mentioned above these cards works on x86 because PCIe IP tires

link up with only Gen1 advertisement after "link number" negotiation fails.

Where as Tegra PCIe IP doesn't try with only Gen1 advertisement. i.e

 1) After LTSSM is initiated by driver, Tegra advertises Gen1 & Gen2
speeds. Link number negotiation does not happen.
 as end point does not lock down to the advertised link number from RP.
 2) LTSSM state moves to disabled.

LTSSM sequence with current patch,
 1) After LTSSM is initiated by driver, Tegra advertises Gen1 speeds.
 2) This time end point responds to the link number in the TS1 and link
comes up

Setting target speed Gen1 is OK because HW autonomous speed change support

is not available in Tegra. After link up driver retrains the link to Gen2 after setting

Target speed.


Tegra doesn't support hot-plug, so no need to worry about this scenario

in hot-plug case.

>
>> I will update this information in next version of this patch to
>> justify why this is required only for Tegra.
>>>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>>>> ---
>>>>  drivers/pci/controller/pci-tegra.c | 11 +++++++++++
>>>>  1 file changed, 11 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>>>> index 7dc728cc5f51..7e24eac12668 100644
>>>> --- a/drivers/pci/controller/pci-tegra.c
>>>> +++ b/drivers/pci/controller/pci-tegra.c
>>>> @@ -670,6 +670,17 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>>>>  		value |= soc->update_fc_val;
>>>>  		writel(value, port->base + RP_VEND_XP);
>>>>  	}
>>>> +
>>>> +	/*
>>>> +	 * PCIe link doesn't come up with few legacy PCIe endpoints
>>>> +	 * if root port advertises both Gen-1 and Gen-2 speeds.
>>>> +	 * Hence, the strategy followed here is to initially advertise
>>>> +	 * only Gen-1 and after link is up, retrain link to Gen-2 speed
>>>> +	 */
>>>> +	value = readl(port->base + RP_LINK_CONTROL_STATUS_2);
>>>> +	value &= ~PCI_EXP_LNKSTA_CLS;
>>>> +	value |= PCI_EXP_LNKSTA_CLS_2_5GB;
>>>> +	writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
>>>>  }
>>>>  
>>>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>>>> -- 
>>>> 2.17.1
>>>>

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence
  2019-04-11 17:03 ` [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence Manikanta Maddireddy
@ 2019-04-15 11:01   ` Thierry Reding
  2019-04-15 14:11     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:01 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 7001 bytes --]

On Thu, Apr 11, 2019 at 10:33:27PM +0530, Manikanta Maddireddy wrote:
> PCIe host power up sequence involves programming AFI(AXI to FPCI bridge)
> registers first and then PCIe registers. Otherwise AFI register settings
> may not latch to PCIe IP.
> 
> PCIe root port starts LTSSM as soon as PCIe xrst is deasserted.
> So deassert PCIe xrst after programming PCIe registers.
> 
> Modify PCIe power up sequence as follows,
>   - Power ungate PCIe partition
>   - Enable AFI clock
>   - Deassert AFI reset
>   - Program AFI registers
>   - Enable PCIe clock
>   - Deassert PCIe reset
>   - Program PCIe registers
>   - Deassert PCIe xrst to start LTSSM
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 73 ++++++++++++++++++------------
>  1 file changed, 43 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index f4f53d092e00..0bf270bcea34 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -966,9 +966,6 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
>  		}
>  	}
>  
> -	/* take the PCIe interface module out of reset */
> -	reset_control_deassert(pcie->pcie_xrst);
> -
>  	/* finally enable PCIe */
>  	value = afi_readl(pcie, AFI_CONFIGURATION);
>  	value |= AFI_CONFIGURATION_EN_FPCI;
> @@ -997,8 +994,6 @@ static void tegra_pcie_disable_controller(struct tegra_pcie *pcie)
>  {
>  	int err;
>  
> -	reset_control_assert(pcie->pcie_xrst);
> -
>  	if (pcie->soc->program_uphy) {
>  		err = tegra_pcie_phy_power_off(pcie);
>  		if (err < 0)
> @@ -1014,13 +1009,11 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
>  	int err;
>  
>  	reset_control_assert(pcie->afi_rst);
> -	reset_control_assert(pcie->pex_rst);
>  
>  	clk_disable_unprepare(pcie->pll_e);
>  	if (soc->has_cml_clk)
>  		clk_disable_unprepare(pcie->cml_clk);
>  	clk_disable_unprepare(pcie->afi_clk);
> -	clk_disable_unprepare(pcie->pex_clk);
>  
>  	if (!dev->pm_domain)
>  		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
> @@ -1036,58 +1029,59 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
>  	const struct tegra_pcie_soc *soc = pcie->soc;
>  	int err;
>  
> -	reset_control_assert(pcie->pcie_xrst);
> -	reset_control_assert(pcie->afi_rst);
> -	reset_control_assert(pcie->pex_rst);
> -
> -	if (!dev->pm_domain)
> -		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
> -

This code was in place to ensure that PCIe was in a known good state
before following the power up sequence below. You mentioned elsewhere
that there's a regression on Cardhu after applying this series, so
perhaps Cardhu relies on the above hunk?

>  	/* enable regulators */
>  	err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
>  	if (err < 0)
>  		dev_err(dev, "failed to enable regulators: %d\n", err);
>  
> -	if (dev->pm_domain) {
> -		err = clk_prepare_enable(pcie->pex_clk);
> +	if (!dev->pm_domain) {
> +		err = tegra_powergate_power_on(TEGRA_POWERGATE_PCIE);
>  		if (err) {
> -			dev_err(dev, "failed to enable PEX clock: %d\n", err);
> -			return err;
> +			dev_err(dev, "power ungate failed: %d\n", err);
> +			goto regulator_disable;
>  		}
> -		reset_control_deassert(pcie->pex_rst);
> -	} else {
> -		err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
> -							pcie->pex_clk,
> -							pcie->pex_rst);
> +		err = tegra_powergate_remove_clamping(TEGRA_POWERGATE_PCIE);
>  		if (err) {
> -			dev_err(dev, "powerup sequence failed: %d\n", err);
> -			return err;
> +			dev_err(dev, "remove clamp failed: %d\n", err);
> +			goto powergate;
>  		}
>  	}
>  
> -	reset_control_deassert(pcie->afi_rst);
> -
>  	err = clk_prepare_enable(pcie->afi_clk);
>  	if (err < 0) {
>  		dev_err(dev, "failed to enable AFI clock: %d\n", err);
> -		return err;
> +		goto powergate;
>  	}
>  
>  	if (soc->has_cml_clk) {
>  		err = clk_prepare_enable(pcie->cml_clk);
>  		if (err < 0) {
>  			dev_err(dev, "failed to enable CML clock: %d\n", err);
> -			return err;
> +			goto afi_clk_disable;
>  		}
>  	}
>  
>  	err = clk_prepare_enable(pcie->pll_e);
>  	if (err < 0) {
>  		dev_err(dev, "failed to enable PLLE clock: %d\n", err);
> -		return err;
> +		goto cml_clk_disable;
>  	}
>  
> +	reset_control_deassert(pcie->afi_rst);
> +
>  	return 0;
> +
> +cml_clk_disable:
> +	if (soc->has_cml_clk)
> +		clk_disable_unprepare(pcie->cml_clk);
> +afi_clk_disable:
> +	clk_disable_unprepare(pcie->afi_clk);
> +powergate:
> +	if (!dev->pm_domain)
> +		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
> +regulator_disable:
> +	regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
> +	return err;
>  }
>  
>  static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
> @@ -2108,7 +2102,12 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>  			 port->index, port->lanes);
>  
>  		tegra_pcie_port_enable(port);
> +	}
> +
> +	/* Start LTSSM from Tegra side */
> +	reset_control_deassert(pcie->pcie_xrst);
>  
> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
>  		if (tegra_pcie_port_check_link(port))
>  			continue;
>  
> @@ -2123,6 +2122,8 @@ static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
>  {
>  	struct tegra_pcie_port *port, *tmp;
>  
> +	reset_control_assert(pcie->pcie_xrst);
> +
>  	list_for_each_entry_safe(port, tmp, &pcie->ports, list)
>  		tegra_pcie_port_disable(port);
>  }
> @@ -2472,6 +2473,9 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
>  
>  	tegra_pcie_disable_ports(pcie);
>  
> +	reset_control_assert(pcie->pex_rst);
> +	clk_disable_unprepare(pcie->pex_clk);
> +
>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>  		tegra_pcie_disable_msi(pcie);
>  
> @@ -2501,10 +2505,19 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>  		tegra_pcie_enable_msi(pcie);
>  
> +	err = clk_prepare_enable(pcie->pex_clk);
> +	if (err) {
> +		dev_err(dev, "failed to enable PEX clock: %d\n", err);
> +		goto disable_controller;
> +	}
> +	reset_control_deassert(pcie->pex_rst);
> +
>  	tegra_pcie_enable_ports(pcie);
>  
>  	return 0;
>  
> +disable_controller:
> +	tegra_pcie_disable_controller(pcie);
>  poweroff:
>  	tegra_pcie_power_off(pcie);
>  

There's quite a bit going on in this patch in general and I find it hard
to review because not all the changes seem related to what you described
in the commit message.

Can you perhaps try to split out the error cleanup changes into a
separate patch where it makes sense? It seems to me like at least for
tegra_pcie_power_on() we're currently missing all of the cleanup code.
You could make that a preparatory patch that goes before this particular
patch, which will hopefully make this patch easier to review.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/30] PCI: tegra: Move REFCLK pad settings out of phy_power_on()
  2019-04-11 17:03 ` [PATCH 03/30] PCI: tegra: Move REFCLK pad settings out of phy_power_on() Manikanta Maddireddy
@ 2019-04-15 11:06   ` Thierry Reding
  2019-04-15 14:20     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:06 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2741 bytes --]

On Thu, Apr 11, 2019 at 10:33:28PM +0530, Manikanta Maddireddy wrote:
> In Tegra186 PHY programming is done by BPMP-FW, so PHY calls are skipped
> in driver. REFCLK pad settings are independent of PHY and should be
> programmed by driver. So move REFCLK pad settings out of phy_power_on().
> These pad settings tune REFCLK peak to peak amplitude.
> 
> Fixes: cf5d31801278 ("PCI: tegra: Program PADS_REFCLK_CFG* always, not
> just on legacy SoCs")
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 0bf270bcea34..a61ce9d475b4 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -852,7 +852,6 @@ static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port)
>  static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
>  {
>  	struct device *dev = pcie->dev;
> -	const struct tegra_pcie_soc *soc = pcie->soc;
>  	struct tegra_pcie_port *port;
>  	int err;
>  
> @@ -878,12 +877,6 @@ static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
>  		}
>  	}
>  
> -	/* Configure the reference clock driver */
> -	pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
> -
> -	if (soc->num_ports > 2)
> -		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
> -
>  	return 0;
>  }
>  
> @@ -2092,11 +2085,24 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
>  	return false;
>  }
>  
> +static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
> +{
> +	const struct tegra_pcie_soc *soc = pcie->soc;
> +
> +	/* Configure the reference clock driver */
> +	pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
> +
> +	if (soc->num_ports > 2)
> +		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
> +}
> +
>  static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>  {
>  	struct device *dev = pcie->dev;
>  	struct tegra_pcie_port *port, *tmp;
>  
> +	tegra_pcie_apply_pad_settings(pcie);
> +
>  	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
>  		dev_info(dev, "probing port %u, using %u lanes\n",
>  			 port->index, port->lanes);

This also seems to move the programming of these registers to a
different point in time. Was that intentional? If so, please mention it
in the commit message and describe why that's necessary.

If that was not intentional, it seems like the right place to call this
would be right after the call to tegra_pcie_enable_controller() in
tegra_pcie_pm_resume().

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support
  2019-04-11 17:03 ` [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support Manikanta Maddireddy
@ 2019-04-15 11:21   ` Thierry Reding
  2019-04-15 14:47     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:21 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 5219 bytes --]

On Thu, Apr 11, 2019 at 10:33:29PM +0530, Manikanta Maddireddy wrote:
> Tegra124, 132, 210 and 186 support Gen2 link speed. After PCIe link is up
> in Gen1, set target link speed as Gen2 and retrain link. Link switches to
> Gen2 speed if Gen2 capable end point is connected, else link stays in Gen1.
> 
> Per PCIe 4.0r0.9 sec 7.6.3.7 implementation note, driver need to wait for
> PCIe LTSSM to come back from recovery before retraining the link.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 61 ++++++++++++++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index a61ce9d475b4..6ccda82735f8 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -191,6 +191,8 @@
>  #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
>  #define  RP_LINK_CONTROL_STATUS_LINKSTAT_MASK	0x3fff0000
>  
> +#define RP_LINK_CONTROL_STATUS_2		0x000000b0
> +
>  #define PADS_CTL_SEL		0x0000009c
>  
>  #define PADS_CTL		0x000000a0
> @@ -2096,6 +2098,62 @@ static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
>  		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
>  }
>  
> +#define LINK_RETRAIN_TIMEOUT 100000

This is oddly placed. I think this should go somewhere near the top of
the file. We already have PME_ACK_TIMEOUT there.

But to be honest, I wouldn't even bother with the #define. This is used
exactly twice and is much longer to type than the actual number.

> +
> +static void tegra_pcie_change_link_speed(struct tegra_pcie *pcie)
> +{
> +	struct device *dev = pcie->dev;
> +	struct tegra_pcie_port *port, *tmp;
> +	ktime_t deadline;
> +	u32 val;

The driver uses u32 value for register values elsewhere. It'd be good to
stay consistent with that convention.

> +
> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> +		/*
> +		 * Link Capabilities 2 register is hardwired to 0 in Tegra,
> +		 * so no need to read it before setting target speed.
> +		 */
> +		val = readl(port->base + RP_LINK_CONTROL_STATUS_2);
> +		val &= ~PCI_EXP_LNKSTA_CLS;
> +		val |= PCI_EXP_LNKSTA_CLS_5_0GB;
> +		writel(val, port->base + RP_LINK_CONTROL_STATUS_2);

The comment says there's no need to read the register, but then the code
goes on and reads it before modifying it.

That's the first thing that came to my mind. Then I realized that the
code doesn't actually do anything with the Link Capabilities 2 register
at all. So what's the deal here? Is it that the Link Capabilities 2
register being hardwired to 0 means that we can change the target speed?
Your comment needs to explain more clearly how it relates to the code.

> +
> +		/*
> +		 * Poll until link comes back from recovery to avoid race
> +		 * condition.
> +		 */
> +		deadline = ktime_add_us(ktime_get(), LINK_RETRAIN_TIMEOUT);
> +		for (;;) {
> +			val = readl(port->base + RP_LINK_CONTROL_STATUS);
> +			if (!(val & PCI_EXP_LNKSTA_LT))
> +				break;
> +			if (ktime_after(ktime_get(), deadline))
> +				break;
> +			usleep_range(2000, 3000);
> +		}

This would be more compact when written as a while loop. Also I think
it's more readable to make the !(...) an explicit comparison. Finally,
use whitespace to improve readability. The above looks very cluttered
and, in my opinion, makes the code difficult to read. Something like
the below is much easier to read, in my opinion:

		while (ktime_before(ktime_get(), deadline)) {
			value = readl(port->base + RP_LINK_CONTROL_STATUS);
			if ((value & PCI_EXP_LNKSTA_LT) == 0)
				break;

			usleep_range(2000, 3000);
		}

> +		if (val & PCI_EXP_LNKSTA_LT)
> +			dev_err(dev, "PCIe port %u link is still in recovery\n",
> +				port->index);

Since you're continuing execution, perhaps make this dev_warn()?

> +
> +		/* Retrain the link */
> +		val = readl(port->base + RP_LINK_CONTROL_STATUS);
> +		val |= PCI_EXP_LNKCTL_RL;
> +		writel(val, port->base + RP_LINK_CONTROL_STATUS);
> +
> +		deadline = ktime_add_us(ktime_get(), LINK_RETRAIN_TIMEOUT);
> +		for (;;) {
> +			val = readl(port->base + RP_LINK_CONTROL_STATUS);
> +			if (!(val & PCI_EXP_LNKSTA_LT))
> +				break;
> +			if (ktime_after(ktime_get(), deadline))
> +				break;
> +			usleep_range(2000, 3000);
> +		}

Same comments as above.

> +		if (val & PCI_EXP_LNKSTA_LT)
> +			dev_err(dev, "link retrain of PCIe port %u failed\n",
> +				port->index);
> +	}

Most of the error messages in this file are of the form:

	"failed to ..."

Perhaps make this:

	"failed to retrain link of port %u\n"

for consistency?

Thierry

> +}
> +
>  static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>  {
>  	struct device *dev = pcie->dev;
> @@ -2122,6 +2180,9 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>  		tegra_pcie_port_disable(port);
>  		tegra_pcie_port_free(port);
>  	}
> +
> +	if (pcie->soc->has_gen2)
> +		tegra_pcie_change_link_speed(pcie);
>  }
>  
>  static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 05/30] PCI: tegra: Advertise PCIe Advanced Error Reporting (AER) capability
  2019-04-11 17:03 ` [PATCH 05/30] PCI: tegra: Advertise PCIe Advanced Error Reporting (AER) capability Manikanta Maddireddy
@ 2019-04-15 11:23   ` Thierry Reding
  2019-04-15 14:49     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:23 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2053 bytes --]

On Thu, Apr 11, 2019 at 10:33:30PM +0530, Manikanta Maddireddy wrote:
> Default root port setting hides AER capability. This patch enables the
> advertisement of AER capability by root port.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 6ccda82735f8..9ff1a0e2797f 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -180,6 +180,9 @@
>  #define RP_VEND_XP	0x00000f00
>  #define  RP_VEND_XP_DL_UP	(1 << 30)
>  
> +#define RP_VEND_CTL1	0x00000f48
> +#define  RP_VEND_CTL1_ERPT	(1 << 13)
> +
>  #define RP_VEND_CTL2 0x00000fa8
>  #define  RP_VEND_CTL2_PCA_ENABLE (1 << 7)
>  
> @@ -478,6 +481,16 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
>  	afi_writel(port->pcie, value, ctrl);
>  }
>  
> +static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)

Why not call this tegra_pcie_enable_aer()? Are you planning on adding a
lot more overrides to this function? If there aren't too many, you may
want to just have one small function per feature and drop the comment in
the function body.

If there's going to be a lot, the above seems okay.

Thierry

> +{
> +	u32 value;
> +
> +	/* Enable AER capability */
> +	value = readl(port->base + RP_VEND_CTL1);
> +	value |= RP_VEND_CTL1_ERPT;
> +	writel(value, port->base + RP_VEND_CTL1);
> +}
> +
>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>  {
>  	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
> @@ -502,6 +515,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>  		value |= RP_VEND_CTL2_PCA_ENABLE;
>  		writel(value, port->base + RP_VEND_CTL2);
>  	}
> +
> +	tegra_pcie_enable_rp_features(port);
>  }
>  
>  static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 06/30] PCI: tegra: Program UPHY electrical settings for Tegra210
  2019-04-11 17:03 ` [PATCH 06/30] PCI: tegra: Program UPHY electrical settings for Tegra210 Manikanta Maddireddy
@ 2019-04-15 11:29   ` Thierry Reding
  2019-04-15 14:55     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:29 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 6253 bytes --]

On Thu, Apr 11, 2019 at 10:33:31PM +0530, Manikanta Maddireddy wrote:
> UPHY electrical programming guidelines are documented in Tegra210 TRM.
> Program these electrical settings for proper eye diagram in Gen1 and Gen2
> link speeds.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 100 +++++++++++++++++++++++++++++
>  1 file changed, 100 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 9ff1a0e2797f..a377245d254d 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -177,6 +177,32 @@
>  
>  #define AFI_PEXBIAS_CTRL_0		0x168
>  
> +#define RP_ECTL_2_R1	0x00000e84

> +#define  RP_ECTL_2_R1_RX_CTLE_1C_MASK		0xffff
> +
> +#define RP_ECTL_4_R1	0x00000e8c
> +#define  RP_ECTL_4_R1_RX_CDR_CTRL_1C_MASK	(0xffff << 16)
> +#define  RP_ECTL_4_R1_RX_CDR_CTRL_1C_SHIFT	16
> +
> +#define RP_ECTL_5_R1	0x00000e90
> +#define  RP_ECTL_5_R1_RX_EQ_CTRL_L_1C_MASK	0xffffffff
> +
> +#define RP_ECTL_6_R1	0x00000e94
> +#define  RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK	0xffffffff
> +
> +#define RP_ECTL_2_R2	0x00000ea4
> +#define  RP_ECTL_2_R2_RX_CTLE_1C_MASK	0xffff
> +
> +#define RP_ECTL_4_R2	0x00000eac
> +#define  RP_ECTL_4_R2_RX_CDR_CTRL_1C_MASK	(0xffff << 16)
> +#define  RP_ECTL_4_R2_RX_CDR_CTRL_1C_SHIFT	16
> +
> +#define RP_ECTL_5_R2	0x00000eb0
> +#define  RP_ECTL_5_R2_RX_EQ_CTRL_L_1C_MASK	0xffffffff
> +
> +#define RP_ECTL_6_R2	0x00000eb4
> +#define  RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK	0xffffffff
> +
>  #define RP_VEND_XP	0x00000f00
>  #define  RP_VEND_XP_DL_UP	(1 << 30)
>  
> @@ -265,6 +291,19 @@ struct tegra_pcie_soc {
>  	bool has_gen2;
>  	bool force_pca_enable;
>  	bool program_uphy;
> +	struct {
> +		struct {
> +			u32 rp_ectl_2_r1;
> +			u32 rp_ectl_4_r1;
> +			u32 rp_ectl_5_r1;
> +			u32 rp_ectl_6_r1;
> +			u32 rp_ectl_2_r2;
> +			u32 rp_ectl_4_r2;
> +			u32 rp_ectl_5_r2;
> +			u32 rp_ectl_6_r2;
> +		} regs;
> +		bool enable;
> +	} ectl;
>  };
>  
>  static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
> @@ -491,6 +530,52 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
>  	writel(value, port->base + RP_VEND_CTL1);
>  }
>  
> +static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
> +{
> +	const struct tegra_pcie_soc *soc = port->pcie->soc;
> +	u32 val;

u32 value for consistency.

> +
> +	val = readl(port->base + RP_ECTL_2_R1);
> +	val &= ~RP_ECTL_2_R1_RX_CTLE_1C_MASK;
> +	val |= soc->ectl.regs.rp_ectl_2_r1;
> +	writel(val, port->base + RP_ECTL_2_R1);
> +
> +	val = readl(port->base + RP_ECTL_4_R1);
> +	val &= ~RP_ECTL_4_R1_RX_CDR_CTRL_1C_MASK;
> +	val |= soc->ectl.regs.rp_ectl_4_r1 << RP_ECTL_4_R1_RX_CDR_CTRL_1C_SHIFT;
> +	writel(val, port->base + RP_ECTL_4_R1);
> +
> +	val = readl(port->base + RP_ECTL_5_R1);
> +	val &= ~RP_ECTL_5_R1_RX_EQ_CTRL_L_1C_MASK;
> +	val |= soc->ectl.regs.rp_ectl_5_r1;
> +	writel(val, port->base + RP_ECTL_5_R1);
> +
> +	val = readl(port->base + RP_ECTL_6_R1);
> +	val &= ~RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK;
> +	val |= soc->ectl.regs.rp_ectl_6_r1;
> +	writel(val, port->base + RP_ECTL_6_R1);
> +
> +	val = readl(port->base + RP_ECTL_2_R2);
> +	val &= ~RP_ECTL_2_R2_RX_CTLE_1C_MASK;
> +	val |= soc->ectl.regs.rp_ectl_2_r2;
> +	writel(val, port->base + RP_ECTL_2_R2);
> +
> +	val = readl(port->base + RP_ECTL_4_R2);
> +	val &= ~RP_ECTL_4_R2_RX_CDR_CTRL_1C_MASK;
> +	val |= soc->ectl.regs.rp_ectl_4_r2 << RP_ECTL_4_R2_RX_CDR_CTRL_1C_SHIFT;
> +	writel(val, port->base + RP_ECTL_4_R2);
> +
> +	val = readl(port->base + RP_ECTL_5_R2);
> +	val &= ~RP_ECTL_5_R2_RX_EQ_CTRL_L_1C_MASK;
> +	val |= soc->ectl.regs.rp_ectl_5_r2;
> +	writel(val, port->base + RP_ECTL_5_R2);
> +
> +	val = readl(port->base + RP_ECTL_6_R2);
> +	val &= ~RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK;
> +	val |= soc->ectl.regs.rp_ectl_6_r2;
> +	writel(val, port->base + RP_ECTL_6_R2);

There are nice macros that help with this nowadays. See the FIELD_*
macros in include/linux/bitfield.h. However, the above is consistent
with the rest of the driver, so feel free to leave this as-is.

> +}
> +
>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>  {
>  	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
> @@ -517,6 +602,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>  	}
>  
>  	tegra_pcie_enable_rp_features(port);
> +	if (soc->ectl.enable)

An empty line above would help declutter this.

> +		tegra_pcie_program_ectl_settings(port);
>  }
>  
>  static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
> @@ -2229,6 +2316,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>  	.has_gen2 = false,
>  	.force_pca_enable = false,
>  	.program_uphy = true,
> +	.ectl.enable = false,
>  };
>  
>  static const struct tegra_pcie_port_soc tegra30_pcie_ports[] = {
> @@ -2252,6 +2340,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>  	.has_gen2 = false,
>  	.force_pca_enable = false,
>  	.program_uphy = true,
> +	.ectl.enable = false,
>  };
>  
>  static const struct tegra_pcie_soc tegra124_pcie = {
> @@ -2268,6 +2357,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>  	.has_gen2 = true,
>  	.force_pca_enable = false,
>  	.program_uphy = true,
> +	.ectl.enable = false,
>  };
>  
>  static const struct tegra_pcie_soc tegra210_pcie = {
> @@ -2284,6 +2374,15 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>  	.has_gen2 = true,
>  	.force_pca_enable = true,
>  	.program_uphy = true,
> +	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
> +	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
> +	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
> +	.ectl.regs.rp_ectl_6_r1 = 0x00000001,
> +	.ectl.regs.rp_ectl_2_r2 = 0x0000008f,
> +	.ectl.regs.rp_ectl_4_r2 = 0x000000c7,
> +	.ectl.regs.rp_ectl_5_r2 = 0x55010000,
> +	.ectl.regs.rp_ectl_6_r2 = 0x00000001,
> +	.ectl.enable = true,

This should be:

	.ectl = {
		.regs = {
			...
		}
		.enable = true;
	},

Do these parameters never differ between board layouts? Are they really
fixed per SoC generation?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 07/30] PCI: tegra: Enable opportunistic update FC and ACK
  2019-04-11 17:03 ` [PATCH 07/30] PCI: tegra: Enable opportunistic update FC and ACK Manikanta Maddireddy
@ 2019-04-15 11:30   ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:30 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 556 bytes --]

On Thu, Apr 11, 2019 at 10:33:32PM +0530, Manikanta Maddireddy wrote:
> Enable opportunistic update FC and ACK to allow data link layer send
> pending ACKs and update FC packets when link is idle instead of waiting
> for timers to expire. This improves the PCIe performance due to better
> utilization of PCIe bandwidth.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 08/30] PCI: tegra: Disable AFI dynamic clock gating
  2019-04-11 17:03 ` [PATCH 08/30] PCI: tegra: Disable AFI dynamic clock gating Manikanta Maddireddy
@ 2019-04-15 11:32   ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:32 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 697 bytes --]

On Thu, Apr 11, 2019 at 10:33:33PM +0530, Manikanta Maddireddy wrote:
> Outstanding write counter in AFI is used to generate idle signal to
> dynamically gate the AFI clock. When there are 32 outstanding writes
> from AFI to memory, the outstanding write counter overflows and
> indicates that there are "0" outstanding write transactions.
> 
> When memory controller is under heavy load, write completions to AFI
> gets delayed and AFI write counter overflows. This causes AFI clock gating
> even when there are outstanding transactions towards memory controller
> resutling in system hang.

s/resutling/resulting/

With that fixed:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 09/30] PCI: tegra: Process pending DLL transactions before entering L1 or L2
  2019-04-11 17:03 ` [PATCH 09/30] PCI: tegra: Process pending DLL transactions before entering L1 or L2 Manikanta Maddireddy
@ 2019-04-15 11:33   ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:33 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 461 bytes --]

On Thu, Apr 11, 2019 at 10:33:34PM +0530, Manikanta Maddireddy wrote:
> PM message are truncated while entering L1 or L2, which is resulting in
> receiver errors. Set the required bit to finish processing DLLP before
> link enter L1 or L2.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-12 14:50       ` Bjorn Helgaas
@ 2019-04-15 11:36         ` Manikanta Maddireddy
  2019-04-15 13:45           ` Thierry Reding
  2019-04-15 14:04           ` Bjorn Helgaas
  0 siblings, 2 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 11:36 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree,
	Jingoo Han, Gustavo Pimentel, Ley Foon Tan, Michal Simek


On 12-Apr-19 8:20 PM, Bjorn Helgaas wrote:
> [+cc Jingoo, Gustavo (dwc maintainers), Ley (altera), Michal (xilinx)]
>
> On Fri, Apr 12, 2019 at 12:30:22PM +0530, Manikanta Maddireddy wrote:
>> On 12-Apr-19 1:45 AM, Bjorn Helgaas wrote:
>>> On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
>>>> Add PCIe link up check in config read and write callback functions
>>>> before accessing endpoint config registers.
>>>>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
>>>>  				  int where, int size, u32 *value)
>>>>  {
>>>> +	struct tegra_pcie *pcie = bus->sysdata;
>>>> +	struct pci_dev *bridge;
>>>> +	struct tegra_pcie_port *port;
>>>> +
>>>>  	if (bus->number == 0)
>>>>  		return pci_generic_config_read32(bus, devfn, where, size,
>>>>  						 value);
>>>>  
>>>> +	bridge = pcie_find_root_port(bus->self);
>>>> +
>>>> +	list_for_each_entry(port, &pcie->ports, list)
>>>> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
>>>> +			break;
>>>> +
>>>> +	/* If there is no link, then there is no device */
>>>> +	if (!tegra_pcie_link_status(port)) {
>>> This is racy and you should avoid it if possible.  The link could go down
>>> between calling tegra_pcie_link_status() and issuing the config read/write.
>>>
>>> If your driver is to be reliable, it must be able to handle any bad
>>> consequence of issuing that config read/write anyway, so I think it's
>>> better if it doesn't even bother checking whether the link is up.
>> This change is made based on similar check present in dwc driver
>> dw_pcie_valid_device(), reasons for making this change in Tegra might
>> differ dwc.
> Yes, you won't be surprised to learn that I don't like the similar
> checks in dwc, altera, xilinx, and xilinx-nwl either :)  I raise this
> issue every time I see it, but I can't remember if I've mentioned dwc
> specifically.
>
> We need to either eradicate this pattern of checking for link up, or
> include a comment about why it is absolutely necessary.

This patch is created to address below scenario in our downstream kernel,
1) Our platform has WiFi on one slot and GPU in another.
2) During WiFi OFF, link is put in L2 and it goes through hot reset
when turning ON WiFi (since Tegra doesn't support hot-plug).
3) Whenever x11 server is started it scans the PCIe bus for video devices.
Here PCIe configuration registers of all devices are read to find out
all available video devices.
4) If "x11 server" started with WiFi OFF, then we are seeing "response
decoding error"(Tegra AFI module specific error).

Best solution we came up with is to have link up check in config access
callback functions.

>
>> Intention here is to reduce the number of AER errors when device is
>> falling off the bus or going through hot reset. So racy condition here is
>> OK
> I'm not convinced about this.  The issues you mention need to be
> solved in a generic way, not a tegra-specific way.
>
> We don't want to end up with code that silently avoids the config
> access 99.99% of the time, but once in a blue moon, we lose the race
> (the device stops responding after we've determined the link is up)
> and the access causes a mysterious AER error that we have no way to
> debug.
>
>>>> +		*value = 0xffffffff;
>>>> +		return PCIBIOS_DEVICE_NOT_FOUND;
>>>> +	}
>>>> +
>>>>  	return pci_generic_config_read(bus, devfn, where, size, value);
>>>>  }

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 10/30] PCI: tegra: Enable PCIe xclk clock clamping
  2019-04-11 17:03 ` [PATCH 10/30] PCI: tegra: Enable PCIe xclk clock clamping Manikanta Maddireddy
@ 2019-04-15 11:37   ` Thierry Reding
  2019-04-15 14:58     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:37 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 4565 bytes --]

On Thu, Apr 11, 2019 at 10:33:35PM +0530, Manikanta Maddireddy wrote:
> Enable xclk clock clamping when entering L1. Clamp threshold will
> determine the time spent waiting for clock module to turn on xclk after
> signalling it. Default threshold value in Tegra124 and 210 is not enough

Perhaps spell out Tegra210.

> to turn ON xlck clock. Increase the clamp threshold to meet the clock

s/ON/on/, s/xlck/xclk/

> module timing in Tegra124 and 210, default threshold value is sufficient

Spell out Tegra210. Also, maybe make the part after the , a separate
sentence? And maybe also mention Tegra20 and Tegra30.

Thierry

> in Tegra186.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 28 ++++++++++++++++++++++++++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index e40df52e46a7..f785ecae2f6b 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -219,8 +219,14 @@
>  #define  RP_VEND_CTL2_PCA_ENABLE (1 << 7)
>  
>  #define RP_PRIV_MISC	0x00000fe0
> -#define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0)
> -#define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0)
> +#define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT		(0xe << 0)
> +#define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT		(0xf << 0)
> +#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD_MASK	(0x7f << 16)
> +#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD		(0xf << 16)
> +#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_ENABLE		(1 << 23)
> +#define  RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD_MASK	(0x7f << 24)
> +#define  RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD		(0xf << 24)
> +#define  RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE		(1 << 31)
>  
>  #define RP_LINK_CONTROL_STATUS			0x00000090
>  #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
> @@ -297,6 +303,7 @@ struct tegra_pcie_soc {
>  	bool has_gen2;
>  	bool force_pca_enable;
>  	bool program_uphy;
> +	bool update_clamp_threshold;
>  	struct {
>  		struct {
>  			u32 rp_ectl_2_r1;
> @@ -528,6 +535,7 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
>  
>  static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
>  {
> +	const struct tegra_pcie_soc *soc = port->pcie->soc;
>  	u32 value;
>  
>  	/* Enable AER capability */
> @@ -548,6 +556,17 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
>  	value = readl(port->base + RP_VEND_XP_BIST);
>  	value |= RP_VEND_XP_BIST_GOTO_L1_L2_AFTER_DLLP_DONE;
>  	writel(value, port->base + RP_VEND_XP_BIST);
> +
> +	value = readl(port->base + RP_PRIV_MISC);
> +	value |= RP_PRIV_MISC_CTLR_CLK_CLAMP_ENABLE;
> +	value |= RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE;
> +	if (soc->update_clamp_threshold) {

Blank line between the above two.

> +		value &= ~(RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD_MASK |
> +				RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD_MASK);
> +		value |= RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD |
> +			RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD;
> +	}
> +	writel(value, port->base + RP_PRIV_MISC);

Ditto.

Thierry

>  }
>  
>  static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
> @@ -2337,6 +2356,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>  	.has_gen2 = false,
>  	.force_pca_enable = false,
>  	.program_uphy = true,
> +	.update_clamp_threshold = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2361,6 +2381,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>  	.has_gen2 = false,
>  	.force_pca_enable = false,
>  	.program_uphy = true,
> +	.update_clamp_threshold = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2378,6 +2399,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>  	.has_gen2 = true,
>  	.force_pca_enable = false,
>  	.program_uphy = true,
> +	.update_clamp_threshold = true,
>  	.ectl.enable = false,
>  };
>  
> @@ -2395,6 +2417,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>  	.has_gen2 = true,
>  	.force_pca_enable = true,
>  	.program_uphy = true,
> +	.update_clamp_threshold = true,
>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
> @@ -2427,6 +2450,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>  	.has_gen2 = true,
>  	.force_pca_enable = false,
>  	.program_uphy = false,
> +	.update_clamp_threshold = false,
>  	.ectl.enable = false,
>  };
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 11/30] PCI: tegra: Increase the deskew retry time
  2019-04-11 17:03 ` [PATCH 11/30] PCI: tegra: Increase the deskew retry time Manikanta Maddireddy
@ 2019-04-15 11:39   ` Thierry Reding
  2019-04-15 14:58     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:39 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 3838 bytes --]

On Thu, Apr 11, 2019 at 10:33:36PM +0530, Manikanta Maddireddy wrote:
> Some times link speed change from Gen2 to Gen1 fails due to instability

"Sometimes"

> in deskew logic on lane-0 in Tegra210. Increase the deskew retry time
> to resolve this issue.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index f785ecae2f6b..9e61da68cfae 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -209,6 +209,10 @@
>  #define  RP_VEND_XP_OPPORTUNISTIC_ACK		(1 << 27)
>  #define  RP_VEND_XP_OPPORTUNISTIC_UPDATEFC	(1 << 28)
>  
> +#define RP_VEND_CTL0	0x00000f44
> +#define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK	(0xf << 12)
> +#define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH	(0x9 << 12)
> +
>  #define RP_VEND_CTL1	0x00000f48
>  #define  RP_VEND_CTL1_ERPT	(1 << 13)
>  
> @@ -304,6 +308,7 @@ struct tegra_pcie_soc {
>  	bool force_pca_enable;
>  	bool program_uphy;
>  	bool update_clamp_threshold;
> +	bool program_deskew_time;
>  	struct {
>  		struct {
>  			u32 rp_ectl_2_r1;
> @@ -615,6 +620,23 @@ static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
>  	writel(val, port->base + RP_ECTL_6_R2);
>  }
>  
> +static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
> +{
> +	const struct tegra_pcie_soc *soc = port->pcie->soc;
> +	u32 value;
> +
> +	/*
> +	 * Tune deskew retry time to take care of Gen2 -> Gen1
> +	 * link speed change error in corner cases
> +	 */
> +	if (soc->program_deskew_time) {
> +		value = readl(port->base + RP_VEND_CTL0);
> +		value &= ~RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK;
> +		value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH;
> +		writel(value, port->base + RP_VEND_CTL0);
> +	}
> +}
> +
>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>  {
>  	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
> @@ -643,6 +665,7 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>  	tegra_pcie_enable_rp_features(port);
>  	if (soc->ectl.enable)
>  		tegra_pcie_program_ectl_settings(port);
> +	tegra_pcie_apply_sw_fixup(port);

Blank line between the above two for readability.

Thierry

>  }
>  
>  static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
> @@ -2357,6 +2380,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>  	.force_pca_enable = false,
>  	.program_uphy = true,
>  	.update_clamp_threshold = false,
> +	.program_deskew_time = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2382,6 +2406,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>  	.force_pca_enable = false,
>  	.program_uphy = true,
>  	.update_clamp_threshold = false,
> +	.program_deskew_time = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2400,6 +2425,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>  	.force_pca_enable = false,
>  	.program_uphy = true,
>  	.update_clamp_threshold = true,
> +	.program_deskew_time = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2418,6 +2444,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>  	.force_pca_enable = true,
>  	.program_uphy = true,
>  	.update_clamp_threshold = true,
> +	.program_deskew_time = true,
>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
> @@ -2451,6 +2478,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>  	.force_pca_enable = false,
>  	.program_uphy = false,
>  	.update_clamp_threshold = false,
> +	.program_deskew_time = false,
>  	.ectl.enable = false,
>  };
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations
  2019-04-12  5:59     ` Manikanta Maddireddy
@ 2019-04-15 11:41       ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:41 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: Bjorn Helgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 1658 bytes --]

On Fri, Apr 12, 2019 at 11:29:35AM +0530, Manikanta Maddireddy wrote:
> 
> On 12-Apr-19 1:31 AM, Bjorn Helgaas wrote:
> > On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote:
> >> The logic which blocks read requests till AFI gets ACK for all outstanding
> >> MC writes does not behave correctly when number of outstanding write
> >> becomes more than 32 in Tegra124 and 132.
> >>
> >> SW fixup to prevent this issue is to limit outstanding posted writes and
> >> tweak updateFC timer threshold.
> >>
> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> >> @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
> >>  	.program_uphy = true,
> >>  	.update_clamp_threshold = false,
> >>  	.program_deskew_time = false,
> >> +	.raw_violation_fixup = false,
> >>  	.ectl.enable = false,
> > It doesn't really matter either way, but you don't *have* to
> > initialize all these flags to "false" since that's the default for
> > uninitialized fields in static structs like these.  If you left them
> > out, the structs would only contain the "true" items, and it'd be
> > easier to see what's special about each SoC.
> 
> SoC flags are explicitly set false if not supported, I am following
> same existing coding style in this driver. Maybe the intention here is
> to convey what is not supported by a particular SoC without going
> through soc struct definition.

Yes, this was originally done on purpose. I think it's good to follow
the existing convention, unless Bjorn feels strongly about it.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations
  2019-04-11 17:03 ` [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations Manikanta Maddireddy
  2019-04-11 20:01   ` Bjorn Helgaas
@ 2019-04-15 11:45   ` Thierry Reding
  2019-04-15 15:02     ` Manikanta Maddireddy
  1 sibling, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:45 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 4892 bytes --]

On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote:
> The logic which blocks read requests till AFI gets ACK for all outstanding
> MC writes does not behave correctly when number of outstanding write
> becomes more than 32 in Tegra124 and 132.
> 
> SW fixup to prevent this issue is to limit outstanding posted writes and
> tweak updateFC timer threshold.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 34 ++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 9e61da68cfae..b74408eeb367 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -178,6 +178,13 @@
>  
>  #define AFI_PEXBIAS_CTRL_0		0x168
>  
> +#define RP_PRIV_XP_DL		0x00000494
> +#define  RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD	(0x1ff << 1)
> +
> +#define RP_RX_HDR_LIMIT		0x00000e00
> +#define  RP_RX_HDR_LIMIT_PW_MASK	(0xff << 8)
> +#define  RP_RX_HDR_LIMIT_PW		(0x0e << 8)
> +
>  #define RP_ECTL_2_R1	0x00000e84
>  #define  RP_ECTL_2_R1_RX_CTLE_1C_MASK		0xffff
>  
> @@ -208,6 +215,7 @@
>  #define  RP_VEND_XP_DL_UP			(1 << 30)
>  #define  RP_VEND_XP_OPPORTUNISTIC_ACK		(1 << 27)
>  #define  RP_VEND_XP_OPPORTUNISTIC_UPDATEFC	(1 << 28)
> +#define  RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK	(0xff << 18)
>  
>  #define RP_VEND_CTL0	0x00000f44
>  #define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK	(0xf << 12)
> @@ -300,6 +308,7 @@ struct tegra_pcie_soc {
>  	u32 tx_ref_sel;
>  	u32 pads_refclk_cfg0;
>  	u32 pads_refclk_cfg1;
> +	u32 update_fc_val;

Shouldn't this be something like "update_fc_threshold" since the mask
defined above is for a field named UPDATE_FC_THRESHOLD?

>  	bool has_pex_clkreq_en;
>  	bool has_pex_bias_ctrl;
>  	bool has_intr_prsnt_sense;
> @@ -309,6 +318,7 @@ struct tegra_pcie_soc {
>  	bool program_uphy;
>  	bool update_clamp_threshold;
>  	bool program_deskew_time;
> +	bool raw_violation_fixup;
>  	struct {
>  		struct {
>  			u32 rp_ectl_2_r1;
> @@ -635,6 +645,23 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>  		value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH;
>  		writel(value, port->base + RP_VEND_CTL0);
>  	}
> +
> +	/* Fixup for read after write violation in T124 & T132 platforms */

No need to mention the SoC generations here, it's already implied by the
per-SoC flag.

Thierry

> +	if (soc->raw_violation_fixup) {
> +		value = readl(port->base + RP_RX_HDR_LIMIT);
> +		value &= ~RP_RX_HDR_LIMIT_PW_MASK;
> +		value |= RP_RX_HDR_LIMIT_PW;
> +		writel(value, port->base + RP_RX_HDR_LIMIT);
> +
> +		value = readl(port->base + RP_PRIV_XP_DL);
> +		value |= RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD;
> +		writel(value, port->base + RP_PRIV_XP_DL);
> +
> +		value = readl(port->base + RP_VEND_XP);
> +		value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK;
> +		value |= soc->update_fc_val;
> +		writel(value, port->base + RP_VEND_XP);
> +	}
>  }
>  
>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>  	.program_uphy = true,
>  	.update_clamp_threshold = false,
>  	.program_deskew_time = false,
> +	.raw_violation_fixup = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>  	.program_uphy = true,
>  	.update_clamp_threshold = false,
>  	.program_deskew_time = false,
> +	.raw_violation_fixup = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2417,6 +2446,8 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>  	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
>  	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
>  	.pads_refclk_cfg0 = 0x44ac44ac,
> +	/* FC threshold is bit[25:18] */
> +	.update_fc_val = 0x03fc0000,



>  	.has_pex_clkreq_en = true,
>  	.has_pex_bias_ctrl = true,
>  	.has_intr_prsnt_sense = true,
> @@ -2426,6 +2457,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>  	.program_uphy = true,
>  	.update_clamp_threshold = true,
>  	.program_deskew_time = false,
> +	.raw_violation_fixup = true,
>  	.ectl.enable = false,
>  };
>  
> @@ -2445,6 +2477,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>  	.program_uphy = true,
>  	.update_clamp_threshold = true,
>  	.program_deskew_time = true,
> +	.raw_violation_fixup = false,
>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
> @@ -2479,6 +2512,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>  	.program_uphy = false,
>  	.update_clamp_threshold = false,
>  	.program_deskew_time = false,
> +	.raw_violation_fixup = false,
>  	.ectl.enable = false,
>  };
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 13/30] PCI: tegra: Update flow control threshold in Tegra210
  2019-04-11 17:03 ` [PATCH 13/30] PCI: tegra: Update flow control threshold in Tegra210 Manikanta Maddireddy
@ 2019-04-15 11:47   ` Thierry Reding
  2019-04-15 15:05     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:47 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 3234 bytes --]

On Thu, Apr 11, 2019 at 10:33:38PM +0530, Manikanta Maddireddy wrote:
> Recommended update FC threshold in Tegra210 is 0x60 for best performance
> of x1 link. Setting this to 0x60 provides the best balance between number
> of UpdateFC and read data sent over the link.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)

Looks to me like part of this patch ended up in 12/30?

Thierry

> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index b74408eeb367..7dc728cc5f51 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -319,6 +319,7 @@ struct tegra_pcie_soc {
>  	bool update_clamp_threshold;
>  	bool program_deskew_time;
>  	bool raw_violation_fixup;
> +	bool update_fc_threshold;
>  	struct {
>  		struct {
>  			u32 rp_ectl_2_r1;
> @@ -662,6 +663,13 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>  		value |= soc->update_fc_val;
>  		writel(value, port->base + RP_VEND_XP);
>  	}
> +
> +	if (soc->update_fc_threshold) {
> +		value = readl(port->base + RP_VEND_XP);
> +		value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK;
> +		value |= soc->update_fc_val;
> +		writel(value, port->base + RP_VEND_XP);
> +	}
>  }
>  
>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> @@ -2409,6 +2417,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>  	.update_clamp_threshold = false,
>  	.program_deskew_time = false,
>  	.raw_violation_fixup = false,
> +	.update_fc_threshold = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2436,6 +2445,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>  	.update_clamp_threshold = false,
>  	.program_deskew_time = false,
>  	.raw_violation_fixup = false,
> +	.update_fc_threshold = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2458,6 +2468,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>  	.update_clamp_threshold = true,
>  	.program_deskew_time = false,
>  	.raw_violation_fixup = true,
> +	.update_fc_threshold = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2468,6 +2479,8 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>  	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
>  	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
>  	.pads_refclk_cfg0 = 0x90b890b8,
> +	/* FC threshold is bit[25:18] */
> +	.update_fc_val = 0x01800000,
>  	.has_pex_clkreq_en = true,
>  	.has_pex_bias_ctrl = true,
>  	.has_intr_prsnt_sense = true,
> @@ -2478,6 +2491,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>  	.update_clamp_threshold = true,
>  	.program_deskew_time = true,
>  	.raw_violation_fixup = false,
> +	.update_fc_threshold = true,
>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
> @@ -2513,6 +2527,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>  	.update_clamp_threshold = false,
>  	.program_deskew_time = false,
>  	.raw_violation_fixup = false,
> +	.update_fc_threshold = false,
>  	.ectl.enable = false,
>  };
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up
  2019-04-11 17:03 ` [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up Manikanta Maddireddy
  2019-04-11 20:04   ` Bjorn Helgaas
@ 2019-04-15 11:52   ` Thierry Reding
  2019-04-15 15:12     ` Manikanta Maddireddy
  1 sibling, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 11:52 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2184 bytes --]

On Thu, Apr 11, 2019 at 10:33:39PM +0530, Manikanta Maddireddy wrote:
> Some of the legacy PCIe endpoints doesn't enumerate if root port advertises
> both Gen-1 and Gen-2 speeds. Hence, the strategy followed here is to
> initially advertise only Gen-1 and after link is up, retrain link to Gen-2
> speed.
> 
> Following two cards display this behaviour,
>   - Fusion HDTV 5 Express card
>   - IOGear SIL - PCIE - SATA card
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 7dc728cc5f51..7e24eac12668 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -670,6 +670,17 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>  		value |= soc->update_fc_val;
>  		writel(value, port->base + RP_VEND_XP);
>  	}
> +
> +	/*
> +	 * PCIe link doesn't come up with few legacy PCIe endpoints
> +	 * if root port advertises both Gen-1 and Gen-2 speeds.
> +	 * Hence, the strategy followed here is to initially advertise
> +	 * only Gen-1 and after link is up, retrain link to Gen-2 speed
> +	 */
> +	value = readl(port->base + RP_LINK_CONTROL_STATUS_2);
> +	value &= ~PCI_EXP_LNKSTA_CLS;
> +	value |= PCI_EXP_LNKSTA_CLS_2_5GB;
> +	writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
>  }
>  
>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)

This looks like it's related to the earlier patch that adds support for
retraining the link at Gen-2. As such, I think the two patches should be
moved closer together to make that more obvious.

Also, perhaps even the order needs to be changed. For example, if the
earlier patch enables advertisement of Gen-2, then there will be a
period of 10 or so patches where the above devices wouldn't work. So if
this fixes an error introduced by an earlier patch, it makes sense to
resort the patches so that we first fix the potential error and then
introduce the code that would cause the error to happen.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 15/30] PCI: tegra: Fix PLLE powerdown issue due to CLKREQ# signal
  2019-04-11 17:03 ` [PATCH 15/30] PCI: tegra: Fix PLLE powerdown issue due to CLKREQ# signal Manikanta Maddireddy
@ 2019-04-15 13:17   ` Thierry Reding
  2019-04-15 15:14     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 13:17 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2723 bytes --]

On Thu, Apr 11, 2019 at 10:33:40PM +0530, Manikanta Maddireddy wrote:
> Disable controllers which failed to link up and configure CLKREQ# signals
> of these controllers as GPIO. This is required to avoid CLKREQ# signal of
> inactive controllers interfering with PLLE powerdown sequence.
> 
> PCIE_CLKREQ_GPIO bits are defined only in Tegra186, however programming
> these bits in other SoCs doesn't cause any side effects. Program these
> bits for all Tegra SoCs to avoid conditional check.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 7e24eac12668..8e5fdc8ce3d6 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -160,6 +160,8 @@
>  #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211	(0x1 << 20)
>  #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411	(0x2 << 20)
>  #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_111	(0x2 << 20)
> +#define  AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(x)		(1 << ((x) + 29))
> +#define  AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO_ALL		(0x7 << 29)
>  
>  #define AFI_FUSE			0x104
>  #define  AFI_FUSE_PCIE_T0_GEN2_DIS	(1 << 2)
> @@ -733,6 +735,15 @@ static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
>  
>  	value &= ~AFI_PEX_CTRL_REFCLK_EN;
>  	afi_writel(port->pcie, value, ctrl);
> +
> +	/*
> +	 * disable PCIe device and set CLKREQ# as gpio

Did you mean to say "PCIe port"? Also, s/gpio/GPIO/, and you can make
use of 78 characters. With those changes, the above may just fit on one
line.

Thierry

> +	 * to allow PLLE power down
> +	 */
> +	value = afi_readl(port->pcie, AFI_PCIE_CONFIG);
> +	value |= AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
> +	value |= AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(port->index);
> +	afi_writel(port->pcie, value, AFI_PCIE_CONFIG);
>  }
>  
>  static void tegra_pcie_port_free(struct tegra_pcie_port *port)
> @@ -1147,9 +1158,12 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
>  	value = afi_readl(pcie, AFI_PCIE_CONFIG);
>  	value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK;
>  	value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config;
> +	value |= AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO_ALL;
>  
> -	list_for_each_entry(port, &pcie->ports, list)
> +	list_for_each_entry(port, &pcie->ports, list) {
>  		value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
> +		value &= ~AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(port->index);
> +	}
>  
>  	afi_writel(pcie, value, AFI_PCIE_CONFIG);
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 16/30] PCI: tegra: Program AFI_CACHE* registers only for Tegra20
  2019-04-11 17:03 ` [PATCH 16/30] PCI: tegra: Program AFI_CACHE* registers only for Tegra20 Manikanta Maddireddy
@ 2019-04-15 13:20   ` Thierry Reding
  2019-04-16 10:47     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 13:20 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2217 bytes --]

On Thu, Apr 11, 2019 at 10:33:41PM +0530, Manikanta Maddireddy wrote:
> AFI_CACHE* registers are available only in Tegra20, program them only
> for Tegra20.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 8e5fdc8ce3d6..cdaaf13a9fd7 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -887,6 +887,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>   */
>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  {
> +	struct device_node *np = pcie->dev->of_node;
>  	u32 fpci_bar, size, axi_address;
>  
>  	/* Bar 0: type 1 extended configuration space */
> @@ -927,11 +928,13 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  	afi_writel(pcie, 0, AFI_AXI_BAR5_SZ);
>  	afi_writel(pcie, 0, AFI_FPCI_BAR5);
>  
> -	/* map all upstream transactions as uncached */
> -	afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
> -	afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
> -	afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
> -	afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
> +	if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {

At this point we've already matched on that compatible string, so we
could probably get that information from the SoC structure. Why are
these registers not available on later chips? How would we mark
transactions as uncached on later generations of Tegra?

Also, typically writing to non-existing registers on Tegra186 would
cause an SError exception, but I haven't seen any of those with PCIe
on Tegra186. So do these really not exist, or are they simply not used?

Thierry

> +		/* map all upstream transactions as uncached */
> +		afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
> +		afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
> +		afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
> +		afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
> +	}
>  
>  	/* MSI translations are setup only when needed */
>  	afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST);
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 17/30] PCI: tegra: Use switch statements in tegra_pcie_isr()
  2019-04-11 17:03 ` [PATCH 17/30] PCI: tegra: Use switch statements in tegra_pcie_isr() Manikanta Maddireddy
@ 2019-04-15 13:25   ` Thierry Reding
  2019-04-15 15:25     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 13:25 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2732 bytes --]

On Thu, Apr 11, 2019 at 10:33:42PM +0530, Manikanta Maddireddy wrote:
> Use switch statements in tegra_pcie_isr() for better code readability.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 37 ++++++++++++++++--------------
>  1 file changed, 20 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index cdaaf13a9fd7..cf2715065a53 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -842,36 +842,39 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>  	};
>  	struct tegra_pcie *pcie = arg;
>  	struct device *dev = pcie->dev;
> -	u32 code, signature;
> +	u32 code, signature, fpci;
> +	u64 address;
>  
>  	code = afi_readl(pcie, AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
>  	signature = afi_readl(pcie, AFI_INTR_SIGNATURE);
>  	afi_writel(pcie, 0, AFI_INTR_CODE);
>  
> -	if (code == AFI_INTR_LEGACY)
> -		return IRQ_NONE;
> -
>  	if (code >= ARRAY_SIZE(err_msg))
> -		code = 0;
> +		return IRQ_NONE;
>  
> +	switch (code) {
> +	case AFI_INTR_LEGACY:
> +		return IRQ_NONE;
>  	/*
>  	 * do not pollute kernel log with master abort reports since they
>  	 * happen a lot during enumeration
>  	 */
> -	if (code == AFI_INTR_MASTER_ABORT)
> +	case AFI_INTR_MASTER_ABORT:
>  		dev_dbg(dev, "%s, signature: %08x\n", err_msg[code], signature);
> -	else
> +		fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
> +		address = (u64)fpci << 32 | (signature & 0xfffffffc);
> +		dev_dbg(dev, "  FPCI address: %10llx\n", address);
> +		break;
> +	case AFI_INTR_TARGET_ABORT:
> +	case AFI_INTR_FPCI_DECODE_ERROR:
>  		dev_err(dev, "%s, signature: %08x\n", err_msg[code], signature);
> -
> -	if (code == AFI_INTR_TARGET_ABORT || code == AFI_INTR_MASTER_ABORT ||
> -	    code == AFI_INTR_FPCI_DECODE_ERROR) {
> -		u32 fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
> -		u64 address = (u64)fpci << 32 | (signature & 0xfffffffc);
> -
> -		if (code == AFI_INTR_MASTER_ABORT)
> -			dev_dbg(dev, "  FPCI address: %10llx\n", address);
> -		else
> -			dev_err(dev, "  FPCI address: %10llx\n", address);
> +		fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
> +		address = (u64)fpci << 32 | (signature & 0xfffffffc);
> +		dev_err(dev, "  FPCI address: %10llx\n", address);
> +		break;
> +	default:
> +		dev_err(dev, "%s, signature: %08x\n", err_msg[code], signature);
> +		break;
>  	}
>  
>  	return IRQ_HANDLED;

I don't think this improves readability. It does duplicate some code and
is actually longer than the previous variant, so I don't think this adds
value.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 20/30] PCI: tegra: Add AFI_PEX2_CTRL reg offset as part of soc struct
  2019-04-11 17:03 ` [PATCH 20/30] PCI: tegra: Add AFI_PEX2_CTRL reg offset as part of soc struct Manikanta Maddireddy
@ 2019-04-15 13:31   ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 13:31 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2412 bytes --]

On Thu, Apr 11, 2019 at 10:33:45PM +0530, Manikanta Maddireddy wrote:
> Tegra186 and Tegra30 have three PCIe root ports. AFI_PEX2_CTRL register
> is defined for third root port. Offset of this register in Tegra186 is
> different from Tegra30, so add offset as part of soc data structure.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 11be88a394e3..8fdc7934d4c9 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -169,7 +169,6 @@
>  
>  #define AFI_PEX0_CTRL			0x110
>  #define AFI_PEX1_CTRL			0x118
> -#define AFI_PEX2_CTRL			0x128
>  #define  AFI_PEX_CTRL_RST		(1 << 0)
>  #define  AFI_PEX_CTRL_CLKREQ_EN		(1 << 1)
>  #define  AFI_PEX_CTRL_REFCLK_EN		(1 << 3)
> @@ -307,6 +306,7 @@ struct tegra_pcie_soc {
>  	unsigned int num_ports;
>  	const struct tegra_pcie_port_soc *ports;
>  	unsigned int msi_base_shift;
> +	unsigned long afi_pex2_ctrl;
>  	u32 pads_pll_ctl;
>  	u32 tx_ref_sel;
>  	u32 pads_refclk_cfg0;
> @@ -516,6 +516,7 @@ static struct pci_ops tegra_pcie_ops = {
>  
>  static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
>  {
> +	const struct tegra_pcie_soc *soc = port->pcie->soc;
>  	unsigned long ret = 0;
>  
>  	switch (port->index) {
> @@ -528,7 +529,7 @@ static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
>  		break;
>  
>  	case 2:
> -		ret = AFI_PEX2_CTRL;
> +		ret = soc->afi_pex2_ctrl;
>  		break;
>  	}
>  
> @@ -2439,6 +2440,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>  	.num_ports = 2,
>  	.ports = tegra20_pcie_ports,
>  	.msi_base_shift = 0,
> +	.afi_pex2_ctrl = 0x128,
>  	.pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
>  	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10,
>  	.pads_refclk_cfg0 = 0xfa5cfa5c,
> @@ -2548,6 +2550,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>  	.num_ports = 3,
>  	.ports = tegra186_pcie_ports,
>  	.msi_base_shift = 8,
> +	.afi_pex2_ctrl = 0x19c,
>  	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
>  	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
>  	.pads_refclk_cfg0 = 0x80b880b8,
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 19/30] PCI: tegra: Use legacy irq for port service drivers
  2019-04-11 17:03 ` [PATCH 19/30] PCI: tegra: Use legacy irq for port service drivers Manikanta Maddireddy
@ 2019-04-15 13:35   ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 13:35 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2130 bytes --]

On Thu, Apr 11, 2019 at 10:33:44PM +0530, Manikanta Maddireddy wrote:
> Tegra signals PCIe services like AER, PME, etc over legacy IRQ line.
> By default service drivers register interrupt routine over MSI IRQ line,
> use pcie_pme_disable_msi() function to disable MSI for service drivers.
> 
> PME and AER interrupts registered to MSI without this change
> cat /proc/interrupts | grep -i pci
> 36: 21 0 0 0 0 0 GICv2 104 Level       PCIE
> 37: 35 0 0 0 0 0 GICv2 105 Level       Tegra PCIe MSI
> 76: 0  0 0 0 0 0 Tegra PCIe MSI 0 Edge PCIe PME, aerdrv, PCIe BW notif
> 
> PME and AER interrupts registered to legacy IRQ with this change
> cat /proc/interrupts | grep -i pci
> 36: 33 0 0 0 0 0 GICv2 104 Level      PCIE, PCIe PME, aerdrv, PCIe BW notif
> 37: 52 0 0 0 0 0 GICv2 105 Level      Tegra PCIe MSI
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index dcfe97711cb5..11be88a394e3 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -41,6 +41,7 @@
>  #include <soc/tegra/pmc.h>
>  
>  #include "../pci.h"
> +#include "../pcie/portdrv.h"
>  
>  #define INT_PCI_MSI_NR (8 * 32)
>  
> @@ -2724,6 +2725,9 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  		goto put_resources;
>  	}
>  
> +	/* PME events are received over legacy INTR, so disable MSI for PME */
> +	pcie_pme_disable_msi();
> +

I don't know about Bjorn, but to me it seems like this should be an
explicit property of the PCI host bridge rather than some global
variable. We already have a couple of flags for similar purposes in
struct pci_host_bridge.

The above seems like it should always work fine and I can't envision a
device where we'd ever have a Tegra PCIe root complex and a different
host bridge, so this wouldn't make a difference one way or the other,
but this global variable seems like a suboptimal solution to me.

Bjorn?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 21/30] PCI: tegra: Add "pci" type check before parsing child device tree node
  2019-04-11 17:03 ` [PATCH 21/30] PCI: tegra: Add "pci" type check before parsing child device tree node Manikanta Maddireddy
@ 2019-04-15 13:37   ` Thierry Reding
  2019-04-15 15:30     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 13:37 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 1220 bytes --]

On Thu, Apr 11, 2019 at 10:33:46PM +0530, Manikanta Maddireddy wrote:
> Each root port is added as a child device tree node of PCIe controller
> node. These child nodes are parsed using open firmware PCI bus accessor
> functions. If the child node is not of "pci" type then device tree
> parsing fails. Add "pci" type check before parsing child device tree node.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 3 +++
>  1 file changed, 3 insertions(+)

Erm... what is the use-case that you're trying to support? Why would we
ever have children nodes that are not of type "pci"?

Thierry

> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 8fdc7934d4c9..d08a63132c77 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -2197,6 +2197,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  		unsigned int index;
>  		u32 value;
>  
> +		if (!of_node_is_type(port, "pci"))
> +			continue;
> +
>  		err = of_pci_get_devfn(port);
>  		if (err < 0) {
>  			dev_err(dev, "failed to parse address: %d\n", err);
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-15 11:36         ` Manikanta Maddireddy
@ 2019-04-15 13:45           ` Thierry Reding
  2019-04-15 13:52             ` Thierry Reding
  2019-04-15 14:04           ` Bjorn Helgaas
  1 sibling, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 13:45 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: Bjorn Helgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree,
	Jingoo Han, Gustavo Pimentel, Ley Foon Tan, Michal Simek

[-- Attachment #1: Type: text/plain, Size: 4511 bytes --]

On Mon, Apr 15, 2019 at 05:06:10PM +0530, Manikanta Maddireddy wrote:
> 
> On 12-Apr-19 8:20 PM, Bjorn Helgaas wrote:
> > [+cc Jingoo, Gustavo (dwc maintainers), Ley (altera), Michal (xilinx)]
> >
> > On Fri, Apr 12, 2019 at 12:30:22PM +0530, Manikanta Maddireddy wrote:
> >> On 12-Apr-19 1:45 AM, Bjorn Helgaas wrote:
> >>> On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
> >>>> Add PCIe link up check in config read and write callback functions
> >>>> before accessing endpoint config registers.
> >>>>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
> >>>>  				  int where, int size, u32 *value)
> >>>>  {
> >>>> +	struct tegra_pcie *pcie = bus->sysdata;
> >>>> +	struct pci_dev *bridge;
> >>>> +	struct tegra_pcie_port *port;
> >>>> +
> >>>>  	if (bus->number == 0)
> >>>>  		return pci_generic_config_read32(bus, devfn, where, size,
> >>>>  						 value);
> >>>>  
> >>>> +	bridge = pcie_find_root_port(bus->self);
> >>>> +
> >>>> +	list_for_each_entry(port, &pcie->ports, list)
> >>>> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
> >>>> +			break;
> >>>> +
> >>>> +	/* If there is no link, then there is no device */
> >>>> +	if (!tegra_pcie_link_status(port)) {
> >>> This is racy and you should avoid it if possible.  The link could go down
> >>> between calling tegra_pcie_link_status() and issuing the config read/write.
> >>>
> >>> If your driver is to be reliable, it must be able to handle any bad
> >>> consequence of issuing that config read/write anyway, so I think it's
> >>> better if it doesn't even bother checking whether the link is up.
> >> This change is made based on similar check present in dwc driver
> >> dw_pcie_valid_device(), reasons for making this change in Tegra might
> >> differ dwc.
> > Yes, you won't be surprised to learn that I don't like the similar
> > checks in dwc, altera, xilinx, and xilinx-nwl either :)  I raise this
> > issue every time I see it, but I can't remember if I've mentioned dwc
> > specifically.
> >
> > We need to either eradicate this pattern of checking for link up, or
> > include a comment about why it is absolutely necessary.
> 
> This patch is created to address below scenario in our downstream kernel,
> 1) Our platform has WiFi on one slot and GPU in another.
> 2) During WiFi OFF, link is put in L2 and it goes through hot reset
> when turning ON WiFi (since Tegra doesn't support hot-plug).
> 3) Whenever x11 server is started it scans the PCIe bus for video devices.
> Here PCIe configuration registers of all devices are read to find out
> all available video devices.
> 4) If "x11 server" started with WiFi OFF, then we are seeing "response
> decoding error"(Tegra AFI module specific error).
> 
> Best solution we came up with is to have link up check in config access
> callback functions.

So we really need this to prevent a userspace access to PCI config space
from triggering these errors? I'm not familiar with how PCI access from
userspace works, but if modifying the accessors fixes this problem it
sounds like userspace would end up calling these accessors. If so, it
sounds more like we should fix this at the point where userspace calls
these accessors. According to what you're saying this should never be an
issue from kernel space, because as long as a driver needs access to its
device, the PCI bus should be up.

And if that wasn't the case, then we probably do want to see these AER
errors to help diagnose the issue.

So could we instead have some sort of host bridge operation that would
expose the link status and use that as part of the userspace access to
PCI configuration space?

Thierry

> >> Intention here is to reduce the number of AER errors when device is
> >> falling off the bus or going through hot reset. So racy condition here is
> >> OK
> > I'm not convinced about this.  The issues you mention need to be
> > solved in a generic way, not a tegra-specific way.
> >
> > We don't want to end up with code that silently avoids the config
> > access 99.99% of the time, but once in a blue moon, we lose the race
> > (the device stops responding after we've determined the link is up)
> > and the access causes a mysterious AER error that we have no way to
> > debug.
> >
> >>>> +		*value = 0xffffffff;
> >>>> +		return PCIBIOS_DEVICE_NOT_FOUND;
> >>>> +	}
> >>>> +
> >>>>  	return pci_generic_config_read(bus, devfn, where, size, value);
> >>>>  }

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-15 13:45           ` Thierry Reding
@ 2019-04-15 13:52             ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 13:52 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: Bjorn Helgaas, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree,
	Jingoo Han, Gustavo Pimentel, Ley Foon Tan, Michal Simek

[-- Attachment #1: Type: text/plain, Size: 4138 bytes --]

On Mon, Apr 15, 2019 at 03:45:16PM +0200, Thierry Reding wrote:
> On Mon, Apr 15, 2019 at 05:06:10PM +0530, Manikanta Maddireddy wrote:
> > 
> > On 12-Apr-19 8:20 PM, Bjorn Helgaas wrote:
> > > [+cc Jingoo, Gustavo (dwc maintainers), Ley (altera), Michal (xilinx)]
> > >
> > > On Fri, Apr 12, 2019 at 12:30:22PM +0530, Manikanta Maddireddy wrote:
> > >> On 12-Apr-19 1:45 AM, Bjorn Helgaas wrote:
> > >>> On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
> > >>>> Add PCIe link up check in config read and write callback functions
> > >>>> before accessing endpoint config registers.
> > >>>>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
> > >>>>  				  int where, int size, u32 *value)
> > >>>>  {
> > >>>> +	struct tegra_pcie *pcie = bus->sysdata;
> > >>>> +	struct pci_dev *bridge;
> > >>>> +	struct tegra_pcie_port *port;
> > >>>> +
> > >>>>  	if (bus->number == 0)
> > >>>>  		return pci_generic_config_read32(bus, devfn, where, size,
> > >>>>  						 value);
> > >>>>  
> > >>>> +	bridge = pcie_find_root_port(bus->self);
> > >>>> +
> > >>>> +	list_for_each_entry(port, &pcie->ports, list)
> > >>>> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
> > >>>> +			break;
> > >>>> +
> > >>>> +	/* If there is no link, then there is no device */
> > >>>> +	if (!tegra_pcie_link_status(port)) {
> > >>> This is racy and you should avoid it if possible.  The link could go down
> > >>> between calling tegra_pcie_link_status() and issuing the config read/write.
> > >>>
> > >>> If your driver is to be reliable, it must be able to handle any bad
> > >>> consequence of issuing that config read/write anyway, so I think it's
> > >>> better if it doesn't even bother checking whether the link is up.
> > >> This change is made based on similar check present in dwc driver
> > >> dw_pcie_valid_device(), reasons for making this change in Tegra might
> > >> differ dwc.
> > > Yes, you won't be surprised to learn that I don't like the similar
> > > checks in dwc, altera, xilinx, and xilinx-nwl either :)  I raise this
> > > issue every time I see it, but I can't remember if I've mentioned dwc
> > > specifically.
> > >
> > > We need to either eradicate this pattern of checking for link up, or
> > > include a comment about why it is absolutely necessary.
> > 
> > This patch is created to address below scenario in our downstream kernel,
> > 1) Our platform has WiFi on one slot and GPU in another.
> > 2) During WiFi OFF, link is put in L2 and it goes through hot reset
> > when turning ON WiFi (since Tegra doesn't support hot-plug).
> > 3) Whenever x11 server is started it scans the PCIe bus for video devices.
> > Here PCIe configuration registers of all devices are read to find out
> > all available video devices.
> > 4) If "x11 server" started with WiFi OFF, then we are seeing "response
> > decoding error"(Tegra AFI module specific error).
> > 
> > Best solution we came up with is to have link up check in config access
> > callback functions.
> 
> So we really need this to prevent a userspace access to PCI config space
> from triggering these errors? I'm not familiar with how PCI access from
> userspace works, but if modifying the accessors fixes this problem it
> sounds like userspace would end up calling these accessors. If so, it
> sounds more like we should fix this at the point where userspace calls
> these accessors. According to what you're saying this should never be an
> issue from kernel space, because as long as a driver needs access to its
> device, the PCI bus should be up.
> 
> And if that wasn't the case, then we probably do want to see these AER
> errors to help diagnose the issue.
> 
> So could we instead have some sort of host bridge operation that would
> expose the link status and use that as part of the userspace access to
> PCI configuration space?

Looks like maybe pci_user_read_config_*() would be a good place to check
for this? They're defined by the PCI_USER_READ_CONFIG() macro in
drivers/pci/access.c. Same for pci_user_write_config_*().

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-15 11:36         ` Manikanta Maddireddy
  2019-04-15 13:45           ` Thierry Reding
@ 2019-04-15 14:04           ` Bjorn Helgaas
  2019-04-15 15:43             ` Manikanta Maddireddy
  1 sibling, 1 reply; 106+ messages in thread
From: Bjorn Helgaas @ 2019-04-15 14:04 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree,
	Jingoo Han, Gustavo Pimentel, Ley Foon Tan, Michal Simek

On Mon, Apr 15, 2019 at 05:06:10PM +0530, Manikanta Maddireddy wrote:
> On 12-Apr-19 8:20 PM, Bjorn Helgaas wrote:
> > On Fri, Apr 12, 2019 at 12:30:22PM +0530, Manikanta Maddireddy wrote:
> >> On 12-Apr-19 1:45 AM, Bjorn Helgaas wrote:
> >>> On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
> >>>> Add PCIe link up check in config read and write callback functions
> >>>> before accessing endpoint config registers.
> >>>>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
> >>>>  				  int where, int size, u32 *value)
> >>>>  {
> >>>> +	struct tegra_pcie *pcie = bus->sysdata;
> >>>> +	struct pci_dev *bridge;
> >>>> +	struct tegra_pcie_port *port;
> >>>> +
> >>>>  	if (bus->number == 0)
> >>>>  		return pci_generic_config_read32(bus, devfn, where, size,
> >>>>  						 value);
> >>>>  
> >>>> +	bridge = pcie_find_root_port(bus->self);
> >>>> +
> >>>> +	list_for_each_entry(port, &pcie->ports, list)
> >>>> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
> >>>> +			break;
> >>>> +
> >>>> +	/* If there is no link, then there is no device */
> >>>> +	if (!tegra_pcie_link_status(port)) {
> >>> This is racy and you should avoid it if possible.  The link could go down
> >>> between calling tegra_pcie_link_status() and issuing the config read/write.
> >>>
> >>> If your driver is to be reliable, it must be able to handle any bad
> >>> consequence of issuing that config read/write anyway, so I think it's
> >>> better if it doesn't even bother checking whether the link is up.
> >> This change is made based on similar check present in dwc driver
> >> dw_pcie_valid_device(), reasons for making this change in Tegra might
> >> differ dwc.
> > Yes, you won't be surprised to learn that I don't like the similar
> > checks in dwc, altera, xilinx, and xilinx-nwl either :)  I raise this
> > issue every time I see it, but I can't remember if I've mentioned dwc
> > specifically.
> >
> > We need to either eradicate this pattern of checking for link up, or
> > include a comment about why it is absolutely necessary.
> 
> This patch is created to address below scenario in our downstream kernel,
> 1) Our platform has WiFi on one slot and GPU in another.
> 2) During WiFi OFF, link is put in L2 and it goes through hot reset
> when turning ON WiFi (since Tegra doesn't support hot-plug).
> 3) Whenever x11 server is started it scans the PCIe bus for video devices.
> Here PCIe configuration registers of all devices are read to find out
> all available video devices.
> 4) If "x11 server" started with WiFi OFF, then we are seeing "response
> decoding error"(Tegra AFI module specific error).

Probably happens with lspci too.  I guess this is when you try to read
the WiFi device config space?

> Best solution we came up with is to have link up check in config access
> callback functions.

Can you check for "response decoding error" in the config accessor and
return 0xffffffff if you see it?

> >> Intention here is to reduce the number of AER errors when device is
> >> falling off the bus or going through hot reset. So racy condition here is
> >> OK
> >
> > I'm not convinced about this.  The issues you mention need to be
> > solved in a generic way, not a tegra-specific way.
> >
> > We don't want to end up with code that silently avoids the config
> > access 99.99% of the time, but once in a blue moon, we lose the race
> > (the device stops responding after we've determined the link is up)
> > and the access causes a mysterious AER error that we have no way to
> > debug.
> >
> >>>> +		*value = 0xffffffff;
> >>>> +		return PCIBIOS_DEVICE_NOT_FOUND;
> >>>> +	}
> >>>> +
> >>>>  	return pci_generic_config_read(bus, devfn, where, size, value);
> >>>>  }

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 23/30] dt-bindings: pci: tegra: Document PCIe DPD pinctrl optional prop
  2019-04-11 17:03 ` [PATCH 23/30] dt-bindings: pci: tegra: Document PCIe DPD pinctrl optional prop Manikanta Maddireddy
@ 2019-04-15 14:07   ` Thierry Reding
  2019-04-15 15:48     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 14:07 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2511 bytes --]

On Thu, Apr 11, 2019 at 10:33:48PM +0530, Manikanta Maddireddy wrote:
> Document PCIe DPD pinctrl optional property to put PEX clk & BIAS pads
> in low power mode.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  .../devicetree/bindings/pci/nvidia,tegra20-pcie.txt      | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> index 145a4f04194f..fbbd3bcb3435 100644
> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> @@ -65,6 +65,15 @@ Required properties:
>    - afi
>    - pcie_x
>  
> +Optional properties:
> +- pinctrl-names : The pin control state names.
> +- pinctrl-0: PCIe IO(bias & REFCLK) deep power down(DPD) disable state.
> +  In Tegra210 PCIe clamps are not controlling IO signals, so there
> +  is leakagae power even after PCIe power partition is off. Pass

leakage

> +  pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
> +- pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
> +  Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.

This is confusingly documented. Your pinctrl-names should list exactly
what states are supported. The generic pinctrl bindings already specify
how to define pinctrl states, so I don't think you need to describe all
of the pinctrl-{0,1,...} states again.

Also, looking at the driver you seem to use custom names for the pinctrl
states, but those states are really just the "active" and the "idle"
states, for which there are standard names.

Something like this perhaps:

- pinctrl-names: A list of pinctrl state names. Must contain the
  following entries:
  - "default": active state, puts PCIe I/O out of deep power down state
  - "idle": puts PCIe I/O into deep power down state

It then goes without saying that the phandle pointed to by pinctrl-0
corresponds to the pinctrl state named by the first entry in
pinctrl-names.

If you use those default names for the states, I don't think you even
need extra code, the pinctrl subsystem should be able to take of that
for you.

Thierry

> +
>  Required properties on Tegra124 and later (deprecated):
>  - phys: Must contain an entry for each entry in phy-names.
>  - phy-names: Must include the following entries:
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 25/30] PCI: tegra: Put PEX CLK & BIAS pads in DPD mode
  2019-04-11 17:03 ` [PATCH 25/30] PCI: tegra: Put PEX CLK & BIAS pads in DPD mode Manikanta Maddireddy
@ 2019-04-15 14:11   ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 14:11 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 6130 bytes --]

On Thu, Apr 11, 2019 at 10:33:50PM +0530, Manikanta Maddireddy wrote:
> In Tegra210 AFI design has clamp value for the BIAS pad as 0, which keeps
> the bias pad in non power down mode. This is leading to power consumption

s/bias/BIAS/

> of 2 mW in BIAS pad, even if the PCIe partition is power gated. To avoid

powergated

> unnecessary power consumption, put PEX CLK & BIAS pads in deep power down
> mode when PCIe partition is power gated.

You should validate, but I'm pretty sure there's a way to make this work
without any code (or very minimal code) in the driver if you're using
the standard pinctrl state names.

Thierry

> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 65 +++++++++++++++++++++++++++++-
>  1 file changed, 64 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index c050687020f0..92c6daa0de84 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -30,6 +30,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/pci.h>
>  #include <linux/phy/phy.h>
> +#include <linux/pinctrl/consumer.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset.h>
>  #include <linux/sizes.h>
> @@ -323,6 +324,7 @@ struct tegra_pcie_soc {
>  	bool program_deskew_time;
>  	bool raw_violation_fixup;
>  	bool update_fc_threshold;
> +	bool config_pex_io_dpd;
>  	struct {
>  		struct {
>  			u32 rp_ectl_2_r1;
> @@ -385,6 +387,10 @@ struct tegra_pcie {
>  
>  	const struct tegra_pcie_soc *soc;
>  	struct dentry *debugfs;
> +
> +	struct pinctrl *pex_pinctrl;
> +	struct pinctrl_state *pex_dpd_enable;
> +	struct pinctrl_state *pex_dpd_disable;
>  };
>  
>  struct tegra_pcie_port {
> @@ -2154,6 +2160,37 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
>  	return tegra_pcie_get_legacy_regulators(pcie);
>  }
>  
> +static int tegra_pcie_parse_pinctrl(struct tegra_pcie *pcie)
> +{
> +	struct device *dev = pcie->dev;
> +	int err = 0;
> +
> +	pcie->pex_pinctrl = devm_pinctrl_get(dev);
> +	if (IS_ERR(pcie->pex_pinctrl)) {
> +		err = PTR_ERR(pcie->pex_pinctrl);
> +		dev_err(dev, "failed to get pinctrl handle: %d\n", err);
> +		return err;
> +	}
> +
> +	pcie->pex_dpd_enable = pinctrl_lookup_state(pcie->pex_pinctrl,
> +						    "pex-dpd-enable");
> +	if (IS_ERR(pcie->pex_dpd_enable)) {
> +		err = PTR_ERR(pcie->pex_dpd_enable);
> +		dev_err(dev, "missing pex-dpd-enable state: %d\n", err);
> +		return err;
> +	}
> +
> +	pcie->pex_dpd_disable = pinctrl_lookup_state(pcie->pex_pinctrl,
> +						     "pex-dpd-disable");
> +	if (IS_ERR(pcie->pex_dpd_disable)) {
> +		err = PTR_ERR(pcie->pex_dpd_disable);
> +		dev_err(dev, "missing pex-dpd-disable state: %d\n", err);
> +		return err;
> +	}
> +
> +	return err;
> +}
> +
>  static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  {
>  	struct device *dev = pcie->dev;
> @@ -2496,6 +2533,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>  	.program_deskew_time = false,
>  	.raw_violation_fixup = false,
>  	.update_fc_threshold = false,
> +	.config_pex_io_dpd = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2524,6 +2562,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>  	.program_deskew_time = false,
>  	.raw_violation_fixup = false,
>  	.update_fc_threshold = false,
> +	.config_pex_io_dpd = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2547,6 +2586,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>  	.program_deskew_time = false,
>  	.raw_violation_fixup = true,
>  	.update_fc_threshold = false,
> +	.config_pex_io_dpd = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2570,6 +2610,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>  	.program_deskew_time = true,
>  	.raw_violation_fixup = false,
>  	.update_fc_threshold = true,
> +	.config_pex_io_dpd = true,
>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
> @@ -2607,6 +2648,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>  	.program_deskew_time = false,
>  	.raw_violation_fixup = false,
>  	.update_fc_threshold = false,
> +	.config_pex_io_dpd = false,
>  	.ectl.enable = false,
>  };
>  
> @@ -2753,6 +2795,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	INIT_LIST_HEAD(&pcie->ports);
>  	pcie->dev = dev;
>  
> +	if (pcie->soc->config_pex_io_dpd) {
> +		err = tegra_pcie_parse_pinctrl(pcie);
> +		if (err < 0)
> +			return err;
> +	}
> +
>  	err = tegra_pcie_parse_dt(pcie);
>  	if (err < 0)
>  		return err;
> @@ -2866,6 +2914,8 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
>  		tegra_pcie_disable_msi(pcie);
>  
>  	tegra_pcie_disable_controller(pcie);
> +	if (pcie->soc->config_pex_io_dpd)
> +		pinctrl_select_state(pcie->pex_pinctrl, pcie->pex_dpd_enable);
>  	tegra_pcie_power_off(pcie);
>  
>  	return 0;
> @@ -2881,10 +2931,20 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
>  		dev_err(dev, "tegra pcie power on fail: %d\n", err);
>  		return err;
>  	}
> +
> +	if (pcie->soc->config_pex_io_dpd) {
> +		err = pinctrl_select_state(pcie->pex_pinctrl,
> +					   pcie->pex_dpd_disable);
> +		if (err < 0) {
> +			dev_err(dev, "disabling PCIe IO DPD failed: %d\n", err);
> +			goto poweroff;
> +		}
> +	}
> +
>  	err = tegra_pcie_enable_controller(pcie);
>  	if (err) {
>  		dev_err(dev, "tegra pcie controller enable fail: %d\n", err);
> -		goto poweroff;
> +		goto pex_dpd_enable;
>  	}
>  	tegra_pcie_setup_translations(pcie);
>  
> @@ -2904,6 +2964,9 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
>  
>  disable_controller:
>  	tegra_pcie_disable_controller(pcie);
> +pex_dpd_enable:
> +	if (pcie->soc->config_pex_io_dpd)
> +		pinctrl_select_state(pcie->pex_pinctrl, pcie->pex_dpd_enable);
>  poweroff:
>  	tegra_pcie_power_off(pcie);
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence
  2019-04-15 11:01   ` Thierry Reding
@ 2019-04-15 14:11     ` Manikanta Maddireddy
  2019-04-15 14:30       ` Thierry Reding
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 14:11 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree


On 15-Apr-19 4:31 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:27PM +0530, Manikanta Maddireddy wrote:
>> PCIe host power up sequence involves programming AFI(AXI to FPCI bridge)
>> registers first and then PCIe registers. Otherwise AFI register settings
>> may not latch to PCIe IP.
>>
>> PCIe root port starts LTSSM as soon as PCIe xrst is deasserted.
>> So deassert PCIe xrst after programming PCIe registers.
>>
>> Modify PCIe power up sequence as follows,
>>   - Power ungate PCIe partition
>>   - Enable AFI clock
>>   - Deassert AFI reset
>>   - Program AFI registers
>>   - Enable PCIe clock
>>   - Deassert PCIe reset
>>   - Program PCIe registers
>>   - Deassert PCIe xrst to start LTSSM
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 73 ++++++++++++++++++------------
>>  1 file changed, 43 insertions(+), 30 deletions(-)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index f4f53d092e00..0bf270bcea34 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -966,9 +966,6 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
>>  		}
>>  	}
>>  
>> -	/* take the PCIe interface module out of reset */
>> -	reset_control_deassert(pcie->pcie_xrst);
>> -
>>  	/* finally enable PCIe */
>>  	value = afi_readl(pcie, AFI_CONFIGURATION);
>>  	value |= AFI_CONFIGURATION_EN_FPCI;
>> @@ -997,8 +994,6 @@ static void tegra_pcie_disable_controller(struct tegra_pcie *pcie)
>>  {
>>  	int err;
>>  
>> -	reset_control_assert(pcie->pcie_xrst);
>> -
>>  	if (pcie->soc->program_uphy) {
>>  		err = tegra_pcie_phy_power_off(pcie);
>>  		if (err < 0)
>> @@ -1014,13 +1009,11 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
>>  	int err;
>>  
>>  	reset_control_assert(pcie->afi_rst);
>> -	reset_control_assert(pcie->pex_rst);
>>  
>>  	clk_disable_unprepare(pcie->pll_e);
>>  	if (soc->has_cml_clk)
>>  		clk_disable_unprepare(pcie->cml_clk);
>>  	clk_disable_unprepare(pcie->afi_clk);
>> -	clk_disable_unprepare(pcie->pex_clk);
>>  
>>  	if (!dev->pm_domain)
>>  		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
>> @@ -1036,58 +1029,59 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
>>  	const struct tegra_pcie_soc *soc = pcie->soc;
>>  	int err;
>>  
>> -	reset_control_assert(pcie->pcie_xrst);
>> -	reset_control_assert(pcie->afi_rst);
>> -	reset_control_assert(pcie->pex_rst);
>> -
>> -	if (!dev->pm_domain)
>> -		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
>> -
> This code was in place to ensure that PCIe was in a known good state
> before following the power up sequence below. You mentioned elsewhere
> that there's a regression on Cardhu after applying this series, so
> perhaps Cardhu relies on the above hunk?
No, Tegra30 and Tegra20 has legacy PHY which are dependent on PEX clk and rst.
PHY power on is done in tegra_pcie_enable_controller(), but in this patch I am
enabling PEX clk and rst after tegra_pcie_enable_controller(). This caused
regression on Cardhu.
I realized that sanity test is failing on Cardhu after publishing this series, I will
fix the issue in V2.
I believe you are talking about the bootloader(uboot) which can enable
PCIe partition and reset. To bring the PCIe into good state then we
have to take care of clocks as well. AFAIK clock_disable() is not added
because it maintains the refcount and any mismatch in the count
will thrown warning. I downstream kernel I see pmc driver itself taking
care of initial state and there after maintaining the state with refcount.
Since bootloader may or may not enable PCIe, Can we get the state fixed
in pmc driver instead of fixing it in PCIe driver?

>
>>  	/* enable regulators */
>>  	err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
>>  	if (err < 0)
>>  		dev_err(dev, "failed to enable regulators: %d\n", err);
>>  
>> -	if (dev->pm_domain) {
>> -		err = clk_prepare_enable(pcie->pex_clk);
>> +	if (!dev->pm_domain) {
>> +		err = tegra_powergate_power_on(TEGRA_POWERGATE_PCIE);
>>  		if (err) {
>> -			dev_err(dev, "failed to enable PEX clock: %d\n", err);
>> -			return err;
>> +			dev_err(dev, "power ungate failed: %d\n", err);
>> +			goto regulator_disable;
>>  		}
>> -		reset_control_deassert(pcie->pex_rst);
>> -	} else {
>> -		err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
>> -							pcie->pex_clk,
>> -							pcie->pex_rst);
>> +		err = tegra_powergate_remove_clamping(TEGRA_POWERGATE_PCIE);
>>  		if (err) {
>> -			dev_err(dev, "powerup sequence failed: %d\n", err);
>> -			return err;
>> +			dev_err(dev, "remove clamp failed: %d\n", err);
>> +			goto powergate;
>>  		}
>>  	}
>>  
>> -	reset_control_deassert(pcie->afi_rst);
>> -
>>  	err = clk_prepare_enable(pcie->afi_clk);
>>  	if (err < 0) {
>>  		dev_err(dev, "failed to enable AFI clock: %d\n", err);
>> -		return err;
>> +		goto powergate;
>>  	}
>>  
>>  	if (soc->has_cml_clk) {
>>  		err = clk_prepare_enable(pcie->cml_clk);
>>  		if (err < 0) {
>>  			dev_err(dev, "failed to enable CML clock: %d\n", err);
>> -			return err;
>> +			goto afi_clk_disable;
>>  		}
>>  	}
>>  
>>  	err = clk_prepare_enable(pcie->pll_e);
>>  	if (err < 0) {
>>  		dev_err(dev, "failed to enable PLLE clock: %d\n", err);
>> -		return err;
>> +		goto cml_clk_disable;
>>  	}
>>  
>> +	reset_control_deassert(pcie->afi_rst);
>> +
>>  	return 0;
>> +
>> +cml_clk_disable:
>> +	if (soc->has_cml_clk)
>> +		clk_disable_unprepare(pcie->cml_clk);
>> +afi_clk_disable:
>> +	clk_disable_unprepare(pcie->afi_clk);
>> +powergate:
>> +	if (!dev->pm_domain)
>> +		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
>> +regulator_disable:
>> +	regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
>> +	return err;
>>  }
>>  
>>  static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
>> @@ -2108,7 +2102,12 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>>  			 port->index, port->lanes);
>>  
>>  		tegra_pcie_port_enable(port);
>> +	}
>> +
>> +	/* Start LTSSM from Tegra side */
>> +	reset_control_deassert(pcie->pcie_xrst);
>>  
>> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
>>  		if (tegra_pcie_port_check_link(port))
>>  			continue;
>>  
>> @@ -2123,6 +2122,8 @@ static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
>>  {
>>  	struct tegra_pcie_port *port, *tmp;
>>  
>> +	reset_control_assert(pcie->pcie_xrst);
>> +
>>  	list_for_each_entry_safe(port, tmp, &pcie->ports, list)
>>  		tegra_pcie_port_disable(port);
>>  }
>> @@ -2472,6 +2473,9 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
>>  
>>  	tegra_pcie_disable_ports(pcie);
>>  
>> +	reset_control_assert(pcie->pex_rst);
>> +	clk_disable_unprepare(pcie->pex_clk);
>> +
>>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>>  		tegra_pcie_disable_msi(pcie);
>>  
>> @@ -2501,10 +2505,19 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
>>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>>  		tegra_pcie_enable_msi(pcie);
>>  
>> +	err = clk_prepare_enable(pcie->pex_clk);
>> +	if (err) {
>> +		dev_err(dev, "failed to enable PEX clock: %d\n", err);
>> +		goto disable_controller;
>> +	}
>> +	reset_control_deassert(pcie->pex_rst);
>> +
>>  	tegra_pcie_enable_ports(pcie);
>>  
>>  	return 0;
>>  
>> +disable_controller:
>> +	tegra_pcie_disable_controller(pcie);
>>  poweroff:
>>  	tegra_pcie_power_off(pcie);
>>  
> There's quite a bit going on in this patch in general and I find it hard
> to review because not all the changes seem related to what you described
> in the commit message.
>
> Can you perhaps try to split out the error cleanup changes into a
> separate patch where it makes sense? It seems to me like at least for
> tegra_pcie_power_on() we're currently missing all of the cleanup code.
> You could make that a preparatory patch that goes before this particular
> patch, which will hopefully make this patch easier to review.
>
> Thierry
Okay, I will prepare new patch for error handling and restrict this patch only for
sequence correction

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-11 17:03 ` [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop Manikanta Maddireddy
  2019-04-11 20:18   ` Bjorn Helgaas
@ 2019-04-15 14:16   ` Thierry Reding
  2019-04-15 17:58     ` Manikanta Maddireddy
  1 sibling, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 14:16 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2496 bytes --]

On Thu, Apr 11, 2019 at 10:33:51PM +0530, Manikanta Maddireddy wrote:
> Document "nvidia,plat-gpios" optional property which supports configuring
> of platform specific gpios.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> index fbbd3bcb3435..dca8393b86d1 100644
> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> @@ -73,6 +73,8 @@ Optional properties:
>    pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
>  - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
> +- nvidia,plat-gpios: A list of platform specific gpios which controls
> +  endpoint's internal regulator or PCIe logic.

We discussed this with Vidya during review of the Tegra194 PCIe device
tree bindings and arrived at the conclusion that all of the GPIOs that
need to be controlled for PCI to work can be modelled as proper device
nodes (I think regulator and GPIO-controlled muxes were the only two
use-cases for which we need this).

Can the same be done for this PCI controller? What use-cases are we
talking about?

>  Required properties on Tegra124 and later (deprecated):
>  - phys: Must contain an entry for each entry in phy-names.
> @@ -567,6 +569,7 @@ Board DTS:
>  		pci@2,0 {
>  			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
>  			phy-names = "pcie-0";
> +			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
>  			status = "okay";
>  		};
>  	};

I recall this being the setup for Jetson Nano and the X.3 GPIO going to
an Ethernet device. Let's find out what exactly this GPIO is used for
and why we need it to be set up as part of the PCI controller driver
rather than the Ethernet device.

If it turns out we can't model this other than with a generic GPIO type
of property we need a better explanation than the above, and the Jetson
Nano use-case would provide that explanation.

And if indeed we cannot model this more accurately, I think we should
use something like the gpio-hog binding rather than some custom PCI
controller property.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 28/30] dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop
  2019-04-11 17:03 ` [PATCH 28/30] dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop Manikanta Maddireddy
@ 2019-04-15 14:20   ` Thierry Reding
  2019-04-15 18:01     ` Manikanta Maddireddy
  2019-04-29 18:33     ` Rob Herring
  0 siblings, 2 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 14:20 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 1856 bytes --]

On Thu, Apr 11, 2019 at 10:33:53PM +0530, Manikanta Maddireddy wrote:
> Document "nvidia,rst-gpio" optional property which supports GPIO based
> PERST# signal.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> index dca8393b86d1..23928fd59538 100644
> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> @@ -75,6 +75,8 @@ Optional properties:
>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
>  - nvidia,plat-gpios: A list of platform specific gpios which controls
>    endpoint's internal regulator or PCIe logic.
> +- nvidia,rst-gpio: If GPIO is used as PERST# signal instead of available
> +  SFIO, add this property with phandle to GPIO controller and GPIO number.

GPIO properties are pretty much standardized, so this should really be
called just "reset-gpio".

Also it looks like this is documented in the wrong place. In the example
below you set this property for the root port, that is inside a child
node of the PCI controller, but if I understand correctly, and it's hard
to say from the context, the above is documented as part of the
properties of the host bridge node.

Thierry

>  
>  Required properties on Tegra124 and later (deprecated):
>  - phys: Must contain an entry for each entry in phy-names.
> @@ -671,6 +673,7 @@ Board DTS:
>  
>  		pci@1,0 {
>  			nvidia,num-lanes = <4>;
> +			nvidia,rst-gpio = <&tegra_main_gpio TEGRA_MAIN_GPIO(A, 3) 0>;
>  			status = "okay";
>  		};
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 03/30] PCI: tegra: Move REFCLK pad settings out of phy_power_on()
  2019-04-15 11:06   ` Thierry Reding
@ 2019-04-15 14:20     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 14:20 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree


On 15-Apr-19 4:36 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:28PM +0530, Manikanta Maddireddy wrote:
>> In Tegra186 PHY programming is done by BPMP-FW, so PHY calls are skipped
>> in driver. REFCLK pad settings are independent of PHY and should be
>> programmed by driver. So move REFCLK pad settings out of phy_power_on().
>> These pad settings tune REFCLK peak to peak amplitude.
>>
>> Fixes: cf5d31801278 ("PCI: tegra: Program PADS_REFCLK_CFG* always, not
>> just on legacy SoCs")
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 20 +++++++++++++-------
>>  1 file changed, 13 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 0bf270bcea34..a61ce9d475b4 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -852,7 +852,6 @@ static int tegra_pcie_port_phy_power_off(struct tegra_pcie_port *port)
>>  static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
>>  {
>>  	struct device *dev = pcie->dev;
>> -	const struct tegra_pcie_soc *soc = pcie->soc;
>>  	struct tegra_pcie_port *port;
>>  	int err;
>>  
>> @@ -878,12 +877,6 @@ static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
>>  		}
>>  	}
>>  
>> -	/* Configure the reference clock driver */
>> -	pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
>> -
>> -	if (soc->num_ports > 2)
>> -		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
>> -
>>  	return 0;
>>  }
>>  
>> @@ -2092,11 +2085,24 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
>>  	return false;
>>  }
>>  
>> +static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
>> +{
>> +	const struct tegra_pcie_soc *soc = pcie->soc;
>> +
>> +	/* Configure the reference clock driver */
>> +	pads_writel(pcie, soc->pads_refclk_cfg0, PADS_REFCLK_CFG0);
>> +
>> +	if (soc->num_ports > 2)
>> +		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
>> +}
>> +
>>  static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>>  {
>>  	struct device *dev = pcie->dev;
>>  	struct tegra_pcie_port *port, *tmp;
>>  
>> +	tegra_pcie_apply_pad_settings(pcie);
>> +
>>  	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
>>  		dev_info(dev, "probing port %u, using %u lanes\n",
>>  			 port->index, port->lanes);
> This also seems to move the programming of these registers to a
> different point in time. Was that intentional? If so, please mention it
> in the commit message and describe why that's necessary.
>
> If that was not intentional, it seems like the right place to call this
> would be right after the call to tegra_pcie_enable_controller() in
> tegra_pcie_pm_resume().
>
> Thierry
PCIe pad registers access needs PEX clk and reset enabled, so I moved to
tegra_pcie_enable_ports(). But looking at this carefully I see a pattern
that only per port PCIe register programming is done, however PCIe
pad register spec is for all controller. So the right place would be
tegra_pcie_pm_resume() after enable PEX clk and reset. I will update
in V2

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 29/30] PCI: tegra: Add support for GPIO based PCIe reset
  2019-04-11 17:03 ` [PATCH 29/30] PCI: tegra: Add support for GPIO based PCIe reset Manikanta Maddireddy
@ 2019-04-15 14:20   ` Thierry Reding
  2019-04-15 18:03     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 14:20 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2876 bytes --]

On Thu, Apr 11, 2019 at 10:33:54PM +0530, Manikanta Maddireddy wrote:
> Add support for GPIO based PERST# instead of SFIO mode controller by AFI.
> GPIO number comes from per port PCIe device tree node.
> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 37 +++++++++++++++++++++++++-----
>  1 file changed, 31 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 4a91c9fb3a9d..75873e6627f9 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -17,6 +17,7 @@
>  #include <linux/debugfs.h>
>  #include <linux/delay.h>
>  #include <linux/export.h>
> +#include <linux/gpio.h>
>  #include <linux/interrupt.h>
>  #include <linux/iopoll.h>
>  #include <linux/irq.h>
> @@ -26,6 +27,7 @@
>  #include <linux/module.h>
>  #include <linux/msi.h>
>  #include <linux/of_address.h>
> +#include <linux/of_gpio.h>
>  #include <linux/of_pci.h>
>  #include <linux/of_platform.h>
>  #include <linux/pci.h>
> @@ -406,6 +408,7 @@ struct tegra_pcie_port {
>  
>  	int n_gpios;
>  	int *gpios;
> +	int rst_gpio;

This should be using GPIO descriptor APIs.

Thierry

>  };
>  
>  struct tegra_pcie_bus {
> @@ -589,15 +592,23 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
>  	unsigned long value;
>  
>  	/* pulse reset signal */
> -	value = afi_readl(port->pcie, ctrl);
> -	value &= ~AFI_PEX_CTRL_RST;
> -	afi_writel(port->pcie, value, ctrl);
> +	if (gpio_is_valid(port->rst_gpio)) {
> +		gpio_set_value(port->rst_gpio, 0);
> +	} else {
> +		value = afi_readl(port->pcie, ctrl);
> +		value &= ~AFI_PEX_CTRL_RST;
> +		afi_writel(port->pcie, value, ctrl);
> +	}
>  
>  	usleep_range(1000, 2000);
>  
> -	value = afi_readl(port->pcie, ctrl);
> -	value |= AFI_PEX_CTRL_RST;
> -	afi_writel(port->pcie, value, ctrl);
> +	if (gpio_is_valid(port->rst_gpio)) {
> +		gpio_set_value(port->rst_gpio, 1);
> +	} else {
> +		value = afi_readl(port->pcie, ctrl);
> +		value |= AFI_PEX_CTRL_RST;
> +		afi_writel(port->pcie, value, ctrl);
> +	}
>  }
>  
>  static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
> @@ -2241,6 +2252,20 @@ static int tegra_pcie_parse_plat_dt(struct tegra_pcie_port *port,
>  		}
>  	}
>  
> +	port->rst_gpio = of_get_named_gpio(np, "nvidia,rst-gpio", 0);
> +	if (gpio_is_valid(port->rst_gpio)) {
> +		err = devm_gpio_request(dev, port->rst_gpio, "pex_rst_gpio");
> +		if (err < 0) {
> +			dev_err(dev, "rst_gpio request failed: %d\n", err);
> +			return err;
> +		}
> +		err = gpio_direction_output(port->rst_gpio, 0);
> +		if (err < 0) {
> +			dev_err(dev, "rst_gpio set o/p failed: %d\n", err);
> +			return err;
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 30/30] PCI: tegra: Change link retry log level to INFO
  2019-04-11 17:03 ` [PATCH 30/30] PCI: tegra: Change link retry log level to INFO Manikanta Maddireddy
@ 2019-04-15 14:23   ` Thierry Reding
  2019-04-15 18:05     ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 14:23 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 1138 bytes --]

On Thu, Apr 11, 2019 at 10:33:55PM +0530, Manikanta Maddireddy wrote:
> Link retry log is info log not error, so change it to INFO log level.

The wording here is confusing. The log is clearly error level right now.
Perhaps you meant to say something like this:

    Letting users know that a link is down and in the process of being
    brought up again is informational, not an error condition.

Thierry

> 
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
>  drivers/pci/controller/pci-tegra.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 75873e6627f9..55f8ff4f3e07 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -2461,7 +2461,7 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
>  		} while (--timeout);
>  
>  		if (!timeout) {
> -			dev_err(dev, "link %u down, retrying\n", port->index);
> +			dev_info(dev, "link %u down, retrying\n", port->index);
>  			goto retry;
>  		}
>  
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence
  2019-04-15 14:11     ` Manikanta Maddireddy
@ 2019-04-15 14:30       ` Thierry Reding
  2019-04-15 18:14         ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 14:30 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 9623 bytes --]

On Mon, Apr 15, 2019 at 07:41:21PM +0530, Manikanta Maddireddy wrote:
> 
> On 15-Apr-19 4:31 PM, Thierry Reding wrote:
> > On Thu, Apr 11, 2019 at 10:33:27PM +0530, Manikanta Maddireddy wrote:
> >> PCIe host power up sequence involves programming AFI(AXI to FPCI bridge)
> >> registers first and then PCIe registers. Otherwise AFI register settings
> >> may not latch to PCIe IP.
> >>
> >> PCIe root port starts LTSSM as soon as PCIe xrst is deasserted.
> >> So deassert PCIe xrst after programming PCIe registers.
> >>
> >> Modify PCIe power up sequence as follows,
> >>   - Power ungate PCIe partition
> >>   - Enable AFI clock
> >>   - Deassert AFI reset
> >>   - Program AFI registers
> >>   - Enable PCIe clock
> >>   - Deassert PCIe reset
> >>   - Program PCIe registers
> >>   - Deassert PCIe xrst to start LTSSM
> >>
> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >> ---
> >>  drivers/pci/controller/pci-tegra.c | 73 ++++++++++++++++++------------
> >>  1 file changed, 43 insertions(+), 30 deletions(-)
> >>
> >> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> >> index f4f53d092e00..0bf270bcea34 100644
> >> --- a/drivers/pci/controller/pci-tegra.c
> >> +++ b/drivers/pci/controller/pci-tegra.c
> >> @@ -966,9 +966,6 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
> >>  		}
> >>  	}
> >>  
> >> -	/* take the PCIe interface module out of reset */
> >> -	reset_control_deassert(pcie->pcie_xrst);
> >> -
> >>  	/* finally enable PCIe */
> >>  	value = afi_readl(pcie, AFI_CONFIGURATION);
> >>  	value |= AFI_CONFIGURATION_EN_FPCI;
> >> @@ -997,8 +994,6 @@ static void tegra_pcie_disable_controller(struct tegra_pcie *pcie)
> >>  {
> >>  	int err;
> >>  
> >> -	reset_control_assert(pcie->pcie_xrst);
> >> -
> >>  	if (pcie->soc->program_uphy) {
> >>  		err = tegra_pcie_phy_power_off(pcie);
> >>  		if (err < 0)
> >> @@ -1014,13 +1009,11 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
> >>  	int err;
> >>  
> >>  	reset_control_assert(pcie->afi_rst);
> >> -	reset_control_assert(pcie->pex_rst);
> >>  
> >>  	clk_disable_unprepare(pcie->pll_e);
> >>  	if (soc->has_cml_clk)
> >>  		clk_disable_unprepare(pcie->cml_clk);
> >>  	clk_disable_unprepare(pcie->afi_clk);
> >> -	clk_disable_unprepare(pcie->pex_clk);
> >>  
> >>  	if (!dev->pm_domain)
> >>  		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
> >> @@ -1036,58 +1029,59 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
> >>  	const struct tegra_pcie_soc *soc = pcie->soc;
> >>  	int err;
> >>  
> >> -	reset_control_assert(pcie->pcie_xrst);
> >> -	reset_control_assert(pcie->afi_rst);
> >> -	reset_control_assert(pcie->pex_rst);
> >> -
> >> -	if (!dev->pm_domain)
> >> -		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
> >> -
> > This code was in place to ensure that PCIe was in a known good state
> > before following the power up sequence below. You mentioned elsewhere
> > that there's a regression on Cardhu after applying this series, so
> > perhaps Cardhu relies on the above hunk?
> No, Tegra30 and Tegra20 has legacy PHY which are dependent on PEX clk and rst.
> PHY power on is done in tegra_pcie_enable_controller(), but in this patch I am
> enabling PEX clk and rst after tegra_pcie_enable_controller(). This caused
> regression on Cardhu.
> I realized that sanity test is failing on Cardhu after publishing this series, I will
> fix the issue in V2.
> I believe you are talking about the bootloader(uboot) which can enable
> PCIe partition and reset. To bring the PCIe into good state then we
> have to take care of clocks as well. AFAIK clock_disable() is not added
> because it maintains the refcount and any mismatch in the count
> will thrown warning. I downstream kernel I see pmc driver itself taking
> care of initial state and there after maintaining the state with refcount.
> Since bootloader may or may not enable PCIe, Can we get the state fixed
> in pmc driver instead of fixing it in PCIe driver?

I don't think we can do that. The PMC driver only knows about which
clocks and resets need to be controlled as part of which power partition
if we use power domains. We don't do that on all platforms, so there is
not enough information.

Even if we had that information, we would still not be able to force the
clock off because of the reference counting.

Generally, though, the clock don't matter all that much for getting the
hardware into a good state. All we really care about is that it is put
into reset so that when we take it out again we start from scratch.

If we can verify that we don't need this anymore, I'm fine with taking
it out, though. Perhaps do it in a separate patch to make it easier to
revert if it turns out to be necessary on some platform after all.

Thierry

> >>  	/* enable regulators */
> >>  	err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
> >>  	if (err < 0)
> >>  		dev_err(dev, "failed to enable regulators: %d\n", err);
> >>  
> >> -	if (dev->pm_domain) {
> >> -		err = clk_prepare_enable(pcie->pex_clk);
> >> +	if (!dev->pm_domain) {
> >> +		err = tegra_powergate_power_on(TEGRA_POWERGATE_PCIE);
> >>  		if (err) {
> >> -			dev_err(dev, "failed to enable PEX clock: %d\n", err);
> >> -			return err;
> >> +			dev_err(dev, "power ungate failed: %d\n", err);
> >> +			goto regulator_disable;
> >>  		}
> >> -		reset_control_deassert(pcie->pex_rst);
> >> -	} else {
> >> -		err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
> >> -							pcie->pex_clk,
> >> -							pcie->pex_rst);
> >> +		err = tegra_powergate_remove_clamping(TEGRA_POWERGATE_PCIE);
> >>  		if (err) {
> >> -			dev_err(dev, "powerup sequence failed: %d\n", err);
> >> -			return err;
> >> +			dev_err(dev, "remove clamp failed: %d\n", err);
> >> +			goto powergate;
> >>  		}
> >>  	}
> >>  
> >> -	reset_control_deassert(pcie->afi_rst);
> >> -
> >>  	err = clk_prepare_enable(pcie->afi_clk);
> >>  	if (err < 0) {
> >>  		dev_err(dev, "failed to enable AFI clock: %d\n", err);
> >> -		return err;
> >> +		goto powergate;
> >>  	}
> >>  
> >>  	if (soc->has_cml_clk) {
> >>  		err = clk_prepare_enable(pcie->cml_clk);
> >>  		if (err < 0) {
> >>  			dev_err(dev, "failed to enable CML clock: %d\n", err);
> >> -			return err;
> >> +			goto afi_clk_disable;
> >>  		}
> >>  	}
> >>  
> >>  	err = clk_prepare_enable(pcie->pll_e);
> >>  	if (err < 0) {
> >>  		dev_err(dev, "failed to enable PLLE clock: %d\n", err);
> >> -		return err;
> >> +		goto cml_clk_disable;
> >>  	}
> >>  
> >> +	reset_control_deassert(pcie->afi_rst);
> >> +
> >>  	return 0;
> >> +
> >> +cml_clk_disable:
> >> +	if (soc->has_cml_clk)
> >> +		clk_disable_unprepare(pcie->cml_clk);
> >> +afi_clk_disable:
> >> +	clk_disable_unprepare(pcie->afi_clk);
> >> +powergate:
> >> +	if (!dev->pm_domain)
> >> +		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
> >> +regulator_disable:
> >> +	regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
> >> +	return err;
> >>  }
> >>  
> >>  static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
> >> @@ -2108,7 +2102,12 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
> >>  			 port->index, port->lanes);
> >>  
> >>  		tegra_pcie_port_enable(port);
> >> +	}
> >> +
> >> +	/* Start LTSSM from Tegra side */
> >> +	reset_control_deassert(pcie->pcie_xrst);
> >>  
> >> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
> >>  		if (tegra_pcie_port_check_link(port))
> >>  			continue;
> >>  
> >> @@ -2123,6 +2122,8 @@ static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
> >>  {
> >>  	struct tegra_pcie_port *port, *tmp;
> >>  
> >> +	reset_control_assert(pcie->pcie_xrst);
> >> +
> >>  	list_for_each_entry_safe(port, tmp, &pcie->ports, list)
> >>  		tegra_pcie_port_disable(port);
> >>  }
> >> @@ -2472,6 +2473,9 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
> >>  
> >>  	tegra_pcie_disable_ports(pcie);
> >>  
> >> +	reset_control_assert(pcie->pex_rst);
> >> +	clk_disable_unprepare(pcie->pex_clk);
> >> +
> >>  	if (IS_ENABLED(CONFIG_PCI_MSI))
> >>  		tegra_pcie_disable_msi(pcie);
> >>  
> >> @@ -2501,10 +2505,19 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
> >>  	if (IS_ENABLED(CONFIG_PCI_MSI))
> >>  		tegra_pcie_enable_msi(pcie);
> >>  
> >> +	err = clk_prepare_enable(pcie->pex_clk);
> >> +	if (err) {
> >> +		dev_err(dev, "failed to enable PEX clock: %d\n", err);
> >> +		goto disable_controller;
> >> +	}
> >> +	reset_control_deassert(pcie->pex_rst);
> >> +
> >>  	tegra_pcie_enable_ports(pcie);
> >>  
> >>  	return 0;
> >>  
> >> +disable_controller:
> >> +	tegra_pcie_disable_controller(pcie);
> >>  poweroff:
> >>  	tegra_pcie_power_off(pcie);
> >>  
> > There's quite a bit going on in this patch in general and I find it hard
> > to review because not all the changes seem related to what you described
> > in the commit message.
> >
> > Can you perhaps try to split out the error cleanup changes into a
> > separate patch where it makes sense? It seems to me like at least for
> > tegra_pcie_power_on() we're currently missing all of the cleanup code.
> > You could make that a preparatory patch that goes before this particular
> > patch, which will hopefully make this patch easier to review.
> >
> > Thierry
> Okay, I will prepare new patch for error handling and restrict this patch only for
> sequence correction

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support
  2019-04-15 11:21   ` Thierry Reding
@ 2019-04-15 14:47     ` Manikanta Maddireddy
  2019-04-15 15:36       ` Thierry Reding
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 14:47 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 4:51 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:29PM +0530, Manikanta Maddireddy wrote:
>> Tegra124, 132, 210 and 186 support Gen2 link speed. After PCIe link is up
>> in Gen1, set target link speed as Gen2 and retrain link. Link switches to
>> Gen2 speed if Gen2 capable end point is connected, else link stays in Gen1.
>>
>> Per PCIe 4.0r0.9 sec 7.6.3.7 implementation note, driver need to wait for
>> PCIe LTSSM to come back from recovery before retraining the link.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 61 ++++++++++++++++++++++++++++++
>>  1 file changed, 61 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index a61ce9d475b4..6ccda82735f8 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -191,6 +191,8 @@
>>  #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
>>  #define  RP_LINK_CONTROL_STATUS_LINKSTAT_MASK	0x3fff0000
>>  
>> +#define RP_LINK_CONTROL_STATUS_2		0x000000b0
>> +
>>  #define PADS_CTL_SEL		0x0000009c
>>  
>>  #define PADS_CTL		0x000000a0
>> @@ -2096,6 +2098,62 @@ static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
>>  		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
>>  }
>>  
>> +#define LINK_RETRAIN_TIMEOUT 100000
> This is oddly placed. I think this should go somewhere near the top of
> the file. We already have PME_ACK_TIMEOUT there.
>
> But to be honest, I wouldn't even bother with the #define. This is used
> exactly twice and is much longer to type than the actual number.
I will move #define to top of the file. Macro name tells us what this timeout,
so I will keep the macro intact.
>
>> +
>> +static void tegra_pcie_change_link_speed(struct tegra_pcie *pcie)
>> +{
>> +	struct device *dev = pcie->dev;
>> +	struct tegra_pcie_port *port, *tmp;
>> +	ktime_t deadline;
>> +	u32 val;
> The driver uses u32 value for register values elsewhere. It'd be good to
> stay consistent with that convention.
Do you mean "unsigned long"? I observed this discrepancy, in few places u32 is used
and in some places "unsigned long" is used to store register value. I am continuing
to u32 and we need a new patch to change all "unsigned long" variables to u32
which are used to store register values.
>> +
>> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
>> +		/*
>> +		 * Link Capabilities 2 register is hardwired to 0 in Tegra,
>> +		 * so no need to read it before setting target speed.
>> +		 */
>> +		val = readl(port->base + RP_LINK_CONTROL_STATUS_2);
>> +		val &= ~PCI_EXP_LNKSTA_CLS;
>> +		val |= PCI_EXP_LNKSTA_CLS_5_0GB;
>> +		writel(val, port->base + RP_LINK_CONTROL_STATUS_2);
> The comment says there's no need to read the register, but then the code
> goes on and reads it before modifying it.
>
> That's the first thing that came to my mind. Then I realized that the
> code doesn't actually do anything with the Link Capabilities 2 register
> at all. So what's the deal here? Is it that the Link Capabilities 2
> register being hardwired to 0 means that we can change the target speed?
> Your comment needs to explain more clearly how it relates to the code.
I want to say that "Supported Link Speeds Vector" in "Link Capabilities 2" is not
supported by Tegra, so no need read supported link speed before going for
retrain. I will update the comment in detailed.
>> +
>> +		/*
>> +		 * Poll until link comes back from recovery to avoid race
>> +		 * condition.
>> +		 */
>> +		deadline = ktime_add_us(ktime_get(), LINK_RETRAIN_TIMEOUT);
>> +		for (;;) {
>> +			val = readl(port->base + RP_LINK_CONTROL_STATUS);
>> +			if (!(val & PCI_EXP_LNKSTA_LT))
>> +				break;
>> +			if (ktime_after(ktime_get(), deadline))
>> +				break;
>> +			usleep_range(2000, 3000);
>> +		}
> This would be more compact when written as a while loop. Also I think
> it's more readable to make the !(...) an explicit comparison. Finally,
> use whitespace to improve readability. The above looks very cluttered
> and, in my opinion, makes the code difficult to read. Something like
> the below is much easier to read, in my opinion:
>
> 		while (ktime_before(ktime_get(), deadline)) {
> 			value = readl(port->base + RP_LINK_CONTROL_STATUS);
> 			if ((value & PCI_EXP_LNKSTA_LT) == 0)
> 				break;
>
> 			usleep_range(2000, 3000);
> 		}
I will take care of it in V2
>> +		if (val & PCI_EXP_LNKSTA_LT)
>> +			dev_err(dev, "PCIe port %u link is still in recovery\n",
>> +				port->index);
> Since you're continuing execution, perhaps make this dev_warn()?
I will take care of it in V2
>
>> +
>> +		/* Retrain the link */
>> +		val = readl(port->base + RP_LINK_CONTROL_STATUS);
>> +		val |= PCI_EXP_LNKCTL_RL;
>> +		writel(val, port->base + RP_LINK_CONTROL_STATUS);
>> +
>> +		deadline = ktime_add_us(ktime_get(), LINK_RETRAIN_TIMEOUT);
>> +		for (;;) {
>> +			val = readl(port->base + RP_LINK_CONTROL_STATUS);
>> +			if (!(val & PCI_EXP_LNKSTA_LT))
>> +				break;
>> +			if (ktime_after(ktime_get(), deadline))
>> +				break;
>> +			usleep_range(2000, 3000);
>> +		}
> Same comments as above.
I will take care of it in V2
>
>> +		if (val & PCI_EXP_LNKSTA_LT)
>> +			dev_err(dev, "link retrain of PCIe port %u failed\n",
>> +				port->index);
>> +	}
> Most of the error messages in this file are of the form:
>
> 	"failed to ..."
>
> Perhaps make this:
>
> 	"failed to retrain link of port %u\n"
>
> for consistency?
>
> Thierry
I will take care of it in V2
>
>> +}
>> +
>>  static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>>  {
>>  	struct device *dev = pcie->dev;
>> @@ -2122,6 +2180,9 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>>  		tegra_pcie_port_disable(port);
>>  		tegra_pcie_port_free(port);
>>  	}
>> +
>> +	if (pcie->soc->has_gen2)
>> +		tegra_pcie_change_link_speed(pcie);
>>  }
>>  
>>  static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 05/30] PCI: tegra: Advertise PCIe Advanced Error Reporting (AER) capability
  2019-04-15 11:23   ` Thierry Reding
@ 2019-04-15 14:49     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 14:49 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 4:53 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:30PM +0530, Manikanta Maddireddy wrote:
>> Default root port setting hides AER capability. This patch enables the
>> advertisement of AER capability by root port.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 6ccda82735f8..9ff1a0e2797f 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -180,6 +180,9 @@
>>  #define RP_VEND_XP	0x00000f00
>>  #define  RP_VEND_XP_DL_UP	(1 << 30)
>>  
>> +#define RP_VEND_CTL1	0x00000f48
>> +#define  RP_VEND_CTL1_ERPT	(1 << 13)
>> +
>>  #define RP_VEND_CTL2 0x00000fa8
>>  #define  RP_VEND_CTL2_PCA_ENABLE (1 << 7)
>>  
>> @@ -478,6 +481,16 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
>>  	afi_writel(port->pcie, value, ctrl);
>>  }
>>  
>> +static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
> Why not call this tegra_pcie_enable_aer()? Are you planning on adding a
> lot more overrides to this function? If there aren't too many, you may
> want to just have one small function per feature and drop the comment in
> the function body.
>
> If there's going to be a lot, the above seems okay.
>
> Thierry
Yes, I am going to add more overrides.
>> +{
>> +	u32 value;
>> +
>> +	/* Enable AER capability */
>> +	value = readl(port->base + RP_VEND_CTL1);
>> +	value |= RP_VEND_CTL1_ERPT;
>> +	writel(value, port->base + RP_VEND_CTL1);
>> +}
>> +
>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>>  {
>>  	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
>> @@ -502,6 +515,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>>  		value |= RP_VEND_CTL2_PCA_ENABLE;
>>  		writel(value, port->base + RP_VEND_CTL2);
>>  	}
>> +
>> +	tegra_pcie_enable_rp_features(port);
>>  }
>>  
>>  static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 06/30] PCI: tegra: Program UPHY electrical settings for Tegra210
  2019-04-15 11:29   ` Thierry Reding
@ 2019-04-15 14:55     ` Manikanta Maddireddy
  2019-04-15 15:38       ` Thierry Reding
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 14:55 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 4:59 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:31PM +0530, Manikanta Maddireddy wrote:
>> UPHY electrical programming guidelines are documented in Tegra210 TRM.
>> Program these electrical settings for proper eye diagram in Gen1 and Gen2
>> link speeds.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 100 +++++++++++++++++++++++++++++
>>  1 file changed, 100 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 9ff1a0e2797f..a377245d254d 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -177,6 +177,32 @@
>>  
>>  #define AFI_PEXBIAS_CTRL_0		0x168
>>  
>> +#define RP_ECTL_2_R1	0x00000e84
>> +#define  RP_ECTL_2_R1_RX_CTLE_1C_MASK		0xffff
>> +
>> +#define RP_ECTL_4_R1	0x00000e8c
>> +#define  RP_ECTL_4_R1_RX_CDR_CTRL_1C_MASK	(0xffff << 16)
>> +#define  RP_ECTL_4_R1_RX_CDR_CTRL_1C_SHIFT	16
>> +
>> +#define RP_ECTL_5_R1	0x00000e90
>> +#define  RP_ECTL_5_R1_RX_EQ_CTRL_L_1C_MASK	0xffffffff
>> +
>> +#define RP_ECTL_6_R1	0x00000e94
>> +#define  RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK	0xffffffff
>> +
>> +#define RP_ECTL_2_R2	0x00000ea4
>> +#define  RP_ECTL_2_R2_RX_CTLE_1C_MASK	0xffff
>> +
>> +#define RP_ECTL_4_R2	0x00000eac
>> +#define  RP_ECTL_4_R2_RX_CDR_CTRL_1C_MASK	(0xffff << 16)
>> +#define  RP_ECTL_4_R2_RX_CDR_CTRL_1C_SHIFT	16
>> +
>> +#define RP_ECTL_5_R2	0x00000eb0
>> +#define  RP_ECTL_5_R2_RX_EQ_CTRL_L_1C_MASK	0xffffffff
>> +
>> +#define RP_ECTL_6_R2	0x00000eb4
>> +#define  RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK	0xffffffff
>> +
>>  #define RP_VEND_XP	0x00000f00
>>  #define  RP_VEND_XP_DL_UP	(1 << 30)
>>  
>> @@ -265,6 +291,19 @@ struct tegra_pcie_soc {
>>  	bool has_gen2;
>>  	bool force_pca_enable;
>>  	bool program_uphy;
>> +	struct {
>> +		struct {
>> +			u32 rp_ectl_2_r1;
>> +			u32 rp_ectl_4_r1;
>> +			u32 rp_ectl_5_r1;
>> +			u32 rp_ectl_6_r1;
>> +			u32 rp_ectl_2_r2;
>> +			u32 rp_ectl_4_r2;
>> +			u32 rp_ectl_5_r2;
>> +			u32 rp_ectl_6_r2;
>> +		} regs;
>> +		bool enable;
>> +	} ectl;
>>  };
>>  
>>  static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
>> @@ -491,6 +530,52 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
>>  	writel(value, port->base + RP_VEND_CTL1);
>>  }
>>  
>> +static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
>> +{
>> +	const struct tegra_pcie_soc *soc = port->pcie->soc;
>> +	u32 val;
> u32 value for consistency.
I will take care of it in V2
>
>> +
>> +	val = readl(port->base + RP_ECTL_2_R1);
>> +	val &= ~RP_ECTL_2_R1_RX_CTLE_1C_MASK;
>> +	val |= soc->ectl.regs.rp_ectl_2_r1;
>> +	writel(val, port->base + RP_ECTL_2_R1);
>> +
>> +	val = readl(port->base + RP_ECTL_4_R1);
>> +	val &= ~RP_ECTL_4_R1_RX_CDR_CTRL_1C_MASK;
>> +	val |= soc->ectl.regs.rp_ectl_4_r1 << RP_ECTL_4_R1_RX_CDR_CTRL_1C_SHIFT;
>> +	writel(val, port->base + RP_ECTL_4_R1);
>> +
>> +	val = readl(port->base + RP_ECTL_5_R1);
>> +	val &= ~RP_ECTL_5_R1_RX_EQ_CTRL_L_1C_MASK;
>> +	val |= soc->ectl.regs.rp_ectl_5_r1;
>> +	writel(val, port->base + RP_ECTL_5_R1);
>> +
>> +	val = readl(port->base + RP_ECTL_6_R1);
>> +	val &= ~RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK;
>> +	val |= soc->ectl.regs.rp_ectl_6_r1;
>> +	writel(val, port->base + RP_ECTL_6_R1);
>> +
>> +	val = readl(port->base + RP_ECTL_2_R2);
>> +	val &= ~RP_ECTL_2_R2_RX_CTLE_1C_MASK;
>> +	val |= soc->ectl.regs.rp_ectl_2_r2;
>> +	writel(val, port->base + RP_ECTL_2_R2);
>> +
>> +	val = readl(port->base + RP_ECTL_4_R2);
>> +	val &= ~RP_ECTL_4_R2_RX_CDR_CTRL_1C_MASK;
>> +	val |= soc->ectl.regs.rp_ectl_4_r2 << RP_ECTL_4_R2_RX_CDR_CTRL_1C_SHIFT;
>> +	writel(val, port->base + RP_ECTL_4_R2);
>> +
>> +	val = readl(port->base + RP_ECTL_5_R2);
>> +	val &= ~RP_ECTL_5_R2_RX_EQ_CTRL_L_1C_MASK;
>> +	val |= soc->ectl.regs.rp_ectl_5_r2;
>> +	writel(val, port->base + RP_ECTL_5_R2);
>> +
>> +	val = readl(port->base + RP_ECTL_6_R2);
>> +	val &= ~RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK;
>> +	val |= soc->ectl.regs.rp_ectl_6_r2;
>> +	writel(val, port->base + RP_ECTL_6_R2);
> There are nice macros that help with this nowadays. See the FIELD_*
> macros in include/linux/bitfield.h. However, the above is consistent
> with the rest of the driver, so feel free to leave this as-is.
I will leave it as-is to be inline with rest of the driver.
>> +}
>> +
>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>>  {
>>  	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
>> @@ -517,6 +602,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>>  	}
>>  
>>  	tegra_pcie_enable_rp_features(port);
>> +	if (soc->ectl.enable)
> An empty line above would help declutter this.
I will take care of it in V2
>
>> +		tegra_pcie_program_ectl_settings(port);
>>  }
>>  
>>  static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
>> @@ -2229,6 +2316,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>>  	.has_gen2 = false,
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>> +	.ectl.enable = false,
>>  };
>>  
>>  static const struct tegra_pcie_port_soc tegra30_pcie_ports[] = {
>> @@ -2252,6 +2340,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>>  	.has_gen2 = false,
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>> +	.ectl.enable = false,
>>  };
>>  
>>  static const struct tegra_pcie_soc tegra124_pcie = {
>> @@ -2268,6 +2357,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>>  	.has_gen2 = true,
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>> +	.ectl.enable = false,
>>  };
>>  
>>  static const struct tegra_pcie_soc tegra210_pcie = {
>> @@ -2284,6 +2374,15 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>>  	.has_gen2 = true,
>>  	.force_pca_enable = true,
>>  	.program_uphy = true,
>> +	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>> +	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>> +	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
>> +	.ectl.regs.rp_ectl_6_r1 = 0x00000001,
>> +	.ectl.regs.rp_ectl_2_r2 = 0x0000008f,
>> +	.ectl.regs.rp_ectl_4_r2 = 0x000000c7,
>> +	.ectl.regs.rp_ectl_5_r2 = 0x55010000,
>> +	.ectl.regs.rp_ectl_6_r2 = 0x00000001,
>> +	.ectl.enable = true,
> This should be:
>
> 	.ectl = {
> 		.regs = {
> 			...
> 		}
> 		.enable = true;
> 	},
>
> Do these parameters never differ between board layouts? Are they really
> fixed per SoC generation?
>
> Thierry
Till now all Tegra210 platform have same UPHY settings. They can differ if
some components like MUX are added in UPHY routing, but I haven't seen
such platforms with Tegra210.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 10/30] PCI: tegra: Enable PCIe xclk clock clamping
  2019-04-15 11:37   ` Thierry Reding
@ 2019-04-15 14:58     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 14:58 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 5:07 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:35PM +0530, Manikanta Maddireddy wrote:
>> Enable xclk clock clamping when entering L1. Clamp threshold will
>> determine the time spent waiting for clock module to turn on xclk after
>> signalling it. Default threshold value in Tegra124 and 210 is not enough
> Perhaps spell out Tegra210.
>
>> to turn ON xlck clock. Increase the clamp threshold to meet the clock
> s/ON/on/, s/xlck/xclk/
>
>> module timing in Tegra124 and 210, default threshold value is sufficient
> Spell out Tegra210. Also, maybe make the part after the , a separate
> sentence? And maybe also mention Tegra20 and Tegra30.
>
> Thierry
>
>> in Tegra186.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 28 ++++++++++++++++++++++++++--
>>  1 file changed, 26 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index e40df52e46a7..f785ecae2f6b 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -219,8 +219,14 @@
>>  #define  RP_VEND_CTL2_PCA_ENABLE (1 << 7)
>>  
>>  #define RP_PRIV_MISC	0x00000fe0
>> -#define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0)
>> -#define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0)
>> +#define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT		(0xe << 0)
>> +#define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT		(0xf << 0)
>> +#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD_MASK	(0x7f << 16)
>> +#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD		(0xf << 16)
>> +#define  RP_PRIV_MISC_CTLR_CLK_CLAMP_ENABLE		(1 << 23)
>> +#define  RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD_MASK	(0x7f << 24)
>> +#define  RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD		(0xf << 24)
>> +#define  RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE		(1 << 31)
>>  
>>  #define RP_LINK_CONTROL_STATUS			0x00000090
>>  #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
>> @@ -297,6 +303,7 @@ struct tegra_pcie_soc {
>>  	bool has_gen2;
>>  	bool force_pca_enable;
>>  	bool program_uphy;
>> +	bool update_clamp_threshold;
>>  	struct {
>>  		struct {
>>  			u32 rp_ectl_2_r1;
>> @@ -528,6 +535,7 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
>>  
>>  static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
>>  {
>> +	const struct tegra_pcie_soc *soc = port->pcie->soc;
>>  	u32 value;
>>  
>>  	/* Enable AER capability */
>> @@ -548,6 +556,17 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
>>  	value = readl(port->base + RP_VEND_XP_BIST);
>>  	value |= RP_VEND_XP_BIST_GOTO_L1_L2_AFTER_DLLP_DONE;
>>  	writel(value, port->base + RP_VEND_XP_BIST);
>> +
>> +	value = readl(port->base + RP_PRIV_MISC);
>> +	value |= RP_PRIV_MISC_CTLR_CLK_CLAMP_ENABLE;
>> +	value |= RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE;
>> +	if (soc->update_clamp_threshold) {
> Blank line between the above two.
>
>> +		value &= ~(RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD_MASK |
>> +				RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD_MASK);
>> +		value |= RP_PRIV_MISC_CTLR_CLK_CLAMP_THRESHOLD |
>> +			RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD;
>> +	}
>> +	writel(value, port->base + RP_PRIV_MISC);
> Ditto.
>
> Thierry
I will take care of all the comments in V2

Manikanta
>>  }
>>  
>>  static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
>> @@ -2337,6 +2356,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>>  	.has_gen2 = false,
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>> +	.update_clamp_threshold = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2361,6 +2381,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>>  	.has_gen2 = false,
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>> +	.update_clamp_threshold = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2378,6 +2399,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>>  	.has_gen2 = true,
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>> +	.update_clamp_threshold = true,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2395,6 +2417,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>>  	.has_gen2 = true,
>>  	.force_pca_enable = true,
>>  	.program_uphy = true,
>> +	.update_clamp_threshold = true,
>>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
>> @@ -2427,6 +2450,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>>  	.has_gen2 = true,
>>  	.force_pca_enable = false,
>>  	.program_uphy = false,
>> +	.update_clamp_threshold = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 11/30] PCI: tegra: Increase the deskew retry time
  2019-04-15 11:39   ` Thierry Reding
@ 2019-04-15 14:58     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 14:58 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 5:09 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:36PM +0530, Manikanta Maddireddy wrote:
>> Some times link speed change from Gen2 to Gen1 fails due to instability
> "Sometimes"
>
>> in deskew logic on lane-0 in Tegra210. Increase the deskew retry time
>> to resolve this issue.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 28 ++++++++++++++++++++++++++++
>>  1 file changed, 28 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index f785ecae2f6b..9e61da68cfae 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -209,6 +209,10 @@
>>  #define  RP_VEND_XP_OPPORTUNISTIC_ACK		(1 << 27)
>>  #define  RP_VEND_XP_OPPORTUNISTIC_UPDATEFC	(1 << 28)
>>  
>> +#define RP_VEND_CTL0	0x00000f44
>> +#define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK	(0xf << 12)
>> +#define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH	(0x9 << 12)
>> +
>>  #define RP_VEND_CTL1	0x00000f48
>>  #define  RP_VEND_CTL1_ERPT	(1 << 13)
>>  
>> @@ -304,6 +308,7 @@ struct tegra_pcie_soc {
>>  	bool force_pca_enable;
>>  	bool program_uphy;
>>  	bool update_clamp_threshold;
>> +	bool program_deskew_time;
>>  	struct {
>>  		struct {
>>  			u32 rp_ectl_2_r1;
>> @@ -615,6 +620,23 @@ static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
>>  	writel(val, port->base + RP_ECTL_6_R2);
>>  }
>>  
>> +static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>> +{
>> +	const struct tegra_pcie_soc *soc = port->pcie->soc;
>> +	u32 value;
>> +
>> +	/*
>> +	 * Tune deskew retry time to take care of Gen2 -> Gen1
>> +	 * link speed change error in corner cases
>> +	 */
>> +	if (soc->program_deskew_time) {
>> +		value = readl(port->base + RP_VEND_CTL0);
>> +		value &= ~RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK;
>> +		value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH;
>> +		writel(value, port->base + RP_VEND_CTL0);
>> +	}
>> +}
>> +
>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>>  {
>>  	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
>> @@ -643,6 +665,7 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>>  	tegra_pcie_enable_rp_features(port);
>>  	if (soc->ectl.enable)
>>  		tegra_pcie_program_ectl_settings(port);
>> +	tegra_pcie_apply_sw_fixup(port);
> Blank line between the above two for readability.
>
> Thierry
I will take care of all the comments in V2

Manikanta
>
>>  }
>>  
>>  static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
>> @@ -2357,6 +2380,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = false,
>> +	.program_deskew_time = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2382,6 +2406,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = false,
>> +	.program_deskew_time = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2400,6 +2425,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>>  	.force_pca_enable = false,
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = true,
>> +	.program_deskew_time = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2418,6 +2444,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>>  	.force_pca_enable = true,
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = true,
>> +	.program_deskew_time = true,
>>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
>> @@ -2451,6 +2478,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>>  	.force_pca_enable = false,
>>  	.program_uphy = false,
>>  	.update_clamp_threshold = false,
>> +	.program_deskew_time = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations
  2019-04-15 11:45   ` Thierry Reding
@ 2019-04-15 15:02     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:02 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 5:15 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:37PM +0530, Manikanta Maddireddy wrote:
>> The logic which blocks read requests till AFI gets ACK for all outstanding
>> MC writes does not behave correctly when number of outstanding write
>> becomes more than 32 in Tegra124 and 132.
>>
>> SW fixup to prevent this issue is to limit outstanding posted writes and
>> tweak updateFC timer threshold.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 34 ++++++++++++++++++++++++++++++
>>  1 file changed, 34 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 9e61da68cfae..b74408eeb367 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -178,6 +178,13 @@
>>  
>>  #define AFI_PEXBIAS_CTRL_0		0x168
>>  
>> +#define RP_PRIV_XP_DL		0x00000494
>> +#define  RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD	(0x1ff << 1)
>> +
>> +#define RP_RX_HDR_LIMIT		0x00000e00
>> +#define  RP_RX_HDR_LIMIT_PW_MASK	(0xff << 8)
>> +#define  RP_RX_HDR_LIMIT_PW		(0x0e << 8)
>> +
>>  #define RP_ECTL_2_R1	0x00000e84
>>  #define  RP_ECTL_2_R1_RX_CTLE_1C_MASK		0xffff
>>  
>> @@ -208,6 +215,7 @@
>>  #define  RP_VEND_XP_DL_UP			(1 << 30)
>>  #define  RP_VEND_XP_OPPORTUNISTIC_ACK		(1 << 27)
>>  #define  RP_VEND_XP_OPPORTUNISTIC_UPDATEFC	(1 << 28)
>> +#define  RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK	(0xff << 18)
>>  
>>  #define RP_VEND_CTL0	0x00000f44
>>  #define  RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK	(0xf << 12)
>> @@ -300,6 +308,7 @@ struct tegra_pcie_soc {
>>  	u32 tx_ref_sel;
>>  	u32 pads_refclk_cfg0;
>>  	u32 pads_refclk_cfg1;
>> +	u32 update_fc_val;
> Shouldn't this be something like "update_fc_threshold" since the mask
> defined above is for a field named UPDATE_FC_THRESHOLD?
>
>>  	bool has_pex_clkreq_en;
>>  	bool has_pex_bias_ctrl;
>>  	bool has_intr_prsnt_sense;
>> @@ -309,6 +318,7 @@ struct tegra_pcie_soc {
>>  	bool program_uphy;
>>  	bool update_clamp_threshold;
>>  	bool program_deskew_time;
>> +	bool raw_violation_fixup;
>>  	struct {
>>  		struct {
>>  			u32 rp_ectl_2_r1;
>> @@ -635,6 +645,23 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>>  		value |= RP_VEND_CTL0_DSK_RST_PULSE_WIDTH;
>>  		writel(value, port->base + RP_VEND_CTL0);
>>  	}
>> +
>> +	/* Fixup for read after write violation in T124 & T132 platforms */
> No need to mention the SoC generations here, it's already implied by the
> per-SoC flag.
>
> Thierry
I will take care of both the comments in V2

Manikanta
>
>> +	if (soc->raw_violation_fixup) {
>> +		value = readl(port->base + RP_RX_HDR_LIMIT);
>> +		value &= ~RP_RX_HDR_LIMIT_PW_MASK;
>> +		value |= RP_RX_HDR_LIMIT_PW;
>> +		writel(value, port->base + RP_RX_HDR_LIMIT);
>> +
>> +		value = readl(port->base + RP_PRIV_XP_DL);
>> +		value |= RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD;
>> +		writel(value, port->base + RP_PRIV_XP_DL);
>> +
>> +		value = readl(port->base + RP_VEND_XP);
>> +		value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK;
>> +		value |= soc->update_fc_val;
>> +		writel(value, port->base + RP_VEND_XP);
>> +	}
>>  }
>>  
>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>> @@ -2381,6 +2408,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = false,
>>  	.program_deskew_time = false,
>> +	.raw_violation_fixup = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2407,6 +2435,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = false,
>>  	.program_deskew_time = false,
>> +	.raw_violation_fixup = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2417,6 +2446,8 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>>  	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
>>  	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
>>  	.pads_refclk_cfg0 = 0x44ac44ac,
>> +	/* FC threshold is bit[25:18] */
>> +	.update_fc_val = 0x03fc0000,
>
>
>>  	.has_pex_clkreq_en = true,
>>  	.has_pex_bias_ctrl = true,
>>  	.has_intr_prsnt_sense = true,
>> @@ -2426,6 +2457,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = true,
>>  	.program_deskew_time = false,
>> +	.raw_violation_fixup = true,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2445,6 +2477,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>>  	.program_uphy = true,
>>  	.update_clamp_threshold = true,
>>  	.program_deskew_time = true,
>> +	.raw_violation_fixup = false,
>>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
>> @@ -2479,6 +2512,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>>  	.program_uphy = false,
>>  	.update_clamp_threshold = false,
>>  	.program_deskew_time = false,
>> +	.raw_violation_fixup = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 13/30] PCI: tegra: Update flow control threshold in Tegra210
  2019-04-15 11:47   ` Thierry Reding
@ 2019-04-15 15:05     ` Manikanta Maddireddy
  2019-04-23  9:27       ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 5:17 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:38PM +0530, Manikanta Maddireddy wrote:
>> Recommended update FC threshold in Tegra210 is 0x60 for best performance
>> of x1 link. Setting this to 0x60 provides the best balance between number
>> of UpdateFC and read data sent over the link.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
> Looks to me like part of this patch ended up in 12/30?
>
> Thierry
Ok, I will squash 12/30 & 13/30 and clearly mentioned what it means for T124 and T210
in commit message.
>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index b74408eeb367..7dc728cc5f51 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -319,6 +319,7 @@ struct tegra_pcie_soc {
>>  	bool update_clamp_threshold;
>>  	bool program_deskew_time;
>>  	bool raw_violation_fixup;
>> +	bool update_fc_threshold;
>>  	struct {
>>  		struct {
>>  			u32 rp_ectl_2_r1;
>> @@ -662,6 +663,13 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>>  		value |= soc->update_fc_val;
>>  		writel(value, port->base + RP_VEND_XP);
>>  	}
>> +
>> +	if (soc->update_fc_threshold) {
>> +		value = readl(port->base + RP_VEND_XP);
>> +		value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK;
>> +		value |= soc->update_fc_val;
>> +		writel(value, port->base + RP_VEND_XP);
>> +	}
>>  }
>>  
>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>> @@ -2409,6 +2417,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>>  	.update_clamp_threshold = false,
>>  	.program_deskew_time = false,
>>  	.raw_violation_fixup = false,
>> +	.update_fc_threshold = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2436,6 +2445,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>>  	.update_clamp_threshold = false,
>>  	.program_deskew_time = false,
>>  	.raw_violation_fixup = false,
>> +	.update_fc_threshold = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2458,6 +2468,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>>  	.update_clamp_threshold = true,
>>  	.program_deskew_time = false,
>>  	.raw_violation_fixup = true,
>> +	.update_fc_threshold = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> @@ -2468,6 +2479,8 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>>  	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
>>  	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
>>  	.pads_refclk_cfg0 = 0x90b890b8,
>> +	/* FC threshold is bit[25:18] */
>> +	.update_fc_val = 0x01800000,
>>  	.has_pex_clkreq_en = true,
>>  	.has_pex_bias_ctrl = true,
>>  	.has_intr_prsnt_sense = true,
>> @@ -2478,6 +2491,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>>  	.update_clamp_threshold = true,
>>  	.program_deskew_time = true,
>>  	.raw_violation_fixup = false,
>> +	.update_fc_threshold = true,
>>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
>> @@ -2513,6 +2527,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>>  	.update_clamp_threshold = false,
>>  	.program_deskew_time = false,
>>  	.raw_violation_fixup = false,
>> +	.update_fc_threshold = false,
>>  	.ectl.enable = false,
>>  };
>>  
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up
  2019-04-15 11:52   ` Thierry Reding
@ 2019-04-15 15:12     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:12 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 5:22 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:39PM +0530, Manikanta Maddireddy wrote:
>> Some of the legacy PCIe endpoints doesn't enumerate if root port advertises
>> both Gen-1 and Gen-2 speeds. Hence, the strategy followed here is to
>> initially advertise only Gen-1 and after link is up, retrain link to Gen-2
>> speed.
>>
>> Following two cards display this behaviour,
>>   - Fusion HDTV 5 Express card
>>   - IOGear SIL - PCIE - SATA card
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 11 +++++++++++
>>  1 file changed, 11 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 7dc728cc5f51..7e24eac12668 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -670,6 +670,17 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>>  		value |= soc->update_fc_val;
>>  		writel(value, port->base + RP_VEND_XP);
>>  	}
>> +
>> +	/*
>> +	 * PCIe link doesn't come up with few legacy PCIe endpoints
>> +	 * if root port advertises both Gen-1 and Gen-2 speeds.
>> +	 * Hence, the strategy followed here is to initially advertise
>> +	 * only Gen-1 and after link is up, retrain link to Gen-2 speed
>> +	 */
>> +	value = readl(port->base + RP_LINK_CONTROL_STATUS_2);
>> +	value &= ~PCI_EXP_LNKSTA_CLS;
>> +	value |= PCI_EXP_LNKSTA_CLS_2_5GB;
>> +	writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
>>  }
>>  
>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> This looks like it's related to the earlier patch that adds support for
> retraining the link at Gen-2. As such, I think the two patches should be
> moved closer together to make that more obvious.
>
> Also, perhaps even the order needs to be changed. For example, if the
> earlier patch enables advertisement of Gen-2, then there will be a
> period of 10 or so patches where the above devices wouldn't work. So if
> this fixes an error introduced by an earlier patch, it makes sense to
> resort the patches so that we first fix the potential error and then
> introduce the code that would cause the error to happen.
>
> Thierry
Both are independent patches. Even though HW init Target speed is Gen2, Tegra
PCIe gets the link up in Gen1 only because HW autonomous speed change feature
is not available. After link up in Gen1 SW has to retrain the link to Gen2, which is
done in 4/30. Current patch changes the HW init value of Target speed to Gen1,
to support the cards mentioned in commit message.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 15/30] PCI: tegra: Fix PLLE powerdown issue due to CLKREQ# signal
  2019-04-15 13:17   ` Thierry Reding
@ 2019-04-15 15:14     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:14 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 6:47 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:40PM +0530, Manikanta Maddireddy wrote:
>> Disable controllers which failed to link up and configure CLKREQ# signals
>> of these controllers as GPIO. This is required to avoid CLKREQ# signal of
>> inactive controllers interfering with PLLE powerdown sequence.
>>
>> PCIE_CLKREQ_GPIO bits are defined only in Tegra186, however programming
>> these bits in other SoCs doesn't cause any side effects. Program these
>> bits for all Tegra SoCs to avoid conditional check.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 16 +++++++++++++++-
>>  1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 7e24eac12668..8e5fdc8ce3d6 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -160,6 +160,8 @@
>>  #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211	(0x1 << 20)
>>  #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411	(0x2 << 20)
>>  #define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_111	(0x2 << 20)
>> +#define  AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(x)		(1 << ((x) + 29))
>> +#define  AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO_ALL		(0x7 << 29)
>>  
>>  #define AFI_FUSE			0x104
>>  #define  AFI_FUSE_PCIE_T0_GEN2_DIS	(1 << 2)
>> @@ -733,6 +735,15 @@ static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
>>  
>>  	value &= ~AFI_PEX_CTRL_REFCLK_EN;
>>  	afi_writel(port->pcie, value, ctrl);
>> +
>> +	/*
>> +	 * disable PCIe device and set CLKREQ# as gpio
> Did you mean to say "PCIe port"? Also, s/gpio/GPIO/, and you can make
> use of 78 characters. With those changes, the above may just fit on one
> line.
>
> Thierry
I will take care of it in V2.

Manikanta
>
>> +	 * to allow PLLE power down
>> +	 */
>> +	value = afi_readl(port->pcie, AFI_PCIE_CONFIG);
>> +	value |= AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
>> +	value |= AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(port->index);
>> +	afi_writel(port->pcie, value, AFI_PCIE_CONFIG);
>>  }
>>  
>>  static void tegra_pcie_port_free(struct tegra_pcie_port *port)
>> @@ -1147,9 +1158,12 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
>>  	value = afi_readl(pcie, AFI_PCIE_CONFIG);
>>  	value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK;
>>  	value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config;
>> +	value |= AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO_ALL;
>>  
>> -	list_for_each_entry(port, &pcie->ports, list)
>> +	list_for_each_entry(port, &pcie->ports, list) {
>>  		value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
>> +		value &= ~AFI_PCIE_CONFIG_PCIE_CLKREQ_GPIO(port->index);
>> +	}
>>  
>>  	afi_writel(pcie, value, AFI_PCIE_CONFIG);
>>  
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 17/30] PCI: tegra: Use switch statements in tegra_pcie_isr()
  2019-04-15 13:25   ` Thierry Reding
@ 2019-04-15 15:25     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:25 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 6:55 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:42PM +0530, Manikanta Maddireddy wrote:
>> Use switch statements in tegra_pcie_isr() for better code readability.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 37 ++++++++++++++++--------------
>>  1 file changed, 20 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index cdaaf13a9fd7..cf2715065a53 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -842,36 +842,39 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>>  	};
>>  	struct tegra_pcie *pcie = arg;
>>  	struct device *dev = pcie->dev;
>> -	u32 code, signature;
>> +	u32 code, signature, fpci;
>> +	u64 address;
>>  
>>  	code = afi_readl(pcie, AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
>>  	signature = afi_readl(pcie, AFI_INTR_SIGNATURE);
>>  	afi_writel(pcie, 0, AFI_INTR_CODE);
>>  
>> -	if (code == AFI_INTR_LEGACY)
>> -		return IRQ_NONE;
>> -
>>  	if (code >= ARRAY_SIZE(err_msg))
>> -		code = 0;
>> +		return IRQ_NONE;
>>  
>> +	switch (code) {
>> +	case AFI_INTR_LEGACY:
>> +		return IRQ_NONE;
>>  	/*
>>  	 * do not pollute kernel log with master abort reports since they
>>  	 * happen a lot during enumeration
>>  	 */
>> -	if (code == AFI_INTR_MASTER_ABORT)
>> +	case AFI_INTR_MASTER_ABORT:
>>  		dev_dbg(dev, "%s, signature: %08x\n", err_msg[code], signature);
>> -	else
>> +		fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
>> +		address = (u64)fpci << 32 | (signature & 0xfffffffc);
>> +		dev_dbg(dev, "  FPCI address: %10llx\n", address);
>> +		break;
>> +	case AFI_INTR_TARGET_ABORT:
>> +	case AFI_INTR_FPCI_DECODE_ERROR:
>>  		dev_err(dev, "%s, signature: %08x\n", err_msg[code], signature);
>> -
>> -	if (code == AFI_INTR_TARGET_ABORT || code == AFI_INTR_MASTER_ABORT ||
>> -	    code == AFI_INTR_FPCI_DECODE_ERROR) {
>> -		u32 fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
>> -		u64 address = (u64)fpci << 32 | (signature & 0xfffffffc);
>> -
>> -		if (code == AFI_INTR_MASTER_ABORT)
>> -			dev_dbg(dev, "  FPCI address: %10llx\n", address);
>> -		else
>> -			dev_err(dev, "  FPCI address: %10llx\n", address);
>> +		fpci = afi_readl(pcie, AFI_UPPER_FPCI_ADDRESS) & 0xff;
>> +		address = (u64)fpci << 32 | (signature & 0xfffffffc);
>> +		dev_err(dev, "  FPCI address: %10llx\n", address);
>> +		break;
>> +	default:
>> +		dev_err(dev, "%s, signature: %08x\n", err_msg[code], signature);
>> +		break;
>>  	}
>>  
>>  	return IRQ_HANDLED;
> I don't think this improves readability. It does duplicate some code and
> is actually longer than the previous variant, so I don't think this adds
> value.
>
> Thierry
There is multiple conditions check in single "if" statement and there is if-else statement
inside "if", so I felt switch case makes it more clear. I agree there is duplicate code.

Manikanta

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 21/30] PCI: tegra: Add "pci" type check before parsing child device tree node
  2019-04-15 13:37   ` Thierry Reding
@ 2019-04-15 15:30     ` Manikanta Maddireddy
  2019-04-15 15:42       ` Thierry Reding
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:30 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 7:07 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:46PM +0530, Manikanta Maddireddy wrote:
>> Each root port is added as a child device tree node of PCIe controller
>> node. These child nodes are parsed using open firmware PCI bus accessor
>> functions. If the child node is not of "pci" type then device tree
>> parsing fails. Add "pci" type check before parsing child device tree node.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 3 +++
>>  1 file changed, 3 insertions(+)
> Erm... what is the use-case that you're trying to support? Why would we
> ever have children nodes that are not of type "pci"?
>
> Thierry
In downstream kernel we have "prod-settings" node as one of the child nodes.
Even though we are not supporting this in upstream kernel, I believe this
check is good to have.

Manikanta
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 8fdc7934d4c9..d08a63132c77 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -2197,6 +2197,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>>  		unsigned int index;
>>  		u32 value;
>>  
>> +		if (!of_node_is_type(port, "pci"))
>> +			continue;
>> +
>>  		err = of_pci_get_devfn(port);
>>  		if (err < 0) {
>>  			dev_err(dev, "failed to parse address: %d\n", err);
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support
  2019-04-15 14:47     ` Manikanta Maddireddy
@ 2019-04-15 15:36       ` Thierry Reding
  2019-04-15 15:53         ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 15:36 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2717 bytes --]

On Mon, Apr 15, 2019 at 08:17:02PM +0530, Manikanta Maddireddy wrote:
> 
> 
> On 15-Apr-19 4:51 PM, Thierry Reding wrote:
> > On Thu, Apr 11, 2019 at 10:33:29PM +0530, Manikanta Maddireddy wrote:
> >> Tegra124, 132, 210 and 186 support Gen2 link speed. After PCIe link is up
> >> in Gen1, set target link speed as Gen2 and retrain link. Link switches to
> >> Gen2 speed if Gen2 capable end point is connected, else link stays in Gen1.
> >>
> >> Per PCIe 4.0r0.9 sec 7.6.3.7 implementation note, driver need to wait for
> >> PCIe LTSSM to come back from recovery before retraining the link.
> >>
> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >> ---
> >>  drivers/pci/controller/pci-tegra.c | 61 ++++++++++++++++++++++++++++++
> >>  1 file changed, 61 insertions(+)
> >>
> >> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> >> index a61ce9d475b4..6ccda82735f8 100644
> >> --- a/drivers/pci/controller/pci-tegra.c
> >> +++ b/drivers/pci/controller/pci-tegra.c
> >> @@ -191,6 +191,8 @@
> >>  #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
> >>  #define  RP_LINK_CONTROL_STATUS_LINKSTAT_MASK	0x3fff0000
> >>  
> >> +#define RP_LINK_CONTROL_STATUS_2		0x000000b0
> >> +
> >>  #define PADS_CTL_SEL		0x0000009c
> >>  
> >>  #define PADS_CTL		0x000000a0
> >> @@ -2096,6 +2098,62 @@ static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
> >>  		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
> >>  }
> >>  
> >> +#define LINK_RETRAIN_TIMEOUT 100000
> > This is oddly placed. I think this should go somewhere near the top of
> > the file. We already have PME_ACK_TIMEOUT there.
> >
> > But to be honest, I wouldn't even bother with the #define. This is used
> > exactly twice and is much longer to type than the actual number.
> I will move #define to top of the file. Macro name tells us what this timeout,
> so I will keep the macro intact.
> >
> >> +
> >> +static void tegra_pcie_change_link_speed(struct tegra_pcie *pcie)
> >> +{
> >> +	struct device *dev = pcie->dev;
> >> +	struct tegra_pcie_port *port, *tmp;
> >> +	ktime_t deadline;
> >> +	u32 val;
> > The driver uses u32 value for register values elsewhere. It'd be good to
> > stay consistent with that convention.
> Do you mean "unsigned long"? I observed this discrepancy, in few places u32 is used
> and in some places "unsigned long" is used to store register value. I am continuing
> to u32 and we need a new patch to change all "unsigned long" variables to u32
> which are used to store register values.

I meant to say that we spell out "value" everywhere else and don't use
the abbreviation.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 06/30] PCI: tegra: Program UPHY electrical settings for Tegra210
  2019-04-15 14:55     ` Manikanta Maddireddy
@ 2019-04-15 15:38       ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 15:38 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 7395 bytes --]

On Mon, Apr 15, 2019 at 08:25:48PM +0530, Manikanta Maddireddy wrote:
> 
> 
> On 15-Apr-19 4:59 PM, Thierry Reding wrote:
> > On Thu, Apr 11, 2019 at 10:33:31PM +0530, Manikanta Maddireddy wrote:
> >> UPHY electrical programming guidelines are documented in Tegra210 TRM.
> >> Program these electrical settings for proper eye diagram in Gen1 and Gen2
> >> link speeds.
> >>
> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >> ---
> >>  drivers/pci/controller/pci-tegra.c | 100 +++++++++++++++++++++++++++++
> >>  1 file changed, 100 insertions(+)
> >>
> >> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> >> index 9ff1a0e2797f..a377245d254d 100644
> >> --- a/drivers/pci/controller/pci-tegra.c
> >> +++ b/drivers/pci/controller/pci-tegra.c
> >> @@ -177,6 +177,32 @@
> >>  
> >>  #define AFI_PEXBIAS_CTRL_0		0x168
> >>  
> >> +#define RP_ECTL_2_R1	0x00000e84
> >> +#define  RP_ECTL_2_R1_RX_CTLE_1C_MASK		0xffff
> >> +
> >> +#define RP_ECTL_4_R1	0x00000e8c
> >> +#define  RP_ECTL_4_R1_RX_CDR_CTRL_1C_MASK	(0xffff << 16)
> >> +#define  RP_ECTL_4_R1_RX_CDR_CTRL_1C_SHIFT	16
> >> +
> >> +#define RP_ECTL_5_R1	0x00000e90
> >> +#define  RP_ECTL_5_R1_RX_EQ_CTRL_L_1C_MASK	0xffffffff
> >> +
> >> +#define RP_ECTL_6_R1	0x00000e94
> >> +#define  RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK	0xffffffff
> >> +
> >> +#define RP_ECTL_2_R2	0x00000ea4
> >> +#define  RP_ECTL_2_R2_RX_CTLE_1C_MASK	0xffff
> >> +
> >> +#define RP_ECTL_4_R2	0x00000eac
> >> +#define  RP_ECTL_4_R2_RX_CDR_CTRL_1C_MASK	(0xffff << 16)
> >> +#define  RP_ECTL_4_R2_RX_CDR_CTRL_1C_SHIFT	16
> >> +
> >> +#define RP_ECTL_5_R2	0x00000eb0
> >> +#define  RP_ECTL_5_R2_RX_EQ_CTRL_L_1C_MASK	0xffffffff
> >> +
> >> +#define RP_ECTL_6_R2	0x00000eb4
> >> +#define  RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK	0xffffffff
> >> +
> >>  #define RP_VEND_XP	0x00000f00
> >>  #define  RP_VEND_XP_DL_UP	(1 << 30)
> >>  
> >> @@ -265,6 +291,19 @@ struct tegra_pcie_soc {
> >>  	bool has_gen2;
> >>  	bool force_pca_enable;
> >>  	bool program_uphy;
> >> +	struct {
> >> +		struct {
> >> +			u32 rp_ectl_2_r1;
> >> +			u32 rp_ectl_4_r1;
> >> +			u32 rp_ectl_5_r1;
> >> +			u32 rp_ectl_6_r1;
> >> +			u32 rp_ectl_2_r2;
> >> +			u32 rp_ectl_4_r2;
> >> +			u32 rp_ectl_5_r2;
> >> +			u32 rp_ectl_6_r2;
> >> +		} regs;
> >> +		bool enable;
> >> +	} ectl;
> >>  };
> >>  
> >>  static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
> >> @@ -491,6 +530,52 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
> >>  	writel(value, port->base + RP_VEND_CTL1);
> >>  }
> >>  
> >> +static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
> >> +{
> >> +	const struct tegra_pcie_soc *soc = port->pcie->soc;
> >> +	u32 val;
> > u32 value for consistency.
> I will take care of it in V2
> >
> >> +
> >> +	val = readl(port->base + RP_ECTL_2_R1);
> >> +	val &= ~RP_ECTL_2_R1_RX_CTLE_1C_MASK;
> >> +	val |= soc->ectl.regs.rp_ectl_2_r1;
> >> +	writel(val, port->base + RP_ECTL_2_R1);
> >> +
> >> +	val = readl(port->base + RP_ECTL_4_R1);
> >> +	val &= ~RP_ECTL_4_R1_RX_CDR_CTRL_1C_MASK;
> >> +	val |= soc->ectl.regs.rp_ectl_4_r1 << RP_ECTL_4_R1_RX_CDR_CTRL_1C_SHIFT;
> >> +	writel(val, port->base + RP_ECTL_4_R1);
> >> +
> >> +	val = readl(port->base + RP_ECTL_5_R1);
> >> +	val &= ~RP_ECTL_5_R1_RX_EQ_CTRL_L_1C_MASK;
> >> +	val |= soc->ectl.regs.rp_ectl_5_r1;
> >> +	writel(val, port->base + RP_ECTL_5_R1);
> >> +
> >> +	val = readl(port->base + RP_ECTL_6_R1);
> >> +	val &= ~RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK;
> >> +	val |= soc->ectl.regs.rp_ectl_6_r1;
> >> +	writel(val, port->base + RP_ECTL_6_R1);
> >> +
> >> +	val = readl(port->base + RP_ECTL_2_R2);
> >> +	val &= ~RP_ECTL_2_R2_RX_CTLE_1C_MASK;
> >> +	val |= soc->ectl.regs.rp_ectl_2_r2;
> >> +	writel(val, port->base + RP_ECTL_2_R2);
> >> +
> >> +	val = readl(port->base + RP_ECTL_4_R2);
> >> +	val &= ~RP_ECTL_4_R2_RX_CDR_CTRL_1C_MASK;
> >> +	val |= soc->ectl.regs.rp_ectl_4_r2 << RP_ECTL_4_R2_RX_CDR_CTRL_1C_SHIFT;
> >> +	writel(val, port->base + RP_ECTL_4_R2);
> >> +
> >> +	val = readl(port->base + RP_ECTL_5_R2);
> >> +	val &= ~RP_ECTL_5_R2_RX_EQ_CTRL_L_1C_MASK;
> >> +	val |= soc->ectl.regs.rp_ectl_5_r2;
> >> +	writel(val, port->base + RP_ECTL_5_R2);
> >> +
> >> +	val = readl(port->base + RP_ECTL_6_R2);
> >> +	val &= ~RP_ECTL_6_R2_RX_EQ_CTRL_H_1C_MASK;
> >> +	val |= soc->ectl.regs.rp_ectl_6_r2;
> >> +	writel(val, port->base + RP_ECTL_6_R2);
> > There are nice macros that help with this nowadays. See the FIELD_*
> > macros in include/linux/bitfield.h. However, the above is consistent
> > with the rest of the driver, so feel free to leave this as-is.
> I will leave it as-is to be inline with rest of the driver.
> >> +}
> >> +
> >>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> >>  {
> >>  	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
> >> @@ -517,6 +602,8 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
> >>  	}
> >>  
> >>  	tegra_pcie_enable_rp_features(port);
> >> +	if (soc->ectl.enable)
> > An empty line above would help declutter this.
> I will take care of it in V2
> >
> >> +		tegra_pcie_program_ectl_settings(port);
> >>  }
> >>  
> >>  static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
> >> @@ -2229,6 +2316,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
> >>  	.has_gen2 = false,
> >>  	.force_pca_enable = false,
> >>  	.program_uphy = true,
> >> +	.ectl.enable = false,
> >>  };
> >>  
> >>  static const struct tegra_pcie_port_soc tegra30_pcie_ports[] = {
> >> @@ -2252,6 +2340,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
> >>  	.has_gen2 = false,
> >>  	.force_pca_enable = false,
> >>  	.program_uphy = true,
> >> +	.ectl.enable = false,
> >>  };
> >>  
> >>  static const struct tegra_pcie_soc tegra124_pcie = {
> >> @@ -2268,6 +2357,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
> >>  	.has_gen2 = true,
> >>  	.force_pca_enable = false,
> >>  	.program_uphy = true,
> >> +	.ectl.enable = false,
> >>  };
> >>  
> >>  static const struct tegra_pcie_soc tegra210_pcie = {
> >> @@ -2284,6 +2374,15 @@ static const struct tegra_pcie_soc tegra210_pcie = {
> >>  	.has_gen2 = true,
> >>  	.force_pca_enable = true,
> >>  	.program_uphy = true,
> >> +	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
> >> +	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
> >> +	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
> >> +	.ectl.regs.rp_ectl_6_r1 = 0x00000001,
> >> +	.ectl.regs.rp_ectl_2_r2 = 0x0000008f,
> >> +	.ectl.regs.rp_ectl_4_r2 = 0x000000c7,
> >> +	.ectl.regs.rp_ectl_5_r2 = 0x55010000,
> >> +	.ectl.regs.rp_ectl_6_r2 = 0x00000001,
> >> +	.ectl.enable = true,
> > This should be:
> >
> > 	.ectl = {
> > 		.regs = {
> > 			...
> > 		}
> > 		.enable = true;
> > 	},
> >
> > Do these parameters never differ between board layouts? Are they really
> > fixed per SoC generation?
> >
> > Thierry
> Till now all Tegra210 platform have same UPHY settings. They can differ if
> some components like MUX are added in UPHY routing, but I haven't seen
> such platforms with Tegra210.

Okay, let's leave it as SoC data for now. If we ever need to override
per board we can add that as a backward-compatible change.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 21/30] PCI: tegra: Add "pci" type check before parsing child device tree node
  2019-04-15 15:30     ` Manikanta Maddireddy
@ 2019-04-15 15:42       ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-15 15:42 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 1236 bytes --]

On Mon, Apr 15, 2019 at 09:00:58PM +0530, Manikanta Maddireddy wrote:
> 
> 
> On 15-Apr-19 7:07 PM, Thierry Reding wrote:
> > On Thu, Apr 11, 2019 at 10:33:46PM +0530, Manikanta Maddireddy wrote:
> >> Each root port is added as a child device tree node of PCIe controller
> >> node. These child nodes are parsed using open firmware PCI bus accessor
> >> functions. If the child node is not of "pci" type then device tree
> >> parsing fails. Add "pci" type check before parsing child device tree node.
> >>
> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >> ---
> >>  drivers/pci/controller/pci-tegra.c | 3 +++
> >>  1 file changed, 3 insertions(+)
> > Erm... what is the use-case that you're trying to support? Why would we
> > ever have children nodes that are not of type "pci"?
> >
> > Thierry
> In downstream kernel we have "prod-settings" node as one of the child nodes.
> Even though we are not supporting this in upstream kernel, I believe this
> check is good to have.

We don't have prod-settings upstream and for good reason. There's no
need to add this check in upstream. We can carry the change downstream
until we've moved away from prod-settings downstream as well.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-15 14:04           ` Bjorn Helgaas
@ 2019-04-15 15:43             ` Manikanta Maddireddy
  2019-04-23 20:24               ` Bjorn Helgaas
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:43 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree,
	Jingoo Han, Gustavo Pimentel, Ley Foon Tan, Michal Simek



On 15-Apr-19 7:34 PM, Bjorn Helgaas wrote:
> On Mon, Apr 15, 2019 at 05:06:10PM +0530, Manikanta Maddireddy wrote:
>> On 12-Apr-19 8:20 PM, Bjorn Helgaas wrote:
>>> On Fri, Apr 12, 2019 at 12:30:22PM +0530, Manikanta Maddireddy wrote:
>>>> On 12-Apr-19 1:45 AM, Bjorn Helgaas wrote:
>>>>> On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
>>>>>> Add PCIe link up check in config read and write callback functions
>>>>>> before accessing endpoint config registers.
>>>>>>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
>>>>>>  				  int where, int size, u32 *value)
>>>>>>  {
>>>>>> +	struct tegra_pcie *pcie = bus->sysdata;
>>>>>> +	struct pci_dev *bridge;
>>>>>> +	struct tegra_pcie_port *port;
>>>>>> +
>>>>>>  	if (bus->number == 0)
>>>>>>  		return pci_generic_config_read32(bus, devfn, where, size,
>>>>>>  						 value);
>>>>>>  
>>>>>> +	bridge = pcie_find_root_port(bus->self);
>>>>>> +
>>>>>> +	list_for_each_entry(port, &pcie->ports, list)
>>>>>> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
>>>>>> +			break;
>>>>>> +
>>>>>> +	/* If there is no link, then there is no device */
>>>>>> +	if (!tegra_pcie_link_status(port)) {
>>>>> This is racy and you should avoid it if possible.  The link could go down
>>>>> between calling tegra_pcie_link_status() and issuing the config read/write.
>>>>>
>>>>> If your driver is to be reliable, it must be able to handle any bad
>>>>> consequence of issuing that config read/write anyway, so I think it's
>>>>> better if it doesn't even bother checking whether the link is up.
>>>> This change is made based on similar check present in dwc driver
>>>> dw_pcie_valid_device(), reasons for making this change in Tegra might
>>>> differ dwc.
>>> Yes, you won't be surprised to learn that I don't like the similar
>>> checks in dwc, altera, xilinx, and xilinx-nwl either :)  I raise this
>>> issue every time I see it, but I can't remember if I've mentioned dwc
>>> specifically.
>>>
>>> We need to either eradicate this pattern of checking for link up, or
>>> include a comment about why it is absolutely necessary.
>> This patch is created to address below scenario in our downstream kernel,
>> 1) Our platform has WiFi on one slot and GPU in another.
>> 2) During WiFi OFF, link is put in L2 and it goes through hot reset
>> when turning ON WiFi (since Tegra doesn't support hot-plug).
>> 3) Whenever x11 server is started it scans the PCIe bus for video devices.
>> Here PCIe configuration registers of all devices are read to find out
>> all available video devices.
>> 4) If "x11 server" started with WiFi OFF, then we are seeing "response
>> decoding error"(Tegra AFI module specific error).
> Probably happens with lspci too.  I guess this is when you try to read
> the WiFi device config space?
Yes, happens with lspci when trying to read WiFi device config space.
>> Best solution we came up with is to have link up check in config access
>> callback functions.
> Can you check for "response decoding error" in the config accessor and
> return 0xffffffff if you see it?
"Response decoding error" is informed by an interrupt(tegra_pcie_isr()), we have
to add polling logic in config accessor to check if config access caused "response
decoding error" or not. This will increase config access time.
Also sometimes BAR access can also cause "Response decoding error", so
matching "Response decoding error" to a particular config access is
going to be difficult.

Manikanta
>
>>>> Intention here is to reduce the number of AER errors when device is
>>>> falling off the bus or going through hot reset. So racy condition here is
>>>> OK
>>> I'm not convinced about this.  The issues you mention need to be
>>> solved in a generic way, not a tegra-specific way.
>>>
>>> We don't want to end up with code that silently avoids the config
>>> access 99.99% of the time, but once in a blue moon, we lose the race
>>> (the device stops responding after we've determined the link is up)
>>> and the access causes a mysterious AER error that we have no way to
>>> debug.
>>>
>>>>>> +		*value = 0xffffffff;
>>>>>> +		return PCIBIOS_DEVICE_NOT_FOUND;
>>>>>> +	}
>>>>>> +
>>>>>>  	return pci_generic_config_read(bus, devfn, where, size, value);
>>>>>>  }


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 23/30] dt-bindings: pci: tegra: Document PCIe DPD pinctrl optional prop
  2019-04-15 14:07   ` Thierry Reding
@ 2019-04-15 15:48     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:48 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 7:37 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:48PM +0530, Manikanta Maddireddy wrote:
>> Document PCIe DPD pinctrl optional property to put PEX clk & BIAS pads
>> in low power mode.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  .../devicetree/bindings/pci/nvidia,tegra20-pcie.txt      | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> index 145a4f04194f..fbbd3bcb3435 100644
>> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> @@ -65,6 +65,15 @@ Required properties:
>>    - afi
>>    - pcie_x
>>  
>> +Optional properties:
>> +- pinctrl-names : The pin control state names.
>> +- pinctrl-0: PCIe IO(bias & REFCLK) deep power down(DPD) disable state.
>> +  In Tegra210 PCIe clamps are not controlling IO signals, so there
>> +  is leakagae power even after PCIe power partition is off. Pass
> leakage
>
>> +  pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
>> +- pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
>> +  Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
> This is confusingly documented. Your pinctrl-names should list exactly
> what states are supported. The generic pinctrl bindings already specify
> how to define pinctrl states, so I don't think you need to describe all
> of the pinctrl-{0,1,...} states again.
>
> Also, looking at the driver you seem to use custom names for the pinctrl
> states, but those states are really just the "active" and the "idle"
> states, for which there are standard names.
>
> Something like this perhaps:
>
> - pinctrl-names: A list of pinctrl state names. Must contain the
>   following entries:
>   - "default": active state, puts PCIe I/O out of deep power down state
>   - "idle": puts PCIe I/O into deep power down state
>
> It then goes without saying that the phandle pointed to by pinctrl-0
> corresponds to the pinctrl state named by the first entry in
> pinctrl-names.
>
> If you use those default names for the states, I don't think you even
> need extra code, the pinctrl subsystem should be able to take of that
> for you.
>
> Thierry
I will take care of naming in V2. However pinctrl states should be controlled
by PCIe driver because it knows when the "PCIe link up" is initiated and
when then link is down.

Manikanta
>
>> +
>>  Required properties on Tegra124 and later (deprecated):
>>  - phys: Must contain an entry for each entry in phy-names.
>>  - phy-names: Must include the following entries:
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support
  2019-04-15 15:36       ` Thierry Reding
@ 2019-04-15 15:53         ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 15:53 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 9:06 PM, Thierry Reding wrote:
> On Mon, Apr 15, 2019 at 08:17:02PM +0530, Manikanta Maddireddy wrote:
>>
>> On 15-Apr-19 4:51 PM, Thierry Reding wrote:
>>> On Thu, Apr 11, 2019 at 10:33:29PM +0530, Manikanta Maddireddy wrote:
>>>> Tegra124, 132, 210 and 186 support Gen2 link speed. After PCIe link is up
>>>> in Gen1, set target link speed as Gen2 and retrain link. Link switches to
>>>> Gen2 speed if Gen2 capable end point is connected, else link stays in Gen1.
>>>>
>>>> Per PCIe 4.0r0.9 sec 7.6.3.7 implementation note, driver need to wait for
>>>> PCIe LTSSM to come back from recovery before retraining the link.
>>>>
>>>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>>>> ---
>>>>  drivers/pci/controller/pci-tegra.c | 61 ++++++++++++++++++++++++++++++
>>>>  1 file changed, 61 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>>>> index a61ce9d475b4..6ccda82735f8 100644
>>>> --- a/drivers/pci/controller/pci-tegra.c
>>>> +++ b/drivers/pci/controller/pci-tegra.c
>>>> @@ -191,6 +191,8 @@
>>>>  #define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
>>>>  #define  RP_LINK_CONTROL_STATUS_LINKSTAT_MASK	0x3fff0000
>>>>  
>>>> +#define RP_LINK_CONTROL_STATUS_2		0x000000b0
>>>> +
>>>>  #define PADS_CTL_SEL		0x0000009c
>>>>  
>>>>  #define PADS_CTL		0x000000a0
>>>> @@ -2096,6 +2098,62 @@ static void tegra_pcie_apply_pad_settings(struct tegra_pcie *pcie)
>>>>  		pads_writel(pcie, soc->pads_refclk_cfg1, PADS_REFCLK_CFG1);
>>>>  }
>>>>  
>>>> +#define LINK_RETRAIN_TIMEOUT 100000
>>> This is oddly placed. I think this should go somewhere near the top of
>>> the file. We already have PME_ACK_TIMEOUT there.
>>>
>>> But to be honest, I wouldn't even bother with the #define. This is used
>>> exactly twice and is much longer to type than the actual number.
>> I will move #define to top of the file. Macro name tells us what this timeout,
>> so I will keep the macro intact.
>>>> +
>>>> +static void tegra_pcie_change_link_speed(struct tegra_pcie *pcie)
>>>> +{
>>>> +	struct device *dev = pcie->dev;
>>>> +	struct tegra_pcie_port *port, *tmp;
>>>> +	ktime_t deadline;
>>>> +	u32 val;
>>> The driver uses u32 value for register values elsewhere. It'd be good to
>>> stay consistent with that convention.
>> Do you mean "unsigned long"? I observed this discrepancy, in few places u32 is used
>> and in some places "unsigned long" is used to store register value. I am continuing
>> to u32 and we need a new patch to change all "unsigned long" variables to u32
>> which are used to store register values.
> I meant to say that we spell out "value" everywhere else and don't use
> the abbreviation.
>
> Thierry
Got it, I will take care of it in V2.

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-15 14:16   ` Thierry Reding
@ 2019-04-15 17:58     ` Manikanta Maddireddy
  2019-04-16 15:34       ` Thierry Reding
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 17:58 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 7:46 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:51PM +0530, Manikanta Maddireddy wrote:
>> Document "nvidia,plat-gpios" optional property which supports configuring
>> of platform specific gpios.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> index fbbd3bcb3435..dca8393b86d1 100644
>> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> @@ -73,6 +73,8 @@ Optional properties:
>>    pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
>>  - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
>>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
>> +- nvidia,plat-gpios: A list of platform specific gpios which controls
>> +  endpoint's internal regulator or PCIe logic.
> We discussed this with Vidya during review of the Tegra194 PCIe device
> tree bindings and arrived at the conclusion that all of the GPIOs that
> need to be controlled for PCI to work can be modelled as proper device
> nodes (I think regulator and GPIO-controlled muxes were the only two
> use-cases for which we need this).
>
> Can the same be done for this PCI controller? What use-cases are we
> talking about?
In Tegra194 case it is apt to use regulator framework because gpios are used
to control regulators. However I published this patch to control vendor defined
gpios in endpoints. For ex: isolate gpio in RTL8111. Since I am not sure if
regulator framework is apt, I published as gpio patch.
>>  Required properties on Tegra124 and later (deprecated):
>>  - phys: Must contain an entry for each entry in phy-names.
>> @@ -567,6 +569,7 @@ Board DTS:
>>  		pci@2,0 {
>>  			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
>>  			phy-names = "pcie-0";
>> +			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
>>  			status = "okay";
>>  		};
>>  	};
> I recall this being the setup for Jetson Nano and the X.3 GPIO going to
> an Ethernet device. Let's find out what exactly this GPIO is used for
> and why we need it to be set up as part of the PCI controller driver
> rather than the Ethernet device.
>
> If it turns out we can't model this other than with a generic GPIO type
> of property we need a better explanation than the above, and the Jetson
> Nano use-case would provide that explanation.
>
> And if indeed we cannot model this more accurately, I think we should
> use something like the gpio-hog binding rather than some custom PCI
> controller property.
>
> Thierry
Yes, in Jetson Nano gpio x.3 is controlling isolate pin of RTL8111.
RTL8111 datasheet available online says that as long as isolate
pin is asserted it'll not sample RX lanes and doesn't drive TX lanes.
Since RTL8111 PCIe IP should be active when PCIe host driver is
attempting link up, this gpio can be controlled by host driver only.

I didn't go for gpio-hog because this gpio should be asserted
during suspend, to enable wake on LAN.

Manikanta

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 28/30] dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop
  2019-04-15 14:20   ` Thierry Reding
@ 2019-04-15 18:01     ` Manikanta Maddireddy
  2019-04-29 18:33     ` Rob Herring
  1 sibling, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 18:01 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 7:50 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:53PM +0530, Manikanta Maddireddy wrote:
>> Document "nvidia,rst-gpio" optional property which supports GPIO based
>> PERST# signal.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> index dca8393b86d1..23928fd59538 100644
>> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>> @@ -75,6 +75,8 @@ Optional properties:
>>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
>>  - nvidia,plat-gpios: A list of platform specific gpios which controls
>>    endpoint's internal regulator or PCIe logic.
>> +- nvidia,rst-gpio: If GPIO is used as PERST# signal instead of available
>> +  SFIO, add this property with phandle to GPIO controller and GPIO number.
> GPIO properties are pretty much standardized, so this should really be
> called just "reset-gpio".
>
> Also it looks like this is documented in the wrong place. In the example
> below you set this property for the root port, that is inside a child
> node of the PCI controller, but if I understand correctly, and it's hard
> to say from the context, the above is documented as part of the
> properties of the host bridge node.
>
> Thierry
I will correct this in V2.

Manikanta
>>  
>>  Required properties on Tegra124 and later (deprecated):
>>  - phys: Must contain an entry for each entry in phy-names.
>> @@ -671,6 +673,7 @@ Board DTS:
>>  
>>  		pci@1,0 {
>>  			nvidia,num-lanes = <4>;
>> +			nvidia,rst-gpio = <&tegra_main_gpio TEGRA_MAIN_GPIO(A, 3) 0>;
>>  			status = "okay";
>>  		};
>>  
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 29/30] PCI: tegra: Add support for GPIO based PCIe reset
  2019-04-15 14:20   ` Thierry Reding
@ 2019-04-15 18:03     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 18:03 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 7:50 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:54PM +0530, Manikanta Maddireddy wrote:
>> Add support for GPIO based PERST# instead of SFIO mode controller by AFI.
>> GPIO number comes from per port PCIe device tree node.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 37 +++++++++++++++++++++++++-----
>>  1 file changed, 31 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 4a91c9fb3a9d..75873e6627f9 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -17,6 +17,7 @@
>>  #include <linux/debugfs.h>
>>  #include <linux/delay.h>
>>  #include <linux/export.h>
>> +#include <linux/gpio.h>
>>  #include <linux/interrupt.h>
>>  #include <linux/iopoll.h>
>>  #include <linux/irq.h>
>> @@ -26,6 +27,7 @@
>>  #include <linux/module.h>
>>  #include <linux/msi.h>
>>  #include <linux/of_address.h>
>> +#include <linux/of_gpio.h>
>>  #include <linux/of_pci.h>
>>  #include <linux/of_platform.h>
>>  #include <linux/pci.h>
>> @@ -406,6 +408,7 @@ struct tegra_pcie_port {
>>  
>>  	int n_gpios;
>>  	int *gpios;
>> +	int rst_gpio;
> This should be using GPIO descriptor APIs.
>
> Thierry
I will take care of it in V2.

Manikanta
>
>>  };
>>  
>>  struct tegra_pcie_bus {
>> @@ -589,15 +592,23 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
>>  	unsigned long value;
>>  
>>  	/* pulse reset signal */
>> -	value = afi_readl(port->pcie, ctrl);
>> -	value &= ~AFI_PEX_CTRL_RST;
>> -	afi_writel(port->pcie, value, ctrl);
>> +	if (gpio_is_valid(port->rst_gpio)) {
>> +		gpio_set_value(port->rst_gpio, 0);
>> +	} else {
>> +		value = afi_readl(port->pcie, ctrl);
>> +		value &= ~AFI_PEX_CTRL_RST;
>> +		afi_writel(port->pcie, value, ctrl);
>> +	}
>>  
>>  	usleep_range(1000, 2000);
>>  
>> -	value = afi_readl(port->pcie, ctrl);
>> -	value |= AFI_PEX_CTRL_RST;
>> -	afi_writel(port->pcie, value, ctrl);
>> +	if (gpio_is_valid(port->rst_gpio)) {
>> +		gpio_set_value(port->rst_gpio, 1);
>> +	} else {
>> +		value = afi_readl(port->pcie, ctrl);
>> +		value |= AFI_PEX_CTRL_RST;
>> +		afi_writel(port->pcie, value, ctrl);
>> +	}
>>  }
>>  
>>  static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
>> @@ -2241,6 +2252,20 @@ static int tegra_pcie_parse_plat_dt(struct tegra_pcie_port *port,
>>  		}
>>  	}
>>  
>> +	port->rst_gpio = of_get_named_gpio(np, "nvidia,rst-gpio", 0);
>> +	if (gpio_is_valid(port->rst_gpio)) {
>> +		err = devm_gpio_request(dev, port->rst_gpio, "pex_rst_gpio");
>> +		if (err < 0) {
>> +			dev_err(dev, "rst_gpio request failed: %d\n", err);
>> +			return err;
>> +		}
>> +		err = gpio_direction_output(port->rst_gpio, 0);
>> +		if (err < 0) {
>> +			dev_err(dev, "rst_gpio set o/p failed: %d\n", err);
>> +			return err;
>> +		}
>> +	}
>> +
>>  	return 0;
>>  }
>>  
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 30/30] PCI: tegra: Change link retry log level to INFO
  2019-04-15 14:23   ` Thierry Reding
@ 2019-04-15 18:05     ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 18:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 7:53 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:55PM +0530, Manikanta Maddireddy wrote:
>> Link retry log is info log not error, so change it to INFO log level.
> The wording here is confusing. The log is clearly error level right now.
> Perhaps you meant to say something like this:
>
>     Letting users know that a link is down and in the process of being
>     brought up again is informational, not an error condition.
>
> Thierry
I will update in V2.

Manikanta
>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 75873e6627f9..55f8ff4f3e07 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -2461,7 +2461,7 @@ static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
>>  		} while (--timeout);
>>  
>>  		if (!timeout) {
>> -			dev_err(dev, "link %u down, retrying\n", port->index);
>> +			dev_info(dev, "link %u down, retrying\n", port->index);
>>  			goto retry;
>>  		}
>>  
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence
  2019-04-15 14:30       ` Thierry Reding
@ 2019-04-15 18:14         ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-15 18:14 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 8:00 PM, Thierry Reding wrote:
> On Mon, Apr 15, 2019 at 07:41:21PM +0530, Manikanta Maddireddy wrote:
>> On 15-Apr-19 4:31 PM, Thierry Reding wrote:
>>> On Thu, Apr 11, 2019 at 10:33:27PM +0530, Manikanta Maddireddy wrote:
>>>> PCIe host power up sequence involves programming AFI(AXI to FPCI bridge)
>>>> registers first and then PCIe registers. Otherwise AFI register settings
>>>> may not latch to PCIe IP.
>>>>
>>>> PCIe root port starts LTSSM as soon as PCIe xrst is deasserted.
>>>> So deassert PCIe xrst after programming PCIe registers.
>>>>
>>>> Modify PCIe power up sequence as follows,
>>>>   - Power ungate PCIe partition
>>>>   - Enable AFI clock
>>>>   - Deassert AFI reset
>>>>   - Program AFI registers
>>>>   - Enable PCIe clock
>>>>   - Deassert PCIe reset
>>>>   - Program PCIe registers
>>>>   - Deassert PCIe xrst to start LTSSM
>>>>
>>>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>>>> ---
>>>>  drivers/pci/controller/pci-tegra.c | 73 ++++++++++++++++++------------
>>>>  1 file changed, 43 insertions(+), 30 deletions(-)
>>>>
>>>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>>>> index f4f53d092e00..0bf270bcea34 100644
>>>> --- a/drivers/pci/controller/pci-tegra.c
>>>> +++ b/drivers/pci/controller/pci-tegra.c
>>>> @@ -966,9 +966,6 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
>>>>  		}
>>>>  	}
>>>>  
>>>> -	/* take the PCIe interface module out of reset */
>>>> -	reset_control_deassert(pcie->pcie_xrst);
>>>> -
>>>>  	/* finally enable PCIe */
>>>>  	value = afi_readl(pcie, AFI_CONFIGURATION);
>>>>  	value |= AFI_CONFIGURATION_EN_FPCI;
>>>> @@ -997,8 +994,6 @@ static void tegra_pcie_disable_controller(struct tegra_pcie *pcie)
>>>>  {
>>>>  	int err;
>>>>  
>>>> -	reset_control_assert(pcie->pcie_xrst);
>>>> -
>>>>  	if (pcie->soc->program_uphy) {
>>>>  		err = tegra_pcie_phy_power_off(pcie);
>>>>  		if (err < 0)
>>>> @@ -1014,13 +1009,11 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie)
>>>>  	int err;
>>>>  
>>>>  	reset_control_assert(pcie->afi_rst);
>>>> -	reset_control_assert(pcie->pex_rst);
>>>>  
>>>>  	clk_disable_unprepare(pcie->pll_e);
>>>>  	if (soc->has_cml_clk)
>>>>  		clk_disable_unprepare(pcie->cml_clk);
>>>>  	clk_disable_unprepare(pcie->afi_clk);
>>>> -	clk_disable_unprepare(pcie->pex_clk);
>>>>  
>>>>  	if (!dev->pm_domain)
>>>>  		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
>>>> @@ -1036,58 +1029,59 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie)
>>>>  	const struct tegra_pcie_soc *soc = pcie->soc;
>>>>  	int err;
>>>>  
>>>> -	reset_control_assert(pcie->pcie_xrst);
>>>> -	reset_control_assert(pcie->afi_rst);
>>>> -	reset_control_assert(pcie->pex_rst);
>>>> -
>>>> -	if (!dev->pm_domain)
>>>> -		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
>>>> -
>>> This code was in place to ensure that PCIe was in a known good state
>>> before following the power up sequence below. You mentioned elsewhere
>>> that there's a regression on Cardhu after applying this series, so
>>> perhaps Cardhu relies on the above hunk?
>> No, Tegra30 and Tegra20 has legacy PHY which are dependent on PEX clk and rst.
>> PHY power on is done in tegra_pcie_enable_controller(), but in this patch I am
>> enabling PEX clk and rst after tegra_pcie_enable_controller(). This caused
>> regression on Cardhu.
>> I realized that sanity test is failing on Cardhu after publishing this series, I will
>> fix the issue in V2.
>> I believe you are talking about the bootloader(uboot) which can enable
>> PCIe partition and reset. To bring the PCIe into good state then we
>> have to take care of clocks as well. AFAIK clock_disable() is not added
>> because it maintains the refcount and any mismatch in the count
>> will thrown warning. I downstream kernel I see pmc driver itself taking
>> care of initial state and there after maintaining the state with refcount.
>> Since bootloader may or may not enable PCIe, Can we get the state fixed
>> in pmc driver instead of fixing it in PCIe driver?
> I don't think we can do that. The PMC driver only knows about which
> clocks and resets need to be controlled as part of which power partition
> if we use power domains. We don't do that on all platforms, so there is
> not enough information.
>
> Even if we had that information, we would still not be able to force the
> clock off because of the reference counting.
>
> Generally, though, the clock don't matter all that much for getting the
> hardware into a good state. All we really care about is that it is put
> into reset so that when we take it out again we start from scratch.
>
> If we can verify that we don't need this anymore, I'm fine with taking
> it out, though. Perhaps do it in a separate patch to make it easier to
> revert if it turns out to be necessary on some platform after all.
>
> Thierry
In one of the Nvidia internal bugs, HW team confirmed that clock matter because
PCIe IP has non re-settable flops. They asked me to use following sequence,
Power up case:
 - Ungate PCIe partition
 - Enable clock
 - Deassert reset
Power down case:
 - Assert reset
 - Disable clock
 - Power gate PCIe partition.
I agree that this clean up should be done in new patch. So when I make new patch set for it,
I will make sure that above sequence is followed to ensure that PCIe IP is in good state.
>
>>>>  	/* enable regulators */
>>>>  	err = regulator_bulk_enable(pcie->num_supplies, pcie->supplies);
>>>>  	if (err < 0)
>>>>  		dev_err(dev, "failed to enable regulators: %d\n", err);
>>>>  
>>>> -	if (dev->pm_domain) {
>>>> -		err = clk_prepare_enable(pcie->pex_clk);
>>>> +	if (!dev->pm_domain) {
>>>> +		err = tegra_powergate_power_on(TEGRA_POWERGATE_PCIE);
>>>>  		if (err) {
>>>> -			dev_err(dev, "failed to enable PEX clock: %d\n", err);
>>>> -			return err;
>>>> +			dev_err(dev, "power ungate failed: %d\n", err);
>>>> +			goto regulator_disable;
>>>>  		}
>>>> -		reset_control_deassert(pcie->pex_rst);
>>>> -	} else {
>>>> -		err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
>>>> -							pcie->pex_clk,
>>>> -							pcie->pex_rst);
>>>> +		err = tegra_powergate_remove_clamping(TEGRA_POWERGATE_PCIE);
>>>>  		if (err) {
>>>> -			dev_err(dev, "powerup sequence failed: %d\n", err);
>>>> -			return err;
>>>> +			dev_err(dev, "remove clamp failed: %d\n", err);
>>>> +			goto powergate;
>>>>  		}
>>>>  	}
>>>>  
>>>> -	reset_control_deassert(pcie->afi_rst);
>>>> -
>>>>  	err = clk_prepare_enable(pcie->afi_clk);
>>>>  	if (err < 0) {
>>>>  		dev_err(dev, "failed to enable AFI clock: %d\n", err);
>>>> -		return err;
>>>> +		goto powergate;
>>>>  	}
>>>>  
>>>>  	if (soc->has_cml_clk) {
>>>>  		err = clk_prepare_enable(pcie->cml_clk);
>>>>  		if (err < 0) {
>>>>  			dev_err(dev, "failed to enable CML clock: %d\n", err);
>>>> -			return err;
>>>> +			goto afi_clk_disable;
>>>>  		}
>>>>  	}
>>>>  
>>>>  	err = clk_prepare_enable(pcie->pll_e);
>>>>  	if (err < 0) {
>>>>  		dev_err(dev, "failed to enable PLLE clock: %d\n", err);
>>>> -		return err;
>>>> +		goto cml_clk_disable;
>>>>  	}
>>>>  
>>>> +	reset_control_deassert(pcie->afi_rst);
>>>> +
>>>>  	return 0;
>>>> +
>>>> +cml_clk_disable:
>>>> +	if (soc->has_cml_clk)
>>>> +		clk_disable_unprepare(pcie->cml_clk);
>>>> +afi_clk_disable:
>>>> +	clk_disable_unprepare(pcie->afi_clk);
>>>> +powergate:
>>>> +	if (!dev->pm_domain)
>>>> +		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
>>>> +regulator_disable:
>>>> +	regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
>>>> +	return err;
>>>>  }
>>>>  
>>>>  static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
>>>> @@ -2108,7 +2102,12 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>>>>  			 port->index, port->lanes);
>>>>  
>>>>  		tegra_pcie_port_enable(port);
>>>> +	}
>>>> +
>>>> +	/* Start LTSSM from Tegra side */
>>>> +	reset_control_deassert(pcie->pcie_xrst);
>>>>  
>>>> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
>>>>  		if (tegra_pcie_port_check_link(port))
>>>>  			continue;
>>>>  
>>>> @@ -2123,6 +2122,8 @@ static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
>>>>  {
>>>>  	struct tegra_pcie_port *port, *tmp;
>>>>  
>>>> +	reset_control_assert(pcie->pcie_xrst);
>>>> +
>>>>  	list_for_each_entry_safe(port, tmp, &pcie->ports, list)
>>>>  		tegra_pcie_port_disable(port);
>>>>  }
>>>> @@ -2472,6 +2473,9 @@ static int __maybe_unused tegra_pcie_pm_suspend(struct device *dev)
>>>>  
>>>>  	tegra_pcie_disable_ports(pcie);
>>>>  
>>>> +	reset_control_assert(pcie->pex_rst);
>>>> +	clk_disable_unprepare(pcie->pex_clk);
>>>> +
>>>>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>>>>  		tegra_pcie_disable_msi(pcie);
>>>>  
>>>> @@ -2501,10 +2505,19 @@ static int __maybe_unused tegra_pcie_pm_resume(struct device *dev)
>>>>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>>>>  		tegra_pcie_enable_msi(pcie);
>>>>  
>>>> +	err = clk_prepare_enable(pcie->pex_clk);
>>>> +	if (err) {
>>>> +		dev_err(dev, "failed to enable PEX clock: %d\n", err);
>>>> +		goto disable_controller;
>>>> +	}
>>>> +	reset_control_deassert(pcie->pex_rst);
>>>> +
>>>>  	tegra_pcie_enable_ports(pcie);
>>>>  
>>>>  	return 0;
>>>>  
>>>> +disable_controller:
>>>> +	tegra_pcie_disable_controller(pcie);
>>>>  poweroff:
>>>>  	tegra_pcie_power_off(pcie);
>>>>  
>>> There's quite a bit going on in this patch in general and I find it hard
>>> to review because not all the changes seem related to what you described
>>> in the commit message.
>>>
>>> Can you perhaps try to split out the error cleanup changes into a
>>> separate patch where it makes sense? It seems to me like at least for
>>> tegra_pcie_power_on() we're currently missing all of the cleanup code.
>>> You could make that a preparatory patch that goes before this particular
>>> patch, which will hopefully make this patch easier to review.
>>>
>>> Thierry
>> Okay, I will prepare new patch for error handling and restrict this patch only for
>> sequence correction


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 16/30] PCI: tegra: Program AFI_CACHE* registers only for Tegra20
  2019-04-15 13:20   ` Thierry Reding
@ 2019-04-16 10:47     ` Manikanta Maddireddy
  2019-04-16 16:11       ` Thierry Reding
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-16 10:47 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 6:50 PM, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:41PM +0530, Manikanta Maddireddy wrote:
>> AFI_CACHE* registers are available only in Tegra20, program them only
>> for Tegra20.
>>
>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>> ---
>>  drivers/pci/controller/pci-tegra.c | 13 ++++++++-----
>>  1 file changed, 8 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 8e5fdc8ce3d6..cdaaf13a9fd7 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -887,6 +887,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>>   */
>>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>>  {
>> +	struct device_node *np = pcie->dev->of_node;
>>  	u32 fpci_bar, size, axi_address;
>>  
>>  	/* Bar 0: type 1 extended configuration space */
>> @@ -927,11 +928,13 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>>  	afi_writel(pcie, 0, AFI_AXI_BAR5_SZ);
>>  	afi_writel(pcie, 0, AFI_FPCI_BAR5);
>>  
>> -	/* map all upstream transactions as uncached */
>> -	afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
>> -	afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
>> -	afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
>> -	afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
>> +	if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
> At this point we've already matched on that compatible string, so we
> could probably get that information from the SoC structure. Why are
> these registers not available on later chips? How would we mark
> transactions as uncached on later generations of Tegra?
>
> Also, typically writing to non-existing registers on Tegra186 would
> cause an SError exception, but I haven't seen any of those with PCIe
> on Tegra186. So do these really not exist, or are they simply not used?
>
> Thierry

Do you want me to add new soc flag for AFI_CACHE registers?

As per the HW team feedback, upstream requests targeting DRAM would
be marked as cacheable when the address of the request are within the
regions defined by the cache_bar_sz/st registers.
All upstream DRAM requests are marked as non-cacheable from T30 to T210
as the field is not used by MSS. In Tegra186 cacheable requests are
supported by new register AFI_AXCACHE_0*. *
These register definitions are not present in Tegra186 TRM, but
register offsets are accessible, so these are not used.
However Tegra186 simulations traps this register access because
it is not defined in register spec.

Manikanta

>> +		/* map all upstream transactions as uncached */
>> +		afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
>> +		afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
>> +		afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
>> +		afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
>> +	}
>>  
>>  	/* MSI translations are setup only when needed */
>>  	afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST);
>> -- 
>> 2.17.1
>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-15 17:58     ` Manikanta Maddireddy
@ 2019-04-16 15:34       ` Thierry Reding
  2019-04-17 11:22         ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-16 15:34 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 5035 bytes --]

On Mon, Apr 15, 2019 at 11:28:29PM +0530, Manikanta Maddireddy wrote:
> 
> 
> On 15-Apr-19 7:46 PM, Thierry Reding wrote:
> > On Thu, Apr 11, 2019 at 10:33:51PM +0530, Manikanta Maddireddy wrote:
> >> Document "nvidia,plat-gpios" optional property which supports configuring
> >> of platform specific gpios.
> >>
> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >> ---
> >>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
> >>  1 file changed, 3 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> >> index fbbd3bcb3435..dca8393b86d1 100644
> >> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> >> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> >> @@ -73,6 +73,8 @@ Optional properties:
> >>    pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
> >>  - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
> >>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
> >> +- nvidia,plat-gpios: A list of platform specific gpios which controls
> >> +  endpoint's internal regulator or PCIe logic.
> > We discussed this with Vidya during review of the Tegra194 PCIe device
> > tree bindings and arrived at the conclusion that all of the GPIOs that
> > need to be controlled for PCI to work can be modelled as proper device
> > nodes (I think regulator and GPIO-controlled muxes were the only two
> > use-cases for which we need this).
> >
> > Can the same be done for this PCI controller? What use-cases are we
> > talking about?
> In Tegra194 case it is apt to use regulator framework because gpios are used
> to control regulators. However I published this patch to control vendor defined
> gpios in endpoints. For ex: isolate gpio in RTL8111. Since I am not sure if
> regulator framework is apt, I published as gpio patch.
> >>  Required properties on Tegra124 and later (deprecated):
> >>  - phys: Must contain an entry for each entry in phy-names.
> >> @@ -567,6 +569,7 @@ Board DTS:
> >>  		pci@2,0 {
> >>  			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
> >>  			phy-names = "pcie-0";
> >> +			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
> >>  			status = "okay";
> >>  		};
> >>  	};
> > I recall this being the setup for Jetson Nano and the X.3 GPIO going to
> > an Ethernet device. Let's find out what exactly this GPIO is used for
> > and why we need it to be set up as part of the PCI controller driver
> > rather than the Ethernet device.
> >
> > If it turns out we can't model this other than with a generic GPIO type
> > of property we need a better explanation than the above, and the Jetson
> > Nano use-case would provide that explanation.
> >
> > And if indeed we cannot model this more accurately, I think we should
> > use something like the gpio-hog binding rather than some custom PCI
> > controller property.
> >
> > Thierry
> Yes, in Jetson Nano gpio x.3 is controlling isolate pin of RTL8111.
> RTL8111 datasheet available online says that as long as isolate
> pin is asserted it'll not sample RX lanes and doesn't drive TX lanes.
> Since RTL8111 PCIe IP should be active when PCIe host driver is
> attempting link up, this gpio can be controlled by host driver only.
> 
> I didn't go for gpio-hog because this gpio should be asserted
> during suspend, to enable wake on LAN.

I don't see code in gpiolib that would cause this to be deasserted
during suspend.

Is there ever a need to manipulate this GPIO at all? Or do we just
need to make sure that it's always asserted?

The problem with adding this to nvidia,plat-gpios in the PCI root port
node is that there's no context at all, so the PCI host driver can't
really do anything with this, other than perhaps exactly one fixed
operation, but then it's pretty much equivalent to a gpio-hog.

If we do need control over the pin, I think it might be worth looking at
adding support to gpiolib for initial pin configuration (so that it does
not hog the GPIO, but still configures it). That would allow us to take
the PCI device out of isolation initially and once the device has been
probed we can control the GPIO from the PCI device. That way the device
driver has the necessary context to assert and deassert the pin at the
appropriate time, while still giving us the possibility to make the
device appear on the PCI bus.

As a side-note, I think it would've been better if the ISOLATEB signal
was wired up such that it would've been active by default. That would
mean that if the bootloader and/or OS were not aware of the ISOLATEB
signal, they would still be able to use the Ethernet device. I think
that would've been a more sensible default, especially if the bus that
the device is on requires the signal to be controlled without even
knowing that the device exists.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 16/30] PCI: tegra: Program AFI_CACHE* registers only for Tegra20
  2019-04-16 10:47     ` Manikanta Maddireddy
@ 2019-04-16 16:11       ` Thierry Reding
  0 siblings, 0 replies; 106+ messages in thread
From: Thierry Reding @ 2019-04-16 16:11 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 2892 bytes --]

On Tue, Apr 16, 2019 at 04:17:46PM +0530, Manikanta Maddireddy wrote:
> 
> 
> On 15-Apr-19 6:50 PM, Thierry Reding wrote:
> > On Thu, Apr 11, 2019 at 10:33:41PM +0530, Manikanta Maddireddy wrote:
> >> AFI_CACHE* registers are available only in Tegra20, program them only
> >> for Tegra20.
> >>
> >> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >> ---
> >>  drivers/pci/controller/pci-tegra.c | 13 ++++++++-----
> >>  1 file changed, 8 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> >> index 8e5fdc8ce3d6..cdaaf13a9fd7 100644
> >> --- a/drivers/pci/controller/pci-tegra.c
> >> +++ b/drivers/pci/controller/pci-tegra.c
> >> @@ -887,6 +887,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
> >>   */
> >>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
> >>  {
> >> +	struct device_node *np = pcie->dev->of_node;
> >>  	u32 fpci_bar, size, axi_address;
> >>  
> >>  	/* Bar 0: type 1 extended configuration space */
> >> @@ -927,11 +928,13 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
> >>  	afi_writel(pcie, 0, AFI_AXI_BAR5_SZ);
> >>  	afi_writel(pcie, 0, AFI_FPCI_BAR5);
> >>  
> >> -	/* map all upstream transactions as uncached */
> >> -	afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
> >> -	afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
> >> -	afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
> >> -	afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
> >> +	if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
> > At this point we've already matched on that compatible string, so we
> > could probably get that information from the SoC structure. Why are
> > these registers not available on later chips? How would we mark
> > transactions as uncached on later generations of Tegra?
> >
> > Also, typically writing to non-existing registers on Tegra186 would
> > cause an SError exception, but I haven't seen any of those with PCIe
> > on Tegra186. So do these really not exist, or are they simply not used?
> >
> > Thierry
> 
> Do you want me to add new soc flag for AFI_CACHE registers?
> 
> As per the HW team feedback, upstream requests targeting DRAM would
> be marked as cacheable when the address of the request are within the
> regions defined by the cache_bar_sz/st registers.
> All upstream DRAM requests are marked as non-cacheable from T30 to T210
> as the field is not used by MSS. In Tegra186 cacheable requests are
> supported by new register AFI_AXCACHE_0*. *
> These register definitions are not present in Tegra186 TRM, but
> register offsets are accessible, so these are not used.
> However Tegra186 simulations traps this register access because
> it is not defined in register spec.

Yes, I think something like .has_cache_bars or similar would be the best
solution here.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-16 15:34       ` Thierry Reding
@ 2019-04-17 11:22         ` Manikanta Maddireddy
  2019-04-17 15:19           ` Thierry Reding
  0 siblings, 1 reply; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-17 11:22 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 16-Apr-19 9:04 PM, Thierry Reding wrote:
> On Mon, Apr 15, 2019 at 11:28:29PM +0530, Manikanta Maddireddy wrote:
>>
>> On 15-Apr-19 7:46 PM, Thierry Reding wrote:
>>> On Thu, Apr 11, 2019 at 10:33:51PM +0530, Manikanta Maddireddy wrote:
>>>> Document "nvidia,plat-gpios" optional property which supports configuring
>>>> of platform specific gpios.
>>>>
>>>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>>>> ---
>>>>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
>>>>  1 file changed, 3 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>>>> index fbbd3bcb3435..dca8393b86d1 100644
>>>> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>>>> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>>>> @@ -73,6 +73,8 @@ Optional properties:
>>>>    pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
>>>>  - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
>>>>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
>>>> +- nvidia,plat-gpios: A list of platform specific gpios which controls
>>>> +  endpoint's internal regulator or PCIe logic.
>>> We discussed this with Vidya during review of the Tegra194 PCIe device
>>> tree bindings and arrived at the conclusion that all of the GPIOs that
>>> need to be controlled for PCI to work can be modelled as proper device
>>> nodes (I think regulator and GPIO-controlled muxes were the only two
>>> use-cases for which we need this).
>>>
>>> Can the same be done for this PCI controller? What use-cases are we
>>> talking about?
>> In Tegra194 case it is apt to use regulator framework because gpios are used
>> to control regulators. However I published this patch to control vendor defined
>> gpios in endpoints. For ex: isolate gpio in RTL8111. Since I am not sure if
>> regulator framework is apt, I published as gpio patch.
>>>>  Required properties on Tegra124 and later (deprecated):
>>>>  - phys: Must contain an entry for each entry in phy-names.
>>>> @@ -567,6 +569,7 @@ Board DTS:
>>>>  		pci@2,0 {
>>>>  			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
>>>>  			phy-names = "pcie-0";
>>>> +			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
>>>>  			status = "okay";
>>>>  		};
>>>>  	};
>>> I recall this being the setup for Jetson Nano and the X.3 GPIO going to
>>> an Ethernet device. Let's find out what exactly this GPIO is used for
>>> and why we need it to be set up as part of the PCI controller driver
>>> rather than the Ethernet device.
>>>
>>> If it turns out we can't model this other than with a generic GPIO type
>>> of property we need a better explanation than the above, and the Jetson
>>> Nano use-case would provide that explanation.
>>>
>>> And if indeed we cannot model this more accurately, I think we should
>>> use something like the gpio-hog binding rather than some custom PCI
>>> controller property.
>>>
>>> Thierry
>> Yes, in Jetson Nano gpio x.3 is controlling isolate pin of RTL8111.
>> RTL8111 datasheet available online says that as long as isolate
>> pin is asserted it'll not sample RX lanes and doesn't drive TX lanes.
>> Since RTL8111 PCIe IP should be active when PCIe host driver is
>> attempting link up, this gpio can be controlled by host driver only.
>>
>> I didn't go for gpio-hog because this gpio should be asserted
>> during suspend, to enable wake on LAN.
> I don't see code in gpiolib that would cause this to be deasserted
> during suspend.
>
> Is there ever a need to manipulate this GPIO at all? Or do we just
> need to make sure that it's always asserted?

Following steps
1) ISOLATEB gpio should be deasserted during boot to enable PCIe section
of RTL8111
2) PCIe host driver enumerates RTL8111
3) When suspend is initiated, ISOLATEB gpio should be asserted after PCIe
host controller suspend is completed to disable PCIe section of RTL8111
and enable Wake on LAN
4) During resume, first ISOLATE gpio should be deasserted to get PCIe link up

> The problem with adding this to nvidia,plat-gpios in the PCI root port
> node is that there's no context at all, so the PCI host driver can't
> really do anything with this, other than perhaps exactly one fixed
> operation, but then it's pretty much equivalent to a gpio-hog.
>
> If we do need control over the pin, I think it might be worth looking at
> adding support to gpiolib for initial pin configuration (so that it does
> not hog the GPIO, but still configures it). That would allow us to take
> the PCI device out of isolation initially and once the device has been
> probed we can control the GPIO from the PCI device. That way the device
> driver has the necessary context to assert and deassert the pin at the
> appropriate time, while still giving us the possibility to make the
> device appear on the PCI bus.

ISOLATEB gpio disables the PCIe section in RTL8111(Rx is not sampled &
doesn't drive Tx), if PCI client driver controls it, then it has
to do it after host controller suspend_noirq callback is completed.
Only suspend callback available after suspend_noirq is syscore_ops.
I didn't go with it because it is take void arguments, so client
driver has to maintain global pointers and I see only core drivers
like irqchip, clk, etc are using it.

Manikanta

>
> As a side-note, I think it would've been better if the ISOLATEB signal
> was wired up such that it would've been active by default. That would
> mean that if the bootloader and/or OS were not aware of the ISOLATEB
> signal, they would still be able to use the Ethernet device. I think
> that would've been a more sensible default, especially if the bus that
> the device is on requires the signal to be controlled without even
> knowing that the device exists.
>
> Thierry


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-17 11:22         ` Manikanta Maddireddy
@ 2019-04-17 15:19           ` Thierry Reding
  2019-04-17 18:26             ` Manikanta Maddireddy
  0 siblings, 1 reply; 106+ messages in thread
From: Thierry Reding @ 2019-04-17 15:19 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree

[-- Attachment #1: Type: text/plain, Size: 7077 bytes --]

On Wed, Apr 17, 2019 at 04:52:46PM +0530, Manikanta Maddireddy wrote:
> 
> 
> On 16-Apr-19 9:04 PM, Thierry Reding wrote:
> > On Mon, Apr 15, 2019 at 11:28:29PM +0530, Manikanta Maddireddy wrote:
> >>
> >> On 15-Apr-19 7:46 PM, Thierry Reding wrote:
> >>> On Thu, Apr 11, 2019 at 10:33:51PM +0530, Manikanta Maddireddy wrote:
> >>>> Document "nvidia,plat-gpios" optional property which supports configuring
> >>>> of platform specific gpios.
> >>>>
> >>>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> >>>> ---
> >>>>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
> >>>>  1 file changed, 3 insertions(+)
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> >>>> index fbbd3bcb3435..dca8393b86d1 100644
> >>>> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> >>>> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> >>>> @@ -73,6 +73,8 @@ Optional properties:
> >>>>    pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
> >>>>  - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
> >>>>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
> >>>> +- nvidia,plat-gpios: A list of platform specific gpios which controls
> >>>> +  endpoint's internal regulator or PCIe logic.
> >>> We discussed this with Vidya during review of the Tegra194 PCIe device
> >>> tree bindings and arrived at the conclusion that all of the GPIOs that
> >>> need to be controlled for PCI to work can be modelled as proper device
> >>> nodes (I think regulator and GPIO-controlled muxes were the only two
> >>> use-cases for which we need this).
> >>>
> >>> Can the same be done for this PCI controller? What use-cases are we
> >>> talking about?
> >> In Tegra194 case it is apt to use regulator framework because gpios are used
> >> to control regulators. However I published this patch to control vendor defined
> >> gpios in endpoints. For ex: isolate gpio in RTL8111. Since I am not sure if
> >> regulator framework is apt, I published as gpio patch.
> >>>>  Required properties on Tegra124 and later (deprecated):
> >>>>  - phys: Must contain an entry for each entry in phy-names.
> >>>> @@ -567,6 +569,7 @@ Board DTS:
> >>>>  		pci@2,0 {
> >>>>  			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
> >>>>  			phy-names = "pcie-0";
> >>>> +			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
> >>>>  			status = "okay";
> >>>>  		};
> >>>>  	};
> >>> I recall this being the setup for Jetson Nano and the X.3 GPIO going to
> >>> an Ethernet device. Let's find out what exactly this GPIO is used for
> >>> and why we need it to be set up as part of the PCI controller driver
> >>> rather than the Ethernet device.
> >>>
> >>> If it turns out we can't model this other than with a generic GPIO type
> >>> of property we need a better explanation than the above, and the Jetson
> >>> Nano use-case would provide that explanation.
> >>>
> >>> And if indeed we cannot model this more accurately, I think we should
> >>> use something like the gpio-hog binding rather than some custom PCI
> >>> controller property.
> >>>
> >>> Thierry
> >> Yes, in Jetson Nano gpio x.3 is controlling isolate pin of RTL8111.
> >> RTL8111 datasheet available online says that as long as isolate
> >> pin is asserted it'll not sample RX lanes and doesn't drive TX lanes.
> >> Since RTL8111 PCIe IP should be active when PCIe host driver is
> >> attempting link up, this gpio can be controlled by host driver only.
> >>
> >> I didn't go for gpio-hog because this gpio should be asserted
> >> during suspend, to enable wake on LAN.
> > I don't see code in gpiolib that would cause this to be deasserted
> > during suspend.
> >
> > Is there ever a need to manipulate this GPIO at all? Or do we just
> > need to make sure that it's always asserted?
> 
> Following steps
> 1) ISOLATEB gpio should be deasserted during boot to enable PCIe section
> of RTL8111
> 2) PCIe host driver enumerates RTL8111
> 3) When suspend is initiated, ISOLATEB gpio should be asserted after PCIe
> host controller suspend is completed to disable PCIe section of RTL8111
> and enable Wake on LAN
> 4) During resume, first ISOLATE gpio should be deasserted to get PCIe link up

I think it's important that we be very clear here. If ISOLATEB is
asserted, does that mean the PCIe link is down? Or does it only mean
that the RTL8111 cannot be enumerated.

If the PCIe link remains down as long as ISOLATEB is asserted, then it
sounds like there's more going on than this GPIO just keeping the
RTL8111 from talking on the PCI bus. In that case we would probably have
to model this as some sort of power regulator for the bus.

However, if the PCIe link can be brought up if the RTL8111 is isolated,
but if the device can only not be enumerated, then we could still have
the RTL8111 driver deassert ISOLATEB early during resume. We only have
to make sure that it happens before any PCI requests are sent to the
device.

Thierry

> > The problem with adding this to nvidia,plat-gpios in the PCI root port
> > node is that there's no context at all, so the PCI host driver can't
> > really do anything with this, other than perhaps exactly one fixed
> > operation, but then it's pretty much equivalent to a gpio-hog.
> >
> > If we do need control over the pin, I think it might be worth looking at
> > adding support to gpiolib for initial pin configuration (so that it does
> > not hog the GPIO, but still configures it). That would allow us to take
> > the PCI device out of isolation initially and once the device has been
> > probed we can control the GPIO from the PCI device. That way the device
> > driver has the necessary context to assert and deassert the pin at the
> > appropriate time, while still giving us the possibility to make the
> > device appear on the PCI bus.
> 
> ISOLATEB gpio disables the PCIe section in RTL8111(Rx is not sampled &
> doesn't drive Tx), if PCI client driver controls it, then it has
> to do it after host controller suspend_noirq callback is completed.
> Only suspend callback available after suspend_noirq is syscore_ops.
> I didn't go with it because it is take void arguments, so client
> driver has to maintain global pointers and I see only core drivers
> like irqchip, clk, etc are using it.
> 
> Manikanta
> 
> >
> > As a side-note, I think it would've been better if the ISOLATEB signal
> > was wired up such that it would've been active by default. That would
> > mean that if the bootloader and/or OS were not aware of the ISOLATEB
> > signal, they would still be able to use the Ethernet device. I think
> > that would've been a more sensible default, especially if the bus that
> > the device is on requires the signal to be controlled without even
> > knowing that the device exists.
> >
> > Thierry
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop
  2019-04-17 15:19           ` Thierry Reding
@ 2019-04-17 18:26             ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-17 18:26 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 17-Apr-19 8:49 PM, Thierry Reding wrote:
> On Wed, Apr 17, 2019 at 04:52:46PM +0530, Manikanta Maddireddy wrote:
>>
>> On 16-Apr-19 9:04 PM, Thierry Reding wrote:
>>> On Mon, Apr 15, 2019 at 11:28:29PM +0530, Manikanta Maddireddy wrote:
>>>> On 15-Apr-19 7:46 PM, Thierry Reding wrote:
>>>>> On Thu, Apr 11, 2019 at 10:33:51PM +0530, Manikanta Maddireddy wrote:
>>>>>> Document "nvidia,plat-gpios" optional property which supports configuring
>>>>>> of platform specific gpios.
>>>>>>
>>>>>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>>>>>> ---
>>>>>>  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
>>>>>>  1 file changed, 3 insertions(+)
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>>>>>> index fbbd3bcb3435..dca8393b86d1 100644
>>>>>> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>>>>>> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
>>>>>> @@ -73,6 +73,8 @@ Optional properties:
>>>>>>    pinctrl phandle to allow driver to explicitly put PCIe IO in DPD state.
>>>>>>  - pinctrl-1: PCIe IO(bias & REFCLK) deep power down(DPD) enable state.
>>>>>>    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
>>>>>> +- nvidia,plat-gpios: A list of platform specific gpios which controls
>>>>>> +  endpoint's internal regulator or PCIe logic.
>>>>> We discussed this with Vidya during review of the Tegra194 PCIe device
>>>>> tree bindings and arrived at the conclusion that all of the GPIOs that
>>>>> need to be controlled for PCI to work can be modelled as proper device
>>>>> nodes (I think regulator and GPIO-controlled muxes were the only two
>>>>> use-cases for which we need this).
>>>>>
>>>>> Can the same be done for this PCI controller? What use-cases are we
>>>>> talking about?
>>>> In Tegra194 case it is apt to use regulator framework because gpios are used
>>>> to control regulators. However I published this patch to control vendor defined
>>>> gpios in endpoints. For ex: isolate gpio in RTL8111. Since I am not sure if
>>>> regulator framework is apt, I published as gpio patch.
>>>>>>  Required properties on Tegra124 and later (deprecated):
>>>>>>  - phys: Must contain an entry for each entry in phy-names.
>>>>>> @@ -567,6 +569,7 @@ Board DTS:
>>>>>>  		pci@2,0 {
>>>>>>  			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
>>>>>>  			phy-names = "pcie-0";
>>>>>> +			nvidia,plat-gpios = <&gpio TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
>>>>>>  			status = "okay";
>>>>>>  		};
>>>>>>  	};
>>>>> I recall this being the setup for Jetson Nano and the X.3 GPIO going to
>>>>> an Ethernet device. Let's find out what exactly this GPIO is used for
>>>>> and why we need it to be set up as part of the PCI controller driver
>>>>> rather than the Ethernet device.
>>>>>
>>>>> If it turns out we can't model this other than with a generic GPIO type
>>>>> of property we need a better explanation than the above, and the Jetson
>>>>> Nano use-case would provide that explanation.
>>>>>
>>>>> And if indeed we cannot model this more accurately, I think we should
>>>>> use something like the gpio-hog binding rather than some custom PCI
>>>>> controller property.
>>>>>
>>>>> Thierry
>>>> Yes, in Jetson Nano gpio x.3 is controlling isolate pin of RTL8111.
>>>> RTL8111 datasheet available online says that as long as isolate
>>>> pin is asserted it'll not sample RX lanes and doesn't drive TX lanes.
>>>> Since RTL8111 PCIe IP should be active when PCIe host driver is
>>>> attempting link up, this gpio can be controlled by host driver only.
>>>>
>>>> I didn't go for gpio-hog because this gpio should be asserted
>>>> during suspend, to enable wake on LAN.
>>> I don't see code in gpiolib that would cause this to be deasserted
>>> during suspend.
>>>
>>> Is there ever a need to manipulate this GPIO at all? Or do we just
>>> need to make sure that it's always asserted?
>> Following steps
>> 1) ISOLATEB gpio should be deasserted during boot to enable PCIe section
>> of RTL8111
>> 2) PCIe host driver enumerates RTL8111
>> 3) When suspend is initiated, ISOLATEB gpio should be asserted after PCIe
>> host controller suspend is completed to disable PCIe section of RTL8111
>> and enable Wake on LAN
>> 4) During resume, first ISOLATE gpio should be deasserted to get PCIe link up
> I think it's important that we be very clear here. If ISOLATEB is
> asserted, does that mean the PCIe link is down? Or does it only mean
> that the RTL8111 cannot be enumerated.
>
> If the PCIe link remains down as long as ISOLATEB is asserted, then it
> sounds like there's more going on than this GPIO just keeping the
> RTL8111 from talking on the PCI bus. In that case we would probably have
> to model this as some sort of power regulator for the bus.
>
> However, if the PCIe link can be brought up if the RTL8111 is isolated,
> but if the device can only not be enumerated, then we could still have
> the RTL8111 driver deassert ISOLATEB early during resume. We only have
> to make sure that it happens before any PCI requests are sent to the
> device.
>
> Thierry

RTL8111 will not drive PCIe outputs(except WAKE#) and will not sample PCIe
input as long as ISOLATEB is asserted. So PCIe link up doesn't happen if
ISOLATEB is asserted.

Manikanta

>
>>> The problem with adding this to nvidia,plat-gpios in the PCI root port
>>> node is that there's no context at all, so the PCI host driver can't
>>> really do anything with this, other than perhaps exactly one fixed
>>> operation, but then it's pretty much equivalent to a gpio-hog.
>>>
>>> If we do need control over the pin, I think it might be worth looking at
>>> adding support to gpiolib for initial pin configuration (so that it does
>>> not hog the GPIO, but still configures it). That would allow us to take
>>> the PCI device out of isolation initially and once the device has been
>>> probed we can control the GPIO from the PCI device. That way the device
>>> driver has the necessary context to assert and deassert the pin at the
>>> appropriate time, while still giving us the possibility to make the
>>> device appear on the PCI bus.
>> ISOLATEB gpio disables the PCIe section in RTL8111(Rx is not sampled &
>> doesn't drive Tx), if PCI client driver controls it, then it has
>> to do it after host controller suspend_noirq callback is completed.
>> Only suspend callback available after suspend_noirq is syscore_ops.
>> I didn't go with it because it is take void arguments, so client
>> driver has to maintain global pointers and I see only core drivers
>> like irqchip, clk, etc are using it.
>>
>> Manikanta
>>
>>> As a side-note, I think it would've been better if the ISOLATEB signal
>>> was wired up such that it would've been active by default. That would
>>> mean that if the bootloader and/or OS were not aware of the ISOLATEB
>>> signal, they would still be able to use the Ethernet device. I think
>>> that would've been a more sensible default, especially if the bus that
>>> the device is on requires the signal to be controlled without even
>>> knowing that the device exists.
>>>
>>> Thierry


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 13/30] PCI: tegra: Update flow control threshold in Tegra210
  2019-04-15 15:05     ` Manikanta Maddireddy
@ 2019-04-23  9:27       ` Manikanta Maddireddy
  0 siblings, 0 replies; 106+ messages in thread
From: Manikanta Maddireddy @ 2019-04-23  9:27 UTC (permalink / raw)
  To: Thierry Reding
  Cc: bhelgaas, robh+dt, mark.rutland, jonathanh, lorenzo.pieralisi,
	vidyas, linux-tegra, linux-pci, devicetree



On 15-Apr-19 8:35 PM, Manikanta Maddireddy wrote:
>
> On 15-Apr-19 5:17 PM, Thierry Reding wrote:
>> On Thu, Apr 11, 2019 at 10:33:38PM +0530, Manikanta Maddireddy wrote:
>>> Recommended update FC threshold in Tegra210 is 0x60 for best performance
>>> of x1 link. Setting this to 0x60 provides the best balance between number
>>> of UpdateFC and read data sent over the link.
>>>
>>> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
>>> ---
>>>  drivers/pci/controller/pci-tegra.c | 15 +++++++++++++++
>>>  1 file changed, 15 insertions(+)
>> Looks to me like part of this patch ended up in 12/30?
>>
>> Thierry
> Ok, I will squash 12/30 & 13/30 and clearly mentioned what it means for T124 and T210
> in commit message.

12/30 and 13/30 are fixing two independent issues, so I couldn't merge these
two patches. However I am providing more details in commit log in V2, please
take a look at V2 and let me know if you have different opinion.

Manikanta

>>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>>> index b74408eeb367..7dc728cc5f51 100644
>>> --- a/drivers/pci/controller/pci-tegra.c
>>> +++ b/drivers/pci/controller/pci-tegra.c
>>> @@ -319,6 +319,7 @@ struct tegra_pcie_soc {
>>>  	bool update_clamp_threshold;
>>>  	bool program_deskew_time;
>>>  	bool raw_violation_fixup;
>>> +	bool update_fc_threshold;
>>>  	struct {
>>>  		struct {
>>>  			u32 rp_ectl_2_r1;
>>> @@ -662,6 +663,13 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
>>>  		value |= soc->update_fc_val;
>>>  		writel(value, port->base + RP_VEND_XP);
>>>  	}
>>> +
>>> +	if (soc->update_fc_threshold) {
>>> +		value = readl(port->base + RP_VEND_XP);
>>> +		value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK;
>>> +		value |= soc->update_fc_val;
>>> +		writel(value, port->base + RP_VEND_XP);
>>> +	}
>>>  }
>>>  
>>>  static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
>>> @@ -2409,6 +2417,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
>>>  	.update_clamp_threshold = false,
>>>  	.program_deskew_time = false,
>>>  	.raw_violation_fixup = false,
>>> +	.update_fc_threshold = false,
>>>  	.ectl.enable = false,
>>>  };
>>>  
>>> @@ -2436,6 +2445,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
>>>  	.update_clamp_threshold = false,
>>>  	.program_deskew_time = false,
>>>  	.raw_violation_fixup = false,
>>> +	.update_fc_threshold = false,
>>>  	.ectl.enable = false,
>>>  };
>>>  
>>> @@ -2458,6 +2468,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
>>>  	.update_clamp_threshold = true,
>>>  	.program_deskew_time = false,
>>>  	.raw_violation_fixup = true,
>>> +	.update_fc_threshold = false,
>>>  	.ectl.enable = false,
>>>  };
>>>  
>>> @@ -2468,6 +2479,8 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>>>  	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
>>>  	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
>>>  	.pads_refclk_cfg0 = 0x90b890b8,
>>> +	/* FC threshold is bit[25:18] */
>>> +	.update_fc_val = 0x01800000,
>>>  	.has_pex_clkreq_en = true,
>>>  	.has_pex_bias_ctrl = true,
>>>  	.has_intr_prsnt_sense = true,
>>> @@ -2478,6 +2491,7 @@ static const struct tegra_pcie_soc tegra210_pcie = {
>>>  	.update_clamp_threshold = true,
>>>  	.program_deskew_time = true,
>>>  	.raw_violation_fixup = false,
>>> +	.update_fc_threshold = true,
>>>  	.ectl.regs.rp_ectl_2_r1 = 0x0000000f,
>>>  	.ectl.regs.rp_ectl_4_r1 = 0x00000067,
>>>  	.ectl.regs.rp_ectl_5_r1 = 0x55010000,
>>> @@ -2513,6 +2527,7 @@ static const struct tegra_pcie_soc tegra186_pcie = {
>>>  	.update_clamp_threshold = false,
>>>  	.program_deskew_time = false,
>>>  	.raw_violation_fixup = false,
>>> +	.update_fc_threshold = false,
>>>  	.ectl.enable = false,
>>>  };
>>>  
>>> -- 
>>> 2.17.1
>>>


^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up
  2019-04-15 15:43             ` Manikanta Maddireddy
@ 2019-04-23 20:24               ` Bjorn Helgaas
  0 siblings, 0 replies; 106+ messages in thread
From: Bjorn Helgaas @ 2019-04-23 20:24 UTC (permalink / raw)
  To: Manikanta Maddireddy
  Cc: thierry.reding, robh+dt, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree,
	Jingoo Han, Gustavo Pimentel, Ley Foon Tan, Michal Simek

Sorry, somehow I forgot to respond to this.

On Mon, Apr 15, 2019 at 09:13:29PM +0530, Manikanta Maddireddy wrote:
> On 15-Apr-19 7:34 PM, Bjorn Helgaas wrote:
> > On Mon, Apr 15, 2019 at 05:06:10PM +0530, Manikanta Maddireddy wrote:
> >> On 12-Apr-19 8:20 PM, Bjorn Helgaas wrote:
> >>> On Fri, Apr 12, 2019 at 12:30:22PM +0530, Manikanta Maddireddy wrote:
> >>>> On 12-Apr-19 1:45 AM, Bjorn Helgaas wrote:
> >>>>> On Thu, Apr 11, 2019 at 10:33:47PM +0530, Manikanta Maddireddy wrote:
> >>>>>> Add PCIe link up check in config read and write callback functions
> >>>>>> before accessing endpoint config registers.
> >>>>>>  static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
> >>>>>>  				  int where, int size, u32 *value)
> >>>>>>  {
> >>>>>> +	struct tegra_pcie *pcie = bus->sysdata;
> >>>>>> +	struct pci_dev *bridge;
> >>>>>> +	struct tegra_pcie_port *port;
> >>>>>> +
> >>>>>>  	if (bus->number == 0)
> >>>>>>  		return pci_generic_config_read32(bus, devfn, where, size,
> >>>>>>  						 value);
> >>>>>>  
> >>>>>> +	bridge = pcie_find_root_port(bus->self);
> >>>>>> +
> >>>>>> +	list_for_each_entry(port, &pcie->ports, list)
> >>>>>> +		if (port->index + 1 == PCI_SLOT(bridge->devfn))
> >>>>>> +			break;
> >>>>>> +
> >>>>>> +	/* If there is no link, then there is no device */
> >>>>>> +	if (!tegra_pcie_link_status(port)) {
> >>>>> This is racy and you should avoid it if possible.  The link could go down
> >>>>> between calling tegra_pcie_link_status() and issuing the config read/write.
> >>>>>
> >>>>> If your driver is to be reliable, it must be able to handle any bad
> >>>>> consequence of issuing that config read/write anyway, so I think it's
> >>>>> better if it doesn't even bother checking whether the link is up.
> >>>> This change is made based on similar check present in dwc driver
> >>>> dw_pcie_valid_device(), reasons for making this change in Tegra might
> >>>> differ dwc.
> >>> Yes, you won't be surprised to learn that I don't like the similar
> >>> checks in dwc, altera, xilinx, and xilinx-nwl either :)  I raise this
> >>> issue every time I see it, but I can't remember if I've mentioned dwc
> >>> specifically.
> >>>
> >>> We need to either eradicate this pattern of checking for link up, or
> >>> include a comment about why it is absolutely necessary.
> >> This patch is created to address below scenario in our downstream kernel,
> >> 1) Our platform has WiFi on one slot and GPU in another.
> >> 2) During WiFi OFF, link is put in L2 and it goes through hot reset
> >> when turning ON WiFi (since Tegra doesn't support hot-plug).
> >> 3) Whenever x11 server is started it scans the PCIe bus for video devices.
> >> Here PCIe configuration registers of all devices are read to find out
> >> all available video devices.
> >> 4) If "x11 server" started with WiFi OFF, then we are seeing "response
> >> decoding error"(Tegra AFI module specific error).
> > Probably happens with lspci too.  I guess this is when you try to read
> > the WiFi device config space?
> Yes, happens with lspci when trying to read WiFi device config space.
> >> Best solution we came up with is to have link up check in config access
> >> callback functions.
> > Can you check for "response decoding error" in the config accessor and
> > return 0xffffffff if you see it?
> "Response decoding error" is informed by an
> interrupt(tegra_pcie_isr()), we have to add polling logic in config
> accessor to check if config access caused "response decoding error"
> or not. This will increase config access time.

Config access is never in a performance path, so the access time
doesn't matter.

> Also sometimes BAR access can also cause "Response decoding error", so
> matching "Response decoding error" to a particular config access is
> going to be difficult.

I'm surprised your hardware can't distinguish a failed config access
from an unclaimed MMIO access.

> >>>> Intention here is to reduce the number of AER errors when device is
> >>>> falling off the bus or going through hot reset. So racy condition here is
> >>>> OK
> >>> I'm not convinced about this.  The issues you mention need to be
> >>> solved in a generic way, not a tegra-specific way.
> >>>
> >>> We don't want to end up with code that silently avoids the config
> >>> access 99.99% of the time, but once in a blue moon, we lose the race
> >>> (the device stops responding after we've determined the link is up)
> >>> and the access causes a mysterious AER error that we have no way to
> >>> debug.
> >>>
> >>>>>> +		*value = 0xffffffff;
> >>>>>> +		return PCIBIOS_DEVICE_NOT_FOUND;
> >>>>>> +	}
> >>>>>> +
> >>>>>>  	return pci_generic_config_read(bus, devfn, where, size, value);
> >>>>>>  }

^ permalink raw reply	[flat|nested] 106+ messages in thread

* Re: [PATCH 28/30] dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop
  2019-04-15 14:20   ` Thierry Reding
  2019-04-15 18:01     ` Manikanta Maddireddy
@ 2019-04-29 18:33     ` Rob Herring
  1 sibling, 0 replies; 106+ messages in thread
From: Rob Herring @ 2019-04-29 18:33 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Manikanta Maddireddy, bhelgaas, mark.rutland, jonathanh,
	lorenzo.pieralisi, vidyas, linux-tegra, linux-pci, devicetree

On Mon, Apr 15, 2019 at 04:20:12PM +0200, Thierry Reding wrote:
> On Thu, Apr 11, 2019 at 10:33:53PM +0530, Manikanta Maddireddy wrote:
> > Document "nvidia,rst-gpio" optional property which supports GPIO based
> > PERST# signal.
> > 
> > Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> > ---
> >  Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> > index dca8393b86d1..23928fd59538 100644
> > --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> > +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> > @@ -75,6 +75,8 @@ Optional properties:
> >    Pass pinctrl phandle to allow driver bring PCIe IO out of DPD state.
> >  - nvidia,plat-gpios: A list of platform specific gpios which controls
> >    endpoint's internal regulator or PCIe logic.
> > +- nvidia,rst-gpio: If GPIO is used as PERST# signal instead of available
> > +  SFIO, add this property with phandle to GPIO controller and GPIO number.
> 
> GPIO properties are pretty much standardized, so this should really be
> called just "reset-gpio".

"reset-gpios" actually.

Rob

^ permalink raw reply	[flat|nested] 106+ messages in thread

end of thread, back to index

Thread overview: 106+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-11 17:03 [PATCH 00/30] Enable Tegra PCIe root port features Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 01/30] soc/tegra: pmc: Export tegra_powergate_power_on() Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 02/30] PCI: tegra: Fix PCIe host power up sequence Manikanta Maddireddy
2019-04-15 11:01   ` Thierry Reding
2019-04-15 14:11     ` Manikanta Maddireddy
2019-04-15 14:30       ` Thierry Reding
2019-04-15 18:14         ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 03/30] PCI: tegra: Move REFCLK pad settings out of phy_power_on() Manikanta Maddireddy
2019-04-15 11:06   ` Thierry Reding
2019-04-15 14:20     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 04/30] PCI: tegra: Add PCIe Gen2 link speed support Manikanta Maddireddy
2019-04-15 11:21   ` Thierry Reding
2019-04-15 14:47     ` Manikanta Maddireddy
2019-04-15 15:36       ` Thierry Reding
2019-04-15 15:53         ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 05/30] PCI: tegra: Advertise PCIe Advanced Error Reporting (AER) capability Manikanta Maddireddy
2019-04-15 11:23   ` Thierry Reding
2019-04-15 14:49     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 06/30] PCI: tegra: Program UPHY electrical settings for Tegra210 Manikanta Maddireddy
2019-04-15 11:29   ` Thierry Reding
2019-04-15 14:55     ` Manikanta Maddireddy
2019-04-15 15:38       ` Thierry Reding
2019-04-11 17:03 ` [PATCH 07/30] PCI: tegra: Enable opportunistic update FC and ACK Manikanta Maddireddy
2019-04-15 11:30   ` Thierry Reding
2019-04-11 17:03 ` [PATCH 08/30] PCI: tegra: Disable AFI dynamic clock gating Manikanta Maddireddy
2019-04-15 11:32   ` Thierry Reding
2019-04-11 17:03 ` [PATCH 09/30] PCI: tegra: Process pending DLL transactions before entering L1 or L2 Manikanta Maddireddy
2019-04-15 11:33   ` Thierry Reding
2019-04-11 17:03 ` [PATCH 10/30] PCI: tegra: Enable PCIe xclk clock clamping Manikanta Maddireddy
2019-04-15 11:37   ` Thierry Reding
2019-04-15 14:58     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 11/30] PCI: tegra: Increase the deskew retry time Manikanta Maddireddy
2019-04-15 11:39   ` Thierry Reding
2019-04-15 14:58     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 12/30] PCI: tegra: Add SW fixup for RAW violations Manikanta Maddireddy
2019-04-11 20:01   ` Bjorn Helgaas
2019-04-12  5:59     ` Manikanta Maddireddy
2019-04-15 11:41       ` Thierry Reding
2019-04-15 11:45   ` Thierry Reding
2019-04-15 15:02     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 13/30] PCI: tegra: Update flow control threshold in Tegra210 Manikanta Maddireddy
2019-04-15 11:47   ` Thierry Reding
2019-04-15 15:05     ` Manikanta Maddireddy
2019-04-23  9:27       ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 14/30] PCI: tegra: Set target speed as Gen1 before link up Manikanta Maddireddy
2019-04-11 20:04   ` Bjorn Helgaas
2019-04-12  6:44     ` Manikanta Maddireddy
2019-04-12 14:35       ` Bjorn Helgaas
2019-04-15 10:43         ` Manikanta Maddireddy
2019-04-15 11:52   ` Thierry Reding
2019-04-15 15:12     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 15/30] PCI: tegra: Fix PLLE powerdown issue due to CLKREQ# signal Manikanta Maddireddy
2019-04-15 13:17   ` Thierry Reding
2019-04-15 15:14     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 16/30] PCI: tegra: Program AFI_CACHE* registers only for Tegra20 Manikanta Maddireddy
2019-04-15 13:20   ` Thierry Reding
2019-04-16 10:47     ` Manikanta Maddireddy
2019-04-16 16:11       ` Thierry Reding
2019-04-11 17:03 ` [PATCH 17/30] PCI: tegra: Use switch statements in tegra_pcie_isr() Manikanta Maddireddy
2019-04-15 13:25   ` Thierry Reding
2019-04-15 15:25     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 18/30] PCI: tegra: Change PRSNT_SENSE irq log to debug Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 19/30] PCI: tegra: Use legacy irq for port service drivers Manikanta Maddireddy
2019-04-15 13:35   ` Thierry Reding
2019-04-11 17:03 ` [PATCH 20/30] PCI: tegra: Add AFI_PEX2_CTRL reg offset as part of soc struct Manikanta Maddireddy
2019-04-15 13:31   ` Thierry Reding
2019-04-11 17:03 ` [PATCH 21/30] PCI: tegra: Add "pci" type check before parsing child device tree node Manikanta Maddireddy
2019-04-15 13:37   ` Thierry Reding
2019-04-15 15:30     ` Manikanta Maddireddy
2019-04-15 15:42       ` Thierry Reding
2019-04-11 17:03 ` [PATCH 22/30] PCI: tegra: Access endpoint config only if PCIe link is up Manikanta Maddireddy
2019-04-11 20:15   ` Bjorn Helgaas
2019-04-12  7:00     ` Manikanta Maddireddy
2019-04-12 14:50       ` Bjorn Helgaas
2019-04-15 11:36         ` Manikanta Maddireddy
2019-04-15 13:45           ` Thierry Reding
2019-04-15 13:52             ` Thierry Reding
2019-04-15 14:04           ` Bjorn Helgaas
2019-04-15 15:43             ` Manikanta Maddireddy
2019-04-23 20:24               ` Bjorn Helgaas
2019-04-11 17:03 ` [PATCH 23/30] dt-bindings: pci: tegra: Document PCIe DPD pinctrl optional prop Manikanta Maddireddy
2019-04-15 14:07   ` Thierry Reding
2019-04-15 15:48     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 24/30] arm64: tegra: Add PEX DPD states as pinctrl properties Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 25/30] PCI: tegra: Put PEX CLK & BIAS pads in DPD mode Manikanta Maddireddy
2019-04-15 14:11   ` Thierry Reding
2019-04-11 17:03 ` [PATCH 26/30] dt-bindings: pci: tegra: Document nvidia,plat-gpios optional prop Manikanta Maddireddy
2019-04-11 20:18   ` Bjorn Helgaas
2019-04-12  7:01     ` Manikanta Maddireddy
2019-04-15 14:16   ` Thierry Reding
2019-04-15 17:58     ` Manikanta Maddireddy
2019-04-16 15:34       ` Thierry Reding
2019-04-17 11:22         ` Manikanta Maddireddy
2019-04-17 15:19           ` Thierry Reding
2019-04-17 18:26             ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 27/30] PCI: tegra: Add support to configure platform GPIOs Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 28/30] dt-bindings: pci: tegra: Document nvidia,rst-gpio optional prop Manikanta Maddireddy
2019-04-15 14:20   ` Thierry Reding
2019-04-15 18:01     ` Manikanta Maddireddy
2019-04-29 18:33     ` Rob Herring
2019-04-11 17:03 ` [PATCH 29/30] PCI: tegra: Add support for GPIO based PCIe reset Manikanta Maddireddy
2019-04-15 14:20   ` Thierry Reding
2019-04-15 18:03     ` Manikanta Maddireddy
2019-04-11 17:03 ` [PATCH 30/30] PCI: tegra: Change link retry log level to INFO Manikanta Maddireddy
2019-04-15 14:23   ` Thierry Reding
2019-04-15 18:05     ` Manikanta Maddireddy

Linux-PCI Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-pci/0 linux-pci/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-pci linux-pci/ https://lore.kernel.org/linux-pci \
		linux-pci@vger.kernel.org linux-pci@archiver.kernel.org
	public-inbox-index linux-pci

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-pci


AGPL code for this site: git clone https://public-inbox.org/ public-inbox