18def929cSTaniya Das // SPDX-License-Identifier: GPL-2.0-only
28def929cSTaniya Das /*
38def929cSTaniya Das * Copyright (c) 2020, The Linux Foundation. All rights reserved.
48def929cSTaniya Das */
58def929cSTaniya Das
68def929cSTaniya Das #include <linux/clk-provider.h>
78def929cSTaniya Das #include <linux/platform_device.h>
88def929cSTaniya Das #include <linux/module.h>
98def929cSTaniya Das #include <linux/pm_clock.h>
108def929cSTaniya Das #include <linux/pm_runtime.h>
118def929cSTaniya Das #include <linux/regmap.h>
128def929cSTaniya Das
138def929cSTaniya Das #include <dt-bindings/clock/qcom,mss-sc7180.h>
148def929cSTaniya Das
158def929cSTaniya Das #include "clk-regmap.h"
168def929cSTaniya Das #include "clk-branch.h"
178def929cSTaniya Das #include "common.h"
188def929cSTaniya Das
198def929cSTaniya Das static struct clk_branch mss_axi_nav_clk = {
208def929cSTaniya Das .halt_reg = 0x20bc,
218def929cSTaniya Das .halt_check = BRANCH_HALT,
228def929cSTaniya Das .clkr = {
238def929cSTaniya Das .enable_reg = 0x20bc,
248def929cSTaniya Das .enable_mask = BIT(0),
258def929cSTaniya Das .hw.init = &(struct clk_init_data){
268def929cSTaniya Das .name = "mss_axi_nav_clk",
278def929cSTaniya Das .parent_data = &(const struct clk_parent_data){
288def929cSTaniya Das .fw_name = "gcc_mss_nav_axi",
298def929cSTaniya Das },
308def929cSTaniya Das .num_parents = 1,
318def929cSTaniya Das .ops = &clk_branch2_ops,
328def929cSTaniya Das },
338def929cSTaniya Das },
348def929cSTaniya Das };
358def929cSTaniya Das
368def929cSTaniya Das static struct clk_branch mss_axi_crypto_clk = {
378def929cSTaniya Das .halt_reg = 0x20cc,
388def929cSTaniya Das .halt_check = BRANCH_HALT,
398def929cSTaniya Das .clkr = {
408def929cSTaniya Das .enable_reg = 0x20cc,
418def929cSTaniya Das .enable_mask = BIT(0),
428def929cSTaniya Das .hw.init = &(struct clk_init_data){
438def929cSTaniya Das .name = "mss_axi_crypto_clk",
448def929cSTaniya Das .parent_data = &(const struct clk_parent_data){
458def929cSTaniya Das .fw_name = "gcc_mss_mfab_axis",
468def929cSTaniya Das },
478def929cSTaniya Das .num_parents = 1,
488def929cSTaniya Das .ops = &clk_branch2_ops,
498def929cSTaniya Das },
508def929cSTaniya Das },
518def929cSTaniya Das };
528def929cSTaniya Das
538def929cSTaniya Das static const struct regmap_config mss_regmap_config = {
548def929cSTaniya Das .reg_bits = 32,
558def929cSTaniya Das .reg_stride = 4,
568def929cSTaniya Das .val_bits = 32,
578def929cSTaniya Das .fast_io = true,
588def929cSTaniya Das .max_register = 0x41aa0cc,
598def929cSTaniya Das };
608def929cSTaniya Das
618def929cSTaniya Das static struct clk_regmap *mss_sc7180_clocks[] = {
628def929cSTaniya Das [MSS_AXI_CRYPTO_CLK] = &mss_axi_crypto_clk.clkr,
638def929cSTaniya Das [MSS_AXI_NAV_CLK] = &mss_axi_nav_clk.clkr,
648def929cSTaniya Das };
658def929cSTaniya Das
668def929cSTaniya Das static const struct qcom_cc_desc mss_sc7180_desc = {
678def929cSTaniya Das .config = &mss_regmap_config,
688def929cSTaniya Das .clks = mss_sc7180_clocks,
698def929cSTaniya Das .num_clks = ARRAY_SIZE(mss_sc7180_clocks),
708def929cSTaniya Das };
718def929cSTaniya Das
mss_sc7180_probe(struct platform_device * pdev)728def929cSTaniya Das static int mss_sc7180_probe(struct platform_device *pdev)
738def929cSTaniya Das {
748def929cSTaniya Das int ret;
758def929cSTaniya Das
7672cfc73fSDmitry Baryshkov ret = devm_pm_runtime_enable(&pdev->dev);
778def929cSTaniya Das if (ret)
7872cfc73fSDmitry Baryshkov return ret;
7972cfc73fSDmitry Baryshkov
8072cfc73fSDmitry Baryshkov ret = devm_pm_clk_create(&pdev->dev);
8172cfc73fSDmitry Baryshkov if (ret)
8272cfc73fSDmitry Baryshkov return ret;
838def929cSTaniya Das
848def929cSTaniya Das ret = pm_clk_add(&pdev->dev, "cfg_ahb");
858def929cSTaniya Das if (ret < 0) {
868def929cSTaniya Das dev_err(&pdev->dev, "failed to acquire iface clock\n");
8772cfc73fSDmitry Baryshkov return ret;
888def929cSTaniya Das }
898def929cSTaniya Das
90*e2349da0SJohan Hovold ret = pm_runtime_resume_and_get(&pdev->dev);
91*e2349da0SJohan Hovold if (ret)
928def929cSTaniya Das return ret;
938def929cSTaniya Das
94*e2349da0SJohan Hovold ret = qcom_cc_probe(pdev, &mss_sc7180_desc);
95*e2349da0SJohan Hovold if (ret < 0)
96*e2349da0SJohan Hovold goto err_put_rpm;
97*e2349da0SJohan Hovold
98*e2349da0SJohan Hovold pm_runtime_put(&pdev->dev);
99*e2349da0SJohan Hovold
1008def929cSTaniya Das return 0;
101*e2349da0SJohan Hovold
102*e2349da0SJohan Hovold err_put_rpm:
103*e2349da0SJohan Hovold pm_runtime_put_sync(&pdev->dev);
104*e2349da0SJohan Hovold
105*e2349da0SJohan Hovold return ret;
1068def929cSTaniya Das }
1078def929cSTaniya Das
1088def929cSTaniya Das static const struct dev_pm_ops mss_sc7180_pm_ops = {
1098def929cSTaniya Das SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
1108def929cSTaniya Das };
1118def929cSTaniya Das
1128def929cSTaniya Das static const struct of_device_id mss_sc7180_match_table[] = {
1138def929cSTaniya Das { .compatible = "qcom,sc7180-mss" },
1148def929cSTaniya Das { }
1158def929cSTaniya Das };
1168def929cSTaniya Das MODULE_DEVICE_TABLE(of, mss_sc7180_match_table);
1178def929cSTaniya Das
1188def929cSTaniya Das static struct platform_driver mss_sc7180_driver = {
1198def929cSTaniya Das .probe = mss_sc7180_probe,
1208def929cSTaniya Das .driver = {
1218def929cSTaniya Das .name = "sc7180-mss",
1228def929cSTaniya Das .of_match_table = mss_sc7180_match_table,
1238def929cSTaniya Das .pm = &mss_sc7180_pm_ops,
1248def929cSTaniya Das },
1258def929cSTaniya Das };
1268def929cSTaniya Das
mss_sc7180_init(void)1278def929cSTaniya Das static int __init mss_sc7180_init(void)
1288def929cSTaniya Das {
1298def929cSTaniya Das return platform_driver_register(&mss_sc7180_driver);
1308def929cSTaniya Das }
1318def929cSTaniya Das subsys_initcall(mss_sc7180_init);
1328def929cSTaniya Das
mss_sc7180_exit(void)1338def929cSTaniya Das static void __exit mss_sc7180_exit(void)
1348def929cSTaniya Das {
1358def929cSTaniya Das platform_driver_unregister(&mss_sc7180_driver);
1368def929cSTaniya Das }
1378def929cSTaniya Das module_exit(mss_sc7180_exit);
1388def929cSTaniya Das
1398def929cSTaniya Das MODULE_DESCRIPTION("QTI MSS SC7180 Driver");
1408def929cSTaniya Das MODULE_LICENSE("GPL v2");
141