Linux GPIO subsystem development
 help / color / mirror / Atom feed
* Re: [PATCH v8 08/21] clk: tegra: periph: Add restore_context support
From: Dmitry Osipenko @ 2019-08-09 11:55 UTC (permalink / raw)
  To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
	marc.zyngier, linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
	robh+dt, devicetree, rjw, viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-9-git-send-email-skomatineni@nvidia.com>

09.08.2019 2:46, Sowjanya Komatineni пишет:
> This patch implements restore_context support for clk-periph and
> clk-sdmmc-mux clock operations to restore clock parent and rates
> on system resume.
> 
> During system suspend, core power goes off and looses the context
> of the Tegra clock controller registers.
> 
> So on system resume, clocks parent and rate are restored back to
> the context before suspend based on cached data.
> 
> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
> ---
>  drivers/clk/tegra/clk-periph.c    | 18 ++++++++++++++++++
>  drivers/clk/tegra/clk-sdmmc-mux.c | 12 ++++++++++++
>  2 files changed, 30 insertions(+)
> 
> diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
> index 58437da25156..c9d28cbadccc 100644
> --- a/drivers/clk/tegra/clk-periph.c
> +++ b/drivers/clk/tegra/clk-periph.c
> @@ -3,6 +3,7 @@
>   * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
>   */
>  
> +#include <linux/clk.h>
>  #include <linux/clk-provider.h>
>  #include <linux/export.h>
>  #include <linux/slab.h>
> @@ -99,6 +100,20 @@ static void clk_periph_disable(struct clk_hw *hw)
>  	gate_ops->disable(gate_hw);
>  }
>  
> +static void clk_periph_restore_context(struct clk_hw *hw)
> +{
> +	struct tegra_clk_periph *periph = to_clk_periph(hw);
> +	const struct clk_ops *div_ops = periph->div_ops;
> +	struct clk_hw *div_hw = &periph->divider.hw;
> +	struct clk_hw *parent = clk_hw_get_parent(hw);
> +	int parent_id = clk_hw_get_parent_index(hw, parent);
> +
> +	if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV))
> +		div_ops->restore_context(div_hw);
> +
> +	clk_periph_set_parent(hw, parent_id);
> +}
> +
>  const struct clk_ops tegra_clk_periph_ops = {
>  	.get_parent = clk_periph_get_parent,
>  	.set_parent = clk_periph_set_parent,
> @@ -108,6 +123,7 @@ const struct clk_ops tegra_clk_periph_ops = {
>  	.is_enabled = clk_periph_is_enabled,
>  	.enable = clk_periph_enable,
>  	.disable = clk_periph_disable,
> +	.restore_context = clk_periph_restore_context,
>  };
>  
>  static const struct clk_ops tegra_clk_periph_nodiv_ops = {
> @@ -116,6 +132,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = {
>  	.is_enabled = clk_periph_is_enabled,
>  	.enable = clk_periph_enable,
>  	.disable = clk_periph_disable,
> +	.restore_context = clk_periph_restore_context,
>  };
>  
>  static const struct clk_ops tegra_clk_periph_no_gate_ops = {
> @@ -124,6 +141,7 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = {
>  	.recalc_rate = clk_periph_recalc_rate,
>  	.round_rate = clk_periph_round_rate,
>  	.set_rate = clk_periph_set_rate,
> +	.restore_context = clk_periph_restore_context,
>  };
>  
>  static struct clk *_tegra_clk_register_periph(const char *name,
> diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c
> index a5cd3e31dbae..8db48966b100 100644
> --- a/drivers/clk/tegra/clk-sdmmc-mux.c
> +++ b/drivers/clk/tegra/clk-sdmmc-mux.c
> @@ -194,6 +194,17 @@ static void clk_sdmmc_mux_disable(struct clk_hw *hw)
>  	gate_ops->disable(gate_hw);
>  }
>  
> +static void clk_sdmmc_mux_restore_context(struct clk_hw *hw)
> +{
> +	struct clk_hw *parent = clk_hw_get_parent(hw);
> +	unsigned long parent_rate = clk_hw_get_rate(parent);
> +	unsigned long rate = clk_hw_get_rate(hw);
> +	int parent_id = clk_hw_get_parent_index(hw, parent);
> +
> +	clk_sdmmc_mux_set_parent(hw, parent_id);
> +	clk_sdmmc_mux_set_rate(hw, rate, parent_rate);

For the periph clocks you're restoring rate at first and then the
parent, while here it's the other way around. I'm wondering if there is
any difference in practice and thus whether rate's divider need to be
set to a some safe value before switching to a new parent that has a
higher clock rate than the old parent.

> +}
> +
>  static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
>  	.get_parent = clk_sdmmc_mux_get_parent,
>  	.set_parent = clk_sdmmc_mux_set_parent,
> @@ -203,6 +214,7 @@ static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
>  	.is_enabled = clk_sdmmc_mux_is_enabled,
>  	.enable = clk_sdmmc_mux_enable,
>  	.disable = clk_sdmmc_mux_disable,
> +	.restore_context = clk_sdmmc_mux_restore_context,
>  };
>  
>  struct clk *tegra_clk_register_sdmmc_mux_div(const char *name,
> 


^ permalink raw reply

* Re: [PATCH v8 07/21] clk: Add API to get index of the clock parent
From: Dmitry Osipenko @ 2019-08-09 11:49 UTC (permalink / raw)
  To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
	marc.zyngier, linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
	robh+dt, devicetree, rjw, viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-8-git-send-email-skomatineni@nvidia.com>

09.08.2019 2:46, Sowjanya Komatineni пишет:
> This patch adds an API clk_hw_get_parent_index to get index of the
> clock parent to use during the clock restore operations on system
> resume.
> 
> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
> ---
>  drivers/clk/clk.c            | 17 +++++++++++++++++
>  include/linux/clk-provider.h |  1 +
>  2 files changed, 18 insertions(+)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index c0990703ce54..f26252e48f73 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -1643,6 +1643,23 @@ static int clk_fetch_parent_index(struct clk_core *core,
>  	return i;
>  }
>  
> +/**
> + * clk_hw_get_parent_index - return the index of parent clock
> + * @hw: clk_hw associated with the clk being consumed
> + * @parent_hw: clk_hw associated with the parent of clk
> + *
> + * Fetches and returns the index of parent clock.
> + * if hw or parent_hw is NULL, returns -EINVAL.
> + */
> +int clk_hw_get_parent_index(struct clk_hw *hw, struct clk_hw *parent_hw)
> +{
> +	if (!hw || !parent_hw)
> +		return -EINVAL;
> +
> +	return clk_fetch_parent_index(hw->core, parent_hw->core);
> +}
> +EXPORT_SYMBOL_GPL(clk_hw_get_parent_index);
> +
>  /*
>   * Update the orphan status of @core and all its children.
>   */
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index 2ae7604783dd..477112946dd2 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -817,6 +817,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
>  struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
>  struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
>  					  unsigned int index);
> +int clk_hw_get_parent_index(struct clk_hw *hw, struct clk_hw *parent_hw);
>  unsigned int __clk_get_enable_count(struct clk *clk);
>  unsigned long clk_hw_get_rate(const struct clk_hw *hw);
>  unsigned long __clk_get_flags(struct clk *clk);
> 

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>

^ permalink raw reply

* Re: [PATCH v8 02/21] pinctrl: tegra: Add write barrier after all pinctrl register writes
From: Dmitry Osipenko @ 2019-08-09 11:39 UTC (permalink / raw)
  To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
	marc.zyngier, linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
	robh+dt, devicetree, rjw, viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-3-git-send-email-skomatineni@nvidia.com>

09.08.2019 2:46, Sowjanya Komatineni пишет:
> This patch adds write barrier after all pinctrl register writes
> during resume to make sure all pinctrl changes are complete.
> 
> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
> ---
>  drivers/pinctrl/tegra/pinctrl-tegra.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
> index 982ee634b3b1..f49fe29fb6df 100644
> --- a/drivers/pinctrl/tegra/pinctrl-tegra.c
> +++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
> @@ -677,6 +677,8 @@ static int tegra_pinctrl_resume(struct device *dev)
>  			writel_relaxed(*backup_regs++, regs++);
>  	}
>  
> +	/* make sure all the pinmux register writes are complete */
> +	wmb();
>  	return 0;
>  }
>  
> 

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>

