609 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Based on dispcc-qcm2290.c4 * Copyright (c) 2020, The Linux Foundation. All rights reserved.5 * Copyright (c) 2021, Linaro Ltd.6 */7 8#include <linux/err.h>9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/of.h>12#include <linux/platform_device.h>13#include <linux/regmap.h>14 15#include <dt-bindings/clock/qcom,sm6115-dispcc.h>16 17#include "clk-alpha-pll.h"18#include "clk-branch.h"19#include "clk-rcg.h"20#include "clk-regmap.h"21#include "clk-regmap-divider.h"22#include "common.h"23#include "gdsc.h"24 25enum {26 DT_BI_TCXO,27 DT_SLEEP_CLK,28 DT_DSI0_PHY_PLL_OUT_BYTECLK,29 DT_DSI0_PHY_PLL_OUT_DSICLK,30 DT_GPLL0_DISP_DIV,31};32 33enum {34 P_BI_TCXO,35 P_DISP_CC_PLL0_OUT_MAIN,36 P_DSI0_PHY_PLL_OUT_BYTECLK,37 P_DSI0_PHY_PLL_OUT_DSICLK,38 P_GPLL0_OUT_MAIN,39 P_SLEEP_CLK,40};41 42static const struct clk_parent_data parent_data_tcxo = { .index = DT_BI_TCXO };43 44static const struct pll_vco spark_vco[] = {45 { 500000000, 1000000000, 2 },46};47 48/* 768MHz configuration */49static const struct alpha_pll_config disp_cc_pll0_config = {50 .l = 0x28,51 .alpha = 0x0,52 .alpha_en_mask = BIT(24),53 .vco_val = 0x2 << 20,54 .vco_mask = GENMASK(21, 20),55 .main_output_mask = BIT(0),56 .config_ctl_val = 0x4001055B,57};58 59static struct clk_alpha_pll disp_cc_pll0 = {60 .offset = 0x0,61 .vco_table = spark_vco,62 .num_vco = ARRAY_SIZE(spark_vco),63 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],64 .clkr = {65 .hw.init = &(struct clk_init_data){66 .name = "disp_cc_pll0",67 .parent_data = &parent_data_tcxo,68 .num_parents = 1,69 .ops = &clk_alpha_pll_ops,70 },71 },72};73 74static const struct clk_div_table post_div_table_disp_cc_pll0_out_main[] = {75 { 0x0, 1 },76 { }77};78static struct clk_alpha_pll_postdiv disp_cc_pll0_out_main = {79 .offset = 0x0,80 .post_div_shift = 8,81 .post_div_table = post_div_table_disp_cc_pll0_out_main,82 .num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_main),83 .width = 4,84 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],85 .clkr.hw.init = &(struct clk_init_data){86 .name = "disp_cc_pll0_out_main",87 .parent_hws = (const struct clk_hw*[]){88 &disp_cc_pll0.clkr.hw,89 },90 .num_parents = 1,91 .flags = CLK_SET_RATE_PARENT,92 .ops = &clk_alpha_pll_postdiv_ops,93 },94};95 96static const struct parent_map disp_cc_parent_map_0[] = {97 { P_BI_TCXO, 0 },98 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },99};100 101static const struct clk_parent_data disp_cc_parent_data_0[] = {102 { .index = DT_BI_TCXO },103 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },104};105 106static const struct parent_map disp_cc_parent_map_1[] = {107 { P_BI_TCXO, 0 },108};109 110static const struct clk_parent_data disp_cc_parent_data_1[] = {111 { .index = DT_BI_TCXO },112};113 114static const struct parent_map disp_cc_parent_map_2[] = {115 { P_BI_TCXO, 0 },116 { P_GPLL0_OUT_MAIN, 4 },117};118 119static const struct clk_parent_data disp_cc_parent_data_2[] = {120 { .index = DT_BI_TCXO },121 { .index = DT_GPLL0_DISP_DIV },122};123 124static const struct parent_map disp_cc_parent_map_3[] = {125 { P_BI_TCXO, 0 },126 { P_DISP_CC_PLL0_OUT_MAIN, 1 },127};128 129static const struct clk_parent_data disp_cc_parent_data_3[] = {130 { .index = DT_BI_TCXO },131 { .hw = &disp_cc_pll0_out_main.clkr.hw },132};133 134static const struct parent_map disp_cc_parent_map_4[] = {135 { P_BI_TCXO, 0 },136 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },137};138 139static const struct clk_parent_data disp_cc_parent_data_4[] = {140 { .index = DT_BI_TCXO },141 { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },142};143 144static const struct parent_map disp_cc_parent_map_5[] = {145 { P_SLEEP_CLK, 0 },146};147 148static const struct clk_parent_data disp_cc_parent_data_5[] = {149 { .index = DT_SLEEP_CLK, },150};151 152static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {153 .cmd_rcgr = 0x20bc,154 .mnd_width = 0,155 .hid_width = 5,156 .parent_map = disp_cc_parent_map_0,157 .clkr.hw.init = &(struct clk_init_data){158 .name = "disp_cc_mdss_byte0_clk_src",159 .parent_data = disp_cc_parent_data_0,160 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),161 /* For set_rate and set_parent to succeed, parent(s) must be enabled */162 .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE,163 .ops = &clk_byte2_ops,164 },165};166 167static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {168 .reg = 0x20d4,169 .shift = 0,170 .width = 2,171 .clkr.hw.init = &(struct clk_init_data) {172 .name = "disp_cc_mdss_byte0_div_clk_src",173 .parent_hws = (const struct clk_hw*[]){174 &disp_cc_mdss_byte0_clk_src.clkr.hw,175 },176 .num_parents = 1,177 .ops = &clk_regmap_div_ops,178 },179};180 181static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {182 F(19200000, P_BI_TCXO, 1, 0, 0),183 F(37500000, P_GPLL0_OUT_MAIN, 8, 0, 0),184 F(75000000, P_GPLL0_OUT_MAIN, 4, 0, 0),185 { }186};187 188static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {189 .cmd_rcgr = 0x2154,190 .mnd_width = 0,191 .hid_width = 5,192 .parent_map = disp_cc_parent_map_2,193 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,194 .clkr.hw.init = &(struct clk_init_data){195 .name = "disp_cc_mdss_ahb_clk_src",196 .parent_data = disp_cc_parent_data_2,197 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),198 .ops = &clk_rcg2_shared_ops,199 },200};201 202static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {203 F(19200000, P_BI_TCXO, 1, 0, 0),204 { }205};206 207static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {208 .cmd_rcgr = 0x20d8,209 .mnd_width = 0,210 .hid_width = 5,211 .parent_map = disp_cc_parent_map_0,212 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,213 .clkr.hw.init = &(struct clk_init_data){214 .name = "disp_cc_mdss_esc0_clk_src",215 .parent_data = disp_cc_parent_data_0,216 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),217 .ops = &clk_rcg2_ops,218 },219};220 221static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {222 F(19200000, P_BI_TCXO, 1, 0, 0),223 F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),224 F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),225 F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),226 F(384000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),227 { }228};229 230static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {231 .cmd_rcgr = 0x2074,232 .mnd_width = 0,233 .hid_width = 5,234 .parent_map = disp_cc_parent_map_3,235 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,236 .clkr.hw.init = &(struct clk_init_data){237 .name = "disp_cc_mdss_mdp_clk_src",238 .parent_data = disp_cc_parent_data_3,239 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),240 .flags = CLK_SET_RATE_PARENT,241 .ops = &clk_rcg2_shared_ops,242 },243};244 245static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {246 .cmd_rcgr = 0x205c,247 .mnd_width = 8,248 .hid_width = 5,249 .parent_map = disp_cc_parent_map_4,250 .clkr.hw.init = &(struct clk_init_data){251 .name = "disp_cc_mdss_pclk0_clk_src",252 .parent_data = disp_cc_parent_data_4,253 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),254 /* For set_rate and set_parent to succeed, parent(s) must be enabled */255 .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE,256 .ops = &clk_pixel_ops,257 },258};259 260static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = {261 F(19200000, P_BI_TCXO, 1, 0, 0),262 F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),263 F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),264 F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),265 { }266};267 268static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {269 .cmd_rcgr = 0x208c,270 .mnd_width = 0,271 .hid_width = 5,272 .parent_map = disp_cc_parent_map_3,273 .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src,274 .clkr.hw.init = &(struct clk_init_data){275 .name = "disp_cc_mdss_rot_clk_src",276 .parent_data = disp_cc_parent_data_3,277 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),278 .flags = CLK_SET_RATE_PARENT,279 .ops = &clk_rcg2_shared_ops,280 },281};282 283static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {284 .cmd_rcgr = 0x20a4,285 .mnd_width = 0,286 .hid_width = 5,287 .parent_map = disp_cc_parent_map_1,288 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,289 .clkr.hw.init = &(struct clk_init_data){290 .name = "disp_cc_mdss_vsync_clk_src",291 .parent_data = disp_cc_parent_data_1,292 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),293 .flags = CLK_SET_RATE_PARENT,294 .ops = &clk_rcg2_shared_ops,295 },296};297 298static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {299 F(32764, P_SLEEP_CLK, 1, 0, 0),300 { }301};302 303static struct clk_rcg2 disp_cc_sleep_clk_src = {304 .cmd_rcgr = 0x6050,305 .mnd_width = 0,306 .hid_width = 5,307 .parent_map = disp_cc_parent_map_5,308 .freq_tbl = ftbl_disp_cc_sleep_clk_src,309 .clkr.hw.init = &(struct clk_init_data){310 .name = "disp_cc_sleep_clk_src",311 .parent_data = disp_cc_parent_data_5,312 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),313 .ops = &clk_rcg2_ops,314 },315};316 317static struct clk_branch disp_cc_mdss_ahb_clk = {318 .halt_reg = 0x2044,319 .halt_check = BRANCH_HALT,320 .clkr = {321 .enable_reg = 0x2044,322 .enable_mask = BIT(0),323 .hw.init = &(struct clk_init_data){324 .name = "disp_cc_mdss_ahb_clk",325 .parent_hws = (const struct clk_hw*[]){326 &disp_cc_mdss_ahb_clk_src.clkr.hw,327 },328 .num_parents = 1,329 .flags = CLK_SET_RATE_PARENT,330 .ops = &clk_branch2_ops,331 },332 },333};334 335static struct clk_branch disp_cc_mdss_byte0_clk = {336 .halt_reg = 0x2024,337 .halt_check = BRANCH_HALT,338 .clkr = {339 .enable_reg = 0x2024,340 .enable_mask = BIT(0),341 .hw.init = &(struct clk_init_data){342 .name = "disp_cc_mdss_byte0_clk",343 .parent_hws = (const struct clk_hw*[]){344 &disp_cc_mdss_byte0_clk_src.clkr.hw,345 },346 .num_parents = 1,347 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,348 .ops = &clk_branch2_ops,349 },350 },351};352 353static struct clk_branch disp_cc_mdss_byte0_intf_clk = {354 .halt_reg = 0x2028,355 .halt_check = BRANCH_HALT,356 .clkr = {357 .enable_reg = 0x2028,358 .enable_mask = BIT(0),359 .hw.init = &(struct clk_init_data){360 .name = "disp_cc_mdss_byte0_intf_clk",361 .parent_hws = (const struct clk_hw*[]){362 &disp_cc_mdss_byte0_div_clk_src.clkr.hw,363 },364 .num_parents = 1,365 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,366 .ops = &clk_branch2_ops,367 },368 },369};370 371static struct clk_branch disp_cc_mdss_esc0_clk = {372 .halt_reg = 0x202c,373 .halt_check = BRANCH_HALT,374 .clkr = {375 .enable_reg = 0x202c,376 .enable_mask = BIT(0),377 .hw.init = &(struct clk_init_data){378 .name = "disp_cc_mdss_esc0_clk",379 .parent_hws = (const struct clk_hw*[]){380 &disp_cc_mdss_esc0_clk_src.clkr.hw,381 },382 .num_parents = 1,383 .flags = CLK_SET_RATE_PARENT,384 .ops = &clk_branch2_ops,385 },386 },387};388 389static struct clk_branch disp_cc_mdss_mdp_clk = {390 .halt_reg = 0x2008,391 .halt_check = BRANCH_HALT,392 .clkr = {393 .enable_reg = 0x2008,394 .enable_mask = BIT(0),395 .hw.init = &(struct clk_init_data){396 .name = "disp_cc_mdss_mdp_clk",397 .parent_hws = (const struct clk_hw*[]){398 &disp_cc_mdss_mdp_clk_src.clkr.hw,399 },400 .num_parents = 1,401 .flags = CLK_SET_RATE_PARENT,402 .ops = &clk_branch2_ops,403 },404 },405};406 407static struct clk_branch disp_cc_mdss_mdp_lut_clk = {408 .halt_reg = 0x2018,409 .halt_check = BRANCH_HALT_VOTED,410 .clkr = {411 .enable_reg = 0x2018,412 .enable_mask = BIT(0),413 .hw.init = &(struct clk_init_data){414 .name = "disp_cc_mdss_mdp_lut_clk",415 .parent_hws = (const struct clk_hw*[]){416 &disp_cc_mdss_mdp_clk_src.clkr.hw,417 },418 .num_parents = 1,419 .flags = CLK_SET_RATE_PARENT,420 .ops = &clk_branch2_ops,421 },422 },423};424 425static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {426 .halt_reg = 0x4004,427 .halt_check = BRANCH_HALT_VOTED,428 .clkr = {429 .enable_reg = 0x4004,430 .enable_mask = BIT(0),431 .hw.init = &(struct clk_init_data){432 .name = "disp_cc_mdss_non_gdsc_ahb_clk",433 .parent_hws = (const struct clk_hw*[]){434 &disp_cc_mdss_ahb_clk_src.clkr.hw,435 },436 .num_parents = 1,437 .flags = CLK_SET_RATE_PARENT,438 .ops = &clk_branch2_ops,439 },440 },441};442 443static struct clk_branch disp_cc_mdss_pclk0_clk = {444 .halt_reg = 0x2004,445 .halt_check = BRANCH_HALT,446 .clkr = {447 .enable_reg = 0x2004,448 .enable_mask = BIT(0),449 .hw.init = &(struct clk_init_data){450 .name = "disp_cc_mdss_pclk0_clk",451 .parent_hws = (const struct clk_hw*[]){452 &disp_cc_mdss_pclk0_clk_src.clkr.hw,453 },454 .num_parents = 1,455 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,456 .ops = &clk_branch2_ops,457 },458 },459};460 461static struct clk_branch disp_cc_mdss_rot_clk = {462 .halt_reg = 0x2010,463 .halt_check = BRANCH_HALT,464 .clkr = {465 .enable_reg = 0x2010,466 .enable_mask = BIT(0),467 .hw.init = &(struct clk_init_data){468 .name = "disp_cc_mdss_rot_clk",469 .parent_hws = (const struct clk_hw*[]) {470 &disp_cc_mdss_rot_clk_src.clkr.hw,471 },472 .num_parents = 1,473 .flags = CLK_SET_RATE_PARENT,474 .ops = &clk_branch2_ops,475 },476 },477};478 479static struct clk_branch disp_cc_mdss_vsync_clk = {480 .halt_reg = 0x2020,481 .halt_check = BRANCH_HALT,482 .clkr = {483 .enable_reg = 0x2020,484 .enable_mask = BIT(0),485 .hw.init = &(struct clk_init_data){486 .name = "disp_cc_mdss_vsync_clk",487 .parent_hws = (const struct clk_hw*[]){488 &disp_cc_mdss_vsync_clk_src.clkr.hw,489 },490 .num_parents = 1,491 .flags = CLK_SET_RATE_PARENT,492 .ops = &clk_branch2_ops,493 },494 },495};496 497static struct clk_branch disp_cc_sleep_clk = {498 .halt_reg = 0x6068,499 .halt_check = BRANCH_HALT,500 .clkr = {501 .enable_reg = 0x6068,502 .enable_mask = BIT(0),503 .hw.init = &(struct clk_init_data){504 .name = "disp_cc_sleep_clk",505 .parent_hws = (const struct clk_hw*[]){506 &disp_cc_sleep_clk_src.clkr.hw,507 },508 .num_parents = 1,509 .flags = CLK_SET_RATE_PARENT,510 .ops = &clk_branch2_ops,511 },512 },513};514 515static struct gdsc mdss_gdsc = {516 .gdscr = 0x3000,517 .pd = {518 .name = "mdss_gdsc",519 },520 .pwrsts = PWRSTS_OFF_ON,521 .flags = HW_CTRL,522};523 524static struct gdsc *disp_cc_sm6115_gdscs[] = {525 [MDSS_GDSC] = &mdss_gdsc,526};527 528static struct clk_regmap *disp_cc_sm6115_clocks[] = {529 [DISP_CC_PLL0] = &disp_cc_pll0.clkr,530 [DISP_CC_PLL0_OUT_MAIN] = &disp_cc_pll0_out_main.clkr,531 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,532 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,533 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,534 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,535 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,536 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,537 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,538 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,539 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,540 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,541 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,542 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,543 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,544 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,545 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,546 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,547 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,548 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,549 [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,550 [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,551};552 553static const struct regmap_config disp_cc_sm6115_regmap_config = {554 .reg_bits = 32,555 .reg_stride = 4,556 .val_bits = 32,557 .max_register = 0x10000,558 .fast_io = true,559};560 561static const struct qcom_cc_desc disp_cc_sm6115_desc = {562 .config = &disp_cc_sm6115_regmap_config,563 .clks = disp_cc_sm6115_clocks,564 .num_clks = ARRAY_SIZE(disp_cc_sm6115_clocks),565 .gdscs = disp_cc_sm6115_gdscs,566 .num_gdscs = ARRAY_SIZE(disp_cc_sm6115_gdscs),567};568 569static const struct of_device_id disp_cc_sm6115_match_table[] = {570 { .compatible = "qcom,sm6115-dispcc" },571 { }572};573MODULE_DEVICE_TABLE(of, disp_cc_sm6115_match_table);574 575static int disp_cc_sm6115_probe(struct platform_device *pdev)576{577 struct regmap *regmap;578 int ret;579 580 regmap = qcom_cc_map(pdev, &disp_cc_sm6115_desc);581 if (IS_ERR(regmap))582 return PTR_ERR(regmap);583 584 clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);585 586 /* Keep some clocks always-on */587 qcom_branch_set_clk_en(regmap, 0x604c); /* DISP_CC_XO_CLK */588 589 ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6115_desc, regmap);590 if (ret) {591 dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");592 return ret;593 }594 595 return ret;596}597 598static struct platform_driver disp_cc_sm6115_driver = {599 .probe = disp_cc_sm6115_probe,600 .driver = {601 .name = "dispcc-sm6115",602 .of_match_table = disp_cc_sm6115_match_table,603 },604};605 606module_platform_driver(disp_cc_sm6115_driver);607MODULE_DESCRIPTION("Qualcomm SM6115 Display Clock controller");608MODULE_LICENSE("GPL");609