File Index
Files and directories
Sign in
FILE

apss-ipq5424.c

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/qcom/apss-ipq5424.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  4 * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
  5 */
  6
  7#include <linux/clk.h>
  8#include <linux/clk-provider.h>
  9#include <linux/err.h>
 10#include <linux/interconnect-provider.h>
 11#include <linux/kernel.h>
 12#include <linux/module.h>
 13#include <linux/platform_device.h>
 14#include <linux/regmap.h>
 15
 16#include <dt-bindings/arm/qcom,ids.h>
 17#include <dt-bindings/clock/qcom,apss-ipq.h>
 18#include <dt-bindings/interconnect/qcom,ipq5424.h>
 19
 20#include "clk-alpha-pll.h"
 21#include "clk-branch.h"
 22#include "clk-rcg.h"
 23#include "clk-regmap.h"
 24#include "common.h"
 25
 26enum {
 27	DT_XO,
 28	DT_CLK_REF,
 29};
 30
 31enum {
 32	P_XO,
 33	P_GPLL0,
 34	P_APSS_PLL_EARLY,
 35	P_L3_PLL,
 36};
 37
 38static const struct alpha_pll_config apss_pll_config = {
 39	.l = 0x3b,
 40	.config_ctl_val = 0x08200920,
 41	.config_ctl_hi_val = 0x05008001,
 42	.config_ctl_hi1_val = 0x04000000,
 43	.user_ctl_val = 0xf,
 44};
 45
 46static struct clk_alpha_pll ipq5424_apss_pll = {
 47	.offset = 0x0,
 48	.config = &apss_pll_config,
 49	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290],
 50	.flags = SUPPORTS_DYNAMIC_UPDATE,
 51	.clkr = {
 52		.enable_reg = 0x0,
 53		.enable_mask = BIT(0),
 54		.hw.init = &(struct clk_init_data){
 55			.name = "apss_pll",
 56			.parent_data = &(const struct clk_parent_data) {
 57				.index = DT_XO,
 58			},
 59			.num_parents = 1,
 60			.ops = &clk_alpha_pll_huayra_ops,
 61		},
 62	},
 63};
 64
 65static const struct clk_parent_data parents_apss_silver_clk_src[] = {
 66	{ .index = DT_XO },
 67	{ .index = DT_CLK_REF },
 68	{ .hw = &ipq5424_apss_pll.clkr.hw },
 69};
 70
 71static const struct parent_map parents_apss_silver_clk_src_map[] = {
 72	{ P_XO, 0 },
 73	{ P_GPLL0, 4 },
 74	{ P_APSS_PLL_EARLY, 5 },
 75};
 76
 77static const struct freq_tbl ftbl_apss_clk_src[] = {
 78	F(816000000, P_APSS_PLL_EARLY, 1, 0, 0),
 79	F(1416000000, P_APSS_PLL_EARLY, 1, 0, 0),
 80	F(1800000000, P_APSS_PLL_EARLY, 1, 0, 0),
 81	{ }
 82};
 83
 84static struct clk_rcg2 apss_silver_clk_src = {
 85	.cmd_rcgr = 0x0080,
 86	.freq_tbl = ftbl_apss_clk_src,
 87	.hid_width = 5,
 88	.parent_map = parents_apss_silver_clk_src_map,
 89	.clkr.hw.init = &(struct clk_init_data) {
 90		.name = "apss_silver_clk_src",
 91		.parent_data = parents_apss_silver_clk_src,
 92		.num_parents = ARRAY_SIZE(parents_apss_silver_clk_src),
 93		.ops = &clk_rcg2_ops,
 94		.flags = CLK_SET_RATE_PARENT,
 95	},
 96};
 97
 98static struct clk_branch apss_silver_core_clk = {
 99	.halt_reg = 0x008c,
100	.clkr = {
101		.enable_reg = 0x008c,
102		.enable_mask = BIT(0),
103		.hw.init = &(struct clk_init_data) {
104			.name = "apss_silver_core_clk",
105			.parent_hws = (const struct clk_hw *[]) {
106				&apss_silver_clk_src.clkr.hw
107			},
108			.num_parents = 1,
109			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
110			.ops = &clk_branch2_ops,
111		},
112	},
113};
114
115static const struct alpha_pll_config l3_pll_config = {
116	.l = 0x29,
117	.config_ctl_val = 0x08200920,
118	.config_ctl_hi_val = 0x05008001,
119	.config_ctl_hi1_val = 0x04000000,
120	.user_ctl_val = 0xf,
121};
122
123static struct clk_alpha_pll ipq5424_l3_pll = {
124	.offset = 0x10000,
125	.config = &l3_pll_config,
126	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA_2290],
127	.flags = SUPPORTS_DYNAMIC_UPDATE,
128	.clkr = {
129		.enable_reg = 0x0,
130		.enable_mask = BIT(0),
131		.hw.init = &(struct clk_init_data) {
132			.name = "l3_pll",
133			.parent_data = &(const struct clk_parent_data) {
134				.index = DT_XO,
135			},
136			.num_parents = 1,
137			.ops = &clk_alpha_pll_huayra_ops,
138		},
139	},
140};
141
142static const struct clk_parent_data parents_l3_clk_src[] = {
143	{ .index = DT_XO },
144	{ .index = DT_CLK_REF },
145	{ .hw = &ipq5424_l3_pll.clkr.hw },
146};
147
148static const struct parent_map parents_l3_clk_src_map[] = {
149	{ P_XO, 0 },
150	{ P_GPLL0, 4 },
151	{ P_L3_PLL, 5 },
152};
153
154static const struct freq_tbl ftbl_l3_clk_src[] = {
155	F(816000000, P_L3_PLL, 1, 0, 0),
156	F(984000000, P_L3_PLL, 1, 0, 0),
157	F(1272000000, P_L3_PLL, 1, 0, 0),
158	{ }
159};
160
161static struct clk_rcg2 l3_clk_src = {
162	.cmd_rcgr = 0x10080,
163	.freq_tbl = ftbl_l3_clk_src,
164	.hid_width = 5,
165	.parent_map = parents_l3_clk_src_map,
166	.clkr.hw.init = &(struct clk_init_data) {
167		.name = "l3_clk_src",
168		.parent_data = parents_l3_clk_src,
169		.num_parents = ARRAY_SIZE(parents_l3_clk_src),
170		.ops = &clk_rcg2_ops,
171		.flags = CLK_SET_RATE_PARENT,
172	},
173};
174
175static struct clk_branch l3_core_clk = {
176	.halt_reg = 0x1008c,
177	.clkr = {
178		.enable_reg = 0x1008c,
179		.enable_mask = BIT(0),
180		.hw.init = &(struct clk_init_data) {
181			.name = "l3_clk",
182			.parent_hws = (const struct clk_hw *[]) {
183				&l3_clk_src.clkr.hw
184			},
185			.num_parents = 1,
186			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
187			.ops = &clk_branch2_ops,
188		},
189	},
190};
191
192static const struct regmap_config apss_ipq5424_regmap_config = {
193	.reg_bits       = 32,
194	.reg_stride     = 4,
195	.val_bits       = 32,
196	.max_register   = 0x20000,
197	.fast_io        = true,
198};
199
200static struct clk_regmap *apss_ipq5424_clks[] = {
201	[APSS_PLL_EARLY] = &ipq5424_apss_pll.clkr,
202	[APSS_SILVER_CLK_SRC] = &apss_silver_clk_src.clkr,
203	[APSS_SILVER_CORE_CLK] = &apss_silver_core_clk.clkr,
204	[L3_PLL] = &ipq5424_l3_pll.clkr,
205	[L3_CLK_SRC] = &l3_clk_src.clkr,
206	[L3_CORE_CLK] = &l3_core_clk.clkr,
207};
208
209static struct clk_alpha_pll *ipa5424_apss_plls[] = {
210	&ipq5424_l3_pll,
211	&ipq5424_apss_pll,
212};
213
214static struct qcom_cc_driver_data ipa5424_apss_driver_data = {
215	.alpha_plls = ipa5424_apss_plls,
216	.num_alpha_plls = ARRAY_SIZE(ipa5424_apss_plls),
217};
218
219#define IPQ_APPS_PLL_ID			(5424 * 3)	/* some unique value */
220
221static const struct qcom_icc_hws_data icc_ipq5424_cpu_l3[] = {
222	{ MASTER_CPU, SLAVE_L3, L3_CORE_CLK },
223};
224
225static const struct qcom_cc_desc apss_ipq5424_desc = {
226	.config = &apss_ipq5424_regmap_config,
227	.clks = apss_ipq5424_clks,
228	.num_clks = ARRAY_SIZE(apss_ipq5424_clks),
229	.icc_hws = icc_ipq5424_cpu_l3,
230	.num_icc_hws = ARRAY_SIZE(icc_ipq5424_cpu_l3),
231	.icc_first_node_id = IPQ_APPS_PLL_ID,
232	.driver_data = &ipa5424_apss_driver_data,
233};
234
235static int apss_ipq5424_probe(struct platform_device *pdev)
236{
237	return qcom_cc_probe(pdev, &apss_ipq5424_desc);
238}
239
240static const struct of_device_id apss_ipq5424_match_table[] = {
241	{ .compatible = "qcom,ipq5424-apss-clk" },
242	{ }
243};
244MODULE_DEVICE_TABLE(of, apss_ipq5424_match_table);
245
246static struct platform_driver apss_ipq5424_driver = {
247	.probe = apss_ipq5424_probe,
248	.driver = {
249		.name   = "apss-ipq5424-clk",
250		.of_match_table = apss_ipq5424_match_table,
251		.sync_state = icc_sync_state,
252	},
253};
254
255module_platform_driver(apss_ipq5424_driver);
256
257MODULE_DESCRIPTION("QCOM APSS IPQ5424 CLK Driver");
258MODULE_LICENSE("GPL");
~/ Read-only file preview.