^ permalink raw reply

* Re: [PATCH v8 01/21] pinctrl: tegra: Fix write barrier placement in pmx_writel
From: Dmitry Osipenko @ 2019-08-09 11:38 UTC (permalink / raw)
  To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
	marc.zyngier, linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
	robh+dt, devicetree, rjw, viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-2-git-send-email-skomatineni@nvidia.com>

09.08.2019 2:46, Sowjanya Komatineni пишет:
> pmx_writel uses writel which inserts write barrier before the
> register write rather.
> 
> This patch has fix to replace writel with writel_relaxed followed
> by a write barrier to ensure write operation before the barrier
> is completed for successful pinctrl change.
> 
> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
> ---
>  drivers/pinctrl/tegra/pinctrl-tegra.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
> index e3a237534281..982ee634b3b1 100644
> --- a/drivers/pinctrl/tegra/pinctrl-tegra.c
> +++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
> @@ -32,7 +32,9 @@ static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)
>  
>  static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
>  {
> -	writel(val, pmx->regs[bank] + reg);
> +	writel_relaxed(val, pmx->regs[bank] + reg);
> +	/* make sure pinmux register write completed */
> +	wmb();
>  }
>  
>  static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
> 

But this only ensures that CPU have sent the write to the APB BUS and
not that the write actually taken into effect? I'm a bit paranoid when
it comes to a cross-domain synchronization things.

Any ways it looks better than it was before.

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>

^ permalink raw reply

* Re: [PATCH v8 05/21] clk: tegra: pll: Save and restore pll context
From: Dmitry Osipenko @ 2019-08-09 11:33 UTC (permalink / raw)
  To: Sowjanya Komatineni, thierry.reding, jonathanh, tglx, jason,
	marc.zyngier, linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, linux-tegra, linux-kernel, mperttunen, spatra,
	robh+dt, devicetree, rjw, viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-6-git-send-email-skomatineni@nvidia.com>

09.08.2019 2:46, Sowjanya Komatineni пишет:
> This patch implements save and restore of PLL context.
> 
> During system suspend, core power goes off and looses the settings
> of the Tegra CAR controller registers.
> 
> So during suspend entry pll context is stored and on resume it is
> restored back along with its state.
> 
> Acked-by: Thierry Reding <treding@nvidia.com>
> Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
> ---
>  drivers/clk/tegra/clk-pll.c | 88 ++++++++++++++++++++++++++++-----------------
>  drivers/clk/tegra/clk.h     |  2 ++
>  2 files changed, 58 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
> index 1583f5fc992f..e52add2bbdbb 100644
> --- a/drivers/clk/tegra/clk-pll.c
> +++ b/drivers/clk/tegra/clk-pll.c
> @@ -1008,6 +1008,28 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
>  	return rate;
>  }
>  
> +static void tegra_clk_pll_restore_context(struct clk_hw *hw)
> +{
> +	struct tegra_clk_pll *pll = to_clk_pll(hw);
> +	struct clk_hw *parent = clk_hw_get_parent(hw);
> +	unsigned long parent_rate = clk_hw_get_rate(parent);
> +	unsigned long rate = clk_hw_get_rate(hw);
> +	u32 val;
> +
> +	if (clk_pll_is_enabled(hw))
> +		return;
> +
> +	if (pll->params->set_defaults)
> +		pll->params->set_defaults(pll);
> +
> +	clk_pll_set_rate(hw, rate, parent_rate);
> +
> +	if (!__clk_get_enable_count(hw->clk))

What about orphaned clocks? Is enable_count > 0 for them?

> +		clk_pll_disable(hw);
> +	else
> +		clk_pll_enable(hw);
> +}

[snip]

^ permalink raw reply

* Re: [PATCH 1/6] dt-bindings: gpio: davinci: Add new compatible for J721E SoCs
From: Keerthy @ 2019-08-09 10:55 UTC (permalink / raw)
  To: Lokesh Vutla, Tero Kristo, Nishanth Menon, linus.walleij
  Cc: Rob Herring, linux-gpio, Device Tree Mailing List,
	Linux ARM Mailing List
In-Reply-To: <20190809082947.30590-2-lokeshvutla@ti.com>



On 09/08/19 1:59 PM, Lokesh Vutla wrote:
> J721e SoCs have same gpio IP as K2G davinci gpio. Add a new compatible to
> handle J721E SoCs.

Reviewed-by: Keerthy <j-keerthy@ti.com>

> 
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
>   Documentation/devicetree/bindings/gpio/gpio-davinci.txt | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
> index bc6b4b62df83..cd91d61eac31 100644
> --- a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
> +++ b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
> @@ -6,6 +6,7 @@ Required Properties:
>   						66AK2E SoCs
>   			"ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G
>   			"ti,am654-gpio", "ti,keystone-gpio": for TI K3 AM654
> +			"ti,j721e-gpio", "ti,keystone-gpio": for J721E SoCs
>   
>   - reg: Physical base address of the controller and the size of memory mapped
>          registers.
> 

^ permalink raw reply

* Re: [PATCH v2] pinctrl: intel: Allow to request locked pads
From: Mika Westerberg @ 2019-08-09  8:40 UTC (permalink / raw)
  To: Andy Shevchenko; +Cc: linux-gpio, Linus Walleij
In-Reply-To: <20190808132128.13359-1-andriy.shevchenko@linux.intel.com>

