1*633a81beSLuca Weiss // SPDX-License-Identifier: GPL-2.0-only 2*633a81beSLuca Weiss /* 3*633a81beSLuca Weiss * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. 4*633a81beSLuca Weiss * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com> 5*633a81beSLuca Weiss */ 6*633a81beSLuca Weiss 7*633a81beSLuca Weiss #include <linux/clk-provider.h> 8*633a81beSLuca Weiss #include <linux/mod_devicetable.h> 9*633a81beSLuca Weiss #include <linux/module.h> 10*633a81beSLuca Weiss #include <linux/platform_device.h> 11*633a81beSLuca Weiss #include <linux/regmap.h> 12*633a81beSLuca Weiss 13*633a81beSLuca Weiss #include <dt-bindings/clock/qcom,milos-videocc.h> 14*633a81beSLuca Weiss 15*633a81beSLuca Weiss #include "clk-alpha-pll.h" 16*633a81beSLuca Weiss #include "clk-branch.h" 17*633a81beSLuca Weiss #include "clk-rcg.h" 18*633a81beSLuca Weiss #include "clk-regmap.h" 19*633a81beSLuca Weiss #include "clk-regmap-divider.h" 20*633a81beSLuca Weiss #include "common.h" 21*633a81beSLuca Weiss #include "gdsc.h" 22*633a81beSLuca Weiss #include "reset.h" 23*633a81beSLuca Weiss 24*633a81beSLuca Weiss /* Need to match the order of clocks in DT binding */ 25*633a81beSLuca Weiss enum { 26*633a81beSLuca Weiss DT_BI_TCXO, 27*633a81beSLuca Weiss DT_BI_TCXO_AO, 28*633a81beSLuca Weiss DT_SLEEP_CLK, 29*633a81beSLuca Weiss DT_IFACE, 30*633a81beSLuca Weiss }; 31*633a81beSLuca Weiss 32*633a81beSLuca Weiss enum { 33*633a81beSLuca Weiss P_BI_TCXO, 34*633a81beSLuca Weiss P_SLEEP_CLK, 35*633a81beSLuca Weiss P_VIDEO_CC_PLL0_OUT_MAIN, 36*633a81beSLuca Weiss }; 37*633a81beSLuca Weiss 38*633a81beSLuca Weiss static const struct pll_vco lucid_ole_vco[] = { 39*633a81beSLuca Weiss { 249600000, 2300000000, 0 }, 40*633a81beSLuca Weiss }; 41*633a81beSLuca Weiss 42*633a81beSLuca Weiss /* 604.8 MHz Configuration */ 43*633a81beSLuca Weiss static const struct alpha_pll_config video_cc_pll0_config = { 44*633a81beSLuca Weiss .l = 0x1f, 45*633a81beSLuca Weiss .alpha = 0x8000, 46*633a81beSLuca Weiss .config_ctl_val = 0x20485699, 47*633a81beSLuca Weiss .config_ctl_hi_val = 0x00182261, 48*633a81beSLuca Weiss .config_ctl_hi1_val = 0x82aa299c, 49*633a81beSLuca Weiss .test_ctl_val = 0x00000000, 50*633a81beSLuca Weiss .test_ctl_hi_val = 0x00000003, 51*633a81beSLuca Weiss .test_ctl_hi1_val = 0x00009000, 52*633a81beSLuca Weiss .test_ctl_hi2_val = 0x00000034, 53*633a81beSLuca Weiss .user_ctl_val = 0x00000000, 54*633a81beSLuca Weiss .user_ctl_hi_val = 0x00000005, 55*633a81beSLuca Weiss }; 56*633a81beSLuca Weiss 57*633a81beSLuca Weiss static struct clk_alpha_pll video_cc_pll0 = { 58*633a81beSLuca Weiss .offset = 0x0, 59*633a81beSLuca Weiss .config = &video_cc_pll0_config, 60*633a81beSLuca Weiss .vco_table = lucid_ole_vco, 61*633a81beSLuca Weiss .num_vco = ARRAY_SIZE(lucid_ole_vco), 62*633a81beSLuca Weiss .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], 63*633a81beSLuca Weiss .clkr = { 64*633a81beSLuca Weiss .hw.init = &(const struct clk_init_data) { 65*633a81beSLuca Weiss .name = "video_cc_pll0", 66*633a81beSLuca Weiss .parent_data = &(const struct clk_parent_data) { 67*633a81beSLuca Weiss .index = DT_BI_TCXO, 68*633a81beSLuca Weiss }, 69*633a81beSLuca Weiss .num_parents = 1, 70*633a81beSLuca Weiss .ops = &clk_alpha_pll_lucid_evo_ops, 71*633a81beSLuca Weiss }, 72*633a81beSLuca Weiss }, 73*633a81beSLuca Weiss }; 74*633a81beSLuca Weiss 75*633a81beSLuca Weiss static const struct parent_map video_cc_parent_map_0[] = { 76*633a81beSLuca Weiss { P_BI_TCXO, 0 }, 77*633a81beSLuca Weiss }; 78*633a81beSLuca Weiss 79*633a81beSLuca Weiss static const struct clk_parent_data video_cc_parent_data_0[] = { 80*633a81beSLuca Weiss { .index = DT_BI_TCXO }, 81*633a81beSLuca Weiss }; 82*633a81beSLuca Weiss 83*633a81beSLuca Weiss static const struct clk_parent_data video_cc_parent_data_0_ao[] = { 84*633a81beSLuca Weiss { .index = DT_BI_TCXO_AO }, 85*633a81beSLuca Weiss }; 86*633a81beSLuca Weiss 87*633a81beSLuca Weiss static const struct parent_map video_cc_parent_map_1[] = { 88*633a81beSLuca Weiss { P_BI_TCXO, 0 }, 89*633a81beSLuca Weiss { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, 90*633a81beSLuca Weiss }; 91*633a81beSLuca Weiss 92*633a81beSLuca Weiss static const struct clk_parent_data video_cc_parent_data_1[] = { 93*633a81beSLuca Weiss { .index = DT_BI_TCXO }, 94*633a81beSLuca Weiss { .hw = &video_cc_pll0.clkr.hw }, 95*633a81beSLuca Weiss }; 96*633a81beSLuca Weiss 97*633a81beSLuca Weiss static const struct parent_map video_cc_parent_map_2[] = { 98*633a81beSLuca Weiss { P_SLEEP_CLK, 0 }, 99*633a81beSLuca Weiss }; 100*633a81beSLuca Weiss 101*633a81beSLuca Weiss static const struct clk_parent_data video_cc_parent_data_2_ao[] = { 102*633a81beSLuca Weiss { .index = DT_SLEEP_CLK }, 103*633a81beSLuca Weiss }; 104*633a81beSLuca Weiss 105*633a81beSLuca Weiss static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { 106*633a81beSLuca Weiss F(19200000, P_BI_TCXO, 1, 0, 0), 107*633a81beSLuca Weiss { } 108*633a81beSLuca Weiss }; 109*633a81beSLuca Weiss 110*633a81beSLuca Weiss static struct clk_rcg2 video_cc_ahb_clk_src = { 111*633a81beSLuca Weiss .cmd_rcgr = 0x8030, 112*633a81beSLuca Weiss .mnd_width = 0, 113*633a81beSLuca Weiss .hid_width = 5, 114*633a81beSLuca Weiss .parent_map = video_cc_parent_map_0, 115*633a81beSLuca Weiss .freq_tbl = ftbl_video_cc_ahb_clk_src, 116*633a81beSLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 117*633a81beSLuca Weiss .name = "video_cc_ahb_clk_src", 118*633a81beSLuca Weiss .parent_data = video_cc_parent_data_0_ao, 119*633a81beSLuca Weiss .num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao), 120*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 121*633a81beSLuca Weiss .ops = &clk_rcg2_shared_ops, 122*633a81beSLuca Weiss }, 123*633a81beSLuca Weiss }; 124*633a81beSLuca Weiss 125*633a81beSLuca Weiss static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { 126*633a81beSLuca Weiss F(604800000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 127*633a81beSLuca Weiss F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 128*633a81beSLuca Weiss F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 129*633a81beSLuca Weiss F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 130*633a81beSLuca Weiss F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 131*633a81beSLuca Weiss F(1656000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 132*633a81beSLuca Weiss { } 133*633a81beSLuca Weiss }; 134*633a81beSLuca Weiss 135*633a81beSLuca Weiss static struct clk_rcg2 video_cc_mvs0_clk_src = { 136*633a81beSLuca Weiss .cmd_rcgr = 0x8000, 137*633a81beSLuca Weiss .mnd_width = 0, 138*633a81beSLuca Weiss .hid_width = 5, 139*633a81beSLuca Weiss .parent_map = video_cc_parent_map_1, 140*633a81beSLuca Weiss .freq_tbl = ftbl_video_cc_mvs0_clk_src, 141*633a81beSLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 142*633a81beSLuca Weiss .name = "video_cc_mvs0_clk_src", 143*633a81beSLuca Weiss .parent_data = video_cc_parent_data_1, 144*633a81beSLuca Weiss .num_parents = ARRAY_SIZE(video_cc_parent_data_1), 145*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 146*633a81beSLuca Weiss .ops = &clk_rcg2_shared_ops, 147*633a81beSLuca Weiss }, 148*633a81beSLuca Weiss }; 149*633a81beSLuca Weiss 150*633a81beSLuca Weiss static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = { 151*633a81beSLuca Weiss F(32000, P_SLEEP_CLK, 1, 0, 0), 152*633a81beSLuca Weiss { } 153*633a81beSLuca Weiss }; 154*633a81beSLuca Weiss 155*633a81beSLuca Weiss static struct clk_rcg2 video_cc_sleep_clk_src = { 156*633a81beSLuca Weiss .cmd_rcgr = 0x8128, 157*633a81beSLuca Weiss .mnd_width = 0, 158*633a81beSLuca Weiss .hid_width = 5, 159*633a81beSLuca Weiss .parent_map = video_cc_parent_map_2, 160*633a81beSLuca Weiss .freq_tbl = ftbl_video_cc_sleep_clk_src, 161*633a81beSLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 162*633a81beSLuca Weiss .name = "video_cc_sleep_clk_src", 163*633a81beSLuca Weiss .parent_data = video_cc_parent_data_2_ao, 164*633a81beSLuca Weiss .num_parents = ARRAY_SIZE(video_cc_parent_data_2_ao), 165*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 166*633a81beSLuca Weiss .ops = &clk_rcg2_ops, 167*633a81beSLuca Weiss }, 168*633a81beSLuca Weiss }; 169*633a81beSLuca Weiss 170*633a81beSLuca Weiss static struct clk_rcg2 video_cc_xo_clk_src = { 171*633a81beSLuca Weiss .cmd_rcgr = 0x810c, 172*633a81beSLuca Weiss .mnd_width = 0, 173*633a81beSLuca Weiss .hid_width = 5, 174*633a81beSLuca Weiss .parent_map = video_cc_parent_map_0, 175*633a81beSLuca Weiss .freq_tbl = ftbl_video_cc_ahb_clk_src, 176*633a81beSLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 177*633a81beSLuca Weiss .name = "video_cc_xo_clk_src", 178*633a81beSLuca Weiss .parent_data = video_cc_parent_data_0, 179*633a81beSLuca Weiss .num_parents = ARRAY_SIZE(video_cc_parent_data_0), 180*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 181*633a81beSLuca Weiss .ops = &clk_rcg2_ops, 182*633a81beSLuca Weiss }, 183*633a81beSLuca Weiss }; 184*633a81beSLuca Weiss 185*633a81beSLuca Weiss static struct clk_regmap_div video_cc_mvs0_div_clk_src = { 186*633a81beSLuca Weiss .reg = 0x80c4, 187*633a81beSLuca Weiss .shift = 0, 188*633a81beSLuca Weiss .width = 4, 189*633a81beSLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 190*633a81beSLuca Weiss .name = "video_cc_mvs0_div_clk_src", 191*633a81beSLuca Weiss .parent_hws = (const struct clk_hw*[]) { 192*633a81beSLuca Weiss &video_cc_mvs0_clk_src.clkr.hw, 193*633a81beSLuca Weiss }, 194*633a81beSLuca Weiss .num_parents = 1, 195*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 196*633a81beSLuca Weiss .ops = &clk_regmap_div_ro_ops, 197*633a81beSLuca Weiss }, 198*633a81beSLuca Weiss }; 199*633a81beSLuca Weiss 200*633a81beSLuca Weiss static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = { 201*633a81beSLuca Weiss .reg = 0x8070, 202*633a81beSLuca Weiss .shift = 0, 203*633a81beSLuca Weiss .width = 4, 204*633a81beSLuca Weiss .clkr.hw.init = &(const struct clk_init_data) { 205*633a81beSLuca Weiss .name = "video_cc_mvs0c_div2_div_clk_src", 206*633a81beSLuca Weiss .parent_hws = (const struct clk_hw*[]) { 207*633a81beSLuca Weiss &video_cc_mvs0_clk_src.clkr.hw, 208*633a81beSLuca Weiss }, 209*633a81beSLuca Weiss .num_parents = 1, 210*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 211*633a81beSLuca Weiss .ops = &clk_regmap_div_ro_ops, 212*633a81beSLuca Weiss }, 213*633a81beSLuca Weiss }; 214*633a81beSLuca Weiss 215*633a81beSLuca Weiss static struct clk_branch video_cc_mvs0_clk = { 216*633a81beSLuca Weiss .halt_reg = 0x80b8, 217*633a81beSLuca Weiss .halt_check = BRANCH_HALT_VOTED, 218*633a81beSLuca Weiss .hwcg_reg = 0x80b8, 219*633a81beSLuca Weiss .hwcg_bit = 1, 220*633a81beSLuca Weiss .clkr = { 221*633a81beSLuca Weiss .enable_reg = 0x80b8, 222*633a81beSLuca Weiss .enable_mask = BIT(0), 223*633a81beSLuca Weiss .hw.init = &(const struct clk_init_data) { 224*633a81beSLuca Weiss .name = "video_cc_mvs0_clk", 225*633a81beSLuca Weiss .parent_hws = (const struct clk_hw*[]) { 226*633a81beSLuca Weiss &video_cc_mvs0_div_clk_src.clkr.hw, 227*633a81beSLuca Weiss }, 228*633a81beSLuca Weiss .num_parents = 1, 229*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 230*633a81beSLuca Weiss .ops = &clk_branch2_ops, 231*633a81beSLuca Weiss }, 232*633a81beSLuca Weiss }, 233*633a81beSLuca Weiss }; 234*633a81beSLuca Weiss 235*633a81beSLuca Weiss static struct clk_branch video_cc_mvs0_shift_clk = { 236*633a81beSLuca Weiss .halt_reg = 0x8144, 237*633a81beSLuca Weiss .halt_check = BRANCH_HALT_VOTED, 238*633a81beSLuca Weiss .hwcg_reg = 0x8144, 239*633a81beSLuca Weiss .hwcg_bit = 1, 240*633a81beSLuca Weiss .clkr = { 241*633a81beSLuca Weiss .enable_reg = 0x8144, 242*633a81beSLuca Weiss .enable_mask = BIT(0), 243*633a81beSLuca Weiss .hw.init = &(const struct clk_init_data) { 244*633a81beSLuca Weiss .name = "video_cc_mvs0_shift_clk", 245*633a81beSLuca Weiss .parent_hws = (const struct clk_hw*[]) { 246*633a81beSLuca Weiss &video_cc_xo_clk_src.clkr.hw, 247*633a81beSLuca Weiss }, 248*633a81beSLuca Weiss .num_parents = 1, 249*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 250*633a81beSLuca Weiss .ops = &clk_branch2_ops, 251*633a81beSLuca Weiss }, 252*633a81beSLuca Weiss }, 253*633a81beSLuca Weiss }; 254*633a81beSLuca Weiss 255*633a81beSLuca Weiss static struct clk_branch video_cc_mvs0c_clk = { 256*633a81beSLuca Weiss .halt_reg = 0x8064, 257*633a81beSLuca Weiss .halt_check = BRANCH_HALT, 258*633a81beSLuca Weiss .clkr = { 259*633a81beSLuca Weiss .enable_reg = 0x8064, 260*633a81beSLuca Weiss .enable_mask = BIT(0), 261*633a81beSLuca Weiss .hw.init = &(const struct clk_init_data) { 262*633a81beSLuca Weiss .name = "video_cc_mvs0c_clk", 263*633a81beSLuca Weiss .parent_hws = (const struct clk_hw*[]) { 264*633a81beSLuca Weiss &video_cc_mvs0c_div2_div_clk_src.clkr.hw, 265*633a81beSLuca Weiss }, 266*633a81beSLuca Weiss .num_parents = 1, 267*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 268*633a81beSLuca Weiss .ops = &clk_branch2_ops, 269*633a81beSLuca Weiss }, 270*633a81beSLuca Weiss }, 271*633a81beSLuca Weiss }; 272*633a81beSLuca Weiss 273*633a81beSLuca Weiss static struct clk_branch video_cc_mvs0c_shift_clk = { 274*633a81beSLuca Weiss .halt_reg = 0x8148, 275*633a81beSLuca Weiss .halt_check = BRANCH_HALT_VOTED, 276*633a81beSLuca Weiss .hwcg_reg = 0x8148, 277*633a81beSLuca Weiss .hwcg_bit = 1, 278*633a81beSLuca Weiss .clkr = { 279*633a81beSLuca Weiss .enable_reg = 0x8148, 280*633a81beSLuca Weiss .enable_mask = BIT(0), 281*633a81beSLuca Weiss .hw.init = &(const struct clk_init_data) { 282*633a81beSLuca Weiss .name = "video_cc_mvs0c_shift_clk", 283*633a81beSLuca Weiss .parent_hws = (const struct clk_hw*[]) { 284*633a81beSLuca Weiss &video_cc_xo_clk_src.clkr.hw, 285*633a81beSLuca Weiss }, 286*633a81beSLuca Weiss .num_parents = 1, 287*633a81beSLuca Weiss .flags = CLK_SET_RATE_PARENT, 288*633a81beSLuca Weiss .ops = &clk_branch2_ops, 289*633a81beSLuca Weiss }, 290*633a81beSLuca Weiss }, 291*633a81beSLuca Weiss }; 292*633a81beSLuca Weiss 293*633a81beSLuca Weiss static struct gdsc video_cc_mvs0c_gdsc = { 294*633a81beSLuca Weiss .gdscr = 0x804c, 295*633a81beSLuca Weiss .en_rest_wait_val = 0x2, 296*633a81beSLuca Weiss .en_few_wait_val = 0x2, 297*633a81beSLuca Weiss .clk_dis_wait_val = 0x6, 298*633a81beSLuca Weiss .pd = { 299*633a81beSLuca Weiss .name = "video_cc_mvs0c_gdsc", 300*633a81beSLuca Weiss }, 301*633a81beSLuca Weiss .pwrsts = PWRSTS_OFF_ON, 302*633a81beSLuca Weiss .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 303*633a81beSLuca Weiss }; 304*633a81beSLuca Weiss 305*633a81beSLuca Weiss static struct gdsc video_cc_mvs0_gdsc = { 306*633a81beSLuca Weiss .gdscr = 0x80a4, 307*633a81beSLuca Weiss .en_rest_wait_val = 0x2, 308*633a81beSLuca Weiss .en_few_wait_val = 0x2, 309*633a81beSLuca Weiss .clk_dis_wait_val = 0x6, 310*633a81beSLuca Weiss .pd = { 311*633a81beSLuca Weiss .name = "video_cc_mvs0_gdsc", 312*633a81beSLuca Weiss }, 313*633a81beSLuca Weiss .pwrsts = PWRSTS_OFF_ON, 314*633a81beSLuca Weiss .parent = &video_cc_mvs0c_gdsc.pd, 315*633a81beSLuca Weiss .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, 316*633a81beSLuca Weiss }; 317*633a81beSLuca Weiss 318*633a81beSLuca Weiss static struct clk_regmap *video_cc_milos_clocks[] = { 319*633a81beSLuca Weiss [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, 320*633a81beSLuca Weiss [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, 321*633a81beSLuca Weiss [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, 322*633a81beSLuca Weiss [VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, 323*633a81beSLuca Weiss [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, 324*633a81beSLuca Weiss [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, 325*633a81beSLuca Weiss [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, 326*633a81beSLuca Weiss [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, 327*633a81beSLuca Weiss [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, 328*633a81beSLuca Weiss [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, 329*633a81beSLuca Weiss [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, 330*633a81beSLuca Weiss }; 331*633a81beSLuca Weiss 332*633a81beSLuca Weiss static struct gdsc *video_cc_milos_gdscs[] = { 333*633a81beSLuca Weiss [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, 334*633a81beSLuca Weiss [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, 335*633a81beSLuca Weiss }; 336*633a81beSLuca Weiss 337*633a81beSLuca Weiss static const struct qcom_reset_map video_cc_milos_resets[] = { 338*633a81beSLuca Weiss [VIDEO_CC_INTERFACE_BCR] = { 0x80f0 }, 339*633a81beSLuca Weiss [VIDEO_CC_MVS0_BCR] = { 0x80a0 }, 340*633a81beSLuca Weiss [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8064, 2 }, 341*633a81beSLuca Weiss [VIDEO_CC_MVS0C_BCR] = { 0x8048 }, 342*633a81beSLuca Weiss }; 343*633a81beSLuca Weiss 344*633a81beSLuca Weiss static struct clk_alpha_pll *video_cc_milos_plls[] = { 345*633a81beSLuca Weiss &video_cc_pll0, 346*633a81beSLuca Weiss }; 347*633a81beSLuca Weiss 348*633a81beSLuca Weiss static u32 video_cc_milos_critical_cbcrs[] = { 349*633a81beSLuca Weiss 0x80f4, /* VIDEO_CC_AHB_CLK */ 350*633a81beSLuca Weiss 0x8140, /* VIDEO_CC_SLEEP_CLK */ 351*633a81beSLuca Weiss 0x8124, /* VIDEO_CC_XO_CLK */ 352*633a81beSLuca Weiss }; 353*633a81beSLuca Weiss 354*633a81beSLuca Weiss static const struct regmap_config video_cc_milos_regmap_config = { 355*633a81beSLuca Weiss .reg_bits = 32, 356*633a81beSLuca Weiss .reg_stride = 4, 357*633a81beSLuca Weiss .val_bits = 32, 358*633a81beSLuca Weiss .max_register = 0x9f50, 359*633a81beSLuca Weiss .fast_io = true, 360*633a81beSLuca Weiss }; 361*633a81beSLuca Weiss 362*633a81beSLuca Weiss static struct qcom_cc_driver_data video_cc_milos_driver_data = { 363*633a81beSLuca Weiss .alpha_plls = video_cc_milos_plls, 364*633a81beSLuca Weiss .num_alpha_plls = ARRAY_SIZE(video_cc_milos_plls), 365*633a81beSLuca Weiss .clk_cbcrs = video_cc_milos_critical_cbcrs, 366*633a81beSLuca Weiss .num_clk_cbcrs = ARRAY_SIZE(video_cc_milos_critical_cbcrs), 367*633a81beSLuca Weiss }; 368*633a81beSLuca Weiss 369*633a81beSLuca Weiss static struct qcom_cc_desc video_cc_milos_desc = { 370*633a81beSLuca Weiss .config = &video_cc_milos_regmap_config, 371*633a81beSLuca Weiss .clks = video_cc_milos_clocks, 372*633a81beSLuca Weiss .num_clks = ARRAY_SIZE(video_cc_milos_clocks), 373*633a81beSLuca Weiss .resets = video_cc_milos_resets, 374*633a81beSLuca Weiss .num_resets = ARRAY_SIZE(video_cc_milos_resets), 375*633a81beSLuca Weiss .gdscs = video_cc_milos_gdscs, 376*633a81beSLuca Weiss .num_gdscs = ARRAY_SIZE(video_cc_milos_gdscs), 377*633a81beSLuca Weiss .use_rpm = true, 378*633a81beSLuca Weiss .driver_data = &video_cc_milos_driver_data, 379*633a81beSLuca Weiss }; 380*633a81beSLuca Weiss 381*633a81beSLuca Weiss static const struct of_device_id video_cc_milos_match_table[] = { 382*633a81beSLuca Weiss { .compatible = "qcom,milos-videocc" }, 383*633a81beSLuca Weiss { } 384*633a81beSLuca Weiss }; 385*633a81beSLuca Weiss MODULE_DEVICE_TABLE(of, video_cc_milos_match_table); 386*633a81beSLuca Weiss 387*633a81beSLuca Weiss static int video_cc_milos_probe(struct platform_device *pdev) 388*633a81beSLuca Weiss { 389*633a81beSLuca Weiss return qcom_cc_probe(pdev, &video_cc_milos_desc); 390*633a81beSLuca Weiss } 391*633a81beSLuca Weiss 392*633a81beSLuca Weiss static struct platform_driver video_cc_milos_driver = { 393*633a81beSLuca Weiss .probe = video_cc_milos_probe, 394*633a81beSLuca Weiss .driver = { 395*633a81beSLuca Weiss .name = "video_cc-milos", 396*633a81beSLuca Weiss .of_match_table = video_cc_milos_match_table, 397*633a81beSLuca Weiss }, 398*633a81beSLuca Weiss }; 399*633a81beSLuca Weiss 400*633a81beSLuca Weiss module_platform_driver(video_cc_milos_driver); 401*633a81beSLuca Weiss 402*633a81beSLuca Weiss MODULE_DESCRIPTION("QTI VIDEO_CC Milos Driver"); 403*633a81beSLuca Weiss MODULE_LICENSE("GPL"); 404