1*e9a7b78bSAbel Vesa // SPDX-License-Identifier: GPL-2.0-only 2*e9a7b78bSAbel Vesa /* 3*e9a7b78bSAbel Vesa * Copyright (c) 2021, The Linux Foundation. All rights reserved. 4*e9a7b78bSAbel Vesa * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. 5*e9a7b78bSAbel Vesa * Copyright (c) 2022, Linaro Limited 6*e9a7b78bSAbel Vesa */ 7*e9a7b78bSAbel Vesa 8*e9a7b78bSAbel Vesa #include <linux/clk-provider.h> 9*e9a7b78bSAbel Vesa #include <linux/module.h> 10*e9a7b78bSAbel Vesa #include <linux/of_device.h> 11*e9a7b78bSAbel Vesa #include <linux/regmap.h> 12*e9a7b78bSAbel Vesa 13*e9a7b78bSAbel Vesa #include <dt-bindings/clock/qcom,sm8550-tcsr.h> 14*e9a7b78bSAbel Vesa 15*e9a7b78bSAbel Vesa #include "clk-alpha-pll.h" 16*e9a7b78bSAbel Vesa #include "clk-branch.h" 17*e9a7b78bSAbel Vesa #include "clk-pll.h" 18*e9a7b78bSAbel Vesa #include "clk-rcg.h" 19*e9a7b78bSAbel Vesa #include "clk-regmap.h" 20*e9a7b78bSAbel Vesa #include "clk-regmap-divider.h" 21*e9a7b78bSAbel Vesa #include "clk-regmap-mux.h" 22*e9a7b78bSAbel Vesa #include "common.h" 23*e9a7b78bSAbel Vesa #include "reset.h" 24*e9a7b78bSAbel Vesa 25*e9a7b78bSAbel Vesa enum { 26*e9a7b78bSAbel Vesa DT_BI_TCXO_PAD, 27*e9a7b78bSAbel Vesa }; 28*e9a7b78bSAbel Vesa 29*e9a7b78bSAbel Vesa static struct clk_branch tcsr_pcie_0_clkref_en = { 30*e9a7b78bSAbel Vesa .halt_reg = 0x15100, 31*e9a7b78bSAbel Vesa .halt_check = BRANCH_HALT_SKIP, 32*e9a7b78bSAbel Vesa .clkr = { 33*e9a7b78bSAbel Vesa .enable_reg = 0x15100, 34*e9a7b78bSAbel Vesa .enable_mask = BIT(0), 35*e9a7b78bSAbel Vesa .hw.init = &(struct clk_init_data){ 36*e9a7b78bSAbel Vesa .name = "tcsr_pcie_0_clkref_en", 37*e9a7b78bSAbel Vesa .parent_data = &(const struct clk_parent_data){ 38*e9a7b78bSAbel Vesa .index = DT_BI_TCXO_PAD, 39*e9a7b78bSAbel Vesa }, 40*e9a7b78bSAbel Vesa .num_parents = 1, 41*e9a7b78bSAbel Vesa .ops = &clk_branch2_ops, 42*e9a7b78bSAbel Vesa }, 43*e9a7b78bSAbel Vesa }, 44*e9a7b78bSAbel Vesa }; 45*e9a7b78bSAbel Vesa 46*e9a7b78bSAbel Vesa static struct clk_branch tcsr_pcie_1_clkref_en = { 47*e9a7b78bSAbel Vesa .halt_reg = 0x15114, 48*e9a7b78bSAbel Vesa .halt_check = BRANCH_HALT_SKIP, 49*e9a7b78bSAbel Vesa .clkr = { 50*e9a7b78bSAbel Vesa .enable_reg = 0x15114, 51*e9a7b78bSAbel Vesa .enable_mask = BIT(0), 52*e9a7b78bSAbel Vesa .hw.init = &(struct clk_init_data){ 53*e9a7b78bSAbel Vesa .name = "tcsr_pcie_1_clkref_en", 54*e9a7b78bSAbel Vesa .parent_data = &(const struct clk_parent_data){ 55*e9a7b78bSAbel Vesa .index = DT_BI_TCXO_PAD, 56*e9a7b78bSAbel Vesa }, 57*e9a7b78bSAbel Vesa .num_parents = 1, 58*e9a7b78bSAbel Vesa .ops = &clk_branch2_ops, 59*e9a7b78bSAbel Vesa }, 60*e9a7b78bSAbel Vesa }, 61*e9a7b78bSAbel Vesa }; 62*e9a7b78bSAbel Vesa 63*e9a7b78bSAbel Vesa static struct clk_branch tcsr_ufs_clkref_en = { 64*e9a7b78bSAbel Vesa .halt_reg = 0x15110, 65*e9a7b78bSAbel Vesa .halt_check = BRANCH_HALT_SKIP, 66*e9a7b78bSAbel Vesa .clkr = { 67*e9a7b78bSAbel Vesa .enable_reg = 0x15110, 68*e9a7b78bSAbel Vesa .enable_mask = BIT(0), 69*e9a7b78bSAbel Vesa .hw.init = &(struct clk_init_data){ 70*e9a7b78bSAbel Vesa .name = "tcsr_ufs_clkref_en", 71*e9a7b78bSAbel Vesa .parent_data = &(const struct clk_parent_data){ 72*e9a7b78bSAbel Vesa .index = DT_BI_TCXO_PAD, 73*e9a7b78bSAbel Vesa }, 74*e9a7b78bSAbel Vesa .num_parents = 1, 75*e9a7b78bSAbel Vesa .ops = &clk_branch2_ops, 76*e9a7b78bSAbel Vesa }, 77*e9a7b78bSAbel Vesa }, 78*e9a7b78bSAbel Vesa }; 79*e9a7b78bSAbel Vesa 80*e9a7b78bSAbel Vesa static struct clk_branch tcsr_ufs_pad_clkref_en = { 81*e9a7b78bSAbel Vesa .halt_reg = 0x15104, 82*e9a7b78bSAbel Vesa .halt_check = BRANCH_HALT_SKIP, 83*e9a7b78bSAbel Vesa .clkr = { 84*e9a7b78bSAbel Vesa .enable_reg = 0x15104, 85*e9a7b78bSAbel Vesa .enable_mask = BIT(0), 86*e9a7b78bSAbel Vesa .hw.init = &(struct clk_init_data){ 87*e9a7b78bSAbel Vesa .name = "tcsr_ufs_pad_clkref_en", 88*e9a7b78bSAbel Vesa .parent_data = &(const struct clk_parent_data){ 89*e9a7b78bSAbel Vesa .index = DT_BI_TCXO_PAD, 90*e9a7b78bSAbel Vesa }, 91*e9a7b78bSAbel Vesa .num_parents = 1, 92*e9a7b78bSAbel Vesa .ops = &clk_branch2_ops, 93*e9a7b78bSAbel Vesa }, 94*e9a7b78bSAbel Vesa }, 95*e9a7b78bSAbel Vesa }; 96*e9a7b78bSAbel Vesa 97*e9a7b78bSAbel Vesa static struct clk_branch tcsr_usb2_clkref_en = { 98*e9a7b78bSAbel Vesa .halt_reg = 0x15118, 99*e9a7b78bSAbel Vesa .halt_check = BRANCH_HALT_SKIP, 100*e9a7b78bSAbel Vesa .clkr = { 101*e9a7b78bSAbel Vesa .enable_reg = 0x15118, 102*e9a7b78bSAbel Vesa .enable_mask = BIT(0), 103*e9a7b78bSAbel Vesa .hw.init = &(struct clk_init_data){ 104*e9a7b78bSAbel Vesa .name = "tcsr_usb2_clkref_en", 105*e9a7b78bSAbel Vesa .parent_data = &(const struct clk_parent_data){ 106*e9a7b78bSAbel Vesa .index = DT_BI_TCXO_PAD, 107*e9a7b78bSAbel Vesa }, 108*e9a7b78bSAbel Vesa .num_parents = 1, 109*e9a7b78bSAbel Vesa .ops = &clk_branch2_ops, 110*e9a7b78bSAbel Vesa }, 111*e9a7b78bSAbel Vesa }, 112*e9a7b78bSAbel Vesa }; 113*e9a7b78bSAbel Vesa 114*e9a7b78bSAbel Vesa static struct clk_branch tcsr_usb3_clkref_en = { 115*e9a7b78bSAbel Vesa .halt_reg = 0x15108, 116*e9a7b78bSAbel Vesa .halt_check = BRANCH_HALT_SKIP, 117*e9a7b78bSAbel Vesa .clkr = { 118*e9a7b78bSAbel Vesa .enable_reg = 0x15108, 119*e9a7b78bSAbel Vesa .enable_mask = BIT(0), 120*e9a7b78bSAbel Vesa .hw.init = &(struct clk_init_data){ 121*e9a7b78bSAbel Vesa .name = "tcsr_usb3_clkref_en", 122*e9a7b78bSAbel Vesa .parent_data = &(const struct clk_parent_data){ 123*e9a7b78bSAbel Vesa .index = DT_BI_TCXO_PAD, 124*e9a7b78bSAbel Vesa }, 125*e9a7b78bSAbel Vesa .num_parents = 1, 126*e9a7b78bSAbel Vesa .ops = &clk_branch2_ops, 127*e9a7b78bSAbel Vesa }, 128*e9a7b78bSAbel Vesa }, 129*e9a7b78bSAbel Vesa }; 130*e9a7b78bSAbel Vesa 131*e9a7b78bSAbel Vesa static struct clk_regmap *tcsr_cc_sm8550_clocks[] = { 132*e9a7b78bSAbel Vesa [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr, 133*e9a7b78bSAbel Vesa [TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr, 134*e9a7b78bSAbel Vesa [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr, 135*e9a7b78bSAbel Vesa [TCSR_UFS_PAD_CLKREF_EN] = &tcsr_ufs_pad_clkref_en.clkr, 136*e9a7b78bSAbel Vesa [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr, 137*e9a7b78bSAbel Vesa [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr, 138*e9a7b78bSAbel Vesa }; 139*e9a7b78bSAbel Vesa 140*e9a7b78bSAbel Vesa static const struct regmap_config tcsr_cc_sm8550_regmap_config = { 141*e9a7b78bSAbel Vesa .reg_bits = 32, 142*e9a7b78bSAbel Vesa .reg_stride = 4, 143*e9a7b78bSAbel Vesa .val_bits = 32, 144*e9a7b78bSAbel Vesa .max_register = 0x2f000, 145*e9a7b78bSAbel Vesa .fast_io = true, 146*e9a7b78bSAbel Vesa }; 147*e9a7b78bSAbel Vesa 148*e9a7b78bSAbel Vesa static const struct qcom_cc_desc tcsr_cc_sm8550_desc = { 149*e9a7b78bSAbel Vesa .config = &tcsr_cc_sm8550_regmap_config, 150*e9a7b78bSAbel Vesa .clks = tcsr_cc_sm8550_clocks, 151*e9a7b78bSAbel Vesa .num_clks = ARRAY_SIZE(tcsr_cc_sm8550_clocks), 152*e9a7b78bSAbel Vesa }; 153*e9a7b78bSAbel Vesa 154*e9a7b78bSAbel Vesa static const struct of_device_id tcsr_cc_sm8550_match_table[] = { 155*e9a7b78bSAbel Vesa { .compatible = "qcom,sm8550-tcsr" }, 156*e9a7b78bSAbel Vesa { } 157*e9a7b78bSAbel Vesa }; 158*e9a7b78bSAbel Vesa MODULE_DEVICE_TABLE(of, tcsr_cc_sm8550_match_table); 159*e9a7b78bSAbel Vesa 160*e9a7b78bSAbel Vesa static int tcsr_cc_sm8550_probe(struct platform_device *pdev) 161*e9a7b78bSAbel Vesa { 162*e9a7b78bSAbel Vesa struct regmap *regmap; 163*e9a7b78bSAbel Vesa 164*e9a7b78bSAbel Vesa regmap = qcom_cc_map(pdev, &tcsr_cc_sm8550_desc); 165*e9a7b78bSAbel Vesa if (IS_ERR(regmap)) 166*e9a7b78bSAbel Vesa return PTR_ERR(regmap); 167*e9a7b78bSAbel Vesa 168*e9a7b78bSAbel Vesa return qcom_cc_really_probe(pdev, &tcsr_cc_sm8550_desc, regmap); 169*e9a7b78bSAbel Vesa } 170*e9a7b78bSAbel Vesa 171*e9a7b78bSAbel Vesa static struct platform_driver tcsr_cc_sm8550_driver = { 172*e9a7b78bSAbel Vesa .probe = tcsr_cc_sm8550_probe, 173*e9a7b78bSAbel Vesa .driver = { 174*e9a7b78bSAbel Vesa .name = "tcsr_cc-sm8550", 175*e9a7b78bSAbel Vesa .of_match_table = tcsr_cc_sm8550_match_table, 176*e9a7b78bSAbel Vesa }, 177*e9a7b78bSAbel Vesa }; 178*e9a7b78bSAbel Vesa 179*e9a7b78bSAbel Vesa static int __init tcsr_cc_sm8550_init(void) 180*e9a7b78bSAbel Vesa { 181*e9a7b78bSAbel Vesa return platform_driver_register(&tcsr_cc_sm8550_driver); 182*e9a7b78bSAbel Vesa } 183*e9a7b78bSAbel Vesa subsys_initcall(tcsr_cc_sm8550_init); 184*e9a7b78bSAbel Vesa 185*e9a7b78bSAbel Vesa static void __exit tcsr_cc_sm8550_exit(void) 186*e9a7b78bSAbel Vesa { 187*e9a7b78bSAbel Vesa platform_driver_unregister(&tcsr_cc_sm8550_driver); 188*e9a7b78bSAbel Vesa } 189*e9a7b78bSAbel Vesa module_exit(tcsr_cc_sm8550_exit); 190*e9a7b78bSAbel Vesa 191*e9a7b78bSAbel Vesa MODULE_DESCRIPTION("QTI TCSRCC SM8550 Driver"); 192*e9a7b78bSAbel Vesa MODULE_LICENSE("GPL"); 193