On Thu, Aug 08, 2019 at 04:21:28PM +0300, Andy Shevchenko wrote:
> Some firmwares would like to protect pads from being modified by OS
> and at the same time provide them to OS as a resource. So, the driver
> in such circumstances may request pad and may not change its state.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> in v2:
> - amended comment in intel_pad_locked() respectively to the change (Mika)
> - described enum values (Linus)
> - lowered case for locking flavour in debugfs for better looking
>  drivers/pinctrl/intel/pinctrl-intel.c | 67 ++++++++++++++++++++-------
>  1 file changed, 50 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
> index c949df07cbdf..b84a5579beee 100644
> --- a/drivers/pinctrl/intel/pinctrl-intel.c
> +++ b/drivers/pinctrl/intel/pinctrl-intel.c
> @@ -220,47 +220,69 @@ static bool intel_pad_acpi_mode(struct intel_pinctrl *pctrl, unsigned int pin)
>  	return !(readl(hostown) & BIT(gpp_offset));
>  }
>  
> -static bool intel_pad_locked(struct intel_pinctrl *pctrl, unsigned int pin)
> +/*

This should be /**

> + * PAD_UNLOCKED:	pad is fully controlled by the configuration registers

These should have @ prefix, I think.

Otherwise looks good.

^ permalink raw reply

* [PATCH 6/6] arm64: dts: k3-j721e: Add gpio-keys on common processor board
From: Lokesh Vutla @ 2019-08-09  8:29 UTC (permalink / raw)
  To: Tero Kristo, Nishanth Menon, linus.walleij
  Cc: Keerthy, Rob Herring, linux-gpio, Device Tree Mailing List,
	Linux ARM Mailing List, Lokesh Vutla
In-Reply-To: <20190809082947.30590-1-lokeshvutla@ti.com>

From: Nikhil Devshatwar <nikhil.nd@ti.com>

Common processor board for K3 J721E platform has two push buttons
namely SW10 and SW11.
Add a gpio-keys device node to model them as input keys in Linux.
Add required pinmux nodes to set GPIO pins as input.

Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 .../dts/ti/k3-j721e-common-proc-board.dts     | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
index 509579ca3db2..d2894d55fbbe 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
@@ -6,12 +6,49 @@
 /dts-v1/;
 
 #include "k3-j721e-som-p0.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
 	chosen {
 		stdout-path = "serial2:115200n8";
 		bootargs = "console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02800000";
 	};
+
+	gpio_keys: gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sw10_button_pins_default &sw11_button_pins_default>;
+
+		sw10: sw10 {
+			label = "GPIO Key USER1";
+			linux,code = <BTN_0>;
+			gpios = <&main_gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		sw11: sw11 {
+			label = "GPIO Key USER2";
+			linux,code = <BTN_1>;
+			gpios = <&wkup_gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&main_pmx0 {
+	sw10_button_pins_default: sw10_button_pins_default {
+		pinctrl-single,pins = <
+			J721E_IOPAD(0x0, PIN_INPUT, 7) /* (AC18) EXTINTn.GPIO0_0 */
+		>;
+	};
+};
+
+&wkup_pmx0 {
+	sw11_button_pins_default: sw11_button_pins_default {
+		pinctrl-single,pins = <
+			J721E_WKUP_IOPAD(0xcc, PIN_INPUT, 7) /* (G28) WKUP_GPIO0_7 */
+		>;
+	};
 };
 
 &wkup_uart0 {
-- 
2.22.0


^ permalink raw reply related

* [PATCH 5/6] dt-bindings: pinctrl: k3: Introduce pinmux definitions for J721E
From: Lokesh Vutla @ 2019-08-09  8:29 UTC (permalink / raw)
  To: Tero Kristo, Nishanth Menon, linus.walleij
  Cc: Keerthy, Rob Herring, linux-gpio, Device Tree Mailing List,
	Linux ARM Mailing List, Lokesh Vutla
In-Reply-To: <20190809082947.30590-1-lokeshvutla@ti.com>

Add pinctrl macros for J721E SoC. These macro definitions are
similar to that of AM6, but adding new definitions to avoid
any naming confusions in the soc dts files.

Acked-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 include/dt-bindings/pinctrl/k3.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/dt-bindings/pinctrl/k3.h b/include/dt-bindings/pinctrl/k3.h
index 45e11b6170ca..499de6216581 100644
--- a/include/dt-bindings/pinctrl/k3.h
+++ b/include/dt-bindings/pinctrl/k3.h
@@ -32,4 +32,7 @@
 #define AM65X_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
 #define AM65X_WKUP_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
 
+#define J721E_IOPAD(pa, val, muxmode)		(((pa) & 0x1fff)) ((val) | (muxmode))
+#define J721E_WKUP_IOPAD(pa, val, muxmode)	(((pa) & 0x1fff)) ((val) | (muxmode))
+
 #endif
-- 
2.22.0


^ permalink raw reply related

* [PATCH 4/6] arm64: dts: ti: k3-j721e-common-proc-board: Disable unused gpio modules
From: Lokesh Vutla @ 2019-08-09  8:29 UTC (permalink / raw)
  To: Tero Kristo, Nishanth Menon, linus.walleij
  Cc: Keerthy, Rob Herring, linux-gpio, Device Tree Mailing List,
	Linux ARM Mailing List, Lokesh Vutla
In-Reply-To: <20190809082947.30590-1-lokeshvutla@ti.com>

There are 10 gpio instances inside SoC with 3 groups as below:
- Group1: main_gpio0, main_gpio2, main_gpio4, main_gpio6
- Group2: main_gpio1, main_gpio3, main_gpio5, main_gpio7
- Group3: wkup_gpio0, wkup_gpio1

Only one instance can be used in each group at a time. So use main_gpio0,
main_gpio1 and wkup_gpio0 for the current linux context and mark other
gpio nodes as disabled.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 .../dts/ti/k3-j721e-common-proc-board.dts     | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
index 63b47b839388..509579ca3db2 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
@@ -52,3 +52,31 @@
 	/* UART not brought out */
 	status = "disabled";
 };
+
+&main_gpio2 {
+	status = "disabled";
+};
+
+&main_gpio3 {
+	status = "disabled";
+};
+
+&main_gpio4 {
+	status = "disabled";
+};
+
+&main_gpio5 {
+	status = "disabled";
+};
+
+&main_gpio6 {
+	status = "disabled";
+};
+
+&main_gpio7 {
+	status = "disabled";
+};
+
+&wkup_gpio1 {
+	status = "disabled";
+};
-- 
2.22.0


^ permalink raw reply related

* [PATCH 2/6] arm64: dts: ti: k3-j721e: Add gpio nodes in main domain
From: Lokesh Vutla @ 2019-08-09  8:29 UTC (permalink / raw)
  To: Tero Kristo, Nishanth Menon, linus.walleij
  Cc: Keerthy, Rob Herring, linux-gpio, Device Tree Mailing List,
	Linux ARM Mailing List, Lokesh Vutla
In-Reply-To: <20190809082947.30590-1-lokeshvutla@ti.com>

There are 8 instances of gpio modules in main domain divided into 2 groups:
- Group1: gpio0, gpio2, gpio4, gpio6
- Group2: gpio1, gpio3, gpio5, gpio7

Groups are created to provide protection between two different processor
virtual worlds. There are x gpio lines coming out of each group. Each module
in a group has equal x gpio lines pinned out. There is a top level mux for
selecting the module instance for each pin coming out of group. Exactly
one module can be selected to control the corresponding pin. This muxing
can be controlled along the pad mux configuration registers.

Group1 pins out 128 lines(8 banks). Group 2 pins out 36 lines(2 banks).

Add DT nodes for each module instance in the main domain. Users should
make sure that correct gpio instance is selected in their pad configuration.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 132 ++++++++++++++++++++++
 1 file changed, 132 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 01661c22c39d..199bc9a00b20 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -240,4 +240,136 @@
 		clocks = <&k3_clks 286 0>;
 		clock-names = "fclk";
 	};
+
+	main_gpio0: gpio@600000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x00600000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio_intr>;
+		interrupts = <105 0>, <105 1>, <105 2>, <105 3>,
+			     <105 4>, <105 5>, <105 6>, <105 7>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <128>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 105 0>;
+		clock-names = "gpio";
+	};
+
+	main_gpio1: gpio@601000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x00601000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio_intr>;
+		interrupts = <106 0>, <106 1>, <106 2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <36>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 106 0>;
+		clock-names = "gpio";
+	};
+
+	main_gpio2: gpio@610000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x00610000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio_intr>;
+		interrupts = <107 0>, <107 1>, <107 2>, <107 3>,
+			     <107 4>, <107 5>, <107 6>, <107 7>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <128>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 107 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 107 0>;
+		clock-names = "gpio";
+	};
+
+	main_gpio3: gpio@611000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x00611000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio_intr>;
+		interrupts = <108 0>, <108 1>, <108 2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <36>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 108 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 108 0>;
+		clock-names = "gpio";
+	};
+
+	main_gpio4: gpio@620000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x00620000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio_intr>;
+		interrupts = <109 0>, <109 1>, <109 2>, <109 3>,
+			     <109 4>, <109 5>, <109 6>, <109 7>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <128>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 109 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 109 0>;
+		clock-names = "gpio";
+	};
+
+	main_gpio5: gpio@621000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x00621000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio_intr>;
+		interrupts = <110 0>, <110 1>, <110 2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <36>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 110 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 110 0>;
+		clock-names = "gpio";
+	};
+
+	main_gpio6: gpio@630000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x00630000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio_intr>;
+		interrupts = <111 0>, <111 1>, <111 2>, <111 3>,
+			     <111 4>, <111 5>, <111 6>, <111 7>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <128>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 111 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 111 0>;
+		clock-names = "gpio";
+	};
+
+	main_gpio7: gpio@631000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x00631000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&main_gpio_intr>;
+		interrupts = <112 0>, <112 1>, <112 2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <36>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 112 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 112 0>;
+		clock-names = "gpio";
+	};
 };
