1892df019SBjorn Andersson // SPDX-License-Identifier: GPL-2.0
2892df019SBjorn Andersson /*
3892df019SBjorn Andersson  * Copyright (c) 2019, Linaro Ltd.
4892df019SBjorn Andersson  */
5892df019SBjorn Andersson 
6892df019SBjorn Andersson #include <linux/bitops.h>
7892df019SBjorn Andersson #include <linux/err.h>
8892df019SBjorn Andersson #include <linux/platform_device.h>
9892df019SBjorn Andersson #include <linux/module.h>
10892df019SBjorn Andersson #include <linux/of_address.h>
11892df019SBjorn Andersson #include <linux/pm_clock.h>
12892df019SBjorn Andersson #include <linux/pm_runtime.h>
13892df019SBjorn Andersson #include <linux/regmap.h>
14892df019SBjorn Andersson 
15892df019SBjorn Andersson #include <dt-bindings/clock/qcom,turingcc-qcs404.h>
16892df019SBjorn Andersson 
17892df019SBjorn Andersson #include "clk-regmap.h"
18892df019SBjorn Andersson #include "clk-branch.h"
19892df019SBjorn Andersson #include "common.h"
20892df019SBjorn Andersson #include "reset.h"
21892df019SBjorn Andersson 
22892df019SBjorn Andersson static struct clk_branch turing_wrapper_aon_cbcr = {
23892df019SBjorn Andersson 	.halt_reg = 0x5098,
24892df019SBjorn Andersson 	.halt_check = BRANCH_HALT,
25892df019SBjorn Andersson 	.clkr = {
26892df019SBjorn Andersson 		.enable_reg = 0x5098,
27892df019SBjorn Andersson 		.enable_mask = BIT(0),
28892df019SBjorn Andersson 		.hw.init = &(struct clk_init_data) {
29892df019SBjorn Andersson 			.name = "turing_wrapper_aon_clk",
30892df019SBjorn Andersson 			.ops = &clk_branch2_aon_ops,
31892df019SBjorn Andersson 		},
32892df019SBjorn Andersson 	},
33892df019SBjorn Andersson };
34892df019SBjorn Andersson 
35892df019SBjorn Andersson static struct clk_branch turing_q6ss_ahbm_aon_cbcr = {
36892df019SBjorn Andersson 	.halt_reg = 0x9000,
37892df019SBjorn Andersson 	.halt_check = BRANCH_HALT,
38892df019SBjorn Andersson 	.clkr = {
39892df019SBjorn Andersson 		.enable_reg = 0x9000,
40892df019SBjorn Andersson 		.enable_mask = BIT(0),
41892df019SBjorn Andersson 		.hw.init = &(struct clk_init_data) {
42892df019SBjorn Andersson 			.name = "turing_q6ss_ahbm_aon_cbcr",
43892df019SBjorn Andersson 			.ops = &clk_branch2_ops,
44892df019SBjorn Andersson 		},
45892df019SBjorn Andersson 	},
46892df019SBjorn Andersson };
47892df019SBjorn Andersson 
48892df019SBjorn Andersson static struct clk_branch turing_q6ss_q6_axim_clk = {
49892df019SBjorn Andersson 	.halt_reg = 0xb000,
50892df019SBjorn Andersson 	.halt_check = BRANCH_HALT,
51892df019SBjorn Andersson 	.clkr = {
52892df019SBjorn Andersson 		.enable_reg = 0xb000,
53892df019SBjorn Andersson 		.enable_mask = BIT(0),
54892df019SBjorn Andersson 		.hw.init = &(struct clk_init_data) {
55892df019SBjorn Andersson 			.name = "turing_q6ss_q6_axim_clk",
56892df019SBjorn Andersson 			.ops = &clk_branch2_aon_ops,
57892df019SBjorn Andersson 		},
58892df019SBjorn Andersson 	},
59892df019SBjorn Andersson };
60892df019SBjorn Andersson 
61892df019SBjorn Andersson static struct clk_branch turing_q6ss_ahbs_aon_cbcr = {
62892df019SBjorn Andersson 	.halt_reg = 0x10000,
63892df019SBjorn Andersson 	.halt_check = BRANCH_HALT,
64892df019SBjorn Andersson 	.clkr = {
65892df019SBjorn Andersson 		.enable_reg = 0x10000,
66892df019SBjorn Andersson 		.enable_mask = BIT(0),
67892df019SBjorn Andersson 		.hw.init = &(struct clk_init_data) {
68892df019SBjorn Andersson 			.name = "turing_q6ss_ahbs_aon_clk",
69892df019SBjorn Andersson 			.ops = &clk_branch2_aon_ops,
70892df019SBjorn Andersson 		},
71892df019SBjorn Andersson 	},
72892df019SBjorn Andersson };
73892df019SBjorn Andersson 
74892df019SBjorn Andersson static struct clk_branch turing_wrapper_qos_ahbs_aon_cbcr = {
75892df019SBjorn Andersson 	.halt_reg = 0x11014,
76892df019SBjorn Andersson 	.halt_check = BRANCH_HALT,
77892df019SBjorn Andersson 	.clkr = {
78892df019SBjorn Andersson 		.enable_reg = 0x11014,
79892df019SBjorn Andersson 		.enable_mask = BIT(0),
80892df019SBjorn Andersson 		.hw.init = &(struct clk_init_data) {
81892df019SBjorn Andersson 			.name = "turing_wrapper_qos_ahbs_aon_clk",
82892df019SBjorn Andersson 			.ops = &clk_branch2_aon_ops,
83892df019SBjorn Andersson 		},
84892df019SBjorn Andersson 	},
85892df019SBjorn Andersson };
86892df019SBjorn Andersson 
87892df019SBjorn Andersson static struct clk_regmap *turingcc_clocks[] = {
88892df019SBjorn Andersson 	[TURING_WRAPPER_AON_CLK] = &turing_wrapper_aon_cbcr.clkr,
89892df019SBjorn Andersson 	[TURING_Q6SS_AHBM_AON_CLK] = &turing_q6ss_ahbm_aon_cbcr.clkr,
90892df019SBjorn Andersson 	[TURING_Q6SS_Q6_AXIM_CLK] = &turing_q6ss_q6_axim_clk.clkr,
91892df019SBjorn Andersson 	[TURING_Q6SS_AHBS_AON_CLK] = &turing_q6ss_ahbs_aon_cbcr.clkr,
92892df019SBjorn Andersson 	[TURING_WRAPPER_QOS_AHBS_AON_CLK] = &turing_wrapper_qos_ahbs_aon_cbcr.clkr,
93892df019SBjorn Andersson };
94892df019SBjorn Andersson 
95892df019SBjorn Andersson static const struct regmap_config turingcc_regmap_config = {
96892df019SBjorn Andersson 	.reg_bits	= 32,
97892df019SBjorn Andersson 	.reg_stride	= 4,
98892df019SBjorn Andersson 	.val_bits	= 32,
993bcff3e4SJorge Ramirez-Ortiz 	.max_register	= 0x23004,
100892df019SBjorn Andersson 	.fast_io	= true,
101892df019SBjorn Andersson };
102892df019SBjorn Andersson 
103892df019SBjorn Andersson static const struct qcom_cc_desc turingcc_desc = {
104892df019SBjorn Andersson 	.config = &turingcc_regmap_config,
105892df019SBjorn Andersson 	.clks = turingcc_clocks,
106892df019SBjorn Andersson 	.num_clks = ARRAY_SIZE(turingcc_clocks),
107892df019SBjorn Andersson };
108892df019SBjorn Andersson 
109892df019SBjorn Andersson static int turingcc_probe(struct platform_device *pdev)
110892df019SBjorn Andersson {
111892df019SBjorn Andersson 	int ret;
112892df019SBjorn Andersson 
113892df019SBjorn Andersson 	pm_runtime_enable(&pdev->dev);
114892df019SBjorn Andersson 	ret = pm_clk_create(&pdev->dev);
115892df019SBjorn Andersson 	if (ret)
116892df019SBjorn Andersson 		goto disable_pm_runtime;
117892df019SBjorn Andersson 
118892df019SBjorn Andersson 	ret = pm_clk_add(&pdev->dev, NULL);
119892df019SBjorn Andersson 	if (ret < 0) {
120892df019SBjorn Andersson 		dev_err(&pdev->dev, "failed to acquire iface clock\n");
121892df019SBjorn Andersson 		goto destroy_pm_clk;
122892df019SBjorn Andersson 	}
123892df019SBjorn Andersson 
124892df019SBjorn Andersson 	ret = qcom_cc_probe(pdev, &turingcc_desc);
125892df019SBjorn Andersson 	if (ret < 0)
126892df019SBjorn Andersson 		goto destroy_pm_clk;
127892df019SBjorn Andersson 
128892df019SBjorn Andersson 	return 0;
129892df019SBjorn Andersson 
130892df019SBjorn Andersson destroy_pm_clk:
131892df019SBjorn Andersson 	pm_clk_destroy(&pdev->dev);
132892df019SBjorn Andersson 
133892df019SBjorn Andersson disable_pm_runtime:
134892df019SBjorn Andersson 	pm_runtime_disable(&pdev->dev);
135892df019SBjorn Andersson 
136892df019SBjorn Andersson 	return ret;
137892df019SBjorn Andersson }
138892df019SBjorn Andersson 
139892df019SBjorn Andersson static int turingcc_remove(struct platform_device *pdev)
140892df019SBjorn Andersson {
141892df019SBjorn Andersson 	pm_clk_destroy(&pdev->dev);
142892df019SBjorn Andersson 	pm_runtime_disable(&pdev->dev);
143892df019SBjorn Andersson 
144892df019SBjorn Andersson 	return 0;
145892df019SBjorn Andersson }
146892df019SBjorn Andersson 
147892df019SBjorn Andersson static const struct dev_pm_ops turingcc_pm_ops = {
148892df019SBjorn Andersson 	SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
149892df019SBjorn Andersson };
150892df019SBjorn Andersson 
151892df019SBjorn Andersson static const struct of_device_id turingcc_match_table[] = {
152892df019SBjorn Andersson 	{ .compatible = "qcom,qcs404-turingcc" },
153892df019SBjorn Andersson 	{ }
154892df019SBjorn Andersson };
155892df019SBjorn Andersson MODULE_DEVICE_TABLE(of, turingcc_match_table);
156892df019SBjorn Andersson 
157892df019SBjorn Andersson static struct platform_driver turingcc_driver = {
158892df019SBjorn Andersson 	.probe		= turingcc_probe,
159892df019SBjorn Andersson 	.remove		= turingcc_remove,
160892df019SBjorn Andersson 	.driver		= {
161892df019SBjorn Andersson 		.name	= "qcs404-turingcc",
162892df019SBjorn Andersson 		.of_match_table = turingcc_match_table,
163892df019SBjorn Andersson 		.pm = &turingcc_pm_ops,
164892df019SBjorn Andersson 	},
165892df019SBjorn Andersson };
166892df019SBjorn Andersson 
167892df019SBjorn Andersson module_platform_driver(turingcc_driver);
168892df019SBjorn Andersson 
169892df019SBjorn Andersson MODULE_DESCRIPTION("Qualcomm QCS404 Turing Clock Controller");
170892df019SBjorn Andersson MODULE_LICENSE("GPL v2");
171