Skip to content

Commit 4661fda

Browse files
Chao XieMichael Turquette
authored andcommitted
clk: mmp: add basic support functions for DT support
In order to support DT for mmp SOC clocks, it defines some basic APIs which are shared by all mmp SOC clock units. Signed-off-by: Chao Xie <[email protected]> Acked-by: Haojian Zhuang <[email protected]> Signed-off-by: Michael Turquette <[email protected]>
1 parent cdce354 commit 4661fda

File tree

3 files changed

+298
-2
lines changed

3 files changed

+298
-2
lines changed

drivers/clk/mmp/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Makefile for mmp specific clk
33
#
44

5-
obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o
5+
obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
66

77
obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
88
obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o

drivers/clk/mmp/clk.c

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#include <linux/io.h>
2+
#include <linux/clk.h>
3+
#include <linux/clk-provider.h>
4+
#include <linux/clkdev.h>
5+
#include <linux/of.h>
6+
#include <linux/of_address.h>
7+
8+
#include "clk.h"
9+
10+
void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
11+
int nr_clks)
12+
{
13+
static struct clk **clk_table;
14+
15+
clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
16+
if (!clk_table)
17+
return;
18+
19+
unit->clk_table = clk_table;
20+
unit->nr_clks = nr_clks;
21+
unit->clk_data.clks = clk_table;
22+
unit->clk_data.clk_num = nr_clks;
23+
of_clk_add_provider(np, of_clk_src_onecell_get, &unit->clk_data);
24+
}
25+
26+
void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
27+
struct mmp_param_fixed_rate_clk *clks,
28+
int size)
29+
{
30+
int i;
31+
struct clk *clk;
32+
33+
for (i = 0; i < size; i++) {
34+
clk = clk_register_fixed_rate(NULL, clks[i].name,
35+
clks[i].parent_name,
36+
clks[i].flags,
37+
clks[i].fixed_rate);
38+
if (IS_ERR(clk)) {
39+
pr_err("%s: failed to register clock %s\n",
40+
__func__, clks[i].name);
41+
continue;
42+
}
43+
if (clks[i].id)
44+
unit->clk_table[clks[i].id] = clk;
45+
}
46+
}
47+
48+
void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
49+
struct mmp_param_fixed_factor_clk *clks,
50+
int size)
51+
{
52+
struct clk *clk;
53+
int i;
54+
55+
for (i = 0; i < size; i++) {
56+
clk = clk_register_fixed_factor(NULL, clks[i].name,
57+
clks[i].parent_name,
58+
clks[i].flags, clks[i].mult,
59+
clks[i].div);
60+
if (IS_ERR(clk)) {
61+
pr_err("%s: failed to register clock %s\n",
62+
__func__, clks[i].name);
63+
continue;
64+
}
65+
if (clks[i].id)
66+
unit->clk_table[clks[i].id] = clk;
67+
}
68+
}
69+
70+
void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
71+
struct mmp_param_general_gate_clk *clks,
72+
void __iomem *base, int size)
73+
{
74+
struct clk *clk;
75+
int i;
76+
77+
for (i = 0; i < size; i++) {
78+
clk = clk_register_gate(NULL, clks[i].name,
79+
clks[i].parent_name,
80+
clks[i].flags,
81+
base + clks[i].offset,
82+
clks[i].bit_idx,
83+
clks[i].gate_flags,
84+
clks[i].lock);
85+
86+
if (IS_ERR(clk)) {
87+
pr_err("%s: failed to register clock %s\n",
88+
__func__, clks[i].name);
89+
continue;
90+
}
91+
if (clks[i].id)
92+
unit->clk_table[clks[i].id] = clk;
93+
}
94+
}
95+
96+
void mmp_register_gate_clks(struct mmp_clk_unit *unit,
97+
struct mmp_param_gate_clk *clks,
98+
void __iomem *base, int size)
99+
{
100+
struct clk *clk;
101+
int i;
102+
103+
for (i = 0; i < size; i++) {
104+
clk = mmp_clk_register_gate(NULL, clks[i].name,
105+
clks[i].parent_name,
106+
clks[i].flags,
107+
base + clks[i].offset,
108+
clks[i].mask,
109+
clks[i].val_enable,
110+
clks[i].val_disable,
111+
clks[i].gate_flags,
112+
clks[i].lock);
113+
114+
if (IS_ERR(clk)) {
115+
pr_err("%s: failed to register clock %s\n",
116+
__func__, clks[i].name);
117+
continue;
118+
}
119+
if (clks[i].id)
120+
unit->clk_table[clks[i].id] = clk;
121+
}
122+
}
123+
124+
void mmp_register_mux_clks(struct mmp_clk_unit *unit,
125+
struct mmp_param_mux_clk *clks,
126+
void __iomem *base, int size)
127+
{
128+
struct clk *clk;
129+
int i;
130+
131+
for (i = 0; i < size; i++) {
132+
clk = clk_register_mux(NULL, clks[i].name,
133+
clks[i].parent_name,
134+
clks[i].num_parents,
135+
clks[i].flags,
136+
base + clks[i].offset,
137+
clks[i].shift,
138+
clks[i].width,
139+
clks[i].mux_flags,
140+
clks[i].lock);
141+
142+
if (IS_ERR(clk)) {
143+
pr_err("%s: failed to register clock %s\n",
144+
__func__, clks[i].name);
145+
continue;
146+
}
147+
if (clks[i].id)
148+
unit->clk_table[clks[i].id] = clk;
149+
}
150+
}
151+
152+
void mmp_register_div_clks(struct mmp_clk_unit *unit,
153+
struct mmp_param_div_clk *clks,
154+
void __iomem *base, int size)
155+
{
156+
struct clk *clk;
157+
int i;
158+
159+
for (i = 0; i < size; i++) {
160+
clk = clk_register_divider(NULL, clks[i].name,
161+
clks[i].parent_name,
162+
clks[i].flags,
163+
base + clks[i].offset,
164+
clks[i].shift,
165+
clks[i].width,
166+
clks[i].div_flags,
167+
clks[i].lock);
168+
169+
if (IS_ERR(clk)) {
170+
pr_err("%s: failed to register clock %s\n",
171+
__func__, clks[i].name);
172+
continue;
173+
}
174+
if (clks[i].id)
175+
unit->clk_table[clks[i].id] = clk;
176+
}
177+
}
178+
179+
void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
180+
struct clk *clk)
181+
{
182+
if (IS_ERR_OR_NULL(clk)) {
183+
pr_err("CLK %d has invalid pointer %p\n", id, clk);
184+
return;
185+
}
186+
if (id > unit->nr_clks) {
187+
pr_err("CLK %d is invalid\n", id);
188+
return;
189+
}
190+
191+
unit->clk_table[id] = clk;
192+
}