-- 
2.22.0


^ permalink raw reply related

* [PATCH 3/6] arm64: dts: ti: k3-j721e: Add gpio nodes in wakeup domain
From: Lokesh Vutla @ 2019-08-09  8:29 UTC (permalink / raw)
  To: Tero Kristo, Nishanth Menon, linus.walleij
  Cc: Keerthy, Rob Herring, linux-gpio, Device Tree Mailing List,
	Linux ARM Mailing List, Lokesh Vutla
In-Reply-To: <20190809082947.30590-1-lokeshvutla@ti.com>

Similar to the gpio groups in main domain, there is one gpio group
in wakup domain with 2 module instances in it. This gpio group pins
out 84 lines(6 banks). Add DT node for these 2 gpio module instances.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 .../boot/dts/ti/k3-j721e-mcu-wakeup.dtsi      | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
index e616c2481f51..555dc7b7aedc 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
@@ -87,4 +87,38 @@
 		ti,sci-dst-id = <14>;
 		ti,sci-rm-range-girq = <0x5>;
 	};
+
+	wkup_gpio0: gpio@42110000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x42110000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&wkup_gpio_intr>;
+		interrupts = <113 0>, <113 1>, <113 2>,
+			     <113 3>, <113 4>, <113 5>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <84>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 113 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 113 0>;
+		clock-names = "gpio";
+	};
+
+	wkup_gpio1: gpio@42100000 {
+		compatible = "ti,j721e-gpio", "ti,keystone-gpio";
+		reg = <0x0 0x42100000 0x0 0x100>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&wkup_gpio_intr>;
+		interrupts = <114 0>, <114 1>, <114 2>,
+			     <114 3>, <114 4>, <114 5>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		ti,ngpio = <84>;
+		ti,davinci-gpio-unbanked = <0>;
+		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
+		clocks = <&k3_clks 114 0>;
+		clock-names = "gpio";
+	};
 };
-- 
2.22.0


^ permalink raw reply related

* [PATCH 1/6] dt-bindings: gpio: davinci: Add new compatible for J721E SoCs
From: Lokesh Vutla @ 2019-08-09  8:29 UTC (permalink / raw)
  To: Tero Kristo, Nishanth Menon, linus.walleij
  Cc: Keerthy, Rob Herring, linux-gpio, Device Tree Mailing List,
	Linux ARM Mailing List, Lokesh Vutla
In-Reply-To: <20190809082947.30590-1-lokeshvutla@ti.com>

J721e SoCs have same gpio IP as K2G davinci gpio. Add a new compatible to
handle J721E SoCs.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 Documentation/devicetree/bindings/gpio/gpio-davinci.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
index bc6b4b62df83..cd91d61eac31 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
@@ -6,6 +6,7 @@ Required Properties:
 						66AK2E SoCs
 			"ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G
 			"ti,am654-gpio", "ti,keystone-gpio": for TI K3 AM654
+			"ti,j721e-gpio", "ti,keystone-gpio": for J721E SoCs
 
 - reg: Physical base address of the controller and the size of memory mapped
        registers.
-- 
2.22.0


^ permalink raw reply related

* [PATCH 0/6] arm64: dts: ti: k3-j721e: Add gpio nodes
From: Lokesh Vutla @ 2019-08-09  8:29 UTC (permalink / raw)
  To: Tero Kristo, Nishanth Menon, linus.walleij
  Cc: Keerthy, Rob Herring, linux-gpio, Device Tree Mailing List,
	Linux ARM Mailing List, Lokesh Vutla

This series adds gpio nodes for J721E SoC and enable gpio keys
in J72E common process board.

Tested Boot log: https://pastebin.ubuntu.com/p/P6QqmZYtSC/

This series depends on Power-domain cells update series:
https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=152109


Lokesh Vutla (5):
  dt-bindings: gpio: davinci: Add new compatible for J721E SoCs
  arm64: dts: ti: k3-j721e: Add gpio nodes in main domain
  arm64: dts: ti: k3-j721e: Add gpio nodes in wakeup domain
  arm64: dts: ti: k3-j721e-common-proc-board: Disable unused gpio
    modules
  dt-bindings: pinctrl: k3: Introduce pinmux definitions for J721E

Nikhil Devshatwar (1):
  arm64: dts: k3-j721e: Add gpio-keys on common processor board

 .../devicetree/bindings/gpio/gpio-davinci.txt |   1 +
 .../dts/ti/k3-j721e-common-proc-board.dts     |  65 +++++++++
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi     | 132 ++++++++++++++++++
 .../boot/dts/ti/k3-j721e-mcu-wakeup.dtsi      |  34 +++++
 include/dt-bindings/pinctrl/k3.h              |   3 +
 5 files changed, 235 insertions(+)

-- 
2.22.0


^ permalink raw reply

* [git pull] pinctrl: sh-pfc: Updates for v5.4
From: Geert Uytterhoeven @ 2019-08-09  7:44 UTC (permalink / raw)
  To: Linus Walleij; +Cc: linux-gpio, linux-renesas-soc, Geert Uytterhoeven

	Hi Linus,

