Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/lantiq/clk.c
26439 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
*
4
* Copyright (C) 2010 Thomas Langer <[email protected]>
5
* Copyright (C) 2010 John Crispin <[email protected]>
6
*/
7
#include <linux/io.h>
8
#include <linux/export.h>
9
#include <linux/init.h>
10
#include <linux/kernel.h>
11
#include <linux/types.h>
12
#include <linux/clk.h>
13
#include <linux/clkdev.h>
14
#include <linux/err.h>
15
#include <linux/list.h>
16
17
#include <asm/time.h>
18
#include <asm/irq.h>
19
#include <asm/div64.h>
20
21
#include <lantiq_soc.h>
22
23
#include "clk.h"
24
#include "prom.h"
25
26
/* lantiq socs have 3 static clocks */
27
static struct clk cpu_clk_generic[4];
28
29
void clkdev_add_static(unsigned long cpu, unsigned long fpi,
30
unsigned long io, unsigned long ppe)
31
{
32
cpu_clk_generic[0].rate = cpu;
33
cpu_clk_generic[1].rate = fpi;
34
cpu_clk_generic[2].rate = io;
35
cpu_clk_generic[3].rate = ppe;
36
}
37
38
struct clk *clk_get_cpu(void)
39
{
40
return &cpu_clk_generic[0];
41
}
42
43
struct clk *clk_get_fpi(void)
44
{
45
return &cpu_clk_generic[1];
46
}
47
EXPORT_SYMBOL_GPL(clk_get_fpi);
48
49
struct clk *clk_get_io(void)
50
{
51
return &cpu_clk_generic[2];
52
}
53
EXPORT_SYMBOL_GPL(clk_get_io);
54
55
struct clk *clk_get_ppe(void)
56
{
57
return &cpu_clk_generic[3];
58
}
59
EXPORT_SYMBOL_GPL(clk_get_ppe);
60
61
static inline int clk_good(struct clk *clk)
62
{
63
return clk && !IS_ERR(clk);
64
}
65
66
unsigned long clk_get_rate(struct clk *clk)
67
{
68
if (unlikely(!clk_good(clk)))
69
return 0;
70
71
if (clk->rate != 0)
72
return clk->rate;
73
74
if (clk->get_rate != NULL)
75
return clk->get_rate();
76
77
return 0;
78
}
79
EXPORT_SYMBOL(clk_get_rate);
80
81
int clk_set_rate(struct clk *clk, unsigned long rate)
82
{
83
if (unlikely(!clk_good(clk)))
84
return 0;
85
if (clk->rates && *clk->rates) {
86
unsigned long *r = clk->rates;
87
88
while (*r && (*r != rate))
89
r++;
90
if (!*r) {
91
pr_err("clk %s.%s: trying to set invalid rate %ld\n",
92
clk->cl.dev_id, clk->cl.con_id, rate);
93
return -1;
94
}
95
}
96
clk->rate = rate;
97
return 0;
98
}
99
EXPORT_SYMBOL(clk_set_rate);
100
101
long clk_round_rate(struct clk *clk, unsigned long rate)
102
{
103
if (unlikely(!clk_good(clk)))
104
return 0;
105
if (clk->rates && *clk->rates) {
106
unsigned long *r = clk->rates;
107
108
while (*r && (*r != rate))
109
r++;
110
if (!*r) {
111
return clk->rate;
112
}
113
}
114
return rate;
115
}
116
EXPORT_SYMBOL(clk_round_rate);
117
118
int clk_enable(struct clk *clk)
119
{
120
if (unlikely(!clk_good(clk)))
121
return -1;
122
123
if (clk->enable)
124
return clk->enable(clk);
125
126
return -1;
127
}
128
EXPORT_SYMBOL(clk_enable);
129
130
void clk_disable(struct clk *clk)
131
{
132
if (unlikely(!clk_good(clk)))
133
return;
134
135
if (clk->disable)
136
clk->disable(clk);
137
}
138
EXPORT_SYMBOL(clk_disable);
139
140
int clk_activate(struct clk *clk)
141
{
142
if (unlikely(!clk_good(clk)))
143
return -1;
144
145
if (clk->activate)
146
return clk->activate(clk);
147
148
return -1;
149
}
150
EXPORT_SYMBOL(clk_activate);
151
152
void clk_deactivate(struct clk *clk)
153
{
154
if (unlikely(!clk_good(clk)))
155
return;
156
157
if (clk->deactivate)
158
clk->deactivate(clk);
159
}
160
EXPORT_SYMBOL(clk_deactivate);
161
162
struct clk *clk_get_parent(struct clk *clk)
163
{
164
return NULL;
165
}
166
EXPORT_SYMBOL(clk_get_parent);
167
168
int clk_set_parent(struct clk *clk, struct clk *parent)
169
{
170
return 0;
171
}
172
EXPORT_SYMBOL(clk_set_parent);
173
174
static inline u32 get_counter_resolution(void)
175
{
176
u32 res;
177
178
__asm__ __volatile__(
179
".set push\n"
180
".set mips32r2\n"
181
"rdhwr %0, $3\n"
182
".set pop\n"
183
: "=&r" (res)
184
: /* no input */
185
: "memory");
186
187
return res;
188
}
189
190
void __init plat_time_init(void)
191
{
192
struct clk *clk;
193
194
ltq_soc_init();
195
196
clk = clk_get_cpu();
197
mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
198
write_c0_compare(read_c0_count());
199
pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
200
clk_put(clk);
201
}
202
203