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