Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  4 * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
  5 * Copyright (c) 2022, Linaro Limited
  6 */
  7
  8#include <linux/clk-provider.h>
  9#include <linux/module.h>
 10#include <linux/of.h>
 11#include <linux/platform_device.h>
 12#include <linux/regmap.h>
 13
 14#include <dt-bindings/clock/qcom,sm8550-tcsr.h>
 15
 16#include "clk-alpha-pll.h"
 17#include "clk-branch.h"
 18#include "clk-pll.h"
 19#include "clk-rcg.h"
 20#include "clk-regmap.h"
 21#include "clk-regmap-divider.h"
 22#include "clk-regmap-mux.h"
 23#include "common.h"
 24#include "reset.h"
 25
 26enum {
 27	DT_BI_TCXO_PAD,
 28};
 29
 30static struct clk_branch tcsr_pcie_0_clkref_en = {
 31	.halt_reg = 0x15100,
 32	.halt_check = BRANCH_HALT_SKIP,
 33	.clkr = {
 34		.enable_reg = 0x15100,
 35		.enable_mask = BIT(0),
 36		.hw.init = &(struct clk_init_data){
 37			.name = "tcsr_pcie_0_clkref_en",
 38			.parent_data = &(const struct clk_parent_data){
 39				.index = DT_BI_TCXO_PAD,
 40			},
 41			.num_parents = 1,
 42			.ops = &clk_branch2_ops,
 43		},
 44	},
 45};
 46
 47static struct clk_branch tcsr_pcie_1_clkref_en = {
 48	.halt_reg = 0x15114,
 49	.halt_check = BRANCH_HALT_SKIP,
 50	.clkr = {
 51		.enable_reg = 0x15114,
 52		.enable_mask = BIT(0),
 53		.hw.init = &(struct clk_init_data){
 54			.name = "tcsr_pcie_1_clkref_en",
 55			.parent_data = &(const struct clk_parent_data){
 56				.index = DT_BI_TCXO_PAD,
 57			},
 58			.num_parents = 1,
 59			.ops = &clk_branch2_ops,
 60		},
 61	},
 62};
 63
 64static struct clk_branch tcsr_ufs_clkref_en = {
 65	.halt_reg = 0x15110,
 66	.halt_check = BRANCH_HALT_SKIP,
 67	.clkr = {
 68		.enable_reg = 0x15110,
 69		.enable_mask = BIT(0),
 70		.hw.init = &(struct clk_init_data){
 71			.name = "tcsr_ufs_clkref_en",
 72			.parent_data = &(const struct clk_parent_data){
 73				.index = DT_BI_TCXO_PAD,
 74			},
 75			.num_parents = 1,
 76			.ops = &clk_branch2_ops,
 77		},
 78	},
 79};
 80
 81static struct clk_branch tcsr_ufs_pad_clkref_en = {
 82	.halt_reg = 0x15104,
 83	.halt_check = BRANCH_HALT_SKIP,
 84	.clkr = {
 85		.enable_reg = 0x15104,
 86		.enable_mask = BIT(0),
 87		.hw.init = &(struct clk_init_data){
 88			.name = "tcsr_ufs_pad_clkref_en",
 89			.parent_data = &(const struct clk_parent_data){
 90				.index = DT_BI_TCXO_PAD,
 91			},
 92			.num_parents = 1,
 93			.ops = &clk_branch2_ops,
 94		},
 95	},
 96};
 97
 98static struct clk_branch tcsr_usb2_clkref_en = {
 99	.halt_reg = 0x15118,
100	.halt_check = BRANCH_HALT_SKIP,
101	.clkr = {
102		.enable_reg = 0x15118,
103		.enable_mask = BIT(0),
104		.hw.init = &(struct clk_init_data){
105			.name = "tcsr_usb2_clkref_en",
106			.parent_data = &(const struct clk_parent_data){
107				.index = DT_BI_TCXO_PAD,
108			},
109			.num_parents = 1,
110			.ops = &clk_branch2_ops,
111		},
112	},
113};
114
115static struct clk_branch tcsr_usb3_clkref_en = {
116	.halt_reg = 0x15108,
117	.halt_check = BRANCH_HALT_SKIP,
118	.clkr = {
119		.enable_reg = 0x15108,
120		.enable_mask = BIT(0),
121		.hw.init = &(struct clk_init_data){
122			.name = "tcsr_usb3_clkref_en",
123			.parent_data = &(const struct clk_parent_data){
124				.index = DT_BI_TCXO_PAD,
125			},
126			.num_parents = 1,
127			.ops = &clk_branch2_ops,
128		},
129	},
130};
131
132static struct clk_regmap *tcsr_cc_sar2130p_clocks[] = {
133	[TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr,
134	[TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr,
135	[TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr,
136	[TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr,
137};
138
139static struct clk_regmap *tcsr_cc_sm8550_clocks[] = {
140	[TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr,
141	[TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr,
142	[TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr,
143	[TCSR_UFS_PAD_CLKREF_EN] = &tcsr_ufs_pad_clkref_en.clkr,
144	[TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr,
145	[TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr,
146};
147
148static const struct regmap_config tcsr_cc_sm8550_regmap_config = {
149	.reg_bits = 32,
150	.reg_stride = 4,
151	.val_bits = 32,
152	.max_register = 0x2f000,
153	.fast_io = true,
154};
155
156static const struct qcom_cc_desc tcsr_cc_sar2130p_desc = {
157	.config = &tcsr_cc_sm8550_regmap_config,
158	.clks = tcsr_cc_sar2130p_clocks,
159	.num_clks = ARRAY_SIZE(tcsr_cc_sar2130p_clocks),
160};
161
162static const struct qcom_cc_desc tcsr_cc_sm8550_desc = {
163	.config = &tcsr_cc_sm8550_regmap_config,
164	.clks = tcsr_cc_sm8550_clocks,
165	.num_clks = ARRAY_SIZE(tcsr_cc_sm8550_clocks),
166};
167
168static const struct of_device_id tcsr_cc_sm8550_match_table[] = {
169	{ .compatible = "qcom,sar2130p-tcsr", .data = &tcsr_cc_sar2130p_desc },
170	{ .compatible = "qcom,sm8550-tcsr", .data = &tcsr_cc_sm8550_desc },
171	{ }
172};
173MODULE_DEVICE_TABLE(of, tcsr_cc_sm8550_match_table);
174
175static int tcsr_cc_sm8550_probe(struct platform_device *pdev)
176{
177	struct regmap *regmap;
178
179	regmap = qcom_cc_map(pdev, of_device_get_match_data(&pdev->dev));
180	if (IS_ERR(regmap))
181		return PTR_ERR(regmap);
182
183	return qcom_cc_really_probe(&pdev->dev, &tcsr_cc_sm8550_desc, regmap);
184}
185
186static struct platform_driver tcsr_cc_sm8550_driver = {
187	.probe = tcsr_cc_sm8550_probe,
188	.driver = {
189		.name = "tcsr_cc-sm8550",
190		.of_match_table = tcsr_cc_sm8550_match_table,
191	},
192};
193
194static int __init tcsr_cc_sm8550_init(void)
195{
196	return platform_driver_register(&tcsr_cc_sm8550_driver);
197}
198subsys_initcall(tcsr_cc_sm8550_init);
199
200static void __exit tcsr_cc_sm8550_exit(void)
201{
202	platform_driver_unregister(&tcsr_cc_sm8550_driver);
203}
204module_exit(tcsr_cc_sm8550_exit);
205
206MODULE_DESCRIPTION("QTI TCSRCC SM8550 Driver");
207MODULE_LICENSE("GPL");