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