Re: [PATCH v1 06/17] soc: pmc: Add blink output clock registration to Tegra PMC

From: Sowjanya Komatineni
Date: Tue Nov 19 2019 - 21:10:28 EST



On 11/19/19 2:13 PM, Sowjanya Komatineni wrote:

On 11/19/19 11:34 AM, Dmitry Osipenko wrote:
19.11.2019 09:50, Sowjanya Komatineni ÐÐÑÐÑ:
Tegra PMC has blink control to output 32 Khz clock out to Tegra
blink pin. Blink pad DPD state and enable controls are part of
Tegra PMC register space.

Currently Tegra clock driver registers blink control by passing
PMC address and register offset to clk_register_gate which performs
direct PMC access during clk_ops and with this when PMC is in secure
mode, any access from non-secure world does not go through.

This patch adds blink control registration to the Tegra PMC driver
using PMC specific clock gate operations that use tegra_pmc_readl
and tegra_pmc_writel to support both secure mode and non-secure
mode PMC register access.

Signed-off-by: Sowjanya Komatineni <skomatineni@xxxxxxxxxx>
---
 drivers/soc/tegra/pmc.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 790a6619ba32..095e89c7fa3f 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -61,12 +61,15 @@
 #define PMC_CNTRL_SYSCLK_OE BIT(11) /* system clock enable */
 #define PMC_CNTRL_SYSCLK_POLARITY BIT(10) /* sys clk polarity */
 #define PMC_CNTRL_PWRREQ_POLARITY BIT(8)
+#define PMC_CNTRL_BLINK_EN BIT(7)
 #define PMC_CNTRL_MAIN_RST BIT(4)
  #define PMC_WAKE_MASK 0x0c
 #define PMC_WAKE_LEVEL 0x10
 #define PMC_WAKE_STATUS 0x14
 #define PMC_SW_WAKE_STATUS 0x18
+#define PMC_DPD_PADS_ORIDEÂÂÂÂÂÂÂ 0x1c
+#define PMC_DPD_PADS_ORIDE_BLINK BIT(20)
  #define DPD_SAMPLE 0x020
 #define DPD_SAMPLE_ENABLE BIT(0)
@@ -79,6 +82,7 @@
  #define PWRGATE_STATUS 0x38
 +#define TEGRA210_PMC_BLINK_TIMER 0x40
 #define PMC_IMPL_E_33V_PWR 0x40
  #define PMC_PWR_DET 0x48
@@ -247,6 +251,9 @@ static struct pmc_clk_init_data tegra_pmc_clks_data[] = {
ÂÂÂÂÂ PMC_CLK(3, 22, 18, 0, 0),
 };
 +static struct pmc_clk_gate blink_override;
+static struct pmc_clk_gate blink;
+
 struct tegra_powergate {
ÂÂÂÂÂ struct generic_pm_domain genpd;
ÂÂÂÂÂ struct tegra_pmc *pmc;
@@ -359,6 +366,7 @@ struct tegra_pmc_soc {
 Â struct pmc_clk_init_data *pmc_clks_data;
ÂÂÂÂÂ unsigned int num_pmc_clks;
+ÂÂÂ bool has_blink_output;
 };
  static const char * const tegra186_reset_sources[] = {
@@ -2530,6 +2538,9 @@ static void tegra_pmc_clock_register(struct tegra_pmc *pmc,
ÂÂÂÂÂ /* each pmc clock output has a mux and a gate */
ÂÂÂÂÂ num_clks = pmc->soc->num_pmc_clks * 2;
 + if (pmc->soc->has_blink_output)
+ÂÂÂÂÂÂÂ num_clks += 1;
+
ÂÂÂÂÂ if (!num_clks)
ÂÂÂÂÂÂÂÂÂ return;
 @@ -2604,6 +2615,30 @@ static void tegra_pmc_clock_register(struct tegra_pmc *pmc,
ÂÂÂÂÂÂÂÂÂ }
ÂÂÂÂÂ }
 + if (pmc->soc->has_blink_output) {
+ÂÂÂÂÂÂÂ tegra_pmc_writel(pmc, 0x0, TEGRA210_PMC_BLINK_TIMER);
+ÂÂÂÂÂÂÂ clkgate = tegra_pmc_clk_gate_register("blink_override",
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "clk_32k",
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ 0, &blink_override,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ PMC_DPD_PADS_ORIDE,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ PMC_DPD_PADS_ORIDE_BLINK,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ NULL);
+ÂÂÂÂÂÂÂ if (IS_ERR(clkgate))
+ÂÂÂÂÂÂÂÂÂÂÂ goto free_clks;
+
+ÂÂÂÂÂÂÂ clkgate = tegra_pmc_clk_gate_register("blink",
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ "blink_override",
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ 0, &blink,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ PMC_CNTRL,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ PMC_CNTRL_BLINK_EN,
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ NULL);
+ÂÂÂÂÂÂÂ if (IS_ERR(clkgate))
+ÂÂÂÂÂÂÂÂÂÂÂ goto free_clks;
+
+ÂÂÂÂÂÂÂ clk_data->clks[TEGRA_PMC_CLK_BLINK] = clkgate;
+ÂÂÂÂÂÂÂ clk_register_clkdev(clkgate, "blink", NULL);
Tegra20 has pmc->soc->num_pmc_clks = 0 and thus num_clks = 1, while
TEGRA_PMC_CLK_BLINK = 6.

BTW, Tegra30 doesn't boot. I'll try again v2.

Please fix it all in v2. Compile-test all patches and make at least a
boot-test where possible.

[snip]

looks like blink output should be enabled during boot for Tegra20 and Tegra30 platforms.

Will add init state for blink output in V2. Will compile for old Tegra's as well and will try boot-test.

Hi Thierry,

With implementation of PMC helper functions for PLLM overrides and PLLE IDDQ PMC programming to use in clock driver during registering PLLM, need tegra_pmc_early_init to happen prior to tegra_clk_init as all helper functions have to use tegra_pmc_soc for flags and pmc register offset.

Any suggestion?