drivers/clk/mmp/clk.h

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ struct mmp_clk_mix {
9696
extern const struct clk_ops mmp_clk_mix_ops;
9797
extern struct clk *mmp_clk_register_mix(struct device *dev,
9898
const char *name,
99-
u8 num_parents,
10099
const char **parent_names,
100+
u8 num_parents,
101101
unsigned long flags,
102102
struct mmp_clk_mix_config *config,
103103
spinlock_t *lock);
@@ -132,4 +132,108 @@ extern struct clk *mmp_clk_register_apbc(const char *name,
132132
extern struct clk *mmp_clk_register_apmu(const char *name,
133133
const char *parent_name, void __iomem *base, u32 enable_mask,
134134
spinlock_t *lock);
135+
136+
struct mmp_clk_unit {
137+
unsigned int nr_clks;
138+
struct clk **clk_table;
139+
struct clk_onecell_data clk_data;
140+
};
141+
142+
struct mmp_param_fixed_rate_clk {
143+
unsigned int id;
144+
char *name;
145+
const char *parent_name;
146+
unsigned long flags;
147+
unsigned long fixed_rate;
148+
};
149+
void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
150+
struct mmp_param_fixed_rate_clk *clks,
151+
int size);
152+
153+
struct mmp_param_fixed_factor_clk {
154+
unsigned int id;
155+
char *name;
156+
const char *parent_name;
157+
unsigned long mult;
158+
unsigned long div;
159+
unsigned long flags;
160+
};
161+
void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
162+
struct mmp_param_fixed_factor_clk *clks,
163+
int size);
164+
165+
struct mmp_param_general_gate_clk {
166+
unsigned int id;
167+
const char *name;
168+
const char *parent_name;
169+
unsigned long flags;
170+
unsigned long offset;
171+
u8 bit_idx;
172+
u8 gate_flags;
173+
spinlock_t *lock;
174+
};
175+
void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
176+
struct mmp_param_general_gate_clk *clks,
177+
void __iomem *base, int size);
178+
179+
struct mmp_param_gate_clk {
180+
unsigned int id;
181+
char *name;
182+
const char *parent_name;
183+
unsigned long flags;
184+
unsigned long offset;
185+
u32 mask;
186+
u32 val_enable;
187+
u32 val_disable;
188+
unsigned int gate_flags;
189+
spinlock_t *lock;
190+
};
191+
void mmp_register_gate_clks(struct mmp_clk_unit *unit,
192+
struct mmp_param_gate_clk *clks,
193+
void __iomem *base, int size);
194+
195+
struct mmp_param_mux_clk {
196+
unsigned int id;
197+
char *name;
198+
const char **parent_name;
199+
u8 num_parents;
200+
unsigned long flags;
201+
unsigned long offset;
202+
u8 shift;
203+
u8 width;
204+
u8 mux_flags;
205+
spinlock_t *lock;
206+
};
207+
void mmp_register_mux_clks(struct mmp_clk_unit *unit,
208+
struct mmp_param_mux_clk *clks,
209+
void __iomem *base, int size);
210+
211+
struct mmp_param_div_clk {
212+
unsigned int id;
213+
char *name;
214+
const char *parent_name;
215+
unsigned long flags;
216+
unsigned long offset;
217+
u8 shift;
218+
u8 width;
219+
u8 div_flags;
220+
spinlock_t *lock;
221+
};
222+
void mmp_register_div_clks(struct mmp_clk_unit *unit,
223+
struct mmp_param_div_clk *clks,
224+
void __iomem *base, int size);
225+
226+
#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc) \
227+
{ \
228+
.width_div = (w_d), \
229+
.shift_div = (s_d), \
230+
.width_mux = (w_m), \
231+
.shift_mux = (s_m), \
232+
.bit_fc = (fc), \
233+
}
234+
235+
void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
236+
int nr_clks);
237+
void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
238+
struct clk *clk);
135239
#endif

0 commit comments

Comments
 (0)