0001
0002
0003
0004
0005
0006 #include <linux/clk-provider.h>
0007 #include <linux/platform_device.h>
0008 #include <linux/module.h>
0009 #include <linux/pm_clock.h>
0010 #include <linux/pm_runtime.h>
0011 #include <linux/regmap.h>
0012
0013 #include <dt-bindings/clock/qcom,mss-sc7180.h>
0014
0015 #include "clk-regmap.h"
0016 #include "clk-branch.h"
0017 #include "common.h"
0018
0019 static struct clk_branch mss_axi_nav_clk = {
0020 .halt_reg = 0x20bc,
0021 .halt_check = BRANCH_HALT,
0022 .clkr = {
0023 .enable_reg = 0x20bc,
0024 .enable_mask = BIT(0),
0025 .hw.init = &(struct clk_init_data){
0026 .name = "mss_axi_nav_clk",
0027 .parent_data = &(const struct clk_parent_data){
0028 .fw_name = "gcc_mss_nav_axi",
0029 },
0030 .num_parents = 1,
0031 .ops = &clk_branch2_ops,
0032 },
0033 },
0034 };
0035
0036 static struct clk_branch mss_axi_crypto_clk = {
0037 .halt_reg = 0x20cc,
0038 .halt_check = BRANCH_HALT,
0039 .clkr = {
0040 .enable_reg = 0x20cc,
0041 .enable_mask = BIT(0),
0042 .hw.init = &(struct clk_init_data){
0043 .name = "mss_axi_crypto_clk",
0044 .parent_data = &(const struct clk_parent_data){
0045 .fw_name = "gcc_mss_mfab_axis",
0046 },
0047 .num_parents = 1,
0048 .ops = &clk_branch2_ops,
0049 },
0050 },
0051 };
0052
0053 static const struct regmap_config mss_regmap_config = {
0054 .reg_bits = 32,
0055 .reg_stride = 4,
0056 .val_bits = 32,
0057 .fast_io = true,
0058 .max_register = 0x41aa0cc,
0059 };
0060
0061 static struct clk_regmap *mss_sc7180_clocks[] = {
0062 [MSS_AXI_CRYPTO_CLK] = &mss_axi_crypto_clk.clkr,
0063 [MSS_AXI_NAV_CLK] = &mss_axi_nav_clk.clkr,
0064 };
0065
0066 static const struct qcom_cc_desc mss_sc7180_desc = {
0067 .config = &mss_regmap_config,
0068 .clks = mss_sc7180_clocks,
0069 .num_clks = ARRAY_SIZE(mss_sc7180_clocks),
0070 };
0071
0072 static int mss_sc7180_probe(struct platform_device *pdev)
0073 {
0074 int ret;
0075
0076 ret = devm_pm_runtime_enable(&pdev->dev);
0077 if (ret)
0078 return ret;
0079
0080 ret = devm_pm_clk_create(&pdev->dev);
0081 if (ret)
0082 return ret;
0083
0084 ret = pm_clk_add(&pdev->dev, "cfg_ahb");
0085 if (ret < 0) {
0086 dev_err(&pdev->dev, "failed to acquire iface clock\n");
0087 return ret;
0088 }
0089
0090 ret = qcom_cc_probe(pdev, &mss_sc7180_desc);
0091 if (ret < 0)
0092 return ret;
0093
0094 return 0;
0095 }
0096
0097 static const struct dev_pm_ops mss_sc7180_pm_ops = {
0098 SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
0099 };
0100
0101 static const struct of_device_id mss_sc7180_match_table[] = {
0102 { .compatible = "qcom,sc7180-mss" },
0103 { }
0104 };
0105 MODULE_DEVICE_TABLE(of, mss_sc7180_match_table);
0106
0107 static struct platform_driver mss_sc7180_driver = {
0108 .probe = mss_sc7180_probe,
0109 .driver = {
0110 .name = "sc7180-mss",
0111 .of_match_table = mss_sc7180_match_table,
0112 .pm = &mss_sc7180_pm_ops,
0113 },
0114 };
0115
0116 static int __init mss_sc7180_init(void)
0117 {
0118 return platform_driver_register(&mss_sc7180_driver);
0119 }
0120 subsys_initcall(mss_sc7180_init);
0121
0122 static void __exit mss_sc7180_exit(void)
0123 {
0124 platform_driver_unregister(&mss_sc7180_driver);
0125 }
0126 module_exit(mss_sc7180_exit);
0127
0128 MODULE_DESCRIPTION("QTI MSS SC7180 Driver");
0129 MODULE_LICENSE("GPL v2");