Commit ef8fe6fe authored by Tony Lindgren's avatar Tony Lindgren

Merge branch 'devel-dt-arch-timer' into devel-dt

parents 3fe05bd9 0c9de3c5
...@@ -33,9 +33,21 @@ aliases { ...@@ -33,9 +33,21 @@ aliases {
cpus { cpus {
cpu@0 { cpu@0 {
compatible = "arm,cortex-a15"; compatible = "arm,cortex-a15";
timer {
compatible = "arm,armv7-timer";
/* 14th PPI IRQ, active low level-sensitive */
interrupts = <1 14 0x308>;
clock-frequency = <6144000>;
};
}; };
cpu@1 { cpu@1 {
compatible = "arm,cortex-a15"; compatible = "arm,cortex-a15";
timer {
compatible = "arm,armv7-timer";
/* 14th PPI IRQ, active low level-sensitive */
interrupts = <1 14 0x308>;
clock-frequency = <6144000>;
};
}; };
}; };
......
...@@ -25,6 +25,9 @@ config ARCH_OMAP2PLUS_TYPICAL ...@@ -25,6 +25,9 @@ config ARCH_OMAP2PLUS_TYPICAL
config SOC_HAS_OMAP2_SDRC config SOC_HAS_OMAP2_SDRC
bool "OMAP2 SDRAM Controller support" bool "OMAP2 SDRAM Controller support"
config SOC_HAS_REALTIME_COUNTER
bool "Real time free running counter"
config ARCH_OMAP2 config ARCH_OMAP2
bool "TI OMAP2" bool "TI OMAP2"
depends on ARCH_OMAP2PLUS depends on ARCH_OMAP2PLUS
...@@ -71,6 +74,8 @@ config SOC_OMAP5 ...@@ -71,6 +74,8 @@ config SOC_OMAP5
select ARM_GIC select ARM_GIC
select HAVE_SMP select HAVE_SMP
select ARM_CPU_SUSPEND if PM select ARM_CPU_SUSPEND if PM
select SOC_HAS_REALTIME_COUNTER
select ARM_ARCH_TIMER
comment "OMAP Core Type" comment "OMAP Core Type"
depends on ARCH_OMAP2 depends on ARCH_OMAP2
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <asm/smp_twd.h> #include <asm/smp_twd.h>
#include <asm/sched_clock.h> #include <asm/sched_clock.h>
#include <asm/arch_timer.h>
#include <plat/omap_hwmod.h> #include <plat/omap_hwmod.h>
#include <plat/omap_device.h> #include <plat/omap_device.h>
#include <plat/dmtimer.h> #include <plat/dmtimer.h>
...@@ -72,6 +73,11 @@ ...@@ -72,6 +73,11 @@
#define OMAP3_SECURE_TIMER 1 #define OMAP3_SECURE_TIMER 1
#endif #endif
#define REALTIME_COUNTER_BASE 0x48243200
#define INCREMENTER_NUMERATOR_OFFSET 0x10
#define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
#define NUMERATOR_DENUMERATOR_MASK 0xfffff000
/* Clockevent code */ /* Clockevent code */
static struct omap_dm_timer clkev; static struct omap_dm_timer clkev;
...@@ -349,6 +355,84 @@ static void __init omap2_clocksource_init(int gptimer_id, ...@@ -349,6 +355,84 @@ static void __init omap2_clocksource_init(int gptimer_id,
omap2_gptimer_clocksource_init(gptimer_id, fck_source); 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, \ #define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \
clksrc_nr, clksrc_src) \ clksrc_nr, clksrc_src) \
static void __init omap##name##_timer_init(void) \ static void __init omap##name##_timer_init(void) \
...@@ -410,7 +494,18 @@ OMAP_SYS_TIMER(4) ...@@ -410,7 +494,18 @@ OMAP_SYS_TIMER(4)
#endif #endif
#ifdef CONFIG_SOC_OMAP5 #ifdef CONFIG_SOC_OMAP5
OMAP_SYS_TIMER_INIT(5, 1, OMAP4_CLKEV_SOURCE, 2, OMAP4_MPU_SOURCE) static void __init omap5_timer_init(void)
{
int err;
omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
realtime_counter_init();
err = arch_timer_of_register();
if (err)
pr_err("%s: arch_timer_register failed %d\n", __func__, err);
}
OMAP_SYS_TIMER(5) OMAP_SYS_TIMER(5)
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment