1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * PLL clock descriptions for TI DA850/OMAP-L138/AM18XX |
4 | * |
5 | * Copyright (C) 2018 David Lechner <david@lechnology.com> |
6 | */ |
7 | |
8 | #include <linux/bitops.h> |
9 | #include <linux/clk-provider.h> |
10 | #include <linux/clk/davinci.h> |
11 | #include <linux/clkdev.h> |
12 | #include <linux/device.h> |
13 | #include <linux/init.h> |
14 | #include <linux/io.h> |
15 | #include <linux/kernel.h> |
16 | #include <linux/mfd/da8xx-cfgchip.h> |
17 | #include <linux/mfd/syscon.h> |
18 | #include <linux/of_address.h> |
19 | #include <linux/of.h> |
20 | #include <linux/types.h> |
21 | |
22 | #include "pll.h" |
23 | |
24 | #define OCSEL_OCSRC_OSCIN 0x14 |
25 | #define OCSEL_OCSRC_PLL0_SYSCLK(n) (0x16 + (n)) |
26 | #define OCSEL_OCSRC_PLL1_OBSCLK 0x1e |
27 | #define OCSEL_OCSRC_PLL1_SYSCLK(n) (0x16 + (n)) |
28 | |
29 | static const struct davinci_pll_clk_info da850_pll0_info = { |
30 | .name = "pll0" , |
31 | .unlock_reg = CFGCHIP(0), |
32 | .unlock_mask = CFGCHIP0_PLL_MASTER_LOCK, |
33 | .pllm_mask = GENMASK(4, 0), |
34 | .pllm_min = 4, |
35 | .pllm_max = 32, |
36 | .pllout_min_rate = 300000000, |
37 | .pllout_max_rate = 600000000, |
38 | .flags = PLL_HAS_CLKMODE | PLL_HAS_PREDIV | PLL_HAS_POSTDIV | |
39 | PLL_HAS_EXTCLKSRC, |
40 | }; |
41 | |
42 | /* |
43 | * NB: Technically, the clocks flagged as SYSCLK_FIXED_DIV are "fixed ratio", |
44 | * meaning that we could change the divider as long as we keep the correct |
45 | * ratio between all of the clocks, but we don't support that because there is |
46 | * currently not a need for it. |
47 | */ |
48 | |
49 | SYSCLK(1, pll0_sysclk1, pll0_pllen, 5, SYSCLK_FIXED_DIV); |
50 | SYSCLK(2, pll0_sysclk2, pll0_pllen, 5, SYSCLK_FIXED_DIV); |
51 | SYSCLK(3, pll0_sysclk3, pll0_pllen, 5, 0); |
52 | SYSCLK(4, pll0_sysclk4, pll0_pllen, 5, SYSCLK_FIXED_DIV); |
53 | SYSCLK(5, pll0_sysclk5, pll0_pllen, 5, 0); |
54 | SYSCLK(6, pll0_sysclk6, pll0_pllen, 5, SYSCLK_ARM_RATE | SYSCLK_FIXED_DIV); |
55 | SYSCLK(7, pll0_sysclk7, pll0_pllen, 5, 0); |
56 | |
57 | static const char * const da850_pll0_obsclk_parent_names[] = { |
58 | "oscin" , |
59 | "pll0_sysclk1" , |
60 | "pll0_sysclk2" , |
61 | "pll0_sysclk3" , |
62 | "pll0_sysclk4" , |
63 | "pll0_sysclk5" , |
64 | "pll0_sysclk6" , |
65 | "pll0_sysclk7" , |
66 | "pll1_obsclk" , |
67 | }; |
68 | |
69 | static u32 da850_pll0_obsclk_table[] = { |
70 | OCSEL_OCSRC_OSCIN, |
71 | OCSEL_OCSRC_PLL0_SYSCLK(1), |
72 | OCSEL_OCSRC_PLL0_SYSCLK(2), |
73 | OCSEL_OCSRC_PLL0_SYSCLK(3), |
74 | OCSEL_OCSRC_PLL0_SYSCLK(4), |
75 | OCSEL_OCSRC_PLL0_SYSCLK(5), |
76 | OCSEL_OCSRC_PLL0_SYSCLK(6), |
77 | OCSEL_OCSRC_PLL0_SYSCLK(7), |
78 | OCSEL_OCSRC_PLL1_OBSCLK, |
79 | }; |
80 | |
81 | static const struct davinci_pll_obsclk_info da850_pll0_obsclk_info = { |
82 | .name = "pll0_obsclk" , |
83 | .parent_names = da850_pll0_obsclk_parent_names, |
84 | .num_parents = ARRAY_SIZE(da850_pll0_obsclk_parent_names), |
85 | .table = da850_pll0_obsclk_table, |
86 | .ocsrc_mask = GENMASK(4, 0), |
87 | }; |
88 | |
89 | int da850_pll0_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) |
90 | { |
91 | struct clk *clk; |
92 | |
93 | davinci_pll_clk_register(dev, info: &da850_pll0_info, parent_name: "ref_clk" , base, cfgchip); |
94 | |
95 | clk = davinci_pll_sysclk_register(dev, info: &pll0_sysclk1, base); |
96 | clk_register_clkdev(clk, "pll0_sysclk1" , "da850-psc0" ); |
97 | |
98 | clk = davinci_pll_sysclk_register(dev, info: &pll0_sysclk2, base); |
99 | clk_register_clkdev(clk, "pll0_sysclk2" , "da850-psc0" ); |
100 | clk_register_clkdev(clk, "pll0_sysclk2" , "da850-psc1" ); |
101 | clk_register_clkdev(clk, "pll0_sysclk2" , "da850-async3-clksrc" ); |
102 | |
103 | clk = davinci_pll_sysclk_register(dev, info: &pll0_sysclk3, base); |
104 | clk_register_clkdev(clk, "pll0_sysclk3" , "da850-async1-clksrc" ); |
105 | |
106 | clk = davinci_pll_sysclk_register(dev, info: &pll0_sysclk4, base); |
107 | clk_register_clkdev(clk, "pll0_sysclk4" , "da850-psc0" ); |
108 | clk_register_clkdev(clk, "pll0_sysclk4" , "da850-psc1" ); |
109 | |
110 | davinci_pll_sysclk_register(dev, info: &pll0_sysclk5, base); |
111 | |
112 | clk = davinci_pll_sysclk_register(dev, info: &pll0_sysclk6, base); |
113 | clk_register_clkdev(clk, "pll0_sysclk6" , "da850-psc0" ); |
114 | |
115 | davinci_pll_sysclk_register(dev, info: &pll0_sysclk7, base); |
116 | |
117 | davinci_pll_auxclk_register(dev, name: "pll0_auxclk" , base); |
118 | |
119 | clk = clk_register_fixed_factor(dev, name: "async2" , parent_name: "pll0_auxclk" , |
120 | CLK_IS_CRITICAL, mult: 1, div: 1); |
121 | |
122 | clk_register_clkdev(clk, NULL, "i2c_davinci.1" ); |
123 | clk_register_clkdev(clk, "timer0" , NULL); |
124 | clk_register_clkdev(clk, NULL, "davinci-wdt" ); |
125 | |
126 | davinci_pll_obsclk_register(dev, info: &da850_pll0_obsclk_info, base); |
127 | |
128 | return 0; |
129 | } |
130 | |
131 | static const struct davinci_pll_sysclk_info *da850_pll0_sysclk_info[] = { |
132 | &pll0_sysclk1, |
133 | &pll0_sysclk2, |
134 | &pll0_sysclk3, |
135 | &pll0_sysclk4, |
136 | &pll0_sysclk5, |
137 | &pll0_sysclk6, |
138 | &pll0_sysclk7, |
139 | NULL |
140 | }; |
141 | |
142 | void of_da850_pll0_init(struct device_node *node) |
143 | { |
144 | void __iomem *base; |
145 | struct regmap *cfgchip; |
146 | |
147 | base = of_iomap(node, index: 0); |
148 | if (!base) { |
149 | pr_err("%s: ioremap failed\n" , __func__); |
150 | return; |
151 | } |
152 | |
153 | cfgchip = syscon_regmap_lookup_by_compatible(s: "ti,da830-cfgchip" ); |
154 | |
155 | of_davinci_pll_init(NULL, node, info: &da850_pll0_info, |
156 | obsclk_info: &da850_pll0_obsclk_info, |
157 | div_info: da850_pll0_sysclk_info, max_sysclk_id: 7, base, cfgchip); |
158 | } |
159 | |
160 | static const struct davinci_pll_clk_info da850_pll1_info = { |
161 | .name = "pll1" , |
162 | .unlock_reg = CFGCHIP(3), |
163 | .unlock_mask = CFGCHIP3_PLL1_MASTER_LOCK, |
164 | .pllm_mask = GENMASK(4, 0), |
165 | .pllm_min = 4, |
166 | .pllm_max = 32, |
167 | .pllout_min_rate = 300000000, |
168 | .pllout_max_rate = 600000000, |
169 | .flags = PLL_HAS_POSTDIV, |
170 | }; |
171 | |
172 | SYSCLK(1, pll1_sysclk1, pll1_pllen, 5, SYSCLK_ALWAYS_ENABLED); |
173 | SYSCLK(2, pll1_sysclk2, pll1_pllen, 5, 0); |
174 | SYSCLK(3, pll1_sysclk3, pll1_pllen, 5, 0); |
175 | |
176 | static const char * const da850_pll1_obsclk_parent_names[] = { |
177 | "oscin" , |
178 | "pll1_sysclk1" , |
179 | "pll1_sysclk2" , |
180 | "pll1_sysclk3" , |
181 | }; |
182 | |
183 | static u32 da850_pll1_obsclk_table[] = { |
184 | OCSEL_OCSRC_OSCIN, |
185 | OCSEL_OCSRC_PLL1_SYSCLK(1), |
186 | OCSEL_OCSRC_PLL1_SYSCLK(2), |
187 | OCSEL_OCSRC_PLL1_SYSCLK(3), |
188 | }; |
189 | |
190 | static const struct davinci_pll_obsclk_info da850_pll1_obsclk_info = { |
191 | .name = "pll1_obsclk" , |
192 | .parent_names = da850_pll1_obsclk_parent_names, |
193 | .num_parents = ARRAY_SIZE(da850_pll1_obsclk_parent_names), |
194 | .table = da850_pll1_obsclk_table, |
195 | .ocsrc_mask = GENMASK(4, 0), |
196 | }; |
197 | |
198 | int da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) |
199 | { |
200 | struct clk *clk; |
201 | |
202 | davinci_pll_clk_register(dev, info: &da850_pll1_info, parent_name: "oscin" , base, cfgchip); |
203 | |
204 | davinci_pll_sysclk_register(dev, info: &pll1_sysclk1, base); |
205 | |
206 | clk = davinci_pll_sysclk_register(dev, info: &pll1_sysclk2, base); |
207 | clk_register_clkdev(clk, "pll1_sysclk2" , "da850-async3-clksrc" ); |
208 | |
209 | davinci_pll_sysclk_register(dev, info: &pll1_sysclk3, base); |
210 | |
211 | davinci_pll_obsclk_register(dev, info: &da850_pll1_obsclk_info, base); |
212 | |
213 | return 0; |
214 | } |
215 | |
216 | static const struct davinci_pll_sysclk_info *da850_pll1_sysclk_info[] = { |
217 | &pll1_sysclk1, |
218 | &pll1_sysclk2, |
219 | &pll1_sysclk3, |
220 | NULL |
221 | }; |
222 | |
223 | int of_da850_pll1_init(struct device *dev, void __iomem *base, struct regmap *cfgchip) |
224 | { |
225 | return of_davinci_pll_init(dev, node: dev->of_node, info: &da850_pll1_info, |
226 | obsclk_info: &da850_pll1_obsclk_info, |
227 | div_info: da850_pll1_sysclk_info, max_sysclk_id: 3, base, cfgchip); |
228 | } |
229 | |