The following changes since commit 5f9e832c137075045d15cd6899ab0505cfb2ca4b:

  Linus 5.3-rc1 (2019-07-21 14:05:38 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git tags/sh-pfc-for-v5.4-tag1

for you to fetch changes up to 625efea83a7c37d281c6a90526813a1366929d24:

  pinctrl: rza1: Use devm_platform_ioremap_resource() helper (2019-08-09 09:34:45 +0200)

----------------------------------------------------------------
pinctrl: sh-pfc: Updates for v5.4

  - Add missing of_node_put() calls on RZ/N1,
  - Small cleanups.

Thanks for pulling!

----------------------------------------------------------------
Geert Uytterhoeven (2):
      pinctrl: sh-pfc: Use dev_notice_once() instead of open-coding
      pinctrl: rza1: Use devm_platform_ioremap_resource() helper

Nishka Dasgupta (1):
      pinctrl: rzn1: Add of_node_put() before return

 drivers/pinctrl/pinctrl-rza1.c |  4 +---
 drivers/pinctrl/pinctrl-rzn1.c | 12 +++++++++---
 drivers/pinctrl/sh-pfc/gpio.c  |  9 ++-------
 3 files changed, 12 insertions(+), 13 deletions(-)
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply

* Re: [libgpiod] [PATCH 5/5] bindings: cxx: Workaround --success run
From: Bartosz Golaszewski @ 2019-08-09  6:55 UTC (permalink / raw)
  To: Alexander Stein; +Cc: open list:GPIO SUBSYSTEM
In-Reply-To: <6061947.U0Wa8ctkoo@kongar>

czw., 8 sie 2019 o 20:41 Alexander Stein <alexander.stein@mailbox.org>
napisał(a):
>
>  On Thursday, August 8, 2019, 5:27:14 PM CEST Bartosz Golaszewski wrote:
> > śr., 7 sie 2019 o 21:51 Alexander Stein <alexander.stein@mailbox.org>
> > napisał(a):
> > >
> > > If run with --success, all expressions are evaluated and printed out.
> > > But REQUIRE_FALSE(chip) tries to iterate over the chip resulting in this
> > > backtrace:
> > > #0  gpiod_chip_num_lines (chip=chip@entry=0x0) at ../../lib/core.c:235
> > > #1  gpiod_line_iter_new (chip=0x0) at ../../lib/iter.c:140
> > > #2  gpiod::(anonymous namespace)::make_line_iter (chip=0x0) at ../../../bindings/cxx/iter.cpp:29
> > > #3  gpiod::line_iter::line_iter (this=0x7fffffffd690, owner=...) at ../../../bindings/cxx/iter.cpp:109
> > > #4  Catch::rangeToString<gpiod::chip> (range=...) at /usr/include/catch2/catch.hpp:1959
> > > [...]
> > >
> > > Workaround by forcing catch2 to call gpiod::chip::operator bool().
> > >
> > > Signed-off-by: Alexander Stein <alexander.stein@mailbox.org>
> > > ---
> > > This actually looks like a flaw in the binding itself that the
> > > gpiod::line_iter can't cope with an empty gpiod::chip.
> > >
> >
> > Do you want to submit a patch that fixes that? Otherwise I can fix it.
> > I think that simply throwing an exception on empty chip is enough,
> > right?
>
> Reading that backtrace today, the actual problem is gpiod_chip_num_lines deferencing the nullptr.
> There are 2 possibilities:
> * if gpiod_chip is NULL in gpiod_line_iter_new(), return NULLL iter as well (which will raise an exception on line iter.cpp:31)
> * return an iter with num_lines = 0
>
> Can't rate the 2nd one if this will raise other problems.
>
> Best regards,
> Alexander
>
>
>

Hardening of argument validation in the core library (checking of
NULL-pointers, etc.) has been on my TODO list for some time now. It
seems I'll finally have to do it.

Thanks for the patches, all applied!

Bartosz

^ permalink raw reply

* [PATCH v8 01/21] pinctrl: tegra: Fix write barrier placement in pmx_writel
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-1-git-send-email-skomatineni@nvidia.com>

pmx_writel uses writel which inserts write barrier before the
register write rather.

This patch has fix to replace writel with writel_relaxed followed
by a write barrier to ensure write operation before the barrier
is completed for successful pinctrl change.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/pinctrl/tegra/pinctrl-tegra.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
index e3a237534281..982ee634b3b1 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
@@ -32,7 +32,9 @@ static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)
 
 static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
 {
-	writel(val, pmx->regs[bank] + reg);
+	writel_relaxed(val, pmx->regs[bank] + reg);
+	/* make sure pinmux register write completed */
+	wmb();
 }
 
 static int tegra_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
-- 
2.7.4


^ permalink raw reply related

* [PATCH v8 03/21] clk: tegra: divider: Save and restore divider rate
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-1-git-send-email-skomatineni@nvidia.com>

This patch implements context restore for clock divider.

During system suspend, core power goes off and looses the settings
of the Tegra CAR controller registers.

So on resume, clock dividers are restored back for normal operation.

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/tegra/clk-divider.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index e76731fb7d69..ca0de5f11f84 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -109,10 +109,21 @@ static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
+static void clk_divider_restore_context(struct clk_hw *hw)
+{
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+	unsigned long parent_rate = clk_hw_get_rate(parent);
+	unsigned long rate = clk_hw_get_rate(hw);
+
+	if (clk_frac_div_set_rate(hw, rate, parent_rate) < 0)
+		WARN_ON(1);
+}
+
 const struct clk_ops tegra_clk_frac_div_ops = {
 	.recalc_rate = clk_frac_div_recalc_rate,
 	.set_rate = clk_frac_div_set_rate,
 	.round_rate = clk_frac_div_round_rate,
+	.restore_context = clk_divider_restore_context,
 };
 
 struct clk *tegra_clk_register_divider(const char *name,
-- 
2.7.4


^ permalink raw reply related

* [PATCH v8 12/21] cpufreq: tegra124: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-1-git-send-email-skomatineni@nvidia.com>

This patch adds suspend and resume pm ops for cpufreq driver.

PLLP is the safe clock source for CPU during system suspend and
resume as PLLP rate is below the CPU Fmax at Vmin.

CPUFreq driver suspend switches the CPU clock source to PLLP and
disables the DFLL clock.

During system resume, warmboot code powers up the CPU with PLLP
clock source. So CPUFreq driver resume enabled DFLL clock and
switches CPU back to DFLL clock source.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/cpufreq/tegra124-cpufreq.c | 60 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/drivers/cpufreq/tegra124-cpufreq.c b/drivers/cpufreq/tegra124-cpufreq.c
index 4f0c637b3b49..e979a3370988 100644
--- a/drivers/cpufreq/tegra124-cpufreq.c
+++ b/drivers/cpufreq/tegra124-cpufreq.c
@@ -6,6 +6,7 @@
 #define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
 
 #include <linux/clk.h>
+#include <linux/cpufreq.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -128,8 +129,67 @@ static int tegra124_cpufreq_probe(struct platform_device *pdev)
 	return ret;
 }
 
+static int __maybe_unused tegra124_cpufreq_suspend(struct device *dev)
+{
+	struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+	int err;
+
+	/*
+	 * PLLP rate 408Mhz is below the CPU Fmax at Vmin and is safe to
+	 * use during suspend and resume. So, switch the CPU clock source
+	 * to PLLP and disable DFLL.
+	 */
+	err = clk_set_parent(priv->cpu_clk, priv->pllp_clk);
+	if (err < 0) {
+		dev_err(dev, "failed to reparent to PLLP: %d\n", err);
+		return err;
+	}
+
+	/* disable DFLL clock */
+	clk_disable_unprepare(priv->dfll_clk);
+
+	return 0;
+}
+
+static int __maybe_unused tegra124_cpufreq_resume(struct device *dev)
+{
+	struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+	int err;
+
+	/*
+	 * Warmboot code powers up the CPU with PLLP clock source.
+	 * Enable DFLL clock and switch CPU clock source back to DFLL.
+	 */
+	err = clk_prepare_enable(priv->dfll_clk);
+	if (err < 0) {
+		dev_err(dev, "failed to enable DFLL clock for CPU: %d\n", err);
+		goto disable_cpufreq;
+	}
+
+	err = clk_set_parent(priv->cpu_clk, priv->dfll_clk);
+	if (err < 0) {
+		dev_err(dev, "failed to reparent to DFLL clock: %d\n", err);
+		goto disable_dfll;
+	}
+
+	return 0;
+
+disable_dfll:
+	clk_disable_unprepare(priv->dfll_clk);
+disable_cpufreq:
+	disable_cpufreq();
+
+	return err;
+}
+
+static const struct dev_pm_ops tegra124_cpufreq_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(tegra124_cpufreq_suspend,
+				tegra124_cpufreq_resume)
+};
+
 static struct platform_driver tegra124_cpufreq_platdrv = {
 	.driver.name	= "cpufreq-tegra124",
+	.driver.pm	= &tegra124_cpufreq_pm_ops,
 	.probe		= tegra124_cpufreq_probe,
 };
 
-- 
2.7.4


^ permalink raw reply related

* [PATCH v8 00/21] SC7 entry and exit support for Tegra210
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm

This patch series includes Tegra210 deepsleep (SC7) support with RTC alarm
wake event.

This series also includes save and restore of PLLs, clocks, OSC contexts
for deepsleep exit to normal operation.

This patch series doesn't support 100% suspend/resume to allow fully
functional state upon resume and we are working on some more drivers suspend
and resume implementations.

