1*c69a5863SAbel Vesa // SPDX-License-Identifier: GPL-2.0-only 2*c69a5863SAbel Vesa /* 3*c69a5863SAbel Vesa * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4*c69a5863SAbel Vesa */ 5*c69a5863SAbel Vesa 6*c69a5863SAbel Vesa #include <linux/clk-provider.h> 7*c69a5863SAbel Vesa #include <linux/mod_devicetable.h> 8*c69a5863SAbel Vesa #include <linux/module.h> 9*c69a5863SAbel Vesa #include <linux/platform_device.h> 10*c69a5863SAbel Vesa #include <linux/regmap.h> 11*c69a5863SAbel Vesa 12*c69a5863SAbel Vesa #include <dt-bindings/clock/qcom,eliza-tcsr.h> 13*c69a5863SAbel Vesa 14*c69a5863SAbel Vesa #include "clk-branch.h" 15*c69a5863SAbel Vesa #include "clk-regmap.h" 16*c69a5863SAbel Vesa #include "common.h" 17*c69a5863SAbel Vesa 18*c69a5863SAbel Vesa enum { 19*c69a5863SAbel Vesa DT_BI_TCXO_PAD, 20*c69a5863SAbel Vesa }; 21*c69a5863SAbel Vesa 22*c69a5863SAbel Vesa static struct clk_branch tcsr_hdmi_clkref_en = { 23*c69a5863SAbel Vesa .halt_reg = 0x14, 24*c69a5863SAbel Vesa .halt_check = BRANCH_HALT_DELAY, 25*c69a5863SAbel Vesa .clkr = { 26*c69a5863SAbel Vesa .enable_reg = 0x14, 27*c69a5863SAbel Vesa .enable_mask = BIT(0), 28*c69a5863SAbel Vesa .hw.init = &(const struct clk_init_data) { 29*c69a5863SAbel Vesa .name = "tcsr_hdmi_clkref_en", 30*c69a5863SAbel Vesa .parent_data = &(const struct clk_parent_data){ 31*c69a5863SAbel Vesa .index = DT_BI_TCXO_PAD, 32*c69a5863SAbel Vesa }, 33*c69a5863SAbel Vesa .num_parents = 1, 34*c69a5863SAbel Vesa .ops = &clk_branch2_ops, 35*c69a5863SAbel Vesa }, 36*c69a5863SAbel Vesa }, 37*c69a5863SAbel Vesa }; 38*c69a5863SAbel Vesa 39*c69a5863SAbel Vesa static struct clk_branch tcsr_pcie_0_clkref_en = { 40*c69a5863SAbel Vesa .halt_reg = 0x0, 41*c69a5863SAbel Vesa .halt_check = BRANCH_HALT_DELAY, 42*c69a5863SAbel Vesa .clkr = { 43*c69a5863SAbel Vesa .enable_reg = 0x0, 44*c69a5863SAbel Vesa .enable_mask = BIT(0), 45*c69a5863SAbel Vesa .hw.init = &(const struct clk_init_data) { 46*c69a5863SAbel Vesa .name = "tcsr_pcie_0_clkref_en", 47*c69a5863SAbel Vesa .parent_data = &(const struct clk_parent_data){ 48*c69a5863SAbel Vesa .index = DT_BI_TCXO_PAD, 49*c69a5863SAbel Vesa }, 50*c69a5863SAbel Vesa .num_parents = 1, 51*c69a5863SAbel Vesa .ops = &clk_branch2_ops, 52*c69a5863SAbel Vesa }, 53*c69a5863SAbel Vesa }, 54*c69a5863SAbel Vesa }; 55*c69a5863SAbel Vesa 56*c69a5863SAbel Vesa static struct clk_branch tcsr_pcie_1_clkref_en = { 57*c69a5863SAbel Vesa .halt_reg = 0x1c, 58*c69a5863SAbel Vesa .halt_check = BRANCH_HALT_DELAY, 59*c69a5863SAbel Vesa .clkr = { 60*c69a5863SAbel Vesa .enable_reg = 0x1c, 61*c69a5863SAbel Vesa .enable_mask = BIT(0), 62*c69a5863SAbel Vesa .hw.init = &(const struct clk_init_data) { 63*c69a5863SAbel Vesa .name = "tcsr_pcie_1_clkref_en", 64*c69a5863SAbel Vesa .parent_data = &(const struct clk_parent_data){ 65*c69a5863SAbel Vesa .index = DT_BI_TCXO_PAD, 66*c69a5863SAbel Vesa }, 67*c69a5863SAbel Vesa .num_parents = 1, 68*c69a5863SAbel Vesa .ops = &clk_branch2_ops, 69*c69a5863SAbel Vesa }, 70*c69a5863SAbel Vesa }, 71*c69a5863SAbel Vesa }; 72*c69a5863SAbel Vesa 73*c69a5863SAbel Vesa static struct clk_branch tcsr_ufs_clkref_en = { 74*c69a5863SAbel Vesa .halt_reg = 0x8, 75*c69a5863SAbel Vesa .halt_check = BRANCH_HALT_DELAY, 76*c69a5863SAbel Vesa .clkr = { 77*c69a5863SAbel Vesa .enable_reg = 0x8, 78*c69a5863SAbel Vesa .enable_mask = BIT(0), 79*c69a5863SAbel Vesa .hw.init = &(const struct clk_init_data) { 80*c69a5863SAbel Vesa .name = "tcsr_ufs_clkref_en", 81*c69a5863SAbel Vesa .parent_data = &(const struct clk_parent_data){ 82*c69a5863SAbel Vesa .index = DT_BI_TCXO_PAD, 83*c69a5863SAbel Vesa }, 84*c69a5863SAbel Vesa .num_parents = 1, 85*c69a5863SAbel Vesa .ops = &clk_branch2_ops, 86*c69a5863SAbel Vesa }, 87*c69a5863SAbel Vesa }, 88*c69a5863SAbel Vesa }; 89*c69a5863SAbel Vesa 90*c69a5863SAbel Vesa static struct clk_branch tcsr_usb2_clkref_en = { 91*c69a5863SAbel Vesa .halt_reg = 0x4, 92*c69a5863SAbel Vesa .halt_check = BRANCH_HALT_DELAY, 93*c69a5863SAbel Vesa .clkr = { 94*c69a5863SAbel Vesa .enable_reg = 0x4, 95*c69a5863SAbel Vesa .enable_mask = BIT(0), 96*c69a5863SAbel Vesa .hw.init = &(const struct clk_init_data) { 97*c69a5863SAbel Vesa .name = "tcsr_usb2_clkref_en", 98*c69a5863SAbel Vesa .parent_data = &(const struct clk_parent_data){ 99*c69a5863SAbel Vesa .index = DT_BI_TCXO_PAD, 100*c69a5863SAbel Vesa }, 101*c69a5863SAbel Vesa .num_parents = 1, 102*c69a5863SAbel Vesa .ops = &clk_branch2_ops, 103*c69a5863SAbel Vesa }, 104*c69a5863SAbel Vesa }, 105*c69a5863SAbel Vesa }; 106*c69a5863SAbel Vesa 107*c69a5863SAbel Vesa static struct clk_branch tcsr_usb3_clkref_en = { 108*c69a5863SAbel Vesa .halt_reg = 0x10, 109*c69a5863SAbel Vesa .halt_check = BRANCH_HALT_DELAY, 110*c69a5863SAbel Vesa .clkr = { 111*c69a5863SAbel Vesa .enable_reg = 0x10, 112*c69a5863SAbel Vesa .enable_mask = BIT(0), 113*c69a5863SAbel Vesa .hw.init = &(const struct clk_init_data) { 114*c69a5863SAbel Vesa .name = "tcsr_usb3_clkref_en", 115*c69a5863SAbel Vesa .parent_data = &(const struct clk_parent_data){ 116*c69a5863SAbel Vesa .index = DT_BI_TCXO_PAD, 117*c69a5863SAbel Vesa }, 118*c69a5863SAbel Vesa .num_parents = 1, 119*c69a5863SAbel Vesa .ops = &clk_branch2_ops, 120*c69a5863SAbel Vesa }, 121*c69a5863SAbel Vesa }, 122*c69a5863SAbel Vesa }; 123*c69a5863SAbel Vesa 124*c69a5863SAbel Vesa static struct clk_regmap *tcsr_cc_eliza_clocks[] = { 125*c69a5863SAbel Vesa [TCSR_HDMI_CLKREF_EN] = &tcsr_hdmi_clkref_en.clkr, 126*c69a5863SAbel Vesa [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr, 127*c69a5863SAbel Vesa [TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr, 128*c69a5863SAbel Vesa [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr, 129*c69a5863SAbel Vesa [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr, 130*c69a5863SAbel Vesa [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr, 131*c69a5863SAbel Vesa }; 132*c69a5863SAbel Vesa 133*c69a5863SAbel Vesa static const struct regmap_config tcsr_cc_eliza_regmap_config = { 134*c69a5863SAbel Vesa .reg_bits = 32, 135*c69a5863SAbel Vesa .reg_stride = 4, 136*c69a5863SAbel Vesa .val_bits = 32, 137*c69a5863SAbel Vesa .max_register = 0x1c, 138*c69a5863SAbel Vesa .fast_io = true, 139*c69a5863SAbel Vesa }; 140*c69a5863SAbel Vesa 141*c69a5863SAbel Vesa static const struct qcom_cc_desc tcsr_cc_eliza_desc = { 142*c69a5863SAbel Vesa .config = &tcsr_cc_eliza_regmap_config, 143*c69a5863SAbel Vesa .clks = tcsr_cc_eliza_clocks, 144*c69a5863SAbel Vesa .num_clks = ARRAY_SIZE(tcsr_cc_eliza_clocks), 145*c69a5863SAbel Vesa }; 146*c69a5863SAbel Vesa 147*c69a5863SAbel Vesa static const struct of_device_id tcsr_cc_eliza_match_table[] = { 148*c69a5863SAbel Vesa { .compatible = "qcom,eliza-tcsr" }, 149*c69a5863SAbel Vesa { } 150*c69a5863SAbel Vesa }; 151*c69a5863SAbel Vesa MODULE_DEVICE_TABLE(of, tcsr_cc_eliza_match_table); 152*c69a5863SAbel Vesa 153*c69a5863SAbel Vesa static int tcsr_cc_eliza_probe(struct platform_device *pdev) 154*c69a5863SAbel Vesa { 155*c69a5863SAbel Vesa return qcom_cc_probe(pdev, &tcsr_cc_eliza_desc); 156*c69a5863SAbel Vesa } 157*c69a5863SAbel Vesa 158*c69a5863SAbel Vesa static struct platform_driver tcsr_cc_eliza_driver = { 159*c69a5863SAbel Vesa .probe = tcsr_cc_eliza_probe, 160*c69a5863SAbel Vesa .driver = { 161*c69a5863SAbel Vesa .name = "tcsr_cc-eliza", 162*c69a5863SAbel Vesa .of_match_table = tcsr_cc_eliza_match_table, 163*c69a5863SAbel Vesa }, 164*c69a5863SAbel Vesa }; 165*c69a5863SAbel Vesa 166*c69a5863SAbel Vesa static int __init tcsr_cc_eliza_init(void) 167*c69a5863SAbel Vesa { 168*c69a5863SAbel Vesa return platform_driver_register(&tcsr_cc_eliza_driver); 169*c69a5863SAbel Vesa } 170*c69a5863SAbel Vesa subsys_initcall(tcsr_cc_eliza_init); 171*c69a5863SAbel Vesa 172*c69a5863SAbel Vesa static void __exit tcsr_cc_eliza_exit(void) 173*c69a5863SAbel Vesa { 174*c69a5863SAbel Vesa platform_driver_unregister(&tcsr_cc_eliza_driver); 175*c69a5863SAbel Vesa } 176*c69a5863SAbel Vesa module_exit(tcsr_cc_eliza_exit); 177*c69a5863SAbel Vesa 178*c69a5863SAbel Vesa MODULE_DESCRIPTION("QTI TCSR_CC Eliza Driver"); 179*c69a5863SAbel Vesa MODULE_LICENSE("GPL"); 180