From 716ca530e1c4515d8683c9d5be3d56b301758b66 Mon Sep 17 00:00:00 2001 From: James <> Date: Wed, 4 Nov 2015 11:49:21 +0000 Subject: trunk-47381 --- .../045-clk-iproc-Add-PWRCTRL-support.patch | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 target/linux/bcm53xx/patches-4.3/045-clk-iproc-Add-PWRCTRL-support.patch (limited to 'target/linux/bcm53xx/patches-4.3/045-clk-iproc-Add-PWRCTRL-support.patch') 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 +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 +--- + 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 = -- cgit v1.2.3