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]