xref: /openbmc/linux/arch/nios2/kernel/time.c (revision 5dc4dca4)
14182de9eSLey Foon Tan /*
24182de9eSLey Foon Tan  * Copyright (C) 2013-2014 Altera Corporation
34182de9eSLey Foon Tan  * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
44182de9eSLey Foon Tan  * Copyright (C) 2004 Microtronix Datacom Ltd.
54182de9eSLey Foon Tan  *
64182de9eSLey Foon Tan  * This file is subject to the terms and conditions of the GNU General Public
74182de9eSLey Foon Tan  * License. See the file "COPYING" in the main directory of this archive
84182de9eSLey Foon Tan  * for more details.
94182de9eSLey Foon Tan  */
104182de9eSLey Foon Tan 
1105dee9c7SHerbert Xu #include <linux/export.h>
124182de9eSLey Foon Tan #include <linux/interrupt.h>
134182de9eSLey Foon Tan #include <linux/clockchips.h>
144182de9eSLey Foon Tan #include <linux/clocksource.h>
154182de9eSLey Foon Tan #include <linux/delay.h>
164182de9eSLey Foon Tan #include <linux/of.h>
174182de9eSLey Foon Tan #include <linux/of_address.h>
184182de9eSLey Foon Tan #include <linux/of_irq.h>
194182de9eSLey Foon Tan #include <linux/io.h>
204182de9eSLey Foon Tan #include <linux/slab.h>
214182de9eSLey Foon Tan 
22a8955cc3SLey Foon Tan #define ALTR_TIMER_COMPATIBLE		"altr,timer-1.0"
23a8955cc3SLey Foon Tan 
244182de9eSLey Foon Tan #define ALTERA_TIMER_STATUS_REG	0
254182de9eSLey Foon Tan #define ALTERA_TIMER_CONTROL_REG	4
264182de9eSLey Foon Tan #define ALTERA_TIMER_PERIODL_REG	8
274182de9eSLey Foon Tan #define ALTERA_TIMER_PERIODH_REG	12
284182de9eSLey Foon Tan #define ALTERA_TIMER_SNAPL_REG		16
294182de9eSLey Foon Tan #define ALTERA_TIMER_SNAPH_REG		20
304182de9eSLey Foon Tan 
314182de9eSLey Foon Tan #define ALTERA_TIMER_CONTROL_ITO_MSK	(0x1)
324182de9eSLey Foon Tan #define ALTERA_TIMER_CONTROL_CONT_MSK	(0x2)
334182de9eSLey Foon Tan #define ALTERA_TIMER_CONTROL_START_MSK	(0x4)
344182de9eSLey Foon Tan #define ALTERA_TIMER_CONTROL_STOP_MSK	(0x8)
354182de9eSLey Foon Tan 
364182de9eSLey Foon Tan struct nios2_timer {
374182de9eSLey Foon Tan 	void __iomem *base;
384182de9eSLey Foon Tan 	unsigned long freq;
394182de9eSLey Foon Tan };
404182de9eSLey Foon Tan 
414182de9eSLey Foon Tan struct nios2_clockevent_dev {
424182de9eSLey Foon Tan 	struct nios2_timer timer;
434182de9eSLey Foon Tan 	struct clock_event_device ced;
444182de9eSLey Foon Tan };
454182de9eSLey Foon Tan 
464182de9eSLey Foon Tan struct nios2_clocksource {
474182de9eSLey Foon Tan 	struct nios2_timer timer;
484182de9eSLey Foon Tan 	struct clocksource cs;
494182de9eSLey Foon Tan };
504182de9eSLey Foon Tan 
514182de9eSLey Foon Tan static inline struct nios2_clockevent_dev *
to_nios2_clkevent(struct clock_event_device * evt)524182de9eSLey Foon Tan 	to_nios2_clkevent(struct clock_event_device *evt)
534182de9eSLey Foon Tan {
544182de9eSLey Foon Tan 	return container_of(evt, struct nios2_clockevent_dev, ced);
554182de9eSLey Foon Tan }
564182de9eSLey Foon Tan 
574182de9eSLey Foon Tan static inline struct nios2_clocksource *
to_nios2_clksource(struct clocksource * cs)584182de9eSLey Foon Tan 	to_nios2_clksource(struct clocksource *cs)
594182de9eSLey Foon Tan {
604182de9eSLey Foon Tan 	return container_of(cs, struct nios2_clocksource, cs);
614182de9eSLey Foon Tan }
624182de9eSLey Foon Tan 
timer_readw(struct nios2_timer * timer,u32 offs)634182de9eSLey Foon Tan static u16 timer_readw(struct nios2_timer *timer, u32 offs)
644182de9eSLey Foon Tan {
654182de9eSLey Foon Tan 	return readw(timer->base + offs);
664182de9eSLey Foon Tan }
674182de9eSLey Foon Tan 
timer_writew(struct nios2_timer * timer,u16 val,u32 offs)684182de9eSLey Foon Tan static void timer_writew(struct nios2_timer *timer, u16 val, u32 offs)
694182de9eSLey Foon Tan {
704182de9eSLey Foon Tan 	writew(val, timer->base + offs);
714182de9eSLey Foon Tan }
724182de9eSLey Foon Tan 
read_timersnapshot(struct nios2_timer * timer)734182de9eSLey Foon Tan static inline unsigned long read_timersnapshot(struct nios2_timer *timer)
744182de9eSLey Foon Tan {
754182de9eSLey Foon Tan 	unsigned long count;
764182de9eSLey Foon Tan 
774182de9eSLey Foon Tan 	timer_writew(timer, 0, ALTERA_TIMER_SNAPL_REG);
784182de9eSLey Foon Tan 	count = timer_readw(timer, ALTERA_TIMER_SNAPH_REG) << 16 |
794182de9eSLey Foon Tan 		timer_readw(timer, ALTERA_TIMER_SNAPL_REG);
804182de9eSLey Foon Tan 
814182de9eSLey Foon Tan 	return count;
824182de9eSLey Foon Tan }
834182de9eSLey Foon Tan 
nios2_timer_read(struct clocksource * cs)84a5a1d1c2SThomas Gleixner static u64 nios2_timer_read(struct clocksource *cs)
854182de9eSLey Foon Tan {
864182de9eSLey Foon Tan 	struct nios2_clocksource *nios2_cs = to_nios2_clksource(cs);
874182de9eSLey Foon Tan 	unsigned long flags;
884182de9eSLey Foon Tan 	u32 count;
894182de9eSLey Foon Tan 
904182de9eSLey Foon Tan 	local_irq_save(flags);
914182de9eSLey Foon Tan 	count = read_timersnapshot(&nios2_cs->timer);
924182de9eSLey Foon Tan 	local_irq_restore(flags);
934182de9eSLey Foon Tan 
944182de9eSLey Foon Tan 	/* Counter is counting down */
954182de9eSLey Foon Tan 	return ~count;
964182de9eSLey Foon Tan }
974182de9eSLey Foon Tan 
984182de9eSLey Foon Tan static struct nios2_clocksource nios2_cs = {
994182de9eSLey Foon Tan 	.cs = {
1004182de9eSLey Foon Tan 		.name	= "nios2-clksrc",
1014182de9eSLey Foon Tan 		.rating	= 250,
1024182de9eSLey Foon Tan 		.read	= nios2_timer_read,
1034182de9eSLey Foon Tan 		.mask	= CLOCKSOURCE_MASK(32),
1044182de9eSLey Foon Tan 		.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
1054182de9eSLey Foon Tan 	},
1064182de9eSLey Foon Tan };
1074182de9eSLey Foon Tan 
get_cycles(void)1084182de9eSLey Foon Tan cycles_t get_cycles(void)
1094182de9eSLey Foon Tan {
11065d1e3ddSGuenter Roeck 	/* Only read timer if it has been initialized */
11165d1e3ddSGuenter Roeck 	if (nios2_cs.timer.base)
1124182de9eSLey Foon Tan 		return nios2_timer_read(&nios2_cs.cs);
11365d1e3ddSGuenter Roeck 	return 0;
1144182de9eSLey Foon Tan }
11505dee9c7SHerbert Xu EXPORT_SYMBOL(get_cycles);
1164182de9eSLey Foon Tan 
nios2_timer_start(struct nios2_timer * timer)1174182de9eSLey Foon Tan static void nios2_timer_start(struct nios2_timer *timer)
1184182de9eSLey Foon Tan {
1194182de9eSLey Foon Tan 	u16 ctrl;
1204182de9eSLey Foon Tan 
1214182de9eSLey Foon Tan 	ctrl = timer_readw(timer, ALTERA_TIMER_CONTROL_REG);
1224182de9eSLey Foon Tan 	ctrl |= ALTERA_TIMER_CONTROL_START_MSK;
1234182de9eSLey Foon Tan 	timer_writew(timer, ctrl, ALTERA_TIMER_CONTROL_REG);
1244182de9eSLey Foon Tan }
1254182de9eSLey Foon Tan 
nios2_timer_stop(struct nios2_timer * timer)1264182de9eSLey Foon Tan static void nios2_timer_stop(struct nios2_timer *timer)
1274182de9eSLey Foon Tan {
1284182de9eSLey Foon Tan 	u16 ctrl;
1294182de9eSLey Foon Tan 
1304182de9eSLey Foon Tan 	ctrl = timer_readw(timer, ALTERA_TIMER_CONTROL_REG);
1314182de9eSLey Foon Tan 	ctrl |= ALTERA_TIMER_CONTROL_STOP_MSK;
1324182de9eSLey Foon Tan 	timer_writew(timer, ctrl, ALTERA_TIMER_CONTROL_REG);
1334182de9eSLey Foon Tan }
1344182de9eSLey Foon Tan 
nios2_timer_config(struct nios2_timer * timer,unsigned long period,bool periodic)1354182de9eSLey Foon Tan static void nios2_timer_config(struct nios2_timer *timer, unsigned long period,
136549a14c1SViresh Kumar 			       bool periodic)
1374182de9eSLey Foon Tan {
1384182de9eSLey Foon Tan 	u16 ctrl;
1394182de9eSLey Foon Tan 
1404182de9eSLey Foon Tan 	/* The timer's actual period is one cycle greater than the value
1414182de9eSLey Foon Tan 	 * stored in the period register. */
1424182de9eSLey Foon Tan 	 period--;
1434182de9eSLey Foon Tan 
1444182de9eSLey Foon Tan 	ctrl = timer_readw(timer, ALTERA_TIMER_CONTROL_REG);
1454182de9eSLey Foon Tan 	/* stop counter */
1464182de9eSLey Foon Tan 	timer_writew(timer, ctrl | ALTERA_TIMER_CONTROL_STOP_MSK,
1474182de9eSLey Foon Tan 		ALTERA_TIMER_CONTROL_REG);
1484182de9eSLey Foon Tan 
1494182de9eSLey Foon Tan 	/* write new count */
1504182de9eSLey Foon Tan 	timer_writew(timer, period, ALTERA_TIMER_PERIODL_REG);
1514182de9eSLey Foon Tan 	timer_writew(timer, period >> 16, ALTERA_TIMER_PERIODH_REG);
1524182de9eSLey Foon Tan 
1534182de9eSLey Foon Tan 	ctrl |= ALTERA_TIMER_CONTROL_START_MSK | ALTERA_TIMER_CONTROL_ITO_MSK;
154549a14c1SViresh Kumar 	if (periodic)
1554182de9eSLey Foon Tan 		ctrl |= ALTERA_TIMER_CONTROL_CONT_MSK;
1564182de9eSLey Foon Tan 	else
1574182de9eSLey Foon Tan 		ctrl &= ~ALTERA_TIMER_CONTROL_CONT_MSK;
1584182de9eSLey Foon Tan 	timer_writew(timer, ctrl, ALTERA_TIMER_CONTROL_REG);
1594182de9eSLey Foon Tan }
1604182de9eSLey Foon Tan 
nios2_timer_set_next_event(unsigned long delta,struct clock_event_device * evt)1614182de9eSLey Foon Tan static int nios2_timer_set_next_event(unsigned long delta,
1624182de9eSLey Foon Tan 	struct clock_event_device *evt)
1634182de9eSLey Foon Tan {
1644182de9eSLey Foon Tan 	struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
1654182de9eSLey Foon Tan 
166549a14c1SViresh Kumar 	nios2_timer_config(&nios2_ced->timer, delta, false);
1674182de9eSLey Foon Tan 
1684182de9eSLey Foon Tan 	return 0;
1694182de9eSLey Foon Tan }
1704182de9eSLey Foon Tan 
nios2_timer_shutdown(struct clock_event_device * evt)171549a14c1SViresh Kumar static int nios2_timer_shutdown(struct clock_event_device *evt)
172549a14c1SViresh Kumar {
173549a14c1SViresh Kumar 	struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
174549a14c1SViresh Kumar 	struct nios2_timer *timer = &nios2_ced->timer;
175549a14c1SViresh Kumar 
176549a14c1SViresh Kumar 	nios2_timer_stop(timer);
177549a14c1SViresh Kumar 	return 0;
178549a14c1SViresh Kumar }
179549a14c1SViresh Kumar 
nios2_timer_set_periodic(struct clock_event_device * evt)180549a14c1SViresh Kumar static int nios2_timer_set_periodic(struct clock_event_device *evt)
1814182de9eSLey Foon Tan {
1824182de9eSLey Foon Tan 	unsigned long period;
1834182de9eSLey Foon Tan 	struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
1844182de9eSLey Foon Tan 	struct nios2_timer *timer = &nios2_ced->timer;
1854182de9eSLey Foon Tan 
1864182de9eSLey Foon Tan 	period = DIV_ROUND_UP(timer->freq, HZ);
187549a14c1SViresh Kumar 	nios2_timer_config(timer, period, true);
188549a14c1SViresh Kumar 	return 0;
1894182de9eSLey Foon Tan }
190549a14c1SViresh Kumar 
nios2_timer_resume(struct clock_event_device * evt)191549a14c1SViresh Kumar static int nios2_timer_resume(struct clock_event_device *evt)
192549a14c1SViresh Kumar {
193549a14c1SViresh Kumar 	struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
194549a14c1SViresh Kumar 	struct nios2_timer *timer = &nios2_ced->timer;
195549a14c1SViresh Kumar 
196549a14c1SViresh Kumar 	nios2_timer_start(timer);
197549a14c1SViresh Kumar 	return 0;
1984182de9eSLey Foon Tan }
1994182de9eSLey Foon Tan 
timer_interrupt(int irq,void * dev_id)2004182de9eSLey Foon Tan irqreturn_t timer_interrupt(int irq, void *dev_id)
2014182de9eSLey Foon Tan {
2024182de9eSLey Foon Tan 	struct clock_event_device *evt = (struct clock_event_device *) dev_id;
2034182de9eSLey Foon Tan 	struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt);
2044182de9eSLey Foon Tan 
2054182de9eSLey Foon Tan 	/* Clear the interrupt condition */
2064182de9eSLey Foon Tan 	timer_writew(&nios2_ced->timer, 0, ALTERA_TIMER_STATUS_REG);
2074182de9eSLey Foon Tan 	evt->event_handler(evt);
2084182de9eSLey Foon Tan 
2094182de9eSLey Foon Tan 	return IRQ_HANDLED;
2104182de9eSLey Foon Tan }
2114182de9eSLey Foon Tan 
nios2_timer_get_base_and_freq(struct device_node * np,void __iomem ** base,u32 * freq)212dd1364a7SDaniel Lezcano static int __init nios2_timer_get_base_and_freq(struct device_node *np,
2134182de9eSLey Foon Tan 				void __iomem **base, u32 *freq)
2144182de9eSLey Foon Tan {
2154182de9eSLey Foon Tan 	*base = of_iomap(np, 0);
216dd1364a7SDaniel Lezcano 	if (!*base) {
2175dc4dca4SRob Herring 		pr_crit("Unable to map reg for %pOFn\n", np);
218dd1364a7SDaniel Lezcano 		return -ENXIO;
219dd1364a7SDaniel Lezcano 	}
2204182de9eSLey Foon Tan 
221dd1364a7SDaniel Lezcano 	if (of_property_read_u32(np, "clock-frequency", freq)) {
2225dc4dca4SRob Herring 		pr_crit("Unable to get %pOFn clock frequency\n", np);
223dd1364a7SDaniel Lezcano 		return -EINVAL;
224dd1364a7SDaniel Lezcano 	}
225dd1364a7SDaniel Lezcano 
226dd1364a7SDaniel Lezcano 	return 0;
2274182de9eSLey Foon Tan }
2284182de9eSLey Foon Tan 
2294182de9eSLey Foon Tan static struct nios2_clockevent_dev nios2_ce = {
2304182de9eSLey Foon Tan 	.ced = {
2314182de9eSLey Foon Tan 		.name = "nios2-clkevent",
2324182de9eSLey Foon Tan 		.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
2334182de9eSLey Foon Tan 		.rating = 250,
2344182de9eSLey Foon Tan 		.shift = 32,
2354182de9eSLey Foon Tan 		.set_next_event = nios2_timer_set_next_event,
236549a14c1SViresh Kumar 		.set_state_shutdown = nios2_timer_shutdown,
237549a14c1SViresh Kumar 		.set_state_periodic = nios2_timer_set_periodic,
238549a14c1SViresh Kumar 		.set_state_oneshot = nios2_timer_shutdown,
239549a14c1SViresh Kumar 		.tick_resume = nios2_timer_resume,
2404182de9eSLey Foon Tan 	},
2414182de9eSLey Foon Tan };
2424182de9eSLey Foon Tan 
nios2_clockevent_init(struct device_node * timer)243dd1364a7SDaniel Lezcano static __init int nios2_clockevent_init(struct device_node *timer)
2444182de9eSLey Foon Tan {
2454182de9eSLey Foon Tan 	void __iomem *iobase;
2464182de9eSLey Foon Tan 	u32 freq;
247dd1364a7SDaniel Lezcano 	int irq, ret;
2484182de9eSLey Foon Tan 
249dd1364a7SDaniel Lezcano 	ret = nios2_timer_get_base_and_freq(timer, &iobase, &freq);
250dd1364a7SDaniel Lezcano 	if (ret)
251dd1364a7SDaniel Lezcano 		return ret;
2524182de9eSLey Foon Tan 
2534182de9eSLey Foon Tan 	irq = irq_of_parse_and_map(timer, 0);
254dd1364a7SDaniel Lezcano 	if (!irq) {
255dd1364a7SDaniel Lezcano 		pr_crit("Unable to parse timer irq\n");
256dd1364a7SDaniel Lezcano 		return -EINVAL;
257dd1364a7SDaniel Lezcano 	}
2584182de9eSLey Foon Tan 
2594182de9eSLey Foon Tan 	nios2_ce.timer.base = iobase;
2604182de9eSLey Foon Tan 	nios2_ce.timer.freq = freq;
2614182de9eSLey Foon Tan 
2624182de9eSLey Foon Tan 	nios2_ce.ced.cpumask = cpumask_of(0);
2634182de9eSLey Foon Tan 	nios2_ce.ced.irq = irq;
2644182de9eSLey Foon Tan 
2654182de9eSLey Foon Tan 	nios2_timer_stop(&nios2_ce.timer);
2664182de9eSLey Foon Tan 	/* clear pending interrupt */
2674182de9eSLey Foon Tan 	timer_writew(&nios2_ce.timer, 0, ALTERA_TIMER_STATUS_REG);
2684182de9eSLey Foon Tan 
269dd1364a7SDaniel Lezcano 	ret = request_irq(irq, timer_interrupt, IRQF_TIMER, timer->name,
270dd1364a7SDaniel Lezcano 			  &nios2_ce.ced);
271dd1364a7SDaniel Lezcano 	if (ret) {
272dd1364a7SDaniel Lezcano 		pr_crit("Unable to setup timer irq\n");
273dd1364a7SDaniel Lezcano 		return ret;
2744182de9eSLey Foon Tan 	}
2754182de9eSLey Foon Tan 
276dd1364a7SDaniel Lezcano 	clockevents_config_and_register(&nios2_ce.ced, freq, 1, ULONG_MAX);
277dd1364a7SDaniel Lezcano 
278dd1364a7SDaniel Lezcano 	return 0;
279dd1364a7SDaniel Lezcano }
280dd1364a7SDaniel Lezcano 
nios2_clocksource_init(struct device_node * timer)281dd1364a7SDaniel Lezcano static __init int nios2_clocksource_init(struct device_node *timer)
2824182de9eSLey Foon Tan {
2834182de9eSLey Foon Tan 	unsigned int ctrl;
2844182de9eSLey Foon Tan 	void __iomem *iobase;
2854182de9eSLey Foon Tan 	u32 freq;
286dd1364a7SDaniel Lezcano 	int ret;
2874182de9eSLey Foon Tan 
288dd1364a7SDaniel Lezcano 	ret = nios2_timer_get_base_and_freq(timer, &iobase, &freq);
289dd1364a7SDaniel Lezcano 	if (ret)
290dd1364a7SDaniel Lezcano 		return ret;
2914182de9eSLey Foon Tan 
2924182de9eSLey Foon Tan 	nios2_cs.timer.base = iobase;
2934182de9eSLey Foon Tan 	nios2_cs.timer.freq = freq;
2944182de9eSLey Foon Tan 
295dd1364a7SDaniel Lezcano 	ret = clocksource_register_hz(&nios2_cs.cs, freq);
296dd1364a7SDaniel Lezcano 	if (ret)
297dd1364a7SDaniel Lezcano 		return ret;
2984182de9eSLey Foon Tan 
2994182de9eSLey Foon Tan 	timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODL_REG);
3004182de9eSLey Foon Tan 	timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODH_REG);
3014182de9eSLey Foon Tan 
3024182de9eSLey Foon Tan 	/* interrupt disable + continuous + start */
3034182de9eSLey Foon Tan 	ctrl = ALTERA_TIMER_CONTROL_CONT_MSK | ALTERA_TIMER_CONTROL_START_MSK;
3044182de9eSLey Foon Tan 	timer_writew(&nios2_cs.timer, ctrl, ALTERA_TIMER_CONTROL_REG);
3054182de9eSLey Foon Tan 
3064182de9eSLey Foon Tan 	/* Calibrate the delay loop directly */
3074182de9eSLey Foon Tan 	lpj_fine = freq / HZ;
308dd1364a7SDaniel Lezcano 
309dd1364a7SDaniel Lezcano 	return 0;
3104182de9eSLey Foon Tan }
3114182de9eSLey Foon Tan 
3124182de9eSLey Foon Tan /*
3134182de9eSLey Foon Tan  * The first timer instance will use as a clockevent. If there are two or
3144182de9eSLey Foon Tan  * more instances, the second one gets used as clocksource and all
3154182de9eSLey Foon Tan  * others are unused.
3164182de9eSLey Foon Tan */
nios2_time_init(struct device_node * timer)317dd1364a7SDaniel Lezcano static int __init nios2_time_init(struct device_node *timer)
3184182de9eSLey Foon Tan {
3194182de9eSLey Foon Tan 	static int num_called;
320dd1364a7SDaniel Lezcano 	int ret;
3214182de9eSLey Foon Tan 
3224182de9eSLey Foon Tan 	switch (num_called) {
3234182de9eSLey Foon Tan 	case 0:
324dd1364a7SDaniel Lezcano 		ret = nios2_clockevent_init(timer);
3254182de9eSLey Foon Tan 		break;
3264182de9eSLey Foon Tan 	case 1:
327dd1364a7SDaniel Lezcano 		ret = nios2_clocksource_init(timer);
3284182de9eSLey Foon Tan 		break;
3294182de9eSLey Foon Tan 	default:
330069013a9SArnd Bergmann 		ret = 0;
3314182de9eSLey Foon Tan 		break;
3324182de9eSLey Foon Tan 	}
3334182de9eSLey Foon Tan 
3344182de9eSLey Foon Tan 	num_called++;
335dd1364a7SDaniel Lezcano 
336dd1364a7SDaniel Lezcano 	return ret;
3374182de9eSLey Foon Tan }
3384182de9eSLey Foon Tan 
read_persistent_clock64(struct timespec64 * ts)3393d9644efSBaolin Wang void read_persistent_clock64(struct timespec64 *ts)
3404182de9eSLey Foon Tan {
3413d9644efSBaolin Wang 	ts->tv_sec = mktime64(2007, 1, 1, 0, 0, 0);
3424182de9eSLey Foon Tan 	ts->tv_nsec = 0;
3434182de9eSLey Foon Tan }
3444182de9eSLey Foon Tan 
time_init(void)3454182de9eSLey Foon Tan void __init time_init(void)
3464182de9eSLey Foon Tan {
347a8955cc3SLey Foon Tan 	struct device_node *np;
348a8955cc3SLey Foon Tan 	int count = 0;
349a8955cc3SLey Foon Tan 
350a8955cc3SLey Foon Tan 	for_each_compatible_node(np, NULL,  ALTR_TIMER_COMPATIBLE)
351a8955cc3SLey Foon Tan 		count++;
352a8955cc3SLey Foon Tan 
353a8955cc3SLey Foon Tan 	if (count < 2)
354a8955cc3SLey Foon Tan 		panic("%d timer is found, it needs 2 timers in system\n", count);
355a8955cc3SLey Foon Tan 
356ba5d08c0SDaniel Lezcano 	timer_probe();
3574182de9eSLey Foon Tan }
3584182de9eSLey Foon Tan 
35917273395SDaniel Lezcano TIMER_OF_DECLARE(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);
360