From: Sowjanya Komatineni <skomatineni@nvidia.com> To: skomatineni@nvidia.com, thierry.reding@gmail.com, jonathanh@nvidia.com, digetx@gmail.com, mperttunen@nvidia.com, gregkh@linuxfoundation.org, sboyd@kernel.org, tglx@linutronix.de, robh+dt@kernel.org, mark.rutland@arm.com Cc: allison@lohutok.net, pdeschrijver@nvidia.com, pgaikwad@nvidia.com, mturquette@baylibre.com, horms+renesas@verge.net.au, Jisheng.Zhang@synaptics.com, krzk@kernel.org, arnd@arndb.de, spujar@nvidia.com, josephl@nvidia.com, vidyas@nvidia.com, daniel.lezcano@linaro.org, mmaddireddy@nvidia.com, markz@nvidia.com, devicetree@vger.kernel.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1 01/17] soc: tegra: pmc: Add helper functions for PLLM overrides Date: Mon, 18 Nov 2019 22:50:18 -0800 [thread overview] Message-ID: <1574146234-3871-2-git-send-email-skomatineni@nvidia.com> (raw) In-Reply-To: <1574146234-3871-1-git-send-email-skomatineni@nvidia.com> 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 <skomatineni@nvidia.com> --- 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
WARNING: multiple messages have this Message-ID (diff)
From: Sowjanya Komatineni <skomatineni@nvidia.com> To: <skomatineni@nvidia.com>, <thierry.reding@gmail.com>, <jonathanh@nvidia.com>, <digetx@gmail.com>, <mperttunen@nvidia.com>, <gregkh@linuxfoundation.org>, <sboyd@kernel.org>, <tglx@linutronix.de>, <robh+dt@kernel.org>, <mark.rutland@arm.com> Cc: <allison@lohutok.net>, <pdeschrijver@nvidia.com>, <pgaikwad@nvidia.com>, <mturquette@baylibre.com>, <horms+renesas@verge.net.au>, <Jisheng.Zhang@synaptics.com>, <krzk@kernel.org>, <arnd@arndb.de>, <spujar@nvidia.com>, <josephl@nvidia.com>, <vidyas@nvidia.com>, <daniel.lezcano@linaro.org>, <mmaddireddy@nvidia.com>, <markz@nvidia.com>, <devicetree@vger.kernel.org>, <linux-clk@vger.kernel.org>, <linux-tegra@vger.kernel.org>, <linux-kernel@vger.kernel.org> Subject: [PATCH v1 01/17] soc: tegra: pmc: Add helper functions for PLLM overrides Date: Mon, 18 Nov 2019 22:50:18 -0800 [thread overview] Message-ID: <1574146234-3871-2-git-send-email-skomatineni@nvidia.com> (raw) In-Reply-To: <1574146234-3871-1-git-send-email-skomatineni@nvidia.com> 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 <skomatineni@nvidia.com> --- 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
next prev parent reply other threads:[~2019-11-19 6:50 UTC|newest] Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-11-19 6:50 [PATCH v1 00/17] Remove direct Tegra PMC access in clock driver Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni [this message] 2019-11-19 6:50 ` [PATCH v1 01/17] soc: tegra: pmc: Add helper functions for PLLM overrides Sowjanya Komatineni 2019-11-19 19:32 ` Dmitry Osipenko 2019-11-19 6:50 ` [PATCH v1 02/17] soc: tegra: pmc: Add helper function for PLLE IDDQ override Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 03/17] dt-bindings: soc: tegra-pmc: Add Tegra PMC clock ids Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-12-03 22:08 ` Rob Herring 2019-12-03 22:19 ` Sowjanya Komatineni 2019-12-03 22:19 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 04/17] soc: tegra: Add Tegra PMC clock registrations into PMC driver Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 19:33 ` Dmitry Osipenko 2019-11-19 20:08 ` Sowjanya Komatineni 2019-11-19 20:08 ` Sowjanya Komatineni 2019-11-19 20:29 ` Sowjanya Komatineni 2019-11-19 20:29 ` Sowjanya Komatineni 2019-11-20 17:46 ` Dmitry Osipenko 2019-11-20 19:09 ` Sowjanya Komatineni 2019-11-20 19:09 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 05/17] dt-bindings: soc: tegra-pmc: Add id for Tegra PMC blink control Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 06/17] soc: pmc: Add blink output clock registration to Tegra PMC Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 19:34 ` Dmitry Osipenko 2019-11-19 22:13 ` Sowjanya Komatineni 2019-11-19 22:13 ` Sowjanya Komatineni 2019-11-20 2:09 ` Sowjanya Komatineni 2019-11-20 2:09 ` Sowjanya Komatineni 2019-11-20 4:26 ` Sowjanya Komatineni 2019-11-20 4:26 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 07/17] clk: tegra: Use Tegra PMC helper functions for PLLM overrides Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 08/17] clk: tegra: Use Tegra PMC helper function for PLLE IDDQ Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 09/17] clk: tegra: Remove PMC base references from clock registration Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 19:33 ` Dmitry Osipenko 2019-11-19 6:50 ` [PATCH v1 10/17] clk: tegra: Remove tegra_pmc_clk_init along with clk ids Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 19:33 ` Dmitry Osipenko 2019-11-19 6:50 ` [PATCH v1 11/17] dt-bindings: clock: tegra: Remove pmc clock ids from clock dt-bindings Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-12-03 22:07 ` Rob Herring 2019-12-03 22:11 ` Sowjanya Komatineni 2019-12-03 22:11 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 12/17] arm: tegra: Add clock-cells property to Tegra pmc Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 19:32 ` Dmitry Osipenko 2019-11-19 6:50 ` [PATCH v1 13/17] arm64: " Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 14/17] dt-bindings: Add Tegra PMC clock configuration bindings Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 15/17] dt-bindings: tegra186-pmc: Add Tegra PMC clock bindings Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-12-03 22:11 ` Rob Herring 2019-12-03 23:28 ` Sowjanya Komatineni 2019-12-03 23:28 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 16/17] arm64: tegra: smaug: Change clk_out_2 provider from tegra_car to pmc Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni 2019-11-19 6:50 ` [PATCH v1 17/17] ASoC: nau8825: change Tegra " Sowjanya Komatineni 2019-11-19 6:50 ` Sowjanya Komatineni
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1574146234-3871-2-git-send-email-skomatineni@nvidia.com \ --to=skomatineni@nvidia.com \ --cc=Jisheng.Zhang@synaptics.com \ --cc=allison@lohutok.net \ --cc=arnd@arndb.de \ --cc=daniel.lezcano@linaro.org \ --cc=devicetree@vger.kernel.org \ --cc=digetx@gmail.com \ --cc=gregkh@linuxfoundation.org \ --cc=horms+renesas@verge.net.au \ --cc=jonathanh@nvidia.com \ --cc=josephl@nvidia.com \ --cc=krzk@kernel.org \ --cc=linux-clk@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-tegra@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=markz@nvidia.com \ --cc=mmaddireddy@nvidia.com \ --cc=mperttunen@nvidia.com \ --cc=mturquette@baylibre.com \ --cc=pdeschrijver@nvidia.com \ --cc=pgaikwad@nvidia.com \ --cc=robh+dt@kernel.org \ --cc=sboyd@kernel.org \ --cc=spujar@nvidia.com \ --cc=tglx@linutronix.de \ --cc=thierry.reding@gmail.com \ --cc=vidyas@nvidia.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.