aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/db8500-prcmu.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 15:09:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-01 15:09:04 -0400
commit2c0c86d5b67ee04e8b71a2ea2a3af6d224611cfc (patch)
tree84cb3b96e68be80b3e8b6876b27fc9ff6ba0370f /drivers/mfd/db8500-prcmu.c
parentfdb2f9c2ebd4f07d7b11a3bc86d8c669eb841697 (diff)
parent494bfec99922d54054d2d0873f1017680cfc3f13 (diff)
Merge tag 'clk-for-linus' of git://git.linaro.org/people/mturquette/linux
Pull clk framework update from Michael Turquette: "The common clk framework changes for 3.7 are dominated by ARM platform ports to the framework along with one MIPS port, one MFD port, one minor framework enhancement and one helper function for platforms expressing their clock data through device tree." * tag 'clk-for-linus' of git://git.linaro.org/people/mturquette/linux: clk: add of_clk_src_onecell_get() support clk: ux500: Define smp_twd clock for u8500 mfd: dbx500: Provide a more accurate smp_twd clock clk: ux500: Support for prmcu_rate clock clk: Provide option for clk_get_rate to issue hw for new rate clock: max77686: Add driver for Maxim 77686 32Khz crystal oscillator. ARM: ux500: Switch to use common clock framework clk: ux500: Clock definitions for u8500 clk: ux500: First version of clock definitions for ux500 clk: ux500: Adapt PRCMU and PRCC clocks for common clk clk: versatile: make config option boolean clk: add Loongson1B clock support arm: mmp: make all SOCs use common clock by default clk: mmp: add clock definition for mmp2 clk: mmp: add clock definition for pxa910 clk: mmp: add clock definition for pxa168 clk: mmp: add mmp specific clocks clk: convert ARM RealView to common clk clk: prima2: move from arch/arm/mach to drivers/clk ARM: PRIMA2: convert to common clk and finish full clk tree
Diffstat (limited to 'drivers/mfd/db8500-prcmu.c')
-rw-r--r--drivers/mfd/db8500-prcmu.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 0e63cdd9b52a..6b67edbdbd01 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -418,6 +418,9 @@ static struct {
418 418
419static atomic_t ac_wake_req_state = ATOMIC_INIT(0); 419static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
420 420
421/* Functions definition */
422static void compute_armss_rate(void);
423
421/* Spinlocks */ 424/* Spinlocks */
422static DEFINE_SPINLOCK(prcmu_lock); 425static DEFINE_SPINLOCK(prcmu_lock);
423static DEFINE_SPINLOCK(clkout_lock); 426static DEFINE_SPINLOCK(clkout_lock);
@@ -517,6 +520,7 @@ static struct dsiescclk dsiescclk[3] = {
517 } 520 }
518}; 521};
519 522
523
520/* 524/*
521* Used by MCDE to setup all necessary PRCMU registers 525* Used by MCDE to setup all necessary PRCMU registers
522*/ 526*/
@@ -1013,6 +1017,7 @@ int db8500_prcmu_set_arm_opp(u8 opp)
1013 (mb1_transfer.ack.arm_opp != opp)) 1017 (mb1_transfer.ack.arm_opp != opp))
1014 r = -EIO; 1018 r = -EIO;
1015 1019
1020 compute_armss_rate();
1016 mutex_unlock(&mb1_transfer.lock); 1021 mutex_unlock(&mb1_transfer.lock);
1017 1022
1018 return r; 1023 return r;
@@ -1612,6 +1617,7 @@ static unsigned long pll_rate(void __iomem *reg, unsigned long src_rate,
1612 if ((branch == PLL_FIX) || ((branch == PLL_DIV) && 1617 if ((branch == PLL_FIX) || ((branch == PLL_DIV) &&
1613 (val & PRCM_PLL_FREQ_DIV2EN) && 1618 (val & PRCM_PLL_FREQ_DIV2EN) &&
1614 ((reg == PRCM_PLLSOC0_FREQ) || 1619 ((reg == PRCM_PLLSOC0_FREQ) ||
1620 (reg == PRCM_PLLARM_FREQ) ||
1615 (reg == PRCM_PLLDDR_FREQ)))) 1621 (reg == PRCM_PLLDDR_FREQ))))
1616 div *= 2; 1622 div *= 2;
1617 1623
@@ -1661,6 +1667,39 @@ static unsigned long clock_rate(u8 clock)
1661 else 1667 else
1662 return 0; 1668 return 0;
1663} 1669}
1670static unsigned long latest_armss_rate;
1671static unsigned long armss_rate(void)
1672{
1673 return latest_armss_rate;
1674}
1675
1676static void compute_armss_rate(void)
1677{
1678 u32 r;
1679 unsigned long rate;
1680
1681 r = readl(PRCM_ARM_CHGCLKREQ);
1682
1683 if (r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ) {
1684 /* External ARMCLKFIX clock */
1685
1686 rate = pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_FIX);
1687
1688 /* Check PRCM_ARM_CHGCLKREQ divider */
1689 if (!(r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL))
1690 rate /= 2;
1691
1692 /* Check PRCM_ARMCLKFIX_MGT divider */
1693 r = readl(PRCM_ARMCLKFIX_MGT);
1694 r &= PRCM_CLK_MGT_CLKPLLDIV_MASK;
1695 rate /= r;
1696
1697 } else {/* ARM PLL */
1698 rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);
1699 }
1700
1701 latest_armss_rate = rate;
1702}
1664 1703
1665static unsigned long dsiclk_rate(u8 n) 1704static unsigned long dsiclk_rate(u8 n)
1666{ 1705{
@@ -1707,6 +1746,8 @@ unsigned long prcmu_clock_rate(u8 clock)
1707 return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW); 1746 return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
1708 else if (clock == PRCMU_PLLSOC1) 1747 else if (clock == PRCMU_PLLSOC1)
1709 return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW); 1748 return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
1749 else if (clock == PRCMU_ARMSS)
1750 return armss_rate();
1710 else if (clock == PRCMU_PLLDDR) 1751 else if (clock == PRCMU_PLLDDR)
1711 return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW); 1752 return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
1712 else if (clock == PRCMU_PLLDSI) 1753 else if (clock == PRCMU_PLLDSI)
@@ -2693,6 +2734,7 @@ void __init db8500_prcmu_early_init(void)
2693 handle_simple_irq); 2734 handle_simple_irq);
2694 set_irq_flags(irq, IRQF_VALID); 2735 set_irq_flags(irq, IRQF_VALID);
2695 } 2736 }
2737 compute_armss_rate();
2696} 2738}
2697 2739
2698static void __init init_prcm_registers(void) 2740static void __init init_prcm_registers(void)