blob: e00544bf8824e651885de72110547ca4e2d805fa [file] [log] [blame]
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001/*
2 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/platform_device.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_device.h>
20#include <linux/clk-provider.h>
21#include <linux/regmap.h>
22#include <linux/reset-controller.h>
Abhishek Sahu4577aa02016-11-25 21:11:28 +053023#include <linux/math64.h>
Varadarajan Narayanan6971e862015-11-19 17:19:29 -060024
25#include <dt-bindings/clock/qcom,gcc-ipq4019.h>
26
27#include "common.h"
28#include "clk-regmap.h"
29#include "clk-rcg.h"
30#include "clk-branch.h"
31#include "reset.h"
Abhishek Sahu4577aa02016-11-25 21:11:28 +053032#include "clk-regmap-divider.h"
33
34#define to_clk_regmap_div(_hw) container_of(to_clk_regmap(_hw),\
35 struct clk_regmap_div, clkr)
36
37#define to_clk_fepll(_hw) container_of(to_clk_regmap_div(_hw),\
38 struct clk_fepll, cdiv)
Varadarajan Narayanan6971e862015-11-19 17:19:29 -060039
40enum {
41 P_XO,
42 P_FEPLL200,
43 P_FEPLL500,
44 P_DDRPLL,
45 P_FEPLLWCSS2G,
46 P_FEPLLWCSS5G,
47 P_FEPLL125DLY,
48 P_DDRPLLAPSS,
49};
50
Abhishek Sahu4577aa02016-11-25 21:11:28 +053051/*
52 * struct clk_fepll_vco - vco feedback divider corresponds for FEPLL clocks
53 * @fdbkdiv_shift: lowest bit for FDBKDIV
54 * @fdbkdiv_width: number of bits in FDBKDIV
55 * @refclkdiv_shift: lowest bit for REFCLKDIV
56 * @refclkdiv_width: number of bits in REFCLKDIV
57 * @reg: PLL_DIV register address
58 */
59struct clk_fepll_vco {
60 u32 fdbkdiv_shift;
61 u32 fdbkdiv_width;
62 u32 refclkdiv_shift;
63 u32 refclkdiv_width;
64 u32 reg;
65};
66
67/*
68 * struct clk_fepll - clk divider corresponds to FEPLL clocks
69 * @fixed_div: fixed divider value if divider is fixed
70 * @parent_map: map from software's parent index to hardware's src_sel field
71 * @cdiv: divider values for PLL_DIV
72 * @pll_vco: vco feedback divider
73 * @div_table: mapping for actual divider value to register divider value
74 * in case of non fixed divider
75 * @freq_tbl: frequency table
76 */
77struct clk_fepll {
78 u32 fixed_div;
79 const u8 *parent_map;
80 struct clk_regmap_div cdiv;
81 const struct clk_fepll_vco *pll_vco;
82 const struct clk_div_table *div_table;
83 const struct freq_tbl *freq_tbl;
84};
85
Varadarajan Narayanan6971e862015-11-19 17:19:29 -060086static struct parent_map gcc_xo_200_500_map[] = {
87 { P_XO, 0 },
88 { P_FEPLL200, 1 },
89 { P_FEPLL500, 2 },
90};
91
92static const char * const gcc_xo_200_500[] = {
93 "xo",
94 "fepll200",
95 "fepll500",
96};
97
98static struct parent_map gcc_xo_200_map[] = {
99 { P_XO, 0 },
100 { P_FEPLL200, 1 },
101};
102
103static const char * const gcc_xo_200[] = {
104 "xo",
105 "fepll200",
106};
107
108static struct parent_map gcc_xo_200_spi_map[] = {
109 { P_XO, 0 },
110 { P_FEPLL200, 2 },
111};
112
113static const char * const gcc_xo_200_spi[] = {
114 "xo",
115 "fepll200",
116};
117
118static struct parent_map gcc_xo_sdcc1_500_map[] = {
119 { P_XO, 0 },
120 { P_DDRPLL, 1 },
121 { P_FEPLL500, 2 },
122};
123
124static const char * const gcc_xo_sdcc1_500[] = {
125 "xo",
126 "ddrpll",
127 "fepll500",
128};
129
130static struct parent_map gcc_xo_wcss2g_map[] = {
131 { P_XO, 0 },
132 { P_FEPLLWCSS2G, 1 },
133};
134
135static const char * const gcc_xo_wcss2g[] = {
136 "xo",
137 "fepllwcss2g",
138};
139
140static struct parent_map gcc_xo_wcss5g_map[] = {
141 { P_XO, 0 },
142 { P_FEPLLWCSS5G, 1 },
143};
144
145static const char * const gcc_xo_wcss5g[] = {
146 "xo",
147 "fepllwcss5g",
148};
149
150static struct parent_map gcc_xo_125_dly_map[] = {
151 { P_XO, 0 },
152 { P_FEPLL125DLY, 1 },
153};
154
155static const char * const gcc_xo_125_dly[] = {
156 "xo",
157 "fepll125dly",
158};
159
160static struct parent_map gcc_xo_ddr_500_200_map[] = {
161 { P_XO, 0 },
162 { P_FEPLL200, 3 },
163 { P_FEPLL500, 2 },
164 { P_DDRPLLAPSS, 1 },
165};
166
167static const char * const gcc_xo_ddr_500_200[] = {
168 "xo",
169 "fepll200",
170 "fepll500",
171 "ddrpllapss",
172};
173
174#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600175
176static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = {
177 F(48000000, P_XO, 1, 0, 0),
Matthew McClintockbc95d4f2016-03-23 17:04:59 -0500178 F(200000000, P_FEPLL200, 1, 0, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600179 { }
180};
181
182static struct clk_rcg2 audio_clk_src = {
183 .cmd_rcgr = 0x1b000,
184 .hid_width = 5,
185 .parent_map = gcc_xo_200_map,
186 .freq_tbl = ftbl_gcc_audio_pwm_clk,
187 .clkr.hw.init = &(struct clk_init_data){
188 .name = "audio_clk_src",
189 .parent_names = gcc_xo_200,
190 .num_parents = 2,
191 .ops = &clk_rcg2_ops,
192
193 },
194};
195
196static struct clk_branch gcc_audio_ahb_clk = {
197 .halt_reg = 0x1b010,
198 .clkr = {
199 .enable_reg = 0x1b010,
200 .enable_mask = BIT(0),
201 .hw.init = &(struct clk_init_data){
202 .name = "gcc_audio_ahb_clk",
203 .parent_names = (const char *[]){
204 "pcnoc_clk_src",
205 },
206 .flags = CLK_SET_RATE_PARENT,
207 .num_parents = 1,
208 .ops = &clk_branch2_ops,
209 },
210 },
211};
212
213static struct clk_branch gcc_audio_pwm_clk = {
214 .halt_reg = 0x1b00C,
215 .clkr = {
216 .enable_reg = 0x1b00C,
217 .enable_mask = BIT(0),
218 .hw.init = &(struct clk_init_data){
219 .name = "gcc_audio_pwm_clk",
220 .parent_names = (const char *[]){
221 "audio_clk_src",
222 },
223 .flags = CLK_SET_RATE_PARENT,
224 .num_parents = 1,
225 .ops = &clk_branch2_ops,
226 },
227 },
228};
229
230static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_i2c_apps_clk[] = {
Abhishek Sahuf7475972016-09-21 17:51:52 +0530231 F(19050000, P_FEPLL200, 10.5, 1, 1),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600232 { }
233};
234
235static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
236 .cmd_rcgr = 0x200c,
237 .hid_width = 5,
238 .parent_map = gcc_xo_200_map,
239 .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk,
240 .clkr.hw.init = &(struct clk_init_data){
241 .name = "blsp1_qup1_i2c_apps_clk_src",
242 .parent_names = gcc_xo_200,
243 .num_parents = 2,
244 .ops = &clk_rcg2_ops,
245 },
246};
247
248static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
249 .halt_reg = 0x2008,
250 .clkr = {
251 .enable_reg = 0x2008,
252 .enable_mask = BIT(0),
253 .hw.init = &(struct clk_init_data){
254 .name = "gcc_blsp1_qup1_i2c_apps_clk",
255 .parent_names = (const char *[]){
256 "blsp1_qup1_i2c_apps_clk_src",
257 },
258 .num_parents = 1,
259 .ops = &clk_branch2_ops,
260 .flags = CLK_SET_RATE_PARENT,
261 },
262 },
263};
264
265static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
266 .cmd_rcgr = 0x3000,
267 .hid_width = 5,
268 .parent_map = gcc_xo_200_map,
269 .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk,
270 .clkr.hw.init = &(struct clk_init_data){
271 .name = "blsp1_qup2_i2c_apps_clk_src",
272 .parent_names = gcc_xo_200,
273 .num_parents = 2,
274 .ops = &clk_rcg2_ops,
275 },
276};
277
278static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
279 .halt_reg = 0x3010,
280 .clkr = {
281 .enable_reg = 0x3010,
282 .enable_mask = BIT(0),
283 .hw.init = &(struct clk_init_data){
284 .name = "gcc_blsp1_qup2_i2c_apps_clk",
285 .parent_names = (const char *[]){
286 "blsp1_qup2_i2c_apps_clk_src",
287 },
288 .num_parents = 1,
289 .ops = &clk_branch2_ops,
290 .flags = CLK_SET_RATE_PARENT,
291 },
292 },
293};
294
295static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_spi_apps_clk[] = {
296 F(960000, P_XO, 12, 1, 4),
297 F(4800000, P_XO, 1, 1, 10),
298 F(9600000, P_XO, 1, 1, 5),
299 F(15000000, P_XO, 1, 1, 3),
300 F(19200000, P_XO, 1, 2, 5),
301 F(24000000, P_XO, 1, 1, 2),
302 F(48000000, P_XO, 1, 0, 0),
303 { }
304};
305
306static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
307 .cmd_rcgr = 0x2024,
308 .mnd_width = 8,
309 .hid_width = 5,
310 .parent_map = gcc_xo_200_spi_map,
311 .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk,
312 .clkr.hw.init = &(struct clk_init_data){
313 .name = "blsp1_qup1_spi_apps_clk_src",
314 .parent_names = gcc_xo_200_spi,
315 .num_parents = 2,
316 .ops = &clk_rcg2_ops,
317 },
318};
319
320static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
321 .halt_reg = 0x2004,
322 .clkr = {
323 .enable_reg = 0x2004,
324 .enable_mask = BIT(0),
325 .hw.init = &(struct clk_init_data){
326 .name = "gcc_blsp1_qup1_spi_apps_clk",
327 .parent_names = (const char *[]){
328 "blsp1_qup1_spi_apps_clk_src",
329 },
330 .num_parents = 1,
331 .ops = &clk_branch2_ops,
332 .flags = CLK_SET_RATE_PARENT,
333 },
334 },
335};
336
337static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
338 .cmd_rcgr = 0x3014,
339 .mnd_width = 8,
340 .hid_width = 5,
341 .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk,
342 .parent_map = gcc_xo_200_spi_map,
343 .clkr.hw.init = &(struct clk_init_data){
344 .name = "blsp1_qup2_spi_apps_clk_src",
345 .parent_names = gcc_xo_200_spi,
346 .num_parents = 2,
347 .ops = &clk_rcg2_ops,
348 },
349};
350
351static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
352 .halt_reg = 0x300c,
353 .clkr = {
354 .enable_reg = 0x300c,
355 .enable_mask = BIT(0),
356 .hw.init = &(struct clk_init_data){
357 .name = "gcc_blsp1_qup2_spi_apps_clk",
358 .parent_names = (const char *[]){
359 "blsp1_qup2_spi_apps_clk_src",
360 },
361 .num_parents = 1,
362 .ops = &clk_branch2_ops,
363 .flags = CLK_SET_RATE_PARENT,
364 },
365 },
366};
367
368static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = {
Matthew McClintockbc95d4f2016-03-23 17:04:59 -0500369 F(1843200, P_FEPLL200, 1, 144, 15625),
370 F(3686400, P_FEPLL200, 1, 288, 15625),
371 F(7372800, P_FEPLL200, 1, 576, 15625),
372 F(14745600, P_FEPLL200, 1, 1152, 15625),
373 F(16000000, P_FEPLL200, 1, 2, 25),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600374 F(24000000, P_XO, 1, 1, 2),
Matthew McClintockbc95d4f2016-03-23 17:04:59 -0500375 F(32000000, P_FEPLL200, 1, 4, 25),
376 F(40000000, P_FEPLL200, 1, 1, 5),
377 F(46400000, P_FEPLL200, 1, 29, 125),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600378 F(48000000, P_XO, 1, 0, 0),
379 { }
380};
381
382static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
383 .cmd_rcgr = 0x2044,
384 .mnd_width = 16,
385 .hid_width = 5,
386 .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk,
387 .parent_map = gcc_xo_200_spi_map,
388 .clkr.hw.init = &(struct clk_init_data){
389 .name = "blsp1_uart1_apps_clk_src",
390 .parent_names = gcc_xo_200_spi,
391 .num_parents = 2,
392 .ops = &clk_rcg2_ops,
393 },
394};
395
396static struct clk_branch gcc_blsp1_uart1_apps_clk = {
397 .halt_reg = 0x203c,
398 .clkr = {
399 .enable_reg = 0x203c,
400 .enable_mask = BIT(0),
401 .hw.init = &(struct clk_init_data){
402 .name = "gcc_blsp1_uart1_apps_clk",
403 .parent_names = (const char *[]){
404 "blsp1_uart1_apps_clk_src",
405 },
406 .flags = CLK_SET_RATE_PARENT,
407 .num_parents = 1,
408 .ops = &clk_branch2_ops,
409 },
410 },
411};
412
413static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
414 .cmd_rcgr = 0x3034,
415 .mnd_width = 16,
416 .hid_width = 5,
417 .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk,
418 .parent_map = gcc_xo_200_spi_map,
419 .clkr.hw.init = &(struct clk_init_data){
420 .name = "blsp1_uart2_apps_clk_src",
421 .parent_names = gcc_xo_200_spi,
422 .num_parents = 2,
423 .ops = &clk_rcg2_ops,
424 },
425};
426
427static struct clk_branch gcc_blsp1_uart2_apps_clk = {
428 .halt_reg = 0x302c,
429 .clkr = {
430 .enable_reg = 0x302c,
431 .enable_mask = BIT(0),
432 .hw.init = &(struct clk_init_data){
433 .name = "gcc_blsp1_uart2_apps_clk",
434 .parent_names = (const char *[]){
435 "blsp1_uart2_apps_clk_src",
436 },
437 .num_parents = 1,
438 .ops = &clk_branch2_ops,
439 .flags = CLK_SET_RATE_PARENT,
440 },
441 },
442};
443
444static const struct freq_tbl ftbl_gcc_gp_clk[] = {
Matthew McClintockbc95d4f2016-03-23 17:04:59 -0500445 F(1250000, P_FEPLL200, 1, 16, 0),
446 F(2500000, P_FEPLL200, 1, 8, 0),
447 F(5000000, P_FEPLL200, 1, 4, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600448 { }
449};
450
451static struct clk_rcg2 gp1_clk_src = {
452 .cmd_rcgr = 0x8004,
453 .mnd_width = 8,
454 .hid_width = 5,
455 .freq_tbl = ftbl_gcc_gp_clk,
456 .parent_map = gcc_xo_200_map,
457 .clkr.hw.init = &(struct clk_init_data){
458 .name = "gp1_clk_src",
459 .parent_names = gcc_xo_200,
460 .num_parents = 2,
461 .ops = &clk_rcg2_ops,
462 },
463};
464
465static struct clk_branch gcc_gp1_clk = {
466 .halt_reg = 0x8000,
467 .clkr = {
468 .enable_reg = 0x8000,
469 .enable_mask = BIT(0),
470 .hw.init = &(struct clk_init_data){
471 .name = "gcc_gp1_clk",
472 .parent_names = (const char *[]){
473 "gp1_clk_src",
474 },
475 .num_parents = 1,
476 .ops = &clk_branch2_ops,
477 .flags = CLK_SET_RATE_PARENT,
478 },
479 },
480};
481
482static struct clk_rcg2 gp2_clk_src = {
483 .cmd_rcgr = 0x9004,
484 .mnd_width = 8,
485 .hid_width = 5,
486 .freq_tbl = ftbl_gcc_gp_clk,
487 .parent_map = gcc_xo_200_map,
488 .clkr.hw.init = &(struct clk_init_data){
489 .name = "gp2_clk_src",
490 .parent_names = gcc_xo_200,
491 .num_parents = 2,
492 .ops = &clk_rcg2_ops,
493 },
494};
495
496static struct clk_branch gcc_gp2_clk = {
497 .halt_reg = 0x9000,
498 .clkr = {
499 .enable_reg = 0x9000,
500 .enable_mask = BIT(0),
501 .hw.init = &(struct clk_init_data){
502 .name = "gcc_gp2_clk",
503 .parent_names = (const char *[]){
504 "gp2_clk_src",
505 },
506 .num_parents = 1,
507 .ops = &clk_branch2_ops,
508 .flags = CLK_SET_RATE_PARENT,
509 },
510 },
511};
512
513static struct clk_rcg2 gp3_clk_src = {
514 .cmd_rcgr = 0xa004,
515 .mnd_width = 8,
516 .hid_width = 5,
517 .freq_tbl = ftbl_gcc_gp_clk,
518 .parent_map = gcc_xo_200_map,
519 .clkr.hw.init = &(struct clk_init_data){
520 .name = "gp3_clk_src",
521 .parent_names = gcc_xo_200,
522 .num_parents = 2,
523 .ops = &clk_rcg2_ops,
524 },
525};
526
527static struct clk_branch gcc_gp3_clk = {
528 .halt_reg = 0xa000,
529 .clkr = {
530 .enable_reg = 0xa000,
531 .enable_mask = BIT(0),
532 .hw.init = &(struct clk_init_data){
533 .name = "gcc_gp3_clk",
534 .parent_names = (const char *[]){
535 "gp3_clk_src",
536 },
537 .num_parents = 1,
538 .ops = &clk_branch2_ops,
539 .flags = CLK_SET_RATE_PARENT,
540 },
541 },
542};
543
544static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = {
545 F(144000, P_XO, 1, 3, 240),
546 F(400000, P_XO, 1, 1, 0),
Matthew McClintockbc95d4f2016-03-23 17:04:59 -0500547 F(20000000, P_FEPLL500, 1, 1, 25),
548 F(25000000, P_FEPLL500, 1, 1, 20),
549 F(50000000, P_FEPLL500, 1, 1, 10),
550 F(100000000, P_FEPLL500, 1, 1, 5),
551 F(193000000, P_DDRPLL, 1, 0, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600552 { }
553};
554
555static struct clk_rcg2 sdcc1_apps_clk_src = {
556 .cmd_rcgr = 0x18004,
557 .hid_width = 5,
558 .freq_tbl = ftbl_gcc_sdcc1_apps_clk,
559 .parent_map = gcc_xo_sdcc1_500_map,
560 .clkr.hw.init = &(struct clk_init_data){
561 .name = "sdcc1_apps_clk_src",
562 .parent_names = gcc_xo_sdcc1_500,
563 .num_parents = 3,
564 .ops = &clk_rcg2_ops,
565 .flags = CLK_SET_RATE_PARENT,
566 },
567};
568
569static const struct freq_tbl ftbl_gcc_apps_clk[] = {
570 F(48000000, P_XO, 1, 0, 0),
Matthew McClintockbc95d4f2016-03-23 17:04:59 -0500571 F(200000000, P_FEPLL200, 1, 0, 0),
572 F(500000000, P_FEPLL500, 1, 0, 0),
573 F(626000000, P_DDRPLLAPSS, 1, 0, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600574 { }
575};
576
577static struct clk_rcg2 apps_clk_src = {
578 .cmd_rcgr = 0x1900c,
579 .hid_width = 5,
580 .freq_tbl = ftbl_gcc_apps_clk,
581 .parent_map = gcc_xo_ddr_500_200_map,
582 .clkr.hw.init = &(struct clk_init_data){
583 .name = "apps_clk_src",
584 .parent_names = gcc_xo_ddr_500_200,
585 .num_parents = 4,
586 .ops = &clk_rcg2_ops,
587 },
588};
589
590static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = {
591 F(48000000, P_XO, 1, 0, 0),
Matthew McClintockbc95d4f2016-03-23 17:04:59 -0500592 F(100000000, P_FEPLL200, 2, 0, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600593 { }
594};
595
596static struct clk_rcg2 apps_ahb_clk_src = {
597 .cmd_rcgr = 0x19014,
598 .hid_width = 5,
599 .parent_map = gcc_xo_200_500_map,
600 .freq_tbl = ftbl_gcc_apps_ahb_clk,
601 .clkr.hw.init = &(struct clk_init_data){
602 .name = "apps_ahb_clk_src",
603 .parent_names = gcc_xo_200_500,
604 .num_parents = 3,
605 .ops = &clk_rcg2_ops,
606 },
607};
608
609static struct clk_branch gcc_apss_ahb_clk = {
610 .halt_reg = 0x19004,
611 .halt_check = BRANCH_HALT_VOTED,
612 .clkr = {
613 .enable_reg = 0x6000,
614 .enable_mask = BIT(14),
615 .hw.init = &(struct clk_init_data){
616 .name = "gcc_apss_ahb_clk",
617 .parent_names = (const char *[]){
618 "apps_ahb_clk_src",
619 },
620 .num_parents = 1,
621 .ops = &clk_branch2_ops,
622 .flags = CLK_SET_RATE_PARENT,
623 },
624 },
625};
626
627static struct clk_branch gcc_blsp1_ahb_clk = {
628 .halt_reg = 0x1008,
629 .halt_check = BRANCH_HALT_VOTED,
630 .clkr = {
631 .enable_reg = 0x6000,
632 .enable_mask = BIT(10),
633 .hw.init = &(struct clk_init_data){
634 .name = "gcc_blsp1_ahb_clk",
635 .parent_names = (const char *[]){
636 "pcnoc_clk_src",
637 },
638 .num_parents = 1,
639 .ops = &clk_branch2_ops,
640 },
641 },
642};
643
644static struct clk_branch gcc_dcd_xo_clk = {
645 .halt_reg = 0x2103c,
646 .clkr = {
647 .enable_reg = 0x2103c,
648 .enable_mask = BIT(0),
649 .hw.init = &(struct clk_init_data){
650 .name = "gcc_dcd_xo_clk",
651 .parent_names = (const char *[]){
652 "xo",
653 },
654 .num_parents = 1,
655 .ops = &clk_branch2_ops,
656 },
657 },
658};
659
660static struct clk_branch gcc_boot_rom_ahb_clk = {
661 .halt_reg = 0x1300c,
662 .clkr = {
663 .enable_reg = 0x1300c,
664 .enable_mask = BIT(0),
665 .hw.init = &(struct clk_init_data){
666 .name = "gcc_boot_rom_ahb_clk",
667 .parent_names = (const char *[]){
668 "pcnoc_clk_src",
669 },
670 .num_parents = 1,
671 .ops = &clk_branch2_ops,
672 .flags = CLK_SET_RATE_PARENT,
673 },
674 },
675};
676
677static struct clk_branch gcc_crypto_ahb_clk = {
678 .halt_reg = 0x16024,
679 .halt_check = BRANCH_HALT_VOTED,
680 .clkr = {
681 .enable_reg = 0x6000,
682 .enable_mask = BIT(0),
683 .hw.init = &(struct clk_init_data){
684 .name = "gcc_crypto_ahb_clk",
685 .parent_names = (const char *[]){
686 "pcnoc_clk_src",
687 },
688 .num_parents = 1,
689 .ops = &clk_branch2_ops,
690 },
691 },
692};
693
694static struct clk_branch gcc_crypto_axi_clk = {
695 .halt_reg = 0x16020,
696 .halt_check = BRANCH_HALT_VOTED,
697 .clkr = {
698 .enable_reg = 0x6000,
699 .enable_mask = BIT(1),
700 .hw.init = &(struct clk_init_data){
701 .name = "gcc_crypto_axi_clk",
702 .parent_names = (const char *[]){
703 "fepll125",
704 },
705 .num_parents = 1,
706 .ops = &clk_branch2_ops,
707 },
708 },
709};
710
711static struct clk_branch gcc_crypto_clk = {
712 .halt_reg = 0x1601c,
713 .halt_check = BRANCH_HALT_VOTED,
714 .clkr = {
715 .enable_reg = 0x6000,
716 .enable_mask = BIT(2),
717 .hw.init = &(struct clk_init_data){
718 .name = "gcc_crypto_clk",
719 .parent_names = (const char *[]){
720 "fepll125",
721 },
722 .num_parents = 1,
723 .ops = &clk_branch2_ops,
724 },
725 },
726};
727
728static struct clk_branch gcc_ess_clk = {
729 .halt_reg = 0x12010,
730 .clkr = {
731 .enable_reg = 0x12010,
732 .enable_mask = BIT(0),
733 .hw.init = &(struct clk_init_data){
734 .name = "gcc_ess_clk",
735 .parent_names = (const char *[]){
736 "fephy_125m_dly_clk_src",
737 },
738 .num_parents = 1,
739 .ops = &clk_branch2_ops,
740 .flags = CLK_SET_RATE_PARENT,
741 },
742 },
743};
744
745static struct clk_branch gcc_imem_axi_clk = {
746 .halt_reg = 0xe004,
747 .halt_check = BRANCH_HALT_VOTED,
748 .clkr = {
749 .enable_reg = 0x6000,
750 .enable_mask = BIT(17),
751 .hw.init = &(struct clk_init_data){
752 .name = "gcc_imem_axi_clk",
753 .parent_names = (const char *[]){
754 "fepll200",
755 },
756 .num_parents = 1,
757 .ops = &clk_branch2_ops,
758 },
759 },
760};
761
762static struct clk_branch gcc_imem_cfg_ahb_clk = {
763 .halt_reg = 0xe008,
764 .clkr = {
765 .enable_reg = 0xe008,
766 .enable_mask = BIT(0),
767 .hw.init = &(struct clk_init_data){
768 .name = "gcc_imem_cfg_ahb_clk",
769 .parent_names = (const char *[]){
770 "pcnoc_clk_src",
771 },
772 .num_parents = 1,
773 .ops = &clk_branch2_ops,
774 },
775 },
776};
777
778static struct clk_branch gcc_pcie_ahb_clk = {
779 .halt_reg = 0x1d00c,
780 .clkr = {
781 .enable_reg = 0x1d00c,
782 .enable_mask = BIT(0),
783 .hw.init = &(struct clk_init_data){
784 .name = "gcc_pcie_ahb_clk",
785 .parent_names = (const char *[]){
786 "pcnoc_clk_src",
787 },
788 .num_parents = 1,
789 .ops = &clk_branch2_ops,
790 },
791 },
792};
793
794static struct clk_branch gcc_pcie_axi_m_clk = {
795 .halt_reg = 0x1d004,
796 .clkr = {
797 .enable_reg = 0x1d004,
798 .enable_mask = BIT(0),
799 .hw.init = &(struct clk_init_data){
800 .name = "gcc_pcie_axi_m_clk",
801 .parent_names = (const char *[]){
802 "fepll200",
803 },
804 .num_parents = 1,
805 .ops = &clk_branch2_ops,
806 },
807 },
808};
809
810static struct clk_branch gcc_pcie_axi_s_clk = {
811 .halt_reg = 0x1d008,
812 .clkr = {
813 .enable_reg = 0x1d008,
814 .enable_mask = BIT(0),
815 .hw.init = &(struct clk_init_data){
816 .name = "gcc_pcie_axi_s_clk",
817 .parent_names = (const char *[]){
818 "fepll200",
819 },
820 .num_parents = 1,
821 .ops = &clk_branch2_ops,
822 },
823 },
824};
825
826static struct clk_branch gcc_prng_ahb_clk = {
827 .halt_reg = 0x13004,
828 .halt_check = BRANCH_HALT_VOTED,
829 .clkr = {
830 .enable_reg = 0x6000,
831 .enable_mask = BIT(8),
832 .hw.init = &(struct clk_init_data){
833 .name = "gcc_prng_ahb_clk",
834 .parent_names = (const char *[]){
835 "pcnoc_clk_src",
836 },
837 .num_parents = 1,
838 .ops = &clk_branch2_ops,
839 },
840 },
841};
842
843static struct clk_branch gcc_qpic_ahb_clk = {
844 .halt_reg = 0x1c008,
845 .clkr = {
846 .enable_reg = 0x1c008,
847 .enable_mask = BIT(0),
848 .hw.init = &(struct clk_init_data){
849 .name = "gcc_qpic_ahb_clk",
850 .parent_names = (const char *[]){
851 "pcnoc_clk_src",
852 },
853 .num_parents = 1,
854 .ops = &clk_branch2_ops,
855 },
856 },
857};
858
859static struct clk_branch gcc_qpic_clk = {
860 .halt_reg = 0x1c004,
861 .clkr = {
862 .enable_reg = 0x1c004,
863 .enable_mask = BIT(0),
864 .hw.init = &(struct clk_init_data){
865 .name = "gcc_qpic_clk",
866 .parent_names = (const char *[]){
867 "pcnoc_clk_src",
868 },
869 .num_parents = 1,
870 .ops = &clk_branch2_ops,
871 },
872 },
873};
874
875static struct clk_branch gcc_sdcc1_ahb_clk = {
876 .halt_reg = 0x18010,
877 .clkr = {
878 .enable_reg = 0x18010,
879 .enable_mask = BIT(0),
880 .hw.init = &(struct clk_init_data){
881 .name = "gcc_sdcc1_ahb_clk",
882 .parent_names = (const char *[]){
883 "pcnoc_clk_src",
884 },
885 .num_parents = 1,
886 .ops = &clk_branch2_ops,
887 },
888 },
889};
890
891static struct clk_branch gcc_sdcc1_apps_clk = {
892 .halt_reg = 0x1800c,
893 .clkr = {
894 .enable_reg = 0x1800c,
895 .enable_mask = BIT(0),
896 .hw.init = &(struct clk_init_data){
897 .name = "gcc_sdcc1_apps_clk",
898 .parent_names = (const char *[]){
899 "sdcc1_apps_clk_src",
900 },
901 .num_parents = 1,
902 .ops = &clk_branch2_ops,
903 .flags = CLK_SET_RATE_PARENT,
904 },
905 },
906};
907
908static struct clk_branch gcc_tlmm_ahb_clk = {
909 .halt_reg = 0x5004,
910 .halt_check = BRANCH_HALT_VOTED,
911 .clkr = {
912 .enable_reg = 0x6000,
913 .enable_mask = BIT(5),
914 .hw.init = &(struct clk_init_data){
915 .name = "gcc_tlmm_ahb_clk",
916 .parent_names = (const char *[]){
917 "pcnoc_clk_src",
918 },
919 .num_parents = 1,
920 .ops = &clk_branch2_ops,
921 },
922 },
923};
924
925static struct clk_branch gcc_usb2_master_clk = {
926 .halt_reg = 0x1e00c,
927 .clkr = {
928 .enable_reg = 0x1e00c,
929 .enable_mask = BIT(0),
930 .hw.init = &(struct clk_init_data){
931 .name = "gcc_usb2_master_clk",
932 .parent_names = (const char *[]){
933 "pcnoc_clk_src",
934 },
935 .num_parents = 1,
936 .ops = &clk_branch2_ops,
937 },
938 },
939};
940
941static struct clk_branch gcc_usb2_sleep_clk = {
942 .halt_reg = 0x1e010,
943 .clkr = {
944 .enable_reg = 0x1e010,
945 .enable_mask = BIT(0),
946 .hw.init = &(struct clk_init_data){
947 .name = "gcc_usb2_sleep_clk",
948 .parent_names = (const char *[]){
949 "gcc_sleep_clk_src",
950 },
951 .num_parents = 1,
952 .ops = &clk_branch2_ops,
953 },
954 },
955};
956
957static struct clk_branch gcc_usb2_mock_utmi_clk = {
958 .halt_reg = 0x1e014,
959 .clkr = {
960 .enable_reg = 0x1e014,
961 .enable_mask = BIT(0),
962 .hw.init = &(struct clk_init_data){
963 .name = "gcc_usb2_mock_utmi_clk",
964 .parent_names = (const char *[]){
965 "usb30_mock_utmi_clk_src",
966 },
967 .num_parents = 1,
968 .ops = &clk_branch2_ops,
969 .flags = CLK_SET_RATE_PARENT,
970 },
971 },
972};
973
974static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = {
Matthew McClintockbc95d4f2016-03-23 17:04:59 -0500975 F(2000000, P_FEPLL200, 10, 0, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -0600976 { }
977};
978
979static struct clk_rcg2 usb30_mock_utmi_clk_src = {
980 .cmd_rcgr = 0x1e000,
981 .hid_width = 5,
982 .parent_map = gcc_xo_200_map,
983 .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk,
984 .clkr.hw.init = &(struct clk_init_data){
985 .name = "usb30_mock_utmi_clk_src",
986 .parent_names = gcc_xo_200,
987 .num_parents = 2,
988 .ops = &clk_rcg2_ops,
989 },
990};
991
992static struct clk_branch gcc_usb3_master_clk = {
993 .halt_reg = 0x1e028,
994 .clkr = {
995 .enable_reg = 0x1e028,
996 .enable_mask = BIT(0),
997 .hw.init = &(struct clk_init_data){
998 .name = "gcc_usb3_master_clk",
999 .parent_names = (const char *[]){
1000 "fepll125",
1001 },
1002 .num_parents = 1,
1003 .ops = &clk_branch2_ops,
1004 },
1005 },
1006};
1007
1008static struct clk_branch gcc_usb3_sleep_clk = {
1009 .halt_reg = 0x1e02C,
1010 .clkr = {
1011 .enable_reg = 0x1e02C,
1012 .enable_mask = BIT(0),
1013 .hw.init = &(struct clk_init_data){
1014 .name = "gcc_usb3_sleep_clk",
1015 .parent_names = (const char *[]){
1016 "gcc_sleep_clk_src",
1017 },
1018 .num_parents = 1,
1019 .ops = &clk_branch2_ops,
1020 },
1021 },
1022};
1023
1024static struct clk_branch gcc_usb3_mock_utmi_clk = {
1025 .halt_reg = 0x1e030,
1026 .clkr = {
1027 .enable_reg = 0x1e030,
1028 .enable_mask = BIT(0),
1029 .hw.init = &(struct clk_init_data){
1030 .name = "gcc_usb3_mock_utmi_clk",
1031 .parent_names = (const char *[]){
1032 "usb30_mock_utmi_clk_src",
1033 },
1034 .num_parents = 1,
1035 .ops = &clk_branch2_ops,
1036 .flags = CLK_SET_RATE_PARENT,
1037 },
1038 },
1039};
1040
1041static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = {
Matthew McClintockbc95d4f2016-03-23 17:04:59 -05001042 F(125000000, P_FEPLL125DLY, 1, 0, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001043 { }
1044};
1045
1046static struct clk_rcg2 fephy_125m_dly_clk_src = {
1047 .cmd_rcgr = 0x12000,
1048 .hid_width = 5,
1049 .parent_map = gcc_xo_125_dly_map,
1050 .freq_tbl = ftbl_gcc_fephy_dly_clk,
1051 .clkr.hw.init = &(struct clk_init_data){
1052 .name = "fephy_125m_dly_clk_src",
1053 .parent_names = gcc_xo_125_dly,
1054 .num_parents = 2,
1055 .ops = &clk_rcg2_ops,
1056 },
1057};
1058
1059
1060static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = {
1061 F(48000000, P_XO, 1, 0, 0),
Matthew McClintockbc95d4f2016-03-23 17:04:59 -05001062 F(250000000, P_FEPLLWCSS2G, 1, 0, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001063 { }
1064};
1065
1066static struct clk_rcg2 wcss2g_clk_src = {
1067 .cmd_rcgr = 0x1f000,
1068 .hid_width = 5,
1069 .freq_tbl = ftbl_gcc_wcss2g_clk,
1070 .parent_map = gcc_xo_wcss2g_map,
1071 .clkr.hw.init = &(struct clk_init_data){
1072 .name = "wcss2g_clk_src",
1073 .parent_names = gcc_xo_wcss2g,
1074 .num_parents = 2,
1075 .ops = &clk_rcg2_ops,
1076 .flags = CLK_SET_RATE_PARENT,
1077 },
1078};
1079
1080static struct clk_branch gcc_wcss2g_clk = {
1081 .halt_reg = 0x1f00C,
1082 .clkr = {
1083 .enable_reg = 0x1f00C,
1084 .enable_mask = BIT(0),
1085 .hw.init = &(struct clk_init_data){
1086 .name = "gcc_wcss2g_clk",
1087 .parent_names = (const char *[]){
1088 "wcss2g_clk_src",
1089 },
1090 .num_parents = 1,
1091 .ops = &clk_branch2_ops,
1092 .flags = CLK_SET_RATE_PARENT,
1093 },
1094 },
1095};
1096
1097static struct clk_branch gcc_wcss2g_ref_clk = {
1098 .halt_reg = 0x1f00C,
1099 .clkr = {
1100 .enable_reg = 0x1f00C,
1101 .enable_mask = BIT(0),
1102 .hw.init = &(struct clk_init_data){
1103 .name = "gcc_wcss2g_ref_clk",
1104 .parent_names = (const char *[]){
1105 "xo",
1106 },
1107 .num_parents = 1,
1108 .ops = &clk_branch2_ops,
1109 .flags = CLK_SET_RATE_PARENT,
1110 },
1111 },
1112};
1113
1114static struct clk_branch gcc_wcss2g_rtc_clk = {
1115 .halt_reg = 0x1f010,
1116 .clkr = {
1117 .enable_reg = 0x1f010,
1118 .enable_mask = BIT(0),
1119 .hw.init = &(struct clk_init_data){
1120 .name = "gcc_wcss2g_rtc_clk",
1121 .parent_names = (const char *[]){
1122 "gcc_sleep_clk_src",
1123 },
1124 .num_parents = 1,
1125 .ops = &clk_branch2_ops,
1126 },
1127 },
1128};
1129
1130static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = {
1131 F(48000000, P_XO, 1, 0, 0),
Matthew McClintockbc95d4f2016-03-23 17:04:59 -05001132 F(250000000, P_FEPLLWCSS5G, 1, 0, 0),
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001133 { }
1134};
1135
1136static struct clk_rcg2 wcss5g_clk_src = {
1137 .cmd_rcgr = 0x20000,
1138 .hid_width = 5,
1139 .parent_map = gcc_xo_wcss5g_map,
1140 .freq_tbl = ftbl_gcc_wcss5g_clk,
1141 .clkr.hw.init = &(struct clk_init_data){
1142 .name = "wcss5g_clk_src",
1143 .parent_names = gcc_xo_wcss5g,
1144 .num_parents = 2,
1145 .ops = &clk_rcg2_ops,
1146 },
1147};
1148
1149static struct clk_branch gcc_wcss5g_clk = {
1150 .halt_reg = 0x2000c,
1151 .clkr = {
1152 .enable_reg = 0x2000c,
1153 .enable_mask = BIT(0),
1154 .hw.init = &(struct clk_init_data){
1155 .name = "gcc_wcss5g_clk",
1156 .parent_names = (const char *[]){
1157 "wcss5g_clk_src",
1158 },
1159 .num_parents = 1,
1160 .ops = &clk_branch2_ops,
1161 .flags = CLK_SET_RATE_PARENT,
1162 },
1163 },
1164};
1165
1166static struct clk_branch gcc_wcss5g_ref_clk = {
1167 .halt_reg = 0x2000c,
1168 .clkr = {
1169 .enable_reg = 0x2000c,
1170 .enable_mask = BIT(0),
1171 .hw.init = &(struct clk_init_data){
1172 .name = "gcc_wcss5g_ref_clk",
1173 .parent_names = (const char *[]){
1174 "xo",
1175 },
1176 .num_parents = 1,
1177 .ops = &clk_branch2_ops,
1178 .flags = CLK_SET_RATE_PARENT,
1179 },
1180 },
1181};
1182
1183static struct clk_branch gcc_wcss5g_rtc_clk = {
1184 .halt_reg = 0x20010,
1185 .clkr = {
1186 .enable_reg = 0x20010,
1187 .enable_mask = BIT(0),
1188 .hw.init = &(struct clk_init_data){
1189 .name = "gcc_wcss5g_rtc_clk",
1190 .parent_names = (const char *[]){
1191 "gcc_sleep_clk_src",
1192 },
1193 .num_parents = 1,
1194 .ops = &clk_branch2_ops,
1195 .flags = CLK_SET_RATE_PARENT,
1196 },
1197 },
1198};
1199
Abhishek Sahu4577aa02016-11-25 21:11:28 +05301200/* Calculates the VCO rate for FEPLL. */
1201static u64 clk_fepll_vco_calc_rate(struct clk_fepll *pll_div,
1202 unsigned long parent_rate)
1203{
1204 const struct clk_fepll_vco *pll_vco = pll_div->pll_vco;
1205 u32 fdbkdiv, refclkdiv, cdiv;
1206 u64 vco;
1207
1208 regmap_read(pll_div->cdiv.clkr.regmap, pll_vco->reg, &cdiv);
1209 refclkdiv = (cdiv >> pll_vco->refclkdiv_shift) &
1210 (BIT(pll_vco->refclkdiv_width) - 1);
1211 fdbkdiv = (cdiv >> pll_vco->fdbkdiv_shift) &
1212 (BIT(pll_vco->fdbkdiv_width) - 1);
1213
1214 vco = parent_rate / refclkdiv;
1215 vco *= 2;
1216 vco *= fdbkdiv;
1217
1218 return vco;
1219}
1220
1221static const struct clk_fepll_vco gcc_apss_ddrpll_vco = {
1222 .fdbkdiv_shift = 16,
1223 .fdbkdiv_width = 8,
1224 .refclkdiv_shift = 24,
1225 .refclkdiv_width = 5,
1226 .reg = 0x2e020,
1227};
1228
1229static const struct clk_fepll_vco gcc_fepll_vco = {
1230 .fdbkdiv_shift = 16,
1231 .fdbkdiv_width = 8,
1232 .refclkdiv_shift = 24,
1233 .refclkdiv_width = 5,
1234 .reg = 0x2f020,
1235};
1236
1237/* Calculates the rate for PLL divider.
1238 * If the divider value is not fixed then it gets the actual divider value
1239 * from divider table. Then, it calculate the clock rate by dividing the
1240 * parent rate with actual divider value.
1241 */
1242static unsigned long
1243clk_regmap_clk_div_recalc_rate(struct clk_hw *hw,
1244 unsigned long parent_rate)
1245{
1246 struct clk_fepll *pll = to_clk_fepll(hw);
1247 u32 cdiv, pre_div = 1;
1248 u64 rate;
1249 const struct clk_div_table *clkt;
1250
1251 if (pll->fixed_div) {
1252 pre_div = pll->fixed_div;
1253 } else {
1254 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
1255 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
1256
1257 for (clkt = pll->div_table; clkt->div; clkt++) {
1258 if (clkt->val == cdiv)
1259 pre_div = clkt->div;
1260 }
1261 }
1262
1263 rate = clk_fepll_vco_calc_rate(pll, parent_rate);
1264 do_div(rate, pre_div);
1265
1266 return rate;
1267};
1268
1269static const struct clk_ops clk_fepll_div_ops = {
1270 .recalc_rate = clk_regmap_clk_div_recalc_rate,
1271};
1272
1273static struct clk_fepll gcc_apss_sdcc_clk = {
1274 .fixed_div = 28,
1275 .cdiv.clkr = {
1276 .hw.init = &(struct clk_init_data){
1277 .name = "ddrpllsdcc",
1278 .parent_names = (const char *[]){
1279 "xo",
1280 },
1281 .num_parents = 1,
1282 .ops = &clk_fepll_div_ops,
1283 },
1284 },
1285 .pll_vco = &gcc_apss_ddrpll_vco,
1286};
1287
1288static struct clk_fepll gcc_fepll125_clk = {
1289 .fixed_div = 32,
1290 .cdiv.clkr = {
1291 .hw.init = &(struct clk_init_data){
1292 .name = "fepll125",
1293 .parent_names = (const char *[]){
1294 "xo",
1295 },
1296 .num_parents = 1,
1297 .ops = &clk_fepll_div_ops,
1298 },
1299 },
1300 .pll_vco = &gcc_fepll_vco,
1301};
1302
1303static struct clk_fepll gcc_fepll125dly_clk = {
1304 .fixed_div = 32,
1305 .cdiv.clkr = {
1306 .hw.init = &(struct clk_init_data){
1307 .name = "fepll125dly",
1308 .parent_names = (const char *[]){
1309 "xo",
1310 },
1311 .num_parents = 1,
1312 .ops = &clk_fepll_div_ops,
1313 },
1314 },
1315 .pll_vco = &gcc_fepll_vco,
1316};
1317
1318static struct clk_fepll gcc_fepll200_clk = {
1319 .fixed_div = 20,
1320 .cdiv.clkr = {
1321 .hw.init = &(struct clk_init_data){
1322 .name = "fepll200",
1323 .parent_names = (const char *[]){
1324 "xo",
1325 },
1326 .num_parents = 1,
1327 .ops = &clk_fepll_div_ops,
1328 },
1329 },
1330 .pll_vco = &gcc_fepll_vco,
1331};
1332
1333static struct clk_fepll gcc_fepll500_clk = {
1334 .fixed_div = 8,
1335 .cdiv.clkr = {
1336 .hw.init = &(struct clk_init_data){
1337 .name = "fepll500",
1338 .parent_names = (const char *[]){
1339 "xo",
1340 },
1341 .num_parents = 1,
1342 .ops = &clk_fepll_div_ops,
1343 },
1344 },
1345 .pll_vco = &gcc_fepll_vco,
1346};
1347
1348static const struct clk_div_table fepllwcss_clk_div_table[] = {
1349 { 0, 15 },
1350 { 1, 16 },
1351 { 2, 18 },
1352 { 3, 20 },
1353 { },
1354};
1355
1356static struct clk_fepll gcc_fepllwcss2g_clk = {
1357 .cdiv.reg = 0x2f020,
1358 .cdiv.shift = 8,
1359 .cdiv.width = 2,
1360 .cdiv.clkr = {
1361 .hw.init = &(struct clk_init_data){
1362 .name = "fepllwcss2g",
1363 .parent_names = (const char *[]){
1364 "xo",
1365 },
1366 .num_parents = 1,
1367 .ops = &clk_fepll_div_ops,
1368 },
1369 },
1370 .div_table = fepllwcss_clk_div_table,
1371 .pll_vco = &gcc_fepll_vco,
1372};
1373
1374static struct clk_fepll gcc_fepllwcss5g_clk = {
1375 .cdiv.reg = 0x2f020,
1376 .cdiv.shift = 12,
1377 .cdiv.width = 2,
1378 .cdiv.clkr = {
1379 .hw.init = &(struct clk_init_data){
1380 .name = "fepllwcss5g",
1381 .parent_names = (const char *[]){
1382 "xo",
1383 },
1384 .num_parents = 1,
1385 .ops = &clk_fepll_div_ops,
1386 },
1387 },
1388 .div_table = fepllwcss_clk_div_table,
1389 .pll_vco = &gcc_fepll_vco,
1390};
1391
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001392static struct clk_regmap *gcc_ipq4019_clocks[] = {
1393 [AUDIO_CLK_SRC] = &audio_clk_src.clkr,
1394 [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
1395 [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
1396 [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
1397 [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
1398 [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
1399 [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
1400 [GCC_USB3_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
1401 [GCC_APPS_CLK_SRC] = &apps_clk_src.clkr,
1402 [GCC_APPS_AHB_CLK_SRC] = &apps_ahb_clk_src.clkr,
1403 [GP1_CLK_SRC] = &gp1_clk_src.clkr,
1404 [GP2_CLK_SRC] = &gp2_clk_src.clkr,
1405 [GP3_CLK_SRC] = &gp3_clk_src.clkr,
1406 [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
1407 [FEPHY_125M_DLY_CLK_SRC] = &fephy_125m_dly_clk_src.clkr,
1408 [WCSS2G_CLK_SRC] = &wcss2g_clk_src.clkr,
1409 [WCSS5G_CLK_SRC] = &wcss5g_clk_src.clkr,
1410 [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
1411 [GCC_AUDIO_AHB_CLK] = &gcc_audio_ahb_clk.clkr,
1412 [GCC_AUDIO_PWM_CLK] = &gcc_audio_pwm_clk.clkr,
1413 [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
1414 [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
1415 [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
1416 [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
1417 [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
1418 [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
1419 [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
1420 [GCC_DCD_XO_CLK] = &gcc_dcd_xo_clk.clkr,
1421 [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
1422 [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
1423 [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
1424 [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
1425 [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
1426 [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
1427 [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
1428 [GCC_ESS_CLK] = &gcc_ess_clk.clkr,
1429 [GCC_IMEM_AXI_CLK] = &gcc_imem_axi_clk.clkr,
1430 [GCC_IMEM_CFG_AHB_CLK] = &gcc_imem_cfg_ahb_clk.clkr,
1431 [GCC_PCIE_AHB_CLK] = &gcc_pcie_ahb_clk.clkr,
1432 [GCC_PCIE_AXI_M_CLK] = &gcc_pcie_axi_m_clk.clkr,
1433 [GCC_PCIE_AXI_S_CLK] = &gcc_pcie_axi_s_clk.clkr,
1434 [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
1435 [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr,
1436 [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr,
1437 [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
1438 [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
1439 [GCC_TLMM_AHB_CLK] = &gcc_tlmm_ahb_clk.clkr,
1440 [GCC_USB2_MASTER_CLK] = &gcc_usb2_master_clk.clkr,
1441 [GCC_USB2_SLEEP_CLK] = &gcc_usb2_sleep_clk.clkr,
1442 [GCC_USB2_MOCK_UTMI_CLK] = &gcc_usb2_mock_utmi_clk.clkr,
1443 [GCC_USB3_MASTER_CLK] = &gcc_usb3_master_clk.clkr,
1444 [GCC_USB3_SLEEP_CLK] = &gcc_usb3_sleep_clk.clkr,
1445 [GCC_USB3_MOCK_UTMI_CLK] = &gcc_usb3_mock_utmi_clk.clkr,
1446 [GCC_WCSS2G_CLK] = &gcc_wcss2g_clk.clkr,
1447 [GCC_WCSS2G_REF_CLK] = &gcc_wcss2g_ref_clk.clkr,
1448 [GCC_WCSS2G_RTC_CLK] = &gcc_wcss2g_rtc_clk.clkr,
1449 [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr,
1450 [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr,
1451 [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr,
Abhishek Sahu4577aa02016-11-25 21:11:28 +05301452 [GCC_SDCC_PLLDIV_CLK] = &gcc_apss_sdcc_clk.cdiv.clkr,
1453 [GCC_FEPLL125_CLK] = &gcc_fepll125_clk.cdiv.clkr,
1454 [GCC_FEPLL125DLY_CLK] = &gcc_fepll125dly_clk.cdiv.clkr,
1455 [GCC_FEPLL200_CLK] = &gcc_fepll200_clk.cdiv.clkr,
1456 [GCC_FEPLL500_CLK] = &gcc_fepll500_clk.cdiv.clkr,
1457 [GCC_FEPLL_WCSS2G_CLK] = &gcc_fepllwcss2g_clk.cdiv.clkr,
1458 [GCC_FEPLL_WCSS5G_CLK] = &gcc_fepllwcss5g_clk.cdiv.clkr,
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001459};
1460
1461static const struct qcom_reset_map gcc_ipq4019_resets[] = {
1462 [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
1463 [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
1464 [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
1465 [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
1466 [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
1467 [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
1468 [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
1469 [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
1470 [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
1471 [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
1472 [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
1473 [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
1474 [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
1475 [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
1476 [USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
1477 [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
1478 [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
1479 [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
1480 [PCIE_AHB_ARES] = { 0x1d010, 10 },
1481 [PCIE_PWR_ARES] = { 0x1d010, 9 },
1482 [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
1483 [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
1484 [PCIE_PHY_ARES] = { 0x1d010, 6 },
1485 [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
1486 [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
1487 [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
1488 [PCIE_PIPE_ARES] = { 0x1d010, 2 },
1489 [PCIE_AXI_S_ARES] = { 0x1d010, 1 },
1490 [PCIE_AXI_M_ARES] = { 0x1d010, 0 },
1491 [ESS_RESET] = { 0x12008, 0},
1492 [GCC_BLSP1_BCR] = {0x01000, 0},
1493 [GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
1494 [GCC_BLSP1_UART1_BCR] = {0x02038, 0},
1495 [GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
1496 [GCC_BLSP1_UART2_BCR] = {0x03028, 0},
1497 [GCC_BIMC_BCR] = {0x04000, 0},
1498 [GCC_TLMM_BCR] = {0x05000, 0},
1499 [GCC_IMEM_BCR] = {0x0E000, 0},
1500 [GCC_ESS_BCR] = {0x12008, 0},
1501 [GCC_PRNG_BCR] = {0x13000, 0},
1502 [GCC_BOOT_ROM_BCR] = {0x13008, 0},
1503 [GCC_CRYPTO_BCR] = {0x16000, 0},
1504 [GCC_SDCC1_BCR] = {0x18000, 0},
1505 [GCC_SEC_CTRL_BCR] = {0x1A000, 0},
1506 [GCC_AUDIO_BCR] = {0x1B008, 0},
1507 [GCC_QPIC_BCR] = {0x1C000, 0},
1508 [GCC_PCIE_BCR] = {0x1D000, 0},
1509 [GCC_USB2_BCR] = {0x1E008, 0},
1510 [GCC_USB2_PHY_BCR] = {0x1E018, 0},
1511 [GCC_USB3_BCR] = {0x1E024, 0},
1512 [GCC_USB3_PHY_BCR] = {0x1E034, 0},
1513 [GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
1514 [GCC_PCNOC_BCR] = {0x2102C, 0},
1515 [GCC_DCD_BCR] = {0x21038, 0},
1516 [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
1517 [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
1518 [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
1519 [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
1520 [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
1521 [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
1522 [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
1523 [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
1524 [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
1525 [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
1526 [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
1527 [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
1528 [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
1529 [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
1530 [GCC_TCSR_BCR] = {0x22000, 0},
1531 [GCC_MPM_BCR] = {0x24000, 0},
1532 [GCC_SPDM_BCR] = {0x25000, 0},
1533};
1534
1535static const struct regmap_config gcc_ipq4019_regmap_config = {
1536 .reg_bits = 32,
1537 .reg_stride = 4,
1538 .val_bits = 32,
Abhishek Sahu4577aa02016-11-25 21:11:28 +05301539 .max_register = 0x2ffff,
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001540 .fast_io = true,
1541};
1542
1543static const struct qcom_cc_desc gcc_ipq4019_desc = {
1544 .config = &gcc_ipq4019_regmap_config,
1545 .clks = gcc_ipq4019_clocks,
1546 .num_clks = ARRAY_SIZE(gcc_ipq4019_clocks),
1547 .resets = gcc_ipq4019_resets,
1548 .num_resets = ARRAY_SIZE(gcc_ipq4019_resets),
1549};
1550
1551static const struct of_device_id gcc_ipq4019_match_table[] = {
1552 { .compatible = "qcom,gcc-ipq4019" },
1553 { }
1554};
1555MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table);
1556
1557static int gcc_ipq4019_probe(struct platform_device *pdev)
1558{
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001559 return qcom_cc_probe(pdev, &gcc_ipq4019_desc);
1560}
1561
1562static struct platform_driver gcc_ipq4019_driver = {
1563 .probe = gcc_ipq4019_probe,
1564 .driver = {
1565 .name = "qcom,gcc-ipq4019",
Varadarajan Narayanan6971e862015-11-19 17:19:29 -06001566 .of_match_table = gcc_ipq4019_match_table,
1567 },
1568};
1569
1570static int __init gcc_ipq4019_init(void)
1571{
1572 return platform_driver_register(&gcc_ipq4019_driver);
1573}
1574core_initcall(gcc_ipq4019_init);
1575
1576static void __exit gcc_ipq4019_exit(void)
1577{
1578 platform_driver_unregister(&gcc_ipq4019_driver);
1579}
1580module_exit(gcc_ipq4019_exit);
1581
1582MODULE_ALIAS("platform:gcc-ipq4019");
1583MODULE_LICENSE("GPL v2");
1584MODULE_DESCRIPTION("QCOM GCC IPQ4019 driver");