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_sm8550_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_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr,
136	[TCSR_UFS_PAD_CLKREF_EN] = &tcsr_ufs_pad_clkref_en.clkr,
137	[TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr,
138	[TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr,
139};
140
141static const struct regmap_config tcsr_cc_sm8550_regmap_config = {
142	.reg_bits = 32,
143	.reg_stride = 4,
144	.val_bits = 32,
145	.max_register = 0x2f000,
146	.fast_io = true,
147};
148
149static const struct qcom_cc_desc tcsr_cc_sm8550_desc = {
150	.config = &tcsr_cc_sm8550_regmap_config,
151	.clks = tcsr_cc_sm8550_clocks,
152	.num_clks = ARRAY_SIZE(tcsr_cc_sm8550_clocks),
153};
154
155static const struct of_device_id tcsr_cc_sm8550_match_table[] = {
156	{ .compatible = "qcom,sm8550-tcsr" },
157	{ }
158};
159MODULE_DEVICE_TABLE(of, tcsr_cc_sm8550_match_table);
160
161static int tcsr_cc_sm8550_probe(struct platform_device *pdev)
162{
163	struct regmap *regmap;
164
165	regmap = qcom_cc_map(pdev, &tcsr_cc_sm8550_desc);
166	if (IS_ERR(regmap))
167		return PTR_ERR(regmap);
168
169	return qcom_cc_really_probe(pdev, &tcsr_cc_sm8550_desc, regmap);
170}
171
172static struct platform_driver tcsr_cc_sm8550_driver = {
173	.probe = tcsr_cc_sm8550_probe,
174	.driver = {
175		.name = "tcsr_cc-sm8550",
176		.of_match_table = tcsr_cc_sm8550_match_table,
177	},
178};
179
180static int __init tcsr_cc_sm8550_init(void)
181{
182	return platform_driver_register(&tcsr_cc_sm8550_driver);
183}
184subsys_initcall(tcsr_cc_sm8550_init);
185
186static void __exit tcsr_cc_sm8550_exit(void)
187{
188	platform_driver_unregister(&tcsr_cc_sm8550_driver);
189}
190module_exit(tcsr_cc_sm8550_exit);
191
192MODULE_DESCRIPTION("QTI TCSRCC SM8550 Driver");
193MODULE_LICENSE("GPL");