~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/clocksource/cyclone.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <linux/clocksource.h>
 
2
#include <linux/string.h>
 
3
#include <linux/errno.h>
 
4
#include <linux/timex.h>
 
5
#include <linux/init.h>
 
6
 
 
7
#include <asm/pgtable.h>
 
8
#include <asm/io.h>
 
9
 
 
10
#include <asm/mach_timer.h>
 
11
 
 
12
#define CYCLONE_CBAR_ADDR       0xFEB00CD0      /* base address ptr */
 
13
#define CYCLONE_PMCC_OFFSET     0x51A0          /* offset to control register */
 
14
#define CYCLONE_MPCS_OFFSET     0x51A8          /* offset to select register */
 
15
#define CYCLONE_MPMC_OFFSET     0x51D0          /* offset to count register */
 
16
#define CYCLONE_TIMER_FREQ      99780000        /* 100Mhz, but not really */
 
17
#define CYCLONE_TIMER_MASK      CLOCKSOURCE_MASK(32) /* 32 bit mask */
 
18
 
 
19
int use_cyclone = 0;
 
20
static void __iomem *cyclone_ptr;
 
21
 
 
22
static cycle_t read_cyclone(struct clocksource *cs)
 
23
{
 
24
        return (cycle_t)readl(cyclone_ptr);
 
25
}
 
26
 
 
27
static struct clocksource clocksource_cyclone = {
 
28
        .name           = "cyclone",
 
29
        .rating         = 250,
 
30
        .read           = read_cyclone,
 
31
        .mask           = CYCLONE_TIMER_MASK,
 
32
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 
33
};
 
34
 
 
35
static int __init init_cyclone_clocksource(void)
 
36
{
 
37
        unsigned long base;     /* saved value from CBAR */
 
38
        unsigned long offset;
 
39
        u32 __iomem* volatile cyclone_timer;    /* Cyclone MPMC0 register */
 
40
        u32 __iomem* reg;
 
41
        int i;
 
42
 
 
43
        /* make sure we're on a summit box: */
 
44
        if (!use_cyclone)
 
45
                return -ENODEV;
 
46
 
 
47
        printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n");
 
48
 
 
49
        /* find base address: */
 
50
        offset = CYCLONE_CBAR_ADDR;
 
51
        reg = ioremap_nocache(offset, sizeof(reg));
 
52
        if (!reg) {
 
53
                printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n");
 
54
                return -ENODEV;
 
55
        }
 
56
        /* even on 64bit systems, this is only 32bits: */
 
57
        base = readl(reg);
 
58
        if (!base) {
 
59
                printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n");
 
60
                return -ENODEV;
 
61
        }
 
62
        iounmap(reg);
 
63
 
 
64
        /* setup PMCC: */
 
65
        offset = base + CYCLONE_PMCC_OFFSET;
 
66
        reg = ioremap_nocache(offset, sizeof(reg));
 
67
        if (!reg) {
 
68
                printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n");
 
69
                return -ENODEV;
 
70
        }
 
71
        writel(0x00000001,reg);
 
72
        iounmap(reg);
 
73
 
 
74
        /* setup MPCS: */
 
75
        offset = base + CYCLONE_MPCS_OFFSET;
 
76
        reg = ioremap_nocache(offset, sizeof(reg));
 
77
        if (!reg) {
 
78
                printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n");
 
79
                return -ENODEV;
 
80
        }
 
81
        writel(0x00000001,reg);
 
82
        iounmap(reg);
 
83
 
 
84
        /* map in cyclone_timer: */
 
85
        offset = base + CYCLONE_MPMC_OFFSET;
 
86
        cyclone_timer = ioremap_nocache(offset, sizeof(u64));
 
87
        if (!cyclone_timer) {
 
88
                printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n");
 
89
                return -ENODEV;
 
90
        }
 
91
 
 
92
        /* quick test to make sure its ticking: */
 
93
        for (i = 0; i < 3; i++){
 
94
                u32 old = readl(cyclone_timer);
 
95
                int stall = 100;
 
96
 
 
97
                while (stall--)
 
98
                        barrier();
 
99
 
 
100
                if (readl(cyclone_timer) == old) {
 
101
                        printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n");
 
102
                        iounmap(cyclone_timer);
 
103
                        cyclone_timer = NULL;
 
104
                        return -ENODEV;
 
105
                }
 
106
        }
 
107
        cyclone_ptr = cyclone_timer;
 
108
 
 
109
        return clocksource_register_hz(&clocksource_cyclone,
 
110
                                        CYCLONE_TIMER_FREQ);
 
111
}
 
112
 
 
113
arch_initcall(init_cyclone_clocksource);