1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/mod_devicetable.h> 8 #include <linux/module.h> 9 #include <linux/platform_device.h> 10 #include <linux/regmap.h> 11 12 #include <dt-bindings/clock/qcom,sm8750-cambistmclkcc.h> 13 14 #include "clk-alpha-pll.h" 15 #include "clk-branch.h" 16 #include "clk-rcg.h" 17 #include "clk-regmap.h" 18 #include "common.h" 19 #include "reset.h" 20 21 enum { 22 DT_IFACE, 23 DT_BI_TCXO, 24 DT_BI_TCXO_AO, 25 DT_SLEEP_CLK, 26 }; 27 28 enum { 29 P_BI_TCXO, 30 P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 31 P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 32 P_SLEEP_CLK, 33 }; 34 35 static const struct pll_vco rivian_elu_vco[] = { 36 { 833000000, 1125000000, 0 }, 37 { 777000000, 1062000000, 1 }, 38 }; 39 40 /* 960.0 MHz Configuration */ 41 static const struct alpha_pll_config cam_bist_mclk_cc_pll0_config = { 42 .l = 0x32, 43 .alpha = 0x0, 44 .config_ctl_val = 0x12000000, 45 .config_ctl_hi_val = 0x00890263, 46 .config_ctl_hi1_val = 0x1af04237, 47 .config_ctl_hi2_val = 0x00000000, 48 }; 49 50 static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = { 51 .offset = 0x0, 52 .config = &cam_bist_mclk_cc_pll0_config, 53 .vco_table = rivian_elu_vco, 54 .num_vco = ARRAY_SIZE(rivian_elu_vco), 55 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_ELU], 56 .clkr = { 57 .hw.init = &(const struct clk_init_data) { 58 .name = "cam_bist_mclk_cc_pll0", 59 .parent_data = &(const struct clk_parent_data) { 60 .index = DT_BI_TCXO, 61 }, 62 .num_parents = 1, 63 .ops = &clk_alpha_pll_rivian_elu_ops, 64 }, 65 }, 66 }; 67 68 static const struct parent_map cam_bist_mclk_cc_parent_map_0[] = { 69 { P_BI_TCXO, 0 }, 70 { P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 3 }, 71 { P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 5 }, 72 }; 73 74 static const struct clk_parent_data cam_bist_mclk_cc_parent_data_0[] = { 75 { .index = DT_BI_TCXO }, 76 { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, 77 { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, 78 }; 79 80 static const struct parent_map cam_bist_mclk_cc_parent_map_1[] = { 81 { P_SLEEP_CLK, 0 }, 82 }; 83 84 static const struct clk_parent_data cam_bist_mclk_cc_parent_data_1[] = { 85 { .index = DT_SLEEP_CLK }, 86 }; 87 88 static const struct freq_tbl ftbl_cam_bist_mclk_cc_mclk0_clk_src[] = { 89 F(12000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 8), 90 F(19200000, P_BI_TCXO, 1, 0, 0), 91 F(24000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 4), 92 F(68571429, P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 14, 0, 0), 93 { } 94 }; 95 96 static struct clk_rcg2 cam_bist_mclk_cc_mclk0_clk_src = { 97 .cmd_rcgr = 0x4000, 98 .mnd_width = 8, 99 .hid_width = 5, 100 .parent_map = cam_bist_mclk_cc_parent_map_0, 101 .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, 102 .clkr.hw.init = &(const struct clk_init_data) { 103 .name = "cam_bist_mclk_cc_mclk0_clk_src", 104 .parent_data = cam_bist_mclk_cc_parent_data_0, 105 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), 106 .flags = CLK_SET_RATE_PARENT, 107 .ops = &clk_rcg2_shared_ops, 108 }, 109 }; 110 111 static struct clk_rcg2 cam_bist_mclk_cc_mclk1_clk_src = { 112 .cmd_rcgr = 0x401c, 113 .mnd_width = 8, 114 .hid_width = 5, 115 .parent_map = cam_bist_mclk_cc_parent_map_0, 116 .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, 117 .clkr.hw.init = &(const struct clk_init_data) { 118 .name = "cam_bist_mclk_cc_mclk1_clk_src", 119 .parent_data = cam_bist_mclk_cc_parent_data_0, 120 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), 121 .flags = CLK_SET_RATE_PARENT, 122 .ops = &clk_rcg2_shared_ops, 123 }, 124 }; 125 126 static struct clk_rcg2 cam_bist_mclk_cc_mclk2_clk_src = { 127 .cmd_rcgr = 0x4038, 128 .mnd_width = 8, 129 .hid_width = 5, 130 .parent_map = cam_bist_mclk_cc_parent_map_0, 131 .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, 132 .clkr.hw.init = &(const struct clk_init_data) { 133 .name = "cam_bist_mclk_cc_mclk2_clk_src", 134 .parent_data = cam_bist_mclk_cc_parent_data_0, 135 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), 136 .flags = CLK_SET_RATE_PARENT, 137 .ops = &clk_rcg2_shared_ops, 138 }, 139 }; 140 141 static struct clk_rcg2 cam_bist_mclk_cc_mclk3_clk_src = { 142 .cmd_rcgr = 0x4054, 143 .mnd_width = 8, 144 .hid_width = 5, 145 .parent_map = cam_bist_mclk_cc_parent_map_0, 146 .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, 147 .clkr.hw.init = &(const struct clk_init_data) { 148 .name = "cam_bist_mclk_cc_mclk3_clk_src", 149 .parent_data = cam_bist_mclk_cc_parent_data_0, 150 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), 151 .flags = CLK_SET_RATE_PARENT, 152 .ops = &clk_rcg2_shared_ops, 153 }, 154 }; 155 156 static struct clk_rcg2 cam_bist_mclk_cc_mclk4_clk_src = { 157 .cmd_rcgr = 0x4070, 158 .mnd_width = 8, 159 .hid_width = 5, 160 .parent_map = cam_bist_mclk_cc_parent_map_0, 161 .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, 162 .clkr.hw.init = &(const struct clk_init_data) { 163 .name = "cam_bist_mclk_cc_mclk4_clk_src", 164 .parent_data = cam_bist_mclk_cc_parent_data_0, 165 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), 166 .flags = CLK_SET_RATE_PARENT, 167 .ops = &clk_rcg2_shared_ops, 168 }, 169 }; 170 171 static struct clk_rcg2 cam_bist_mclk_cc_mclk5_clk_src = { 172 .cmd_rcgr = 0x408c, 173 .mnd_width = 8, 174 .hid_width = 5, 175 .parent_map = cam_bist_mclk_cc_parent_map_0, 176 .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, 177 .clkr.hw.init = &(const struct clk_init_data) { 178 .name = "cam_bist_mclk_cc_mclk5_clk_src", 179 .parent_data = cam_bist_mclk_cc_parent_data_0, 180 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), 181 .flags = CLK_SET_RATE_PARENT, 182 .ops = &clk_rcg2_shared_ops, 183 }, 184 }; 185 186 static struct clk_rcg2 cam_bist_mclk_cc_mclk6_clk_src = { 187 .cmd_rcgr = 0x40a8, 188 .mnd_width = 8, 189 .hid_width = 5, 190 .parent_map = cam_bist_mclk_cc_parent_map_0, 191 .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, 192 .clkr.hw.init = &(const struct clk_init_data) { 193 .name = "cam_bist_mclk_cc_mclk6_clk_src", 194 .parent_data = cam_bist_mclk_cc_parent_data_0, 195 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), 196 .flags = CLK_SET_RATE_PARENT, 197 .ops = &clk_rcg2_shared_ops, 198 }, 199 }; 200 201 static struct clk_rcg2 cam_bist_mclk_cc_mclk7_clk_src = { 202 .cmd_rcgr = 0x40c4, 203 .mnd_width = 8, 204 .hid_width = 5, 205 .parent_map = cam_bist_mclk_cc_parent_map_0, 206 .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, 207 .clkr.hw.init = &(const struct clk_init_data) { 208 .name = "cam_bist_mclk_cc_mclk7_clk_src", 209 .parent_data = cam_bist_mclk_cc_parent_data_0, 210 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), 211 .flags = CLK_SET_RATE_PARENT, 212 .ops = &clk_rcg2_shared_ops, 213 }, 214 }; 215 216 static const struct freq_tbl ftbl_cam_bist_mclk_cc_sleep_clk_src[] = { 217 F(32000, P_SLEEP_CLK, 1, 0, 0), 218 { } 219 }; 220 221 static struct clk_rcg2 cam_bist_mclk_cc_sleep_clk_src = { 222 .cmd_rcgr = 0x40e0, 223 .mnd_width = 0, 224 .hid_width = 5, 225 .parent_map = cam_bist_mclk_cc_parent_map_1, 226 .freq_tbl = ftbl_cam_bist_mclk_cc_sleep_clk_src, 227 .clkr.hw.init = &(const struct clk_init_data) { 228 .name = "cam_bist_mclk_cc_sleep_clk_src", 229 .parent_data = cam_bist_mclk_cc_parent_data_1, 230 .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_1), 231 .flags = CLK_SET_RATE_PARENT, 232 .ops = &clk_rcg2_shared_ops, 233 }, 234 }; 235 236 static struct clk_branch cam_bist_mclk_cc_mclk0_clk = { 237 .halt_reg = 0x4018, 238 .halt_check = BRANCH_HALT, 239 .clkr = { 240 .enable_reg = 0x4018, 241 .enable_mask = BIT(0), 242 .hw.init = &(const struct clk_init_data) { 243 .name = "cam_bist_mclk_cc_mclk0_clk", 244 .parent_hws = (const struct clk_hw*[]) { 245 &cam_bist_mclk_cc_mclk0_clk_src.clkr.hw, 246 }, 247 .num_parents = 1, 248 .flags = CLK_SET_RATE_PARENT, 249 .ops = &clk_branch2_ops, 250 }, 251 }, 252 }; 253 254 static struct clk_branch cam_bist_mclk_cc_mclk1_clk = { 255 .halt_reg = 0x4034, 256 .halt_check = BRANCH_HALT, 257 .clkr = { 258 .enable_reg = 0x4034, 259 .enable_mask = BIT(0), 260 .hw.init = &(const struct clk_init_data) { 261 .name = "cam_bist_mclk_cc_mclk1_clk", 262 .parent_hws = (const struct clk_hw*[]) { 263 &cam_bist_mclk_cc_mclk1_clk_src.clkr.hw, 264 }, 265 .num_parents = 1, 266 .flags = CLK_SET_RATE_PARENT, 267 .ops = &clk_branch2_ops, 268 }, 269 }, 270 }; 271 272 static struct clk_branch cam_bist_mclk_cc_mclk2_clk = { 273 .halt_reg = 0x4050, 274 .halt_check = BRANCH_HALT, 275 .clkr = { 276 .enable_reg = 0x4050, 277 .enable_mask = BIT(0), 278 .hw.init = &(const struct clk_init_data) { 279 .name = "cam_bist_mclk_cc_mclk2_clk", 280 .parent_hws = (const struct clk_hw*[]) { 281 &cam_bist_mclk_cc_mclk2_clk_src.clkr.hw, 282 }, 283 .num_parents = 1, 284 .flags = CLK_SET_RATE_PARENT, 285 .ops = &clk_branch2_ops, 286 }, 287 }, 288 }; 289 290 static struct clk_branch cam_bist_mclk_cc_mclk3_clk = { 291 .halt_reg = 0x406c, 292 .halt_check = BRANCH_HALT, 293 .clkr = { 294 .enable_reg = 0x406c, 295 .enable_mask = BIT(0), 296 .hw.init = &(const struct clk_init_data) { 297 .name = "cam_bist_mclk_cc_mclk3_clk", 298 .parent_hws = (const struct clk_hw*[]) { 299 &cam_bist_mclk_cc_mclk3_clk_src.clkr.hw, 300 }, 301 .num_parents = 1, 302 .flags = CLK_SET_RATE_PARENT, 303 .ops = &clk_branch2_ops, 304 }, 305 }, 306 }; 307 308 static struct clk_branch cam_bist_mclk_cc_mclk4_clk = { 309 .halt_reg = 0x4088, 310 .halt_check = BRANCH_HALT, 311 .clkr = { 312 .enable_reg = 0x4088, 313 .enable_mask = BIT(0), 314 .hw.init = &(const struct clk_init_data) { 315 .name = "cam_bist_mclk_cc_mclk4_clk", 316 .parent_hws = (const struct clk_hw*[]) { 317 &cam_bist_mclk_cc_mclk4_clk_src.clkr.hw, 318 }, 319 .num_parents = 1, 320 .flags = CLK_SET_RATE_PARENT, 321 .ops = &clk_branch2_ops, 322 }, 323 }, 324 }; 325 326 static struct clk_branch cam_bist_mclk_cc_mclk5_clk = { 327 .halt_reg = 0x40a4, 328 .halt_check = BRANCH_HALT, 329 .clkr = { 330 .enable_reg = 0x40a4, 331 .enable_mask = BIT(0), 332 .hw.init = &(const struct clk_init_data) { 333 .name = "cam_bist_mclk_cc_mclk5_clk", 334 .parent_hws = (const struct clk_hw*[]) { 335 &cam_bist_mclk_cc_mclk5_clk_src.clkr.hw, 336 }, 337 .num_parents = 1, 338 .flags = CLK_SET_RATE_PARENT, 339 .ops = &clk_branch2_ops, 340 }, 341 }, 342 }; 343 344 static struct clk_branch cam_bist_mclk_cc_mclk6_clk = { 345 .halt_reg = 0x40c0, 346 .halt_check = BRANCH_HALT, 347 .clkr = { 348 .enable_reg = 0x40c0, 349 .enable_mask = BIT(0), 350 .hw.init = &(const struct clk_init_data) { 351 .name = "cam_bist_mclk_cc_mclk6_clk", 352 .parent_hws = (const struct clk_hw*[]) { 353 &cam_bist_mclk_cc_mclk6_clk_src.clkr.hw, 354 }, 355 .num_parents = 1, 356 .flags = CLK_SET_RATE_PARENT, 357 .ops = &clk_branch2_ops, 358 }, 359 }, 360 }; 361 362 static struct clk_branch cam_bist_mclk_cc_mclk7_clk = { 363 .halt_reg = 0x40dc, 364 .halt_check = BRANCH_HALT, 365 .clkr = { 366 .enable_reg = 0x40dc, 367 .enable_mask = BIT(0), 368 .hw.init = &(const struct clk_init_data) { 369 .name = "cam_bist_mclk_cc_mclk7_clk", 370 .parent_hws = (const struct clk_hw*[]) { 371 &cam_bist_mclk_cc_mclk7_clk_src.clkr.hw, 372 }, 373 .num_parents = 1, 374 .flags = CLK_SET_RATE_PARENT, 375 .ops = &clk_branch2_ops, 376 }, 377 }, 378 }; 379 380 static struct clk_regmap *cam_bist_mclk_cc_sm8750_clocks[] = { 381 [CAM_BIST_MCLK_CC_MCLK0_CLK] = &cam_bist_mclk_cc_mclk0_clk.clkr, 382 [CAM_BIST_MCLK_CC_MCLK0_CLK_SRC] = &cam_bist_mclk_cc_mclk0_clk_src.clkr, 383 [CAM_BIST_MCLK_CC_MCLK1_CLK] = &cam_bist_mclk_cc_mclk1_clk.clkr, 384 [CAM_BIST_MCLK_CC_MCLK1_CLK_SRC] = &cam_bist_mclk_cc_mclk1_clk_src.clkr, 385 [CAM_BIST_MCLK_CC_MCLK2_CLK] = &cam_bist_mclk_cc_mclk2_clk.clkr, 386 [CAM_BIST_MCLK_CC_MCLK2_CLK_SRC] = &cam_bist_mclk_cc_mclk2_clk_src.clkr, 387 [CAM_BIST_MCLK_CC_MCLK3_CLK] = &cam_bist_mclk_cc_mclk3_clk.clkr, 388 [CAM_BIST_MCLK_CC_MCLK3_CLK_SRC] = &cam_bist_mclk_cc_mclk3_clk_src.clkr, 389 [CAM_BIST_MCLK_CC_MCLK4_CLK] = &cam_bist_mclk_cc_mclk4_clk.clkr, 390 [CAM_BIST_MCLK_CC_MCLK4_CLK_SRC] = &cam_bist_mclk_cc_mclk4_clk_src.clkr, 391 [CAM_BIST_MCLK_CC_MCLK5_CLK] = &cam_bist_mclk_cc_mclk5_clk.clkr, 392 [CAM_BIST_MCLK_CC_MCLK5_CLK_SRC] = &cam_bist_mclk_cc_mclk5_clk_src.clkr, 393 [CAM_BIST_MCLK_CC_MCLK6_CLK] = &cam_bist_mclk_cc_mclk6_clk.clkr, 394 [CAM_BIST_MCLK_CC_MCLK6_CLK_SRC] = &cam_bist_mclk_cc_mclk6_clk_src.clkr, 395 [CAM_BIST_MCLK_CC_MCLK7_CLK] = &cam_bist_mclk_cc_mclk7_clk.clkr, 396 [CAM_BIST_MCLK_CC_MCLK7_CLK_SRC] = &cam_bist_mclk_cc_mclk7_clk_src.clkr, 397 [CAM_BIST_MCLK_CC_PLL0] = &cam_bist_mclk_cc_pll0.clkr, 398 [CAM_BIST_MCLK_CC_SLEEP_CLK_SRC] = &cam_bist_mclk_cc_sleep_clk_src.clkr, 399 }; 400 401 static struct clk_alpha_pll *cam_bist_mclk_cc_sm8750_plls[] = { 402 &cam_bist_mclk_cc_pll0, 403 }; 404 405 static u32 cam_bist_mclk_cc_sm8750_critical_cbcrs[] = { 406 0x40f8, /* CAM_BIST_MCLK_CC_SLEEP_CLK */ 407 }; 408 409 static const struct regmap_config cam_bist_mclk_cc_sm8750_regmap_config = { 410 .reg_bits = 32, 411 .reg_stride = 4, 412 .val_bits = 32, 413 .max_register = 0x5010, 414 .fast_io = true, 415 }; 416 417 static struct qcom_cc_driver_data cam_bist_mclk_cc_sm8750_driver_data = { 418 .alpha_plls = cam_bist_mclk_cc_sm8750_plls, 419 .num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_plls), 420 .clk_cbcrs = cam_bist_mclk_cc_sm8750_critical_cbcrs, 421 .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_critical_cbcrs), 422 }; 423 424 static const struct qcom_cc_desc cam_bist_mclk_cc_sm8750_desc = { 425 .config = &cam_bist_mclk_cc_sm8750_regmap_config, 426 .clks = cam_bist_mclk_cc_sm8750_clocks, 427 .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_clocks), 428 .use_rpm = true, 429 .driver_data = &cam_bist_mclk_cc_sm8750_driver_data, 430 }; 431 432 static const struct of_device_id cam_bist_mclk_cc_sm8750_match_table[] = { 433 { .compatible = "qcom,sm8750-cambistmclkcc" }, 434 { } 435 }; 436 MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_sm8750_match_table); 437 438 static int cam_bist_mclk_cc_sm8750_probe(struct platform_device *pdev) 439 { 440 return qcom_cc_probe(pdev, &cam_bist_mclk_cc_sm8750_desc); 441 } 442 443 static struct platform_driver cam_bist_mclk_cc_sm8750_driver = { 444 .probe = cam_bist_mclk_cc_sm8750_probe, 445 .driver = { 446 .name = "cambistmclkcc-sm8750", 447 .of_match_table = cam_bist_mclk_cc_sm8750_match_table, 448 }, 449 }; 450 451 module_platform_driver(cam_bist_mclk_cc_sm8750_driver); 452 453 MODULE_DESCRIPTION("QTI CAMBISTMCLKCC SM8750 Driver"); 454 MODULE_LICENSE("GPL"); 455