1*453361cdSAmit Nischal // SPDX-License-Identifier: GPL-2.0 2*453361cdSAmit Nischal /* 3*453361cdSAmit Nischal * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4*453361cdSAmit Nischal */ 5*453361cdSAmit Nischal 6*453361cdSAmit Nischal #include <linux/clk-provider.h> 7*453361cdSAmit Nischal #include <linux/module.h> 8*453361cdSAmit Nischal #include <linux/platform_device.h> 9*453361cdSAmit Nischal #include <linux/regmap.h> 10*453361cdSAmit Nischal 11*453361cdSAmit Nischal #include <dt-bindings/clock/qcom,gpucc-sdm845.h> 12*453361cdSAmit Nischal 13*453361cdSAmit Nischal #include "common.h" 14*453361cdSAmit Nischal #include "clk-alpha-pll.h" 15*453361cdSAmit Nischal #include "clk-branch.h" 16*453361cdSAmit Nischal #include "clk-pll.h" 17*453361cdSAmit Nischal #include "clk-rcg.h" 18*453361cdSAmit Nischal #include "clk-regmap.h" 19*453361cdSAmit Nischal #include "gdsc.h" 20*453361cdSAmit Nischal 21*453361cdSAmit Nischal #define CX_GMU_CBCR_SLEEP_MASK 0xf 22*453361cdSAmit Nischal #define CX_GMU_CBCR_SLEEP_SHIFT 4 23*453361cdSAmit Nischal #define CX_GMU_CBCR_WAKE_MASK 0xf 24*453361cdSAmit Nischal #define CX_GMU_CBCR_WAKE_SHIFT 8 25*453361cdSAmit Nischal #define CLK_DIS_WAIT_SHIFT 12 26*453361cdSAmit Nischal #define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) 27*453361cdSAmit Nischal 28*453361cdSAmit Nischal enum { 29*453361cdSAmit Nischal P_BI_TCXO, 30*453361cdSAmit Nischal P_CORE_BI_PLL_TEST_SE, 31*453361cdSAmit Nischal P_GPLL0_OUT_MAIN, 32*453361cdSAmit Nischal P_GPLL0_OUT_MAIN_DIV, 33*453361cdSAmit Nischal P_GPU_CC_PLL1_OUT_EVEN, 34*453361cdSAmit Nischal P_GPU_CC_PLL1_OUT_MAIN, 35*453361cdSAmit Nischal P_GPU_CC_PLL1_OUT_ODD, 36*453361cdSAmit Nischal }; 37*453361cdSAmit Nischal 38*453361cdSAmit Nischal static const struct parent_map gpu_cc_parent_map_0[] = { 39*453361cdSAmit Nischal { P_BI_TCXO, 0 }, 40*453361cdSAmit Nischal { P_GPU_CC_PLL1_OUT_MAIN, 3 }, 41*453361cdSAmit Nischal { P_GPLL0_OUT_MAIN, 5 }, 42*453361cdSAmit Nischal { P_GPLL0_OUT_MAIN_DIV, 6 }, 43*453361cdSAmit Nischal { P_CORE_BI_PLL_TEST_SE, 7 }, 44*453361cdSAmit Nischal }; 45*453361cdSAmit Nischal 46*453361cdSAmit Nischal static const char * const gpu_cc_parent_names_0[] = { 47*453361cdSAmit Nischal "bi_tcxo", 48*453361cdSAmit Nischal "gpu_cc_pll1", 49*453361cdSAmit Nischal "gcc_gpu_gpll0_clk_src", 50*453361cdSAmit Nischal "gcc_gpu_gpll0_div_clk_src", 51*453361cdSAmit Nischal "core_bi_pll_test_se", 52*453361cdSAmit Nischal }; 53*453361cdSAmit Nischal 54*453361cdSAmit Nischal static const struct alpha_pll_config gpu_cc_pll1_config = { 55*453361cdSAmit Nischal .l = 0x1a, 56*453361cdSAmit Nischal .alpha = 0xaab, 57*453361cdSAmit Nischal }; 58*453361cdSAmit Nischal 59*453361cdSAmit Nischal static struct clk_alpha_pll gpu_cc_pll1 = { 60*453361cdSAmit Nischal .offset = 0x100, 61*453361cdSAmit Nischal .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 62*453361cdSAmit Nischal .clkr = { 63*453361cdSAmit Nischal .hw.init = &(struct clk_init_data){ 64*453361cdSAmit Nischal .name = "gpu_cc_pll1", 65*453361cdSAmit Nischal .parent_names = (const char *[]){ "bi_tcxo" }, 66*453361cdSAmit Nischal .num_parents = 1, 67*453361cdSAmit Nischal .ops = &clk_alpha_pll_fabia_ops, 68*453361cdSAmit Nischal }, 69*453361cdSAmit Nischal }, 70*453361cdSAmit Nischal }; 71*453361cdSAmit Nischal 72*453361cdSAmit Nischal static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 73*453361cdSAmit Nischal F(19200000, P_BI_TCXO, 1, 0, 0), 74*453361cdSAmit Nischal F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), 75*453361cdSAmit Nischal F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), 76*453361cdSAmit Nischal { } 77*453361cdSAmit Nischal }; 78*453361cdSAmit Nischal 79*453361cdSAmit Nischal static struct clk_rcg2 gpu_cc_gmu_clk_src = { 80*453361cdSAmit Nischal .cmd_rcgr = 0x1120, 81*453361cdSAmit Nischal .mnd_width = 0, 82*453361cdSAmit Nischal .hid_width = 5, 83*453361cdSAmit Nischal .parent_map = gpu_cc_parent_map_0, 84*453361cdSAmit Nischal .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 85*453361cdSAmit Nischal .clkr.hw.init = &(struct clk_init_data){ 86*453361cdSAmit Nischal .name = "gpu_cc_gmu_clk_src", 87*453361cdSAmit Nischal .parent_names = gpu_cc_parent_names_0, 88*453361cdSAmit Nischal .num_parents = 6, 89*453361cdSAmit Nischal .ops = &clk_rcg2_shared_ops, 90*453361cdSAmit Nischal }, 91*453361cdSAmit Nischal }; 92*453361cdSAmit Nischal 93*453361cdSAmit Nischal static struct clk_branch gpu_cc_cx_gmu_clk = { 94*453361cdSAmit Nischal .halt_reg = 0x1098, 95*453361cdSAmit Nischal .halt_check = BRANCH_HALT, 96*453361cdSAmit Nischal .clkr = { 97*453361cdSAmit Nischal .enable_reg = 0x1098, 98*453361cdSAmit Nischal .enable_mask = BIT(0), 99*453361cdSAmit Nischal .hw.init = &(struct clk_init_data){ 100*453361cdSAmit Nischal .name = "gpu_cc_cx_gmu_clk", 101*453361cdSAmit Nischal .parent_names = (const char *[]){ 102*453361cdSAmit Nischal "gpu_cc_gmu_clk_src", 103*453361cdSAmit Nischal }, 104*453361cdSAmit Nischal .num_parents = 1, 105*453361cdSAmit Nischal .flags = CLK_SET_RATE_PARENT, 106*453361cdSAmit Nischal .ops = &clk_branch2_ops, 107*453361cdSAmit Nischal }, 108*453361cdSAmit Nischal }, 109*453361cdSAmit Nischal }; 110*453361cdSAmit Nischal 111*453361cdSAmit Nischal static struct clk_branch gpu_cc_cxo_clk = { 112*453361cdSAmit Nischal .halt_reg = 0x109c, 113*453361cdSAmit Nischal .halt_check = BRANCH_HALT, 114*453361cdSAmit Nischal .clkr = { 115*453361cdSAmit Nischal .enable_reg = 0x109c, 116*453361cdSAmit Nischal .enable_mask = BIT(0), 117*453361cdSAmit Nischal .hw.init = &(struct clk_init_data){ 118*453361cdSAmit Nischal .name = "gpu_cc_cxo_clk", 119*453361cdSAmit Nischal .ops = &clk_branch2_ops, 120*453361cdSAmit Nischal }, 121*453361cdSAmit Nischal }, 122*453361cdSAmit Nischal }; 123*453361cdSAmit Nischal 124*453361cdSAmit Nischal static struct gdsc gpu_cx_gdsc = { 125*453361cdSAmit Nischal .gdscr = 0x106c, 126*453361cdSAmit Nischal .gds_hw_ctrl = 0x1540, 127*453361cdSAmit Nischal .pd = { 128*453361cdSAmit Nischal .name = "gpu_cx_gdsc", 129*453361cdSAmit Nischal }, 130*453361cdSAmit Nischal .pwrsts = PWRSTS_OFF_ON, 131*453361cdSAmit Nischal .flags = VOTABLE, 132*453361cdSAmit Nischal }; 133*453361cdSAmit Nischal 134*453361cdSAmit Nischal static struct gdsc gpu_gx_gdsc = { 135*453361cdSAmit Nischal .gdscr = 0x100c, 136*453361cdSAmit Nischal .clamp_io_ctrl = 0x1508, 137*453361cdSAmit Nischal .pd = { 138*453361cdSAmit Nischal .name = "gpu_gx_gdsc", 139*453361cdSAmit Nischal }, 140*453361cdSAmit Nischal .pwrsts = PWRSTS_OFF_ON, 141*453361cdSAmit Nischal .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR, 142*453361cdSAmit Nischal }; 143*453361cdSAmit Nischal 144*453361cdSAmit Nischal static struct clk_regmap *gpu_cc_sdm845_clocks[] = { 145*453361cdSAmit Nischal [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 146*453361cdSAmit Nischal [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 147*453361cdSAmit Nischal [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 148*453361cdSAmit Nischal [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, 149*453361cdSAmit Nischal }; 150*453361cdSAmit Nischal 151*453361cdSAmit Nischal static struct gdsc *gpu_cc_sdm845_gdscs[] = { 152*453361cdSAmit Nischal [GPU_CX_GDSC] = &gpu_cx_gdsc, 153*453361cdSAmit Nischal [GPU_GX_GDSC] = &gpu_gx_gdsc, 154*453361cdSAmit Nischal }; 155*453361cdSAmit Nischal 156*453361cdSAmit Nischal static const struct regmap_config gpu_cc_sdm845_regmap_config = { 157*453361cdSAmit Nischal .reg_bits = 32, 158*453361cdSAmit Nischal .reg_stride = 4, 159*453361cdSAmit Nischal .val_bits = 32, 160*453361cdSAmit Nischal .max_register = 0x8008, 161*453361cdSAmit Nischal .fast_io = true, 162*453361cdSAmit Nischal }; 163*453361cdSAmit Nischal 164*453361cdSAmit Nischal static const struct qcom_cc_desc gpu_cc_sdm845_desc = { 165*453361cdSAmit Nischal .config = &gpu_cc_sdm845_regmap_config, 166*453361cdSAmit Nischal .clks = gpu_cc_sdm845_clocks, 167*453361cdSAmit Nischal .num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks), 168*453361cdSAmit Nischal .gdscs = gpu_cc_sdm845_gdscs, 169*453361cdSAmit Nischal .num_gdscs = ARRAY_SIZE(gpu_cc_sdm845_gdscs), 170*453361cdSAmit Nischal }; 171*453361cdSAmit Nischal 172*453361cdSAmit Nischal static const struct of_device_id gpu_cc_sdm845_match_table[] = { 173*453361cdSAmit Nischal { .compatible = "qcom,sdm845-gpucc" }, 174*453361cdSAmit Nischal { } 175*453361cdSAmit Nischal }; 176*453361cdSAmit Nischal MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table); 177*453361cdSAmit Nischal 178*453361cdSAmit Nischal static int gpu_cc_sdm845_probe(struct platform_device *pdev) 179*453361cdSAmit Nischal { 180*453361cdSAmit Nischal struct regmap *regmap; 181*453361cdSAmit Nischal unsigned int value, mask; 182*453361cdSAmit Nischal 183*453361cdSAmit Nischal regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc); 184*453361cdSAmit Nischal if (IS_ERR(regmap)) 185*453361cdSAmit Nischal return PTR_ERR(regmap); 186*453361cdSAmit Nischal 187*453361cdSAmit Nischal clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); 188*453361cdSAmit Nischal 189*453361cdSAmit Nischal /* 190*453361cdSAmit Nischal * Configure gpu_cc_cx_gmu_clk with recommended 191*453361cdSAmit Nischal * wakeup/sleep settings 192*453361cdSAmit Nischal */ 193*453361cdSAmit Nischal mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT; 194*453361cdSAmit Nischal mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT; 195*453361cdSAmit Nischal value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT; 196*453361cdSAmit Nischal regmap_update_bits(regmap, 0x1098, mask, value); 197*453361cdSAmit Nischal 198*453361cdSAmit Nischal /* Configure clk_dis_wait for gpu_cx_gdsc */ 199*453361cdSAmit Nischal regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK, 200*453361cdSAmit Nischal 8 << CLK_DIS_WAIT_SHIFT); 201*453361cdSAmit Nischal 202*453361cdSAmit Nischal return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap); 203*453361cdSAmit Nischal } 204*453361cdSAmit Nischal 205*453361cdSAmit Nischal static struct platform_driver gpu_cc_sdm845_driver = { 206*453361cdSAmit Nischal .probe = gpu_cc_sdm845_probe, 207*453361cdSAmit Nischal .driver = { 208*453361cdSAmit Nischal .name = "sdm845-gpucc", 209*453361cdSAmit Nischal .of_match_table = gpu_cc_sdm845_match_table, 210*453361cdSAmit Nischal }, 211*453361cdSAmit Nischal }; 212*453361cdSAmit Nischal 213*453361cdSAmit Nischal static int __init gpu_cc_sdm845_init(void) 214*453361cdSAmit Nischal { 215*453361cdSAmit Nischal return platform_driver_register(&gpu_cc_sdm845_driver); 216*453361cdSAmit Nischal } 217*453361cdSAmit Nischal subsys_initcall(gpu_cc_sdm845_init); 218*453361cdSAmit Nischal 219*453361cdSAmit Nischal static void __exit gpu_cc_sdm845_exit(void) 220*453361cdSAmit Nischal { 221*453361cdSAmit Nischal platform_driver_unregister(&gpu_cc_sdm845_driver); 222*453361cdSAmit Nischal } 223*453361cdSAmit Nischal module_exit(gpu_cc_sdm845_exit); 224*453361cdSAmit Nischal 225*453361cdSAmit Nischal MODULE_DESCRIPTION("QTI GPUCC SDM845 Driver"); 226*453361cdSAmit Nischal MODULE_LICENSE("GPL v2"); 227