Tegra PMC has clk_out_1, clk_out_2, clk_out_3 and blink controls which
are currently registered by Tegra clock driver using clk_regiser_mux and
clk_register_gate which performs direct Tegra PMC register access.
When Tegra PMC is in secure mode, any access from non-secure world will
not go through.
This patch series adds these Tegra PMC clocks and blink controls to Tegra
PMC driver with PMC as clock provider and removed them from Tegra clock
driver. This also adds PMC specific clock id's to use in device tree and
removed clock ids of PMC clock from Tegra clock driver.
This series also includes patch to update clock provider from tegra_car
to pmc in the device tree tegra210-smaug.dts that uses clk_out_2 from PMC.
Tegra PMC also has WB0 PLLM overrides and PLLE pads IDDQ controls which
are currently configured by Tegra clock driver using direct PMC access.
This series also includes patches that adds helper functions in Tegra PMC
driver to allow programming these from Tegra clock driver and removes
direct PMC access from the clock driver.
Sowjanya Komatineni (17):
soc: tegra: pmc: Add helper functions for PLLM overrides
soc: tegra: pmc: Add helper function for PLLE IDDQ override
dt-bindings: soc: tegra-pmc: Add Tegra PMC clock ids
soc: tegra: Add Tegra PMC clock registrations into PMC driver
dt-bindings: soc: tegra-pmc: Add id for Tegra PMC blink control
soc: pmc: Add blink output clock registration to Tegra PMC
clk: tegra: Use Tegra PMC helper functions for PLLM overrides
clk: tegra: Use Tegra PMC helper function for PLLE IDDQ
clk: tegra: Remove PMC base references from clock registration
clk: tegra: Remove tegra_pmc_clk_init along with clk ids
dt-bindings: clock: tegra: Remove pmc clock ids from clock dt-bindings
arm: tegra: Add clock-cells property to Tegra pmc
arm64: tegra: Add clock-cells property to Tegra pmc
dt-bindings: Add Tegra PMC clock configuration bindings
dt-bindings: tegra186-pmc: Add Tegra PMC clock bindings
arm64: tegra: smaug: Change clk_out_2 provider from tegra_car to pmc
ASoC: nau8825: change Tegra clk_out_2 provider from tegra_car to pmc
.../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 44 ++
.../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 42 ++
.../devicetree/bindings/sound/nau8825.txt | 2 +-
arch/arm/boot/dts/tegra114.dtsi | 4 +-
arch/arm/boot/dts/tegra124.dtsi | 4 +-
arch/arm/boot/dts/tegra30.dtsi | 4 +-
arch/arm64/boot/dts/nvidia/tegra132.dtsi | 4 +-
arch/arm64/boot/dts/nvidia/tegra186.dtsi | 2 +
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 2 +
arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 2 +-
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 2 +
drivers/clk/tegra/Makefile | 1 -
drivers/clk/tegra/clk-id.h | 7 -
drivers/clk/tegra/clk-pll.c | 135 ++---
drivers/clk/tegra/clk-tegra-audio.c | 4 +-
drivers/clk/tegra/clk-tegra-periph.c | 8 +-
drivers/clk/tegra/clk-tegra-super-gen4.c | 11 +-
drivers/clk/tegra/clk-tegra114.c | 75 +--
drivers/clk/tegra/clk-tegra124.c | 86 +--
drivers/clk/tegra/clk-tegra20.c | 30 +-
drivers/clk/tegra/clk-tegra210.c | 74 +--
drivers/clk/tegra/clk-tegra30.c | 59 +-
drivers/clk/tegra/clk.h | 48 +-
drivers/soc/tegra/pmc.c | 598 ++++++++++++++++++++-
include/dt-bindings/clock/tegra114-car.h | 14 +-
include/dt-bindings/clock/tegra124-car-common.h | 14 +-
include/dt-bindings/clock/tegra20-car.h | 2 +-
include/dt-bindings/clock/tegra210-car.h | 14 +-
include/dt-bindings/clock/tegra30-car.h | 14 +-
include/dt-bindings/soc/tegra-pmc.h | 17 +
include/soc/tegra/pmc.h | 6 +
31 files changed, 879 insertions(+), 450 deletions(-)
create mode 100644 include/dt-bindings/soc/tegra-pmc.h
--
2.7.4
Tegra PMC has clk_out_1, clk_out_2, clk_out_3 clocks and each of
these clocks has mux and a gate as a part of PMC controller.
This patch adds ids for each of these PMC clock mux and gates to
use with the devicetree.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
include/dt-bindings/soc/tegra-pmc.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 include/dt-bindings/soc/tegra-pmc.h
diff --git a/include/dt-bindings/soc/tegra-pmc.h b/include/dt-bindings/soc/tegra-pmc.h
new file mode 100644
index 000000000000..fa1ccfc2514b
--- /dev/null
+++ b/include/dt-bindings/soc/tegra-pmc.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_SOC_TEGRA_PMC_H
+#define _DT_BINDINGS_SOC_TEGRA_PMC_H
+
+#define TEGRA_PMC_CLK_OUT_1_MUX 0
+#define TEGRA_PMC_CLK_OUT_1 1
+#define TEGRA_PMC_CLK_OUT_2_MUX 2
+#define TEGRA_PMC_CLK_OUT_2 3
+#define TEGRA_PMC_CLK_OUT_3_MUX 4
+#define TEGRA_PMC_CLK_OUT_3 5
+
+#endif /* _DT_BINDINGS_SOC_TEGRA_PMC_H */
--
2.7.4
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 <[email protected]>
---
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);
+ }
+
of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
return;
@@ -2943,6 +2978,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.num_reset_levels = 0,
.pmc_clks_data = NULL,
.num_pmc_clks = 0,
+ .has_blink_output = true,
};
static const char * const tegra30_powergates[] = {
@@ -2993,6 +3029,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.num_reset_levels = 0,
.pmc_clks_data = tegra_pmc_clks_data,
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+ .has_blink_output = true,
};
static const char * const tegra114_powergates[] = {
@@ -3047,6 +3084,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.num_reset_levels = 0,
.pmc_clks_data = tegra_pmc_clks_data,
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+ .has_blink_output = true,
};
static const char * const tegra124_powergates[] = {
@@ -3161,6 +3199,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.num_reset_levels = 0,
.pmc_clks_data = tegra_pmc_clks_data,
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+ .has_blink_output = true,
};
static const char * const tegra210_powergates[] = {
@@ -3278,6 +3317,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
.wake_events = tegra210_wake_events,
.pmc_clks_data = tegra_pmc_clks_data,
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+ .has_blink_output = true,
};
#define TEGRA186_IO_PAD_TABLE(_pad) \
@@ -3419,6 +3459,7 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
.wake_events = tegra186_wake_events,
.pmc_clks_data = tegra_pmc_clks_data,
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+ .has_blink_output = false,
};
static const struct tegra_io_pad_soc tegra194_io_pads[] = {
@@ -3496,6 +3537,7 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
.wake_events = tegra194_wake_events,
.pmc_clks_data = tegra_pmc_clks_data,
.num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+ .has_blink_output = false,
};
static const struct of_device_id tegra_pmc_match[] = {
--
2.7.4
Tegra PMC has a blinking control to output 32 KHz clock to blink
pin.
This patch adds id for this blink control to use for enabling or
disabling the blink output through devicetree.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
include/dt-bindings/soc/tegra-pmc.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/dt-bindings/soc/tegra-pmc.h b/include/dt-bindings/soc/tegra-pmc.h
index fa1ccfc2514b..bcb24e17981f 100644
--- a/include/dt-bindings/soc/tegra-pmc.h
+++ b/include/dt-bindings/soc/tegra-pmc.h
@@ -12,5 +12,6 @@
#define TEGRA_PMC_CLK_OUT_2 3
#define TEGRA_PMC_CLK_OUT_3_MUX 4
#define TEGRA_PMC_CLK_OUT_3 5
+#define TEGRA_PMC_CLK_BLINK 6
#endif /* _DT_BINDINGS_SOC_TEGRA_PMC_H */
--
2.7.4
Tegra PMC has PLLE IDDQ programming to bring the PLLE pads out of
DPD idle state through software by overriding the hardware control.
Currently Tegra clock driver programs Tegra PMC registers directly
for enabling software override and to bring PLLE pads out of DPD
idle state. With this, when Tegra PMC is in secure mode, any direct
PMC register access from non-secure world will not go through.
This patch updates Tegra clock driver to use Tegra PMC helper function
to clear PLLE IDDQ through software control that does PMC programming
using tegra_pmc_writel and tegra_pmc_readl which supports both secure
mode and non-secure mode PMC access.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/clk/tegra/clk-pll.c | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index f3c0a637174f..4ae9e282e7be 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -143,10 +143,6 @@
#define PLLCX_MISC2_DEFAULT 0x30211200
#define PLLCX_MISC3_DEFAULT 0x200
-#define PMC_SATA_PWRGT 0x1ac
-#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
-#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
-
#define PLLSS_MISC_KCP 0
#define PLLSS_MISC_KVCO 0
#define PLLSS_MISC_SETUP 0
@@ -863,24 +859,11 @@ static int clk_plle_training(struct tegra_clk_pll *pll)
u32 val;
unsigned long timeout;
- if (!pll->pmc)
- return -ENOSYS;
-
/*
* PLLE is already disabled, and setup cleared;
* create falling edge on PLLE IDDQ input.
*/
- val = readl(pll->pmc + PMC_SATA_PWRGT);
- val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
- writel(val, pll->pmc + PMC_SATA_PWRGT);
-
- val = readl(pll->pmc + PMC_SATA_PWRGT);
- val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
- writel(val, pll->pmc + PMC_SATA_PWRGT);
-
- val = readl(pll->pmc + PMC_SATA_PWRGT);
- val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
- writel(val, pll->pmc + PMC_SATA_PWRGT);
+ tegra_pmc_clear_plle_iddq();
val = pll_readl_misc(pll);
--
2.7.4
Tegra PMC has PLLM override registers to override PLLM clock
dividers and enable state programmed by Tegra CAR PLLM registers
to have PLLM enabled during warmboot.
Currently Tegra clock driver programs these overrides by direct
PMC access. With this, when PMC is in secure mode any direct access
from non-secure world does not go through and these overrides from
clock driver will not be set.
Tegra PMC helper functions for PLLM overrides happen thru
tegra_pmc_writel and tegra_pmc_readl which supports both secure mode
and non-secure mode access.
This patch updates Tegra clock driver to use Tegra PMC helper
functions for programming these overrides.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/clk/tegra/clk-pll.c | 56 ++++++++++------------------------------
drivers/clk/tegra/clk-tegra114.c | 9 -------
drivers/clk/tegra/clk-tegra124.c | 8 ------
drivers/clk/tegra/clk-tegra210.c | 8 ------
drivers/clk/tegra/clk-tegra30.c | 8 ------
drivers/clk/tegra/clk.h | 10 -------
6 files changed, 13 insertions(+), 86 deletions(-)
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 531c2b3d814e..f3c0a637174f 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -9,6 +9,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
+#include <soc/tegra/pmc.h>
#include "clk.h"
@@ -38,10 +39,6 @@
#define OUT_OF_TABLE_CPCON 8
-#define PMC_PLLP_WB0_OVERRIDE 0xf8
-#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
-#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE BIT(11)
-
#define PLL_POST_LOCK_DELAY 50
#define PLLDU_LFCON_SET_DIVN 600
@@ -230,14 +227,12 @@
#define pll_readl(offset, p) readl_relaxed(p->clk_base + offset)
#define pll_readl_base(p) pll_readl(p->params->base_reg, p)
#define pll_readl_misc(p) pll_readl(p->params->misc_reg, p)
-#define pll_override_readl(offset, p) readl_relaxed(p->pmc + offset)
#define pll_readl_sdm_din(p) pll_readl(p->params->sdm_din_reg, p)
#define pll_readl_sdm_ctrl(p) pll_readl(p->params->sdm_ctrl_reg, p)
#define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset)
#define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p)
#define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p)
-#define pll_override_writel(val, offset, p) writel(val, p->pmc + offset)
#define pll_writel_sdm_din(val, p) pll_writel(val, p->params->sdm_din_reg, p)
#define pll_writel_sdm_ctrl(val, p) pll_writel(val, p->params->sdm_ctrl_reg, p)
@@ -332,11 +327,9 @@ static int clk_pll_is_enabled(struct clk_hw *hw)
struct tegra_clk_pll *pll = to_clk_pll(hw);
u32 val;
- if (pll->params->flags & TEGRA_PLLM) {
- val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
- if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)
- return val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE ? 1 : 0;
- }
+ if ((pll->params->flags & TEGRA_PLLM) &&
+ tegra_pmc_is_pllm_wb0_override_enabled())
+ return tegra_pmc_is_pllm_wb0_enabled();
val = pll_readl_base(pll);
@@ -369,11 +362,8 @@ static void _clk_pll_enable(struct clk_hw *hw)
val |= PLL_BASE_ENABLE;
pll_writel_base(val, pll);
- if (pll->params->flags & TEGRA_PLLM) {
- val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
- val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
- writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
- }
+ if (pll->params->flags & TEGRA_PLLM)
+ tegra_pmc_set_pllm_wb0_enable(true);
}
static void _clk_pll_disable(struct clk_hw *hw)
@@ -387,11 +377,8 @@ static void _clk_pll_disable(struct clk_hw *hw)
val &= ~PLL_BASE_ENABLE;
pll_writel_base(val, pll);
- if (pll->params->flags & TEGRA_PLLM) {
- val = readl_relaxed(pll->pmc + PMC_PLLP_WB0_OVERRIDE);
- val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
- writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
- }
+ if (pll->params->flags & TEGRA_PLLM)
+ tegra_pmc_set_pllm_wb0_enable(false);
if (pll->params->reset_reg) {
val = pll_readl(pll->params->reset_reg, pll);
@@ -644,22 +631,10 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll,
{
u32 val;
struct tegra_clk_pll_params *params = pll->params;
- struct div_nmp *div_nmp = params->div_nmp;
if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) &&
- (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) &
- PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) {
- val = pll_override_readl(params->pmc_divp_reg, pll);
- val &= ~(divp_mask(pll) << div_nmp->override_divp_shift);
- val |= cfg->p << div_nmp->override_divp_shift;
- pll_override_writel(val, params->pmc_divp_reg, pll);
-
- val = pll_override_readl(params->pmc_divnm_reg, pll);
- val &= ~((divm_mask(pll) << div_nmp->override_divm_shift) |
- (divn_mask(pll) << div_nmp->override_divn_shift));
- val |= (cfg->m << div_nmp->override_divm_shift) |
- (cfg->n << div_nmp->override_divn_shift);
- pll_override_writel(val, params->pmc_divnm_reg, pll);
+ tegra_pmc_is_pllm_wb0_override_enabled()) {
+ tegra_pmc_set_pllm_wb0_mnp_overrides(cfg->m, cfg->n, cfg->p);
} else {
val = pll_readl_base(pll);
@@ -686,14 +661,9 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll,
*cfg = (struct tegra_clk_pll_freq_table) { };
if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) &&
- (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) &
- PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) {
- val = pll_override_readl(params->pmc_divp_reg, pll);
- cfg->p = (val >> div_nmp->override_divp_shift) & divp_mask(pll);
-
- val = pll_override_readl(params->pmc_divnm_reg, pll);
- cfg->m = (val >> div_nmp->override_divm_shift) & divm_mask(pll);
- cfg->n = (val >> div_nmp->override_divn_shift) & divn_mask(pll);
+ tegra_pmc_is_pllm_wb0_override_enabled()) {
+ tegra_pmc_get_pllm_wb0_mnp_overrides(&cfg->m, &cfg->n,
+ &cfg->p);
} else {
val = pll_readl_base(pll);
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 4efcaaf51b3a..77904334b6f0 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -105,10 +105,6 @@
#define CLK_SOURCE_CSITE 0x1d4
#define CLK_SOURCE_EMC 0x19c
-/* PLLM override registers */
-#define PMC_PLLM_WB0_OVERRIDE 0x1dc
-#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
-
/* Tegra CPU clock and reset control regs */
#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
@@ -272,13 +268,10 @@ static struct tegra_clk_pll_params pll_c3_params = {
static struct div_nmp pllm_nmp = {
.divm_shift = 0,
.divm_width = 8,
- .override_divm_shift = 0,
.divn_shift = 8,
.divn_width = 8,
- .override_divn_shift = 8,
.divp_shift = 20,
.divp_width = 1,
- .override_divp_shift = 27,
};
static const struct pdiv_map pllm_p[] = {
@@ -311,8 +304,6 @@ static struct tegra_clk_pll_params pll_m_params = {
.max_p = 2,
.pdiv_tohw = pllm_p,
.div_nmp = &pllm_nmp,
- .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
- .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2,
.freq_table = pll_m_freq_table,
.flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE |
TEGRA_PLL_FIXED,
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index b3110d5b5a6c..010daac53ea7 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -84,9 +84,6 @@
#define PLLXC_SW_MAX_P 6
-#define PMC_PLLM_WB0_OVERRIDE 0x1dc
-#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
-
#define CCLKG_BURST_POLICY 0x368
/* Tegra CPU clock and reset control regs */
@@ -401,13 +398,10 @@ static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
static struct div_nmp pllm_nmp = {
.divm_shift = 0,
.divm_width = 8,
- .override_divm_shift = 0,
.divn_shift = 8,
.divn_width = 8,
- .override_divn_shift = 8,
.divp_shift = 20,
.divp_width = 1,
- .override_divp_shift = 27,
};
static struct tegra_clk_pll_params pll_m_params = {
@@ -424,8 +418,6 @@ static struct tegra_clk_pll_params pll_m_params = {
.max_p = 5,
.pdiv_tohw = pllm_p,
.div_nmp = &pllm_nmp,
- .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
- .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2,
.freq_table = pll_m_freq_table,
.flags = TEGRA_PLL_USE_LOCK,
};
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 762cd186f714..63f8a778821f 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -151,9 +151,6 @@
#define PLLDP_SS_CTRL1 0x59c
#define PLLDP_SS_CTRL2 0x5a0
-#define PMC_PLLM_WB0_OVERRIDE 0x1dc
-#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
-
#define UTMIP_PLL_CFG2 0x488
#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xfff) << 6)
#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
@@ -1809,13 +1806,10 @@ static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
static struct div_nmp pllm_nmp = {
.divm_shift = 0,
.divm_width = 8,
- .override_divm_shift = 0,
.divn_shift = 8,
.divn_width = 8,
- .override_divn_shift = 8,
.divp_shift = 20,
.divp_width = 5,
- .override_divp_shift = 27,
};
static struct tegra_clk_pll_params pll_m_params = {
@@ -1838,8 +1832,6 @@ static struct tegra_clk_pll_params pll_m_params = {
.round_p_to_pdiv = pll_qlin_p_to_pdiv,
.pdiv_tohw = pll_qlin_pdiv_to_hw,
.div_nmp = &pllm_nmp,
- .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
- .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2,
.freq_table = pll_m_freq_table,
.flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
.calc_rate = tegra210_pll_fixed_mdiv_cfg,
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index c8bc18e4d7e5..e3b64c66acdc 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -131,9 +131,6 @@
#define CLK_RESET_CCLK_RUN_POLICY 2
#define CLK_RESET_CCLK_BURST_POLICY_PLLX 8
-/* PLLM override registers */
-#define PMC_PLLM_WB0_OVERRIDE 0x1dc
-
#ifdef CONFIG_PM_SLEEP
static struct cpu_clk_suspend_context {
u32 pllx_misc;
@@ -367,13 +364,10 @@ static struct tegra_clk_pll_params pll_c_params __ro_after_init = {
static struct div_nmp pllm_nmp = {
.divn_shift = 8,
.divn_width = 10,
- .override_divn_shift = 5,
.divm_shift = 0,
.divm_width = 5,
- .override_divm_shift = 0,
.divp_shift = 20,
.divp_width = 3,
- .override_divp_shift = 15,
};
static struct tegra_clk_pll_params pll_m_params __ro_after_init = {
@@ -389,8 +383,6 @@ static struct tegra_clk_pll_params pll_m_params __ro_after_init = {
.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
.lock_delay = 300,
.div_nmp = &pllm_nmp,
- .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
- .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE,
.freq_table = pll_m_freq_table,
.flags = TEGRA_PLLM | TEGRA_PLL_HAS_CPCON |
TEGRA_PLL_SET_DCCON | TEGRA_PLL_USE_LOCK |
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 416a6b09f6a3..9a4473f94fe0 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -191,9 +191,6 @@ struct pdiv_map {
* @divm_width: width of the input divider bit field
* @divp_shift: shift to the post divider bit field
* @divp_width: width of the post divider bit field
- * @override_divn_shift: shift to the feedback divider bitfield in override reg
- * @override_divm_shift: shift to the input divider bitfield in override reg
- * @override_divp_shift: shift to the post divider bitfield in override reg
*/
struct div_nmp {
u8 divn_shift;
@@ -202,9 +199,6 @@ struct div_nmp {
u8 divm_width;
u8 divp_shift;
u8 divp_width;
- u8 override_divn_shift;
- u8 override_divm_shift;
- u8 override_divp_shift;
};
#define MAX_PLL_MISC_REG_COUNT 6
@@ -238,8 +232,6 @@ struct tegra_clk_pll;
* @aux_reg: AUX register offset
* @dyn_ramp_reg: Dynamic ramp control register offset
* @ext_misc_reg: Miscellaneous control register offsets
- * @pmc_divnm_reg: n, m divider PMC override register offset (PLLM)
- * @pmc_divp_reg: p divider PMC override register offset (PLLM)
* @flags: PLL flags
* @stepa_shift: Dynamic ramp step A field shift
* @stepb_shift: Dynamic ramp step B field shift
@@ -319,8 +311,6 @@ struct tegra_clk_pll_params {
u32 aux_reg;
u32 dyn_ramp_reg;
u32 ext_misc_reg[MAX_PLL_MISC_REG_COUNT];
- u32 pmc_divnm_reg;
- u32 pmc_divp_reg;
u32 flags;
int stepa_shift;
int stepb_shift;
--
2.7.4
Tegra clk_out_1, clk_out_2, and clk_out_3 are part of PMC block and pmc is
the provider for these clocks.
Update bindings document to use pmc as clock provider for clk_out_2 and
change id to pmc clock id.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
Documentation/devicetree/bindings/sound/nau8825.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/nau8825.txt b/Documentation/devicetree/bindings/sound/nau8825.txt
index d16d96839bcb..487eb9574ee2 100644
--- a/Documentation/devicetree/bindings/sound/nau8825.txt
+++ b/Documentation/devicetree/bindings/sound/nau8825.txt
@@ -101,5 +101,5 @@ Example:
nuvoton,crosstalk-enable;
clock-names = "mclk";
- clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_2>;
+ clocks = <&pmc TEGRA_PMC_CLK_OUT_2>;
};
--
2.7.4
clk_out_2 is the clocks from Tegra PMC block with clock source and state
control part of Tegra PMC.
Tegra pmc node is the provider for these clocks.
This patch changes clk_out_2 provider to pmc and uses corresponding pmc
clock id for clk_out_2.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
index 72c7a04ac1df..4376c38d78f4 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
@@ -1592,7 +1592,7 @@
reg = <0x1a>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(E, 6) IRQ_TYPE_LEVEL_LOW>;
- clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_2>;
+ clocks = <&pmc TEGRA_PMC_CLK_OUT_2>;
clock-names = "mclk";
nuvoton,jkdet-enable;
--
2.7.4
Tegra pmc has 3 clocks clk_out_1, clk_out_2, clk_out_3 with mux and gate
for each of these clocks as part of pmc and Tegra pmc is the clock provider
for these clocks.
These clock ids are part of pmc dt-bindings.
This patch includes pmc dt-bindings and adds #clock-cells propert
with 1 clock specifier to Tegra pmc node.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
arch/arm64/boot/dts/nvidia/tegra132.dtsi | 4 +++-
arch/arm64/boot/dts/nvidia/tegra186.dtsi | 2 ++
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 2 ++
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 2 ++
4 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
index 631a7f77c386..5bdb4a6a6b90 100644
--- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/thermal/tegra124-soctherm.h>
+#include <dt-bindings/soc/tegra-pmc.h>
/ {
compatible = "nvidia,tegra132", "nvidia,tegra124";
@@ -577,11 +578,12 @@
clock-names = "rtc";
};
- pmc@7000e400 {
+ pmc: pmc@7000e400 {
compatible = "nvidia,tegra124-pmc";
reg = <0x0 0x7000e400 0x0 0x400>;
clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
};
fuse@7000f800 {
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 7893d78a0fb6..627108ce2f56 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/power/tegra186-powergate.h>
#include <dt-bindings/reset/tegra186-reset.h>
#include <dt-bindings/thermal/tegra186-bpmp-thermal.h>
+#include <dt-bindings/soc/tegra-pmc.h>
/ {
compatible = "nvidia,tegra186";
@@ -670,6 +671,7 @@
<0 0x0c390000 0 0x10000>;
reg-names = "pmc", "wake", "aotag", "scratch";
+ #clock-cells = <1>;
#interrupt-cells = <2>;
interrupt-controller;
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 11220d97adb8..37dc19f49e4f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -7,6 +7,7 @@
#include <dt-bindings/power/tegra194-powergate.h>
#include <dt-bindings/reset/tegra194-reset.h>
#include <dt-bindings/thermal/tegra194-bpmp-thermal.h>
+#include <dt-bindings/soc/tegra-pmc.h>
/ {
compatible = "nvidia,tegra194";
@@ -799,6 +800,7 @@
<0x0c3a0000 0x10000>;
reg-names = "pmc", "wake", "aotag", "scratch", "misc";
+ #clock-cells = <1>;
#interrupt-cells = <2>;
interrupt-controller;
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 48c63256ba7f..0d0432d3b37a 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -7,6 +7,7 @@
#include <dt-bindings/reset/tegra210-car.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/thermal/tegra124-soctherm.h>
+#include <dt-bindings/soc/tegra-pmc.h>
/ {
compatible = "nvidia,tegra210";
@@ -780,6 +781,7 @@
reg = <0x0 0x7000e400 0x0 0x400>;
clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
#interrupt-cells = <2>;
interrupt-controller;
--
2.7.4
clk_out_1, clk_out_2, clk_out_3, blink are part of Tegra pmc clocks.
This patch removes ids for these clocks from Tegra clock dt-bindings.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
include/dt-bindings/clock/tegra114-car.h | 14 +++++++-------
include/dt-bindings/clock/tegra124-car-common.h | 14 +++++++-------
include/dt-bindings/clock/tegra20-car.h | 2 +-
include/dt-bindings/clock/tegra210-car.h | 14 +++++++-------
include/dt-bindings/clock/tegra30-car.h | 14 +++++++-------
5 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/include/dt-bindings/clock/tegra114-car.h b/include/dt-bindings/clock/tegra114-car.h
index bb5c2c999c05..9175cd0571b5 100644
--- a/include/dt-bindings/clock/tegra114-car.h
+++ b/include/dt-bindings/clock/tegra114-car.h
@@ -270,10 +270,10 @@
#define TEGRA114_CLK_AUDIO3 242
#define TEGRA114_CLK_AUDIO4 243
#define TEGRA114_CLK_SPDIF 244
-#define TEGRA114_CLK_CLK_OUT_1 245
-#define TEGRA114_CLK_CLK_OUT_2 246
-#define TEGRA114_CLK_CLK_OUT_3 247
-#define TEGRA114_CLK_BLINK 248
+/* 245 */
+/* 246 */
+/* 247 */
+/* 248 */
/* 249 */
/* 250 */
/* 251 */
@@ -333,9 +333,9 @@
#define TEGRA114_CLK_AUDIO3_MUX 303
#define TEGRA114_CLK_AUDIO4_MUX 304
#define TEGRA114_CLK_SPDIF_MUX 305
-#define TEGRA114_CLK_CLK_OUT_1_MUX 306
-#define TEGRA114_CLK_CLK_OUT_2_MUX 307
-#define TEGRA114_CLK_CLK_OUT_3_MUX 308
+/* 306 */
+/* 307 */
+/* 308 */
#define TEGRA114_CLK_DSIA_MUX 309
#define TEGRA114_CLK_DSIB_MUX 310
#define TEGRA114_CLK_XUSB_SS_DIV2 311
diff --git a/include/dt-bindings/clock/tegra124-car-common.h b/include/dt-bindings/clock/tegra124-car-common.h
index 0c4f5be0a742..90a0c5e7eb5f 100644
--- a/include/dt-bindings/clock/tegra124-car-common.h
+++ b/include/dt-bindings/clock/tegra124-car-common.h
@@ -269,10 +269,10 @@
#define TEGRA124_CLK_AUDIO3 242
#define TEGRA124_CLK_AUDIO4 243
#define TEGRA124_CLK_SPDIF 244
-#define TEGRA124_CLK_CLK_OUT_1 245
-#define TEGRA124_CLK_CLK_OUT_2 246
-#define TEGRA124_CLK_CLK_OUT_3 247
-#define TEGRA124_CLK_BLINK 248
+/* 245 */
+/* 246 */
+/* 247 */
+/* 248 */
/* 249 */
/* 250 */
/* 251 */
@@ -332,9 +332,9 @@
#define TEGRA124_CLK_AUDIO3_MUX 303
#define TEGRA124_CLK_AUDIO4_MUX 304
#define TEGRA124_CLK_SPDIF_MUX 305
-#define TEGRA124_CLK_CLK_OUT_1_MUX 306
-#define TEGRA124_CLK_CLK_OUT_2_MUX 307
-#define TEGRA124_CLK_CLK_OUT_3_MUX 308
+/* 306 */
+/* 307 */
+/* 308 */
/* 309 */
/* 310 */
#define TEGRA124_CLK_SOR0_LVDS 311 /* deprecated */
diff --git a/include/dt-bindings/clock/tegra20-car.h b/include/dt-bindings/clock/tegra20-car.h
index b21a0eb32921..fe541f627965 100644
--- a/include/dt-bindings/clock/tegra20-car.h
+++ b/include/dt-bindings/clock/tegra20-car.h
@@ -131,7 +131,7 @@
#define TEGRA20_CLK_CCLK 108
#define TEGRA20_CLK_HCLK 109
#define TEGRA20_CLK_PCLK 110
-#define TEGRA20_CLK_BLINK 111
+/* 111 */
#define TEGRA20_CLK_PLL_A 112
#define TEGRA20_CLK_PLL_A_OUT0 113
#define TEGRA20_CLK_PLL_C 114
diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h
index 44f60623f99b..a3d8d3e75728 100644
--- a/include/dt-bindings/clock/tegra210-car.h
+++ b/include/dt-bindings/clock/tegra210-car.h
@@ -304,10 +304,10 @@
#define TEGRA210_CLK_AUDIO3 274
#define TEGRA210_CLK_AUDIO4 275
#define TEGRA210_CLK_SPDIF 276
-#define TEGRA210_CLK_CLK_OUT_1 277
-#define TEGRA210_CLK_CLK_OUT_2 278
-#define TEGRA210_CLK_CLK_OUT_3 279
-#define TEGRA210_CLK_BLINK 280
+/* 277 */
+/* 278 */
+/* 279 */
+/* 280 */
#define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */
#define TEGRA210_CLK_SOR0_OUT 281
#define TEGRA210_CLK_SOR1_OUT 282
@@ -386,9 +386,9 @@
#define TEGRA210_CLK_AUDIO3_MUX 353
#define TEGRA210_CLK_AUDIO4_MUX 354
#define TEGRA210_CLK_SPDIF_MUX 355
-#define TEGRA210_CLK_CLK_OUT_1_MUX 356
-#define TEGRA210_CLK_CLK_OUT_2_MUX 357
-#define TEGRA210_CLK_CLK_OUT_3_MUX 358
+/* 356 */
+/* 357 */
+/* 358 */
#define TEGRA210_CLK_DSIA_MUX 359
#define TEGRA210_CLK_DSIB_MUX 360
/* 361 */
diff --git a/include/dt-bindings/clock/tegra30-car.h b/include/dt-bindings/clock/tegra30-car.h
index 3c90f1535551..20ef2462d9e1 100644
--- a/include/dt-bindings/clock/tegra30-car.h
+++ b/include/dt-bindings/clock/tegra30-car.h
@@ -230,11 +230,11 @@
#define TEGRA30_CLK_AUDIO3 204
#define TEGRA30_CLK_AUDIO4 205
#define TEGRA30_CLK_SPDIF 206
-#define TEGRA30_CLK_CLK_OUT_1 207 /* (extern1) */
-#define TEGRA30_CLK_CLK_OUT_2 208 /* (extern2) */
-#define TEGRA30_CLK_CLK_OUT_3 209 /* (extern3) */
+/* 207 */
+/* 208 */
+/* 209 */
#define TEGRA30_CLK_SCLK 210
-#define TEGRA30_CLK_BLINK 211
+/* 211 */
#define TEGRA30_CLK_CCLK_G 212
#define TEGRA30_CLK_CCLK_LP 213
#define TEGRA30_CLK_TWD 214
@@ -260,9 +260,9 @@
/* 297 */
/* 298 */
/* 299 */
-#define TEGRA30_CLK_CLK_OUT_1_MUX 300
-#define TEGRA30_CLK_CLK_OUT_2_MUX 301
-#define TEGRA30_CLK_CLK_OUT_3_MUX 302
+/* 300 */
+/* 301 */
+/* 302 */
#define TEGRA30_CLK_AUDIO0_MUX 303
#define TEGRA30_CLK_AUDIO1_MUX 304
#define TEGRA30_CLK_AUDIO2_MUX 305
--
2.7.4
Tegra pmc has 3 clocks clk_out_1, clk_out_2, clk_out_3 with mux and gate
for each of these clocks as part of pmc and Tegra pmc is the clock provider
for these clocks.
This patch adds #clock-cells property with 1 clock specifier to
the Tegra pmc node.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
arch/arm/boot/dts/tegra114.dtsi | 4 +++-
arch/arm/boot/dts/tegra124.dtsi | 4 +++-
arch/arm/boot/dts/tegra30.dtsi | 4 +++-
3 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
index 0d7a6327e404..b8f12f24f314 100644
--- a/arch/arm/boot/dts/tegra114.dtsi
+++ b/arch/arm/boot/dts/tegra114.dtsi
@@ -4,6 +4,7 @@
#include <dt-bindings/memory/tegra114-mc.h>
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/tegra-pmc.h>
/ {
compatible = "nvidia,tegra114";
@@ -514,11 +515,12 @@
status = "disabled";
};
- pmc@7000e400 {
+ pmc: pmc@7000e400 {
compatible = "nvidia,tegra114-pmc";
reg = <0x7000e400 0x400>;
clocks = <&tegra_car TEGRA114_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
};
fuse@7000f800 {
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 413bfb981de8..d0802c4ae3bf 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/tegra124-car.h>
#include <dt-bindings/thermal/tegra124-soctherm.h>
+#include <dt-bindings/soc/tegra-pmc.h>
/ {
compatible = "nvidia,tegra124";
@@ -595,11 +596,12 @@
clocks = <&tegra_car TEGRA124_CLK_RTC>;
};
- pmc@7000e400 {
+ pmc: pmc@7000e400 {
compatible = "nvidia,tegra124-pmc";
reg = <0x0 0x7000e400 0x0 0x400>;
clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
};
fuse@7000f800 {
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 55ae050042ce..4d5e9d0001d3 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -4,6 +4,7 @@
#include <dt-bindings/memory/tegra30-mc.h>
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/tegra-pmc.h>
/ {
compatible = "nvidia,tegra30";
@@ -714,11 +715,12 @@
status = "disabled";
};
- pmc@7000e400 {
+ pmc: pmc@7000e400 {
compatible = "nvidia,tegra30-pmc";
reg = <0x7000e400 0x400>;
clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
};
mc: memory-controller@7000f000 {
--
2.7.4
Tegra PMC has an option to override the CAR PLLM configuration during
the warmboot.
PLLM dividers and enable overrides from Tegra PMC are applicable only
when PLLM_OVERRIDE bit in PMC_PLLP_WB0_OVERRIDE register is set by Tegra
the bootloader. During warmboot based on this override enable, PLLM
divider and enable configuration from overrides in PMC or from CAR
module are used.
Currently PLLM overrides in Tegra PMC are directly programmed by the Tegra
clock driver and with this when PMC is in secure mode, any direct PMC
register access from non-secure world will not go through.
This patch adds helper functions for use by the Tegra clock driver to
configure these PLLM overrides during PLLM clock rate and state changes.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/soc/tegra/pmc.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++-
include/soc/tegra/pmc.h | 5 ++
2 files changed, 205 insertions(+), 4 deletions(-)
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 8db63cfba833..224e7cf8dc00 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -79,6 +79,14 @@
#define PMC_PWR_DET 0x48
+#define TEGRA186_PMC_PLLP_WB0_OVERRIDE 0x4c
+#define PMC_PLLP_WB0_OVERRIDE 0xf8
+#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
+#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE BIT(11)
+
+#define TEGRA186_PMC_PLLM_WB0_OVERRIDE_FREQ 0x50
+#define TEGRA186_PMC_PLLM_WB0_OVERRIDE_2 0x54
+
#define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
#define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
#define PMC_SCRATCH0_MODE_RCM BIT(1)
@@ -122,6 +130,9 @@
#define IO_DPD2_STATUS 0x1c4
#define SEL_DPD_TIM 0x1c8
+#define PMC_PLLM_WB0_OVERRIDE_FREQ 0x1dc
+#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
+
#define PMC_SCRATCH54 0x258
#define PMC_SCRATCH54_DATA_SHIFT 8
#define PMC_SCRATCH54_ADDR_SHIFT 0
@@ -182,6 +193,15 @@ struct tegra_pmc_regs {
unsigned int rst_source_mask;
unsigned int rst_level_shift;
unsigned int rst_level_mask;
+ unsigned int pllp_wb0_override;
+ unsigned int pllm_wb0_override_freq;
+ unsigned int pllm_wb0_override_2;
+ unsigned int override_divm_shift;
+ unsigned int override_divm_mask;
+ unsigned int override_divn_shift;
+ unsigned int override_divn_mask;
+ unsigned int override_divp_shift;
+ unsigned int override_divp_mask;
};
struct tegra_wake_event {
@@ -227,6 +247,7 @@ struct tegra_pmc_soc {
bool needs_mbist_war;
bool has_impl_33v_pwr;
bool maybe_tz_only;
+ bool has_pllm_wb0_override;
const struct tegra_io_pad_soc *io_pads;
unsigned int num_io_pads;
@@ -1156,6 +1177,99 @@ static void tegra_powergate_remove_all(struct device_node *parent)
of_node_put(np);
}
+bool tegra_pmc_is_pllm_wb0_override_enabled(void)
+{
+ u32 val;
+
+ if (pmc->soc->has_pllm_wb0_override) {
+ val = tegra_pmc_readl(pmc, pmc->soc->regs->pllp_wb0_override);
+ return (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) ? 1 : 0;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_pmc_is_pllm_wb0_override_enabled);
+
+bool tegra_pmc_is_pllm_wb0_enabled(void)
+{
+ u32 val;
+
+ if (pmc->soc->has_pllm_wb0_override) {
+ val = tegra_pmc_readl(pmc, pmc->soc->regs->pllp_wb0_override);
+ return (val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE) ? 1 : 0;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_pmc_is_pllm_wb0_enabled);
+
+void tegra_pmc_set_pllm_wb0_enable(bool enable)
+{
+ u32 val;
+
+ if (pmc->soc->has_pllm_wb0_override) {
+ val = tegra_pmc_readl(pmc, pmc->soc->regs->pllp_wb0_override);
+ if (enable)
+ val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
+ else
+ val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
+ tegra_pmc_writel(pmc, val, pmc->soc->regs->pllp_wb0_override);
+ }
+}
+EXPORT_SYMBOL(tegra_pmc_set_pllm_wb0_enable);
+
+void tegra_pmc_get_pllm_wb0_mnp_overrides(u32 *divm, u32 *divn, u8 *divp)
+{
+ u32 val;
+ unsigned int divnm_reg, divp_reg;
+
+ if (pmc->soc->has_pllm_wb0_override) {
+ divnm_reg = pmc->soc->regs->pllm_wb0_override_freq;
+ divp_reg = pmc->soc->regs->pllm_wb0_override_2;
+
+ if (tegra_pmc_is_pllm_wb0_override_enabled()) {
+ val = tegra_pmc_readl(pmc, divnm_reg);
+ *divm = (val >> pmc->soc->regs->override_divm_shift) &
+ pmc->soc->regs->override_divm_mask;
+ *divn = (val >> pmc->soc->regs->override_divn_shift) &
+ pmc->soc->regs->override_divn_mask;
+ val = tegra_pmc_readl(pmc, divp_reg);
+ *divp = (val >> pmc->soc->regs->override_divp_shift) &
+ pmc->soc->regs->override_divp_mask;
+ }
+ }
+}
+EXPORT_SYMBOL(tegra_pmc_get_pllm_wb0_mnp_overrides);
+
+void tegra_pmc_set_pllm_wb0_mnp_overrides(u32 divm, u32 divn, u8 divp)
+{
+ u32 val;
+ unsigned int divnm_reg, divp_reg;
+
+ if (pmc->soc->has_pllm_wb0_override) {
+ divnm_reg = pmc->soc->regs->pllm_wb0_override_freq;
+ divp_reg = pmc->soc->regs->pllm_wb0_override_2;
+
+ if (tegra_pmc_is_pllm_wb0_override_enabled()) {
+ val = tegra_pmc_readl(pmc, divp_reg);
+ val &= ~(pmc->soc->regs->override_divp_mask <<
+ pmc->soc->regs->override_divp_shift);
+ val |= (divp << pmc->soc->regs->override_divp_shift);
+ tegra_pmc_writel(pmc, val, divp_reg);
+
+ val = tegra_pmc_readl(pmc, divnm_reg);
+ val &= ~(pmc->soc->regs->override_divm_mask <<
+ pmc->soc->regs->override_divm_shift);
+ val |= divm << pmc->soc->regs->override_divm_shift;
+ val &= ~(pmc->soc->regs->override_divn_mask <<
+ pmc->soc->regs->override_divn_shift);
+ val |= divn << pmc->soc->regs->override_divn_shift;
+ tegra_pmc_writel(pmc, val, divnm_reg);
+ }
+ }
+}
+EXPORT_SYMBOL(tegra_pmc_set_pllm_wb0_mnp_overrides);
+
static const struct tegra_io_pad_soc *
tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
{
@@ -2345,6 +2459,72 @@ static const struct tegra_pmc_regs tegra20_pmc_regs = {
.rst_level_mask = 0x0,
};
+static const struct tegra_pmc_regs tegra30_pmc_regs = {
+ .scratch0 = 0x50,
+ .dpd_req = 0x1b8,
+ .dpd_status = 0x1bc,
+ .dpd2_req = 0x1c0,
+ .dpd2_status = 0x1c4,
+ .rst_status = 0x1b4,
+ .rst_source_shift = 0x0,
+ .rst_source_mask = 0x7,
+ .rst_level_shift = 0x0,
+ .rst_level_mask = 0x0,
+ .pllp_wb0_override = PMC_PLLP_WB0_OVERRIDE,
+ .pllm_wb0_override_freq = PMC_PLLM_WB0_OVERRIDE_FREQ,
+ .pllm_wb0_override_2 = PMC_PLLM_WB0_OVERRIDE_FREQ,
+ .override_divm_shift = 0,
+ .override_divm_mask = 0x1f,
+ .override_divn_shift = 5,
+ .override_divn_mask = 0x3ff,
+ .override_divp_shift = 15,
+ .override_divp_mask = 0x7,
+};
+
+static const struct tegra_pmc_regs tegra114_pmc_regs = {
+ .scratch0 = 0x50,
+ .dpd_req = 0x1b8,
+ .dpd_status = 0x1bc,
+ .dpd2_req = 0x1c0,
+ .dpd2_status = 0x1c4,
+ .rst_status = 0x1b4,
+ .rst_source_shift = 0x0,
+ .rst_source_mask = 0x7,
+ .rst_level_shift = 0x0,
+ .rst_level_mask = 0x0,
+ .pllp_wb0_override = PMC_PLLP_WB0_OVERRIDE,
+ .pllm_wb0_override_freq = PMC_PLLM_WB0_OVERRIDE_FREQ,
+ .pllm_wb0_override_2 = PMC_PLLM_WB0_OVERRIDE_2,
+ .override_divm_shift = 0,
+ .override_divm_mask = 0xff,
+ .override_divn_shift = 8,
+ .override_divn_mask = 0xff,
+ .override_divp_shift = 27,
+ .override_divp_mask = 0x1,
+};
+
+static const struct tegra_pmc_regs tegra210_pmc_regs = {
+ .scratch0 = 0x50,
+ .dpd_req = 0x1b8,
+ .dpd_status = 0x1bc,
+ .dpd2_req = 0x1c0,
+ .dpd2_status = 0x1c4,
+ .rst_status = 0x1b4,
+ .rst_source_shift = 0x0,
+ .rst_source_mask = 0x7,
+ .rst_level_shift = 0x0,
+ .rst_level_mask = 0x0,
+ .pllp_wb0_override = PMC_PLLP_WB0_OVERRIDE,
+ .pllm_wb0_override_freq = PMC_PLLM_WB0_OVERRIDE_FREQ,
+ .pllm_wb0_override_2 = PMC_PLLM_WB0_OVERRIDE_2,
+ .override_divm_shift = 0,
+ .override_divm_mask = 0xff,
+ .override_divn_shift = 8,
+ .override_divn_mask = 0xff,
+ .override_divp_shift = 27,
+ .override_divp_mask = 0x1f,
+};
+
static void tegra20_pmc_init(struct tegra_pmc *pmc)
{
u32 value, osc, pmu, off;
@@ -2411,6 +2591,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.needs_mbist_war = false,
.has_impl_33v_pwr = false,
.maybe_tz_only = false,
+ .has_pllm_wb0_override = false,
.num_io_pads = 0,
.io_pads = NULL,
.num_pin_descs = 0,
@@ -2458,11 +2639,12 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.needs_mbist_war = false,
.has_impl_33v_pwr = false,
.maybe_tz_only = false,
+ .has_pllm_wb0_override = true,
.num_io_pads = 0,
.io_pads = NULL,
.num_pin_descs = 0,
.pin_descs = NULL,
- .regs = &tegra20_pmc_regs,
+ .regs = &tegra30_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
.reset_sources = tegra30_reset_sources,
@@ -2509,11 +2691,12 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.needs_mbist_war = false,
.has_impl_33v_pwr = false,
.maybe_tz_only = false,
+ .has_pllm_wb0_override = true,
.num_io_pads = 0,
.io_pads = NULL,
.num_pin_descs = 0,
.pin_descs = NULL,
- .regs = &tegra20_pmc_regs,
+ .regs = &tegra114_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
.reset_sources = tegra30_reset_sources,
@@ -2620,11 +2803,12 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.needs_mbist_war = false,
.has_impl_33v_pwr = false,
.maybe_tz_only = false,
+ .has_pllm_wb0_override = true,
.num_io_pads = ARRAY_SIZE(tegra124_io_pads),
.io_pads = tegra124_io_pads,
.num_pin_descs = ARRAY_SIZE(tegra124_pin_descs),
.pin_descs = tegra124_pin_descs,
- .regs = &tegra20_pmc_regs,
+ .regs = &tegra114_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
.reset_sources = tegra30_reset_sources,
@@ -2730,11 +2914,12 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
.needs_mbist_war = true,
.has_impl_33v_pwr = false,
.maybe_tz_only = true,
+ .has_pllm_wb0_override = true,
.num_io_pads = ARRAY_SIZE(tegra210_io_pads),
.io_pads = tegra210_io_pads,
.num_pin_descs = ARRAY_SIZE(tegra210_pin_descs),
.pin_descs = tegra210_pin_descs,
- .regs = &tegra20_pmc_regs,
+ .regs = &tegra210_pmc_regs,
.init = tegra20_pmc_init,
.setup_irq_polarity = tegra20_pmc_setup_irq_polarity,
.irq_set_wake = tegra210_pmc_irq_set_wake,
@@ -2807,6 +2992,15 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = {
.rst_source_mask = 0x3C,
.rst_level_shift = 0x0,
.rst_level_mask = 0x3,
+ .pllp_wb0_override = TEGRA186_PMC_PLLP_WB0_OVERRIDE,
+ .pllm_wb0_override_freq = TEGRA186_PMC_PLLM_WB0_OVERRIDE_FREQ,
+ .pllm_wb0_override_2 = TEGRA186_PMC_PLLM_WB0_OVERRIDE_2,
+ .override_divm_shift = 0,
+ .override_divm_mask = 0xff,
+ .override_divn_shift = 8,
+ .override_divn_mask = 0xff,
+ .override_divp_shift = 27,
+ .override_divp_mask = 0x1f,
};
static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
@@ -2859,6 +3053,7 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
.needs_mbist_war = false,
.has_impl_33v_pwr = true,
.maybe_tz_only = false,
+ .has_pllm_wb0_override = true,
.num_io_pads = ARRAY_SIZE(tegra186_io_pads),
.io_pads = tegra186_io_pads,
.num_pin_descs = ARRAY_SIZE(tegra186_pin_descs),
@@ -2941,6 +3136,7 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
.needs_mbist_war = false,
.has_impl_33v_pwr = false,
.maybe_tz_only = false,
+ .has_pllm_wb0_override = false,
.num_io_pads = ARRAY_SIZE(tegra194_io_pads),
.io_pads = tegra194_io_pads,
.regs = &tegra186_pmc_regs,
diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h
index 57e58faf660b..cbf23e0d3c55 100644
--- a/include/soc/tegra/pmc.h
+++ b/include/soc/tegra/pmc.h
@@ -20,6 +20,11 @@ struct reset_control;
bool tegra_pmc_cpu_is_powered(unsigned int cpuid);
int tegra_pmc_cpu_power_on(unsigned int cpuid);
int tegra_pmc_cpu_remove_clamping(unsigned int cpuid);
+bool tegra_pmc_is_pllm_wb0_override_enabled(void);
+bool tegra_pmc_is_pllm_wb0_enabled(void);
+void tegra_pmc_set_pllm_wb0_enable(bool enable);
+void tegra_pmc_get_pllm_wb0_mnp_overrides(u32 *divm, u32 *divn, u8 *divp);
+void tegra_pmc_set_pllm_wb0_mnp_overrides(u32 divm, u32 divn, u8 divp);
/*
* powergate and I/O rail APIs
--
2.7.4
Tegra PMC has PLLE IDDQ mode override to allow software control
of PLLE power up or down.
PLLE is put in IDDQ mode by the hardware. Software can override
the PLLE IDDQ control by setting the IDDQ override bit and IDDQ
SWCTL bits in the PMC_SATA_PWRGT PMC register.
Currently Tegra clock driver overrides hardware IDDQ control and
clears PLLE IDDQ during PLLE training by direct Tegra PMC register
access. With this, when PMC is in secure mode any direct PMC register
access from non-secure mode will not go through.
This patch adds helper function for software control of PLLE IDDQ
to use by Tegra clock driver.
Helper function uses tegra_pmc_readl and tegra_pmc_writel which
handles both secure mode and non-secure mode PMC register access.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/soc/tegra/pmc.c | 22 ++++++++++++++++++++++
include/soc/tegra/pmc.h | 1 +
2 files changed, 23 insertions(+)
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 224e7cf8dc00..7a5aab0b993b 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -108,6 +108,10 @@
#define PMC_WAKE2_STATUS 0x168
#define PMC_SW_WAKE2_STATUS 0x16c
+#define PMC_SATA_PWRGT 0x1ac
+#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
+#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
+
#define PMC_SENSOR_CTRL 0x1b0
#define PMC_SENSOR_CTRL_SCRATCH_WRITE BIT(2)
#define PMC_SENSOR_CTRL_ENABLE_RST BIT(1)
@@ -1177,6 +1181,24 @@ static void tegra_powergate_remove_all(struct device_node *parent)
of_node_put(np);
}
+void tegra_pmc_clear_plle_iddq(void)
+{
+ u32 val;
+
+ val = tegra_pmc_readl(pmc, PMC_SATA_PWRGT);
+ val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+ tegra_pmc_writel(pmc, val, PMC_SATA_PWRGT);
+
+ val = tegra_pmc_readl(pmc, PMC_SATA_PWRGT);
+ val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
+ tegra_pmc_writel(pmc, val, PMC_SATA_PWRGT);
+
+ val = tegra_pmc_readl(pmc, PMC_SATA_PWRGT);
+ val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+ tegra_pmc_writel(pmc, val, PMC_SATA_PWRGT);
+}
+EXPORT_SYMBOL(tegra_pmc_clear_plle_iddq);
+
bool tegra_pmc_is_pllm_wb0_override_enabled(void)
{
u32 val;
diff --git a/include/soc/tegra/pmc.h b/include/soc/tegra/pmc.h
index cbf23e0d3c55..2fdd60484765 100644
--- a/include/soc/tegra/pmc.h
+++ b/include/soc/tegra/pmc.h
@@ -25,6 +25,7 @@ bool tegra_pmc_is_pllm_wb0_enabled(void);
void tegra_pmc_set_pllm_wb0_enable(bool enable);
void tegra_pmc_get_pllm_wb0_mnp_overrides(u32 *divm, u32 *divn, u8 *divp);
void tegra_pmc_set_pllm_wb0_mnp_overrides(u32 divm, u32 divn, u8 divp);
+void tegra_pmc_clear_plle_iddq(void);
/*
* powergate and I/O rail APIs
--
2.7.4
Document clock bindings for pmc clocks clk_out_1, clk_out_2 and clk_out_3.
These clocks are part of Tegra PMC block and pmc node is the provider for
these clocks.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
.../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
index 2d89cdc39eb0..4576de92e4cc 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
@@ -12,6 +12,10 @@ Required properties:
- "aotag"
- "scratch"
- "misc" (Only for Tegra194)
+- #clock-cells : Should be 1 for Tegra30 and higher.
+ In clock consumers, this cell represents the PMC clock ID.
+ The assignments may be found in header file
+ <dt-bindings/soc/tegra-pmc.h>.
Optional properties:
- nvidia,invert-interrupt: If present, inverts the PMU interrupt signal.
@@ -130,3 +134,43 @@ Pinctrl client example:
pinctrl-1 = <&hdmi_on>;
pinctrl-names = "hdmi-on", "hdmi-off";
};
+
+== Clock Control ==
+
+Tegra PMC has 3 clocks clk_1, clk_2 and clk_3. Each of these clocks has
+source selection and enable/disable gate.
+Parent/source for these clocks can be either of clk_m, clk_m_div2, clk_m_div4,
+or extern clock from Tegra CAR module.
+
+Clock configuration example:
+ pmc: pmc@7000e400 {
+ compatible = "nvidia,tegra186-pmc";
+ reg = <0 0x0c360000 0 0x10000>,
+ <0 0x0c370000 0 0x10000>,
+ <0 0x0c380000 0 0x10000>,
+ <0 0x0c390000 0 0x10000>;
+ reg-names = "pmc", "wake", "aotag", "scratch";
+ ...
+ #clock-cells = <1>;
+ ...
+ };
+
+Clock consumer example:
+ host1x@50000000 {
+ ...
+ vi@54080000 {
+ ...
+ assigned-clocks = <&pmc TEGRA_PMC_CLK_OUT_3_MUX>;
+ assigned-clock-parents = <&tegra_car TEGRA210_CLK_EXTERN3>;
+ };
+ ...
+ };
+ ...
+ i2c@7000c500 {
+ cam_sensor {
+ ...
+ clocks = <&pmc TEGRA_PMC_CLK_OUT_3>;
+ clock-names = "mclk";
+ ...
+ };
+ };
--
2.7.4
Current Tegra clock driver registers PMC clocks clk_out_1, clk_out_2,
clk_out_3 and blink output in tegra_pmc_init() which does direct Tegra
PMC access during clk_ops and these PMC register read and write access
will not happen when PMC is in secure mode.
Any direct PMC register access from non-secure world will not go
through and all the PMC clocks and blink control are done in Tegra PMC
driver with PMC as clock provider.
This patch removes tegra_pmc_clk_init along with corresponding clk ids
from Tegra clock driver.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/clk/tegra/Makefile | 1 -
drivers/clk/tegra/clk-id.h | 7 -------
drivers/clk/tegra/clk-tegra114.c | 33 ------------------------------
drivers/clk/tegra/clk-tegra124.c | 44 +++++-----------------------------------
drivers/clk/tegra/clk-tegra20.c | 24 ----------------------
drivers/clk/tegra/clk-tegra210.c | 32 -----------------------------
drivers/clk/tegra/clk-tegra30.c | 32 -----------------------------
drivers/clk/tegra/clk.h | 1 -
8 files changed, 5 insertions(+), 169 deletions(-)
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index df966ca06788..1f7c30f87ece 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -12,7 +12,6 @@ obj-y += clk-sdmmc-mux.o
obj-y += clk-super.o
obj-y += clk-tegra-audio.o
obj-y += clk-tegra-periph.o
-obj-y += clk-tegra-pmc.o
obj-y += clk-tegra-fixed.o
obj-y += clk-tegra-super-gen4.o
obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o
diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
index c4faebd32760..5913357a8000 100644
--- a/drivers/clk/tegra/clk-id.h
+++ b/drivers/clk/tegra/clk-id.h
@@ -32,7 +32,6 @@ enum clk_id {
tegra_clk_audio4,
tegra_clk_audio4_2x,
tegra_clk_audio4_mux,
- tegra_clk_blink,
tegra_clk_bsea,
tegra_clk_bsev,
tegra_clk_cclk_g,
@@ -46,12 +45,6 @@ enum clk_id {
tegra_clk_clk_m,
tegra_clk_clk_m_div2,
tegra_clk_clk_m_div4,
- tegra_clk_clk_out_1,
- tegra_clk_clk_out_1_mux,
- tegra_clk_clk_out_2,
- tegra_clk_clk_out_2_mux,
- tegra_clk_clk_out_3,
- tegra_clk_clk_out_3_mux,
tegra_clk_cml0,
tegra_clk_cml1,
tegra_clk_csi,
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index e7c4af928da3..e125c1c50b3a 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -124,7 +124,6 @@ static struct cpu_clk_suspend_context {
#endif
static void __iomem *clk_base;
-static void __iomem *pmc_base;
static DEFINE_SPINLOCK(pll_d_lock);
static DEFINE_SPINLOCK(pll_d2_lock);
@@ -769,10 +768,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
[tegra_clk_audio3] = { .dt_id = TEGRA114_CLK_AUDIO3, .present = true },
[tegra_clk_audio4] = { .dt_id = TEGRA114_CLK_AUDIO4, .present = true },
[tegra_clk_spdif] = { .dt_id = TEGRA114_CLK_SPDIF, .present = true },
- [tegra_clk_clk_out_1] = { .dt_id = TEGRA114_CLK_CLK_OUT_1, .present = true },
- [tegra_clk_clk_out_2] = { .dt_id = TEGRA114_CLK_CLK_OUT_2, .present = true },
- [tegra_clk_clk_out_3] = { .dt_id = TEGRA114_CLK_CLK_OUT_3, .present = true },
- [tegra_clk_blink] = { .dt_id = TEGRA114_CLK_BLINK, .present = true },
[tegra_clk_xusb_host_src] = { .dt_id = TEGRA114_CLK_XUSB_HOST_SRC, .present = true },
[tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA114_CLK_XUSB_FALCON_SRC, .present = true },
[tegra_clk_xusb_fs_src] = { .dt_id = TEGRA114_CLK_XUSB_FS_SRC, .present = true },
@@ -794,9 +789,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
[tegra_clk_audio3_mux] = { .dt_id = TEGRA114_CLK_AUDIO3_MUX, .present = true },
[tegra_clk_audio4_mux] = { .dt_id = TEGRA114_CLK_AUDIO4_MUX, .present = true },
[tegra_clk_spdif_mux] = { .dt_id = TEGRA114_CLK_SPDIF_MUX, .present = true },
- [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_1_MUX, .present = true },
- [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_2_MUX, .present = true },
- [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA114_CLK_CLK_OUT_3_MUX, .present = true },
[tegra_clk_dsia_mux] = { .dt_id = TEGRA114_CLK_DSIA_MUX, .present = true },
[tegra_clk_dsib_mux] = { .dt_id = TEGRA114_CLK_DSIB_MUX, .present = true },
[tegra_clk_cec] = { .dt_id = TEGRA114_CLK_CEC, .present = true },
@@ -857,7 +849,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA114_CLK_EXTERN1 },
{ .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA114_CLK_EXTERN2 },
{ .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA114_CLK_EXTERN3 },
- { .con_id = "blink", .dt_id = TEGRA114_CLK_BLINK },
{ .con_id = "cclk_g", .dt_id = TEGRA114_CLK_CCLK_G },
{ .con_id = "cclk_lp", .dt_id = TEGRA114_CLK_CCLK_LP },
{ .con_id = "sclk", .dt_id = TEGRA114_CLK_SCLK },
@@ -1127,11 +1118,6 @@ static struct tegra_cpu_car_ops tegra114_cpu_car_ops = {
#endif
};
-static const struct of_device_id pmc_match[] __initconst = {
- { .compatible = "nvidia,tegra114-pmc" },
- { },
-};
-
/*
* dfll_soc/dfll_ref apparently must be kept enabled, otherwise I2C5
* breaks
@@ -1144,8 +1130,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{ TEGRA114_CLK_PLL_A, TEGRA114_CLK_CLK_MAX, 564480000, 1 },
{ TEGRA114_CLK_PLL_A_OUT0, TEGRA114_CLK_CLK_MAX, 11289600, 1 },
{ TEGRA114_CLK_EXTERN1, TEGRA114_CLK_PLL_A_OUT0, 0, 1 },
- { TEGRA114_CLK_CLK_OUT_1_MUX, TEGRA114_CLK_EXTERN1, 0, 1 },
- { TEGRA114_CLK_CLK_OUT_1, TEGRA114_CLK_CLK_MAX, 0, 1 },
{ TEGRA114_CLK_I2S0, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA114_CLK_I2S1, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA114_CLK_I2S2, TEGRA114_CLK_PLL_A_OUT0, 11289600, 0 },
@@ -1309,28 +1293,12 @@ EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset);
static void __init tegra114_clock_init(struct device_node *np)
{
- struct device_node *node;
-
clk_base = of_iomap(np, 0);
if (!clk_base) {
pr_err("ioremap tegra114 CAR failed\n");
return;
}
- node = of_find_matching_node(NULL, pmc_match);
- if (!node) {
- pr_err("Failed to find pmc node\n");
- WARN_ON(1);
- return;
- }
-
- pmc_base = of_iomap(node, 0);
- if (!pmc_base) {
- pr_err("Can't map pmc registers\n");
- WARN_ON(1);
- return;
- }
-
clks = tegra_clk_init(clk_base, TEGRA114_CLK_CLK_MAX,
TEGRA114_CLK_PERIPH_BANKS);
if (!clks)
@@ -1346,7 +1314,6 @@ static void __init tegra114_clock_init(struct device_node *np)
tegra114_periph_clk_init(clk_base);
tegra_audio_clk_init(clk_base, tegra114_clks, tegra114_audio_plls,
ARRAY_SIZE(tegra114_audio_plls), 24000000);
- tegra_pmc_clk_init(pmc_base, tegra114_clks);
tegra_super_clk_gen4_init(clk_base, tegra114_clks, &pll_x_params);
tegra_add_of_provider(np, of_clk_src_onecell_get);
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 0b7532857a58..ff2ec0dcdefa 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -114,7 +114,6 @@ static struct cpu_clk_suspend_context {
#endif
static void __iomem *clk_base;
-static void __iomem *pmc_base;
static unsigned long osc_freq;
static unsigned long pll_ref_freq;
@@ -894,10 +893,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
[tegra_clk_audio3] = { .dt_id = TEGRA124_CLK_AUDIO3, .present = true },
[tegra_clk_audio4] = { .dt_id = TEGRA124_CLK_AUDIO4, .present = true },
[tegra_clk_spdif] = { .dt_id = TEGRA124_CLK_SPDIF, .present = true },
- [tegra_clk_clk_out_1] = { .dt_id = TEGRA124_CLK_CLK_OUT_1, .present = true },
- [tegra_clk_clk_out_2] = { .dt_id = TEGRA124_CLK_CLK_OUT_2, .present = true },
- [tegra_clk_clk_out_3] = { .dt_id = TEGRA124_CLK_CLK_OUT_3, .present = true },
- [tegra_clk_blink] = { .dt_id = TEGRA124_CLK_BLINK, .present = true },
[tegra_clk_xusb_host_src] = { .dt_id = TEGRA124_CLK_XUSB_HOST_SRC, .present = true },
[tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true },
[tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true },
@@ -923,9 +918,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
[tegra_clk_audio3_mux] = { .dt_id = TEGRA124_CLK_AUDIO3_MUX, .present = true },
[tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true },
[tegra_clk_spdif_mux] = { .dt_id = TEGRA124_CLK_SPDIF_MUX, .present = true },
- [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_1_MUX, .present = true },
- [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_2_MUX, .present = true },
- [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true },
[tegra_clk_cec] = { .dt_id = TEGRA124_CLK_CEC, .present = true },
};
@@ -983,7 +975,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA124_CLK_EXTERN1 },
{ .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA124_CLK_EXTERN2 },
{ .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA124_CLK_EXTERN3 },
- { .con_id = "blink", .dt_id = TEGRA124_CLK_BLINK },
{ .con_id = "cclk_g", .dt_id = TEGRA124_CLK_CCLK_G },
{ .con_id = "cclk_lp", .dt_id = TEGRA124_CLK_CCLK_LP },
{ .con_id = "sclk", .dt_id = TEGRA124_CLK_SCLK },
@@ -1278,11 +1269,6 @@ static struct tegra_cpu_car_ops tegra124_cpu_car_ops = {
#endif
};
-static const struct of_device_id pmc_match[] __initconst = {
- { .compatible = "nvidia,tegra124-pmc" },
- { },
-};
-
static struct tegra_clk_init_table common_init_table[] __initdata = {
{ TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 408000000, 0 },
{ TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0 },
@@ -1291,8 +1277,6 @@ static struct tegra_clk_init_table common_init_table[] __initdata = {
{ TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 1 },
{ TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 1 },
{ TEGRA124_CLK_EXTERN1, TEGRA124_CLK_PLL_A_OUT0, 0, 1 },
- { TEGRA124_CLK_CLK_OUT_1_MUX, TEGRA124_CLK_EXTERN1, 0, 1 },
- { TEGRA124_CLK_CLK_OUT_1, TEGRA124_CLK_CLK_MAX, 0, 1 },
{ TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
@@ -1447,15 +1431,12 @@ static void __init tegra132_clock_apply_init_table(void)
* tegra124_132_clock_init_pre - clock initialization preamble for T124/T132
* @np: struct device_node * of the DT node for the SoC CAR IP block
*
- * Register most of the clocks controlled by the CAR IP block, along
- * with a few clocks controlled by the PMC IP block. Everything in
- * this function should be common to Tegra124 and Tegra132. XXX The
- * PMC clock initialization should probably be moved to PMC-specific
- * driver code. No return value.
+ * Register most of the clocks controlled by the CAR IP block.
+ * Everything in this function should be common to Tegra124 and Tegra132.
+ * No return value.
*/
static void __init tegra124_132_clock_init_pre(struct device_node *np)
{
- struct device_node *node;
u32 plld_base;
clk_base = of_iomap(np, 0);
@@ -1464,20 +1445,6 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
return;
}
- node = of_find_matching_node(NULL, pmc_match);
- if (!node) {
- pr_err("Failed to find pmc node\n");
- WARN_ON(1);
- return;
- }
-
- pmc_base = of_iomap(node, 0);
- if (!pmc_base) {
- pr_err("Can't map pmc registers\n");
- WARN_ON(1);
- return;
- }
-
clks = tegra_clk_init(clk_base, TEGRA124_CLK_CLK_MAX,
TEGRA124_CAR_BANK_COUNT);
if (!clks)
@@ -1493,7 +1460,6 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
tegra124_periph_clk_init(clk_base);
tegra_audio_clk_init(clk_base, tegra124_clks, tegra124_audio_plls,
ARRAY_SIZE(tegra124_audio_plls), 24576000);
- tegra_pmc_clk_init(pmc_base, tegra124_clks);
/* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */
plld_base = readl(clk_base + PLLD_BASE);
@@ -1505,8 +1471,8 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
* tegra124_132_clock_init_post - clock initialization postamble for T124/T132
* @np: struct device_node * of the DT node for the SoC CAR IP block
*
- * Register most of the along with a few clocks controlled by the PMC
- * IP block. Everything in this function should be common to Tegra124
+ * Register most of the clocks controlled by the CAR IP block.
+ * Everything in this function should be common to Tegra124
* and Tegra132. This function must be called after
* tegra124_132_clock_init_pre(), otherwise clk_base will not be set.
* No return value.
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 5cf33c99976d..585ceabd1ea7 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -128,7 +128,6 @@ static struct cpu_clk_suspend_context {
#endif
static void __iomem *clk_base;
-static void __iomem *pmc_base;
#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \
_clk_num, _gate_flags, _clk_id) \
@@ -458,7 +457,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .con_id = "cdev1", .dt_id = TEGRA20_CLK_CDEV1 },
{ .con_id = "cdev2", .dt_id = TEGRA20_CLK_CDEV2 },
{ .con_id = "clk_32k", .dt_id = TEGRA20_CLK_CLK_32K },
- { .con_id = "blink", .dt_id = TEGRA20_CLK_BLINK },
{ .con_id = "clk_m", .dt_id = TEGRA20_CLK_CLK_M },
{ .con_id = "pll_ref", .dt_id = TEGRA20_CLK_PLL_REF },
{ .dev_id = "tegra20-i2s.0", .dt_id = TEGRA20_CLK_I2S1 },
@@ -537,7 +535,6 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = {
[tegra_clk_csi] = { .dt_id = TEGRA20_CLK_CSI, .present = true },
[tegra_clk_isp] = { .dt_id = TEGRA20_CLK_ISP, .present = true },
[tegra_clk_clk_32k] = { .dt_id = TEGRA20_CLK_CLK_32K, .present = true },
- [tegra_clk_blink] = { .dt_id = TEGRA20_CLK_BLINK, .present = true },
[tegra_clk_hclk] = { .dt_id = TEGRA20_CLK_HCLK, .present = true },
[tegra_clk_pclk] = { .dt_id = TEGRA20_CLK_PCLK, .present = true },
[tegra_clk_pll_p_out1] = { .dt_id = TEGRA20_CLK_PLL_P_OUT1, .present = true },
@@ -1034,7 +1031,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{ TEGRA20_CLK_PLL_A, TEGRA20_CLK_CLK_MAX, 56448000, 1 },
{ TEGRA20_CLK_PLL_A_OUT0, TEGRA20_CLK_CLK_MAX, 11289600, 1 },
{ TEGRA20_CLK_CDEV1, TEGRA20_CLK_CLK_MAX, 0, 1 },
- { TEGRA20_CLK_BLINK, TEGRA20_CLK_CLK_MAX, 32768, 1 },
{ TEGRA20_CLK_I2S1, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA20_CLK_I2S2, TEGRA20_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0 },
@@ -1074,11 +1070,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
TEGRA_CLK_DUPLICATE(TEGRA20_CLK_CLK_MAX, NULL, NULL),
};
-static const struct of_device_id pmc_match[] __initconst = {
- { .compatible = "nvidia,tegra20-pmc" },
- { },
-};
-
static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
void *data)
{
@@ -1116,26 +1107,12 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
static void __init tegra20_clock_init(struct device_node *np)
{
- struct device_node *node;
-
clk_base = of_iomap(np, 0);
if (!clk_base) {
pr_err("Can't map CAR registers\n");
BUG();
}
- node = of_find_matching_node(NULL, pmc_match);
- if (!node) {
- pr_err("Failed to find pmc node\n");
- BUG();
- }
-
- pmc_base = of_iomap(node, 0);
- if (!pmc_base) {
- pr_err("Can't map pmc registers\n");
- BUG();
- }
-
clks = tegra_clk_init(clk_base, TEGRA20_CLK_CLK_MAX,
TEGRA20_CLK_PERIPH_BANKS);
if (!clks)
@@ -1148,7 +1125,6 @@ static void __init tegra20_clock_init(struct device_node *np)
tegra_super_clk_gen4_init(clk_base, tegra20_clks, NULL);
tegra20_periph_clk_init();
tegra20_audio_clk_init();
- tegra_pmc_clk_init(pmc_base, tegra20_clks);
tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX);
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 86d0b847be0d..71f29cf8d13e 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -288,7 +288,6 @@ struct tegra210_domain_mbist_war {
static struct clk **clks;
static void __iomem *clk_base;
-static void __iomem *pmc_base;
static void __iomem *ahub_base;
static void __iomem *dispa_base;
static void __iomem *vic_base;
@@ -2409,10 +2408,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
[tegra_clk_audio3] = { .dt_id = TEGRA210_CLK_AUDIO3, .present = true },
[tegra_clk_audio4] = { .dt_id = TEGRA210_CLK_AUDIO4, .present = true },
[tegra_clk_spdif] = { .dt_id = TEGRA210_CLK_SPDIF, .present = true },
- [tegra_clk_clk_out_1] = { .dt_id = TEGRA210_CLK_CLK_OUT_1, .present = true },
- [tegra_clk_clk_out_2] = { .dt_id = TEGRA210_CLK_CLK_OUT_2, .present = true },
- [tegra_clk_clk_out_3] = { .dt_id = TEGRA210_CLK_CLK_OUT_3, .present = true },
- [tegra_clk_blink] = { .dt_id = TEGRA210_CLK_BLINK, .present = true },
[tegra_clk_xusb_gate] = { .dt_id = TEGRA210_CLK_XUSB_GATE, .present = true },
[tegra_clk_xusb_host_src_8] = { .dt_id = TEGRA210_CLK_XUSB_HOST_SRC, .present = true },
[tegra_clk_xusb_falcon_src_8] = { .dt_id = TEGRA210_CLK_XUSB_FALCON_SRC, .present = true },
@@ -2444,9 +2439,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
[tegra_clk_audio3_mux] = { .dt_id = TEGRA210_CLK_AUDIO3_MUX, .present = true },
[tegra_clk_audio4_mux] = { .dt_id = TEGRA210_CLK_AUDIO4_MUX, .present = true },
[tegra_clk_spdif_mux] = { .dt_id = TEGRA210_CLK_SPDIF_MUX, .present = true },
- [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_1_MUX, .present = true },
- [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_2_MUX, .present = true },
- [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_3_MUX, .present = true },
[tegra_clk_maud] = { .dt_id = TEGRA210_CLK_MAUD, .present = true },
[tegra_clk_mipibif] = { .dt_id = TEGRA210_CLK_MIPIBIF, .present = true },
[tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .present = true },
@@ -2535,7 +2527,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA210_CLK_EXTERN1 },
{ .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA210_CLK_EXTERN2 },
{ .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA210_CLK_EXTERN3 },
- { .con_id = "blink", .dt_id = TEGRA210_CLK_BLINK },
{ .con_id = "cclk_g", .dt_id = TEGRA210_CLK_CCLK_G },
{ .con_id = "cclk_lp", .dt_id = TEGRA210_CLK_CCLK_LP },
{ .con_id = "sclk", .dt_id = TEGRA210_CLK_SCLK },
@@ -3428,11 +3419,6 @@ static struct tegra_cpu_car_ops tegra210_cpu_car_ops = {
#endif
};
-static const struct of_device_id pmc_match[] __initconst = {
- { .compatible = "nvidia,tegra210-pmc" },
- { },
-};
-
static struct tegra_clk_init_table init_table[] __initdata = {
{ TEGRA210_CLK_UARTA, TEGRA210_CLK_PLL_P, 408000000, 0 },
{ TEGRA210_CLK_UARTB, TEGRA210_CLK_PLL_P, 408000000, 0 },
@@ -3441,8 +3427,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{ TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1 },
{ TEGRA210_CLK_PLL_A_OUT0, TEGRA210_CLK_CLK_MAX, 11289600, 1 },
{ TEGRA210_CLK_EXTERN1, TEGRA210_CLK_PLL_A_OUT0, 0, 1 },
- { TEGRA210_CLK_CLK_OUT_1_MUX, TEGRA210_CLK_EXTERN1, 0, 1 },
- { TEGRA210_CLK_CLK_OUT_1, TEGRA210_CLK_CLK_MAX, 0, 1 },
{ TEGRA210_CLK_I2S0, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA210_CLK_I2S1, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA210_CLK_I2S2, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
@@ -3623,7 +3607,6 @@ static void tegra210_mbist_clk_init(void)
*/
static void __init tegra210_clock_init(struct device_node *np)
{
- struct device_node *node;
u32 value, clk_m_div;
clk_base = of_iomap(np, 0);
@@ -3632,20 +3615,6 @@ static void __init tegra210_clock_init(struct device_node *np)
return;
}
- node = of_find_matching_node(NULL, pmc_match);
- if (!node) {
- pr_err("Failed to find pmc node\n");
- WARN_ON(1);
- return;
- }
-
- pmc_base = of_iomap(node, 0);
- if (!pmc_base) {
- pr_err("Can't map pmc registers\n");
- WARN_ON(1);
- return;
- }
-
ahub_base = ioremap(TEGRA210_AHUB_BASE, SZ_64K);
if (!ahub_base) {
pr_err("ioremap tegra210 APE failed\n");
@@ -3682,7 +3651,6 @@ static void __init tegra210_clock_init(struct device_node *np)
tegra210_periph_clk_init(clk_base);
tegra_audio_clk_init(clk_base, tegra210_clks, tegra210_audio_plls,
ARRAY_SIZE(tegra210_audio_plls), 24576000);
- tegra_pmc_clk_init(pmc_base, tegra210_clks);
/* For Tegra210, PLLD is the only source for DSIA & DSIB */
value = readl(clk_base + PLLD_BASE);
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index d65e7edf0cfd..02a8c21ac52c 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -143,7 +143,6 @@ static struct cpu_clk_suspend_context {
#endif
static void __iomem *clk_base;
-static void __iomem *pmc_base;
static unsigned long input_freq;
static DEFINE_SPINLOCK(cml_lock);
@@ -564,7 +563,6 @@ static struct tegra_devclk devclks[] __initdata = {
{ .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA30_CLK_EXTERN1 },
{ .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA30_CLK_EXTERN2 },
{ .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA30_CLK_EXTERN3 },
- { .con_id = "blink", .dt_id = TEGRA30_CLK_BLINK },
{ .con_id = "cclk_g", .dt_id = TEGRA30_CLK_CCLK_G },
{ .con_id = "cclk_lp", .dt_id = TEGRA30_CLK_CCLK_LP },
{ .con_id = "sclk", .dt_id = TEGRA30_CLK_SCLK },
@@ -703,13 +701,6 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = {
[tegra_clk_audio3_2x] = { .dt_id = TEGRA30_CLK_AUDIO3_2X, .present = true },
[tegra_clk_audio4_2x] = { .dt_id = TEGRA30_CLK_AUDIO4_2X, .present = true },
[tegra_clk_spdif_2x] = { .dt_id = TEGRA30_CLK_SPDIF_2X, .present = true },
- [tegra_clk_clk_out_1] = { .dt_id = TEGRA30_CLK_CLK_OUT_1, .present = true },
- [tegra_clk_clk_out_2] = { .dt_id = TEGRA30_CLK_CLK_OUT_2, .present = true },
- [tegra_clk_clk_out_3] = { .dt_id = TEGRA30_CLK_CLK_OUT_3, .present = true },
- [tegra_clk_blink] = { .dt_id = TEGRA30_CLK_BLINK, .present = true },
- [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_1_MUX, .present = true },
- [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_2_MUX, .present = true },
- [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_3_MUX, .present = true },
[tegra_clk_hclk] = { .dt_id = TEGRA30_CLK_HCLK, .present = true },
[tegra_clk_pclk] = { .dt_id = TEGRA30_CLK_PCLK, .present = true },
[tegra_clk_i2s0] = { .dt_id = TEGRA30_CLK_I2S0, .present = true },
@@ -1222,9 +1213,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{ TEGRA30_CLK_PLL_A, TEGRA30_CLK_CLK_MAX, 564480000, 1 },
{ TEGRA30_CLK_PLL_A_OUT0, TEGRA30_CLK_CLK_MAX, 11289600, 1 },
{ TEGRA30_CLK_EXTERN1, TEGRA30_CLK_PLL_A_OUT0, 0, 1 },
- { TEGRA30_CLK_CLK_OUT_1_MUX, TEGRA30_CLK_EXTERN1, 0, 0 },
- { TEGRA30_CLK_CLK_OUT_1, TEGRA30_CLK_CLK_MAX, 0, 1 },
- { TEGRA30_CLK_BLINK, TEGRA30_CLK_CLK_MAX, 0, 1 },
{ TEGRA30_CLK_I2S0, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA30_CLK_I2S1, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 },
{ TEGRA30_CLK_I2S2, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 },
@@ -1288,11 +1276,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
TEGRA_CLK_DUPLICATE(TEGRA30_CLK_CLK_MAX, NULL, NULL),
};
-static const struct of_device_id pmc_match[] __initconst = {
- { .compatible = "nvidia,tegra30-pmc" },
- { },
-};
-
static struct tegra_audio_clk_info tegra30_audio_plls[] = {
{ "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
};
@@ -1319,26 +1302,12 @@ static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec,
static void __init tegra30_clock_init(struct device_node *np)
{
- struct device_node *node;
-
clk_base = of_iomap(np, 0);
if (!clk_base) {
pr_err("ioremap tegra30 CAR failed\n");
return;
}
- node = of_find_matching_node(NULL, pmc_match);
- if (!node) {
- pr_err("Failed to find pmc node\n");
- BUG();
- }
-
- pmc_base = of_iomap(node, 0);
- if (!pmc_base) {
- pr_err("Can't map pmc registers\n");
- BUG();
- }
-
clks = tegra_clk_init(clk_base, TEGRA30_CLK_CLK_MAX,
TEGRA30_CLK_PERIPH_BANKS);
if (!clks)
@@ -1355,7 +1324,6 @@ static void __init tegra30_clock_init(struct device_node *np)
tegra30_periph_clk_init();
tegra_audio_clk_init(clk_base, tegra30_clks, tegra30_audio_plls,
ARRAY_SIZE(tegra30_audio_plls), 24000000);
- tegra_pmc_clk_init(pmc_base, tegra30_clks);
tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index cd79b7fc4e5e..88236ae9e33d 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -837,7 +837,6 @@ void tegra_periph_clk_init(void __iomem *clk_base,
struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params);
-void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks);
void tegra_fixed_clk_init(struct tegra_clk *tegra_clks);
int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
unsigned long *input_freqs, unsigned int num,
--
2.7.4
Document clock bindings for pmc clocks clk_out_1, clk_out_2 and clk_out_3.
These clocks are part of Tegra PMC block and pmc node is the provider for
these clocks.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
.../bindings/arm/tegra/nvidia,tegra20-pmc.txt | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
index cb12f33a247f..602a1ac5c0b6 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
@@ -21,6 +21,10 @@ Required properties:
- clock-names : Must include the following entries:
"pclk" (The Tegra clock of that name),
"clk32k_in" (The 32KHz clock input to Tegra).
+- #clock-cells : Should be 1 for Tegra30 and higher.
+ In clock consumers, this cell represents the PMC clock ID.
+ The assignments may be found in header file
+ <dt-bindings/soc/tegra-pmc.h>.
Optional properties:
- nvidia,invert-interrupt : If present, inverts the PMU interrupt signal.
@@ -171,6 +175,7 @@ Example:
reg = <0x0 0x7000e400 0x0 0x400>;
clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
powergates {
pd_audio: aud {
@@ -260,6 +265,7 @@ Pad configuration state example:
reg = <0x0 0x7000e400 0x0 0x400>;
clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
...
@@ -298,3 +304,39 @@ Pinctrl client example:
pinctrl-1 = <&hdmi_on>;
pinctrl-names = "hdmi-on", "hdmi-off";
};
+
+== Clock Control ==
+
+Tegra PMC has 3 clocks clk_1, clk_2 and clk_3. Each of these clocks has
+source selection and enable/disable gate.
+Parent/source for these clocks can be either of clk_m, clk_m_div2, clk_m_div4,
+or extern clock from Tegra CAR module.
+
+Clock configuration example:
+ pmc: pmc@7000e400 {
+ compatible = "nvidia,tegra210-pmc";
+ reg = <0x0 0x7000e400 0x0 0x400>;
+ clocks = <&tegra_car TEGRA210_CLK_PCLK>, <&clk32k_in>;
+ clock-names = "pclk", "clk32k_in";
+ #clock-cells = <1>;
+ };
+
+Clock consumer example:
+ host1x@50000000 {
+ ...
+ vi@54080000 {
+ ...
+ assigned-clocks = <&pmc TEGRA_PMC_CLK_OUT_3_MUX>;
+ assigned-clock-parents = <&tegra_car TEGRA210_CLK_EXTERN3>;
+ };
+ ...
+ };
+ ...
+ i2c@7000c500 {
+ cam_sensor {
+ ...
+ clocks = <&pmc TEGRA_PMC_CLK_OUT_3>;
+ clock-names = "mclk";
+ ...
+ };
+ };
--
2.7.4
Tegra clock driver uses helper functions from Tegra PMC driver.
This patch removes PMC base references from all clocks registration.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/clk/tegra/clk-pll.c | 60 ++++++++++++++------------------
drivers/clk/tegra/clk-tegra-audio.c | 4 +--
drivers/clk/tegra/clk-tegra-periph.c | 8 ++---
drivers/clk/tegra/clk-tegra-super-gen4.c | 11 +++---
drivers/clk/tegra/clk-tegra114.c | 33 ++++++++----------
drivers/clk/tegra/clk-tegra124.c | 34 ++++++++----------
drivers/clk/tegra/clk-tegra20.c | 6 ++--
drivers/clk/tegra/clk-tegra210.c | 34 ++++++++----------
drivers/clk/tegra/clk-tegra30.c | 19 +++++-----
drivers/clk/tegra/clk.h | 37 ++++++++------------
10 files changed, 108 insertions(+), 138 deletions(-)
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 4ae9e282e7be..6a9b4be8ef2a 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -1801,7 +1801,7 @@ static void _clk_plle_tegra_init_parent(struct tegra_clk_pll *pll)
#endif
static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
- void __iomem *pmc, struct tegra_clk_pll_params *pll_params,
+ struct tegra_clk_pll_params *pll_params,
spinlock_t *lock)
{
struct tegra_clk_pll *pll;
@@ -1811,7 +1811,6 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
return ERR_PTR(-ENOMEM);
pll->clk_base = clk_base;
- pll->pmc = pmc;
pll->params = pll_params;
pll->lock = lock;
@@ -1852,8 +1851,8 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll,
}
struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags, struct tegra_clk_pll_params *pll_params,
+ void __iomem *clk_base, unsigned long flags,
+ struct tegra_clk_pll_params *pll_params,
spinlock_t *lock)
{
struct tegra_clk_pll *pll;
@@ -1861,7 +1860,7 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
pll_params->flags |= TEGRA_PLL_BYPASS;
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -1883,8 +1882,8 @@ static struct div_nmp pll_e_nmp = {
};
struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags, struct tegra_clk_pll_params *pll_params,
+ void __iomem *clk_base, unsigned long flags,
+ struct tegra_clk_pll_params *pll_params,
spinlock_t *lock)
{
struct tegra_clk_pll *pll;
@@ -1895,7 +1894,7 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
if (!pll_params->div_nmp)
pll_params->div_nmp = &pll_e_nmp;
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -1916,7 +1915,7 @@ struct clk *tegra_clk_register_pllu(const char *name, const char *parent_name,
pll_params->flags |= TEGRA_PLLU;
- pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -1974,8 +1973,7 @@ static const struct clk_ops tegra_clk_pllu_tegra114_ops = {
};
struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock)
{
@@ -2025,7 +2023,7 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
}
}
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2038,8 +2036,7 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
}
struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock, unsigned long parent_rate)
{
@@ -2053,7 +2050,7 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
pll_params->vco_min = pll_params->adjust_vco(pll_params,
parent_rate);
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2087,8 +2084,7 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
}
struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock)
{
@@ -2116,7 +2112,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
pll_params->flags |= TEGRA_PLL_BYPASS;
pll_params->flags |= TEGRA_PLLM;
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2129,8 +2125,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
}
struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock)
{
@@ -2155,7 +2150,7 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
pll_params->flags |= TEGRA_PLL_BYPASS;
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2211,7 +2206,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
struct tegra_clk_pll *pll;
struct clk *clk;
- pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2236,7 +2231,7 @@ tegra_clk_register_pllu_tegra114(const char *name, const char *parent_name,
pll_params->flags |= TEGRA_PLLU;
- pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2282,7 +2277,7 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
return ERR_PTR(-EINVAL);
}
- pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2344,7 +2339,7 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
struct clk *tegra_clk_register_pllre_tegra210(const char *name,
const char *parent_name, void __iomem *clk_base,
- void __iomem *pmc, unsigned long flags,
+ unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock, unsigned long parent_rate)
{
@@ -2357,7 +2352,7 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name,
pll_params->vco_min = pll_params->adjust_vco(pll_params,
parent_rate);
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2526,7 +2521,7 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
struct tegra_clk_pll *pll;
struct clk *clk;
- pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2542,7 +2537,7 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
struct clk *tegra_clk_register_pllc_tegra210(const char *name,
const char *parent_name, void __iomem *clk_base,
- void __iomem *pmc, unsigned long flags,
+ unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock)
{
@@ -2570,7 +2565,7 @@ struct clk *tegra_clk_register_pllc_tegra210(const char *name,
parent_rate);
pll_params->flags |= TEGRA_PLL_BYPASS;
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2618,7 +2613,7 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name,
parent_rate);
pll_params->flags |= TEGRA_PLL_BYPASS;
- pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2632,8 +2627,7 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name,
}
struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock)
{
@@ -2661,7 +2655,7 @@ struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name,
pll_params->flags |= TEGRA_PLL_BYPASS;
pll_params->flags |= TEGRA_PLLMB;
- pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
+ pll = _tegra_init_pll(clk_base, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
diff --git a/drivers/clk/tegra/clk-tegra-audio.c b/drivers/clk/tegra/clk-tegra-audio.c
index c99e34d69711..1c813a7b89e7 100644
--- a/drivers/clk/tegra/clk-tegra-audio.c
+++ b/drivers/clk/tegra/clk-tegra-audio.c
@@ -161,7 +161,7 @@ static void __init tegra_audio_sync_clk_init(void __iomem *clk_base,
}
void __init tegra_audio_clk_init(void __iomem *clk_base,
- void __iomem *pmc_base, struct tegra_clk *tegra_clks,
+ struct tegra_clk *tegra_clks,
struct tegra_audio_clk_info *audio_info,
unsigned int num_plls, unsigned long sync_max_rate)
{
@@ -181,7 +181,7 @@ void __init tegra_audio_clk_init(void __iomem *clk_base,
dt_clk = tegra_lookup_dt_id(info->clk_id, tegra_clks);
if (dt_clk) {
clk = tegra_clk_register_pll(info->name, info->parent,
- clk_base, pmc_base, 0, info->pll_params,
+ clk_base, 0, info->pll_params,
NULL);
*dt_clk = clk;
}
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index 0d07c0ba49b6..e2979b972526 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -936,7 +936,7 @@ static void __init div_clk_init(void __iomem *clk_base,
}
}
-static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base,
+static void __init init_pllp(void __iomem *clk_base,
struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params)
{
@@ -948,7 +948,7 @@ static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base,
if (dt_clk) {
/* PLLP */
clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base,
- pmc_base, 0, pll_params, NULL);
+ 0, pll_params, NULL);
clk_register_clkdev(clk, "pll_p", NULL);
*dt_clk = clk;
}
@@ -1020,10 +1020,10 @@ static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base,
}
void __init tegra_periph_clk_init(void __iomem *clk_base,
- void __iomem *pmc_base, struct tegra_clk *tegra_clks,
+ struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params)
{
- init_pllp(clk_base, pmc_base, tegra_clks, pll_params);
+ init_pllp(clk_base, tegra_clks, pll_params);
periph_clk_init(clk_base, tegra_clks);
gate_clk_init(clk_base, tegra_clks);
div_clk_init(clk_base, tegra_clks);
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
index 5760c978bef7..26c9bc606228 100644
--- a/drivers/clk/tegra/clk-tegra-super-gen4.c
+++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
@@ -163,7 +163,6 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
}
static void __init tegra_super_clk_init(void __iomem *clk_base,
- void __iomem *pmc_base,
struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *params,
const struct tegra_super_gen_info *gen_info)
@@ -231,11 +230,11 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
if (gen_info->gen == gen5)
clk = tegra_clk_register_pllc_tegra210("pll_x", "pll_ref",
- clk_base, pmc_base, CLK_IGNORE_UNUSED, params, NULL);
+ clk_base, CLK_IGNORE_UNUSED, params, NULL);
else
#endif
clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base,
- pmc_base, CLK_IGNORE_UNUSED, params, NULL);
+ CLK_IGNORE_UNUSED, params, NULL);
*dt_clk = clk;
@@ -251,19 +250,17 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
}
void __init tegra_super_clk_gen4_init(void __iomem *clk_base,
- void __iomem *pmc_base,
struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *params)
{
- tegra_super_clk_init(clk_base, pmc_base, tegra_clks, params,
+ tegra_super_clk_init(clk_base, tegra_clks, params,
&tegra_super_gen_info_gen4);
}
void __init tegra_super_clk_gen5_init(void __iomem *clk_base,
- void __iomem *pmc_base,
struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *params)
{
- tegra_super_clk_init(clk_base, pmc_base, tegra_clks, params,
+ tegra_super_clk_init(clk_base, tegra_clks, params,
&tegra_super_gen_info_gen5);
}
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 77904334b6f0..e7c4af928da3 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -904,14 +904,13 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base)
}
-static void __init tegra114_pll_init(void __iomem *clk_base,
- void __iomem *pmc)
+static void __init tegra114_pll_init(void __iomem *clk_base)
{
struct clk *clk;
/* PLLC */
clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base,
- pmc, 0, &pll_c_params, NULL);
+ 0, &pll_c_params, NULL);
clks[TEGRA114_CLK_PLL_C] = clk;
/* PLLC_OUT1 */
@@ -924,17 +923,17 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
clks[TEGRA114_CLK_PLL_C_OUT1] = clk;
/* PLLC2 */
- clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0,
+ clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, 0,
&pll_c2_params, NULL);
clks[TEGRA114_CLK_PLL_C2] = clk;
/* PLLC3 */
- clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0,
+ clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, 0,
&pll_c3_params, NULL);
clks[TEGRA114_CLK_PLL_C3] = clk;
/* PLLM */
- clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
+ clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base,
CLK_SET_RATE_GATE, &pll_m_params, NULL);
clks[TEGRA114_CLK_PLL_M] = clk;
@@ -978,7 +977,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
clks[TEGRA114_CLK_PLL_U_12M] = clk;
/* PLLD */
- clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
+ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, 0,
&pll_d_params, &pll_d_lock);
clks[TEGRA114_CLK_PLL_D] = clk;
@@ -988,7 +987,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
clks[TEGRA114_CLK_PLL_D_OUT0] = clk;
/* PLLD2 */
- clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0,
+ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, 0,
&pll_d2_params, &pll_d2_lock);
clks[TEGRA114_CLK_PLL_D2] = clk;
@@ -998,7 +997,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
clks[TEGRA114_CLK_PLL_D2_OUT0] = clk;
/* PLLRE */
- clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
+ clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base,
0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq);
clks[TEGRA114_CLK_PLL_RE_VCO] = clk;
@@ -1019,8 +1018,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = {
MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR),
};
-static __init void tegra114_periph_clk_init(void __iomem *clk_base,
- void __iomem *pmc_base)
+static __init void tegra114_periph_clk_init(void __iomem *clk_base)
{
struct clk *clk;
struct tegra_periph_init_data *data;
@@ -1075,8 +1073,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
clks[data->clk_id] = clk;
}
- tegra_periph_clk_init(clk_base, pmc_base, tegra114_clks,
- &pll_p_params);
+ tegra_periph_clk_init(clk_base, tegra114_clks, &pll_p_params);
}
/* Tegra114 CPU clock and reset control functions */
@@ -1345,14 +1342,12 @@ static void __init tegra114_clock_init(struct device_node *np)
return;
tegra114_fixed_clk_init(clk_base);
- tegra114_pll_init(clk_base, pmc_base);
- tegra114_periph_clk_init(clk_base, pmc_base);
- tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks,
- tegra114_audio_plls,
+ tegra114_pll_init(clk_base);
+ tegra114_periph_clk_init(clk_base);
+ tegra_audio_clk_init(clk_base, tegra114_clks, tegra114_audio_plls,
ARRAY_SIZE(tegra114_audio_plls), 24000000);
tegra_pmc_clk_init(pmc_base, tegra114_clks);
- tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
- &pll_x_params);
+ tegra_super_clk_gen4_init(clk_base, tegra114_clks, &pll_x_params);
tegra_add_of_provider(np, of_clk_src_onecell_get);
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 010daac53ea7..0b7532857a58 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1019,8 +1019,7 @@ static struct tegra_periph_init_data tegra124_periph[] = {
static struct clk **clks;
-static __init void tegra124_periph_clk_init(void __iomem *clk_base,
- void __iomem *pmc_base)
+static __init void tegra124_periph_clk_init(void __iomem *clk_base)
{
struct clk *clk;
unsigned int i;
@@ -1078,17 +1077,16 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base,
*clkp = clk;
}
- tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params);
+ tegra_periph_clk_init(clk_base, tegra124_clks, &pll_p_params);
}
-static void __init tegra124_pll_init(void __iomem *clk_base,
- void __iomem *pmc)
+static void __init tegra124_pll_init(void __iomem *clk_base)
{
struct clk *clk;
/* PLLC */
clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base,
- pmc, 0, &pll_c_params, NULL);
+ 0, &pll_c_params, NULL);
clk_register_clkdev(clk, "pll_c", NULL);
clks[TEGRA124_CLK_PLL_C] = clk;
@@ -1109,19 +1107,19 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
clks[TEGRA124_CLK_PLL_C_UD] = clk;
/* PLLC2 */
- clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0,
+ clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, 0,
&pll_c2_params, NULL);
clk_register_clkdev(clk, "pll_c2", NULL);
clks[TEGRA124_CLK_PLL_C2] = clk;
/* PLLC3 */
- clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0,
+ clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, 0,
&pll_c3_params, NULL);
clk_register_clkdev(clk, "pll_c3", NULL);
clks[TEGRA124_CLK_PLL_C3] = clk;
/* PLLM */
- clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
+ clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base,
CLK_SET_RATE_GATE, &pll_m_params, NULL);
clk_register_clkdev(clk, "pll_m", NULL);
clks[TEGRA124_CLK_PLL_M] = clk;
@@ -1174,7 +1172,7 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
clks[TEGRA124_CLK_PLL_U_12M] = clk;
/* PLLD */
- clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
+ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, 0,
&pll_d_params, &pll_d_lock);
clk_register_clkdev(clk, "pll_d", NULL);
clks[TEGRA124_CLK_PLL_D] = clk;
@@ -1186,7 +1184,7 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
clks[TEGRA124_CLK_PLL_D_OUT0] = clk;
/* PLLRE */
- clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
+ clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base,
0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq);
clk_register_clkdev(clk, "pll_re_vco", NULL);
clks[TEGRA124_CLK_PLL_RE_VCO] = clk;
@@ -1491,10 +1489,9 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
return;
tegra_fixed_clk_init(tegra124_clks);
- tegra124_pll_init(clk_base, pmc_base);
- tegra124_periph_clk_init(clk_base, pmc_base);
- tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks,
- tegra124_audio_plls,
+ tegra124_pll_init(clk_base);
+ tegra124_periph_clk_init(clk_base);
+ tegra_audio_clk_init(clk_base, tegra124_clks, tegra124_audio_plls,
ARRAY_SIZE(tegra124_audio_plls), 24576000);
tegra_pmc_clk_init(pmc_base, tegra124_clks);
@@ -1511,13 +1508,12 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
* Register most of the along with a few clocks controlled by the PMC
* IP block. Everything in this function should be common to Tegra124
* and Tegra132. This function must be called after
- * tegra124_132_clock_init_pre(), otherwise clk_base and pmc_base will
- * not be set. No return value.
+ * tegra124_132_clock_init_pre(), otherwise clk_base will not be set.
+ * No return value.
*/
static void __init tegra124_132_clock_init_post(struct device_node *np)
{
- tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks,
- &pll_x_params);
+ tegra_super_clk_gen4_init(clk_base, tegra124_clks, &pll_x_params);
tegra_init_special_resets(1, tegra124_reset_assert,
tegra124_reset_deassert);
tegra_add_of_provider(np, of_clk_src_onecell_get);
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 4d8222f5c638..5cf33c99976d 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -687,7 +687,7 @@ static void tegra20_pll_init(void)
clks[TEGRA20_CLK_PLL_A_OUT0] = clk;
/* PLLE */
- clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base,
+ clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base,
0, &pll_e_params, NULL);
clks[TEGRA20_CLK_PLL_E] = clk;
}
@@ -853,7 +853,7 @@ static void __init tegra20_periph_clk_init(void)
clks[data->clk_id] = clk;
}
- tegra_periph_clk_init(clk_base, pmc_base, tegra20_clks, &pll_p_params);
+ tegra_periph_clk_init(clk_base, tegra20_clks, &pll_p_params);
}
static void __init tegra20_osc_clk_init(void)
@@ -1145,7 +1145,7 @@ static void __init tegra20_clock_init(struct device_node *np)
tegra_fixed_clk_init(tegra20_clks);
tegra20_pll_init();
tegra20_super_clk_init();
- tegra_super_clk_gen4_init(clk_base, pmc_base, tegra20_clks, NULL);
+ tegra_super_clk_gen4_init(clk_base, tegra20_clks, NULL);
tegra20_periph_clk_init();
tegra20_audio_clk_init();
tegra_pmc_clk_init(pmc_base, tegra20_clks);
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 63f8a778821f..86d0b847be0d 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -2993,8 +2993,7 @@ static const char * const la_parents[] = {
static struct tegra_clk_periph tegra210_la =
TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, 0);
-static __init void tegra210_periph_clk_init(void __iomem *clk_base,
- void __iomem *pmc_base)
+static __init void tegra210_periph_clk_init(void __iomem *clk_base)
{
struct clk *clk;
unsigned int i;
@@ -3090,17 +3089,16 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
*clkp = clk;
}
- tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params);
+ tegra_periph_clk_init(clk_base, tegra210_clks, &pll_p_params);
}
-static void __init tegra210_pll_init(void __iomem *clk_base,
- void __iomem *pmc)
+static void __init tegra210_pll_init(void __iomem *clk_base)
{
struct clk *clk;
/* PLLC */
clk = tegra_clk_register_pllc_tegra210("pll_c", "pll_ref", clk_base,
- pmc, 0, &pll_c_params, NULL);
+ 0, &pll_c_params, NULL);
if (!WARN_ON(IS_ERR(clk)))
clk_register_clkdev(clk, "pll_c", NULL);
clks[TEGRA210_CLK_PLL_C] = clk;
@@ -3123,24 +3121,24 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
/* PLLC2 */
clk = tegra_clk_register_pllc_tegra210("pll_c2", "pll_ref", clk_base,
- pmc, 0, &pll_c2_params, NULL);
+ 0, &pll_c2_params, NULL);
clk_register_clkdev(clk, "pll_c2", NULL);
clks[TEGRA210_CLK_PLL_C2] = clk;
/* PLLC3 */
clk = tegra_clk_register_pllc_tegra210("pll_c3", "pll_ref", clk_base,
- pmc, 0, &pll_c3_params, NULL);
+ 0, &pll_c3_params, NULL);
clk_register_clkdev(clk, "pll_c3", NULL);
clks[TEGRA210_CLK_PLL_C3] = clk;
/* PLLM */
- clk = tegra_clk_register_pllm("pll_m", "osc", clk_base, pmc,
+ clk = tegra_clk_register_pllm("pll_m", "osc", clk_base,
CLK_SET_RATE_GATE, &pll_m_params, NULL);
clk_register_clkdev(clk, "pll_m", NULL);
clks[TEGRA210_CLK_PLL_M] = clk;
/* PLLMB */
- clk = tegra_clk_register_pllmb("pll_mb", "osc", clk_base, pmc,
+ clk = tegra_clk_register_pllmb("pll_mb", "osc", clk_base,
CLK_SET_RATE_GATE, &pll_mb_params, NULL);
clk_register_clkdev(clk, "pll_mb", NULL);
clks[TEGRA210_CLK_PLL_MB] = clk;
@@ -3210,7 +3208,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
clks[TEGRA210_CLK_PLL_U_48M] = clk;
/* PLLD */
- clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
+ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, 0,
&pll_d_params, &pll_d_lock);
clk_register_clkdev(clk, "pll_d", NULL);
clks[TEGRA210_CLK_PLL_D] = clk;
@@ -3223,7 +3221,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
/* PLLRE */
clk = tegra_clk_register_pllre_tegra210("pll_re_vco", "pll_ref",
- clk_base, pmc, 0,
+ clk_base, 0,
&pll_re_vco_params,
&pll_re_lock, pll_ref_freq);
clk_register_clkdev(clk, "pll_re_vco", NULL);
@@ -3251,7 +3249,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
clks[TEGRA210_CLK_PLL_E] = clk;
/* PLLC4 */
- clk = tegra_clk_register_pllre("pll_c4_vco", "pll_ref", clk_base, pmc,
+ clk = tegra_clk_register_pllre("pll_c4_vco", "pll_ref", clk_base,
0, &pll_c4_vco_params, NULL, pll_ref_freq);
clk_register_clkdev(clk, "pll_c4_vco", NULL);
clks[TEGRA210_CLK_PLL_C4] = clk;
@@ -3680,10 +3678,9 @@ static void __init tegra210_clock_init(struct device_node *np)
return;
tegra_fixed_clk_init(tegra210_clks);
- tegra210_pll_init(clk_base, pmc_base);
- tegra210_periph_clk_init(clk_base, pmc_base);
- tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks,
- tegra210_audio_plls,
+ tegra210_pll_init(clk_base);
+ tegra210_periph_clk_init(clk_base);
+ tegra_audio_clk_init(clk_base, tegra210_clks, tegra210_audio_plls,
ARRAY_SIZE(tegra210_audio_plls), 24576000);
tegra_pmc_clk_init(pmc_base, tegra210_clks);
@@ -3694,8 +3691,7 @@ static void __init tegra210_clock_init(struct device_node *np)
tegra_clk_apply_init_table = tegra210_clock_apply_init_table;
- tegra_super_clk_gen5_init(clk_base, pmc_base, tegra210_clks,
- &pll_x_params);
+ tegra_super_clk_gen5_init(clk_base, tegra210_clks, &pll_x_params);
tegra_init_special_resets(2, tegra210_reset_assert,
tegra210_reset_deassert);
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index e3b64c66acdc..d65e7edf0cfd 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -809,7 +809,7 @@ static void __init tegra30_pll_init(void)
struct clk *clk;
/* PLLC */
- clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0,
+ clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, 0,
&pll_c_params, NULL);
clks[TEGRA30_CLK_PLL_C] = clk;
@@ -823,7 +823,7 @@ static void __init tegra30_pll_init(void)
clks[TEGRA30_CLK_PLL_C_OUT1] = clk;
/* PLLM */
- clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
+ clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base,
CLK_SET_RATE_GATE, &pll_m_params, NULL);
clks[TEGRA30_CLK_PLL_M] = clk;
@@ -837,7 +837,7 @@ static void __init tegra30_pll_init(void)
clks[TEGRA30_CLK_PLL_M_OUT1] = clk;
/* PLLX */
- clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0,
+ clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, 0,
&pll_x_params, NULL);
clks[TEGRA30_CLK_PLL_X] = clk;
@@ -852,7 +852,7 @@ static void __init tegra30_pll_init(void)
clks[TEGRA30_CLK_PLL_U] = clk;
/* PLLD */
- clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0,
+ clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, 0,
&pll_d_params, &pll_d_lock);
clks[TEGRA30_CLK_PLL_D] = clk;
@@ -862,7 +862,7 @@ static void __init tegra30_pll_init(void)
clks[TEGRA30_CLK_PLL_D_OUT0] = clk;
/* PLLD2 */
- clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0,
+ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, 0,
&pll_d2_params, NULL);
clks[TEGRA30_CLK_PLL_D2] = clk;
@@ -876,7 +876,7 @@ static void __init tegra30_pll_init(void)
ARRAY_SIZE(pll_e_parents),
CLK_SET_RATE_NO_REPARENT,
clk_base + PLLE_AUX, 2, 1, 0, NULL);
- clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base,
+ clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base
CLK_GET_RATE_NOCACHE, &pll_e_params, NULL);
clks[TEGRA30_CLK_PLL_E] = clk;
}
@@ -980,7 +980,7 @@ static void __init tegra30_super_clk_init(void)
CLK_SET_RATE_PARENT, 1, 2);
clks[TEGRA30_CLK_TWD] = clk;
- tegra_super_clk_gen4_init(clk_base, pmc_base, tegra30_clks, NULL);
+ tegra_super_clk_gen4_init(clk_base, tegra30_clks, NULL);
}
static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p",
@@ -1067,7 +1067,7 @@ static void __init tegra30_periph_clk_init(void)
clks[data->clk_id] = clk;
}
- tegra_periph_clk_init(clk_base, pmc_base, tegra30_clks, &pll_p_params);
+ tegra_periph_clk_init(clk_base, tegra30_clks, &pll_p_params);
}
/* Tegra30 CPU clock and reset control functions */
@@ -1353,8 +1353,7 @@ static void __init tegra30_clock_init(struct device_node *np)
tegra30_pll_init();
tegra30_super_clk_init();
tegra30_periph_clk_init();
- tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks,
- tegra30_audio_plls,
+ tegra_audio_clk_init(clk_base, tegra30_clks, tegra30_audio_plls,
ARRAY_SIZE(tegra30_audio_plls), 24000000);
tegra_pmc_clk_init(pmc_base, tegra30_clks);
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 9a4473f94fe0..cd79b7fc4e5e 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -354,14 +354,12 @@ struct tegra_clk_pll_params {
*
* @hw: handle between common and hardware-specifix interfaces
* @clk_base: address of CAR controller
- * @pmc: address of PMC, required to read override bits
* @lock: register lock
* @params: PLL parameters
*/
struct tegra_clk_pll {
struct clk_hw hw;
void __iomem *clk_base;
- void __iomem *pmc;
spinlock_t *lock;
struct tegra_clk_pll_params *params;
};
@@ -386,42 +384,38 @@ struct tegra_audio_clk_info {
extern const struct clk_ops tegra_clk_pll_ops;
extern const struct clk_ops tegra_clk_plle_ops;
struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags, struct tegra_clk_pll_params *pll_params,
+ void __iomem *clk_base, unsigned long flags,
+ struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags, struct tegra_clk_pll_params *pll_params,
+ void __iomem *clk_base, unsigned long flags,
+ struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock, unsigned long parent_rate);
struct clk *tegra_clk_register_pllre_tegra210(const char *name,
const char *parent_name, void __iomem *clk_base,
- void __iomem *pmc, unsigned long flags,
+ unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock, unsigned long parent_rate);
@@ -439,7 +433,7 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
struct clk *tegra_clk_register_pllc_tegra210(const char *name,
const char *parent_name, void __iomem *clk_base,
- void __iomem *pmc, unsigned long flags,
+ unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
@@ -455,8 +449,7 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
spinlock_t *lock);
struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name,
- void __iomem *clk_base, void __iomem *pmc,
- unsigned long flags,
+ void __iomem *clk_base, unsigned long flags,
struct tegra_clk_pll_params *pll_params,
spinlock_t *lock);
@@ -836,11 +829,11 @@ void tegra_add_of_provider(struct device_node *np, void *clk_src_onecell_get);
void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
void tegra_audio_clk_init(void __iomem *clk_base,
- void __iomem *pmc_base, struct tegra_clk *tegra_clks,
+ struct tegra_clk *tegra_clks,
struct tegra_audio_clk_info *audio_info,
unsigned int num_plls, unsigned long sync_max_rate);
-void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
+void tegra_periph_clk_init(void __iomem *clk_base,
struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params);
@@ -851,10 +844,10 @@ int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
unsigned int clk_m_div, unsigned long *osc_freq,
unsigned long *pll_ref_freq);
void tegra_super_clk_gen4_init(void __iomem *clk_base,
- void __iomem *pmc_base, struct tegra_clk *tegra_clks,
+ struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params);
void tegra_super_clk_gen5_init(void __iomem *clk_base,
- void __iomem *pmc_base, struct tegra_clk *tegra_clks,
+ struct tegra_clk *tegra_clks,
struct tegra_clk_pll_params *pll_params);
#ifdef CONFIG_TEGRA_CLK_EMC
--
2.7.4
Tegra PMC has clk_out_1, clk_out_2, clk_out_3 with mux and gate for
each of these clocks.
Currently these PMC clocks are registered by Tegra clock driver using
clk_register_mux and clk_register_gate by passing PMC base address
and register offsets and PMC programming for these clocks happens
through direct PMC access by the clock driver.
With this, when PMC is in secure mode any direct PMC access from the
non-secure world does not go through and these clocks will not be
functional.
This patch adds these clocks registration with PMC as a clock provider
for these clocks. clk_ops callback implementations for these clocks
uses tegra_pmc_readl and tegra_pmc_writel which supports PMC programming
in secure mode and non-secure mode.
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/soc/tegra/pmc.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 330 insertions(+)
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 7a5aab0b993b..790a6619ba32 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -13,6 +13,9 @@
#include <linux/arm-smccc.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/clk-conf.h>
#include <linux/clk/tegra.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -48,6 +51,7 @@
#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
#include <dt-bindings/gpio/tegra186-gpio.h>
#include <dt-bindings/gpio/tegra194-gpio.h>
+#include <dt-bindings/soc/tegra-pmc.h>
#define PMC_CNTRL 0x0
#define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
@@ -108,6 +112,7 @@
#define PMC_WAKE2_STATUS 0x168
#define PMC_SW_WAKE2_STATUS 0x16c
+#define PMC_CLK_OUT_CNTRL 0x1a8
#define PMC_SATA_PWRGT 0x1ac
#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
@@ -170,6 +175,78 @@
#define TEGRA_SMC_PMC_READ 0xaa
#define TEGRA_SMC_PMC_WRITE 0xbb
+struct pmc_clk_mux {
+ struct clk_hw hw;
+ unsigned long offs;
+ u32 mask;
+ u32 shift;
+ /* register lock */
+ spinlock_t *lock;
+};
+
+#define to_pmc_clk_mux(_hw) container_of(_hw, struct pmc_clk_mux, hw)
+
+struct pmc_clk_gate {
+ struct clk_hw hw;
+ unsigned long offs;
+ u32 shift;
+ /* register lock */
+ spinlock_t *lock;
+};
+
+#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
+
+struct pmc_clk_init_data {
+ char *mux_name;
+ char *gate_name;
+ const char **parents;
+ int num_parents;
+ int mux_id;
+ int gate_id;
+ char *dev_name;
+ u8 mux_shift;
+ u8 gate_shift;
+ u8 init_parent;
+ int init_state;
+ struct pmc_clk_mux mux;
+ struct pmc_clk_gate gate;
+};
+
+#define PMC_CLK(_num, _mux_shift, _gate_shift, _init_parent, _init_state)\
+ {\
+ .mux_name = "clk_out_" #_num "_mux",\
+ .gate_name = "clk_out_" #_num,\
+ .parents = clk_out ##_num ##_parents,\
+ .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\
+ .mux_id = TEGRA_PMC_CLK_OUT_ ##_num ##_MUX,\
+ .gate_id = TEGRA_PMC_CLK_OUT_ ##_num,\
+ .dev_name = "extern" #_num,\
+ .mux_shift = _mux_shift,\
+ .gate_shift = _gate_shift,\
+ .init_parent = _init_parent,\
+ .init_state = _init_state,\
+ }
+
+static DEFINE_SPINLOCK(clk_out_lock);
+
+static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
+ "clk_m_div4", "extern1",
+};
+
+static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
+ "clk_m_div4", "extern2",
+};
+
+static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
+ "clk_m_div4", "extern3",
+};
+
+static struct pmc_clk_init_data tegra_pmc_clks_data[] = {
+ PMC_CLK(1, 6, 2, 3, 1),
+ PMC_CLK(2, 14, 10, 0, 0),
+ PMC_CLK(3, 22, 18, 0, 0),
+};
+
struct tegra_powergate {
struct generic_pm_domain genpd;
struct tegra_pmc *pmc;
@@ -279,6 +356,9 @@ struct tegra_pmc_soc {
*/
const struct tegra_wake_event *wake_events;
unsigned int num_wake_events;
+
+ struct pmc_clk_init_data *pmc_clks_data;
+ unsigned int num_pmc_clks;
};
static const char * const tegra186_reset_sources[] = {
@@ -2299,6 +2379,241 @@ static int tegra_pmc_clk_notify_cb(struct notifier_block *nb,
return NOTIFY_OK;
}
+static void pmc_clk_fence_udelay(u32 offset)
+{
+ tegra_pmc_readl(pmc, offset);
+ /* pmc clk propagation delay 2 us */
+ udelay(2);
+}
+
+static u8 pmc_clk_mux_get_parent(struct clk_hw *hw)
+{
+ struct pmc_clk_mux *mux = to_pmc_clk_mux(hw);
+ int num_parents = clk_hw_get_num_parents(hw);
+ u32 val;
+
+ val = tegra_pmc_readl(pmc, mux->offs) >> mux->shift;
+ val &= mux->mask;
+
+ if (val >= num_parents)
+ return -EINVAL;
+
+ return val;
+}
+
+static int pmc_clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct pmc_clk_mux *mux = to_pmc_clk_mux(hw);
+ u32 val;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(mux->lock, flags);
+
+ val = tegra_pmc_readl(pmc, mux->offs);
+ val &= ~(mux->mask << mux->shift);
+ val |= index << mux->shift;
+ tegra_pmc_writel(pmc, val, mux->offs);
+ pmc_clk_fence_udelay(mux->offs);
+
+ spin_unlock_irqrestore(mux->lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops pmc_clk_mux_ops = {
+ .get_parent = pmc_clk_mux_get_parent,
+ .set_parent = pmc_clk_mux_set_parent,
+ .determine_rate = __clk_mux_determine_rate,
+};
+
+static struct clk *
+tegra_pmc_clk_mux_register(const char *name, const char * const *parent_names,
+ int num_parents, unsigned long flags,
+ struct pmc_clk_mux *mux, unsigned long offset,
+ u32 shift, u32 mask, spinlock_t *lock)
+{
+ struct clk_init_data init;
+
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &pmc_clk_mux_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = flags;
+
+ mux->hw.init = &init;
+ mux->offs = offset;
+ mux->mask = mask;
+ mux->shift = shift;
+ mux->lock = lock;
+
+ return clk_register(NULL, &mux->hw);
+}
+
+static int pmc_clk_is_enabled(struct clk_hw *hw)
+{
+ struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
+
+ return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0;
+}
+
+static void pmc_clk_set_state(struct clk_hw *hw, int state)
+{
+ struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
+ u32 val;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(gate->lock, flags);
+
+ val = tegra_pmc_readl(pmc, gate->offs);
+ val = state ? (val | BIT(gate->shift)) : (val & ~BIT(gate->shift));
+ tegra_pmc_writel(pmc, val, gate->offs);
+ pmc_clk_fence_udelay(gate->offs);
+
+ spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int pmc_clk_enable(struct clk_hw *hw)
+{
+ pmc_clk_set_state(hw, 1);
+
+ return 0;
+}
+
+static void pmc_clk_disable(struct clk_hw *hw)
+{
+ pmc_clk_set_state(hw, 0);
+}
+
+static const struct clk_ops pmc_clk_gate_ops = {
+ .is_enabled = pmc_clk_is_enabled,
+ .enable = pmc_clk_enable,
+ .disable = pmc_clk_disable,
+};
+
+static struct clk *
+tegra_pmc_clk_gate_register(const char *name, const char *parent_name,
+ unsigned long flags, struct pmc_clk_gate *gate,
+ unsigned long offset, u32 shift, spinlock_t *lock)
+{
+ struct clk_init_data init;
+
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &pmc_clk_gate_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.flags = flags;
+
+ gate->hw.init = &init;
+ gate->offs = offset;
+ gate->shift = shift;
+ gate->lock = lock;
+
+ return clk_register(NULL, &gate->hw);
+}
+
+static void tegra_pmc_clock_register(struct tegra_pmc *pmc,
+ struct device_node *np)
+{
+ struct clk *clkmux, *clkgate, *parent;
+ struct clk_onecell_data *clk_data;
+ unsigned int num_clks;
+ int i, ret = 0;
+
+ /* each pmc clock output has a mux and a gate */
+ num_clks = pmc->soc->num_pmc_clks * 2;
+
+ if (!num_clks)
+ return;
+
+ clk_data = kmalloc(sizeof(*clk_data), GFP_KERNEL);
+ if (!clk_data)
+ return;
+
+ clk_data->clks = kcalloc(num_clks, sizeof(*clk_data->clks),
+ GFP_KERNEL);
+ if (!clk_data->clks)
+ goto free_clkdata;
+
+ clk_data->clk_num = num_clks;
+
+ for (i = 0; i < pmc->soc->num_pmc_clks; i++) {
+ struct pmc_clk_init_data *data;
+
+ data = pmc->soc->pmc_clks_data + i;
+
+ clkmux = tegra_pmc_clk_mux_register(data->mux_name,
+ data->parents,
+ data->num_parents,
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_SET_RATE_PARENT,
+ &data->mux,
+ PMC_CLK_OUT_CNTRL,
+ data->mux_shift,
+ 3, &clk_out_lock);
+ if (IS_ERR(clkmux))
+ goto free_clks;
+
+ clk_data->clks[data->mux_id] = clkmux;
+
+ clkgate = tegra_pmc_clk_gate_register(data->gate_name,
+ data->mux_name,
+ CLK_SET_RATE_PARENT,
+ &data->gate,
+ PMC_CLK_OUT_CNTRL,
+ data->gate_shift,
+ &clk_out_lock);
+ if (IS_ERR(clkgate))
+ goto free_clks;
+
+ clk_data->clks[data->gate_id] = clkgate;
+
+ ret = clk_set_parent(clkgate, clkmux);
+ if (ret < 0) {
+ pr_err("%s: Failed to set parent of %s to %s\n",
+ __func__, __clk_get_name(clkgate),
+ __clk_get_name(clkmux));
+ }
+
+ clk_register_clkdev(clkgate, data->dev_name, data->gate_name);
+
+ /* configure initial clock parent and state */
+ parent = clk_get_sys(data->gate_name,
+ data->parents[data->init_parent]);
+ ret = clk_set_parent(clkmux, parent);
+ if (ret < 0) {
+ pr_err("%s: Failed to set parent of %s to %s\n",
+ __func__, __clk_get_name(clkmux),
+ __clk_get_name(parent));
+ WARN_ON(1);
+ }
+
+ if (data->init_state) {
+ if (clk_prepare_enable(clkgate)) {
+ pr_err("%s: Failed to enable %s\n", __func__,
+ __clk_get_name(clkgate));
+ WARN_ON(1);
+ }
+ }
+ }
+
+ of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+
+ return;
+
+free_clks:
+ kfree(clk_data->clks);
+free_clkdata:
+ kfree(clk_data);
+}
+
static int tegra_pmc_probe(struct platform_device *pdev)
{
void __iomem *base;
@@ -2417,6 +2732,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
pmc->base = base;
mutex_unlock(&pmc->powergates_lock);
+ tegra_pmc_clock_register(pmc, pdev->dev.of_node);
platform_set_drvdata(pdev, pmc);
return 0;
@@ -2625,6 +2941,8 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.num_reset_sources = 0,
.reset_levels = NULL,
.num_reset_levels = 0,
+ .pmc_clks_data = NULL,
+ .num_pmc_clks = 0,
};
static const char * const tegra30_powergates[] = {
@@ -2673,6 +2991,8 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
.reset_levels = NULL,
.num_reset_levels = 0,
+ .pmc_clks_data = tegra_pmc_clks_data,
+ .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
};
static const char * const tegra114_powergates[] = {
@@ -2725,6 +3045,8 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
.reset_levels = NULL,
.num_reset_levels = 0,
+ .pmc_clks_data = tegra_pmc_clks_data,
+ .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
};
static const char * const tegra124_powergates[] = {
@@ -2837,6 +3159,8 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.num_reset_sources = ARRAY_SIZE(tegra30_reset_sources),
.reset_levels = NULL,
.num_reset_levels = 0,
+ .pmc_clks_data = tegra_pmc_clks_data,
+ .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
};
static const char * const tegra210_powergates[] = {
@@ -2952,6 +3276,8 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
.num_reset_levels = 0,
.num_wake_events = ARRAY_SIZE(tegra210_wake_events),
.wake_events = tegra210_wake_events,
+ .pmc_clks_data = tegra_pmc_clks_data,
+ .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
};
#define TEGRA186_IO_PAD_TABLE(_pad) \
@@ -3091,6 +3417,8 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
.num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
.num_wake_events = ARRAY_SIZE(tegra186_wake_events),
.wake_events = tegra186_wake_events,
+ .pmc_clks_data = tegra_pmc_clks_data,
+ .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
};
static const struct tegra_io_pad_soc tegra194_io_pads[] = {
@@ -3166,6 +3494,8 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
.num_wake_events = ARRAY_SIZE(tegra194_wake_events),
.wake_events = tegra194_wake_events,
+ .pmc_clks_data = tegra_pmc_clks_data,
+ .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
};
static const struct of_device_id tegra_pmc_match[] = {
--
2.7.4
19.11.2019 09:50, Sowjanya Komatineni пишет:
> Tegra PMC has an option to override the CAR PLLM configuration during
> the warmboot.
>
> PLLM dividers and enable overrides from Tegra PMC are applicable only
> when PLLM_OVERRIDE bit in PMC_PLLP_WB0_OVERRIDE register is set by Tegra
> the bootloader. During warmboot based on this override enable, PLLM
> divider and enable configuration from overrides in PMC or from CAR
> module are used.
>
> Currently PLLM overrides in Tegra PMC are directly programmed by the Tegra
> clock driver and with this when PMC is in secure mode, any direct PMC
> register access from non-secure world will not go through.
>
> This patch adds helper functions for use by the Tegra clock driver to
> configure these PLLM overrides during PLLM clock rate and state changes.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>
> ---
> drivers/soc/tegra/pmc.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++-
> include/soc/tegra/pmc.h | 5 ++
> 2 files changed, 205 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
> index 8db63cfba833..224e7cf8dc00 100644
> --- a/drivers/soc/tegra/pmc.c
> +++ b/drivers/soc/tegra/pmc.c
> @@ -79,6 +79,14 @@
>
> #define PMC_PWR_DET 0x48
>
> +#define TEGRA186_PMC_PLLP_WB0_OVERRIDE 0x4c
> +#define PMC_PLLP_WB0_OVERRIDE 0xf8
> +#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE BIT(12)
> +#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE BIT(11)
> +
> +#define TEGRA186_PMC_PLLM_WB0_OVERRIDE_FREQ 0x50
> +#define TEGRA186_PMC_PLLM_WB0_OVERRIDE_2 0x54
> +
> #define PMC_SCRATCH0_MODE_RECOVERY BIT(31)
> #define PMC_SCRATCH0_MODE_BOOTLOADER BIT(30)
> #define PMC_SCRATCH0_MODE_RCM BIT(1)
> @@ -122,6 +130,9 @@
> #define IO_DPD2_STATUS 0x1c4
> #define SEL_DPD_TIM 0x1c8
>
> +#define PMC_PLLM_WB0_OVERRIDE_FREQ 0x1dc
> +#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
> +
> #define PMC_SCRATCH54 0x258
> #define PMC_SCRATCH54_DATA_SHIFT 8
> #define PMC_SCRATCH54_ADDR_SHIFT 0
> @@ -182,6 +193,15 @@ struct tegra_pmc_regs {
> unsigned int rst_source_mask;
> unsigned int rst_level_shift;
> unsigned int rst_level_mask;
> + unsigned int pllp_wb0_override;
> + unsigned int pllm_wb0_override_freq;
> + unsigned int pllm_wb0_override_2;
> + unsigned int override_divm_shift;
> + unsigned int override_divm_mask;
> + unsigned int override_divn_shift;
> + unsigned int override_divn_mask;
> + unsigned int override_divp_shift;
> + unsigned int override_divp_mask;
> };
>
> struct tegra_wake_event {
> @@ -227,6 +247,7 @@ struct tegra_pmc_soc {
> bool needs_mbist_war;
> bool has_impl_33v_pwr;
> bool maybe_tz_only;
> + bool has_pllm_wb0_override;
>
> const struct tegra_io_pad_soc *io_pads;
> unsigned int num_io_pads;
> @@ -1156,6 +1177,99 @@ static void tegra_powergate_remove_all(struct device_node *parent)
> of_node_put(np);
> }
>
> +bool tegra_pmc_is_pllm_wb0_override_enabled(void)
> +{
> + u32 val;
> +
> + if (pmc->soc->has_pllm_wb0_override) {
> + val = tegra_pmc_readl(pmc, pmc->soc->regs->pllp_wb0_override);
> + return (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) ? 1 : 0;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(tegra_pmc_is_pllm_wb0_override_enabled);
> +
> +bool tegra_pmc_is_pllm_wb0_enabled(void)
> +{
> + u32 val;
> +
> + if (pmc->soc->has_pllm_wb0_override) {
> + val = tegra_pmc_readl(pmc, pmc->soc->regs->pllp_wb0_override);
> + return (val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE) ? 1 : 0;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(tegra_pmc_is_pllm_wb0_enabled);
> +
> +void tegra_pmc_set_pllm_wb0_enable(bool enable)
> +{
> + u32 val;
> +
> + if (pmc->soc->has_pllm_wb0_override) {
> + val = tegra_pmc_readl(pmc, pmc->soc->regs->pllp_wb0_override);
> + if (enable)
> + val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
> + else
> + val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
> + tegra_pmc_writel(pmc, val, pmc->soc->regs->pllp_wb0_override);
> + }
> +}
> +EXPORT_SYMBOL(tegra_pmc_set_pllm_wb0_enable);
> +
> +void tegra_pmc_get_pllm_wb0_mnp_overrides(u32 *divm, u32 *divn, u8 *divp)
> +{
> + u32 val;
> + unsigned int divnm_reg, divp_reg;
> +
> + if (pmc->soc->has_pllm_wb0_override) {
> + divnm_reg = pmc->soc->regs->pllm_wb0_override_freq;
> + divp_reg = pmc->soc->regs->pllm_wb0_override_2;
> +
> + if (tegra_pmc_is_pllm_wb0_override_enabled()) {
> + val = tegra_pmc_readl(pmc, divnm_reg);
> + *divm = (val >> pmc->soc->regs->override_divm_shift) &
> + pmc->soc->regs->override_divm_mask;
> + *divn = (val >> pmc->soc->regs->override_divn_shift) &
> + pmc->soc->regs->override_divn_mask;
> + val = tegra_pmc_readl(pmc, divp_reg);
> + *divp = (val >> pmc->soc->regs->override_divp_shift) &
> + pmc->soc->regs->override_divp_mask;
> + }
> + }
> +}
> +EXPORT_SYMBOL(tegra_pmc_get_pllm_wb0_mnp_overrides);
> +
> +void tegra_pmc_set_pllm_wb0_mnp_overrides(u32 divm, u32 divn, u8 divp)
> +{
> + u32 val;
> + unsigned int divnm_reg, divp_reg;
> +
> + if (pmc->soc->has_pllm_wb0_override) {
> + divnm_reg = pmc->soc->regs->pllm_wb0_override_freq;
> + divp_reg = pmc->soc->regs->pllm_wb0_override_2;
> +
> + if (tegra_pmc_is_pllm_wb0_override_enabled()) {
> + val = tegra_pmc_readl(pmc, divp_reg);
> + val &= ~(pmc->soc->regs->override_divp_mask <<
> + pmc->soc->regs->override_divp_shift);
> + val |= (divp << pmc->soc->regs->override_divp_shift);
> + tegra_pmc_writel(pmc, val, divp_reg);
> +
> + val = tegra_pmc_readl(pmc, divnm_reg);
> + val &= ~(pmc->soc->regs->override_divm_mask <<
> + pmc->soc->regs->override_divm_shift);
> + val |= divm << pmc->soc->regs->override_divm_shift;
> + val &= ~(pmc->soc->regs->override_divn_mask <<
> + pmc->soc->regs->override_divn_shift);
> + val |= divn << pmc->soc->regs->override_divn_shift;
> + tegra_pmc_writel(pmc, val, divnm_reg);
> + }
> + }
> +}
> +EXPORT_SYMBOL(tegra_pmc_set_pllm_wb0_mnp_overrides);
Hello Sowjanya,
The exporting isn't needed because both PMC and CaR drivers are
built-in. Same for the other patches.
[snip]
19.11.2019 09:50, Sowjanya Komatineni пишет:
> Tegra clock driver uses helper functions from Tegra PMC driver.
>
> This patch removes PMC base references from all clocks registration.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>
> ---
> drivers/clk/tegra/clk-pll.c | 60 ++++++++++++++------------------
> drivers/clk/tegra/clk-tegra-audio.c | 4 +--
> drivers/clk/tegra/clk-tegra-periph.c | 8 ++---
> drivers/clk/tegra/clk-tegra-super-gen4.c | 11 +++---
> drivers/clk/tegra/clk-tegra114.c | 33 ++++++++----------
> drivers/clk/tegra/clk-tegra124.c | 34 ++++++++----------
> drivers/clk/tegra/clk-tegra20.c | 6 ++--
> drivers/clk/tegra/clk-tegra210.c | 34 ++++++++----------
> drivers/clk/tegra/clk-tegra30.c | 19 +++++-----
> drivers/clk/tegra/clk.h | 37 ++++++++------------
> 10 files changed, 108 insertions(+), 138 deletions(-)
>
> diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
> index 4ae9e282e7be..6a9b4be8ef2a 100644
> --- a/drivers/clk/tegra/clk-pll.c
> +++ b/drivers/clk/tegra/clk-pll.c
> @@ -1801,7 +1801,7 @@ static void _clk_plle_tegra_init_parent(struct tegra_clk_pll *pll)
> #endif
>
> static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
> - void __iomem *pmc, struct tegra_clk_pll_params *pll_params,
> + struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock)
> {
> struct tegra_clk_pll *pll;
> @@ -1811,7 +1811,6 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
> return ERR_PTR(-ENOMEM);
>
> pll->clk_base = clk_base;
> - pll->pmc = pmc;
>
> pll->params = pll_params;
> pll->lock = lock;
> @@ -1852,8 +1851,8 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll,
> }
>
> struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
> - void __iomem *clk_base, void __iomem *pmc,
> - unsigned long flags, struct tegra_clk_pll_params *pll_params,
> + void __iomem *clk_base, unsigned long flags,
> + struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock)
> {
> struct tegra_clk_pll *pll;
> @@ -1861,7 +1860,7 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
>
> pll_params->flags |= TEGRA_PLL_BYPASS;
>
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -1883,8 +1882,8 @@ static struct div_nmp pll_e_nmp = {
> };
>
> struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
> - void __iomem *clk_base, void __iomem *pmc,
> - unsigned long flags, struct tegra_clk_pll_params *pll_params,
> + void __iomem *clk_base, unsigned long flags,
> + struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock)
> {
> struct tegra_clk_pll *pll;
> @@ -1895,7 +1894,7 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
> if (!pll_params->div_nmp)
> pll_params->div_nmp = &pll_e_nmp;
>
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -1916,7 +1915,7 @@ struct clk *tegra_clk_register_pllu(const char *name, const char *parent_name,
>
> pll_params->flags |= TEGRA_PLLU;
>
> - pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -1974,8 +1973,7 @@ static const struct clk_ops tegra_clk_pllu_tegra114_ops = {
> };
>
> struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
> - void __iomem *clk_base, void __iomem *pmc,
> - unsigned long flags,
> + void __iomem *clk_base, unsigned long flags,
> struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock)
> {
> @@ -2025,7 +2023,7 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
> }
> }
>
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2038,8 +2036,7 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
> }
>
> struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
> - void __iomem *clk_base, void __iomem *pmc,
> - unsigned long flags,
> + void __iomem *clk_base, unsigned long flags,
> struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock, unsigned long parent_rate)
> {
> @@ -2053,7 +2050,7 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
> pll_params->vco_min = pll_params->adjust_vco(pll_params,
> parent_rate);
>
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2087,8 +2084,7 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
> }
>
> struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
> - void __iomem *clk_base, void __iomem *pmc,
> - unsigned long flags,
> + void __iomem *clk_base, unsigned long flags,
> struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock)
> {
> @@ -2116,7 +2112,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
>
> pll_params->flags |= TEGRA_PLL_BYPASS;
> pll_params->flags |= TEGRA_PLLM;
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2129,8 +2125,7 @@ struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
> }
>
> struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
> - void __iomem *clk_base, void __iomem *pmc,
> - unsigned long flags,
> + void __iomem *clk_base, unsigned long flags,
> struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock)
> {
> @@ -2155,7 +2150,7 @@ struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
> pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
>
> pll_params->flags |= TEGRA_PLL_BYPASS;
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2211,7 +2206,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
> struct tegra_clk_pll *pll;
> struct clk *clk;
>
> - pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2236,7 +2231,7 @@ tegra_clk_register_pllu_tegra114(const char *name, const char *parent_name,
>
> pll_params->flags |= TEGRA_PLLU;
>
> - pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2282,7 +2277,7 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
> return ERR_PTR(-EINVAL);
> }
>
> - pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2344,7 +2339,7 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
> #if defined(CONFIG_ARCH_TEGRA_210_SOC)
> struct clk *tegra_clk_register_pllre_tegra210(const char *name,
> const char *parent_name, void __iomem *clk_base,
> - void __iomem *pmc, unsigned long flags,
> + unsigned long flags,
> struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock, unsigned long parent_rate)
> {
> @@ -2357,7 +2352,7 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name,
> pll_params->vco_min = pll_params->adjust_vco(pll_params,
> parent_rate);
>
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2526,7 +2521,7 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
> struct tegra_clk_pll *pll;
> struct clk *clk;
>
> - pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2542,7 +2537,7 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
>
> struct clk *tegra_clk_register_pllc_tegra210(const char *name,
> const char *parent_name, void __iomem *clk_base,
> - void __iomem *pmc, unsigned long flags,
> + unsigned long flags,
> struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock)
> {
> @@ -2570,7 +2565,7 @@ struct clk *tegra_clk_register_pllc_tegra210(const char *name,
> parent_rate);
>
> pll_params->flags |= TEGRA_PLL_BYPASS;
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2618,7 +2613,7 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name,
> parent_rate);
>
> pll_params->flags |= TEGRA_PLL_BYPASS;
> - pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> @@ -2632,8 +2627,7 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name,
> }
>
> struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name,
> - void __iomem *clk_base, void __iomem *pmc,
> - unsigned long flags,
> + void __iomem *clk_base, unsigned long flags,
> struct tegra_clk_pll_params *pll_params,
> spinlock_t *lock)
> {
> @@ -2661,7 +2655,7 @@ struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name,
>
> pll_params->flags |= TEGRA_PLL_BYPASS;
> pll_params->flags |= TEGRA_PLLMB;
> - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
> + pll = _tegra_init_pll(clk_base, pll_params, lock);
> if (IS_ERR(pll))
> return ERR_CAST(pll);
>
> diff --git a/drivers/clk/tegra/clk-tegra-audio.c b/drivers/clk/tegra/clk-tegra-audio.c
> index c99e34d69711..1c813a7b89e7 100644
> --- a/drivers/clk/tegra/clk-tegra-audio.c
> +++ b/drivers/clk/tegra/clk-tegra-audio.c
> @@ -161,7 +161,7 @@ static void __init tegra_audio_sync_clk_init(void __iomem *clk_base,
> }
>
> void __init tegra_audio_clk_init(void __iomem *clk_base,
> - void __iomem *pmc_base, struct tegra_clk *tegra_clks,
> + struct tegra_clk *tegra_clks,
> struct tegra_audio_clk_info *audio_info,
> unsigned int num_plls, unsigned long sync_max_rate)
> {
> @@ -181,7 +181,7 @@ void __init tegra_audio_clk_init(void __iomem *clk_base,
> dt_clk = tegra_lookup_dt_id(info->clk_id, tegra_clks);
> if (dt_clk) {
> clk = tegra_clk_register_pll(info->name, info->parent,
> - clk_base, pmc_base, 0, info->pll_params,
> + clk_base, 0, info->pll_params,
> NULL);
> *dt_clk = clk;
> }
> diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
> index 0d07c0ba49b6..e2979b972526 100644
> --- a/drivers/clk/tegra/clk-tegra-periph.c
> +++ b/drivers/clk/tegra/clk-tegra-periph.c
> @@ -936,7 +936,7 @@ static void __init div_clk_init(void __iomem *clk_base,
> }
> }
>
> -static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base,
> +static void __init init_pllp(void __iomem *clk_base,
> struct tegra_clk *tegra_clks,
> struct tegra_clk_pll_params *pll_params)
> {
> @@ -948,7 +948,7 @@ static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base,
> if (dt_clk) {
> /* PLLP */
> clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base,
> - pmc_base, 0, pll_params, NULL);
> + 0, pll_params, NULL);
> clk_register_clkdev(clk, "pll_p", NULL);
> *dt_clk = clk;
> }
> @@ -1020,10 +1020,10 @@ static void __init init_pllp(void __iomem *clk_base, void __iomem *pmc_base,
> }
>
> void __init tegra_periph_clk_init(void __iomem *clk_base,
> - void __iomem *pmc_base, struct tegra_clk *tegra_clks,
> + struct tegra_clk *tegra_clks,
> struct tegra_clk_pll_params *pll_params)
> {
> - init_pllp(clk_base, pmc_base, tegra_clks, pll_params);
> + init_pllp(clk_base, tegra_clks, pll_params);
> periph_clk_init(clk_base, tegra_clks);
> gate_clk_init(clk_base, tegra_clks);
> div_clk_init(clk_base, tegra_clks);
> diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
> index 5760c978bef7..26c9bc606228 100644
> --- a/drivers/clk/tegra/clk-tegra-super-gen4.c
> +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
> @@ -163,7 +163,6 @@ static void __init tegra_sclk_init(void __iomem *clk_base,
> }
>
> static void __init tegra_super_clk_init(void __iomem *clk_base,
> - void __iomem *pmc_base,
> struct tegra_clk *tegra_clks,
> struct tegra_clk_pll_params *params,
> const struct tegra_super_gen_info *gen_info)
> @@ -231,11 +230,11 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
> #if defined(CONFIG_ARCH_TEGRA_210_SOC)
> if (gen_info->gen == gen5)
> clk = tegra_clk_register_pllc_tegra210("pll_x", "pll_ref",
> - clk_base, pmc_base, CLK_IGNORE_UNUSED, params, NULL);
> + clk_base, CLK_IGNORE_UNUSED, params, NULL);
> else
> #endif
> clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base,
> - pmc_base, CLK_IGNORE_UNUSED, params, NULL);
> + CLK_IGNORE_UNUSED, params, NULL);
>
> *dt_clk = clk;
>
> @@ -251,19 +250,17 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
> }
>
> void __init tegra_super_clk_gen4_init(void __iomem *clk_base,
> - void __iomem *pmc_base,
> struct tegra_clk *tegra_clks,
> struct tegra_clk_pll_params *params)
> {
> - tegra_super_clk_init(clk_base, pmc_base, tegra_clks, params,
> + tegra_super_clk_init(clk_base, tegra_clks, params,
> &tegra_super_gen_info_gen4);
> }
>
> void __init tegra_super_clk_gen5_init(void __iomem *clk_base,
> - void __iomem *pmc_base,
> struct tegra_clk *tegra_clks,
> struct tegra_clk_pll_params *params)
> {
> - tegra_super_clk_init(clk_base, pmc_base, tegra_clks, params,
> + tegra_super_clk_init(clk_base, tegra_clks, params,
> &tegra_super_gen_info_gen5);
> }
> diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
> index 77904334b6f0..e7c4af928da3 100644
> --- a/drivers/clk/tegra/clk-tegra114.c
> +++ b/drivers/clk/tegra/clk-tegra114.c
> @@ -904,14 +904,13 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base)
>
> }
>
> -static void __init tegra114_pll_init(void __iomem *clk_base,
> - void __iomem *pmc)
> +static void __init tegra114_pll_init(void __iomem *clk_base)
> {
> struct clk *clk;
>
> /* PLLC */
> clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base,
> - pmc, 0, &pll_c_params, NULL);
> + 0, &pll_c_params, NULL);
> clks[TEGRA114_CLK_PLL_C] = clk;
>
> /* PLLC_OUT1 */
> @@ -924,17 +923,17 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
> clks[TEGRA114_CLK_PLL_C_OUT1] = clk;
>
> /* PLLC2 */
> - clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0,
> + clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, 0,
> &pll_c2_params, NULL);
> clks[TEGRA114_CLK_PLL_C2] = clk;
>
> /* PLLC3 */
> - clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0,
> + clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, 0,
> &pll_c3_params, NULL);
> clks[TEGRA114_CLK_PLL_C3] = clk;
>
> /* PLLM */
> - clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
> + clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base,
> CLK_SET_RATE_GATE, &pll_m_params, NULL);
> clks[TEGRA114_CLK_PLL_M] = clk;
>
> @@ -978,7 +977,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
> clks[TEGRA114_CLK_PLL_U_12M] = clk;
>
> /* PLLD */
> - clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
> + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, 0,
> &pll_d_params, &pll_d_lock);
> clks[TEGRA114_CLK_PLL_D] = clk;
>
> @@ -988,7 +987,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
> clks[TEGRA114_CLK_PLL_D_OUT0] = clk;
>
> /* PLLD2 */
> - clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0,
> + clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, 0,
> &pll_d2_params, &pll_d2_lock);
> clks[TEGRA114_CLK_PLL_D2] = clk;
>
> @@ -998,7 +997,7 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
> clks[TEGRA114_CLK_PLL_D2_OUT0] = clk;
>
> /* PLLRE */
> - clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
> + clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base,
> 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq);
> clks[TEGRA114_CLK_PLL_RE_VCO] = clk;
>
> @@ -1019,8 +1018,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = {
> MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR),
> };
>
> -static __init void tegra114_periph_clk_init(void __iomem *clk_base,
> - void __iomem *pmc_base)
> +static __init void tegra114_periph_clk_init(void __iomem *clk_base)
> {
> struct clk *clk;
> struct tegra_periph_init_data *data;
> @@ -1075,8 +1073,7 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
> clks[data->clk_id] = clk;
> }
>
> - tegra_periph_clk_init(clk_base, pmc_base, tegra114_clks,
> - &pll_p_params);
> + tegra_periph_clk_init(clk_base, tegra114_clks, &pll_p_params);
> }
>
> /* Tegra114 CPU clock and reset control functions */
> @@ -1345,14 +1342,12 @@ static void __init tegra114_clock_init(struct device_node *np)
> return;
>
> tegra114_fixed_clk_init(clk_base);
> - tegra114_pll_init(clk_base, pmc_base);
> - tegra114_periph_clk_init(clk_base, pmc_base);
> - tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks,
> - tegra114_audio_plls,
> + tegra114_pll_init(clk_base);
> + tegra114_periph_clk_init(clk_base);
> + tegra_audio_clk_init(clk_base, tegra114_clks, tegra114_audio_plls,
> ARRAY_SIZE(tegra114_audio_plls), 24000000);
> tegra_pmc_clk_init(pmc_base, tegra114_clks);
> - tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
> - &pll_x_params);
> + tegra_super_clk_gen4_init(clk_base, tegra114_clks, &pll_x_params);
>
> tegra_add_of_provider(np, of_clk_src_onecell_get);
> tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
> diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
> index 010daac53ea7..0b7532857a58 100644
> --- a/drivers/clk/tegra/clk-tegra124.c
> +++ b/drivers/clk/tegra/clk-tegra124.c
> @@ -1019,8 +1019,7 @@ static struct tegra_periph_init_data tegra124_periph[] = {
>
> static struct clk **clks;
>
> -static __init void tegra124_periph_clk_init(void __iomem *clk_base,
> - void __iomem *pmc_base)
> +static __init void tegra124_periph_clk_init(void __iomem *clk_base)
> {
> struct clk *clk;
> unsigned int i;
> @@ -1078,17 +1077,16 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base,
> *clkp = clk;
> }
>
> - tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params);
> + tegra_periph_clk_init(clk_base, tegra124_clks, &pll_p_params);
> }
>
> -static void __init tegra124_pll_init(void __iomem *clk_base,
> - void __iomem *pmc)
> +static void __init tegra124_pll_init(void __iomem *clk_base)
> {
> struct clk *clk;
>
> /* PLLC */
> clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base,
> - pmc, 0, &pll_c_params, NULL);
> + 0, &pll_c_params, NULL);
> clk_register_clkdev(clk, "pll_c", NULL);
> clks[TEGRA124_CLK_PLL_C] = clk;
>
> @@ -1109,19 +1107,19 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
> clks[TEGRA124_CLK_PLL_C_UD] = clk;
>
> /* PLLC2 */
> - clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0,
> + clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, 0,
> &pll_c2_params, NULL);
> clk_register_clkdev(clk, "pll_c2", NULL);
> clks[TEGRA124_CLK_PLL_C2] = clk;
>
> /* PLLC3 */
> - clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0,
> + clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, 0,
> &pll_c3_params, NULL);
> clk_register_clkdev(clk, "pll_c3", NULL);
> clks[TEGRA124_CLK_PLL_C3] = clk;
>
> /* PLLM */
> - clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
> + clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base,
> CLK_SET_RATE_GATE, &pll_m_params, NULL);
> clk_register_clkdev(clk, "pll_m", NULL);
> clks[TEGRA124_CLK_PLL_M] = clk;
> @@ -1174,7 +1172,7 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
> clks[TEGRA124_CLK_PLL_U_12M] = clk;
>
> /* PLLD */
> - clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
> + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, 0,
> &pll_d_params, &pll_d_lock);
> clk_register_clkdev(clk, "pll_d", NULL);
> clks[TEGRA124_CLK_PLL_D] = clk;
> @@ -1186,7 +1184,7 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
> clks[TEGRA124_CLK_PLL_D_OUT0] = clk;
>
> /* PLLRE */
> - clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
> + clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base,
> 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq);
> clk_register_clkdev(clk, "pll_re_vco", NULL);
> clks[TEGRA124_CLK_PLL_RE_VCO] = clk;
> @@ -1491,10 +1489,9 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
> return;
>
> tegra_fixed_clk_init(tegra124_clks);
> - tegra124_pll_init(clk_base, pmc_base);
> - tegra124_periph_clk_init(clk_base, pmc_base);
> - tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks,
> - tegra124_audio_plls,
> + tegra124_pll_init(clk_base);
> + tegra124_periph_clk_init(clk_base);
> + tegra_audio_clk_init(clk_base, tegra124_clks, tegra124_audio_plls,
> ARRAY_SIZE(tegra124_audio_plls), 24576000);
> tegra_pmc_clk_init(pmc_base, tegra124_clks);
>
> @@ -1511,13 +1508,12 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
> * Register most of the along with a few clocks controlled by the PMC
> * IP block. Everything in this function should be common to Tegra124
> * and Tegra132. This function must be called after
> - * tegra124_132_clock_init_pre(), otherwise clk_base and pmc_base will
> - * not be set. No return value.
> + * tegra124_132_clock_init_pre(), otherwise clk_base will not be set.
> + * No return value.
> */
> static void __init tegra124_132_clock_init_post(struct device_node *np)
> {
> - tegra_super_clk_gen4_init(clk_base, pmc_base, tegra124_clks,
> - &pll_x_params);
> + tegra_super_clk_gen4_init(clk_base, tegra124_clks, &pll_x_params);
> tegra_init_special_resets(1, tegra124_reset_assert,
> tegra124_reset_deassert);
> tegra_add_of_provider(np, of_clk_src_onecell_get);
> diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
> index 4d8222f5c638..5cf33c99976d 100644
> --- a/drivers/clk/tegra/clk-tegra20.c
> +++ b/drivers/clk/tegra/clk-tegra20.c
> @@ -687,7 +687,7 @@ static void tegra20_pll_init(void)
> clks[TEGRA20_CLK_PLL_A_OUT0] = clk;
>
> /* PLLE */
> - clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base,
> + clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base,
> 0, &pll_e_params, NULL);
> clks[TEGRA20_CLK_PLL_E] = clk;
> }
> @@ -853,7 +853,7 @@ static void __init tegra20_periph_clk_init(void)
> clks[data->clk_id] = clk;
> }
>
> - tegra_periph_clk_init(clk_base, pmc_base, tegra20_clks, &pll_p_params);
> + tegra_periph_clk_init(clk_base, tegra20_clks, &pll_p_params);
> }
>
> static void __init tegra20_osc_clk_init(void)
> @@ -1145,7 +1145,7 @@ static void __init tegra20_clock_init(struct device_node *np)
> tegra_fixed_clk_init(tegra20_clks);
> tegra20_pll_init();
> tegra20_super_clk_init();
> - tegra_super_clk_gen4_init(clk_base, pmc_base, tegra20_clks, NULL);
> + tegra_super_clk_gen4_init(clk_base, tegra20_clks, NULL);
> tegra20_periph_clk_init();
> tegra20_audio_clk_init();
> tegra_pmc_clk_init(pmc_base, tegra20_clks);
> diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
> index 63f8a778821f..86d0b847be0d 100644
> --- a/drivers/clk/tegra/clk-tegra210.c
> +++ b/drivers/clk/tegra/clk-tegra210.c
> @@ -2993,8 +2993,7 @@ static const char * const la_parents[] = {
> static struct tegra_clk_periph tegra210_la =
> TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, 0);
>
> -static __init void tegra210_periph_clk_init(void __iomem *clk_base,
> - void __iomem *pmc_base)
> +static __init void tegra210_periph_clk_init(void __iomem *clk_base)
> {
> struct clk *clk;
> unsigned int i;
> @@ -3090,17 +3089,16 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
> *clkp = clk;
> }
>
> - tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params);
> + tegra_periph_clk_init(clk_base, tegra210_clks, &pll_p_params);
> }
>
> -static void __init tegra210_pll_init(void __iomem *clk_base,
> - void __iomem *pmc)
> +static void __init tegra210_pll_init(void __iomem *clk_base)
> {
> struct clk *clk;
>
> /* PLLC */
> clk = tegra_clk_register_pllc_tegra210("pll_c", "pll_ref", clk_base,
> - pmc, 0, &pll_c_params, NULL);
> + 0, &pll_c_params, NULL);
> if (!WARN_ON(IS_ERR(clk)))
> clk_register_clkdev(clk, "pll_c", NULL);
> clks[TEGRA210_CLK_PLL_C] = clk;
> @@ -3123,24 +3121,24 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
>
> /* PLLC2 */
> clk = tegra_clk_register_pllc_tegra210("pll_c2", "pll_ref", clk_base,
> - pmc, 0, &pll_c2_params, NULL);
> + 0, &pll_c2_params, NULL);
> clk_register_clkdev(clk, "pll_c2", NULL);
> clks[TEGRA210_CLK_PLL_C2] = clk;
>
> /* PLLC3 */
> clk = tegra_clk_register_pllc_tegra210("pll_c3", "pll_ref", clk_base,
> - pmc, 0, &pll_c3_params, NULL);
> + 0, &pll_c3_params, NULL);
> clk_register_clkdev(clk, "pll_c3", NULL);
> clks[TEGRA210_CLK_PLL_C3] = clk;
>
> /* PLLM */
> - clk = tegra_clk_register_pllm("pll_m", "osc", clk_base, pmc,
> + clk = tegra_clk_register_pllm("pll_m", "osc", clk_base,
> CLK_SET_RATE_GATE, &pll_m_params, NULL);
> clk_register_clkdev(clk, "pll_m", NULL);
> clks[TEGRA210_CLK_PLL_M] = clk;
>
> /* PLLMB */
> - clk = tegra_clk_register_pllmb("pll_mb", "osc", clk_base, pmc,
> + clk = tegra_clk_register_pllmb("pll_mb", "osc", clk_base,
> CLK_SET_RATE_GATE, &pll_mb_params, NULL);
> clk_register_clkdev(clk, "pll_mb", NULL);
> clks[TEGRA210_CLK_PLL_MB] = clk;
> @@ -3210,7 +3208,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
> clks[TEGRA210_CLK_PLL_U_48M] = clk;
>
> /* PLLD */
> - clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
> + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, 0,
> &pll_d_params, &pll_d_lock);
> clk_register_clkdev(clk, "pll_d", NULL);
> clks[TEGRA210_CLK_PLL_D] = clk;
> @@ -3223,7 +3221,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
>
> /* PLLRE */
> clk = tegra_clk_register_pllre_tegra210("pll_re_vco", "pll_ref",
> - clk_base, pmc, 0,
> + clk_base, 0,
> &pll_re_vco_params,
> &pll_re_lock, pll_ref_freq);
> clk_register_clkdev(clk, "pll_re_vco", NULL);
> @@ -3251,7 +3249,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
> clks[TEGRA210_CLK_PLL_E] = clk;
>
> /* PLLC4 */
> - clk = tegra_clk_register_pllre("pll_c4_vco", "pll_ref", clk_base, pmc,
> + clk = tegra_clk_register_pllre("pll_c4_vco", "pll_ref", clk_base,
> 0, &pll_c4_vco_params, NULL, pll_ref_freq);
> clk_register_clkdev(clk, "pll_c4_vco", NULL);
> clks[TEGRA210_CLK_PLL_C4] = clk;
> @@ -3680,10 +3678,9 @@ static void __init tegra210_clock_init(struct device_node *np)
> return;
>
> tegra_fixed_clk_init(tegra210_clks);
> - tegra210_pll_init(clk_base, pmc_base);
> - tegra210_periph_clk_init(clk_base, pmc_base);
> - tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks,
> - tegra210_audio_plls,
> + tegra210_pll_init(clk_base);
> + tegra210_periph_clk_init(clk_base);
> + tegra_audio_clk_init(clk_base, tegra210_clks, tegra210_audio_plls,
> ARRAY_SIZE(tegra210_audio_plls), 24576000);
> tegra_pmc_clk_init(pmc_base, tegra210_clks);
>
> @@ -3694,8 +3691,7 @@ static void __init tegra210_clock_init(struct device_node *np)
>
> tegra_clk_apply_init_table = tegra210_clock_apply_init_table;
>
> - tegra_super_clk_gen5_init(clk_base, pmc_base, tegra210_clks,
> - &pll_x_params);
> + tegra_super_clk_gen5_init(clk_base, tegra210_clks, &pll_x_params);
> tegra_init_special_resets(2, tegra210_reset_assert,
> tegra210_reset_deassert);
>
> diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
> index e3b64c66acdc..d65e7edf0cfd 100644
> --- a/drivers/clk/tegra/clk-tegra30.c
> +++ b/drivers/clk/tegra/clk-tegra30.c
> @@ -809,7 +809,7 @@ static void __init tegra30_pll_init(void)
> struct clk *clk;
>
> /* PLLC */
> - clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0,
> + clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, 0,
> &pll_c_params, NULL);
> clks[TEGRA30_CLK_PLL_C] = clk;
>
> @@ -823,7 +823,7 @@ static void __init tegra30_pll_init(void)
> clks[TEGRA30_CLK_PLL_C_OUT1] = clk;
>
> /* PLLM */
> - clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
> + clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base,
> CLK_SET_RATE_GATE, &pll_m_params, NULL);
> clks[TEGRA30_CLK_PLL_M] = clk;
>
> @@ -837,7 +837,7 @@ static void __init tegra30_pll_init(void)
> clks[TEGRA30_CLK_PLL_M_OUT1] = clk;
>
> /* PLLX */
> - clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, pmc_base, 0,
> + clk = tegra_clk_register_pll("pll_x", "pll_ref", clk_base, 0,
> &pll_x_params, NULL);
> clks[TEGRA30_CLK_PLL_X] = clk;
>
> @@ -852,7 +852,7 @@ static void __init tegra30_pll_init(void)
> clks[TEGRA30_CLK_PLL_U] = clk;
>
> /* PLLD */
> - clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc_base, 0,
> + clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, 0,
> &pll_d_params, &pll_d_lock);
> clks[TEGRA30_CLK_PLL_D] = clk;
>
> @@ -862,7 +862,7 @@ static void __init tegra30_pll_init(void)
> clks[TEGRA30_CLK_PLL_D_OUT0] = clk;
>
> /* PLLD2 */
> - clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0,
> + clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, 0,
> &pll_d2_params, NULL);
> clks[TEGRA30_CLK_PLL_D2] = clk;
Same needs to be done for clk-tegra20.c:
drivers/clk/tegra/clk-tegra20.c:627:61: note: in expansion of macro ‘NULL’
627 | clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, NULL, 0,
| ^~~~
In file included from drivers/clk/tegra/clk-tegra20.c:15:
drivers/clk/tegra/clk.h:392:13: note: expected ‘long unsigned int’ but
argument is of type ‘void *’
392 | struct clk *tegra_clk_register_pll(const char *name, const char
*parent_name,
| ^~~~~~~~~~~~~~~~~~~~~~
drivers/clk/tegra/clk-tegra20.c:628:8: error: passing argument 6 of
‘tegra_clk_register_pll’ from incompatible pointer type
[-Werror=incompatible-pointer-types]
628 | &pll_c_params, NULL);
>
> @@ -876,7 +876,7 @@ static void __init tegra30_pll_init(void)
> ARRAY_SIZE(pll_e_parents),
> CLK_SET_RATE_NO_REPARENT,
> clk_base + PLLE_AUX, 2, 1, 0, NULL);
> - clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base,
> + clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base
Comma is missed:
drivers/clk/tegra/clk-tegra30.c: In function ‘tegra30_pll_init’:
drivers/clk/tegra/clk-tegra30.c:872:54: error: called object ‘clk_base’
is not a function or function pointer
872 | clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base
[snip]
19.11.2019 09:50, Sowjanya Komatineni пишет:
> Current Tegra clock driver registers PMC clocks clk_out_1, clk_out_2,
> clk_out_3 and blink output in tegra_pmc_init() which does direct Tegra
> PMC access during clk_ops and these PMC register read and write access
> will not happen when PMC is in secure mode.
>
> Any direct PMC register access from non-secure world will not go
> through and all the PMC clocks and blink control are done in Tegra PMC
> driver with PMC as clock provider.
>
> This patch removes tegra_pmc_clk_init along with corresponding clk ids
> from Tegra clock driver.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>
> ---
> drivers/clk/tegra/Makefile | 1 -
> drivers/clk/tegra/clk-id.h | 7 -------
> drivers/clk/tegra/clk-tegra114.c | 33 ------------------------------
> drivers/clk/tegra/clk-tegra124.c | 44 +++++-----------------------------------
> drivers/clk/tegra/clk-tegra20.c | 24 ----------------------
> drivers/clk/tegra/clk-tegra210.c | 32 -----------------------------
> drivers/clk/tegra/clk-tegra30.c | 32 -----------------------------
> drivers/clk/tegra/clk.h | 1 -
> 8 files changed, 5 insertions(+), 169 deletions(-)
>
> diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
> index df966ca06788..1f7c30f87ece 100644
> --- a/drivers/clk/tegra/Makefile
> +++ b/drivers/clk/tegra/Makefile
> @@ -12,7 +12,6 @@ obj-y += clk-sdmmc-mux.o
> obj-y += clk-super.o
> obj-y += clk-tegra-audio.o
> obj-y += clk-tegra-periph.o
> -obj-y += clk-tegra-pmc.o
> obj-y += clk-tegra-fixed.o
> obj-y += clk-tegra-super-gen4.o
> obj-$(CONFIG_TEGRA_CLK_EMC) += clk-emc.o
Why clk-tegra-pmc.c itself isn't removed?
[snip]
19.11.2019 09:50, Sowjanya Komatineni пишет:
> Tegra PMC has clk_out_1, clk_out_2, clk_out_3 with mux and gate for
> each of these clocks.
>
> Currently these PMC clocks are registered by Tegra clock driver using
> clk_register_mux and clk_register_gate by passing PMC base address
> and register offsets and PMC programming for these clocks happens
> through direct PMC access by the clock driver.
>
> With this, when PMC is in secure mode any direct PMC access from the
> non-secure world does not go through and these clocks will not be
> functional.
>
> This patch adds these clocks registration with PMC as a clock provider
> for these clocks. clk_ops callback implementations for these clocks
> uses tegra_pmc_readl and tegra_pmc_writel which supports PMC programming
> in secure mode and non-secure mode.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>
> ---
> drivers/soc/tegra/pmc.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 330 insertions(+)
>
> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
> index 7a5aab0b993b..790a6619ba32 100644
> --- a/drivers/soc/tegra/pmc.c
> +++ b/drivers/soc/tegra/pmc.c
> @@ -13,6 +13,9 @@
>
> #include <linux/arm-smccc.h>
> #include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk/clk-conf.h>
> #include <linux/clk/tegra.h>
> #include <linux/debugfs.h>
> #include <linux/delay.h>
> @@ -48,6 +51,7 @@
> #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
> #include <dt-bindings/gpio/tegra186-gpio.h>
> #include <dt-bindings/gpio/tegra194-gpio.h>
> +#include <dt-bindings/soc/tegra-pmc.h>
>
> #define PMC_CNTRL 0x0
> #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
> @@ -108,6 +112,7 @@
> #define PMC_WAKE2_STATUS 0x168
> #define PMC_SW_WAKE2_STATUS 0x16c
>
> +#define PMC_CLK_OUT_CNTRL 0x1a8
> #define PMC_SATA_PWRGT 0x1ac
> #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
> #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
> @@ -170,6 +175,78 @@
> #define TEGRA_SMC_PMC_READ 0xaa
> #define TEGRA_SMC_PMC_WRITE 0xbb
>
> +struct pmc_clk_mux {
> + struct clk_hw hw;
> + unsigned long offs;
> + u32 mask;
> + u32 shift;
> + /* register lock */
> + spinlock_t *lock;
> +};
> +
> +#define to_pmc_clk_mux(_hw) container_of(_hw, struct pmc_clk_mux, hw)
> +
> +struct pmc_clk_gate {
> + struct clk_hw hw;
> + unsigned long offs;
> + u32 shift;
> + /* register lock */
> + spinlock_t *lock;
> +};
> +
> +#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
> +
> +struct pmc_clk_init_data {
> + char *mux_name;
> + char *gate_name;
> + const char **parents;
> + int num_parents;
> + int mux_id;
> + int gate_id;
> + char *dev_name;
> + u8 mux_shift;
> + u8 gate_shift;
> + u8 init_parent;
> + int init_state;
> + struct pmc_clk_mux mux;
> + struct pmc_clk_gate gate;
> +};
> +
> +#define PMC_CLK(_num, _mux_shift, _gate_shift, _init_parent, _init_state)\
> + {\
> + .mux_name = "clk_out_" #_num "_mux",\
> + .gate_name = "clk_out_" #_num,\
> + .parents = clk_out ##_num ##_parents,\
> + .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\
> + .mux_id = TEGRA_PMC_CLK_OUT_ ##_num ##_MUX,\
> + .gate_id = TEGRA_PMC_CLK_OUT_ ##_num,\
> + .dev_name = "extern" #_num,\
> + .mux_shift = _mux_shift,\
> + .gate_shift = _gate_shift,\
> + .init_parent = _init_parent,\
> + .init_state = _init_state,\
> + }
> +
> +static DEFINE_SPINLOCK(clk_out_lock);
> +
> +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
> + "clk_m_div4", "extern1",
> +};
> +
> +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
> + "clk_m_div4", "extern2",
> +};
> +
> +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
> + "clk_m_div4", "extern3",
> +};
Why these are unused?
> +static struct pmc_clk_init_data tegra_pmc_clks_data[] = {
> + PMC_CLK(1, 6, 2, 3, 1),
> + PMC_CLK(2, 14, 10, 0, 0),
> + PMC_CLK(3, 22, 18, 0, 0),
> +};
> +
> struct tegra_powergate {
> struct generic_pm_domain genpd;
> struct tegra_pmc *pmc;
> @@ -279,6 +356,9 @@ struct tegra_pmc_soc {
> */
> const struct tegra_wake_event *wake_events;
> unsigned int num_wake_events;
> +
> + struct pmc_clk_init_data *pmc_clks_data;
> + unsigned int num_pmc_clks;
> };
>
> static const char * const tegra186_reset_sources[] = {
> @@ -2299,6 +2379,241 @@ static int tegra_pmc_clk_notify_cb(struct notifier_block *nb,
> return NOTIFY_OK;
> }
>
> +static void pmc_clk_fence_udelay(u32 offset)
> +{
> + tegra_pmc_readl(pmc, offset);
> + /* pmc clk propagation delay 2 us */
> + udelay(2);
> +}
> +
> +static u8 pmc_clk_mux_get_parent(struct clk_hw *hw)
> +{
> + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw);
> + int num_parents = clk_hw_get_num_parents(hw);
> + u32 val;
> +
> + val = tegra_pmc_readl(pmc, mux->offs) >> mux->shift;
> + val &= mux->mask;
> +
> + if (val >= num_parents)
> + return -EINVAL;
> +
> + return val;
> +}
> +
> +static int pmc_clk_mux_set_parent(struct clk_hw *hw, u8 index)
> +{
> + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw);
> + u32 val;
> + unsigned long flags = 0;
> +
> + spin_lock_irqsave(mux->lock, flags);
> +
> + val = tegra_pmc_readl(pmc, mux->offs);
> + val &= ~(mux->mask << mux->shift);
> + val |= index << mux->shift;
> + tegra_pmc_writel(pmc, val, mux->offs);
> + pmc_clk_fence_udelay(mux->offs);
> +
> + spin_unlock_irqrestore(mux->lock, flags);
> +
> + return 0;
> +}
> +
> +static const struct clk_ops pmc_clk_mux_ops = {
> + .get_parent = pmc_clk_mux_get_parent,
> + .set_parent = pmc_clk_mux_set_parent,
> + .determine_rate = __clk_mux_determine_rate,
> +};
> +
> +static struct clk *
> +tegra_pmc_clk_mux_register(const char *name, const char * const *parent_names,
> + int num_parents, unsigned long flags,
> + struct pmc_clk_mux *mux, unsigned long offset,
> + u32 shift, u32 mask, spinlock_t *lock)
> +{
> + struct clk_init_data init;
> +
> + mux = kzalloc(sizeof(*mux), GFP_KERNEL);
> + if (!mux)
> + return ERR_PTR(-ENOMEM);
> +
> + init.name = name;
> + init.ops = &pmc_clk_mux_ops;
> + init.parent_names = parent_names;
> + init.num_parents = num_parents;
> + init.flags = flags;
> +
> + mux->hw.init = &init;
> + mux->offs = offset;
> + mux->mask = mask;
> + mux->shift = shift;
> + mux->lock = lock;
> +
> + return clk_register(NULL, &mux->hw);
> +}
> +
> +static int pmc_clk_is_enabled(struct clk_hw *hw)
> +{
> + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
> +
> + return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0;
> +}
> +
> +static void pmc_clk_set_state(struct clk_hw *hw, int state)
> +{
> + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
> + u32 val;
> + unsigned long flags = 0;
> +
> + spin_lock_irqsave(gate->lock, flags);
> +
> + val = tegra_pmc_readl(pmc, gate->offs);
> + val = state ? (val | BIT(gate->shift)) : (val & ~BIT(gate->shift));
> + tegra_pmc_writel(pmc, val, gate->offs);
> + pmc_clk_fence_udelay(gate->offs);
> +
> + spin_unlock_irqrestore(gate->lock, flags);
> +}
> +
> +static int pmc_clk_enable(struct clk_hw *hw)
> +{
> + pmc_clk_set_state(hw, 1);
> +
> + return 0;
> +}
> +
> +static void pmc_clk_disable(struct clk_hw *hw)
> +{
> + pmc_clk_set_state(hw, 0);
> +}
> +
> +static const struct clk_ops pmc_clk_gate_ops = {
> + .is_enabled = pmc_clk_is_enabled,
> + .enable = pmc_clk_enable,
> + .disable = pmc_clk_disable,
> +};
> +
> +static struct clk *
> +tegra_pmc_clk_gate_register(const char *name, const char *parent_name,
> + unsigned long flags, struct pmc_clk_gate *gate,
> + unsigned long offset, u32 shift, spinlock_t *lock)
> +{
> + struct clk_init_data init;
> +
> + gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> + if (!gate)
> + return ERR_PTR(-ENOMEM);
Why *gate is a function argument?
> +
> + init.name = name;
> + init.ops = &pmc_clk_gate_ops;
> + init.parent_names = &parent_name;
> + init.num_parents = 1;
> + init.flags = flags;
> +
> + gate->hw.init = &init;
> + gate->offs = offset;
> + gate->shift = shift;
> + gate->lock = lock;
> +
> + return clk_register(NULL, &gate->hw);
> +}
[snip]
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 <[email protected]>
> ---
> 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]
19.11.2019 09:50, Sowjanya Komatineni пишет:
> Tegra pmc has 3 clocks clk_out_1, clk_out_2, clk_out_3 with mux and gate
> for each of these clocks as part of pmc and Tegra pmc is the clock provider
> for these clocks.
>
> This patch adds #clock-cells property with 1 clock specifier to
> the Tegra pmc node.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>
> ---
> arch/arm/boot/dts/tegra114.dtsi | 4 +++-
> arch/arm/boot/dts/tegra124.dtsi | 4 +++-
> arch/arm/boot/dts/tegra30.dtsi | 4 +++-
> 3 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
> index 0d7a6327e404..b8f12f24f314 100644
> --- a/arch/arm/boot/dts/tegra114.dtsi
> +++ b/arch/arm/boot/dts/tegra114.dtsi
> @@ -4,6 +4,7 @@
> #include <dt-bindings/memory/tegra114-mc.h>
> #include <dt-bindings/pinctrl/pinctrl-tegra.h>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/soc/tegra-pmc.h>
>
> / {
> compatible = "nvidia,tegra114";
> @@ -514,11 +515,12 @@
> status = "disabled";
> };
>
> - pmc@7000e400 {
> + pmc: pmc@7000e400 {
> compatible = "nvidia,tegra114-pmc";
> reg = <0x7000e400 0x400>;
> clocks = <&tegra_car TEGRA114_CLK_PCLK>, <&clk32k_in>;
> clock-names = "pclk", "clk32k_in";
> + #clock-cells = <1>;
> };
>
> fuse@7000f800 {
> diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
> index 413bfb981de8..d0802c4ae3bf 100644
> --- a/arch/arm/boot/dts/tegra124.dtsi
> +++ b/arch/arm/boot/dts/tegra124.dtsi
> @@ -6,6 +6,7 @@
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> #include <dt-bindings/reset/tegra124-car.h>
> #include <dt-bindings/thermal/tegra124-soctherm.h>
> +#include <dt-bindings/soc/tegra-pmc.h>
>
> / {
> compatible = "nvidia,tegra124";
> @@ -595,11 +596,12 @@
> clocks = <&tegra_car TEGRA124_CLK_RTC>;
> };
>
> - pmc@7000e400 {
> + pmc: pmc@7000e400 {
> compatible = "nvidia,tegra124-pmc";
> reg = <0x0 0x7000e400 0x0 0x400>;
> clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>;
> clock-names = "pclk", "clk32k_in";
> + #clock-cells = <1>;
> };
>
> fuse@7000f800 {
> diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
> index 55ae050042ce..4d5e9d0001d3 100644
> --- a/arch/arm/boot/dts/tegra30.dtsi
> +++ b/arch/arm/boot/dts/tegra30.dtsi
> @@ -4,6 +4,7 @@
> #include <dt-bindings/memory/tegra30-mc.h>
> #include <dt-bindings/pinctrl/pinctrl-tegra.h>
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/soc/tegra-pmc.h>
>
> / {
> compatible = "nvidia,tegra30";
> @@ -714,11 +715,12 @@
> status = "disabled";
> };
>
> - pmc@7000e400 {
> + pmc: pmc@7000e400 {
> compatible = "nvidia,tegra30-pmc";
> reg = <0x7000e400 0x400>;
> clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>;
> clock-names = "pclk", "clk32k_in";
> + #clock-cells = <1>;
> };
>
> mc: memory-controller@7000f000 {
>
What about Tegra20?
On 11/19/19 11:33 AM, Dmitry Osipenko wrote:
> 19.11.2019 09:50, Sowjanya Komatineni пишет:
>> Tegra PMC has clk_out_1, clk_out_2, clk_out_3 with mux and gate for
>> each of these clocks.
>>
>> Currently these PMC clocks are registered by Tegra clock driver using
>> clk_register_mux and clk_register_gate by passing PMC base address
>> and register offsets and PMC programming for these clocks happens
>> through direct PMC access by the clock driver.
>>
>> With this, when PMC is in secure mode any direct PMC access from the
>> non-secure world does not go through and these clocks will not be
>> functional.
>>
>> This patch adds these clocks registration with PMC as a clock provider
>> for these clocks. clk_ops callback implementations for these clocks
>> uses tegra_pmc_readl and tegra_pmc_writel which supports PMC programming
>> in secure mode and non-secure mode.
>>
>> Signed-off-by: Sowjanya Komatineni <[email protected]>
>> ---
>> drivers/soc/tegra/pmc.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 330 insertions(+)
>>
>> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
>> index 7a5aab0b993b..790a6619ba32 100644
>> --- a/drivers/soc/tegra/pmc.c
>> +++ b/drivers/soc/tegra/pmc.c
>> @@ -13,6 +13,9 @@
>>
>> #include <linux/arm-smccc.h>
>> #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/clkdev.h>
>> +#include <linux/clk/clk-conf.h>
>> #include <linux/clk/tegra.h>
>> #include <linux/debugfs.h>
>> #include <linux/delay.h>
>> @@ -48,6 +51,7 @@
>> #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
>> #include <dt-bindings/gpio/tegra186-gpio.h>
>> #include <dt-bindings/gpio/tegra194-gpio.h>
>> +#include <dt-bindings/soc/tegra-pmc.h>
>>
>> #define PMC_CNTRL 0x0
>> #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR polarity */
>> @@ -108,6 +112,7 @@
>> #define PMC_WAKE2_STATUS 0x168
>> #define PMC_SW_WAKE2_STATUS 0x16c
>>
>> +#define PMC_CLK_OUT_CNTRL 0x1a8
>> #define PMC_SATA_PWRGT 0x1ac
>> #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
>> #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
>> @@ -170,6 +175,78 @@
>> #define TEGRA_SMC_PMC_READ 0xaa
>> #define TEGRA_SMC_PMC_WRITE 0xbb
>>
>> +struct pmc_clk_mux {
>> + struct clk_hw hw;
>> + unsigned long offs;
>> + u32 mask;
>> + u32 shift;
>> + /* register lock */
>> + spinlock_t *lock;
>> +};
>> +
>> +#define to_pmc_clk_mux(_hw) container_of(_hw, struct pmc_clk_mux, hw)
>> +
>> +struct pmc_clk_gate {
>> + struct clk_hw hw;
>> + unsigned long offs;
>> + u32 shift;
>> + /* register lock */
>> + spinlock_t *lock;
>> +};
>> +
>> +#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
>> +
>> +struct pmc_clk_init_data {
>> + char *mux_name;
>> + char *gate_name;
>> + const char **parents;
>> + int num_parents;
>> + int mux_id;
>> + int gate_id;
>> + char *dev_name;
>> + u8 mux_shift;
>> + u8 gate_shift;
>> + u8 init_parent;
>> + int init_state;
>> + struct pmc_clk_mux mux;
>> + struct pmc_clk_gate gate;
>> +};
>> +
>> +#define PMC_CLK(_num, _mux_shift, _gate_shift, _init_parent, _init_state)\
>> + {\
>> + .mux_name = "clk_out_" #_num "_mux",\
>> + .gate_name = "clk_out_" #_num,\
>> + .parents = clk_out ##_num ##_parents,\
>> + .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\
>> + .mux_id = TEGRA_PMC_CLK_OUT_ ##_num ##_MUX,\
>> + .gate_id = TEGRA_PMC_CLK_OUT_ ##_num,\
>> + .dev_name = "extern" #_num,\
>> + .mux_shift = _mux_shift,\
>> + .gate_shift = _gate_shift,\
>> + .init_parent = _init_parent,\
>> + .init_state = _init_state,\
>> + }
>> +
>> +static DEFINE_SPINLOCK(clk_out_lock);
>> +
>> +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
>> + "clk_m_div4", "extern1",
>> +};
>> +
>> +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
>> + "clk_m_div4", "extern2",
>> +};
>> +
>> +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
>> + "clk_m_div4", "extern3",
>> +};
> Why these are unused?
They are used in PMC_CLK macro
>
>> +static struct pmc_clk_init_data tegra_pmc_clks_data[] = {
>> + PMC_CLK(1, 6, 2, 3, 1),
>> + PMC_CLK(2, 14, 10, 0, 0),
>> + PMC_CLK(3, 22, 18, 0, 0),
>> +};
>> +
>> struct tegra_powergate {
>> struct generic_pm_domain genpd;
>> struct tegra_pmc *pmc;
>> @@ -279,6 +356,9 @@ struct tegra_pmc_soc {
>> */
>> const struct tegra_wake_event *wake_events;
>> unsigned int num_wake_events;
>> +
>> + struct pmc_clk_init_data *pmc_clks_data;
>> + unsigned int num_pmc_clks;
>> };
>>
>> static const char * const tegra186_reset_sources[] = {
>> @@ -2299,6 +2379,241 @@ static int tegra_pmc_clk_notify_cb(struct notifier_block *nb,
>> return NOTIFY_OK;
>> }
>>
>> +static void pmc_clk_fence_udelay(u32 offset)
>> +{
>> + tegra_pmc_readl(pmc, offset);
>> + /* pmc clk propagation delay 2 us */
>> + udelay(2);
>> +}
>> +
>> +static u8 pmc_clk_mux_get_parent(struct clk_hw *hw)
>> +{
>> + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw);
>> + int num_parents = clk_hw_get_num_parents(hw);
>> + u32 val;
>> +
>> + val = tegra_pmc_readl(pmc, mux->offs) >> mux->shift;
>> + val &= mux->mask;
>> +
>> + if (val >= num_parents)
>> + return -EINVAL;
>> +
>> + return val;
>> +}
>> +
>> +static int pmc_clk_mux_set_parent(struct clk_hw *hw, u8 index)
>> +{
>> + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw);
>> + u32 val;
>> + unsigned long flags = 0;
>> +
>> + spin_lock_irqsave(mux->lock, flags);
>> +
>> + val = tegra_pmc_readl(pmc, mux->offs);
>> + val &= ~(mux->mask << mux->shift);
>> + val |= index << mux->shift;
>> + tegra_pmc_writel(pmc, val, mux->offs);
>> + pmc_clk_fence_udelay(mux->offs);
>> +
>> + spin_unlock_irqrestore(mux->lock, flags);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct clk_ops pmc_clk_mux_ops = {
>> + .get_parent = pmc_clk_mux_get_parent,
>> + .set_parent = pmc_clk_mux_set_parent,
>> + .determine_rate = __clk_mux_determine_rate,
>> +};
>> +
>> +static struct clk *
>> +tegra_pmc_clk_mux_register(const char *name, const char * const *parent_names,
>> + int num_parents, unsigned long flags,
>> + struct pmc_clk_mux *mux, unsigned long offset,
>> + u32 shift, u32 mask, spinlock_t *lock)
>> +{
>> + struct clk_init_data init;
>> +
>> + mux = kzalloc(sizeof(*mux), GFP_KERNEL);
>> + if (!mux)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + init.name = name;
>> + init.ops = &pmc_clk_mux_ops;
>> + init.parent_names = parent_names;
>> + init.num_parents = num_parents;
>> + init.flags = flags;
>> +
>> + mux->hw.init = &init;
>> + mux->offs = offset;
>> + mux->mask = mask;
>> + mux->shift = shift;
>> + mux->lock = lock;
>> +
>> + return clk_register(NULL, &mux->hw);
>> +}
>> +
>> +static int pmc_clk_is_enabled(struct clk_hw *hw)
>> +{
>> + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
>> +
>> + return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0;
>> +}
>> +
>> +static void pmc_clk_set_state(struct clk_hw *hw, int state)
>> +{
>> + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
>> + u32 val;
>> + unsigned long flags = 0;
>> +
>> + spin_lock_irqsave(gate->lock, flags);
>> +
>> + val = tegra_pmc_readl(pmc, gate->offs);
>> + val = state ? (val | BIT(gate->shift)) : (val & ~BIT(gate->shift));
>> + tegra_pmc_writel(pmc, val, gate->offs);
>> + pmc_clk_fence_udelay(gate->offs);
>> +
>> + spin_unlock_irqrestore(gate->lock, flags);
>> +}
>> +
>> +static int pmc_clk_enable(struct clk_hw *hw)
>> +{
>> + pmc_clk_set_state(hw, 1);
>> +
>> + return 0;
>> +}
>> +
>> +static void pmc_clk_disable(struct clk_hw *hw)
>> +{
>> + pmc_clk_set_state(hw, 0);
>> +}
>> +
>> +static const struct clk_ops pmc_clk_gate_ops = {
>> + .is_enabled = pmc_clk_is_enabled,
>> + .enable = pmc_clk_enable,
>> + .disable = pmc_clk_disable,
>> +};
>> +
>> +static struct clk *
>> +tegra_pmc_clk_gate_register(const char *name, const char *parent_name,
>> + unsigned long flags, struct pmc_clk_gate *gate,
>> + unsigned long offset, u32 shift, spinlock_t *lock)
>> +{
>> + struct clk_init_data init;
>> +
>> + gate = kzalloc(sizeof(*gate), GFP_KERNEL);
>> + if (!gate)
>> + return ERR_PTR(-ENOMEM);
> Why *gate is a function argument?
for storing corresponding gate register info to use for gate clk_ops
>
>> +
>> + init.name = name;
>> + init.ops = &pmc_clk_gate_ops;
>> + init.parent_names = &parent_name;
>> + init.num_parents = 1;
>> + init.flags = flags;
>> +
>> + gate->hw.init = &init;
>> + gate->offs = offset;
>> + gate->shift = shift;
>> + gate->lock = lock;
>> +
>> + return clk_register(NULL, &gate->hw);
>> +}
> [snip]
On 11/19/19 12:08 PM, Sowjanya Komatineni wrote:
>
> On 11/19/19 11:33 AM, Dmitry Osipenko wrote:
>> 19.11.2019 09:50, Sowjanya Komatineni пишет:
>>> Tegra PMC has clk_out_1, clk_out_2, clk_out_3 with mux and gate for
>>> each of these clocks.
>>>
>>> Currently these PMC clocks are registered by Tegra clock driver using
>>> clk_register_mux and clk_register_gate by passing PMC base address
>>> and register offsets and PMC programming for these clocks happens
>>> through direct PMC access by the clock driver.
>>>
>>> With this, when PMC is in secure mode any direct PMC access from the
>>> non-secure world does not go through and these clocks will not be
>>> functional.
>>>
>>> This patch adds these clocks registration with PMC as a clock provider
>>> for these clocks. clk_ops callback implementations for these clocks
>>> uses tegra_pmc_readl and tegra_pmc_writel which supports PMC
>>> programming
>>> in secure mode and non-secure mode.
>>>
>>> Signed-off-by: Sowjanya Komatineni <[email protected]>
>>> ---
>>> drivers/soc/tegra/pmc.c | 330
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 330 insertions(+)
>>>
>>> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
>>> index 7a5aab0b993b..790a6619ba32 100644
>>> --- a/drivers/soc/tegra/pmc.c
>>> +++ b/drivers/soc/tegra/pmc.c
>>> @@ -13,6 +13,9 @@
>>> #include <linux/arm-smccc.h>
>>> #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/clkdev.h>
>>> +#include <linux/clk/clk-conf.h>
>>> #include <linux/clk/tegra.h>
>>> #include <linux/debugfs.h>
>>> #include <linux/delay.h>
>>> @@ -48,6 +51,7 @@
>>> #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
>>> #include <dt-bindings/gpio/tegra186-gpio.h>
>>> #include <dt-bindings/gpio/tegra194-gpio.h>
>>> +#include <dt-bindings/soc/tegra-pmc.h>
>>> #define PMC_CNTRL 0x0
>>> #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR
>>> polarity */
>>> @@ -108,6 +112,7 @@
>>> #define PMC_WAKE2_STATUS 0x168
>>> #define PMC_SW_WAKE2_STATUS 0x16c
>>> +#define PMC_CLK_OUT_CNTRL 0x1a8
>>> #define PMC_SATA_PWRGT 0x1ac
>>> #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
>>> #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
>>> @@ -170,6 +175,78 @@
>>> #define TEGRA_SMC_PMC_READ 0xaa
>>> #define TEGRA_SMC_PMC_WRITE 0xbb
>>> +struct pmc_clk_mux {
>>> + struct clk_hw hw;
>>> + unsigned long offs;
>>> + u32 mask;
>>> + u32 shift;
>>> + /* register lock */
>>> + spinlock_t *lock;
>>> +};
>>> +
>>> +#define to_pmc_clk_mux(_hw) container_of(_hw, struct pmc_clk_mux, hw)
>>> +
>>> +struct pmc_clk_gate {
>>> + struct clk_hw hw;
>>> + unsigned long offs;
>>> + u32 shift;
>>> + /* register lock */
>>> + spinlock_t *lock;
>>> +};
>>> +
>>> +#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate,
>>> hw)
>>> +
>>> +struct pmc_clk_init_data {
>>> + char *mux_name;
>>> + char *gate_name;
>>> + const char **parents;
>>> + int num_parents;
>>> + int mux_id;
>>> + int gate_id;
>>> + char *dev_name;
>>> + u8 mux_shift;
>>> + u8 gate_shift;
>>> + u8 init_parent;
>>> + int init_state;
>>> + struct pmc_clk_mux mux;
>>> + struct pmc_clk_gate gate;
>>> +};
>>> +
>>> +#define PMC_CLK(_num, _mux_shift, _gate_shift, _init_parent,
>>> _init_state)\
>>> + {\
>>> + .mux_name = "clk_out_" #_num "_mux",\
>>> + .gate_name = "clk_out_" #_num,\
>>> + .parents = clk_out ##_num ##_parents,\
>>> + .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\
>>> + .mux_id = TEGRA_PMC_CLK_OUT_ ##_num ##_MUX,\
>>> + .gate_id = TEGRA_PMC_CLK_OUT_ ##_num,\
>>> + .dev_name = "extern" #_num,\
>>> + .mux_shift = _mux_shift,\
>>> + .gate_shift = _gate_shift,\
>>> + .init_parent = _init_parent,\
>>> + .init_state = _init_state,\
>>> + }
>>> +
>>> +static DEFINE_SPINLOCK(clk_out_lock);
>>> +
>>> +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
>>> + "clk_m_div4", "extern1",
>>> +};
>>> +
>>> +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
>>> + "clk_m_div4", "extern2",
>>> +};
>>> +
>>> +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
>>> + "clk_m_div4", "extern3",
>>> +};
>> Why these are unused?
> They are used in PMC_CLK macro
>>
>>> +static struct pmc_clk_init_data tegra_pmc_clks_data[] = {
>>> + PMC_CLK(1, 6, 2, 3, 1),
>>> + PMC_CLK(2, 14, 10, 0, 0),
>>> + PMC_CLK(3, 22, 18, 0, 0),
>>> +};
>>> +
>>> struct tegra_powergate {
>>> struct generic_pm_domain genpd;
>>> struct tegra_pmc *pmc;
>>> @@ -279,6 +356,9 @@ struct tegra_pmc_soc {
>>> */
>>> const struct tegra_wake_event *wake_events;
>>> unsigned int num_wake_events;
>>> +
>>> + struct pmc_clk_init_data *pmc_clks_data;
>>> + unsigned int num_pmc_clks;
>>> };
>>> static const char * const tegra186_reset_sources[] = {
>>> @@ -2299,6 +2379,241 @@ static int tegra_pmc_clk_notify_cb(struct
>>> notifier_block *nb,
>>> return NOTIFY_OK;
>>> }
>>> +static void pmc_clk_fence_udelay(u32 offset)
>>> +{
>>> + tegra_pmc_readl(pmc, offset);
>>> + /* pmc clk propagation delay 2 us */
>>> + udelay(2);
>>> +}
>>> +
>>> +static u8 pmc_clk_mux_get_parent(struct clk_hw *hw)
>>> +{
>>> + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw);
>>> + int num_parents = clk_hw_get_num_parents(hw);
>>> + u32 val;
>>> +
>>> + val = tegra_pmc_readl(pmc, mux->offs) >> mux->shift;
>>> + val &= mux->mask;
>>> +
>>> + if (val >= num_parents)
>>> + return -EINVAL;
>>> +
>>> + return val;
>>> +}
>>> +
>>> +static int pmc_clk_mux_set_parent(struct clk_hw *hw, u8 index)
>>> +{
>>> + struct pmc_clk_mux *mux = to_pmc_clk_mux(hw);
>>> + u32 val;
>>> + unsigned long flags = 0;
>>> +
>>> + spin_lock_irqsave(mux->lock, flags);
>>> +
>>> + val = tegra_pmc_readl(pmc, mux->offs);
>>> + val &= ~(mux->mask << mux->shift);
>>> + val |= index << mux->shift;
>>> + tegra_pmc_writel(pmc, val, mux->offs);
>>> + pmc_clk_fence_udelay(mux->offs);
>>> +
>>> + spin_unlock_irqrestore(mux->lock, flags);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static const struct clk_ops pmc_clk_mux_ops = {
>>> + .get_parent = pmc_clk_mux_get_parent,
>>> + .set_parent = pmc_clk_mux_set_parent,
>>> + .determine_rate = __clk_mux_determine_rate,
>>> +};
>>> +
>>> +static struct clk *
>>> +tegra_pmc_clk_mux_register(const char *name, const char * const
>>> *parent_names,
>>> + int num_parents, unsigned long flags,
>>> + struct pmc_clk_mux *mux, unsigned long offset,
>>> + u32 shift, u32 mask, spinlock_t *lock)
>>> +{
>>> + struct clk_init_data init;
>>> +
>>> + mux = kzalloc(sizeof(*mux), GFP_KERNEL);
>>> + if (!mux)
>>> + return ERR_PTR(-ENOMEM);
>>> +
>>> + init.name = name;
>>> + init.ops = &pmc_clk_mux_ops;
>>> + init.parent_names = parent_names;
>>> + init.num_parents = num_parents;
>>> + init.flags = flags;
>>> +
>>> + mux->hw.init = &init;
>>> + mux->offs = offset;
>>> + mux->mask = mask;
>>> + mux->shift = shift;
>>> + mux->lock = lock;
>>> +
>>> + return clk_register(NULL, &mux->hw);
>>> +}
>>> +
>>> +static int pmc_clk_is_enabled(struct clk_hw *hw)
>>> +{
>>> + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
>>> +
>>> + return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1
>>> : 0;
>>> +}
>>> +
>>> +static void pmc_clk_set_state(struct clk_hw *hw, int state)
>>> +{
>>> + struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
>>> + u32 val;
>>> + unsigned long flags = 0;
>>> +
>>> + spin_lock_irqsave(gate->lock, flags);
>>> +
>>> + val = tegra_pmc_readl(pmc, gate->offs);
>>> + val = state ? (val | BIT(gate->shift)) : (val &
>>> ~BIT(gate->shift));
>>> + tegra_pmc_writel(pmc, val, gate->offs);
>>> + pmc_clk_fence_udelay(gate->offs);
>>> +
>>> + spin_unlock_irqrestore(gate->lock, flags);
>>> +}
>>> +
>>> +static int pmc_clk_enable(struct clk_hw *hw)
>>> +{
>>> + pmc_clk_set_state(hw, 1);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static void pmc_clk_disable(struct clk_hw *hw)
>>> +{
>>> + pmc_clk_set_state(hw, 0);
>>> +}
>>> +
>>> +static const struct clk_ops pmc_clk_gate_ops = {
>>> + .is_enabled = pmc_clk_is_enabled,
>>> + .enable = pmc_clk_enable,
>>> + .disable = pmc_clk_disable,
>>> +};
>>> +
>>> +static struct clk *
>>> +tegra_pmc_clk_gate_register(const char *name, const char *parent_name,
>>> + unsigned long flags, struct pmc_clk_gate *gate,
>>> + unsigned long offset, u32 shift, spinlock_t *lock)
>>> +{
>>> + struct clk_init_data init;
>>> +
>>> + gate = kzalloc(sizeof(*gate), GFP_KERNEL);
>>> + if (!gate)
>>> + return ERR_PTR(-ENOMEM);
>> Why *gate is a function argument?
> for storing corresponding gate register info to use for gate clk_ops
I had gate and mux as members of pmc_clk_init_data.
Actually we don't need that so will remove it and also passing argument
in next version
>>
>>> +
>>> + init.name = name;
>>> + init.ops = &pmc_clk_gate_ops;
>>> + init.parent_names = &parent_name;
>>> + init.num_parents = 1;
>>> + init.flags = flags;
>>> +
>>> + gate->hw.init = &init;
>>> + gate->offs = offset;
>>> + gate->shift = shift;
>>> + gate->lock = lock;
>>> +
>>> + return clk_register(NULL, &gate->hw);
>>> +}
>> [snip]
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 <[email protected]>
>> ---
>> 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.
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 <[email protected]>
>>> ---
>>> 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?
On 11/19/19 6:09 PM, Sowjanya Komatineni wrote:
>
> 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 <[email protected]>
>>>> ---
>>>> 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?
>
>
I think using CLK_OF_DECLARE_DRIVER and add clock driver probe for
registering PLLM related clocks should work as by them both initial
clock inits and pmc early init happens and then during clock driver
probe PLLM gets registered.
19.11.2019 23:08, Sowjanya Komatineni пишет:
>
> On 11/19/19 11:33 AM, Dmitry Osipenko wrote:
>> 19.11.2019 09:50, Sowjanya Komatineni пишет:
>>> Tegra PMC has clk_out_1, clk_out_2, clk_out_3 with mux and gate for
>>> each of these clocks.
>>>
>>> Currently these PMC clocks are registered by Tegra clock driver using
>>> clk_register_mux and clk_register_gate by passing PMC base address
>>> and register offsets and PMC programming for these clocks happens
>>> through direct PMC access by the clock driver.
>>>
>>> With this, when PMC is in secure mode any direct PMC access from the
>>> non-secure world does not go through and these clocks will not be
>>> functional.
>>>
>>> This patch adds these clocks registration with PMC as a clock provider
>>> for these clocks. clk_ops callback implementations for these clocks
>>> uses tegra_pmc_readl and tegra_pmc_writel which supports PMC programming
>>> in secure mode and non-secure mode.
>>>
>>> Signed-off-by: Sowjanya Komatineni <[email protected]>
>>> ---
>>> drivers/soc/tegra/pmc.c | 330
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 330 insertions(+)
>>>
>>> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
>>> index 7a5aab0b993b..790a6619ba32 100644
>>> --- a/drivers/soc/tegra/pmc.c
>>> +++ b/drivers/soc/tegra/pmc.c
>>> @@ -13,6 +13,9 @@
>>> #include <linux/arm-smccc.h>
>>> #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/clkdev.h>
>>> +#include <linux/clk/clk-conf.h>
>>> #include <linux/clk/tegra.h>
>>> #include <linux/debugfs.h>
>>> #include <linux/delay.h>
>>> @@ -48,6 +51,7 @@
>>> #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
>>> #include <dt-bindings/gpio/tegra186-gpio.h>
>>> #include <dt-bindings/gpio/tegra194-gpio.h>
>>> +#include <dt-bindings/soc/tegra-pmc.h>
>>> #define PMC_CNTRL 0x0
>>> #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR
>>> polarity */
>>> @@ -108,6 +112,7 @@
>>> #define PMC_WAKE2_STATUS 0x168
>>> #define PMC_SW_WAKE2_STATUS 0x16c
>>> +#define PMC_CLK_OUT_CNTRL 0x1a8
>>> #define PMC_SATA_PWRGT 0x1ac
>>> #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
>>> #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
>>> @@ -170,6 +175,78 @@
>>> #define TEGRA_SMC_PMC_READ 0xaa
>>> #define TEGRA_SMC_PMC_WRITE 0xbb
>>> +struct pmc_clk_mux {
>>> + struct clk_hw hw;
>>> + unsigned long offs;
>>> + u32 mask;
>>> + u32 shift;
>>> + /* register lock */
>>> + spinlock_t *lock;
>>> +};
>>> +
>>> +#define to_pmc_clk_mux(_hw) container_of(_hw, struct pmc_clk_mux, hw)
>>> +
>>> +struct pmc_clk_gate {
>>> + struct clk_hw hw;
>>> + unsigned long offs;
>>> + u32 shift;
>>> + /* register lock */
>>> + spinlock_t *lock;
Why clk_out_lock is needed at all? CCLK framework already takes care of
the clock's locking and then nothing else in PMC code uses that lock to
avoid races, thus that spinlock doesn't do anything useful and should be
removed from both mux and gate.
>>> +};
>>> +
>>> +#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
>>> +
>>> +struct pmc_clk_init_data {
>>> + char *mux_name;
>>> + char *gate_name;
>>> + const char **parents;
>>> + int num_parents;
>>> + int mux_id;
>>> + int gate_id;
>>> + char *dev_name;
>>> + u8 mux_shift;
>>> + u8 gate_shift;
>>> + u8 init_parent;
>>> + int init_state;
>>> + struct pmc_clk_mux mux;
>>> + struct pmc_clk_gate gate;
>>> +};
>>> +
>>> +#define PMC_CLK(_num, _mux_shift, _gate_shift, _init_parent,
>>> _init_state)\
>>> + {\
>>> + .mux_name = "clk_out_" #_num "_mux",\
>>> + .gate_name = "clk_out_" #_num,\
>>> + .parents = clk_out ##_num ##_parents,\
>>> + .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\
>>> + .mux_id = TEGRA_PMC_CLK_OUT_ ##_num ##_MUX,\
>>> + .gate_id = TEGRA_PMC_CLK_OUT_ ##_num,\
>>> + .dev_name = "extern" #_num,\
>>> + .mux_shift = _mux_shift,\
>>> + .gate_shift = _gate_shift,\
>>> + .init_parent = _init_parent,\
>>> + .init_state = _init_state,\
>>> + }
>>> +
>>> +static DEFINE_SPINLOCK(clk_out_lock);
>>> +
>>> +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
>>> + "clk_m_div4", "extern1",
>>> +};
>>> +
>>> +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
>>> + "clk_m_div4", "extern2",
>>> +};
>>> +
>>> +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
>>> + "clk_m_div4", "extern3",
>>> +};
>> Why these are unused?
> They are used in PMC_CLK macro
Looks like it will better to define those three structs directly,
without the PMC_CLK macro.
[snip]
On 11/20/19 9:46 AM, Dmitry Osipenko wrote:
> 19.11.2019 23:08, Sowjanya Komatineni пишет:
>> On 11/19/19 11:33 AM, Dmitry Osipenko wrote:
>>> 19.11.2019 09:50, Sowjanya Komatineni пишет:
>>>> Tegra PMC has clk_out_1, clk_out_2, clk_out_3 with mux and gate for
>>>> each of these clocks.
>>>>
>>>> Currently these PMC clocks are registered by Tegra clock driver using
>>>> clk_register_mux and clk_register_gate by passing PMC base address
>>>> and register offsets and PMC programming for these clocks happens
>>>> through direct PMC access by the clock driver.
>>>>
>>>> With this, when PMC is in secure mode any direct PMC access from the
>>>> non-secure world does not go through and these clocks will not be
>>>> functional.
>>>>
>>>> This patch adds these clocks registration with PMC as a clock provider
>>>> for these clocks. clk_ops callback implementations for these clocks
>>>> uses tegra_pmc_readl and tegra_pmc_writel which supports PMC programming
>>>> in secure mode and non-secure mode.
>>>>
>>>> Signed-off-by: Sowjanya Komatineni <[email protected]>
>>>> ---
>>>> drivers/soc/tegra/pmc.c | 330
>>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>>> 1 file changed, 330 insertions(+)
>>>>
>>>> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
>>>> index 7a5aab0b993b..790a6619ba32 100644
>>>> --- a/drivers/soc/tegra/pmc.c
>>>> +++ b/drivers/soc/tegra/pmc.c
>>>> @@ -13,6 +13,9 @@
>>>> #include <linux/arm-smccc.h>
>>>> #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>> +#include <linux/clkdev.h>
>>>> +#include <linux/clk/clk-conf.h>
>>>> #include <linux/clk/tegra.h>
>>>> #include <linux/debugfs.h>
>>>> #include <linux/delay.h>
>>>> @@ -48,6 +51,7 @@
>>>> #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
>>>> #include <dt-bindings/gpio/tegra186-gpio.h>
>>>> #include <dt-bindings/gpio/tegra194-gpio.h>
>>>> +#include <dt-bindings/soc/tegra-pmc.h>
>>>> #define PMC_CNTRL 0x0
>>>> #define PMC_CNTRL_INTR_POLARITY BIT(17) /* inverts INTR
>>>> polarity */
>>>> @@ -108,6 +112,7 @@
>>>> #define PMC_WAKE2_STATUS 0x168
>>>> #define PMC_SW_WAKE2_STATUS 0x16c
>>>> +#define PMC_CLK_OUT_CNTRL 0x1a8
>>>> #define PMC_SATA_PWRGT 0x1ac
>>>> #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
>>>> #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
>>>> @@ -170,6 +175,78 @@
>>>> #define TEGRA_SMC_PMC_READ 0xaa
>>>> #define TEGRA_SMC_PMC_WRITE 0xbb
>>>> +struct pmc_clk_mux {
>>>> + struct clk_hw hw;
>>>> + unsigned long offs;
>>>> + u32 mask;
>>>> + u32 shift;
>>>> + /* register lock */
>>>> + spinlock_t *lock;
>>>> +};
>>>> +
>>>> +#define to_pmc_clk_mux(_hw) container_of(_hw, struct pmc_clk_mux, hw)
>>>> +
>>>> +struct pmc_clk_gate {
>>>> + struct clk_hw hw;
>>>> + unsigned long offs;
>>>> + u32 shift;
>>>> + /* register lock */
>>>> + spinlock_t *lock;
> Why clk_out_lock is needed at all? CCLK framework already takes care of
> the clock's locking and then nothing else in PMC code uses that lock to
> avoid races, thus that spinlock doesn't do anything useful and should be
> removed from both mux and gate.
Will remove spinlock in next version.
>>>> +};
>>>> +
>>>> +#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
>>>> +
>>>> +struct pmc_clk_init_data {
>>>> + char *mux_name;
>>>> + char *gate_name;
>>>> + const char **parents;
>>>> + int num_parents;
>>>> + int mux_id;
>>>> + int gate_id;
>>>> + char *dev_name;
>>>> + u8 mux_shift;
>>>> + u8 gate_shift;
>>>> + u8 init_parent;
>>>> + int init_state;
>>>> + struct pmc_clk_mux mux;
>>>> + struct pmc_clk_gate gate;
>>>> +};
>>>> +
>>>> +#define PMC_CLK(_num, _mux_shift, _gate_shift, _init_parent,
>>>> _init_state)\
>>>> + {\
>>>> + .mux_name = "clk_out_" #_num "_mux",\
>>>> + .gate_name = "clk_out_" #_num,\
>>>> + .parents = clk_out ##_num ##_parents,\
>>>> + .num_parents = ARRAY_SIZE(clk_out ##_num ##_parents),\
>>>> + .mux_id = TEGRA_PMC_CLK_OUT_ ##_num ##_MUX,\
>>>> + .gate_id = TEGRA_PMC_CLK_OUT_ ##_num,\
>>>> + .dev_name = "extern" #_num,\
>>>> + .mux_shift = _mux_shift,\
>>>> + .gate_shift = _gate_shift,\
>>>> + .init_parent = _init_parent,\
>>>> + .init_state = _init_state,\
>>>> + }
>>>> +
>>>> +static DEFINE_SPINLOCK(clk_out_lock);
>>>> +
>>>> +static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
>>>> + "clk_m_div4", "extern1",
>>>> +};
>>>> +
>>>> +static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
>>>> + "clk_m_div4", "extern2",
>>>> +};
>>>> +
>>>> +static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
>>>> + "clk_m_div4", "extern3",
>>>> +};
>>> Why these are unused?
>> They are used in PMC_CLK macro
> Looks like it will better to define those three structs directly,
> without the PMC_CLK macro.
>
> [snip]
ok, will define structs directly in next version.
On Mon, Nov 18, 2019 at 10:50:28PM -0800, Sowjanya Komatineni wrote:
> clk_out_1, clk_out_2, clk_out_3, blink are part of Tegra pmc clocks.
>
> This patch removes ids for these clocks from Tegra clock dt-bindings.
Your commit message should answer why, not what.
This is not a backwards compatible change if any of these IDs are used.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>
> ---
> include/dt-bindings/clock/tegra114-car.h | 14 +++++++-------
> include/dt-bindings/clock/tegra124-car-common.h | 14 +++++++-------
> include/dt-bindings/clock/tegra20-car.h | 2 +-
> include/dt-bindings/clock/tegra210-car.h | 14 +++++++-------
> include/dt-bindings/clock/tegra30-car.h | 14 +++++++-------
> 5 files changed, 29 insertions(+), 29 deletions(-)
>
> diff --git a/include/dt-bindings/clock/tegra114-car.h b/include/dt-bindings/clock/tegra114-car.h
> index bb5c2c999c05..9175cd0571b5 100644
> --- a/include/dt-bindings/clock/tegra114-car.h
> +++ b/include/dt-bindings/clock/tegra114-car.h
> @@ -270,10 +270,10 @@
> #define TEGRA114_CLK_AUDIO3 242
> #define TEGRA114_CLK_AUDIO4 243
> #define TEGRA114_CLK_SPDIF 244
> -#define TEGRA114_CLK_CLK_OUT_1 245
> -#define TEGRA114_CLK_CLK_OUT_2 246
> -#define TEGRA114_CLK_CLK_OUT_3 247
> -#define TEGRA114_CLK_BLINK 248
> +/* 245 */
> +/* 246 */
> +/* 247 */
> +/* 248 */
> /* 249 */
> /* 250 */
> /* 251 */
> @@ -333,9 +333,9 @@
> #define TEGRA114_CLK_AUDIO3_MUX 303
> #define TEGRA114_CLK_AUDIO4_MUX 304
> #define TEGRA114_CLK_SPDIF_MUX 305
> -#define TEGRA114_CLK_CLK_OUT_1_MUX 306
> -#define TEGRA114_CLK_CLK_OUT_2_MUX 307
> -#define TEGRA114_CLK_CLK_OUT_3_MUX 308
> +/* 306 */
> +/* 307 */
> +/* 308 */
> #define TEGRA114_CLK_DSIA_MUX 309
> #define TEGRA114_CLK_DSIB_MUX 310
> #define TEGRA114_CLK_XUSB_SS_DIV2 311
> diff --git a/include/dt-bindings/clock/tegra124-car-common.h b/include/dt-bindings/clock/tegra124-car-common.h
> index 0c4f5be0a742..90a0c5e7eb5f 100644
> --- a/include/dt-bindings/clock/tegra124-car-common.h
> +++ b/include/dt-bindings/clock/tegra124-car-common.h
> @@ -269,10 +269,10 @@
> #define TEGRA124_CLK_AUDIO3 242
> #define TEGRA124_CLK_AUDIO4 243
> #define TEGRA124_CLK_SPDIF 244
> -#define TEGRA124_CLK_CLK_OUT_1 245
> -#define TEGRA124_CLK_CLK_OUT_2 246
> -#define TEGRA124_CLK_CLK_OUT_3 247
> -#define TEGRA124_CLK_BLINK 248
> +/* 245 */
> +/* 246 */
> +/* 247 */
> +/* 248 */
> /* 249 */
> /* 250 */
> /* 251 */
> @@ -332,9 +332,9 @@
> #define TEGRA124_CLK_AUDIO3_MUX 303
> #define TEGRA124_CLK_AUDIO4_MUX 304
> #define TEGRA124_CLK_SPDIF_MUX 305
> -#define TEGRA124_CLK_CLK_OUT_1_MUX 306
> -#define TEGRA124_CLK_CLK_OUT_2_MUX 307
> -#define TEGRA124_CLK_CLK_OUT_3_MUX 308
> +/* 306 */
> +/* 307 */
> +/* 308 */
> /* 309 */
> /* 310 */
> #define TEGRA124_CLK_SOR0_LVDS 311 /* deprecated */
> diff --git a/include/dt-bindings/clock/tegra20-car.h b/include/dt-bindings/clock/tegra20-car.h
> index b21a0eb32921..fe541f627965 100644
> --- a/include/dt-bindings/clock/tegra20-car.h
> +++ b/include/dt-bindings/clock/tegra20-car.h
> @@ -131,7 +131,7 @@
> #define TEGRA20_CLK_CCLK 108
> #define TEGRA20_CLK_HCLK 109
> #define TEGRA20_CLK_PCLK 110
> -#define TEGRA20_CLK_BLINK 111
> +/* 111 */
> #define TEGRA20_CLK_PLL_A 112
> #define TEGRA20_CLK_PLL_A_OUT0 113
> #define TEGRA20_CLK_PLL_C 114
> diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h
> index 44f60623f99b..a3d8d3e75728 100644
> --- a/include/dt-bindings/clock/tegra210-car.h
> +++ b/include/dt-bindings/clock/tegra210-car.h
> @@ -304,10 +304,10 @@
> #define TEGRA210_CLK_AUDIO3 274
> #define TEGRA210_CLK_AUDIO4 275
> #define TEGRA210_CLK_SPDIF 276
> -#define TEGRA210_CLK_CLK_OUT_1 277
> -#define TEGRA210_CLK_CLK_OUT_2 278
> -#define TEGRA210_CLK_CLK_OUT_3 279
> -#define TEGRA210_CLK_BLINK 280
> +/* 277 */
> +/* 278 */
> +/* 279 */
> +/* 280 */
> #define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */
> #define TEGRA210_CLK_SOR0_OUT 281
> #define TEGRA210_CLK_SOR1_OUT 282
> @@ -386,9 +386,9 @@
> #define TEGRA210_CLK_AUDIO3_MUX 353
> #define TEGRA210_CLK_AUDIO4_MUX 354
> #define TEGRA210_CLK_SPDIF_MUX 355
> -#define TEGRA210_CLK_CLK_OUT_1_MUX 356
> -#define TEGRA210_CLK_CLK_OUT_2_MUX 357
> -#define TEGRA210_CLK_CLK_OUT_3_MUX 358
> +/* 356 */
> +/* 357 */
> +/* 358 */
> #define TEGRA210_CLK_DSIA_MUX 359
> #define TEGRA210_CLK_DSIB_MUX 360
> /* 361 */
> diff --git a/include/dt-bindings/clock/tegra30-car.h b/include/dt-bindings/clock/tegra30-car.h
> index 3c90f1535551..20ef2462d9e1 100644
> --- a/include/dt-bindings/clock/tegra30-car.h
> +++ b/include/dt-bindings/clock/tegra30-car.h
> @@ -230,11 +230,11 @@
> #define TEGRA30_CLK_AUDIO3 204
> #define TEGRA30_CLK_AUDIO4 205
> #define TEGRA30_CLK_SPDIF 206
> -#define TEGRA30_CLK_CLK_OUT_1 207 /* (extern1) */
> -#define TEGRA30_CLK_CLK_OUT_2 208 /* (extern2) */
> -#define TEGRA30_CLK_CLK_OUT_3 209 /* (extern3) */
> +/* 207 */
> +/* 208 */
> +/* 209 */
> #define TEGRA30_CLK_SCLK 210
> -#define TEGRA30_CLK_BLINK 211
> +/* 211 */
> #define TEGRA30_CLK_CCLK_G 212
> #define TEGRA30_CLK_CCLK_LP 213
> #define TEGRA30_CLK_TWD 214
> @@ -260,9 +260,9 @@
> /* 297 */
> /* 298 */
> /* 299 */
> -#define TEGRA30_CLK_CLK_OUT_1_MUX 300
> -#define TEGRA30_CLK_CLK_OUT_2_MUX 301
> -#define TEGRA30_CLK_CLK_OUT_3_MUX 302
> +/* 300 */
> +/* 301 */
> +/* 302 */
> #define TEGRA30_CLK_AUDIO0_MUX 303
> #define TEGRA30_CLK_AUDIO1_MUX 304
> #define TEGRA30_CLK_AUDIO2_MUX 305
> --
> 2.7.4
>
On Mon, Nov 18, 2019 at 10:50:20PM -0800, Sowjanya Komatineni wrote:
> Tegra PMC has clk_out_1, clk_out_2, clk_out_3 clocks and each of
> these clocks has mux and a gate as a part of PMC controller.
>
> This patch adds ids for each of these PMC clock mux and gates to
> use with the devicetree.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>
> ---
> include/dt-bindings/soc/tegra-pmc.h | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
> create mode 100644 include/dt-bindings/soc/tegra-pmc.h
This should be part of the binding patch.
>
> diff --git a/include/dt-bindings/soc/tegra-pmc.h b/include/dt-bindings/soc/tegra-pmc.h
> new file mode 100644
> index 000000000000..fa1ccfc2514b
> --- /dev/null
> +++ b/include/dt-bindings/soc/tegra-pmc.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
> + */
> +
> +#ifndef _DT_BINDINGS_SOC_TEGRA_PMC_H
> +#define _DT_BINDINGS_SOC_TEGRA_PMC_H
> +
> +#define TEGRA_PMC_CLK_OUT_1_MUX 0
> +#define TEGRA_PMC_CLK_OUT_1 1
> +#define TEGRA_PMC_CLK_OUT_2_MUX 2
> +#define TEGRA_PMC_CLK_OUT_2 3
> +#define TEGRA_PMC_CLK_OUT_3_MUX 4
> +#define TEGRA_PMC_CLK_OUT_3 5
> +
> +#endif /* _DT_BINDINGS_SOC_TEGRA_PMC_H */
> --
> 2.7.4
>
On 12/3/19 2:07 PM, Rob Herring wrote:
> On Mon, Nov 18, 2019 at 10:50:28PM -0800, Sowjanya Komatineni wrote:
>> clk_out_1, clk_out_2, clk_out_3, blink are part of Tegra pmc clocks.
>>
>> This patch removes ids for these clocks from Tegra clock dt-bindings.
> Your commit message should answer why, not what.
>
> This is not a backwards compatible change if any of these IDs are used.
Only Tegra210 samsung platform is using one of these clocks and this
series includes samsung platform device tree update to change provider
to PMC and use PMC clock ids.
Sure, Will update commit message to explain the reason for moving these
clocks to PMC...
>> Signed-off-by: Sowjanya Komatineni <[email protected]>
>> ---
>> include/dt-bindings/clock/tegra114-car.h | 14 +++++++-------
>> include/dt-bindings/clock/tegra124-car-common.h | 14 +++++++-------
>> include/dt-bindings/clock/tegra20-car.h | 2 +-
>> include/dt-bindings/clock/tegra210-car.h | 14 +++++++-------
>> include/dt-bindings/clock/tegra30-car.h | 14 +++++++-------
>> 5 files changed, 29 insertions(+), 29 deletions(-)
>>
>> diff --git a/include/dt-bindings/clock/tegra114-car.h b/include/dt-bindings/clock/tegra114-car.h
>> index bb5c2c999c05..9175cd0571b5 100644
>> --- a/include/dt-bindings/clock/tegra114-car.h
>> +++ b/include/dt-bindings/clock/tegra114-car.h
>> @@ -270,10 +270,10 @@
>> #define TEGRA114_CLK_AUDIO3 242
>> #define TEGRA114_CLK_AUDIO4 243
>> #define TEGRA114_CLK_SPDIF 244
>> -#define TEGRA114_CLK_CLK_OUT_1 245
>> -#define TEGRA114_CLK_CLK_OUT_2 246
>> -#define TEGRA114_CLK_CLK_OUT_3 247
>> -#define TEGRA114_CLK_BLINK 248
>> +/* 245 */
>> +/* 246 */
>> +/* 247 */
>> +/* 248 */
>> /* 249 */
>> /* 250 */
>> /* 251 */
>> @@ -333,9 +333,9 @@
>> #define TEGRA114_CLK_AUDIO3_MUX 303
>> #define TEGRA114_CLK_AUDIO4_MUX 304
>> #define TEGRA114_CLK_SPDIF_MUX 305
>> -#define TEGRA114_CLK_CLK_OUT_1_MUX 306
>> -#define TEGRA114_CLK_CLK_OUT_2_MUX 307
>> -#define TEGRA114_CLK_CLK_OUT_3_MUX 308
>> +/* 306 */
>> +/* 307 */
>> +/* 308 */
>> #define TEGRA114_CLK_DSIA_MUX 309
>> #define TEGRA114_CLK_DSIB_MUX 310
>> #define TEGRA114_CLK_XUSB_SS_DIV2 311
>> diff --git a/include/dt-bindings/clock/tegra124-car-common.h b/include/dt-bindings/clock/tegra124-car-common.h
>> index 0c4f5be0a742..90a0c5e7eb5f 100644
>> --- a/include/dt-bindings/clock/tegra124-car-common.h
>> +++ b/include/dt-bindings/clock/tegra124-car-common.h
>> @@ -269,10 +269,10 @@
>> #define TEGRA124_CLK_AUDIO3 242
>> #define TEGRA124_CLK_AUDIO4 243
>> #define TEGRA124_CLK_SPDIF 244
>> -#define TEGRA124_CLK_CLK_OUT_1 245
>> -#define TEGRA124_CLK_CLK_OUT_2 246
>> -#define TEGRA124_CLK_CLK_OUT_3 247
>> -#define TEGRA124_CLK_BLINK 248
>> +/* 245 */
>> +/* 246 */
>> +/* 247 */
>> +/* 248 */
>> /* 249 */
>> /* 250 */
>> /* 251 */
>> @@ -332,9 +332,9 @@
>> #define TEGRA124_CLK_AUDIO3_MUX 303
>> #define TEGRA124_CLK_AUDIO4_MUX 304
>> #define TEGRA124_CLK_SPDIF_MUX 305
>> -#define TEGRA124_CLK_CLK_OUT_1_MUX 306
>> -#define TEGRA124_CLK_CLK_OUT_2_MUX 307
>> -#define TEGRA124_CLK_CLK_OUT_3_MUX 308
>> +/* 306 */
>> +/* 307 */
>> +/* 308 */
>> /* 309 */
>> /* 310 */
>> #define TEGRA124_CLK_SOR0_LVDS 311 /* deprecated */
>> diff --git a/include/dt-bindings/clock/tegra20-car.h b/include/dt-bindings/clock/tegra20-car.h
>> index b21a0eb32921..fe541f627965 100644
>> --- a/include/dt-bindings/clock/tegra20-car.h
>> +++ b/include/dt-bindings/clock/tegra20-car.h
>> @@ -131,7 +131,7 @@
>> #define TEGRA20_CLK_CCLK 108
>> #define TEGRA20_CLK_HCLK 109
>> #define TEGRA20_CLK_PCLK 110
>> -#define TEGRA20_CLK_BLINK 111
>> +/* 111 */
>> #define TEGRA20_CLK_PLL_A 112
>> #define TEGRA20_CLK_PLL_A_OUT0 113
>> #define TEGRA20_CLK_PLL_C 114
>> diff --git a/include/dt-bindings/clock/tegra210-car.h b/include/dt-bindings/clock/tegra210-car.h
>> index 44f60623f99b..a3d8d3e75728 100644
>> --- a/include/dt-bindings/clock/tegra210-car.h
>> +++ b/include/dt-bindings/clock/tegra210-car.h
>> @@ -304,10 +304,10 @@
>> #define TEGRA210_CLK_AUDIO3 274
>> #define TEGRA210_CLK_AUDIO4 275
>> #define TEGRA210_CLK_SPDIF 276
>> -#define TEGRA210_CLK_CLK_OUT_1 277
>> -#define TEGRA210_CLK_CLK_OUT_2 278
>> -#define TEGRA210_CLK_CLK_OUT_3 279
>> -#define TEGRA210_CLK_BLINK 280
>> +/* 277 */
>> +/* 278 */
>> +/* 279 */
>> +/* 280 */
>> #define TEGRA210_CLK_SOR0_LVDS 281 /* deprecated */
>> #define TEGRA210_CLK_SOR0_OUT 281
>> #define TEGRA210_CLK_SOR1_OUT 282
>> @@ -386,9 +386,9 @@
>> #define TEGRA210_CLK_AUDIO3_MUX 353
>> #define TEGRA210_CLK_AUDIO4_MUX 354
>> #define TEGRA210_CLK_SPDIF_MUX 355
>> -#define TEGRA210_CLK_CLK_OUT_1_MUX 356
>> -#define TEGRA210_CLK_CLK_OUT_2_MUX 357
>> -#define TEGRA210_CLK_CLK_OUT_3_MUX 358
>> +/* 356 */
>> +/* 357 */
>> +/* 358 */
>> #define TEGRA210_CLK_DSIA_MUX 359
>> #define TEGRA210_CLK_DSIB_MUX 360
>> /* 361 */
>> diff --git a/include/dt-bindings/clock/tegra30-car.h b/include/dt-bindings/clock/tegra30-car.h
>> index 3c90f1535551..20ef2462d9e1 100644
>> --- a/include/dt-bindings/clock/tegra30-car.h
>> +++ b/include/dt-bindings/clock/tegra30-car.h
>> @@ -230,11 +230,11 @@
>> #define TEGRA30_CLK_AUDIO3 204
>> #define TEGRA30_CLK_AUDIO4 205
>> #define TEGRA30_CLK_SPDIF 206
>> -#define TEGRA30_CLK_CLK_OUT_1 207 /* (extern1) */
>> -#define TEGRA30_CLK_CLK_OUT_2 208 /* (extern2) */
>> -#define TEGRA30_CLK_CLK_OUT_3 209 /* (extern3) */
>> +/* 207 */
>> +/* 208 */
>> +/* 209 */
>> #define TEGRA30_CLK_SCLK 210
>> -#define TEGRA30_CLK_BLINK 211
>> +/* 211 */
>> #define TEGRA30_CLK_CCLK_G 212
>> #define TEGRA30_CLK_CCLK_LP 213
>> #define TEGRA30_CLK_TWD 214
>> @@ -260,9 +260,9 @@
>> /* 297 */
>> /* 298 */
>> /* 299 */
>> -#define TEGRA30_CLK_CLK_OUT_1_MUX 300
>> -#define TEGRA30_CLK_CLK_OUT_2_MUX 301
>> -#define TEGRA30_CLK_CLK_OUT_3_MUX 302
>> +/* 300 */
>> +/* 301 */
>> +/* 302 */
>> #define TEGRA30_CLK_AUDIO0_MUX 303
>> #define TEGRA30_CLK_AUDIO1_MUX 304
>> #define TEGRA30_CLK_AUDIO2_MUX 305
>> --
>> 2.7.4
>>
On Mon, Nov 18, 2019 at 10:50:32PM -0800, Sowjanya Komatineni wrote:
> Document clock bindings for pmc clocks clk_out_1, clk_out_2 and clk_out_3.
> These clocks are part of Tegra PMC block and pmc node is the provider for
> these clocks.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>
> ---
> .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 44 ++++++++++++++++++++++
> 1 file changed, 44 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
> index 2d89cdc39eb0..4576de92e4cc 100644
> --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
> +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
> @@ -12,6 +12,10 @@ Required properties:
> - "aotag"
> - "scratch"
> - "misc" (Only for Tegra194)
> +- #clock-cells : Should be 1 for Tegra30 and higher.
> + In clock consumers, this cell represents the PMC clock ID.
> + The assignments may be found in header file
> + <dt-bindings/soc/tegra-pmc.h>.
Kind of strange the header is shared, but the binding doc is not.
>
> Optional properties:
> - nvidia,invert-interrupt: If present, inverts the PMU interrupt signal.
> @@ -130,3 +134,43 @@ Pinctrl client example:
> pinctrl-1 = <&hdmi_on>;
> pinctrl-names = "hdmi-on", "hdmi-off";
> };
> +
> +== Clock Control ==
> +
> +Tegra PMC has 3 clocks clk_1, clk_2 and clk_3. Each of these clocks has
> +source selection and enable/disable gate.
> +Parent/source for these clocks can be either of clk_m, clk_m_div2, clk_m_div4,
> +or extern clock from Tegra CAR module.
> +
> +Clock configuration example:
> + pmc: pmc@7000e400 {
> + compatible = "nvidia,tegra186-pmc";
> + reg = <0 0x0c360000 0 0x10000>,
> + <0 0x0c370000 0 0x10000>,
> + <0 0x0c380000 0 0x10000>,
> + <0 0x0c390000 0 0x10000>;
> + reg-names = "pmc", "wake", "aotag", "scratch";
> + ...
> + #clock-cells = <1>;
> + ...
Once converted to schema, the examples have to compile and this won't.
They also have to be complete enough to pass validation checks.
> + };
> +
> +Clock consumer example:
> + host1x@50000000 {
> + ...
> + vi@54080000 {
> + ...
> + assigned-clocks = <&pmc TEGRA_PMC_CLK_OUT_3_MUX>;
> + assigned-clock-parents = <&tegra_car TEGRA210_CLK_EXTERN3>;
Indentation is wrong.
> + };
> + ...
> + };
> + ...
> + i2c@7000c500 {
> + cam_sensor {
> + ...
> + clocks = <&pmc TEGRA_PMC_CLK_OUT_3>;
> + clock-names = "mclk";
Same here.
> + ...
> + };
> + };
> --
> 2.7.4
>
On 12/3/19 2:08 PM, Rob Herring wrote:
> On Mon, Nov 18, 2019 at 10:50:20PM -0800, Sowjanya Komatineni wrote:
>> Tegra PMC has clk_out_1, clk_out_2, clk_out_3 clocks and each of
>> these clocks has mux and a gate as a part of PMC controller.
>>
>> This patch adds ids for each of these PMC clock mux and gates to
>> use with the devicetree.
>>
>> Signed-off-by: Sowjanya Komatineni <[email protected]>
>> ---
>> include/dt-bindings/soc/tegra-pmc.h | 16 ++++++++++++++++
>> 1 file changed, 16 insertions(+)
>> create mode 100644 include/dt-bindings/soc/tegra-pmc.h
> This should be part of the binding patch.
ok, will combine in v3
>> diff --git a/include/dt-bindings/soc/tegra-pmc.h b/include/dt-bindings/soc/tegra-pmc.h
>> new file mode 100644
>> index 000000000000..fa1ccfc2514b
>> --- /dev/null
>> +++ b/include/dt-bindings/soc/tegra-pmc.h
>> @@ -0,0 +1,16 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
>> + */
>> +
>> +#ifndef _DT_BINDINGS_SOC_TEGRA_PMC_H
>> +#define _DT_BINDINGS_SOC_TEGRA_PMC_H
>> +
>> +#define TEGRA_PMC_CLK_OUT_1_MUX 0
>> +#define TEGRA_PMC_CLK_OUT_1 1
>> +#define TEGRA_PMC_CLK_OUT_2_MUX 2
>> +#define TEGRA_PMC_CLK_OUT_2 3
>> +#define TEGRA_PMC_CLK_OUT_3_MUX 4
>> +#define TEGRA_PMC_CLK_OUT_3 5
>> +
>> +#endif /* _DT_BINDINGS_SOC_TEGRA_PMC_H */
>> --
>> 2.7.4
>>
On 12/3/19 2:11 PM, Rob Herring wrote:
> On Mon, Nov 18, 2019 at 10:50:32PM -0800, Sowjanya Komatineni wrote:
>> Document clock bindings for pmc clocks clk_out_1, clk_out_2 and clk_out_3.
>> These clocks are part of Tegra PMC block and pmc node is the provider for
>> these clocks.
>>
>> Signed-off-by: Sowjanya Komatineni <[email protected]>
>> ---
>> .../bindings/arm/tegra/nvidia,tegra186-pmc.txt | 44 ++++++++++++++++++++++
>> 1 file changed, 44 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
>> index 2d89cdc39eb0..4576de92e4cc 100644
>> --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
>> +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
>> @@ -12,6 +12,10 @@ Required properties:
>> - "aotag"
>> - "scratch"
>> - "misc" (Only for Tegra194)
>> +- #clock-cells : Should be 1 for Tegra30 and higher.
>> + In clock consumers, this cell represents the PMC clock ID.
>> + The assignments may be found in header file
>> + <dt-bindings/soc/tegra-pmc.h>.
> Kind of strange the header is shared, but the binding doc is not.
v2 has this patch removed. Tegra186 does not have pmc clocks. They were
accidentally added in v1 and this is fixed in v2.
>
>>
>> Optional properties:
>> - nvidia,invert-interrupt: If present, inverts the PMU interrupt signal.
>> @@ -130,3 +134,43 @@ Pinctrl client example:
>> pinctrl-1 = <&hdmi_on>;
>> pinctrl-names = "hdmi-on", "hdmi-off";
>> };
>> +
>> +== Clock Control ==
>> +
>> +Tegra PMC has 3 clocks clk_1, clk_2 and clk_3. Each of these clocks has
>> +source selection and enable/disable gate.
>> +Parent/source for these clocks can be either of clk_m, clk_m_div2, clk_m_div4,
>> +or extern clock from Tegra CAR module.
>> +
>> +Clock configuration example:
>> + pmc: pmc@7000e400 {
>> + compatible = "nvidia,tegra186-pmc";
>> + reg = <0 0x0c360000 0 0x10000>,
>> + <0 0x0c370000 0 0x10000>,
>> + <0 0x0c380000 0 0x10000>,
>> + <0 0x0c390000 0 0x10000>;
>> + reg-names = "pmc", "wake", "aotag", "scratch";
>> + ...
>> + #clock-cells = <1>;
>> + ...
> Once converted to schema, the examples have to compile and this won't.
> They also have to be complete enough to pass validation checks.
ok, will go thru and run the validation checks.
>> + };
>> +
>> +Clock consumer example:
>> + host1x@50000000 {
>> + ...
>> + vi@54080000 {
>> + ...
>> + assigned-clocks = <&pmc TEGRA_PMC_CLK_OUT_3_MUX>;
>> + assigned-clock-parents = <&tegra_car TEGRA210_CLK_EXTERN3>;
> Indentation is wrong.
>
>> + };
>> + ...
>> + };
>> + ...
>> + i2c@7000c500 {
>> + cam_sensor {
>> + ...
>> + clocks = <&pmc TEGRA_PMC_CLK_OUT_3>;
>> + clock-names = "mclk";
> Same here.
>
>> + ...
>> + };
>> + };
>> --
>> 2.7.4
>>