~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/mips/lantiq/clk.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  This program is free software; you can redistribute it and/or modify it
 
3
 *  under the terms of the GNU General Public License version 2 as published
 
4
 *  by the Free Software Foundation.
 
5
 *
 
6
 * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
 
7
 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
 
8
 */
 
9
#include <linux/io.h>
 
10
#include <linux/module.h>
 
11
#include <linux/init.h>
 
12
#include <linux/kernel.h>
 
13
#include <linux/types.h>
 
14
#include <linux/clk.h>
 
15
#include <linux/err.h>
 
16
#include <linux/list.h>
 
17
 
 
18
#include <asm/time.h>
 
19
#include <asm/irq.h>
 
20
#include <asm/div64.h>
 
21
 
 
22
#include <lantiq_soc.h>
 
23
 
 
24
#include "clk.h"
 
25
 
 
26
struct clk {
 
27
        const char *name;
 
28
        unsigned long rate;
 
29
        unsigned long (*get_rate) (void);
 
30
};
 
31
 
 
32
static struct clk *cpu_clk;
 
33
static int cpu_clk_cnt;
 
34
 
 
35
/* lantiq socs have 3 static clocks */
 
36
static struct clk cpu_clk_generic[] = {
 
37
        {
 
38
                .name = "cpu",
 
39
                .get_rate = ltq_get_cpu_hz,
 
40
        }, {
 
41
                .name = "fpi",
 
42
                .get_rate = ltq_get_fpi_hz,
 
43
        }, {
 
44
                .name = "io",
 
45
                .get_rate = ltq_get_io_region_clock,
 
46
        },
 
47
};
 
48
 
 
49
static struct resource ltq_cgu_resource = {
 
50
        .name   = "cgu",
 
51
        .start  = LTQ_CGU_BASE_ADDR,
 
52
        .end    = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
 
53
        .flags  = IORESOURCE_MEM,
 
54
};
 
55
 
 
56
/* remapped clock register range */
 
57
void __iomem *ltq_cgu_membase;
 
58
 
 
59
void clk_init(void)
 
60
{
 
61
        cpu_clk = cpu_clk_generic;
 
62
        cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
 
63
}
 
64
 
 
65
static inline int clk_good(struct clk *clk)
 
66
{
 
67
        return clk && !IS_ERR(clk);
 
68
}
 
69
 
 
70
unsigned long clk_get_rate(struct clk *clk)
 
71
{
 
72
        if (unlikely(!clk_good(clk)))
 
73
                return 0;
 
74
 
 
75
        if (clk->rate != 0)
 
76
                return clk->rate;
 
77
 
 
78
        if (clk->get_rate != NULL)
 
79
                return clk->get_rate();
 
80
 
 
81
        return 0;
 
82
}
 
83
EXPORT_SYMBOL(clk_get_rate);
 
84
 
 
85
struct clk *clk_get(struct device *dev, const char *id)
 
86
{
 
87
        int i;
 
88
 
 
89
        for (i = 0; i < cpu_clk_cnt; i++)
 
90
                if (!strcmp(id, cpu_clk[i].name))
 
91
                        return &cpu_clk[i];
 
92
        BUG();
 
93
        return ERR_PTR(-ENOENT);
 
94
}
 
95
EXPORT_SYMBOL(clk_get);
 
96
 
 
97
void clk_put(struct clk *clk)
 
98
{
 
99
        /* not used */
 
100
}
 
101
EXPORT_SYMBOL(clk_put);
 
102
 
 
103
static inline u32 ltq_get_counter_resolution(void)
 
104
{
 
105
        u32 res;
 
106
 
 
107
        __asm__ __volatile__(
 
108
                ".set   push\n"
 
109
                ".set   mips32r2\n"
 
110
                "rdhwr  %0, $3\n"
 
111
                ".set pop\n"
 
112
                : "=&r" (res)
 
113
                : /* no input */
 
114
                : "memory");
 
115
 
 
116
        return res;
 
117
}
 
118
 
 
119
void __init plat_time_init(void)
 
120
{
 
121
        struct clk *clk;
 
122
 
 
123
        if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
 
124
                panic("Failed to insert cgu memory\n");
 
125
 
 
126
        if (request_mem_region(ltq_cgu_resource.start,
 
127
                        resource_size(&ltq_cgu_resource), "cgu") < 0)
 
128
                panic("Failed to request cgu memory\n");
 
129
 
 
130
        ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
 
131
                                resource_size(&ltq_cgu_resource));
 
132
        if (!ltq_cgu_membase) {
 
133
                pr_err("Failed to remap cgu memory\n");
 
134
                unreachable();
 
135
        }
 
136
        clk = clk_get(0, "cpu");
 
137
        mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
 
138
        write_c0_compare(read_c0_count());
 
139
        clk_put(clk);
 
140
}