18d3e5b9cSTaniya Das // SPDX-License-Identifier: GPL-2.0
28d3e5b9cSTaniya Das /*
38d3e5b9cSTaniya Das * Copyright (c) 2018, The Linux Foundation. All rights reserved.
48d3e5b9cSTaniya Das */
58d3e5b9cSTaniya Das
6*3333607bSVinod Koul #include <linux/clk-provider.h>
78d3e5b9cSTaniya Das #include <linux/platform_device.h>
88d3e5b9cSTaniya Das #include <linux/module.h>
98d3e5b9cSTaniya Das #include <linux/of_address.h>
108d3e5b9cSTaniya Das #include <linux/regmap.h>
118d3e5b9cSTaniya Das
128d3e5b9cSTaniya Das #include <dt-bindings/clock/qcom,lpass-sdm845.h>
138d3e5b9cSTaniya Das
148d3e5b9cSTaniya Das #include "clk-regmap.h"
158d3e5b9cSTaniya Das #include "clk-branch.h"
168d3e5b9cSTaniya Das #include "common.h"
178d3e5b9cSTaniya Das
188d3e5b9cSTaniya Das static struct clk_branch lpass_q6ss_ahbm_aon_clk = {
198d3e5b9cSTaniya Das .halt_reg = 0x12000,
208d3e5b9cSTaniya Das .halt_check = BRANCH_VOTED,
218d3e5b9cSTaniya Das .clkr = {
228d3e5b9cSTaniya Das .enable_reg = 0x12000,
238d3e5b9cSTaniya Das .enable_mask = BIT(0),
248d3e5b9cSTaniya Das .hw.init = &(struct clk_init_data){
258d3e5b9cSTaniya Das .name = "lpass_q6ss_ahbm_aon_clk",
268d3e5b9cSTaniya Das .ops = &clk_branch2_ops,
278d3e5b9cSTaniya Das },
288d3e5b9cSTaniya Das },
298d3e5b9cSTaniya Das };
308d3e5b9cSTaniya Das
318d3e5b9cSTaniya Das static struct clk_branch lpass_q6ss_ahbs_aon_clk = {
328d3e5b9cSTaniya Das .halt_reg = 0x1f000,
338d3e5b9cSTaniya Das .halt_check = BRANCH_VOTED,
348d3e5b9cSTaniya Das .clkr = {
358d3e5b9cSTaniya Das .enable_reg = 0x1f000,
368d3e5b9cSTaniya Das .enable_mask = BIT(0),
378d3e5b9cSTaniya Das .hw.init = &(struct clk_init_data){
388d3e5b9cSTaniya Das .name = "lpass_q6ss_ahbs_aon_clk",
398d3e5b9cSTaniya Das .ops = &clk_branch2_ops,
408d3e5b9cSTaniya Das },
418d3e5b9cSTaniya Das },
428d3e5b9cSTaniya Das };
438d3e5b9cSTaniya Das
448d3e5b9cSTaniya Das static struct clk_branch lpass_qdsp6ss_core_clk = {
458d3e5b9cSTaniya Das .halt_reg = 0x20,
468d3e5b9cSTaniya Das /* CLK_OFF would not toggle until LPASS is out of reset */
478d3e5b9cSTaniya Das .halt_check = BRANCH_HALT_SKIP,
488d3e5b9cSTaniya Das .clkr = {
498d3e5b9cSTaniya Das .enable_reg = 0x20,
508d3e5b9cSTaniya Das .enable_mask = BIT(0),
518d3e5b9cSTaniya Das .hw.init = &(struct clk_init_data){
528d3e5b9cSTaniya Das .name = "lpass_qdsp6ss_core_clk",
538d3e5b9cSTaniya Das .ops = &clk_branch2_ops,
548d3e5b9cSTaniya Das },
558d3e5b9cSTaniya Das },
568d3e5b9cSTaniya Das };
578d3e5b9cSTaniya Das
588d3e5b9cSTaniya Das static struct clk_branch lpass_qdsp6ss_xo_clk = {
598d3e5b9cSTaniya Das .halt_reg = 0x38,
608d3e5b9cSTaniya Das /* CLK_OFF would not toggle until LPASS is out of reset */
618d3e5b9cSTaniya Das .halt_check = BRANCH_HALT_SKIP,
628d3e5b9cSTaniya Das .clkr = {
638d3e5b9cSTaniya Das .enable_reg = 0x38,
648d3e5b9cSTaniya Das .enable_mask = BIT(0),
658d3e5b9cSTaniya Das .hw.init = &(struct clk_init_data){
668d3e5b9cSTaniya Das .name = "lpass_qdsp6ss_xo_clk",
678d3e5b9cSTaniya Das .ops = &clk_branch2_ops,
688d3e5b9cSTaniya Das },
698d3e5b9cSTaniya Das },
708d3e5b9cSTaniya Das };
718d3e5b9cSTaniya Das
728d3e5b9cSTaniya Das static struct clk_branch lpass_qdsp6ss_sleep_clk = {
738d3e5b9cSTaniya Das .halt_reg = 0x3c,
748d3e5b9cSTaniya Das /* CLK_OFF would not toggle until LPASS is out of reset */
758d3e5b9cSTaniya Das .halt_check = BRANCH_HALT_SKIP,
768d3e5b9cSTaniya Das .clkr = {
778d3e5b9cSTaniya Das .enable_reg = 0x3c,
788d3e5b9cSTaniya Das .enable_mask = BIT(0),
798d3e5b9cSTaniya Das .hw.init = &(struct clk_init_data){
808d3e5b9cSTaniya Das .name = "lpass_qdsp6ss_sleep_clk",
818d3e5b9cSTaniya Das .ops = &clk_branch2_ops,
828d3e5b9cSTaniya Das },
838d3e5b9cSTaniya Das },
848d3e5b9cSTaniya Das };
858d3e5b9cSTaniya Das
868d3e5b9cSTaniya Das static struct regmap_config lpass_regmap_config = {
878d3e5b9cSTaniya Das .reg_bits = 32,
888d3e5b9cSTaniya Das .reg_stride = 4,
898d3e5b9cSTaniya Das .val_bits = 32,
908d3e5b9cSTaniya Das .fast_io = true,
918d3e5b9cSTaniya Das };
928d3e5b9cSTaniya Das
938d3e5b9cSTaniya Das static struct clk_regmap *lpass_cc_sdm845_clocks[] = {
948d3e5b9cSTaniya Das [LPASS_Q6SS_AHBM_AON_CLK] = &lpass_q6ss_ahbm_aon_clk.clkr,
958d3e5b9cSTaniya Das [LPASS_Q6SS_AHBS_AON_CLK] = &lpass_q6ss_ahbs_aon_clk.clkr,
968d3e5b9cSTaniya Das };
978d3e5b9cSTaniya Das
988d3e5b9cSTaniya Das static const struct qcom_cc_desc lpass_cc_sdm845_desc = {
998d3e5b9cSTaniya Das .config = &lpass_regmap_config,
1008d3e5b9cSTaniya Das .clks = lpass_cc_sdm845_clocks,
1018d3e5b9cSTaniya Das .num_clks = ARRAY_SIZE(lpass_cc_sdm845_clocks),
1028d3e5b9cSTaniya Das };
1038d3e5b9cSTaniya Das
1048d3e5b9cSTaniya Das static struct clk_regmap *lpass_qdsp6ss_sdm845_clocks[] = {
1058d3e5b9cSTaniya Das [LPASS_QDSP6SS_XO_CLK] = &lpass_qdsp6ss_xo_clk.clkr,
1068d3e5b9cSTaniya Das [LPASS_QDSP6SS_SLEEP_CLK] = &lpass_qdsp6ss_sleep_clk.clkr,
1078d3e5b9cSTaniya Das [LPASS_QDSP6SS_CORE_CLK] = &lpass_qdsp6ss_core_clk.clkr,
1088d3e5b9cSTaniya Das };
1098d3e5b9cSTaniya Das
1108d3e5b9cSTaniya Das static const struct qcom_cc_desc lpass_qdsp6ss_sdm845_desc = {
1118d3e5b9cSTaniya Das .config = &lpass_regmap_config,
1128d3e5b9cSTaniya Das .clks = lpass_qdsp6ss_sdm845_clocks,
1138d3e5b9cSTaniya Das .num_clks = ARRAY_SIZE(lpass_qdsp6ss_sdm845_clocks),
1148d3e5b9cSTaniya Das };
1158d3e5b9cSTaniya Das
lpass_cc_sdm845_probe(struct platform_device * pdev)1168d3e5b9cSTaniya Das static int lpass_cc_sdm845_probe(struct platform_device *pdev)
1178d3e5b9cSTaniya Das {
1188d3e5b9cSTaniya Das const struct qcom_cc_desc *desc;
1198d3e5b9cSTaniya Das int ret;
1208d3e5b9cSTaniya Das
1218d3e5b9cSTaniya Das lpass_regmap_config.name = "cc";
1228d3e5b9cSTaniya Das desc = &lpass_cc_sdm845_desc;
1238d3e5b9cSTaniya Das
12475e0a1e3SGovind Singh ret = qcom_cc_probe_by_index(pdev, 0, desc);
1258d3e5b9cSTaniya Das if (ret)
1268d3e5b9cSTaniya Das return ret;
1278d3e5b9cSTaniya Das
1288d3e5b9cSTaniya Das lpass_regmap_config.name = "qdsp6ss";
1298d3e5b9cSTaniya Das desc = &lpass_qdsp6ss_sdm845_desc;
1308d3e5b9cSTaniya Das
13175e0a1e3SGovind Singh return qcom_cc_probe_by_index(pdev, 1, desc);
1328d3e5b9cSTaniya Das }
1338d3e5b9cSTaniya Das
1348d3e5b9cSTaniya Das static const struct of_device_id lpass_cc_sdm845_match_table[] = {
1358d3e5b9cSTaniya Das { .compatible = "qcom,sdm845-lpasscc" },
1368d3e5b9cSTaniya Das { }
1378d3e5b9cSTaniya Das };
1388d3e5b9cSTaniya Das MODULE_DEVICE_TABLE(of, lpass_cc_sdm845_match_table);
1398d3e5b9cSTaniya Das
1408d3e5b9cSTaniya Das static struct platform_driver lpass_cc_sdm845_driver = {
1418d3e5b9cSTaniya Das .probe = lpass_cc_sdm845_probe,
1428d3e5b9cSTaniya Das .driver = {
1438d3e5b9cSTaniya Das .name = "sdm845-lpasscc",
1448d3e5b9cSTaniya Das .of_match_table = lpass_cc_sdm845_match_table,
1458d3e5b9cSTaniya Das },
1468d3e5b9cSTaniya Das };
1478d3e5b9cSTaniya Das
lpass_cc_sdm845_init(void)1488d3e5b9cSTaniya Das static int __init lpass_cc_sdm845_init(void)
1498d3e5b9cSTaniya Das {
1508d3e5b9cSTaniya Das return platform_driver_register(&lpass_cc_sdm845_driver);
1518d3e5b9cSTaniya Das }
1528d3e5b9cSTaniya Das subsys_initcall(lpass_cc_sdm845_init);
1538d3e5b9cSTaniya Das
lpass_cc_sdm845_exit(void)1548d3e5b9cSTaniya Das static void __exit lpass_cc_sdm845_exit(void)
1558d3e5b9cSTaniya Das {
1568d3e5b9cSTaniya Das platform_driver_unregister(&lpass_cc_sdm845_driver);
1578d3e5b9cSTaniya Das }
1588d3e5b9cSTaniya Das module_exit(lpass_cc_sdm845_exit);
1598d3e5b9cSTaniya Das
1608d3e5b9cSTaniya Das MODULE_DESCRIPTION("QTI LPASS_CC SDM845 Driver");
1618d3e5b9cSTaniya Das MODULE_LICENSE("GPL v2");
162