linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] soc/tegra: Turn on XUSB partitions
@ 2016-06-30 10:56 Jon Hunter
  2016-06-30 10:56 ` [PATCH 1/4] soc/tegra: pmc: Add specific error messages for initialising a powergate Jon Hunter
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Jon Hunter @ 2016-06-30 10:56 UTC (permalink / raw)
  To: Stephen Warren, Thierry Reding, Alexandre Courbot
  Cc: linux-tegra, linux-kernel, Jon Hunter

The Tegra XHCI driver currently assumes the XUSB power partitions have
been enabled by the bootloader. This is not for the Tegra210 Smaug board
and so cause the kernel to hang when enabling XHCI support. Although the
XHCI driver itself needs to manage these partitions, for now enable the
partitions if the XHCI driver is enabled.

In order to do this I have made a fundamental change to the PMC driver
to initialise the power partitions during early init. A benefit of this
is that if CONFIG_PM_GENERIC_DOMAINS is not enabled, then we can simply
turn on the partitions early before any devices are probed.

This is based upon the PMC fixes series [0].

Changes from initial RFC:
- Added patch to add more detailed error messages when initialising
  powergates.

[0] http://marc.info/?l=linux-tegra&m=146711078013182&w=2

Jon Hunter (4):
  soc/tegra: pmc: Add specific error messages for initialising a
    powergate
  soc/tegra: pmc: Initialise power partitions early
  soc/tegra: pmc: Enable XUSB partitions on boot
  arm64: tegra210: Add XUSB powergates

 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 24 +++++++++++++
 drivers/soc/tegra/pmc.c                  | 60 +++++++++++++++++++++++---------
 2 files changed, 67 insertions(+), 17 deletions(-)

-- 
2.1.4

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

* [PATCH 1/4] soc/tegra: pmc: Add specific error messages for initialising a powergate
  2016-06-30 10:56 [PATCH 0/4] soc/tegra: Turn on XUSB partitions Jon Hunter
@ 2016-06-30 10:56 ` Jon Hunter
  2016-06-30 10:56 ` [PATCH 2/4] soc/tegra: pmc: Initialise power partitions early Jon Hunter
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Jon Hunter @ 2016-06-30 10:56 UTC (permalink / raw)
  To: Stephen Warren, Thierry Reding, Alexandre Courbot
  Cc: linux-tegra, linux-kernel, Jon Hunter

When initialising a powergate, only a single error message is shown if
the initialisation fails. Add more error messages to give specific
details of what failed if the initialisation failed and remove the
generic failure message.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 1f702538f8ec..df61c85e75c7 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -793,11 +793,13 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
 
 	pg = kzalloc(sizeof(*pg), GFP_KERNEL);
 	if (!pg)
-		goto error;
+		return;
 
 	id = tegra_powergate_lookup(pmc, np->name);
-	if (id < 0)
+	if (id < 0) {
+		dev_err(pmc->dev, "powergate lookup failed for %s\n", np->name);
 		goto free_mem;
+	}
 
 	/*
 	 * Clear the bit for this powergate so it cannot be managed
@@ -813,16 +815,23 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
 
 	off = !tegra_powergate_is_powered(pg->id);
 
-	if (tegra_powergate_of_get_clks(pg, np))
+	if (tegra_powergate_of_get_clks(pg, np)) {
+		dev_err(pmc->dev, "failed to get clocks for %s\n", np->name);
 		goto set_available;
+	}
 
-	if (tegra_powergate_of_get_resets(pg, np, off))
+	if (tegra_powergate_of_get_resets(pg, np, off)) {
+		dev_err(pmc->dev, "failed to get resets for %s\n", np->name);
 		goto remove_clks;
+	}
 
 	pm_genpd_init(&pg->genpd, NULL, off);
 
-	if (of_genpd_add_provider_simple(np, &pg->genpd))
+	if (of_genpd_add_provider_simple(np, &pg->genpd)) {
+		dev_err(pmc->dev, "failed to add genpd provider for %s\n",
+			np->name);
 		goto remove_resets;
+	}
 
 	dev_dbg(pmc->dev, "added power domain %s\n", pg->genpd.name);
 
@@ -843,9 +852,6 @@ set_available:
 
 free_mem:
 	kfree(pg);
-
-error:
-	dev_err(pmc->dev, "failed to create power domain for %s\n", np->name);
 }
 
 static void tegra_powergate_init(struct tegra_pmc *pmc)
-- 
2.1.4

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

* [PATCH 2/4] soc/tegra: pmc: Initialise power partitions early
  2016-06-30 10:56 [PATCH 0/4] soc/tegra: Turn on XUSB partitions Jon Hunter
  2016-06-30 10:56 ` [PATCH 1/4] soc/tegra: pmc: Add specific error messages for initialising a powergate Jon Hunter
