Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
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");