12 #include <linux/kernel.h>
18 #include <linux/sched.h>
26 #include <asm/cpuinfo.h>
27 #include <asm/setup.h>
32 #ifdef CONFIG_SELFMOD_TIMER
34 #define TIMER_BASE BARRIER_BASE_ADDR
36 static unsigned int timer_baseaddr;
37 #define TIMER_BASE timer_baseaddr
40 static unsigned int freq_div_hz;
41 static unsigned int timer_clock_freq;
50 #define TCSR_MDT (1<<0)
51 #define TCSR_UDT (1<<1)
52 #define TCSR_GENT (1<<2)
53 #define TCSR_CAPT (1<<3)
54 #define TCSR_ARHT (1<<4)
55 #define TCSR_LOAD (1<<5)
56 #define TCSR_ENIT (1<<6)
57 #define TCSR_ENT (1<<7)
58 #define TCSR_TINT (1<<8)
59 #define TCSR_PWMA (1<<9)
60 #define TCSR_ENALL (1<<10)
62 static inline void microblaze_timer0_stop(
void)
67 static inline void microblaze_timer0_start_periodic(
unsigned long load_val)
93 static inline void microblaze_timer0_start_oneshot(
unsigned long load_val)
106 static int microblaze_timer_set_next_event(
unsigned long delta,
107 struct clock_event_device *
dev)
109 pr_debug(
"%s: next event, delta %x\n", __func__, (
u32)delta);
110 microblaze_timer0_start_oneshot(delta);
114 static void microblaze_timer_set_mode(
enum clock_event_mode
mode,
115 struct clock_event_device *
evt)
118 case CLOCK_EVT_MODE_PERIODIC:
119 pr_info(
"%s: periodic\n", __func__);
120 microblaze_timer0_start_periodic(freq_div_hz);
122 case CLOCK_EVT_MODE_ONESHOT:
123 pr_info(
"%s: oneshot\n", __func__);
125 case CLOCK_EVT_MODE_UNUSED:
126 pr_info(
"%s: unused\n", __func__);
128 case CLOCK_EVT_MODE_SHUTDOWN:
129 pr_info(
"%s: shutdown\n", __func__);
130 microblaze_timer0_stop();
132 case CLOCK_EVT_MODE_RESUME:
133 pr_info(
"%s: resume\n", __func__);
138 static struct clock_event_device clockevent_microblaze_timer = {
139 .name =
"microblaze_clockevent",
140 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
143 .set_next_event = microblaze_timer_set_next_event,
144 .set_mode = microblaze_timer_set_mode,
147 static inline void timer_ack(
void)
154 struct clock_event_device *evt = &clockevent_microblaze_timer;
155 #ifdef CONFIG_HEART_BEAT
159 evt->event_handler(evt);
167 .dev_id = &clockevent_microblaze_timer,
170 static __init void microblaze_clockevent_init(
void)
172 clockevent_microblaze_timer.mult =
174 clockevent_microblaze_timer.shift);
175 clockevent_microblaze_timer.max_delta_ns =
177 clockevent_microblaze_timer.min_delta_ns =
179 clockevent_microblaze_timer.cpumask =
cpumask_of(0);
195 return microblaze_read(
NULL);
199 .read = microblaze_cc_read,
204 static int __init init_microblaze_timecounter(
void)
207 microblaze_cc.
shift);
214 static struct clocksource clocksource_microblaze = {
215 .name =
"microblaze_clocksource",
217 .read = microblaze_read,
222 static int __init microblaze_clocksource_init(
void)
224 if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq))
225 panic(
"failed to register clocksource");
233 init_microblaze_timecounter();
241 static int timer_initialized;
249 #ifdef CONFIG_SELFMOD_TIMER
250 unsigned int timer_baseaddr = 0;
252 (
int)µblaze_read,
254 (
int)µblaze_clocksource_init,
255 (
int)µblaze_timer_set_mode,
256 (
int)µblaze_timer_set_next_event,
264 pr_info(
"No chosen timer found, using default\n");
268 "xlnx,xps-timer-1.00.a");
275 "xlnx,one-timer-only",
NULL));
277 pr_emerg(
"Please enable two timers in HW\n");
281 #ifdef CONFIG_SELFMOD_TIMER
284 pr_info(
"%s #0 at 0x%08x, irq=%d\n",
285 timer->
name, timer_baseaddr, irq);
294 freq_div_hz = timer_clock_freq /
HZ;
297 #ifdef CONFIG_HEART_BEAT
300 microblaze_clocksource_init();
301 microblaze_clockevent_init();
302 timer_initialized = 1;
307 if (timer_initialized) {
311 return clocksource_cyc2ns(cyc, cs->
mult, cs->
shift);