@ 2016-06-30 10:56 ` Jon Hunter
  2016-06-30 10:56 ` [PATCH 3/4] soc/tegra: pmc: Enable XUSB partitions on boot Jon Hunter
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Jon Hunter @ 2016-06-30 10:56 UTC (permalink / raw)
  To: Stephen Warren, Thierry Reding, Alexandre Courbot
  Cc: linux-tegra, linux-kernel, Jon Hunter

If CONFIG_PM_GENERIC_DOMAINS is not enabled, then power partitions
associated with a device will not be enabled automatically by the PM
core when the device is in use. To avoid situations where a device in
a power partition is to be used but the partition is not enabled,
initialise the power partitions for Tegra early in the boot process and
if CONFIG_PM_GENERIC_DOMAINS is not enabled, then power on all
partitions defined in the device-tree blob.

Note that if CONFIG_PM_GENERIC_DOMAINS is not enabled, after the
partitions are turned on, the clocks and resets used as part of the
sequence for turning on the partition are released again as they are no
longer needed by the PMC driver. Another benefit of this is that this
avoids any issues of sharing resets between the PMC driver and other
device drivers that may wish to independently control a particular
reset.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index df61c85e75c7..dd36ad974c67 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -825,6 +825,9 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
 		goto remove_clks;
 	}
 
+	if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS))
+		goto power_on_cleanup;
+
 	pm_genpd_init(&pg->genpd, NULL, off);
 
 	if (of_genpd_add_provider_simple(np, &pg->genpd)) {
@@ -837,6 +840,10 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
 
 	return;
 
+power_on_cleanup:
+	if (off)
+		WARN_ON(tegra_powergate_power_up(pg, true));
+
 remove_resets:
 	while (pg->num_resets--)
 		reset_control_put(pg->resets[pg->num_resets]);
@@ -854,11 +861,18 @@ free_mem:
 	kfree(pg);
 }
 
