1*f4b5b408STaniya Das // SPDX-License-Identifier: GPL-2.0-only 2*f4b5b408STaniya Das /* 3*f4b5b408STaniya Das * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. 4*f4b5b408STaniya Das */ 5*f4b5b408STaniya Das 6*f4b5b408STaniya Das #include <linux/clk-provider.h> 7*f4b5b408STaniya Das #include <linux/module.h> 8*f4b5b408STaniya Das #include <linux/mod_devicetable.h> 9*f4b5b408STaniya Das #include <linux/of.h> 10*f4b5b408STaniya Das #include <linux/platform_device.h> 11*f4b5b408STaniya Das #include <linux/regmap.h> 12*f4b5b408STaniya Das 13*f4b5b408STaniya Das #include <dt-bindings/clock/qcom,qcs615-gpucc.h> 14*f4b5b408STaniya Das 15*f4b5b408STaniya Das #include "clk-alpha-pll.h" 16*f4b5b408STaniya Das #include "clk-branch.h" 17*f4b5b408STaniya Das #include "clk-pll.h" 18*f4b5b408STaniya Das #include "clk-rcg.h" 19*f4b5b408STaniya Das #include "clk-regmap.h" 20*f4b5b408STaniya Das #include "clk-regmap-divider.h" 21*f4b5b408STaniya Das #include "clk-regmap-mux.h" 22*f4b5b408STaniya Das #include "common.h" 23*f4b5b408STaniya Das #include "gdsc.h" 24*f4b5b408STaniya Das #include "reset.h" 25*f4b5b408STaniya Das 26*f4b5b408STaniya Das enum { 27*f4b5b408STaniya Das DT_BI_TCXO, 28*f4b5b408STaniya Das DT_GPLL0_OUT_MAIN, 29*f4b5b408STaniya Das DT_GPLL0_OUT_MAIN_DIV, 30*f4b5b408STaniya Das }; 31*f4b5b408STaniya Das 32*f4b5b408STaniya Das enum { 33*f4b5b408STaniya Das P_BI_TCXO, 34*f4b5b408STaniya Das P_GPLL0_OUT_MAIN, 35*f4b5b408STaniya Das P_GPLL0_OUT_MAIN_DIV, 36*f4b5b408STaniya Das P_GPU_CC_PLL0_2X_CLK, 37*f4b5b408STaniya Das P_CRC_DIV_PLL0_OUT_AUX2, 38*f4b5b408STaniya Das P_GPU_CC_PLL0_OUT_MAIN, 39*f4b5b408STaniya Das P_GPU_CC_PLL1_OUT_AUX, 40*f4b5b408STaniya Das P_CRC_DIV_PLL1_OUT_AUX2, 41*f4b5b408STaniya Das P_GPU_CC_PLL1_OUT_MAIN, 42*f4b5b408STaniya Das }; 43*f4b5b408STaniya Das 44*f4b5b408STaniya Das static const struct pll_vco gpu_cc_pll0_vco[] = { 45*f4b5b408STaniya Das { 1000000000, 2100000000, 0 }, 46*f4b5b408STaniya Das }; 47*f4b5b408STaniya Das 48*f4b5b408STaniya Das static struct pll_vco gpu_cc_pll1_vco[] = { 49*f4b5b408STaniya Das { 500000000, 1000000000, 2 }, 50*f4b5b408STaniya Das }; 51*f4b5b408STaniya Das 52*f4b5b408STaniya Das /* 1020MHz configuration VCO - 0 */ 53*f4b5b408STaniya Das static struct alpha_pll_config gpu_cc_pll0_config = { 54*f4b5b408STaniya Das .l = 0x35, 55*f4b5b408STaniya Das .config_ctl_val = 0x4001055b, 56*f4b5b408STaniya Das .test_ctl_hi_val = 0x1, 57*f4b5b408STaniya Das .test_ctl_hi_mask = 0x1, 58*f4b5b408STaniya Das .alpha_hi = 0x20, 59*f4b5b408STaniya Das .alpha = 0x00, 60*f4b5b408STaniya Das .alpha_en_mask = BIT(24), 61*f4b5b408STaniya Das .vco_val = 0x0, 62*f4b5b408STaniya Das .vco_mask = GENMASK(21, 20), 63*f4b5b408STaniya Das .aux2_output_mask = BIT(2), 64*f4b5b408STaniya Das }; 65*f4b5b408STaniya Das 66*f4b5b408STaniya Das static struct clk_alpha_pll gpu_cc_pll0 = { 67*f4b5b408STaniya Das .offset = 0x0, 68*f4b5b408STaniya Das .config = &gpu_cc_pll0_config, 69*f4b5b408STaniya Das .vco_table = gpu_cc_pll0_vco, 70*f4b5b408STaniya Das .num_vco = ARRAY_SIZE(gpu_cc_pll0_vco), 71*f4b5b408STaniya Das .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], 72*f4b5b408STaniya Das .clkr = { 73*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 74*f4b5b408STaniya Das .name = "gpu_cc_pll0", 75*f4b5b408STaniya Das .parent_data = &(const struct clk_parent_data) { 76*f4b5b408STaniya Das .index = DT_BI_TCXO, 77*f4b5b408STaniya Das }, 78*f4b5b408STaniya Das .num_parents = 1, 79*f4b5b408STaniya Das .ops = &clk_alpha_pll_slew_ops, 80*f4b5b408STaniya Das }, 81*f4b5b408STaniya Das }, 82*f4b5b408STaniya Das }; 83*f4b5b408STaniya Das 84*f4b5b408STaniya Das /* 930MHz configuration VCO - 2 */ 85*f4b5b408STaniya Das static struct alpha_pll_config gpu_cc_pll1_config = { 86*f4b5b408STaniya Das .l = 0x30, 87*f4b5b408STaniya Das .config_ctl_val = 0x4001055b, 88*f4b5b408STaniya Das .test_ctl_hi_val = 0x1, 89*f4b5b408STaniya Das .test_ctl_hi_mask = 0x1, 90*f4b5b408STaniya Das .alpha_hi = 0x70, 91*f4b5b408STaniya Das .alpha = 0x00, 92*f4b5b408STaniya Das .alpha_en_mask = BIT(24), 93*f4b5b408STaniya Das .vco_val = BIT(21), 94*f4b5b408STaniya Das .vco_mask = GENMASK(21, 20), 95*f4b5b408STaniya Das .aux2_output_mask = BIT(2), 96*f4b5b408STaniya Das }; 97*f4b5b408STaniya Das 98*f4b5b408STaniya Das static struct clk_alpha_pll gpu_cc_pll1 = { 99*f4b5b408STaniya Das .offset = 0x100, 100*f4b5b408STaniya Das .config = &gpu_cc_pll1_config, 101*f4b5b408STaniya Das .vco_table = gpu_cc_pll1_vco, 102*f4b5b408STaniya Das .num_vco = ARRAY_SIZE(gpu_cc_pll1_vco), 103*f4b5b408STaniya Das .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], 104*f4b5b408STaniya Das .clkr = { 105*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 106*f4b5b408STaniya Das .name = "gpu_cc_pll1", 107*f4b5b408STaniya Das .parent_data = &(const struct clk_parent_data) { 108*f4b5b408STaniya Das .index = DT_BI_TCXO, 109*f4b5b408STaniya Das }, 110*f4b5b408STaniya Das .num_parents = 1, 111*f4b5b408STaniya Das .ops = &clk_alpha_pll_slew_ops, 112*f4b5b408STaniya Das }, 113*f4b5b408STaniya Das } 114*f4b5b408STaniya Das }; 115*f4b5b408STaniya Das 116*f4b5b408STaniya Das /* Clock Ramp Controller */ 117*f4b5b408STaniya Das static struct clk_fixed_factor crc_div_pll0 = { 118*f4b5b408STaniya Das .mult = 1, 119*f4b5b408STaniya Das .div = 2, 120*f4b5b408STaniya Das .hw.init = &(struct clk_init_data){ 121*f4b5b408STaniya Das .name = "crc_div_pll0", 122*f4b5b408STaniya Das .parent_data = &(const struct clk_parent_data){ 123*f4b5b408STaniya Das .hw = &gpu_cc_pll0.clkr.hw, 124*f4b5b408STaniya Das }, 125*f4b5b408STaniya Das .num_parents = 1, 126*f4b5b408STaniya Das .flags = CLK_SET_RATE_PARENT, 127*f4b5b408STaniya Das .ops = &clk_fixed_factor_ops, 128*f4b5b408STaniya Das }, 129*f4b5b408STaniya Das }; 130*f4b5b408STaniya Das 131*f4b5b408STaniya Das /* Clock Ramp Controller */ 132*f4b5b408STaniya Das static struct clk_fixed_factor crc_div_pll1 = { 133*f4b5b408STaniya Das .mult = 1, 134*f4b5b408STaniya Das .div = 2, 135*f4b5b408STaniya Das .hw.init = &(struct clk_init_data){ 136*f4b5b408STaniya Das .name = "crc_div_pll1", 137*f4b5b408STaniya Das .parent_data = &(const struct clk_parent_data){ 138*f4b5b408STaniya Das .hw = &gpu_cc_pll1.clkr.hw, 139*f4b5b408STaniya Das }, 140*f4b5b408STaniya Das .num_parents = 1, 141*f4b5b408STaniya Das .flags = CLK_SET_RATE_PARENT, 142*f4b5b408STaniya Das .ops = &clk_fixed_factor_ops, 143*f4b5b408STaniya Das }, 144*f4b5b408STaniya Das }; 145*f4b5b408STaniya Das 146*f4b5b408STaniya Das static const struct parent_map gpu_cc_parent_map_0[] = { 147*f4b5b408STaniya Das { P_BI_TCXO, 0 }, 148*f4b5b408STaniya Das { P_GPU_CC_PLL0_OUT_MAIN, 1 }, 149*f4b5b408STaniya Das { P_GPU_CC_PLL1_OUT_MAIN, 3 }, 150*f4b5b408STaniya Das { P_GPLL0_OUT_MAIN, 5 }, 151*f4b5b408STaniya Das { P_GPLL0_OUT_MAIN_DIV, 6 }, 152*f4b5b408STaniya Das }; 153*f4b5b408STaniya Das 154*f4b5b408STaniya Das static const struct clk_parent_data gpu_cc_parent_data_0[] = { 155*f4b5b408STaniya Das { .index = DT_BI_TCXO }, 156*f4b5b408STaniya Das { .hw = &gpu_cc_pll0.clkr.hw }, 157*f4b5b408STaniya Das { .hw = &gpu_cc_pll1.clkr.hw }, 158*f4b5b408STaniya Das { .index = DT_GPLL0_OUT_MAIN }, 159*f4b5b408STaniya Das { .index = DT_GPLL0_OUT_MAIN_DIV }, 160*f4b5b408STaniya Das }; 161*f4b5b408STaniya Das 162*f4b5b408STaniya Das static const struct parent_map gpu_cc_parent_map_1[] = { 163*f4b5b408STaniya Das { P_BI_TCXO, 0 }, 164*f4b5b408STaniya Das { P_GPU_CC_PLL0_2X_CLK, 1 }, 165*f4b5b408STaniya Das { P_CRC_DIV_PLL0_OUT_AUX2, 2 }, 166*f4b5b408STaniya Das { P_GPU_CC_PLL1_OUT_AUX, 3 }, 167*f4b5b408STaniya Das { P_CRC_DIV_PLL1_OUT_AUX2, 4 }, 168*f4b5b408STaniya Das { P_GPLL0_OUT_MAIN, 5 }, 169*f4b5b408STaniya Das }; 170*f4b5b408STaniya Das 171*f4b5b408STaniya Das static const struct clk_parent_data gpu_cc_parent_data_1[] = { 172*f4b5b408STaniya Das { .index = DT_BI_TCXO }, 173*f4b5b408STaniya Das { .hw = &gpu_cc_pll0.clkr.hw }, 174*f4b5b408STaniya Das { .hw = &crc_div_pll0.hw }, 175*f4b5b408STaniya Das { .hw = &gpu_cc_pll1.clkr.hw }, 176*f4b5b408STaniya Das { .hw = &crc_div_pll1.hw }, 177*f4b5b408STaniya Das { .index = DT_GPLL0_OUT_MAIN }, 178*f4b5b408STaniya Das }; 179*f4b5b408STaniya Das 180*f4b5b408STaniya Das static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 181*f4b5b408STaniya Das F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 182*f4b5b408STaniya Das { } 183*f4b5b408STaniya Das }; 184*f4b5b408STaniya Das 185*f4b5b408STaniya Das static struct clk_rcg2 gpu_cc_gmu_clk_src = { 186*f4b5b408STaniya Das .cmd_rcgr = 0x1120, 187*f4b5b408STaniya Das .mnd_width = 0, 188*f4b5b408STaniya Das .hid_width = 5, 189*f4b5b408STaniya Das .parent_map = gpu_cc_parent_map_0, 190*f4b5b408STaniya Das .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 191*f4b5b408STaniya Das .clkr.hw.init = &(const struct clk_init_data) { 192*f4b5b408STaniya Das .name = "gpu_cc_gmu_clk_src", 193*f4b5b408STaniya Das .parent_data = gpu_cc_parent_data_0, 194*f4b5b408STaniya Das .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), 195*f4b5b408STaniya Das .ops = &clk_rcg2_shared_ops, 196*f4b5b408STaniya Das }, 197*f4b5b408STaniya Das }; 198*f4b5b408STaniya Das 199*f4b5b408STaniya Das static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = { 200*f4b5b408STaniya Das F(290000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0), 201*f4b5b408STaniya Das F(350000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0), 202*f4b5b408STaniya Das F(435000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0), 203*f4b5b408STaniya Das F(500000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0), 204*f4b5b408STaniya Das F(550000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0), 205*f4b5b408STaniya Das F(650000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0), 206*f4b5b408STaniya Das F(700000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0), 207*f4b5b408STaniya Das F(745000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0), 208*f4b5b408STaniya Das F(845000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0), 209*f4b5b408STaniya Das F(895000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0), 210*f4b5b408STaniya Das { } 211*f4b5b408STaniya Das }; 212*f4b5b408STaniya Das 213*f4b5b408STaniya Das static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { 214*f4b5b408STaniya Das .cmd_rcgr = 0x101c, 215*f4b5b408STaniya Das .mnd_width = 0, 216*f4b5b408STaniya Das .hid_width = 5, 217*f4b5b408STaniya Das .parent_map = gpu_cc_parent_map_1, 218*f4b5b408STaniya Das .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src, 219*f4b5b408STaniya Das .clkr.hw.init = &(const struct clk_init_data) { 220*f4b5b408STaniya Das .name = "gpu_cc_gx_gfx3d_clk_src", 221*f4b5b408STaniya Das .parent_data = gpu_cc_parent_data_1, 222*f4b5b408STaniya Das .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), 223*f4b5b408STaniya Das .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 224*f4b5b408STaniya Das .ops = &clk_rcg2_shared_ops, 225*f4b5b408STaniya Das }, 226*f4b5b408STaniya Das }; 227*f4b5b408STaniya Das 228*f4b5b408STaniya Das static struct clk_branch gpu_cc_crc_ahb_clk = { 229*f4b5b408STaniya Das .halt_reg = 0x107c, 230*f4b5b408STaniya Das .halt_check = BRANCH_HALT_VOTED, 231*f4b5b408STaniya Das .clkr = { 232*f4b5b408STaniya Das .enable_reg = 0x107c, 233*f4b5b408STaniya Das .enable_mask = BIT(0), 234*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 235*f4b5b408STaniya Das .name = "gpu_cc_crc_ahb_clk", 236*f4b5b408STaniya Das .ops = &clk_branch2_ops, 237*f4b5b408STaniya Das }, 238*f4b5b408STaniya Das }, 239*f4b5b408STaniya Das }; 240*f4b5b408STaniya Das 241*f4b5b408STaniya Das static struct clk_branch gpu_cc_cx_gfx3d_clk = { 242*f4b5b408STaniya Das .halt_reg = 0x10a4, 243*f4b5b408STaniya Das .halt_check = BRANCH_HALT_DELAY, 244*f4b5b408STaniya Das .clkr = { 245*f4b5b408STaniya Das .enable_reg = 0x10a4, 246*f4b5b408STaniya Das .enable_mask = BIT(0), 247*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 248*f4b5b408STaniya Das .name = "gpu_cc_cx_gfx3d_clk", 249*f4b5b408STaniya Das .parent_hws = (const struct clk_hw*[]) { 250*f4b5b408STaniya Das &gpu_cc_gx_gfx3d_clk_src.clkr.hw, 251*f4b5b408STaniya Das }, 252*f4b5b408STaniya Das .num_parents = 1, 253*f4b5b408STaniya Das .flags = CLK_SET_RATE_PARENT, 254*f4b5b408STaniya Das .ops = &clk_branch2_ops, 255*f4b5b408STaniya Das }, 256*f4b5b408STaniya Das }, 257*f4b5b408STaniya Das }; 258*f4b5b408STaniya Das 259*f4b5b408STaniya Das static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = { 260*f4b5b408STaniya Das .halt_reg = 0x10a8, 261*f4b5b408STaniya Das .halt_check = BRANCH_HALT_DELAY, 262*f4b5b408STaniya Das .clkr = { 263*f4b5b408STaniya Das .enable_reg = 0x10a8, 264*f4b5b408STaniya Das .enable_mask = BIT(0), 265*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 266*f4b5b408STaniya Das .name = "gpu_cc_cx_gfx3d_slv_clk", 267*f4b5b408STaniya Das .parent_hws = (const struct clk_hw*[]) { 268*f4b5b408STaniya Das &gpu_cc_gx_gfx3d_clk_src.clkr.hw, 269*f4b5b408STaniya Das }, 270*f4b5b408STaniya Das .num_parents = 1, 271*f4b5b408STaniya Das .flags = CLK_SET_RATE_PARENT, 272*f4b5b408STaniya Das .ops = &clk_branch2_ops, 273*f4b5b408STaniya Das }, 274*f4b5b408STaniya Das }, 275*f4b5b408STaniya Das }; 276*f4b5b408STaniya Das 277*f4b5b408STaniya Das static struct clk_branch gpu_cc_cx_gmu_clk = { 278*f4b5b408STaniya Das .halt_reg = 0x1098, 279*f4b5b408STaniya Das .halt_check = BRANCH_HALT, 280*f4b5b408STaniya Das .clkr = { 281*f4b5b408STaniya Das .enable_reg = 0x1098, 282*f4b5b408STaniya Das .enable_mask = BIT(0), 283*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 284*f4b5b408STaniya Das .name = "gpu_cc_cx_gmu_clk", 285*f4b5b408STaniya Das .parent_hws = (const struct clk_hw*[]) { 286*f4b5b408STaniya Das &gpu_cc_gmu_clk_src.clkr.hw, 287*f4b5b408STaniya Das }, 288*f4b5b408STaniya Das .num_parents = 1, 289*f4b5b408STaniya Das .flags = CLK_SET_RATE_PARENT, 290*f4b5b408STaniya Das .ops = &clk_branch2_ops, 291*f4b5b408STaniya Das }, 292*f4b5b408STaniya Das }, 293*f4b5b408STaniya Das }; 294*f4b5b408STaniya Das 295*f4b5b408STaniya Das static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { 296*f4b5b408STaniya Das .halt_reg = 0x108c, 297*f4b5b408STaniya Das .halt_check = BRANCH_HALT_VOTED, 298*f4b5b408STaniya Das .clkr = { 299*f4b5b408STaniya Das .enable_reg = 0x108c, 300*f4b5b408STaniya Das .enable_mask = BIT(0), 301*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 302*f4b5b408STaniya Das .name = "gpu_cc_cx_snoc_dvm_clk", 303*f4b5b408STaniya Das .ops = &clk_branch2_ops, 304*f4b5b408STaniya Das }, 305*f4b5b408STaniya Das }, 306*f4b5b408STaniya Das }; 307*f4b5b408STaniya Das 308*f4b5b408STaniya Das static struct clk_branch gpu_cc_cxo_aon_clk = { 309*f4b5b408STaniya Das .halt_reg = 0x1004, 310*f4b5b408STaniya Das .halt_check = BRANCH_HALT_VOTED, 311*f4b5b408STaniya Das .clkr = { 312*f4b5b408STaniya Das .enable_reg = 0x1004, 313*f4b5b408STaniya Das .enable_mask = BIT(0), 314*f4b5b408STaniya Das .hw.init = &(struct clk_init_data){ 315*f4b5b408STaniya Das .name = "gpu_cc_cxo_aon_clk", 316*f4b5b408STaniya Das .ops = &clk_branch2_ops, 317*f4b5b408STaniya Das }, 318*f4b5b408STaniya Das }, 319*f4b5b408STaniya Das }; 320*f4b5b408STaniya Das 321*f4b5b408STaniya Das static struct clk_branch gpu_cc_cxo_clk = { 322*f4b5b408STaniya Das .halt_reg = 0x109c, 323*f4b5b408STaniya Das .halt_check = BRANCH_HALT, 324*f4b5b408STaniya Das .clkr = { 325*f4b5b408STaniya Das .enable_reg = 0x109c, 326*f4b5b408STaniya Das .enable_mask = BIT(0), 327*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 328*f4b5b408STaniya Das .name = "gpu_cc_cxo_clk", 329*f4b5b408STaniya Das .ops = &clk_branch2_ops, 330*f4b5b408STaniya Das }, 331*f4b5b408STaniya Das }, 332*f4b5b408STaniya Das }; 333*f4b5b408STaniya Das 334*f4b5b408STaniya Das static struct clk_branch gpu_cc_gx_gfx3d_clk = { 335*f4b5b408STaniya Das .halt_reg = 0x1054, 336*f4b5b408STaniya Das .halt_check = BRANCH_HALT_SKIP, 337*f4b5b408STaniya Das .clkr = { 338*f4b5b408STaniya Das .enable_reg = 0x1054, 339*f4b5b408STaniya Das .enable_mask = BIT(0), 340*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 341*f4b5b408STaniya Das .name = "gpu_cc_gx_gfx3d_clk", 342*f4b5b408STaniya Das .parent_hws = (const struct clk_hw*[]) { 343*f4b5b408STaniya Das &gpu_cc_gx_gfx3d_clk_src.clkr.hw, 344*f4b5b408STaniya Das }, 345*f4b5b408STaniya Das .num_parents = 1, 346*f4b5b408STaniya Das .flags = CLK_SET_RATE_PARENT, 347*f4b5b408STaniya Das .ops = &clk_branch2_ops, 348*f4b5b408STaniya Das }, 349*f4b5b408STaniya Das }, 350*f4b5b408STaniya Das }; 351*f4b5b408STaniya Das 352*f4b5b408STaniya Das static struct clk_branch gpu_cc_gx_gmu_clk = { 353*f4b5b408STaniya Das .halt_reg = 0x1064, 354*f4b5b408STaniya Das .halt_check = BRANCH_HALT, 355*f4b5b408STaniya Das .clkr = { 356*f4b5b408STaniya Das .enable_reg = 0x1064, 357*f4b5b408STaniya Das .enable_mask = BIT(0), 358*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 359*f4b5b408STaniya Das .name = "gpu_cc_gx_gmu_clk", 360*f4b5b408STaniya Das .parent_hws = (const struct clk_hw*[]) { 361*f4b5b408STaniya Das &gpu_cc_gmu_clk_src.clkr.hw, 362*f4b5b408STaniya Das }, 363*f4b5b408STaniya Das .num_parents = 1, 364*f4b5b408STaniya Das .flags = CLK_SET_RATE_PARENT, 365*f4b5b408STaniya Das .ops = &clk_branch2_ops, 366*f4b5b408STaniya Das }, 367*f4b5b408STaniya Das }, 368*f4b5b408STaniya Das }; 369*f4b5b408STaniya Das 370*f4b5b408STaniya Das static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { 371*f4b5b408STaniya Das .halt_reg = 0x5000, 372*f4b5b408STaniya Das .halt_check = BRANCH_VOTED, 373*f4b5b408STaniya Das .clkr = { 374*f4b5b408STaniya Das .enable_reg = 0x5000, 375*f4b5b408STaniya Das .enable_mask = BIT(0), 376*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 377*f4b5b408STaniya Das .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", 378*f4b5b408STaniya Das .ops = &clk_branch2_ops, 379*f4b5b408STaniya Das }, 380*f4b5b408STaniya Das }, 381*f4b5b408STaniya Das }; 382*f4b5b408STaniya Das 383*f4b5b408STaniya Das static struct clk_branch gpu_cc_sleep_clk = { 384*f4b5b408STaniya Das .halt_reg = 0x1090, 385*f4b5b408STaniya Das .halt_check = BRANCH_HALT_VOTED, 386*f4b5b408STaniya Das .clkr = { 387*f4b5b408STaniya Das .enable_reg = 0x1090, 388*f4b5b408STaniya Das .enable_mask = BIT(0), 389*f4b5b408STaniya Das .hw.init = &(const struct clk_init_data) { 390*f4b5b408STaniya Das .name = "gpu_cc_sleep_clk", 391*f4b5b408STaniya Das .ops = &clk_branch2_ops, 392*f4b5b408STaniya Das }, 393*f4b5b408STaniya Das }, 394*f4b5b408STaniya Das }; 395*f4b5b408STaniya Das 396*f4b5b408STaniya Das static struct clk_hw *gpu_cc_qcs615_hws[] = { 397*f4b5b408STaniya Das [CRC_DIV_PLL0] = &crc_div_pll0.hw, 398*f4b5b408STaniya Das [CRC_DIV_PLL1] = &crc_div_pll1.hw, 399*f4b5b408STaniya Das }; 400*f4b5b408STaniya Das 401*f4b5b408STaniya Das static struct gdsc cx_gdsc = { 402*f4b5b408STaniya Das .gdscr = 0x106c, 403*f4b5b408STaniya Das .gds_hw_ctrl = 0x1540, 404*f4b5b408STaniya Das .en_rest_wait_val = 0x2, 405*f4b5b408STaniya Das .en_few_wait_val = 0x2, 406*f4b5b408STaniya Das .clk_dis_wait_val = 0x8, 407*f4b5b408STaniya Das .pd = { 408*f4b5b408STaniya Das .name = "cx_gdsc", 409*f4b5b408STaniya Das }, 410*f4b5b408STaniya Das .pwrsts = PWRSTS_OFF_ON, 411*f4b5b408STaniya Das .flags = POLL_CFG_GDSCR, 412*f4b5b408STaniya Das }; 413*f4b5b408STaniya Das 414*f4b5b408STaniya Das static struct gdsc gx_gdsc = { 415*f4b5b408STaniya Das .gdscr = 0x100c, 416*f4b5b408STaniya Das .en_rest_wait_val = 0x2, 417*f4b5b408STaniya Das .en_few_wait_val = 0x2, 418*f4b5b408STaniya Das .clk_dis_wait_val = 0x2, 419*f4b5b408STaniya Das .pd = { 420*f4b5b408STaniya Das .name = "gx_gdsc", 421*f4b5b408STaniya Das }, 422*f4b5b408STaniya Das .pwrsts = PWRSTS_OFF_ON, 423*f4b5b408STaniya Das .flags = POLL_CFG_GDSCR, 424*f4b5b408STaniya Das }; 425*f4b5b408STaniya Das 426*f4b5b408STaniya Das static struct clk_regmap *gpu_cc_qcs615_clocks[] = { 427*f4b5b408STaniya Das [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, 428*f4b5b408STaniya Das [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr, 429*f4b5b408STaniya Das [GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr, 430*f4b5b408STaniya Das [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 431*f4b5b408STaniya Das [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, 432*f4b5b408STaniya Das [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, 433*f4b5b408STaniya Das [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 434*f4b5b408STaniya Das [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 435*f4b5b408STaniya Das [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr, 436*f4b5b408STaniya Das [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr, 437*f4b5b408STaniya Das [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, 438*f4b5b408STaniya Das [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, 439*f4b5b408STaniya Das [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, 440*f4b5b408STaniya Das [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, 441*f4b5b408STaniya Das [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, 442*f4b5b408STaniya Das }; 443*f4b5b408STaniya Das 444*f4b5b408STaniya Das static struct gdsc *gpu_cc_qcs615_gdscs[] = { 445*f4b5b408STaniya Das [CX_GDSC] = &cx_gdsc, 446*f4b5b408STaniya Das [GX_GDSC] = &gx_gdsc, 447*f4b5b408STaniya Das }; 448*f4b5b408STaniya Das 449*f4b5b408STaniya Das static const struct qcom_reset_map gpu_cc_qcs615_resets[] = { 450*f4b5b408STaniya Das [GPU_CC_CX_BCR] = { 0x1068 }, 451*f4b5b408STaniya Das [GPU_CC_GFX3D_AON_BCR] = { 0x10a0 }, 452*f4b5b408STaniya Das [GPU_CC_GMU_BCR] = { 0x111c }, 453*f4b5b408STaniya Das [GPU_CC_GX_BCR] = { 0x1008 }, 454*f4b5b408STaniya Das [GPU_CC_XO_BCR] = { 0x1000 }, 455*f4b5b408STaniya Das }; 456*f4b5b408STaniya Das 457*f4b5b408STaniya Das static struct clk_alpha_pll *gpu_cc_qcs615_plls[] = { 458*f4b5b408STaniya Das &gpu_cc_pll0, 459*f4b5b408STaniya Das &gpu_cc_pll1, 460*f4b5b408STaniya Das }; 461*f4b5b408STaniya Das 462*f4b5b408STaniya Das static u32 gpu_cc_qcs615_critical_cbcrs[] = { 463*f4b5b408STaniya Das 0x1078, /* GPU_CC_AHB_CLK */ 464*f4b5b408STaniya Das }; 465*f4b5b408STaniya Das 466*f4b5b408STaniya Das static const struct regmap_config gpu_cc_qcs615_regmap_config = { 467*f4b5b408STaniya Das .reg_bits = 32, 468*f4b5b408STaniya Das .reg_stride = 4, 469*f4b5b408STaniya Das .val_bits = 32, 470*f4b5b408STaniya Das .max_register = 0x7008, 471*f4b5b408STaniya Das .fast_io = true, 472*f4b5b408STaniya Das }; 473*f4b5b408STaniya Das 474*f4b5b408STaniya Das static void clk_qcs615_regs_crc_configure(struct device *dev, struct regmap *regmap) 475*f4b5b408STaniya Das { 476*f4b5b408STaniya Das /* Recommended WAKEUP/SLEEP settings for the gpu_cc_cx_gmu_clk */ 477*f4b5b408STaniya Das regmap_update_bits(regmap, gpu_cc_cx_gmu_clk.clkr.enable_reg, 0xff0, 0xff0); 478*f4b5b408STaniya Das 479*f4b5b408STaniya Das /* 480*f4b5b408STaniya Das * After POR, Clock Ramp Controller(CRC) will be in bypass mode. 481*f4b5b408STaniya Das * Software needs to do the following operation to enable the CRC 482*f4b5b408STaniya Das * for GFX3D clock and divide the input clock by div by 2. 483*f4b5b408STaniya Das */ 484*f4b5b408STaniya Das regmap_update_bits(regmap, 0x1028, 0x00015011, 0x00015011); 485*f4b5b408STaniya Das regmap_update_bits(regmap, 0x1024, 0x00800000, 0x00800000); 486*f4b5b408STaniya Das } 487*f4b5b408STaniya Das 488*f4b5b408STaniya Das static struct qcom_cc_driver_data gpu_cc_qcs615_driver_data = { 489*f4b5b408STaniya Das .alpha_plls = gpu_cc_qcs615_plls, 490*f4b5b408STaniya Das .num_alpha_plls = ARRAY_SIZE(gpu_cc_qcs615_plls), 491*f4b5b408STaniya Das .clk_cbcrs = gpu_cc_qcs615_critical_cbcrs, 492*f4b5b408STaniya Das .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_qcs615_critical_cbcrs), 493*f4b5b408STaniya Das .clk_regs_configure = clk_qcs615_regs_crc_configure, 494*f4b5b408STaniya Das }; 495*f4b5b408STaniya Das 496*f4b5b408STaniya Das static const struct qcom_cc_desc gpu_cc_qcs615_desc = { 497*f4b5b408STaniya Das .config = &gpu_cc_qcs615_regmap_config, 498*f4b5b408STaniya Das .clks = gpu_cc_qcs615_clocks, 499*f4b5b408STaniya Das .num_clks = ARRAY_SIZE(gpu_cc_qcs615_clocks), 500*f4b5b408STaniya Das .clk_hws = gpu_cc_qcs615_hws, 501*f4b5b408STaniya Das .num_clk_hws = ARRAY_SIZE(gpu_cc_qcs615_hws), 502*f4b5b408STaniya Das .resets = gpu_cc_qcs615_resets, 503*f4b5b408STaniya Das .num_resets = ARRAY_SIZE(gpu_cc_qcs615_resets), 504*f4b5b408STaniya Das .gdscs = gpu_cc_qcs615_gdscs, 505*f4b5b408STaniya Das .num_gdscs = ARRAY_SIZE(gpu_cc_qcs615_gdscs), 506*f4b5b408STaniya Das .driver_data = &gpu_cc_qcs615_driver_data, 507*f4b5b408STaniya Das }; 508*f4b5b408STaniya Das 509*f4b5b408STaniya Das static const struct of_device_id gpu_cc_qcs615_match_table[] = { 510*f4b5b408STaniya Das { .compatible = "qcom,qcs615-gpucc" }, 511*f4b5b408STaniya Das { } 512*f4b5b408STaniya Das }; 513*f4b5b408STaniya Das MODULE_DEVICE_TABLE(of, gpu_cc_qcs615_match_table); 514*f4b5b408STaniya Das 515*f4b5b408STaniya Das static int gpu_cc_qcs615_probe(struct platform_device *pdev) 516*f4b5b408STaniya Das { 517*f4b5b408STaniya Das return qcom_cc_probe(pdev, &gpu_cc_qcs615_desc); 518*f4b5b408STaniya Das } 519*f4b5b408STaniya Das 520*f4b5b408STaniya Das static struct platform_driver gpu_cc_qcs615_driver = { 521*f4b5b408STaniya Das .probe = gpu_cc_qcs615_probe, 522*f4b5b408STaniya Das .driver = { 523*f4b5b408STaniya Das .name = "gpucc-qcs615", 524*f4b5b408STaniya Das .of_match_table = gpu_cc_qcs615_match_table, 525*f4b5b408STaniya Das }, 526*f4b5b408STaniya Das }; 527*f4b5b408STaniya Das 528*f4b5b408STaniya Das module_platform_driver(gpu_cc_qcs615_driver); 529*f4b5b408STaniya Das 530*f4b5b408STaniya Das MODULE_DESCRIPTION("QTI GPUCC QCS615 Driver"); 531*f4b5b408STaniya Das MODULE_LICENSE("GPL"); 532