1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Wyon Bi <bivvy.bi@rock-chips.com>
6 */
7
8 #include <linux/clk.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/clk-provider.h>
12 #include <linux/reset-controller.h>
13 #include <linux/mfd/rk628.h>
14 #include <dt-bindings/reset/rk628-rgu.h>
15 #include <dt-bindings/clock/rk628-cgu.h>
16
17 #include "clk-regmap.h"
18
19 #define RK628_PLL(_id, _name, _parent_name, _reg, _flags) \
20 PLL(_id, _name, _parent_name, _reg, 13, 12, 10, _flags)
21
22 #define REG(x) ((x) + 0xc0000)
23
24 #define CRU_CPLL_CON0 REG(0x0000)
25 #define CRU_CPLL_CON1 REG(0x0004)
26 #define CRU_CPLL_CON2 REG(0x0008)
27 #define CRU_CPLL_CON3 REG(0x000c)
28 #define CRU_CPLL_CON4 REG(0x0010)
29 #define CRU_GPLL_CON0 REG(0x0020)
30 #define CRU_GPLL_CON1 REG(0x0024)
31 #define CRU_GPLL_CON2 REG(0x0028)
32 #define CRU_GPLL_CON3 REG(0x002c)
33 #define CRU_GPLL_CON4 REG(0x0030)
34 #define CRU_MODE_CON REG(0x0060)
35 #define CRU_CLKSEL_CON00 REG(0x0080)
36 #define CRU_CLKSEL_CON01 REG(0x0084)
37 #define CRU_CLKSEL_CON02 REG(0x0088)
38 #define CRU_CLKSEL_CON03 REG(0x008c)
39 #define CRU_CLKSEL_CON04 REG(0x0090)
40 #define CRU_CLKSEL_CON05 REG(0x0094)
41 #define CRU_CLKSEL_CON06 REG(0x0098)
42 #define CRU_CLKSEL_CON07 REG(0x009c)
43 #define CRU_CLKSEL_CON08 REG(0x00a0)
44 #define CRU_CLKSEL_CON09 REG(0x00a4)
45 #define CRU_CLKSEL_CON10 REG(0x00a8)
46 #define CRU_CLKSEL_CON11 REG(0x00ac)
47 #define CRU_CLKSEL_CON12 REG(0x00b0)
48 #define CRU_CLKSEL_CON13 REG(0x00b4)
49 #define CRU_CLKSEL_CON14 REG(0x00b8)
50 #define CRU_CLKSEL_CON15 REG(0x00bc)
51 #define CRU_CLKSEL_CON16 REG(0x00c0)
52 #define CRU_CLKSEL_CON17 REG(0x00c4)
53 #define CRU_CLKSEL_CON18 REG(0x00c8)
54 #define CRU_CLKSEL_CON20 REG(0x00d0)
55 #define CRU_CLKSEL_CON21 REG(0x00d4)
56 #define CRU_GATE_CON00 REG(0x0180)
57 #define CRU_GATE_CON01 REG(0x0184)
58 #define CRU_GATE_CON02 REG(0x0188)
59 #define CRU_GATE_CON03 REG(0x018c)
60 #define CRU_GATE_CON04 REG(0x0190)
61 #define CRU_GATE_CON05 REG(0x0194)
62 #define CRU_SOFTRST_CON00 REG(0x0200)
63 #define CRU_SOFTRST_CON01 REG(0x0204)
64 #define CRU_SOFTRST_CON02 REG(0x0208)
65 #define CRU_SOFTRST_CON04 REG(0x0210)
66 #define CRU_MAX_REGISTER CRU_SOFTRST_CON04
67
68 #define reset_to_cru(_rst) container_of(_rst, struct rk628_cru, rcdev)
69
70 struct rk628_cru {
71 struct device *dev;
72 struct rk628 *parent;
73 struct regmap *regmap;
74 struct reset_controller_dev rcdev;
75 struct clk_onecell_data clk_data;
76 };
77
78 #define CNAME(x) "rk628_" x
79
80 #define PNAME(x) static const char *const x[]
81
82 PNAME(mux_cpll_osc_p) = { CNAME("xin_osc0_func"), CNAME("clk_cpll") };
83 PNAME(mux_gpll_osc_p) = { CNAME("xin_osc0_func"), CNAME("clk_gpll") };
84 PNAME(mux_cpll_gpll_mux_p) = { CNAME("clk_cpll_mux"), CNAME("clk_gpll_mux") };
85 PNAME(mux_mclk_i2s_8ch_p) = { CNAME("clk_i2s_8ch_src"),
86 CNAME("clk_i2s_8ch_frac"), CNAME("i2s_mclkin"),
87 CNAME("xin_osc0_half") };
88 PNAME(mux_i2s_mclkout_p) = { CNAME("mclk_i2s_8ch"), CNAME("xin_osc0_half") };
89 PNAME(mux_clk_testout_p) = { CNAME("xin_osc0_func"), CNAME("xin_osc0_half"),
90 CNAME("clk_gpll"), CNAME("clk_gpll_mux"),
91 CNAME("clk_cpll"), CNAME("clk_gpll_mux"),
92 CNAME("pclk_logic"), CNAME("sclk_vop"),
93 CNAME("mclk_i2s_8ch"), CNAME("i2s_mclkout"),
94 CNAME("dummy"), CNAME("clk_hdmirx_aud"),
95 CNAME("clk_hdmirx_cec"), CNAME("clk_imodet"),
96 CNAME("clk_txesc"), CNAME("clk_gpio_db0") };
97
98 static const struct clk_pll_data rk628_clk_plls[] = {
99 RK628_PLL(CGU_CLK_CPLL, CNAME("clk_cpll"), CNAME("xin_osc0_func"),
100 CRU_CPLL_CON0,
101 0),
102 RK628_PLL(CGU_CLK_GPLL, CNAME("clk_gpll"), CNAME("xin_osc0_func"),
103 CRU_GPLL_CON0,
104 0),
105 };
106
107 static const struct clk_mux_data rk628_clk_muxes[] = {
108 MUX(CGU_CLK_CPLL_MUX, CNAME("clk_cpll_mux"), mux_cpll_osc_p,
109 CRU_MODE_CON, 0, 1,
110 0),
111 MUX(CGU_CLK_GPLL_MUX, CNAME("clk_gpll_mux"), mux_gpll_osc_p,
112 CRU_MODE_CON, 2, 1,
113 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT),
114 };
115
116 static const struct clk_gate_data rk628_clk_gates[] = {
117 GATE(CGU_PCLK_GPIO0, CNAME("pclk_gpio0"), CNAME("pclk_logic"),
118 CRU_GATE_CON01, 0,
119 0),
120 GATE(CGU_PCLK_GPIO1, CNAME("pclk_gpio1"), CNAME("pclk_logic"),
121 CRU_GATE_CON01, 1,
122 0),
123 GATE(CGU_PCLK_GPIO2, CNAME("pclk_gpio2"), CNAME("pclk_logic"),
124 CRU_GATE_CON01, 2,
125 0),
126 GATE(CGU_PCLK_GPIO3, CNAME("pclk_gpio3"), CNAME("pclk_logic"),
127 CRU_GATE_CON01, 3,
128 0),
129
130 GATE(CGU_PCLK_TXPHY_CON, CNAME("pclk_txphy_con"), CNAME("pclk_logic"),
131 CRU_GATE_CON02, 3,
132 CLK_IGNORE_UNUSED),
133 GATE(CGU_PCLK_EFUSE, CNAME("pclk_efuse"), CNAME("pclk_logic"),
134 CRU_GATE_CON00, 5,
135 0),
136 GATE(0, CNAME("pclk_i2c2apb"), CNAME("pclk_logic"),
137 CRU_GATE_CON00, 3,
138 CLK_IGNORE_UNUSED),
139 GATE(0, CNAME("pclk_cru"), CNAME("pclk_logic"),
140 CRU_GATE_CON00, 1,
141 CLK_IGNORE_UNUSED),
142 GATE(0, CNAME("pclk_adapter"), CNAME("pclk_logic"),
143 CRU_GATE_CON00, 7,
144 CLK_IGNORE_UNUSED),
145 GATE(0, CNAME("pclk_regfile"), CNAME("pclk_logic"),
146 CRU_GATE_CON00, 2,
147 CLK_IGNORE_UNUSED),
148 GATE(CGU_PCLK_DSI0, CNAME("pclk_dsi0"), CNAME("pclk_logic"),
149 CRU_GATE_CON02, 6,
150 0),
151 GATE(CGU_PCLK_DSI1, CNAME("pclk_dsi1"), CNAME("pclk_logic"),
152 CRU_GATE_CON02, 7,
153 0),
154 GATE(CGU_PCLK_CSI, CNAME("pclk_csi"), CNAME("pclk_logic"),
155 CRU_GATE_CON02, 8,
156 0),
157 GATE(CGU_PCLK_HDMITX, CNAME("pclk_hdmitx"), CNAME("pclk_logic"),
158 CRU_GATE_CON02, 4,
159 0),
160 GATE(CGU_PCLK_RXPHY, CNAME("pclk_rxphy"), CNAME("pclk_logic"),
161 CRU_GATE_CON02, 0,
162 0),
163 GATE(CGU_PCLK_HDMIRX, CNAME("pclk_hdmirx"), CNAME("pclk_logic"),
164 CRU_GATE_CON02, 2,
165 0),
166 GATE(CGU_PCLK_GVIHOST, CNAME("pclk_gvihost"), CNAME("pclk_logic"),
167 CRU_GATE_CON02, 5,
168 0),
169 GATE(CGU_CLK_CFG_DPHY0, CNAME("clk_cfg_dphy0"), CNAME("xin_osc0_func"),
170 CRU_GATE_CON02, 13,
171 0),
172 GATE(CGU_CLK_CFG_DPHY1, CNAME("clk_cfg_dphy1"), CNAME("xin_osc0_func"),
173 CRU_GATE_CON02, 14,
174 0),
175 GATE(CGU_CLK_TXESC, CNAME("clk_txesc"), CNAME("xin_osc0_func"),
176 CRU_GATE_CON02, 12,
177 0),
178 };
179
180 static const struct clk_composite_data rk628_clk_composites[] = {
181 COMPOSITE(CGU_CLK_IMODET, CNAME("clk_imodet"), mux_cpll_gpll_mux_p,
182 CRU_CLKSEL_CON05, 5, 1,
183 CRU_CLKSEL_CON05, 0, 5,
184 CRU_GATE_CON02, 11,
185 0),
186 COMPOSITE(CGU_CLK_HDMIRX_AUD, CNAME("clk_hdmirx_aud"),
187 mux_cpll_gpll_mux_p,
188 CRU_CLKSEL_CON05, 15, 1,
189 CRU_CLKSEL_CON05, 6, 8,
190 CRU_GATE_CON02, 10,
191 CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT),
192 COMPOSITE_FRAC_NOMUX(CGU_CLK_HDMIRX_CEC, CNAME("clk_hdmirx_cec"),
193 CNAME("xin_osc0_func"),
194 CRU_CLKSEL_CON12,
195 CRU_GATE_CON01, 15,
196 0),
197 COMPOSITE_FRAC(CGU_CLK_RX_READ, CNAME("clk_rx_read"),
198 mux_cpll_gpll_mux_p,
199 CRU_CLKSEL_CON02, 8, 1,
200 CRU_CLKSEL_CON14,
201 CRU_GATE_CON00, 11,
202 0),
203 COMPOSITE_FRAC(CGU_SCLK_VOP, CNAME("sclk_vop"), mux_cpll_gpll_mux_p,
204 CRU_CLKSEL_CON02, 9, 1,
205 CRU_CLKSEL_CON13,
206 CRU_GATE_CON00, 13,
207 CLK_SET_RATE_NO_REPARENT),
208 COMPOSITE(CGU_PCLK_LOGIC, CNAME("pclk_logic"), mux_cpll_gpll_mux_p,
209 CRU_CLKSEL_CON00, 7, 1,
210 CRU_CLKSEL_CON00, 0, 5,
211 CRU_GATE_CON00, 0,
212 0),
213 COMPOSITE_NOMUX(CGU_CLK_GPIO_DB0, CNAME("clk_gpio_db0"),
214 CNAME("xin_osc0_func"),
215 CRU_CLKSEL_CON08, 0, 10,
216 CRU_GATE_CON01, 4,
217 0),
218 COMPOSITE_NOMUX(CGU_CLK_GPIO_DB1, CNAME("clk_gpio_db1"),
219 CNAME("xin_osc0_func"),
220 CRU_CLKSEL_CON09, 0, 10,
221 CRU_GATE_CON01, 5,
222 0),
223 COMPOSITE_NOMUX(CGU_CLK_GPIO_DB2, CNAME("clk_gpio_db2"),
224 CNAME("xin_osc0_func"),
225 CRU_CLKSEL_CON10, 0, 10,
226 CRU_GATE_CON01, 6,
227 0),
228 COMPOSITE_NOMUX(CGU_CLK_GPIO_DB3, CNAME("clk_gpio_db3"),
229 CNAME("xin_osc0_func"),
230 CRU_CLKSEL_CON11, 0, 10,
231 CRU_GATE_CON01, 7,
232 0),
233 COMPOSITE(CGU_CLK_I2S_8CH_SRC, CNAME("clk_i2s_8ch_src"),
234 mux_cpll_gpll_mux_p,
235 CRU_CLKSEL_CON03, 13, 1,
236 CRU_CLKSEL_CON03, 8, 5,
237 CRU_GATE_CON03, 9,
238 0),
239 COMPOSITE_FRAC_NOMUX(CGU_CLK_I2S_8CH_FRAC, CNAME("clk_i2s_8ch_frac"),
240 CNAME("clk_i2s_8ch_src"),
241 CRU_CLKSEL_CON04,
242 CRU_GATE_CON03, 10,
243 0),
244 COMPOSITE_NODIV(CGU_MCLK_I2S_8CH, CNAME("mclk_i2s_8ch"),
245 mux_mclk_i2s_8ch_p,
246 CRU_CLKSEL_CON03, 14, 2,
247 CRU_GATE_CON03, 11,
248 CLK_SET_RATE_PARENT),
249 COMPOSITE_NODIV(CGU_I2S_MCLKOUT, CNAME("i2s_mclkout"),
250 mux_i2s_mclkout_p,
251 CRU_CLKSEL_CON03, 7, 1,
252 CRU_GATE_CON03, 12,
253 CLK_SET_RATE_PARENT),
254 COMPOSITE(CGU_BT1120DEC, CNAME("clk_bt1120dec"), mux_cpll_gpll_mux_p,
255 CRU_CLKSEL_CON02, 7, 1,
256 CRU_CLKSEL_CON02, 0, 5,
257 CRU_GATE_CON00, 12,
258 0),
259 COMPOSITE(CGU_CLK_TESTOUT, CNAME("clk_testout"), mux_clk_testout_p,
260 CRU_CLKSEL_CON06, 0, 4,
261 CRU_CLKSEL_CON06, 8, 6,
262 CRU_GATE_CON04, 7,
263 0),
264 };
265
rk628_clk_add_lookup(struct rk628_cru * cru,struct clk * clk,unsigned int id)266 static void rk628_clk_add_lookup(struct rk628_cru *cru, struct clk *clk,
267 unsigned int id)
268 {
269 if (cru->clk_data.clks && id)
270 cru->clk_data.clks[id] = clk;
271 }
272
rk628_clk_register_muxes(struct rk628_cru * cru)273 static void rk628_clk_register_muxes(struct rk628_cru *cru)
274 {
275 struct clk *clk;
276 unsigned int i;
277
278 for (i = 0; i < ARRAY_SIZE(rk628_clk_muxes); i++) {
279 const struct clk_mux_data *data = &rk628_clk_muxes[i];
280
281 clk = devm_clk_regmap_register_mux(cru->dev, data->name,
282 data->parent_names,
283 data->num_parents,
284 cru->regmap, data->reg,
285 data->shift, data->width,
286 data->flags);
287 if (IS_ERR(clk)) {
288 dev_err(cru->dev, "failed to register clock %s\n",
289 data->name);
290 continue;
291 }
292
293 rk628_clk_add_lookup(cru, clk, data->id);
294 }
295 }
296
rk628_clk_register_gates(struct rk628_cru * cru)297 static void rk628_clk_register_gates(struct rk628_cru *cru)
298 {
299 struct clk *clk;
300 unsigned int i;
301
302 for (i = 0; i < ARRAY_SIZE(rk628_clk_gates); i++) {
303 const struct clk_gate_data *data = &rk628_clk_gates[i];
304
305 clk = devm_clk_regmap_register_gate(cru->dev, data->name,
306 data->parent_name,
307 cru->regmap,
308 data->reg, data->shift,
309 data->flags);
310 if (IS_ERR(clk)) {
311 dev_err(cru->dev, "failed to register clock %s\n",
312 data->name);
313 continue;
314 }
315
316 rk628_clk_add_lookup(cru, clk, data->id);
317 }
318 }
319
rk628_clk_register_composites(struct rk628_cru * cru)320 static void rk628_clk_register_composites(struct rk628_cru *cru)
321 {
322 struct clk *clk;
323 unsigned int i;
324
325 for (i = 0; i < ARRAY_SIZE(rk628_clk_composites); i++) {
326 const struct clk_composite_data *data =
327 &rk628_clk_composites[i];
328
329 clk = devm_clk_regmap_register_composite(cru->dev, data->name,
330 data->parent_names,
331 data->num_parents,
332 cru->regmap,
333 data->mux_reg,
334 data->mux_shift,
335 data->mux_width,
336 data->div_reg,
337 data->div_shift,
338 data->div_width,
339 data->div_flags,
340 data->gate_reg,
341 data->gate_shift,
342 data->flags);
343 if (IS_ERR(clk)) {
344 dev_err(cru->dev, "failed to register clock %s\n",
345 data->name);
346 continue;
347 }
348
349 rk628_clk_add_lookup(cru, clk, data->id);
350 }
351 }
352
rk628_clk_register_plls(struct rk628_cru * cru)353 static void rk628_clk_register_plls(struct rk628_cru *cru)
354 {
355 struct clk *clk;
356 unsigned int i;
357
358 for (i = 0; i < ARRAY_SIZE(rk628_clk_plls); i++) {
359 const struct clk_pll_data *data = &rk628_clk_plls[i];
360
361 clk = devm_clk_regmap_register_pll(cru->dev, data->name,
362 data->parent_name,
363 cru->regmap,
364 data->reg,
365 data->pd_shift,
366 data->dsmpd_shift,
367 data->lock_shift,
368 data->flags);
369 if (IS_ERR(clk)) {
370 dev_err(cru->dev, "failed to register clock %s\n",
371 data->name);
372 continue;
373 }
374
375 rk628_clk_add_lookup(cru, clk, data->id);
376 }
377 }
378
379 struct rk628_rgu_data {
380 unsigned int id;
381 unsigned int reg;
382 unsigned int bit;
383 };
384
385 #define RSTGEN(_id, _reg, _bit) \
386 { \
387 .id = (_id), \
388 .reg = (_reg), \
389 .bit = (_bit), \
390 }
391
392 static const struct rk628_rgu_data rk628_rgu_data[] = {
393 RSTGEN(RGU_LOGIC, CRU_SOFTRST_CON00, 0),
394 RSTGEN(RGU_CRU, CRU_SOFTRST_CON00, 1),
395 RSTGEN(RGU_REGFILE, CRU_SOFTRST_CON00, 2),
396 RSTGEN(RGU_I2C2APB, CRU_SOFTRST_CON00, 3),
397 RSTGEN(RGU_EFUSE, CRU_SOFTRST_CON00, 5),
398 RSTGEN(RGU_ADAPTER, CRU_SOFTRST_CON00, 7),
399 RSTGEN(RGU_CLK_RX, CRU_SOFTRST_CON00, 11),
400 RSTGEN(RGU_BT1120DEC, CRU_SOFTRST_CON00, 12),
401 RSTGEN(RGU_VOP, CRU_SOFTRST_CON00, 13),
402
403 RSTGEN(RGU_GPIO0, CRU_SOFTRST_CON01, 0),
404 RSTGEN(RGU_GPIO1, CRU_SOFTRST_CON01, 1),
405 RSTGEN(RGU_GPIO2, CRU_SOFTRST_CON01, 2),
406 RSTGEN(RGU_GPIO3, CRU_SOFTRST_CON01, 3),
407 RSTGEN(RGU_GPIO_DB0, CRU_SOFTRST_CON01, 4),
408 RSTGEN(RGU_GPIO_DB1, CRU_SOFTRST_CON01, 5),
409 RSTGEN(RGU_GPIO_DB2, CRU_SOFTRST_CON01, 6),
410 RSTGEN(RGU_GPIO_DB3, CRU_SOFTRST_CON01, 7),
411
412 RSTGEN(RGU_RXPHY, CRU_SOFTRST_CON02, 0),
413 RSTGEN(RGU_HDMIRX, CRU_SOFTRST_CON02, 2),
414 RSTGEN(RGU_TXPHY_CON, CRU_SOFTRST_CON02, 3),
415 RSTGEN(RGU_HDMITX, CRU_SOFTRST_CON02, 4),
416 RSTGEN(RGU_GVIHOST, CRU_SOFTRST_CON02, 5),
417 RSTGEN(RGU_DSI0, CRU_SOFTRST_CON02, 6),
418 RSTGEN(RGU_DSI1, CRU_SOFTRST_CON02, 7),
419 RSTGEN(RGU_CSI, CRU_SOFTRST_CON02, 8),
420 RSTGEN(RGU_TXDATA, CRU_SOFTRST_CON02, 9),
421 RSTGEN(RGU_DECODER, CRU_SOFTRST_CON02, 10),
422 RSTGEN(RGU_ENCODER, CRU_SOFTRST_CON02, 11),
423 RSTGEN(RGU_HDMIRX_PON, CRU_SOFTRST_CON02, 12),
424 RSTGEN(RGU_TXBYTEHS, CRU_SOFTRST_CON02, 13),
425 RSTGEN(RGU_TXESC, CRU_SOFTRST_CON02, 14),
426 };
427
rk628_rgu_update(struct rk628_cru * cru,unsigned long id,int assert)428 static int rk628_rgu_update(struct rk628_cru *cru, unsigned long id, int assert)
429 {
430 const struct rk628_rgu_data *data = &rk628_rgu_data[id];
431
432 return regmap_write(cru->regmap, data->reg,
433 BIT(data->bit + 16) | (assert << data->bit));
434 }
435
rk628_rgu_assert(struct reset_controller_dev * rcdev,unsigned long id)436 static int rk628_rgu_assert(struct reset_controller_dev *rcdev,
437 unsigned long id)
438 {
439 struct rk628_cru *cru = reset_to_cru(rcdev);
440
441 return rk628_rgu_update(cru, id, 1);
442 }
443
rk628_rgu_deassert(struct reset_controller_dev * rcdev,unsigned long id)444 static int rk628_rgu_deassert(struct reset_controller_dev *rcdev,
445 unsigned long id)
446 {
447 struct rk628_cru *cru = reset_to_cru(rcdev);
448
449 return rk628_rgu_update(cru, id, 0);
450 }
451
452 static struct reset_control_ops rk628_rgu_ops = {
453 .assert = rk628_rgu_assert,
454 .deassert = rk628_rgu_deassert,
455 };
456
rk628_reset_controller_register(struct rk628_cru * cru)457 static int rk628_reset_controller_register(struct rk628_cru *cru)
458 {
459 struct device *dev = cru->dev;
460
461 cru->rcdev.owner = THIS_MODULE;
462 cru->rcdev.nr_resets = ARRAY_SIZE(rk628_rgu_data);
463 cru->rcdev.of_node = dev->of_node;
464 cru->rcdev.ops = &rk628_rgu_ops;
465
466 return devm_reset_controller_register(dev, &cru->rcdev);
467 }
468
469 static const struct regmap_range rk628_cru_readable_ranges[] = {
470 regmap_reg_range(CRU_CPLL_CON0, CRU_CPLL_CON4),
471 regmap_reg_range(CRU_GPLL_CON0, CRU_GPLL_CON4),
472 regmap_reg_range(CRU_MODE_CON, CRU_MODE_CON),
473 regmap_reg_range(CRU_CLKSEL_CON00, CRU_CLKSEL_CON21),
474 regmap_reg_range(CRU_GATE_CON00, CRU_GATE_CON05),
475 regmap_reg_range(CRU_SOFTRST_CON00, CRU_SOFTRST_CON04),
476 };
477
478 static const struct regmap_access_table rk628_cru_readable_table = {
479 .yes_ranges = rk628_cru_readable_ranges,
480 .n_yes_ranges = ARRAY_SIZE(rk628_cru_readable_ranges),
481 };
482
483 static const struct regmap_config rk628_cru_regmap_config = {
484 .name = "cru",
485 .reg_bits = 32,
486 .val_bits = 32,
487 .reg_stride = 4,
488 .max_register = CRU_MAX_REGISTER,
489 .reg_format_endian = REGMAP_ENDIAN_LITTLE,
490 .val_format_endian = REGMAP_ENDIAN_LITTLE,
491 .rd_table = &rk628_cru_readable_table,
492 };
493
rk628_cru_init(struct rk628_cru * cru)494 static void rk628_cru_init(struct rk628_cru *cru)
495 {
496 u32 val = 0;
497 u8 mcu_mode;
498
499 regmap_read(cru->parent->grf, GRF_SYSTEM_STATUS0, &val);
500 mcu_mode = (val & I2C_ONLY_FLAG) ? 0 : 1;
501 if (mcu_mode)
502 return;
503
504 /* clock switch and first set gpll almost 99MHz */
505 regmap_write(cru->regmap, CRU_GPLL_CON0, 0xffff701d);
506 usleep_range(1000, 1100);
507 /* set clk_gpll_mux from gpll */
508 regmap_write(cru->regmap, CRU_MODE_CON, 0xffff0004);
509 usleep_range(1000, 1100);
510 /* set pclk_logic from clk_gpll_mux and set pclk div 4 */
511 regmap_write(cru->regmap, CRU_CLKSEL_CON00, 0xff0080);
512 regmap_write(cru->regmap, CRU_CLKSEL_CON00, 0xff0083);
513 /* set cpll almost 400MHz */
514 regmap_write(cru->regmap, CRU_CPLL_CON0, 0xffff3063);
515 usleep_range(1000, 1100);
516 /* set clk_cpll_mux from clk_cpll */
517 regmap_write(cru->regmap, CRU_MODE_CON, 0xffff0005);
518 /* set pclk use cpll, now div is 4 */
519 regmap_write(cru->regmap, CRU_CLKSEL_CON00, 0xff0003);
520 /* set pclk use cpll, now div is 12 */
521 regmap_write(cru->regmap, CRU_CLKSEL_CON00, 0xff000b);
522 /* gpll 983.04MHz */
523 regmap_write(cru->regmap, CRU_GPLL_CON0, 0xffff1028);
524 usleep_range(1000, 1100);
525 /* set pclk use gpll, nuw div is 0xb */
526 regmap_write(cru->regmap, CRU_CLKSEL_CON00, 0xff008b);
527 /* set cpll 1188MHz */
528 regmap_write(cru->regmap, CRU_CPLL_CON0, 0xffff1063);
529 usleep_range(1000, 1100);
530 /* set pclk use cpll, and set pclk 99MHz */
531 regmap_write(cru->regmap, CRU_CLKSEL_CON00, 0xff000b);
532 }
533
rk628_cru_probe(struct platform_device * pdev)534 static int rk628_cru_probe(struct platform_device *pdev)
535 {
536 struct rk628 *rk628 = dev_get_drvdata(pdev->dev.parent);
537 struct device *dev = &pdev->dev;
538 struct rk628_cru *cru;
539 struct clk **clk_table;
540 unsigned int i;
541 int ret;
542
543 cru = devm_kzalloc(dev, sizeof(*cru), GFP_KERNEL);
544 if (!cru)
545 return -ENOMEM;
546
547 cru->dev = dev;
548 cru->parent = rk628;
549 platform_set_drvdata(pdev, cru);
550
551 cru->regmap = devm_regmap_init_i2c(rk628->client,
552 &rk628_cru_regmap_config);
553 if (IS_ERR(cru->regmap)) {
554 ret = PTR_ERR(cru->regmap);
555 dev_err(dev, "failed to allocate register map: %d\n", ret);
556 return ret;
557 }
558
559 rk628_cru_init(cru);
560
561 clk_table = devm_kcalloc(dev, CGU_NR_CLKS, sizeof(struct clk *),
562 GFP_KERNEL);
563 if (!clk_table)
564 return -ENOMEM;
565
566 for (i = 0; i < CGU_NR_CLKS; i++)
567 clk_table[i] = ERR_PTR(-ENOENT);
568
569 cru->clk_data.clks = clk_table;
570 cru->clk_data.clk_num = CGU_NR_CLKS;
571
572 rk628_clk_register_plls(cru);
573 rk628_clk_register_muxes(cru);
574 rk628_clk_register_gates(cru);
575 rk628_clk_register_composites(cru);
576 rk628_reset_controller_register(cru);
577
578 clk_prepare_enable(clk_table[CGU_PCLK_LOGIC]);
579
580 return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
581 &cru->clk_data);
582 }
583
rk628_cru_remove(struct platform_device * pdev)584 static int rk628_cru_remove(struct platform_device *pdev)
585 {
586 of_clk_del_provider(pdev->dev.of_node);
587
588 return 0;
589 }
590
591 static const struct of_device_id rk628_cru_of_match[] = {
592 { .compatible = "rockchip,rk628-cru", },
593 {},
594 };
595 MODULE_DEVICE_TABLE(of, rk628_cru_of_match);
596
597 static struct platform_driver rk628_cru_driver = {
598 .driver = {
599 .name = "rk628-cru",
600 .of_match_table = of_match_ptr(rk628_cru_of_match),
601 },
602 .probe = rk628_cru_probe,
603 .remove = rk628_cru_remove,
604 };
605 module_platform_driver(rk628_cru_driver);
606
607 MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
608 MODULE_DESCRIPTION("Rockchip RK628 CRU driver");
609 MODULE_LICENSE("GPL v2");
610