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