diff options
| -rw-r--r-- | drivers/mfd/db8500-prcmu.c | 42 | ||||
| -rw-r--r-- | drivers/mfd/dbx500-prcmu-regs.h | 4 | ||||
| -rw-r--r-- | include/linux/mfd/dbx500-prcmu.h | 1 |
3 files changed, 46 insertions, 1 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 7040a0081130..6b37e2d6ed8f 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
| @@ -418,6 +418,9 @@ static struct { | |||
| 418 | 418 | ||
| 419 | static atomic_t ac_wake_req_state = ATOMIC_INIT(0); | 419 | static atomic_t ac_wake_req_state = ATOMIC_INIT(0); |
| 420 | 420 | ||
| 421 | /* Functions definition */ | ||
| 422 | static void compute_armss_rate(void); | ||
| 423 | |||
| 421 | /* Spinlocks */ | 424 | /* Spinlocks */ |
| 422 | static DEFINE_SPINLOCK(prcmu_lock); | 425 | static DEFINE_SPINLOCK(prcmu_lock); |
| 423 | static DEFINE_SPINLOCK(clkout_lock); | 426 | static 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 | } |
| 1670 | static unsigned long latest_armss_rate; | ||
| 1671 | static unsigned long armss_rate(void) | ||
| 1672 | { | ||
| 1673 | return latest_armss_rate; | ||
| 1674 | } | ||
| 1675 | |||
| 1676 | static 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 | ||
| 1665 | static unsigned long dsiclk_rate(u8 n) | 1704 | static 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 | ||
| 2698 | static void __init init_prcm_registers(void) | 2740 | static void __init init_prcm_registers(void) |
diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h index 23108a6e3167..79c76ebdba52 100644 --- a/drivers/mfd/dbx500-prcmu-regs.h +++ b/drivers/mfd/dbx500-prcmu-regs.h | |||
| @@ -61,7 +61,8 @@ | |||
| 61 | #define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 | 61 | #define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 |
| 62 | 62 | ||
| 63 | #define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) | 63 | #define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) |
| 64 | #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ 0x1 | 64 | #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0) |
| 65 | #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL BIT(16) | ||
| 65 | 66 | ||
| 66 | #define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) | 67 | #define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) |
| 67 | #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 | 68 | #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 |
| @@ -140,6 +141,7 @@ | |||
| 140 | /* PRCMU clock/PLL/reset registers */ | 141 | /* PRCMU clock/PLL/reset registers */ |
| 141 | #define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080) | 142 | #define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080) |
| 142 | #define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084) | 143 | #define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084) |
| 144 | #define PRCM_PLLARM_FREQ (_PRCMU_BASE + 0x088) | ||
| 143 | #define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C) | 145 | #define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C) |
| 144 | #define PRCM_PLL_FREQ_D_SHIFT 0 | 146 | #define PRCM_PLL_FREQ_D_SHIFT 0 |
| 145 | #define PRCM_PLL_FREQ_D_MASK BITS(0, 7) | 147 | #define PRCM_PLL_FREQ_D_MASK BITS(0, 7) |
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index 5b90e94399e1..c410d99bd667 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h | |||
| @@ -136,6 +136,7 @@ enum prcmu_clock { | |||
| 136 | PRCMU_TIMCLK, | 136 | PRCMU_TIMCLK, |
| 137 | PRCMU_PLLSOC0, | 137 | PRCMU_PLLSOC0, |
| 138 | PRCMU_PLLSOC1, | 138 | PRCMU_PLLSOC1, |
| 139 | PRCMU_ARMSS, | ||
| 139 | PRCMU_PLLDDR, | 140 | PRCMU_PLLDDR, |
| 140 | PRCMU_PLLDSI, | 141 | PRCMU_PLLDSI, |
| 141 | PRCMU_DSI0CLK, | 142 | PRCMU_DSI0CLK, |