-static void tegra_powergate_init(struct tegra_pmc *pmc)
+static void tegra_powergate_init(struct tegra_pmc *pmc,
+				 struct device_node *parent)
 {
 	struct device_node *np, *child;
+	unsigned int i;
 
-	np = of_get_child_by_name(pmc->dev->of_node, "powergates");
+	/* Create a bit-map of the available and valid partitions */
+	for (i = 0; i < pmc->soc->num_powergates; i++)
+		if (pmc->soc->powergates[i])
+			set_bit(i, pmc->powergates_available);
+
+	np = of_get_child_by_name(parent, "powergates");
 	if (!np)
 		return;
 
@@ -1279,8 +1293,6 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	tegra_powergate_init(pmc);
-
 	mutex_lock(&pmc->powergates_lock);
 	iounmap(pmc->base);
 	pmc->base = base;
@@ -1514,7 +1526,6 @@ static int __init tegra_pmc_early_init(void)
 	const struct of_device_id *match;
 	struct device_node *np;
 	struct resource regs;
-	unsigned int i;
 	bool invert;
 	u32 value;
 
@@ -1569,10 +1580,7 @@ static int __init tegra_pmc_early_init(void)
 	if (np) {
 		pmc->soc = match->data;
 
-		/* Create a bit-map of the available and valid partitions */
-		for (i = 0; i < pmc->soc->num_powergates; i++)
-			if (pmc->soc->powergates[i])
-				set_bit(i, pmc->powergates_available);
+		tegra_powergate_init(pmc, np);
 
 		/*
 		 * Invert the interrupt polarity if a PMC device tree node
-- 
2.1.4

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

* [PATCH 3/4] soc/tegra: pmc: Enable XUSB partitions on boot
  2016-06-30 10:56 [PATCH 0/4] soc/tegra: Turn on XUSB partitions Jon Hunter
  2016-06-30 10:56 ` [PATCH 1/4] soc/tegra: pmc: Add specific error messages for initialising a powergate Jon Hunter
  2016-06-30 10:56 ` [PATCH 2/4] soc/tegra: pmc: Initialise power partitions early Jon Hunter
@ 2016-06-30 10:56 ` Jon Hunter
  2016-06-30 10:56 ` [PATCH 4/4] arm64: tegra210: Add XUSB powergates Jon Hunter
  2016-06-30 13:24 ` [PATCH 0/4] soc/tegra: Turn on XUSB partitions Thierry Reding
  4 siblings, 0 replies; 6+ messages in thread
From: Jon Hunter @ 2016-06-30 10:56 UTC (permalink / raw)
  To: Stephen Warren, Thierry Reding, Alexandre Courbot
  Cc: linux-tegra, linux-kernel, Jon Hunter

The Tegra XHCI driver does not currently manage the Tegra XUSB power
partitions and so it these partitions have not been enabled by the
bootloader then the system will crash when probing the XHCI device.

While proper support for managing the power partitions is being
developed to the XHCI driver for Tegra, for now power on all the XUSB
partitions for USB host and super-speed on boot if the XHCI driver is
enabled.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/soc/tegra/pmc.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index dd36ad974c67..7d72eef92b9b 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -828,6 +828,18 @@ static void tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np)
 	if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS))
 		goto power_on_cleanup;
 
+	/*
+	 * FIXME: If XHCI is enabled for Tegra, then power-up the XUSB
+	 * host and super-speed partitions. Once the XHCI driver
+	 * manages the partitions itself this code can be removed. Note
+	 * that we don't register these partitions with the genpd core
+	 * to avoid it from powering down the partitions as they appear
+	 * to be unused.
+	 */
+	if (IS_ENABLED(CONFIG_USB_XHCI_TEGRA) &&
+	    (id == TEGRA_POWERGATE_XUSBA || id == TEGRA_POWERGATE_XUSBC))
+		goto power_on_cleanup;
+
 	pm_genpd_init(&pg->genpd, NULL, off);
 
 	if (of_genpd_add_provider_simple(np, &pg->genpd)) {
-- 
2.1.4

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

* [PATCH 4/4] arm64: tegra210: Add XUSB powergates
  2016-06-30 10:56 [PATCH 0/4] soc/tegra: Turn on XUSB partitions Jon Hunter
                   ` (2 preceding siblings ...)
  2016-06-30 10:56 ` [PATCH 3/4] soc/tegra: pmc: Enable XUSB partitions on boot Jon Hunter
@ 2016-06-30 10:56 ` Jon Hunter
  2016-06-30 13:24 ` [PATCH 0/4] soc/tegra: Turn on XUSB partitions Thierry Reding
  4 siblings, 0 replies; 6+ messages in thread
From: Jon Hunter @ 2016-06-30 10:56 UTC (permalink / raw)
  To: Stephen Warren, Thierry Reding, Alexandre Courbot
  Cc: linux-tegra, linux-kernel, Jon Hunter

The Tegra210 XUSB subsystem has 3 power partitions which are XUSBA
(super-speed logic), XUSBB (USB device logic) and XUSBC (USB host
logic). Populate the device-tree nodes for these XUSB partitions.

Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 65b829b762bb..efb0fd98b789 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -670,6 +670,30 @@
 					 <&tegra_car TEGRA210_CLK_MIPI_CAL>;
 				#power-domain-cells = <0>;
 			};
+
+			pd_xusbss: xusba {
+				clocks = <&tegra_car TEGRA210_CLK_XUSB_SS>;
+				clock-names = "xusb_ss";
+				resets = <&tegra_car TEGRA210_CLK_XUSB_SS>;
+				reset-names = "xusb_ss";
+				#power-domain-cells = <0>;
+			};
+
+			pd_xusbdev: xusbb {
+				clocks = <&tegra_car TEGRA210_CLK_XUSB_DEV>;
+				clock-names = "xusb_dev";
+				resets = <&tegra_car 95>;
+				reset-names = "xusb_dev";
+				#power-domain-cells = <0>;
+			};
+
+			pd_xusbhost: xusbc {
+				clocks = <&tegra_car TEGRA210_CLK_XUSB_HOST>;
+				clock-names = "xusb_host";
+				resets = <&tegra_car TEGRA210_CLK_XUSB_HOST>;
+				reset-names = "xusb_host";
+				#power-domain-cells = <0>;
+			};
 		};
 	};
 
