~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/arch/arm/cpu/arm926ejs/spear/timer.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2009
 
3
 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
 
4
 *
 
5
 * SPDX-License-Identifier:     GPL-2.0+
 
6
 */
 
7
 
 
8
#include <common.h>
 
9
#include <asm/io.h>
 
10
#include <asm/arch/hardware.h>
 
11
#include <asm/arch/spr_gpt.h>
 
12
#include <asm/arch/spr_misc.h>
 
13
 
 
14
#define GPT_RESOLUTION  (CONFIG_SPEAR_HZ_CLOCK / CONFIG_SPEAR_HZ)
 
15
#define READ_TIMER()    (readl(&gpt_regs_p->count) & GPT_FREE_RUNNING)
 
16
 
 
17
static struct gpt_regs *const gpt_regs_p =
 
18
    (struct gpt_regs *)CONFIG_SPEAR_TIMERBASE;
 
19
 
 
20
static struct misc_regs *const misc_regs_p =
 
21
    (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
 
22
 
 
23
DECLARE_GLOBAL_DATA_PTR;
 
24
 
 
25
#define timestamp gd->arch.tbl
 
26
#define lastdec gd->arch.lastinc
 
27
 
 
28
int timer_init(void)
 
29
{
 
30
        u32 synth;
 
31
 
 
32
        /* Prescaler setting */
 
33
#if defined(CONFIG_SPEAR3XX)
 
34
        writel(MISC_PRSC_CFG, &misc_regs_p->prsc2_clk_cfg);
 
35
        synth = MISC_GPT4SYNTH;
 
36
#elif defined(CONFIG_SPEAR600)
 
37
        writel(MISC_PRSC_CFG, &misc_regs_p->prsc1_clk_cfg);
 
38
        synth = MISC_GPT3SYNTH;
 
39
#else
 
40
# error Incorrect config. Can only be spear{600|300|310|320}
 
41
#endif
 
42
 
 
43
        writel(readl(&misc_regs_p->periph_clk_cfg) | synth,
 
44
               &misc_regs_p->periph_clk_cfg);
 
45
 
 
46
        /* disable timers */
 
47
        writel(GPT_PRESCALER_1 | GPT_MODE_AUTO_RELOAD, &gpt_regs_p->control);
 
48
 
 
49
        /* load value for free running */
 
50
        writel(GPT_FREE_RUNNING, &gpt_regs_p->compare);
 
51
 
 
52
        /* auto reload, start timer */
 
53
        writel(readl(&gpt_regs_p->control) | GPT_ENABLE, &gpt_regs_p->control);
 
54
 
 
55
        /* Reset the timer */
 
56
        lastdec = READ_TIMER();
 
57
        timestamp = 0;
 
58
 
 
59
        return 0;
 
60
}
 
61
 
 
62
/*
 
63
 * timer without interrupts
 
64
 */
 
65
ulong get_timer(ulong base)
 
66
{
 
67
        return (get_timer_masked() / GPT_RESOLUTION) - base;
 
68
}
 
69
 
 
70
void __udelay(unsigned long usec)
 
71
{
 
72
        ulong tmo;
 
73
        ulong start = get_timer_masked();
 
74
        ulong tenudelcnt = CONFIG_SPEAR_HZ_CLOCK / (1000 * 100);
 
75
        ulong rndoff;
 
76
 
 
77
        rndoff = (usec % 10) ? 1 : 0;
 
78
 
 
79
        /* tenudelcnt timer tick gives 10 microsecconds delay */
 
80
        tmo = ((usec / 10) + rndoff) * tenudelcnt;
 
81
 
 
82
        while ((ulong) (get_timer_masked() - start) < tmo)
 
83
                ;
 
84
}
 
85
 
 
86
ulong get_timer_masked(void)
 
87
{
 
88
        ulong now = READ_TIMER();
 
89
 
 
90
        if (now >= lastdec) {
 
91
                /* normal mode */
 
92
                timestamp += now - lastdec;
 
93
        } else {
 
94
                /* we have an overflow ... */
 
95
                timestamp += now + GPT_FREE_RUNNING - lastdec;
 
96
        }
 
97
        lastdec = now;
 
98
 
 
99
        return timestamp;
 
100
}
 
101
 
 
102
void udelay_masked(unsigned long usec)
 
103
{
 
104
        return udelay(usec);
 
105
}
 
106
 
 
107
/*
 
108
 * This function is derived from PowerPC code (read timebase as long long).
 
109
 * On ARM it just returns the timer value.
 
110
 */
 
111
unsigned long long get_ticks(void)
 
112
{
 
113
        return get_timer(0);
 
114
}
 
115
 
 
116
/*
 
117
 * This function is derived from PowerPC code (timebase clock frequency).
 
118
 * On ARM it returns the number of timer ticks per second.
 
119
 */
 
120
ulong get_tbclk(void)
 
121
{
 
122
        return CONFIG_SPEAR_HZ;
 
123
}