1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019, Linaro Ltd.
6 #include <linux/bitops.h>
8 #include <linux/platform_device.h>
9 #include <linux/module.h>
10 #include <linux/of_address.h>
11 #include <linux/pm_clock.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/regmap.h>
15 #include <dt-bindings/clock/qcom,turingcc-qcs404.h>
17 #include "clk-regmap.h"
18 #include "clk-branch.h"
22 static struct clk_branch turing_wrapper_aon_cbcr
= {
24 .halt_check
= BRANCH_HALT
,
27 .enable_mask
= BIT(0),
28 .hw
.init
= &(struct clk_init_data
) {
29 .name
= "turing_wrapper_aon_clk",
30 .ops
= &clk_branch2_aon_ops
,
35 static struct clk_branch turing_q6ss_ahbm_aon_cbcr
= {
37 .halt_check
= BRANCH_HALT
,
40 .enable_mask
= BIT(0),
41 .hw
.init
= &(struct clk_init_data
) {
42 .name
= "turing_q6ss_ahbm_aon_cbcr",
43 .ops
= &clk_branch2_ops
,
48 static struct clk_branch turing_q6ss_q6_axim_clk
= {
50 .halt_check
= BRANCH_HALT
,
53 .enable_mask
= BIT(0),
54 .hw
.init
= &(struct clk_init_data
) {
55 .name
= "turing_q6ss_q6_axim_clk",
56 .ops
= &clk_branch2_aon_ops
,
61 static struct clk_branch turing_q6ss_ahbs_aon_cbcr
= {
63 .halt_check
= BRANCH_HALT
,
65 .enable_reg
= 0x10000,
66 .enable_mask
= BIT(0),
67 .hw
.init
= &(struct clk_init_data
) {
68 .name
= "turing_q6ss_ahbs_aon_clk",
69 .ops
= &clk_branch2_aon_ops
,
74 static struct clk_branch turing_wrapper_qos_ahbs_aon_cbcr
= {
76 .halt_check
= BRANCH_HALT
,
78 .enable_reg
= 0x11014,
79 .enable_mask
= BIT(0),
80 .hw
.init
= &(struct clk_init_data
) {
81 .name
= "turing_wrapper_qos_ahbs_aon_clk",
82 .ops
= &clk_branch2_aon_ops
,
87 static struct clk_regmap
*turingcc_clocks
[] = {
88 [TURING_WRAPPER_AON_CLK
] = &turing_wrapper_aon_cbcr
.clkr
,
89 [TURING_Q6SS_AHBM_AON_CLK
] = &turing_q6ss_ahbm_aon_cbcr
.clkr
,
90 [TURING_Q6SS_Q6_AXIM_CLK
] = &turing_q6ss_q6_axim_clk
.clkr
,
91 [TURING_Q6SS_AHBS_AON_CLK
] = &turing_q6ss_ahbs_aon_cbcr
.clkr
,
92 [TURING_WRAPPER_QOS_AHBS_AON_CLK
] = &turing_wrapper_qos_ahbs_aon_cbcr
.clkr
,
95 static const struct regmap_config turingcc_regmap_config
= {
99 .max_register
= 0x23004,
103 static const struct qcom_cc_desc turingcc_desc
= {
104 .config
= &turingcc_regmap_config
,
105 .clks
= turingcc_clocks
,
106 .num_clks
= ARRAY_SIZE(turingcc_clocks
),
109 static int turingcc_probe(struct platform_device
*pdev
)
113 pm_runtime_enable(&pdev
->dev
);
114 ret
= pm_clk_create(&pdev
->dev
);
116 goto disable_pm_runtime
;
118 ret
= pm_clk_add(&pdev
->dev
, NULL
);
120 dev_err(&pdev
->dev
, "failed to acquire iface clock\n");
124 ret
= qcom_cc_probe(pdev
, &turingcc_desc
);
131 pm_clk_destroy(&pdev
->dev
);
134 pm_runtime_disable(&pdev
->dev
);
139 static int turingcc_remove(struct platform_device
*pdev
)
141 pm_clk_destroy(&pdev
->dev
);
142 pm_runtime_disable(&pdev
->dev
);
147 static const struct dev_pm_ops turingcc_pm_ops
= {
148 SET_RUNTIME_PM_OPS(pm_clk_suspend
, pm_clk_resume
, NULL
)
151 static const struct of_device_id turingcc_match_table
[] = {
152 { .compatible
= "qcom,qcs404-turingcc" },
155 MODULE_DEVICE_TABLE(of
, turingcc_match_table
);
157 static struct platform_driver turingcc_driver
= {
158 .probe
= turingcc_probe
,
159 .remove
= turingcc_remove
,
161 .name
= "qcs404-turingcc",
162 .of_match_table
= turingcc_match_table
,
163 .pm
= &turingcc_pm_ops
,
167 module_platform_driver(turingcc_driver
);
169 MODULE_DESCRIPTION("Qualcomm QCS404 Turing Clock Controller");
170 MODULE_LICENSE("GPL v2");