-- 
2.1.4

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

* Re: [PATCH 0/4] soc/tegra: Turn on XUSB partitions
  2016-06-30 10:56 [PATCH 0/4] soc/tegra: Turn on XUSB partitions Jon Hunter
                   ` (3 preceding siblings ...)
  2016-06-30 10:56 ` [PATCH 4/4] arm64: tegra210: Add XUSB powergates Jon Hunter
@ 2016-06-30 13:24 ` Thierry Reding
  4 siblings, 0 replies; 6+ messages in thread
From: Thierry Reding @ 2016-06-30 13:24 UTC (permalink / raw)
  To: Jon Hunter; +Cc: Stephen Warren, Alexandre Courbot, linux-tegra, linux-kernel

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

On Thu, Jun 30, 2016 at 11:56:23AM +0100, Jon Hunter wrote:
> The Tegra XHCI driver currently assumes the XUSB power partitions have
> been enabled by the bootloader. This is not for the Tegra210 Smaug board
> and so cause the kernel to hang when enabling XHCI support. Although the
> XHCI driver itself needs to manage these partitions, for now enable the
> partitions if the XHCI driver is enabled.
> 
> In order to do this I have made a fundamental change to the PMC driver
> to initialise the power partitions during early init. A benefit of this
> is that if CONFIG_PM_GENERIC_DOMAINS is not enabled, then we can simply
> turn on the partitions early before any devices are probed.
> 
> This is based upon the PMC fixes series [0].
> 
> Changes from initial RFC:
> - Added patch to add more detailed error messages when initialising
>   powergates.
> 
> [0] http://marc.info/?l=linux-tegra&m=146711078013182&w=2
> 
> Jon Hunter (4):
>   soc/tegra: pmc: Add specific error messages for initialising a
>     powergate
>   soc/tegra: pmc: Initialise power partitions early
>   soc/tegra: pmc: Enable XUSB partitions on boot
>   arm64: tegra210: Add XUSB powergates
> 
>  arch/arm64/boot/dts/nvidia/tegra210.dtsi | 24 +++++++++++++
>  drivers/soc/tegra/pmc.c                  | 60 +++++++++++++++++++++++---------
>  2 files changed, 67 insertions(+), 17 deletions(-)

Applied, thanks.

Thierry

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

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

end of thread, other threads:[~2016-06-30 13:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-30 10:56 [PATCH 0/4] soc/tegra: Turn on XUSB partitions Jon Hunter
2016-06-30 10:56 ` [PATCH 1/4] soc/tegra: pmc: Add specific error messages for initialising a powergate Jon Hunter
2016-06-30 10:56 ` [PATCH 2/4] soc/tegra: pmc: Initialise power partitions early Jon Hunter
2016-06-30 10:56 ` [PATCH 3/4] soc/tegra: pmc: Enable XUSB partitions on boot Jon Hunter
2016-06-30 10:56 ` [PATCH 4/4] arm64: tegra210: Add XUSB powergates Jon Hunter
2016-06-30 13:24 ` [PATCH 0/4] soc/tegra: Turn on XUSB partitions Thierry Reding

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).