blob: c4717de6a9c4ccdd3d551c1e5acd8016d93f840a [file] [log] [blame]
wdenk32fe2872002-10-11 07:57:01 +00001/*
Marek Vasutd1bb9442011-11-26 10:02:41 +01002 * Marvell PXA2xx/3xx timer driver
wdenk32fe2872002-10-11 07:57:01 +00003 *
Marek Vasutd1bb9442011-11-26 10:02:41 +01004 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
wdenk32fe2872002-10-11 07:57:01 +00005 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenk32fe2872002-10-11 07:57:01 +00007 */
8
wdenk32fe2872002-10-11 07:57:01 +00009#include <asm/arch/pxa-regs.h>
Marek Vasut3ba8bf72010-09-09 09:50:39 +020010#include <asm/io.h>
11#include <common.h>
Jean-Christophe PLAGNIOL-VILLARDa922fdb2009-02-24 06:13:10 +010012#include <div64.h>
wdenk32fe2872002-10-11 07:57:01 +000013
Marek Vasutd1bb9442011-11-26 10:02:41 +010014DECLARE_GLOBAL_DATA_PTR;
15
16#define TIMER_LOAD_VAL 0xffffffff
17
Simon Glass66ee6922012-12-13 20:48:34 +000018#define timestamp (gd->arch.tbl)
Simon Glass582601d2012-12-13 20:48:35 +000019#define lastinc (gd->arch.lastinc)
wdenk32fe2872002-10-11 07:57:01 +000020
Marek Vasutabc20ab2011-11-26 07:20:07 +010021#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS)
Marek Vasutd1bb9442011-11-26 10:02:41 +010022#define TIMER_FREQ_HZ 3250000
Marek Vasutabc20ab2011-11-26 07:20:07 +010023#elif defined(CONFIG_CPU_PXA25X)
Marek Vasutd1bb9442011-11-26 10:02:41 +010024#define TIMER_FREQ_HZ 3686400
Micha Kalfon94a33122009-02-11 19:50:11 +020025#else
26#error "Timer frequency unknown - please config PXA CPU type"
27#endif
28
Marek Vasutd1bb9442011-11-26 10:02:41 +010029static unsigned long long tick_to_time(unsigned long long tick)
Jean-Christophe PLAGNIOL-VILLARDa922fdb2009-02-24 06:13:10 +010030{
Tom Rini49a90e22013-12-05 14:48:37 -050031 return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ);
Jean-Christophe PLAGNIOL-VILLARDa922fdb2009-02-24 06:13:10 +010032}
33
Marek Vasutd1bb9442011-11-26 10:02:41 +010034static unsigned long long us_to_tick(unsigned long long us)
Jean-Christophe PLAGNIOL-VILLARDa922fdb2009-02-24 06:13:10 +010035{
Tom Rini49a90e22013-12-05 14:48:37 -050036 return lldiv(us * TIMER_FREQ_HZ, 1000000);
Jean-Christophe PLAGNIOL-VILLARDa922fdb2009-02-24 06:13:10 +010037}
38
Marek Vasutd1bb9442011-11-26 10:02:41 +010039int timer_init(void)
wdenk32fe2872002-10-11 07:57:01 +000040{
Graeme Russ17659d72011-07-15 02:21:14 +000041 writel(0, OSCR);
Jean-Christophe PLAGNIOL-VILLARDb54384e2009-05-15 23:47:02 +020042 return 0;
wdenk32fe2872002-10-11 07:57:01 +000043}
44
Marek Vasutd1bb9442011-11-26 10:02:41 +010045unsigned long long get_ticks(void)
wdenk32fe2872002-10-11 07:57:01 +000046{
Marek Vasutd1bb9442011-11-26 10:02:41 +010047 /* Current tick value */
48 uint32_t now = readl(OSCR);
49
50 if (now >= lastinc) {
51 /*
52 * Normal mode (non roll)
53 * Move stamp forward with absolute diff ticks
54 */
55 timestamp += (now - lastinc);
56 } else {
57 /* We have rollover of incrementer */
58 timestamp += (TIMER_LOAD_VAL - lastinc) + now;
59 }
60
61 lastinc = now;
62 return timestamp;
wdenk32fe2872002-10-11 07:57:01 +000063}
64
Marek Vasutd1bb9442011-11-26 10:02:41 +010065ulong get_timer(ulong base)
wdenk32fe2872002-10-11 07:57:01 +000066{
Marek Vasutd1bb9442011-11-26 10:02:41 +010067 return tick_to_time(get_ticks()) - base;
wdenk32fe2872002-10-11 07:57:01 +000068}
69
Marek Vasutd1bb9442011-11-26 10:02:41 +010070void __udelay(unsigned long usec)
wdenk32fe2872002-10-11 07:57:01 +000071{
Jean-Christophe PLAGNIOL-VILLARDa922fdb2009-02-24 06:13:10 +010072 unsigned long long tmp;
wdenk32fe2872002-10-11 07:57:01 +000073 ulong tmo;
74
Jean-Christophe PLAGNIOL-VILLARDa922fdb2009-02-24 06:13:10 +010075 tmo = us_to_tick(usec);
76 tmp = get_ticks() + tmo; /* get current timestamp */
wdenk32fe2872002-10-11 07:57:01 +000077
Jean-Christophe PLAGNIOL-VILLARDa922fdb2009-02-24 06:13:10 +010078 while (get_ticks() < tmp) /* loop till event */
79 /*NOP*/;
wdenkfc3e2162003-10-08 22:33:00 +000080}
Marek Vasut30a14ea2012-02-27 13:59:47 +010081
82ulong get_tbclk(void)
83{
84 return TIMER_FREQ_HZ;
85}