0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/err.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/of_device.h>
0012 #include <linux/clk-provider.h>
0013 #include <linux/regmap.h>
0014 #include <linux/reset-controller.h>
0015 #include <linux/math64.h>
0016 #include <linux/delay.h>
0017 #include <linux/clk.h>
0018
0019 #include <dt-bindings/clock/qcom,gcc-ipq4019.h>
0020
0021 #include "common.h"
0022 #include "clk-regmap.h"
0023 #include "clk-rcg.h"
0024 #include "clk-branch.h"
0025 #include "reset.h"
0026 #include "clk-regmap-divider.h"
0027
0028 #define to_clk_regmap_div(_hw) container_of(to_clk_regmap(_hw),\
0029 struct clk_regmap_div, clkr)
0030
0031 #define to_clk_fepll(_hw) container_of(to_clk_regmap_div(_hw),\
0032 struct clk_fepll, cdiv)
0033
0034 enum {
0035 P_XO,
0036 P_FEPLL200,
0037 P_FEPLL500,
0038 P_DDRPLL,
0039 P_FEPLLWCSS2G,
0040 P_FEPLLWCSS5G,
0041 P_FEPLL125DLY,
0042 P_DDRPLLAPSS,
0043 };
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 struct clk_fepll_vco {
0054 u32 fdbkdiv_shift;
0055 u32 fdbkdiv_width;
0056 u32 refclkdiv_shift;
0057 u32 refclkdiv_width;
0058 u32 reg;
0059 };
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 struct clk_fepll {
0072 u32 fixed_div;
0073 const u8 *parent_map;
0074 struct clk_regmap_div cdiv;
0075 const struct clk_fepll_vco *pll_vco;
0076 const struct clk_div_table *div_table;
0077 const struct freq_tbl *freq_tbl;
0078 };
0079
0080 static struct parent_map gcc_xo_200_500_map[] = {
0081 { P_XO, 0 },
0082 { P_FEPLL200, 1 },
0083 { P_FEPLL500, 2 },
0084 };
0085
0086 static const char * const gcc_xo_200_500[] = {
0087 "xo",
0088 "fepll200",
0089 "fepll500",
0090 };
0091
0092 static struct parent_map gcc_xo_200_map[] = {
0093 { P_XO, 0 },
0094 { P_FEPLL200, 1 },
0095 };
0096
0097 static const char * const gcc_xo_200[] = {
0098 "xo",
0099 "fepll200",
0100 };
0101
0102 static struct parent_map gcc_xo_200_spi_map[] = {
0103 { P_XO, 0 },
0104 { P_FEPLL200, 2 },
0105 };
0106
0107 static const char * const gcc_xo_200_spi[] = {
0108 "xo",
0109 "fepll200",
0110 };
0111
0112 static struct parent_map gcc_xo_sdcc1_500_map[] = {
0113 { P_XO, 0 },
0114 { P_DDRPLL, 1 },
0115 { P_FEPLL500, 2 },
0116 };
0117
0118 static const char * const gcc_xo_sdcc1_500[] = {
0119 "xo",
0120 "ddrpllsdcc",
0121 "fepll500",
0122 };
0123
0124 static struct parent_map gcc_xo_wcss2g_map[] = {
0125 { P_XO, 0 },
0126 { P_FEPLLWCSS2G, 1 },
0127 };
0128
0129 static const char * const gcc_xo_wcss2g[] = {
0130 "xo",
0131 "fepllwcss2g",
0132 };
0133
0134 static struct parent_map gcc_xo_wcss5g_map[] = {
0135 { P_XO, 0 },
0136 { P_FEPLLWCSS5G, 1 },
0137 };
0138
0139 static const char * const gcc_xo_wcss5g[] = {
0140 "xo",
0141 "fepllwcss5g",
0142 };
0143
0144 static struct parent_map gcc_xo_125_dly_map[] = {
0145 { P_XO, 0 },
0146 { P_FEPLL125DLY, 1 },
0147 };
0148
0149 static const char * const gcc_xo_125_dly[] = {
0150 "xo",
0151 "fepll125dly",
0152 };
0153
0154 static struct parent_map gcc_xo_ddr_500_200_map[] = {
0155 { P_XO, 0 },
0156 { P_FEPLL200, 3 },
0157 { P_FEPLL500, 2 },
0158 { P_DDRPLLAPSS, 1 },
0159 };
0160
0161
0162
0163
0164
0165
0166 static const int gcc_ipq4019_cpu_safe_parent = 2;
0167 static const char * const gcc_xo_ddr_500_200[] = {
0168 "xo",
0169 "fepll200",
0170 "fepll500",
0171 "ddrpllapss",
0172 };
0173
0174 static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = {
0175 F(48000000, P_XO, 1, 0, 0),
0176 F(200000000, P_FEPLL200, 1, 0, 0),
0177 { }
0178 };
0179
0180 static struct clk_rcg2 audio_clk_src = {
0181 .cmd_rcgr = 0x1b000,
0182 .hid_width = 5,
0183 .parent_map = gcc_xo_200_map,
0184 .freq_tbl = ftbl_gcc_audio_pwm_clk,
0185 .clkr.hw.init = &(struct clk_init_data){
0186 .name = "audio_clk_src",
0187 .parent_names = gcc_xo_200,
0188 .num_parents = 2,
0189 .ops = &clk_rcg2_ops,
0190
0191 },
0192 };
0193
0194 static struct clk_branch gcc_audio_ahb_clk = {
0195 .halt_reg = 0x1b010,
0196 .clkr = {
0197 .enable_reg = 0x1b010,
0198 .enable_mask = BIT(0),
0199 .hw.init = &(struct clk_init_data){
0200 .name = "gcc_audio_ahb_clk",
0201 .parent_names = (const char *[]){
0202 "pcnoc_clk_src",
0203 },
0204 .flags = CLK_SET_RATE_PARENT,
0205 .num_parents = 1,
0206 .ops = &clk_branch2_ops,
0207 },
0208 },
0209 };
0210
0211 static struct clk_branch gcc_audio_pwm_clk = {
0212 .halt_reg = 0x1b00C,
0213 .clkr = {
0214 .enable_reg = 0x1b00C,
0215 .enable_mask = BIT(0),
0216 .hw.init = &(struct clk_init_data){
0217 .name = "gcc_audio_pwm_clk",
0218 .parent_names = (const char *[]){
0219 "audio_clk_src",
0220 },
0221 .flags = CLK_SET_RATE_PARENT,
0222 .num_parents = 1,
0223 .ops = &clk_branch2_ops,
0224 },
0225 },
0226 };
0227
0228 static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_i2c_apps_clk[] = {
0229 F(19050000, P_FEPLL200, 10.5, 1, 1),
0230 { }
0231 };
0232
0233 static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
0234 .cmd_rcgr = 0x200c,
0235 .hid_width = 5,
0236 .parent_map = gcc_xo_200_map,
0237 .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk,
0238 .clkr.hw.init = &(struct clk_init_data){
0239 .name = "blsp1_qup1_i2c_apps_clk_src",
0240 .parent_names = gcc_xo_200,
0241 .num_parents = 2,
0242 .ops = &clk_rcg2_ops,
0243 },
0244 };
0245
0246 static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
0247 .halt_reg = 0x2008,
0248 .clkr = {
0249 .enable_reg = 0x2008,
0250 .enable_mask = BIT(0),
0251 .hw.init = &(struct clk_init_data){
0252 .name = "gcc_blsp1_qup1_i2c_apps_clk",
0253 .parent_names = (const char *[]){
0254 "blsp1_qup1_i2c_apps_clk_src",
0255 },
0256 .num_parents = 1,
0257 .ops = &clk_branch2_ops,
0258 .flags = CLK_SET_RATE_PARENT,
0259 },
0260 },
0261 };
0262
0263 static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
0264 .cmd_rcgr = 0x3000,
0265 .hid_width = 5,
0266 .parent_map = gcc_xo_200_map,
0267 .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk,
0268 .clkr.hw.init = &(struct clk_init_data){
0269 .name = "blsp1_qup2_i2c_apps_clk_src",
0270 .parent_names = gcc_xo_200,
0271 .num_parents = 2,
0272 .ops = &clk_rcg2_ops,
0273 },
0274 };
0275
0276 static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
0277 .halt_reg = 0x3010,
0278 .clkr = {
0279 .enable_reg = 0x3010,
0280 .enable_mask = BIT(0),
0281 .hw.init = &(struct clk_init_data){
0282 .name = "gcc_blsp1_qup2_i2c_apps_clk",
0283 .parent_names = (const char *[]){
0284 "blsp1_qup2_i2c_apps_clk_src",
0285 },
0286 .num_parents = 1,
0287 .ops = &clk_branch2_ops,
0288 .flags = CLK_SET_RATE_PARENT,
0289 },
0290 },
0291 };
0292
0293 static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_spi_apps_clk[] = {
0294 F(960000, P_XO, 12, 1, 4),
0295 F(4800000, P_XO, 1, 1, 10),
0296 F(9600000, P_XO, 1, 1, 5),
0297 F(15000000, P_XO, 1, 1, 3),
0298 F(19200000, P_XO, 1, 2, 5),
0299 F(24000000, P_XO, 1, 1, 2),
0300 F(48000000, P_XO, 1, 0, 0),
0301 { }
0302 };
0303
0304 static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
0305 .cmd_rcgr = 0x2024,
0306 .mnd_width = 8,
0307 .hid_width = 5,
0308 .parent_map = gcc_xo_200_spi_map,
0309 .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk,
0310 .clkr.hw.init = &(struct clk_init_data){
0311 .name = "blsp1_qup1_spi_apps_clk_src",
0312 .parent_names = gcc_xo_200_spi,
0313 .num_parents = 2,
0314 .ops = &clk_rcg2_ops,
0315 },
0316 };
0317
0318 static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
0319 .halt_reg = 0x2004,
0320 .clkr = {
0321 .enable_reg = 0x2004,
0322 .enable_mask = BIT(0),
0323 .hw.init = &(struct clk_init_data){
0324 .name = "gcc_blsp1_qup1_spi_apps_clk",
0325 .parent_names = (const char *[]){
0326 "blsp1_qup1_spi_apps_clk_src",
0327 },
0328 .num_parents = 1,
0329 .ops = &clk_branch2_ops,
0330 .flags = CLK_SET_RATE_PARENT,
0331 },
0332 },
0333 };
0334
0335 static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
0336 .cmd_rcgr = 0x3014,
0337 .mnd_width = 8,
0338 .hid_width = 5,
0339 .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk,
0340 .parent_map = gcc_xo_200_spi_map,
0341 .clkr.hw.init = &(struct clk_init_data){
0342 .name = "blsp1_qup2_spi_apps_clk_src",
0343 .parent_names = gcc_xo_200_spi,
0344 .num_parents = 2,
0345 .ops = &clk_rcg2_ops,
0346 },
0347 };
0348
0349 static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
0350 .halt_reg = 0x300c,
0351 .clkr = {
0352 .enable_reg = 0x300c,
0353 .enable_mask = BIT(0),
0354 .hw.init = &(struct clk_init_data){
0355 .name = "gcc_blsp1_qup2_spi_apps_clk",
0356 .parent_names = (const char *[]){
0357 "blsp1_qup2_spi_apps_clk_src",
0358 },
0359 .num_parents = 1,
0360 .ops = &clk_branch2_ops,
0361 .flags = CLK_SET_RATE_PARENT,
0362 },
0363 },
0364 };
0365
0366 static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = {
0367 F(1843200, P_FEPLL200, 1, 144, 15625),
0368 F(3686400, P_FEPLL200, 1, 288, 15625),
0369 F(7372800, P_FEPLL200, 1, 576, 15625),
0370 F(14745600, P_FEPLL200, 1, 1152, 15625),
0371 F(16000000, P_FEPLL200, 1, 2, 25),
0372 F(24000000, P_XO, 1, 1, 2),
0373 F(32000000, P_FEPLL200, 1, 4, 25),
0374 F(40000000, P_FEPLL200, 1, 1, 5),
0375 F(46400000, P_FEPLL200, 1, 29, 125),
0376 F(48000000, P_XO, 1, 0, 0),
0377 { }
0378 };
0379
0380 static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
0381 .cmd_rcgr = 0x2044,
0382 .mnd_width = 16,
0383 .hid_width = 5,
0384 .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk,
0385 .parent_map = gcc_xo_200_spi_map,
0386 .clkr.hw.init = &(struct clk_init_data){
0387 .name = "blsp1_uart1_apps_clk_src",
0388 .parent_names = gcc_xo_200_spi,
0389 .num_parents = 2,
0390 .ops = &clk_rcg2_ops,
0391 },
0392 };
0393
0394 static struct clk_branch gcc_blsp1_uart1_apps_clk = {
0395 .halt_reg = 0x203c,
0396 .clkr = {
0397 .enable_reg = 0x203c,
0398 .enable_mask = BIT(0),
0399 .hw.init = &(struct clk_init_data){
0400 .name = "gcc_blsp1_uart1_apps_clk",
0401 .parent_names = (const char *[]){
0402 "blsp1_uart1_apps_clk_src",
0403 },
0404 .flags = CLK_SET_RATE_PARENT,
0405 .num_parents = 1,
0406 .ops = &clk_branch2_ops,
0407 },
0408 },
0409 };
0410
0411 static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
0412 .cmd_rcgr = 0x3034,
0413 .mnd_width = 16,
0414 .hid_width = 5,
0415 .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk,
0416 .parent_map = gcc_xo_200_spi_map,
0417 .clkr.hw.init = &(struct clk_init_data){
0418 .name = "blsp1_uart2_apps_clk_src",
0419 .parent_names = gcc_xo_200_spi,
0420 .num_parents = 2,
0421 .ops = &clk_rcg2_ops,
0422 },
0423 };
0424
0425 static struct clk_branch gcc_blsp1_uart2_apps_clk = {
0426 .halt_reg = 0x302c,
0427 .clkr = {
0428 .enable_reg = 0x302c,
0429 .enable_mask = BIT(0),
0430 .hw.init = &(struct clk_init_data){
0431 .name = "gcc_blsp1_uart2_apps_clk",
0432 .parent_names = (const char *[]){
0433 "blsp1_uart2_apps_clk_src",
0434 },
0435 .num_parents = 1,
0436 .ops = &clk_branch2_ops,
0437 .flags = CLK_SET_RATE_PARENT,
0438 },
0439 },
0440 };
0441
0442 static const struct freq_tbl ftbl_gcc_gp_clk[] = {
0443 F(1250000, P_FEPLL200, 1, 16, 0),
0444 F(2500000, P_FEPLL200, 1, 8, 0),
0445 F(5000000, P_FEPLL200, 1, 4, 0),
0446 { }
0447 };
0448
0449 static struct clk_rcg2 gp1_clk_src = {
0450 .cmd_rcgr = 0x8004,
0451 .mnd_width = 8,
0452 .hid_width = 5,
0453 .freq_tbl = ftbl_gcc_gp_clk,
0454 .parent_map = gcc_xo_200_map,
0455 .clkr.hw.init = &(struct clk_init_data){
0456 .name = "gp1_clk_src",
0457 .parent_names = gcc_xo_200,
0458 .num_parents = 2,
0459 .ops = &clk_rcg2_ops,
0460 },
0461 };
0462
0463 static struct clk_branch gcc_gp1_clk = {
0464 .halt_reg = 0x8000,
0465 .clkr = {
0466 .enable_reg = 0x8000,
0467 .enable_mask = BIT(0),
0468 .hw.init = &(struct clk_init_data){
0469 .name = "gcc_gp1_clk",
0470 .parent_names = (const char *[]){
0471 "gp1_clk_src",
0472 },
0473 .num_parents = 1,
0474 .ops = &clk_branch2_ops,
0475 .flags = CLK_SET_RATE_PARENT,
0476 },
0477 },
0478 };
0479
0480 static struct clk_rcg2 gp2_clk_src = {
0481 .cmd_rcgr = 0x9004,
0482 .mnd_width = 8,
0483 .hid_width = 5,
0484 .freq_tbl = ftbl_gcc_gp_clk,
0485 .parent_map = gcc_xo_200_map,
0486 .clkr.hw.init = &(struct clk_init_data){
0487 .name = "gp2_clk_src",
0488 .parent_names = gcc_xo_200,
0489 .num_parents = 2,
0490 .ops = &clk_rcg2_ops,
0491 },
0492 };
0493
0494 static struct clk_branch gcc_gp2_clk = {
0495 .halt_reg = 0x9000,
0496 .clkr = {
0497 .enable_reg = 0x9000,
0498 .enable_mask = BIT(0),
0499 .hw.init = &(struct clk_init_data){
0500 .name = "gcc_gp2_clk",
0501 .parent_names = (const char *[]){
0502 "gp2_clk_src",
0503 },
0504 .num_parents = 1,
0505 .ops = &clk_branch2_ops,
0506 .flags = CLK_SET_RATE_PARENT,
0507 },
0508 },
0509 };
0510
0511 static struct clk_rcg2 gp3_clk_src = {
0512 .cmd_rcgr = 0xa004,
0513 .mnd_width = 8,
0514 .hid_width = 5,
0515 .freq_tbl = ftbl_gcc_gp_clk,
0516 .parent_map = gcc_xo_200_map,
0517 .clkr.hw.init = &(struct clk_init_data){
0518 .name = "gp3_clk_src",
0519 .parent_names = gcc_xo_200,
0520 .num_parents = 2,
0521 .ops = &clk_rcg2_ops,
0522 },
0523 };
0524
0525 static struct clk_branch gcc_gp3_clk = {
0526 .halt_reg = 0xa000,
0527 .clkr = {
0528 .enable_reg = 0xa000,
0529 .enable_mask = BIT(0),
0530 .hw.init = &(struct clk_init_data){
0531 .name = "gcc_gp3_clk",
0532 .parent_names = (const char *[]){
0533 "gp3_clk_src",
0534 },
0535 .num_parents = 1,
0536 .ops = &clk_branch2_ops,
0537 .flags = CLK_SET_RATE_PARENT,
0538 },
0539 },
0540 };
0541
0542 static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = {
0543 F(144000, P_XO, 1, 3, 240),
0544 F(400000, P_XO, 1, 1, 0),
0545 F(20000000, P_FEPLL500, 1, 1, 25),
0546 F(25000000, P_FEPLL500, 1, 1, 20),
0547 F(50000000, P_FEPLL500, 1, 1, 10),
0548 F(100000000, P_FEPLL500, 1, 1, 5),
0549 F(192000000, P_DDRPLL, 1, 0, 0),
0550 { }
0551 };
0552
0553 static struct clk_rcg2 sdcc1_apps_clk_src = {
0554 .cmd_rcgr = 0x18004,
0555 .hid_width = 5,
0556 .freq_tbl = ftbl_gcc_sdcc1_apps_clk,
0557 .parent_map = gcc_xo_sdcc1_500_map,
0558 .clkr.hw.init = &(struct clk_init_data){
0559 .name = "sdcc1_apps_clk_src",
0560 .parent_names = gcc_xo_sdcc1_500,
0561 .num_parents = 3,
0562 .ops = &clk_rcg2_ops,
0563 .flags = CLK_SET_RATE_PARENT,
0564 },
0565 };
0566
0567 static const struct freq_tbl ftbl_gcc_apps_clk[] = {
0568 F(48000000, P_XO, 1, 0, 0),
0569 F(200000000, P_FEPLL200, 1, 0, 0),
0570 F(384000000, P_DDRPLLAPSS, 1, 0, 0),
0571 F(413000000, P_DDRPLLAPSS, 1, 0, 0),
0572 F(448000000, P_DDRPLLAPSS, 1, 0, 0),
0573 F(488000000, P_DDRPLLAPSS, 1, 0, 0),
0574 F(500000000, P_FEPLL500, 1, 0, 0),
0575 F(512000000, P_DDRPLLAPSS, 1, 0, 0),
0576 F(537000000, P_DDRPLLAPSS, 1, 0, 0),
0577 F(565000000, P_DDRPLLAPSS, 1, 0, 0),
0578 F(597000000, P_DDRPLLAPSS, 1, 0, 0),
0579 F(632000000, P_DDRPLLAPSS, 1, 0, 0),
0580 F(672000000, P_DDRPLLAPSS, 1, 0, 0),
0581 F(716000000, P_DDRPLLAPSS, 1, 0, 0),
0582 { }
0583 };
0584
0585 static struct clk_rcg2 apps_clk_src = {
0586 .cmd_rcgr = 0x1900c,
0587 .hid_width = 5,
0588 .freq_tbl = ftbl_gcc_apps_clk,
0589 .parent_map = gcc_xo_ddr_500_200_map,
0590 .clkr.hw.init = &(struct clk_init_data){
0591 .name = "apps_clk_src",
0592 .parent_names = gcc_xo_ddr_500_200,
0593 .num_parents = 4,
0594 .ops = &clk_rcg2_ops,
0595 .flags = CLK_SET_RATE_PARENT,
0596 },
0597 };
0598
0599 static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = {
0600 F(48000000, P_XO, 1, 0, 0),
0601 F(100000000, P_FEPLL200, 2, 0, 0),
0602 { }
0603 };
0604
0605 static struct clk_rcg2 apps_ahb_clk_src = {
0606 .cmd_rcgr = 0x19014,
0607 .hid_width = 5,
0608 .parent_map = gcc_xo_200_500_map,
0609 .freq_tbl = ftbl_gcc_apps_ahb_clk,
0610 .clkr.hw.init = &(struct clk_init_data){
0611 .name = "apps_ahb_clk_src",
0612 .parent_names = gcc_xo_200_500,
0613 .num_parents = 3,
0614 .ops = &clk_rcg2_ops,
0615 },
0616 };
0617
0618 static struct clk_branch gcc_apss_ahb_clk = {
0619 .halt_reg = 0x19004,
0620 .halt_check = BRANCH_HALT_VOTED,
0621 .clkr = {
0622 .enable_reg = 0x6000,
0623 .enable_mask = BIT(14),
0624 .hw.init = &(struct clk_init_data){
0625 .name = "gcc_apss_ahb_clk",
0626 .parent_names = (const char *[]){
0627 "apps_ahb_clk_src",
0628 },
0629 .num_parents = 1,
0630 .ops = &clk_branch2_ops,
0631 .flags = CLK_SET_RATE_PARENT,
0632 },
0633 },
0634 };
0635
0636 static struct clk_branch gcc_blsp1_ahb_clk = {
0637 .halt_reg = 0x1008,
0638 .halt_check = BRANCH_HALT_VOTED,
0639 .clkr = {
0640 .enable_reg = 0x6000,
0641 .enable_mask = BIT(10),
0642 .hw.init = &(struct clk_init_data){
0643 .name = "gcc_blsp1_ahb_clk",
0644 .parent_names = (const char *[]){
0645 "pcnoc_clk_src",
0646 },
0647 .num_parents = 1,
0648 .ops = &clk_branch2_ops,
0649 },
0650 },
0651 };
0652
0653 static struct clk_branch gcc_dcd_xo_clk = {
0654 .halt_reg = 0x2103c,
0655 .clkr = {
0656 .enable_reg = 0x2103c,
0657 .enable_mask = BIT(0),
0658 .hw.init = &(struct clk_init_data){
0659 .name = "gcc_dcd_xo_clk",
0660 .parent_names = (const char *[]){
0661 "xo",
0662 },
0663 .num_parents = 1,
0664 .ops = &clk_branch2_ops,
0665 },
0666 },
0667 };
0668
0669 static struct clk_branch gcc_boot_rom_ahb_clk = {
0670 .halt_reg = 0x1300c,
0671 .clkr = {
0672 .enable_reg = 0x1300c,
0673 .enable_mask = BIT(0),
0674 .hw.init = &(struct clk_init_data){
0675 .name = "gcc_boot_rom_ahb_clk",
0676 .parent_names = (const char *[]){
0677 "pcnoc_clk_src",
0678 },
0679 .num_parents = 1,
0680 .ops = &clk_branch2_ops,
0681 .flags = CLK_SET_RATE_PARENT,
0682 },
0683 },
0684 };
0685
0686 static struct clk_branch gcc_crypto_ahb_clk = {
0687 .halt_reg = 0x16024,
0688 .halt_check = BRANCH_HALT_VOTED,
0689 .clkr = {
0690 .enable_reg = 0x6000,
0691 .enable_mask = BIT(0),
0692 .hw.init = &(struct clk_init_data){
0693 .name = "gcc_crypto_ahb_clk",
0694 .parent_names = (const char *[]){
0695 "pcnoc_clk_src",
0696 },
0697 .num_parents = 1,
0698 .ops = &clk_branch2_ops,
0699 },
0700 },
0701 };
0702
0703 static struct clk_branch gcc_crypto_axi_clk = {
0704 .halt_reg = 0x16020,
0705 .halt_check = BRANCH_HALT_VOTED,
0706 .clkr = {
0707 .enable_reg = 0x6000,
0708 .enable_mask = BIT(1),
0709 .hw.init = &(struct clk_init_data){
0710 .name = "gcc_crypto_axi_clk",
0711 .parent_names = (const char *[]){
0712 "fepll125",
0713 },
0714 .num_parents = 1,
0715 .ops = &clk_branch2_ops,
0716 },
0717 },
0718 };
0719
0720 static struct clk_branch gcc_crypto_clk = {
0721 .halt_reg = 0x1601c,
0722 .halt_check = BRANCH_HALT_VOTED,
0723 .clkr = {
0724 .enable_reg = 0x6000,
0725 .enable_mask = BIT(2),
0726 .hw.init = &(struct clk_init_data){
0727 .name = "gcc_crypto_clk",
0728 .parent_names = (const char *[]){
0729 "fepll125",
0730 },
0731 .num_parents = 1,
0732 .ops = &clk_branch2_ops,
0733 },
0734 },
0735 };
0736
0737 static struct clk_branch gcc_ess_clk = {
0738 .halt_reg = 0x12010,
0739 .clkr = {
0740 .enable_reg = 0x12010,
0741 .enable_mask = BIT(0),
0742 .hw.init = &(struct clk_init_data){
0743 .name = "gcc_ess_clk",
0744 .parent_names = (const char *[]){
0745 "fephy_125m_dly_clk_src",
0746 },
0747 .num_parents = 1,
0748 .ops = &clk_branch2_ops,
0749 .flags = CLK_SET_RATE_PARENT,
0750 },
0751 },
0752 };
0753
0754 static struct clk_branch gcc_imem_axi_clk = {
0755 .halt_reg = 0xe004,
0756 .halt_check = BRANCH_HALT_VOTED,
0757 .clkr = {
0758 .enable_reg = 0x6000,
0759 .enable_mask = BIT(17),
0760 .hw.init = &(struct clk_init_data){
0761 .name = "gcc_imem_axi_clk",
0762 .parent_names = (const char *[]){
0763 "fepll200",
0764 },
0765 .num_parents = 1,
0766 .ops = &clk_branch2_ops,
0767 },
0768 },
0769 };
0770
0771 static struct clk_branch gcc_imem_cfg_ahb_clk = {
0772 .halt_reg = 0xe008,
0773 .clkr = {
0774 .enable_reg = 0xe008,
0775 .enable_mask = BIT(0),
0776 .hw.init = &(struct clk_init_data){
0777 .name = "gcc_imem_cfg_ahb_clk",
0778 .parent_names = (const char *[]){
0779 "pcnoc_clk_src",
0780 },
0781 .num_parents = 1,
0782 .ops = &clk_branch2_ops,
0783 },
0784 },
0785 };
0786
0787 static struct clk_branch gcc_pcie_ahb_clk = {
0788 .halt_reg = 0x1d00c,
0789 .clkr = {
0790 .enable_reg = 0x1d00c,
0791 .enable_mask = BIT(0),
0792 .hw.init = &(struct clk_init_data){
0793 .name = "gcc_pcie_ahb_clk",
0794 .parent_names = (const char *[]){
0795 "pcnoc_clk_src",
0796 },
0797 .num_parents = 1,
0798 .ops = &clk_branch2_ops,
0799 },
0800 },
0801 };
0802
0803 static struct clk_branch gcc_pcie_axi_m_clk = {
0804 .halt_reg = 0x1d004,
0805 .clkr = {
0806 .enable_reg = 0x1d004,
0807 .enable_mask = BIT(0),
0808 .hw.init = &(struct clk_init_data){
0809 .name = "gcc_pcie_axi_m_clk",
0810 .parent_names = (const char *[]){
0811 "fepll200",
0812 },
0813 .num_parents = 1,
0814 .ops = &clk_branch2_ops,
0815 },
0816 },
0817 };
0818
0819 static struct clk_branch gcc_pcie_axi_s_clk = {
0820 .halt_reg = 0x1d008,
0821 .clkr = {
0822 .enable_reg = 0x1d008,
0823 .enable_mask = BIT(0),
0824 .hw.init = &(struct clk_init_data){
0825 .name = "gcc_pcie_axi_s_clk",
0826 .parent_names = (const char *[]){
0827 "fepll200",
0828 },
0829 .num_parents = 1,
0830 .ops = &clk_branch2_ops,
0831 },
0832 },
0833 };
0834
0835 static struct clk_branch gcc_prng_ahb_clk = {
0836 .halt_reg = 0x13004,
0837 .halt_check = BRANCH_HALT_VOTED,
0838 .clkr = {
0839 .enable_reg = 0x6000,
0840 .enable_mask = BIT(8),
0841 .hw.init = &(struct clk_init_data){
0842 .name = "gcc_prng_ahb_clk",
0843 .parent_names = (const char *[]){
0844 "pcnoc_clk_src",
0845 },
0846 .num_parents = 1,
0847 .ops = &clk_branch2_ops,
0848 },
0849 },
0850 };
0851
0852 static struct clk_branch gcc_qpic_ahb_clk = {
0853 .halt_reg = 0x1c008,
0854 .clkr = {
0855 .enable_reg = 0x1c008,
0856 .enable_mask = BIT(0),
0857 .hw.init = &(struct clk_init_data){
0858 .name = "gcc_qpic_ahb_clk",
0859 .parent_names = (const char *[]){
0860 "pcnoc_clk_src",
0861 },
0862 .num_parents = 1,
0863 .ops = &clk_branch2_ops,
0864 },
0865 },
0866 };
0867
0868 static struct clk_branch gcc_qpic_clk = {
0869 .halt_reg = 0x1c004,
0870 .clkr = {
0871 .enable_reg = 0x1c004,
0872 .enable_mask = BIT(0),
0873 .hw.init = &(struct clk_init_data){
0874 .name = "gcc_qpic_clk",
0875 .parent_names = (const char *[]){
0876 "pcnoc_clk_src",
0877 },
0878 .num_parents = 1,
0879 .ops = &clk_branch2_ops,
0880 },
0881 },
0882 };
0883
0884 static struct clk_branch gcc_sdcc1_ahb_clk = {
0885 .halt_reg = 0x18010,
0886 .clkr = {
0887 .enable_reg = 0x18010,
0888 .enable_mask = BIT(0),
0889 .hw.init = &(struct clk_init_data){
0890 .name = "gcc_sdcc1_ahb_clk",
0891 .parent_names = (const char *[]){
0892 "pcnoc_clk_src",
0893 },
0894 .num_parents = 1,
0895 .ops = &clk_branch2_ops,
0896 },
0897 },
0898 };
0899
0900 static struct clk_branch gcc_sdcc1_apps_clk = {
0901 .halt_reg = 0x1800c,
0902 .clkr = {
0903 .enable_reg = 0x1800c,
0904 .enable_mask = BIT(0),
0905 .hw.init = &(struct clk_init_data){
0906 .name = "gcc_sdcc1_apps_clk",
0907 .parent_names = (const char *[]){
0908 "sdcc1_apps_clk_src",
0909 },
0910 .num_parents = 1,
0911 .ops = &clk_branch2_ops,
0912 .flags = CLK_SET_RATE_PARENT,
0913 },
0914 },
0915 };
0916
0917 static struct clk_branch gcc_tlmm_ahb_clk = {
0918 .halt_reg = 0x5004,
0919 .halt_check = BRANCH_HALT_VOTED,
0920 .clkr = {
0921 .enable_reg = 0x6000,
0922 .enable_mask = BIT(5),
0923 .hw.init = &(struct clk_init_data){
0924 .name = "gcc_tlmm_ahb_clk",
0925 .parent_names = (const char *[]){
0926 "pcnoc_clk_src",
0927 },
0928 .num_parents = 1,
0929 .ops = &clk_branch2_ops,
0930 },
0931 },
0932 };
0933
0934 static struct clk_branch gcc_usb2_master_clk = {
0935 .halt_reg = 0x1e00c,
0936 .clkr = {
0937 .enable_reg = 0x1e00c,
0938 .enable_mask = BIT(0),
0939 .hw.init = &(struct clk_init_data){
0940 .name = "gcc_usb2_master_clk",
0941 .parent_names = (const char *[]){
0942 "pcnoc_clk_src",
0943 },
0944 .num_parents = 1,
0945 .ops = &clk_branch2_ops,
0946 },
0947 },
0948 };
0949
0950 static struct clk_branch gcc_usb2_sleep_clk = {
0951 .halt_reg = 0x1e010,
0952 .clkr = {
0953 .enable_reg = 0x1e010,
0954 .enable_mask = BIT(0),
0955 .hw.init = &(struct clk_init_data){
0956 .name = "gcc_usb2_sleep_clk",
0957 .parent_names = (const char *[]){
0958 "gcc_sleep_clk_src",
0959 },
0960 .num_parents = 1,
0961 .ops = &clk_branch2_ops,
0962 },
0963 },
0964 };
0965
0966 static struct clk_branch gcc_usb2_mock_utmi_clk = {
0967 .halt_reg = 0x1e014,
0968 .clkr = {
0969 .enable_reg = 0x1e014,
0970 .enable_mask = BIT(0),
0971 .hw.init = &(struct clk_init_data){
0972 .name = "gcc_usb2_mock_utmi_clk",
0973 .parent_names = (const char *[]){
0974 "usb30_mock_utmi_clk_src",
0975 },
0976 .num_parents = 1,
0977 .ops = &clk_branch2_ops,
0978 .flags = CLK_SET_RATE_PARENT,
0979 },
0980 },
0981 };
0982
0983 static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = {
0984 F(2000000, P_FEPLL200, 10, 0, 0),
0985 { }
0986 };
0987
0988 static struct clk_rcg2 usb30_mock_utmi_clk_src = {
0989 .cmd_rcgr = 0x1e000,
0990 .hid_width = 5,
0991 .parent_map = gcc_xo_200_map,
0992 .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk,
0993 .clkr.hw.init = &(struct clk_init_data){
0994 .name = "usb30_mock_utmi_clk_src",
0995 .parent_names = gcc_xo_200,
0996 .num_parents = 2,
0997 .ops = &clk_rcg2_ops,
0998 },
0999 };
1000
1001 static struct clk_branch gcc_usb3_master_clk = {
1002 .halt_reg = 0x1e028,
1003 .clkr = {
1004 .enable_reg = 0x1e028,
1005 .enable_mask = BIT(0),
1006 .hw.init = &(struct clk_init_data){
1007 .name = "gcc_usb3_master_clk",
1008 .parent_names = (const char *[]){
1009 "fepll125",
1010 },
1011 .num_parents = 1,
1012 .ops = &clk_branch2_ops,
1013 },
1014 },
1015 };
1016
1017 static struct clk_branch gcc_usb3_sleep_clk = {
1018 .halt_reg = 0x1e02C,
1019 .clkr = {
1020 .enable_reg = 0x1e02C,
1021 .enable_mask = BIT(0),
1022 .hw.init = &(struct clk_init_data){
1023 .name = "gcc_usb3_sleep_clk",
1024 .parent_names = (const char *[]){
1025 "gcc_sleep_clk_src",
1026 },
1027 .num_parents = 1,
1028 .ops = &clk_branch2_ops,
1029 },
1030 },
1031 };
1032
1033 static struct clk_branch gcc_usb3_mock_utmi_clk = {
1034 .halt_reg = 0x1e030,
1035 .clkr = {
1036 .enable_reg = 0x1e030,
1037 .enable_mask = BIT(0),
1038 .hw.init = &(struct clk_init_data){
1039 .name = "gcc_usb3_mock_utmi_clk",
1040 .parent_names = (const char *[]){
1041 "usb30_mock_utmi_clk_src",
1042 },
1043 .num_parents = 1,
1044 .ops = &clk_branch2_ops,
1045 .flags = CLK_SET_RATE_PARENT,
1046 },
1047 },
1048 };
1049
1050 static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = {
1051 F(125000000, P_FEPLL125DLY, 1, 0, 0),
1052 { }
1053 };
1054
1055 static struct clk_rcg2 fephy_125m_dly_clk_src = {
1056 .cmd_rcgr = 0x12000,
1057 .hid_width = 5,
1058 .parent_map = gcc_xo_125_dly_map,
1059 .freq_tbl = ftbl_gcc_fephy_dly_clk,
1060 .clkr.hw.init = &(struct clk_init_data){
1061 .name = "fephy_125m_dly_clk_src",
1062 .parent_names = gcc_xo_125_dly,
1063 .num_parents = 2,
1064 .ops = &clk_rcg2_ops,
1065 },
1066 };
1067
1068
1069 static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = {
1070 F(48000000, P_XO, 1, 0, 0),
1071 F(250000000, P_FEPLLWCSS2G, 1, 0, 0),
1072 { }
1073 };
1074
1075 static struct clk_rcg2 wcss2g_clk_src = {
1076 .cmd_rcgr = 0x1f000,
1077 .hid_width = 5,
1078 .freq_tbl = ftbl_gcc_wcss2g_clk,
1079 .parent_map = gcc_xo_wcss2g_map,
1080 .clkr.hw.init = &(struct clk_init_data){
1081 .name = "wcss2g_clk_src",
1082 .parent_names = gcc_xo_wcss2g,
1083 .num_parents = 2,
1084 .ops = &clk_rcg2_ops,
1085 .flags = CLK_SET_RATE_PARENT,
1086 },
1087 };
1088
1089 static struct clk_branch gcc_wcss2g_clk = {
1090 .halt_reg = 0x1f00C,
1091 .clkr = {
1092 .enable_reg = 0x1f00C,
1093 .enable_mask = BIT(0),
1094 .hw.init = &(struct clk_init_data){
1095 .name = "gcc_wcss2g_clk",
1096 .parent_names = (const char *[]){
1097 "wcss2g_clk_src",
1098 },
1099 .num_parents = 1,
1100 .ops = &clk_branch2_ops,
1101 .flags = CLK_SET_RATE_PARENT,
1102 },
1103 },
1104 };
1105
1106 static struct clk_branch gcc_wcss2g_ref_clk = {
1107 .halt_reg = 0x1f00C,
1108 .clkr = {
1109 .enable_reg = 0x1f00C,
1110 .enable_mask = BIT(0),
1111 .hw.init = &(struct clk_init_data){
1112 .name = "gcc_wcss2g_ref_clk",
1113 .parent_names = (const char *[]){
1114 "xo",
1115 },
1116 .num_parents = 1,
1117 .ops = &clk_branch2_ops,
1118 .flags = CLK_SET_RATE_PARENT,
1119 },
1120 },
1121 };
1122
1123 static struct clk_branch gcc_wcss2g_rtc_clk = {
1124 .halt_reg = 0x1f010,
1125 .clkr = {
1126 .enable_reg = 0x1f010,
1127 .enable_mask = BIT(0),
1128 .hw.init = &(struct clk_init_data){
1129 .name = "gcc_wcss2g_rtc_clk",
1130 .parent_names = (const char *[]){
1131 "gcc_sleep_clk_src",
1132 },
1133 .num_parents = 1,
1134 .ops = &clk_branch2_ops,
1135 },
1136 },
1137 };
1138
1139 static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = {
1140 F(48000000, P_XO, 1, 0, 0),
1141 F(250000000, P_FEPLLWCSS5G, 1, 0, 0),
1142 { }
1143 };
1144
1145 static struct clk_rcg2 wcss5g_clk_src = {
1146 .cmd_rcgr = 0x20000,
1147 .hid_width = 5,
1148 .parent_map = gcc_xo_wcss5g_map,
1149 .freq_tbl = ftbl_gcc_wcss5g_clk,
1150 .clkr.hw.init = &(struct clk_init_data){
1151 .name = "wcss5g_clk_src",
1152 .parent_names = gcc_xo_wcss5g,
1153 .num_parents = 2,
1154 .ops = &clk_rcg2_ops,
1155 },
1156 };
1157
1158 static struct clk_branch gcc_wcss5g_clk = {
1159 .halt_reg = 0x2000c,
1160 .clkr = {
1161 .enable_reg = 0x2000c,
1162 .enable_mask = BIT(0),
1163 .hw.init = &(struct clk_init_data){
1164 .name = "gcc_wcss5g_clk",
1165 .parent_names = (const char *[]){
1166 "wcss5g_clk_src",
1167 },
1168 .num_parents = 1,
1169 .ops = &clk_branch2_ops,
1170 .flags = CLK_SET_RATE_PARENT,
1171 },
1172 },
1173 };
1174
1175 static struct clk_branch gcc_wcss5g_ref_clk = {
1176 .halt_reg = 0x2000c,
1177 .clkr = {
1178 .enable_reg = 0x2000c,
1179 .enable_mask = BIT(0),
1180 .hw.init = &(struct clk_init_data){
1181 .name = "gcc_wcss5g_ref_clk",
1182 .parent_names = (const char *[]){
1183 "xo",
1184 },
1185 .num_parents = 1,
1186 .ops = &clk_branch2_ops,
1187 .flags = CLK_SET_RATE_PARENT,
1188 },
1189 },
1190 };
1191
1192 static struct clk_branch gcc_wcss5g_rtc_clk = {
1193 .halt_reg = 0x20010,
1194 .clkr = {
1195 .enable_reg = 0x20010,
1196 .enable_mask = BIT(0),
1197 .hw.init = &(struct clk_init_data){
1198 .name = "gcc_wcss5g_rtc_clk",
1199 .parent_names = (const char *[]){
1200 "gcc_sleep_clk_src",
1201 },
1202 .num_parents = 1,
1203 .ops = &clk_branch2_ops,
1204 .flags = CLK_SET_RATE_PARENT,
1205 },
1206 },
1207 };
1208
1209
1210 static u64 clk_fepll_vco_calc_rate(struct clk_fepll *pll_div,
1211 unsigned long parent_rate)
1212 {
1213 const struct clk_fepll_vco *pll_vco = pll_div->pll_vco;
1214 u32 fdbkdiv, refclkdiv, cdiv;
1215 u64 vco;
1216
1217 regmap_read(pll_div->cdiv.clkr.regmap, pll_vco->reg, &cdiv);
1218 refclkdiv = (cdiv >> pll_vco->refclkdiv_shift) &
1219 (BIT(pll_vco->refclkdiv_width) - 1);
1220 fdbkdiv = (cdiv >> pll_vco->fdbkdiv_shift) &
1221 (BIT(pll_vco->fdbkdiv_width) - 1);
1222
1223 vco = parent_rate / refclkdiv;
1224 vco *= 2;
1225 vco *= fdbkdiv;
1226
1227 return vco;
1228 }
1229
1230 static const struct clk_fepll_vco gcc_apss_ddrpll_vco = {
1231 .fdbkdiv_shift = 16,
1232 .fdbkdiv_width = 8,
1233 .refclkdiv_shift = 24,
1234 .refclkdiv_width = 5,
1235 .reg = 0x2e020,
1236 };
1237
1238 static const struct clk_fepll_vco gcc_fepll_vco = {
1239 .fdbkdiv_shift = 16,
1240 .fdbkdiv_width = 8,
1241 .refclkdiv_shift = 24,
1242 .refclkdiv_width = 5,
1243 .reg = 0x2f020,
1244 };
1245
1246
1247
1248
1249
1250
1251 static long clk_cpu_div_round_rate(struct clk_hw *hw, unsigned long rate,
1252 unsigned long *p_rate)
1253 {
1254 struct clk_fepll *pll = to_clk_fepll(hw);
1255 struct clk_hw *p_hw;
1256 const struct freq_tbl *f;
1257
1258 f = qcom_find_freq(pll->freq_tbl, rate);
1259 if (!f)
1260 return -EINVAL;
1261
1262 p_hw = clk_hw_get_parent_by_index(hw, f->src);
1263 *p_rate = clk_hw_get_rate(p_hw);
1264
1265 return f->freq;
1266 };
1267
1268
1269
1270
1271
1272
1273 static int clk_cpu_div_set_rate(struct clk_hw *hw, unsigned long rate,
1274 unsigned long parent_rate)
1275 {
1276 struct clk_fepll *pll = to_clk_fepll(hw);
1277 const struct freq_tbl *f;
1278 u32 mask;
1279
1280 f = qcom_find_freq(pll->freq_tbl, rate);
1281 if (!f)
1282 return -EINVAL;
1283
1284 mask = (BIT(pll->cdiv.width) - 1) << pll->cdiv.shift;
1285 regmap_update_bits(pll->cdiv.clkr.regmap,
1286 pll->cdiv.reg, mask,
1287 f->pre_div << pll->cdiv.shift);
1288
1289
1290
1291
1292 udelay(1);
1293
1294 return 0;
1295 };
1296
1297
1298
1299
1300
1301
1302
1303 static unsigned long
1304 clk_cpu_div_recalc_rate(struct clk_hw *hw,
1305 unsigned long parent_rate)
1306 {
1307 struct clk_fepll *pll = to_clk_fepll(hw);
1308 u32 cdiv, pre_div;
1309 u64 rate;
1310
1311 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
1312 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
1313
1314
1315
1316
1317
1318
1319 if (cdiv > 10)
1320 pre_div = (cdiv + 1) * 2;
1321 else
1322 pre_div = cdiv + 12;
1323
1324 rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2;
1325 do_div(rate, pre_div);
1326
1327 return rate;
1328 };
1329
1330 static const struct clk_ops clk_regmap_cpu_div_ops = {
1331 .round_rate = clk_cpu_div_round_rate,
1332 .set_rate = clk_cpu_div_set_rate,
1333 .recalc_rate = clk_cpu_div_recalc_rate,
1334 };
1335
1336 static const struct freq_tbl ftbl_apss_ddr_pll[] = {
1337 { 384000000, P_XO, 0xd, 0, 0 },
1338 { 413000000, P_XO, 0xc, 0, 0 },
1339 { 448000000, P_XO, 0xb, 0, 0 },
1340 { 488000000, P_XO, 0xa, 0, 0 },
1341 { 512000000, P_XO, 0x9, 0, 0 },
1342 { 537000000, P_XO, 0x8, 0, 0 },
1343 { 565000000, P_XO, 0x7, 0, 0 },
1344 { 597000000, P_XO, 0x6, 0, 0 },
1345 { 632000000, P_XO, 0x5, 0, 0 },
1346 { 672000000, P_XO, 0x4, 0, 0 },
1347 { 716000000, P_XO, 0x3, 0, 0 },
1348 { 768000000, P_XO, 0x2, 0, 0 },
1349 { 823000000, P_XO, 0x1, 0, 0 },
1350 { 896000000, P_XO, 0x0, 0, 0 },
1351 { }
1352 };
1353
1354 static struct clk_fepll gcc_apss_cpu_plldiv_clk = {
1355 .cdiv.reg = 0x2e020,
1356 .cdiv.shift = 4,
1357 .cdiv.width = 4,
1358 .cdiv.clkr = {
1359 .enable_reg = 0x2e000,
1360 .enable_mask = BIT(0),
1361 .hw.init = &(struct clk_init_data){
1362 .name = "ddrpllapss",
1363 .parent_names = (const char *[]){
1364 "xo",
1365 },
1366 .num_parents = 1,
1367 .ops = &clk_regmap_cpu_div_ops,
1368 },
1369 },
1370 .freq_tbl = ftbl_apss_ddr_pll,
1371 .pll_vco = &gcc_apss_ddrpll_vco,
1372 };
1373
1374
1375
1376
1377
1378
1379 static unsigned long
1380 clk_regmap_clk_div_recalc_rate(struct clk_hw *hw,
1381 unsigned long parent_rate)
1382 {
1383 struct clk_fepll *pll = to_clk_fepll(hw);
1384 u32 cdiv, pre_div = 1;
1385 u64 rate;
1386 const struct clk_div_table *clkt;
1387
1388 if (pll->fixed_div) {
1389 pre_div = pll->fixed_div;
1390 } else {
1391 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv);
1392 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1);
1393
1394 for (clkt = pll->div_table; clkt->div; clkt++) {
1395 if (clkt->val == cdiv)
1396 pre_div = clkt->div;
1397 }
1398 }
1399
1400 rate = clk_fepll_vco_calc_rate(pll, parent_rate);
1401 do_div(rate, pre_div);
1402
1403 return rate;
1404 };
1405
1406 static const struct clk_ops clk_fepll_div_ops = {
1407 .recalc_rate = clk_regmap_clk_div_recalc_rate,
1408 };
1409
1410 static struct clk_fepll gcc_apss_sdcc_clk = {
1411 .fixed_div = 28,
1412 .cdiv.clkr = {
1413 .hw.init = &(struct clk_init_data){
1414 .name = "ddrpllsdcc",
1415 .parent_names = (const char *[]){
1416 "xo",
1417 },
1418 .num_parents = 1,
1419 .ops = &clk_fepll_div_ops,
1420 },
1421 },
1422 .pll_vco = &gcc_apss_ddrpll_vco,
1423 };
1424
1425 static struct clk_fepll gcc_fepll125_clk = {
1426 .fixed_div = 32,
1427 .cdiv.clkr = {
1428 .hw.init = &(struct clk_init_data){
1429 .name = "fepll125",
1430 .parent_names = (const char *[]){
1431 "xo",
1432 },
1433 .num_parents = 1,
1434 .ops = &clk_fepll_div_ops,
1435 },
1436 },
1437 .pll_vco = &gcc_fepll_vco,
1438 };
1439
1440 static struct clk_fepll gcc_fepll125dly_clk = {
1441 .fixed_div = 32,
1442 .cdiv.clkr = {
1443 .hw.init = &(struct clk_init_data){
1444 .name = "fepll125dly",
1445 .parent_names = (const char *[]){
1446 "xo",
1447 },
1448 .num_parents = 1,
1449 .ops = &clk_fepll_div_ops,
1450 },
1451 },
1452 .pll_vco = &gcc_fepll_vco,
1453 };
1454
1455 static struct clk_fepll gcc_fepll200_clk = {
1456 .fixed_div = 20,
1457 .cdiv.clkr = {
1458 .hw.init = &(struct clk_init_data){
1459 .name = "fepll200",
1460 .parent_names = (const char *[]){
1461 "xo",
1462 },
1463 .num_parents = 1,
1464 .ops = &clk_fepll_div_ops,
1465 },
1466 },
1467 .pll_vco = &gcc_fepll_vco,
1468 };
1469
1470 static struct clk_fepll gcc_fepll500_clk = {
1471 .fixed_div = 8,
1472 .cdiv.clkr = {
1473 .hw.init = &(struct clk_init_data){
1474 .name = "fepll500",
1475 .parent_names = (const char *[]){
1476 "xo",
1477 },
1478 .num_parents = 1,
1479 .ops = &clk_fepll_div_ops,
1480 },
1481 },
1482 .pll_vco = &gcc_fepll_vco,
1483 };
1484
1485 static const struct clk_div_table fepllwcss_clk_div_table[] = {
1486 { 0, 15 },
1487 { 1, 16 },
1488 { 2, 18 },
1489 { 3, 20 },
1490 { },
1491 };
1492
1493 static struct clk_fepll gcc_fepllwcss2g_clk = {
1494 .cdiv.reg = 0x2f020,
1495 .cdiv.shift = 8,
1496 .cdiv.width = 2,
1497 .cdiv.clkr = {
1498 .hw.init = &(struct clk_init_data){
1499 .name = "fepllwcss2g",
1500 .parent_names = (const char *[]){
1501 "xo",
1502 },
1503 .num_parents = 1,
1504 .ops = &clk_fepll_div_ops,
1505 },
1506 },
1507 .div_table = fepllwcss_clk_div_table,
1508 .pll_vco = &gcc_fepll_vco,
1509 };
1510
1511 static struct clk_fepll gcc_fepllwcss5g_clk = {
1512 .cdiv.reg = 0x2f020,
1513 .cdiv.shift = 12,
1514 .cdiv.width = 2,
1515 .cdiv.clkr = {
1516 .hw.init = &(struct clk_init_data){
1517 .name = "fepllwcss5g",
1518 .parent_names = (const char *[]){
1519 "xo",
1520 },
1521 .num_parents = 1,
1522 .ops = &clk_fepll_div_ops,
1523 },
1524 },
1525 .div_table = fepllwcss_clk_div_table,
1526 .pll_vco = &gcc_fepll_vco,
1527 };
1528
1529 static const struct freq_tbl ftbl_gcc_pcnoc_ahb_clk[] = {
1530 F(48000000, P_XO, 1, 0, 0),
1531 F(100000000, P_FEPLL200, 2, 0, 0),
1532 { }
1533 };
1534
1535 static struct clk_rcg2 gcc_pcnoc_ahb_clk_src = {
1536 .cmd_rcgr = 0x21024,
1537 .hid_width = 5,
1538 .parent_map = gcc_xo_200_500_map,
1539 .freq_tbl = ftbl_gcc_pcnoc_ahb_clk,
1540 .clkr.hw.init = &(struct clk_init_data){
1541 .name = "gcc_pcnoc_ahb_clk_src",
1542 .parent_names = gcc_xo_200_500,
1543 .num_parents = 3,
1544 .ops = &clk_rcg2_ops,
1545 },
1546 };
1547
1548 static struct clk_branch pcnoc_clk_src = {
1549 .halt_reg = 0x21030,
1550 .clkr = {
1551 .enable_reg = 0x21030,
1552 .enable_mask = BIT(0),
1553 .hw.init = &(struct clk_init_data){
1554 .name = "pcnoc_clk_src",
1555 .parent_names = (const char *[]){
1556 "gcc_pcnoc_ahb_clk_src",
1557 },
1558 .num_parents = 1,
1559 .ops = &clk_branch2_ops,
1560 .flags = CLK_SET_RATE_PARENT |
1561 CLK_IS_CRITICAL,
1562 },
1563 },
1564 };
1565
1566 static struct clk_regmap *gcc_ipq4019_clocks[] = {
1567 [AUDIO_CLK_SRC] = &audio_clk_src.clkr,
1568 [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
1569 [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
1570 [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
1571 [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
1572 [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
1573 [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
1574 [GCC_USB3_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
1575 [GCC_APPS_CLK_SRC] = &apps_clk_src.clkr,
1576 [GCC_APPS_AHB_CLK_SRC] = &apps_ahb_clk_src.clkr,
1577 [GP1_CLK_SRC] = &gp1_clk_src.clkr,
1578 [GP2_CLK_SRC] = &gp2_clk_src.clkr,
1579 [GP3_CLK_SRC] = &gp3_clk_src.clkr,
1580 [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
1581 [FEPHY_125M_DLY_CLK_SRC] = &fephy_125m_dly_clk_src.clkr,
1582 [WCSS2G_CLK_SRC] = &wcss2g_clk_src.clkr,
1583 [WCSS5G_CLK_SRC] = &wcss5g_clk_src.clkr,
1584 [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
1585 [GCC_AUDIO_AHB_CLK] = &gcc_audio_ahb_clk.clkr,
1586 [GCC_AUDIO_PWM_CLK] = &gcc_audio_pwm_clk.clkr,
1587 [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
1588 [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
1589 [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
1590 [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
1591 [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
1592 [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
1593 [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
1594 [GCC_DCD_XO_CLK] = &gcc_dcd_xo_clk.clkr,
1595 [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
1596 [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
1597 [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
1598 [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
1599 [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
1600 [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
1601 [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
1602 [GCC_ESS_CLK] = &gcc_ess_clk.clkr,
1603 [GCC_IMEM_AXI_CLK] = &gcc_imem_axi_clk.clkr,
1604 [GCC_IMEM_CFG_AHB_CLK] = &gcc_imem_cfg_ahb_clk.clkr,
1605 [GCC_PCIE_AHB_CLK] = &gcc_pcie_ahb_clk.clkr,
1606 [GCC_PCIE_AXI_M_CLK] = &gcc_pcie_axi_m_clk.clkr,
1607 [GCC_PCIE_AXI_S_CLK] = &gcc_pcie_axi_s_clk.clkr,
1608 [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
1609 [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr,
1610 [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr,
1611 [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
1612 [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
1613 [GCC_TLMM_AHB_CLK] = &gcc_tlmm_ahb_clk.clkr,
1614 [GCC_USB2_MASTER_CLK] = &gcc_usb2_master_clk.clkr,
1615 [GCC_USB2_SLEEP_CLK] = &gcc_usb2_sleep_clk.clkr,
1616 [GCC_USB2_MOCK_UTMI_CLK] = &gcc_usb2_mock_utmi_clk.clkr,
1617 [GCC_USB3_MASTER_CLK] = &gcc_usb3_master_clk.clkr,
1618 [GCC_USB3_SLEEP_CLK] = &gcc_usb3_sleep_clk.clkr,
1619 [GCC_USB3_MOCK_UTMI_CLK] = &gcc_usb3_mock_utmi_clk.clkr,
1620 [GCC_WCSS2G_CLK] = &gcc_wcss2g_clk.clkr,
1621 [GCC_WCSS2G_REF_CLK] = &gcc_wcss2g_ref_clk.clkr,
1622 [GCC_WCSS2G_RTC_CLK] = &gcc_wcss2g_rtc_clk.clkr,
1623 [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr,
1624 [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr,
1625 [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr,
1626 [GCC_SDCC_PLLDIV_CLK] = &gcc_apss_sdcc_clk.cdiv.clkr,
1627 [GCC_FEPLL125_CLK] = &gcc_fepll125_clk.cdiv.clkr,
1628 [GCC_FEPLL125DLY_CLK] = &gcc_fepll125dly_clk.cdiv.clkr,
1629 [GCC_FEPLL200_CLK] = &gcc_fepll200_clk.cdiv.clkr,
1630 [GCC_FEPLL500_CLK] = &gcc_fepll500_clk.cdiv.clkr,
1631 [GCC_FEPLL_WCSS2G_CLK] = &gcc_fepllwcss2g_clk.cdiv.clkr,
1632 [GCC_FEPLL_WCSS5G_CLK] = &gcc_fepllwcss5g_clk.cdiv.clkr,
1633 [GCC_APSS_CPU_PLLDIV_CLK] = &gcc_apss_cpu_plldiv_clk.cdiv.clkr,
1634 [GCC_PCNOC_AHB_CLK_SRC] = &gcc_pcnoc_ahb_clk_src.clkr,
1635 [GCC_PCNOC_AHB_CLK] = &pcnoc_clk_src.clkr,
1636 };
1637
1638 static const struct qcom_reset_map gcc_ipq4019_resets[] = {
1639 [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
1640 [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
1641 [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
1642 [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
1643 [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
1644 [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
1645 [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
1646 [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
1647 [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
1648 [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
1649 [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
1650 [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
1651 [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
1652 [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
1653 [USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
1654 [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
1655 [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
1656 [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
1657 [PCIE_AHB_ARES] = { 0x1d010, 10 },
1658 [PCIE_PWR_ARES] = { 0x1d010, 9 },
1659 [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
1660 [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
1661 [PCIE_PHY_ARES] = { 0x1d010, 6 },
1662 [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
1663 [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
1664 [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
1665 [PCIE_PIPE_ARES] = { 0x1d010, 2 },
1666 [PCIE_AXI_S_ARES] = { 0x1d010, 1 },
1667 [PCIE_AXI_M_ARES] = { 0x1d010, 0 },
1668 [ESS_RESET] = { 0x12008, 0},
1669 [GCC_BLSP1_BCR] = {0x01000, 0},
1670 [GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
1671 [GCC_BLSP1_UART1_BCR] = {0x02038, 0},
1672 [GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
1673 [GCC_BLSP1_UART2_BCR] = {0x03028, 0},
1674 [GCC_BIMC_BCR] = {0x04000, 0},
1675 [GCC_TLMM_BCR] = {0x05000, 0},
1676 [GCC_IMEM_BCR] = {0x0E000, 0},
1677 [GCC_ESS_BCR] = {0x12008, 0},
1678 [GCC_PRNG_BCR] = {0x13000, 0},
1679 [GCC_BOOT_ROM_BCR] = {0x13008, 0},
1680 [GCC_CRYPTO_BCR] = {0x16000, 0},
1681 [GCC_SDCC1_BCR] = {0x18000, 0},
1682 [GCC_SEC_CTRL_BCR] = {0x1A000, 0},
1683 [GCC_AUDIO_BCR] = {0x1B008, 0},
1684 [GCC_QPIC_BCR] = {0x1C000, 0},
1685 [GCC_PCIE_BCR] = {0x1D000, 0},
1686 [GCC_USB2_BCR] = {0x1E008, 0},
1687 [GCC_USB2_PHY_BCR] = {0x1E018, 0},
1688 [GCC_USB3_BCR] = {0x1E024, 0},
1689 [GCC_USB3_PHY_BCR] = {0x1E034, 0},
1690 [GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
1691 [GCC_PCNOC_BCR] = {0x2102C, 0},
1692 [GCC_DCD_BCR] = {0x21038, 0},
1693 [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
1694 [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
1695 [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
1696 [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
1697 [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
1698 [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
1699 [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
1700 [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
1701 [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
1702 [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
1703 [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
1704 [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
1705 [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
1706 [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
1707 [GCC_TCSR_BCR] = {0x22000, 0},
1708 [GCC_MPM_BCR] = {0x24000, 0},
1709 [GCC_SPDM_BCR] = {0x25000, 0},
1710 };
1711
1712 static const struct regmap_config gcc_ipq4019_regmap_config = {
1713 .reg_bits = 32,
1714 .reg_stride = 4,
1715 .val_bits = 32,
1716 .max_register = 0x2ffff,
1717 .fast_io = true,
1718 };
1719
1720 static const struct qcom_cc_desc gcc_ipq4019_desc = {
1721 .config = &gcc_ipq4019_regmap_config,
1722 .clks = gcc_ipq4019_clocks,
1723 .num_clks = ARRAY_SIZE(gcc_ipq4019_clocks),
1724 .resets = gcc_ipq4019_resets,
1725 .num_resets = ARRAY_SIZE(gcc_ipq4019_resets),
1726 };
1727
1728 static const struct of_device_id gcc_ipq4019_match_table[] = {
1729 { .compatible = "qcom,gcc-ipq4019" },
1730 { }
1731 };
1732 MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table);
1733
1734 static int
1735 gcc_ipq4019_cpu_clk_notifier_fn(struct notifier_block *nb,
1736 unsigned long action, void *data)
1737 {
1738 int err = 0;
1739
1740 if (action == PRE_RATE_CHANGE)
1741 err = clk_rcg2_ops.set_parent(&apps_clk_src.clkr.hw,
1742 gcc_ipq4019_cpu_safe_parent);
1743
1744 return notifier_from_errno(err);
1745 }
1746
1747 static struct notifier_block gcc_ipq4019_cpu_clk_notifier = {
1748 .notifier_call = gcc_ipq4019_cpu_clk_notifier_fn,
1749 };
1750
1751 static int gcc_ipq4019_probe(struct platform_device *pdev)
1752 {
1753 int err;
1754
1755 err = qcom_cc_probe(pdev, &gcc_ipq4019_desc);
1756 if (err)
1757 return err;
1758
1759 return clk_notifier_register(apps_clk_src.clkr.hw.clk,
1760 &gcc_ipq4019_cpu_clk_notifier);
1761 }
1762
1763 static int gcc_ipq4019_remove(struct platform_device *pdev)
1764 {
1765 return clk_notifier_unregister(apps_clk_src.clkr.hw.clk,
1766 &gcc_ipq4019_cpu_clk_notifier);
1767 }
1768
1769 static struct platform_driver gcc_ipq4019_driver = {
1770 .probe = gcc_ipq4019_probe,
1771 .remove = gcc_ipq4019_remove,
1772 .driver = {
1773 .name = "qcom,gcc-ipq4019",
1774 .of_match_table = gcc_ipq4019_match_table,
1775 },
1776 };
1777
1778 static int __init gcc_ipq4019_init(void)
1779 {
1780 return platform_driver_register(&gcc_ipq4019_driver);
1781 }
1782 core_initcall(gcc_ipq4019_init);
1783
1784 static void __exit gcc_ipq4019_exit(void)
1785 {
1786 platform_driver_unregister(&gcc_ipq4019_driver);
1787 }
1788 module_exit(gcc_ipq4019_exit);
1789
1790 MODULE_ALIAS("platform:gcc-ipq4019");
1791 MODULE_LICENSE("GPL v2");
1792 MODULE_DESCRIPTION("QCOM GCC IPQ4019 driver");