1007 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.4 * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>5 * Copyright (c) 2024, David Wronek <david@mainlining.org>6 */7 8#include <linux/clk-provider.h>9#include <linux/mod_devicetable.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,sm7150-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_BI_TCXO_AO,28 DT_GCC_DISP_GPLL0_CLK,29 DT_CHIP_SLEEP_CLK,30 DT_DSI0_PHY_PLL_OUT_BYTECLK,31 DT_DSI0_PHY_PLL_OUT_DSICLK,32 DT_DSI1_PHY_PLL_OUT_BYTECLK,33 DT_DSI1_PHY_PLL_OUT_DSICLK,34 DT_DP_PHY_PLL_LINK_CLK,35 DT_DP_PHY_PLL_VCO_DIV_CLK,36};37 38enum {39 P_BI_TCXO,40 P_CHIP_SLEEP_CLK,41 P_DISPCC_PLL0_OUT_EVEN,42 P_DISPCC_PLL0_OUT_MAIN,43 P_DP_PHY_PLL_LINK_CLK,44 P_DP_PHY_PLL_VCO_DIV_CLK,45 P_DSI0_PHY_PLL_OUT_BYTECLK,46 P_DSI0_PHY_PLL_OUT_DSICLK,47 P_DSI1_PHY_PLL_OUT_BYTECLK,48 P_DSI1_PHY_PLL_OUT_DSICLK,49 P_GCC_DISP_GPLL0_CLK,50};51 52static const struct pll_vco fabia_vco[] = {53 { 249600000, 2000000000, 0 },54 { 125000000, 1000000000, 1 },55};56 57/* 860MHz configuration */58static const struct alpha_pll_config dispcc_pll0_config = {59 .l = 0x2c,60 .alpha = 0xcaaa,61 .test_ctl_val = 0x40000000,62};63 64static struct clk_alpha_pll dispcc_pll0 = {65 .offset = 0x0,66 .vco_table = fabia_vco,67 .num_vco = ARRAY_SIZE(fabia_vco),68 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],69 .clkr = {70 .hw.init = &(const struct clk_init_data) {71 .name = "dispcc_pll0",72 .parent_data = &(const struct clk_parent_data) {73 .index = DT_BI_TCXO,74 },75 .num_parents = 1,76 .ops = &clk_alpha_pll_fabia_ops,77 },78 },79};80 81static const struct parent_map dispcc_parent_map_0[] = {82 { P_BI_TCXO, 0 },83 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },84 { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },85};86 87static const struct clk_parent_data dispcc_parent_data_0[] = {88 { .index = DT_BI_TCXO },89 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },90 { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },91};92 93static const struct parent_map dispcc_parent_map_1[] = {94 { P_BI_TCXO, 0 },95 { P_DP_PHY_PLL_LINK_CLK, 1 },96 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },97};98 99static const struct clk_parent_data dispcc_parent_data_1[] = {100 { .index = DT_BI_TCXO },101 { .index = DT_DP_PHY_PLL_LINK_CLK },102 { .index = DT_DP_PHY_PLL_VCO_DIV_CLK },103};104 105static const struct parent_map dispcc_parent_map_2[] = {106 { P_BI_TCXO, 0 },107};108 109static const struct clk_parent_data dispcc_parent_data_2[] = {110 { .index = DT_BI_TCXO },111};112 113static const struct clk_parent_data dispcc_parent_data_2_ao[] = {114 { .index = DT_BI_TCXO_AO },115};116 117static const struct parent_map dispcc_parent_map_3[] = {118 { P_BI_TCXO, 0 },119 { P_DISPCC_PLL0_OUT_MAIN, 1 },120 { P_GCC_DISP_GPLL0_CLK, 4 },121 { P_DISPCC_PLL0_OUT_EVEN, 5 },122};123 124static const struct clk_parent_data dispcc_parent_data_3[] = {125 { .index = DT_BI_TCXO },126 { .hw = &dispcc_pll0.clkr.hw },127 { .index = DT_GCC_DISP_GPLL0_CLK },128 { .hw = &dispcc_pll0.clkr.hw },129};130 131static const struct parent_map dispcc_parent_map_4[] = {132 { P_BI_TCXO, 0 },133 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },134 { P_DSI1_PHY_PLL_OUT_DSICLK, 2 },135};136 137static const struct clk_parent_data dispcc_parent_data_4[] = {138 { .index = DT_BI_TCXO },139 { .index = DT_DSI0_PHY_PLL_OUT_DSICLK },140 { .index = DT_DSI1_PHY_PLL_OUT_DSICLK },141};142 143static const struct parent_map dispcc_parent_map_5[] = {144 { P_BI_TCXO, 0 },145 { P_GCC_DISP_GPLL0_CLK, 4 },146};147 148static const struct clk_parent_data dispcc_parent_data_5[] = {149 { .index = DT_BI_TCXO },150 { .index = DT_GCC_DISP_GPLL0_CLK },151};152 153static const struct parent_map dispcc_parent_map_6[] = {154 { P_CHIP_SLEEP_CLK, 0 },155};156 157static const struct clk_parent_data dispcc_parent_data_6[] = {158 { .index = DT_CHIP_SLEEP_CLK },159};160 161static const struct freq_tbl ftbl_dispcc_mdss_ahb_clk_src[] = {162 F(19200000, P_BI_TCXO, 1, 0, 0),163 F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0),164 F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),165 { }166};167 168static struct clk_rcg2 dispcc_mdss_ahb_clk_src = {169 .cmd_rcgr = 0x22bc,170 .mnd_width = 0,171 .hid_width = 5,172 .parent_map = dispcc_parent_map_5,173 .freq_tbl = ftbl_dispcc_mdss_ahb_clk_src,174 .clkr.hw.init = &(const struct clk_init_data) {175 .name = "dispcc_mdss_ahb_clk_src",176 .parent_data = dispcc_parent_data_5,177 .num_parents = ARRAY_SIZE(dispcc_parent_data_5),178 .flags = CLK_SET_RATE_PARENT,179 .ops = &clk_rcg2_shared_ops,180 },181};182 183static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src[] = {184 F(19200000, P_BI_TCXO, 1, 0, 0),185 { }186};187 188static struct clk_rcg2 dispcc_mdss_byte0_clk_src = {189 .cmd_rcgr = 0x2110,190 .mnd_width = 0,191 .hid_width = 5,192 .parent_map = dispcc_parent_map_0,193 .clkr.hw.init = &(const struct clk_init_data) {194 .name = "dispcc_mdss_byte0_clk_src",195 .parent_data = dispcc_parent_data_0,196 .num_parents = ARRAY_SIZE(dispcc_parent_data_0),197 .flags = CLK_SET_RATE_PARENT,198 .ops = &clk_byte2_ops,199 },200};201 202static struct clk_rcg2 dispcc_mdss_byte1_clk_src = {203 .cmd_rcgr = 0x212c,204 .mnd_width = 0,205 .hid_width = 5,206 .parent_map = dispcc_parent_map_0,207 .clkr.hw.init = &(const struct clk_init_data) {208 .name = "dispcc_mdss_byte1_clk_src",209 .parent_data = dispcc_parent_data_0,210 .num_parents = ARRAY_SIZE(dispcc_parent_data_0),211 .flags = CLK_SET_RATE_PARENT,212 .ops = &clk_byte2_ops,213 },214};215 216static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src = {217 .cmd_rcgr = 0x21dc,218 .mnd_width = 0,219 .hid_width = 5,220 .parent_map = dispcc_parent_map_2,221 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,222 .clkr.hw.init = &(const struct clk_init_data) {223 .name = "dispcc_mdss_dp_aux_clk_src",224 .parent_data = dispcc_parent_data_2,225 .num_parents = ARRAY_SIZE(dispcc_parent_data_2),226 .ops = &clk_rcg2_ops,227 },228};229 230static const struct freq_tbl ftbl_dispcc_mdss_dp_crypto_clk_src[] = {231 F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),232 F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),233 F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),234 F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),235 { }236};237 238static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src = {239 .cmd_rcgr = 0x2194,240 .mnd_width = 0,241 .hid_width = 5,242 .parent_map = dispcc_parent_map_1,243 .freq_tbl = ftbl_dispcc_mdss_dp_crypto_clk_src,244 .clkr.hw.init = &(const struct clk_init_data) {245 .name = "dispcc_mdss_dp_crypto_clk_src",246 .parent_data = dispcc_parent_data_1,247 .num_parents = ARRAY_SIZE(dispcc_parent_data_1),248 .ops = &clk_rcg2_ops,249 },250};251 252static struct clk_rcg2 dispcc_mdss_dp_link_clk_src = {253 .cmd_rcgr = 0x2178,254 .mnd_width = 0,255 .hid_width = 5,256 .parent_map = dispcc_parent_map_1,257 .clkr.hw.init = &(const struct clk_init_data) {258 .name = "dispcc_mdss_dp_link_clk_src",259 .parent_data = dispcc_parent_data_1,260 .num_parents = ARRAY_SIZE(dispcc_parent_data_1),261 .flags = CLK_SET_RATE_PARENT,262 .ops = &clk_byte2_ops,263 },264};265 266static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src = {267 .cmd_rcgr = 0x21c4,268 .mnd_width = 16,269 .hid_width = 5,270 .parent_map = dispcc_parent_map_1,271 .clkr.hw.init = &(const struct clk_init_data) {272 .name = "dispcc_mdss_dp_pixel1_clk_src",273 .parent_data = dispcc_parent_data_1,274 .num_parents = ARRAY_SIZE(dispcc_parent_data_1),275 .flags = CLK_SET_RATE_PARENT,276 .ops = &clk_dp_ops,277 },278};279 280static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src = {281 .cmd_rcgr = 0x21ac,282 .mnd_width = 16,283 .hid_width = 5,284 .parent_map = dispcc_parent_map_1,285 .clkr.hw.init = &(const struct clk_init_data) {286 .name = "dispcc_mdss_dp_pixel_clk_src",287 .parent_data = dispcc_parent_data_1,288 .num_parents = ARRAY_SIZE(dispcc_parent_data_1),289 .flags = CLK_SET_RATE_PARENT,290 .ops = &clk_dp_ops,291 },292};293 294static struct clk_rcg2 dispcc_mdss_esc0_clk_src = {295 .cmd_rcgr = 0x2148,296 .mnd_width = 0,297 .hid_width = 5,298 .parent_map = dispcc_parent_map_0,299 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,300 .clkr.hw.init = &(const struct clk_init_data) {301 .name = "dispcc_mdss_esc0_clk_src",302 .parent_data = dispcc_parent_data_0,303 .num_parents = ARRAY_SIZE(dispcc_parent_data_0),304 .ops = &clk_rcg2_ops,305 },306};307 308static struct clk_rcg2 dispcc_mdss_esc1_clk_src = {309 .cmd_rcgr = 0x2160,310 .mnd_width = 0,311 .hid_width = 5,312 .parent_map = dispcc_parent_map_0,313 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,314 .clkr.hw.init = &(const struct clk_init_data) {315 .name = "dispcc_mdss_esc1_clk_src",316 .parent_data = dispcc_parent_data_0,317 .num_parents = ARRAY_SIZE(dispcc_parent_data_0),318 .ops = &clk_rcg2_ops,319 },320};321 322static const struct freq_tbl ftbl_dispcc_mdss_mdp_clk_src[] = {323 F(19200000, P_BI_TCXO, 1, 0, 0),324 F(85714286, P_GCC_DISP_GPLL0_CLK, 7, 0, 0),325 F(100000000, P_GCC_DISP_GPLL0_CLK, 6, 0, 0),326 F(150000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0),327 F(172000000, P_DISPCC_PLL0_OUT_MAIN, 5, 0, 0),328 F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),329 F(286666667, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0),330 F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),331 F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0),332 F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0),333 { }334};335 336static struct clk_rcg2 dispcc_mdss_mdp_clk_src = {337 .cmd_rcgr = 0x20c8,338 .mnd_width = 0,339 .hid_width = 5,340 .parent_map = dispcc_parent_map_3,341 .freq_tbl = ftbl_dispcc_mdss_mdp_clk_src,342 .clkr.hw.init = &(const struct clk_init_data) {343 .name = "dispcc_mdss_mdp_clk_src",344 .parent_data = dispcc_parent_data_3,345 .num_parents = ARRAY_SIZE(dispcc_parent_data_3),346 .flags = CLK_SET_RATE_PARENT,347 .ops = &clk_rcg2_shared_ops,348 },349};350 351static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = {352 .cmd_rcgr = 0x2098,353 .mnd_width = 8,354 .hid_width = 5,355 .parent_map = dispcc_parent_map_4,356 .clkr.hw.init = &(const struct clk_init_data) {357 .name = "dispcc_mdss_pclk0_clk_src",358 .parent_data = dispcc_parent_data_4,359 .num_parents = ARRAY_SIZE(dispcc_parent_data_4),360 .flags = CLK_SET_RATE_PARENT,361 .ops = &clk_pixel_ops,362 },363};364 365static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = {366 .cmd_rcgr = 0x20b0,367 .mnd_width = 8,368 .hid_width = 5,369 .parent_map = dispcc_parent_map_4,370 .clkr.hw.init = &(const struct clk_init_data) {371 .name = "dispcc_mdss_pclk1_clk_src",372 .parent_data = dispcc_parent_data_4,373 .num_parents = ARRAY_SIZE(dispcc_parent_data_4),374 .flags = CLK_SET_RATE_PARENT,375 .ops = &clk_pixel_ops,376 },377};378 379static const struct freq_tbl ftbl_dispcc_mdss_rot_clk_src[] = {380 F(19200000, P_BI_TCXO, 1, 0, 0),381 F(171428571, P_GCC_DISP_GPLL0_CLK, 3.5, 0, 0),382 F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),383 F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),384 F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0),385 F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0),386 { }387};388 389static struct clk_rcg2 dispcc_mdss_rot_clk_src = {390 .cmd_rcgr = 0x20e0,391 .mnd_width = 0,392 .hid_width = 5,393 .parent_map = dispcc_parent_map_3,394 .freq_tbl = ftbl_dispcc_mdss_rot_clk_src,395 .clkr.hw.init = &(const struct clk_init_data) {396 .name = "dispcc_mdss_rot_clk_src",397 .parent_data = dispcc_parent_data_3,398 .num_parents = ARRAY_SIZE(dispcc_parent_data_3),399 .ops = &clk_rcg2_shared_ops,400 },401};402 403static struct clk_rcg2 dispcc_mdss_vsync_clk_src = {404 .cmd_rcgr = 0x20f8,405 .mnd_width = 0,406 .hid_width = 5,407 .parent_map = dispcc_parent_map_2,408 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,409 .clkr.hw.init = &(const struct clk_init_data) {410 .name = "dispcc_mdss_vsync_clk_src",411 .parent_data = dispcc_parent_data_2,412 .num_parents = ARRAY_SIZE(dispcc_parent_data_2),413 .ops = &clk_rcg2_ops,414 },415};416 417static const struct freq_tbl ftbl_dispcc_sleep_clk_src[] = {418 F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0),419 { }420};421 422static struct clk_rcg2 dispcc_sleep_clk_src = {423 .cmd_rcgr = 0x6060,424 .mnd_width = 0,425 .hid_width = 5,426 .parent_map = dispcc_parent_map_6,427 .freq_tbl = ftbl_dispcc_sleep_clk_src,428 .clkr.hw.init = &(const struct clk_init_data) {429 .name = "dispcc_sleep_clk_src",430 .parent_data = dispcc_parent_data_6,431 .num_parents = ARRAY_SIZE(dispcc_parent_data_6),432 .ops = &clk_rcg2_ops,433 },434};435 436static struct clk_rcg2 dispcc_xo_clk_src = {437 .cmd_rcgr = 0x6044,438 .mnd_width = 0,439 .hid_width = 5,440 .parent_map = dispcc_parent_map_2,441 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,442 .clkr.hw.init = &(const struct clk_init_data) {443 .name = "dispcc_xo_clk_src",444 .parent_data = dispcc_parent_data_2_ao,445 .num_parents = ARRAY_SIZE(dispcc_parent_data_2_ao),446 .ops = &clk_rcg2_ops,447 },448};449 450static struct clk_branch dispcc_mdss_ahb_clk = {451 .halt_reg = 0x2080,452 .halt_check = BRANCH_HALT,453 .clkr = {454 .enable_reg = 0x2080,455 .enable_mask = BIT(0),456 .hw.init = &(const struct clk_init_data) {457 .name = "dispcc_mdss_ahb_clk",458 .parent_hws = (const struct clk_hw*[]) {459 &dispcc_mdss_ahb_clk_src.clkr.hw,460 },461 .num_parents = 1,462 .flags = CLK_SET_RATE_PARENT,463 .ops = &clk_branch2_ops,464 },465 },466};467 468static struct clk_branch dispcc_mdss_byte0_clk = {469 .halt_reg = 0x2028,470 .halt_check = BRANCH_HALT,471 .clkr = {472 .enable_reg = 0x2028,473 .enable_mask = BIT(0),474 .hw.init = &(const struct clk_init_data) {475 .name = "dispcc_mdss_byte0_clk",476 .parent_hws = (const struct clk_hw*[]) {477 &dispcc_mdss_byte0_clk_src.clkr.hw,478 },479 .num_parents = 1,480 .flags = CLK_SET_RATE_PARENT,481 .ops = &clk_branch2_ops,482 },483 },484};485 486static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src = {487 .reg = 0x2128,488 .shift = 0,489 .width = 2,490 .clkr = {491 .hw.init = &(const struct clk_init_data) {492 .name = "dispcc_mdss_byte0_div_clk_src",493 .parent_hws = (const struct clk_hw*[]) {494 &dispcc_mdss_byte0_clk_src.clkr.hw,495 },496 .num_parents = 1,497 .ops = &clk_regmap_div_ops,498 },499 },500};501 502static struct clk_branch dispcc_mdss_byte0_intf_clk = {503 .halt_reg = 0x202c,504 .halt_check = BRANCH_HALT,505 .clkr = {506 .enable_reg = 0x202c,507 .enable_mask = BIT(0),508 .hw.init = &(const struct clk_init_data) {509 .name = "dispcc_mdss_byte0_intf_clk",510 .parent_hws = (const struct clk_hw*[]) {511 &dispcc_mdss_byte0_div_clk_src.clkr.hw,512 },513 .num_parents = 1,514 .ops = &clk_branch2_ops,515 },516 },517};518 519static struct clk_branch dispcc_mdss_byte1_clk = {520 .halt_reg = 0x2030,521 .halt_check = BRANCH_HALT,522 .clkr = {523 .enable_reg = 0x2030,524 .enable_mask = BIT(0),525 .hw.init = &(const struct clk_init_data) {526 .name = "dispcc_mdss_byte1_clk",527 .parent_hws = (const struct clk_hw*[]) {528 &dispcc_mdss_byte1_clk_src.clkr.hw,529 },530 .num_parents = 1,531 .flags = CLK_SET_RATE_PARENT,532 .ops = &clk_branch2_ops,533 },534 },535};536 537static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src = {538 .reg = 0x2144,539 .shift = 0,540 .width = 2,541 .clkr = {542 .hw.init = &(const struct clk_init_data) {543 .name = "dispcc_mdss_byte1_div_clk_src",544 .parent_hws = (const struct clk_hw*[]) {545 &dispcc_mdss_byte1_clk_src.clkr.hw,546 },547 .num_parents = 1,548 .ops = &clk_regmap_div_ops,549 },550 },551};552 553static struct clk_branch dispcc_mdss_byte1_intf_clk = {554 .halt_reg = 0x2034,555 .halt_check = BRANCH_HALT,556 .clkr = {557 .enable_reg = 0x2034,558 .enable_mask = BIT(0),559 .hw.init = &(const struct clk_init_data) {560 .name = "dispcc_mdss_byte1_intf_clk",561 .parent_hws = (const struct clk_hw*[]) {562 &dispcc_mdss_byte1_div_clk_src.clkr.hw,563 },564 .num_parents = 1,565 .flags = CLK_SET_RATE_PARENT,566 .ops = &clk_branch2_ops,567 },568 },569};570 571static struct clk_branch dispcc_mdss_dp_aux_clk = {572 .halt_reg = 0x2054,573 .halt_check = BRANCH_HALT,574 .clkr = {575 .enable_reg = 0x2054,576 .enable_mask = BIT(0),577 .hw.init = &(const struct clk_init_data) {578 .name = "dispcc_mdss_dp_aux_clk",579 .parent_hws = (const struct clk_hw*[]) {580 &dispcc_mdss_dp_aux_clk_src.clkr.hw,581 },582 .num_parents = 1,583 .flags = CLK_SET_RATE_PARENT,584 .ops = &clk_branch2_ops,585 },586 },587};588 589static struct clk_branch dispcc_mdss_dp_crypto_clk = {590 .halt_reg = 0x2048,591 .halt_check = BRANCH_HALT,592 .clkr = {593 .enable_reg = 0x2048,594 .enable_mask = BIT(0),595 .hw.init = &(const struct clk_init_data) {596 .name = "dispcc_mdss_dp_crypto_clk",597 .parent_hws = (const struct clk_hw*[]) {598 &dispcc_mdss_dp_crypto_clk_src.clkr.hw,599 },600 .num_parents = 1,601 .flags = CLK_SET_RATE_PARENT,602 .ops = &clk_branch2_ops,603 },604 },605};606 607static struct clk_branch dispcc_mdss_dp_link_clk = {608 .halt_reg = 0x2040,609 .halt_check = BRANCH_HALT,610 .clkr = {611 .enable_reg = 0x2040,612 .enable_mask = BIT(0),613 .hw.init = &(const struct clk_init_data) {614 .name = "dispcc_mdss_dp_link_clk",615 .parent_hws = (const struct clk_hw*[]) {616 &dispcc_mdss_dp_link_clk_src.clkr.hw,617 },618 .num_parents = 1,619 .flags = CLK_SET_RATE_PARENT,620 .ops = &clk_branch2_ops,621 },622 },623};624 625static struct clk_branch dispcc_mdss_dp_link_intf_clk = {626 .halt_reg = 0x2044,627 .halt_check = BRANCH_HALT,628 .clkr = {629 .enable_reg = 0x2044,630 .enable_mask = BIT(0),631 .hw.init = &(const struct clk_init_data) {632 .name = "dispcc_mdss_dp_link_intf_clk",633 .parent_hws = (const struct clk_hw*[]) {634 &dispcc_mdss_dp_link_clk_src.clkr.hw,635 },636 .num_parents = 1,637 .ops = &clk_branch2_ops,638 },639 },640};641 642static struct clk_branch dispcc_mdss_dp_pixel1_clk = {643 .halt_reg = 0x2050,644 .halt_check = BRANCH_HALT,645 .clkr = {646 .enable_reg = 0x2050,647 .enable_mask = BIT(0),648 .hw.init = &(const struct clk_init_data) {649 .name = "dispcc_mdss_dp_pixel1_clk",650 .parent_hws = (const struct clk_hw*[]) {651 &dispcc_mdss_dp_pixel1_clk_src.clkr.hw,652 },653 .num_parents = 1,654 .flags = CLK_SET_RATE_PARENT,655 .ops = &clk_branch2_ops,656 },657 },658};659 660static struct clk_branch dispcc_mdss_dp_pixel_clk = {661 .halt_reg = 0x204c,662 .halt_check = BRANCH_HALT,663 .clkr = {664 .enable_reg = 0x204c,665 .enable_mask = BIT(0),666 .hw.init = &(const struct clk_init_data) {667 .name = "dispcc_mdss_dp_pixel_clk",668 .parent_hws = (const struct clk_hw*[]) {669 &dispcc_mdss_dp_pixel_clk_src.clkr.hw,670 },671 .num_parents = 1,672 .flags = CLK_SET_RATE_PARENT,673 .ops = &clk_branch2_ops,674 },675 },676};677 678static struct clk_branch dispcc_mdss_esc0_clk = {679 .halt_reg = 0x2038,680 .halt_check = BRANCH_HALT,681 .clkr = {682 .enable_reg = 0x2038,683 .enable_mask = BIT(0),684 .hw.init = &(const struct clk_init_data) {685 .name = "dispcc_mdss_esc0_clk",686 .parent_hws = (const struct clk_hw*[]) {687 &dispcc_mdss_esc0_clk_src.clkr.hw,688 },689 .num_parents = 1,690 .flags = CLK_SET_RATE_PARENT,691 .ops = &clk_branch2_ops,692 },693 },694};695 696static struct clk_branch dispcc_mdss_esc1_clk = {697 .halt_reg = 0x203c,698 .halt_check = BRANCH_HALT,699 .clkr = {700 .enable_reg = 0x203c,701 .enable_mask = BIT(0),702 .hw.init = &(const struct clk_init_data) {703 .name = "dispcc_mdss_esc1_clk",704 .parent_hws = (const struct clk_hw*[]) {705 &dispcc_mdss_esc1_clk_src.clkr.hw,706 },707 .num_parents = 1,708 .flags = CLK_SET_RATE_PARENT,709 .ops = &clk_branch2_ops,710 },711 },712};713 714static struct clk_branch dispcc_mdss_mdp_clk = {715 .halt_reg = 0x200c,716 .halt_check = BRANCH_HALT,717 .clkr = {718 .enable_reg = 0x200c,719 .enable_mask = BIT(0),720 .hw.init = &(const struct clk_init_data) {721 .name = "dispcc_mdss_mdp_clk",722 .parent_hws = (const struct clk_hw*[]) {723 &dispcc_mdss_mdp_clk_src.clkr.hw,724 },725 .num_parents = 1,726 .flags = CLK_SET_RATE_PARENT,727 .ops = &clk_branch2_ops,728 },729 },730};731 732static struct clk_branch dispcc_mdss_mdp_lut_clk = {733 .halt_reg = 0x201c,734 .halt_check = BRANCH_VOTED,735 .clkr = {736 .enable_reg = 0x201c,737 .enable_mask = BIT(0),738 .hw.init = &(const struct clk_init_data) {739 .name = "dispcc_mdss_mdp_lut_clk",740 .parent_hws = (const struct clk_hw*[]) {741 &dispcc_mdss_mdp_clk_src.clkr.hw,742 },743 .num_parents = 1,744 .ops = &clk_branch2_ops,745 },746 },747};748 749static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk = {750 .halt_reg = 0x4004,751 .halt_check = BRANCH_VOTED,752 .clkr = {753 .enable_reg = 0x4004,754 .enable_mask = BIT(0),755 .hw.init = &(const struct clk_init_data) {756 .name = "dispcc_mdss_non_gdsc_ahb_clk",757 .parent_hws = (const struct clk_hw*[]) {758 &dispcc_mdss_ahb_clk_src.clkr.hw,759 },760 .num_parents = 1,761 .flags = CLK_SET_RATE_PARENT,762 .ops = &clk_branch2_ops,763 },764 },765};766 767static struct clk_branch dispcc_mdss_pclk0_clk = {768 .halt_reg = 0x2004,769 .halt_check = BRANCH_HALT,770 .clkr = {771 .enable_reg = 0x2004,772 .enable_mask = BIT(0),773 .hw.init = &(const struct clk_init_data) {774 .name = "dispcc_mdss_pclk0_clk",775 .parent_hws = (const struct clk_hw*[]) {776 &dispcc_mdss_pclk0_clk_src.clkr.hw,777 },778 .num_parents = 1,779 .flags = CLK_SET_RATE_PARENT,780 .ops = &clk_branch2_ops,781 },782 },783};784 785static struct clk_branch dispcc_mdss_pclk1_clk = {786 .halt_reg = 0x2008,787 .halt_check = BRANCH_HALT,788 .clkr = {789 .enable_reg = 0x2008,790 .enable_mask = BIT(0),791 .hw.init = &(const struct clk_init_data) {792 .name = "dispcc_mdss_pclk1_clk",793 .parent_hws = (const struct clk_hw*[]) {794 &dispcc_mdss_pclk1_clk_src.clkr.hw,795 },796 .num_parents = 1,797 .flags = CLK_SET_RATE_PARENT,798 .ops = &clk_branch2_ops,799 },800 },801};802 803static struct clk_branch dispcc_mdss_rot_clk = {804 .halt_reg = 0x2014,805 .halt_check = BRANCH_HALT,806 .clkr = {807 .enable_reg = 0x2014,808 .enable_mask = BIT(0),809 .hw.init = &(const struct clk_init_data) {810 .name = "dispcc_mdss_rot_clk",811 .parent_hws = (const struct clk_hw*[]) {812 &dispcc_mdss_rot_clk_src.clkr.hw,813 },814 .num_parents = 1,815 .flags = CLK_SET_RATE_PARENT,816 .ops = &clk_branch2_ops,817 },818 },819};820 821static struct clk_branch dispcc_mdss_rscc_ahb_clk = {822 .halt_reg = 0x400c,823 .halt_check = BRANCH_HALT,824 .clkr = {825 .enable_reg = 0x400c,826 .enable_mask = BIT(0),827 .hw.init = &(const struct clk_init_data) {828 .name = "dispcc_mdss_rscc_ahb_clk",829 .parent_names = (const char *[]) {830 "dispcc_mdss_ahb_clk_src",831 },832 .num_parents = 1,833 .flags = CLK_SET_RATE_PARENT,834 .ops = &clk_branch2_ops,835 },836 },837};838 839static struct clk_branch dispcc_mdss_rscc_vsync_clk = {840 .halt_reg = 0x4008,841 .halt_check = BRANCH_HALT,842 .clkr = {843 .enable_reg = 0x4008,844 .enable_mask = BIT(0),845 .hw.init = &(const struct clk_init_data) {846 .name = "dispcc_mdss_rscc_vsync_clk",847 .parent_hws = (const struct clk_hw*[]) {848 &dispcc_mdss_vsync_clk_src.clkr.hw,849 },850 .num_parents = 1,851 .flags = CLK_SET_RATE_PARENT,852 .ops = &clk_branch2_ops,853 },854 },855};856 857static struct clk_branch dispcc_mdss_vsync_clk = {858 .halt_reg = 0x2024,859 .halt_check = BRANCH_HALT,860 .clkr = {861 .enable_reg = 0x2024,862 .enable_mask = BIT(0),863 .hw.init = &(const struct clk_init_data) {864 .name = "dispcc_mdss_vsync_clk",865 .parent_hws = (const struct clk_hw*[]) {866 &dispcc_mdss_vsync_clk_src.clkr.hw,867 },868 .num_parents = 1,869 .flags = CLK_SET_RATE_PARENT,870 .ops = &clk_branch2_ops,871 },872 },873};874 875static struct clk_branch dispcc_sleep_clk = {876 .halt_reg = 0x6078,877 .halt_check = BRANCH_HALT,878 .clkr = {879 .enable_reg = 0x6078,880 .enable_mask = BIT(0),881 .hw.init = &(const struct clk_init_data) {882 .name = "dispcc_sleep_clk",883 .parent_names = (const char *[]) {884 "dispcc_sleep_clk_src",885 },886 .num_parents = 1,887 .flags = CLK_SET_RATE_PARENT,888 .ops = &clk_branch2_ops,889 },890 },891};892 893static struct gdsc mdss_gdsc = {894 .gdscr = 0x3000,895 .en_rest_wait_val = 0x2,896 .en_few_wait_val = 0x2,897 .clk_dis_wait_val = 0xf,898 .pd = {899 .name = "mdss_gdsc",900 },901 .pwrsts = PWRSTS_OFF_ON,902 .flags = HW_CTRL,903};904 905static struct clk_regmap *dispcc_sm7150_clocks[] = {906 [DISPCC_MDSS_AHB_CLK] = &dispcc_mdss_ahb_clk.clkr,907 [DISPCC_MDSS_AHB_CLK_SRC] = &dispcc_mdss_ahb_clk_src.clkr,908 [DISPCC_MDSS_BYTE0_CLK] = &dispcc_mdss_byte0_clk.clkr,909 [DISPCC_MDSS_BYTE0_CLK_SRC] = &dispcc_mdss_byte0_clk_src.clkr,910 [DISPCC_MDSS_BYTE0_DIV_CLK_SRC] = &dispcc_mdss_byte0_div_clk_src.clkr,911 [DISPCC_MDSS_BYTE0_INTF_CLK] = &dispcc_mdss_byte0_intf_clk.clkr,912 [DISPCC_MDSS_BYTE1_CLK] = &dispcc_mdss_byte1_clk.clkr,913 [DISPCC_MDSS_BYTE1_CLK_SRC] = &dispcc_mdss_byte1_clk_src.clkr,914 [DISPCC_MDSS_BYTE1_DIV_CLK_SRC] = &dispcc_mdss_byte1_div_clk_src.clkr,915 [DISPCC_MDSS_BYTE1_INTF_CLK] = &dispcc_mdss_byte1_intf_clk.clkr,916 [DISPCC_MDSS_DP_AUX_CLK] = &dispcc_mdss_dp_aux_clk.clkr,917 [DISPCC_MDSS_DP_AUX_CLK_SRC] = &dispcc_mdss_dp_aux_clk_src.clkr,918 [DISPCC_MDSS_DP_CRYPTO_CLK] = &dispcc_mdss_dp_crypto_clk.clkr,919 [DISPCC_MDSS_DP_CRYPTO_CLK_SRC] = &dispcc_mdss_dp_crypto_clk_src.clkr,920 [DISPCC_MDSS_DP_LINK_CLK] = &dispcc_mdss_dp_link_clk.clkr,921 [DISPCC_MDSS_DP_LINK_CLK_SRC] = &dispcc_mdss_dp_link_clk_src.clkr,922 [DISPCC_MDSS_DP_LINK_INTF_CLK] = &dispcc_mdss_dp_link_intf_clk.clkr,923 [DISPCC_MDSS_DP_PIXEL1_CLK] = &dispcc_mdss_dp_pixel1_clk.clkr,924 [DISPCC_MDSS_DP_PIXEL1_CLK_SRC] = &dispcc_mdss_dp_pixel1_clk_src.clkr,925 [DISPCC_MDSS_DP_PIXEL_CLK] = &dispcc_mdss_dp_pixel_clk.clkr,926 [DISPCC_MDSS_DP_PIXEL_CLK_SRC] = &dispcc_mdss_dp_pixel_clk_src.clkr,927 [DISPCC_MDSS_ESC0_CLK] = &dispcc_mdss_esc0_clk.clkr,928 [DISPCC_MDSS_ESC0_CLK_SRC] = &dispcc_mdss_esc0_clk_src.clkr,929 [DISPCC_MDSS_ESC1_CLK] = &dispcc_mdss_esc1_clk.clkr,930 [DISPCC_MDSS_ESC1_CLK_SRC] = &dispcc_mdss_esc1_clk_src.clkr,931 [DISPCC_MDSS_MDP_CLK] = &dispcc_mdss_mdp_clk.clkr,932 [DISPCC_MDSS_MDP_CLK_SRC] = &dispcc_mdss_mdp_clk_src.clkr,933 [DISPCC_MDSS_MDP_LUT_CLK] = &dispcc_mdss_mdp_lut_clk.clkr,934 [DISPCC_MDSS_NON_GDSC_AHB_CLK] = &dispcc_mdss_non_gdsc_ahb_clk.clkr,935 [DISPCC_MDSS_PCLK0_CLK] = &dispcc_mdss_pclk0_clk.clkr,936 [DISPCC_MDSS_PCLK0_CLK_SRC] = &dispcc_mdss_pclk0_clk_src.clkr,937 [DISPCC_MDSS_PCLK1_CLK] = &dispcc_mdss_pclk1_clk.clkr,938 [DISPCC_MDSS_PCLK1_CLK_SRC] = &dispcc_mdss_pclk1_clk_src.clkr,939 [DISPCC_MDSS_ROT_CLK] = &dispcc_mdss_rot_clk.clkr,940 [DISPCC_MDSS_ROT_CLK_SRC] = &dispcc_mdss_rot_clk_src.clkr,941 [DISPCC_MDSS_RSCC_AHB_CLK] = &dispcc_mdss_rscc_ahb_clk.clkr,942 [DISPCC_MDSS_RSCC_VSYNC_CLK] = &dispcc_mdss_rscc_vsync_clk.clkr,943 [DISPCC_MDSS_VSYNC_CLK] = &dispcc_mdss_vsync_clk.clkr,944 [DISPCC_MDSS_VSYNC_CLK_SRC] = &dispcc_mdss_vsync_clk_src.clkr,945 [DISPCC_PLL0] = &dispcc_pll0.clkr,946 [DISPCC_SLEEP_CLK] = &dispcc_sleep_clk.clkr,947 [DISPCC_SLEEP_CLK_SRC] = &dispcc_sleep_clk_src.clkr,948 [DISPCC_XO_CLK_SRC] = &dispcc_xo_clk_src.clkr,949};950 951static struct gdsc *dispcc_sm7150_gdscs[] = {952 [MDSS_GDSC] = &mdss_gdsc,953};954 955static const struct regmap_config dispcc_sm7150_regmap_config = {956 .reg_bits = 32,957 .reg_stride = 4,958 .val_bits = 32,959 .max_register = 0x10000,960 .fast_io = true,961};962 963static const struct qcom_cc_desc dispcc_sm7150_desc = {964 .config = &dispcc_sm7150_regmap_config,965 .clks = dispcc_sm7150_clocks,966 .num_clks = ARRAY_SIZE(dispcc_sm7150_clocks),967 .gdscs = dispcc_sm7150_gdscs,968 .num_gdscs = ARRAY_SIZE(dispcc_sm7150_gdscs),969};970 971static const struct of_device_id dispcc_sm7150_match_table[] = {972 { .compatible = "qcom,sm7150-dispcc" },973 { }974};975MODULE_DEVICE_TABLE(of, dispcc_sm7150_match_table);976 977static int dispcc_sm7150_probe(struct platform_device *pdev)978{979 struct regmap *regmap;980 981 regmap = qcom_cc_map(pdev, &dispcc_sm7150_desc);982 if (IS_ERR(regmap))983 return PTR_ERR(regmap);984 985 clk_fabia_pll_configure(&dispcc_pll0, regmap, &dispcc_pll0_config);986 /* Enable clock gating for DSI and MDP clocks */987 regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);988 989 /* Keep some clocks always-on */990 qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */991 992 return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7150_desc, regmap);993}994 995static struct platform_driver dispcc_sm7150_driver = {996 .probe = dispcc_sm7150_probe,997 .driver = {998 .name = "dispcc-sm7150",999 .of_match_table = dispcc_sm7150_match_table,1000 },1001};1002 1003module_platform_driver(dispcc_sm7150_driver);1004 1005MODULE_DESCRIPTION("Qualcomm SM7150 Display Clock Controller");1006MODULE_LICENSE("GPL");1007