322 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.4 */5 6#include <linux/clk-provider.h>7#include <linux/module.h>8#include <linux/platform_device.h>9#include <linux/regmap.h>10 11#include <dt-bindings/clock/qcom,gpucc-sm8150.h>12 13#include "common.h"14#include "clk-alpha-pll.h"15#include "clk-branch.h"16#include "clk-pll.h"17#include "clk-rcg.h"18#include "clk-regmap.h"19#include "reset.h"20#include "gdsc.h"21 22enum {23 P_BI_TCXO,24 P_GPLL0_OUT_MAIN,25 P_GPLL0_OUT_MAIN_DIV,26 P_GPU_CC_PLL1_OUT_MAIN,27};28 29static const struct pll_vco trion_vco[] = {30 { 249600000, 2000000000, 0 },31};32 33static struct alpha_pll_config gpu_cc_pll1_config = {34 .l = 0x1a,35 .alpha = 0xaaa,36 .config_ctl_val = 0x20485699,37 .config_ctl_hi_val = 0x00002267,38 .config_ctl_hi1_val = 0x00000024,39 .test_ctl_val = 0x00000000,40 .test_ctl_hi_val = 0x00000000,41 .test_ctl_hi1_val = 0x00000020,42 .user_ctl_val = 0x00000000,43 .user_ctl_hi_val = 0x00000805,44 .user_ctl_hi1_val = 0x000000d0,45};46 47static struct clk_alpha_pll gpu_cc_pll1 = {48 .offset = 0x100,49 .vco_table = trion_vco,50 .num_vco = ARRAY_SIZE(trion_vco),51 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],52 .clkr = {53 .hw.init = &(struct clk_init_data){54 .name = "gpu_cc_pll1",55 .parent_data = &(const struct clk_parent_data){56 .fw_name = "bi_tcxo",57 },58 .num_parents = 1,59 .ops = &clk_alpha_pll_trion_ops,60 },61 },62};63 64static const struct parent_map gpu_cc_parent_map_0[] = {65 { P_BI_TCXO, 0 },66 { P_GPU_CC_PLL1_OUT_MAIN, 3 },67 { P_GPLL0_OUT_MAIN, 5 },68 { P_GPLL0_OUT_MAIN_DIV, 6 },69};70 71static const struct clk_parent_data gpu_cc_parent_data_0[] = {72 { .fw_name = "bi_tcxo" },73 { .hw = &gpu_cc_pll1.clkr.hw },74 { .fw_name = "gcc_gpu_gpll0_clk_src" },75 { .fw_name = "gcc_gpu_gpll0_div_clk_src" },76};77 78static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {79 F(19200000, P_BI_TCXO, 1, 0, 0),80 F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),81 F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),82 { }83};84 85static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src_sc8180x[] = {86 F(19200000, P_BI_TCXO, 1, 0, 0),87 F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),88 F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),89 F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),90 { }91};92 93static struct clk_rcg2 gpu_cc_gmu_clk_src = {94 .cmd_rcgr = 0x1120,95 .mnd_width = 0,96 .hid_width = 5,97 .parent_map = gpu_cc_parent_map_0,98 .freq_tbl = ftbl_gpu_cc_gmu_clk_src,99 .clkr.hw.init = &(struct clk_init_data){100 .name = "gpu_cc_gmu_clk_src",101 .parent_data = gpu_cc_parent_data_0,102 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),103 .flags = CLK_SET_RATE_PARENT,104 .ops = &clk_rcg2_ops,105 },106};107 108static struct clk_branch gpu_cc_ahb_clk = {109 .halt_reg = 0x1078,110 .halt_check = BRANCH_HALT_DELAY,111 .clkr = {112 .enable_reg = 0x1078,113 .enable_mask = BIT(0),114 .hw.init = &(struct clk_init_data){115 .name = "gpu_cc_ahb_clk",116 .ops = &clk_branch2_ops,117 },118 },119};120 121static struct clk_branch gpu_cc_crc_ahb_clk = {122 .halt_reg = 0x107c,123 .halt_check = BRANCH_HALT,124 .clkr = {125 .enable_reg = 0x107c,126 .enable_mask = BIT(0),127 .hw.init = &(struct clk_init_data){128 .name = "gpu_cc_crc_ahb_clk",129 .ops = &clk_branch2_ops,130 },131 },132};133 134static struct clk_branch gpu_cc_cx_apb_clk = {135 .halt_reg = 0x1088,136 .halt_check = BRANCH_HALT,137 .clkr = {138 .enable_reg = 0x1088,139 .enable_mask = BIT(0),140 .hw.init = &(struct clk_init_data){141 .name = "gpu_cc_cx_apb_clk",142 .ops = &clk_branch2_ops,143 },144 },145};146 147static struct clk_branch gpu_cc_cx_gmu_clk = {148 .halt_reg = 0x1098,149 .halt_check = BRANCH_HALT,150 .clkr = {151 .enable_reg = 0x1098,152 .enable_mask = BIT(0),153 .hw.init = &(struct clk_init_data){154 .name = "gpu_cc_cx_gmu_clk",155 .parent_hws = (const struct clk_hw*[]){156 &gpu_cc_gmu_clk_src.clkr.hw,157 },158 .num_parents = 1,159 .flags = CLK_SET_RATE_PARENT,160 .ops = &clk_branch2_ops,161 },162 },163};164 165static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {166 .halt_reg = 0x108c,167 .halt_check = BRANCH_HALT,168 .clkr = {169 .enable_reg = 0x108c,170 .enable_mask = BIT(0),171 .hw.init = &(struct clk_init_data){172 .name = "gpu_cc_cx_snoc_dvm_clk",173 .ops = &clk_branch2_ops,174 },175 },176};177 178static struct clk_branch gpu_cc_cxo_aon_clk = {179 .halt_reg = 0x1004,180 .halt_check = BRANCH_HALT,181 .clkr = {182 .enable_reg = 0x1004,183 .enable_mask = BIT(0),184 .hw.init = &(struct clk_init_data){185 .name = "gpu_cc_cxo_aon_clk",186 .ops = &clk_branch2_ops,187 },188 },189};190 191static struct clk_branch gpu_cc_cxo_clk = {192 .halt_reg = 0x109c,193 .halt_check = BRANCH_HALT,194 .clkr = {195 .enable_reg = 0x109c,196 .enable_mask = BIT(0),197 .hw.init = &(struct clk_init_data){198 .name = "gpu_cc_cxo_clk",199 .ops = &clk_branch2_ops,200 },201 },202};203 204static struct clk_branch gpu_cc_gx_gmu_clk = {205 .halt_reg = 0x1064,206 .halt_check = BRANCH_HALT,207 .clkr = {208 .enable_reg = 0x1064,209 .enable_mask = BIT(0),210 .hw.init = &(struct clk_init_data){211 .name = "gpu_cc_gx_gmu_clk",212 .parent_hws = (const struct clk_hw*[]){213 &gpu_cc_gmu_clk_src.clkr.hw,214 },215 .num_parents = 1,216 .flags = CLK_SET_RATE_PARENT,217 .ops = &clk_branch2_ops,218 },219 },220};221 222static struct gdsc gpu_cx_gdsc = {223 .gdscr = 0x106c,224 .gds_hw_ctrl = 0x1540,225 .pd = {226 .name = "gpu_cx_gdsc",227 },228 .pwrsts = PWRSTS_OFF_ON,229 .flags = VOTABLE,230};231 232static struct gdsc gpu_gx_gdsc = {233 .gdscr = 0x100c,234 .clamp_io_ctrl = 0x1508,235 .pd = {236 .name = "gpu_gx_gdsc",237 .power_on = gdsc_gx_do_nothing_enable,238 },239 .pwrsts = PWRSTS_OFF_ON,240 .flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,241};242 243static struct clk_regmap *gpu_cc_sm8150_clocks[] = {244 [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,245 [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,246 [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,247 [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,248 [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,249 [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,250 [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,251 [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,252 [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,253 [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,254};255 256static const struct qcom_reset_map gpu_cc_sm8150_resets[] = {257 [GPUCC_GPU_CC_CX_BCR] = { 0x1068 },258 [GPUCC_GPU_CC_GMU_BCR] = { 0x111c },259 [GPUCC_GPU_CC_GX_BCR] = { 0x1008 },260 [GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 },261 [GPUCC_GPU_CC_XO_BCR] = { 0x1000 },262};263 264static struct gdsc *gpu_cc_sm8150_gdscs[] = {265 [GPU_CX_GDSC] = &gpu_cx_gdsc,266 [GPU_GX_GDSC] = &gpu_gx_gdsc,267};268 269static const struct regmap_config gpu_cc_sm8150_regmap_config = {270 .reg_bits = 32,271 .reg_stride = 4,272 .val_bits = 32,273 .max_register = 0x8008,274 .fast_io = true,275};276 277static const struct qcom_cc_desc gpu_cc_sm8150_desc = {278 .config = &gpu_cc_sm8150_regmap_config,279 .clks = gpu_cc_sm8150_clocks,280 .num_clks = ARRAY_SIZE(gpu_cc_sm8150_clocks),281 .resets = gpu_cc_sm8150_resets,282 .num_resets = ARRAY_SIZE(gpu_cc_sm8150_resets),283 .gdscs = gpu_cc_sm8150_gdscs,284 .num_gdscs = ARRAY_SIZE(gpu_cc_sm8150_gdscs),285};286 287static const struct of_device_id gpu_cc_sm8150_match_table[] = {288 { .compatible = "qcom,sc8180x-gpucc" },289 { .compatible = "qcom,sm8150-gpucc" },290 { }291};292MODULE_DEVICE_TABLE(of, gpu_cc_sm8150_match_table);293 294static int gpu_cc_sm8150_probe(struct platform_device *pdev)295{296 struct regmap *regmap;297 298 regmap = qcom_cc_map(pdev, &gpu_cc_sm8150_desc);299 if (IS_ERR(regmap))300 return PTR_ERR(regmap);301 302 if (of_device_is_compatible(pdev->dev.of_node, "qcom,sc8180x-gpucc"))303 gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sc8180x;304 305 clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);306 307 return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8150_desc, regmap);308}309 310static struct platform_driver gpu_cc_sm8150_driver = {311 .probe = gpu_cc_sm8150_probe,312 .driver = {313 .name = "sm8150-gpucc",314 .of_match_table = gpu_cc_sm8150_match_table,315 },316};317 318module_platform_driver(gpu_cc_sm8150_driver);319 320MODULE_DESCRIPTION("QTI GPUCC SM8150 Driver");321MODULE_LICENSE("GPL v2");322