mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	These patches are written by Broadcom and will be in mainline Linux kernel soon. I had some problems to get them backported to kernel 4.1, so currently they are only available for 4.3. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> SVN-Revision: 47253
		
			
				
	
	
		
			121 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| 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 =
 |