162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2020, The Linux Foundation. All rights reserved. 462306a36Sopenharmony_ci * Copyright (c) 2020, AngeloGioacchino Del Regno 562306a36Sopenharmony_ci * <angelogioacchino.delregno@somainline.org> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/bitops.h> 962306a36Sopenharmony_ci#include <linux/clk.h> 1062306a36Sopenharmony_ci#include <linux/clk-provider.h> 1162306a36Sopenharmony_ci#include <linux/err.h> 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/platform_device.h> 1562306a36Sopenharmony_ci#include <linux/of.h> 1662306a36Sopenharmony_ci#include <linux/regmap.h> 1762306a36Sopenharmony_ci#include <linux/reset-controller.h> 1862306a36Sopenharmony_ci#include <dt-bindings/clock/qcom,gpucc-sdm660.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include "clk-alpha-pll.h" 2162306a36Sopenharmony_ci#include "common.h" 2262306a36Sopenharmony_ci#include "clk-regmap.h" 2362306a36Sopenharmony_ci#include "clk-pll.h" 2462306a36Sopenharmony_ci#include "clk-rcg.h" 2562306a36Sopenharmony_ci#include "clk-branch.h" 2662306a36Sopenharmony_ci#include "gdsc.h" 2762306a36Sopenharmony_ci#include "reset.h" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cienum { 3062306a36Sopenharmony_ci P_GPU_XO, 3162306a36Sopenharmony_ci P_GPLL0_OUT_MAIN, 3262306a36Sopenharmony_ci P_GPLL0_OUT_MAIN_DIV, 3362306a36Sopenharmony_ci P_GPU_PLL0_PLL_OUT_MAIN, 3462306a36Sopenharmony_ci P_GPU_PLL1_PLL_OUT_MAIN, 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic struct clk_branch gpucc_cxo_clk = { 3862306a36Sopenharmony_ci .halt_reg = 0x1020, 3962306a36Sopenharmony_ci .clkr = { 4062306a36Sopenharmony_ci .enable_reg = 0x1020, 4162306a36Sopenharmony_ci .enable_mask = BIT(0), 4262306a36Sopenharmony_ci .hw.init = &(struct clk_init_data){ 4362306a36Sopenharmony_ci .name = "gpucc_cxo_clk", 4462306a36Sopenharmony_ci .parent_data = &(const struct clk_parent_data){ 4562306a36Sopenharmony_ci .fw_name = "xo" 4662306a36Sopenharmony_ci }, 4762306a36Sopenharmony_ci .num_parents = 1, 4862306a36Sopenharmony_ci .ops = &clk_branch2_ops, 4962306a36Sopenharmony_ci .flags = CLK_IS_CRITICAL, 5062306a36Sopenharmony_ci }, 5162306a36Sopenharmony_ci }, 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic struct pll_vco gpu_vco[] = { 5562306a36Sopenharmony_ci { 1000000000, 2000000000, 0 }, 5662306a36Sopenharmony_ci { 500000000, 1000000000, 2 }, 5762306a36Sopenharmony_ci { 250000000, 500000000, 3 }, 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic struct clk_alpha_pll gpu_pll0_pll_out_main = { 6162306a36Sopenharmony_ci .offset = 0x0, 6262306a36Sopenharmony_ci .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], 6362306a36Sopenharmony_ci .vco_table = gpu_vco, 6462306a36Sopenharmony_ci .num_vco = ARRAY_SIZE(gpu_vco), 6562306a36Sopenharmony_ci .clkr.hw.init = &(struct clk_init_data){ 6662306a36Sopenharmony_ci .name = "gpu_pll0_pll_out_main", 6762306a36Sopenharmony_ci .parent_hws = (const struct clk_hw*[]){ 6862306a36Sopenharmony_ci &gpucc_cxo_clk.clkr.hw, 6962306a36Sopenharmony_ci }, 7062306a36Sopenharmony_ci .num_parents = 1, 7162306a36Sopenharmony_ci .ops = &clk_alpha_pll_ops, 7262306a36Sopenharmony_ci }, 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic struct clk_alpha_pll gpu_pll1_pll_out_main = { 7662306a36Sopenharmony_ci .offset = 0x40, 7762306a36Sopenharmony_ci .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], 7862306a36Sopenharmony_ci .vco_table = gpu_vco, 7962306a36Sopenharmony_ci .num_vco = ARRAY_SIZE(gpu_vco), 8062306a36Sopenharmony_ci .clkr.hw.init = &(struct clk_init_data){ 8162306a36Sopenharmony_ci .name = "gpu_pll1_pll_out_main", 8262306a36Sopenharmony_ci .parent_hws = (const struct clk_hw*[]){ 8362306a36Sopenharmony_ci &gpucc_cxo_clk.clkr.hw, 8462306a36Sopenharmony_ci }, 8562306a36Sopenharmony_ci .num_parents = 1, 8662306a36Sopenharmony_ci .ops = &clk_alpha_pll_ops, 8762306a36Sopenharmony_ci }, 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic const struct parent_map gpucc_parent_map_1[] = { 9162306a36Sopenharmony_ci { P_GPU_XO, 0 }, 9262306a36Sopenharmony_ci { P_GPU_PLL0_PLL_OUT_MAIN, 1 }, 9362306a36Sopenharmony_ci { P_GPU_PLL1_PLL_OUT_MAIN, 3 }, 9462306a36Sopenharmony_ci { P_GPLL0_OUT_MAIN, 5 }, 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic const struct clk_parent_data gpucc_parent_data_1[] = { 9862306a36Sopenharmony_ci { .hw = &gpucc_cxo_clk.clkr.hw }, 9962306a36Sopenharmony_ci { .hw = &gpu_pll0_pll_out_main.clkr.hw }, 10062306a36Sopenharmony_ci { .hw = &gpu_pll1_pll_out_main.clkr.hw }, 10162306a36Sopenharmony_ci { .fw_name = "gcc_gpu_gpll0_clk" }, 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic struct clk_rcg2_gfx3d gfx3d_clk_src = { 10562306a36Sopenharmony_ci .div = 2, 10662306a36Sopenharmony_ci .rcg = { 10762306a36Sopenharmony_ci .cmd_rcgr = 0x1070, 10862306a36Sopenharmony_ci .mnd_width = 0, 10962306a36Sopenharmony_ci .hid_width = 5, 11062306a36Sopenharmony_ci .parent_map = gpucc_parent_map_1, 11162306a36Sopenharmony_ci .clkr.hw.init = &(struct clk_init_data){ 11262306a36Sopenharmony_ci .name = "gfx3d_clk_src", 11362306a36Sopenharmony_ci .parent_data = gpucc_parent_data_1, 11462306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(gpucc_parent_data_1), 11562306a36Sopenharmony_ci .ops = &clk_gfx3d_ops, 11662306a36Sopenharmony_ci .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 11762306a36Sopenharmony_ci }, 11862306a36Sopenharmony_ci }, 11962306a36Sopenharmony_ci .hws = (struct clk_hw*[]){ 12062306a36Sopenharmony_ci &gpucc_cxo_clk.clkr.hw, 12162306a36Sopenharmony_ci &gpu_pll0_pll_out_main.clkr.hw, 12262306a36Sopenharmony_ci &gpu_pll1_pll_out_main.clkr.hw, 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci}; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic struct clk_branch gpucc_gfx3d_clk = { 12762306a36Sopenharmony_ci .halt_reg = 0x1098, 12862306a36Sopenharmony_ci .halt_check = BRANCH_HALT, 12962306a36Sopenharmony_ci .hwcg_reg = 0x1098, 13062306a36Sopenharmony_ci .hwcg_bit = 1, 13162306a36Sopenharmony_ci .clkr = { 13262306a36Sopenharmony_ci .enable_reg = 0x1098, 13362306a36Sopenharmony_ci .enable_mask = BIT(0), 13462306a36Sopenharmony_ci .hw.init = &(struct clk_init_data){ 13562306a36Sopenharmony_ci .name = "gpucc_gfx3d_clk", 13662306a36Sopenharmony_ci .parent_hws = (const struct clk_hw*[]){ 13762306a36Sopenharmony_ci &gfx3d_clk_src.rcg.clkr.hw, 13862306a36Sopenharmony_ci }, 13962306a36Sopenharmony_ci .num_parents = 1, 14062306a36Sopenharmony_ci .ops = &clk_branch2_ops, 14162306a36Sopenharmony_ci .flags = CLK_SET_RATE_PARENT, 14262306a36Sopenharmony_ci }, 14362306a36Sopenharmony_ci }, 14462306a36Sopenharmony_ci}; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic const struct parent_map gpucc_parent_map_0[] = { 14762306a36Sopenharmony_ci { P_GPU_XO, 0 }, 14862306a36Sopenharmony_ci { P_GPLL0_OUT_MAIN, 5 }, 14962306a36Sopenharmony_ci { P_GPLL0_OUT_MAIN_DIV, 6 }, 15062306a36Sopenharmony_ci}; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cistatic const struct clk_parent_data gpucc_parent_data_0[] = { 15362306a36Sopenharmony_ci { .hw = &gpucc_cxo_clk.clkr.hw }, 15462306a36Sopenharmony_ci { .fw_name = "gcc_gpu_gpll0_clk" }, 15562306a36Sopenharmony_ci { .fw_name = "gcc_gpu_gpll0_div_clk" }, 15662306a36Sopenharmony_ci}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic const struct freq_tbl ftbl_rbbmtimer_clk_src[] = { 15962306a36Sopenharmony_ci F(19200000, P_GPU_XO, 1, 0, 0), 16062306a36Sopenharmony_ci { } 16162306a36Sopenharmony_ci}; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic struct clk_rcg2 rbbmtimer_clk_src = { 16462306a36Sopenharmony_ci .cmd_rcgr = 0x10b0, 16562306a36Sopenharmony_ci .mnd_width = 0, 16662306a36Sopenharmony_ci .hid_width = 5, 16762306a36Sopenharmony_ci .parent_map = gpucc_parent_map_0, 16862306a36Sopenharmony_ci .freq_tbl = ftbl_rbbmtimer_clk_src, 16962306a36Sopenharmony_ci .clkr.hw.init = &(struct clk_init_data){ 17062306a36Sopenharmony_ci .name = "rbbmtimer_clk_src", 17162306a36Sopenharmony_ci .parent_data = gpucc_parent_data_0, 17262306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(gpucc_parent_data_0), 17362306a36Sopenharmony_ci .ops = &clk_rcg2_ops, 17462306a36Sopenharmony_ci }, 17562306a36Sopenharmony_ci}; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistatic const struct freq_tbl ftbl_rbcpr_clk_src[] = { 17862306a36Sopenharmony_ci F(19200000, P_GPU_XO, 1, 0, 0), 17962306a36Sopenharmony_ci F(50000000, P_GPLL0_OUT_MAIN_DIV, 6, 0, 0), 18062306a36Sopenharmony_ci { } 18162306a36Sopenharmony_ci}; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistatic struct clk_rcg2 rbcpr_clk_src = { 18462306a36Sopenharmony_ci .cmd_rcgr = 0x1030, 18562306a36Sopenharmony_ci .mnd_width = 0, 18662306a36Sopenharmony_ci .hid_width = 5, 18762306a36Sopenharmony_ci .parent_map = gpucc_parent_map_0, 18862306a36Sopenharmony_ci .freq_tbl = ftbl_rbcpr_clk_src, 18962306a36Sopenharmony_ci .clkr.hw.init = &(struct clk_init_data){ 19062306a36Sopenharmony_ci .name = "rbcpr_clk_src", 19162306a36Sopenharmony_ci .parent_data = gpucc_parent_data_0, 19262306a36Sopenharmony_ci .num_parents = ARRAY_SIZE(gpucc_parent_data_0), 19362306a36Sopenharmony_ci .ops = &clk_rcg2_ops, 19462306a36Sopenharmony_ci }, 19562306a36Sopenharmony_ci}; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic struct clk_branch gpucc_rbbmtimer_clk = { 19862306a36Sopenharmony_ci .halt_reg = 0x10d0, 19962306a36Sopenharmony_ci .halt_check = BRANCH_HALT, 20062306a36Sopenharmony_ci .clkr = { 20162306a36Sopenharmony_ci .enable_reg = 0x10d0, 20262306a36Sopenharmony_ci .enable_mask = BIT(0), 20362306a36Sopenharmony_ci .hw.init = &(struct clk_init_data){ 20462306a36Sopenharmony_ci .name = "gpucc_rbbmtimer_clk", 20562306a36Sopenharmony_ci .parent_hws = (const struct clk_hw*[]){ 20662306a36Sopenharmony_ci &rbbmtimer_clk_src.clkr.hw, 20762306a36Sopenharmony_ci }, 20862306a36Sopenharmony_ci .num_parents = 1, 20962306a36Sopenharmony_ci .flags = CLK_SET_RATE_PARENT, 21062306a36Sopenharmony_ci .ops = &clk_branch2_ops, 21162306a36Sopenharmony_ci }, 21262306a36Sopenharmony_ci }, 21362306a36Sopenharmony_ci}; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistatic struct clk_branch gpucc_rbcpr_clk = { 21662306a36Sopenharmony_ci .halt_reg = 0x1054, 21762306a36Sopenharmony_ci .halt_check = BRANCH_HALT, 21862306a36Sopenharmony_ci .clkr = { 21962306a36Sopenharmony_ci .enable_reg = 0x1054, 22062306a36Sopenharmony_ci .enable_mask = BIT(0), 22162306a36Sopenharmony_ci .hw.init = &(struct clk_init_data){ 22262306a36Sopenharmony_ci .name = "gpucc_rbcpr_clk", 22362306a36Sopenharmony_ci .parent_hws = (const struct clk_hw*[]){ 22462306a36Sopenharmony_ci &rbcpr_clk_src.clkr.hw, 22562306a36Sopenharmony_ci }, 22662306a36Sopenharmony_ci .num_parents = 1, 22762306a36Sopenharmony_ci .flags = CLK_SET_RATE_PARENT, 22862306a36Sopenharmony_ci .ops = &clk_branch2_ops, 22962306a36Sopenharmony_ci }, 23062306a36Sopenharmony_ci }, 23162306a36Sopenharmony_ci}; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_cistatic struct gdsc gpu_cx_gdsc = { 23462306a36Sopenharmony_ci .gdscr = 0x1004, 23562306a36Sopenharmony_ci .gds_hw_ctrl = 0x1008, 23662306a36Sopenharmony_ci .pd = { 23762306a36Sopenharmony_ci .name = "gpu_cx", 23862306a36Sopenharmony_ci }, 23962306a36Sopenharmony_ci .pwrsts = PWRSTS_OFF_ON, 24062306a36Sopenharmony_ci .flags = VOTABLE, 24162306a36Sopenharmony_ci}; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_cistatic struct gdsc gpu_gx_gdsc = { 24462306a36Sopenharmony_ci .gdscr = 0x1094, 24562306a36Sopenharmony_ci .clamp_io_ctrl = 0x130, 24662306a36Sopenharmony_ci .resets = (unsigned int []){ GPU_GX_BCR }, 24762306a36Sopenharmony_ci .reset_count = 1, 24862306a36Sopenharmony_ci .cxcs = (unsigned int []){ 0x1098 }, 24962306a36Sopenharmony_ci .cxc_count = 1, 25062306a36Sopenharmony_ci .pd = { 25162306a36Sopenharmony_ci .name = "gpu_gx", 25262306a36Sopenharmony_ci }, 25362306a36Sopenharmony_ci .parent = &gpu_cx_gdsc.pd, 25462306a36Sopenharmony_ci .pwrsts = PWRSTS_OFF | PWRSTS_ON | PWRSTS_RET, 25562306a36Sopenharmony_ci .flags = CLAMP_IO | SW_RESET | AON_RESET | NO_RET_PERIPH, 25662306a36Sopenharmony_ci}; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic struct gdsc *gpucc_sdm660_gdscs[] = { 25962306a36Sopenharmony_ci [GPU_CX_GDSC] = &gpu_cx_gdsc, 26062306a36Sopenharmony_ci [GPU_GX_GDSC] = &gpu_gx_gdsc, 26162306a36Sopenharmony_ci}; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_cistatic const struct qcom_reset_map gpucc_sdm660_resets[] = { 26462306a36Sopenharmony_ci [GPU_CX_BCR] = { 0x1000 }, 26562306a36Sopenharmony_ci [RBCPR_BCR] = { 0x1050 }, 26662306a36Sopenharmony_ci [GPU_GX_BCR] = { 0x1090 }, 26762306a36Sopenharmony_ci [SPDM_BCR] = { 0x10E0 }, 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic struct clk_regmap *gpucc_sdm660_clocks[] = { 27162306a36Sopenharmony_ci [GPUCC_CXO_CLK] = &gpucc_cxo_clk.clkr, 27262306a36Sopenharmony_ci [GPU_PLL0_PLL] = &gpu_pll0_pll_out_main.clkr, 27362306a36Sopenharmony_ci [GPU_PLL1_PLL] = &gpu_pll1_pll_out_main.clkr, 27462306a36Sopenharmony_ci [GFX3D_CLK_SRC] = &gfx3d_clk_src.rcg.clkr, 27562306a36Sopenharmony_ci [RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr, 27662306a36Sopenharmony_ci [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr, 27762306a36Sopenharmony_ci [GPUCC_RBCPR_CLK] = &gpucc_rbcpr_clk.clkr, 27862306a36Sopenharmony_ci [GPUCC_GFX3D_CLK] = &gpucc_gfx3d_clk.clkr, 27962306a36Sopenharmony_ci [GPUCC_RBBMTIMER_CLK] = &gpucc_rbbmtimer_clk.clkr, 28062306a36Sopenharmony_ci}; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cistatic const struct regmap_config gpucc_660_regmap_config = { 28362306a36Sopenharmony_ci .reg_bits = 32, 28462306a36Sopenharmony_ci .reg_stride = 4, 28562306a36Sopenharmony_ci .val_bits = 32, 28662306a36Sopenharmony_ci .max_register = 0x9034, 28762306a36Sopenharmony_ci .fast_io = true, 28862306a36Sopenharmony_ci}; 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic const struct qcom_cc_desc gpucc_sdm660_desc = { 29162306a36Sopenharmony_ci .config = &gpucc_660_regmap_config, 29262306a36Sopenharmony_ci .clks = gpucc_sdm660_clocks, 29362306a36Sopenharmony_ci .num_clks = ARRAY_SIZE(gpucc_sdm660_clocks), 29462306a36Sopenharmony_ci .resets = gpucc_sdm660_resets, 29562306a36Sopenharmony_ci .num_resets = ARRAY_SIZE(gpucc_sdm660_resets), 29662306a36Sopenharmony_ci .gdscs = gpucc_sdm660_gdscs, 29762306a36Sopenharmony_ci .num_gdscs = ARRAY_SIZE(gpucc_sdm660_gdscs), 29862306a36Sopenharmony_ci}; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_cistatic const struct of_device_id gpucc_sdm660_match_table[] = { 30162306a36Sopenharmony_ci { .compatible = "qcom,gpucc-sdm660" }, 30262306a36Sopenharmony_ci { .compatible = "qcom,gpucc-sdm630" }, 30362306a36Sopenharmony_ci { } 30462306a36Sopenharmony_ci}; 30562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, gpucc_sdm660_match_table); 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic int gpucc_sdm660_probe(struct platform_device *pdev) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci struct regmap *regmap; 31062306a36Sopenharmony_ci struct alpha_pll_config gpu_pll_config = { 31162306a36Sopenharmony_ci .config_ctl_val = 0x4001055b, 31262306a36Sopenharmony_ci .alpha = 0xaaaaab00, 31362306a36Sopenharmony_ci .alpha_en_mask = BIT(24), 31462306a36Sopenharmony_ci .vco_val = 0x2 << 20, 31562306a36Sopenharmony_ci .vco_mask = 0x3 << 20, 31662306a36Sopenharmony_ci .main_output_mask = 0x1, 31762306a36Sopenharmony_ci }; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci regmap = qcom_cc_map(pdev, &gpucc_sdm660_desc); 32062306a36Sopenharmony_ci if (IS_ERR(regmap)) 32162306a36Sopenharmony_ci return PTR_ERR(regmap); 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci /* 800MHz configuration for GPU PLL0 */ 32462306a36Sopenharmony_ci gpu_pll_config.l = 0x29; 32562306a36Sopenharmony_ci gpu_pll_config.alpha_hi = 0xaa; 32662306a36Sopenharmony_ci clk_alpha_pll_configure(&gpu_pll0_pll_out_main, regmap, &gpu_pll_config); 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci /* 740MHz configuration for GPU PLL1 */ 32962306a36Sopenharmony_ci gpu_pll_config.l = 0x26; 33062306a36Sopenharmony_ci gpu_pll_config.alpha_hi = 0x8a; 33162306a36Sopenharmony_ci clk_alpha_pll_configure(&gpu_pll1_pll_out_main, regmap, &gpu_pll_config); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci return qcom_cc_really_probe(pdev, &gpucc_sdm660_desc, regmap); 33462306a36Sopenharmony_ci} 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cistatic struct platform_driver gpucc_sdm660_driver = { 33762306a36Sopenharmony_ci .probe = gpucc_sdm660_probe, 33862306a36Sopenharmony_ci .driver = { 33962306a36Sopenharmony_ci .name = "gpucc-sdm660", 34062306a36Sopenharmony_ci .of_match_table = gpucc_sdm660_match_table, 34162306a36Sopenharmony_ci }, 34262306a36Sopenharmony_ci}; 34362306a36Sopenharmony_cimodule_platform_driver(gpucc_sdm660_driver); 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ciMODULE_DESCRIPTION("Qualcomm SDM630/SDM660 GPUCC Driver"); 34662306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 347