mfd: dbx500: Provide a more accurate smp_twd clock
The local timer clock is based on ARM subsystem clock. This patch obtains a more exact value of that clock by reading PRCMU registers. Using this increases the accuracy of the local timer events. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Rickard Andersson <rickard.andersson@stericsson.com> Signed-off-by: Michel Jaouen <michel.jaouen@stericsson.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mike Turquette <mturquette@linaro.org>
This commit is contained in:
Родитель
70b1fce2ec
Коммит
20aee5b6d7
|
@ -418,6 +418,9 @@ static struct {
|
|||
|
||||
static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
|
||||
|
||||
/* Functions definition */
|
||||
static void compute_armss_rate(void);
|
||||
|
||||
/* Spinlocks */
|
||||
static DEFINE_SPINLOCK(prcmu_lock);
|
||||
static DEFINE_SPINLOCK(clkout_lock);
|
||||
|
@ -517,6 +520,7 @@ static struct dsiescclk dsiescclk[3] = {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Used by MCDE to setup all necessary PRCMU registers
|
||||
*/
|
||||
|
@ -1013,6 +1017,7 @@ int db8500_prcmu_set_arm_opp(u8 opp)
|
|||
(mb1_transfer.ack.arm_opp != opp))
|
||||
r = -EIO;
|
||||
|
||||
compute_armss_rate();
|
||||
mutex_unlock(&mb1_transfer.lock);
|
||||
|
||||
return r;
|
||||
|
@ -1612,6 +1617,7 @@ static unsigned long pll_rate(void __iomem *reg, unsigned long src_rate,
|
|||
if ((branch == PLL_FIX) || ((branch == PLL_DIV) &&
|
||||
(val & PRCM_PLL_FREQ_DIV2EN) &&
|
||||
((reg == PRCM_PLLSOC0_FREQ) ||
|
||||
(reg == PRCM_PLLARM_FREQ) ||
|
||||
(reg == PRCM_PLLDDR_FREQ))))
|
||||
div *= 2;
|
||||
|
||||
|
@ -1661,6 +1667,39 @@ static unsigned long clock_rate(u8 clock)
|
|||
else
|
||||
return 0;
|
||||
}
|
||||
static unsigned long latest_armss_rate;
|
||||
static unsigned long armss_rate(void)
|
||||
{
|
||||
return latest_armss_rate;
|
||||
}
|
||||
|
||||
static void compute_armss_rate(void)
|
||||
{
|
||||
u32 r;
|
||||
unsigned long rate;
|
||||
|
||||
r = readl(PRCM_ARM_CHGCLKREQ);
|
||||
|
||||
if (r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ) {
|
||||
/* External ARMCLKFIX clock */
|
||||
|
||||
rate = pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_FIX);
|
||||
|
||||
/* Check PRCM_ARM_CHGCLKREQ divider */
|
||||
if (!(r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL))
|
||||
rate /= 2;
|
||||
|
||||
/* Check PRCM_ARMCLKFIX_MGT divider */
|
||||
r = readl(PRCM_ARMCLKFIX_MGT);
|
||||
r &= PRCM_CLK_MGT_CLKPLLDIV_MASK;
|
||||
rate /= r;
|
||||
|
||||
} else {/* ARM PLL */
|
||||
rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);
|
||||
}
|
||||
|
||||
latest_armss_rate = rate;
|
||||
}
|
||||
|
||||
static unsigned long dsiclk_rate(u8 n)
|
||||
{
|
||||
|
@ -1707,6 +1746,8 @@ unsigned long prcmu_clock_rate(u8 clock)
|
|||
return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
|
||||
else if (clock == PRCMU_PLLSOC1)
|
||||
return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
|
||||
else if (clock == PRCMU_ARMSS)
|
||||
return armss_rate();
|
||||
else if (clock == PRCMU_PLLDDR)
|
||||
return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
|
||||
else if (clock == PRCMU_PLLDSI)
|
||||
|
@ -2693,6 +2734,7 @@ void __init db8500_prcmu_early_init(void)
|
|||
handle_simple_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
compute_armss_rate();
|
||||
}
|
||||
|
||||
static void __init init_prcm_registers(void)
|
||||
|
|
|
@ -61,7 +61,8 @@
|
|||
#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2
|
||||
|
||||
#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114)
|
||||
#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ 0x1
|
||||
#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0)
|
||||
#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL BIT(16)
|
||||
|
||||
#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98)
|
||||
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1
|
||||
|
@ -140,6 +141,7 @@
|
|||
/* PRCMU clock/PLL/reset registers */
|
||||
#define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080)
|
||||
#define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084)
|
||||
#define PRCM_PLLARM_FREQ (_PRCMU_BASE + 0x088)
|
||||
#define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C)
|
||||
#define PRCM_PLL_FREQ_D_SHIFT 0
|
||||
#define PRCM_PLL_FREQ_D_MASK BITS(0, 7)
|
||||
|
|
|
@ -136,6 +136,7 @@ enum prcmu_clock {
|
|||
PRCMU_TIMCLK,
|
||||
PRCMU_PLLSOC0,
|
||||
PRCMU_PLLSOC1,
|
||||
PRCMU_ARMSS,
|
||||
PRCMU_PLLDDR,
|
||||
PRCMU_PLLDSI,
|
||||
PRCMU_DSI0CLK,
|
||||
|
|
Загрузка…
Ссылка в новой задаче