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