[v8]: Changes between v7 & v8 are
	- v7 feedback fixes
	- moved clock enable/disable state and reset enable/disable state
	  restore from clk_save/restore_context back to clk-tegra210 driver
	  to do complete register value store/restore.
	- Removed manual store/restore of peripheral parent context and added
	  API in clk core to retrieve clock parent index to use during
	  restoring parent on resume.
	- Implemented Tegra recommended clock source programming sequence
	  during restore (CLK ENB ON followed by divider/source programming
	  followed by restoring CLK ENB ON/OFF state followed by restoring
	  RST state).
	- Removed pinctrl suspend/resume patch from this series as pinctrl
	  suspend/resume patch from v7 got acked and merged.
	- Added pinctrl patch-0001 to update pmx_writel for proper placement
	  of write barrier.
	- Added pinctrl patch-0002 to insert write barrier after all pinctrl
	  register writes during pinctrl resume.

	Note:
	  Below patch is also needed for SC7 support as GPIO restore need
	  to happen prior to pinctrl.
	  https://patchwork.kernel.org/patch/11012077/

[v7]: Changes between V6 & v7 are
	- V6 feedback fixes
	- Removed patch-0001 from V6 which keeps COP IRQ enabled. Looking
	  more into ATF FW, it loads SC7 entry FW into IRAM and sets the
	  COP reset vector to SC7 FW load address and resets COP. So, COP
	  IRQ can be cleared during suspend.

	Note:
	  Below patch is also needed for SC7 support as GPIO restore need
	  to happen prior to pinctrl.
	  https://patchwork.kernel.org/patch/11012077/

[V6]: Changes between V5 & V6 are
	- V5 feedback fixes
	- DFLL suspend and resume moved to DFLL clock driver
	- Add suspend and resume support for CPUFreq driver to explicitly
	  switch source to safe source of PLLP and disable DFLL clock.
	- Fix to super clock driver to enable PLLP branch to CPU before
	  source switch to PLLP.
	- Added save and restore support for super clock driver.

[V5]: Changes between V4 & V5 are
	- V4 feedback fixes

[V4]: Changes between V3 & V4 are
	- V3 feedback fixes
	- Removed park bits clear for EMMC pads in pinctrl-tegra driver
	  function tegra_pinctrl_clear_parked_bits as based on V3 feedback
	  parked_bit is updated to parked_bitmask to use with DRV_PINGROUP
	  as well and thierry posted patch series for this.
	- Implemented all peripheral clocks save and restore through their
	  corresponding clk_ops save_context and restore_context and removed
	  all direct registers store and restore in clk-tegra210 driver.
	- Created separate patch for fence_delay update during PLLU init based
	  on V3 feedback.
	- Added more comments in tegra210_clk_resume regarding dfll restore
	  sequence and its dependency on peripheral clocks restore.

[V3]: Changes between V2 & V3 are
	- V2 feedback fixes
	- GPIO restore should happen prior to Pinctrl restore to prevent
	  glitch on GPIO lines. So using resume_noirq for gpio tegra to allow
	  gpio resume prior to pinctrl resume.
	- Implemented save_context and restore_context callbacks for clock
	  plls, pll outs and dividers in corresponding drivers.
	  Note: Peripheral clocks and clock enable and reset need to be in
	  Tegra210 clock suspend/resume as they need to be in proper sequence
	  w.r.t DFLL resume for restoring CPU clock.
	- Removed gpio-tegra changes for hierarchical support to have PMC as
	  parent to GPIOs for GPIO wake event support. Thierry is working on
	  gpiolib for some cleanup before adding hierarchical support. So
	  holding on to GPIO wake support for now.

[V2] : V1 feedback fixes
	Patch 0002: This version still using syscore. Thierry suggest not to
	use syscore and waiting on suggestion from Linux Walleij for any better
	way of storing current state of pins before suspend entry and restoring
	them on resume at very early stage. So left this the same way as V1 and
	will address once I get more feedback on this.
	Also need to findout and implement proper way of forcing resume order
	between pinctrl and gpio driver.

[V1]:	Tegra210 SC7 entry and exit thru RTC wake and Power button GPIO wake
	using hierarchical IRQ with PMC as parent to GPIO.


Sowjanya Komatineni (21):
  pinctrl: tegra: Fix write barrier placement in pmx_writel
  pinctrl: tegra: Add write barrier after all pinctrl register writes
  clk: tegra: divider: Save and restore divider rate
  clk: tegra: pllout: Save and restore pllout context
  clk: tegra: pll: Save and restore pll context
  clk: tegra: Support for OSC context save and restore
  clk: Add API to get index of the clock parent
  clk: tegra: periph: Add restore_context support
  clk: tegra: clk-super: Fix to enable PLLP branches to CPU
  clk: tegra: clk-super: Add restore-context support
  clk: tegra: clk-dfll: Add suspend and resume support
  cpufreq: tegra124: Add suspend and resume support
  clk: tegra210: Use fence_udelay during PLLU init
  clk: tegra210: Add suspend and resume support
  soc/tegra: pmc: Allow to support more tegras wake
  soc/tegra: pmc: Add pmc wake support for tegra210
  arm64: tegra: Enable wake from deep sleep on RTC alarm
  soc/tegra: pmc: Configure core power request polarity
  soc/tegra: pmc: Configure deep sleep control settings
  arm64: dts: tegra210-p2180: Jetson TX1 SC7 timings
  arm64: dts: tegra210-p3450: Jetson Nano SC7 timings

 arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi     |   7 ++
 arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts |   7 ++
 arch/arm64/boot/dts/nvidia/tegra210.dtsi           |   5 +-
 drivers/clk/clk.c                                  |  17 +++
 drivers/clk/tegra/clk-dfll.c                       |  56 +++++++++
 drivers/clk/tegra/clk-dfll.h                       |   2 +
 drivers/clk/tegra/clk-divider.c                    |  11 ++
 drivers/clk/tegra/clk-periph.c                     |  18 +++
 drivers/clk/tegra/clk-pll-out.c                    |   9 ++
 drivers/clk/tegra/clk-pll.c                        |  88 +++++++++-----
 drivers/clk/tegra/clk-sdmmc-mux.c                  |  12 ++
 drivers/clk/tegra/clk-super.c                      |  35 ++++++
 drivers/clk/tegra/clk-tegra-fixed.c                |  15 +++
 drivers/clk/tegra/clk-tegra-super-gen4.c           |   7 +-
 drivers/clk/tegra/clk-tegra124-dfll-fcpu.c         |   1 +
 drivers/clk/tegra/clk-tegra210.c                   | 114 ++++++++++++++++--
 drivers/clk/tegra/clk.c                            |  78 +++++++++++++
 drivers/clk/tegra/clk.h                            |  17 +++
 drivers/cpufreq/tegra124-cpufreq.c                 |  60 ++++++++++
 drivers/pinctrl/tegra/pinctrl-tegra.c              |   6 +-
 drivers/soc/tegra/pmc.c                            | 129 ++++++++++++++++++++-
 include/linux/clk-provider.h                       |   1 +
 22 files changed, 646 insertions(+), 49 deletions(-)

-- 
2.7.4


^ permalink raw reply

* [PATCH v8 08/21] clk: tegra: periph: Add restore_context support
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-1-git-send-email-skomatineni@nvidia.com>

This patch implements restore_context support for clk-periph and
clk-sdmmc-mux clock operations to restore clock parent and rates
on system resume.

During system suspend, core power goes off and looses the context
of the Tegra clock controller registers.

So on system resume, clocks parent and rate are restored back to
the context before suspend based on cached data.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/tegra/clk-periph.c    | 18 ++++++++++++++++++
 drivers/clk/tegra/clk-sdmmc-mux.c | 12 ++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index 58437da25156..c9d28cbadccc 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/export.h>
 #include <linux/slab.h>
