Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2019, Linaro Ltd.
0004  */
0005 
0006 #include <linux/bitops.h>
0007 #include <linux/clk-provider.h>
0008 #include <linux/err.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/module.h>
0011 #include <linux/of_address.h>
0012 #include <linux/pm_clock.h>
0013 #include <linux/pm_runtime.h>
0014 #include <linux/regmap.h>
0015 
0016 #include <dt-bindings/clock/qcom,turingcc-qcs404.h>
0017 
0018 #include "clk-regmap.h"
0019 #include "clk-branch.h"
0020 #include "common.h"
0021 #include "reset.h"
0022 
0023 static struct clk_branch turing_wrapper_aon_cbcr = {
0024     .halt_reg = 0x5098,
0025     .halt_check = BRANCH_HALT,
0026     .clkr = {
0027         .enable_reg = 0x5098,
0028         .enable_mask = BIT(0),
0029         .hw.init = &(struct clk_init_data) {
0030             .name = "turing_wrapper_aon_clk",
0031             .ops = &clk_branch2_aon_ops,
0032         },
0033     },
0034 };
0035 
0036 static struct clk_branch turing_q6ss_ahbm_aon_cbcr = {
0037     .halt_reg = 0x9000,
0038     .halt_check = BRANCH_HALT,
0039     .clkr = {
0040         .enable_reg = 0x9000,
0041         .enable_mask = BIT(0),
0042         .hw.init = &(struct clk_init_data) {
0043             .name = "turing_q6ss_ahbm_aon_cbcr",
0044             .ops = &clk_branch2_ops,
0045         },
0046     },
0047 };
0048 
0049 static struct clk_branch turing_q6ss_q6_axim_clk = {
0050     .halt_reg = 0xb000,
0051     .halt_check = BRANCH_HALT,
0052     .clkr = {
0053         .enable_reg = 0xb000,
0054         .enable_mask = BIT(0),
0055         .hw.init = &(struct clk_init_data) {
0056             .name = "turing_q6ss_q6_axim_clk",
0057             .ops = &clk_branch2_aon_ops,
0058         },
0059     },
0060 };
0061 
0062 static struct clk_branch turing_q6ss_ahbs_aon_cbcr = {
0063     .halt_reg = 0x10000,
0064     .halt_check = BRANCH_HALT,
0065     .clkr = {
0066         .enable_reg = 0x10000,
0067         .enable_mask = BIT(0),
0068         .hw.init = &(struct clk_init_data) {
0069             .name = "turing_q6ss_ahbs_aon_clk",
0070             .ops = &clk_branch2_aon_ops,
0071         },
0072     },
0073 };
0074 
0075 static struct clk_branch turing_wrapper_qos_ahbs_aon_cbcr = {
0076     .halt_reg = 0x11014,
0077     .halt_check = BRANCH_HALT,
0078     .clkr = {
0079         .enable_reg = 0x11014,
0080         .enable_mask = BIT(0),
0081         .hw.init = &(struct clk_init_data) {
0082             .name = "turing_wrapper_qos_ahbs_aon_clk",
0083             .ops = &clk_branch2_aon_ops,
0084         },
0085     },
0086 };
0087 
0088 static struct clk_regmap *turingcc_clocks[] = {
0089     [TURING_WRAPPER_AON_CLK] = &turing_wrapper_aon_cbcr.clkr,
0090     [TURING_Q6SS_AHBM_AON_CLK] = &turing_q6ss_ahbm_aon_cbcr.clkr,
0091     [TURING_Q6SS_Q6_AXIM_CLK] = &turing_q6ss_q6_axim_clk.clkr,
0092     [TURING_Q6SS_AHBS_AON_CLK] = &turing_q6ss_ahbs_aon_cbcr.clkr,
0093     [TURING_WRAPPER_QOS_AHBS_AON_CLK] = &turing_wrapper_qos_ahbs_aon_cbcr.clkr,
0094 };
0095 
0096 static const struct regmap_config turingcc_regmap_config = {
0097     .reg_bits   = 32,
0098     .reg_stride = 4,
0099     .val_bits   = 32,
0100     .max_register   = 0x23004,
0101     .fast_io    = true,
0102 };
0103 
0104 static const struct qcom_cc_desc turingcc_desc = {
0105     .config = &turingcc_regmap_config,
0106     .clks = turingcc_clocks,
0107     .num_clks = ARRAY_SIZE(turingcc_clocks),
0108 };
0109 
0110 static int turingcc_probe(struct platform_device *pdev)
0111 {
0112     int ret;
0113 
0114     ret = devm_pm_runtime_enable(&pdev->dev);
0115     if (ret)
0116         return ret;
0117 
0118     ret = devm_pm_clk_create(&pdev->dev);
0119     if (ret)
0120         return ret;
0121 
0122     ret = pm_clk_add(&pdev->dev, NULL);
0123     if (ret < 0) {
0124         dev_err(&pdev->dev, "failed to acquire iface clock\n");
0125         return ret;
0126     }
0127 
0128     ret = qcom_cc_probe(pdev, &turingcc_desc);
0129     if (ret < 0)
0130         return ret;
0131 
0132     return 0;
0133 }
0134 
0135 static const struct dev_pm_ops turingcc_pm_ops = {
0136     SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
0137 };
0138 
0139 static const struct of_device_id turingcc_match_table[] = {
0140     { .compatible = "qcom,qcs404-turingcc" },
0141     { }
0142 };
0143 MODULE_DEVICE_TABLE(of, turingcc_match_table);
0144 
0145 static struct platform_driver turingcc_driver = {
0146     .probe      = turingcc_probe,
0147     .driver     = {
0148         .name   = "qcs404-turingcc",
0149         .of_match_table = turingcc_match_table,
0150         .pm = &turingcc_pm_ops,
0151     },
0152 };
0153 
0154 module_platform_driver(turingcc_driver);
0155 
0156 MODULE_DESCRIPTION("Qualcomm QCS404 Turing Clock Controller");
0157 MODULE_LICENSE("GPL v2");