Skip to content

Commit

Permalink
ARM: OMAP: Add initialisation for the real-time counter.
Browse files Browse the repository at this point in the history
The real time counter also called master counter, is a free-running
counter. It produces the count used by the CPU local timer peripherals
in the MPU cluster. The timer counts at a rate of 6.144 MHz.

The ratio registers needs to be configured based on system clock
only onetime. After initialisation, hardware takes care of adjusting
the clock in different low power modes to keep counter rate constant.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
  • Loading branch information
Santosh Shilimkar committed Sep 19, 2012
1 parent 5698bd7 commit fa6d79d
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 1 deletion.
4 changes: 4 additions & 0 deletions arch/arm/mach-omap2/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ config ARCH_OMAP2PLUS_TYPICAL
config SOC_HAS_OMAP2_SDRC
bool "OMAP2 SDRAM Controller support"

config SOC_HAS_REALTIME_COUNTER
bool "Real time free running counter"

config ARCH_OMAP2
bool "TI OMAP2"
depends on ARCH_OMAP2PLUS
Expand Down Expand Up @@ -70,6 +73,7 @@ config SOC_OMAP5
select ARM_GIC
select HAVE_SMP
select ARM_CPU_SUSPEND if PM
select SOC_HAS_REALTIME_COUNTER

comment "OMAP Core Type"
depends on ARCH_OMAP2
Expand Down
90 changes: 89 additions & 1 deletion arch/arm/mach-omap2/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
#define OMAP3_SECURE_TIMER 1
#endif

#define REALTIME_COUNTER_BASE 0x48243200
#define INCREMENTER_NUMERATOR_OFFSET 0x10
#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
#define NUMERATOR_DENUMERATOR_MASK 0xfffff000

/* Clockevent code */

static struct omap_dm_timer clkev;
Expand Down Expand Up @@ -346,6 +351,84 @@ static void __init omap2_clocksource_init(int gptimer_id,
omap2_gptimer_clocksource_init(gptimer_id, fck_source);
}

#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
/*
* The realtime counter also called master counter, is a free-running
* counter, which is related to real time. It produces the count used
* by the CPU local timer peripherals in the MPU cluster. The timer counts
* at a rate of 6.144 MHz. Because the device operates on different clocks
* in different power modes, the master counter shifts operation between
* clocks, adjusting the increment per clock in hardware accordingly to
* maintain a constant count rate.
*/
static void __init realtime_counter_init(void)
{
void __iomem *base;
static struct clk *sys_clk;
unsigned long rate;
unsigned int reg, num, den;

base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
if (!base) {
pr_err("%s: ioremap failed\n", __func__);
return;
}
sys_clk = clk_get(NULL, "sys_clkin_ck");
if (!sys_clk) {
pr_err("%s: failed to get system clock handle\n", __func__);
iounmap(base);
return;
}

rate = clk_get_rate(sys_clk);
/* Numerator/denumerator values refer TRM Realtime Counter section */
switch (rate) {
case 1200000:
num = 64;
den = 125;
break;
case 1300000:
num = 768;
den = 1625;
break;
case 19200000:
num = 8;
den = 25;
break;
case 2600000:
num = 384;
den = 1625;
break;
case 2700000:
num = 256;
den = 1125;
break;
case 38400000:
default:
/* Program it for 38.4 MHz */
num = 4;
den = 25;
break;
}

/* Program numerator and denumerator registers */
reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
NUMERATOR_DENUMERATOR_MASK;
reg |= num;
__raw_writel(reg, base + INCREMENTER_NUMERATOR_OFFSET);

reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) &
NUMERATOR_DENUMERATOR_MASK;
reg |= den;
__raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);

iounmap(base);
}
#else
static inline void __init realtime_counter_init(void)
{}
#endif

#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \
clksrc_nr, clksrc_src) \
static void __init omap##name##_timer_init(void) \
Expand Down Expand Up @@ -403,7 +486,12 @@ OMAP_SYS_TIMER(4)
#endif

#ifdef CONFIG_SOC_OMAP5
OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE)
static void __init omap5_timer_init(void)
{
omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
realtime_counter_init();
}
OMAP_SYS_TIMER(5)
#endif

Expand Down

0 comments on commit fa6d79d

Please sign in to comment.