@@ -99,6 +100,20 @@ static void clk_periph_disable(struct clk_hw *hw)
 	gate_ops->disable(gate_hw);
 }
 
+static void clk_periph_restore_context(struct clk_hw *hw)
+{
+	struct tegra_clk_periph *periph = to_clk_periph(hw);
+	const struct clk_ops *div_ops = periph->div_ops;
+	struct clk_hw *div_hw = &periph->divider.hw;
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+	int parent_id = clk_hw_get_parent_index(hw, parent);
+
+	if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV))
+		div_ops->restore_context(div_hw);
+
+	clk_periph_set_parent(hw, parent_id);
+}
+
 const struct clk_ops tegra_clk_periph_ops = {
 	.get_parent = clk_periph_get_parent,
 	.set_parent = clk_periph_set_parent,
@@ -108,6 +123,7 @@ const struct clk_ops tegra_clk_periph_ops = {
 	.is_enabled = clk_periph_is_enabled,
 	.enable = clk_periph_enable,
 	.disable = clk_periph_disable,
+	.restore_context = clk_periph_restore_context,
 };
 
 static const struct clk_ops tegra_clk_periph_nodiv_ops = {
@@ -116,6 +132,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = {
 	.is_enabled = clk_periph_is_enabled,
 	.enable = clk_periph_enable,
 	.disable = clk_periph_disable,
+	.restore_context = clk_periph_restore_context,
 };
 
 static const struct clk_ops tegra_clk_periph_no_gate_ops = {
@@ -124,6 +141,7 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = {
 	.recalc_rate = clk_periph_recalc_rate,
 	.round_rate = clk_periph_round_rate,
 	.set_rate = clk_periph_set_rate,
+	.restore_context = clk_periph_restore_context,
 };
 
 static struct clk *_tegra_clk_register_periph(const char *name,
diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c
index a5cd3e31dbae..8db48966b100 100644
--- a/drivers/clk/tegra/clk-sdmmc-mux.c
+++ b/drivers/clk/tegra/clk-sdmmc-mux.c
@@ -194,6 +194,17 @@ static void clk_sdmmc_mux_disable(struct clk_hw *hw)
 	gate_ops->disable(gate_hw);
 }
 
+static void clk_sdmmc_mux_restore_context(struct clk_hw *hw)
+{
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+	unsigned long parent_rate = clk_hw_get_rate(parent);
+	unsigned long rate = clk_hw_get_rate(hw);
+	int parent_id = clk_hw_get_parent_index(hw, parent);
+
+	clk_sdmmc_mux_set_parent(hw, parent_id);
+	clk_sdmmc_mux_set_rate(hw, rate, parent_rate);
+}
+
 static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
 	.get_parent = clk_sdmmc_mux_get_parent,
 	.set_parent = clk_sdmmc_mux_set_parent,
@@ -203,6 +214,7 @@ static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
 	.is_enabled = clk_sdmmc_mux_is_enabled,
 	.enable = clk_sdmmc_mux_enable,
 	.disable = clk_sdmmc_mux_disable,
+	.restore_context = clk_sdmmc_mux_restore_context,
 };
 
 struct clk *tegra_clk_register_sdmmc_mux_div(const char *name,
-- 
2.7.4


^ permalink raw reply related

* [PATCH v8 07/21] clk: Add API to get index of the clock parent
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-1-git-send-email-skomatineni@nvidia.com>

This patch adds an API clk_hw_get_parent_index to get index of the
clock parent to use during the clock restore operations on system
resume.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/clk.c            | 17 +++++++++++++++++
 include/linux/clk-provider.h |  1 +
 2 files changed, 18 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index c0990703ce54..f26252e48f73 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1643,6 +1643,23 @@ static int clk_fetch_parent_index(struct clk_core *core,
 	return i;
 }
 
+/**
+ * clk_hw_get_parent_index - return the index of parent clock
+ * @hw: clk_hw associated with the clk being consumed
+ * @parent_hw: clk_hw associated with the parent of clk
+ *
+ * Fetches and returns the index of parent clock.
+ * if hw or parent_hw is NULL, returns -EINVAL.
+ */
+int clk_hw_get_parent_index(struct clk_hw *hw, struct clk_hw *parent_hw)
+{
+	if (!hw || !parent_hw)
+		return -EINVAL;
+
+	return clk_fetch_parent_index(hw->core, parent_hw->core);
+}
+EXPORT_SYMBOL_GPL(clk_hw_get_parent_index);
+
 /*
  * Update the orphan status of @core and all its children.
  */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 2ae7604783dd..477112946dd2 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -817,6 +817,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
 					  unsigned int index);
+int clk_hw_get_parent_index(struct clk_hw *hw, struct clk_hw *parent_hw);
 unsigned int __clk_get_enable_count(struct clk *clk);
 unsigned long clk_hw_get_rate(const struct clk_hw *hw);
 unsigned long __clk_get_flags(struct clk *clk);
-- 
2.7.4


^ permalink raw reply related

* [PATCH v8 09/21] clk: tegra: clk-super: Fix to enable PLLP branches to CPU
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-1-git-send-email-skomatineni@nvidia.com>

This patch has a fix to enable PLLP branches to CPU before changing
the CPU cluster clock source to PLLP for Gen5 Super clock and
disables PLLP branches to CPU when not in use.

During system suspend entry and exit, CPU source will be switched
to PLLP and this needs PLLP branches to be enabled to CPU prior to
the switch.

On system resume, warmboot code enables PLLP branches to CPU and
powers up the CPU with PLLP clock source.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/tegra/clk-super.c            | 14 ++++++++++++++
 drivers/clk/tegra/clk-tegra-super-gen4.c |  7 ++++++-
 drivers/clk/tegra/clk.c                  | 14 ++++++++++++++
 drivers/clk/tegra/clk.h                  |  5 +++++
 4 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index 39ef31b46df5..e2a1e95a8db7 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -28,6 +28,9 @@
 #define super_state_to_src_shift(m, s) ((m->width * s))
 #define super_state_to_src_mask(m) (((1 << m->width) - 1))
 
+#define CCLK_SRC_PLLP_OUT0 4
+#define CCLK_SRC_PLLP_OUT4 5
+
 static u8 clk_super_get_parent(struct clk_hw *hw)
 {
 	struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
@@ -97,12 +100,23 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index)
 		if (index == mux->div2_index)
 			index = mux->pllx_index;
 	}
+
+	/* enable PLLP branches to CPU before selecting PLLP source */
+	if ((mux->flags & TEGRA210_CPU_CLK) &&
+	    (index == CCLK_SRC_PLLP_OUT0 || index == CCLK_SRC_PLLP_OUT4))
+		tegra_clk_set_pllp_out_cpu(true);
+
 	val &= ~((super_state_to_src_mask(mux)) << shift);
 	val |= (index & (super_state_to_src_mask(mux))) << shift;
 
 	writel_relaxed(val, mux->reg);
 	udelay(2);
 
+	/* disable PLLP branches to CPU if not used */
+	if ((mux->flags & TEGRA210_CPU_CLK) &&
+	    index != CCLK_SRC_PLLP_OUT0 && index != CCLK_SRC_PLLP_OUT4)
+		tegra_clk_set_pllp_out_cpu(false);
+
 out:
 	if (mux->lock)
 		spin_unlock_irqrestore(mux->lock, flags);
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
index cdfe7c9697e1..98538f79b0c4 100644
--- a/drivers/clk/tegra/clk-tegra-super-gen4.c
+++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
@@ -180,7 +180,7 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
 					gen_info->num_cclk_g_parents,
 					CLK_SET_RATE_PARENT,
 					clk_base + CCLKG_BURST_POLICY,
-					0, 4, 8, 0, NULL);
+					TEGRA210_CPU_CLK, 4, 8, 0, NULL);
 		} else {
 			clk = tegra_clk_register_super_mux("cclk_g",
 					gen_info->cclk_g_parents,
@@ -196,6 +196,11 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
 	dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks);
 	if (dt_clk) {
 		if (gen_info->gen == gen5) {
+		/*
+		 * TEGRA210_CPU_CLK flag is not needed for cclk_lp as cluster
+		 * switching is not currently supported on Tegra210 and also
+		 * cpu_lp is not used.
+		 */
 			clk = tegra_clk_register_super_mux("cclk_lp",
 					gen_info->cclk_lp_parents,
 					gen_info->num_cclk_lp_parents,
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index 573e3c967ae1..eb08047fd02f 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -23,6 +23,7 @@
 #define CLK_OUT_ENB_W			0x364
 #define CLK_OUT_ENB_X			0x280
 #define CLK_OUT_ENB_Y			0x298
+#define CLK_ENB_PLLP_OUT_CPU		BIT(31)
 #define CLK_OUT_ENB_SET_L		0x320
 #define CLK_OUT_ENB_CLR_L		0x324
 #define CLK_OUT_ENB_SET_H		0x328
@@ -199,6 +200,19 @@ const struct tegra_clk_periph_regs *get_reg_bank(int clkid)
 	}
 }
 
+void tegra_clk_set_pllp_out_cpu(bool enable)
+{
+	u32 val;
+
+	val = readl_relaxed(clk_base + CLK_OUT_ENB_Y);
+	if (enable)
+		val |= CLK_ENB_PLLP_OUT_CPU;
+	else
+		val &= ~CLK_ENB_PLLP_OUT_CPU;
+
+	writel_relaxed(val, clk_base + CLK_OUT_ENB_Y);
+}
+
 struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
 {
 	clk_base = regs;
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 8a9af45b6084..560e2bcb3d7d 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -677,6 +677,9 @@ struct clk *tegra_clk_register_periph_data(void __iomem *clk_base,
  * Flags:
  * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
  *     that this is LP cluster clock.
+ * TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5
+ * super mux parent using PLLP branches. To use PLLP branches to CPU, need
+ * to configure additional bit PLLP_OUT_CPU in the clock registers.
  */
 struct tegra_clk_super_mux {
 	struct clk_hw	hw;
@@ -693,6 +696,7 @@ struct tegra_clk_super_mux {
 #define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw)
 
 #define TEGRA_DIVIDER_2 BIT(0)
+#define TEGRA210_CPU_CLK BIT(1)
 
 extern const struct clk_ops tegra_clk_super_ops;
 struct clk *tegra_clk_register_super_mux(const char *name,
@@ -838,6 +842,7 @@ int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
 int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
 		 u8 frac_width, u8 flags);
 void tegra_clk_osc_resume(void __iomem *clk_base);
+void tegra_clk_set_pllp_out_cpu(bool enable);
 
 
 /* Combined read fence with delay */
-- 
2.7.4


^ permalink raw reply related

* [PATCH v8 10/21] clk: tegra: clk-super: Add restore-context support
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-1-git-send-email-skomatineni@nvidia.com>

This patch implements restore_context for clk_super_mux and clk_super.

During system supend, core power goes off the and context of Tegra
CAR registers is lost.

So on system resume, context of super clock registers are restored
to have them in same state as before suspend.

Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/tegra/clk-super.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index e2a1e95a8db7..74c9e913e41c 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -124,9 +124,18 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index)
 	return err;
 }
 
+static void clk_super_mux_restore_context(struct clk_hw *hw)
+{
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+	int parent_id = clk_hw_get_parent_index(hw, parent);
+
+	clk_super_set_parent(hw, parent_id);
+}
+
 static const struct clk_ops tegra_clk_super_mux_ops = {
 	.get_parent = clk_super_get_parent,
 	.set_parent = clk_super_set_parent,
+	.restore_context = clk_super_mux_restore_context,
 };
 
 static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -162,12 +171,24 @@ static int clk_super_set_rate(struct clk_hw *hw, unsigned long rate,
 	return super->div_ops->set_rate(div_hw, rate, parent_rate);
 }
 
+static void clk_super_restore_context(struct clk_hw *hw)
+{
+	struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
+	struct clk_hw *div_hw = &super->frac_div.hw;
+	struct clk_hw *parent = clk_hw_get_parent(hw);
+	int parent_id = clk_hw_get_parent_index(hw, parent);
+
+	super->div_ops->restore_context(div_hw);
+	clk_super_set_parent(hw, parent_id);
+}
+
 const struct clk_ops tegra_clk_super_ops = {
 	.get_parent = clk_super_get_parent,
 	.set_parent = clk_super_set_parent,
 	.set_rate = clk_super_set_rate,
 	.round_rate = clk_super_round_rate,
 	.recalc_rate = clk_super_recalc_rate,
+	.restore_context = clk_super_restore_context,
 };
 
 struct clk *tegra_clk_register_super_mux(const char *name,
-- 
2.7.4


^ permalink raw reply related

* [PATCH v8 06/21] clk: tegra: Support for OSC context save and restore
From: Sowjanya Komatineni @ 2019-08-08 23:46 UTC (permalink / raw)
  To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
	linus.walleij, stefan, mark.rutland
  Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
	josephl, talho, skomatineni, linux-tegra, linux-kernel,
	mperttunen, spatra, robh+dt, digetx, devicetree, rjw,
	viresh.kumar, linux-pm
In-Reply-To: <1565308020-31952-1-git-send-email-skomatineni@nvidia.com>

This patch adds support for saving OSC clock frequency and the
drive-strength during OSC clock init and creates an API to restore
OSC control register value from the saved context.

This API is invoked by Tegra210 clock driver during system resume
to restore the  OSC clock settings.

Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
 drivers/clk/tegra/clk-tegra-fixed.c | 15 +++++++++++++++
 drivers/clk/tegra/clk.h             |  1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c
index 8d91b2b191cf..7c6c8abfcde6 100644
--- a/drivers/clk/tegra/clk-tegra-fixed.c
+++ b/drivers/clk/tegra/clk-tegra-fixed.c
@@ -17,6 +17,10 @@
 #define OSC_CTRL			0x50
 #define OSC_CTRL_OSC_FREQ_SHIFT		28
 #define OSC_CTRL_PLL_REF_DIV_SHIFT	26
+#define OSC_CTRL_MASK			(0x3f2 |	\
+					(0xf << OSC_CTRL_OSC_FREQ_SHIFT))
+
+static u32 osc_ctrl_ctx;
 
 int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
 			      unsigned long *input_freqs, unsigned int num,
@@ -29,6 +33,7 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
 	unsigned osc_idx;
 
 	val = readl_relaxed(clk_base + OSC_CTRL);
+	osc_ctrl_ctx = val & OSC_CTRL_MASK;
 	osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT;
 
 	if (osc_idx < num)
@@ -96,3 +101,13 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks)
 		*dt_clk = clk;
 	}
 }
+
+void tegra_clk_osc_resume(void __iomem *clk_base)
+{
+	u32 val;
+
+	val = readl_relaxed(clk_base + OSC_CTRL) & ~OSC_CTRL_MASK;
+	val |= osc_ctrl_ctx;
+	writel_relaxed(val, clk_base + OSC_CTRL);
+	fence_udelay(2, clk_base);
+}
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index dc546292e030..8a9af45b6084 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -837,6 +837,7 @@ u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
 int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
 int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
 		 u8 frac_width, u8 flags);
+void tegra_clk_osc_resume(void __iomem *clk_base);
 
 
 /* Combined read fence with delay */
-- 
2.7.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox