1*980d7c84SLuca Weiss // SPDX-License-Identifier: GPL-2.0-only 2*980d7c84SLuca Weiss /* 3*980d7c84SLuca Weiss * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. 4*980d7c84SLuca Weiss * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com> 5*980d7c84SLuca Weiss */ 6*980d7c84SLuca Weiss 7*980d7c84SLuca Weiss #include <linux/clk-provider.h> 8*980d7c84SLuca Weiss #include <linux/mod_devicetable.h> 9*980d7c84SLuca Weiss #include <linux/module.h> 10*980d7c84SLuca Weiss #include <linux/platform_device.h> 11*980d7c84SLuca Weiss #include <linux/regmap.h> 12*980d7c84SLuca Weiss 13*980d7c84SLuca Weiss #include <dt-bindings/clock/qcom,milos-gpucc.h> 14*980d7c84SLuca Weiss 15*980d7c84SLuca Weiss #include "clk-alpha-pll.h" 16*980d7c84SLuca Weiss #include "clk-branch.h" 17*980d7c84SLuca Weiss #include "clk-pll.h" 18*980d7c84SLuca Weiss #include "clk-rcg.h" 19*980d7c84SLuca Weiss #include "clk-regmap.h" 20*980d7c84SLuca Weiss #include "clk-regmap-divider.h" 21*980d7c84SLuca Weiss #include "clk-regmap-mux.h" 22*980d7c84SLuca Weiss #include "common.h" 23*980d7c84SLuca Weiss #include "gdsc.h" 24*980d7c84SLuca Weiss #include "reset.h" 25*980d7c84SLuca Weiss 26*980d7c84SLuca Weiss /* Need to match the order of clocks in DT binding */ 27*980d7c84SLuca Weiss enum { 28*980d7c84SLuca Weiss DT_BI_TCXO, 29*980d7c84SLuca Weiss DT_GPLL0_OUT_MAIN, 30*980d7c84SLuca Weiss DT_GPLL0_OUT_MAIN_DIV, 31*980d7c84SLuca Weiss }; 32*980d7c84SLuca Weiss 33*980d7c84SLuca Weiss enum { 34*980d7c84SLuca Weiss P_BI_TCXO, 35*980d7c84SLuca Weiss P_GPLL0_OUT_MAIN, 36*980d7c84SLuca Weiss P_GPLL0_OUT_MAIN_DIV, 37*980d7c84SLuca Weiss P_GPU_CC_PLL0_OUT_EVEN, 38*980d7c84SLuca Weiss P_GPU_CC_PLL0_OUT_MAIN, 39*980d7c84SLuca Weiss P_GPU_CC_PLL0_OUT_ODD, 40*980d7c84SLuca Weiss }; 41*980d7c84SLuca Weiss 42*980d7c84SLuca Weiss static const struct pll_vco lucid_ole_vco[] = { 43*980d7c84SLuca Weiss { 249600000, 2300000000, 0 }, 44*980d7c84SLuca Weiss }; 45*980d7c84SLuca Weiss 46*980d7c84SLuca Weiss /* 700.0 MHz Configuration */ 47*980d7c84SLuca Weiss static const struct alpha_pll_config gpu_cc_pll0_config = { 48*980d7c84SLuca Weiss .l = 0x24, 49*980d7c84SLuca Weiss .alpha = 0x7555, 50*980d7c84SLuca Weiss .config_ctl_val = 0x20485699, 51*980d7c84SLuca Weiss .config_ctl_hi_val = 0x00182261, 52*980d7c84SLuca Weiss .config_ctl_hi1_val = 0x82aa299c, 53*980d7c84SLuca Weiss .test_ctl_val = 0x00000000, 54*980d7c84SLuca Weiss .test_ctl_hi_val = 0x00000003, 55*980d7c84SLuca Weiss .test_ctl_hi1_val = 0x00009000, 56*980d7c84SLuca Weiss .test_ctl_hi2_val = 0x00000034, 57*980d7c84SLuca Weiss .user_ctl_val = 0x00000400, 58*980d7c84SLuca Weiss .user_ctl_hi_val = 0x00000005, 59*980d7c84SLuca Weiss }; 60*980d7c84SLuca Weiss 61*980d7c84SLuca Weiss static struct clk_alpha_pll gpu_cc_pll0 = { 62*980d7c84SLuca Weiss .offset = 0x0, 63*980d7c84SLuca Weiss .config = &gpu_cc_pll0_config, 64*980d7c84SLuca Weiss .vco_table = lucid_ole_vco, 65*980d7c84SLuca Weiss .num_vco = ARRAY_SIZE(lucid_ole_vco), 66*980d7c84SLuca Weiss .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], 67*980d7c84SLuca Weiss .clkr = { 68*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 69*980d7c84SLuca Weiss .name = "gpu_cc_pll0", 70*980d7c84SLuca Weiss .parent_data = &(const struct clk_parent_data) { 71*980d7c84SLuca Weiss .index = DT_BI_TCXO, 72*980d7c84SLuca Weiss }, 73*980d7c84SLuca Weiss .num_parents = 1, 74*980d7c84SLuca Weiss .ops = &clk_alpha_pll_lucid_evo_ops, 75*980d7c84SLuca Weiss }, 76*980d7c84SLuca Weiss }, 77*980d7c84SLuca Weiss }; 78*980d7c84SLuca Weiss 79*980d7c84SLuca Weiss static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = { 80*980d7c84SLuca Weiss { 0x1, 2 }, 81*980d7c84SLuca Weiss { } 82*980d7c84SLuca Weiss }; 83*980d7c84SLuca Weiss 84*980d7c84SLuca Weiss static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { 85*980d7c84SLuca Weiss .offset = 0x0, 86*980d7c84SLuca Weiss .post_div_shift = 10, 87*980d7c84SLuca Weiss .post_div_table = post_div_table_gpu_cc_pll0_out_even, 88*980d7c84SLuca Weiss .num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even), 89*980d7c84SLuca Weiss .width = 4, 90*980d7c84SLuca Weiss .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], 91*980d7c84SLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 92*980d7c84SLuca Weiss .name = "gpu_cc_pll0_out_even", 93*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 94*980d7c84SLuca Weiss &gpu_cc_pll0.clkr.hw, 95*980d7c84SLuca Weiss }, 96*980d7c84SLuca Weiss .num_parents = 1, 97*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 98*980d7c84SLuca Weiss .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, 99*980d7c84SLuca Weiss }, 100*980d7c84SLuca Weiss }; 101*980d7c84SLuca Weiss 102*980d7c84SLuca Weiss static const struct parent_map gpu_cc_parent_map_0[] = { 103*980d7c84SLuca Weiss { P_BI_TCXO, 0 }, 104*980d7c84SLuca Weiss { P_GPLL0_OUT_MAIN, 5 }, 105*980d7c84SLuca Weiss { P_GPLL0_OUT_MAIN_DIV, 6 }, 106*980d7c84SLuca Weiss }; 107*980d7c84SLuca Weiss 108*980d7c84SLuca Weiss static const struct clk_parent_data gpu_cc_parent_data_0[] = { 109*980d7c84SLuca Weiss { .index = DT_BI_TCXO }, 110*980d7c84SLuca Weiss { .index = DT_GPLL0_OUT_MAIN }, 111*980d7c84SLuca Weiss { .index = DT_GPLL0_OUT_MAIN_DIV }, 112*980d7c84SLuca Weiss }; 113*980d7c84SLuca Weiss 114*980d7c84SLuca Weiss static const struct parent_map gpu_cc_parent_map_1[] = { 115*980d7c84SLuca Weiss { P_BI_TCXO, 0 }, 116*980d7c84SLuca Weiss { P_GPU_CC_PLL0_OUT_MAIN, 1 }, 117*980d7c84SLuca Weiss { P_GPU_CC_PLL0_OUT_EVEN, 2 }, 118*980d7c84SLuca Weiss { P_GPU_CC_PLL0_OUT_ODD, 3 }, 119*980d7c84SLuca Weiss { P_GPLL0_OUT_MAIN, 5 }, 120*980d7c84SLuca Weiss { P_GPLL0_OUT_MAIN_DIV, 6 }, 121*980d7c84SLuca Weiss }; 122*980d7c84SLuca Weiss 123*980d7c84SLuca Weiss static const struct clk_parent_data gpu_cc_parent_data_1[] = { 124*980d7c84SLuca Weiss { .index = DT_BI_TCXO }, 125*980d7c84SLuca Weiss { .hw = &gpu_cc_pll0.clkr.hw }, 126*980d7c84SLuca Weiss { .hw = &gpu_cc_pll0_out_even.clkr.hw }, 127*980d7c84SLuca Weiss { .hw = &gpu_cc_pll0.clkr.hw }, 128*980d7c84SLuca Weiss { .index = DT_GPLL0_OUT_MAIN }, 129*980d7c84SLuca Weiss { .index = DT_GPLL0_OUT_MAIN_DIV }, 130*980d7c84SLuca Weiss }; 131*980d7c84SLuca Weiss 132*980d7c84SLuca Weiss static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = { 133*980d7c84SLuca Weiss F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 134*980d7c84SLuca Weiss { } 135*980d7c84SLuca Weiss }; 136*980d7c84SLuca Weiss 137*980d7c84SLuca Weiss static struct clk_rcg2 gpu_cc_ff_clk_src = { 138*980d7c84SLuca Weiss .cmd_rcgr = 0x9474, 139*980d7c84SLuca Weiss .mnd_width = 0, 140*980d7c84SLuca Weiss .hid_width = 5, 141*980d7c84SLuca Weiss .parent_map = gpu_cc_parent_map_0, 142*980d7c84SLuca Weiss .freq_tbl = ftbl_gpu_cc_ff_clk_src, 143*980d7c84SLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 144*980d7c84SLuca Weiss .name = "gpu_cc_ff_clk_src", 145*980d7c84SLuca Weiss .parent_data = gpu_cc_parent_data_0, 146*980d7c84SLuca Weiss .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), 147*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 148*980d7c84SLuca Weiss .ops = &clk_rcg2_shared_ops, 149*980d7c84SLuca Weiss }, 150*980d7c84SLuca Weiss }; 151*980d7c84SLuca Weiss 152*980d7c84SLuca Weiss static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 153*980d7c84SLuca Weiss F(19200000, P_BI_TCXO, 1, 0, 0), 154*980d7c84SLuca Weiss F(350000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), 155*980d7c84SLuca Weiss F(650000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), 156*980d7c84SLuca Weiss F(687500000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), 157*980d7c84SLuca Weiss { } 158*980d7c84SLuca Weiss }; 159*980d7c84SLuca Weiss 160*980d7c84SLuca Weiss static struct clk_rcg2 gpu_cc_gmu_clk_src = { 161*980d7c84SLuca Weiss .cmd_rcgr = 0x9318, 162*980d7c84SLuca Weiss .mnd_width = 0, 163*980d7c84SLuca Weiss .hid_width = 5, 164*980d7c84SLuca Weiss .parent_map = gpu_cc_parent_map_1, 165*980d7c84SLuca Weiss .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 166*980d7c84SLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 167*980d7c84SLuca Weiss .name = "gpu_cc_gmu_clk_src", 168*980d7c84SLuca Weiss .parent_data = gpu_cc_parent_data_1, 169*980d7c84SLuca Weiss .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), 170*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 171*980d7c84SLuca Weiss .ops = &clk_rcg2_shared_ops, 172*980d7c84SLuca Weiss }, 173*980d7c84SLuca Weiss }; 174*980d7c84SLuca Weiss 175*980d7c84SLuca Weiss static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { 176*980d7c84SLuca Weiss F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 177*980d7c84SLuca Weiss F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 178*980d7c84SLuca Weiss F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), 179*980d7c84SLuca Weiss { } 180*980d7c84SLuca Weiss }; 181*980d7c84SLuca Weiss 182*980d7c84SLuca Weiss static struct clk_rcg2 gpu_cc_hub_clk_src = { 183*980d7c84SLuca Weiss .cmd_rcgr = 0x93ec, 184*980d7c84SLuca Weiss .mnd_width = 0, 185*980d7c84SLuca Weiss .hid_width = 5, 186*980d7c84SLuca Weiss .parent_map = gpu_cc_parent_map_1, 187*980d7c84SLuca Weiss .freq_tbl = ftbl_gpu_cc_hub_clk_src, 188*980d7c84SLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 189*980d7c84SLuca Weiss .name = "gpu_cc_hub_clk_src", 190*980d7c84SLuca Weiss .parent_data = gpu_cc_parent_data_1, 191*980d7c84SLuca Weiss .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), 192*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 193*980d7c84SLuca Weiss .ops = &clk_rcg2_shared_ops, 194*980d7c84SLuca Weiss }, 195*980d7c84SLuca Weiss }; 196*980d7c84SLuca Weiss 197*980d7c84SLuca Weiss static struct clk_regmap_div gpu_cc_hub_div_clk_src = { 198*980d7c84SLuca Weiss .reg = 0x942c, 199*980d7c84SLuca Weiss .shift = 0, 200*980d7c84SLuca Weiss .width = 4, 201*980d7c84SLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 202*980d7c84SLuca Weiss .name = "gpu_cc_hub_div_clk_src", 203*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 204*980d7c84SLuca Weiss &gpu_cc_hub_clk_src.clkr.hw, 205*980d7c84SLuca Weiss }, 206*980d7c84SLuca Weiss .num_parents = 1, 207*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 208*980d7c84SLuca Weiss .ops = &clk_regmap_div_ro_ops, 209*980d7c84SLuca Weiss }, 210*980d7c84SLuca Weiss }; 211*980d7c84SLuca Weiss 212*980d7c84SLuca Weiss static struct clk_branch gpu_cc_ahb_clk = { 213*980d7c84SLuca Weiss .halt_reg = 0x90bc, 214*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_DELAY, 215*980d7c84SLuca Weiss .clkr = { 216*980d7c84SLuca Weiss .enable_reg = 0x90bc, 217*980d7c84SLuca Weiss .enable_mask = BIT(0), 218*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 219*980d7c84SLuca Weiss .name = "gpu_cc_ahb_clk", 220*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 221*980d7c84SLuca Weiss &gpu_cc_hub_div_clk_src.clkr.hw, 222*980d7c84SLuca Weiss }, 223*980d7c84SLuca Weiss .num_parents = 1, 224*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 225*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 226*980d7c84SLuca Weiss }, 227*980d7c84SLuca Weiss }, 228*980d7c84SLuca Weiss }; 229*980d7c84SLuca Weiss 230*980d7c84SLuca Weiss static struct clk_branch gpu_cc_cx_accu_shift_clk = { 231*980d7c84SLuca Weiss .halt_reg = 0x910c, 232*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_VOTED, 233*980d7c84SLuca Weiss .clkr = { 234*980d7c84SLuca Weiss .enable_reg = 0x910c, 235*980d7c84SLuca Weiss .enable_mask = BIT(0), 236*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 237*980d7c84SLuca Weiss .name = "gpu_cc_cx_accu_shift_clk", 238*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 239*980d7c84SLuca Weiss }, 240*980d7c84SLuca Weiss }, 241*980d7c84SLuca Weiss }; 242*980d7c84SLuca Weiss 243*980d7c84SLuca Weiss static struct clk_branch gpu_cc_cx_ff_clk = { 244*980d7c84SLuca Weiss .halt_reg = 0x90ec, 245*980d7c84SLuca Weiss .halt_check = BRANCH_HALT, 246*980d7c84SLuca Weiss .clkr = { 247*980d7c84SLuca Weiss .enable_reg = 0x90ec, 248*980d7c84SLuca Weiss .enable_mask = BIT(0), 249*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 250*980d7c84SLuca Weiss .name = "gpu_cc_cx_ff_clk", 251*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 252*980d7c84SLuca Weiss &gpu_cc_ff_clk_src.clkr.hw, 253*980d7c84SLuca Weiss }, 254*980d7c84SLuca Weiss .num_parents = 1, 255*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 256*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 257*980d7c84SLuca Weiss }, 258*980d7c84SLuca Weiss }, 259*980d7c84SLuca Weiss }; 260*980d7c84SLuca Weiss 261*980d7c84SLuca Weiss static struct clk_branch gpu_cc_cx_gmu_clk = { 262*980d7c84SLuca Weiss .halt_reg = 0x90d4, 263*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_VOTED, 264*980d7c84SLuca Weiss .clkr = { 265*980d7c84SLuca Weiss .enable_reg = 0x90d4, 266*980d7c84SLuca Weiss .enable_mask = BIT(0), 267*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 268*980d7c84SLuca Weiss .name = "gpu_cc_cx_gmu_clk", 269*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 270*980d7c84SLuca Weiss &gpu_cc_gmu_clk_src.clkr.hw, 271*980d7c84SLuca Weiss }, 272*980d7c84SLuca Weiss .num_parents = 1, 273*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 274*980d7c84SLuca Weiss .ops = &clk_branch2_aon_ops, 275*980d7c84SLuca Weiss }, 276*980d7c84SLuca Weiss }, 277*980d7c84SLuca Weiss }; 278*980d7c84SLuca Weiss 279*980d7c84SLuca Weiss static struct clk_branch gpu_cc_cxo_clk = { 280*980d7c84SLuca Weiss .halt_reg = 0x90e4, 281*980d7c84SLuca Weiss .halt_check = BRANCH_HALT, 282*980d7c84SLuca Weiss .clkr = { 283*980d7c84SLuca Weiss .enable_reg = 0x90e4, 284*980d7c84SLuca Weiss .enable_mask = BIT(0), 285*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 286*980d7c84SLuca Weiss .name = "gpu_cc_cxo_clk", 287*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 288*980d7c84SLuca Weiss }, 289*980d7c84SLuca Weiss }, 290*980d7c84SLuca Weiss }; 291*980d7c84SLuca Weiss 292*980d7c84SLuca Weiss static struct clk_branch gpu_cc_dpm_clk = { 293*980d7c84SLuca Weiss .halt_reg = 0x9110, 294*980d7c84SLuca Weiss .halt_check = BRANCH_HALT, 295*980d7c84SLuca Weiss .clkr = { 296*980d7c84SLuca Weiss .enable_reg = 0x9110, 297*980d7c84SLuca Weiss .enable_mask = BIT(0), 298*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 299*980d7c84SLuca Weiss .name = "gpu_cc_dpm_clk", 300*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 301*980d7c84SLuca Weiss }, 302*980d7c84SLuca Weiss }, 303*980d7c84SLuca Weiss }; 304*980d7c84SLuca Weiss 305*980d7c84SLuca Weiss static struct clk_branch gpu_cc_freq_measure_clk = { 306*980d7c84SLuca Weiss .halt_reg = 0x900c, 307*980d7c84SLuca Weiss .halt_check = BRANCH_HALT, 308*980d7c84SLuca Weiss .clkr = { 309*980d7c84SLuca Weiss .enable_reg = 0x900c, 310*980d7c84SLuca Weiss .enable_mask = BIT(0), 311*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 312*980d7c84SLuca Weiss .name = "gpu_cc_freq_measure_clk", 313*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 314*980d7c84SLuca Weiss }, 315*980d7c84SLuca Weiss }, 316*980d7c84SLuca Weiss }; 317*980d7c84SLuca Weiss 318*980d7c84SLuca Weiss static struct clk_branch gpu_cc_gx_accu_shift_clk = { 319*980d7c84SLuca Weiss .halt_reg = 0x9070, 320*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_VOTED, 321*980d7c84SLuca Weiss .clkr = { 322*980d7c84SLuca Weiss .enable_reg = 0x9070, 323*980d7c84SLuca Weiss .enable_mask = BIT(0), 324*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 325*980d7c84SLuca Weiss .name = "gpu_cc_gx_accu_shift_clk", 326*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 327*980d7c84SLuca Weiss }, 328*980d7c84SLuca Weiss }, 329*980d7c84SLuca Weiss }; 330*980d7c84SLuca Weiss 331*980d7c84SLuca Weiss static struct clk_branch gpu_cc_gx_acd_ahb_ff_clk = { 332*980d7c84SLuca Weiss .halt_reg = 0x9068, 333*980d7c84SLuca Weiss .halt_check = BRANCH_HALT, 334*980d7c84SLuca Weiss .clkr = { 335*980d7c84SLuca Weiss .enable_reg = 0x9068, 336*980d7c84SLuca Weiss .enable_mask = BIT(0), 337*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 338*980d7c84SLuca Weiss .name = "gpu_cc_gx_acd_ahb_ff_clk", 339*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 340*980d7c84SLuca Weiss &gpu_cc_ff_clk_src.clkr.hw, 341*980d7c84SLuca Weiss }, 342*980d7c84SLuca Weiss .num_parents = 1, 343*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 344*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 345*980d7c84SLuca Weiss }, 346*980d7c84SLuca Weiss }, 347*980d7c84SLuca Weiss }; 348*980d7c84SLuca Weiss 349*980d7c84SLuca Weiss static struct clk_branch gpu_cc_gx_gmu_clk = { 350*980d7c84SLuca Weiss .halt_reg = 0x9060, 351*980d7c84SLuca Weiss .halt_check = BRANCH_HALT, 352*980d7c84SLuca Weiss .clkr = { 353*980d7c84SLuca Weiss .enable_reg = 0x9060, 354*980d7c84SLuca Weiss .enable_mask = BIT(0), 355*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 356*980d7c84SLuca Weiss .name = "gpu_cc_gx_gmu_clk", 357*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 358*980d7c84SLuca Weiss &gpu_cc_gmu_clk_src.clkr.hw, 359*980d7c84SLuca Weiss }, 360*980d7c84SLuca Weiss .num_parents = 1, 361*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 362*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 363*980d7c84SLuca Weiss }, 364*980d7c84SLuca Weiss }, 365*980d7c84SLuca Weiss }; 366*980d7c84SLuca Weiss 367*980d7c84SLuca Weiss static struct clk_branch gpu_cc_gx_rcg_ahb_ff_clk = { 368*980d7c84SLuca Weiss .halt_reg = 0x906c, 369*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_VOTED, 370*980d7c84SLuca Weiss .clkr = { 371*980d7c84SLuca Weiss .enable_reg = 0x906c, 372*980d7c84SLuca Weiss .enable_mask = BIT(0), 373*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 374*980d7c84SLuca Weiss .name = "gpu_cc_gx_rcg_ahb_ff_clk", 375*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 376*980d7c84SLuca Weiss &gpu_cc_ff_clk_src.clkr.hw, 377*980d7c84SLuca Weiss }, 378*980d7c84SLuca Weiss .num_parents = 1, 379*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 380*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 381*980d7c84SLuca Weiss }, 382*980d7c84SLuca Weiss }, 383*980d7c84SLuca Weiss }; 384*980d7c84SLuca Weiss 385*980d7c84SLuca Weiss static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { 386*980d7c84SLuca Weiss .halt_reg = 0x7000, 387*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_VOTED, 388*980d7c84SLuca Weiss .clkr = { 389*980d7c84SLuca Weiss .enable_reg = 0x7000, 390*980d7c84SLuca Weiss .enable_mask = BIT(0), 391*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 392*980d7c84SLuca Weiss .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", 393*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 394*980d7c84SLuca Weiss }, 395*980d7c84SLuca Weiss }, 396*980d7c84SLuca Weiss }; 397*980d7c84SLuca Weiss 398*980d7c84SLuca Weiss static struct clk_branch gpu_cc_hub_aon_clk = { 399*980d7c84SLuca Weiss .halt_reg = 0x93e8, 400*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_VOTED, 401*980d7c84SLuca Weiss .clkr = { 402*980d7c84SLuca Weiss .enable_reg = 0x93e8, 403*980d7c84SLuca Weiss .enable_mask = BIT(0), 404*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 405*980d7c84SLuca Weiss .name = "gpu_cc_hub_aon_clk", 406*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 407*980d7c84SLuca Weiss &gpu_cc_hub_clk_src.clkr.hw, 408*980d7c84SLuca Weiss }, 409*980d7c84SLuca Weiss .num_parents = 1, 410*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 411*980d7c84SLuca Weiss .ops = &clk_branch2_aon_ops, 412*980d7c84SLuca Weiss }, 413*980d7c84SLuca Weiss }, 414*980d7c84SLuca Weiss }; 415*980d7c84SLuca Weiss 416*980d7c84SLuca Weiss static struct clk_branch gpu_cc_hub_cx_int_clk = { 417*980d7c84SLuca Weiss .halt_reg = 0x90e8, 418*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_VOTED, 419*980d7c84SLuca Weiss .clkr = { 420*980d7c84SLuca Weiss .enable_reg = 0x90e8, 421*980d7c84SLuca Weiss .enable_mask = BIT(0), 422*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 423*980d7c84SLuca Weiss .name = "gpu_cc_hub_cx_int_clk", 424*980d7c84SLuca Weiss .parent_hws = (const struct clk_hw*[]) { 425*980d7c84SLuca Weiss &gpu_cc_hub_clk_src.clkr.hw, 426*980d7c84SLuca Weiss }, 427*980d7c84SLuca Weiss .num_parents = 1, 428*980d7c84SLuca Weiss .flags = CLK_SET_RATE_PARENT, 429*980d7c84SLuca Weiss .ops = &clk_branch2_aon_ops, 430*980d7c84SLuca Weiss }, 431*980d7c84SLuca Weiss }, 432*980d7c84SLuca Weiss }; 433*980d7c84SLuca Weiss 434*980d7c84SLuca Weiss static struct clk_branch gpu_cc_memnoc_gfx_clk = { 435*980d7c84SLuca Weiss .halt_reg = 0x90f4, 436*980d7c84SLuca Weiss .halt_check = BRANCH_HALT_VOTED, 437*980d7c84SLuca Weiss .clkr = { 438*980d7c84SLuca Weiss .enable_reg = 0x90f4, 439*980d7c84SLuca Weiss .enable_mask = BIT(0), 440*980d7c84SLuca Weiss .hw.init = &(const struct clk_init_data) { 441*980d7c84SLuca Weiss .name = "gpu_cc_memnoc_gfx_clk", 442*980d7c84SLuca Weiss .ops = &clk_branch2_ops, 443*980d7c84SLuca Weiss }, 444*980d7c84SLuca Weiss }, 445*980d7c84SLuca Weiss }; 446*980d7c84SLuca Weiss 447*980d7c84SLuca Weiss static struct gdsc gpu_cc_cx_gdsc = { 448*980d7c84SLuca Weiss .gdscr = 0x9080, 449*980d7c84SLuca Weiss .gds_hw_ctrl = 0x9094, 450*980d7c84SLuca Weiss .en_rest_wait_val = 0x2, 451*980d7c84SLuca Weiss .en_few_wait_val = 0x2, 452*980d7c84SLuca Weiss .clk_dis_wait_val = 0x8, 453*980d7c84SLuca Weiss .pd = { 454*980d7c84SLuca Weiss .name = "gpu_cc_cx_gdsc", 455*980d7c84SLuca Weiss }, 456*980d7c84SLuca Weiss .pwrsts = PWRSTS_OFF_ON, 457*980d7c84SLuca Weiss .flags = RETAIN_FF_ENABLE | VOTABLE, 458*980d7c84SLuca Weiss }; 459*980d7c84SLuca Weiss 460*980d7c84SLuca Weiss static struct clk_regmap *gpu_cc_milos_clocks[] = { 461*980d7c84SLuca Weiss [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, 462*980d7c84SLuca Weiss [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr, 463*980d7c84SLuca Weiss [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr, 464*980d7c84SLuca Weiss [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 465*980d7c84SLuca Weiss [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 466*980d7c84SLuca Weiss [GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.clkr, 467*980d7c84SLuca Weiss [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr, 468*980d7c84SLuca Weiss [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr, 469*980d7c84SLuca Weiss [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 470*980d7c84SLuca Weiss [GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr, 471*980d7c84SLuca Weiss [GPU_CC_GX_ACD_AHB_FF_CLK] = &gpu_cc_gx_acd_ahb_ff_clk.clkr, 472*980d7c84SLuca Weiss [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, 473*980d7c84SLuca Weiss [GPU_CC_GX_RCG_AHB_FF_CLK] = &gpu_cc_gx_rcg_ahb_ff_clk.clkr, 474*980d7c84SLuca Weiss [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, 475*980d7c84SLuca Weiss [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, 476*980d7c84SLuca Weiss [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, 477*980d7c84SLuca Weiss [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, 478*980d7c84SLuca Weiss [GPU_CC_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr, 479*980d7c84SLuca Weiss [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, 480*980d7c84SLuca Weiss [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, 481*980d7c84SLuca Weiss [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr, 482*980d7c84SLuca Weiss }; 483*980d7c84SLuca Weiss 484*980d7c84SLuca Weiss static struct gdsc *gpu_cc_milos_gdscs[] = { 485*980d7c84SLuca Weiss [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, 486*980d7c84SLuca Weiss }; 487*980d7c84SLuca Weiss 488*980d7c84SLuca Weiss static const struct qcom_reset_map gpu_cc_milos_resets[] = { 489*980d7c84SLuca Weiss [GPU_CC_CB_BCR] = { 0x93a0 }, 490*980d7c84SLuca Weiss [GPU_CC_CX_BCR] = { 0x907c }, 491*980d7c84SLuca Weiss [GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, 492*980d7c84SLuca Weiss [GPU_CC_FF_BCR] = { 0x9470 }, 493*980d7c84SLuca Weiss [GPU_CC_GMU_BCR] = { 0x9314 }, 494*980d7c84SLuca Weiss [GPU_CC_GX_BCR] = { 0x905c }, 495*980d7c84SLuca Weiss [GPU_CC_RBCPR_BCR] = { 0x91e0 }, 496*980d7c84SLuca Weiss [GPU_CC_XO_BCR] = { 0x9000 }, 497*980d7c84SLuca Weiss }; 498*980d7c84SLuca Weiss 499*980d7c84SLuca Weiss static struct clk_alpha_pll *gpu_cc_milos_plls[] = { 500*980d7c84SLuca Weiss &gpu_cc_pll0, 501*980d7c84SLuca Weiss }; 502*980d7c84SLuca Weiss 503*980d7c84SLuca Weiss static u32 gpu_cc_milos_critical_cbcrs[] = { 504*980d7c84SLuca Weiss 0x93a4, /* GPU_CC_CB_CLK */ 505*980d7c84SLuca Weiss 0x9008, /* GPU_CC_CXO_AON_CLK */ 506*980d7c84SLuca Weiss 0x9010, /* GPU_CC_DEMET_CLK */ 507*980d7c84SLuca Weiss 0x9064, /* GPU_CC_GX_AHB_FF_CLK */ 508*980d7c84SLuca Weiss 0x93a8, /* GPU_CC_RSCC_HUB_AON_CLK */ 509*980d7c84SLuca Weiss 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */ 510*980d7c84SLuca Weiss 0x90cc, /* GPU_CC_SLEEP_CLK */ 511*980d7c84SLuca Weiss }; 512*980d7c84SLuca Weiss 513*980d7c84SLuca Weiss static const struct regmap_config gpu_cc_milos_regmap_config = { 514*980d7c84SLuca Weiss .reg_bits = 32, 515*980d7c84SLuca Weiss .reg_stride = 4, 516*980d7c84SLuca Weiss .val_bits = 32, 517*980d7c84SLuca Weiss .max_register = 0x95e8, 518*980d7c84SLuca Weiss .fast_io = true, 519*980d7c84SLuca Weiss }; 520*980d7c84SLuca Weiss 521*980d7c84SLuca Weiss static struct qcom_cc_driver_data gpu_cc_milos_driver_data = { 522*980d7c84SLuca Weiss .alpha_plls = gpu_cc_milos_plls, 523*980d7c84SLuca Weiss .num_alpha_plls = ARRAY_SIZE(gpu_cc_milos_plls), 524*980d7c84SLuca Weiss .clk_cbcrs = gpu_cc_milos_critical_cbcrs, 525*980d7c84SLuca Weiss .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_milos_critical_cbcrs), 526*980d7c84SLuca Weiss }; 527*980d7c84SLuca Weiss 528*980d7c84SLuca Weiss static const struct qcom_cc_desc gpu_cc_milos_desc = { 529*980d7c84SLuca Weiss .config = &gpu_cc_milos_regmap_config, 530*980d7c84SLuca Weiss .clks = gpu_cc_milos_clocks, 531*980d7c84SLuca Weiss .num_clks = ARRAY_SIZE(gpu_cc_milos_clocks), 532*980d7c84SLuca Weiss .resets = gpu_cc_milos_resets, 533*980d7c84SLuca Weiss .num_resets = ARRAY_SIZE(gpu_cc_milos_resets), 534*980d7c84SLuca Weiss .gdscs = gpu_cc_milos_gdscs, 535*980d7c84SLuca Weiss .num_gdscs = ARRAY_SIZE(gpu_cc_milos_gdscs), 536*980d7c84SLuca Weiss .use_rpm = true, 537*980d7c84SLuca Weiss .driver_data = &gpu_cc_milos_driver_data, 538*980d7c84SLuca Weiss }; 539*980d7c84SLuca Weiss 540*980d7c84SLuca Weiss static const struct of_device_id gpu_cc_milos_match_table[] = { 541*980d7c84SLuca Weiss { .compatible = "qcom,milos-gpucc" }, 542*980d7c84SLuca Weiss { } 543*980d7c84SLuca Weiss }; 544*980d7c84SLuca Weiss MODULE_DEVICE_TABLE(of, gpu_cc_milos_match_table); 545*980d7c84SLuca Weiss 546*980d7c84SLuca Weiss static int gpu_cc_milos_probe(struct platform_device *pdev) 547*980d7c84SLuca Weiss { 548*980d7c84SLuca Weiss return qcom_cc_probe(pdev, &gpu_cc_milos_desc); 549*980d7c84SLuca Weiss } 550*980d7c84SLuca Weiss 551*980d7c84SLuca Weiss static struct platform_driver gpu_cc_milos_driver = { 552*980d7c84SLuca Weiss .probe = gpu_cc_milos_probe, 553*980d7c84SLuca Weiss .driver = { 554*980d7c84SLuca Weiss .name = "gpu_cc-milos", 555*980d7c84SLuca Weiss .of_match_table = gpu_cc_milos_match_table, 556*980d7c84SLuca Weiss }, 557*980d7c84SLuca Weiss }; 558*980d7c84SLuca Weiss 559*980d7c84SLuca Weiss module_platform_driver(gpu_cc_milos_driver); 560*980d7c84SLuca Weiss 561*980d7c84SLuca Weiss MODULE_DESCRIPTION("QTI GPU_CC Milos Driver"); 562*980d7c84SLuca Weiss MODULE_LICENSE("GPL"); 563