1*e55d937dSBjorn Andersson // SPDX-License-Identifier: GPL-2.0-only 2*e55d937dSBjorn Andersson /* 3*e55d937dSBjorn Andersson * Copyright (c) 2021, The Linux Foundation. All rights reserved. 4*e55d937dSBjorn Andersson */ 5*e55d937dSBjorn Andersson 6*e55d937dSBjorn Andersson #include <linux/clk-provider.h> 7*e55d937dSBjorn Andersson #include <linux/kernel.h> 8*e55d937dSBjorn Andersson #include <linux/module.h> 9*e55d937dSBjorn Andersson #include <linux/platform_device.h> 10*e55d937dSBjorn Andersson #include <linux/regmap.h> 11*e55d937dSBjorn Andersson 12*e55d937dSBjorn Andersson #include <dt-bindings/clock/qcom,gpucc-sc8280xp.h> 13*e55d937dSBjorn Andersson 14*e55d937dSBjorn Andersson #include "clk-alpha-pll.h" 15*e55d937dSBjorn Andersson #include "clk-branch.h" 16*e55d937dSBjorn Andersson #include "clk-rcg.h" 17*e55d937dSBjorn Andersson #include "clk-regmap-divider.h" 18*e55d937dSBjorn Andersson #include "common.h" 19*e55d937dSBjorn Andersson #include "reset.h" 20*e55d937dSBjorn Andersson #include "gdsc.h" 21*e55d937dSBjorn Andersson 22*e55d937dSBjorn Andersson /* Need to match the order of clocks in DT binding */ 23*e55d937dSBjorn Andersson enum { 24*e55d937dSBjorn Andersson DT_BI_TCXO, 25*e55d937dSBjorn Andersson DT_GCC_GPU_GPLL0_CLK_SRC, 26*e55d937dSBjorn Andersson DT_GCC_GPU_GPLL0_DIV_CLK_SRC, 27*e55d937dSBjorn Andersson }; 28*e55d937dSBjorn Andersson 29*e55d937dSBjorn Andersson enum { 30*e55d937dSBjorn Andersson P_BI_TCXO, 31*e55d937dSBjorn Andersson P_GCC_GPU_GPLL0_CLK_SRC, 32*e55d937dSBjorn Andersson P_GCC_GPU_GPLL0_DIV_CLK_SRC, 33*e55d937dSBjorn Andersson P_GPU_CC_PLL0_OUT_MAIN, 34*e55d937dSBjorn Andersson P_GPU_CC_PLL1_OUT_MAIN, 35*e55d937dSBjorn Andersson }; 36*e55d937dSBjorn Andersson 37*e55d937dSBjorn Andersson static const struct clk_parent_data parent_data_tcxo = { .index = DT_BI_TCXO }; 38*e55d937dSBjorn Andersson 39*e55d937dSBjorn Andersson static const struct pll_vco lucid_5lpe_vco[] = { 40*e55d937dSBjorn Andersson { 249600000, 1800000000, 0 }, 41*e55d937dSBjorn Andersson }; 42*e55d937dSBjorn Andersson 43*e55d937dSBjorn Andersson static struct alpha_pll_config gpu_cc_pll0_config = { 44*e55d937dSBjorn Andersson .l = 0x1c, 45*e55d937dSBjorn Andersson .alpha = 0xa555, 46*e55d937dSBjorn Andersson .config_ctl_val = 0x20485699, 47*e55d937dSBjorn Andersson .config_ctl_hi_val = 0x00002261, 48*e55d937dSBjorn Andersson .config_ctl_hi1_val = 0x2a9a699c, 49*e55d937dSBjorn Andersson .test_ctl_val = 0x00000000, 50*e55d937dSBjorn Andersson .test_ctl_hi_val = 0x00000000, 51*e55d937dSBjorn Andersson .test_ctl_hi1_val = 0x01800000, 52*e55d937dSBjorn Andersson .user_ctl_val = 0x00000000, 53*e55d937dSBjorn Andersson .user_ctl_hi_val = 0x00000805, 54*e55d937dSBjorn Andersson .user_ctl_hi1_val = 0x00000000, 55*e55d937dSBjorn Andersson }; 56*e55d937dSBjorn Andersson 57*e55d937dSBjorn Andersson static struct clk_alpha_pll gpu_cc_pll0 = { 58*e55d937dSBjorn Andersson .offset = 0x0, 59*e55d937dSBjorn Andersson .vco_table = lucid_5lpe_vco, 60*e55d937dSBjorn Andersson .num_vco = ARRAY_SIZE(lucid_5lpe_vco), 61*e55d937dSBjorn Andersson .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 62*e55d937dSBjorn Andersson .clkr = { 63*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 64*e55d937dSBjorn Andersson .name = "gpu_cc_pll0", 65*e55d937dSBjorn Andersson .parent_data = &parent_data_tcxo, 66*e55d937dSBjorn Andersson .num_parents = 1, 67*e55d937dSBjorn Andersson .ops = &clk_alpha_pll_lucid_5lpe_ops, 68*e55d937dSBjorn Andersson }, 69*e55d937dSBjorn Andersson }, 70*e55d937dSBjorn Andersson }; 71*e55d937dSBjorn Andersson 72*e55d937dSBjorn Andersson static struct alpha_pll_config gpu_cc_pll1_config = { 73*e55d937dSBjorn Andersson .l = 0x1A, 74*e55d937dSBjorn Andersson .alpha = 0xaaa, 75*e55d937dSBjorn Andersson .config_ctl_val = 0x20485699, 76*e55d937dSBjorn Andersson .config_ctl_hi_val = 0x00002261, 77*e55d937dSBjorn Andersson .config_ctl_hi1_val = 0x2a9a699c, 78*e55d937dSBjorn Andersson .test_ctl_val = 0x00000000, 79*e55d937dSBjorn Andersson .test_ctl_hi_val = 0x00000000, 80*e55d937dSBjorn Andersson .test_ctl_hi1_val = 0x01800000, 81*e55d937dSBjorn Andersson .user_ctl_val = 0x00000000, 82*e55d937dSBjorn Andersson .user_ctl_hi_val = 0x00000805, 83*e55d937dSBjorn Andersson .user_ctl_hi1_val = 0x00000000, 84*e55d937dSBjorn Andersson }; 85*e55d937dSBjorn Andersson 86*e55d937dSBjorn Andersson static struct clk_alpha_pll gpu_cc_pll1 = { 87*e55d937dSBjorn Andersson .offset = 0x100, 88*e55d937dSBjorn Andersson .vco_table = lucid_5lpe_vco, 89*e55d937dSBjorn Andersson .num_vco = ARRAY_SIZE(lucid_5lpe_vco), 90*e55d937dSBjorn Andersson .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 91*e55d937dSBjorn Andersson .clkr = { 92*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 93*e55d937dSBjorn Andersson .name = "gpu_cc_pll1", 94*e55d937dSBjorn Andersson .parent_data = &parent_data_tcxo, 95*e55d937dSBjorn Andersson .num_parents = 1, 96*e55d937dSBjorn Andersson .ops = &clk_alpha_pll_lucid_5lpe_ops, 97*e55d937dSBjorn Andersson }, 98*e55d937dSBjorn Andersson }, 99*e55d937dSBjorn Andersson }; 100*e55d937dSBjorn Andersson 101*e55d937dSBjorn Andersson static const struct parent_map gpu_cc_parent_map_0[] = { 102*e55d937dSBjorn Andersson { P_BI_TCXO, 0 }, 103*e55d937dSBjorn Andersson { P_GPU_CC_PLL0_OUT_MAIN, 1 }, 104*e55d937dSBjorn Andersson { P_GPU_CC_PLL1_OUT_MAIN, 3 }, 105*e55d937dSBjorn Andersson { P_GCC_GPU_GPLL0_CLK_SRC, 5 }, 106*e55d937dSBjorn Andersson { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 }, 107*e55d937dSBjorn Andersson }; 108*e55d937dSBjorn Andersson 109*e55d937dSBjorn Andersson static const struct clk_parent_data gpu_cc_parent_data_0[] = { 110*e55d937dSBjorn Andersson { .index = DT_BI_TCXO }, 111*e55d937dSBjorn Andersson { .hw = &gpu_cc_pll0.clkr.hw }, 112*e55d937dSBjorn Andersson { .hw = &gpu_cc_pll1.clkr.hw }, 113*e55d937dSBjorn Andersson { .index = DT_GCC_GPU_GPLL0_CLK_SRC }, 114*e55d937dSBjorn Andersson { .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC }, 115*e55d937dSBjorn Andersson }; 116*e55d937dSBjorn Andersson 117*e55d937dSBjorn Andersson static const struct parent_map gpu_cc_parent_map_1[] = { 118*e55d937dSBjorn Andersson { P_BI_TCXO, 0 }, 119*e55d937dSBjorn Andersson { P_GPU_CC_PLL1_OUT_MAIN, 3 }, 120*e55d937dSBjorn Andersson { P_GCC_GPU_GPLL0_CLK_SRC, 5 }, 121*e55d937dSBjorn Andersson { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 }, 122*e55d937dSBjorn Andersson }; 123*e55d937dSBjorn Andersson 124*e55d937dSBjorn Andersson static const struct clk_parent_data gpu_cc_parent_data_1[] = { 125*e55d937dSBjorn Andersson { .index = DT_BI_TCXO }, 126*e55d937dSBjorn Andersson { .hw = &gpu_cc_pll1.clkr.hw }, 127*e55d937dSBjorn Andersson { .index = DT_GCC_GPU_GPLL0_CLK_SRC }, 128*e55d937dSBjorn Andersson { .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC }, 129*e55d937dSBjorn Andersson }; 130*e55d937dSBjorn Andersson 131*e55d937dSBjorn Andersson static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 132*e55d937dSBjorn Andersson F(19200000, P_BI_TCXO, 1, 0, 0), 133*e55d937dSBjorn Andersson F(200000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 1.5, 0, 0), 134*e55d937dSBjorn Andersson F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), 135*e55d937dSBjorn Andersson { } 136*e55d937dSBjorn Andersson }; 137*e55d937dSBjorn Andersson 138*e55d937dSBjorn Andersson static struct clk_rcg2 gpu_cc_gmu_clk_src = { 139*e55d937dSBjorn Andersson .cmd_rcgr = 0x1120, 140*e55d937dSBjorn Andersson .mnd_width = 0, 141*e55d937dSBjorn Andersson .hid_width = 5, 142*e55d937dSBjorn Andersson .parent_map = gpu_cc_parent_map_0, 143*e55d937dSBjorn Andersson .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 144*e55d937dSBjorn Andersson .clkr.hw.init = &(const struct clk_init_data){ 145*e55d937dSBjorn Andersson .name = "gpu_cc_gmu_clk_src", 146*e55d937dSBjorn Andersson .parent_data = gpu_cc_parent_data_0, 147*e55d937dSBjorn Andersson .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), 148*e55d937dSBjorn Andersson .ops = &clk_rcg2_shared_ops, 149*e55d937dSBjorn Andersson }, 150*e55d937dSBjorn Andersson }; 151*e55d937dSBjorn Andersson 152*e55d937dSBjorn Andersson static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { 153*e55d937dSBjorn Andersson F(200000000, P_GCC_GPU_GPLL0_CLK_SRC, 3, 0, 0), 154*e55d937dSBjorn Andersson F(300000000, P_GCC_GPU_GPLL0_CLK_SRC, 2, 0, 0), 155*e55d937dSBjorn Andersson F(400000000, P_GCC_GPU_GPLL0_CLK_SRC, 1.5, 0, 0), 156*e55d937dSBjorn Andersson { } 157*e55d937dSBjorn Andersson }; 158*e55d937dSBjorn Andersson 159*e55d937dSBjorn Andersson static struct clk_rcg2 gpu_cc_hub_clk_src = { 160*e55d937dSBjorn Andersson .cmd_rcgr = 0x117c, 161*e55d937dSBjorn Andersson .mnd_width = 0, 162*e55d937dSBjorn Andersson .hid_width = 5, 163*e55d937dSBjorn Andersson .parent_map = gpu_cc_parent_map_1, 164*e55d937dSBjorn Andersson .freq_tbl = ftbl_gpu_cc_hub_clk_src, 165*e55d937dSBjorn Andersson .clkr.hw.init = &(const struct clk_init_data){ 166*e55d937dSBjorn Andersson .name = "gpu_cc_hub_clk_src", 167*e55d937dSBjorn Andersson .parent_data = gpu_cc_parent_data_1, 168*e55d937dSBjorn Andersson .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), 169*e55d937dSBjorn Andersson .ops = &clk_rcg2_shared_ops, 170*e55d937dSBjorn Andersson }, 171*e55d937dSBjorn Andersson }; 172*e55d937dSBjorn Andersson 173*e55d937dSBjorn Andersson static struct clk_regmap_div gpu_cc_hub_ahb_div_clk_src = { 174*e55d937dSBjorn Andersson .reg = 0x11c0, 175*e55d937dSBjorn Andersson .shift = 0, 176*e55d937dSBjorn Andersson .width = 4, 177*e55d937dSBjorn Andersson .clkr.hw.init = &(const struct clk_init_data) { 178*e55d937dSBjorn Andersson .name = "gpu_cc_hub_ahb_div_clk_src", 179*e55d937dSBjorn Andersson .parent_hws = (const struct clk_hw*[]){ 180*e55d937dSBjorn Andersson &gpu_cc_hub_clk_src.clkr.hw, 181*e55d937dSBjorn Andersson }, 182*e55d937dSBjorn Andersson .num_parents = 1, 183*e55d937dSBjorn Andersson .flags = CLK_SET_RATE_PARENT, 184*e55d937dSBjorn Andersson .ops = &clk_regmap_div_ro_ops, 185*e55d937dSBjorn Andersson }, 186*e55d937dSBjorn Andersson }; 187*e55d937dSBjorn Andersson 188*e55d937dSBjorn Andersson static struct clk_regmap_div gpu_cc_hub_cx_int_div_clk_src = { 189*e55d937dSBjorn Andersson .reg = 0x11bc, 190*e55d937dSBjorn Andersson .shift = 0, 191*e55d937dSBjorn Andersson .width = 4, 192*e55d937dSBjorn Andersson .clkr.hw.init = &(const struct clk_init_data) { 193*e55d937dSBjorn Andersson .name = "gpu_cc_hub_cx_int_div_clk_src", 194*e55d937dSBjorn Andersson .parent_hws = (const struct clk_hw*[]){ 195*e55d937dSBjorn Andersson &gpu_cc_hub_clk_src.clkr.hw, 196*e55d937dSBjorn Andersson }, 197*e55d937dSBjorn Andersson .num_parents = 1, 198*e55d937dSBjorn Andersson .flags = CLK_SET_RATE_PARENT, 199*e55d937dSBjorn Andersson .ops = &clk_regmap_div_ro_ops, 200*e55d937dSBjorn Andersson }, 201*e55d937dSBjorn Andersson }; 202*e55d937dSBjorn Andersson 203*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_ahb_clk = { 204*e55d937dSBjorn Andersson .halt_reg = 0x1078, 205*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT_DELAY, 206*e55d937dSBjorn Andersson .clkr = { 207*e55d937dSBjorn Andersson .enable_reg = 0x1078, 208*e55d937dSBjorn Andersson .enable_mask = BIT(0), 209*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 210*e55d937dSBjorn Andersson .name = "gpu_cc_ahb_clk", 211*e55d937dSBjorn Andersson .parent_hws = (const struct clk_hw*[]){ 212*e55d937dSBjorn Andersson &gpu_cc_hub_ahb_div_clk_src.clkr.hw, 213*e55d937dSBjorn Andersson }, 214*e55d937dSBjorn Andersson .num_parents = 1, 215*e55d937dSBjorn Andersson .flags = CLK_SET_RATE_PARENT, 216*e55d937dSBjorn Andersson .ops = &clk_branch2_ops, 217*e55d937dSBjorn Andersson }, 218*e55d937dSBjorn Andersson }, 219*e55d937dSBjorn Andersson }; 220*e55d937dSBjorn Andersson 221*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_crc_ahb_clk = { 222*e55d937dSBjorn Andersson .halt_reg = 0x107c, 223*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT_VOTED, 224*e55d937dSBjorn Andersson .clkr = { 225*e55d937dSBjorn Andersson .enable_reg = 0x107c, 226*e55d937dSBjorn Andersson .enable_mask = BIT(0), 227*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 228*e55d937dSBjorn Andersson .name = "gpu_cc_crc_ahb_clk", 229*e55d937dSBjorn Andersson .parent_hws = (const struct clk_hw*[]){ 230*e55d937dSBjorn Andersson &gpu_cc_hub_ahb_div_clk_src.clkr.hw, 231*e55d937dSBjorn Andersson }, 232*e55d937dSBjorn Andersson .num_parents = 1, 233*e55d937dSBjorn Andersson .flags = CLK_SET_RATE_PARENT, 234*e55d937dSBjorn Andersson .ops = &clk_branch2_ops, 235*e55d937dSBjorn Andersson }, 236*e55d937dSBjorn Andersson }, 237*e55d937dSBjorn Andersson }; 238*e55d937dSBjorn Andersson 239*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_cx_gmu_clk = { 240*e55d937dSBjorn Andersson .halt_reg = 0x1098, 241*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT, 242*e55d937dSBjorn Andersson .clkr = { 243*e55d937dSBjorn Andersson .enable_reg = 0x1098, 244*e55d937dSBjorn Andersson .enable_mask = BIT(0), 245*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 246*e55d937dSBjorn Andersson .name = "gpu_cc_cx_gmu_clk", 247*e55d937dSBjorn Andersson .parent_hws = (const struct clk_hw*[]){ 248*e55d937dSBjorn Andersson &gpu_cc_gmu_clk_src.clkr.hw, 249*e55d937dSBjorn Andersson }, 250*e55d937dSBjorn Andersson .num_parents = 1, 251*e55d937dSBjorn Andersson .flags = CLK_SET_RATE_PARENT, 252*e55d937dSBjorn Andersson .ops = &clk_branch2_aon_ops, 253*e55d937dSBjorn Andersson }, 254*e55d937dSBjorn Andersson }, 255*e55d937dSBjorn Andersson }; 256*e55d937dSBjorn Andersson 257*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { 258*e55d937dSBjorn Andersson .halt_reg = 0x108c, 259*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT_VOTED, 260*e55d937dSBjorn Andersson .clkr = { 261*e55d937dSBjorn Andersson .enable_reg = 0x108c, 262*e55d937dSBjorn Andersson .enable_mask = BIT(0), 263*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 264*e55d937dSBjorn Andersson .name = "gpu_cc_cx_snoc_dvm_clk", 265*e55d937dSBjorn Andersson .ops = &clk_branch2_ops, 266*e55d937dSBjorn Andersson }, 267*e55d937dSBjorn Andersson }, 268*e55d937dSBjorn Andersson }; 269*e55d937dSBjorn Andersson 270*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_cxo_aon_clk = { 271*e55d937dSBjorn Andersson .halt_reg = 0x1004, 272*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT_VOTED, 273*e55d937dSBjorn Andersson .clkr = { 274*e55d937dSBjorn Andersson .enable_reg = 0x1004, 275*e55d937dSBjorn Andersson .enable_mask = BIT(0), 276*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 277*e55d937dSBjorn Andersson .name = "gpu_cc_cxo_aon_clk", 278*e55d937dSBjorn Andersson .ops = &clk_branch2_ops, 279*e55d937dSBjorn Andersson }, 280*e55d937dSBjorn Andersson }, 281*e55d937dSBjorn Andersson }; 282*e55d937dSBjorn Andersson 283*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_gx_gmu_clk = { 284*e55d937dSBjorn Andersson .halt_reg = 0x1064, 285*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT, 286*e55d937dSBjorn Andersson .clkr = { 287*e55d937dSBjorn Andersson .enable_reg = 0x1064, 288*e55d937dSBjorn Andersson .enable_mask = BIT(0), 289*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 290*e55d937dSBjorn Andersson .name = "gpu_cc_gx_gmu_clk", 291*e55d937dSBjorn Andersson .parent_hws = (const struct clk_hw*[]){ 292*e55d937dSBjorn Andersson &gpu_cc_gmu_clk_src.clkr.hw, 293*e55d937dSBjorn Andersson }, 294*e55d937dSBjorn Andersson .num_parents = 1, 295*e55d937dSBjorn Andersson .flags = CLK_SET_RATE_PARENT, 296*e55d937dSBjorn Andersson .ops = &clk_branch2_ops, 297*e55d937dSBjorn Andersson }, 298*e55d937dSBjorn Andersson }, 299*e55d937dSBjorn Andersson }; 300*e55d937dSBjorn Andersson 301*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { 302*e55d937dSBjorn Andersson .halt_reg = 0x5000, 303*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT_VOTED, 304*e55d937dSBjorn Andersson .clkr = { 305*e55d937dSBjorn Andersson .enable_reg = 0x5000, 306*e55d937dSBjorn Andersson .enable_mask = BIT(0), 307*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 308*e55d937dSBjorn Andersson .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", 309*e55d937dSBjorn Andersson .ops = &clk_branch2_ops, 310*e55d937dSBjorn Andersson }, 311*e55d937dSBjorn Andersson }, 312*e55d937dSBjorn Andersson }; 313*e55d937dSBjorn Andersson 314*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_hub_aon_clk = { 315*e55d937dSBjorn Andersson .halt_reg = 0x1178, 316*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT, 317*e55d937dSBjorn Andersson .clkr = { 318*e55d937dSBjorn Andersson .enable_reg = 0x1178, 319*e55d937dSBjorn Andersson .enable_mask = BIT(0), 320*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 321*e55d937dSBjorn Andersson .name = "gpu_cc_hub_aon_clk", 322*e55d937dSBjorn Andersson .parent_hws = (const struct clk_hw*[]){ 323*e55d937dSBjorn Andersson &gpu_cc_hub_clk_src.clkr.hw, 324*e55d937dSBjorn Andersson }, 325*e55d937dSBjorn Andersson .num_parents = 1, 326*e55d937dSBjorn Andersson .flags = CLK_SET_RATE_PARENT, 327*e55d937dSBjorn Andersson .ops = &clk_branch2_aon_ops, 328*e55d937dSBjorn Andersson }, 329*e55d937dSBjorn Andersson }, 330*e55d937dSBjorn Andersson }; 331*e55d937dSBjorn Andersson 332*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_hub_cx_int_clk = { 333*e55d937dSBjorn Andersson .halt_reg = 0x1204, 334*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT, 335*e55d937dSBjorn Andersson .clkr = { 336*e55d937dSBjorn Andersson .enable_reg = 0x1204, 337*e55d937dSBjorn Andersson .enable_mask = BIT(0), 338*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 339*e55d937dSBjorn Andersson .name = "gpu_cc_hub_cx_int_clk", 340*e55d937dSBjorn Andersson .parent_hws = (const struct clk_hw*[]){ 341*e55d937dSBjorn Andersson &gpu_cc_hub_cx_int_div_clk_src.clkr.hw, 342*e55d937dSBjorn Andersson }, 343*e55d937dSBjorn Andersson .num_parents = 1, 344*e55d937dSBjorn Andersson .flags = CLK_SET_RATE_PARENT, 345*e55d937dSBjorn Andersson .ops = &clk_branch2_aon_ops, 346*e55d937dSBjorn Andersson }, 347*e55d937dSBjorn Andersson }, 348*e55d937dSBjorn Andersson }; 349*e55d937dSBjorn Andersson 350*e55d937dSBjorn Andersson static struct clk_branch gpu_cc_sleep_clk = { 351*e55d937dSBjorn Andersson .halt_reg = 0x1090, 352*e55d937dSBjorn Andersson .halt_check = BRANCH_HALT_VOTED, 353*e55d937dSBjorn Andersson .clkr = { 354*e55d937dSBjorn Andersson .enable_reg = 0x1090, 355*e55d937dSBjorn Andersson .enable_mask = BIT(0), 356*e55d937dSBjorn Andersson .hw.init = &(const struct clk_init_data){ 357*e55d937dSBjorn Andersson .name = "gpu_cc_sleep_clk", 358*e55d937dSBjorn Andersson .ops = &clk_branch2_ops, 359*e55d937dSBjorn Andersson }, 360*e55d937dSBjorn Andersson }, 361*e55d937dSBjorn Andersson }; 362*e55d937dSBjorn Andersson 363*e55d937dSBjorn Andersson static struct clk_regmap *gpu_cc_sc8280xp_clocks[] = { 364*e55d937dSBjorn Andersson [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, 365*e55d937dSBjorn Andersson [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, 366*e55d937dSBjorn Andersson [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 367*e55d937dSBjorn Andersson [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, 368*e55d937dSBjorn Andersson [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, 369*e55d937dSBjorn Andersson [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 370*e55d937dSBjorn Andersson [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, 371*e55d937dSBjorn Andersson [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, 372*e55d937dSBjorn Andersson [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr, 373*e55d937dSBjorn Andersson [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, 374*e55d937dSBjorn Andersson [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, 375*e55d937dSBjorn Andersson [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, 376*e55d937dSBjorn Andersson [GPU_CC_HUB_CX_INT_DIV_CLK_SRC] = &gpu_cc_hub_cx_int_div_clk_src.clkr, 377*e55d937dSBjorn Andersson [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, 378*e55d937dSBjorn Andersson [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, 379*e55d937dSBjorn Andersson [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, 380*e55d937dSBjorn Andersson }; 381*e55d937dSBjorn Andersson 382*e55d937dSBjorn Andersson static struct gdsc cx_gdsc = { 383*e55d937dSBjorn Andersson .gdscr = 0x106c, 384*e55d937dSBjorn Andersson .gds_hw_ctrl = 0x1540, 385*e55d937dSBjorn Andersson .pd = { 386*e55d937dSBjorn Andersson .name = "cx_gdsc", 387*e55d937dSBjorn Andersson }, 388*e55d937dSBjorn Andersson .pwrsts = PWRSTS_OFF_ON, 389*e55d937dSBjorn Andersson .flags = VOTABLE | RETAIN_FF_ENABLE, 390*e55d937dSBjorn Andersson }; 391*e55d937dSBjorn Andersson 392*e55d937dSBjorn Andersson static struct gdsc gx_gdsc = { 393*e55d937dSBjorn Andersson .gdscr = 0x100c, 394*e55d937dSBjorn Andersson .clamp_io_ctrl = 0x1508, 395*e55d937dSBjorn Andersson .pd = { 396*e55d937dSBjorn Andersson .name = "gx_gdsc", 397*e55d937dSBjorn Andersson .power_on = gdsc_gx_do_nothing_enable, 398*e55d937dSBjorn Andersson }, 399*e55d937dSBjorn Andersson .pwrsts = PWRSTS_OFF_ON, 400*e55d937dSBjorn Andersson .flags = CLAMP_IO | RETAIN_FF_ENABLE, 401*e55d937dSBjorn Andersson }; 402*e55d937dSBjorn Andersson 403*e55d937dSBjorn Andersson static struct gdsc *gpu_cc_sc8280xp_gdscs[] = { 404*e55d937dSBjorn Andersson [GPU_CC_CX_GDSC] = &cx_gdsc, 405*e55d937dSBjorn Andersson [GPU_CC_GX_GDSC] = &gx_gdsc, 406*e55d937dSBjorn Andersson }; 407*e55d937dSBjorn Andersson 408*e55d937dSBjorn Andersson static const struct regmap_config gpu_cc_sc8280xp_regmap_config = { 409*e55d937dSBjorn Andersson .reg_bits = 32, 410*e55d937dSBjorn Andersson .reg_stride = 4, 411*e55d937dSBjorn Andersson .val_bits = 32, 412*e55d937dSBjorn Andersson .max_register = 0x8030, 413*e55d937dSBjorn Andersson .fast_io = true, 414*e55d937dSBjorn Andersson }; 415*e55d937dSBjorn Andersson 416*e55d937dSBjorn Andersson static struct qcom_cc_desc gpu_cc_sc8280xp_desc = { 417*e55d937dSBjorn Andersson .config = &gpu_cc_sc8280xp_regmap_config, 418*e55d937dSBjorn Andersson .clks = gpu_cc_sc8280xp_clocks, 419*e55d937dSBjorn Andersson .num_clks = ARRAY_SIZE(gpu_cc_sc8280xp_clocks), 420*e55d937dSBjorn Andersson .gdscs = gpu_cc_sc8280xp_gdscs, 421*e55d937dSBjorn Andersson .num_gdscs = ARRAY_SIZE(gpu_cc_sc8280xp_gdscs), 422*e55d937dSBjorn Andersson }; 423*e55d937dSBjorn Andersson 424*e55d937dSBjorn Andersson static int gpu_cc_sc8280xp_probe(struct platform_device *pdev) 425*e55d937dSBjorn Andersson { 426*e55d937dSBjorn Andersson struct regmap *regmap; 427*e55d937dSBjorn Andersson 428*e55d937dSBjorn Andersson regmap = qcom_cc_map(pdev, &gpu_cc_sc8280xp_desc); 429*e55d937dSBjorn Andersson if (IS_ERR(regmap)) 430*e55d937dSBjorn Andersson return PTR_ERR(regmap); 431*e55d937dSBjorn Andersson 432*e55d937dSBjorn Andersson clk_lucid_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); 433*e55d937dSBjorn Andersson clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); 434*e55d937dSBjorn Andersson 435*e55d937dSBjorn Andersson /* 436*e55d937dSBjorn Andersson * Keep the clocks always-ON 437*e55d937dSBjorn Andersson * GPU_CC_CB_CLK, GPU_CC_CXO_CLK 438*e55d937dSBjorn Andersson */ 439*e55d937dSBjorn Andersson regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0)); 440*e55d937dSBjorn Andersson regmap_update_bits(regmap, 0x109c, BIT(0), BIT(0)); 441*e55d937dSBjorn Andersson 442*e55d937dSBjorn Andersson return qcom_cc_really_probe(pdev, &gpu_cc_sc8280xp_desc, regmap); 443*e55d937dSBjorn Andersson } 444*e55d937dSBjorn Andersson 445*e55d937dSBjorn Andersson static const struct of_device_id gpu_cc_sc8280xp_match_table[] = { 446*e55d937dSBjorn Andersson { .compatible = "qcom,sc8280xp-gpucc" }, 447*e55d937dSBjorn Andersson { } 448*e55d937dSBjorn Andersson }; 449*e55d937dSBjorn Andersson MODULE_DEVICE_TABLE(of, gpu_cc_sc8280xp_match_table); 450*e55d937dSBjorn Andersson 451*e55d937dSBjorn Andersson static struct platform_driver gpu_cc_sc8280xp_driver = { 452*e55d937dSBjorn Andersson .probe = gpu_cc_sc8280xp_probe, 453*e55d937dSBjorn Andersson .driver = { 454*e55d937dSBjorn Andersson .name = "gpu_cc-sc8280xp", 455*e55d937dSBjorn Andersson .of_match_table = gpu_cc_sc8280xp_match_table, 456*e55d937dSBjorn Andersson }, 457*e55d937dSBjorn Andersson }; 458*e55d937dSBjorn Andersson module_platform_driver(gpu_cc_sc8280xp_driver); 459*e55d937dSBjorn Andersson 460*e55d937dSBjorn Andersson MODULE_DESCRIPTION("Qualcomm SC8280XP GPU clock controller"); 461*e55d937dSBjorn Andersson MODULE_LICENSE("GPL"); 462