29f0126cbd05bc77227d523deb7adaebf9744dc6
[openwrt/staging/stintel.git] / target / linux / airoha / files-5.15 / drivers / clk / clk-en7523.c
1 // SPDX-License-Identifier: GPL-2.0-only
2
3 #include <linux/delay.h>
4 #include <linux/clk-provider.h>
5 #include <linux/of.h>
6 #include <linux/of_address.h>
7 #include <linux/of_device.h>
8 #include <linux/platform_device.h>
9 #include <dt-bindings/clock/en7523-clk.h>
10
11 #define REG_PCI_CONTROL 0x88
12 #define REG_PCI_CONTROL_PERSTOUT BIT(29)
13 #define REG_PCI_CONTROL_PERSTOUT1 BIT(26)
14 #define REG_PCI_CONTROL_REFCLK_EN1 BIT(22)
15 #define REG_GSW_CLK_DIV_SEL 0x1b4
16 #define REG_EMI_CLK_DIV_SEL 0x1b8
17 #define REG_BUS_CLK_DIV_SEL 0x1bc
18 #define REG_SPI_CLK_DIV_SEL 0x1c4
19 #define REG_SPI_CLK_FREQ_SEL 0x1c8
20 #define REG_NPU_CLK_DIV_SEL 0x1fc
21 #define REG_CRYPTO_CLKSRC 0x200
22 #define REG_RESET_CONTROL 0x834
23 #define REG_RESET_CONTROL_PCIEHB BIT(29)
24 #define REG_RESET_CONTROL_PCIE1 BIT(27)
25 #define REG_RESET_CONTROL_PCIE2 BIT(26)
26
27 struct en_clk_desc {
28 int id;
29 const char *name;
30 u32 base_reg;
31 u8 base_bits;
32 u8 base_shift;
33 union {
34 const unsigned int *base_values;
35 unsigned int base_value;
36 };
37 size_t n_base_values;
38
39 u16 div_reg;
40 u8 div_bits;
41 u8 div_shift;
42 u16 div_val0;
43 u8 div_step;
44 };
45
46 struct en_clk_gate {
47 void __iomem *base;
48 struct clk_hw hw;
49 };
50
51 static const u32 gsw_base[] = { 400000000, 500000000 };
52 static const u32 emi_base[] = { 333000000, 400000000 };
53 static const u32 bus_base[] = { 500000000, 540000000 };
54 static const u32 slic_base[] = { 100000000, 3125000 };
55 static const u32 npu_base[] = { 333000000, 400000000, 500000000 };
56
57 static const struct en_clk_desc en7523_base_clks[] = {
58 {
59 .id = EN7523_CLK_GSW,
60 .name = "gsw",
61
62 .base_reg = REG_GSW_CLK_DIV_SEL,
63 .base_bits = 1,
64 .base_shift = 8,
65 .base_values = gsw_base,
66 .n_base_values = ARRAY_SIZE(gsw_base),
67
68 .div_bits = 3,
69 .div_shift = 0,
70 .div_step = 1,
71 }, {
72 .id = EN7523_CLK_EMI,
73 .name = "emi",
74
75 .base_reg = REG_EMI_CLK_DIV_SEL,
76 .base_bits = 1,
77 .base_shift = 8,
78 .base_values = emi_base,
79 .n_base_values = ARRAY_SIZE(emi_base),
80
81 .div_bits = 3,
82 .div_shift = 0,
83 .div_step = 1,
84 }, {
85 .id = EN7523_CLK_BUS,
86 .name = "bus",
87
88 .base_reg = REG_BUS_CLK_DIV_SEL,
89 .base_bits = 1,
90 .base_shift = 8,
91 .base_values = bus_base,
92 .n_base_values = ARRAY_SIZE(bus_base),
93
94 .div_bits = 3,
95 .div_shift = 0,
96 .div_step = 1,
97 }, {
98 .id = EN7523_CLK_SLIC,
99 .name = "slic",
100
101 .base_reg = REG_SPI_CLK_FREQ_SEL,
102 .base_bits = 1,
103 .base_shift = 0,
104 .base_values = slic_base,
105 .n_base_values = ARRAY_SIZE(slic_base),
106
107 .div_reg = REG_SPI_CLK_DIV_SEL,
108 .div_bits = 5,
109 .div_shift = 24,
110 .div_val0 = 20,
111 .div_step = 2,
112 }, {
113 .id = EN7523_CLK_SPI,
114 .name = "spi",
115
116 .base_reg = REG_SPI_CLK_DIV_SEL,
117
118 .base_value = 400000000,
119
120 .div_bits = 5,
121 .div_shift = 8,
122 .div_val0 = 40,
123 .div_step = 2,
124 }, {
125 .id = EN7523_CLK_NPU,
126 .name = "npu",
127
128 .base_reg = REG_NPU_CLK_DIV_SEL,
129 .base_bits = 2,
130 .base_shift = 8,
131 .base_values = npu_base,
132 .n_base_values = ARRAY_SIZE(npu_base),
133
134 .div_bits = 3,
135 .div_shift = 0,
136 .div_step = 1,
137 }, {
138 .id = EN7523_CLK_CRYPTO,
139 .name = "crypto",
140
141 .base_reg = REG_CRYPTO_CLKSRC,
142 .base_bits = 1,
143 .base_shift = 8,
144 .base_values = emi_base,
145 .n_base_values = ARRAY_SIZE(emi_base),
146 }
147 };
148
149 static const struct of_device_id of_match_clk_en7523[] = {
150 { .compatible = "airoha,en7523-scu", },
151 { /* sentinel */ }
152 };
153
154 static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
155 {
156 const struct en_clk_desc *desc = &en7523_base_clks[i];
157 u32 val;
158
159 if (!desc->base_bits)
160 return desc->base_value;
161
162 val = readl(base + desc->base_reg);
163 val >>= desc->base_shift;
164 val &= (1 << desc->base_bits) - 1;
165
166 if (val >= desc->n_base_values)
167 return 0;
168
169 return desc->base_values[val];
170 }
171
172 static u32 en7523_get_div(void __iomem *base, int i)
173 {
174 const struct en_clk_desc *desc = &en7523_base_clks[i];
175 u32 reg, val;
176
177 if (!desc->div_bits)
178 return 1;
179
180 reg = desc->div_reg ? desc->div_reg : desc->base_reg;
181 val = readl(base + reg);
182 val >>= desc->div_shift;
183 val &= (1 << desc->div_bits) - 1;
184
185 if (!val && desc->div_val0)
186 return desc->div_val0;
187
188 return (val + 1) * desc->div_step;
189 }
190
191 static int en7523_pci_is_enabled(struct clk_hw *hw)
192 {
193 struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
194
195 return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1);
196 }
197
198 static int en7523_pci_prepare(struct clk_hw *hw)
199 {
200 struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
201 void __iomem *np_base = cg->base;
202 u32 val, mask;
203
204 /* Need to pull device low before reset */
205 val = readl(np_base + REG_PCI_CONTROL);
206 val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT);
207 writel(val, np_base + REG_PCI_CONTROL);
208 usleep_range(1000, 2000);
209
210 /* Enable PCIe port 1 */
211 val |= REG_PCI_CONTROL_REFCLK_EN1;
212 writel(val, np_base + REG_PCI_CONTROL);
213 usleep_range(1000, 2000);
214
215 /* Reset to default */
216 val = readl(np_base + REG_RESET_CONTROL);
217 mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
218 REG_RESET_CONTROL_PCIEHB;
219 writel(val & ~mask, np_base + REG_RESET_CONTROL);
220 usleep_range(1000, 2000);
221 writel(val | mask, np_base + REG_RESET_CONTROL);
222 msleep(100);
223 writel(val & ~mask, np_base + REG_RESET_CONTROL);
224 usleep_range(5000, 10000);
225
226 /* Release device */
227 mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT;
228 val = readl(np_base + REG_PCI_CONTROL);
229 writel(val & ~mask, np_base + REG_PCI_CONTROL);
230 usleep_range(1000, 2000);
231 writel(val | mask, np_base + REG_PCI_CONTROL);
232 msleep(250);
233
234 return 0;
235 }
236
237 static void en7523_pci_unprepare(struct clk_hw *hw)
238 {
239 struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
240 void __iomem *np_base = cg->base;
241 u32 val;
242
243 val = readl(np_base + REG_PCI_CONTROL);
244 val &= ~REG_PCI_CONTROL_REFCLK_EN1;
245 writel(val, np_base + REG_PCI_CONTROL);
246 }
247
248 static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
249 void __iomem *np_base)
250 {
251 static const struct clk_ops pcie_gate_ops = {
252 .is_enabled = en7523_pci_is_enabled,
253 .prepare = en7523_pci_prepare,
254 .unprepare = en7523_pci_unprepare,
255 };
256 struct clk_init_data init = {
257 .name = "pcie",
258 .ops = &pcie_gate_ops,
259 };
260 struct en_clk_gate *cg;
261
262 cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
263 if (!cg)
264 return NULL;
265
266 cg->base = np_base;
267 cg->hw.init = &init;
268 en7523_pci_unprepare(&cg->hw);
269
270 if (clk_hw_register(dev, &cg->hw))
271 return NULL;
272
273 return &cg->hw;
274 }
275
276 static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
277 void __iomem *base, void __iomem *np_base)
278 {
279 struct clk_hw *hw;
280 u32 rate;
281 int i;
282
283 for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
284 const struct en_clk_desc *desc = &en7523_base_clks[i];
285
286 rate = en7523_get_base_rate(base, i);
287 rate /= en7523_get_div(base, i);
288
289 hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
290 if (IS_ERR(hw)) {
291 pr_err("Failed to register clk %s: %ld\n",
292 desc->name, PTR_ERR(hw));
293 continue;
294 }
295
296 clk_data->hws[desc->id] = hw;
297 }
298
299 hw = en7523_register_pcie_clk(dev, np_base);
300 clk_data->hws[EN7523_CLK_PCIE] = hw;
301
302 clk_data->num = EN7523_NUM_CLOCKS;
303 }
304
305 static int en7523_clk_probe(struct platform_device *pdev)
306 {
307 struct device_node *node = pdev->dev.of_node;
308 struct clk_hw_onecell_data *clk_data;
309 void __iomem *base, *np_base;
310 int r;
311
312 base = devm_platform_ioremap_resource(pdev, 0);
313 if (IS_ERR(base))
314 return PTR_ERR(base);
315
316 np_base = devm_platform_ioremap_resource(pdev, 1);
317 if (IS_ERR(np_base))
318 return PTR_ERR(np_base);
319
320 clk_data = devm_kzalloc(&pdev->dev,
321 struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
322 GFP_KERNEL);
323 if (!clk_data)
324 return -ENOMEM;
325
326 en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
327
328 r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
329 if (r)
330 dev_err(&pdev->dev,
331 "could not register clock provider: %s: %d\n",
332 pdev->name, r);
333
334 return r;
335 }
336
337 static struct platform_driver clk_en7523_drv = {
338 .probe = en7523_clk_probe,
339 .driver = {
340 .name = "clk-en7523",
341 .of_match_table = of_match_clk_en7523,
342 .suppress_bind_attrs = true,
343 },
344 };
345
346 static int __init clk_en7523_init(void)
347 {
348 return platform_driver_register(&clk_en7523_drv);
349 }
350
351 arch_initcall(clk_en7523_init);