Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 473 lines 12 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 */ 5#include <linux/clk-provider.h> 6#include <linux/mod_devicetable.h> 7#include <linux/module.h> 8#include <linux/platform_device.h> 9#include <linux/pm_runtime.h> 10#include <linux/regmap.h> 11 12#include <dt-bindings/clock/qcom,sm8750-gpucc.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 "clk-regmap-divider.h" 19#include "clk-regmap-mux.h" 20#include "gdsc.h" 21#include "reset.h" 22 23enum { 24 DT_BI_TCXO, 25 DT_GPLL0_OUT_MAIN, 26 DT_GPLL0_OUT_MAIN_DIV, 27}; 28 29enum { 30 P_BI_TCXO, 31 P_GPLL0_OUT_MAIN, 32 P_GPLL0_OUT_MAIN_DIV, 33 P_GPU_CC_PLL0_OUT_EVEN, 34 P_GPU_CC_PLL0_OUT_MAIN, 35 P_GPU_CC_PLL0_OUT_ODD, 36}; 37 38static const struct pll_vco taycan_elu_vco[] = { 39 { 249600000, 2500000000, 0 }, 40}; 41 42static const struct alpha_pll_config gpu_cc_pll0_config = { 43 .l = 0x34, 44 .alpha = 0x1555, 45 .config_ctl_val = 0x19660387, 46 .config_ctl_hi_val = 0x098060a0, 47 .config_ctl_hi1_val = 0xb416cb20, 48 .user_ctl_val = 0x00000400, 49 .user_ctl_hi_val = 0x00000002, 50}; 51 52static struct clk_alpha_pll gpu_cc_pll0 = { 53 .offset = 0x0, 54 .config = &gpu_cc_pll0_config, 55 .vco_table = taycan_elu_vco, 56 .num_vco = ARRAY_SIZE(taycan_elu_vco), 57 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], 58 .clkr = { 59 .hw.init = &(const struct clk_init_data) { 60 .name = "gpu_cc_pll0", 61 .parent_data = &(const struct clk_parent_data) { 62 .index = DT_BI_TCXO, 63 }, 64 .num_parents = 1, 65 .ops = &clk_alpha_pll_taycan_elu_ops, 66 }, 67 }, 68}; 69 70static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = { 71 { 0x1, 2 }, 72 { } 73}; 74 75static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { 76 .offset = 0x0, 77 .post_div_shift = 10, 78 .post_div_table = post_div_table_gpu_cc_pll0_out_even, 79 .num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even), 80 .width = 4, 81 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], 82 .clkr.hw.init = &(const struct clk_init_data) { 83 .name = "gpu_cc_pll0_out_even", 84 .parent_hws = (const struct clk_hw*[]) { 85 &gpu_cc_pll0.clkr.hw, 86 }, 87 .num_parents = 1, 88 .flags = CLK_SET_RATE_PARENT, 89 .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, 90 }, 91}; 92 93static const struct parent_map gpu_cc_parent_map_1[] = { 94 { P_BI_TCXO, 0 }, 95 { P_GPU_CC_PLL0_OUT_MAIN, 1 }, 96 { P_GPU_CC_PLL0_OUT_EVEN, 2 }, 97 { P_GPU_CC_PLL0_OUT_ODD, 3 }, 98 { P_GPLL0_OUT_MAIN, 5 }, 99 { P_GPLL0_OUT_MAIN_DIV, 6 }, 100}; 101 102static const struct clk_parent_data gpu_cc_parent_data_1[] = { 103 { .index = DT_BI_TCXO }, 104 { .hw = &gpu_cc_pll0.clkr.hw }, 105 { .hw = &gpu_cc_pll0_out_even.clkr.hw }, 106 { .hw = &gpu_cc_pll0.clkr.hw }, 107 { .index = DT_GPLL0_OUT_MAIN }, 108 { .index = DT_GPLL0_OUT_MAIN_DIV }, 109}; 110 111static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 112 F(19200000, P_BI_TCXO, 1, 0, 0), 113 F(500000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), 114 F(650000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), 115 F(687500000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), 116 { } 117}; 118 119static struct clk_rcg2 gpu_cc_gmu_clk_src = { 120 .cmd_rcgr = 0x9318, 121 .mnd_width = 0, 122 .hid_width = 5, 123 .parent_map = gpu_cc_parent_map_1, 124 .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 125 .clkr.hw.init = &(const struct clk_init_data) { 126 .name = "gpu_cc_gmu_clk_src", 127 .parent_data = gpu_cc_parent_data_1, 128 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), 129 .flags = CLK_SET_RATE_PARENT, 130 .ops = &clk_rcg2_shared_ops, 131 }, 132}; 133 134static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { 135 F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 136 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 137 F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), 138 { } 139}; 140 141static struct clk_rcg2 gpu_cc_hub_clk_src = { 142 .cmd_rcgr = 0x93ec, 143 .mnd_width = 0, 144 .hid_width = 5, 145 .parent_map = gpu_cc_parent_map_1, 146 .freq_tbl = ftbl_gpu_cc_hub_clk_src, 147 .clkr.hw.init = &(const struct clk_init_data) { 148 .name = "gpu_cc_hub_clk_src", 149 .parent_data = gpu_cc_parent_data_1, 150 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), 151 .flags = CLK_SET_RATE_PARENT, 152 .ops = &clk_rcg2_shared_ops, 153 }, 154}; 155 156static struct clk_regmap_div gpu_cc_hub_div_clk_src = { 157 .reg = 0x942c, 158 .shift = 0, 159 .width = 4, 160 .clkr.hw.init = &(const struct clk_init_data) { 161 .name = "gpu_cc_hub_div_clk_src", 162 .parent_hws = (const struct clk_hw*[]) { 163 &gpu_cc_hub_clk_src.clkr.hw, 164 }, 165 .num_parents = 1, 166 .flags = CLK_SET_RATE_PARENT, 167 .ops = &clk_regmap_div_ro_ops, 168 }, 169}; 170 171static struct clk_branch gpu_cc_ahb_clk = { 172 .halt_reg = 0x90bc, 173 .halt_check = BRANCH_HALT_DELAY, 174 .clkr = { 175 .enable_reg = 0x90bc, 176 .enable_mask = BIT(0), 177 .hw.init = &(const struct clk_init_data) { 178 .name = "gpu_cc_ahb_clk", 179 .parent_hws = (const struct clk_hw*[]) { 180 &gpu_cc_hub_div_clk_src.clkr.hw, 181 }, 182 .num_parents = 1, 183 .flags = CLK_SET_RATE_PARENT, 184 .ops = &clk_branch2_ops, 185 }, 186 }, 187}; 188 189static struct clk_branch gpu_cc_cx_accu_shift_clk = { 190 .halt_reg = 0x910c, 191 .halt_check = BRANCH_HALT_VOTED, 192 .clkr = { 193 .enable_reg = 0x910c, 194 .enable_mask = BIT(0), 195 .hw.init = &(const struct clk_init_data) { 196 .name = "gpu_cc_cx_accu_shift_clk", 197 .ops = &clk_branch2_ops, 198 }, 199 }, 200}; 201 202static struct clk_branch gpu_cc_cx_gmu_clk = { 203 .halt_reg = 0x90d4, 204 .halt_check = BRANCH_HALT_VOTED, 205 .clkr = { 206 .enable_reg = 0x90d4, 207 .enable_mask = BIT(0), 208 .hw.init = &(const struct clk_init_data) { 209 .name = "gpu_cc_cx_gmu_clk", 210 .parent_hws = (const struct clk_hw*[]) { 211 &gpu_cc_gmu_clk_src.clkr.hw, 212 }, 213 .num_parents = 1, 214 .flags = CLK_SET_RATE_PARENT, 215 .ops = &clk_branch2_aon_ops, 216 }, 217 }, 218}; 219 220static struct clk_branch gpu_cc_cxo_clk = { 221 .halt_reg = 0x90e4, 222 .halt_check = BRANCH_HALT, 223 .clkr = { 224 .enable_reg = 0x90e4, 225 .enable_mask = BIT(0), 226 .hw.init = &(const struct clk_init_data) { 227 .name = "gpu_cc_cxo_clk", 228 .ops = &clk_branch2_ops, 229 }, 230 }, 231}; 232 233static struct clk_branch gpu_cc_demet_clk = { 234 .halt_reg = 0x9010, 235 .halt_check = BRANCH_HALT_VOTED, 236 .clkr = { 237 .enable_reg = 0x9010, 238 .enable_mask = BIT(0), 239 .hw.init = &(const struct clk_init_data) { 240 .name = "gpu_cc_demet_clk", 241 .ops = &clk_branch2_ops, 242 }, 243 }, 244}; 245 246static struct clk_branch gpu_cc_dpm_clk = { 247 .halt_reg = 0x9110, 248 .halt_check = BRANCH_HALT, 249 .clkr = { 250 .enable_reg = 0x9110, 251 .enable_mask = BIT(0), 252 .hw.init = &(const struct clk_init_data) { 253 .name = "gpu_cc_dpm_clk", 254 .ops = &clk_branch2_ops, 255 }, 256 }, 257}; 258 259static struct clk_branch gpu_cc_freq_measure_clk = { 260 .halt_reg = 0x900c, 261 .halt_check = BRANCH_HALT, 262 .clkr = { 263 .enable_reg = 0x900c, 264 .enable_mask = BIT(0), 265 .hw.init = &(const struct clk_init_data) { 266 .name = "gpu_cc_freq_measure_clk", 267 .ops = &clk_branch2_ops, 268 }, 269 }, 270}; 271 272static struct clk_branch gpu_cc_gx_accu_shift_clk = { 273 .halt_reg = 0x9070, 274 .halt_check = BRANCH_HALT_VOTED, 275 .clkr = { 276 .enable_reg = 0x9070, 277 .enable_mask = BIT(0), 278 .hw.init = &(const struct clk_init_data) { 279 .name = "gpu_cc_gx_accu_shift_clk", 280 .ops = &clk_branch2_ops, 281 }, 282 }, 283}; 284 285static struct clk_branch gpu_cc_gx_gmu_clk = { 286 .halt_reg = 0x9060, 287 .halt_check = BRANCH_HALT, 288 .clkr = { 289 .enable_reg = 0x9060, 290 .enable_mask = BIT(0), 291 .hw.init = &(const struct clk_init_data) { 292 .name = "gpu_cc_gx_gmu_clk", 293 .parent_hws = (const struct clk_hw*[]) { 294 &gpu_cc_gmu_clk_src.clkr.hw, 295 }, 296 .num_parents = 1, 297 .flags = CLK_SET_RATE_PARENT, 298 .ops = &clk_branch2_ops, 299 }, 300 }, 301}; 302 303static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { 304 .halt_reg = 0x7000, 305 .halt_check = BRANCH_HALT_VOTED, 306 .clkr = { 307 .enable_reg = 0x7000, 308 .enable_mask = BIT(0), 309 .hw.init = &(const struct clk_init_data) { 310 .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", 311 .ops = &clk_branch2_ops, 312 }, 313 }, 314}; 315 316static struct clk_branch gpu_cc_hub_aon_clk = { 317 .halt_reg = 0x93e8, 318 .halt_check = BRANCH_HALT_VOTED, 319 .clkr = { 320 .enable_reg = 0x93e8, 321 .enable_mask = BIT(0), 322 .hw.init = &(const struct clk_init_data) { 323 .name = "gpu_cc_hub_aon_clk", 324 .parent_hws = (const struct clk_hw*[]) { 325 &gpu_cc_hub_clk_src.clkr.hw, 326 }, 327 .num_parents = 1, 328 .flags = CLK_SET_RATE_PARENT, 329 .ops = &clk_branch2_aon_ops, 330 }, 331 }, 332}; 333 334static struct clk_branch gpu_cc_hub_cx_int_clk = { 335 .halt_reg = 0x90e8, 336 .halt_check = BRANCH_HALT_VOTED, 337 .clkr = { 338 .enable_reg = 0x90e8, 339 .enable_mask = BIT(0), 340 .hw.init = &(const struct clk_init_data) { 341 .name = "gpu_cc_hub_cx_int_clk", 342 .parent_hws = (const struct clk_hw*[]) { 343 &gpu_cc_hub_clk_src.clkr.hw, 344 }, 345 .num_parents = 1, 346 .flags = CLK_SET_RATE_PARENT, 347 .ops = &clk_branch2_aon_ops, 348 }, 349 }, 350}; 351 352static struct clk_branch gpu_cc_memnoc_gfx_clk = { 353 .halt_reg = 0x90f4, 354 .halt_check = BRANCH_HALT_VOTED, 355 .clkr = { 356 .enable_reg = 0x90f4, 357 .enable_mask = BIT(0), 358 .hw.init = &(const struct clk_init_data) { 359 .name = "gpu_cc_memnoc_gfx_clk", 360 .ops = &clk_branch2_ops, 361 }, 362 }, 363}; 364 365static struct gdsc gpu_cc_cx_gdsc = { 366 .gdscr = 0x9080, 367 .gds_hw_ctrl = 0x9094, 368 .en_rest_wait_val = 0x2, 369 .en_few_wait_val = 0x2, 370 .clk_dis_wait_val = 0x8, 371 .pd = { 372 .name = "gpu_cc_cx_gdsc", 373 }, 374 .pwrsts = PWRSTS_OFF_ON, 375 .flags = RETAIN_FF_ENABLE | VOTABLE, 376}; 377 378static struct clk_regmap *gpu_cc_sm8750_clocks[] = { 379 [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, 380 [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr, 381 [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 382 [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 383 [GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr, 384 [GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.clkr, 385 [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr, 386 [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 387 [GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr, 388 [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, 389 [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, 390 [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, 391 [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, 392 [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, 393 [GPU_CC_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr, 394 [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, 395 [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, 396 [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr, 397}; 398 399static struct gdsc *gpu_cc_sm8750_gdscs[] = { 400 [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, 401}; 402 403static const struct qcom_reset_map gpu_cc_sm8750_resets[] = { 404 [GPU_CC_GPU_CC_XO_BCR] = { 0x9000 }, 405 [GPU_CC_GPU_CC_GX_BCR] = { 0x905c }, 406 [GPU_CC_GPU_CC_CX_BCR] = { 0x907c }, 407 [GPU_CC_GPU_CC_GMU_BCR] = { 0x9314 }, 408 [GPU_CC_GPU_CC_CB_BCR] = { 0x93a0 }, 409 [GPU_CC_GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, 410}; 411 412static const struct regmap_config gpu_cc_sm8750_regmap_config = { 413 .reg_bits = 32, 414 .reg_stride = 4, 415 .val_bits = 32, 416 .max_register = 0x9800, 417 .fast_io = true, 418}; 419 420static struct clk_alpha_pll *gpu_cc_alpha_plls[] = { 421 &gpu_cc_pll0, 422}; 423 424static u32 gpu_cc_sm8750_critical_cbcrs[] = { 425 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */ 426 0x9008, /* GPU_CC_CXO_AON_CLK */ 427 0x9064, /* GPU_CC_GX_AHB_FF_CLK */ 428 0x90cc, /* GPU_CC_SLEEP_CLK */ 429 0x93a4, /* GPU_CC_CB_CLK */ 430 0x93a8, /* GPU_CC_RSCC_HUB_AON_CLK */ 431}; 432 433static struct qcom_cc_driver_data gpu_cc_sm8750_driver_data = { 434 .alpha_plls = gpu_cc_alpha_plls, 435 .num_alpha_plls = ARRAY_SIZE(gpu_cc_alpha_plls), 436 .clk_cbcrs = gpu_cc_sm8750_critical_cbcrs, 437 .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_sm8750_critical_cbcrs), 438}; 439 440static const struct qcom_cc_desc gpu_cc_sm8750_desc = { 441 .config = &gpu_cc_sm8750_regmap_config, 442 .clks = gpu_cc_sm8750_clocks, 443 .num_clks = ARRAY_SIZE(gpu_cc_sm8750_clocks), 444 .resets = gpu_cc_sm8750_resets, 445 .num_resets = ARRAY_SIZE(gpu_cc_sm8750_resets), 446 .gdscs = gpu_cc_sm8750_gdscs, 447 .num_gdscs = ARRAY_SIZE(gpu_cc_sm8750_gdscs), 448 .use_rpm = true, 449 .driver_data = &gpu_cc_sm8750_driver_data, 450}; 451 452static const struct of_device_id gpu_cc_sm8750_match_table[] = { 453 { .compatible = "qcom,sm8750-gpucc" }, 454 { } 455}; 456MODULE_DEVICE_TABLE(of, gpu_cc_sm8750_match_table); 457 458static int gpu_cc_sm8750_probe(struct platform_device *pdev) 459{ 460 return qcom_cc_probe(pdev, &gpu_cc_sm8750_desc); 461} 462 463static struct platform_driver gpu_cc_sm8750_driver = { 464 .probe = gpu_cc_sm8750_probe, 465 .driver = { 466 .name = "sm8750-gpucc", 467 .of_match_table = gpu_cc_sm8750_match_table, 468 }, 469}; 470module_platform_driver(gpu_cc_sm8750_driver); 471 472MODULE_DESCRIPTION("QTI GPU_CC SM8750 Driver"); 473MODULE_LICENSE("GPL");