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.

clk: qcom: Add GPU clock controller driver for SM6125

Add support for the GPU clock controller found on SM6125.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Link: https://lore.kernel.org/r/20230208091340.124641-7-konrad.dybcio@linaro.org

authored by

Konrad Dybcio and committed by
Bjorn Andersson
a6b18286 b96fbb03

+434
+9
drivers/clk/qcom/Kconfig
··· 798 798 Say Y if you want to use peripheral devices such as UART, 799 799 SPI, I2C, USB, SD/UFS, PCIe etc. 800 800 801 + config SM_GPUCC_6125 802 + tristate "SM6125 Graphics Clock Controller" 803 + select SM_GCC_6125 804 + depends on ARM64 || COMPILE_TEST 805 + help 806 + Support for the graphics clock controller on SM6125 devices. 807 + Say Y if you want to support graphics controller devices and 808 + functionality such as 3D graphics. 809 + 801 810 config SM_GPUCC_6350 802 811 tristate "SM6350 Graphics Clock Controller" 803 812 select SM_GCC_6350
+1
drivers/clk/qcom/Makefile
··· 112 112 obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o 113 113 obj-$(CONFIG_SM_GCC_8450) += gcc-sm8450.o 114 114 obj-$(CONFIG_SM_GCC_8550) += gcc-sm8550.o 115 + obj-$(CONFIG_SM_GPUCC_6125) += gpucc-sm6125.o 115 116 obj-$(CONFIG_SM_GPUCC_6350) += gpucc-sm6350.o 116 117 obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o 117 118 obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o
+424
drivers/clk/qcom/gpucc-sm6125.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2019, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2023, Linaro Limited 5 + */ 6 + 7 + #include <linux/clk-provider.h> 8 + #include <linux/module.h> 9 + #include <linux/of_device.h> 10 + #include <linux/regmap.h> 11 + 12 + #include <dt-bindings/clock/qcom,sm6125-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 "clk-regmap-phy-mux.h" 21 + #include "gdsc.h" 22 + #include "reset.h" 23 + 24 + enum { 25 + DT_BI_TCXO, 26 + DT_GCC_GPU_GPLL0_CLK_SRC, 27 + }; 28 + 29 + enum { 30 + P_BI_TCXO, 31 + P_GPLL0_OUT_MAIN, 32 + P_GPU_CC_PLL0_2X_CLK, 33 + P_GPU_CC_PLL0_OUT_AUX2, 34 + P_GPU_CC_PLL1_OUT_AUX, 35 + P_GPU_CC_PLL1_OUT_AUX2, 36 + }; 37 + 38 + static struct pll_vco gpu_cc_pll_vco[] = { 39 + { 1000000000, 2000000000, 0 }, 40 + { 500000000, 1000000000, 2 }, 41 + }; 42 + 43 + /* 1020MHz configuration */ 44 + static const struct alpha_pll_config gpu_pll0_config = { 45 + .l = 0x35, 46 + .config_ctl_val = 0x4001055b, 47 + .alpha_hi = 0x20, 48 + .alpha = 0x00, 49 + .alpha_en_mask = BIT(24), 50 + .vco_val = 0x0 << 20, 51 + .vco_mask = 0x3 << 20, 52 + .aux2_output_mask = BIT(2), 53 + }; 54 + 55 + /* 930MHz configuration */ 56 + static const struct alpha_pll_config gpu_pll1_config = { 57 + .l = 0x30, 58 + .config_ctl_val = 0x4001055b, 59 + .alpha_hi = 0x70, 60 + .alpha = 0x00, 61 + .alpha_en_mask = BIT(24), 62 + .vco_val = 0x2 << 20, 63 + .vco_mask = 0x3 << 20, 64 + .aux2_output_mask = BIT(2), 65 + }; 66 + 67 + static struct clk_alpha_pll gpu_cc_pll0_out_aux2 = { 68 + .offset = 0x0, 69 + .vco_table = gpu_cc_pll_vco, 70 + .num_vco = ARRAY_SIZE(gpu_cc_pll_vco), 71 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], 72 + .flags = SUPPORTS_DYNAMIC_UPDATE, 73 + .clkr = { 74 + .hw.init = &(struct clk_init_data){ 75 + .name = "gpu_cc_pll0_out_aux2", 76 + .parent_data = &(const struct clk_parent_data) { 77 + .index = DT_BI_TCXO, 78 + }, 79 + .num_parents = 1, 80 + .ops = &clk_alpha_pll_ops, 81 + }, 82 + }, 83 + }; 84 + 85 + static struct clk_alpha_pll gpu_cc_pll1_out_aux2 = { 86 + .offset = 0x100, 87 + .vco_table = gpu_cc_pll_vco, 88 + .num_vco = ARRAY_SIZE(gpu_cc_pll_vco), 89 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], 90 + .flags = SUPPORTS_DYNAMIC_UPDATE, 91 + .clkr = { 92 + .hw.init = &(struct clk_init_data){ 93 + .name = "gpu_cc_pll1_out_aux2", 94 + .parent_data = &(const struct clk_parent_data) { 95 + .index = DT_BI_TCXO, 96 + }, 97 + .num_parents = 1, 98 + .ops = &clk_alpha_pll_ops, 99 + }, 100 + }, 101 + }; 102 + 103 + static const struct parent_map gpu_cc_parent_map_0[] = { 104 + { P_BI_TCXO, 0 }, 105 + { P_GPLL0_OUT_MAIN, 5 }, 106 + }; 107 + 108 + static const struct clk_parent_data gpu_cc_parent_data_0[] = { 109 + { .index = DT_BI_TCXO }, 110 + { .index = DT_GCC_GPU_GPLL0_CLK_SRC }, 111 + }; 112 + 113 + static const struct parent_map gpu_cc_parent_map_1[] = { 114 + { P_BI_TCXO, 0 }, 115 + { P_GPU_CC_PLL0_OUT_AUX2, 2 }, 116 + { P_GPU_CC_PLL1_OUT_AUX2, 4 }, 117 + }; 118 + 119 + static const struct clk_parent_data gpu_cc_parent_data_1[] = { 120 + { .index = DT_BI_TCXO }, 121 + { .hw = &gpu_cc_pll0_out_aux2.clkr.hw }, 122 + { .hw = &gpu_cc_pll1_out_aux2.clkr.hw }, 123 + }; 124 + 125 + static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 126 + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 127 + { } 128 + }; 129 + 130 + static struct clk_rcg2 gpu_cc_gmu_clk_src = { 131 + .cmd_rcgr = 0x1120, 132 + .mnd_width = 0, 133 + .hid_width = 5, 134 + .parent_map = gpu_cc_parent_map_0, 135 + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 136 + .clkr.hw.init = &(struct clk_init_data){ 137 + .name = "gpu_cc_gmu_clk_src", 138 + .parent_data = gpu_cc_parent_data_0, 139 + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), 140 + .ops = &clk_rcg2_shared_ops, 141 + }, 142 + }; 143 + 144 + static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = { 145 + F(320000000, P_GPU_CC_PLL1_OUT_AUX2, 2, 0, 0), 146 + F(465000000, P_GPU_CC_PLL1_OUT_AUX2, 2, 0, 0), 147 + F(600000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), 148 + F(745000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), 149 + F(820000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), 150 + F(900000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), 151 + F(950000000, P_GPU_CC_PLL0_OUT_AUX2, 2, 0, 0), 152 + { } 153 + }; 154 + 155 + static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { 156 + .cmd_rcgr = 0x101c, 157 + .mnd_width = 0, 158 + .hid_width = 5, 159 + .parent_map = gpu_cc_parent_map_1, 160 + .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src, 161 + .clkr.hw.init = &(struct clk_init_data){ 162 + .name = "gpu_cc_gx_gfx3d_clk_src", 163 + .parent_data = gpu_cc_parent_data_1, 164 + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), 165 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 166 + .ops = &clk_rcg2_ops, 167 + }, 168 + }; 169 + 170 + static struct clk_branch gpu_cc_crc_ahb_clk = { 171 + .halt_reg = 0x107c, 172 + .halt_check = BRANCH_HALT_DELAY, 173 + .clkr = { 174 + .enable_reg = 0x107c, 175 + .enable_mask = BIT(0), 176 + .hw.init = &(struct clk_init_data){ 177 + .name = "gpu_cc_crc_ahb_clk", 178 + .ops = &clk_branch2_ops, 179 + }, 180 + }, 181 + }; 182 + 183 + static struct clk_branch gpu_cc_cx_apb_clk = { 184 + .halt_reg = 0x1088, 185 + .halt_check = BRANCH_HALT_DELAY, 186 + .clkr = { 187 + .enable_reg = 0x1088, 188 + .enable_mask = BIT(0), 189 + .hw.init = &(struct clk_init_data){ 190 + .name = "gpu_cc_cx_apb_clk", 191 + .ops = &clk_branch2_ops, 192 + }, 193 + }, 194 + }; 195 + 196 + static struct clk_branch gpu_cc_gx_gfx3d_clk = { 197 + .halt_reg = 0x1054, 198 + .halt_check = BRANCH_HALT_SKIP, 199 + .clkr = { 200 + .enable_reg = 0x1054, 201 + .enable_mask = BIT(0), 202 + .hw.init = &(struct clk_init_data){ 203 + .name = "gpu_cc_gx_gfx3d_clk", 204 + .parent_hws = (const struct clk_hw*[]) { 205 + &gpu_cc_gx_gfx3d_clk_src.clkr.hw, 206 + }, 207 + .num_parents = 1, 208 + .flags = CLK_SET_RATE_PARENT, 209 + .ops = &clk_branch2_ops, 210 + }, 211 + }, 212 + }; 213 + 214 + static struct clk_branch gpu_cc_cx_gfx3d_clk = { 215 + .halt_reg = 0x10a4, 216 + .halt_check = BRANCH_HALT_DELAY, 217 + .clkr = { 218 + .enable_reg = 0x10a4, 219 + .enable_mask = BIT(0), 220 + .hw.init = &(struct clk_init_data){ 221 + .name = "gpu_cc_cx_gfx3d_clk", 222 + .parent_hws = (const struct clk_hw*[]) { 223 + &gpu_cc_gx_gfx3d_clk.clkr.hw, 224 + }, 225 + .num_parents = 1, 226 + .flags = CLK_SET_RATE_PARENT, 227 + .ops = &clk_branch2_ops, 228 + }, 229 + }, 230 + }; 231 + 232 + static struct clk_branch gpu_cc_cx_gmu_clk = { 233 + .halt_reg = 0x1098, 234 + .halt_check = BRANCH_HALT, 235 + .clkr = { 236 + .enable_reg = 0x1098, 237 + .enable_mask = BIT(0), 238 + .hw.init = &(struct clk_init_data){ 239 + .name = "gpu_cc_cx_gmu_clk", 240 + .parent_hws = (const struct clk_hw*[]) { 241 + &gpu_cc_gmu_clk_src.clkr.hw, 242 + }, 243 + .num_parents = 1, 244 + .flags = CLK_SET_RATE_PARENT, 245 + .ops = &clk_branch2_ops, 246 + }, 247 + }, 248 + }; 249 + 250 + static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { 251 + .halt_reg = 0x108c, 252 + .halt_check = BRANCH_HALT_DELAY, 253 + .clkr = { 254 + .enable_reg = 0x108c, 255 + .enable_mask = BIT(0), 256 + .hw.init = &(struct clk_init_data){ 257 + .name = "gpu_cc_cx_snoc_dvm_clk", 258 + .ops = &clk_branch2_ops, 259 + }, 260 + }, 261 + }; 262 + 263 + static struct clk_branch gpu_cc_cxo_aon_clk = { 264 + .halt_reg = 0x1004, 265 + .halt_check = BRANCH_HALT_DELAY, 266 + .clkr = { 267 + .enable_reg = 0x1004, 268 + .enable_mask = BIT(0), 269 + .hw.init = &(struct clk_init_data){ 270 + .name = "gpu_cc_cxo_aon_clk", 271 + .ops = &clk_branch2_ops, 272 + }, 273 + }, 274 + }; 275 + 276 + static struct clk_branch gpu_cc_cxo_clk = { 277 + .halt_reg = 0x109c, 278 + .halt_check = BRANCH_HALT, 279 + .clkr = { 280 + .enable_reg = 0x109c, 281 + .enable_mask = BIT(0), 282 + .hw.init = &(struct clk_init_data){ 283 + .name = "gpu_cc_cxo_clk", 284 + .ops = &clk_branch2_ops, 285 + }, 286 + }, 287 + }; 288 + 289 + static struct clk_branch gpu_cc_sleep_clk = { 290 + .halt_reg = 0x1090, 291 + .halt_check = BRANCH_HALT_DELAY, 292 + .clkr = { 293 + .enable_reg = 0x1090, 294 + .enable_mask = BIT(0), 295 + .hw.init = &(struct clk_init_data){ 296 + .name = "gpu_cc_sleep_clk", 297 + .ops = &clk_branch2_ops, 298 + }, 299 + }, 300 + }; 301 + 302 + static struct clk_branch gpu_cc_ahb_clk = { 303 + .halt_reg = 0x1078, 304 + .halt_check = BRANCH_HALT_DELAY, 305 + .clkr = { 306 + .enable_reg = 0x1078, 307 + .enable_mask = BIT(0), 308 + .hw.init = &(struct clk_init_data){ 309 + .name = "gpu_cc_ahb_clk", 310 + .flags = CLK_IS_CRITICAL, 311 + .ops = &clk_branch2_ops, 312 + }, 313 + }, 314 + }; 315 + 316 + static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { 317 + .halt_reg = 0x5000, 318 + .halt_check = BRANCH_VOTED, 319 + .clkr = { 320 + .enable_reg = 0x5000, 321 + .enable_mask = BIT(0), 322 + .hw.init = &(struct clk_init_data){ 323 + .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", 324 + .ops = &clk_branch2_ops, 325 + }, 326 + }, 327 + }; 328 + 329 + static struct gdsc gpu_cx_gdsc = { 330 + .gdscr = 0x106c, 331 + .gds_hw_ctrl = 0x1540, 332 + .pd = { 333 + .name = "gpu_cx_gdsc", 334 + }, 335 + .pwrsts = PWRSTS_OFF_ON, 336 + .flags = VOTABLE, 337 + }; 338 + 339 + static struct gdsc gpu_gx_gdsc = { 340 + .gdscr = 0x100c, 341 + .pd = { 342 + .name = "gpu_gx_gdsc", 343 + }, 344 + .pwrsts = PWRSTS_OFF_ON, 345 + .flags = VOTABLE, 346 + }; 347 + 348 + static struct clk_regmap *gpu_cc_sm6125_clocks[] = { 349 + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, 350 + [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr, 351 + [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr, 352 + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 353 + [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, 354 + [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, 355 + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 356 + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 357 + [GPU_CC_PLL0_OUT_AUX2] = &gpu_cc_pll0_out_aux2.clkr, 358 + [GPU_CC_PLL1_OUT_AUX2] = &gpu_cc_pll1_out_aux2.clkr, 359 + [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, 360 + [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr, 361 + [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr, 362 + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, 363 + [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, 364 + }; 365 + 366 + static struct gdsc *gpucc_sm6125_gdscs[] = { 367 + [GPU_CX_GDSC] = &gpu_cx_gdsc, 368 + [GPU_GX_GDSC] = &gpu_gx_gdsc, 369 + }; 370 + 371 + static const struct regmap_config gpu_cc_sm6125_regmap_config = { 372 + .reg_bits = 32, 373 + .reg_stride = 4, 374 + .val_bits = 32, 375 + .max_register = 0x9000, 376 + .fast_io = true, 377 + }; 378 + 379 + static const struct qcom_cc_desc gpu_cc_sm6125_desc = { 380 + .config = &gpu_cc_sm6125_regmap_config, 381 + .clks = gpu_cc_sm6125_clocks, 382 + .num_clks = ARRAY_SIZE(gpu_cc_sm6125_clocks), 383 + .gdscs = gpucc_sm6125_gdscs, 384 + .num_gdscs = ARRAY_SIZE(gpucc_sm6125_gdscs), 385 + }; 386 + 387 + static const struct of_device_id gpu_cc_sm6125_match_table[] = { 388 + { .compatible = "qcom,sm6125-gpucc" }, 389 + { } 390 + }; 391 + MODULE_DEVICE_TABLE(of, gpu_cc_sm6125_match_table); 392 + 393 + static int gpu_cc_sm6125_probe(struct platform_device *pdev) 394 + { 395 + struct regmap *regmap; 396 + 397 + regmap = qcom_cc_map(pdev, &gpu_cc_sm6125_desc); 398 + if (IS_ERR(regmap)) 399 + return PTR_ERR(regmap); 400 + 401 + clk_alpha_pll_configure(&gpu_cc_pll0_out_aux2, regmap, &gpu_pll0_config); 402 + clk_alpha_pll_configure(&gpu_cc_pll1_out_aux2, regmap, &gpu_pll1_config); 403 + 404 + /* Set recommended WAKEUP/SLEEP settings for the gpu_cc_cx_gmu_clk */ 405 + qcom_branch_set_wakeup(regmap, gpu_cc_cx_gmu_clk, 0xf); 406 + qcom_branch_set_sleep(regmap, gpu_cc_cx_gmu_clk, 0xf); 407 + 408 + qcom_branch_set_force_mem_core(regmap, gpu_cc_gx_gfx3d_clk, true); 409 + qcom_branch_set_force_periph_on(regmap, gpu_cc_gx_gfx3d_clk, true); 410 + 411 + return qcom_cc_really_probe(pdev, &gpu_cc_sm6125_desc, regmap); 412 + } 413 + 414 + static struct platform_driver gpu_cc_sm6125_driver = { 415 + .probe = gpu_cc_sm6125_probe, 416 + .driver = { 417 + .name = "gpucc-sm6125", 418 + .of_match_table = gpu_cc_sm6125_match_table, 419 + }, 420 + }; 421 + module_platform_driver(gpu_cc_sm6125_driver); 422 + 423 + MODULE_DESCRIPTION("QTI GPUCC SM6125 Driver"); 424 + MODULE_LICENSE("GPL");