aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm53xx/patches-4.3/045-clk-iproc-Add-PWRCTRL-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm53xx/patches-4.3/045-clk-iproc-Add-PWRCTRL-support.patch')
-rw-r--r--target/linux/bcm53xx/patches-4.3/045-clk-iproc-Add-PWRCTRL-support.patch120
1 files changed, 120 insertions, 0 deletions
diff --git a/target/linux/bcm53xx/patches-4.3/045-clk-iproc-Add-PWRCTRL-support.patch b/target/linux/bcm53xx/patches-4.3/045-clk-iproc-Add-PWRCTRL-support.patch
new file mode 100644
index 0000000..318bd5c
--- /dev/null
+++ b/target/linux/bcm53xx/patches-4.3/045-clk-iproc-Add-PWRCTRL-support.patch
@@ -0,0 +1,120 @@
+From 7c70cb333deb6e2f88da9c94ddd6b3b00c97b93a Mon Sep 17 00:00:00 2001
+From: Jon Mason <jonmason@broadcom.com>
+Date: Thu, 15 Oct 2015 15:48:26 -0400
+Subject: [PATCH 45/50] clk: iproc: Add PWRCTRL support
+
+Some iProc SoC clocks use a different way to control clock power, via
+the PWRDWN bit in the PLL control register. Since the PLL control
+register is used to access the PWRDWN bit, there is no need for the
+pwr_base when this is being used. A new flag, IPROC_CLK_EMBED_PWRCTRL,
+has been added to identify this usage. We can use the AON interface to
+write the values to enable/disable PWRDOWN.
+
+Signed-off-by: Jon Mason <jonmason@broadcom.com>
+---
+ drivers/clk/bcm/clk-iproc-pll.c | 55 ++++++++++++++++++++++++++++-------------
+ drivers/clk/bcm/clk-iproc.h | 6 +++++
+ 2 files changed, 44 insertions(+), 17 deletions(-)
+
+--- a/drivers/clk/bcm/clk-iproc-pll.c
++++ b/drivers/clk/bcm/clk-iproc-pll.c
+@@ -148,14 +148,25 @@ static void __pll_disable(struct iproc_p
+ writel(val, pll->asiu_base + ctrl->asiu.offset);
+ }
+
+- /* latch input value so core power can be shut down */
+- val = readl(pll->pwr_base + ctrl->aon.offset);
+- val |= (1 << ctrl->aon.iso_shift);
+- writel(val, pll->pwr_base + ctrl->aon.offset);
+-
+- /* power down the core */
+- val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
+- writel(val, pll->pwr_base + ctrl->aon.offset);
++ if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
++ val = readl(pll->pll_base + ctrl->aon.offset);
++ val |= (bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
++ writel(val, pll->pll_base + ctrl->aon.offset);
++
++ if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
++ readl(pll->pll_base + ctrl->aon.offset);
++ }
++
++ if (pll->pwr_base) {
++ /* latch input value so core power can be shut down */
++ val = readl(pll->pwr_base + ctrl->aon.offset);
++ val |= (1 << ctrl->aon.iso_shift);
++ writel(val, pll->pwr_base + ctrl->aon.offset);
++
++ /* power down the core */
++ val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
++ writel(val, pll->pwr_base + ctrl->aon.offset);
++ }
+ }
+
+ static int __pll_enable(struct iproc_pll *pll)
+@@ -163,11 +174,22 @@ static int __pll_enable(struct iproc_pll
+ const struct iproc_pll_ctrl *ctrl = pll->ctrl;
+ u32 val;
+
+- /* power up the PLL and make sure it's not latched */
+- val = readl(pll->pwr_base + ctrl->aon.offset);
+- val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
+- val &= ~(1 << ctrl->aon.iso_shift);
+- writel(val, pll->pwr_base + ctrl->aon.offset);
++ if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
++ val = readl(pll->pll_base + ctrl->aon.offset);
++ val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
++ writel(val, pll->pll_base + ctrl->aon.offset);
++
++ if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
++ readl(pll->pll_base + ctrl->aon.offset);
++ }
++
++ if (pll->pwr_base) {
++ /* power up the PLL and make sure it's not latched */
++ val = readl(pll->pwr_base + ctrl->aon.offset);
++ val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
++ val &= ~(1 << ctrl->aon.iso_shift);
++ writel(val, pll->pwr_base + ctrl->aon.offset);
++ }
+
+ /* certain PLLs also need to be ungated from the ASIU top level */
+ if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
+@@ -607,9 +629,8 @@ void __init iproc_pll_clk_setup(struct d
+ if (WARN_ON(!pll->pll_base))
+ goto err_pll_iomap;
+
++ /* Some SoCs do not require the pwr_base, thus failing is not fatal */
+ pll->pwr_base = of_iomap(node, 1);
+- if (WARN_ON(!pll->pwr_base))
+- goto err_pwr_iomap;
+
+ /* some PLLs require gating control at the top ASIU level */
+ if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) {
+@@ -692,9 +713,9 @@ err_pll_register:
+ iounmap(pll->asiu_base);
+
+ err_asiu_iomap:
+- iounmap(pll->pwr_base);
++ if (pll->pwr_base)
++ iounmap(pll->pwr_base);
+
+-err_pwr_iomap:
+ iounmap(pll->pll_base);
+
+ err_pll_iomap:
+--- a/drivers/clk/bcm/clk-iproc.h
++++ b/drivers/clk/bcm/clk-iproc.h
+@@ -49,6 +49,12 @@
+ #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4)
+
+ /*
++ * Some PLLs use a different way to control clock power, via the PWRDWN bit in
++ * the PLL control register
++ */
++#define IPROC_CLK_EMBED_PWRCTRL BIT(5)
++
++/*
+ * Parameters for VCO frequency configuration
+ *
+ * VCO frequency =