Commit ccea0e6e authored by Michal Simek's avatar Michal Simek

microblaze: Support timer on AXI lite

New microblaze systems uses two buses. One for memories
and flashes and the second for low-speed peripherals
which can run on different CLK. This is the reason
why the kernel is trying to read clock-frequency
directly from node. If there is then the kernel will
work with it. If not then cpu CLK is used.
Signed-off-by: default avatarMichal Simek <monstr@monstr.eu>
parent 02b08045
...@@ -77,7 +77,6 @@ struct cpuinfo { ...@@ -77,7 +77,6 @@ struct cpuinfo {
u32 num_rd_brk; u32 num_rd_brk;
u32 num_wr_brk; u32 num_wr_brk;
u32 cpu_clock_freq; /* store real freq of cpu */ u32 cpu_clock_freq; /* store real freq of cpu */
u32 freq_div_hz; /* store freq/HZ */
/* FPGA family */ /* FPGA family */
u32 fpga_family_code; u32 fpga_family_code;
......
...@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr; ...@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr;
#define TIMER_BASE timer_baseaddr #define TIMER_BASE timer_baseaddr
#endif #endif
unsigned int freq_div_hz;
unsigned int timer_clock_freq;
#define TCSR0 (0x00) #define TCSR0 (0x00)
#define TLR0 (0x04) #define TLR0 (0x04)
#define TCR0 (0x08) #define TCR0 (0x08)
...@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode, ...@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
switch (mode) { switch (mode) {
case CLOCK_EVT_MODE_PERIODIC: case CLOCK_EVT_MODE_PERIODIC:
printk(KERN_INFO "%s: periodic\n", __func__); printk(KERN_INFO "%s: periodic\n", __func__);
microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); microblaze_timer0_start_periodic(freq_div_hz);
break; break;
case CLOCK_EVT_MODE_ONESHOT: case CLOCK_EVT_MODE_ONESHOT:
printk(KERN_INFO "%s: oneshot\n", __func__); printk(KERN_INFO "%s: oneshot\n", __func__);
...@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = { ...@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
static __init void microblaze_clockevent_init(void) static __init void microblaze_clockevent_init(void)
{ {
clockevent_microblaze_timer.mult = clockevent_microblaze_timer.mult =
div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, div_sc(timer_clock_freq, NSEC_PER_SEC,
clockevent_microblaze_timer.shift); clockevent_microblaze_timer.shift);
clockevent_microblaze_timer.max_delta_ns = clockevent_microblaze_timer.max_delta_ns =
clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
...@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = { ...@@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = {
int __init init_microblaze_timecounter(void) int __init init_microblaze_timecounter(void)
{ {
microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
microblaze_cc.shift); microblaze_cc.shift);
timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock()); timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
...@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = { ...@@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = {
static int __init microblaze_clocksource_init(void) static int __init microblaze_clocksource_init(void)
{ {
clocksource_microblaze.mult = clocksource_microblaze.mult =
clocksource_hz2mult(cpuinfo.cpu_clock_freq, clocksource_hz2mult(timer_clock_freq,
clocksource_microblaze.shift); clocksource_microblaze.shift);
if (clocksource_register(&clocksource_microblaze)) if (clocksource_register(&clocksource_microblaze))
panic("failed to register clocksource"); panic("failed to register clocksource");
...@@ -247,6 +250,7 @@ void __init time_init(void) ...@@ -247,6 +250,7 @@ void __init time_init(void)
u32 irq, i = 0; u32 irq, i = 0;
u32 timer_num = 1; u32 timer_num = 1;
struct device_node *timer = NULL; struct device_node *timer = NULL;
const void *prop;
#ifdef CONFIG_SELFMOD_TIMER #ifdef CONFIG_SELFMOD_TIMER
unsigned int timer_baseaddr = 0; unsigned int timer_baseaddr = 0;
int arr_func[] = { int arr_func[] = {
...@@ -286,7 +290,14 @@ void __init time_init(void) ...@@ -286,7 +290,14 @@ void __init time_init(void)
printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
timer_list[i], timer_baseaddr, irq); timer_list[i], timer_baseaddr, irq);
cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; /* If there is clock-frequency property than use it */
prop = of_get_property(timer, "clock-frequency", NULL);
if (prop)
timer_clock_freq = be32_to_cpup(prop);
else
timer_clock_freq = cpuinfo.cpu_clock_freq;
freq_div_hz = timer_clock_freq / HZ;
setup_irq(irq, &timer_irqaction); setup_irq(irq, &timer_irqaction);
#ifdef CONFIG_HEART_BEAT #ifdef CONFIG_HEART_BEAT
......
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