1 /* 2 * Copyright (c) 2014, 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/bitops.h> 16 #include <linux/err.h> 17 #include <linux/platform_device.h> 18 #include <linux/module.h> 19 #include <linux/of.h> 20 #include <linux/of_device.h> 21 #include <linux/clk-provider.h> 22 #include <linux/regmap.h> 23 24 #include <dt-bindings/clock/qcom,lcc-msm8960.h> 25 26 #include "common.h" 27 #include "clk-regmap.h" 28 #include "clk-pll.h" 29 #include "clk-rcg.h" 30 #include "clk-branch.h" 31 #include "clk-regmap-divider.h" 32 #include "clk-regmap-mux.h" 33 34 static struct clk_pll pll4 = { 35 .l_reg = 0x4, 36 .m_reg = 0x8, 37 .n_reg = 0xc, 38 .config_reg = 0x14, 39 .mode_reg = 0x0, 40 .status_reg = 0x18, 41 .status_bit = 16, 42 .clkr.hw.init = &(struct clk_init_data){ 43 .name = "pll4", 44 .parent_names = (const char *[]){ "pxo" }, 45 .num_parents = 1, 46 .ops = &clk_pll_ops, 47 }, 48 }; 49 50 #define P_PXO 0 51 #define P_PLL4 1 52 53 static const u8 lcc_pxo_pll4_map[] = { 54 [P_PXO] = 0, 55 [P_PLL4] = 2, 56 }; 57 58 static const char *lcc_pxo_pll4[] = { 59 "pxo", 60 "pll4_vote", 61 }; 62 63 static struct freq_tbl clk_tbl_aif_osr_492[] = { 64 { 512000, P_PLL4, 4, 1, 240 }, 65 { 768000, P_PLL4, 4, 1, 160 }, 66 { 1024000, P_PLL4, 4, 1, 120 }, 67 { 1536000, P_PLL4, 4, 1, 80 }, 68 { 2048000, P_PLL4, 4, 1, 60 }, 69 { 3072000, P_PLL4, 4, 1, 40 }, 70 { 4096000, P_PLL4, 4, 1, 30 }, 71 { 6144000, P_PLL4, 4, 1, 20 }, 72 { 8192000, P_PLL4, 4, 1, 15 }, 73 { 12288000, P_PLL4, 4, 1, 10 }, 74 { 24576000, P_PLL4, 4, 1, 5 }, 75 { 27000000, P_PXO, 1, 0, 0 }, 76 { } 77 }; 78 79 static struct freq_tbl clk_tbl_aif_osr_393[] = { 80 { 512000, P_PLL4, 4, 1, 192 }, 81 { 768000, P_PLL4, 4, 1, 128 }, 82 { 1024000, P_PLL4, 4, 1, 96 }, 83 { 1536000, P_PLL4, 4, 1, 64 }, 84 { 2048000, P_PLL4, 4, 1, 48 }, 85 { 3072000, P_PLL4, 4, 1, 32 }, 86 { 4096000, P_PLL4, 4, 1, 24 }, 87 { 6144000, P_PLL4, 4, 1, 16 }, 88 { 8192000, P_PLL4, 4, 1, 12 }, 89 { 12288000, P_PLL4, 4, 1, 8 }, 90 { 24576000, P_PLL4, 4, 1, 4 }, 91 { 27000000, P_PXO, 1, 0, 0 }, 92 { } 93 }; 94 95 static struct clk_rcg mi2s_osr_src = { 96 .ns_reg = 0x48, 97 .md_reg = 0x4c, 98 .mn = { 99 .mnctr_en_bit = 8, 100 .mnctr_reset_bit = 7, 101 .mnctr_mode_shift = 5, 102 .n_val_shift = 24, 103 .m_val_shift = 8, 104 .width = 8, 105 }, 106 .p = { 107 .pre_div_shift = 3, 108 .pre_div_width = 2, 109 }, 110 .s = { 111 .src_sel_shift = 0, 112 .parent_map = lcc_pxo_pll4_map, 113 }, 114 .freq_tbl = clk_tbl_aif_osr_393, 115 .clkr = { 116 .enable_reg = 0x48, 117 .enable_mask = BIT(9), 118 .hw.init = &(struct clk_init_data){ 119 .name = "mi2s_osr_src", 120 .parent_names = lcc_pxo_pll4, 121 .num_parents = 2, 122 .ops = &clk_rcg_ops, 123 .flags = CLK_SET_RATE_GATE, 124 }, 125 }, 126 }; 127 128 static const char *lcc_mi2s_parents[] = { 129 "mi2s_osr_src", 130 }; 131 132 static struct clk_branch mi2s_osr_clk = { 133 .halt_reg = 0x50, 134 .halt_bit = 1, 135 .halt_check = BRANCH_HALT_ENABLE, 136 .clkr = { 137 .enable_reg = 0x48, 138 .enable_mask = BIT(17), 139 .hw.init = &(struct clk_init_data){ 140 .name = "mi2s_osr_clk", 141 .parent_names = lcc_mi2s_parents, 142 .num_parents = 1, 143 .ops = &clk_branch_ops, 144 .flags = CLK_SET_RATE_PARENT, 145 }, 146 }, 147 }; 148 149 static struct clk_regmap_div mi2s_div_clk = { 150 .reg = 0x48, 151 .shift = 10, 152 .width = 4, 153 .clkr = { 154 .enable_reg = 0x48, 155 .enable_mask = BIT(15), 156 .hw.init = &(struct clk_init_data){ 157 .name = "mi2s_div_clk", 158 .parent_names = lcc_mi2s_parents, 159 .num_parents = 1, 160 .ops = &clk_regmap_div_ops, 161 }, 162 }, 163 }; 164 165 static struct clk_branch mi2s_bit_div_clk = { 166 .halt_reg = 0x50, 167 .halt_bit = 0, 168 .halt_check = BRANCH_HALT_ENABLE, 169 .clkr = { 170 .enable_reg = 0x48, 171 .enable_mask = BIT(15), 172 .hw.init = &(struct clk_init_data){ 173 .name = "mi2s_bit_div_clk", 174 .parent_names = (const char *[]){ "mi2s_div_clk" }, 175 .num_parents = 1, 176 .ops = &clk_branch_ops, 177 .flags = CLK_SET_RATE_PARENT, 178 }, 179 }, 180 }; 181 182 static struct clk_regmap_mux mi2s_bit_clk = { 183 .reg = 0x48, 184 .shift = 14, 185 .width = 1, 186 .clkr = { 187 .hw.init = &(struct clk_init_data){ 188 .name = "mi2s_bit_clk", 189 .parent_names = (const char *[]){ 190 "mi2s_bit_div_clk", 191 "mi2s_codec_clk", 192 }, 193 .num_parents = 2, 194 .ops = &clk_regmap_mux_closest_ops, 195 .flags = CLK_SET_RATE_PARENT, 196 }, 197 }, 198 }; 199 200 #define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr) \ 201 static struct clk_rcg prefix##_osr_src = { \ 202 .ns_reg = _ns, \ 203 .md_reg = _md, \ 204 .mn = { \ 205 .mnctr_en_bit = 8, \ 206 .mnctr_reset_bit = 7, \ 207 .mnctr_mode_shift = 5, \ 208 .n_val_shift = 24, \ 209 .m_val_shift = 8, \ 210 .width = 8, \ 211 }, \ 212 .p = { \ 213 .pre_div_shift = 3, \ 214 .pre_div_width = 2, \ 215 }, \ 216 .s = { \ 217 .src_sel_shift = 0, \ 218 .parent_map = lcc_pxo_pll4_map, \ 219 }, \ 220 .freq_tbl = clk_tbl_aif_osr_393, \ 221 .clkr = { \ 222 .enable_reg = _ns, \ 223 .enable_mask = BIT(9), \ 224 .hw.init = &(struct clk_init_data){ \ 225 .name = #prefix "_osr_src", \ 226 .parent_names = lcc_pxo_pll4, \ 227 .num_parents = 2, \ 228 .ops = &clk_rcg_ops, \ 229 .flags = CLK_SET_RATE_GATE, \ 230 }, \ 231 }, \ 232 }; \ 233 \ 234 static const char *lcc_##prefix##_parents[] = { \ 235 #prefix "_osr_src", \ 236 }; \ 237 \ 238 static struct clk_branch prefix##_osr_clk = { \ 239 .halt_reg = hr, \ 240 .halt_bit = 1, \ 241 .halt_check = BRANCH_HALT_ENABLE, \ 242 .clkr = { \ 243 .enable_reg = _ns, \ 244 .enable_mask = BIT(21), \ 245 .hw.init = &(struct clk_init_data){ \ 246 .name = #prefix "_osr_clk", \ 247 .parent_names = lcc_##prefix##_parents, \ 248 .num_parents = 1, \ 249 .ops = &clk_branch_ops, \ 250 .flags = CLK_SET_RATE_PARENT, \ 251 }, \ 252 }, \ 253 }; \ 254 \ 255 static struct clk_regmap_div prefix##_div_clk = { \ 256 .reg = _ns, \ 257 .shift = 10, \ 258 .width = 8, \ 259 .clkr = { \ 260 .hw.init = &(struct clk_init_data){ \ 261 .name = #prefix "_div_clk", \ 262 .parent_names = lcc_##prefix##_parents, \ 263 .num_parents = 1, \ 264 .ops = &clk_regmap_div_ops, \ 265 }, \ 266 }, \ 267 }; \ 268 \ 269 static struct clk_branch prefix##_bit_div_clk = { \ 270 .halt_reg = hr, \ 271 .halt_bit = 0, \ 272 .halt_check = BRANCH_HALT_ENABLE, \ 273 .clkr = { \ 274 .enable_reg = _ns, \ 275 .enable_mask = BIT(19), \ 276 .hw.init = &(struct clk_init_data){ \ 277 .name = #prefix "_bit_div_clk", \ 278 .parent_names = (const char *[]){ \ 279 #prefix "_div_clk" \ 280 }, \ 281 .num_parents = 1, \ 282 .ops = &clk_branch_ops, \ 283 .flags = CLK_SET_RATE_PARENT, \ 284 }, \ 285 }, \ 286 }; \ 287 \ 288 static struct clk_regmap_mux prefix##_bit_clk = { \ 289 .reg = _ns, \ 290 .shift = 18, \ 291 .width = 1, \ 292 .clkr = { \ 293 .hw.init = &(struct clk_init_data){ \ 294 .name = #prefix "_bit_clk", \ 295 .parent_names = (const char *[]){ \ 296 #prefix "_bit_div_clk", \ 297 #prefix "_codec_clk", \ 298 }, \ 299 .num_parents = 2, \ 300 .ops = &clk_regmap_mux_closest_ops, \ 301 .flags = CLK_SET_RATE_PARENT, \ 302 }, \ 303 }, \ 304 } 305 306 CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68); 307 CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80); 308 CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74); 309 CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c); 310 311 static struct freq_tbl clk_tbl_pcm_492[] = { 312 { 256000, P_PLL4, 4, 1, 480 }, 313 { 512000, P_PLL4, 4, 1, 240 }, 314 { 768000, P_PLL4, 4, 1, 160 }, 315 { 1024000, P_PLL4, 4, 1, 120 }, 316 { 1536000, P_PLL4, 4, 1, 80 }, 317 { 2048000, P_PLL4, 4, 1, 60 }, 318 { 3072000, P_PLL4, 4, 1, 40 }, 319 { 4096000, P_PLL4, 4, 1, 30 }, 320 { 6144000, P_PLL4, 4, 1, 20 }, 321 { 8192000, P_PLL4, 4, 1, 15 }, 322 { 12288000, P_PLL4, 4, 1, 10 }, 323 { 24576000, P_PLL4, 4, 1, 5 }, 324 { 27000000, P_PXO, 1, 0, 0 }, 325 { } 326 }; 327 328 static struct freq_tbl clk_tbl_pcm_393[] = { 329 { 256000, P_PLL4, 4, 1, 384 }, 330 { 512000, P_PLL4, 4, 1, 192 }, 331 { 768000, P_PLL4, 4, 1, 128 }, 332 { 1024000, P_PLL4, 4, 1, 96 }, 333 { 1536000, P_PLL4, 4, 1, 64 }, 334 { 2048000, P_PLL4, 4, 1, 48 }, 335 { 3072000, P_PLL4, 4, 1, 32 }, 336 { 4096000, P_PLL4, 4, 1, 24 }, 337 { 6144000, P_PLL4, 4, 1, 16 }, 338 { 8192000, P_PLL4, 4, 1, 12 }, 339 { 12288000, P_PLL4, 4, 1, 8 }, 340 { 24576000, P_PLL4, 4, 1, 4 }, 341 { 27000000, P_PXO, 1, 0, 0 }, 342 { } 343 }; 344 345 static struct clk_rcg pcm_src = { 346 .ns_reg = 0x54, 347 .md_reg = 0x58, 348 .mn = { 349 .mnctr_en_bit = 8, 350 .mnctr_reset_bit = 7, 351 .mnctr_mode_shift = 5, 352 .n_val_shift = 16, 353 .m_val_shift = 16, 354 .width = 16, 355 }, 356 .p = { 357 .pre_div_shift = 3, 358 .pre_div_width = 2, 359 }, 360 .s = { 361 .src_sel_shift = 0, 362 .parent_map = lcc_pxo_pll4_map, 363 }, 364 .freq_tbl = clk_tbl_pcm_393, 365 .clkr = { 366 .enable_reg = 0x54, 367 .enable_mask = BIT(9), 368 .hw.init = &(struct clk_init_data){ 369 .name = "pcm_src", 370 .parent_names = lcc_pxo_pll4, 371 .num_parents = 2, 372 .ops = &clk_rcg_ops, 373 .flags = CLK_SET_RATE_GATE, 374 }, 375 }, 376 }; 377 378 static struct clk_branch pcm_clk_out = { 379 .halt_reg = 0x5c, 380 .halt_bit = 0, 381 .halt_check = BRANCH_HALT_ENABLE, 382 .clkr = { 383 .enable_reg = 0x54, 384 .enable_mask = BIT(11), 385 .hw.init = &(struct clk_init_data){ 386 .name = "pcm_clk_out", 387 .parent_names = (const char *[]){ "pcm_src" }, 388 .num_parents = 1, 389 .ops = &clk_branch_ops, 390 .flags = CLK_SET_RATE_PARENT, 391 }, 392 }, 393 }; 394 395 static struct clk_regmap_mux pcm_clk = { 396 .reg = 0x54, 397 .shift = 10, 398 .width = 1, 399 .clkr = { 400 .hw.init = &(struct clk_init_data){ 401 .name = "pcm_clk", 402 .parent_names = (const char *[]){ 403 "pcm_clk_out", 404 "pcm_codec_clk", 405 }, 406 .num_parents = 2, 407 .ops = &clk_regmap_mux_closest_ops, 408 .flags = CLK_SET_RATE_PARENT, 409 }, 410 }, 411 }; 412 413 static struct clk_rcg slimbus_src = { 414 .ns_reg = 0xcc, 415 .md_reg = 0xd0, 416 .mn = { 417 .mnctr_en_bit = 8, 418 .mnctr_reset_bit = 7, 419 .mnctr_mode_shift = 5, 420 .n_val_shift = 16, 421 .m_val_shift = 16, 422 .width = 8, 423 }, 424 .p = { 425 .pre_div_shift = 3, 426 .pre_div_width = 2, 427 }, 428 .s = { 429 .src_sel_shift = 0, 430 .parent_map = lcc_pxo_pll4_map, 431 }, 432 .freq_tbl = clk_tbl_aif_osr_393, 433 .clkr = { 434 .enable_reg = 0xcc, 435 .enable_mask = BIT(9), 436 .hw.init = &(struct clk_init_data){ 437 .name = "slimbus_src", 438 .parent_names = lcc_pxo_pll4, 439 .num_parents = 2, 440 .ops = &clk_rcg_ops, 441 .flags = CLK_SET_RATE_GATE, 442 }, 443 }, 444 }; 445 446 static const char *lcc_slimbus_parents[] = { 447 "slimbus_src", 448 }; 449 450 static struct clk_branch audio_slimbus_clk = { 451 .halt_reg = 0xd4, 452 .halt_bit = 0, 453 .halt_check = BRANCH_HALT_ENABLE, 454 .clkr = { 455 .enable_reg = 0xcc, 456 .enable_mask = BIT(10), 457 .hw.init = &(struct clk_init_data){ 458 .name = "audio_slimbus_clk", 459 .parent_names = lcc_slimbus_parents, 460 .num_parents = 1, 461 .ops = &clk_branch_ops, 462 .flags = CLK_SET_RATE_PARENT, 463 }, 464 }, 465 }; 466 467 static struct clk_branch sps_slimbus_clk = { 468 .halt_reg = 0xd4, 469 .halt_bit = 1, 470 .halt_check = BRANCH_HALT_ENABLE, 471 .clkr = { 472 .enable_reg = 0xcc, 473 .enable_mask = BIT(12), 474 .hw.init = &(struct clk_init_data){ 475 .name = "sps_slimbus_clk", 476 .parent_names = lcc_slimbus_parents, 477 .num_parents = 1, 478 .ops = &clk_branch_ops, 479 .flags = CLK_SET_RATE_PARENT, 480 }, 481 }, 482 }; 483 484 static struct clk_regmap *lcc_msm8960_clks[] = { 485 [PLL4] = &pll4.clkr, 486 [MI2S_OSR_SRC] = &mi2s_osr_src.clkr, 487 [MI2S_OSR_CLK] = &mi2s_osr_clk.clkr, 488 [MI2S_DIV_CLK] = &mi2s_div_clk.clkr, 489 [MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr, 490 [MI2S_BIT_CLK] = &mi2s_bit_clk.clkr, 491 [PCM_SRC] = &pcm_src.clkr, 492 [PCM_CLK_OUT] = &pcm_clk_out.clkr, 493 [PCM_CLK] = &pcm_clk.clkr, 494 [SLIMBUS_SRC] = &slimbus_src.clkr, 495 [AUDIO_SLIMBUS_CLK] = &audio_slimbus_clk.clkr, 496 [SPS_SLIMBUS_CLK] = &sps_slimbus_clk.clkr, 497 [CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr, 498 [CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr, 499 [CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr, 500 [CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr, 501 [CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr, 502 [SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr, 503 [SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr, 504 [SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr, 505 [SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr, 506 [SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr, 507 [CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr, 508 [CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr, 509 [CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr, 510 [CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr, 511 [CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr, 512 [SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr, 513 [SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr, 514 [SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr, 515 [SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr, 516 [SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr, 517 }; 518 519 static const struct regmap_config lcc_msm8960_regmap_config = { 520 .reg_bits = 32, 521 .reg_stride = 4, 522 .val_bits = 32, 523 .max_register = 0xfc, 524 .fast_io = true, 525 }; 526 527 static const struct qcom_cc_desc lcc_msm8960_desc = { 528 .config = &lcc_msm8960_regmap_config, 529 .clks = lcc_msm8960_clks, 530 .num_clks = ARRAY_SIZE(lcc_msm8960_clks), 531 }; 532 533 static const struct of_device_id lcc_msm8960_match_table[] = { 534 { .compatible = "qcom,lcc-msm8960" }, 535 { .compatible = "qcom,lcc-apq8064" }, 536 { } 537 }; 538 MODULE_DEVICE_TABLE(of, lcc_msm8960_match_table); 539 540 static int lcc_msm8960_probe(struct platform_device *pdev) 541 { 542 u32 val; 543 struct regmap *regmap; 544 545 regmap = qcom_cc_map(pdev, &lcc_msm8960_desc); 546 if (IS_ERR(regmap)) 547 return PTR_ERR(regmap); 548 549 /* Use the correct frequency plan depending on speed of PLL4 */ 550 val = regmap_read(regmap, 0x4, &val); 551 if (val == 0x12) { 552 slimbus_src.freq_tbl = clk_tbl_aif_osr_492; 553 mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492; 554 codec_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492; 555 spare_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492; 556 codec_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492; 557 spare_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492; 558 pcm_src.freq_tbl = clk_tbl_pcm_492; 559 } 560 /* Enable PLL4 source on the LPASS Primary PLL Mux */ 561 regmap_write(regmap, 0xc4, 0x1); 562 563 return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap); 564 } 565 566 static int lcc_msm8960_remove(struct platform_device *pdev) 567 { 568 qcom_cc_remove(pdev); 569 return 0; 570 } 571 572 static struct platform_driver lcc_msm8960_driver = { 573 .probe = lcc_msm8960_probe, 574 .remove = lcc_msm8960_remove, 575 .driver = { 576 .name = "lcc-msm8960", 577 .owner = THIS_MODULE, 578 .of_match_table = lcc_msm8960_match_table, 579 }, 580 }; 581 module_platform_driver(lcc_msm8960_driver); 582 583 MODULE_DESCRIPTION("QCOM LCC MSM8960 Driver"); 584 MODULE_LICENSE("GPL v2"); 585 MODULE_ALIAS("platform:lcc-msm8960"); 586