xref: /linux/drivers/clk/qcom/dispcc-qcm2290.c (revision c334ecf355a1b1039344e29f9ef026e98760c918)
1cc517ea3SLoic Poulain // SPDX-License-Identifier: GPL-2.0-only
2cc517ea3SLoic Poulain /*
3cc517ea3SLoic Poulain  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
4cc517ea3SLoic Poulain  * Copyright (c) 2021, Linaro Ltd.
5cc517ea3SLoic Poulain  */
6cc517ea3SLoic Poulain 
7cc517ea3SLoic Poulain #include <linux/err.h>
8cc517ea3SLoic Poulain #include <linux/kernel.h>
9cc517ea3SLoic Poulain #include <linux/module.h>
10cc517ea3SLoic Poulain #include <linux/of.h>
11a96cbb14SRob Herring #include <linux/platform_device.h>
12cc517ea3SLoic Poulain #include <linux/regmap.h>
13cc517ea3SLoic Poulain 
14cc517ea3SLoic Poulain #include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
15cc517ea3SLoic Poulain 
16cc517ea3SLoic Poulain #include "clk-alpha-pll.h"
17cc517ea3SLoic Poulain #include "clk-branch.h"
18cc517ea3SLoic Poulain #include "clk-rcg.h"
19cc517ea3SLoic Poulain #include "clk-regmap.h"
20cc517ea3SLoic Poulain #include "clk-regmap-divider.h"
21cc517ea3SLoic Poulain #include "common.h"
22cc517ea3SLoic Poulain #include "gdsc.h"
23002c3fb6SKonrad Dybcio #include "reset.h"
24cc517ea3SLoic Poulain 
25cc517ea3SLoic Poulain enum {
26cc517ea3SLoic Poulain 	P_BI_TCXO,
2792dfee0fSKonrad Dybcio 	P_BI_TCXO_AO,
28cc517ea3SLoic Poulain 	P_DISP_CC_PLL0_OUT_MAIN,
29cc517ea3SLoic Poulain 	P_DSI0_PHY_PLL_OUT_BYTECLK,
30cc517ea3SLoic Poulain 	P_DSI0_PHY_PLL_OUT_DSICLK,
3163d56adfSKonrad Dybcio 	P_GPLL0_OUT_DIV,
32cc517ea3SLoic Poulain 	P_GPLL0_OUT_MAIN,
33cc517ea3SLoic Poulain 	P_SLEEP_CLK,
34cc517ea3SLoic Poulain };
35cc517ea3SLoic Poulain 
36cc517ea3SLoic Poulain static const struct pll_vco spark_vco[] = {
37cc517ea3SLoic Poulain 	{ 500000000, 1000000000, 2 },
38cc517ea3SLoic Poulain };
39cc517ea3SLoic Poulain 
40cc517ea3SLoic Poulain /* 768MHz configuration */
41cc517ea3SLoic Poulain static const struct alpha_pll_config disp_cc_pll0_config = {
42cc517ea3SLoic Poulain 	.l = 0x28,
43cc517ea3SLoic Poulain 	.alpha = 0x0,
44cc517ea3SLoic Poulain 	.alpha_en_mask = BIT(24),
45cc517ea3SLoic Poulain 	.vco_val = 0x2 << 20,
46cc517ea3SLoic Poulain 	.vco_mask = GENMASK(21, 20),
47cc517ea3SLoic Poulain 	.main_output_mask = BIT(0),
48cc517ea3SLoic Poulain 	.config_ctl_val = 0x4001055B,
49cc517ea3SLoic Poulain };
50cc517ea3SLoic Poulain 
51cc517ea3SLoic Poulain static struct clk_alpha_pll disp_cc_pll0 = {
52cc517ea3SLoic Poulain 	.offset = 0x0,
53cc517ea3SLoic Poulain 	.vco_table = spark_vco,
54cc517ea3SLoic Poulain 	.num_vco = ARRAY_SIZE(spark_vco),
55cc517ea3SLoic Poulain 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
56cc517ea3SLoic Poulain 	.clkr = {
57cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
58cc517ea3SLoic Poulain 			.name = "disp_cc_pll0",
59cc517ea3SLoic Poulain 			.parent_data = &(const struct clk_parent_data){
60cc517ea3SLoic Poulain 				.fw_name = "bi_tcxo",
61cc517ea3SLoic Poulain 			},
62cc517ea3SLoic Poulain 			.num_parents = 1,
63cc517ea3SLoic Poulain 			.ops = &clk_alpha_pll_ops,
64cc517ea3SLoic Poulain 		},
65cc517ea3SLoic Poulain 	},
66cc517ea3SLoic Poulain };
67cc517ea3SLoic Poulain 
68cc517ea3SLoic Poulain static const struct parent_map disp_cc_parent_map_0[] = {
69cc517ea3SLoic Poulain 	{ P_BI_TCXO, 0 },
70cc517ea3SLoic Poulain 	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
71cc517ea3SLoic Poulain };
72cc517ea3SLoic Poulain 
73cc517ea3SLoic Poulain static const struct clk_parent_data disp_cc_parent_data_0[] = {
74cc517ea3SLoic Poulain 	{ .fw_name = "bi_tcxo" },
75cc517ea3SLoic Poulain 	{ .fw_name = "dsi0_phy_pll_out_byteclk" },
76cc517ea3SLoic Poulain };
77cc517ea3SLoic Poulain 
78cc517ea3SLoic Poulain static const struct parent_map disp_cc_parent_map_1[] = {
79cc517ea3SLoic Poulain 	{ P_BI_TCXO, 0 },
80cc517ea3SLoic Poulain };
81cc517ea3SLoic Poulain 
82cc517ea3SLoic Poulain static const struct clk_parent_data disp_cc_parent_data_1[] = {
83cc517ea3SLoic Poulain 	{ .fw_name = "bi_tcxo" },
84cc517ea3SLoic Poulain };
85cc517ea3SLoic Poulain 
86cc517ea3SLoic Poulain static const struct parent_map disp_cc_parent_map_2[] = {
8792dfee0fSKonrad Dybcio 	{ P_BI_TCXO_AO, 0 },
8863d56adfSKonrad Dybcio 	{ P_GPLL0_OUT_DIV, 4 },
89cc517ea3SLoic Poulain };
90cc517ea3SLoic Poulain 
91cc517ea3SLoic Poulain static const struct clk_parent_data disp_cc_parent_data_2[] = {
92cc517ea3SLoic Poulain 	{ .fw_name = "bi_tcxo_ao" },
93cc517ea3SLoic Poulain 	{ .fw_name = "gcc_disp_gpll0_div_clk_src" },
94cc517ea3SLoic Poulain };
95cc517ea3SLoic Poulain 
96cc517ea3SLoic Poulain static const struct parent_map disp_cc_parent_map_3[] = {
97cc517ea3SLoic Poulain 	{ P_BI_TCXO, 0 },
98cc517ea3SLoic Poulain 	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
99cc517ea3SLoic Poulain 	{ P_GPLL0_OUT_MAIN, 4 },
100cc517ea3SLoic Poulain };
101cc517ea3SLoic Poulain 
102cc517ea3SLoic Poulain static const struct clk_parent_data disp_cc_parent_data_3[] = {
103cc517ea3SLoic Poulain 	{ .fw_name = "bi_tcxo" },
104cc517ea3SLoic Poulain 	{ .hw = &disp_cc_pll0.clkr.hw },
105cc517ea3SLoic Poulain 	{ .fw_name = "gcc_disp_gpll0_clk_src" },
106cc517ea3SLoic Poulain };
107cc517ea3SLoic Poulain 
108cc517ea3SLoic Poulain static const struct parent_map disp_cc_parent_map_4[] = {
109cc517ea3SLoic Poulain 	{ P_BI_TCXO, 0 },
110cc517ea3SLoic Poulain 	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
111cc517ea3SLoic Poulain };
112cc517ea3SLoic Poulain 
113cc517ea3SLoic Poulain static const struct clk_parent_data disp_cc_parent_data_4[] = {
114cc517ea3SLoic Poulain 	{ .fw_name = "bi_tcxo" },
115cc517ea3SLoic Poulain 	{ .fw_name = "dsi0_phy_pll_out_dsiclk" },
116cc517ea3SLoic Poulain };
117cc517ea3SLoic Poulain 
118cc517ea3SLoic Poulain static const struct parent_map disp_cc_parent_map_5[] = {
119cc517ea3SLoic Poulain 	{ P_SLEEP_CLK, 0 },
120cc517ea3SLoic Poulain };
121cc517ea3SLoic Poulain 
122cc517ea3SLoic Poulain static const struct clk_parent_data disp_cc_parent_data_5[] = {
123cc517ea3SLoic Poulain 	{ .fw_name = "sleep_clk" },
124cc517ea3SLoic Poulain };
125cc517ea3SLoic Poulain 
126cc517ea3SLoic Poulain static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
127cc517ea3SLoic Poulain 	.cmd_rcgr = 0x20a4,
128cc517ea3SLoic Poulain 	.mnd_width = 0,
129cc517ea3SLoic Poulain 	.hid_width = 5,
130cc517ea3SLoic Poulain 	.parent_map = disp_cc_parent_map_0,
131cc517ea3SLoic Poulain 	.clkr.hw.init = &(struct clk_init_data){
132cc517ea3SLoic Poulain 		.name = "disp_cc_mdss_byte0_clk_src",
133cc517ea3SLoic Poulain 		.parent_data = disp_cc_parent_data_0,
134cc517ea3SLoic Poulain 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
135cc517ea3SLoic Poulain 		/* For set_rate and set_parent to succeed, parent(s) must be enabled */
136cc517ea3SLoic Poulain 		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
137cc517ea3SLoic Poulain 		.ops = &clk_byte2_ops,
138cc517ea3SLoic Poulain 	},
139cc517ea3SLoic Poulain };
140cc517ea3SLoic Poulain 
141cc517ea3SLoic Poulain static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
142cc517ea3SLoic Poulain 	.reg = 0x20bc,
143cc517ea3SLoic Poulain 	.shift = 0,
144cc517ea3SLoic Poulain 	.width = 2,
145cc517ea3SLoic Poulain 	.clkr.hw.init = &(struct clk_init_data) {
146cc517ea3SLoic Poulain 		.name = "disp_cc_mdss_byte0_div_clk_src",
147cc517ea3SLoic Poulain 		.parent_hws = (const struct clk_hw*[]){
148cc517ea3SLoic Poulain 			&disp_cc_mdss_byte0_clk_src.clkr.hw,
149cc517ea3SLoic Poulain 		},
150cc517ea3SLoic Poulain 		.num_parents = 1,
151cc517ea3SLoic Poulain 		.ops = &clk_regmap_div_ops,
152cc517ea3SLoic Poulain 	},
153cc517ea3SLoic Poulain };
154cc517ea3SLoic Poulain 
155cc517ea3SLoic Poulain static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
15692dfee0fSKonrad Dybcio 	F(19200000, P_BI_TCXO_AO, 1, 0, 0),
15763d56adfSKonrad Dybcio 	F(37500000, P_GPLL0_OUT_DIV, 8, 0, 0),
15863d56adfSKonrad Dybcio 	F(75000000, P_GPLL0_OUT_DIV, 4, 0, 0),
159cc517ea3SLoic Poulain 	{ }
160cc517ea3SLoic Poulain };
161cc517ea3SLoic Poulain 
162cc517ea3SLoic Poulain static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
163cc517ea3SLoic Poulain 	.cmd_rcgr = 0x2154,
164cc517ea3SLoic Poulain 	.mnd_width = 0,
165cc517ea3SLoic Poulain 	.hid_width = 5,
166cc517ea3SLoic Poulain 	.parent_map = disp_cc_parent_map_2,
167cc517ea3SLoic Poulain 	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
168cc517ea3SLoic Poulain 	.clkr.hw.init = &(struct clk_init_data){
169cc517ea3SLoic Poulain 		.name = "disp_cc_mdss_ahb_clk_src",
170cc517ea3SLoic Poulain 		.parent_data = disp_cc_parent_data_2,
171cc517ea3SLoic Poulain 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
172cc517ea3SLoic Poulain 		.ops = &clk_rcg2_shared_ops,
173cc517ea3SLoic Poulain 	},
174cc517ea3SLoic Poulain };
175cc517ea3SLoic Poulain 
176cc517ea3SLoic Poulain static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
177cc517ea3SLoic Poulain 	F(19200000, P_BI_TCXO, 1, 0, 0),
178cc517ea3SLoic Poulain 	{ }
179cc517ea3SLoic Poulain };
180cc517ea3SLoic Poulain 
181cc517ea3SLoic Poulain static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
182cc517ea3SLoic Poulain 	.cmd_rcgr = 0x20c0,
183cc517ea3SLoic Poulain 	.mnd_width = 0,
184cc517ea3SLoic Poulain 	.hid_width = 5,
185cc517ea3SLoic Poulain 	.parent_map = disp_cc_parent_map_0,
186cc517ea3SLoic Poulain 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
187cc517ea3SLoic Poulain 	.clkr.hw.init = &(struct clk_init_data){
188cc517ea3SLoic Poulain 		.name = "disp_cc_mdss_esc0_clk_src",
189cc517ea3SLoic Poulain 		.parent_data = disp_cc_parent_data_0,
190cc517ea3SLoic Poulain 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
191cc517ea3SLoic Poulain 		.ops = &clk_rcg2_ops,
192cc517ea3SLoic Poulain 	},
193cc517ea3SLoic Poulain };
194cc517ea3SLoic Poulain 
195cc517ea3SLoic Poulain static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
196cc517ea3SLoic Poulain 	F(19200000, P_BI_TCXO, 1, 0, 0),
197cc517ea3SLoic Poulain 	F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
198cc517ea3SLoic Poulain 	F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
199cc517ea3SLoic Poulain 	F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
200cc517ea3SLoic Poulain 	F(384000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0),
201cc517ea3SLoic Poulain 	{ }
202cc517ea3SLoic Poulain };
203cc517ea3SLoic Poulain 
204cc517ea3SLoic Poulain static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
205cc517ea3SLoic Poulain 	.cmd_rcgr = 0x2074,
206cc517ea3SLoic Poulain 	.mnd_width = 0,
207cc517ea3SLoic Poulain 	.hid_width = 5,
208cc517ea3SLoic Poulain 	.parent_map = disp_cc_parent_map_3,
209cc517ea3SLoic Poulain 	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
210cc517ea3SLoic Poulain 	.clkr.hw.init = &(struct clk_init_data){
211cc517ea3SLoic Poulain 		.name = "disp_cc_mdss_mdp_clk_src",
212cc517ea3SLoic Poulain 		.parent_data = disp_cc_parent_data_3,
213cc517ea3SLoic Poulain 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
214cc517ea3SLoic Poulain 		.flags = CLK_SET_RATE_PARENT,
215cc517ea3SLoic Poulain 		.ops = &clk_rcg2_shared_ops,
216cc517ea3SLoic Poulain 	},
217cc517ea3SLoic Poulain };
218cc517ea3SLoic Poulain 
219cc517ea3SLoic Poulain static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
220cc517ea3SLoic Poulain 	.cmd_rcgr = 0x205c,
221cc517ea3SLoic Poulain 	.mnd_width = 8,
222cc517ea3SLoic Poulain 	.hid_width = 5,
223cc517ea3SLoic Poulain 	.parent_map = disp_cc_parent_map_4,
224cc517ea3SLoic Poulain 	.clkr.hw.init = &(struct clk_init_data){
225cc517ea3SLoic Poulain 		.name = "disp_cc_mdss_pclk0_clk_src",
226cc517ea3SLoic Poulain 		.parent_data = disp_cc_parent_data_4,
227cc517ea3SLoic Poulain 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
228cc517ea3SLoic Poulain 		/* For set_rate and set_parent to succeed, parent(s) must be enabled */
229cc517ea3SLoic Poulain 		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
230cc517ea3SLoic Poulain 		.ops = &clk_pixel_ops,
231cc517ea3SLoic Poulain 	},
232cc517ea3SLoic Poulain };
233cc517ea3SLoic Poulain 
234cc517ea3SLoic Poulain static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
235cc517ea3SLoic Poulain 	.cmd_rcgr = 0x208c,
236cc517ea3SLoic Poulain 	.mnd_width = 0,
237cc517ea3SLoic Poulain 	.hid_width = 5,
238cc517ea3SLoic Poulain 	.parent_map = disp_cc_parent_map_1,
239cc517ea3SLoic Poulain 	.freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src,
240cc517ea3SLoic Poulain 	.clkr.hw.init = &(struct clk_init_data){
241cc517ea3SLoic Poulain 		.name = "disp_cc_mdss_vsync_clk_src",
242cc517ea3SLoic Poulain 		.parent_data = disp_cc_parent_data_1,
243cc517ea3SLoic Poulain 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
244cc517ea3SLoic Poulain 		.flags = CLK_SET_RATE_PARENT,
245cc517ea3SLoic Poulain 		.ops = &clk_rcg2_shared_ops,
246cc517ea3SLoic Poulain 	},
247cc517ea3SLoic Poulain };
248cc517ea3SLoic Poulain 
249cc517ea3SLoic Poulain static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
250cc517ea3SLoic Poulain 	F(32764, P_SLEEP_CLK, 1, 0, 0),
251cc517ea3SLoic Poulain 	{ }
252cc517ea3SLoic Poulain };
253cc517ea3SLoic Poulain 
254cc517ea3SLoic Poulain static struct clk_rcg2 disp_cc_sleep_clk_src = {
255cc517ea3SLoic Poulain 	.cmd_rcgr = 0x6050,
256cc517ea3SLoic Poulain 	.mnd_width = 0,
257cc517ea3SLoic Poulain 	.hid_width = 5,
258cc517ea3SLoic Poulain 	.parent_map = disp_cc_parent_map_5,
259cc517ea3SLoic Poulain 	.freq_tbl = ftbl_disp_cc_sleep_clk_src,
260cc517ea3SLoic Poulain 	.clkr.hw.init = &(struct clk_init_data){
261cc517ea3SLoic Poulain 		.name = "disp_cc_sleep_clk_src",
262cc517ea3SLoic Poulain 		.parent_data = disp_cc_parent_data_5,
263cc517ea3SLoic Poulain 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
264cc517ea3SLoic Poulain 		.ops = &clk_rcg2_ops,
265cc517ea3SLoic Poulain 	},
266cc517ea3SLoic Poulain };
267cc517ea3SLoic Poulain 
268cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_ahb_clk = {
269cc517ea3SLoic Poulain 	.halt_reg = 0x2044,
270cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT,
271cc517ea3SLoic Poulain 	.clkr = {
272cc517ea3SLoic Poulain 		.enable_reg = 0x2044,
273cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
274cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
275cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_ahb_clk",
276cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
277cc517ea3SLoic Poulain 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
278cc517ea3SLoic Poulain 			},
279cc517ea3SLoic Poulain 			.num_parents = 1,
280cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
281cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
282cc517ea3SLoic Poulain 		},
283cc517ea3SLoic Poulain 	},
284cc517ea3SLoic Poulain };
285cc517ea3SLoic Poulain 
286cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_byte0_clk = {
287cc517ea3SLoic Poulain 	.halt_reg = 0x201c,
288cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT,
289cc517ea3SLoic Poulain 	.clkr = {
290cc517ea3SLoic Poulain 		.enable_reg = 0x201c,
291cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
292cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
293cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_byte0_clk",
294cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
295cc517ea3SLoic Poulain 				&disp_cc_mdss_byte0_clk_src.clkr.hw,
296cc517ea3SLoic Poulain 			},
297cc517ea3SLoic Poulain 			.num_parents = 1,
298cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
299cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
300cc517ea3SLoic Poulain 		},
301cc517ea3SLoic Poulain 	},
302cc517ea3SLoic Poulain };
303cc517ea3SLoic Poulain 
304cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
305cc517ea3SLoic Poulain 	.halt_reg = 0x2020,
306cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT,
307cc517ea3SLoic Poulain 	.clkr = {
308cc517ea3SLoic Poulain 		.enable_reg = 0x2020,
309cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
310cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
311cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_byte0_intf_clk",
312cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
313cc517ea3SLoic Poulain 				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
314cc517ea3SLoic Poulain 			},
315cc517ea3SLoic Poulain 			.num_parents = 1,
316cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
317cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
318cc517ea3SLoic Poulain 		},
319cc517ea3SLoic Poulain 	},
320cc517ea3SLoic Poulain };
321cc517ea3SLoic Poulain 
322cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_esc0_clk = {
323cc517ea3SLoic Poulain 	.halt_reg = 0x2024,
324cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT,
325cc517ea3SLoic Poulain 	.clkr = {
326cc517ea3SLoic Poulain 		.enable_reg = 0x2024,
327cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
328cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
329cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_esc0_clk",
330cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
331cc517ea3SLoic Poulain 				&disp_cc_mdss_esc0_clk_src.clkr.hw,
332cc517ea3SLoic Poulain 			},
333cc517ea3SLoic Poulain 			.num_parents = 1,
334cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
335cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
336cc517ea3SLoic Poulain 		},
337cc517ea3SLoic Poulain 	},
338cc517ea3SLoic Poulain };
339cc517ea3SLoic Poulain 
340cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_mdp_clk = {
341cc517ea3SLoic Poulain 	.halt_reg = 0x2008,
342cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT,
343cc517ea3SLoic Poulain 	.clkr = {
344cc517ea3SLoic Poulain 		.enable_reg = 0x2008,
345cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
346cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
347cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_mdp_clk",
348cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
349cc517ea3SLoic Poulain 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
350cc517ea3SLoic Poulain 			},
351cc517ea3SLoic Poulain 			.num_parents = 1,
352cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
353cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
354cc517ea3SLoic Poulain 		},
355cc517ea3SLoic Poulain 	},
356cc517ea3SLoic Poulain };
357cc517ea3SLoic Poulain 
358cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
359cc517ea3SLoic Poulain 	.halt_reg = 0x2010,
360cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT_VOTED,
361cc517ea3SLoic Poulain 	.clkr = {
362cc517ea3SLoic Poulain 		.enable_reg = 0x2010,
363cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
364cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
365cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_mdp_lut_clk",
366cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
367cc517ea3SLoic Poulain 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
368cc517ea3SLoic Poulain 			},
369cc517ea3SLoic Poulain 			.num_parents = 1,
370cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
371cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
372cc517ea3SLoic Poulain 		},
373cc517ea3SLoic Poulain 	},
374cc517ea3SLoic Poulain };
375cc517ea3SLoic Poulain 
376cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
377cc517ea3SLoic Poulain 	.halt_reg = 0x4004,
378cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT_VOTED,
379cc517ea3SLoic Poulain 	.clkr = {
380cc517ea3SLoic Poulain 		.enable_reg = 0x4004,
381cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
382cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
383cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
384cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
385cc517ea3SLoic Poulain 				&disp_cc_mdss_ahb_clk_src.clkr.hw,
386cc517ea3SLoic Poulain 			},
387cc517ea3SLoic Poulain 			.num_parents = 1,
388cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
389cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
390cc517ea3SLoic Poulain 		},
391cc517ea3SLoic Poulain 	},
392cc517ea3SLoic Poulain };
393cc517ea3SLoic Poulain 
394cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_pclk0_clk = {
395cc517ea3SLoic Poulain 	.halt_reg = 0x2004,
396cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT,
397cc517ea3SLoic Poulain 	.clkr = {
398cc517ea3SLoic Poulain 		.enable_reg = 0x2004,
399cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
400cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
401cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_pclk0_clk",
402cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
403cc517ea3SLoic Poulain 				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
404cc517ea3SLoic Poulain 			},
405cc517ea3SLoic Poulain 			.num_parents = 1,
406cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
407cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
408cc517ea3SLoic Poulain 		},
409cc517ea3SLoic Poulain 	},
410cc517ea3SLoic Poulain };
411cc517ea3SLoic Poulain 
412cc517ea3SLoic Poulain static struct clk_branch disp_cc_mdss_vsync_clk = {
413cc517ea3SLoic Poulain 	.halt_reg = 0x2018,
414cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT,
415cc517ea3SLoic Poulain 	.clkr = {
416cc517ea3SLoic Poulain 		.enable_reg = 0x2018,
417cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
418cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
419cc517ea3SLoic Poulain 			.name = "disp_cc_mdss_vsync_clk",
420cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
421cc517ea3SLoic Poulain 				&disp_cc_mdss_vsync_clk_src.clkr.hw,
422cc517ea3SLoic Poulain 			},
423cc517ea3SLoic Poulain 			.num_parents = 1,
424cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
425cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
426cc517ea3SLoic Poulain 		},
427cc517ea3SLoic Poulain 	},
428cc517ea3SLoic Poulain };
429cc517ea3SLoic Poulain 
430cc517ea3SLoic Poulain static struct clk_branch disp_cc_sleep_clk = {
431cc517ea3SLoic Poulain 	.halt_reg = 0x6068,
432cc517ea3SLoic Poulain 	.halt_check = BRANCH_HALT,
433cc517ea3SLoic Poulain 	.clkr = {
434cc517ea3SLoic Poulain 		.enable_reg = 0x6068,
435cc517ea3SLoic Poulain 		.enable_mask = BIT(0),
436cc517ea3SLoic Poulain 		.hw.init = &(struct clk_init_data){
437cc517ea3SLoic Poulain 			.name = "disp_cc_sleep_clk",
438cc517ea3SLoic Poulain 			.parent_hws = (const struct clk_hw*[]){
439cc517ea3SLoic Poulain 				&disp_cc_sleep_clk_src.clkr.hw,
440cc517ea3SLoic Poulain 			},
441cc517ea3SLoic Poulain 			.num_parents = 1,
442cc517ea3SLoic Poulain 			.flags = CLK_SET_RATE_PARENT,
443cc517ea3SLoic Poulain 			.ops = &clk_branch2_ops,
444cc517ea3SLoic Poulain 		},
445cc517ea3SLoic Poulain 	},
446cc517ea3SLoic Poulain };
447cc517ea3SLoic Poulain 
448002c3fb6SKonrad Dybcio static const struct qcom_reset_map disp_cc_qcm2290_resets[] = {
449002c3fb6SKonrad Dybcio 	[DISP_CC_MDSS_CORE_BCR] = { 0x2000 },
450002c3fb6SKonrad Dybcio };
451002c3fb6SKonrad Dybcio 
452cc517ea3SLoic Poulain static struct gdsc mdss_gdsc = {
453cc517ea3SLoic Poulain 	.gdscr = 0x3000,
454cc517ea3SLoic Poulain 	.pd = {
455cc517ea3SLoic Poulain 		.name = "mdss_gdsc",
456cc517ea3SLoic Poulain 	},
457cc517ea3SLoic Poulain 	.pwrsts = PWRSTS_OFF_ON,
458cc517ea3SLoic Poulain 	.flags = HW_CTRL,
459cc517ea3SLoic Poulain };
460cc517ea3SLoic Poulain 
461cc517ea3SLoic Poulain static struct gdsc *disp_cc_qcm2290_gdscs[] = {
462cc517ea3SLoic Poulain 	[MDSS_GDSC] = &mdss_gdsc,
463cc517ea3SLoic Poulain };
464cc517ea3SLoic Poulain 
465cc517ea3SLoic Poulain static struct clk_regmap *disp_cc_qcm2290_clocks[] = {
466cc517ea3SLoic Poulain 	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
467cc517ea3SLoic Poulain 	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
468cc517ea3SLoic Poulain 	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
469cc517ea3SLoic Poulain 	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
470cc517ea3SLoic Poulain 	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
471cc517ea3SLoic Poulain 	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
472cc517ea3SLoic Poulain 	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
473cc517ea3SLoic Poulain 	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
474cc517ea3SLoic Poulain 	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
475cc517ea3SLoic Poulain 	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
476cc517ea3SLoic Poulain 	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
477cc517ea3SLoic Poulain 	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
478cc517ea3SLoic Poulain 	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
479cc517ea3SLoic Poulain 	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
480cc517ea3SLoic Poulain 	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
481cc517ea3SLoic Poulain 	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
482cc517ea3SLoic Poulain 	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
483cc517ea3SLoic Poulain 	[DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
484cc517ea3SLoic Poulain 	[DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
485cc517ea3SLoic Poulain };
486cc517ea3SLoic Poulain 
487cc517ea3SLoic Poulain static const struct regmap_config disp_cc_qcm2290_regmap_config = {
488cc517ea3SLoic Poulain 	.reg_bits = 32,
489cc517ea3SLoic Poulain 	.reg_stride = 4,
490cc517ea3SLoic Poulain 	.val_bits = 32,
491cc517ea3SLoic Poulain 	.max_register = 0x10000,
492cc517ea3SLoic Poulain 	.fast_io = true,
493cc517ea3SLoic Poulain };
494cc517ea3SLoic Poulain 
495cc517ea3SLoic Poulain static const struct qcom_cc_desc disp_cc_qcm2290_desc = {
496cc517ea3SLoic Poulain 	.config = &disp_cc_qcm2290_regmap_config,
497cc517ea3SLoic Poulain 	.clks = disp_cc_qcm2290_clocks,
498cc517ea3SLoic Poulain 	.num_clks = ARRAY_SIZE(disp_cc_qcm2290_clocks),
499cc517ea3SLoic Poulain 	.gdscs = disp_cc_qcm2290_gdscs,
500cc517ea3SLoic Poulain 	.num_gdscs = ARRAY_SIZE(disp_cc_qcm2290_gdscs),
501002c3fb6SKonrad Dybcio 	.resets = disp_cc_qcm2290_resets,
502002c3fb6SKonrad Dybcio 	.num_resets = ARRAY_SIZE(disp_cc_qcm2290_resets),
503cc517ea3SLoic Poulain };
504cc517ea3SLoic Poulain 
505cc517ea3SLoic Poulain static const struct of_device_id disp_cc_qcm2290_match_table[] = {
506cc517ea3SLoic Poulain 	{ .compatible = "qcom,qcm2290-dispcc" },
507cc517ea3SLoic Poulain 	{ }
508cc517ea3SLoic Poulain };
509cc517ea3SLoic Poulain MODULE_DEVICE_TABLE(of, disp_cc_qcm2290_match_table);
510cc517ea3SLoic Poulain 
511cc517ea3SLoic Poulain static int disp_cc_qcm2290_probe(struct platform_device *pdev)
512cc517ea3SLoic Poulain {
513cc517ea3SLoic Poulain 	struct regmap *regmap;
514cc517ea3SLoic Poulain 	int ret;
515cc517ea3SLoic Poulain 
516cc517ea3SLoic Poulain 	regmap = qcom_cc_map(pdev, &disp_cc_qcm2290_desc);
517cc517ea3SLoic Poulain 	if (IS_ERR(regmap))
518cc517ea3SLoic Poulain 		return PTR_ERR(regmap);
519cc517ea3SLoic Poulain 
520cc517ea3SLoic Poulain 	clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
521cc517ea3SLoic Poulain 
522cc517ea3SLoic Poulain 	/* Keep DISP_CC_XO_CLK always-ON */
523cc517ea3SLoic Poulain 	regmap_update_bits(regmap, 0x604c, BIT(0), BIT(0));
524cc517ea3SLoic Poulain 
525cc517ea3SLoic Poulain 	ret = qcom_cc_really_probe(pdev, &disp_cc_qcm2290_desc, regmap);
526cc517ea3SLoic Poulain 	if (ret) {
527cc517ea3SLoic Poulain 		dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");
528cc517ea3SLoic Poulain 		return ret;
529cc517ea3SLoic Poulain 	}
530cc517ea3SLoic Poulain 
531cc517ea3SLoic Poulain 	return ret;
532cc517ea3SLoic Poulain }
533cc517ea3SLoic Poulain 
534cc517ea3SLoic Poulain static struct platform_driver disp_cc_qcm2290_driver = {
535cc517ea3SLoic Poulain 	.probe = disp_cc_qcm2290_probe,
536cc517ea3SLoic Poulain 	.driver = {
537cc517ea3SLoic Poulain 		.name = "dispcc-qcm2290",
538cc517ea3SLoic Poulain 		.of_match_table = disp_cc_qcm2290_match_table,
539cc517ea3SLoic Poulain 	},
540cc517ea3SLoic Poulain };
541cc517ea3SLoic Poulain 
542c334ecf3SDmitry Baryshkov module_platform_driver(disp_cc_qcm2290_driver);
543cc517ea3SLoic Poulain 
544cc517ea3SLoic Poulain MODULE_DESCRIPTION("QTI DISP_CC qcm2290 Driver");
545cc517ea3SLoic Poulain MODULE_LICENSE("GPL v2");
546