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) 2023, Linaro Limited
  6 */
  7
  8#include <linux/clk-provider.h>
  9#include <linux/mod_devicetable.h>
 10#include <linux/module.h>
 11#include <linux/platform_device.h>
 12#include <linux/regmap.h>
 13
 14#include <dt-bindings/clock/qcom,sm8650-tcsr.h>
 15
 16#include "clk-branch.h"
 17#include "clk-regmap.h"
 18#include "common.h"
 19#include "reset.h"
 20
 21enum {
 22	DT_BI_TCXO_PAD,
 23};
 24
 25static struct clk_branch tcsr_pcie_0_clkref_en = {
 26	.halt_reg = 0x31100,
 27	.halt_check = BRANCH_HALT_DELAY,
 28	.clkr = {
 29		.enable_reg = 0x31100,
 30		.enable_mask = BIT(0),
 31		.hw.init = &(struct clk_init_data){
 32			.name = "tcsr_pcie_0_clkref_en",
 33			.parent_data = &(const struct clk_parent_data){
 34				.index = DT_BI_TCXO_PAD,
 35			},
 36			.num_parents = 1,
 37			.ops = &clk_branch2_ops,
 38		},
 39	},
 40};
 41
 42static struct clk_branch tcsr_pcie_1_clkref_en = {
 43	.halt_reg = 0x31114,
 44	.halt_check = BRANCH_HALT_DELAY,
 45	.clkr = {
 46		.enable_reg = 0x31114,
 47		.enable_mask = BIT(0),
 48		.hw.init = &(struct clk_init_data){
 49			.name = "tcsr_pcie_1_clkref_en",
 50			.parent_data = &(const struct clk_parent_data){
 51				.index = DT_BI_TCXO_PAD,
 52			},
 53			.num_parents = 1,
 54			.ops = &clk_branch2_ops,
 55		},
 56	},
 57};
 58
 59static struct clk_branch tcsr_ufs_clkref_en = {
 60	.halt_reg = 0x31110,
 61	.halt_check = BRANCH_HALT_DELAY,
 62	.clkr = {
 63		.enable_reg = 0x31110,
 64		.enable_mask = BIT(0),
 65		.hw.init = &(struct clk_init_data){
 66			.name = "tcsr_ufs_clkref_en",
 67			.parent_data = &(const struct clk_parent_data){
 68				.index = DT_BI_TCXO_PAD,
 69			},
 70			.num_parents = 1,
 71			.ops = &clk_branch2_ops,
 72		},
 73	},
 74};
 75
 76static struct clk_branch tcsr_ufs_pad_clkref_en = {
 77	.halt_reg = 0x31104,
 78	.halt_check = BRANCH_HALT_DELAY,
 79	.clkr = {
 80		.enable_reg = 0x31104,
 81		.enable_mask = BIT(0),
 82		.hw.init = &(struct clk_init_data){
 83			.name = "tcsr_ufs_pad_clkref_en",
 84			.parent_data = &(const struct clk_parent_data){
 85				.index = DT_BI_TCXO_PAD,
 86			},
 87			.num_parents = 1,
 88			.ops = &clk_branch2_ops,
 89		},
 90	},
 91};
 92
 93static struct clk_branch tcsr_usb2_clkref_en = {
 94	.halt_reg = 0x31118,
 95	.halt_check = BRANCH_HALT_DELAY,
 96	.clkr = {
 97		.enable_reg = 0x31118,
 98		.enable_mask = BIT(0),
 99		.hw.init = &(struct clk_init_data){
100			.name = "tcsr_usb2_clkref_en",
101			.parent_data = &(const struct clk_parent_data){
102				.index = DT_BI_TCXO_PAD,
103			},
104			.num_parents = 1,
105			.ops = &clk_branch2_ops,
106		},
107	},
108};
109
110static struct clk_branch tcsr_usb3_clkref_en = {
111	.halt_reg = 0x31108,
112	.halt_check = BRANCH_HALT_DELAY,
113	.clkr = {
114		.enable_reg = 0x31108,
115		.enable_mask = BIT(0),
116		.hw.init = &(struct clk_init_data){
117			.name = "tcsr_usb3_clkref_en",
118			.parent_data = &(const struct clk_parent_data){
119				.index = DT_BI_TCXO_PAD,
120			},
121			.num_parents = 1,
122			.ops = &clk_branch2_ops,
123		},
124	},
125};
126
127static struct clk_regmap *tcsr_cc_sm8650_clocks[] = {
128	[TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr,
129	[TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr,
130	[TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr,
131	[TCSR_UFS_PAD_CLKREF_EN] = &tcsr_ufs_pad_clkref_en.clkr,
132	[TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr,
133	[TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr,
134};
135
136static const struct regmap_config tcsr_cc_sm8650_regmap_config = {
137	.reg_bits = 32,
138	.reg_stride = 4,
139	.val_bits = 32,
140	.max_register = 0x3b000,
141	.fast_io = true,
142};
143
144static const struct qcom_cc_desc tcsr_cc_sm8650_desc = {
145	.config = &tcsr_cc_sm8650_regmap_config,
146	.clks = tcsr_cc_sm8650_clocks,
147	.num_clks = ARRAY_SIZE(tcsr_cc_sm8650_clocks),
148};
149
150static const struct of_device_id tcsr_cc_sm8650_match_table[] = {
151	{ .compatible = "qcom,sm8650-tcsr" },
152	{ }
153};
154MODULE_DEVICE_TABLE(of, tcsr_cc_sm8650_match_table);
155
156static int tcsr_cc_sm8650_probe(struct platform_device *pdev)
157{
158	return qcom_cc_probe(pdev, &tcsr_cc_sm8650_desc);
159}
160
161static struct platform_driver tcsr_cc_sm8650_driver = {
162	.probe = tcsr_cc_sm8650_probe,
163	.driver = {
164		.name = "tcsr_cc-sm8650",
165		.of_match_table = tcsr_cc_sm8650_match_table,
166	},
167};
168
169static int __init tcsr_cc_sm8650_init(void)
170{
171	return platform_driver_register(&tcsr_cc_sm8650_driver);
172}
173subsys_initcall(tcsr_cc_sm8650_init);
174
175static void __exit tcsr_cc_sm8650_exit(void)
176{
177	platform_driver_unregister(&tcsr_cc_sm8650_driver);
178}
179module_exit(tcsr_cc_sm8650_exit);
180
181MODULE_DESCRIPTION("QTI TCSRCC SM8650 Driver");
182MODULE_LICENSE("GPL");