1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020-2021 SiFive, Inc.
4  * Copyright (C) 2020-2021 Zong Li
5  */
6 
7 #ifndef __SIFIVE_CLK_FU740_PRCI_H
8 #define __SIFIVE_CLK_FU740_PRCI_H
9 
10 #include <linux/module.h>
11 
12 #include <dt-bindings/clock/sifive-fu740-prci.h>
13 
14 #include "sifive-prci.h"
15 
16 /* PRCI integration data for each WRPLL instance */
17 
18 static struct __prci_wrpll_data sifive_fu740_prci_corepll_data = {
19 	.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
20 	.cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
21 	.enable_bypass = sifive_prci_coreclksel_use_hfclk,
22 	.disable_bypass = sifive_prci_coreclksel_use_final_corepll,
23 };
24 
25 static struct __prci_wrpll_data sifive_fu740_prci_ddrpll_data = {
26 	.cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
27 	.cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
28 };
29 
30 static struct __prci_wrpll_data sifive_fu740_prci_gemgxlpll_data = {
31 	.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
32 	.cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
33 };
34 
35 static struct __prci_wrpll_data sifive_fu740_prci_dvfscorepll_data = {
36 	.cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET,
37 	.cfg1_offs = PRCI_DVFSCOREPLLCFG1_OFFSET,
38 	.enable_bypass = sifive_prci_corepllsel_use_corepll,
39 	.disable_bypass = sifive_prci_corepllsel_use_dvfscorepll,
40 };
41 
42 static struct __prci_wrpll_data sifive_fu740_prci_hfpclkpll_data = {
43 	.cfg0_offs = PRCI_HFPCLKPLLCFG0_OFFSET,
44 	.cfg1_offs = PRCI_HFPCLKPLLCFG1_OFFSET,
45 	.enable_bypass = sifive_prci_hfpclkpllsel_use_hfclk,
46 	.disable_bypass = sifive_prci_hfpclkpllsel_use_hfpclkpll,
47 };
48 
49 static struct __prci_wrpll_data sifive_fu740_prci_cltxpll_data = {
50 	.cfg0_offs = PRCI_CLTXPLLCFG0_OFFSET,
51 	.cfg1_offs = PRCI_CLTXPLLCFG1_OFFSET,
52 };
53 
54 /* Linux clock framework integration */
55 
56 static const struct clk_ops sifive_fu740_prci_wrpll_clk_ops = {
57 	.set_rate = sifive_prci_wrpll_set_rate,
58 	.round_rate = sifive_prci_wrpll_round_rate,
59 	.recalc_rate = sifive_prci_wrpll_recalc_rate,
60 	.enable = sifive_prci_clock_enable,
61 	.disable = sifive_prci_clock_disable,
62 	.is_enabled = sifive_clk_is_enabled,
63 };
64 
65 static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = {
66 	.recalc_rate = sifive_prci_wrpll_recalc_rate,
67 };
68 
69 static const struct clk_ops sifive_fu740_prci_tlclksel_clk_ops = {
70 	.recalc_rate = sifive_prci_tlclksel_recalc_rate,
71 };
72 
73 static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = {
74 	.recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
75 };
76 
77 static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
78 	.enable = sifive_prci_pcie_aux_clock_enable,
79 	.disable = sifive_prci_pcie_aux_clock_disable,
80 	.is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
81 };
82 
83 /* List of clock controls provided by the PRCI */
84 static struct __prci_clock __prci_init_clocks_fu740[] = {
85 	[FU740_PRCI_CLK_COREPLL] = {
86 		.name = "corepll",
87 		.parent_name = "hfclk",
88 		.ops = &sifive_fu740_prci_wrpll_clk_ops,
89 		.pwd = &sifive_fu740_prci_corepll_data,
90 	},
91 	[FU740_PRCI_CLK_DDRPLL] = {
92 		.name = "ddrpll",
93 		.parent_name = "hfclk",
94 		.ops = &sifive_fu740_prci_wrpll_ro_clk_ops,
95 		.pwd = &sifive_fu740_prci_ddrpll_data,
96 	},
97 	[FU740_PRCI_CLK_GEMGXLPLL] = {
98 		.name = "gemgxlpll",
99 		.parent_name = "hfclk",
100 		.ops = &sifive_fu740_prci_wrpll_clk_ops,
101 		.pwd = &sifive_fu740_prci_gemgxlpll_data,
102 	},
103 	[FU740_PRCI_CLK_DVFSCOREPLL] = {
104 		.name = "dvfscorepll",
105 		.parent_name = "hfclk",
106 		.ops = &sifive_fu740_prci_wrpll_clk_ops,
107 		.pwd = &sifive_fu740_prci_dvfscorepll_data,
108 	},
109 	[FU740_PRCI_CLK_HFPCLKPLL] = {
110 		.name = "hfpclkpll",
111 		.parent_name = "hfclk",
112 		.ops = &sifive_fu740_prci_wrpll_clk_ops,
113 		.pwd = &sifive_fu740_prci_hfpclkpll_data,
114 	},
115 	[FU740_PRCI_CLK_CLTXPLL] = {
116 		.name = "cltxpll",
117 		.parent_name = "hfclk",
118 		.ops = &sifive_fu740_prci_wrpll_clk_ops,
119 		.pwd = &sifive_fu740_prci_cltxpll_data,
120 	},
121 	[FU740_PRCI_CLK_TLCLK] = {
122 		.name = "tlclk",
123 		.parent_name = "corepll",
124 		.ops = &sifive_fu740_prci_tlclksel_clk_ops,
125 	},
126 	[FU740_PRCI_CLK_PCLK] = {
127 		.name = "pclk",
128 		.parent_name = "hfpclkpll",
129 		.ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops,
130 	},
131 	[FU740_PRCI_CLK_PCIE_AUX] = {
132 		.name = "pcie_aux",
133 		.parent_name = "hfclk",
134 		.ops = &sifive_fu740_prci_pcie_aux_clk_ops,
135 	},
136 };
137 
138 static const struct prci_clk_desc prci_clk_fu740 = {
139 	.clks = __prci_init_clocks_fu740,
140 	.num_clks = ARRAY_SIZE(__prci_init_clocks_fu740),
141 };
142 
143 #endif /* __SIFIVE_CLK_FU740_PRCI_H */
144